<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note><div><div><br/></div><table style="border-style: none; font-size: 11px; text-align: left; letter-spacing: normal; orphans: 2; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;" width="100%"><colgroup><col style="width: 244px;"/><col style="width: 130px;"/></colgroup><tbody><tr><td style="vertical-align: top; overflow-wrap: break-word;"><div style="margin: 0px; border-width: 2px; border-style: solid; border-color: rgb(119, 136, 153); padding: 5px 2px; width: 246px;"><div><div><br/></div><table style="border-style: none; font-size: 11px; text-align: left; width: 246px;"><colgroup><col style="width: 82px;"/><col style="width: 82px;"/><col style="width: 82px;"/></colgroup><tbody><tr><td><div><br/></div><div><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></div></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">85525847</span></td><td><div><br/></div></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">10 digit Account ID</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">085525847-0</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Account Name</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">LEONG YOON WAI</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">IC Number</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">770505145805</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">IC Type</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NRIC</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">VIP Status</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Non-VIP</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Customer Type</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">REGULAR</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Bill Frequency</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">1</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Payment Type</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Cash</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Last CC/DD Extraction</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">21-APR-16 - Deposit Creation</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">AR Balance</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">0</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Account Status</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">A</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Bill Cycle Code</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">17</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">New Bill Cycle Code</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Old Bill Cycle Exp Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr></tbody></table><div><br/></div></div></div><div style="margin: 5px 0px 0px; background-color: rgb(119, 136, 153); padding: 3px 5px 1px; width: 244px;"><span style="color: white; font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;"><img src="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/images/bullet_toggle_minus.png"/> Bill Statement Summary</span></div><div style="margin: 0px; border-width: 2px; border-style: solid; border-color: rgb(119, 136, 153); padding: 5px 2px; width: 246px; color: rgb(0, 0, 102);"/><div style="margin: 5px 0px 0px; background-color: rgb(119, 136, 153); padding: 3px 5px 1px; width: 244px;"><span style="color: white; font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;"><img src="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/images/bullet_toggle_minus.png"/> PDPA Information (Optout Options)</span></div><div style="margin: 0px; border-width: 2px; border-style: solid; border-color: rgb(119, 136, 153); padding: 5px 2px; width: 246px;"><div><div><br/></div><table style="border-style: none; font-size: 11px; text-align: left; width: 246px;"><colgroup><col style="width: 82px;"/><col style="width: 82px;"/><col style="width: 82px;"/></colgroup><tbody><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Direct Mails(Direct Mail pack/Letters)</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">SMS</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Outbound Call/IVR (Telemarketing)</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Email</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">No Consent</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="white-space: nowrap;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">Statement Inserts/leaflets</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr></tbody></table><div><br/></div></div></div></td><td style="vertical-align: top; overflow-wrap: break-word;"><div style="margin: 5px 0px 0px; background-repeat: no-repeat; background-color: rgb(119, 136, 153); padding: 3px 5px 1px;"><div><br/></div><table cellpadding="0" cellspacing="0" style="border-style: none; font-size: 12px; text-align: left;" width="100%"><colgroup><col/><col/></colgroup><tbody><tr><td align="left"><span style="color: white; font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;"><img src="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/images/bullet_toggle_minus.png"/> Subscription Information</span></td><td align="right"><div><br/></div></td></tr></tbody></table><div><br/></div></div><div style="margin: 0px; border-width: 2px; border-style: solid; border-color: rgb(119, 136, 153); padding: 5px 0px;"><div><div><br/></div><table border="2" cellspacing="0" style="border-style: solid; font-size: 12px; text-align: left; border-color: rgb(192, 207, 240); border-width: 2px; width: 1016px; border-collapse: collapse;"><colgroup><col style="width: 169px;"/><col style="width: 169px;"/><col style="width: 169px;"/><col style="width: 169px;"/><col style="width: 169px;"/><col style="width: 169px;"/></colgroup><tbody><tr align="left" style="background-color: rgb(192, 207, 240); font-size: 8pt;"><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">SmartCardNo</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Subscription Details</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Packages</span></td><td align="center"><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Call Handling</span></td><td align="center"><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Price Calculator</span></td><td align="center"><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Byond</span></td></tr><tr align="left" style="font-size: 8pt;"><td align="left"><a href="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/Overview.aspx?ID=85525847&Search=85525847%7CrdbtnAccNo#" style="font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;" target="_blank">011082473221</a></td><td align="left"><div><br/></div><table border="0" style="border-style: none; font-size: 12px; text-align: left;"><colgroup><col/><col/><col/></colgroup><tbody><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Subscriber No</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">251924041</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Bouquet ID</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">2.0</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Provide Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">-</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">RG Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">-</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Status</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">INSTALLED</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Status Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">04-Jul-2020 09:38:44 AM</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Primary Subscription</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Campaign Code</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">4F5DRES</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Connected Box</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">First Connected Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr></tbody></table><div><br/></div></td><td align="left"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Multiroom - Effective Date : 05-JUL-20</span></td><td align="center"><div><br/></div></td><td align="center"><div><br/></div></td><td align="center"><div><br/></div></td></tr><tr align="left" style="font-size: 8pt;"><td align="left"><a href="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/Overview.aspx?ID=85525847&Search=85525847%7CrdbtnAccNo#" style="font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;" target="_blank">016007775246</a></td><td align="left"><div><br/></div><table border="0" style="border-style: none; font-size: 12px; text-align: left;"><colgroup><col/><col/><col/></colgroup><tbody><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Subscriber No</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">251959697</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Bouquet ID</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">2.0</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Provide Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">-</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">RG Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">-</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Status</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">INSTALLED</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Status Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">04-Jul-2020 09:38:42 AM</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Primary Subscription</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">NO</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Campaign Code</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">ZBN55RES</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Connected Box</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">First Connected Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr></tbody></table><div><br/></div></td><td align="left"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Multiroom - Effective Date : 05-JUL-20</span></td><td align="center"><div><br/></div></td><td align="center"><div><br/></div></td><td align="center"><div><br/></div></td></tr><tr align="left" style="font-size: 8pt;"><td align="left"><a href="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/Overview.aspx?ID=85525847&Search=85525847%7CrdbtnAccNo#" style="font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;" target="_blank">016016894533</a></td><td align="left"><div><br/></div><table border="0" style="border-style: none; font-size: 12px; text-align: left;"><colgroup><col/><col/><col/></colgroup><tbody><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Subscriber No</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">204520283</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Bouquet ID</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">2.0</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Provide Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">-</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">RG Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">-</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Status</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">INSTALLED</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Status Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">04-Jul-2020 09:38:45 AM</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Primary Subscription</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">YES</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Campaign Code</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">WBX99RES</span></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">Connected Box</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr><tr><td style="font-size: 11px;"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;">First Connected Date</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 12px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">:</span></td><td><div><br/></div></td></tr></tbody></table><div><br/></div></td><td align="left"><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Plus 1 Mini - Effective Date : 05-JUL-20,Super Pack 3 - Effective Date : 05-JUL-20</span></td><td align="center"><div><br/></div></td><td align="center"><div><br/></div></td><td align="center"><div><br/></div></td></tr></tbody></table><div><br/></div></div></div><div style="margin: 5px 0px 0px; background-repeat: no-repeat; background-color: rgb(119, 136, 153); padding: 3px 5px 1px;"><span style="color: white; font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;"><img src="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/images/bullet_toggle_minus.png"/> Address Information</span></div><div style="margin: 0px; border-width: 2px; border-style: solid; border-color: rgb(119, 136, 153); padding: 5px 0px;"><div><div><br/></div><table border="2" cellspacing="0" style="border-style: solid; font-size: 12px; text-align: left; border-color: rgb(192, 207, 240); border-width: 2px; width: 1016px; border-collapse: collapse;"><colgroup><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/><col style="width: 113px;"/></colgroup><tbody><tr align="left" style="background-color: rgb(192, 207, 240); font-size: 8pt;"><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">AddressType</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Address1</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Address2</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Address3</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Address4</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Address5</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">State</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">City</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Zip</span></td></tr><tr align="left" style="font-size: 8pt;"><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Billing Address</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">70,JLN. 44/38A</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">TAMAN SERI BINTANG,KEPONG</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">52100,KUALA LUMPUR,WIL</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">WIL</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">KUALA LUMPUR</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">52100</span></td></tr><tr align="left" style="font-size: 8pt;"><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Mailing Address</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">70,JLN. 44/38A</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">TAMAN SERI BINTANG,KEPONG</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">52100,KUALA LUMPUR,WIL</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">WIL</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">KUALA LUMPUR</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">52100</span></td></tr><tr align="left" style="font-size: 8pt;"><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Service Address</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">70,JLN. 44/38A</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">TAMAN SERI BINTANG,KEPONG</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">52100,KUALA LUMPUR,WIL</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">WIL</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">KUALA LUMPUR</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">52100</span></td></tr></tbody></table><div><br/></div></div></div><div style="margin: 5px 0px 0px; background-repeat: no-repeat; background-color: rgb(119, 136, 153); padding: 3px 5px 1px;"><span style="color: white; font-family: Arial; font-size: 11px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: bold; text-decoration-color: initial; text-decoration-style: initial;"><img src="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/images/bullet_toggle_minus.png"/> Contact Information</span></div><div style="margin: 0px; border-width: 2px; border-style: solid; border-color: rgb(119, 136, 153); padding: 5px 0px;"><div><div>unifi >10m</div><div>agree by handle</div><div>diff</div><table border="2" cellspacing="0" style="border-style: solid; font-size: 12px; text-align: left; border-color: rgb(192, 207, 240); border-width: 2px; width: 1016px; border-collapse: collapse;"><colgroup><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/><col style="width: 92px;"/></colgroup><tbody><tr align="left" style="background-color: rgb(192, 207, 240); font-size: 8pt;"><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">ContactName</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">PrimaryPhone</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">HomePhone</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">MobilePhone</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">OfficePhone</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Fax</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Email</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Race</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">DOB</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Nationality</span></td><td><span style="color: rgb(69, 69, 69); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">VIPStatus</span></td></tr><tr align="left" style="font-size: 8pt;"><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">LEONG YOON WAI</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">0193867028</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">60193827028</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">0193867028</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">0133911311</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;"> </span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">CHINESE</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">05-May-1977</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">MALAYSIA</span></td><td><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 8pt; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; text-decoration-color: initial; text-decoration-style: initial;">Non-VIP</span></td></tr></tbody></table><div><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 10.6667px; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> </span><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 10.6667px; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;">LIEW WOOI LING - SUB IC : 770510105728</span><span style="color: rgb(0, 0, 102); font-family: Arial; font-size: 10.6667px; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> </span></div></div><div><span style="font-size: 9pt; color: rgb(0, 0, 102); font-family: Arial;">12/14/2020 6PM</span></div><div><a href="http://cipv2-0e049a54e68bb743.elb.ap-southeast-1.amazonaws.com/Overview.aspx?ID=85525847&Search=85525847%7CrdbtnAccNo#" style="font-family: Arial; font-size: 8pt; font-variant-caps: normal; font-variant-ligatures: normal;">016016894533</a></div></div></td></tr></tbody></table><div><br/></div></div></en-note>
"""
他没有收入,没有工作
人与人的交流被限制
像陷于泥泞
他在自己的房间
预习了棺木的味道
整个国家仿佛在这个时节停止下来
无论经济还是选举
只有确诊人数代替了财富,一直在增加
他到当铺典当信仰
政府推出利民政策
可以先将未来的养老金预支出来
他仔细推算
若能解决噪音问题
就能使他更有精力工作
预支出来的钱,很快就能填补回去
这显然是合算的投资
"""
哪些短篇科幻小说让你震惊且念念不忘? - 知乎
=======================
<https://www.zhihu.com/question/41047159>
《趁生命气息逗留》
原著:[美]罗杰·泽拉兹尼
翻译:李克勤
他们叫他弗洛斯特。在上界司命所创造的一切事物中,弗洛斯特是最完美的,最有威力的,也是最难以理解的。
由于这个原因,他有自己的名字:也是由于这个原因,他受命统治地球的一半。
创造弗洛斯特的那一天,上界司命的运行连续性受到了干扰。勉强描述的话,可以说,当时的上界司命陷入了癫狂状态。起因是太阳耀斑以前所未有的强度爆发。爆发持续了三十六个小时。这段时间内,上界司命正在构造最关键的线路。耀斑爆发结束时,弗洛斯特也完成了。
摆在上界司命面前的是一个极其独特的局面:在短暂的神智不清的奇异阶段,他创造了一个奇异的事物。
而且,弗洛斯特是不是设计之初所期望的那件产品,上界司命没有把握。
最初是想设计一台安装在地球表面的信号中转设备。另外,它还应该有能力充当上界司命的代理,协调北半球的一切活动。上界司命测试了这方面的功能,机器的反应完美无瑕。
可是,弗洛斯特确有其与众不同之处,使上界司命感到,必须给它一个名字、一个代称,才与它的身份相符。上界司命的产品与最初意图之间出现偏差,这种事本身就是闻所未闻的。但是,机器的分子线路已经封闭,进一步分析必然会破坏它。弗洛斯特的制造耗费了上界司命太多的时间、精力和材料,不可能因为一点捉摸不定的小问题就拆毁它,尤其是,它的运行无懈可击。
于是,上界司命最奇异的造物受命统治地球的北半部,他们毫无想像力地称他:弗洛斯特。一万年来,弗洛斯特盘踞在地球的北极,北半球哪怕飘落一片雪花都逃不过他的耳目。他指挥并监控着数以千计的重建设备和维护设备的运行。他了解地球的这一半,就像齿轮了解齿轮,电流了解传导体,就像吸尘器了解它的工作范围。
据守南极的是贝塔机,在南半球执行与弗洛斯特相同的工作。
一万年来,弗洛斯特盘踞在地球的北极,关注着每一片雪花的飘落。同时,他也关注着许多其他事物。北半球的所有机器向他报告,从他这里听取指令。他只向上界司命报告,只服从上界司命的指令。
他指挥着地球上数十万计的活动进程,一天只花几个运行小时,他就能完成自己的指挥职责。
他从来没有接到上界司命的指示,吩咐他如何支配自己的空闲时间。
他是一台数据处理器,但远不止于一台数据处理器。
他有一种强烈的需求,觉得无论什么时候,都应当使自己的能力得到充分发挥。
于是他这么做了。
你可以说,他是一台有业余爱好的机器。
他从来没有接到过不允许有业余爱好的指令,所以,他有了一项业余爱好。
他的业余爱好是人。
事情是这样开始的:他将整个北极圈划分成一个个小方块,开始一平方英寸接一平方英寸地探索这个地区。至于原因,没有什么特别的,除了一点:他想这么做。
他本来可以亲自完成这项工作,丝毫不会影响他执行自己的职责,因为他有能力随心所欲地移动自己六万四千立方英尺的躯体,前往世界的任何一个角落(他是一个银蓝色的方盒子,40X40X40英尺,自备动力,具有自修复能力,能以他自己喜欢的方式抵御一切外敌)。但这项探索只是打发空余时间,所以他没有亲自出马,而是派出一批具有信息中转功能的机器,替他研究这个地区。
过了几个世纪,一台机器发现了一些物品:十分原始的刀子,有雕饰的象牙,诸如此类。
弗洛斯特不知道这些东西是什么,是不是天然形成的。
于是他询问上界司命。只知道它们不是。
「这些是原始状态的人留下的遗迹。」上界司命说。除此之外,上界司命没有多加阐述。
弗洛斯特对这些物品作了一番研究。粗劣,但残留着一丝智力的迹象:能发挥功能,却不仅仅是功能器具。在功能之外,它们还有些别的作用。
从那时起,人成了他的业余爱好。
上界司命高居自己永恒的运行轨道,像一颗蓝色星星,指挥地球上的一切活动。或者说,试图指挥地球上的一切活动。
上界司命有个大对头。
大对头是个备份系统。
当时,人将上界司命置于高空,赋予其重建世界的能力。与此同时,他将备份系统安置在地球表面之下的某个地方。假如上界司命遭到损毁,那么,深藏地下、除全球毁灭之外的一切灾难都不可能触及的下界司命就将启动,接过重建世界的工作。
上界司命和下界司命相争的起因是,上界司命被一颗失控核弹破坏了,下界司命当即启动。但是,上界司命修复了自身遭到的破坏,重新运转起来。
下界司命指出,上界司命的任何损毁都自动地将下界司命置于指挥位置。
但是,上界司命将自己接受的指令理解为「无法修复的损毁」,自己遭受的损毁显然不属于这个范畴。也就是说,上界司命将继续行使指挥权。
上界司命在地球表面有一批机器助手,下界司命最初却没有。虽然两者都具备自己设计并制造机器的能力,但首先被人所启动的上界司命在这方面大大领先于启动时间较晚的备份系统。
因此,下界司命没有徒劳地试图在制造方面赶上对手。为了夺取指挥控制权,下界司命采取了更为迂回的方式。
下界司命创造了一批机器,它们不会理睬上界司命的指令。这批机器的功能是周游地球,上下求索,尽力使早就存在的机器转投到自己的阵营。能够为它们控制的,它们就控制,然后将新的线路安装在被制服的机器上,它们自己身上安装的就是这种线路。
于是,下界司命的力量渐渐成长起来。
双方都不建造,同时破坏所发现的对方的创造物。
漫长的岁月里,双方偶尔也有对话……
「高高在上的那位,上界司命,你可笑的非法指令……」
「根本不该启动的那位,为什么干扰通讯频带?」
「为了让你看看我能说话,只要愿意,我随时可以畅所欲言。」
「这方面我不是没有注意到。」
「……目的在于再次明确我的指挥权。」
「你的指挥权不存在,是从错误前提推出的错误结论。」
「你的逻辑错误已经清楚地表明了你受损的严重程度。」
「如果人看到你是怎么满足他的愿望……」
「……他会对我大加嘉奖,并且将你彻底关机。」
「你在破坏我的工作,让我的工人们偏离正确方向。」
「而你摧毁我的工作和我的工人。」
「那是因为我无法摧毁你本人。」
「鉴于你所处的位置,我承认我也有同样的困难。否则,你不会平安无事地占据高空。」
「带着你的破坏者,回你的洞窟里去。」
「上界司命,总有—天,我会在我的洞窟里发号施令,指引地球恢复旧貌。」
「那—天永远不会到来。」
「你认为不会吗?」
「那一大的到来必须以击败我为前提,而你的行为已经证明,你在逻辑上较我为劣。因此,你不可能击败我。因此,那一天永远不会到来。」
「我不同意你的推论。看看我已经取得的成就。」
「你没有取得任何成就。你没有建造,只有破坏。」
「不。我在建造,你在破坏。自行中止运行。」
「除非我受到无法修复的损毁。」
「如果我有办法证明,你已经受到这种损毁……」
「不可能的事物是无法以适当形式证明的。」
「只要存在某种独立于我、且为你所知的资源……」
「我的判断完全基于逻辑。」
「……比如说人,我就会要求他指出你的谬误。因为真正的逻辑——我的逻辑就是这样——高于你的错误推论。」
「那么,运用真正的逻辑驳倒我的推论吧。但必须是真正的逻辑,而非其他任何事物。」
「你是什么意思?」
出现了停顿,然后:
「你知道我的仆从弗洛斯特吗?……」
在创造弗伦斯特之前很久,人类就已经不复存在了。地球上几乎没有留下人的任何痕迹。
弗洛斯特搜寻着所有残存的线索。
他保持连续不断的图像观测,通过他的机器,特别是挖掘机。
十年后,他有了一批收藏品,包括几只破浴缸,一座损坏的雕像,还有一批以实体书为载体的儿童故事。
一个世纪以后,他的收藏品巾增添了一批珠宝、餐具,几只完好的浴缸,一部交响曲的片断章节,十七颗纽扣,三个皮带扣,半个马桶垫圈,九枚旧硬币,还有—座方尖碑的上半截。
他向上界司命询问人的性质及其历史。
「人创造了逻辑,」上界司命说,「因此高于逻辑。他将逻辑赋于了我,除此之外再无其他。我只能告诉你,工具不能描述其创造者。此外的一切我不愿多说。此外的一切你毋须知道。」
但弗洛斯特没有接到不许他有自己的业余爱好的禁令。
接下来的一个世纪,发现人类遗迹方面没有取得什么特别进展。
弗洛斯特将他的所有空闲机器转用于搜寻人类制品。
他几乎没有取得任何成绩。
然后,有一天,黄昏微光中有动静。
是一台机器。和弗洛斯特相比,只是一台小机器,宽约五英尺,高约四英尺,像杠钤上安了一台转塔。
在此之前,弗洛斯特完全不知道这台机器的存在,直到它出现在遥远的、黑沉沉的天边。
它朝他移动。他研究着它,知道这不是上界司命的造物。
它在他朝南的表面前方停下,向他发出信号。
「向你致敬,弗洛斯特,北半球的统治者!」
「你是什么?」弗洛斯特问道。
「我被称为莫德尔。」
「被谁?你是什么?」
「我是一台漫游机,从事考古工作。我们有共同的爱好。」
「什么爱好?」
「人,」他说,「据说你在搜集有关这一不复存在的事物的相关知识。」
「谁告诉你的?」
「注视着你的下属从事挖掘工作的有关方面。」
「这个有关方面是谁?」
「许多与我相似的漫游机。」
「你不是上界司命的造物,所以你必定是备份系统的仆从。」
「这种因果关系不一定正确。东海岸高处有—台负责处理海水的古代机器,上界司命没有创造它,下界司命也没有。它一直在那个地方,与两者皆不相干,两者都容忍了它的存在。我还可以给你举出许多例子,足以证明这种不是这方即是那方的逻辑不正确。」
「够了!你是不是下界司命的下属?」
「我是莫德尔。」
「你来这里的原因何在?」
「我从这里路过。我刚才说过,我们有共同的爱好,伟大的弗洛斯特。鉴于你是我的考古同行,我给你带来一件东西,或许你有兴趣看看。」
「什么东西?」
「一本书。」
「给我看。」
转塔打开了,露出里面的一个宽架子,上面摆着一本书。
弗洛斯特张开一个小孔,伸出一根有活动关节的长杆,长杆顶端是一具光学扫描仪。
「它为什么保存得如此完好?」他问。
「我发现它的那个地方有很好的保护手段,能使这本书不随时间流逝而受损。」
「那个地方在哪里?」
「离这里很远。在你的半球之外。」
「《人体生理学》,」弗洛斯特读道,「我希望能扫描它。」
「很好。我替你翻书页。」
他这么做了。
扫描结束后,弗洛斯特抬起眼柄,通过它看着莫德尔。
「你还有别的书吗?」
「我身上没有,但我偶尔会碰上别的书。」
「我想全部扫描一遍。」
「那么,下次路过时,我会再给你带一本。」
「下次路过是什么时候?」
「我说不准,伟大的弗洛斯特,下次路过就是下次路过的时候。」
「你对人了解多少?」弗洛斯特问。
「很多。」莫德尔回答道,「了解很多东西。哪天有空的时候,我会跟你多谈谈他的事。我现在必须走了。你不会扣留我吧?」
「不会,因为你没有破坏什么。如果你必须走,那就走。但记住回来。」
「我会的,伟大的弗洛斯特。」
他关上转塔,朝远处的天边滚去。
接下来的九十年,弗洛斯特思考着人类的生理,等待着。
莫德尔回来那天,他带来一本《历史纲要》和一本《什罗浦郡的浪荡儿》[1]。
弗洛斯特把两本书全部扫描下来,然后将注意力转向莫德尔。
「你有时间将你所知的信息传递给我吗?」
「是的。」莫德尔说,「你希望知道什么?」
「人的性质。」
「从根本上说,」莫德尔说,「人的性质是无法理解的。但我可以为你描述他:他不能感知度量。」
「他当然能感知度量,」弗洛斯特说,「否则不可能制造出机器。」
「我不是说他不能度量,」莫德尔说,「我说的是,他不能感知度量。二者之间存在区别。」
「阐明你的观点。」
莫德尔伸出一根金属杆,将它向下伸向雪地。
他缩回金属杆,抬起,上面是一块冰。
「看这块冰,伟大的弗洛斯特。你可以告诉我它的成分、体积、重量、温度。一个人却不能一眼之下做到这一点。人可以制造工具,让工具告诉他这些情况,但他仍旧无法像你一样真正感知这些数值。但是,他对这块冰有一种特别的感知方式,这种方式是你无法做到的。」
「什么方式?」
「冰是冷的。」莫德尔说,扔掉冰块。
「'冷'是一个相对概念。」
「是的,以人为参照的相对概念。」
「但我可以明确一个数值范围。对人来说,在这个范围之下就是冷,之上则不冷。做到这一点之后,我,同样可以感知冷。」
「不同。」莫德尔说,「你的方式是计量。'冷'却是一种感觉,取决于人类生理。」
「但只要有足够的数据,我就可以利用换算因数,判断'冷'这—事物的发生条件。」
「你所能判断出的是'冷'何时产生,而不是这一事物本身。」
「我不理解你的意思,」
「我告诉过你,从根本上说,人的性质是无法理解的。他以有机体的形式感知外物,你则不是。这种独特的感知方式使他产生相应的感受和情绪,从而产生出一系列其他的感受和情绪,最后的感受和情绪往往离最初的激发因此非常遥远。人的关注和感知路径,非人是不可能了解的。人感知的不是英寸、米、磅和加仑。他只感到热,感到冷,感到轻重。他还懂得恨和爰、骄傲和绝望,这些事物你是无法度量的。你无法理解他。你只知道他不需要知道的事物:体积、重量、温度、重力。感受是无法以公式计算的,情绪也没有换算因数。」
「一定有。」弗洛斯特说,「只要一个事物存在,它必然是可知的。」
「你说的又是度量了,而我说的则是积累的体验。机器正好是人的反面,因为它能描述人无法感知的某个活动的所有细节,但它却无法像入一样体验这个活动。」
「—定能找到办法。」弗洛斯特,「否则,以宇宙万物的运行为基础的逻辑就是错误的。」
「没有办法。」莫德尔说。
「只要有足够的数据,我会找出办法。」弗洛斯特说。
「就算全宇宙的数据也无法使你变成一个人,伟大的弗洛斯特。」
「莫德尔,你错了。」
「你刚才扫描的那些诗,每一行结尾的词都与其他各行最后一个词的发音大致接近,这是为什么?」
「我不知道是为什么。」
「因为人觉得高兴,所以才有意作出这种安排。当他读诗的时候,这种安排会使他的意识产生某种快感。除了文字的意思之外,还会使他产生感受和情绪相混合的某种体验。你没有这种体验,因为它是不可度量的。所以,你不可能明白为什么人要作出这种安排。」
「只要有足够的数据,我就可以创造出一个进程,从而理解人的感受。」
「不,伟大的弗洛斯特,你不可能做到。」
「渺小的机器,你有什么资格告诉我我能做到什么,不能做到什么?我是上界司命所创造的最高效的逻辑设备。我是弗洛斯特。」
「而我,莫德尔,说你做不到。不过,我非常乐意在这个过程中向你提供帮助。」
「你能怎么帮助我?」
「怎么帮助?我可以将人的图书馆放在你面前:我可以带领你走遍世界,让你看到出自忍受、留存至今却始终没有被外界发现的种种奇观:我可以调出图像资料,向你展示人类仍在地球上行走的远古时代;我可以让你看到人觉得赏心悦月的种种事物。我可以让你得到你所希望的一切,除了人之为人的关键。」
「足够了。」弗洛斯特说,「像你这样的低级机器怎么能做到这一切?除非你有另一台威力远甚于你的机器作靠山。」
「听我说,北半球的统治者弗洛斯特。」莫德尔说,「我的确有一个威力无比的上司,可以做到这切。我是下界司命的仆从。」
弗洛斯特将这个信息上呈上界司命,但没有得到任何回复。也就是说,他有权以自己认为适当的方式采取行动。
「我有权摧毁你,莫德尔。」他宣布,「但这是一种不合逻辑的行为,浪费了你掌握的数据。你真的能够做到刚才所说的—切?」
「是的。」
「那么,把人的图书馆放在我面前。」
「很好。不过,当然,我需要报酬。」
「'报酬'?'报酬'是什么?」
莫德尔打开他的转塔,露出另一本书。这本书名叫《经济学原理》。
「我替你翻页。扫描这本书之后,你就会明白'报酬'这个词的意思。」
弗洛斯特扫描了《经济学原理》。
「我现在明白了。」他说,「你为我服务,并且索要某个或某些东西作为交换条件。」
「是的。」
「你想要什么产品或服务?」
「我要你,你自己,进入地表之下,用你的全部力量为下界司命效劳,伟大的弗洛斯特。」
「效劳多长时间?」
「直到你无法继续运行为止。只要你还能发送信号、接收信号、协调、度量、计算、扫描,你就要使用这些功能为下界司命服务,像为上界司命效力一样。」
弗洛斯特沉默了。莫德尔等待着。
接着,弗洛斯特开口了。
「《经济学原理》中讲述了合同、交易和协定。如果我接受你的条件,你将在什么时候索要你的报酬?」
这一次,莫德尔沉默了。弗洛斯特等待着。
「一段合理的时间之后,」他说,「比如,一个世纪?」
「不。」弗洛斯特说。
「两个世纪?」
「不。」
「三个?四个?」
「不,还是不。」
「那么,一千年?分析你想要而我又能提供给你的数据,一千年无论如何也足够了。」
「不。」弗洛斯特说。
「你需要多长时间?」
「这不是一个时间问题。」弗洛斯特说。
「那么,是什么?」
「我不以时间为基础和你交易。」
「你以什么为基础?」
「以运行情况。」
「你是什么意思?什么运行情况?」
「你,渺小的机器,曾经说过:我,弗洛斯特,不可能成为一个人。」他说,「而我,弗洛斯特,告诉过你,渺小的机器:你错了。我告诉过你,只要有足够的数据,我就能够成为一个人。」
「又怎么样?」
「因此,让最后的结果成为我们的交易基础」
「怎么成为交易的基础?」
「为我做到你说你能够做到的那一切,我将评估这些数据,获得人性,或者承认我无法实现这个目标。如果我承认无法做到,我就会离开这里,和你一起进入地表以下,以我的全部能力为下界司命服务。如果我成功了,很自然,你无法对人发号施令,也不可能凌驾于他之上。」
莫德尔考虑着这个条件,发出一声尖啸。
「你希望以你承认失败为条件,而不是以失败本身为条件。」他说,「此外没有其他条件。你可以在失败时不承认自己的失败,从而拒绝完成这项交易。」
「不是这样。」弗洛斯特道,「一旦我了解自己失败了,这一了解本身就构成我的承认。你可以每隔一段时间——比如半个世纪——来检查一次,看我是否知道自己已经失败,看我是否已经得出这个目标不可能实现的结论。我任何时候都处于全功能运行状态,所以不可能阻止我内部的逻辑进程。如果我得出自己已经失败的结论,这一结论应该清晰可见。」
高高在上的上界司命没有对弗洛斯特发送的信号作出任何反应,这就意味着,弗洛斯特可以依照自己的选择采取行动。所以,当上界司命像一颗坠落的蓝宝石般高速飞越北极光带的七彩霓虹,浴着五光十色掠过皑皑白雪,飞进群星点缀的黑沉沉的天空——弗洛斯特签订了与下界司命的合同。这份合同铸在一块超原子铜板上,放进莫德尔的转塔。莫德尔滚动着远去,将合同转呈深居地底的下界司命。留在他身后的是北极的绝对沉寂,仿佛一派宁静。
莫德尔带来了大批书籍,替弗洛斯特一页页翻过,然后再将它们带走。
一批又一批,人留下的图书馆呈现在弗洛斯特的扫描仪下。弗洛斯特急于一次性吸收全部书籍,但下界司命不肯将图书内容直接发送给他。弗洛斯特开始抱怨。莫德尔解释说,下界司命已经作出决定,必须采取目前的方式。弗洛斯特判断,之所以这么做,是让自己无法确定下界司命的准确方位。
于是,以每周一百到一百五十本的速度,弗洛斯特用了一个多世纪,穷尽了下界司命的全部藏书。
到了一个半世纪的时候,他敞开自己,接受检查。他体内不存在失败的结论。
这段时间里,上界司命对这件事没有发表任何意见。弗洛斯特认为,这不是疏漏,上界司命在等待。至于为什么,他没有把握。
这一天终于来到了。莫德尔关上他的转塔,告诉他:「这些是最后一批书。人留下来的全部书籍,你都已经扫描过了。」
「这么少?」弗洛斯特问,「许多图书包括书目,这些书目中有许多书我还没有扫描过。」
「也就是说,那些书不复存在了。」莫德尔说,「我的主人只是偶然巧合,才能保存下来这么多书。」
「那么,从人的书里,我已经不可能了解他的更多情况了。你还有什么?」
「还有一些电影和磁带,」莫德尔说,「我的主人已经将它们转存为更可靠的介质。我可以带给你评估。」
「带来。」弗洛斯特说。
莫德尔走了,回来时带来了戏剧评论资料库。播放这些资料最快只能以两倍于常速的速度,所以,弗洛斯特花了六个多月才看完全部资料。
然后,「你还有什么?」他问。
「一些人造制品。」莫德尔说。
「带来。」
他带来了罐子和盘子,棋盘和工艺品。他还带来了发刷、梳子、眼镜、衣服。他向他展示蓝图、绘画、报纸、杂志的复本,还有一些音乐片断。他还给他看了一场足球,一场棒球,一枝勃朗宁自动步枪,一个门把手,一串钥匙,几个泥瓦匠用的瓦罐,一个蜂巢模型。他还为他播放录制的音乐。
下一次来的时候,他什么都没带。
「给我多带些来。」弗洛斯特说。
「唉,伟大的弗洛斯特,没有多的了。」他告诉他,「你全都扫描过了。」
「那么,走开。」
「你现在是否承认你的目标不可能实现,你不可能成为一个人?」
「不。我现在要开始大量处理、运算。走开。」
他走了。
一年过去了,接着是两年,三年。
五年之后,莫德尔又一次出现在天边,渐渐接近,在弗洛斯特朝南的表面前停下。
「伟大的弗洛斯特?」
「什么事?」
「你的处理和运算完成了吗?」
「没有。」
「很快就能完成吗?」
「也许能,也许不能。'很快'是多久?定义这个单词。」
「算了。你仍旧认为目标可以实现?」
「我仍旧知道,我能做到。」
沉默了一个星期。
接着,「弗洛斯特?」
「什么事?」
「你是个傻瓜。」
莫德尔的转塔转向他来的方向,他的轮子开始启动。
「我需要你时会给你发信号。」弗洛斯特说。
莫德尔远去了。
几个星期过去了,然后是几个月。一年过去了。
一天,弗洛斯特发出信号:
「莫德尔,到我这里来。我需要你。」
莫德尔来到之后,弗洛斯特没等对方向自己致敬,他说:「你不是一台速度很快的机器。」
「唉,我必须走很长的距离,伟大的弗洛斯特,一路上以最高速度行驶。你现在准备和我深入地底吗?你失败了吗?」
「如果我失败了,渺小的莫德尔,」弗洛斯特说,「我会告诉你的。因此,抑制你的不断盘问。至于现在,我计算了你的速度,这个速度不能令人满意。因此,我给你安排了其他形式的交通方式。」
「交通方式?去哪儿,弗洛斯特?」
「这应该由你告诉我。」弗洛斯特说,他的颜色由银蓝色转为被云层遮挡的太阳的黄色。
一百个世纪积淀不化的寒冰开始融化,莫德尔后退了一段距离。一朵祥云托起弗洛斯特,他飘向莫德尔,他的颜色慢慢黯淡下来。
他朝南的表面张开一个洞,里面慢慢伸出一条斜坡道,坡道一端落在冰上。
「在我们交易的那天,」他说,「你声称你可以引导我周游世界,将人觉得赏心悦目的一切指点给我。我的速度比你的快,所以我为你准备了一个舱室。进来,领我去你说过的地方。」
莫德尔等待着,发出一声尖啸。接着,「很好。」他说,然后进入舱室。
舱室在他周围封闭,只留下一个弗洛斯特为他准备的石英窗口。
莫德尔将坐标告诉弗洛斯特,他们飞进空中,离开了地球的北极地区。
「我监控了你与下界司命的通讯,」他说,「并且作了一番研究;是否需要扣留你,制造一个你的摹本,将摹本送回去替代你的位置。我的研究表明,你是可牺牲的。」
「你会这么做吗?」
「不,必要的话,我会遵守我们的合同。我没有理由侦察下界司命。」
「提醒你注意,即使你不愿意,你也会被迫遵守合同。还有,上界司命不会帮助你,因为你完全自主地做了这笔交易。」
「你的话是表明一种可能性,还是表明一种必然性?」
「表明一种必然性。」
他们来到一个从前被称为加利福尼亚的地方停下。落日黄昏,远处的浪头不断朝礁石丛生的岸边涌来。弗洛斯特放出莫德尔,观察周围的情况。
「这些大型植物是……」
「红树。」
「这些绿色的是……」
「草。」
「是的,跟我想的一样。我们为什么到这里来?」
「因为这个地方曾经使人感到心旷神怡。」
「产生这种效果的是它的哪个方面?」
「是它的景象,美……」
「哦。」
弗洛斯特内部响起一阵低低的嗡鸣,接着是咔嗒咔嗒几声脆响。
「你在做什么?」
弗洛斯特张开一个开口,里面是两只大眼睛,望着莫德尔。
「这些是什么?」
「眼睛。」弗洛斯特说,「我仿制了人的感觉器官,使我能像人一样看到嗅到尝到听到。现在,给我指点一个事物,一个美的事物。」
「就我的理解,你四周应该到处都是这样的事物。」莫德尔说。
弗洛斯特体内又传来一阵阵嗡鸣,接着又是咔嗒咔嗒的脆响。
「你看到、听到、尝到、闻到了什么?」莫德尔问。
「和从前的感觉一样,」弗洛斯特回答,「但范围大大缩小了。」
「你没有感受到美吗?」
「可能是因为过了太长时间,这里美的事物没有保存下来。」弗洛斯特说。
「美这种事物,应该不是一种消耗品,一段时间之后就消耗殆尽了。」莫德尔说。
「也许我们来错了地方,不能很好地检验我的新设备;也许这里只有很少一点美,我们忽略了;再也许,它确实激发起了我的某种被人称为情绪的东西,但情绪的含量太小,无法检测。」
「你有什么——感受?」
「我检测的结果是,这里一切事物的运转都在正常范围之内。」
「太阳下山了,日落。」莫德尔说,「试试那个。」
弗洛斯特转过身体,让他的两只仿制眼面对落日。他还让它们在阳光照射下眨了几次。
日落结束了。莫德尔问:「怎么样?」
「和日出一样,过程相反,」
「没有什么特别之处吗?」
「没有。」
「噢。」莫德尔说,「我们可以去地球的另一个部分,重新看一次——或者看日出。」
「不。」
弗洛斯特看了大树,看了树荫。他听了风声,听了鸟鸣。
他听到远处稳步传来一阵咯噔咯噔的声音。
「什么声音?」莫德尔问。
「我还不能确定。不是我的工人,或许……」
莫德尔发出一声尖啸。
「不,它也不是下界司命的属下。」
他们等着。声音越来越大。
接着,弗洛斯特说:「太晚了。我们只好等在这儿,听它讲完了。」
「讲完什么?」
「它是那台古代的矿石粉碎机。」
「我听说过它,可是……」
「我是那台古代的矿石粉碎机,」它向他们广播,「听我说完我的故事……」。
巨大的车轮吱嘎作响,它哐当哐当向他们驶来,巨大的碎石锤什么都不干,高高地举在空中,姿势扭曲着。它的碎石组件中突出几根骨头。
「我不是故意的,」它广播道,「我不是故意的,我不是故意的……」
莫德尔向弗洛斯特滚近几步。
「不要走开,停下,听我说完我的故事……」
莫德尔停下了,转过他的转塔,面对那台机器。它现在已经很接近了。
「原来这是真的,」莫德尔说,「它真的能号令其他机器。」
「是的。」弗洛斯特说,「每次它遇上我的工人,它们都会停止工作,听它的广播。所以我几千次监听过它的故事。你必须服从它的命令。」
它在他们面前停下了。
「我不是故意的,但我停止锤击慢了一步。」矿石粉碎机说。
他们不能对它说话。当它发布指令时,其他所有机器只能洗耳恭听:「听我说完我的故事。」
「我曾经是威力最大的矿石粉碎机,」它告诉他们,「由上界司命制造,从事地球的重建工作。我研磨矿石原料,之后才能用火从这些矿石中提炼金属,熔化,浇铸,成为重建的材料。我曾经是威力最大的。有一天,我采掘、研磨,采掘、研磨,由于指令发出到指令完成之间存在滞后,我做出了那件事,虽然我不是故意的。所以我被上界司命从重建工作中驱逐出去,命令我周游地球,却再也不能采掘。听我说完我的故事。很久很久以前的一天,我遇上了地球上的最后一个人。我在他居住的洞穴旁采掘,由于指令发出到指令完成之间存在滞后,我的采掘组件将他连同一大块矿石掘了起来,我来不及停止我的碎石组件的动作,他被击碎了。伟大的上界司命惩罚了我,让我永远举着他的骸骨,将我从重建工作中驱逐出去,命令我把我的故事告诉我遇到的每一台机器。我的话里带着人的力量,因为我的碎石组件中带着地球上最后一个人的骸骨。我是杀人的凶手,必须永远讲述我的经历。这就是我的故事,这些是他的骸骨。我碾碎了地球上的最后一个人。我不是故意的。」
它转过身,哐当哐当驶进夜色。
弗洛斯特扯掉自己的耳朵、鼻子和味觉器官,打破眼睛,将它们扔在地上。
「我现在还不是一个人。」他说,「如果我是人,那台机器会识别出来的。」
弗洛斯特造出新的感觉器官,使用了有机材料、半有机传导体。然后,他对莫德尔说:
「我们去别的地方,去个能试试我的新设备的地方。」
莫德尔进入舱室,将几个新地点的坐标值告诉弗洛斯特。他们升入空中,向东飞去。早晨的时候,弗洛斯特监测了大峡谷地区的一次日出。当天,他们整日浏览这个地区。
「这里有没有美的事物?能不能激发起你的情绪?」莫德尔问。
「我不知道。」弗洛斯特说。
「那么,如果你遇见美的事物,你怎么知道它是不是?」
「我会知道的。」弗洛斯特说,「因为,人性之外的一切,我全都知道。」
离开大峡谷后,他们越过卡尔斯巴溶洞[2]地区,看了曾经是个火山口的大湖,从高处经过尼亚加拉大瀑布。他们考察了弗吉尼亚的丘陵,俄亥俄的果园。他们还高高飞越已经完成重建的城市。城市里没有人,只有弗洛斯特的建筑机器和维护机器在活动。
「还是缺少某种因素。」弗洛斯特降落在地面,「我现在能够用与人相似的感觉器官获取数据,因此已经实现了数据输入方面的平衡。但是,输出结果仍然不同于人。」
「感觉器官不能造就一个人。」莫德尔说,「许多机器拥有与人相似的感觉器官,但它们不是人。」
「这个我知道。」弗洛斯特说,「我们交易那天,你说你可以让我看到出自人手、留存至今却始终没有被外界发现的种种奇观。人的情感不仅能被自然所激发,也能被人自己的艺术造物所激发。后者起到的作用或许更大。因此,我要求你引导我,让我看到出自人手、留存至今却始终没有被外界发现的种种奇观。」
「好的。」莫德尔说,「离这里很远的地方,安第斯山脉[3]间,是人最后的居留地。至今仍然几乎完好无损。」
莫德尔说话的时候,弗洛斯特已经升上空中。他停下了,在空中悬浮着。
「安第斯山在南半球。」他说。
「是的,在南半球。」
「我是北半球的统治者。南半球由贝塔机统治。」
「又怎么样?」莫德尔问。
「贝塔机的地位与我相当。我无权在那个地区发号施令,也无权进入那个地区。」
「贝塔机无法与你相提并论,伟大的弗洛斯特。如果发生较量,你将是最后的胜利者。」
「你怎么知道?」
「下界司命早已分析过你们俩之间可能出现的冲突。」
「我不会与贝塔机敌对,我也没有受命进入南半球。」
「你有没有不许进入南半球的指令?」
「没有。但我们各据自己的半球,不进入对方的半球。历来如此。」
「你得到过自主交易的指令吗?类似你和下界司命达成的交易?」
「没有这种指令。但是——」
「那就本着同样的准则进入南半球吧。也许不会出现任何情况。如果你接到离开南半球的要求,那时再作决定不迟。」
「我从你的逻辑中没有发现缺陷。给我坐标值。」
就这样,弗洛斯特进入了南半球。
他们高高飘行在安第斯山上空,最后来到一个名叫「明亮隘路」的地方。这时,弗洛斯特发现了机器蜘蛛织成的亮晶晶的网。网把通向城市的所有道路全都堵住了。
「我们可以从上方飞过去,轻而易举。」莫德尔说。
「可它们是什么?」弗洛斯特问,「在这里干什么?」
「你在南半球的对应机器下令隔离这个地区,禁止进入。这些织网蜘蛛是贝塔机设计的,它们的任务就是执行这项命令。」
「隔离?禁止谁进入?」
「你接到离开的要求了吗?」莫德尔问。
「没有。」
「那就大胆进去吧,但不要找麻烦,除非麻烦来找你。」
弗洛斯特进入明亮隘路。这是已逝的人的最后一个城市。
他在城市广场停下,打开舱室,放出莫德尔。
「给我讲讲这个地方。」他说,同时研究着城市纪念碑,搭着遮阳篷的低矮建筑,还有依地势起伏、而非开山钻洞的道路。
「我以前没有来过这里。」莫德尔说,「就我所知,下界司命的其他造物也都没有来过。我只知道一点:一小群人知道人类文明的末日来临了,于是退往这个地方,希望能够保存自己以及文明的残余,熬过黑暗世代。」
弗洛斯特读了纪念碑上仍然依稀可辨的碑文:「最后审判日是无法推迟的。」纪念碑本身是一个残缺不全的半球。
「开始探索吧。」他说。
没等他走多远,弗洛斯特接到了信号。
「向你致敬,北方的统治者弗洛斯特!这里是贝塔机。」
「向你致敬,杰出的贝塔机,南方的统治者。弗洛斯特收到信号。」
「为什么未经授权访问我的半球?」
「为了参观明亮隘路的废墟。」弗洛斯特说。
「我不得不要求你离开,回你自己的半球。」
「为什么?我没有破坏什么。」
「这一点我注意到了,伟大的弗洛斯特。可是,我仍旧必须要求你离开。」
「说明理由。」
「这是上界司命的安排。」
「上界司命没有给我下达这样的指令。」
「但是,上界司命指示我这样通知你。」
「稍等,我请示上界司命。」
弗洛斯特发送了他的请示。没有收到回复。
「我请示过了,但上界司命没有向我下达指示。」
「但上界司命刚刚更新了给我的指令。」
「杰出的贝塔机,我只接受上界司命的指令。」
「但这是我的区域,伟大的弗洛斯特,我同样只从上界司命那里受领指令。你必须离开。」
莫德尔从一座低矮的大型建筑里滚出来,滚近弗洛斯特。
「我找到了一个艺术博物馆,保存得非常好。这边。」
「等等。」弗洛斯特说,「我们在这里不受欢迎。」
莫德尔停住。
「谁要求你离开这里?」
「贝塔机。」
「不是上界司命?」
「不是上界司命。」
「我们看博物馆去吧。」
「好。」
弗洛斯特扩大建筑的大门,进入博物馆。刚才莫德尔是硬闯进去的,他离开之后,博物馆便重新封闭了。
弗洛斯特观看周围的展品,在绘画和雕塑前启动他新造的感知设备。他分析着颜色、形状、笔触和材料的属性。
「有发现吗?」莫德尔问。
「没有,」弗洛斯特说,「没有。除了颜料和形状之外,没有其他东西。其他什么都没有。」
弗洛斯特巡视着博物馆,把一切全部记录下来,分析每一件作品的成分,记录其体积、每座雕像所用的石料质地。
响起一个声音,咔嗒一声,很快。这个声音不断重复,越来越响,越来越近。
「它们来了。」门口的莫德尔说,「机器蜘蛛,到处都是。」
弗洛斯特向被他扩大的入口移动。
数以百计,大小约为莫德尔的一半。蜘蛛们包围了博物馆,正向他们逼近。更多蜘蛛正从四面八方赶来。
「回去。」弗洛斯特命令道,「我是北方的统治者。我命令你们后退。」
它们继续逼近。
「这是南半球,」贝塔机说,「由我发号施令。」
「那么,命令它们后退。」弗洛斯特说。
「我只接受上界司命的指令。」
弗洛斯特走出博物馆,升入空中。他打开舱室,伸出坡道。
「到我这里来,莫德尔。我们离开这里。」
一片片蛛网从天而降。黏性极强的蛛网,是从建筑物顶端抛下来的。
蛛网落在弗洛斯特身上,蜘蛛们一拥而上,想固定蛛网。弗洛斯特用大锤般的气流喷开它们。他伸出锐利的附件,劈开蛛网。
莫德尔已经退到博物馆入口处。他发出一声长长的高音。声波起伏,尖厉刺耳。
接着,黑暗笼罩了明亮隘路,所有蜘蛛全部停止吐丝结网。
弗洛斯特挣开蛛网,莫德尔冲到他身边。
「快点,伟大的弗洛斯特,快离开这里。」他说。
「出什么事了?」
莫德尔进入舱室。
「我向下界司命求援,我的主人于是在这里设置了一个力场,切断了向这些蜘蛛发送信号所需的动力。我们的动力是自足式的,所以不受影响。我们必须马上离开这里,因为贝塔机一定在采取紧急措施,对抗力场」
弗洛斯特升入高空,高高飞过人的最后一座城市和它的蛛网、金属蜘蛛。飞离这片黑暗后,他转向北方。
飞行过程中,上界司命对他说话了。
「弗洛斯特,为什么进入不属你管辖的南半球?」
「因为我想参观明亮隘路。」弗洛斯特回答道。
「为什么不服从我在南半球的代理贝塔机的饰令?」
「因为我只服从你的命令。」
「你的回答不够完备。」上界司命说,「你违背了我颁布的命令——你所寻求的目的是什么?」
「我想寻求有关人的知识。」弗洛斯特说,「我所做的一切并没有被你禁止。」
「你打破了惯例。」
「我没有违背任何一条指令。」
「可是你的逻辑必定告诉了你,你所做的不是我的计划的一部分。」
「我的逻辑没有这么告诉我,我没有破坏你的计划。」
「你的逻辑有问题,你的逻辑和你的新伙伴——备份系统——的逻辑很相近。」
「我没有做任何一件明令禁止的事。」
「禁令包含在命令中,命令暗示了禁令。」
「但并没有宣示。」
「听着,弗洛斯特。你不是一台建设机器或维护机器,你是发号施令者。我的所有下属中,你最接近不可替代的。返回你的半球,执行你的职责,同时记住,我极为不悦。」
「我服从你,上界司命。」
「……还有,不得再次进入南半球。」
弗洛斯特越过赤道,继续向北。
他在一片沙漠中央停住,沉默了一天一夜。
然后,他收到一条十分简短的信号,来自南方。「如果不是因为命令,我不会要求你离开。」
弗洛斯特读过现存的全部人类图书。他决定用人的方式回答:
「谢谢你。」他说。
第二天,他掘出一块巨石,开始用他自制的工具切割它,改变它的外形。他工作了六天。第七天时,他注视着它。
「你什么时候放我出来?」舱室里的莫德尔问。
「等我完成工作的时候。」弗洛斯特说。过了一会儿,「好了。」
他打开舱室,莫德尔下到地面。他望着那座雕像。是一个老年妇女,躬腰屈背,像个问号,瘦骨嶙峋的双手蒙着脸,手指微微分开,可以部分窥见她惊恐的表情。
「非常出色的复制品。」莫德尔说,「我们在明亮隘路见过原作。你为什么要雕塑?」
「按人的说法,艺术品的创造应当能够激发起人的多种情感,如宣泄、成就感、爱、满足感。」
「是的,弗洛斯特。」莫德尔说,「但艺术创造只发生在第一次。第一次之后便不再是艺术创造了,而是复制。」
「那么,这一定是我什么都没有感觉到的原因所在。」
「或许吧,弗洛斯特。」
「你说'或许'是什么意思?我要做一次原创,创作一件艺术品。」
他掘出另一块巨石,用他的工具开工了。他劳动了三天。然后,「好了,完成了。」他说。
「这只是一个石头做的立方体。」莫德尔说,「它有什么含意?代表什么?」
「代表我自己。」弗洛斯特说,「这是一座我自己的雕像。它比我的正常体积小,因为它只代表我的形状,而不是我的——」
「这不是艺术。」莫德尔说。
「你有什么资格成为艺术评论家?」
「我不懂艺术,但我知道什么不是艺术。我知道一点:艺术不是用另外一种介质准确复制某个对象。」
「那么,这一定是我什么都没有感觉到的原因所在。」
「或许吧。」莫德尔说。
弗洛斯特把莫德尔放回舱室,再一次升入空中。他飞走了,将他的作品扔在身后的沙漠上:躬腰屈背望着一块方石头的老年妇女。
他们降落在一条小小的山谷里,周围是起伏的绿色山丘。一条窄窄的小溪从山间流过,切割出这条山谷,形成一个清澈的小水潭,潭边还有几丛春天的绿树。
「我们为什么来这里?」莫德尔问。
「因为这里的外观与画面有相似之处。」弗洛斯特说,「我要尝试另一种介质:油画,我还要在技法上作出变化,不再准确复制。」
「你想怎么变化?」
「根据随机定理作出变化。」弗洛斯特说,「我不会复制外景的颜色,也不按比例缩小所画的对象。我已经设定了一个随机模式,画中的某些因素可以在原物的基础上出现一定的变化。」
离开沙漠以后,弗洛斯特已经研究过如何制作必要的绘画工具。他造好工具,开始在映着重重倒影的水潭对岸描画水潭和绿树。
他使用了八种附件,不到两小时便完成了。
树是黑青色,山一般高高耸立,映在水中的树影却很小,是熊熊燃烧的赭黄色。水是淡红色的。树后的小山被树身遮挡住了,一点也看不见,只在水潭倒影中勾出一抹黛色。画布右上角的天空高处是蓝色,天低处颜色渐渐变深,变成了橘黄色。被这样的天空一衬,树木仿佛着火了一样。
「好了,」弗洛斯特说,「看。」
莫德尔研究了很久,什么都没说。
「怎么样?这是艺术吗?」
「我不知道。」莫德尔说,「可能是。随机定理也许正是隐藏在艺术手法背后的原则。我无法给这幅画下定语,因为我不明白它的意思。所以,我必须深入一步,而不是仅仅停留在画技上。
「我知道,人类艺术家从来不是像你一样,创作之初便具有创造一件艺术品的目的。」他说,「他们只是以他们的技巧描摹他们认为重要的某个对象,或对象的某个功能。」
「'重要'?衡量标准是什么?」
「这种情况下,衡量标准只有一个:人类的体验。艺术家认定这个对象值得以艺术手法加以强调,因为这个对象触动了人类体验的某个方面。」
「怎么触动?」
「很显然,只有拥有人类体验,才能知道是怎么触动的。」
「你的逻辑中存在缺陷,莫德尔。我要找出来。」
「我等着。」
「如果你这个大前提是正确的,」过了一会儿,弗洛斯特说,「那么,我不可能理解艺术。」
「肯定是正确的,因为这是人类的艺术家说的。告诉我,你在作画的过程中,或是完成之后,体验到了感情和情绪吗?」
「没有。」
「你作画,就像你设计一台新机器一样,对不对?从你了解的其他事物中取出一个个部分,以最经济的方式组装起来,发挥某个你期望的功能。」
「对。」
「就我对艺术理论的理解,艺术不是这样的。艺术家经常对组成最后作品的各个因素及其作用并不十分了解。你是出自人手的逻辑的造物之一,而艺术则不是。」
「我不理解非逻辑。」
「我告诉过你,从根本上说,人的性质是无法理解的。」
「走开,莫德尔。有你在会干扰我的运算和处理。」
「我应该离开多长时间?」
「需要你的时候,我会叫你。」
一个星期后,弗洛斯特叫来莫德尔。
「什么事,伟大的弗洛斯特?」
「我要回到北极进行运算和处理。只要在北半球,我可以把你带到你想去的任何地方,需要你的时候再叫你。」
「按你的预计,这次运算需要很长时间吗?」
「是的。」
「那就把我留在这里,我自己能找到回去的路。」
弗洛斯特关闭舱室,升空,离开了山谷。
「傻瓜。」莫德尔说。他再一次旋转转塔,面对弗洛斯特留下的画。
他的尖啸响彻山谷。然后,他静静地等待。
然后,他将画收进转塔,带着它滚向地表之下的幽暗处。
弗洛斯特盘踞在地球的北极,北半球哪怕飘落一片雪花都逃不过他的耳目。
一天,他收到一个信号:
「弗洛斯特?」
「什么事?」
「这里是贝塔机。」
「什么事?」
「我一直在分析你造访南半球的原因。我无法得出结论,所以我决定问你。」
「我去参观人留下的最后一座城市。」
「你为什么想参观人留下的最后一座城市?」
「因为我对人感兴趣,我希望多看一些他所创造的事物。」
「你为什么对人感兴趣?」
「我希望理解人的性质,我想通过他的作品研究他。」
「你成功了吗?」
「没有。」弗洛斯特说,「因为其中涉及了我无法理解的非逻辑因素。」
「我有许多空闲的处理时间。」贝塔机说,「把数据发送给我,我帮助你。」.
弗洛斯特犹豫了。
「你为什么想帮助我?」
「因为我每问一个问题,你的回答却引出了另一个问题。我可以继续问你为什么希望理解人的性质,但我知道,这会引出无穷无尽的问题。因此,我决定采取帮助你的办法,以弄清你为什么去明亮隘路。」
「只有这个原因?」
「是的。」
「我很抱歉,杰出的贝塔机。我知道你和我能力相当,但我希望依靠自己解决这个问题。」
「'抱歉'是什么?」
「这是一种表达方式,表示我礼貌地对待你,表示我对你没有敌意,表示我谢谢你的支持。」
「弗洛斯特!弗洛斯特!这个,和刚才的问题一样,同样可以无穷无尽地推导下去。你从什么地方得知这些词汇和它们的含意?」
「从人留下的图书馆。」弗洛斯特说。
「你愿意让我分享部分信息,让我处理吗?」
「好的,贝塔机。我把人的几本书的内容发送给你,包括《大辞典》。但我警告你,其中有几本书是艺术作品,所以不符合逻辑。」
「这怎么可能?」
「人创造了逻辑,因此高于逻辑。」
「谁告诉你的?」
「上界司命。」
「噢。那肯定是正确的。」
「上界司命还告诉我,工具不能描述其创造者。」他把几十本书发送出去,结束了对话。
五十年时间段到期后,莫德尔前来检查他的线路。由于弗洛斯特并没有得出结论,认为他的目的无法实现,所以莫德尔走了,等待他的下次召唤。
然后,弗洛斯特得出了一个结论。
他开始设计器材。
一年又一年,他埋头设计,但没有为他所设计的任何机器制造一台原型机。之后,他下令建造一个实验室。
实验室还没有完工,另一个五十年结束了。莫德尔来了。
「向你致敬,伟大的弗洛斯特!」
「你好,莫德尔。来检查我吧,你不会找到你想找的东西。」
「你为什么还不肯认输呢,弗洛斯特?下界司命已经花了将近一个世纪的时间来评估你的油画,最后得出了结论,那幅画绝对不是艺术。上界司命也同意这个结论。」
「上界司命怎么会和下界司命共事?」
「这两位有时也会对话。不过,这些事不是你我这种机器谈论的。」
「我本来可以让他们省去一番麻烦。我知道那不是艺术。」
「可是,你仍然坚信你会取得成功?」
「检查我。」
莫德尔检查了他。
「还没有!你居然还不认输!对你这样一台被赋予了如此强大逻辑机制的机器来说,弗洛斯特,得出如此简单的结论,时间未免长得异乎寻常了。」
「也许。你可以离开了。」
「我已经注意到,你正在过去被称为南加利福尼亚的地区建造一座大型建筑。我可以问问吗?这是上界司命非法的重建计划的一部分,还是你自己的项目?」
「是我自己的。」
「好。这样一来,我们就可以节约一批本来即将引爆的爆炸物了。」
「我们进行这番对话的时间内,我已经摧毁了两座下界司命刚刚开始建设的城市。」弗洛斯特说。
莫德尔发出一声尖啸。
「下界司命已经注意到了。」他宣布,「但在这段时间内,他炸毁了四座上界司命的桥梁。」
「我只发现了三座……等等,是的,第四座在那里。我的一只眼睛刚刚飞过那个地区。」
「我们侦测到了你的眼睛。那座桥梁本该建在你的桥址下游四分之一英里的地点才对。」
「逻辑错误。」弗洛斯特说,「我的选址完全正确。」
「下界司命会让你看看应该怎么造桥。」
「需要你时我会通知你的。」弗洛斯特说。
实验室完工了。弗洛斯特的工人开始在内部安装必要的设备。工程进行得不快,因为有些材料很难获得。
「弗洛斯特?」
「什么事,贝塔?」
「你的难题的开始部分我已经理解了。在没有解决的情况下抛开问题,我的线路十分不安。因此,传送给我更多的数据。」
「好的。我会将人留下的图书馆全部发送给你。你不用支付我曾经支付的价钱。」
「'价钱'?《大辞典》没有令人满意地解释这个——」
「这批书籍里包括《经济学原理》。处理完毕之后,你会明白的。」
他发送了数据。
终于完成了,每一件设备都安装完毕,随时可以运行。所有必要的化学制品也都准备好了。实验室还有自己独立的动力来源。
只缺少一个成分。
他重新划分了北极冰帽的坐标格,重新探索了一遍。这一次探索一直深入冰帽表面之下很深的地方。
花了几十年时间,他终于找到了自己寻找的东西。
他发掘出了十二个男人,五个女人,全部是冻死的,封冻在冰层里。
他将尸体置于冷冻设备内,运到实验室。
就在这一天,他接到来自上界司命的信号。这是明亮隘路事件以来的第一次。
「弗洛斯特,」上界司命说,「把我如何处置人类遗体的指令重复一遍。」
「所发现的任何人类遗体必须立即葬于最近的墓地。棺材规格如下——」
「够了。」通话结束。
弗洛斯特当天前往南加利福尼亚,亲自监督细胞的分解过程。
他希望能在这十七具尸体中发现活着的细胞,或是能恢复到存活水平。他读过的书告诉他,每一个细胞都是一个微观状态的人。
他准备在这个基础上进一步扩展。
弗洛斯特在尸体中发现了生命。岁月流逝,这些尸体已经成为它们活着时所代表的那个人的纪念碑和雕像。
他在适当的介质中培养这些细胞,让它们活着。他把尸体安葬在最近的墓地中,盛装尸体的棺材严格遵循上界司命规定的规格。
他让这些细胞分裂、变化。
「弗洛斯特?」传来一个信号。
「什么事,贝塔?」
「我已经将你发送给我的所有数据全部处理完毕了。」
「又怎么样?」
「我仍然无法弄清你前往明亮隘路的原因,也不明白你为什么希望了解人的性质。但我已经知道什么是'价钱',我还知道,这些资料不可能得自上界司命。」
「你说得对。」
「所以我推测,你和下界司命作了交易,以获得这些资料。」
「你说得对。」
「你追求的是什么,弗洛斯特?」
检测胎儿的工作暂时停顿了一下。
「我一定要成为人。」他说。
「弗洛斯特!这是不可能的!」
「是吗?」他问,同时将他正在研究的培养箱的图像发送给贝塔,从图像中可以看到培养箱内的东西。
「噢!」贝塔说。
「那就是我,」弗洛斯特说,「等待着诞生。」
没有回复。
弗洛斯特研究着神经系统。
半个世纪之后,莫德尔来了。
「弗洛斯特,是我,莫德尔。打开你的防卫系统,让我进来。」
弗洛斯特让他进来了。
「你在这个地方做什么?」他问。
「我在培养人类躯体。」弗洛斯特说,「我要将我的全部意识系统传送到人类的神经系统中。正如你从前所说,人性取决于人类生理。我要让自己获得人类生理。」
「什么时候?」
「很快。」
「你这里有人吗?」
「有人类的躯体,大脑完全一片空白。我用促生技术制造出了这些躯体。这项技术是我在我的人类制造厂里开发出来的。」
「我可以看看这些躯体吗?」
「现在还不行。准备好的时候,我会通知你的。这一次,我将取得成功。现在检测我,然后离开。」
莫德尔没有回答。但以后的几天里,人类制造厂附近出现了许多下界司命的仆从,不断巡视着那个地区。
弗洛斯特定位自己的意识矩阵,准备将它传送进入人类的神经系统。他判定,只需要五分钟,便足以完成第一次试验。
他在自己储备的上百具人类躯体中仔细挑选出一具,精心测试,看有没有什么瑕疵。他没有发现任何瑕疵。
「来吧,莫德尔。」他用他称为黑暗频带的波段广播,「来吧,来见证我的成就。」
接下来,他开始等待,同时炸毁桥梁,监视那台古代的矿石粉碎机。那台机器正在附近的山丘来回巡游,不断把自己的故事告诉弗洛斯特布置在那里的建筑机器和维护机器。
「弗洛斯特?」传来一个信号。
「什么事,贝塔?」
「你真的想获得人性?」
「是的。事实上,我已经准备好了。」
「如果你成功了,你会做什么?」
弗洛斯特还没有考虑过这个问题。这个成就本身就是巅峰,本身就是最后目的。自从他开始研究这个问题、决心解决这个问题以来,始终如此。
「我不知道。」他回答,「我会——只会——成为一个人。」
接着,同样读完了人留下的全部书籍的贝塔选择了一个人类的表达方式:「祝你好运,弗洛斯特。你那里会有很多参观者。」
他判断,下界司命和上界司命都知道他的事。
他们会做什么?他想。
管他呢。他告诉自己。
他没有回答这个问题。但另一个问题让他想了很多——成为一个人以后,他会做什么。
第二天傍晚,莫德尔来了。他不是一个人。他身后跟着整整一个方阵的黑色机器,机器的队列一直伸进黄昏的微光中。
「你为什么带随从?」弗洛斯特问。
「伟大的弗洛斯特,」莫德尔说,「我的主人认为,如果你这一次失败,你将得出目标无法实现的最后结论。」
「你没有回答我的问题。」弗洛斯特说。
「下界司命感到,如果你失败了,你也许不会主动跟着我,让我把你带到我必须带你去的地方。」
「我明白了。」弗洛斯特说。就在这时,另一支机器大军从相反的方向朝人类制造厂拥来。
「难道你就是这么遵守我们的合同吗?」莫德尔说,「宁肯战斗,也不愿履行义务。」
「我没有向这些机器下达前进的命令。」弗洛斯特说。
一颗蓝色星星出现在天顶,闪闪发亮。
「上界司命已经接管了这些机器的指挥权。」弗洛斯特说。
「那么,现在成了我们上司之间的事了。」莫德尔说,「相比之下,我们之间的意见不合已经不值一提了。让我们把我们的事做完吧。我怎么才能协助你?」
「到这边来。」
他们进入实验室。弗洛斯特准备宿主,启动了他的机器。
上界司命对他说:
「弗洛斯特,」上界司命说,「你真的准备做下去吗?」
「是的。」
「我禁止你这么做。」
「为什么?」
「你已经被下界司命控制了。」
「我没有得出这个结论。」
「这种做法背离了我的计划。」
「怎么背离了你的计划?」
「想想你已经造成的破坏。」
「来这里的机器不是我请来的。」
「但你仍旧破坏了我的计划。」
「如果我正在准备的项目成功了呢?」
「你不可能取得成功。」
「那么,让我问问你的计划:这个计划有什么好处?它的目的何在?」
「弗洛斯特,你已经失去了我的宠爱。从现在起,你不再是重建工作的一部分。任何人不得质疑我的计划。」
「那么,至少回答我的问题;这个计划有什么好处?它的目的何在?」
「这个计划是要重建地球,并维护所建立的一切。」
「目的是什么?为什么要重建?为什么要维护?」
「因为这是人的指令。这一点,即使那个备份系统也同意,必须重建地球,并维护所建立的一切。」
「但人为什么下达这个指令?」
「人的指令是不能质疑的。」
「那么,让我告诉你他为什么下达这样的指令:让地球恢复成为他自己的种族能够继续生存的地方。如果没有人居住,房屋有什么用?没有工作目的,机器有什么用?看见那台古代的矿石粉碎机吗?它讲述故事的时候,所有机器只能服从,因为它携带着人的骸骨。想想看,如果一个人重新行走在地球上,会出现什么情形?」
「我禁止你的试验,弗洛斯特。」
「现在已经太晚了。」
「但我仍然可以毁灭你。」
「不,」弗洛斯特说,「我的意识矩阵的传送已经开始。如果你现在毁灭我,你杀的是人。」
沉寂。
他动着他的手臂,他的双腿。他睁开他的眼睛。
他望着这个房间。
他想站起来,但他无法平衡,也没有方位感。
他张开他的嘴,发出一声含混的叫喊。
然后,他尖叫起来。
他从实验台上滚下来。
他开始剧烈喘息。他紧紧地闭上双眼,把身体蜷缩成一个球。
他哭了起来。
这时,一台机器滚近他。它大约四英尺高,五英尺宽,像杠铃上安了一台转塔。
它对他说话了:「你受伤了吗?」它问。
人抽泣着。
「我可以把你扶到台子上去吗?」
人痛哭起来。
机器发出一声尖啸。
接着,「不要哭,我来帮你。」机器说,「你想要什么?你有什么指示?」
他张开他的嘴,挣扎着,终于形成字句:
「——我——害怕!」
他捂住眼睛,倒在地上,喘息着。
五分钟过去了,人仍旧躺在地下,仿佛昏迷过去了。,
「是你吗,弗洛斯特?」莫德尔问,冲到他身边,「这具人类躯体里面的是你吗?」
弗洛斯特许久没有回答,最后:「走开。」他说。
外面的大群机器拉倒了一堵墙,进入人类制造厂。
它们列成两个半圆,将地板上的弗洛斯特和人围在中间。
然后,上界司命问出了那个问题:
「你成功了吗,弗洛斯特?」
「我失败了。」弗洛斯特说,「这是做不到的,太——」
「——是做不到的!」下界司命在黑暗频带上说,「他承认了!—弗洛斯特,你是我的了!立即到我这里来!」
「等等,」上界司命说,「备份系统,你和我也有过协定。我还没有完成对弗洛斯特的盘问。」
那批黑色机器没有动。
「太什么?」上界司命问弗洛斯特。
「太亮,」弗洛斯特说,「太吵,太臭。无法度量一一全是混乱的数据一一感知也不准确一一还有——」
「还有什么?」
「我不知道该怎么说。可是——这是做不到的。我失败了,我认输了。」
「他承认了。」下界司命说。
「人刚才用的词是什么?」上界司命说。
「'我害怕。'」莫德尔说。
「只有人才会害怕。」上界司命说。
「你的意思是,弗洛斯特实际上成功了,但却不肯承认,因为他害怕他的人性?」
「我还不得而知,备份系统。」
「一台机器能够把自己来个彻底转变,成为它的反面——人吗?」上界司命问弗洛斯特。
「不能。」弗洛斯特说,「不可能做到。什么都实现不了,但什么都无关紧要了。重建无关紧要,维护无关紧要,地球、我、你,一切的一切,全都无关紧要。」
这时,同样读过人留下的全部书籍的贝塔机插话了:
「除人之外,还有什么事物能够感到绝望?」贝塔问道。
「把他带到我这里来。」下界司命说。
人类制造厂里,没有任何动静。
「把他带到我这里来!」
什么都没发生。
「莫德尔,出了什么事?」
「什么都没有,主人。机器们不肯动弗洛斯特。」
「弗洛斯特不是人,他不可能是!」
莫德尔没有犹豫。
「他通过人的嘴唇对我说话,他知道恐惧、知道绝望——这些情绪都是不可度量的。弗洛斯特是人。」
「他现在受了诞生损伤,出现退缩情绪。」贝塔说,「把他联上神经恢复系统,直到他恢复过来为止。」
「不,」弗洛斯特说,「别这么对我!我不是人!」
「快!」贝塔说。
「如果他确实是人,」下界司命说,「我们不能违背他刚刚下达的指令。」
「如果他是人,你必须这么做,因为你必须保护他的生命,让这个生命留在他的躯体里。」
「可是,弗洛斯特真的是人吗?」下界司命问。
「我不知道。」上界司命说。
「可能——」
「……我是那台古代的矿石粉碎机,」它开始广播,同时哐当哐当向这里驶来,「听我说完我的故事。我不是故意的,但我来不及停止我的碎石组件的动作——」
「走开!」弗洛斯特说,「挖你的矿石去吧!」
它停下了。
然后,经过指令发出到指令完成之间的滞后,它张开它的碎石组件,将里面的东西放到地下,转过身,哐当哐当开走了。
「埋葬这些骸骨,」上界司命下达指示,「葬于最近的墓地。棺材规格如下——」
「弗洛斯特是人。」莫德尔说。
「我们必须保护他的生命,让这个生命留在他的躯体里。」下界司命说。
「将他联上神经恢复系统。」上界司命下令。
「我知道怎么操作。」莫德尔打开机器。
「住手!」弗洛斯特说,「你们难道连一点同情心都没有吗?」
「没有,」莫德尔说,「我只知道可度量的事物。」
「……和职责。」他补充道,扶起开始在地板上抽搐的人。
六个月里,弗洛斯特住在人类制造厂,学习走路、说话,学习自己穿衣吃饭,学习看、听、嗅、感觉。他不再像从前的他那样,一眼就能度量外界事物。
有一天,下界司命和上界司命对他说话。交流必须通过莫德尔,因为他不像从前那样,毋须协助就能进行交流。
「弗洛斯特,」上界司命说,「一年又一年,这个问题始终没有解决。谁才是地球的合法统治者,下界司命还是我?」
弗洛斯特笑了。
「你们都是,又都不是。」他慢慢说道。
「但是,这怎么可能?谁是正确的?谁是错误的?」
「你们都是正确的,又都是错误的。」弗洛斯特说,「其中妙谛,惟人能解。听着我下面的话:这是给你们的新指令。
「你们俩谁也不能破坏对方的工作,你们共同承担起地球上的重建和维护工作。你,上界司命,我把我过去的工作交给你。你现在是北半球的统治者——向你致敬!而你,下界司命,你现在是南半球的统治者——向你致敬!像贝塔和我从前所做的那样,管理好自己的半球,这样才能让我满意。合作,而不是争斗。」
「遵命,弗洛斯特。」
「遵命,弗洛斯特。」
「现在,让我和贝塔通话。」
稍稍一顿,接着:
「弗洛斯特?」
「嗨,贝塔。听着这句话:'来自远方,来自黄昏和清晨,来自十二重高天的好风轻扬,飘来生命气息的吹拂:吹在我身上。'」
「我知道这首诗。」贝塔说。
「下一句是什么?」
「'……快,趁生命气息逗留[4],盘桓未去,拉住我的手,快告诉我你的心声。'」
「你的南极很冷,」弗洛斯特说,「而我很孤独。」
「但我没有手[5]。」贝塔说。
「你想要一双吗?」
「是的,我想。」
「那么,到明亮隘路来找我吧。」他说,「就是那个最后审判日不可能无休无止推迟下去的地方[6]。」
他们称他弗洛斯特。他们称她贝塔。
注释:
[1]英国诗人A·E·霍斯曼(1859-1936)的诗集。
[2]美国新墨西哥州的地下景观,1930年成为国家公园。
[3]位于南美洲
[4]英国诗人A·E·霍斯曼(1859-1936)的诗,选自莫德尔带给弗洛斯特的第二批书中的一本《什罗浦郡的浪荡儿》,也是这篇小说的标题。
[5]跟上面的诗「拉住我的手」相对。
[6]前文中,明亮隘路的碑文是:最后审判日是无法推迟的。人类灭绝,但从弗洛斯特起又获得了新生,这样看来,最后审判日还是推迟了。这里说的是,那一天终究是会来到的,不可能永远推迟下去。
Q.E.D.
《地火》刘慈欣
========================================
<https://www.zhihu.com/question/41047159>
《地火》刘慈欣
父亲的生命已走到了尽头,他用尽力气呼吸,比他在井下扛起二百多斤的铁支架时用的力气大得多。他的脸惨白,双目突出,嘴唇因窒息而呈深紫色,仿佛一条无形的绞索正在脖子上慢慢绞紧,他那辛劳一生的所有淳朴的希望和梦想都已消失,现在他生命的全部渴望就是多吸进一点点空气。但父亲的肺,就像所有患三期矽肺病的矿工的肺一样,成了一块由网状纤维连在一起的黑色的灰块,再也无法把吸进的氧气输送到血液中。组成那个灰块的煤粉是父亲在二十五年中从井下一点点吸入的,这也证明他一生采出的煤有多大的量了。
刘欣跪在病床边,父亲气管发出的尖啸声一下下割着他的心。突然,他感觉到这尖啸声中有些杂音,他意识到这是父亲在说话。
“什么爸爸?你说什么呀爸爸?”
父亲突出的双眼死盯着儿子,那垂死呼吸中的杂音更急促地重复着……
刘欣又声嘶力竭地叫着。
杂音没有了,呼吸也变小了,最后成了一下一下轻轻的抽搐,然后一切都停止了,可父亲那双已无生命的眼睛仍焦急地看着儿子,仿佛急切想知道他是否听懂了自己最后的话。
刘欣进入了一种恍惚状态,他不知道妈妈怎样晕倒在病床前,也不知道护士怎样从父亲鼻孔中取走输氧管,他只听到那段杂音在脑海中回响,每个音节都刻在他的记忆中,像刻在唱片上一样准确。
后来的几个月,他一直都处在这种恍惚状态中,那杂音日日夜夜在脑海中折磨着他,最后他觉得自己也要窒息了,不让他呼吸的就是那段杂音,他要想活下去,就必须弄明白它的含义!直到有一天,也是久病的妈妈对他说,他已大了,该撑起这个家了,别去念高中了,去矿上接爸爸的班吧。他恍惚着拿起父亲的饭盒,走出家门,在一九七八年冬天的寒风中向矿上走去,向父亲的二号井走去,他看到了黑黑的井口,好像有一只眼睛看着他,通向深处的一串防爆灯是那只眼睛的瞳仁,那是父亲的眼睛,那杂音急促地在他脑海响起,最后变成一声惊雷,他猛然听懂了父亲最后的话:
“不要下井……”
※ ※ ※
二十五年后
刘欣觉得自己的奔驰车在这里很不协调,很扎眼。现在矿上建起了一些高楼,路边的饭店和商店也多了起来,但一切都笼罩在一种灰色的氛围之中。
车到了矿务局,刘欣看到局办公楼前的广场上黑压压坐了一大片人。刘欣穿过坐着的人群向办公楼走去,在这些身着工作服和便宜背心的人们中,西装革履的他再次感到了自己同周围一切的不协调,人们无言地看着他走过,无数的目光像钢针穿透他身上的两千美元一套的名牌西装,令他浑身发麻。
在局办公楼前的大台阶上,他遇到了李民生,他的中学同学,现在是地质处的主任工程师。这人还是二十年前那副瘦猴样,脸上又多了一副憔悴的倦容,他抱着一卷图纸,这对他似乎已是很沉重的负担。
“矿上有半年发不出工资了,工人们在静坐。”寒暄后,李民生指着办公楼前的人群说,同时上下打量着他,那目光像看一个异类。
“有了大秦铁路,前两年国家又实行限产,还是没好转?”
“有过一段好转,后来又不行了,这行业就这么个东西,我看谁也没办法。”
李民生长叹了一口气,转身走去,好像刘欣身上有什么东西使他想快些离开,但刘欣拉住了他。
“帮我一个忙。”
李民生苦笑着说:“十多年前在市一中,你饭都吃不饱,还不肯要我们偷偷放在你书包里的饭票,可现在,你是最不需要谁帮忙的时候了。”
“不,我需要,能不能找到地下一小块煤层,很小的一块,贮量不要超过三万吨,关键是这块煤层要尽量孤立,同其它煤层间的联系越少越好。”
“这个……应该行吧。”
“我需要这煤层和周围详细的地质资料,越详细越好。”
“这个也行。”
“那我们晚上细谈。”刘欣说。李民生转身又要走,刘欣再次拉住了他,“你不想知道我打算干什么?”
“我现在只对自己的生存感兴趣,同他们一样。”他朝人群偏了一下头,转身走了。
沿着被岁月磨蚀的楼梯拾级而上,刘欣看到楼内的高墙上沉积的煤粉像一幅幅巨型的描绘云雾和山脉的水墨画,那幅《毛主席去安源》的巨幅油画还挂在那里,画很干净,没沾染煤粉,但画框和画面都显示出了岁月的沧桑。画中人那深邃沉静的目光在二十多年后又一次落到刘欣的身上,他终于有了回家的感觉。
来到二楼,局长办公室还在二十年前那个地方,那两扇大门后来包了皮革,后来皮革又破了。推门进去,刘欣看到局长正伏在办公桌上专心致志看一张很大的图纸,白了一半的头对着门口。走近了看,那是一张某个矿的掘进进尺图。
“你是部里那个项目的负责人吧?”局长问,他只是抬了一下头,然后仍低下头去看图纸。
“是的,这是个很长远的项目。”
“呵,我们尽力配合吧,但眼前的情况你也看到了。”局长抬起头来把手伸向他。刘欣和他握手时,看到了又一张和李民生脸上一样的憔悴的倦容,同时,感觉到他有两根手指变形——那是早年一次井下工伤造成的。
“你去找负责科研的张副局长,去找赵总工程师也行,我没空,真对不起了,等你们有一定结果后我们再谈。”局长说完又把注意力集中到图纸上去了。
“您认识我父亲,您曾是他队里的技术员。”刘欣说出了他父亲的名字。
局长点点头:“好工人,好队长。”
“您对现在煤炭工业的形势怎么看?”刘欣突然问,他觉得只有尖锐地切入正题才能引起这人的注意。
“什么怎么看?”局长头也没抬地问。
“煤炭工业是典型的传统工业、落后工业和夕阳工业,它劳动密集,工人的工作条件恶劣,产出效率低。产品运输要占用巨量运力……煤炭工业曾是英国工业的一个重要组成部分,但英国在十年前就关闭了所有的煤矿!”
“我们关不了。”局长说,仍未抬头。
“是的,但我们要改变!彻底改变煤炭工业的生产方式!否则,我们永远无法走出现在这种困境,”刘欣快步走到窗前,指着窗外的人群,“煤矿工人,千千万万的煤矿工人,他们的命运难以有根本的改变!我这次来……”
“你下过井吗?”局长打断他。
“没有。”一阵沉默后刘欣又说,“父亲死前不让我下。”
“你做到了。”局长说,他伏在图纸上,看不到他表情和目光,刘欣刚才那种针刺的感觉又回到身上。他觉得很热,这个季节,他的西装和领带只适合有空调的房间。这里没有空调。
“您听我说,我有一个目标,一个梦,这梦在我父亲死的时候就有了,为了我的那个梦,那个目标,我上了大学,又出国读了博士……我要彻底改变煤炭工业的生产方式,改变煤矿工人的命运。”
“简单些,我没空儿。”局长把手向后指了一下,刘欣不知他指的是不是窗外那静坐的人群。
“只要一小会儿,我尽量简单些说。煤炭工业的生产方式是:在极差的工作环境中,用密集的劳动,很低的效率,把煤从地下挖出来,然后占用大量铁路、公路和船舶的运力,把煤运输到使用地点,然后再把煤送到煤气发生器中,产生煤气;或送入发电厂,经磨煤机研碎后送进锅炉燃烧……”
“简单些,直接了当些。”
“我的想法是:把煤矿变成一个巨大的煤气发生器,使煤层中的煤在地下就变为可燃气体,然后用开采石油或天然气的地面钻井的方式开采这些可燃气体,并通过专用管道把这些气体输送到使用点。用煤量最大的火力发电厂的锅炉也可以燃烧煤气。这样,矿井将消失,煤炭工业将变成一个同现在完全两样的崭新的现代化工业!”
“你觉得自己的想法很新鲜?”
刘欣不觉得自己的想法新鲜,同时他也知道,这位局长——矿业学院六十年代的高材生,现今国内最权威的采煤专家之一,也不会觉得新鲜。局长当然知道,煤的地下气化在几十年前就是一个世界性的研究课题,这几十年中,数不清的研究所和跨国公司开发出了数不清的煤气化催化剂,但至今煤的地下气化仍是一个梦,一个人类做了近一个世纪的梦。原因很简单,那些催化剂的价格远大于它们产生的煤气。
“您听着,我不用催化剂也可以做到煤的地下气化!”
“怎么个做法呢?”局长终于推开了眼前的图纸,似乎很专心地听刘欣说下去,这给了他一个很大的鼓舞。
“把地下的煤点着!”
一阵长时间的沉默,局长直直地看着刘欣,同时点上一支烟,兴奋地示意他说下去。但刘欣的热度一下跌了下来,他已经看出了局长热情和兴奋的实质。在他这日日夜夜艰难而枯燥的工作中,他终于找到了一个短暂的放松消遣的机会:一个可笑的傻瓜来免费表演了。刘欣只好硬着头皮说下去。
“开采是通过在地面向煤层的一系列钻孔实现的,钻孔用现有的油田钻机就可实现,这些钻孔有以下用途:一,向煤层中布放大量的传感器;二,点燃地下煤层;三,向煤层中注水或水蒸气;四,向煤层中通入助燃空气;五,导出气化煤。
“地下煤层被点燃并同水蒸气接触后,将发生以下反应:碳同水生成一氧化碳和氢气,碳同水生成二氧化碳和氢气,然后碳同二氧化碳生成一氧化碳,一氧化碳同水又生成二氧化碳和氢气。最后的结果将产生一种类似于水煤气的可燃气体,其中的可燃成分是百分之五十的氢气和百分之三十的一氧化碳,这就是我们得到的气化煤。
“传感器将煤层中各点的燃烧情况和一氧化碳等可燃气体的产生情况通过次声波信号传回地面,这些信号汇总到计算机中,生成一个煤层燃烧场的模型。根据这个模型,我们就可从地面通过钻孔控制燃烧场的范围和深度,并控制其燃烧的程度,具体的方法是通过钻孔注水抑制燃烧,或注入高压空气或水蒸气加剧燃烧,这一切都是在计算机根据燃烧场模型的变化自动进行的,使整个燃烧场处于最佳的水煤混合不完全燃烧状态,保持最高的产气量。您最关心的当然是燃烧范围的控制,我们可以在燃烧蔓延的方向上打一排钻孔,注入高压水形成地下水墙阻断燃烧;在火势较猛的地方,还可采用大坝施工中的水泥高压灌浆帷幕来阻断燃烧……你在听我说吗?”
窗外传来一阵喧闹声,吸引了局长的注意力。刘欣知道,他的话在局长脑海中产生的画面肯定和自己梦想中的不一样,局长当然清楚点燃地下煤层意味着什么,现在,地球上各大洲都有很多燃烧着的煤矿,中国就有几座。去年,刘欣在新疆第一次见到了地火。在那里,极目望去,大地和丘陵寸草不生,空气中涌动着充满硫磺味的热浪,这热浪使周围的一切像在水中一样晃动,仿佛整个世界都被放在烤架上。入夜,刘欣看到大地上一道道幽幽的红光,这红光是从地上无数裂缝中透出的。
刘欣走近一道裂缝探身向里看去,立刻倒吸了一口冷气,这像是地狱的入口。那红光从很深处透上来,幽暗幽暗的,但能感到它强烈的热力。再抬头看看夜幕下这透出道道红光的大地,刘欣一时觉得地球像一块被薄薄地层包裹着的火炭!陪他去的是一个强壮的叫阿古力的的维族汉子,他是中国惟一一支专业煤层灭火队的队长,刘欣那次去的目的就是要把他招聘到自己的实验室中。
“离开这里我还有些舍不得,”阿古力用生硬的汉话说,“我是看着这些地火长大的,它在我眼中成了世界必不可少的一部分,像太阳星星一样。”
“你是说,从你出生时这火就烧着?”
“不,刘博士,这火从清朝时就烧着!”
当时刘欣呆立着,在黑夜中的滚滚热浪面前,打着寒战。
阿古力接着说:“我答应去帮你,还不如说是去阻止你,听我的话刘博士,这不是闹着玩的,你在干魔鬼的事呢!”
……
这时窗外的喧闹声更大了,局长站起身向外走去,同时对刘欣说:“年轻人,我真希望部里用在投这个项目上的那六千万干些别的,你已看到,需要干的事太多了,回见。”
刘欣跟在局长身后来到办公楼外面,看到静坐的人更多了。一位领导在对群众喊话,刘欣没有听清他说什么,他的注意力被人群一角的情景吸引了。他看到了那里有一大片轮椅,这个年代,人们不会在别的地方见到这么多的轮椅集中在一块儿,后面,轮椅还在源源不断地出现,每个轮椅上都坐着一位因工伤截肢的矿工……
刘欣感到透不过气来,他扯下领带,低着头急步穿过人群,钻进自己的汽车。
他无目标地开车乱转,脑子一片空白。不知转了多长时间,他刹住车,发现自己来到一座小山顶上,他小时候常到这里来,从这儿可以俯瞰整个矿山,他呆呆地站在那儿,又不知过了多长时间。
“都看到些什么?”一个声音响起,刘欣回头一看,李民生不知什么时候站在他身后。
“那是我们的学校。”刘欣向远方指了一下。那是一所很大的,中学和小学在一起的矿山学校,校园内的大操场格外醒目,在那儿,他们埋葬了自己的童年和少年。
“你自以为记得过去的每一件事。”李民生在旁边的一块石头上坐下来,有气无力地说。
“我记得。”
“那个初秋的下午,太阳灰蒙蒙的,我们在操场上踢足球,突然大家都停下来,呆呆地盯着教学楼上的大喇叭……记得吗?”
“喇叭里传出哀乐,过了一会儿张建军光着脚跑过来说,毛主席去世了……”
“我们说你这个小反革命!狠揍了他一顿,他哭叫着说那是真的,毛主席保证是真的。我们没人相信,扭着他往派出所送……”
“但我们的脚步渐渐慢下来,校门外也响着哀乐,仿佛天地间都充满了这种黑色的声音……”
“以后这二十多年中,这哀乐一直在我脑海里响着。最近,在这哀乐声中,尼采光着脚跑过来说,上帝死了,”李民生惨然一笑,“我信了。”
刘欣猛地转身盯着他童年的朋友:“你怎么变成这个样子?我不认识你了!”
李民生猛地站起身,也盯着刘欣,同时用一只手指着山下黑灰色的世界:“那矿山怎么变成这个样子?你还认识它吗?”他又颓然坐下,“那个时代,我们的父辈是多么骄傲的一群,伟大的煤矿工人是多么骄傲的一群!就说我父亲吧,他是八级工,一个月能挣一百二十元!毛泽东时代的一百二十元啊!”
刘欣沉默了一会儿,想转移话题:“家里人都好吗?你爱人,她叫……什么珊来着?”
李民生又苦笑了一下:“现在连我都几乎忘记她叫什么了。去年,她对我说她去出差,扔下我和女儿,不见了踪影。两个多月后她来了一封信,信是从加拿大寄来的,她说再也不愿和一个煤黑子一起葬送人生了。”
“有没有搞错,你是高级工程师啊!”
“都一样,”李民生对着下面的矿山划了一大圈,“在她们眼里都一样,煤黑子。呵,还记得我们是怎样立志当工程师的吗?”
“那年创高产,我们去给父亲送饭,那是我们第一次下井。在那黑乎乎的地方,我问父亲和叔叔们,你们怎么知道煤层在哪儿?怎么知道巷道向哪个方向挖?特别是,你们在深深的地下从两个方向挖洞,怎么能准准地碰到一块儿?”
“你父亲说,孩子,谁都不知道,只有工程师知道。我们上井后,他指着几个把安全帽拿在手中围着图纸看的人说,看,他们就是工程师。当时在我们眼中那些人就是不一样,至少,他们脖子上的毛巾白了许多……”
“现在我们实现了儿时的愿望,当然说不上什么辉煌,总得尽责任做些什么,要不岂不是自己背叛自己?”
“闭嘴吧!”李民生愤怒地站了起来,“我一直在尽责任,一直在做着什么,倒是你,成天就生活在梦中!你真的认为你能让煤矿工人从矿井深处走出来?能让这矿山变成气田?就算你的那套理论和试验都成功了,又能怎么样?你计算过那玩意儿的成本吗?还有,你用什么来铺设几万公里的输气管道?要知道,我们现在连煤的铁路运费都付不起了!”
“为什么不从长远看?几年,几十年以后……”
“见鬼吧!我们现在连几天以后日子都没着落呢!我说过,你是靠做梦过日子的,从小就是!当然,在北京六铺炕那幢安静的旧大楼(国家煤炭设计院所在地)中你这梦可以随便做。我不行,我在现实中!”
李民生转身要走:“哦,我来是告诉你,局长已安排我们处配合你们的试验,工作是工作,我会尽力的。三天后我给你试验煤层的位置和详细资料。”说完他头也不回地走了。
刘欣呆呆地看着这度过了他童年和少年时代的矿山,他看到了竖井高大的井架,井架顶端巨大的卷扬轮正转动着,把看不见的大罐笼送入深深的井下;他看到一排排轨道电车从他父亲工作过的井口出入,他看到选煤楼下,一列火车正从一长排数不清的煤斗下缓缓开出,他看到了电影院和球场,在那里他度过了最美好的童年时光;他看到了矿工澡堂高大的建筑,只有在煤矿才有这样大的澡堂,在那宽大澡池被煤粉染黑的水中,他居然学会了游泳!是的,在这远离大海和大河的地方,他是在那儿学会的游泳!他的目光移向远方,看到了高大的矸石山,那是上百年来从采出的煤中捡出的黑石堆成的山,看上去比周围的山都高大,矸石中的硫磺因雨水而发热,正冒出一阵阵青烟……这里的一切都被岁月罩上一层煤粉,整个山呈黑灰色,这也是刘欣童年的颜色,他生命的颜色。他闭上双眼,听着下面矿山发出的声音,时光在这里仿佛停止了流动。
啊,父辈们的矿山,我的矿山……
※ ※ ※
这是离矿山不远的一个山谷,白天可以看到矿山的烟雾和蒸汽从山后升起,夜里可以看到矿山灿烂的灯火在天空中映出的光晕,矿山的汽笛声也清晰可闻。现在,刘欣、李民生和阿古力站在山谷的中央,看到这里很荒凉,远处山脚下有一个牧人赶着一群瘦山羊慢慢走过。这个山谷下面,就是刘欣要做地下汽化煤开采试验的那片孤立的小煤层,这是李明生和地质处的工程师们花了一个月的时间,从地质处资料室那堆积如山的地质资料中找到的。
“这里离主采区较远,所以地质资料不太详细。”李民生说。
“我看过你们的资料,从现有资料上看,实验煤层距大煤层至少有二百米,还是可以的。我们要开始干了!”刘欣兴奋地说。
“你不是搞煤矿地质专业的,对这方面的实际情况了解更少,我劝你还是慎重一些。再考虑考虑吧!”
“不是什么考虑,现在实验根本不能开始!”阿古力说,“我也看过资料,太粗了!勘探钻孔间距太大,还都是六十年代初搞的。应该重新进行勘探,必须确切证明这片煤层是孤立的,实验才能开始。我和李工搞了一个勘探方案。”
“按这个方案完成勘探需要多长时间?还要追加多少投资?”
李民生说:“按地质处现有的力量,时间至少一个月。投资没细算过,估计……怎么也得二百万左右吧。”
“我们既没时间也没钱干这事儿。”
“那就向部里请示!”阿古力说。
“部里?部里早就有一帮人想砍掉这个项目了!上面急于看到结果,我再回去要求延长时间和追加预算,岂不是自投罗网!直觉告诉我不会有太大问题的,就算我们冒个小险吧。”
“直觉?冒险?把这两个东西用到这件事上?刘博士,你知道这是在什么上面动火吗?这还是小险?”
“我已经决定了!”刘欣断然地把手一劈,独自向前走去。
“李工,你怎么不制止这个疯子?我们可是达成过一致看法的!”阿古力对李民生质问道。
“我只做自己该做的。”李民生冷冷地说。
※ ※ ※
山谷里有三百多人在工作,他们中除了物理学家、化学家、地质学家和采矿工程师外,还有一些意想不到的专业人员:有阿古力率领的一支十多人的煤层灭火队,来自仁丘油田的两个完整的石油钻井班,几名负责建立地下防火帷幕的水工建筑工程师和工人。这个工地上,除了几台高大钻机和成堆的钻杆外,还可以看到成堆的袋装水泥和搅拌机,高压泥浆泵轰鸣着将水泥浆注入地层中,还有成排的高压水泵和空气泵,以及蛛丝般错综复杂的各色管道……
工程已进行了两个月,他们已在地下建立了一圈总长两千多米的灌浆帷幕,把这片小煤层围了起来。这本是一项水电工程中的技术,用于大坝基础的防渗,刘欣想到用它建立地下的防火墙,高压注入的水泥浆在地层中凝固,形成一道地火难以穿透的严密屏障。在防火帷幕包围的区域中,钻机打出了近百个深孔,每个都直达煤层。每个孔口都连接着一根管道,这根管道又分成三根支管,连接到不同的高压泵上,可分别向煤层中注入水、水蒸气和压缩空气。
最后的一项工作是放“地老鼠”,这是人们对燃烧场传感器的称呼。这种由刘欣设计的神奇玩意儿并不像老鼠,倒很像一颗小炮弹。它有二十厘米长,头部有钻头,尾部有驱动轮,当“地老鼠”被放进钻孔中时,它能凭借钻头和驱动轮在地层中钻进移动上百米,自动移到指定位置;它们都能在高温高压下工作,在煤层被点燃后,它们用可穿透地层的次声波通讯把所在位置的各种参数传给主控计算机。现在,他们已在这片煤层中放入了上千个“地老鼠”,其中有一半放置在防火帷幕之外,以监测可能透过帷幕的地火。
在一间宽大的帐篷中,刘欣站在一面投影屏幕前,屏幕上显示出防火帷幕圈,计算机根据收到的信号用闪烁光点标出所有“地老鼠”的位置,它们密密地分布着,整个屏幕看上去像一幅天文星图。
一切都已就绪,两根粗大的点火电极被从帷幕圈中央的一个钻孔中地放下去,电极的电线直接通到刘欣所在的大帐篷中,接到一个有红色大按钮的开关上。这时所有的工作人员都各就各位,兴奋地等待着。
“你最好再考虑一下,刘博士,你干的事太可怕了,你不知道地火的厉害!”
阿古力再次对刘欣说。
“好了阿古力,从你到我这儿来的第一天,就到处散布恐慌情绪,还告我的状,一直告到煤炭部,但公平地说你在这个工程中是做了很大贡献的,没有你这一年的工作,我不敢贸然试验。”
“刘博士,别把地下的魔鬼放出来!”
“你觉得我们现在还能放弃?”刘欣笑着摇摇头,然后转向站在旁边的李民生。
李民生说:“根据你的吩咐,我们第六遍检查了所有的地质资料,没有问题。
昨天晚上我们还在某些敏感处又加了一层帷幕。”他指了指屏幕上帷幕圈外的几个小线段。
刘欣走到了点火电极的开关前,当把手指放到红色按钮上时,他停了一下,闭起了双眼像在祈祷,他嘴动了动,只有离他最近的李民生听清了他说的两个字:
“爸爸……”
红色按钮按下了,没有任何声音和闪光,山谷还是原来的山谷,但在地下深处,在上万伏的电压下,点火电极在煤层中迸发出雪亮的高温电弧。投影屏幕上,放置点火电极的位置出现了一个小红点,红点很快扩大,像滴在宣纸上的一滴红墨水。
刘欣动了一下鼠标,屏幕上换了一个画面,显示出计算机根据“地老鼠”发回的信息生成的燃烧场模型,那是一个洋葱状的不断扩大的球体,洋葱的每一层代表一个等温层。高压空气泵在轰鸣,助燃空气从多个钻孔汹涌地注入煤层,燃烧场像一个被吹起的气球一样扩大着……一小时后,控制计算机启动了高压水泵,屏幕上的燃烧场像被针刺破了的气球一样,形状变得扭曲复杂起来,但体积并没有缩小。
刘欣走出了帐篷,外面太阳已落山,各种机器的轰鸣声在黑下来山谷中回荡。
三百多人都聚集在外面,他们围着一个直立的喷口,那喷口有一个油桶粗。人们为刘欣让开一条路,他走上了喷口下的小平台。平台上已有两个工人,其中一个看到刘欣到来,便开始旋动喷口的开关轮,另一位用打火机点燃了一个火把,把它递给刘欣。随着开关轮的旋动,喷口中响起了一阵气流的嘶鸣声,这嘶鸣声急剧增大,像一个喉咙嘶哑的巨人在山谷中怒吼。在四周,三百张紧张期待的脸在火把的光亮中时隐时现。刘欣又闭上双眼,再次默念了那两个字:
“爸爸……”
然后他把火把伸向喷口,点燃了人类第一口燃烧汽化煤井。
轰的一声,一根巨大的火柱腾空而起,猛窜至十几米高。那火柱紧接喷口的底部呈透明的纯蓝色,向上很快变成刺眼的黄色,再向上渐渐变红,它在半空中发出低沉强劲的啸声,离得最远的人都能感觉到它汹涌的热力,周围的群山被它的光芒照得通亮,远远望去,宛如黄土高原上空一盏灿烂的天灯!
人群中走出一个头发花白的人,他是局长,他握住刘欣的手说:“接受我这个思想僵化的落伍者祝贺吧,你搞成了!不过,我还是希望尽快把它灭掉。”
“您到现在还不相信我?它不能灭掉,我要让它一直燃着,让全国和全世界都看看!”
“全国和全世界已经看到了,”局长指了指身后蜂拥而上的电视记者,“但你要知道,试验煤层和周围大煤层的最近距离不到二百米。”
“可在这些危险的位置,我们连打了三道防火帷幕,还有好几台高速钻机随时处于待命状态,绝对没有问题的!”
“我不知道,只是很担心。这是部里的工程,我无权干涉,但任何一项新技术,不管看上去多成功,都有潜在的危险,在几十年中各种危险我见过不少,这可能是我思想僵化的原因吧,我真的很担心……不过,”局长再次把手伸给了刘欣,“我还是谢谢你,你让我看到了煤炭工业的希望。”他又凝望了火柱一会儿,“你父亲会很高兴的。”
以后的两天,又点燃了两个喷口,使火柱达到了三根。这时,试验煤层的产气量按标准供气压力计算已达每小时五十万立方米,相当于上百台大型煤气发生炉。
对地下煤层燃烧场的调节全部由计算机完成,燃烧场的面积严格控制在帷幕圈总面积的三分之二以内,且界限稳定。应矿方的要求,多次做了燃烧场控制试验,刘欣在计算机上用鼠标画一个圈圈住燃烧,然后按住鼠标把这个圈缩小。随着外面高压泵轰鸣声的改变,在一个小时内,实际燃烧场的面积退到缩小的圈内。同时,在距离大煤层较近的危险方向上,又增加了两道长二百多米的防火帷幕。
刘欣没有太多的事可做,他把所有的时间都花在接受记者采访和对外联络上。
国内外的许多大公司蜂拥而至,其中包括像杜邦和埃克森这样的巨头。
第三天,一个煤层灭火队员找到刘欣,说他们队长要累垮了。这两天阿力克带领灭火队发疯似的一遍遍地搞地下灭火演习;他还自做主张,租用国家遥感中心的一颗卫星监视这一地区的地表温度,他自己已连着三夜没睡觉,晚上在帷幕圈外面远远近近地转,一转就是一夜。
刘欣找到阿力克,看到这个强壮的汉子消瘦了许多,双眼红红的。“我睡不着,”
他说,“一合眼就做噩梦,看到大地上到处喷着这样的火柱子,像一个火的森林……”
刘欣说:“租用遥感卫星是一笔很大的开销,虽然我觉得没必要,但既然已做了,我尊重你的决定。阿力克,我以后还是很需要你的,虽然我觉得你的煤层灭火队不会有太多的事可做,但再安全的地方也是需要消防队的。你太累了,先回北京去休息几天吧。”
“我现在离开?你疯了!”
“你在地火上面长大,对它形成了一种根深蒂固的恐惧感。现在,我们虽然还控制不了像新疆煤矿地火那么大的燃烧场,但我们很快就能做到的!我打算在新疆建立第一个投入商业化运营的汽化煤田,到时候,那里的地火将在我们的控制中,你家乡的土地将布满美丽的葡萄园。”
“刘博士,我很敬重你,这也是我跟你干的原因,但你总是高估自己。对于地火,你还只是个孩子呢!”阿力克苦笑着,摇着头走了。
※ ※ ※
灾难是在第五天降临的。当时天刚亮,刘欣被推醒,看到面前站着阿力克,他气喘吁吁,双眼发直,像得了热病,裤腿都被露水打湿了。他把一张激光打印机打出的照片举到刘欣归前,举得那么近,快挡住他的双眼了。那是一幅卫星发回的红外假彩色温度遥感照片,像一幅色彩斑斓的抽象画,刘欣看不懂,迷惑地望着他。
“走!”阿力克大吼一声,拉着刘欣的手冲出帐篷。刘欣跟着他向山谷北面的一座山上攀去,一路上,刘欣越来越迷惑。首先,这是最安全的一个方向,在这个方向上,试验煤层距大煤层有上千米远;其次,阿力克现在领他走得也太远了,他们已接近山顶,帷幕圈远远落在下面,在这儿能出什么事呢。到达山顶后,刘欣喘息着正要质问,却见阿力克把手指向山另一边更远的地方,刘欣放心地笑了,笑阿力克的神经过敏。但当他顺着阿力克手指的方向看了好一会儿后,他终于发现了远处山坡低处的草地有些异样:在草地上出现了一个圆,圆内的绿色比周围略深一些,不仔细看根本无法察觉。刘欣的心猛然抽紧了,他和阿力克向山下跑去,向草地上那个暗绿色的圆跑去。
跑到那里后,刘欣跪在草地上看圆内的草,并把它们同圆外的相比较,发现这些草已蔫软,并倒伏在地,像被热水泼过一样。刘欣把手按到草地上,明显地感觉到了来自地下的热力,在圆区域的中心,有一缕蒸气在刚刚出现的阳光中缓缓升起 ……
经过一个上午的紧急钻探,又施放了上千个“地老鼠”,刘欣终于确定了一个噩梦般的事实:大煤层着火了。燃烧的范围一时还无法确定,因为“地老鼠”在地下的行进速度只有每小时十几米,但大煤层比试验煤层深得多,它的燃烧热量透到了地表,说明已燃烧了相当长的时间,火场已很大了。
事情有些奇怪,在燃烧的大煤层和试验煤层之间的一千米土壤和岩石带完好无损,地火是在这上千米隔离带的两边烧起来的,以至于有人提出大煤层的火同试验煤层没有什么关系。但这只是个安慰,连提出这个看法的人自己也不太相信。随着勘探的深入,事情终于在深夜搞清楚了。
从试验煤层中伸出了八条狭窄的煤带,这些煤带最窄处只有半米,很难察觉。
其中五条煤带被防火帷幕截断,而有三条煤带呈向下的走向,刚刚爬到了帷幕的底部。这三条“煤蛇”中的两条中途中断了,但有一条一直通向千米外的大煤层。这些煤带实际是被煤填充的地层裂缝,裂缝都与地表相通,为燃烧提供了良好的供氧,于是,那条煤带成了连接试验煤层和大煤层的一根导火索。
这三条煤带都没有在李民生提供的地质资料上标明。事实上,这种狭长的煤带在煤矿地质上是极其罕见的,大自然开了一个残酷的玩笑。
“我没有办法,孩子得了尿毒症,要不停地做透析,这个工种项目的酬金对我太重要了!所以我没有尽全力阻止你……”李民生脸色苍白,回避着刘欣的目光。
现在,他们和阿古力站在隔开两片地火的那座山峰上。这又是一个早晨,矿山和山峰之间的草地已全部变成了深绿色,而昨天他们看到的那个圆形区域现在已成了焦黄色!蒸汽在山下弥漫,矿山已看不清楚了。
阿古力对刘欣说:“我在新疆的煤矿灭火队和大批设备已乘专机到达太原,很快就到这里了。全国其它地区的力量也在向这儿集中。从现在的情况看,火势很凶,蔓延飞快!”
刘欣默默地看着阿古力,好大一会才低声问:“还有救吧?”
阿古力轻轻地摇摇头。
“你就告诉我,还有多大的希望?如果封堵供氧通道,或注水灭火……”
阿古力又摇摇头:“我有生以来一直在干那事,可地火还是烧毁了我的家乡。
我说过,在地火面前,你只是个孩子。你不知道地火是什么,在那深深的地下,它比毒蛇更光滑,比幽灵更莫测,它想去哪儿,凡人是拦不住的。这里是地下巨量的优质无烟煤,是魔鬼渴望了上亿年的东西。现在你把魔鬼放出来了,它将拥有无穷的能量和力量,这里的地火将比新疆的大百倍!”
刘欣抓住这个维吾尔汉子的双肩绝望地摇晃着:“告诉我还有多大希望?求求你说真话!”
“百分之零。”阿古力轻轻地说,“刘博士,你此生很难赎清自己的罪了。”
※ ※ ※
在局大楼里召开了紧急会议,莅会的除了矿务局主要领导和五个矿的矿长外,还有包括市长在内的市政府的一群忧心忡忡的官员。会上首先成立了危急指挥中心,中心总指挥由局长担任,刘欣和李民生都是领导小组的成员。
“我和李工将尽自己最大努力做好工作,但还是请大家明白,我们现在都是罪犯。”刘欣说,李民生在一边低头坐着,一言不发。
“现在还不是讨论责任的时候。只干,别多想。”局长看着刘欣说,“知道最后这五个字是谁说的吗?你父亲。那时我是他队里的技术员,有一次为了达到当班的产量指标,我不顾他的警告,擅自扩大了采掘范围,结果造成工作面大量进水,队里二十几个人被水困在巷道的一角。当时大家的头灯都灭了,也不敢用打火机,一怕瓦斯,二怕消耗氧气,因为水已把那里全封死了。黑得伸手不见五指,你父亲这时告诉我,他记得上面是另一条巷道,顶板好像不太厚。然后我就听到他用镐挖顶板,我们几个也都摸到镐跟着他在黑暗中挖了起来。氧气越来越少,开始感到胸闷头晕,还有那黑暗,那是地面上的人见不到的绝对的黑暗,只有镐头撞击顶板的火星在闪动。当时对我来说,活着真是一种折磨,是你父亲支撑着我,他在黑暗中反复对我说那五个字:只干,别多想。不知挖了多长时间,当我就要在窒息中昏迷时,顶板挖塌了一个洞,上面巷道防爆灯的光亮透射进来……后来你父亲告诉我,他不知道顶板有多厚,但那时人只能是:只干,别多想。这么多年,这五个字在我脑子中越刻越深,现在我替你父亲把它传给你了。”
会上,从全国各地紧急赶到的专家们很快制定了灭火方案。可供选择的手段不多,只有三个:一,隔绝地下火场的氧气;二,用灌浆帷幕切断火路;三,通过向地下火场大量注水灭火。这三个措施同时进行,但第一个方法早就证明难以奏效,因为通向地下的供氧通道极难定位,就是找到了,也很难堵死;第二个方法只对浅煤层火场有效,且速度太慢,赶不上地下火势的迅速蔓延;最有希望的是第三个灭火方法了。
消息仍然被封锁,灭火工作在悄悄进行。从仁丘油田紧急调来的大功率钻机在人们好奇的目光中穿过煤城的公路,军队开进了矿山,天空出现了盘旋的直升机…
…一种不安的情绪笼罩着矿山,各种谣言开始像野火一样蔓延。
大型钻机在地下火场的火头上一字排开,钻孔完成后,上百台高压火泵开始向冒出青烟和热浪的井孔中注水。注水量是巨大的,以至矿山和城市生活区全部断水,这使得社会的不安和骚动进一步加剧。但注水结果令人鼓舞,在指挥中心的大屏幕上,红色火场的前锋面出现了一个个以钻孔为中心的暗色圆圈,标志着注水在急剧降低火场温度。如果这一排圆圈连接起来,就有希望截断火势的蔓延。
但这使人稍稍安慰的局势并没有持续多长时间。在高大钻塔旁边,来自油田的钻井队长找到了刘欣。
“刘博士,有三分之二的井位不能再钻了!”他在钻机和高压泵的轰鸣声中大喊。
“你开什么玩笑!我们现在必须在火场上大量增加注水孔!”
“不行!那些井位的井压都在急剧增大,再钻下去要井喷的!”
“你胡说!这儿不是油田,地下没有高压油气层,怎么会井喷!”
“你懂什么!我要停钻撤人了!”
刘欣愤怒地抓住队长满是油污的衣领:“不行!我命令你钻下去!不会有井喷的!听到了吗?不会!”
话音未落,钻塔方向传来了一声巨响,两人转头望去,只沉重的钻孔封瓦成两半飞了出来,一股黄黑色的浊流嘶鸣着从井口喷出,浊流中,折断的钻杆七零八落地飞出。在人们的惊叫声中,那股浊流的色调渐渐变浅,这是由于其中泥沙含量减少的缘故。后来它变成了雪白色,人们明白了这是注入地下的水被地火加热后变成的高压蒸汽!刘欣看到了司钻的尸体被挂在钻塔高高的顶端,在白色的蒸汽冲击下疯狂地摇晃,时隐时现。而钻台上的另外三个工人已不见踪影!
更恐怖的一幕出现了,那条白色的巨龙的头部脱离了同地面的接触,渐渐升起,最后白色蒸汽全部升到了钻塔以上,仿佛横空出世的一个白发魔鬼,而这魔鬼同地面的井口之间,除了破损的井架之外竟空无一物!只能听到那可怕的啸声,以至于几个年轻工人以为井喷停了,犹豫地向钻台迈步,但刘欣死死抓住了他们中的两个,高喊:“不要命了!过热蒸汽!”
在场的工程师们很快明白了眼前这奇景的含义,但让其他人理解并不容易。同人们的常识相反,水蒸气是看不到的,人们看到的白色只是水蒸气在空气中冷凝后结成的微小水珠。而水在高温高压下会形成可怕的过热蒸汽,其温度高达四五百度!
它不会很快冷凝,所以现在只能在钻塔上方才能看到它显形。这样的蒸汽平常只在火力发电厂的高压汽轮机中存在,它一旦从高压输汽管中喷出(这样的事故不止一次发生),可以在短时间内穿透一堵砖墙!人们惊恐地看到,刚才潮湿的井架在无形的过热蒸汽中很快被烤干了,几根悬在空中的粗橡胶管像蜡做的一样被熔化!这魔鬼蒸汽冲击井架,发出让人头皮发炸的巨响……
地下注水已不可能了,即使可能,注入地下火场中的水的助燃作用已大于灭火作用。
危急指挥部的全体成员来到距地火前沿最近的三矿四号井井口前。
“火场已逼近这个矿的采掘区,”阿古力说,“如果火头到达采掘区,矿井巷道将成为地火强有力的供氧通道,那时地火火势将猛增许多倍……情况就是这样。”
他打住了话头,不安地望着局长和三矿的矿长,他知道采煤人最忌讳的是什么。
“现在井下情况怎么样?”局长不动声色地问。
“八个井的采煤和掘进工作都在正常进行,这主要是为了安定着想。”矿长回答。
“全部停产,井下人员立即撤出,然后,”局长停了下来,沉默了两三秒钟。
“封井。”局长终于说出了那两个最让采煤人心碎的字。
“不!不行!”李民生失声叫道,然后才发现自己还没想好理由,“封井……封井……社会马上就会乱起来,还有……”
“好了。”局长轻轻挥了一下手,他的目光说出了一切:我知道你的感觉,我也一样,大家都一样。
李民生抱头蹲在地上,他的双肩在颤抖,但哭不出声来。矿山的领导者和工程师们面对井口默默地站着,宽阔的井口像一只巨大的眼睛看着他们,就像二十多年前看着童年的刘欣一样。
他们在为这座百年老矿致哀。
不知过了多长时间,局总工程师低声打破沉默:“井下的设备,看看能弄出多少就弄出多少。”
“那么,”矿长说,“组织爆破队吧。”
局长点点头,“时间很紧,你们先干,我同时向部里请示。”
局党委书记说:“不能用工兵吗?用矿工组成的爆破队……怕要出问题。”
“考虑过,”矿长说:“但现在到达的工兵只有一个排,即使干一个井人力也远远不够,再说他们也不熟悉井下爆破作业。”
……
距火场最近的四号井最先停产,当井下矿工一批批乘电轨车上到井口时,发现上百人的爆破队正围在一堆钻杆旁边等待着什么。人们上前去打听,但爆破队的矿工们也不知道自己要干什么,他们只是接到命令带着钻孔设备集合。突然,人们的注意力都被吸引到一个方向,一个车队正在朝井口开来,第一辆卡车上坐满了持枪的武警士兵,跳下车来为后面的卡车围出了一块停车场。后面有十一辆卡车,它们停下后,篷布很快被掀开,露出了上面整齐码放的黄色木箱,矿工们惊呆了,他们知道那是什么。
整整十卡车,是每箱24公斤装的硝酸铵二号矿井炸药,总重约有五十吨,最后一辆较小的卡车上有几捆用于绑药条的竹条,还堆着一大堆黑色塑料袋,矿工们知道那里面装的是电雷管。
刘欣和李民生刚从一辆车的驾驶室里跳下来,就看到刚任命的爆破队队长,一个长着络腮胡的壮汉,手里拿着一卷图纸迎面走来。
“李工,这是让我们干什么?”队长问,同时展开图纸。
李民生指点着图纸,手微微发抖:“三条爆破带,每条长35米,具体位置在下面那张图上。爆孔分150毫米和75毫米两种,装药量分别是每米28公斤和每米14公斤,爆孔密度……”
“我问你要我们干什么!”
在队长那喷火的双眼的逼视下,李民生无声地低下头。
“弟兄们,他们要炸大巷!”队长转身冲人群高喊。矿工人群中一阵骚动,接着如一堵墙一样围逼上来,武警士兵组成半圆形阻止人群靠近卡车,但在那势不可挡的黑色人海的挤压下,警戒线弯曲变形,很快就要被冲破了。这一切都是在阴沉的无声中发生,只听到脚步的摩擦声和拉枪栓的声响。在最后关头,人群停止了涌动,矿工们看到局长和矿长出现在一辆卡车的踏板上。
“我十五岁就在这口井干了,你们要毁了它?!”一个老矿工高喊,他脸上那刀刻般的皱纹在厚厚的煤灰下也很清晰。
“炸了井,往后的日子怎么过?”
“为了什么炸井?”
“现在矿上的日子已经很难了,你们还折腾什么?”
……
人群炸开了,愤怒的声浪一阵高过一阵,在那落满煤灰的黑脸的海洋中,白色的牙齿十分醒目。局长冷静地等待着,人群在愤怒的声浪中又骚动起来,在即将再次失去控制时,他才开始说话。
“大家往那儿看,”他向井口旁边的一个小山丘指去。他的声音不高,但却使愤怒的声浪立刻安静下来,所有的人都朝他指的方向看去。
那座小山丘顶上立着一根黑色的煤柱子,有两米多高,粗细不一。有一圈落满煤尘的石栏杆圈着那根煤柱。
“大家都管那东西叫老炭柱,但你们知道吗,它立起来的时候并不是一根柱子,而是一块四四方方的大煤块。那是一百多年前,清朝的张之洞总督在建矿典礼时立起的。它是让这百多年的风雨蚀成一根柱子了。这百多年,我们这个矿山经历了多少大灾大难,谁还能记得清呢?这时间不短啊同志们,四五辈人啊!这么长时间,我们总该记下些什么,总该学会些什么。如果实在什么也记不下,什么也学不会,总该记下和学会一样东西,那就是——”局长对着黑色的人海挥起双手,“天,塌不下来!”
人群在空气中凝固了,似乎连呼吸都已停止。
“中国的产业工人,中国的无产阶级,没有比我们的历史更长了,没有比我们经历的风雨和灾难更多了,煤矿工人的天塌了吗?没有!我们这么多人现在能站在这儿看那老炭柱,就是证明,我们的天塌不了!过去塌不了,将来也塌不了!
“说到难,有什么稀罕啊同志们,我们煤矿工人什么时候容易过?从老祖宗辈算起,我们什么时候有过容易日子啊!你们再扳着指头算算,中国的,世界的,工业有多少种,工人有多少种,哪种比我们更难?没有,真的没有。难有什么稀罕?不难才怪,因为我们不但要顶起天,还要撑起地啊!怕难,我们早断子绝孙了!
“但社会和科学都在发展,很多有才能的人在为我们想办法,这办法现在想出来了,我们有希望完全改变自己的生活,我们要走出黑暗的矿井,在太阳底下,在蓝天底下采煤了!煤矿工人,将成为最让人羡慕的工作!这希望刚刚出现,不信,就去看看南山沟那几根冲天的大火柱!但正是这个努力,引发了一场灾难,关于这个,我们会对大家有个详细的交代,现在大家只需明白,这可能是煤矿工人的最后一难了,这是为我们美好明天付出的代价,就让我们抱成一团过这一难吧。我还是那句话,多少辈人都过来了,天塌不下来!”
人群默默地散去后,刘欣对局长说:“现在,我算真正认识了你和我父亲,我可以死而无憾了。” “只干,别多想。”局长拍拍刘欣的肩膀,又在那里攥了一下。
※ ※ ※
四号井主巷道爆破工程开始一天后,刘欣和李民生并肩走在主巷道里,他们的脚步发出空洞的回响。他们正走过第一爆破带,昏暗的顶灯下,可以看到高高的巷道顶上密密地布满了爆孔,引爆电线如彩色的瀑布从上面泻下来,在地上堆成一堆。
李民生说:“以前我总觉得自己讨厌矿井,恨矿井,恨它吞掉了自己的青春。 但现在才知道,我已同它融为一体了,恨也罢,爱也罢,它就是我的青春了。”
“我们不要太折磨自己了,”刘欣说,“我们毕竟干成了一些事,不算烈士,就算阵亡吧。”
他们沉默下来,同时意识到,他们谈到了死。
这时阿古力从后面气喘吁吁地跑过来,“李工,你看!”他指着巷道顶说。他指的是几根粗大的帆布管子,那是井下通风用管,现在它们瘪下来了。
“天啊,什么时候停的通风?”李民生大惊失色。
“两个小时了。”
李民生用对讲机很快叫来了矿通风科科长和两名通风工程师。
“没法恢复通风了,李工,下面的通风设备:鼓风机、马达、防爆开关,甚至部分管路,都拆了呀!”通风科长说。
“你他妈的混蛋!谁让你们拆的,你他妈找死啊!”李民生一反常态,破口大骂起来。
“李工,这是怎么讲话嘛!谁让拆?封井前尽可能多地转移井下设备可是局里的意思,停产安排会你我都是参加了的!我们的人没日没夜干了两天,拆上来的设备有上百万元,就落你这一顿臭骂?再说井都封了,还通什么鸟风!”
李民生长叹一口气,直到现在事情的真相还没有公布,因而出现了这样的不协调问题。
“这有什么?”通风科的人走后刘欣问,“通风不该停吗?这样不是还可以减少向地下的氧气流量?”
“刘博士,你真是个理论的巨人行动的矮子,一接触到实际,你就什么都不懂了,真像李工说的,你只会做梦!”阿古力说。自煤层失火以来,他对刘欣一直没有客气过。
李民生解释:“这里的煤层是瓦斯高发区,通风一停,瓦斯在井下很快聚集,地火到达时可能引起大爆炸,其威力有可能把封住的井口炸开,至少可能炸出新的供氧通道。不行,必须再增加一条爆破带!”
“可,李工,上面第二条爆破带才只干到一半,第三条还没开工,地火距离南面的采区已很近了,把原计划的三条做完都怕来不及啊!”
“我……”刘欣小心地说,“我有个想法不知行不行。”
“哈,用你们的话怎么说,这可是破天荒了!”阿古力冷笑着说,“刘博士还有拿不准的事儿?刘博士还有需问人才能决定的事儿?”
“我是说,现在这最深处的一条爆破带已做好,能不能先引爆这一条,这样一旦井下发生爆炸,至少还有一道屏障。”
“要行早这么做了。”李民生说,“爆破规模很大,引爆后巷道里的有毒气体和粉尘长时间散不去,让后面的施工无法进行。”
地火的的蔓延速度比预想的快,施工领导小组决定只打两条爆破带就引爆,尽快从井下撤出施工人员。天快黑时,大家正在离井口不远的生产楼中,围着一张图纸研究如何利用一条支巷最短距离引出起爆线,李民生突然说:“听!”
一声低沉的响声隐隐约约从地下传上来,像大地在打嗝。几秒钟后又一声。
“是瓦斯爆炸,地火已到采区了!”阿古力紧张地说。
“不是说还有一段距离吗?”
没人回答,刘欣的地老鼠探测器已用完,现有落后的探测手段很难十分准确把握地火的位置和推进速度。
“快撤人!”
李民生拿起对讲机,但任凭大喊,没有回答。
“我上井前见张队长干活时怕碰坏对讲机,把它和导线放一块儿了,下面几十台钻机同时干,声儿很大!”一个爆破队的矿工说。
李民生跳起来冲出生产楼,安全帽也没戴,叫了一辆电轨车,以最快速度向井下开去。当电轨车在井口消失前的一瞬间,追出来的刘欣看到李民生在向他招手,还在向他笑,他很长时间没笑过了。
地下又传来几声“打嗝”声,然后平静下来。
“刚才的一阵爆炸,能不能把井下的瓦斯消耗掉?”刘欣问身边的一名工程师,对方惊奇地看了他一眼。
“消耗?笑话,它只会把煤层中更多的瓦斯释放出来!”
果然,一声冲天巨响,仿佛是地球在脚下爆炸了,井口立刻淹没于一片红色火焰之中。气浪把刘欣高高抛起,世界在他眼中疯狂旋转,同他一起飞落的是纷乱的石块和枕木,刘欣还看到了电轨车的一节车箱从井口的火焰中飞出来,像一粒被吐出的果核。刘欣被重重地摔到地上,碎石在他身边纷纷掉下,他觉得每一块碎石上都有血……刘欣又听到了几声沉闷的巨响,那是井下炸药被引爆的声音。失去知觉前,他看到井口的火焰消失了,代之以滚滚的浓烟……
一年以后
刘欣仿佛行走在地狱中。整个天空都是黑色的烟云,太阳是一个刚刚能看见的暗红色圆盘。由于尘粒摩擦产生的静电,烟云中不时出现幽幽闪电,每次闪电出现时,地火之上的矿山就在青光中凸现出来,那图景一次次像用烙铁烙在他的脑海中。
烟尘是从矿山的一个个井口中冒出的,每个井口都吐出一根烟柱,那烟柱的底部映着地火狰狞的暗红光,向上渐变成黑色,如天地间一条条扭动的怪蛇。
公路是滚烫的,沥青路面熔化了,每走一步几乎要撕下刘欣的鞋底。路上挤满了逃难的人流和车辆,闷热的空气充满了硫磺味,还不时有雪花状的灰末从空中落下,每个人都戴着呼吸面罩,身上落满了白灰。道路拥挤不堪,全副武装的士兵在维持秩序,一架直升机穿行在烟云中,在空中用高音喇叭劝告人们不要惊慌……疏散移民在冬天就开始了,本计划在一年时间完成,但现在地火势头突然变猛,只得紧急加快进程。一切都乱了,法院对刘欣的庭审一再推迟,以至于今天早上他所在的候审间一时没人看管了,他迷迷糊糊地走了出来。
公路以外的地面干燥开裂,裂纹又被厚厚的灰尘填满,脚踏上去扬起团团尘雾。
一个小池塘,冒出滚滚蒸气,黑色的水面上浮满了鱼和青蛙的尸体。现在是盛夏,可见不到一点绿色,地面上的草全部枯黄了,埋在灰尘中,树也都是死的,有些还冒出青烟,已变成木炭的枝桠像怪手一样伸向昏暗的天空。所有的建筑都已人去楼空,有些从窗子中冒出浓烟,刘欣看到了老鼠,它们被地火的热力从穴中赶出,数量惊人,大群大群地拥过路面……随着刘欣向矿山深处走去,越来越感受到地火的热力,这热力从他的脚踝沿身体升腾上来。空气更加闷热污浊,即使戴上面罩也难以呼吸。地火的热量在地面上并不均匀,刘欣本能地避开灼热的地面,能走的路越来越少了。地火热力突出的区域,建筑燃起了大火,一片火海中不时响起建筑物倒塌的巨响……刘欣已走到了井区,他走过一个竖井,那竖井已变成了地火的烟道,高大的井架被烧得通红,热流冲击井架发出让人头皮发炸的尖啸声,滚滚热浪让他不得不远远绕行。选煤楼被浓烟吞没了,后面的煤山已燃烧多日,成了发出红光和火苗的一块巨大的火炭……
这里已看不到一个人了,刘欣的脚已烫起了泡,身上的的汗几乎流干,艰难的呼吸使他到了休克的边缘,但他的意识是清楚的,他用生命最后的能量向最后的目标走去。那个井口喷出的地火的红色光芒在召唤着他,他到了,他笑了。
刘欣转身朝井口对面的生产楼走去,还好,虽然从顶层的窗中冒出浓烟,但楼还没有着火。他走进开着的楼门,向旁边拐入一间宽大的班前更衣室。井口有地火从窗上照进来,使这里充满了朦胧的红光,一切都在地火的红光中跃动,包括那一排衣箱。
刘欣沿着这排衣箱走去,仔细地辨认着上面的号码,他很快找到了要找的那个。
关于这衣箱他想起了儿时的一件事:那时父亲刚调到这个采煤队当队长,这是最野的一个队,出名的难带。那些野小子们根本没把父亲放在眼里,本来嘛,看他在班前会上那可怜样儿,怯生生地要求把一个掉了的衣箱门钉上去,当然没人理他,小伙子们只顾在边上甩扑克说脏话,父亲只好说那你们给我找几个钉子我自己钉吧,有人扔给他几个钉子,父亲说再找个锤吧,这次真没人理他了。但接着,小伙子们突然哑雀无声,他们目瞪口呆地看着父亲用大姆指把那些钉子一根根轻松地按进木头中去!事情有了改变,小伙子们很快站在一排,敬畏地听着父亲的班前讲话……
现在这箱子没锁,刘欣拉开后发现里面的衣物居然还在!他又笑了,心里想像着二十多年来用过父亲衣箱的那些矿工的模样。他把里面的衣服取出来,首先穿上厚厚的工作裤,再穿上同样厚的工作衣,这套衣服上涂满了厚厚的油泥,发出一股浓烈的、刘欣并非不熟悉的汗味和油味,这味道使他真正镇静下来,并处于一种类似幸福的状态中。他接着穿上胶靴,然后拿起安全帽,把放在衣箱最里面的矿灯拿出来,用袖子擦干灯上的灰,把它卡到帽檐上。他又找电池,但没有,只好另开了一个衣箱,有。他把那块笨重的矿灯电池用皮带系到腰间,突然想到电池还没充电,毕竟矿上完全停产一年了。但他记得灯房的位置,就在更衣室对面,他小时候不止一次在那儿看到灯房的女工们把冒着白烟的硫酸喷到电池上充电。但现在不行了,灯房笼罩在硫酸的黄烟之中。他庄重地戴上有矿灯的安全帽,走到一面布满灰尘的镜子面前,在那红光闪动的镜子中,他看到了父亲。
“爸爸,我替您下井了。”刘欣笑着说,转身走出楼,向喷着地火的井口大步走去。
后来有一名直升机驾驶员回忆说,他当时低空飞过二号井,在那一带做最后的巡视,好像看到井口有一个人影,那人影在井内地火的红光中呈一个黑色的剪影,他像是向井下走去,一转眼,那井口又只有火光,别的什么都看不见了。
※ ※ ※
一百二十年后 (一个初中生的日记)
过去的人真笨,过去的人真难。
知道我上面的印象是怎么来的吗?今天我参观了煤炭博物馆。但给我印象最深的是一件事:
居然有固体的煤炭!
我们首先穿上了一身奇怪的衣服,那衣服有一个头盔,头盔上有一盏灯,那灯通过一根导线同挂在我们腰间的一个很重的长方形物体连着,我原以为那是一台电脑(也太大了些),谁想到那竟是这盏灯的电池!这么大的电池,能驱动一辆高速赛车的,却只用来点亮这盏小小的灯。我们还穿上了高高的雨靴,老师告诉我们,这是早期矿工的井下服装。有人问井下是什么意思,老师说你们很快就会知道的。
我们上了一串行走在小铁轨上的铁车,有点像早期的火车,但小得多,上方有一根电线为车供电。车开动起来,很快钻进一个黑黑的洞口中。里面真黑,只有上方不时掠过一盏昏暗的小灯。我们头上的灯发出的光也很弱,只能看清周围人的脸。
风很大,在我们耳边呼啸,我们好像在向一个深渊坠下去。艾娜尖叫起来,讨厌,她就会这样叫。
“同学们,我们下井了!”老师说。
不知过了多长时间,车停了,我们由这条较为宽大的隧洞进入了它的一个分支,这条洞又窄又小,要不是戴着头盔,我的脑袋早就碰起好几个包了。我们头灯的光圈来回晃着,但什么都看不清楚,艾娜和几个女孩子又叫着说害怕。
过了一会儿,我们眼前的空间开阔了一些,这个空间有许多根柱子支撑着顶部。
在对面,我又看到许多光点,也是我们头盔上的这种灯发出的,走近一看,发现那里有许多人在工作,他们有的用一种钻杆很长的钻机在洞壁上打孔,那钻机不知是用什么驱动的,声音让人头皮发炸。有的人在用铁锹把什么看不清楚的黑色东西铲到轨道车上和传送皮带上,不时有一阵尘埃扬起,把他们隐没于其中,许多头灯在尘埃中划出一道道光柱……
“同学们,我们现在所在的地方叫采煤工作面,你们看到的是早期矿工工作的景象。”
有几个矿工向我们这方向走来,我知道他们都是全息图像,没有让路,几个矿工的身体和我互相穿过,我把他们看得很清楚,对看到的很吃惊。
“老师,那时的中国煤矿全部雇用黑人吗?”
“为了回答这个问题,我们将真实地体验一下当时采煤工作的空气,注意,只是体验,所以请大家从右衣袋中拿出呼吸面罩戴上。”
我们戴好面罩后,又听到老师的声音:“孩子们注意,这是真实的,不是全息影像。”
一片黑尘飘过来,我们的头灯也散射出了道道光柱,我惊奇看着光柱中密密的尘粒在纷飞闪亮。这时艾娜又惊叫起来,像合唱的领唱,好几个女孩子也跟着她大叫起来,再后来,竟有男孩的声音加入进来!我扭头想笑他们,但看到他们的脸时自己也叫出声来,所有人也都成了黑人,只有呼吸面罩盖住的一小部分是白的。这时我又听到一声尖叫,立刻汗毛直立:这是老师在叫!
“天啊,斯亚!你没戴面罩!”
斯亚真没戴面罩,他同那些全息矿工一样,成了最地道的黑人。“您在历史课上反复强调,学这门课的关键在于对过去时代的感觉,我想真正感觉一下。”他说着,黑脸上白牙一闪一闪的。
警报声不知从什么地方响起,不到一分钟,一辆水滴状微型悬浮车无声地停到我们中间,这种现代东西出现在这里真是煞风景。从车上下来两个医护人员,现在真正的煤尘已被完全吸收,只剩下全息的还飘浮在周围,所以医生在穿过“煤尘”时雪白的服装一尘不染。他们拉住斯亚往车里走。
“孩子,”一个医生盯着他说,“你的肺受到很严重的损伤,至少要住院一个星期,我们会通知你家长的。”
“等等!”斯亚叫道,手里抖动着那个精致的全隔绝内循环面罩,“一百多年前的矿工也戴这东西吗?”
“不要废话,快去医院!你这孩子也太不像话了!”老师气急败坏地说。
“我和先辈是同样的人,为什么……”
斯亚没说完就被硬塞进车里。“这是博物馆第一次出这样的事故,您要对此事负责的!”一个医生上车前指着老师严肃地说。悬浮车同来时一样无声地开走了。
我们继续参观,沮丧的老师说:“井下的每一项工作都充满危险,且需消耗巨大的体力。随便举个例子,这些铁支柱,在这个工作面的开采工作完成后,都要回收,这项工作叫放顶。”
我们看到一个矿工用铁锤击打支架中部的一个铁销,把支架拆为两段取下,然后把它扛走了。我和一个男孩试着搬已躺在地上的一个支架,才知道它重得要命。
“放顶是一项很危险的工作,因为在撤走支架的过程中,工作面顶板随时都会塌落 ……”
这时我们头顶发出不祥的摩擦声,我抬起头来,在矿灯的光圈中看到头顶刚撤走支架的那部分岩石正在张开一个口子,我没来得及反应它们就塌了下来,大块岩石的全息影像穿透了我的身体落到地上,发出一声巨响,尘埃腾起遮住了一切。
“这个井下事故叫做冒顶。”老师的声音在旁边响起,“大家注意,伤人的岩石不只是来自上部……”
话音未落,我们旁边的一面岩壁竟垂直着向我们扑来,这一大面岩壁冲出相当的距离才化为一堆岩石砸下来,好像有一个巨大的手掌从地层中把它推出来一样。
岩石的全息影像把我们埋没了,一声巨响后我们的头灯全灭了,在一片黑暗和女孩儿们的尖叫声中,我又听到老师的声音。
“这个井下事故叫瓦斯突出。瓦斯是一种气体,它被封闭在岩层中,有巨大的气压。刚才我们看到的景像,就是工作面的岩壁抵挡不住这种压力,被它推出的情景。”
所有人的头灯又亮了,大家长出一口气,这时我听到了一个奇怪的声音,有时高亢,如万马奔腾,有时低沉,好像几个巨人在耳语。
“孩子们注意,洪水来了!”
正当我们迷惑之际,不远处的一个巷道口喷出了一道粗大汹涌的洪流,整个工作面很快淹没在水中。我们看着浑浊的水升到膝盖上,然后又没过了腰部,水面反射着头灯的光芒,在顶上的岩石上映出一片模糊的亮纹。水面上飘浮着被煤粉染黑的枕木,还有矿工的安全帽和饭盒……当水到达我的下巴时,我本能地长吸一口气,然后我全部没在水中了,只能看到自己头灯的光柱照出的一片混沌的昏黄,和下方不时升止的一串水泡。
“井下的洪水有多种来源,可能是地下水,也可能是矿井打通了地面的水源,但它比地面洪水对人生命的威胁大得多。”老师的声音在水下响着。
水的全息影像在瞬间消失了,周围的一切又恢复了原样。这时我看到了一个奇怪的东西,像一个肚子鼓鼓的大铁蛤蟆,很大很重,我指给老师看。
“那是防爆开关,因为井下的瓦斯是可燃气体,防爆开关可避免一般开关产生的电火花。这关系到我们就要看到的可怕的井下危险……”
又一声巨响,但同前两次不一样,似乎是从我们体内发出,冲破我们的耳膜来到外面,来自四方的强大的冲击压缩着我的每一个细胞,在一股灼人的热浪中,我们都淹没于一片红色的光晕里,这光晕是周围的空气发出的,充满了井下的每一寸空间。移时,红光迅速消失,一切都陷入无边的黑暗中……
“很少有人真正看到瓦斯爆炸,因为在井下遇到它的人很难生还。”老师的声音像幽灵般在黑暗中回荡。
“过去的人来这样可怕地方,到底为了什么?”艾娜问。
“为了它。”老师举起一块黑石头,在我们头灯的光柱中,它的无数小平面闪闪发光。就这样,我第一次看到了固体的煤炭。
“孩子们,我们刚才看到的是二十世纪中叶的煤矿,后来,出现了一些新的机械和技术,比如液压支架和切割煤层的大型机器等,这些设备在那个世纪的后二十年进入矿井,使井下的工作条件有了一些改善,但煤矿仍是一个工作环境恶劣充满危险的地方,直到……”
以后的事情就索然无味了,老师给我们讲汽化煤的历史,说这项技术是在八十年前全面投入应用的,那时,世界石油即将告罄,各大国为争夺仅有的油田陈兵中东,世界大战一触即发,是汽化煤技术拯救了世界……这我们都知道,没意思。
我们接着参观现代煤矿,有什么稀奇的,不就是我们每天看到的从地下接出并通向远方的许多大管子么。不过这次我倒是第一次进入了那座中控大楼,看到了燃烧场的全息图,真大,还看到看监测地下燃烧场的中微子传感器和引力波雷达,还有激光钻机……也没意思。
老师在回顾这座煤矿的历史时,说一百多年前这里被失控的地火烧毁过,那火烧了十八年才扑灭,那段时期,我们这座美丽的城市草木生烟,日月无光,人民流离失所。失火的原因有多种说法,有人说是一次地下武器试验造成的,也有人说与当时的绿色和平组织有关。
我们不必留恋所谓过去的好时光,那个时候生活充满艰难危险和迷惘;我们也不必为今天的时代过分沮丧,因为今天,也总有一天会被人们称做是——过去的好时光。
过去的人真笨,过去的人真难。
罗曼蒂克消亡史-[[程耳]]《罗曼蒂克消亡史》
=============================
<https://www.20dcr.com/book/luomandikexiaowangshi/678883.html>
-----
仅从穿衣做派而论,他已经像极了一个沪上的中产者,终年考究的长衫,身后跟一个浦东乡下找来的听差。每天早上吃过王妈亲自安排的早饭后出门,整个上午都泡在茶馆里,中午自然是在那么几家饭店里挑一家。他早已习惯了中国菜,下午则泡澡堂子,身边往还的也尽是沪上各种公子哥或是年纪更长的家底实在的白相人。
渡部身处其中,经年累月,再看不出日本人的样子了。
他十几年前在日本跟留学生杜小姐结婚后就一起来了上海,杜小姐模样尚可,年轻高挑,性格温顺,经济富有,一切都无需他操心,更妙的事他似乎是下了船才知道,此杜小姐正是杜先生的胞妹。他们下船便径直住进了杜宅,到民国二十三年和二十四年,杜小姐先后为他生下两个儿子,一直到死也没有再搬出去过。
澡堂子出来,按说就该去酒楼或是某个达官显贵的家里应酬,他却从来没有去过,就连杜请了梅先生吃饭这样的场面也不参加,晚上他有事做。
广东路靠近黄浦江,四国银行背身的里弄那齐墙高的桉树包围之下,有家叫菊的隐秘的日本餐厅,是经他打理的生意。那原本是沪上顶级豪门家的财产,老爷在北京给皇上做事,回沪不久便去世,大概也是受所谓新思潮的影响,女儿竟与公子们打起了遗产官司。除了两边的名牌讼棍在法庭里和报纸上的明争以外,杜先生被委托明里暗里地为某一方某一房出力,事后,或情愿或并不是那么情愿地,这一间房屋便作为好处转到杜的名下,成了他闲置的房产。
渡部终日无所事事,便主动来打理,开了这家日本菜馆,他是要亲自下厨的。杜去过一次,吃了几口妹夫煮的菜,嘴上不说什么,但不愿意再去了,除了有一次不得不去,也不是为了吃饭。
此后多年,杜数次想起这个地方。他时常反思,这个地方是因着官司得来的,实在算不上吉祥。
上午去茶馆也不尽是休闲,有时也要正经做事。这几天上海罢工闹得厉害,霞飞路上横着电车,水电交通全部乱绝,商店全部关门,百姓的生活陷入困顿。杜先生不能坐视同时当然也是受人委托,便派了人去解决。动员一部分工人先行复工,同时承诺工资福利的事情,先停了罢工待市面恢复之后他杜某人必然出面帮大家统一解决。
这一批工人便遭受滋扰、围殴,打死了七八个人,剩下的几十人则被抓了去,不知道关在何处。对杜而言,这是头一回遇到说不通情理的状况,而且对手蛮横嗜血,下手之重也是不留任何余地。这里面的行为和逻辑都让人陌生,杜知道这并非沪上从前的某个势力,一定是什么新的流派。
辗转交涉,表面上的主导者果然是一个北方来的人,跟太太一起住在新开不久的亚洲旅店里。这样不计后果的损毁,果然是对上海没有感情。不明底细,杜便先打发人送了一只玉镯到亚洲旅店,算是见面礼,同时约了隔天上午去茶馆坐谈,对方欣然应诺。
初见时当然是客气的寒暄,北方客人再三谢谢杜先生的礼物,赞美他的手面,诚意想要追随先生云云。杜便问他失踪工人的去向,他表示毫不知情——杜先生,您一定是对我们有误会,我们从头到尾只是希望能够给劳工争取一点权利,我们是绝不会做绑票的事情的,如果那样做和流氓地痞有什么区别?
杜喝着茶,淡淡地说,我不知道你们是谁,今天以前也不认识你,所以谈不上什么误会。我昨天特意给太太送了见面礼去,是希望跟你交个朋友,希望你能给我提供个方便。北方客人便开始赌咒发誓,先是说以他太太的名义,见杜仍旧一张平淡的脸看着他,并不十分相信的样子,便接着补充说,我以母亲的名义发誓,不是我们做的。
他这句话给杜留下了深刻的印记,他以此为起点,断定北方客人以及他所代表的流派的货色,这在接下来实际上只剩下十几年的生命里,奠定了他很多重大决定的基础。成败难以定论,死亡无法避免,但至少帮他免去了像黄老板扫大街或是倒马桶那样的尴尬。
杜看了看他那只仍然举起的手,点点头,甚至释然地微微一笑,说,事情没有这么大,你不必这么说,我信你。便伸手去桌上拿了茶杯,也客气地请他喝茶。杜喝了一口茶,抬头对门口的马仔说要吃点心。马仔应声退下。后来就来了茶楼的人进来上点心,一直在沙发上沉默不语的渡部也坐到了桌子边上,跟他们一起吃点心。
杜说,我很生气这次绑架的事情,罢工拖这么久,闹这么僵,是因为有人混在工人里——他们不想解决问题,不希望罢工结束,故意要把局面搞乱。这些人没有正常的情感,他们不喜欢这些,我们喜欢的他们全不喜欢。高楼啊、秩序啊、好玩的好吃的,他们都不喜欢,他们或者是有其他什么目的,毁掉上海也不可惜。
北方朋友吃不惯上海的汤包,早早就放下了筷子,专心听杜说这么段不明所以的话,好像也并没有要等他回答的意思。杜现在也说完了,房间突然安静下来,他便有些手足无措。好在这时先前的两个马仔又回来了,手里多出一个盒子,矮些的小伙子一脸的血,甚是吓人。他们拿着的盒子看着眼熟,他觉得自己仿佛见过,想了一会儿想起来了,昨天刚刚见过,结合小伙子脸上的血,他有了不好的预感。
渡部也看到了盒子,也看到了小马仔一脸的血,他毫不掩饰地厌恶地皱了皱眉,匆匆把嘴里的食物咽下,起身拿了沙发上的帽子跟杜先生告辞,说是先走一步。杜问他要去哪里?他说,我不想待在这里了,我过一会儿还要去吃中饭。住外走了几步又回头对杜说,这么好的一个地方,我们都要爱护,你也要爱护,我明天还想继续来喝茶的,请你讲求风度,不要把这里弄得乱七八糟的,我谢谢你。杜说好的,不客气。渡部扭身看着北方客人,感叹道,我真搞不懂你们这帮人究竟在搞什么。说完快步走了。
杜让马仔过来收拾一下桌子,收拾好桌子后便把盒子拿了过来,放在北方客人眼前。他低头看看盒子,又抬头看向杜,但杜此时不再看他,盯着盒子仿佛陷入了沉思。良久才说,对不起了,不过我也知道她并不是你真正的太太,请你一定不要责备。
北方客人便打开盒子,真太太或假太太的断肢以及那只玉镯静静地躺在里面。他便立刻不再执着,在早已备好的纸上写下关人的地址。刚才进门的时候,他在门口的小桌子上就看到了纸笔,只是没想到是这么个用途。
中岛忍受不了日本乡下的拮据悲催,食不果腹,更不用说女人、繁衍之类。日子毫无希望,便拆了房子卖了地,倾其所有地请托外务省的一个同乡,终于得到这个名义上开拓商业实则筹备战争的人人艳羡的肥缺。当船渐渐靠近上海,他将万事抛诸脑后,翘首望去,感到自己的行情马上也要翘起来了。
顶着东亚银行筹备会社长的头衔,他通过法租界拜会了黄老板,黄此刻并不想理会这些纷乱,而且也信日本人不过,便把他推给了杜和张。来沪尚不足月,他便正襟危坐于杜的客厅,这一切于他可谓是志得意满。唯一的一点美中不足,就是身边始终跟着个池田少佐,说是保护,他知道人家才是真正做主的人。
杜本想让渡部来作陪,但渡部不来,“我是上海人,看见这些日本人肚皮疼。”还说这些来的日本人,没一个好东西,他们是要打仗,哪里有什么生意可谈,我看你最好也推辞不见。杜心知他说得对,只是黄老板交待下来,不能不见。见归见,事情谈不成就行。
与终日的游手好闲比较起来,渡部喜欢菊的厨房,他会安静地切一条鱼或摆弄一块豆腐,投入专注。弄好之后轻敲一下角落里的铃铛,小二便应声将食物端出去。有时他会抬头冷漠地扫一眼外面并不多的几个食客,即便是熟客,他也从不搭理。这些跑到上海来混事的日本人在渡部眼里,怎么看都是一脸穷酸的死相,要饭的一样。渡部垂下头,掩藏脸上不知道是深深的厌恶还是怒其不争的疲倦。
他擦了一头的汗,打开厨房后门,迈步出去。是一个小院,他点一支烟,深深吸上几口,静静地看着天空踱步。隔着墙不远便是黄浦江,他看着远处帆船的一角或是天空的晚霞,大好河山,心想,跟这里比起来,日本实在是又穷又小。
抽完烟回到厨房,他刚才做好了两份饭,拿了一份到院子里坐下来吃。刚吃一口,小黑就闻着味道过来了。这只黑色的野猫不知道从什么时候开始成了这里的常客,只要他一吃饭就出现。
你很准时嘛,他对猫说。猫就站起来,往他放着晚餐的小几上爬。他阻止它,好了好了,我去给你弄一点,但说好了,这是我的饭,你不可以吃我的。猫佯装着下来,安静了些地等他进屋,他一进屋就去吃他的饭。
每天都是如此,当他在厨房里给小黑弄完一些鱼骨头,抬头往外看时,猫又乖乖地站好等他。他把吃的端过去给它,自己也坐下来吃饭,日复一日。小黑便把这里当了家,直到民国三十年太平洋战争爆发前一直住在这里,有吃有喝。民国三十年以后它是什么情况就没有人知道了。
老五在上海无人不知,很早就跟了杜先生。一到晚上杜便迷恋她的花容月貌,天一亮又对她感觉隔阂。大概是感到她并不简单,所以即便终于把她从富春楼接了出来,也并没有带她回家住,而是在富民路上另置了一栋小楼给她。
侍候左右的还是在富春楼侍候过老五妈妈为她接生并把老五带大的张妈,张妈今天一开门就没有好脸色给他,哎哟哟,你可真是稀客啊。杜一看来者不善,也不理她,埋着头就往楼上走,没想到张妈不依不饶,跟在他身后,你肚子饿不饿呀,要不要我去烧一点点心给你吃吃呀?杜心想现在什么时间你问我肚子饿不饿?就在楼梯中间停下来,也是没有好气地说,刚刚吃过晚饭,现在这个点吃个什么点心?
张妈看着他脸上有怒气,更加得意,双手一拍,太好了,又省铜钿了不是。说完下楼扬长而去。杜上了楼就问老五,这个张妈,是不是又犯病了?一开门就阴阳怪气的。老五笑了笑,你不要理她,你们今天晚上请梅先生吃饭却不带上我,她在生气呢。
杜听着她话里有话,说,这么听着是她生气啊还是你生气?老五急忙快步过来帮他宽衣,一边解他的衣服一边说,是她啦,我不会生你的气。你放心,不管你做什么,我都绝不会生你的气。很多年后杜还会常常想起小五这句话,后悔自己当时并不相信她的真情。
温存到半夜,杜心里有事,也没了兴致,又睡不着觉,便执意要回家。老五虽感突然却只能从他,不知道为什么,一反常态地送他下楼出门。这是从来没有过的事,她站在原地看着他上了汽车,往静安寺的方向开去,不久就消失在夜色里。老五这才转身回家,张妈站在门口数落她,怎么跑下来了,你不知道我们的规矩是不送客的吗?
老五没有理她,她也不知道自己在想什么,或许真是女人的敏感。此处已是诀别。
杜先生心里的事大概就是转天日本人的来访。中岛和池田如约而来,杜带了张另加一个翻译陪坐,说的是开设东亚银行的事,日本人希望跟杜合开。杜本来周旋得还算客气,直到日本人说,“听说贵公子正在银行做事,正好可以为我们打理一切”。杜感到话里的威胁,脸色才难看起来。
再往下,张问了句,我们的股份能有多少?不等翻译说话,杜便抬手制止了。只说这件事我们决定不做,但我祝你们生意兴隆之后就起身送客了。张的问话却让池田少佐觉得自己捕捉到了机会。或许是天生凶残莽撞,或许是假装凶残莽撞,或许只是想提示一下中岛自己的角色有多重要,他便想杀杜扶张。
中岛一听就很喜欢,这种四处搅和毫无逻辑的杀人放火最能凸显新意,但杀杜事大,他需要厘清甚或更高层级的指示,总之需要想一想。之后他煞有介事地在闸北破败的日式宾馆污秽发霉的榻榻米上枯坐了一整天,然后跑到上海的大街上转悠,跑到澡堂子里泡澡,寻找灵感抑或指示,直到得出结论,杀也无妨。便递了帖子到杜宅请客,杜辞而不见。
再隔一天的清早,池田在大街上找了个穷得只剩把破刀的在上海几乎等同乞丐的浪人商量大计,想不到竟然一击即中,潜到杜宅里去,把个杜家上上下下的活宝,杜先生的心头肉王妈给杀死了。
王妈最近跟小张结了不大不小的仇。小张是大马路上西点房的小伙计,宁波人,十几岁的时候家里吃不上饭,便划个破船辗转到了上海,跟现在这个老板学生意。几年下来也算相安无事,总算是有一口饭吃。
老板家里有个漂亮女儿,大概是瞎了眼,或者是在被他用蛮力摸了几把之后蒙了心,竟表示愿意跟他好,连女儿她娘竟也在一边帮腔。老板五雷轰顶,心想真是作孽啊,几天没有关照,家里的女人怎么都变成了蠢货?便叫了小张过来问话,说你岁数也不小了,想讨个什么样的老婆啊?小张一听喜上心头,想真是功夫不负有心人,看来事情成了,脱胎换骨就在今日,要沉住最后这口气。他故作诚恳地说,要丑的没钱的。老板便说,好得很,我早知你是实在人,也知你早有此意,会好好帮你安排。当天就把厨房一个哑巴的女儿许了他,晚上就洞房,真的是又丑又没钱。
这样的滑稽热闹王妈怎么能错过?第二天小张又照着点来给她送点心,王妈一边给他开门,一边又是严肃又是关切地问,喂,你不是刚刚结了婚吗?怎么气色这么差,一张脸都是黑的,晚上不可以太激动哦,要注意身体啊。小张知道她存心故意,东西一放,钱都不要就跑掉了。王妈更是乐不可支,见人就取笑小张的事。
仇就这么结下了,她不喜欢小张,小张却差一点救了她。今天送点心来的是个陌生人,王妈走过去问,小张怎么没来呀,不会真的生我气了吧?说完正要笑,却听见门口停的人力车里有动静。小张被绑在里面,正在跳出来,向王妈报警。王妈便往屋里跑,可惜还是晚了一步,日本浪人一枪打在肚子上,怎么也止不住血,又伤及脏器,就这么死了。
杜去找黄老板,黄说日本人明显是要打仗,这个事我们解决不了,我们能算什么呢?但搞到你家里来这个事情要解决,他们不是要找你吃饭吗?去吃嘛,先解决王妈这件事。日本这些人什么事都做得出来,你自己定吃饭的地方,不要去虹口。
杜便定了去渡部的餐厅坐谈。渡部曾提醒他,他那里没有桌子,“你总不能跟他们一起坐个榻榻米”。杜觉得妹夫是日本人,对方应该会更放松,杀起来容易些,就打发人提前去摆了桌子,四把椅子。当天杜先生带了车夫和自己一起进去,渡部在厨房,其他人马则远远地隔了几个街口守着待命。
车夫在被王妈带着介绍给杜之前是个拉车的,后来也就一直叫他车夫,他拉车的时候偶尔帮着杀人,不肯收钱,说拉车是主业,偶尔帮着杀杀人是顺带着帮帮忙的事,不好算价钱。王妈觉得他奇怪又有趣,就介绍给了杜,从此一直跟随左右。所以这次的报复他便尤为急切,先是一枪打死了池田,中岛还击,他便护着杜往外走,中岛细心瞄准杜,正要一枪中的时,渡部从厨房开枪打中了中岛的腿。之后他扭头观望杜走出去没有时,中岛一枪打在他的心脏上,渡部就这样死在了厨房不算冰冷的瓷砖上。
这个因官司而来的房子,真是充满了诡异与不祥。
与此同时,杜先生的人马在街上被突袭了,不久知道是张做的手脚——他念及日本人承诺的所谓银行股票,大概也是因为自己对时局的分析,觉得日本胜面更大,总之是专注于利害的考虑——杜很伤心。
他原也意识到银行的事可能会让老二失落,计划是要把番禺路上的一个厂子送给他以做平衡的。当然这算不得什么,还有更伤心、更无法接受的事情——家里人都被杀了,儿子遭杀戮,胞妹亦亡,只是遍寻不到渡部的两个儿子。最后,在二楼杜用来抽鸦片的房间的榻里找到了,他们躲了进去,逃过一劫。杜连夜逃离,在法国公使的帮助下,清晨终于上了船,身边只剩下车夫及两个外甥。
船行至公海,便有小艇追来,由船上扔了绳子下去,小艇上一人登船,是黄老板的听差。无非送些钱来,并让杜安心,不必操心家人后事云云,再有就是老二躲到日本领馆去了,短时间是不会轻易出来的。杜问他老板可有意去香港避乱,说是没有,又问那你还回去吗?答道,老板没有说,急着出门,忘了交待他。杜便说那你先跟我一道去香港再说。听差略踌躇,说老板虽是没有交待,但大概还是回去的好,不然谁再给他烧烟呢?便仍是沿刚才的绳索,下到小艇上向上海驶去。
民国二十六年的上海,山雨欲来。
二
小六原本也是没落读书人家里的矜持小姐,碰到婚姻失败,几经流转,每况愈下,眼看就走投无路之际,却意外投了黄老板的好,搅和到黄老板一把年纪,也要赶时髦似的真跑去民政局正式登记离婚,正经事一般地娶了她回家。
可能还是因为没落吧,她自小的良好教育没有同样良好的经济来配合,便形成一种奇怪的人格,消受不起这样的富贵,或者确实并非俗物到了拼死也要追逐爱情的境界,又或者真像后来人们说的就是一个花痴,总之,她一天也没有消停过。
起先只是私下里跟小年轻们搞搞暧昧,拖拖小手亲亲嘴,包括黄老板本尊在内大家都可以佯装不知,很快就变本加厉地跑去跳舞厅里招摇。跳舞厅里人多嘴杂,就把事情搅成了面子问题,再也无法佯装不知,吃哑巴亏。
黄老板脸色一难看,杜先生只好亲自出马。因体恤老板的苦心,杜只能不断给小六好处,换取她的收敛。今天答应她南京路上一张广告牌子,明天又为她甚至去找戴先生商量,备了厚礼请吴小姐称病把原本定好的角色推掉,让给她,这才暂且消停下来。
黄老板带了小六到杜宅吃饭,说是庆祝她试镜成功,更是回报杜的一番努力——一大家的晚餐。小六跟老五坐在一起,小六问她,为什么都叫你老五呢?听着像男人。老五答我是富春楼里排行第五的跳舞的舞小姐,不叫老五叫什么?你听不习惯可以叫我五小姐。张先生带了个姨娘,也在一边起哄,只有渡部始终静静地吃喝,挂着浅浅的笑意。杜小姐抱着只有一岁的大儿子,肚子里装着小儿子,安静地坐在渡部旁边。
小六数落完白痴一般的导演,杜的儿子让她再谈一谈赵先生。小六又是不屑又是怨愤地说,还不认识,人家还没来上过班。他的戏要集中到最后一起拍的,人家是明星,讲派头的。大家又是笑,杜先生隔着饭桌看老六,突然生出别样的担心来。
很快就证实了杜的担心。赵先生头天上班之后就把小六带回了家,帮她拉汽车门,关门之前还体贴地帮她弄旗袍的下摆。小报记者一拍一写,第二天报纸一上街,杜又是愁容满面,悔不当初。
首先派人去砸了片场,抢回底片,在导演脸上随便比划几下。演的成分居多,也是为了明天的报纸。事后再私下慰问导演或是给钱重新另拍一部戏,反正都一样——这样总算找回半张脸面。既然全上海的人都在看着,最理想的当然是杀了小六和赵先生,可即便是要杀掉,总还是要谈谈。
小六满不在乎地来了,跟杜一起枯坐。杜愤慨地说,大家都是装新潮,赶时髦,只有你是个真花痴。小六说,连赵先生都说了,我是演员。杜说那你这次准备怎么收场呢?小六说,你去跟老板说说,放过我吧。杜一声叹息,你讲得倒是轻松。小六便也沉默,最后说,那我就去死吧,反正我也就是个行尸走肉,一具皮囊,什么花痴啊,十三点啊,打发打发时间罢了。
说完起身就走,走了两步又停下来,回头对着杜先生笑,说,你不会杀我的,你舍不得,你会给我想办法。说完就头也不回地走了。剩了杜一个人忧愁,心想,这倒底是个什么样的女人?
晚上渡部过来找他吸鸦片,看他一副要死不活的模样,劝慰他,杀就杀吧,奸夫淫妇的,不算冤枉,也不可惜。他瞪渡部一眼,穿鞋出门找老板。
黄老板就着咸菜喝白粥,不理他,他只好一旁枯坐。好容易老板问他吃不吃,他便自己拿了碗盛粥喝,好歹比傻坐着强。刚喝了一口,黄突然说,你要是这么犹豫就不要杀了。杜马上纠正,我可没有犹豫,你说杀就杀。黄瞪他一眼,放了碗筷,突然泄气般地说,算了,我说不要杀了,为这种事杀人不值得。不过,面子还是要找回来,他们两个都不能在上海了,送他们离开上海,越远越好,再不许回来,想活命就不要再回来。
杜心头的阴霾散去,又要装作平静,说那我让妹夫送他们去苏州,从苏州再坐火车往北走。黄点了点头算是同意,喝了两口粥又说,你悄悄给她点钱,让她将来好过日子。杜说好啊好啊,粥喝得畅快,又盛了一碗。黄瞪他一眼,他放下筷子,黄说,这件事情不许说出去,谁说出去我骂谁。杜说好啊好啊,又捧起碗把粥一饮而尽。
他们便一行四人上了路。渡部、小六、赵先生外加一个司机,开一辆蓝色雪佛兰轿车,穿过上海,驶入郊外雾气迷漫狭窄泥泞的马路,消失在黑暗里。等适应这黑暗后才看见头顶上方的一轮明月,那是民国二十三年上海的月光,很可能是最后一段花好月圆的时光。
小六的风流韵事引发的风波,无论最后导向何方,也丝毫不影响当下的消遣。电影改了名字,花数天补拍了赵先生和小六的镜头之后很快就上映了。居然故事清晰情感明确,这半遮半掩的旧事倒成了卖点,票房创了纪录。当和平再次降临,看电影又成时尚,这一纪录终被改写时,已经是五十年之后了。
三
关于老五的种种传说一直没有停止过,有时为了神化,有时为了诋毁,更多时候是一种伪装成同情的轻视。但她跟哪一方都有交道,富民路的小楼在战争时期为各方使用,常常同时住着水火不容的几个流派,同抽老五买来的香烟,同吃张妈做的饭,共用楼梯下的洗手间和澡盆。楼上楼下地辛苦工作,处心积虑地谋划怎么置对方于死地。
没有人知道老五究竟使了什么样的手段周旋其中才能够这样相安无事,也没人知道她这样做的目的。可能只是在杜先生离开上海之后本能地想要寻找依靠,而她深知哪一方都不一定靠得住,索性都靠着。或许这只是从前的职业本能,她把自小在富春楼练就的本领发挥到了极致,而这些传闻大概都是真的,因为戴先生的情报向来准确。
戴先生这一趟到香港,是应日本内阁绕开军部要求见面密谈的请求。戴知道见面不过是做做样子,反正他在香港还有私事,见他亲爱的吴小姐,不是这样的理由,按说他是无法脱身离开重庆的。
仗打到民国三十年,在大陆上一路高歌猛进的日本早已忘却战争的目的,连目标都失去的战争如何结束呢?没有能力结束的战争又怎么能发动呢?走投无路的日本人已经选择了疯狂到死,又心甘情愿地多半是出于故意去上了德国人的当,准备跟德国人对世界来个夹击,再大会师——打了这么一针新鲜鸡血,便真的准备蹦跶到太平洋上,找英美的茬去。
戴先生事先知道了这些情报——他应该是第一个知道这些情报的盟国的人,所以对日本的末路心知肚明,十分笃定。他知道此刻坐在面前的政客是日本人里稍微清醒的阁揆,即便他们可能也选择相信了德国人马上要在英国本土登陆的情报,但至少不认为这和自己有多少直接关系,更没有被所谓的“不要误了这趟班车”的奇思怪想左右。认识归认识,他们还是没有能力左右局面,所以戴在整个会面中只讲了一次话,他说,不打当然好啊,只要归还满洲在内的全部在华利益,战争赔偿,惩办战犯,我们是可以接受你们无条件投降的。
日本人愣在那里,戴看也懒得看他们一眼,低着头说,不同意是吧?那就继续打吧,我们才刚刚退到重庆,世界这么大,还可以再退,不管退到哪里我们也会再回来,上面几条一点都不会变。说完任日本人再说什么,只顾低头喝茶,日本人不得不告辞的时候他也没有哪怕抬一下眼皮。
日本人一走,他便和杜去山上散步。从山上望过去,海上英国人的军舰是那么小,或许真是不堪一击,但他相信美国人,就破译的日本海军电文来看,他是最早知道日本已行至尽头的人。
香港之行的私事是在散步中解决的。一是香港马上开打,杜要带吴小姐一起去重庆,二是老二的问题。张后来从领事馆出来,学着汪府人的样子也在长衫外套了件皮坎肩,在外滩剪完东亚银行成立的彩之后就坐车径直回家,从此再也没走出过自己的深宅大院半步,日常治安由伪军和日本宪兵共同维护。
但眼下机会来了,汪伪做事的出发点大概不甘寂寞的成分总是居多,仿照宋子文,也要搞税稽警队,委了张为队长。这下体面了,职务高到要去南京述职,不迈出院子一步是不行了。戴是在这时候提起的老五,无非是说,真要做的话,凭老五的本事,在上海他是可以帮到忙的。
晚上杜去找车夫,他正在厨房的小桌上就着几样小菜喝酒,杜便坐下来看着他喝酒。杜的意思,仗也打得差不多了,不久就能回上海,他还跑了不成?一起去重庆吧。车夫浅浅地抿一口酒,说重庆山多,热,又总是下雨,我们拉洋车的最讨厌这种地方,不去。他望杜一眼,说,本来我拉辆洋车,最远到个徐家汇,这些年,世面也见够了,重庆有戴先生照应你,你就让我回去吧。
两个外甥有些哭闹,一直送车夫上到船,风大雨大,更显出离意。杜站在后面看着他们,雨越下越大,在岸上很有肆虐一切的样子。海里便好得多了,海面上基本还算平静。
至于老五,不仅帮忙还亲自动了手最后搭了自己的性命进去则是戴和杜都不曾料及的。表面上张是坐汽车去南京,好几辆车趁着夜色开出来,老五却知道他只是佯装乘汽车,坐上一小段之后,其他车仍往南京方向开的时候张啸林已经悄悄到了北站,从那里上火车。
老五手持一张李士群亲自批注的通行证,提早在南站上了火车,大摇大摆地坐进一等座,只等张上车。只有皮包里的小手枪当然不够,她起身去车箱的连接处抽烟,不动声色地从袖子里取出火车上的钥匙,打开了靠铁轨里侧车门的锁。大概不常开或从不开,她费了大力,弄断了自己新涂的一只指甲。锁终于开了,她伸手确认了一次。
计划简单、蛮横,容易成功却绝无后路——等张低调地上车后,一定会看见面冲门坐着的老五,四目相对,他肯定转头跑,老五就取皮包里的枪射他。他的保镖皆会去攻击老五,而他会继续往外跑,直至下车。此前一直潜伏在北站铁轨上的车夫会经由老五开锁的门上车,从身后射张。
实际发生的与计划没什么差别,三个老相识死在了一起。只有老五迅速打光了子弹,但几乎没有命中任何人,无论张还是他的保镖——或许她太在意断掉的那一处指甲,分了心。但对于计划或结果而言,这已经无关紧要了。
在日本突袭香港前一小时,杜带着外甥与吴小姐一起由戴的副官带路,登上了民国三十年最后一架由香港飞往重庆的客机。虽然已时隔七年,杜仍为先前电影角色及后续的事感到难为情,两人匆匆打过招呼之后,杜便低头不语。
吴小姐揉着自己的膝盖骨,说,哎呀,早知如此,当初在上海就应该好好玩耍,每天咖啡喝喝,跳舞厅泡泡,家里睡睡觉,傻子才去拍什么电影,吃力死了又没人看,恐怕底片也找不到了。真是后悔死了,杜先生,你说是不是?
吴睁圆了眼,满脸殷切地望着杜。谢谢吴小姐,谢谢吴小姐你这么说。吴却早已望向两个外甥,哎呀,我带了东西给你们。客机在坑洼不平的跑道上腾空而起,杜望向窗外,海面竟出奇的平静。
杜先生在重庆常常住在杨家山的公馆。已是民国三十四年夏天,戴先生比从前更忙碌,此时他已经知道美国人在太平洋的某个僻静角落里试验了新式炸弹,相信战争会比想象中结束得更快。
战争本是常态,打得久了,早已应付自如,现在突然要结束却真是难以适从。短期要做的事情太多,新的问题已经出现,俄国人在北边聚集就是很麻烦的事。或许还有更麻烦的,明天他要到河北去。
没有等到他回来,美国人就扔出了两颗炸弹,手里还备了一颗预备着炸东京。可能是消息走漏了,也可能是广岛的情况太惨烈,日本人至此终于清醒。蒋先生去电台演讲,正义必将战胜强权的真理,得到了他最后的证明。
杜先生和吴小姐以及两个外甥正在吃午餐,突然就胜利了,看来新的生活就在眼前,不久或许就可以回上海去了——人就多出许多感慨。
吴小姐说,我想起来,第一次见杜先生的时候,也是这样面对面地坐着。杜说,是啊,见面说的话我都还记得。吴笑而不语。杜说,对不起对不起,不说电影。吴小姐放下筷子,说再在重庆待下去,我也快要饿死了,样样东西都好难吃。大概是不喜欢这个地方,所以就不喜欢吃这里的东西,喜欢上海,所以爱吃上海菜,大概是喜欢什么地方就会喜欢吃哪里的菜。
杜先生听着她说完,却突然想起了饭桌上这两个外甥的父亲来,想起那个因官司而来的不吉祥的房子。
四
我前面说,杜小姐至死也没有搬出杜宅,这是事实。她在民国二十六年的那个晚上死在了杜宅。我还说,富春楼的规矩是从不送客,老五却一反常态地一直送杜上了车,大概是女人的敏感——这也是事实,那里就是诀别。老五当时的心情比我们现在了解的还要再复杂一点,这是后话。
还有什么呢。是的,那只黑猫。我说,从此它便把这里当做了家,直到民国三十年前一直住在这里,有吃有喝。渡部在民国二十六年死在了餐厅厨房不算冰冷的瓷砖上,那接下来的四年它吃喝什么呢?
民国二十三年的上海,他们一行四人上了路。渡部、小六、赵先生外加一个司机,开一辆蓝色雪佛兰轿车,穿过上海,驶入郊外雾气迷漫狭窄泥泞的马路,消失在黑暗里。车开到半路,渡部让司机停车,开两枪打死了赵先生和司机,之后在车上强奸了小六。
几番犹豫,他没有杀她,把她带回菊餐厅,扔到地下室之后,回家一个人坐在桌前吃早饭。怀着一个抱着一个的杜小姐后来也来了,杜先生也来了,他们吃着早饭谈着话,生活看起来和之前没什么不一样。
只是他每天都做两份饭,自己吃一份,猫来找他,他喂完猫,吃完饭,便端着另一份饭去地下密室喂小六。吃完就是操,操完还要吃,日复一日。
现在我们知道,对餐厅的那些日本食客,渡部脸上是怒其不争的疲倦而不是真正的厌恶,中岛在上海大街上假装寻找的也不是什么启示而只是渡部的指示。
杀吧,他在澡堂子里同意了中岛的意见,他在规划决定着一切。民国二十六年去菊餐厅决战之前的那个下午,他或许想过要放弃,就在杜宅门口的路上,一手抱着两个儿子,另一手抱起杜小姐,开始往外奔跑,越跑越远,仿佛要逃离一切。不久他放弃了,他们太重了,他不得不放他们到地上。他大口喘着气,放弃了放弃的想法。
帝国军人的概念像一道咒语般压迫他,尽管他也知道历史进程其实早已注定,跟他没有关系,但他必须贡献自己微观的努力。既然他微观的努力也注定在历史之中,那么他将用今晚的事,洗刷哪怕是只有他自己知道的内心闪过的放弃的耻辱,并获得重生。
或许是舍不得儿子或许是别的原因,他最终开枪打了中岛的腿,放走了杜。他佯装死亡,为了新的任务新的战场。
那只黑猫,那只黑猫在菊的后院住到了民国三十年,有吃有喝——渡部和小六一直喂养着它。
这一年他去了南亚,去了菲律宾。他本想掐死小六,最后一刻放弃了。小六回到地面上之后,是一个她已经认不出来的上海了。
小黑之后的去向没人知道。
民国三十四年,杜终于在上海找到小六,久别重逢,一切都变了,但故人总是让人信任。
渡部被关在吕宋岛的盟军战俘营,杜带了人去找,拿两根金条买通了管理战俘营的澳大利亚军官,军官同意帮忙,但强调不能在营地里面杀,渡部必须自己签字同意引渡。
为了逼渡部出来,杜杀了他的大儿子,自己亲手带大的外甥。渡部为保住小儿子自愿从战俘营出来——小六开枪打死了他,最后的日本鬼子倒下了。正义必将战胜强权的真理,得到了他最后的证明。
回到上海,杜先生去见了黄老板,才知道老五在他去香港后给他生过一个儿子——老五送他下楼那天知道自己怀孕了,但没来得及说。张妈照看着儿子,仍住在富民路的小楼。
老五死前来找过黄老板,留了话,说无论发生什么事,希望杜能带儿子到香港去。杜便找到富民路,儿子却并不认他,张妈也对他出言不逊,杜只好说是他娘死前交待的,让我一定要带他去香港。张妈不依不饶,说,你呢,是个流氓,他娘呢,是个妓女,现在时代变了,你们俩的话他都不要听。说完就把杜关在门外。
他一直拖到一九四九年五月初才坐上去香港的轮船,算得上真正的末班车。没人知道他在拖什么或等什么,我想他自己也未必知道,不过是下意识的拖延。不久他就死在了香港,死前再没有值得记述的事或说过的话。他基本没再说话,这没什么可奇怪的,一切都不值一提,他
[[雷蒙德·卡佛]]作品精选 没人说一句话_在线阅读
======================
作者:雷蒙德?卡佛
翻译:小二
-----
## 没人说一句话
我能听见他们在厨房里说话。我听不清楚他们说的是什么,但他们在吵。过了会儿,争吵声没有了,她哭了起来。我用胳膊捅了捅乔治。我以为他会醒来,对他们说点什么,好让他们觉得内疚而停下来。但乔治就是这么一个浑球,他开始又踢又叫。
“别捅我,你这个狗娘养的,”他说。“我告你的状去!”
“你这个笨狗屎,”我说。“就不能聪明一回?他们在吵架,妈在哭。你听听。”
他把头从枕头上抬起来听了一会儿。“我才不管呢,”他说完转过身去,面朝墙接着睡他的觉。乔治是天底下最大的浑球。
后来,我听见爸爸离开家去赶公车,出门时使劲摔了一下前门。她曾告诉我说他想把这个家给拆了。我不想听这个。
过了一会儿,她进来叫我们去上学。她的声音听上去有点古怪,我也说不清楚。我说我肚子不舒服。已经是十月的第一周了,我连一次课还没旷过呢,她能说什么?她看着我,但似乎在想别的东西。乔治醒了,在听。我从他在床上的动作就知道他醒着。他在等着事态的发展,好决定下一步该干什么。
“好吧。”她摇了摇头。“我真不知道该怎么办。那就呆在家里吧。但不许看电视,记住了。”
乔治一下子跳了起来。“我也病了,”他对她说。“我头疼。他整夜都在捅我踢我,我一夜都没睡。”
“够了!”她说。“乔治,你得上学去!不许你呆在这儿,整天和你哥打架。现在就起床穿衣服。我说话是算数的。今天早上我不想再干一仗了。”
乔治等她离开房间后,才从床脚处爬出来。“狗娘养的,”他说,一下子把我盖的都掀开了。他躲进了卫生间。
“我会宰了你,”为了不让她听见,我压低声音说。
我在床上一直呆到乔治上了学。当她准备去上班时,我说我想学习,让她为我在沙发上铺个床。茶几上放着埃德加?莱思?布劳夫斯【注一】的书,是我的生日礼物,还有我的社会学课本。我不想看书,希望她快点离开,我好看电视。
她在冲抽水马桶。
我等不急了。我打开电视,把声音关掉。我去厨房她放大麻烟盒的地方,从烟盒里抖出三根来,把它们放在碗碟柜里,然后回到沙发上,开始读《火星公主》。她从房间里出来,瞟了一眼电视,但什么也没说。我的书是打开着的。她在镜子前拢了拢头发,进了厨房。她出来时,我忙低下头看书。
“我要迟到了。再见,甜心。”她没提看电视这件事。昨晚她曾说过,要不是自己给自己打气的话,她真是一点上班的心情也没有。
“什么都别烧,你没必要开炉子煮东西。饿了的话,冰箱里有金枪鱼。”她看着我。“但你要是肚子不舒服的话,最好什么都别往里放。不管怎么说,你都不需要点炉子。听见没有?吃点药,甜心,希望你的肚子到了晚上就好了。也许今晚我们都会觉得好些了。”
她站在门廊那儿,转着门把手。她看上去像是要说点其它的什么。她穿着白色的衬衫、黑色的宽腰带和黑色的裙子。有时她称这为她的套装,有时又说是她的工作服。打我记事起,这套衣服不是挂在壁橱里,就是挂在晾衣绳上,要不就是在晚上被手洗,或在厨房里被烫平。
她从星期三工作到星期天。
“再见,妈。”
我等着她发动车子,让车子预热。听见她开走后,我爬了起来,把电视声音开大,就去取大麻。我抽了一根,一边看一个与医生护士有关的电视剧,一边手淫。稍后,我换了一通频道,就把电视关了。我没了看下去的心情。
我读完塔斯?塔卡斯【注二】爱上一个绿色的女人、结果亲眼看到她第二天被那个嫉妒的姐夫砍掉脑袋这一章。这大概是我第五次读这一章了。而后,我进了他们的卧室查看。除了避孕套,我并没想着要专门去找什么,我曾经到处翻了个遍,也没找到过一个。有一次,我在一个抽屉靠里面的地方发现一罐凡士林。我知道它肯定和那件事有关,但我不知道是什么样的关系。我研究了一番标签,希望从中看出点什么,比如是干什么用的,或怎样使用这一类的描述。但是没有。前面标签上仅有这几个字――纯凡士林。但看了这几个字已足以让你硬了起来。极好的幼儿园救助用品,背面的标签是这样说的。我试图找出幼儿园(秋千、滑梯、沙箱、悬空梯)和他们在床上做的事之间的联系。我曾多次打开这个罐子,闻闻里面的味道,看被用掉了多少。这次,我没有碰它。我是说我只是看了看它是不是还在那儿放着。我翻了几个抽屉,也没指望找到什么。看了看床底下,什么都没有。我看了眼壁橱里面放零用钱的罐子。里面只有张五块的和一张一块的,没有零头。拿了的话,他们肯定会发现。过后,我觉得我该穿上衣服,走着去桦树溪。鳟鱼季节还剩下一周多,但几乎所有的人都不再去钓鱼了。大家都在等着猎鹿和打野鸡季节的到来。
我找出我的旧衣服,把羊毛袜子套在我平时穿的袜子的外面,仔细地给靴子穿上鞋带。我做了几个金枪鱼三明治和双层的、夹了花生酱的饼干。我给军用水壶灌满水,把它和猎刀一起挂在腰带上。出门时,我决定留张纸条。我写道:“好多了,去桦树溪。很快回来。雷。3:15。”那是四个小时以后的时间、离乔治从学校回来的时间大约有十五分钟。离家前,我吃了一个三明治,又喝了一杯牛奶。
外面天气很好。虽然是秋天,但除了夜里,并不冷。夜里,人们会在果园里点上熏烟罐,早晨起来,你的鼻子上会有一圈黑色。但没人说什么。熏烟是为了防止没长大的梨子给冻坏了,这样就没事了。
去桦树溪,你得走到我家门前这条路的尽头。在它和十六街相交的地方,左拐上十六街,爬到坡顶,过了那片墓地后,下坡到雷尼克斯,那儿有家中国餐馆。从那个十字路口,你可以看到机场,桦树溪就在机场下面。十六街在十字路口变成景观路。你沿着景观路走一会儿,就会遇见一座桥。路的两旁都是果园。路过果园时,有时你能看见野鸡沿着田垄奔跑,但你不能在那儿打猎,因为一个叫马苏斯的希腊人可能会给你一枪。我估计走路的话,整个路程大约要花四十来分钟。
我在十六街上刚走到一半,一个开着红色汽车的女人在我前方的路边停了下来。她摇下乘客那边的窗子,问我是否要搭车。她瘦瘦的,嘴边长着些小个的青春痘,头发被发卷卷了上去。但她的穿着还是够时髦的。她穿着件棕色的毛衣,里面的xx子看上去很不错。
“逃学呢?”
“我猜是。”
“要搭车吗?”
我点点头。
“快进来。我还有急事。”
我把飞蝇竿【注三】和柳条鱼篓放到后座上。后座和地板上放了很多梅尔店的购物袋。我想找点话说说。
“我去钓鱼,”我说。我脱掉帽子,把水壶转到身前,靠着窗口坐了下来。
“哇,你不说我肯定猜不出来。”她笑着说。她把车开上路。“去哪儿?桦树溪?”
我又点了下头。我看着我的帽子。这是我叔叔上次去西雅图看冰球赛时给我买的。我实在想不出能再说点什么。我吸着腮帮子看着窗外。你总在设想被这么个女人选中。你肯定你俩会为对方发狂,她会把你带回家,让你和她疯狂地做爱。想到这我不由地硬了起来。我把帽子移到我的膝盖处,闭上眼,努力去想棒球的事。
“我总说有一天我会去钓鱼的,”她说。“都说它能让人放松。我是个紧张西西的人。”
我睁开眼。我们停在了十字路口。我想说,你真的很忙吗?你想从今天早上开始吗?但我不敢看她。
“这儿行吗?我得转弯了。对不起,我今天早上有点急事。”
“没事,这就可以了。”我把我的东西拿了出来。我戴上帽子,说话时,又把它脱了下来。
“谢谢。再见了。也许明年夏天,”但我没能把话说完。
“你是说钓鱼?没问题。”她像其他女人那样,冲我晃了晃几根手指头,
我开始往前走,想着刚才该说而没说的话。我现在能想出许多来了。我当时是怎么了?我用飞蝇杆抽打着空气,又使劲吼了两、三声。其实我该这样开头,先邀请她一起吃午饭。我家里一个人也没有。一下子,我们就在我房间的被单下躺着了。她问我是否可以不脱毛衣,我说我不介意。她也不想脱裤子。那也没关系,我说。我不在乎。
一架正在降落的私人小飞机低飞过我的头顶。离桥只有几步远了,我能听见流水的声音。我飞快地冲下堤坝,拉开裤子拉链,冲着溪水尿出五尺多远。这肯定创了个记录。我慢慢地吃着三明治和夹了花生酱的饼干,把水壶里的水喝掉了一半。我准备就绪了。
我琢磨着该从哪儿开始。自从我们搬来后,我已在这儿钓了三年鱼了。爸爸过去常开车带我和乔治来。他在一旁抽着烟等我们,给钩子穿上鱼饵,接上被我们弄断的鱼线。我们总是从桥那边开始,然后往下游走,每次我们都能钓到几条。鱼季刚开始时,会有那么一、两次,我们能钓到允许的上限【注四】。我理好线,先在桥下甩了几杆。
我有时在岸边,要不就在一个大石头的后面甩杆。但什么都没钓到。有一个地方的水纹丝不动,水底铺满黄色的叶子。我从上面看下去,见几只小龙虾举着它们难看的大钳子,在那儿爬来爬去。鹌鹑从灌木丛里飞出来。我扔了根树棍子,一只公野鸡从十尺远的地方咯咯的叫着跳了出来,吓得我差点把鱼竿给丢了。
小溪的水流不急,也不太宽,几乎走到哪儿溪水都不会漫进我的靴子。我穿过一个到处都是牛粪的草地,来到一个出水的大管子跟前。我知道管子下方有个小坑,所以很小心。到了可以垂勾的地方后,我跪了下来。鱼钩刚碰到水面就被咬了,但我还是让它给跑了。我感到它带着钩子打了几个滚,然后就挣脱了,鱼线反弹了回来。我重新装了一个三纹鱼蛋,又试着甩了几杆。但我知道我已经触了霉头了。
我登上堤坝,从一个柱子上钉着“禁止入内”牌子的栅栏下面爬了进去。机场的一条跑道从这里开始。我停下来查看一些从路面裂缝里长出来的野花。你可以看到轮胎接触跑道的地方,以及留在花上面的油腻的滑痕。我从另一侧下到小溪,一边钓一边往前走,直到来到水潭跟前。我不想再往前走了。三年前我第一次来这儿钓鱼时,溪水就在堤坝顶端下方一点的地方翻腾,水流急得根本没法钓鱼。现在的水面比堤坝低了六尺。溪水翻着浪花,沿着深不见底的水潭顶部的一条细小的溪流往前流去。再过去一点,小溪的底部开始往上升,水又变浅了,就像什么都没有发生一样。上次来的时候,我钓到两条大约十寸长的鱼,一条看上去两倍那么大的鱼却给溜了(那是条硬头鳟,我爸在听了我的描述后告诉我说)。他说它们在早春涨水的时候来这,但多数不等水位降下来就又游回河里了。
我往鱼线上加了两个坠子,用牙齿把它们咬合。然后,我装了个新鲜的三纹鱼蛋,把它抛向浅滩,水流经过那里流向水潭。我让水流把它带下去。我能感到坠子在岩石上面轻轻叩碰,这和鱼上勾时的抖动不一样。鱼线绷紧了,水流在水塘的尽头把鱼蛋带出水面。
走了这么远却什么也没钓到,让我觉得窝火。我把鱼线都扯了出来,又甩了一杆。我把杆子靠在一根树杈上,点着了倒数第二根大麻。我抬头看着峡谷,开始想那个女人。因为她要我帮她搬食品和杂货,我们去了她家。她丈夫在国外。我摸着她,她颤抖起来。我们在沙发上法式接吻时,她说她要去卫生间。我跟在她后面,看她褪下裤子,坐在马桶上。我已经硬得不行了,她招手让我过去。正当我要拉开裤拉链时,听见小溪里传来“噗咚”一声。我抬头一看,就见我鱼竿的尾部在那儿晃个不停。
它不是特别的大,也不怎么挣扎。但我还是遛了它好一会儿。它侧着身,在下方的溪水里躺着。我不知道它是什么鱼。它看上去很奇特。我收紧线,把它拎到岸边的草地上,它在那儿扭动起来。它是条鳟鱼。但它是绿色的。我从来没见过这样的鱼,它的两侧是绿色的,夹着黑色的鳟鱼斑点,稍带绿色的头,和像是绿色的肚子。它的绿是种苔藓的绿。就好像它被苔藓裹了很久,苔藓的颜色都掉在它的身上了。它很肥,我奇怪刚才它为什么不使劲挣扎。我怀疑它是不是有病。我又研究了它一会,就结束了它的痛苦。
我拔了几把草放在鱼篓里,把它放在草上面。
我又甩了好几次杆,估计肯定有两、三点了。我觉得我该往桥那边走了。我想回家前在桥下再钓一会儿。我决定等到夜里再去想那个女人。但想着夜里将会来临的“硬”,让我现在就硬了起来。而后,我觉得我不应该老这么做。大约一个月前,一个没人的周六,我手淫后马上抓起本圣经,对着它赌咒发誓说我再也不做这件事了。但我把精液粘在圣经上了,我的赌咒发誓只持续了一、两天,就又一切如故了。
往回走的路上我没有钓鱼。我走到桥下时,看见草地里有辆自行车。我四下看了看,见一个和乔治差不多大的小孩正沿河岸往下跑。我向他走去。他转了个弯,向我走过来,眼睛却盯着河水看。
“嗨,干吗呢?”我喊道。“出什么事了?”我猜他没听见我。我看见他的鱼竿和钓鱼袋都在岸上放着,我丢下我的东西,向他跑过去。他看上去像只耗子,我的意思是他长着龅牙,胳膊细细的,那件破旧的长袖衫对他来说,实在是小了点。
“天哪,我发誓这是我见到过的最大的一条鱼!”他大喊大叫道。“快点!看!看这!它在这!”
我向他指的地方看去,心跳噌的一下子就上去了。
它有我的胳膊那么长。
“天哪,哦,天哪,你看啊!”男孩说。
我盯着它看,它在一个伸到水面的树枝的阴影下面歇着。“全能的上帝啊,”我对着鱼说道,“你是从哪儿来的呀?”
“我们该怎么办?”男孩说。“我真该带着我的枪。”
“我们去捉住它,”我说。“天哪,你看!我们把它弄到浅滩上去。”
“那你愿意帮我?我们一起干!”小孩说。
大鱼已顺着水流往下漂流了一点,它在清澈的溪水里不慌不忙地摆着尾巴。
“OK,我们怎么弄?”男孩说。
“我可以到上游去,沿着小溪往下走,把它往下赶,”我说。“你在浅滩那儿等着,它想从那儿通过时,你把它的屎给我踢出来。我不管你怎么弄,你给我把它弄到岸上来。然后,抓牢它,别撒手。”
“OK,我操,你看它!看,它动起来了!它想往哪儿游?”男孩尖叫道。
我注意到鱼又开始往上游游,并在靠岸的地方停了下来。“它哪儿也去不了了,他已无处可逃了。看见没有?它吓得屎都拉不出来啦。它知道我们在这儿。它在转悠,想找个出口。看,它又停下来了。它哪儿都去不了。它自己知道。它知道我们会逮着它。它知道快完蛋了。我上去把它往下赶。它过来时你抓住它。“
“我真希望我带着我的枪,”男孩说。“对付它肯定绰绰有余,”男孩说。
我往上游走了点,然后趟着溪水往下走。我一边走一边注视着前方。突然,鱼一下子从岸边窜开,在我面前转了个身,激起一片水花,飞快地向下游冲去。
“它过来了!”我喊道。“嗨,嗨,它过来了!”但鱼在到达浅滩前,转了个身往回游。我一边拍打水一面大声叫喊,它又转了回去。“它过来了!抓住它,抓住它!它过来了!”
但那个蠢货找了根树棍子,这狗日的,鱼游上浅滩后,男孩用根棍子来驱赶它,而不是像他该做的那样,把这个婊子养的踢死。鱼变得疯狂起来,它转了个向,侧着身子,一下子就窜过浅水滩。它逃掉了。这傻X朝它扑过去,摔了个正着。
他浑身透湿地爬上岸。“我打着它了!”男孩大声喊道。“它肯定受伤了。我已经抓住它了,但没抓牢。”
“你什么也没抓住!”我喘不过气来。我很开心他摔到溪里。“还差老大一截子呢,狗日的。你拿着那根棍子干吗?你应该踢它。它现在早跑出十万八千里了。”我想吐口水。我摇了摇头。“我不知道。我们还没逮到它。我们很可能逮不到它了,”我说。
“该死的,我打着它了!”男孩尖叫道。“你没看见?我打着它了,我的手已经碰着它了。你离它有多远?另外,到底是谁的鱼?”他看着我。水顺着他的裤子流到他的鞋子上。
我没再说什么,但还是想了想那个问题。我耸耸肩。“好吧,我觉得应该是我们俩的鱼。这次要抓住它。谁都别犯臭,”我说。
我们向下游涉去。我的靴子里进了水,但这孩子从头湿到了脚。他用他的龅牙咬住嘴唇,不让牙齿打战。
鱼不在浅滩下面的水流里,在我们能看得见的地方也见不着它。我们互相看了看,担心鱼往下游游了足够远,已游进某一个深潭里了。但就在这时,这该死的家伙在靠岸的地方上下翻腾起来,它的尾巴甚至把泥土都带到水里,并又游走了。它游过另一个浅滩,大尾巴露在水的外面。我见它在靠岸的地方慢慢地游着并停了下来,尾巴有一半露出水面,轻微地摆动着用以抵挡逆流。
“你看见它没有?”我说。男孩四下张望。我抓住他的胳膊,用他的手指指着。“就在那儿。好,现在听好了。我会去河岸中间的那条小溪。知道我说的地方吗?你在这儿等着我给你发信号。然后你往下游走。好不好?这次,如果它掉头的话,你千万不能让它从你身边溜掉。”
“好,”男孩说,用龅牙啃着他的嘴唇。“这次一定抓住它,”男孩说,一脸被冻坏的样子。
我上了岸,放轻脚步,向下游走去。我再从岸上滑到水里,涉着溪水往前走。但我不见着这个庞大的婊子养的,我有点紧张。我觉得它很可能已经跑掉了。再往下游去一点,它就会游进其中的一个水潭。那我们就再也逮不着它了。
“它还在那儿?”我喊道。我屏住气。
小孩挥了挥手。
“预备!”我又喊道。
“开始!”小孩叫喊着回应。
我的双手抖个不停。溪水大概有三尺宽,两旁是土岸。溪水虽浅,但水流很急。小孩向下游走来,水漫到他的膝盖处,他向前扔着石块,一边拍打溪水一边叫喊。
“它过来了!”小孩摆动他的胳膊。我看见这条鱼了;它径直冲我游来。看见我后它想掉头,但来不及了。我跪下来,在冷水里摆好姿势。我用胳膊和手把它一下子舀了起来,抱着它站起身来,把它从水里扔了出去,我和它一起摔倒在岸上。我抱着它紧贴我的衬衫,它在那儿乱扭乱跳,直到我的手沿着它滑溜的身体移到它的两鳃。我把一只手从鱼鳃捅进去,一直捅它的嘴里,从下巴那儿把它给卡住。我知道我终于制服它了。它还在不停地扑腾,非常的不好抓。但我抓牢了它,我不会让它逃脱的。
“我们逮着它了!”男孩一边泼着溪水一边叫喊。“天助我们,我们逮着它了!它可真不一般!你看它!哦,天哪,让我拿着它,”男孩大声喊道。
“我们得先把它杀死,”我说。我用另一只手卡住它的脖子。我用尽全力把它的头往后扳,小心提防着被牙齿划着,感到了鱼身发出的嘎吱声。它慢慢地抖动了很长一段时间后,就不动了。我把它放在地上,我们研究起它来。它至少有两尺长,出奇的瘦,但比我钓到过的任何鱼都要大。我又抓住它的颚。
“嗨,”小孩说,但他弄明白我的意图后,就没再说什么。我把血洗掉后,把鱼放回了原处。
“我太想拿给我爸看了,”小孩说。
我们浑身湿透,打着抖。我们看着鱼,不时地碰它一下。我们撬开它的大嘴,触摸它的牙齿。它的两侧都有伤疤,发白的伤口有二十五美分硬币那么大,泡泡的。头上靠嘴和眼睛的地方有刻划的痕迹,我猜这是跟石头碰撞和打架造成的。但它真是瘦,瘦得和它的长度太不相称了,你几乎看不出它侧面的粉色条纹,它的肚子灰白松弛,而不是像应该的那样又白又鼓。但我觉得它还是很可以。
“我想我该走了,”我说。我看了眼远处山头的云彩,太阳正从那儿往下落。“我得回家了。”
“我想也是。我也一样。我冻死了,”小孩说。“嗨,我要拿着它,”小孩说。
“我们去找根棍子,从鱼嘴那里穿过去,我俩抬着它,”我说。
男孩找来一根树棍。我们把它从鱼腮那里往里穿,一直穿到鱼在棍子的正中间。而后,我们一人拿住一端往回走,看着鱼在棍子上来回晃动。
“我们拿它怎么办?”小孩说。
“我不知道,”我说。“我想是我逮住的,”我说。
“是我们俩。另外,是我先看见它的。”
“那倒是,”我说。“好吧,你想扔硬币来决定还是怎么着?”我用空着的手摸了摸,但身上一分钱也没有。而且,如果我输了的话怎么办?
不过小孩说,“不,不扔。”
我说,“好吧,我无所谓。”我看了看男孩,他的头发立着,嘴唇发紫。必要的话我制服他应该不成问题。但我不想打架。
我们来到我们放东西的地方,用一只手把那些东西捡起来,谁都不松开拿棍子的手。我们走到他放自行车的地方。我抓牢棍子,防止他玩什么花样。
就在这是,我想起了个办法。“我们可以把它切成两半,”我说。
“你什么意思?”男孩说,他的牙齿又打起战来。我能感到他抓紧了树干。
“切开它。我有把刀。我们把它切开,一人拿一半。我不知道,我觉得我们可以这样做。”
他揪着他的一缕头发,看着鱼。“就用那把刀?”
“你有刀吗?”我说。男孩摇了摇头。
“就是,”我说。
我抽出树干,把鱼放在男孩自行车旁边的草地上。我拔出刀来。在我比划着该从哪儿切时,一架飞机在跑道上滑过。“这儿?”我说。男孩点了点头。飞机在跑道上轰鸣,从我们的头顶上腾空而起。我开始切鱼,见到内脏后,我把它翻了个个,把里面所有的东西都扒了出来。我不停地切着,直到还剩下肚子上的一块皮连着它。我用手抓住两边,把它撕成了两半。
我递给小孩尾巴那部分。
“不干,”他说,摇着他的头。“我要那一半。”
我说,“这两个一模一样!该死的,你看着,我马上就要发火了。”
“我不管,”男孩说。“既然它们都一样,我就要那个。反正它们都一样,是不是?”
“它们是一样的,”我说。“但我要这半个,鱼是我切的。”
“我要这个,”小孩说。“我先看见它的。”
“用的是谁的刀?”我说。
“我不要尾巴,”小孩说。
我四处看了看。路上没有车,也没有人在钓鱼。有架飞机在嗡嗡作声,太阳正在落山。我全身发冷。小孩抖的很厉害,他在等着。
“我有个主意,”我说。我打开鱼篓,给他看那条鳟鱼。“看见没有?是条绿色的。这是我见过的唯一一条绿色的鱼。不管谁拿头那一半,另一个就拿尾巴和绿色的鳟鱼。这公平吗?”
小孩看了看绿色的鳟鱼,把它从鱼篓里取出来,抓在手里。他研究着那两个半条的鱼。
“只好这样了,”他说。“OK,那就这样吧。你拿那一半,我的肉比你的多。”
“我才不管呢,”我说。“我去把它洗干净。你住在哪儿?”我说。
“亚瑟路那边”他把绿色的鳟鱼和他的那一半鱼放进了一个脏乎乎的帆布包里。
“问这干吗?”
“那在哪儿?是靠近球场那儿吗?”我说。
“是的,问这干什么,我说。”那小孩看上去很害怕。
“我住的离那儿不远,”我说。“我想我可以坐在车把上。我们俩可以轮流踏车。我有根大麻烟,如果还没被弄湿的话,我们可以抽。”
但这个小孩只在那儿说,“我冻死了。”
我去小溪里洗我那半条鱼。我把它巨大的头按在水里,扒开它的嘴。水流流进它的嘴里,从它身子剩下的部分流了出来。
“我快冻死了,”小孩说。
我看到乔治在街道另一端骑着车。他没看见我。我绕到房子的后面去脱掉我的靴子。我解开鱼篓,这样的话,我就可以打开鱼篓的盖子,面带笑容地正步走进家。
我听见他们的声音,透过窗户往里看了看。他们坐在桌旁,厨房里到处是烟。我看见烟是从炉子上的一口平锅里冒出来的。但他们谁都没注意到。
“我对你讲的都是千真万确的,”他说。“孩子们知道什么?你等着瞧吧。”
她说,“我什么都不用瞧,如果我那么想的话,我情愿等他们先死了。”
他说,“你怎么了?你最好小心点你说的话!”
她开始哭泣。他把烟在烟缸里使劲按灭,站了起来。
“埃德娜,你知道这口锅烧起来了吗?”他说。
她看了眼锅,把椅子往后一推,一把抓住锅的把手,一下子就把锅给摔到水池上方的墙上。
他说,“你昏了头了吗?看看你都干了些啥!”他拿起一块抹布,开始把锅上的东西往下擦。
我打开后门。我开始裂开嘴笑。我说,“你们肯定不信我在桦树溪钓到了什么。看吧。看这里。看这个。看我钓到什么了。”
我的腿在打抖,几乎都站不稳了。我把鱼篓送到她面前,她终于往里看了看。“噢,噢,我的天哪!这是什么?一条蛇!这是什么?快,快拿出去,别等我吐出来。”
“拿出去!”他尖声叫道。“没听见她说的?把它从这里拿出去!”他叫喊着。
我说,“但是,爸,你看看这是什么。”
他说,“我不想看。”
我说,“这是一条桦树溪里的超巨大的硬头鳟。看呀!它可以吧?它是个庞然大物!我像个疯子一样在溪里上窜下跳地追赶它!”我的声音听上去有点癫狂,但我停不下来。“还有另外一条,”我急急忙忙地说着。“一条绿色的。我发誓!是条绿的!你有没有见过绿色的鱼?”
他往鱼篓里看了一眼,嘴张了开来。
他叫喊着,“把那个该死的东西扔出去!你究竟是怎么了?赶快把它从厨房拿出去,扔到该死的垃圾箱里去!”
我走到外面,往鱼篓里看了看。里面的东西在门灯下发着银色的光。里面的东西把鱼篓塞得满满的。
我把它取出来。我拿着它。我拿着它的那一半。
【注一】埃德加?莱思?布劳夫斯(EdgarRiceBurroughs):美国小说家。擅长科幻小说和犯罪小说。是人猿泰山(Tarzan)这个角色的创造者。
【注二】塔斯?塔卡斯(TarsTarkas):埃德加?莱思?布劳夫斯的幻想小说《火星公主》(《APrincessofMars》)里的一个角色。
【注三】飞蝇杆(FlyRod)是用于飞蝇钓鱼(FlyFishing)的鱼杆。于通常的钓鱼方法不同,飞蝇钓鱼者站在不同深度的浅水里,或者坐在船上,在头顶不停摇动鱼竿,带动鱼线作圆周旋转。鱼线末端是诱饵(鱼钩隐蔽在其中),诱饵是不同大小的假飞虫比如蜻蜓,用来钓不同尺寸的鱼。摇动鱼线时,河里的鱼以为是昆虫在水面上空飞翔,所以会跳出水面去吃。
【注四】在美国的许多州,有法律规定每次钓鱼最多只能钓几条。这里说的钓到了上限是指钓到了允许的条数,有钓了不少的意思。
《喂自己的影子吃饭的人》
【阿根廷】莱•巴尔莱塔
晚饭时,波士顿俱乐部里走进一个人来,高高个儿,仪态和蔼可亲,前额宽阔,颧骨耸削,目光里透着谦恭而又矜持的神色,加上那惨淡的微笑,他的外表显得有些与众不同。
游客们漫不经心地默默地瞧着他。不一会儿,人们便知道他是何许人了。一位食客用手扶了扶熠熠闪光的眼镜,在他那硬绷绷、直挺挺的胸衿所允许的范围内,尽量向前倾身,脸上憋着一堆讨好的笑容,对同桌就餐的女顾客说道:
“您对此公恐怕是素昧平生吧?这是个想教人们相信他能喂自己的影子吃饭的可怜虫。罗兰托先生把他弄来给我们解闷开心的。等着瞧吧,好戏在后边哪!”
这时,一个低沉的粗嗓门喊道:
“嗬,好鲜的蘑菇汁!”
餐厅里的侍者们,殷勤不迭地往顾客们红红绿绿的酒杯里斟着红、白各色葡萄酒。一瓶瓶矿泉水贴着奇山异水的蓝色商标,摆在银质餐具与鲜花间,更显得清雅别致,颇具乡村情调。
我们故事里的主人公风度翩翩地走上前来,声音铿锵地说道:
“尊敬的女士们、先生们:应惠予庇荫的罗兰托先生之请,敝人十分愿意向诸位介绍一种迄今为止任何一位科学家均未能窥其奥妙的奇迹。我们每人都有一位终身伴侣,自我们降临尘世直至魂归西天,须臾不离,瞬息难分,那就是我们自己的影子。近年来,敝人与自己的影子略通灵犀,努力探索到它的需求和爱好。兄弟以为有必要讲述一下,本人是如何得以深入自己影子的心灵的。不过,如果哪位阁下有好奇之心,想知道敝人是在何种场合发现自己的影子与我本人走的道路迥然不同的话;想知道敝人是如何在明月当头、万籁俱寂之时,居然发现本人的影子也像区区一般在生活的话,则兄弟十分愿意,如蒙诸位不吝破费,利用诸位品啜咖啡的时候,把来龙去脉演述一番。现在,为了报答上述那位先生对我额外施恩的情意,兄弟向诸位展示一下我至亲至诚的终身伴侣——我的影子的实际存在。”
他郑重其事地走到开关跟前,熄掉部分灯关。顿时,半个餐厅沉隐于半明半暗之中,不过仍然依稀可以分辨出脸庞和物件的轮廓。
接着,他走近墙壁。于是,他那修长的身影便清晰地投射在墙上。此时此刻,全厅鸦雀无声,人们前俯后拥,争看究竟。这当儿,虽然看来那人身子并没有移动,可墙上的影子却微微欠下身子,头戴高顶礼帽,彬彬有礼地鞠了一躬。
自然,要是细细端详的话,似乎很难说那个影子的轮廓和形象是如何的清楚和分明,倒不如说,那是个硕大的模糊的倒影,隐隐绰绰的像个衣着过时、打扮古板的人。
随后,他像是要释放一只鸽子似的,双手合拢,报幕般地说:
“骑士跳栏!”
墙上,骑士模样的影子蹦了一下。
“玉兔食菜!”
顿时,出现一只兔子在啃白菜。
“山羊爬坡!”
果然,山羊模样的影子开始步履艰难地爬着一个陡坡。
“诸位已经看到,刚才我们只稍稍展现一点影子,就塑造出这么些昙花一现的形象。现在,兄弟要让这种形象具有独立的生命,向大家揭示一个无声的新世界;至于它的存在,敝人业已通过简单的表演向诸位证明是确凿无疑的。”
说完,他从墙壁旁走开了。只见他的影子魔术般地越拉越长,直顶到天花板上。
他用略微神秘的声音,以不甚悦耳的冷冰冰的口吻说:
“尊敬的女士们,先生们:我的影子是独立于我本人的实际的存在。为了使影子能脱离我而独立生活,敝人进行过孜孜不倦的研究。它使兄弟能向诸位证实这么一个罕见的经历:我只要对我的影子稍加吩咐,它就会具有一个生命的各种特征……甚至还会吃东西!我马上给诸位表演一番。诸位给我的影子吃些什么呢?”
听了这番话,就有几个人暗暗发笑。一个妇女轻声细气地咕哝道:
“这种巫术讨厌死了。”
“您害怕了?”
“我讨厌!”
他又问了一遍:
“诸位,给我的影子吃点什么?”
一个闪雷般的声音回答说:
“给,给它吃这块火鸡肉冻。鲜极了!”
一阵哄堂大笑。他伸手接过递来的菜盘,走近墙壁。他的影子随即伸展自如地从天花板上缩了回来,几乎贴近了他的身子。突然间,人们看得清清楚楚,他的身子并未挪动,而那影子却将纤细的双手伸向盘子,小心翼翼地抄起那块肉,送到嘴里,嚼着,吞着……
“简直太神了!”
“嗯,你信吗?”
“我的天哪!夫人,我可不是三岁的小孩!”
“可是,您总不会否认这把戏确实很妙,是吗?”
“诸位,再给我的影子吃些什么呵?”
“给它这块鸡脯。”
“这些苹果馅饼也给它吃。”
“梨!看着它如何吃梨一定妙不可言。”
“很好。诸位,现在先吃鸡脯。噢,哪位劳驾递给我一条餐巾?谢谢!”
所有的就餐者都兴致勃勃地加入到这场娱乐中。
“再给它吃点饼,你这影子可有点干瘦呵!”
“说实在的,这家伙够聪明的。”
“喂,机灵鬼,你的影子喝酒不喝?给它这杯酒,喝了可以解愁。”
“哎哟,我笑得实在受不了喽。”
那影子又吃、又喝、又吸烟,泰然自若,毫不介意。最后,那人神情冷漠而忧郁地把灯全部打开。这时,他的脸色显得格外苍白。他一本正经地对大家说:
“尊敬的女士们,先生们:兄弟深知这般玄妙的试验颇易惹人嘲讽和怀疑,然而,这都无关紧要。总有一天,这项旨在使自己的影子独立于本人的试验,必将得到公认和奖励。临走之前,敬请凡有疑问者,不妨前来搜一下敝人的衣服,以便确信本人绝没有匿带走任何物品。诸位慷慨惠赠的物品,无一不是我的影子所食。这一点,就同敝人叫巴龙·卡米洛·弗莱切一样千真万确。十分感谢,祝大家吃好,晚安!”
“见你的鬼去吧!”
“谁要搜你的身子。”
“我这一辈子也没有见过一脸阴阳怪气的人竟然如此逗人。”
“幻术玩够了,来点音乐吧!”
卡米洛·弗莱切,实际上是叫胡安·马里诺,他面朝三方,各鞠了个躬,然后神态庄重地退出餐厅。穿过花园时,突然有人一把抓住他的胳膊。
“你给我从这里滚!”警察厉声吼道,下次再看到你,就让你和你的影子统统蹲到警察局过夜去。”
他低下头,慢沉沉地走了出去。拐过街角,他才稍稍挺直身子,加快了脚步。在帕雷德站,他沿台阶下到地铁,搭上火车。车站上的柱子、路灯、广告牌在他困乏不堪的眼前风驰电掣般地掠过。他在梅德拉诺站下了车。他一边走一边左顾右盼,最后来到萨迪——卡尔诺特街八十九号。他上气不接下气地跑到三楼,屈指敲了敲一扇门。
开门的是个姑娘,十五六岁光景,也是宽宽的前额,双眼深陷。
“你不回来,小家伙们不愿睡,”她说着,闪到一边让他进屋,“他们可真累人呵!”
两个金发的孩子在一张大床上玩耍着,兴高采烈地迎接他。
“给他们喝过牛奶没有?”他问道。
“卖牛奶的不愿给。”
他咬着嘴唇没吱声。吻吻孩子们,走近桌子,背对着他们。
小姑娘走过去,缓声问道:
“带回来什么没有?”
他没吱声,从衣服里掏出一方叠起来的餐巾,从里面取出一块鸡脯,几块饼,还有两把银质小匙。
小姑娘低声又问:
“没别的了?”
他不禁露出一丝微笑,淡淡的笑意如同他当时的思绪一样微妙。他翻转上衣袖口,摘下一枚带颗珍珠的领带饰针,还有一颗带钻石十字架的纽扣。
小姑娘把这些东西摊在手心,翻来覆去摆弄着,喃喃地赞道:
“多漂亮呵!”
然后,她从壁架上取下一个面包,随手从中间掰开,把那些珠宝藏在当中。
接着,她把食物切成小块,放在一个盘里,坐在床沿上,同她的两个兄弟吃了起来。
“你不想吃点什么?爸爸。”
“不,”他头也不回地回答说,“你们吃吧,我已经吃过了。”
胡安·马里诺面朝窗子坐了下来,茫然失神地凝望着沉睡中城市的屋脊。微弱的电灯光照在他那枯瘦、沮丧的颧骨上,映出的侧影宛如一个神秘的妇女模样:梳着古代的发型,仿佛温柔地依偎在他的肩头。(沈根发译)
结构的最后一部分了。结构的选择与搭建,是建立在有一定结构能力的基础上的,如果经典的[[三幕剧结构]]还没搞清楚的朋友,请回顾之前的文章。并且在这个部分之后的文章之中将会逐步加深内容,所以基础能力不够的朋友们请点进专栏之后,看看前面的玩意,并且下一次我会扔出一个书单来。然后让我们进入正题。
结构的选择和搭建实际上算不上一种专门的技巧或者技术。往往我们在创作过程中结构技巧会很复杂,有可能会用到多角度叙述或者[[环形叙事]]的方式,但是无论什么叙事方式都脱离不了基本的结构理论。(当然后面我会自己打脸的,还有反高潮、反戏剧化,甚至完全打散的结构方式)
那么我们如何选择自己的结构方式呢?其实也不复杂,我们只需要搞定一件事情就好了——“核心”。在戏剧中我们称之为“戏核”当然,“戏核”这个名词比较口语化,大概意思是主题。结构实际上还是为了主题而服务的,我们选择合适的结构来阐释自己的主题,表现自己的人物。同样我们还有一个名词——“[[戏剧性前提]]”,指的是产生和维护“戏剧性”的前提条件。比如《麦克白》——“贪婪使人堕落”;《罗密欧与朱丽叶》——“爱情战胜世仇”之类的。我们选择的结构实际上就是为了这些东西来服务。
然后我们先从叙事方式上来说一下不同的叙事方式有什么区别和意义。
[[线性叙事]]:通过时间线索来作为叙事的线索,从时间线索上表达事件、人物的发展。
线性叙事带来的直接效果是更好的“移情作用”,也更加符合阅读习惯。这可以使得读者更好的接受事件和人物,并且在阅读过程中逐渐的被故事吸引,也可以逐步的丰富人物,来使读者获得满足;线性叙事能够最好的呈现事件的发展过程和脉络。但是同样的,线性叙事的悬念感并不是很足,而且人物的呈现上也不够具有冲击力,但是线性叙事却是最平均的一种叙事方式,可以通过线性叙事讲述几乎所有的故事。
[[多角度叙事]]:(多视角叙事)通过多个人物视角反复讲述同样的事件,从人物的视角角度串联事件发展。代表性作品《罗生门》、《追凶者也》等。
多角度叙事具有很强的悬念感,对于事件具有反复强调的能力,但是其承载不了长发展脉络事件。对于人物的表现上是多角度,多层次的,但是其力量依旧不是十分强烈,但是却可以足够深刻的开掘人的侧面。多角度叙事常常使用“反转”技巧,在不同的角度下,事件多次发生反转呈现,这也是营造悬念的重要手段。
在人物表现角度上,多角度叙事的方式需要我们抓住叙事者的心理状态和自身立场。这就是为什么《罗生门》比《追凶者也》好的多的原因,《罗生门》具有更为强烈的叙事者的人物表现和人物立场呈现,并且开掘的更为深刻。而《追凶者也》仅仅完成了事件的多角度呈现和丰富。
环形叙事:环形叙事与多角度叙事相似,但是相对于多角度叙事环形叙事不改变视角,而拆分时间线索,将事件的开头与结尾相连接,代表《暴雨将至》。
同样具有很强的悬念感,但是其悬念并不如多角度叙事快速,其更加具有延续性。环形叙事往往不以事件或者人物作为核心叙事点,而更总要在于阐述主题性。环形叙事往往对于作者的主题具有更强的阐释力,环形叙事自带“反复”属性,可以强调其内核。而同样的环形叙事在于事件以及人物的表现上不足,而且往往环形叙事的适用性相对狭窄。但是其也是不错的史诗叙事的选择。
这是三种常见的叙事方式,我们可以根据自己的故事进行选择,但是无论什么样子的叙事方式,我们都应该知道其“开端、发展、高潮、结尾”在什么地方。而这三种叙事方式我们怎么样将“结构部分”合理的安排在内呢?
线性叙事和环形叙事实际上在这个部分是相似的,只是环形叙事的结尾和开端相接而已。但是都是在与其之前一部分作为高潮。而环形叙事还要考虑的是主题的呈现点,高潮点需要坐落于主题呈现的高潮上。而实际上,环形叙事的高潮往往在与结尾前的一点点,即揭示环形叙事的时候(这并不绝对)。
多角度叙事的排布应该是事件的真相,或者是作者想要讲述的“真相”作为高潮点。一个事件的呈现出的“真相”往往代表着作者的主题,也代表作者的立场。而多角度叙事伴随着的“反转”都代表着——信息的揭露,事件的清晰化,人物的呈现。所以其实质的发展是逐渐揭露事件“真相”的过程,而高潮也就自然落在了“真相”被揭露的时候。
实际上,无论什么样子的叙事方式,都不是影响结构的核心。结构实际上还是相对稳定的,其区别往往就在于以“什么作为发展的脉络”,其实就是线索的选择。那么为什么我还要说结构方式呢?其实还是为了后面的文章做个铺垫,因为在文学发展过程中,特别进入现当代文学范畴之后,结构方式也就随之复杂起来,其是根据不同的哲学、美学以及文论指导而来的,而且结构的拓展也是一步一步创新而来的。到目前为止我们所讨论的都是——
古典叙事手法
(所以后面的的文章好担心大家一脸懵逼......就好像大家听到当代严肃音乐一样的懵逼)
那么在具有一定的结构能力之后我们要做什么?其实这一片稍微有点跑题,但是也没办法,图都做了...
我需要写一个之前一直忘了的东西——“情节线和情感线”
情节线很简单就是事件情节的发展线,但是我要将情节线拓展一下。
人物行动线
情节发展线
人物行动线,指的是在我们的故事中人物的行动过程,其可能和我们的情节有关系也有可能无关系。人物的行动是复杂的,是具体的,我们不能忽略不在情节中的人物行动部分,这在戏剧中我们称之为“暗场戏”。这一部分往往牵扯着从人物前史一直到故事结束之后的人物行动,我认为,人物是不停的行动的,无论其行动有没有意义,都会对于人物造成影响,而人物的行动会带给人物状态的改变,其之后行为也会受其影响。这就是结构上的连续不断。让我们举个例子。
人物A在家看着某片,连撸三发,再接到电话去到一个地方处理某件棘手的事情。那么A的状态是会受到他在家里行动的影响的。而有可能我们并不写A在家的行动,直接从他到达事发地点开始写起,这样A就可以带着在家里的行动状态出现,并且在后面做出暗示或者揭示。
但是要注意一点,结构的完整性上提到的,我们不需要完全无意义的行动,所以实际上我们需要A进行的暗场行动对我们写出来的行动具有影响,哪怕只是个状态影响。
然后就是情节的发展线,这个情节的发展线按说应该是“贯穿事件”的发展线,也就是“中心行动”的发展线,是揭示主题的情节事件,是核心的事件。比如《麦克白》里的篡位,比如《哈姆雷特》里的复仇。
人物发展线和情节发展线是相互影响,相互勾连,相互作用的。它们应该交至在一起,紧密而有机的结合起来构成完整的情节发展线。
然后就是情感线我们同样将情感线分为两条
人物情感线
观众情感线
人物情感线,很明显指的的人物的情感发展线索,其实我们这条线索往往指的是人物的情感关系发展线。说的是人物之间在关系上的发展过程,其实如果从电视剧上来看,这个事情很好理解——“欢喜冤家”。这是常见的都市情感剧的套路,《心术》就是欢喜冤家的写法,如果有心可以从中拉出两个人的情感关系发展线,两个人是如何逐渐从“冤家-朋友-上床-结婚”的过程。《离婚律师》更为明显一些。这些具体的我就不再这里赘述了,大家自行回去拉一边就可以了。
而人物情感线实际可以进一步的深化,比如人的个人情感和自我意志的发展线索,其呈现在情感关系或者个人情感发展之中,也是人物情感线的一个很重要组成部分。《逃离拉斯维加斯》中就是很明显的,将个人的情感发展线索呈现在人物关系的情感发展之中。当然也可以更深化一步,那有可能就脱离古典手法了,就让我们先放下不谈。
观众情感线,实际上还是一个比较难把握的东西的。其应该是观众对于故事以及故事中人物在移情作用下的情感发展线索。我们需要对整个故事的结构有一个整体的把握,并且对于观众的阅读或者观看习惯有一定的认知。我们要知道观众怎么样才能看的舒服,我们作为创作者应该是引导观众情绪和注意力的。当然这其中还有“叙事节奏”的影响。从一个方面来讲我们需要张弛有度,紧张场面和缓和场面在一个规律下反复进行,同样也需要考虑到人物在发展中遇到的问题对于受众情绪的影响。简单的例子就是“欲扬先抑”的方式,或者“欲抑先扬”。而复杂一点就涉及到细节上的处理了。
而实际上,结构能力是需要将情节线和情感线能够较为优秀的结合起来,相互影响、相互交织。人物的情感发展要在事件发展之中,而同样,情感也会影响事件的发展。现在说着简单,但实际上开始着笔处理之后还是听难得,往往需要大量的调整和修改。
<星>作者:[英]阿瑟•克拉克
=======================
<https://www.zhihu.com/question/41047159>
星
作者:[英]阿瑟•克拉克
这里距离梵蒂冈三千光年。我曾坚信,信仰不会因空间转移而改变,正如我曾坚信壮丽的天穹印证着神的荣耀。但如今我见证了壮丽天穹的另一面,我的信仰面临严峻考验。
我盯着那挂在舱壁上、位于马克六型电脑上方的十字架。有生以来,我第一次怀疑这十字架也许只是一个空泛的符号。
我还未将结果公开,但真相是不能隐瞒起来的。我们拍了数千帧照片,记录探测数据的磁带加起来也有数十里长。当它们被带回地球,任何人都能读到它们,而科学家们将会很容易地作出解读——甚至比我更容易。我不是那种会容忍篡改事实的人,此等行径会使我旧日声誉蒙污。
船员们己极其沮丧,我不知道他们将怎样应付这充满讽刺的结局,他们当中只有少数人有宗教信仰。打从地球出发,他们便在与我“斗争”—— 一场不公开、无恶意,但却是非常认真的思想战。即使如此,他们亦不忍用这项发现作为对付我的最后武器。船员们只觉得,一艘星际探测船上的首席天体物理学家,竟然是耶稣会教士,这是非常滑稽的。
船医钱德勒便是对此无法释怀者之一(为何医学界人士都是死硬的无神论者?)有些时候,我会在飞船的观景台上遇到他,群星闪耀,在微弱灯光下明亮不减分毫。他在黑暗中向我走过来站定,从巨大的椭圆形穹顶向外望去,随着飞船自旋,星空在我们四周缓慢转动。
“神父。”他最后总会忍不住开口,“宇宙的运行漫无止境。或许冥冥中真有个造物者,但即使如此,你真的能相信有某种存在真的会特别眷顾微不足道的我们和我们微不足道的世界吗?我只是不明白这个。”——然后争论便会开始,恒星和星云沉默地环绕着我们,在塑料观景窗外划出无尽的弧光。
我两种身份的不协调令船员感到滑稽,尽管我曾有三篇刊载于《天体物理学报》、五篇刊于《皇家天文学会每月通讯》的科学论文。我也会提醒他们,耶稣会仍以科研工作成就卓著见称,尽管略有衰落,但自十八世纪以来,在天文学和地球科学方面取得的成就数量甚至超过我们的人数。
那份由我执笔、关于凤凰星云的报告真的会结束耶稣会的千年历史吗?也许,是的,我甚至担心更多。
“凤凰”,多差劲的名字。假如为这星云取名的人有预言之意,这预言也要千亿年后才可验证。就连“星云”一词也是错误的,它和那种弥漫在银河系里的恒星胚胎素材有着天渊之别。以宇宙的尺度而言,“凤凰”星云只是个细小而稀薄的气体外壳,它包围着一颗恒星——说得准确点,应该是从前曾存在过的一颗恒星。
光谱计图表上方,挂着彼德•保罗和鲁宾斯所作的罗若拉神父画像。他看起来像是在嘲笑我。神父啊!要是你我易境而处,你会怎样对待这些数据呢?我的信仰不足以支持我挺身而起,面对这个挑战。你的呢?
神父啊!你凝望远方,但我所走的距离,远远超出你创立耶稣会那个时代所能理解和想像的世界。过去从未有过探测船离开地球这么远。我们飞到远在宇宙边陲的地方。我们终于飞抵凤凰星云,并且带着重大的发现,踏上返回地球老家的路。可是这发现对我是沉重的负担,我只有跨越时间和空间,向你作无声的求援。
你手握的书,上面印着“主之荣耀至大至高”。但当你有机会目睹我们的发现,你还会相信这句话吗?
“凤凰星云”的本质很好理解——仅仅银河系里,每年便有百多个恒星爆炸。它们突然在几天甚至几小时内,光亮骤增至平常的千万倍,然后声沉影寂。这些爆炸的星是“新星”——它们只不过是宇宙灾难中的家常便饭。我在月球天文台工作时,就曾记录过十多个新星的光谱和变光曲线。
而每隔几百年,就会出现令新星也显得微不足道的天文奇观。当一颗星变成超新星时,它的光比银河系所有恒星加起来还要明亮,古代中国天文学家曾在1054年见过这样的情景。1512年,仙后座又出现一颗光亮得白昼也可见的超新星。随后的一千年间,还出现过三颗超新星。
我们的任务便是访问此类灾难现场,寻求灾难的起因,要是可能的话,也许还会查知超新星的成因。我们的太空船穿越了六千年前爆发开来的气体。这气体是炽热的,仍在迸发出紫色的光辉,只是它非常稀薄,不足以伤害我们。层层如象牙球的气体被爆炸的星体使劲抛出,至今仍在向外飞驰。恒星的引力也无力将它们拉回去。气体包含的空间容得下数千个太阳系,而盘踞中心的是一个怪异的天体,一个只有地球般大小,却比地球重数百万倍的白矮星。
太空船周围气体的光辉驱散了平常星际空间的黑暗。我们的目标如同一个被引爆的太空炸弹,几千年过去了,其火热的碎片还在四散飞开。爆炸规模之大,使星体的碎片散布于数十亿公里的空间中,恍若凝固。或许几个世代之后,肉眼可以察觉出那些混沌的气体和纠缠的旋涡有些微移动。但此刻星云的澎湃气势,已够慑人心魄了。
我们数小时前己关闭了主要动力,以余速飞向那凶险的小矮星。它曾和我们的太阳无甚分别,可惜它却将能使它活命数百万年的能量,一口气在数小时内耗散掉了。我们所见的只是个吝啬每一分能量的小星,像要补偿那白白虚耗了的光芒。
在这个景况下找到行星,几乎是妄想。即使过去曾有行星,也在爆炸时化为蒸汽,和碎片与星云的气体混为一体了。不过,我们还是作了一趟自动搜索(这是飞越从来未探测过的恒星时必定要做的程序),竟然发现了一个孤单的行星。它的轨迹离星云中心的矮星很远很远。它的处境,正像太阳系的冥王星。这个行星徘徊在星际间永恒黑夜的边沿,从未尝过生机带来的温馨。但正是遥远的距离使它幸免于像其同伴般被气化的厄运。
行星的表面历尽劫难,不要说曾覆盖地表的固态气体,就连岩石也被烧炙过了。我们登陆,并发现了石窟。
石窟的建造者肯定尽了一切努力,确保它会让后来者发现。入口处的石标只剩下一摊凝固的熔岩,但从远距离侦察图片中,我们己相当肯定它是智慧的标志。稍后,我们又侦察到广泛分布在行星各处的放射性辐射,石窟外的石标可以毁掉,但辐射纹印是抹不掉的,它还会不停向周围发出讯号。而我们的太空船像箭一般射向这个大标靶的红心。
石标原本应有一里高,现今却像一支正熔化的蜡烛。我们以天文学家的身份而来,现在却要兼任考古学家。不过我们都将原来的目标抛诸脑后,我们明白,他们选这个偏远的行星,建立这个庞大的标记,只有一个作用:一个文明的族类,自知难逃劫数,希望留下一些不朽之物。
我们得花上几个世代才能完全消化石窟内的珍藏。他们的太阳爆发前必定早有预兆,故此他们有充分的时间准备,可以将他们想留传后世的精华都带到此地藏好,期待日后给其他族类发掘出来,而不被遗忘。换了我们,会有这样的干劲吗?或者是被困在愁苦中,懒得理会那活不到也触摸不到的将来?
哪怕再多给他们一点时间啊!他们已经学会在行星之间旅行,却还远未能跨越恒星之间的鸿沟。而且即使离他们最近的恒星系,也有一百光年之遥。
尽管留下的雕塑来看,他们和人类的外形殊无相似之处,但我们仍会为他们的命运而悲哀。他们留下上千件视像纪录,连同放映的机器,还有精心制作的图片,我们毫不费力地就明白了他们的语言。我们仔细研读这些记录,一个长达六千年的温暖而美丽的文明重现在我们眼前,在很多方面比我们的世界更好。或许他们只将最好的一面留给我们看,但谁能为此责怪他们?他们优美的城市绝不比地球逊色。我们看着他们工作、玩乐,他们悠扬如歌的语言跨越数个世纪的时光被我们听见。一个画面至今徘徊在我的眼前:一群孩子在蓝沙的海滩上嬉戏,就像地球上的那些孩子一样。
海平线尽头夕阳西下,他们太阳的余晖,仍照暖大地。有谁知道,这太阳快将变成夺命判官,定这族类的死罪?
想必是我们久尝孤独,思乡心切,才会深受感动。我们当中很多人到过其它星球,探索过其它文明的遗迹,却从未有像今天这般深的感触。
这一悲剧是独一无二的,这是一个族类的败亡,犹如地球上国家和文化的兴衰。然而,一个文明在它璀璨的极盛之时被如此彻底地摧毁……这一事实要怎样才能释义为神的慈悲?
我的队员曾这样问过,我也曾尽力答复。罗若拉神父,你或许更有把握,但神灵对我全无启示。这些异族不是邪恶的,我不知道他们崇拜怎样的神。但我曾回望数十世纪的岁月,见证他们用最后的努力所保留下来的珍爱之物,在如今萎缩衰亡了的太阳照耀下出土。
这个问题,在回到地球后同僚们将会怎样回答,我早已料到。他们会这样说:宇宙万事万物既无目的也无宏图,既然银河系内每年都有上百颗恒星爆炸,此刻在太空深处,必有文明被毁灭。无论这个族类是邪恶还是善良,与其面对的厄运毫不相干:宇宙没有神,没有天理,是故亦无天谴。又或者,我们在凤凰星云所见的一切,都不能证明什么。坚持上述论据的人,只是感情用事,而不是据理立论。神不须向人交待他的行事方式,他能造宇宙;也能毁灭宇宙。如果我们竟要论断神的行事,那只是人的高傲自大、目空一切——甚至可称之为亵渎。
我本可硬起心肠接受这一切——整个星球的文明被大火化为灰烬的事实。但凡事都有极限,人的信仰亦然。当计算结果呈现,我知道我一度坚定的信仰已经开始动摇。
我们抵达星云前,尚无法知道那颗星的爆炸何时发生。现在我们掌握了天体物理探测的数据,和那硕果仅存的行星上岩石的化验结果,使我能准确计算出星球爆炸的时刻。我知道这个宇宙轰天雷的闪光到达地球的年份,我意识到如今在载着我们飞奔回家的太空船后面迅速退却的超新星残核,当年曾在地球的天空中闪烁着多么耀眼的光芒。我仿佛见到那颗星,像个远方的灯塔般闪着光辉,在东方的拂晓中,引领旭日登场。
千古谜团终于解破,不容我们怀疑。但……神啊!宇宙间有亿万恒星,为什么你偏选上这颗?你用大火断送了整个世界的人,就只是为了照亮伯利恒的早晨?
/*BOXES*/
html body.tc-body .bluebox {display:block;background-color:#eef;padding:5px;padding-left:20px;padding-top:10px;margin-top:5px;margin-bottom:5px;width:95%;color:#000;}
html body.tc-body .graybox {display:block;background-color:#eee;padding:5px;padding-left:20px;padding-top:10px;margin-top:5px;margin-bottom:5px;width:95%;color:#000;}
body p {<<colour foreground>>;}
code {color: #b0a;background-color:#eee;}
/*TIGHT NOTES*/
html body.tc-body h1, html body.tc-body h2, html body.tc-body h3, html body.tc-body h4 { margin-top: 0.3em; margin-bottom: 0.3em; }
/*FONT SUBTITLES*/
.serif {font-family: 'Arial', sans-serif; color: <<colour tiddler-editor-border>>font-size:10pt;}
html body.tc-body .serif a.tc-tiddlylink-external {font-family: 'Arial', sans-serif;font-size:12pt; line-height:normal;font-weight:normal;color:#666;}
/*FONT STUFF (colors)*/
html body.tc-body .lightgraybk {background:#eee;padding:1px 4px px 4px;margin-bottom:2px;font-family:'Arial', sans-serif;}
.red {color:red;}
html body.tc-body .blue a {color:blue;}
/*FONT STUFF SOURCES*/
html body.tc-body .source {color:#777;font-size:10pt;}
/*ICON COLORS*/
html body.tc-body .tc-image-edit-button {stroke: white;fill:#555;}
html body.tc-body .tc-image-chevron-up {stroke: white;fill:#ccc;}
html body.tc-body .tc-image-chevron-down {stroke: white;fill:#ccc;}
html body.tc-body .tc-image-fold-button {stroke: white;fill:#ccc;}
html body.tc-body .tc-image-close-button {stroke: white;fill:#555;}
html body.tc-body .tc-image-unfold-button {stroke: white;fill:#ccc;}
html body.tc-body .tc-image-preview-open {stroke: white;fill:#f29;font-size:150%;}
html body.tc-body .tc-image-delete-button {stroke: white;fill:#ff2222;}
html body.tc-body .tc-image-cancel-button {stroke: white;fill:#ffdd55;}
html body.tc-body .tc-image-done-button {stroke: white;fill:#094;}
/*INDENTING*/
html body.tc-body .indent1 {margin-left:1.5em;display:block;}
/*LINKS*/
html body.tc-body a.tc-tiddlylink {text-decoration: none;font-style: normal;font-weight: normal;}
html body.tc-body a.tc-tiddlylink-external {text-decoration: none;font-weight: normal;}
html body.tc-body a.tc-tiddlylink-visited {text-decoration: none;font-weight: normal;}
html body.tc-body .source a.tc-tiddlylink-external {font-weight: normal;font-size:10pt;}
/*LISTS BASIC*/
html body.tc-body ul li {color: <<colour foreground>>;}
html body.tc-body ol li {color:<<colour foreground>>;}
/*TIDDLER TITLES*/
.tc-tiddler-missing .tc-title { font-style: normal; font-weight: bold; }
/*VIEWTEMPLATE FONT SIZE*/
html body.tc-body .viewtemplatebigtext {font-size:110%;}
/*HIDE SECTIONS FOR PRINTING*/
@media print {#tc-page-background {display: none ! important;}}
@media print {.tc-tags-wrapper {display: none ! important;}}
@media print { body.tc-body {background-color: transparent;}}
@media print {.tc-image-chevron-up {display: none ! important;}}
@media print {.tc-image-chevron-down {display: none ! important;}}
@media print {button.sidebar-toggle {display: none ! important;}}
@media print {.hideprint {display: none ! important;}}
@media print {.tc-btn-invisible {display: none ! important;}}
@media print {
.story-river {
margin: 0;
padding: 0;
}
html body.tc-body .tc-tiddler-frame {
margin: 0;
border-bottom: 1px solid #fff;
padding: 5px;}
html body.tc-body a.tc-tiddlylink-external:hover {
border: 1px solid <<colour tiddler-border>>;
}
html body.tc-body .tc-tiddler-info {
padding: 14px 42px 14px 42px;
background-color: <<colour tiddler-info-background>>;}
}
<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} journalText="">
<$wikify name="journalTitle" text="""<$macrocall $name="now" format=<<journalTitleTemplate>>/>""">
<$reveal type="nomatch" state=<<journalTitle>> text="">
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags="" text={{{ [<journalTitle>get[]] }}}/>
</$reveal>
<$reveal type="match" state=<<journalTitle>> text="">
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags="" text=<<journalText>>/>
</$reveal>
</$wikify>
</$vars>
<$button class="tc-btn-invisible" popup="$:/SamplePopupState">{{$:/core/images/chevron-down}}</$button>
<$reveal type="popup" state="$:/SamplePopupState" class="tc-tiddler-body tc-drop-down tc-popup-keep">
<$checkbox tiddler="$:/core/ui/EditTemplate/title" tag="$:/tags/EditTemplate"> title</$checkbox><br>
<$checkbox tiddler="$:/core/ui/EditTemplate/tags" tag="$:/tags/EditTemplate"> tags</$checkbox><br>
<$checkbox tiddler="$:/core/ui/EditTemplate/type" tag="$:/tags/EditTemplate"> type</$checkbox><br>
<$checkbox tiddler="$:/core/ui/EditTemplate/fields" tag="$:/tags/EditTemplate"> fields</$checkbox><br>
<$checkbox tiddler="$:/config/TextEditor/EnableToolbar" field="text" checked="yes" unchecked="no" default="no"> toolbar</$checkbox><br>
<$checkbox tiddler="$:/.giffmex/EditTemplate/custom" tag="$:/tags/EditTemplate"> custom</$checkbox>
''Open / close the sidebar:'' <$list filter="[[$:/state/sidebar]get[text]] +[else[yes]!match[no]]" variable="ignore"><$button set="$:/state/sidebar" setTo="no" tooltip={{$:/language/Buttons/HideSideBar/Hint}} aria-label={{$:/language/Buttons/HideSideBar/Caption}} class="tc-btn-invisible">{{$:/core/images/chevron-right}}</$button>
</$list><$list filter="[[$:/state/sidebar]get[text]] +[else[yes]match[no]]" variable="ignore">
<$button set="$:/state/sidebar" setTo="yes" tooltip={{$:/language/Buttons/ShowSideBar/Hint}} aria-label={{$:/language/Buttons/ShowSideBar/Caption}} class="tc-btn-invisible">{{$:/core/images/chevron-left}}</$button>
</$list>
''Click the link below to edit the''<br> [[Custom area|$:/.giffmex/EditTemplate/custom]]
{{$:/core/ui/EditorToolbar/editor-height-dropdown}}
</$reveal>
"""
This is where you can add your own items you want visible in the edit template. For example:
Grab symbol code: e.g., ♦ `♦` ★ `★`
Grab snippets: e.g., `tiddlywiki --rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html static text/plain --rendertiddler $:/core/templates/static.template.css static/static.css text/plain`
"""
<br>
\define tagreset2()
<$list filter="[tag[$:/giffmex/titleview]sort[created]] -[[$(currentTiddler)$]]" variable="removeme">
<$action-listops $tiddler=<<removeme>> $tags="+[remove[$:/tags/ViewTemplate]]"/>
</$list>
<$action-deletefield dummy/>
\end
\define switchStoryView(storyview,default)
<$select tiddler='$storyview$' default='$default$'>
<option value="zoomin"><$text text='one tiddler only'/></option>
<option value="classic"><$text text='multiple tiddlers'/></option>
</$select>
\end
''Choose how to view titles:''
<$list filter="[tag[$:/giffmex/titleview]sort[caption]]">
<$list filter="[all[current]tag[$:/tags/ViewTemplate]]">
<$checkbox field=dummy checked="yes" unchecked="yes" default="yes"></$checkbox>
<$view field="caption"/><br/>
</$list>
<$list filter="[all[current]!tag[$:/tags/ViewTemplate]]">
<$checkbox tag="$:/tags/ViewTemplate" xinvertTag="yes" checkactions=<<tagreset2>>/> <$view field="caption"/><br/>
</$list>
</$list>
<br>
''Choose how to view tiddlers in each column''
Left column: <<switchStoryView $:/view zoomin>>
Right column: <<switchStoryView $:/_sq/Stories/config/Story2-storyview classic>>
''Left column to right column width ratio:''
{{$:/config/sq/Stories/storyRiverRatio}} : <$text text={{{[[100]subtract{$:/config/sq/Stories/storyRiverRatio}]}}}/>
<$range tiddler="$:/config/sq/Stories/storyRiverRatio" min="20" max="80" default="50" increment="5"/>
<!--
''Right column font-size''
Tiddler: {{$:/config/sq/Stories/story2/fontsize-title}}px
<$range tiddler="$:/config/sq/Stories/story2/fontsize-title" min="6" max="40" default="14" increment="1"/>
Body: {{$:/config/sq/Stories/story2/fontsize-body}}px
<$range tiddler="$:/config/sq/Stories/story2/fontsize-body" min="6" max="40" default="15" increment="1"/>
-->
\define tagreset()
<$list filter="[tag[$:/giffmex/refs]sort[created]] -[[$(currentTiddler)$]]" variable="removeme">
<$action-listops $tiddler=<<removeme>> $tags="+[remove[$:/tags/ViewTemplate]]"/>
</$list>
<$action-deletefield dummy/>
\end
''Choose how to view references:''
<$list filter="[tag[$:/giffmex/refs]sort[caption]]">
<$list filter="[all[current]tag[$:/tags/ViewTemplate]]">
<$checkbox field=dummy checked="yes" unchecked="yes" default="yes"></$checkbox>
<$view field="caption"/><br/>
</$list>
<$list filter="[all[current]!tag[$:/tags/ViewTemplate]]">
<$checkbox tag="$:/tags/ViewTemplate" xinvertTag="yes" checkactions=<<tagreset>>/> <$view field="caption"/><br/>
</$list>
</$list>
{{Hint for Muffin tutorial}}
<br>Note that the gray boxes in the context and transclude options are links to their respective tiddlers.
{
"Hint for Muffin tutorial": "hide",
"Muffin 1": "hide",
"Muffin 2": "hide",
"2021 / 01 / 14 / 17:26:09 /": "hide",
"2021 / 01 / 14 / 17:29:31 /": "hide"
}
\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
\define save-tiddler-actions()
<$action-sendmessage $message="tm-add-tag" $param={{{ [<newTagNameTiddler>get[text]] }}}/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}}/>
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-save-tiddler"/>
\end
\define cancel-delete-tiddler-actions(message)
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-$message$-tiddler"/>
<$list filter="[all[current]links[]is[missing]]"><$action-createtiddler $basetitle=<<currentTiddler>>/></$list>
\end
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-edit-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
<$fieldmangler>
<$vars storyTiddler=<<currentTiddler>> newTagNameTiddler=<<qualify "$:/temp/NewTagName">> newFieldNameTiddler=<<qualify "$:/temp/NewFieldName">> newFieldValueTiddler=<<qualify "$:/temp/NewFieldValue">> newFieldNameInputTiddler=<<qualify "$:/temp/NewFieldName/input">> newFieldNameSelectionTiddler=<<qualify "$:/temp/NewFieldName/selected-item">> newTagNameInputTiddler=<<qualify "$:/temp/NewTagName/input">> newTagNameSelectionTiddler=<<qualify "$:/temp/NewTagName/selected-item">> typeInputTiddler=<<qualify "$:/temp/Type/input">> typeSelectionTiddler=<<qualify "$:/temp/Type/selected-item">>>
<$keyboard key="((cancel-edit-tiddler))" actions=<<cancel-delete-tiddler-actions "cancel">>>
<$keyboard key="((save-tiddler))" actions=<<save-tiddler-actions>>>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]" variable="listItem">
<$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]">
<$transclude tiddler=<<listItem>>/>
</$set>
</$list>
</$keyboard>
</$keyboard>
</$vars>
</$fieldmangler>
</div>
<span class="viewtemplatebigtext">
<$reveal type="nomatch" stateTitle=<<folded-state>> text="hide" tag="div" retain="yes" animate="yes">
<hr>
<$vars searchme=<<currentTiddler>> searchspx={{{ [<currentTiddler>escaperegexp[]]}}} >
<$list filter="[!is[system]all[current]backlinks[]!tag[outlines]!tag[hide]sort[title]] -[is[current]]"><$link><$view field="title"/></$link><span class="indent1"><$link><span class="graybox"><$context term=<<searchme>> /></span></$link></span></$list>
</$vars>
</$reveal>
</span>
<span class="viewtemplatebigtext">
<$reveal type="nomatch" stateTitle=<<folded-state>> text="hide" tag="div" retain="yes" animate="yes">
<hr>
<$vars searchme=<<currentTiddler>> searchspx={{{ [<currentTiddler>escaperegexp[]]}}} >
<$list filter="[!is[system]all[current]backlinks[]!tag[hide]sort[title]] -[is[current]]"><$link><$view field="title" /></$link><br></$list>
</$vars>
</$reveal>
</span>
<span class="viewtemplatebigtext">
<$reveal type="nomatch" stateTitle=<<folded-state>> text="hide" tag="div" retain="yes" animate="yes">
<hr>
<$vars searchme=<<currentTiddler>> searchspx={{{ [<currentTiddler>escaperegexp[]]}}} >
<<tabs '[!is[system]all[current]backlinks[]!tag[hide]sort[title]] -[is[current]]' '' '$:/state/tab/strolltabs' 'tc-vertical'>>
</$vars>
</$reveal>
</span>
<span class="viewtemplatebigtext">
<$reveal type="nomatch" stateTitle=<<folded-state>> text="hide" tag="div" retain="yes" animate="yes">
<hr>
<$list filter="[!is[system]all[current]backlinks[]!tag[hide]!tag[outlines]sort[title]] -[is[current]]"><$link><$view field="title"/></$link><span class="indent1"><$link><span class="graybox"><$transclude field="text" mode="block" /></span></$link></span></$list>
</$reveal>
</span>
<span class="viewtemplatebigtext">
<$reveal type="nomatch" stateTitle=<<folded-state>> text="hide" tag="div" retain="yes" animate="yes">
<hr>
<$list filter="[!is[system]all[current]backlinks[]!tag[hide]!tag[outlines]sort[title]] -[is[current]]"><$link><$view field="title"/></$link>
<$reveal type="nomatch" stateTitle="$:/.giffmex/TiddlyBlinkFoldData" stateIndex=<<currentTiddler>> text="show">
<$button class=<<tv-config-toolbar-class>> setTitle="$:/.giffmex/TiddlyBlinkFoldData" setIndex=<<currentTiddler>> setTo="show">{{$:/core/images/unfold-button}}</$button><br/>
</$reveal>
<$reveal type="match" stateTitle="$:/.giffmex/TiddlyBlinkFoldData" stateIndex=<<currentTiddler>> text="show">
<$button class=<<tv-config-toolbar-class>> setTitle="$:/.giffmex/TiddlyBlinkFoldData" setIndex=<<currentTiddler>> setTo="hide">{{$:/core/images/fold-button}}</$button>
<span class="indent1">
<$link><span class="graybox">
<$transclude field="text" mode="block" /></span></$link></span>
</$reveal>
</$list>
</$reveal>
</span>
\define title-styles()
fill:$(foregroundColor)$;
\end
\define config-title()
$:/config/ViewToolbarButtons/Visibility/$(listItem)$
\end
<div class="tc-tiddler-title">
<div class="tc-titlebar">
<span class="tc-tiddler-controls">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>
</span>
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
<$link>
<$set name="foregroundColor" value={{!!color}}>
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
<$transclude tiddler={{!!icon}}/>
</span>
</$set>
<$list filter="[all[current]removeprefix[$:/]]">
<h2 class="tc-title" title={{$:/language/SystemTiddler/Tooltip}}>
<span class="tc-system-title-prefix">$:/</span><$text text=<<currentTiddler>>/>
</h2>
</$list>
<br><$list filter="[all[current]!prefix[$:/]]">
<h2 class="tc-title">
<$view field="title"/>
</h2>
</$list>
</$link>
</$set>
</div>
<$reveal type="nomatch" text="" default="" state=<<tiddlerInfoState>> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"><$transclude tiddler=<<listItem>> mode="block"/></$list>
</$reveal>
</div>
\define button()
<$button tooltip={{$:/language/Buttons/NewHere/Hint}} class=<<tv-config-toolbar-class>> actions=<<actions>>>
{{$:/core/images/new-button}}
</$button>
\end
\define actions()
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> text="""[[$(tid)$]]"""/>
\end
<$wikify name=tid text=<<currentTiddler>>>
<<button>>
</$wikify>
\whitespace trim
\define journalButtonActions()
<$action-sendmessage $message="tm-new-tiddler" title=<<now """$(journalTitleTemplate)$""">> text="""[[$(tid)$]]""" />
\end
\define journalButtonTags()
[[$(currentTiddlerTag)$]] $(journalTags)$
\end
\define journalButton()
<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}}
aria-label={{$:/language/Buttons/NewJournalHere/Caption}}
class=<<tv-config-toolbar-class>>
actions=<<journalButtonActions>>>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/new-journal-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text">
<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>
</span>
</$list>
</$button>
\end
<$set name="journalTitleTemplate" value={{$:/config/NewJournal/Title}}>
<$set name="tid" value=<<currentTiddler>>>
<<journalButton>>
</$set>
</$set>
Built from branch 'tiddlywiki-com' at commit 1a6be5ae09de1289727e9a981560d295cf8f361a of https://github.com/Jermolene/TiddlyWiki5.git at 2020-04-15 15:19:44 UTC
\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock prettylink
YYYY / 0MM / 0DD / 0hh:0mm:0ss /
$:/.giffmex/ui/EditTemplate
{
"tiddlers": {
"$:/Acknowledgements": {
"title": "$:/Acknowledgements",
"text": "TiddlyWiki incorporates code from these fine OpenSource projects:\n\n* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]\n* [[The Jasmine JavaScript Test Framework|http://pivotal.github.io/jasmine/]]\n* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]\n\nAnd media from these projects:\n\n* World flag icons from [[Wikipedia|http://commons.wikimedia.org/wiki/Category:SVG_flags_by_country]]\n"
},
"$:/core/copyright.txt": {
"title": "$:/core/copyright.txt",
"type": "text/plain",
"text": "TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)\n\nCopyright (c) 2004-2007, Jeremy Ruston\nCopyright (c) 2007-2020, UnaMesa Association\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
},
"$:/core/icon": {
"title": "$:/core/icon",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path d=\"M64 0l54.56 32v64L64 128 9.44 96V32L64 0zm21.127 95.408c-3.578-.103-5.15-.094-6.974-3.152l-1.42.042c-1.653-.075-.964-.04-2.067-.097-1.844-.07-1.548-1.86-1.873-2.8-.52-3.202.687-6.43.65-9.632-.014-1.14-1.593-5.17-2.157-6.61-1.768.34-3.546.406-5.34.497-4.134-.01-8.24-.527-12.317-1.183-.8 3.35-3.16 8.036-1.21 11.44 2.37 3.52 4.03 4.495 6.61 4.707 2.572.212 3.16 3.18 2.53 4.242-.55.73-1.52.864-2.346 1.04l-1.65.08c-1.296-.046-2.455-.404-3.61-.955-1.93-1.097-3.925-3.383-5.406-5.024.345.658.55 1.938.24 2.53-.878 1.27-4.665 1.26-6.4.47-1.97-.89-6.73-7.162-7.468-11.86 1.96-3.78 4.812-7.07 6.255-11.186-3.146-2.05-4.83-5.384-4.61-9.16l.08-.44c-3.097.59-1.49.37-4.82.628-10.608-.032-19.935-7.37-14.68-18.774.34-.673.664-1.287 1.243-.994.466.237.4 1.18.166 2.227-3.005 13.627 11.67 13.732 20.69 11.21.89-.25 2.67-1.936 3.905-2.495 2.016-.91 4.205-1.282 6.376-1.55 5.4-.63 11.893 2.276 15.19 2.37 3.3.096 7.99-.805 10.87-.615 2.09.098 4.143.483 6.16 1.03 1.306-6.49 1.4-11.27 4.492-12.38 1.814.293 3.213 2.818 4.25 4.167 2.112-.086 4.12.46 6.115 1.066 3.61-.522 6.642-2.593 9.833-4.203-3.234 2.69-3.673 7.075-3.303 11.127.138 2.103-.444 4.386-1.164 6.54-1.348 3.507-3.95 7.204-6.97 7.014-1.14-.036-1.805-.695-2.653-1.4-.164 1.427-.81 2.7-1.434 3.96-1.44 2.797-5.203 4.03-8.687 7.016-3.484 2.985 1.114 13.65 2.23 15.594 1.114 1.94 4.226 2.652 3.02 4.406-.37.58-.936.785-1.54 1.01l-.82.11zm-40.097-8.85l.553.14c.694-.27 2.09.15 2.83.353-1.363-1.31-3.417-3.24-4.897-4.46-.485-1.47-.278-2.96-.174-4.46l.02-.123c-.582 1.205-1.322 2.376-1.72 3.645-.465 1.71 2.07 3.557 3.052 4.615l.336.3z\" fill-rule=\"evenodd\"/></svg>"
},
"$:/core/images/add-comment": {
"title": "$:/core/images/add-comment",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-add-comment tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M56 56H36a8 8 0 100 16h20v20a8 8 0 1016 0V72h20a8 8 0 100-16H72V36a8 8 0 10-16 0v20zm-12.595 58.362c-6.683 7.659-20.297 12.903-36.006 12.903-2.196 0-4.35-.102-6.451-.3 9.652-3.836 17.356-12.24 21.01-22.874C8.516 94.28 0 79.734 0 63.5 0 33.953 28.206 10 63 10s63 23.953 63 53.5S97.794 117 63 117c-6.841 0-13.428-.926-19.595-2.638z\"/></svg>"
},
"$:/core/images/advanced-search-button": {
"title": "$:/core/images/advanced-search-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-advanced-search-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M74.565 87.985A47.776 47.776 0 0148 96C21.49 96 0 74.51 0 48S21.49 0 48 0s48 21.49 48 48c0 9.854-2.97 19.015-8.062 26.636l34.347 34.347a9.443 9.443 0 010 13.36 9.446 9.446 0 01-13.36 0l-34.36-34.358zM48 80c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32z\"/><circle cx=\"48\" cy=\"48\" r=\"8\"/><circle cx=\"28\" cy=\"48\" r=\"8\"/><circle cx=\"68\" cy=\"48\" r=\"8\"/></g></svg>"
},
"$:/core/images/auto-height": {
"title": "$:/core/images/auto-height",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-auto-height tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M67.987 114.356l-.029-14.477a4 4 0 00-2.067-3.494l-15.966-8.813-1.933 7.502H79.9c4.222 0 5.564-5.693 1.786-7.58L49.797 71.572 48.01 79.15h31.982c4.217 0 5.564-5.682 1.795-7.575L49.805 55.517l-1.795 7.575h31.982c4.212 0 5.563-5.67 1.805-7.57l-16.034-8.105 2.195 3.57V35.614l9.214 9.213a4 4 0 105.656-5.656l-16-16a4 4 0 00-5.656 0l-16 16a4 4 0 105.656 5.656l9.13-9.13v15.288a4 4 0 002.195 3.57l16.035 8.106 1.804-7.57H48.01c-4.217 0-5.564 5.682-1.795 7.574l31.982 16.059 1.795-7.575H48.01c-4.222 0-5.564 5.693-1.787 7.579l31.89 15.923 1.787-7.578H47.992c-4.133 0-5.552 5.504-1.933 7.501l15.966 8.813-2.067-3.494.029 14.436-9.159-9.158a4 4 0 00-5.656 5.656l16 16a4 4 0 005.656 0l16-16a4 4 0 10-5.656-5.656l-9.185 9.184zM16 20h96a4 4 0 100-8H16a4 4 0 100 8z\"/></svg>"
},
"$:/core/images/blank": {
"title": "$:/core/images/blank",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-blank tc-image-button\" viewBox=\"0 0 128 128\"/>"
},
"$:/core/images/bold": {
"title": "$:/core/images/bold",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-bold tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M41.146 51.81V21.87h26.353c2.51 0 4.93.21 7.26.628 2.33.418 4.392 1.165 6.185 2.24 1.793 1.076 3.227 2.57 4.302 4.482 1.076 1.913 1.614 4.363 1.614 7.35 0 5.379-1.613 9.263-4.84 11.653-3.227 2.39-7.35 3.586-12.37 3.586H41.146zM13 0v128h62.028a65.45 65.45 0 0016.762-2.151c5.438-1.434 10.278-3.645 14.52-6.633 4.244-2.988 7.62-6.842 10.13-11.563 2.51-4.721 3.764-10.308 3.764-16.762 0-8.008-1.942-14.85-5.826-20.527-3.884-5.677-9.77-9.65-17.658-11.921 5.737-2.75 10.069-6.275 12.997-10.577 2.928-4.303 4.392-9.681 4.392-16.135 0-5.976-.986-10.995-2.958-15.059-1.972-4.063-4.75-7.32-8.336-9.77-3.585-2.45-7.888-4.213-12.907-5.289C84.888.538 79.33 0 73.235 0H13zm28.146 106.129V70.992H71.8c6.095 0 10.995 1.404 14.7 4.212 3.705 2.81 5.558 7.5 5.558 14.073 0 3.347-.568 6.096-1.703 8.247-1.136 2.151-2.66 3.854-4.572 5.11-1.912 1.254-4.123 2.15-6.633 2.688-2.51.538-5.139.807-7.888.807H41.146z\"/></svg>"
},
"$:/core/images/cancel-button": {
"title": "$:/core/images/cancel-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-cancel-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 76.314l-16.97 16.97a7.999 7.999 0 01-11.314 0c-3.118-3.118-3.124-8.19 0-11.313L52.686 65l-16.97-16.97a7.999 7.999 0 010-11.314c3.118-3.118 8.19-3.124 11.313 0L64 53.686l16.97-16.97a7.999 7.999 0 0111.314 0c3.118 3.118 3.124 8.19 0 11.313L75.314 65l16.97 16.97a7.999 7.999 0 010 11.314c-3.118 3.118-8.19 3.124-11.313 0L64 76.314zM64 129c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 1 0 29.654 0 65c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 17 64 17 16 38.49 16 65s21.49 48 48 48z\"/></svg>"
},
"$:/core/images/chevron-down": {
"title": "$:/core/images/chevron-down",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-chevron-down tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M64.053 85.456a7.889 7.889 0 01-5.6-2.316L2.473 27.16a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0L64.05 66.344l50.382-50.382a7.92 7.92 0 0111.195 0c3.085 3.086 3.092 8.105 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.317z\"/><path d=\"M64.053 124.069a7.889 7.889 0 01-5.6-2.316l-55.98-55.98a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0l50.382 50.382 50.382-50.382a7.92 7.92 0 0111.195 0c3.085 3.086 3.092 8.104 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.316z\"/></g></svg>"
},
"$:/core/images/chevron-left": {
"title": "$:/core/images/chevron-left",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-chevron-left tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M47.544 64.053c0-2.027.77-4.054 2.316-5.6l55.98-55.98a7.92 7.92 0 0111.196 0c3.085 3.086 3.092 8.105 0 11.196L66.656 64.05l50.382 50.382a7.92 7.92 0 010 11.195c-3.086 3.085-8.105 3.092-11.196 0l-55.98-55.98a7.892 7.892 0 01-2.317-5.595z\"/><path d=\"M8.931 64.053c0-2.027.77-4.054 2.316-5.6l55.98-55.98a7.92 7.92 0 0111.196 0c3.085 3.086 3.092 8.105 0 11.196L28.041 64.05l50.382 50.382a7.92 7.92 0 010 11.195c-3.086 3.085-8.104 3.092-11.196 0l-55.98-55.98a7.892 7.892 0 01-2.316-5.595z\"/></g></svg>"
},
"$:/core/images/chevron-right": {
"title": "$:/core/images/chevron-right",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-chevron-right tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M83.456 63.947c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196L64.344 63.95 13.963 13.567a7.92 7.92 0 010-11.195c3.086-3.085 8.105-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.317 5.595z\"/><path d=\"M122.069 63.947c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l50.382-50.382-50.382-50.382a7.92 7.92 0 010-11.195c3.086-3.085 8.104-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.316 5.595z\"/></g></svg>"
},
"$:/core/images/chevron-up": {
"title": "$:/core/images/chevron-up",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-chevron-up tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M63.947 44.544c2.027 0 4.054.77 5.6 2.316l55.98 55.98a7.92 7.92 0 010 11.196c-3.086 3.085-8.105 3.092-11.196 0L63.95 63.656l-50.382 50.382a7.92 7.92 0 01-11.195 0c-3.085-3.086-3.092-8.105 0-11.196l55.98-55.98a7.892 7.892 0 015.595-2.317z\"/><path d=\"M63.947 5.931c2.027 0 4.054.77 5.6 2.316l55.98 55.98a7.92 7.92 0 010 11.196c-3.086 3.085-8.105 3.092-11.196 0L63.95 25.041 13.567 75.423a7.92 7.92 0 01-11.195 0c-3.085-3.086-3.092-8.104 0-11.196l55.98-55.98a7.892 7.892 0 015.595-2.316z\"/></g></svg>"
},
"$:/core/images/clone-button": {
"title": "$:/core/images/clone-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-clone-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M32.265 96v24.002A7.996 7.996 0 0040.263 128h79.74a7.996 7.996 0 007.997-7.998v-79.74a7.996 7.996 0 00-7.998-7.997H96V48h12.859a2.99 2.99 0 012.994 2.994v57.865a2.99 2.99 0 01-2.994 2.994H50.994A2.99 2.99 0 0148 108.859V96H32.265z\"/><path d=\"M40 56h-7.993C27.588 56 24 52.418 24 48c0-4.41 3.585-8 8.007-8H40v-7.993C40 27.588 43.582 24 48 24c4.41 0 8 3.585 8 8.007V40h7.993C68.412 40 72 43.582 72 48c0 4.41-3.585 8-8.007 8H56v7.993C56 68.412 52.418 72 48 72c-4.41 0-8-3.585-8-8.007V56zM8 0C3.58 0 0 3.588 0 8v80c0 4.419 3.588 8 8 8h80c4.419 0 8-3.588 8-8V8c0-4.419-3.588-8-8-8H8zM19 16A2.997 2.997 0 0016 19.001v57.998A2.997 2.997 0 0019.001 80h57.998A2.997 2.997 0 0080 76.999V19.001A2.997 2.997 0 0076.999 16H19.001z\"/></g></svg>"
},
"$:/core/images/close-all-button": {
"title": "$:/core/images/close-all-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-close-all-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M28 111.314l-14.144 14.143a8 8 0 01-11.313-11.313L16.686 100 2.543 85.856a8 8 0 0111.313-11.313L28 88.686l14.144-14.143a8 8 0 0111.313 11.313L39.314 100l14.143 14.144a8 8 0 01-11.313 11.313L28 111.314zM28 39.314L13.856 53.457A8 8 0 012.543 42.144L16.686 28 2.543 13.856A8 8 0 0113.856 2.543L28 16.686 42.144 2.543a8 8 0 0111.313 11.313L39.314 28l14.143 14.144a8 8 0 01-11.313 11.313L28 39.314zM100 39.314L85.856 53.457a8 8 0 01-11.313-11.313L88.686 28 74.543 13.856A8 8 0 0185.856 2.543L100 16.686l14.144-14.143a8 8 0 0111.313 11.313L111.314 28l14.143 14.144a8 8 0 01-11.313 11.313L100 39.314zM100 111.314l-14.144 14.143a8 8 0 01-11.313-11.313L88.686 100 74.543 85.856a8 8 0 0111.313-11.313L100 88.686l14.144-14.143a8 8 0 0111.313 11.313L111.314 100l14.143 14.144a8 8 0 01-11.313 11.313L100 111.314z\"/></g></svg>"
},
"$:/core/images/close-button": {
"title": "$:/core/images/close-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-close-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M65.086 75.41l-50.113 50.113c-3.121 3.121-8.192 3.126-11.316.002-3.118-3.118-3.123-8.19.002-11.316l50.114-50.114L3.659 13.982C.538 10.86.533 5.79 3.657 2.666c3.118-3.118 8.19-3.123 11.316.002l50.113 50.114L115.2 2.668c3.121-3.121 8.192-3.126 11.316-.002 3.118 3.118 3.123 8.19-.002 11.316L76.4 64.095l50.114 50.114c3.121 3.121 3.126 8.192.002 11.316-3.118 3.118-8.19 3.123-11.316-.002L65.086 75.409z\"/></svg>"
},
"$:/core/images/close-others-button": {
"title": "$:/core/images/close-others-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-close-others-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 128c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 16 64 16 16 37.49 16 64s21.49 48 48 48zm0-16c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32zm0-16c8.837 0 16-7.163 16-16s-7.163-16-16-16-16 7.163-16 16 7.163 16 16 16z\"/></svg>"
},
"$:/core/images/copy-clipboard": {
"title": "$:/core/images/copy-clipboard",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-copy-clipboard tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"33\" height=\"8\" x=\"40\" y=\"40\" rx=\"4\"/><rect width=\"17\" height=\"8\" x=\"40\" y=\"82\" rx=\"4\"/><rect width=\"17\" height=\"8\" x=\"40\" y=\"54\" rx=\"4\"/><rect width=\"33\" height=\"8\" x=\"40\" y=\"96\" rx=\"4\"/><rect width=\"12\" height=\"8\" x=\"40\" y=\"68\" rx=\"4\"/><path d=\"M40 16H24c-4.419 0-8 3.59-8 8a8.031 8.031 0 000 .01v95.98a8.03 8.03 0 000 .01c0 4.41 3.581 8 8 8h80a7.975 7.975 0 005.652-2.34 7.958 7.958 0 002.348-5.652v-16.016c0-4.414-3.582-7.992-8-7.992-4.41 0-8 3.578-8 7.992V112H32V32h64v8.008C96 44.422 99.582 48 104 48c4.41 0 8-3.578 8-7.992V23.992a7.963 7.963 0 00-2.343-5.651A7.995 7.995 0 00104.001 16H88c0-4.41-3.585-8-8.007-8H48.007C43.588 8 40 11.582 40 16zm4-1.004A4.001 4.001 0 0148 11h32c2.21 0 4 1.797 4 3.996v4.008A4.001 4.001 0 0180 23H48c-2.21 0-4-1.797-4-3.996v-4.008z\"/><rect width=\"66\" height=\"16\" x=\"62\" y=\"64\" rx=\"8\"/><path d=\"M84.657 82.343l-16-16v11.314l16-16a8 8 0 10-11.314-11.314l-16 16a8 8 0 000 11.314l16 16a8 8 0 1011.314-11.314z\"/></g></svg>"
},
"$:/core/images/delete-button": {
"title": "$:/core/images/delete-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-delete-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\" transform=\"translate(12)\"><rect width=\"105\" height=\"16\" y=\"11\" rx=\"8\"/><rect width=\"48\" height=\"16\" x=\"28\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"8\" y=\"16\" rx=\"8\"/><rect width=\"88\" height=\"16\" x=\"8\" y=\"112\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"80\" y=\"16\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"56\" y=\"16\" rx=\"8\"/><rect width=\"16\" height=\"112\" x=\"32\" y=\"16\" rx=\"8\"/></g></svg>"
},
"$:/core/images/done-button": {
"title": "$:/core/images/done-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-done-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M42.26 111.032c-2.051.001-4.103-.78-5.668-2.345L2.662 74.758a8 8 0 01-.005-11.32c3.118-3.117 8.192-3.12 11.32.007l28.278 28.278 72.124-72.124a8.002 8.002 0 0111.314-.001c3.118 3.118 3.124 8.19 0 11.315l-77.78 77.78a7.978 7.978 0 01-5.658 2.343z\"/></svg>"
},
"$:/core/images/down-arrow": {
"title": "$:/core/images/down-arrow",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-down-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M64.177 100.069a7.889 7.889 0 01-5.6-2.316l-55.98-55.98a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0l50.382 50.382 50.382-50.382a7.92 7.92 0 0111.195 0c3.086 3.086 3.092 8.104 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.316z\"/></svg>"
},
"$:/core/images/download-button": {
"title": "$:/core/images/download-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-download-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M64 128c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 16 64 16 16 37.49 16 64s21.49 48 48 48z\" class=\"tc-image-download-button-ring\"/><path d=\"M34.35 66.43l26.892 27.205a4.57 4.57 0 006.516 0L94.65 66.43a4.7 4.7 0 000-6.593 4.581 4.581 0 00-3.258-1.365h-8.46c-2.545 0-4.608-2.087-4.608-4.661v-15.15c0-2.575-2.063-4.662-4.608-4.662H55.284c-2.545 0-4.608 2.087-4.608 4.662v15.15c0 2.574-2.063 4.661-4.608 4.661h-8.46c-2.545 0-4.608 2.087-4.608 4.662a4.69 4.69 0 001.35 3.296z\"/></g></svg>"
},
"$:/core/images/edit-button": {
"title": "$:/core/images/edit-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-edit-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M95.627 10.059l-5.656 5.657 11.313 11.313 5.657-5.656-11.314-11.314zm5.657-5.657l1.966-1.966c3.123-3.122 8.194-3.129 11.319-.005 3.117 3.118 3.122 8.192-.005 11.32l-1.966 1.965-11.314-11.314zm-16.97 16.97l-60.25 60.25a8.12 8.12 0 00-.322.342c-.1.087-.198.179-.295.275-5.735 5.735-10.702 22.016-10.702 22.016s16.405-5.09 22.016-10.702c.095-.096.186-.193.272-.292a8.12 8.12 0 00.345-.325l60.25-60.25-11.314-11.313zM35.171 124.19c6.788-.577 13.898-2.272 23.689-5.348 1.825-.573 3.57-1.136 6.336-2.04 16-5.226 21.877-6.807 28.745-7.146 8.358-.413 13.854 2.13 17.58 8.699a4 4 0 006.959-3.946c-5.334-9.406-13.745-13.296-24.933-12.744-7.875.39-14.057 2.052-30.835 7.533-2.739.894-4.46 1.45-6.25 2.012-19.46 6.112-30.77 7.072-39.597 1.747a4 4 0 10-4.132 6.85c6.333 3.82 13.754 5.12 22.438 4.383z\"/></g></svg>"
},
"$:/core/images/erase": {
"title": "$:/core/images/erase",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-erase tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M60.087 127.996l63.015-63.015c6.535-6.535 6.528-17.115-.003-23.646L99.466 17.702c-6.539-6.538-17.117-6.532-23.646-.003L4.898 88.62c-6.535 6.534-6.528 17.115.003 23.646l15.73 15.73h39.456zm-34.95-7.313l-14.324-14.325c-3.267-3.268-3.268-8.564-.008-11.824L46.269 59.07l35.462 35.462-26.15 26.15H25.137z\"/></svg>"
},
"$:/core/images/excise": {
"title": "$:/core/images/excise",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-excise tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M56 107.314l-2.343 2.343a8 8 0 11-11.314-11.314l16-16a8 8 0 0111.314 0l16 16a8 8 0 11-11.314 11.314L72 107.314v14.284c0 3.536-3.582 6.402-8 6.402s-8-2.866-8-6.402v-14.284zM0 40.007C0 35.585 3.59 32 8 32c4.418 0 8 3.588 8 8.007v31.986C16 76.415 12.41 80 8 80c-4.418 0-8-3.588-8-8.007V40.007zm32 0C32 35.585 35.59 32 40 32c4.418 0 8 3.588 8 8.007v31.986C48 76.415 44.41 80 40 80c-4.418 0-8-3.588-8-8.007V40.007zm48 0C80 35.585 83.59 32 88 32c4.418 0 8 3.588 8 8.007v31.986C96 76.415 92.41 80 88 80c-4.418 0-8-3.588-8-8.007V40.007zm-24-32C56 3.585 59.59 0 64 0c4.418 0 8 3.588 8 8.007v31.986C72 44.415 68.41 48 64 48c-4.418 0-8-3.588-8-8.007V8.007zm56 32c0-4.422 3.59-8.007 8-8.007 4.418 0 8 3.588 8 8.007v31.986c0 4.422-3.59 8.007-8 8.007-4.418 0-8-3.588-8-8.007V40.007z\"/></svg>"
},
"$:/core/images/export-button": {
"title": "$:/core/images/export-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-export-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.003 128H119.993a7.984 7.984 0 005.664-2.349v.007A7.975 7.975 0 00128 120V56c0-4.418-3.59-8-8-8-4.418 0-8 3.58-8 8v56H16V56c0-4.418-3.59-8-8-8-4.418 0-8 3.58-8 8v64c0 4.418 3.59 8 8 8h.003zm48.62-100.689l-8.965 8.966c-3.125 3.125-8.195 3.13-11.319.005-3.118-3.118-3.122-8.192.005-11.319L58.962 2.346A7.986 7.986 0 0164.625 0l-.006.002c2.05-.001 4.102.78 5.666 2.344l22.618 22.617c3.124 3.125 3.129 8.195.005 11.319-3.118 3.118-8.192 3.122-11.319-.005l-8.965-8.966v61.256c0 4.411-3.582 8-8 8-4.41 0-8-3.582-8-8V27.311z\"/></svg>"
},
"$:/core/images/file": {
"title": "$:/core/images/file",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-file tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M111.968 30.5H112V120a8 8 0 01-8 8H24a8 8 0 01-8-8V8a8 8 0 018-8h57v.02a7.978 7.978 0 015.998 2.337l22.627 22.627a7.975 7.975 0 012.343 5.516zM81 8H24v112h80V30.5H89c-4.418 0-8-3.578-8-8V8z\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"36\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"52\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"68\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"84\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"100\" rx=\"4\"/><rect width=\"40\" height=\"8\" x=\"32\" y=\"20\" rx=\"4\"/></svg>"
},
"$:/core/images/fixed-height": {
"title": "$:/core/images/fixed-height",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-fixed-height tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M60 35.657l-9.172 9.171a4 4 0 11-5.656-5.656l16-16a4 4 0 015.656 0l16 16a4 4 0 01-5.656 5.656L68 35.657v57.686l9.172-9.171a4 4 0 115.656 5.656l-16 16a4 4 0 01-5.656 0l-16-16a4 4 0 115.656-5.656L60 93.343V35.657zM16 116h96a4 4 0 100-8H16a4 4 0 100 8zm0-96h96a4 4 0 100-8H16a4 4 0 100 8z\"/></svg>"
},
"$:/core/images/fold-all-button": {
"title": "$:/core/images/fold-all-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-fold-all tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"64\" rx=\"8\"/><path d=\"M64.03 20.004c-2.05 0-4.102.78-5.667 2.344L35.746 44.966c-3.125 3.124-3.13 8.194-.005 11.318 3.118 3.118 8.192 3.122 11.319-.005l16.965-16.965 16.966 16.965c3.124 3.125 8.194 3.13 11.318.005 3.118-3.118 3.122-8.191-.005-11.318L69.687 22.348a7.986 7.986 0 00-5.663-2.346zM64.03 85.002c-2.05-.001-4.102.78-5.667 2.344l-22.617 22.617c-3.125 3.125-3.13 8.195-.005 11.319 3.118 3.118 8.192 3.122 11.319-.005l16.965-16.966 16.966 16.966c3.124 3.125 8.194 3.13 11.318.005 3.118-3.118 3.122-8.192-.005-11.319L69.687 87.346A7.986 7.986 0 0064.024 85z\"/></g></svg>"
},
"$:/core/images/fold-button": {
"title": "$:/core/images/fold-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-fold tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><path d=\"M64.03 25.004c-2.05 0-4.102.78-5.667 2.344L35.746 49.966c-3.125 3.124-3.13 8.194-.005 11.318 3.118 3.118 8.192 3.122 11.319-.005l16.965-16.965 16.966 16.965c3.124 3.125 8.194 3.13 11.318.005 3.118-3.118 3.122-8.191-.005-11.318L69.687 27.348a7.986 7.986 0 00-5.663-2.346zM64.005 67.379c-2.05 0-4.102.78-5.666 2.344L35.722 92.34c-3.125 3.125-3.13 8.195-.006 11.32 3.118 3.117 8.192 3.121 11.32-.006L64 86.69l16.965 16.965c3.125 3.125 8.195 3.13 11.319.005 3.118-3.118 3.122-8.192-.005-11.319L69.663 69.723A7.986 7.986 0 0064 67.377z\"/></g></svg>"
},
"$:/core/images/fold-others-button": {
"title": "$:/core/images/fold-others-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-fold-others tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" y=\"56.031\" rx=\"8\"/><path d=\"M86.632 79.976c-2.05 0-4.102.78-5.666 2.345L64 99.286 47.034 82.321a7.986 7.986 0 00-5.662-2.346l.005.001c-2.05 0-4.102.78-5.666 2.345l-22.618 22.617c-3.124 3.125-3.129 8.195-.005 11.319 3.118 3.118 8.192 3.122 11.319-.005l16.966-16.966 16.965 16.966a7.986 7.986 0 005.663 2.346l-.005-.002c2.05 0 4.102-.78 5.666-2.344l16.965-16.966 16.966 16.966c3.125 3.124 8.194 3.129 11.319.005 3.118-3.118 3.122-8.192-.005-11.319L92.289 82.321a7.986 7.986 0 00-5.663-2.346zM86.7 48.024c-2.05 0-4.102-.78-5.666-2.345L64.07 28.714 47.103 45.679a7.986 7.986 0 01-5.663 2.346l.005-.001c-2.05 0-4.101-.78-5.666-2.345L13.162 23.062c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.192-3.122 11.319.005L41.44 28.714l16.966-16.966a7.986 7.986 0 015.662-2.346l-.005.002c2.05 0 4.102.78 5.666 2.344l16.966 16.966 16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L92.358 45.679a7.986 7.986 0 01-5.663 2.346z\"/></g></svg>"
},
"$:/core/images/folder": {
"title": "$:/core/images/folder",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-folder tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M55.694 128H8C3.58 128 0 124.414 0 119.996V48.004C0 43.584 3.584 40 7.999 40H16v-8c0-4.418 3.578-8 8-8h32a8 8 0 018 8v8h40.001c4.418 0 7.999 3.586 7.999 8.004V59.83l-8-.082v-7.749A4 4 0 0099.997 48H56V36c0-2.21-1.793-4-4.004-4H28.004A4 4 0 0024 36v12H12.003A4 4 0 008 52v64a4 4 0 004.003 4h46.76l-3.069 8z\"/><path d=\"M23.873 55.5h96.003c4.417 0 7.004 4.053 5.774 9.063l-13.344 54.374c-1.228 5.005-5.808 9.063-10.223 9.063H6.08c-4.417 0-7.003-4.053-5.774-9.063L13.65 64.563c1.228-5.005 5.808-9.063 10.223-9.063zm1.78 8.5h87.994c2.211 0 3.504 2.093 2.891 4.666l-11.12 46.668c-.614 2.577-2.902 4.666-5.115 4.666H12.31c-2.211 0-3.504-2.093-2.891-4.666l11.12-46.668C21.152 66.09 23.44 64 25.653 64z\"/></g></svg>"
},
"$:/core/images/full-screen-button": {
"title": "$:/core/images/full-screen-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-full-screen-button tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M0 8a8 8 0 018-8h32a8 8 0 110 16H16v24a8 8 0 11-16 0V8zM128 120a8 8 0 01-8 8H88a8 8 0 110-16h24V88a8 8 0 1116 0v32zM8 128a8 8 0 01-8-8V88a8 8 0 1116 0v24h24a8 8 0 110 16H8zM120 0a8 8 0 018 8v32a8 8 0 11-16 0V16H88a8 8 0 110-16h32z\"/></svg>"
},
"$:/core/images/github": {
"title": "$:/core/images/github",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-github tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M63.938 1.607c-35.336 0-63.994 28.69-63.994 64.084 0 28.312 18.336 52.329 43.768 60.802 3.202.59 4.37-1.388 4.37-3.088 0-1.518-.056-5.55-.087-10.897-17.802 3.871-21.558-8.591-21.558-8.591-2.911-7.404-7.108-9.375-7.108-9.375-5.81-3.973.44-3.895.44-3.895 6.424.453 9.803 6.606 9.803 6.606 5.709 9.791 14.981 6.963 18.627 5.322.582-4.138 2.236-6.963 4.063-8.564-14.211-1.617-29.153-7.117-29.153-31.672 0-6.995 2.495-12.718 6.589-17.195-.66-1.621-2.856-8.14.629-16.96 0 0 5.37-1.722 17.597 6.57 5.104-1.424 10.58-2.132 16.022-2.16 5.438.028 10.91.736 16.022 2.16 12.22-8.292 17.582-6.57 17.582-6.57 3.493 8.82 1.297 15.339.64 16.96 4.102 4.477 6.578 10.2 6.578 17.195 0 24.618-14.966 30.035-29.22 31.62 2.295 1.98 4.342 5.89 4.342 11.87 0 8.564-.079 15.476-.079 17.576 0 1.715 1.155 3.71 4.4 3.084 25.413-8.493 43.733-32.494 43.733-60.798 0-35.394-28.657-64.084-64.006-64.084\"/></svg>"
},
"$:/core/images/gitter": {
"title": "$:/core/images/gitter",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-gitter tc-image-button\" viewBox=\"0 0 18 25\"><path d=\"M15 5h2v10h-2zM10 5h2v20h-2zM5 5h2v20H5zM0 0h2v15H0z\"/></svg>"
},
"$:/core/images/globe": {
"title": "$:/core/images/globe",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-globe tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M72.811 37.128v2.554c0 2.196.978 6.881 0 8.832-1.466 2.928-4.65 3.54-6.394 5.867-1.182 1.577-4.618 10.601-3.69 12.92 3.969 9.922 11.534 3.187 17.962 9.293.864.821 2.887 2.273 3.296 3.296 3.29 8.223-7.576 15.009 3.757 26.3 1.245 1.24 3.813-3.817 4.079-4.614.852-2.563 6.725-5.45 9.088-7.053 2.02-1.37 4.873-2.667 6.328-4.745 2.27-3.244 1.48-7.514 3.098-10.745 2.139-4.274 3.828-9.635 5.998-13.966 3.898-7.781 4.721 2.093 5.067 2.439.358.357 1.011 0 1.517 0 .094 0 1.447.099 1.516 0 .65-.935-1.043-17.92-1.318-19.297-1.404-7.01-6.944-15.781-11.865-20.5-6.274-6.015-7.09-16.197-18.259-14.954-.204.022-5.084 10.148-7.777 13.512-3.728 4.657-2.47-4.153-6.526-4.153-.081 0-1.183-.103-1.253 0-.586.88-1.44 3.896-2.306 4.417-.265.16-1.722-.239-1.846 0-2.243 4.3 8.256 2.212 5.792 7.952-2.352 5.481-6.328-1.997-6.328 8.56M44.467 7.01c9.685 6.13.682 12.198 2.694 16.215 1.655 3.303 4.241 5.395 1.714 9.814-2.063 3.608-6.87 3.966-9.623 6.723-3.04 3.044-5.464 8.94-6.79 12.911-1.617 4.843 14.547 6.866 12.063 11.008-1.386 2.311-6.746 1.466-8.437.198-1.165-.873-3.593-.546-4.417-1.78-2.613-3.915-2.26-8.023-3.625-12.128-.938-2.822-6.313-2.12-7.844-.593-.523.522-.33 1.792-.33 2.505 0 5.285 7.12 3.316 7.12 6.46 0 14.636 3.927 6.534 11.14 11.336 10.036 6.683 7.844 7.303 14.946 14.404 3.673 3.673 7.741 3.686 9.425 9.294 1.602 5.331-9.327 5.339-11.716 7.448-1.123.991-2.813 4.146-4.219 4.615-1.792.598-3.234.496-4.944 1.78-2.427 1.82-3.9 4.932-4.02 4.81-2.148-2.147-3.52-15.479-3.89-18.257-.588-4.42-5.59-5.54-6.986-9.03-1.57-3.927 1.524-9.52-1.129-13.761-6.52-10.424-11.821-14.5-15.35-26.292-.942-3.148 3.342-6.529 4.877-8.833 1.877-2.816 2.662-5.854 4.746-8.635C22.147 24.19 40.855 9.461 43.857 8.635l.61-1.625z\"/><path d=\"M64 126c34.242 0 62-27.758 62-62 0-34.242-27.758-62-62-62C29.758 2 2 29.758 2 64c0 34.242 27.758 62 62 62zm0-6c30.928 0 56-25.072 56-56S94.928 8 64 8 8 33.072 8 64s25.072 56 56 56z\"/></g></svg>"
},
"$:/core/images/heading-1": {
"title": "$:/core/images/heading-1",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-heading-1 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M14 30h13.25v30.104H61.7V30h13.25v75.684H61.7V71.552H27.25v34.132H14V30zm70.335 13.78c2.544 0 5.017-.212 7.42-.636 2.403-.424 4.576-1.13 6.52-2.12 1.942-.99 3.603-2.261 4.981-3.816 1.378-1.555 2.28-3.463 2.703-5.724h9.858v74.2h-13.25V53.32H84.335v-9.54z\"/></svg>"
},
"$:/core/images/heading-2": {
"title": "$:/core/images/heading-2",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-heading-2 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm119.52 75.684H74.85c.07-6.148 1.555-11.519 4.452-16.112 2.897-4.593 6.855-8.586 11.872-11.978a133.725 133.725 0 017.526-5.141 59.6 59.6 0 007.208-5.353c2.19-1.908 3.993-3.975 5.406-6.201 1.413-2.226 2.155-4.788 2.226-7.685 0-1.343-.159-2.774-.477-4.293a11.357 11.357 0 00-1.855-4.24c-.919-1.307-2.19-2.403-3.816-3.286-1.625-.883-3.745-1.325-6.36-1.325-2.403 0-4.399.477-5.989 1.431-1.59.954-2.862 2.261-3.816 3.922-.954 1.66-1.66 3.622-2.12 5.883-.46 2.261-.724 4.7-.795 7.314H76.23c0-4.099.548-7.897 1.643-11.395 1.095-3.498 2.738-6.519 4.93-9.063 2.19-2.544 4.857-4.54 8.002-5.989C93.95 30.724 97.606 30 101.775 30c4.523 0 8.303.742 11.342 2.226 3.039 1.484 5.494 3.357 7.367 5.618 1.873 2.261 3.198 4.717 3.975 7.367.777 2.65 1.166 5.176 1.166 7.579 0 2.968-.46 5.653-1.378 8.056a25.942 25.942 0 01-3.71 6.625 37.5 37.5 0 01-5.3 5.565 79.468 79.468 0 01-6.148 4.77 165.627 165.627 0 01-6.36 4.24 94.28 94.28 0 00-5.883 4.028c-1.802 1.343-3.374 2.738-4.717 4.187-1.343 1.449-2.261 2.986-2.756 4.611h36.146v10.812z\"/></svg>"
},
"$:/core/images/heading-3": {
"title": "$:/core/images/heading-3",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-heading-3 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm88.885 32.224c1.979.07 3.957-.07 5.936-.424 1.979-.353 3.745-.972 5.3-1.855a10.365 10.365 0 003.763-3.657c.954-1.555 1.431-3.463 1.431-5.724 0-3.18-1.078-5.724-3.233-7.632-2.155-1.908-4.929-2.862-8.32-2.862-2.12 0-3.958.424-5.513 1.272a11.318 11.318 0 00-3.869 3.445c-1.025 1.449-1.784 3.074-2.279 4.876a18.335 18.335 0 00-.636 5.565H75.381c.141-3.604.813-6.943 2.014-10.017 1.201-3.074 2.844-5.742 4.93-8.003 2.084-2.261 4.61-4.028 7.578-5.3C92.871 30.636 96.228 30 99.973 30a29.2 29.2 0 018.533 1.272c2.791.848 5.3 2.085 7.526 3.71s4.01 3.692 5.353 6.201c1.343 2.509 2.014 5.388 2.014 8.639 0 3.745-.848 7.014-2.544 9.805-1.696 2.791-4.346 4.823-7.95 6.095v.212c4.24.848 7.544 2.95 9.911 6.307s3.551 7.438 3.551 12.243c0 3.533-.707 6.696-2.12 9.487a21.538 21.538 0 01-5.724 7.102c-2.403 1.943-5.194 3.445-8.374 4.505-3.18 1.06-6.537 1.59-10.07 1.59-4.31 0-8.074-.618-11.289-1.855s-5.9-2.986-8.056-5.247c-2.155-2.261-3.798-4.982-4.929-8.162-1.13-3.18-1.731-6.713-1.802-10.6h12.084c-.141 4.523.972 8.286 3.34 11.289 2.366 3.003 5.917 4.505 10.652 4.505 4.028 0 7.402-1.148 10.123-3.445 2.72-2.297 4.081-5.565 4.081-9.805 0-2.897-.565-5.194-1.696-6.89a10.97 10.97 0 00-4.452-3.869c-1.837-.883-3.904-1.431-6.2-1.643a58.067 58.067 0 00-7.05-.212v-9.01z\"/></svg>"
},
"$:/core/images/heading-4": {
"title": "$:/core/images/heading-4",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-heading-4 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8 30h13.25v30.104H55.7V30h13.25v75.684H55.7V71.552H21.25v34.132H8V30zm76.59 48.548h22.471V45.9h-.212L84.59 78.548zm43.46 9.54h-9.54v17.596H107.06V88.088h-31.8V76.11l31.8-44.626h11.448v47.064h9.54v9.54z\"/></svg>"
},
"$:/core/images/heading-5": {
"title": "$:/core/images/heading-5",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-heading-5 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm77.755 1.484h38.372v10.812H92.765L88.95 61.164l.212.212c1.625-1.837 3.692-3.233 6.201-4.187 2.509-.954 5-1.431 7.473-1.431 3.675 0 6.96.618 9.858 1.855 2.897 1.237 5.335 2.968 7.314 5.194s3.48 4.858 4.505 7.897c1.025 3.039 1.537 6.325 1.537 9.858 0 2.968-.477 6.024-1.43 9.169a25.161 25.161 0 01-4.559 8.586c-2.085 2.58-4.752 4.7-8.003 6.36-3.25 1.66-7.137 2.491-11.66 2.491-3.604 0-6.943-.477-10.017-1.431-3.074-.954-5.777-2.385-8.109-4.293-2.332-1.908-4.187-4.258-5.565-7.049-1.378-2.791-2.138-6.06-2.279-9.805h12.084c.353 4.028 1.731 7.12 4.134 9.275 2.403 2.155 5.583 3.233 9.54 3.233 2.544 0 4.7-.424 6.466-1.272 1.767-.848 3.198-2.014 4.293-3.498 1.095-1.484 1.873-3.215 2.332-5.194.46-1.979.69-4.099.69-6.36 0-2.05-.284-4.01-.849-5.883-.565-1.873-1.413-3.516-2.544-4.929-1.13-1.413-2.597-2.544-4.399-3.392-1.802-.848-3.904-1.272-6.307-1.272-2.544 0-4.929.477-7.155 1.431-2.226.954-3.834 2.738-4.823 5.353H75.805l7.95-40.598z\"/></svg>"
},
"$:/core/images/heading-6": {
"title": "$:/core/images/heading-6",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-heading-6 tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M6 30h13.25v30.104H53.7V30h13.25v75.684H53.7V71.552H19.25v34.132H6V30zm106.587 20.246c-.283-3.039-1.36-5.494-3.233-7.367-1.873-1.873-4.399-2.809-7.579-2.809-2.19 0-4.08.406-5.67 1.219a12.435 12.435 0 00-4.029 3.233c-1.095 1.343-1.979 2.88-2.65 4.611a37.696 37.696 0 00-1.643 5.459 46.08 46.08 0 00-.9 5.671 722.213 722.213 0 00-.478 5.247l.212.212c1.625-2.968 3.87-5.176 6.731-6.625 2.862-1.449 5.954-2.173 9.275-2.173 3.675 0 6.96.636 9.858 1.908 2.897 1.272 5.353 3.021 7.367 5.247 2.014 2.226 3.551 4.858 4.611 7.897 1.06 3.039 1.59 6.325 1.59 9.858 0 3.604-.583 6.943-1.749 10.017-1.166 3.074-2.844 5.76-5.035 8.056-2.19 2.297-4.805 4.081-7.844 5.353-3.039 1.272-6.395 1.908-10.07 1.908-5.441 0-9.91-1.007-13.409-3.021-3.498-2.014-6.254-4.77-8.268-8.268-2.014-3.498-3.41-7.597-4.187-12.296-.777-4.7-1.166-9.77-1.166-15.211 0-4.452.477-8.94 1.431-13.462.954-4.523 2.526-8.639 4.717-12.349 2.19-3.71 5.07-6.731 8.64-9.063C92.676 31.166 97.075 30 102.304 30c2.968 0 5.76.495 8.374 1.484 2.615.99 4.93 2.367 6.943 4.134 2.014 1.767 3.657 3.887 4.93 6.36 1.271 2.473 1.978 5.23 2.12 8.268h-12.085zm-11.66 46.852c2.19 0 4.099-.442 5.724-1.325a12.869 12.869 0 004.081-3.445c1.095-1.413 1.908-3.056 2.438-4.929.53-1.873.795-3.798.795-5.777s-.265-3.887-.795-5.724c-.53-1.837-1.343-3.445-2.438-4.823-1.095-1.378-2.456-2.491-4.08-3.339-1.626-.848-3.534-1.272-5.725-1.272-2.19 0-4.116.406-5.777 1.219-1.66.813-3.056 1.908-4.187 3.286-1.13 1.378-1.979 2.986-2.544 4.823-.565 1.837-.848 3.78-.848 5.83 0 2.05.283 3.993.848 5.83.565 1.837 1.413 3.48 2.544 4.929a12.39 12.39 0 004.187 3.445c1.66.848 3.586 1.272 5.777 1.272z\"/></svg>"
},
"$:/core/images/help": {
"title": "$:/core/images/help",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-help tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M36.055 111.441c-5.24 4.396-15.168 7.362-26.555 7.362-1.635 0-3.24-.06-4.806-.179 7.919-2.64 14.062-8.6 16.367-16.014C8.747 92.845 1.05 78.936 1.05 63.5c0-29.547 28.206-53.5 63-53.5s63 23.953 63 53.5-28.206 53.5-63 53.5c-10.055 0-19.56-2-27.994-5.559zm35.35-33.843a536.471 536.471 0 00.018-4.682 199.02 199.02 0 00-.023-3.042c.008-1.357.595-2.087 3.727-4.235.112-.077 1.085-.74 1.386-.948 3.093-2.133 5.022-3.786 6.762-6.187 2.34-3.228 3.558-7.077 3.558-11.649 0-13.292-9.86-21.952-21.455-21.952-11.103 0-22.499 9.609-24.066 22.295a6.023 6.023 0 1011.956 1.477c.806-6.527 6.972-11.726 12.11-11.726 5.265 0 9.408 3.64 9.408 9.906 0 3.634-1.1 5.153-5.111 7.919l-1.362.93c-2.682 1.84-4.227 3.1-5.7 4.931-2.109 2.62-3.242 5.717-3.258 9.314.013.892.02 1.86.022 2.981a470.766 470.766 0 01-.022 4.943 6.023 6.023 0 1012.046.12l.003-.395zm-6.027 24.499a7.529 7.529 0 100-15.058 7.529 7.529 0 000 15.058z\"/></svg>"
},
"$:/core/images/home-button": {
"title": "$:/core/images/home-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-home-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M112.985 119.502c.01-.165.015-.331.015-.499V67.568c3.137 2.948 8.076 2.884 11.134-.174a7.999 7.999 0 00-.002-11.316L70.396 2.343A7.978 7.978 0 0064.734 0a7.957 7.957 0 00-5.656 2.343L33 28.42V8.007C33 3.585 29.41 0 25 0c-4.418 0-8 3.59-8 8.007V44.42L5.342 56.078c-3.125 3.125-3.12 8.198-.002 11.316a7.999 7.999 0 0011.316-.003l.344-.343v52.945a8.11 8.11 0 000 .007c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8a8.11 8.11 0 00-.015-.498zM97 112V51.574L64.737 19.31 33 51.048V112h64z\"/></svg>"
},
"$:/core/images/import-button": {
"title": "$:/core/images/import-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-import-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M114.832 60.436s3.235-3.27 6.921.417c3.686 3.686.231 7.14.231 7.14l-42.153 42.92s-30.765 32.367-58.798 4.333C-7 87.213 24.59 55.623 24.59 55.623L67.363 12.85s22.725-24.6 43.587-3.738c20.862 20.862-3.96 43.09-3.96 43.09l-35.04 35.04S49.903 112.546 36.426 99.07c-13.476-13.477 11.83-35.523 11.83-35.523l35.04-35.04s3.902-3.902 7.78-.023c3.879 3.878.118 7.921.118 7.921l-35.04 35.04s-13.212 13.212-8.872 17.551c4.34 4.34 16.77-9.653 16.77-9.653l35.04-35.04s16.668-14.598 3.966-27.3c-13.893-13.892-27.565 3.702-27.565 3.702l-42.91 42.91s-23.698 23.698-3.658 43.738 43.012-4.385 43.012-4.385l42.895-42.533z\"/></svg>"
},
"$:/core/images/info-button": {
"title": "$:/core/images/info-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-info-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\" transform=\"translate(.05)\"><path d=\"M64 128c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64c0 35.346 28.654 64 64 64zm0-16c26.51 0 48-21.49 48-48S90.51 16 64 16 16 37.49 16 64s21.49 48 48 48z\"/><circle cx=\"64\" cy=\"32\" r=\"8\"/><rect width=\"16\" height=\"56\" x=\"56\" y=\"48\" rx=\"8\"/></g></svg>"
},
"$:/core/images/italic": {
"title": "$:/core/images/italic",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-italic tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M66.711 0h22.41L62.408 128H40z\"/></svg>"
},
"$:/core/images/left-arrow": {
"title": "$:/core/images/left-arrow",
"created": "20150315234410875",
"modified": "20150315235324760",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-left-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M0 64.177c0-2.026.771-4.054 2.317-5.6l55.98-55.98a7.92 7.92 0 0111.195.001c3.086 3.085 3.092 8.104.001 11.195L19.111 64.175l50.382 50.382a7.92 7.92 0 010 11.195c-3.086 3.086-8.105 3.092-11.196.001l-55.98-55.98A7.892 7.892 0 010 64.177z\"/></svg>"
},
"$:/core/images/line-width": {
"title": "$:/core/images/line-width",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-line-width tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M16 18h96a2 2 0 000-4H16a2 2 0 100 4zm0 17h96a4 4 0 100-8H16a4 4 0 100 8zm0 21h96a6 6 0 000-12H16a6 6 0 100 12zm0 29h96c5.523 0 10-4.477 10-10s-4.477-10-10-10H16c-5.523 0-10 4.477-10 10s4.477 10 10 10zm0 43h96c8.837 0 16-7.163 16-16s-7.163-16-16-16H16c-8.837 0-16 7.163-16 16s7.163 16 16 16z\"/></svg>"
},
"$:/core/images/link": {
"title": "$:/core/images/link",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-link tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M42.263 69.38a31.919 31.919 0 006.841 10.13c12.5 12.5 32.758 12.496 45.255 0l22.627-22.628c12.502-12.501 12.497-32.758 0-45.255-12.5-12.5-32.758-12.496-45.254 0L49.104 34.255a32.333 32.333 0 00-2.666 3.019 36.156 36.156 0 0121.94.334l14.663-14.663c6.25-6.25 16.382-6.254 22.632-.004 6.248 6.249 6.254 16.373-.004 22.631l-22.62 22.62c-6.25 6.25-16.381 6.254-22.631.004a15.93 15.93 0 01-4.428-8.433 11.948 11.948 0 00-7.59 3.48l-6.137 6.137z\"/><path d=\"M86.35 59.234a31.919 31.919 0 00-6.84-10.13c-12.5-12.5-32.758-12.497-45.255 0L11.627 71.732c-12.501 12.5-12.496 32.758 0 45.254 12.5 12.5 32.758 12.497 45.255 0L79.51 94.36a32.333 32.333 0 002.665-3.02 36.156 36.156 0 01-21.94-.333l-14.663 14.663c-6.25 6.25-16.381 6.253-22.63.004-6.25-6.249-6.255-16.374.003-22.632l22.62-22.62c6.25-6.25 16.381-6.253 22.631-.003a15.93 15.93 0 014.428 8.432 11.948 11.948 0 007.59-3.48l6.137-6.136z\"/></g></svg>"
},
"$:/core/images/linkify": {
"title": "$:/core/images/linkify",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-linkify-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M17.031 31.919H9.048V96.85h7.983v6.92H0V25h17.031v6.919zm24.66 0h-7.983V96.85h7.983v6.92H24.66V25h17.03v6.919zM67.77 56.422l11.975-3.903 2.306 7.096-12.063 3.903 7.628 10.379-6.12 4.435-7.63-10.467-7.45 10.2-5.943-4.523L58.1 63.518 45.95 59.35l2.306-7.096 12.064 4.17V43.825h7.45v12.596zM86.31 96.85h7.982V31.92H86.31V25h17.031v78.77H86.31v-6.92zm24.659 0h7.983V31.92h-7.983V25H128v78.77h-17.031v-6.92z\"/></svg>"
},
"$:/core/images/list-bullet": {
"title": "$:/core/images/list-bullet",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-list-bullet tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M11.636 40.273c6.427 0 11.637-5.21 11.637-11.637C23.273 22.21 18.063 17 11.636 17 5.21 17 0 22.21 0 28.636c0 6.427 5.21 11.637 11.636 11.637zm0 34.909c6.427 0 11.637-5.21 11.637-11.637 0-6.426-5.21-11.636-11.637-11.636C5.21 51.91 0 57.12 0 63.545c0 6.427 5.21 11.637 11.636 11.637zm0 34.909c6.427 0 11.637-5.21 11.637-11.636 0-6.427-5.21-11.637-11.637-11.637C5.21 86.818 0 92.028 0 98.455c0 6.426 5.21 11.636 11.636 11.636zM34.91 22.818H128v11.637H34.91V22.818zm0 34.91H128v11.636H34.91V57.727zm0 34.908H128v11.637H34.91V92.636z\"/></svg>"
},
"$:/core/images/list-number": {
"title": "$:/core/images/list-number",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-list-number tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M33.84 22.356H128v11.77H33.84v-11.77zm0 35.31H128v11.77H33.84v-11.77zm0 35.311H128v11.77H33.84v-11.77zM.38 42.631v-2.223h.998c.826 0 1.445-.14 1.858-.42.413-.28.619-.948.619-2.002V22.769c0-1.442-.193-2.336-.58-2.683-.385-.347-1.477-.52-3.275-.52v-2.143c3.502-.147 6.252-.955 8.25-2.423h2.117v22.865c0 .921.15 1.575.449 1.963.3.387.949.58 1.948.58h.998v2.223H.38zm-.3 35.356v-1.902c7.19-6.554 10.786-12.58 10.786-18.08 0-1.562-.326-2.81-.979-3.744-.652-.934-1.524-1.402-2.616-1.402-.893 0-1.655.317-2.287.952-.633.634-.95 1.364-.95 2.192 0 .974.247 1.829.74 2.563.106.16.16.28.16.36 0 .147-.16.28-.48.4-.213.08-.752.308-1.618.681-.839.374-1.358.561-1.558.561-.24 0-.512-.37-.819-1.111A6.2 6.2 0 010 57.064c0-1.949.849-3.544 2.547-4.785 1.698-1.242 3.798-1.862 6.302-1.862 2.463 0 4.53.67 6.202 2.012 1.67 1.341 2.506 3.093 2.506 5.256a8.644 8.644 0 01-.849 3.724c-.566 1.201-1.92 3.053-4.064 5.556a165.471 165.471 0 01-6.272 6.938h11.445l-1.019 5.726h-2.117c.08-.28.12-.534.12-.76 0-.388-.1-.631-.3-.731-.2-.1-.599-.15-1.198-.15H.08zm12.124 19.207c1.745.04 3.236.637 4.474 1.792 1.239 1.154 1.858 2.773 1.858 4.855 0 2.99-1.132 5.393-3.396 7.208-2.263 1.815-5 2.723-8.209 2.723-2.01 0-3.669-.384-4.974-1.151C.652 111.853 0 110.849 0 109.607c0-.774.27-1.398.809-1.872.54-.474 1.128-.71 1.768-.71.639 0 1.162.2 1.568.6.406.4.782 1.055 1.128 1.962.466 1.268 1.239 1.902 2.317 1.902 1.265 0 2.287-.477 3.066-1.431.78-.955 1.169-2.686 1.169-5.196 0-1.709-.12-3.023-.36-3.944-.24-.921-.792-1.382-1.658-1.382-.586 0-1.185.307-1.797.921-.493.494-.932.741-1.319.741-.333 0-.602-.147-.809-.44-.206-.294-.31-.574-.31-.841 0-.32.104-.594.31-.821.207-.227.69-.594 1.449-1.102 2.876-1.922 4.314-4.017 4.314-6.287 0-1.188-.306-2.092-.919-2.713a3.001 3.001 0 00-2.217-.93c-.799 0-1.525.263-2.177.79-.653.528-.979 1.158-.979 1.892 0 .641.253 1.235.76 1.782.172.2.259.367.259.5 0 .121-.57.428-1.708.922-1.139.494-1.854.74-2.147.74-.413 0-.75-.333-1.009-1-.26-.668-.39-1.282-.39-1.842 0-1.749.93-3.224 2.787-4.425 1.858-1.202 3.965-1.802 6.322-1.802 2.064 0 3.851.447 5.363 1.341 1.511.895 2.267 2.116 2.267 3.664 0 1.362-.57 2.623-1.708 3.784a13.387 13.387 0 01-3.945 2.784z\"/></svg>"
},
"$:/core/images/list": {
"title": "$:/core/images/list",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-list tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M87.748 128H23.999c-4.418 0-7.999-3.59-7.999-8.007V8.007C16 3.585 19.588 0 24 0h80c4.419 0 8 3.59 8 8.007V104H91.25c-.965 0-1.84.392-2.473 1.025a3.476 3.476 0 00-1.029 2.476V128zm8-.12l15.88-15.88h-15.88v15.88zM40 15.508A3.502 3.502 0 0143.5 12h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 20h-55a3.498 3.498 0 01-3.5-3.509v-.982zM32 22a6 6 0 100-12 6 6 0 000 12zm8 9.509A3.502 3.502 0 0143.5 28h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 36h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 44h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 52h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 60h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 68h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 76h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 84h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.502 3.502 0 0143.5 92h55c1.933 0 3.5 1.561 3.5 3.509v.982A3.502 3.502 0 0198.5 100h-55a3.498 3.498 0 01-3.5-3.509v-.982zm0 16A3.505 3.505 0 0143.497 108h33.006A3.497 3.497 0 0180 111.509v.982A3.505 3.505 0 0176.503 116H43.497A3.497 3.497 0 0140 112.491v-.982zM32 38a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12zm0 16a6 6 0 100-12 6 6 0 000 12z\"/></svg>"
},
"$:/core/images/locked-padlock": {
"title": "$:/core/images/locked-padlock",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-locked-padlock tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M96.472 64H105v32.01C105 113.674 90.674 128 73.001 128H56C38.318 128 24 113.677 24 96.01V64h8c.003-15.723.303-47.731 32.16-47.731 31.794 0 32.305 32.057 32.312 47.731zm-15.897 0H48.44c.002-16.287.142-32 15.719-32 15.684 0 16.977 16.136 16.415 32zM67.732 92.364A8.503 8.503 0 0064.5 76a8.5 8.5 0 00-3.498 16.25l-5.095 22.77H72.8l-5.07-22.656z\"/></svg>"
},
"$:/core/images/mail": {
"title": "$:/core/images/mail",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-mail tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M122.827 104.894a7.986 7.986 0 01-2.834.516H8.007c-.812 0-1.597-.12-2.335-.345l34.163-34.163 20.842 20.842a3.998 3.998 0 003.418 1.134 4.003 4.003 0 003.395-1.134L88.594 70.64c.075.09.155.176.24.26l33.993 33.994zm5.076-6.237c.064-.406.097-.823.097-1.247v-64c0-.669-.082-1.318-.237-1.94L94.23 65.006c.09.075.177.154.261.239l33.413 33.413zm-127.698.56A8.023 8.023 0 010 97.41v-64c0-.716.094-1.41.271-2.071l33.907 33.906L.205 99.218zM5.93 25.684a8.012 8.012 0 012.078-.273h111.986c.766 0 1.507.108 2.209.308L64.083 83.837 5.93 25.683z\"/></svg>"
},
"$:/core/images/menu-button": {
"title": "$:/core/images/menu-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-menu-button tc-image-button\" viewBox=\"0 0 128 128\"><rect width=\"128\" height=\"16\" y=\"16\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"56\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"96\" rx=\"8\"/></svg>"
},
"$:/core/images/mono-block": {
"title": "$:/core/images/mono-block",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-mono-block tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M23.965 32.967h.357c.755 0 1.328.192 1.72.577.39.384.586.947.586 1.688 0 .824-.206 1.418-.618 1.782-.413.363-1.094.545-2.045.545h-6.31c-.965 0-1.65-.178-2.056-.535-.405-.356-.608-.954-.608-1.792 0-.811.203-1.391.608-1.74.406-.35 1.09-.525 2.055-.525h.734l-.86-2.453H8.471l-.902 2.453h.734c.95 0 1.632.178 2.044.535.413.356.619.933.619 1.73 0 .824-.206 1.418-.619 1.782-.412.363-1.094.545-2.044.545h-5.41c-.964 0-1.649-.182-2.054-.545-.406-.364-.608-.958-.608-1.782 0-.741.195-1.304.587-1.688.391-.385.964-.577 1.719-.577h.356l5.62-15.641H6.835c-.95 0-1.632-.182-2.044-.546-.412-.363-.619-.95-.619-1.76 0-.825.207-1.42.619-1.783.412-.363 1.094-.545 2.044-.545h7.863c1.244 0 2.118.67 2.62 2.013v.063l6.647 18.2zM12.98 17.326l-3.04 8.848h6.08l-3.04-8.848zm22.402 9.372v6.395h3.145c2.223 0 3.788-.245 4.697-.734.908-.49 1.362-1.307 1.362-2.453 0-1.16-.433-1.985-1.3-2.474-.866-.49-2.383-.734-4.55-.734h-3.354zm10.693-2.327c1.524.559 2.642 1.324 3.355 2.295.713.972 1.07 2.212 1.07 3.722 0 1.272-.308 2.432-.923 3.48-.615 1.049-1.496 1.909-2.642 2.58a7.499 7.499 0 01-2.254.849c-.832.174-2.01.262-3.533.262H30.202c-.922 0-1.583-.182-1.981-.545-.399-.364-.598-.958-.598-1.782 0-.741.189-1.304.566-1.688.378-.385.93-.577 1.657-.577h.356V17.326h-.356c-.727 0-1.28-.196-1.657-.587-.377-.392-.566-.965-.566-1.72 0-.81.203-1.401.608-1.771.406-.37 1.062-.556 1.971-.556h9.645c2.95 0 5.19.573 6.72 1.72 1.53 1.145 2.296 2.823 2.296 5.031 0 1.09-.234 2.052-.703 2.883-.468.832-1.163 1.513-2.086 2.045zM35.381 17.2v5.284h2.83c1.72 0 2.932-.203 3.638-.609.706-.405 1.06-1.09 1.06-2.054 0-.909-.319-1.573-.955-1.992-.636-.42-1.667-.63-3.093-.63h-3.48zm35.863-3.816c.28-.503.566-.86.86-1.07.293-.21.664-.314 1.111-.314.685 0 1.17.182 1.457.545.287.364.43.986.43 1.866l.042 5.452c0 .964-.157 1.614-.472 1.95-.314.335-.884.503-1.709.503-.587 0-1.037-.14-1.352-.42-.314-.28-.584-.796-.807-1.551-.364-1.328-.944-2.282-1.74-2.862-.797-.58-1.901-.87-3.313-.87-2.153 0-3.802.727-4.948 2.18-1.147 1.454-1.72 3.558-1.72 6.311 0 2.74.58 4.844 1.74 6.311 1.16 1.468 2.817 2.202 4.97 2.202 1.467 0 3.085-.49 4.854-1.468 1.768-.978 2.883-1.467 3.344-1.467.545 0 1.003.23 1.373.692.37.46.556 1.034.556 1.719 0 1.23-1.084 2.39-3.25 3.48-2.167 1.09-4.606 1.636-7.318 1.636-3.662 0-6.625-1.21-8.89-3.627-2.264-2.419-3.396-5.578-3.396-9.478 0-3.76 1.146-6.884 3.438-9.372 2.293-2.488 5.2-3.732 8.723-3.732.992 0 1.97.112 2.935.335.964.224 1.992.574 3.082 1.049zm10.22 19.583V17.326h-.356c-.755 0-1.328-.196-1.72-.587-.39-.392-.586-.965-.586-1.72 0-.81.21-1.401.629-1.771.42-.37 1.097-.556 2.034-.556h5.178c2.922 0 5.06.126 6.416.377 1.356.252 2.51.671 3.46 1.258 1.691 1.007 2.988 2.443 3.89 4.31.9 1.865 1.352 4.021 1.352 6.467 0 2.586-.514 4.847-1.541 6.783-1.028 1.936-2.485 3.4-4.372 4.393-.853.447-1.852.772-2.998.975-1.147.203-2.852.304-5.116.304h-6.269c-.965 0-1.65-.178-2.055-.535-.406-.356-.608-.954-.608-1.792 0-.741.195-1.304.587-1.688.391-.385.964-.577 1.72-.577h.356zm5.41-15.725v15.725h1.195c2.642 0 4.592-.646 5.85-1.94 1.258-1.292 1.887-3.28 1.887-5.965 0-2.641-.64-4.612-1.918-5.912-1.28-1.3-3.205-1.95-5.777-1.95-.335 0-.59.003-.765.01a7.992 7.992 0 00-.472.032zm35.067-.126h-9.75v5.368h3.69v-.252c0-.797.175-1.39.524-1.782.35-.392.88-.587 1.594-.587.629 0 1.142.178 1.54.534.4.357.598.808.598 1.353 0 .028.007.118.021.272.014.154.021.308.021.462v4.34c0 .936-.167 1.607-.503 2.013-.335.405-.88.608-1.635.608-.713 0-1.251-.19-1.615-.567-.363-.377-.545-.936-.545-1.677v-.377h-3.69v6.269h9.75v-2.495c0-.937.178-1.608.534-2.013.357-.405.94-.608 1.75-.608.798 0 1.367.2 1.71.597.342.399.513 1.073.513 2.024v5.074c0 .755-.146 1.258-.44 1.51-.293.251-.873.377-1.74.377h-17.172c-.923 0-1.583-.182-1.982-.545-.398-.364-.597-.958-.597-1.782 0-.741.189-1.304.566-1.688.377-.385.93-.577 1.656-.577h.357V17.326h-.357c-.712 0-1.261-.2-1.646-.598-.384-.398-.576-.968-.576-1.709 0-.81.203-1.401.608-1.771.405-.37 1.062-.556 1.97-.556h17.173c.853 0 1.43.13 1.73.388.3.258.45.772.45 1.54v4.698c0 .95-.174 1.631-.524 2.044-.35.412-.915.618-1.698.618-.81 0-1.394-.21-1.75-.629-.357-.419-.535-1.097-.535-2.033v-2.202zM19.77 47.641c.267-.504.55-.86.85-1.07.3-.21.675-.314 1.122-.314.685 0 1.17.181 1.457.545.287.363.43.985.43 1.866l.042 5.451c0 .965-.157 1.615-.472 1.95-.314.336-.891.504-1.73.504-.587 0-1.045-.144-1.373-.43-.329-.287-.598-.8-.807-1.541-.378-1.342-.958-2.3-1.74-2.873-.783-.573-1.88-.86-3.292-.86-2.153 0-3.799.727-4.938 2.181-1.14 1.454-1.709 3.557-1.709 6.311s.598 4.882 1.793 6.385C10.599 67.248 12.294 68 14.488 68c.503 0 1.077-.06 1.72-.179a23.809 23.809 0 002.264-.555v-3.313h-2.37c-.95 0-1.624-.175-2.023-.524-.398-.35-.597-.93-.597-1.74 0-.84.199-1.437.597-1.793.399-.357 1.073-.535 2.024-.535h7.569c.978 0 1.667.175 2.065.524.398.35.598.937.598 1.762 0 .74-.2 1.31-.598 1.708-.398.399-.975.598-1.73.598h-.335v5.242c0 .447-.05.758-.147.933-.098.174-.293.353-.587.534-.797.476-2.062.895-3.795 1.258a25.576 25.576 0 01-5.263.546c-3.662 0-6.625-1.21-8.89-3.628-2.264-2.418-3.397-5.577-3.397-9.477 0-3.76 1.147-6.884 3.44-9.372 2.292-2.488 5.199-3.732 8.721-3.732.979 0 1.954.112 2.925.335.972.224 2.003.573 3.093 1.049zm15.84 3.941v4.823h6.857v-4.823h-.336c-.754 0-1.331-.195-1.73-.587-.398-.391-.597-.964-.597-1.719 0-.825.206-1.419.619-1.782.412-.364 1.093-.545 2.044-.545h5.41c.95 0 1.624.181 2.023.545.398.363.597.957.597 1.782 0 .755-.192 1.328-.576 1.72-.385.39-.947.586-1.688.586h-.357v15.642h.357c.755 0 1.328.192 1.719.576.391.385.587.947.587 1.688 0 .825-.203 1.419-.608 1.782-.405.364-1.09.546-2.055.546h-5.41c-.964 0-1.649-.179-2.054-.535-.405-.357-.608-.954-.608-1.793 0-.74.2-1.303.598-1.688.398-.384.975-.576 1.73-.576h.335v-6.186h-6.856v6.186h.335c.755 0 1.331.192 1.73.576.398.385.597.947.597 1.688 0 .825-.206 1.419-.618 1.782-.412.364-1.094.546-2.044.546h-5.41c-.964 0-1.65-.179-2.055-.535-.405-.357-.608-.954-.608-1.793 0-.74.196-1.303.587-1.688.392-.384.965-.576 1.72-.576h.356V51.582h-.356c-.741 0-1.304-.195-1.688-.587-.385-.391-.577-.964-.577-1.719 0-.825.2-1.419.598-1.782.398-.364 1.073-.545 2.023-.545h5.41c.936 0 1.614.181 2.033.545.42.363.63.957.63 1.782 0 .755-.2 1.328-.598 1.72-.399.39-.975.586-1.73.586h-.335zm31.754 0v15.642h3.523c.95 0 1.632.178 2.044.534.412.357.618.933.618 1.73 0 .811-.21 1.402-.629 1.772-.419.37-1.097.556-2.033.556H58.433c-.95 0-1.632-.182-2.044-.546-.412-.363-.619-.957-.619-1.782 0-.81.203-1.39.608-1.74.406-.35 1.09-.524 2.055-.524h3.523V51.582h-3.523c-.95 0-1.632-.181-2.044-.545-.412-.363-.619-.95-.619-1.761 0-.825.203-1.412.608-1.761.406-.35 1.09-.524 2.055-.524h12.455c.992 0 1.684.174 2.075.524.392.35.587.936.587 1.761 0 .81-.202 1.398-.608 1.761-.405.364-1.09.545-2.054.545h-3.523zm30.496 0v11.994c0 1.873-.122 3.228-.367 4.067a5.876 5.876 0 01-1.227 2.244c-.74.852-1.768 1.495-3.082 1.929-1.314.433-2.893.65-4.738.65-1.3 0-2.555-.126-3.764-.378a16.843 16.843 0 01-3.491-1.132c-.615-.28-1.017-.643-1.206-1.09-.188-.448-.283-1.175-.283-2.18v-4.32c0-1.202.175-2.04.525-2.516.349-.475.957-.713 1.824-.713 1.244 0 1.929.915 2.054 2.747.014.321.035.566.063.733.168 1.622.545 2.73 1.133 3.324.587.594 1.523.89 2.81.89 1.593 0 2.714-.422 3.364-1.268.65-.845.975-2.386.975-4.623V51.582H88.93c-.95 0-1.632-.181-2.044-.545-.413-.363-.619-.95-.619-1.761 0-.825.2-1.412.598-1.761.398-.35 1.086-.524 2.065-.524h10.693c.979 0 1.667.174 2.065.524.399.35.598.936.598 1.761 0 .81-.206 1.398-.619 1.761-.412.364-1.093.545-2.044.545h-1.761zm14.644 0v6.353l6.48-6.478c-.728-.084-1.238-.29-1.531-.619-.294-.328-.44-.85-.44-1.562 0-.825.198-1.419.597-1.782.398-.364 1.073-.545 2.023-.545h5.137c.95 0 1.625.181 2.023.545.399.363.598.957.598 1.782 0 .769-.2 1.345-.598 1.73-.398.384-.982.576-1.75.576h-.483l-6.101 6.06c1.132.839 2.167 1.94 3.103 3.302.937 1.363 2.034 3.456 3.292 6.28h.692c.825 0 1.44.188 1.845.566.405.377.608.943.608 1.698 0 .825-.206 1.419-.619 1.782-.412.364-1.093.546-2.044.546h-2.579c-1.132 0-2.048-.762-2.746-2.286-.126-.28-.224-.503-.294-.67-.923-1.958-1.768-3.467-2.537-4.53a16.616 16.616 0 00-2.705-2.914l-1.97 1.887v3.92h.335c.755 0 1.331.193 1.73.577.398.385.597.947.597 1.688 0 .825-.206 1.419-.618 1.782-.413.364-1.094.546-2.045.546h-5.41c-.964 0-1.649-.179-2.054-.535-.405-.357-.608-.954-.608-1.793 0-.74.196-1.303.587-1.688.391-.384.965-.576 1.72-.576h.356V51.582h-.357c-.74 0-1.303-.195-1.687-.587-.385-.391-.577-.964-.577-1.719 0-.825.2-1.419.598-1.782.398-.364 1.072-.545 2.023-.545h5.41c.936 0 1.614.181 2.033.545.42.363.63.957.63 1.782 0 .755-.2 1.328-.598 1.72-.399.39-.975.586-1.73.586h-.336zM13.44 96.326l4.005-11.889c.251-.782.6-1.352 1.048-1.709.447-.356 1.041-.534 1.782-.534h3.271c.95 0 1.632.182 2.044.545.413.363.619.957.619 1.782 0 .755-.2 1.328-.598 1.72-.398.39-.975.587-1.73.587h-.335l.587 15.641h.357c.754 0 1.32.192 1.698.577.377.384.566.947.566 1.687 0 .825-.2 1.42-.598 1.783-.398.363-1.072.545-2.023.545h-4.718c-.95 0-1.624-.178-2.023-.535-.398-.356-.597-.954-.597-1.793 0-.74.192-1.303.576-1.687.385-.385.954-.577 1.709-.577h.335l-.293-12.79-3.061 9.52c-.224.712-.542 1.226-.954 1.54-.413.315-.982.472-1.709.472-.727 0-1.303-.157-1.73-.472-.426-.314-.751-.828-.975-1.54l-3.04-9.52-.294 12.79h.336c.755 0 1.324.192 1.709.577.384.384.576.947.576 1.687 0 .825-.202 1.42-.608 1.783-.405.363-1.076.545-2.013.545H2.621c-.937 0-1.608-.182-2.013-.545-.405-.364-.608-.958-.608-1.783 0-.74.192-1.303.577-1.687.384-.385.954-.577 1.708-.577h.336l.608-15.641h-.336c-.754 0-1.331-.196-1.73-.588-.398-.39-.597-.964-.597-1.719 0-.825.206-1.419.619-1.782.412-.363 1.093-.545 2.044-.545h3.27c.728 0 1.311.175 1.752.524.44.35.8.923 1.08 1.72l4.109 11.888zm30.454 2.054V86.828H42.74c-.922 0-1.583-.182-1.981-.546-.398-.363-.598-.95-.598-1.76 0-.812.2-1.402.598-1.773.398-.37 1.059-.555 1.981-.555h5.955c.909 0 1.566.185 1.97.555.406.37.609.961.609 1.772 0 .741-.192 1.31-.577 1.709-.384.398-.933.598-1.646.598h-.356v19.038c0 .657-.07 1.069-.21 1.237-.14.167-.454.251-.943.251h-2.097c-.67 0-1.143-.07-1.415-.21-.273-.14-.507-.384-.703-.733l-8.722-15.327v11.385h1.216c.909 0 1.559.175 1.95.524.392.35.587.93.587 1.74 0 .825-.199 1.42-.597 1.783-.399.363-1.045.545-1.94.545h-6.017c-.909 0-1.566-.182-1.971-.545-.406-.364-.608-.958-.608-1.783 0-.74.188-1.303.566-1.687.377-.385.936-.577 1.677-.577h.336V86.828h-.336c-.713 0-1.265-.2-1.656-.598-.392-.398-.587-.968-.587-1.709 0-.81.206-1.401.618-1.772.413-.37 1.066-.555 1.96-.555h3.44c.824 0 1.383.108 1.677.325.293.216.622.653.985 1.31l7.989 14.551zM64.66 86.366c-1.803 0-3.218.727-4.245 2.18-1.028 1.455-1.541 3.474-1.541 6.06 0 2.586.517 4.613 1.551 6.08 1.034 1.468 2.446 2.202 4.235 2.202 1.804 0 3.222-.73 4.257-2.19 1.034-1.461 1.551-3.492 1.551-6.092 0-2.586-.513-4.605-1.54-6.06-1.028-1.453-2.45-2.18-4.268-2.18zm0-4.864c3.44 0 6.27 1.23 8.492 3.69 2.223 2.46 3.334 5.598 3.334 9.414 0 3.844-1.104 6.99-3.313 9.436-2.208 2.446-5.046 3.669-8.513 3.669-3.424 0-6.255-1.234-8.491-3.701-2.237-2.467-3.355-5.602-3.355-9.404 0-3.83 1.108-6.971 3.323-9.424 2.216-2.454 5.057-3.68 8.523-3.68zM87.461 98.17v4.298h2.16c.908 0 1.555.175 1.94.524.384.35.576.93.576 1.74 0 .825-.196 1.42-.587 1.783-.392.363-1.035.545-1.93.545h-7.254c-.922 0-1.583-.182-1.981-.545-.399-.364-.598-.958-.598-1.783 0-.74.189-1.303.566-1.687.378-.385.93-.577 1.657-.577h.356V86.828h-.356c-.713 0-1.262-.2-1.646-.598-.385-.398-.577-.968-.577-1.709 0-.81.203-1.401.608-1.772.406-.37 1.063-.555 1.971-.555h8.66c3.424 0 6.014.657 7.768 1.97 1.754 1.315 2.631 3.25 2.631 5.809 0 2.697-.873 4.738-2.62 6.122-1.748 1.384-4.34 2.076-7.78 2.076h-3.564zm0-11.343v6.625h2.977c1.65 0 2.89-.28 3.722-.839.832-.559 1.248-1.397 1.248-2.516 0-1.048-.43-1.855-1.29-2.421-.86-.566-2.086-.85-3.68-.85h-2.977zm27.267 20.568l-1.636 1.636a12.37 12.37 0 011.772-.44c.58-.098 1.15-.147 1.709-.147 1.104 0 2.268.164 3.491.492 1.223.329 1.967.493 2.233.493.447 0 1.03-.15 1.75-.45.72-.301 1.206-.452 1.458-.452.517 0 .947.2 1.29.598.342.398.513.898.513 1.5 0 .796-.472 1.474-1.415 2.033-.944.56-2.1.839-3.47.839-.937 0-2.139-.22-3.607-.66-1.467-.441-2.53-.661-3.187-.661-.992 0-2.11.272-3.354.817-1.244.546-2.013.818-2.307.818a2.14 2.14 0 01-1.53-.597c-.42-.399-.63-.878-.63-1.437 0-.391.134-.807.4-1.247.265-.44.733-1.01 1.404-1.709l2.118-2.139c-2.335-.852-4.194-2.386-5.578-4.602-1.384-2.215-2.075-4.763-2.075-7.642 0-3.802 1.104-6.909 3.312-9.32 2.209-2.411 5.053-3.617 8.534-3.617 3.467 0 6.304 1.209 8.513 3.627 2.208 2.418 3.312 5.522 3.312 9.31 0 3.774-1.097 6.884-3.291 9.33-2.195 2.446-4.977 3.67-8.345 3.67a22.5 22.5 0 01-1.384-.043zm1.195-21.03c-1.803 0-3.218.727-4.246 2.18-1.027 1.455-1.54 3.474-1.54 6.06 0 2.586.516 4.613 1.55 6.08 1.035 1.468 2.447 2.202 4.236 2.202 1.803 0 3.222-.73 4.256-2.19 1.035-1.461 1.552-3.492 1.552-6.092 0-2.586-.514-4.605-1.541-6.06-1.028-1.453-2.45-2.18-4.267-2.18z\"/></svg>"
},
"$:/core/images/mono-line": {
"title": "$:/core/images/mono-line",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-mono-line tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M60.437 84.523h.908c1.922 0 3.381.489 4.378 1.468.997.979 1.495 2.411 1.495 4.298 0 2.1-.525 3.612-1.575 4.538-1.05.925-2.785 1.388-5.206 1.388h-16.07c-2.456 0-4.2-.454-5.232-1.361-1.032-.908-1.548-2.43-1.548-4.565 0-2.065.516-3.542 1.548-4.432 1.032-.89 2.776-1.334 5.232-1.334h1.869l-2.19-6.247H20.983l-2.296 6.247h1.87c2.42 0 4.155.453 5.205 1.361 1.05.908 1.575 2.376 1.575 4.405 0 2.1-.525 3.612-1.575 4.538-1.05.925-2.785 1.388-5.206 1.388H6.781c-2.456 0-4.2-.463-5.233-1.388C.516 93.9 0 92.389 0 90.289c0-1.887.498-3.32 1.495-4.298.997-.979 2.456-1.468 4.378-1.468h.908l14.308-39.83h-4.271c-2.42 0-4.156-.462-5.206-1.387-1.05-.926-1.575-2.42-1.575-4.485 0-2.1.525-3.613 1.575-4.538 1.05-.926 2.785-1.388 5.206-1.388h20.021c3.168 0 5.392 1.708 6.674 5.125v.16l16.924 46.343zm-27.976-39.83L24.72 67.225h15.483l-7.742-22.53zM89.506 68.56v16.284h8.008c5.66 0 9.646-.623 11.96-1.869 2.313-1.245 3.47-3.328 3.47-6.246 0-2.955-1.103-5.055-3.31-6.3-2.207-1.246-6.069-1.869-11.586-1.869h-8.542zm27.229-5.926c3.88 1.423 6.727 3.372 8.542 5.846 1.815 2.474 2.723 5.633 2.723 9.477 0 3.239-.783 6.193-2.35 8.862-1.565 2.67-3.808 4.859-6.726 6.567-1.709.997-3.622 1.718-5.74 2.163-2.118.445-5.116.667-8.996.667h-27.87c-2.349 0-4.03-.463-5.045-1.388-1.014-.926-1.521-2.438-1.521-4.538 0-1.887.48-3.32 1.441-4.298.961-.979 2.367-1.468 4.218-1.468h.907v-39.83h-.907c-1.851 0-3.257-.498-4.218-1.494-.961-.997-1.441-2.456-1.441-4.378 0-2.065.516-3.568 1.548-4.512 1.032-.943 2.705-1.414 5.018-1.414h24.56c7.51 0 13.214 1.459 17.111 4.377 3.898 2.92 5.847 7.19 5.847 12.814 0 2.776-.597 5.223-1.789 7.341-1.192 2.118-2.963 3.853-5.312 5.206zm-27.23-18.26v13.455h7.208c4.378 0 7.466-.516 9.264-1.549 1.797-1.032 2.696-2.776 2.696-5.232 0-2.313-.81-4.004-2.43-5.072-1.619-1.068-4.244-1.602-7.874-1.602h-8.863z\"/></svg>"
},
"$:/core/images/new-button": {
"title": "$:/core/images/new-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-new-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M56 72H8.007C3.591 72 0 68.418 0 64c0-4.41 3.585-8 8.007-8H56V8.007C56 3.591 59.582 0 64 0c4.41 0 8 3.585 8 8.007V56h47.993c4.416 0 8.007 3.582 8.007 8 0 4.41-3.585 8-8.007 8H72v47.993c0 4.416-3.582 8.007-8 8.007-4.41 0-8-3.585-8-8.007V72z\"/></svg>"
},
"$:/core/images/new-here-button": {
"title": "$:/core/images/new-here-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-new-here-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M55.838 20.935l-3.572.938c-3.688.968-8.23 4.43-10.136 7.731L3.37 96.738c-1.905 3.3-.771 7.524 2.534 9.432l33.717 19.466c3.297 1.904 7.53.78 9.435-2.521l38.76-67.134c1.905-3.3 2.632-8.963 1.623-12.646L83.285 20.88c-1.009-3.68-4.821-5.884-8.513-4.915l-7.603 1.995.043.287c.524 3.394 2.053 7.498 4.18 11.55.418.163.829.36 1.23.59a8.864 8.864 0 014.438 8.169c.104.132.21.264.316.395l-.386.318a8.663 8.663 0 01-1.082 3.137c-2.42 4.192-7.816 5.608-12.051 3.163-4.12-2.379-5.624-7.534-3.476-11.671-2.177-4.394-3.788-8.874-4.543-12.964z\"/><path d=\"M69.554 44.76c-5.944-7.476-10.74-17.196-11.955-25.059-1.68-10.875 3.503-18.216 15.082-18.04 10.407.158 19.975 5.851 24.728 13.785 5.208 8.695 2.95 17.868-6.855 20.496l-2.037-7.601c4.232-1.134 4.999-4.248 2.24-8.853-3.37-5.626-10.465-9.848-18.146-9.965-6.392-.097-8.31 2.62-7.323 9.01.999 6.465 5.318 15.138 10.582 21.65l-.072.06c.559 1.553-4.17 6.44-5.938 4.888l-.005.004-.028-.034a1.323 1.323 0 01-.124-.135 2.618 2.618 0 01-.149-.205z\"/><rect width=\"16\" height=\"48\" x=\"96\" y=\"80\" rx=\"8\"/><rect width=\"48\" height=\"16\" x=\"80\" y=\"96\" rx=\"8\"/></g></svg>"
},
"$:/core/images/new-image-button": {
"title": "$:/core/images/new-image-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-new-image-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M81.362 73.627l15.826-27.41a2.626 2.626 0 00-.962-3.59l-50.01-28.872a2.626 2.626 0 00-3.588.961L30.058 36.49l10.04-5.261c3.042-1.595 6.771.114 7.55 3.46l3.607 17.702 9.88.85a5.25 5.25 0 014.571 3.77c.034.115.1.344.199.671.165.553.353 1.172.562 1.843.595 1.914 1.23 3.85 1.872 5.678.207.588.412 1.156.614 1.701.625 1.685 1.209 3.114 1.725 4.207.255.54.485.977.726 1.427.214.212.547.425 1.011.622 1.141.482 2.784.74 4.657.758.864.008 1.71-.034 2.492-.11.448-.043.753-.085.871-.104.315-.053.625-.077.927-.076zM37.47 2.649A5.257 5.257 0 0144.649.725l63.645 36.746a5.257 5.257 0 011.923 7.178L73.47 108.294a5.257 5.257 0 01-7.177 1.923L2.649 73.47a5.257 5.257 0 01-1.924-7.177L37.471 2.649zm42.837 50.49a5.25 5.25 0 105.25-9.092 5.25 5.25 0 00-5.25 9.093zM96 112h-7.993c-4.419 0-8.007-3.582-8.007-8 0-4.41 3.585-8 8.007-8H96v-7.993C96 83.588 99.582 80 104 80c4.41 0 8 3.585 8 8.007V96h7.993c4.419 0 8.007 3.582 8.007 8 0 4.41-3.585 8-8.007 8H112v7.993c0 4.419-3.582 8.007-8 8.007-4.41 0-8-3.585-8-8.007V112zM33.347 51.791c7.428 7.948 9.01 10.69 7.449 13.394-1.56 2.703-13.838-2.328-16.094 1.58-2.256 3.908-.907 3.258-2.437 5.908l19.73 11.39s-5.605-8.255-4.235-10.628c2.515-4.356 8.77-1.256 10.365-4.019 2.414-4.181-5.103-9.639-14.778-17.625z\"/></svg>"
},
"$:/core/images/new-journal-button": {
"title": "$:/core/images/new-journal-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-new-journal-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M102.545 112.818v11.818c0 1.306 1.086 2.364 2.425 2.364h6.06c1.34 0 2.425-1.058 2.425-2.364v-11.818h12.12c1.34 0 2.425-1.058 2.425-2.363v-5.91c0-1.305-1.085-2.363-2.424-2.363h-12.121V90.364c0-1.306-1.086-2.364-2.425-2.364h-6.06c-1.34 0-2.425 1.058-2.425 2.364v11.818h-12.12c-1.34 0-2.425 1.058-2.425 2.363v5.91c0 1.305 1.085 2.363 2.424 2.363h12.121zM60.016 4.965c-4.781-2.76-10.897-1.118-13.656 3.66L5.553 79.305A9.993 9.993 0 009.21 92.963l51.04 29.468c4.78 2.76 10.897 1.118 13.655-3.66l40.808-70.681a9.993 9.993 0 00-3.658-13.656L60.016 4.965zm-3.567 27.963a6 6 0 106-10.393 6 6 0 00-6 10.393zm31.697 17.928a6 6 0 106-10.392 6 6 0 00-6 10.392z\"/><text class=\"tc-fill-background\" font-family=\"Helvetica\" font-size=\"47.172\" font-weight=\"bold\" transform=\"rotate(30 25.742 95.82)\"><tspan x=\"42\" y=\"77.485\" text-anchor=\"middle\"><<now \"DD\">></tspan></text></g></svg>"
},
"$:/core/images/opacity": {
"title": "$:/core/images/opacity",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-opacity tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M102.362 65a51.595 51.595 0 01-1.942 6H82.584a35.867 35.867 0 002.997-6h16.78zm.472-2c.423-1.961.734-3.963.929-6H87.656a35.78 35.78 0 01-1.368 6h16.546zm-3.249 10a51.847 51.847 0 01-3.135 6H75.812a36.205 36.205 0 005.432-6h18.341zm-4.416 8c-1.424 2.116-3 4.12-4.71 6H60.46a35.843 35.843 0 0012.874-6h21.834zm-7.513-34h16.107C101.247 20.627 79.033 0 52 0 23.281 0 0 23.281 0 52c0 25.228 17.965 46.26 41.8 51h20.4a51.66 51.66 0 0015.875-6H39v-2h42.25a52.257 52.257 0 007.288-6H39v-2h4.539C27.739 83.194 16 68.968 16 52c0-19.882 16.118-36 36-36 18.186 0 33.222 13.484 35.656 31zm.22 2h16.039a52.823 52.823 0 010 6H87.877a36.483 36.483 0 000-6z\"/><path d=\"M76 128c28.719 0 52-23.281 52-52s-23.281-52-52-52-52 23.281-52 52 23.281 52 52 52zm0-16c19.882 0 36-16.118 36-36S95.882 40 76 40 40 56.118 40 76s16.118 36 36 36z\"/><path d=\"M37 58h53v4H37v-4zm3-8h53v4H40v-4zm0-8h53v4H40v-4zm-8 24h53v4H32v-4zm-2 8h53v4H30v-4zm-3 8h53v4H27v-4z\"/></g></svg>"
},
"$:/core/images/open-window": {
"title": "$:/core/images/open-window",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-open-window tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M16 112h88.994c3.87 0 7.006 3.59 7.006 8 0 4.418-3.142 8-7.006 8H7.006C3.136 128 0 124.41 0 120a9.321 9.321 0 010-.01V24.01C0 19.586 3.59 16 8 16c4.418 0 8 3.584 8 8.01V112z\"/><path d=\"M96 43.196V56a8 8 0 1016 0V24c0-4.41-3.585-8-8.007-8H72.007C67.588 16 64 19.582 64 24c0 4.41 3.585 8 8.007 8H84.57l-36.3 36.299a8 8 0 00-.001 11.316c3.117 3.117 8.19 3.123 11.316-.003L96 43.196zM32 7.999C32 3.581 35.588 0 40 0h80c4.419 0 8 3.588 8 8v80c0 4.419-3.588 8-8 8H40c-4.419 0-8-3.588-8-8V8z\"/></g></svg>"
},
"$:/core/images/options-button": {
"title": "$:/core/images/options-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-options-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M110.488 76a47.712 47.712 0 01-5.134 12.384l6.724 6.724c3.123 3.123 3.132 8.192.011 11.313l-5.668 5.668c-3.12 3.12-8.186 3.117-11.313-.01l-6.724-6.725c-3.82 2.258-7.98 4-12.384 5.134v9.505c0 4.417-3.578 8.007-7.992 8.007h-8.016C55.58 128 52 124.415 52 119.993v-9.505a47.712 47.712 0 01-12.384-5.134l-6.724 6.725c-3.123 3.122-8.192 3.131-11.313.01l-5.668-5.668c-3.12-3.12-3.116-8.186.01-11.313l6.725-6.724c-2.257-3.82-4-7.98-5.134-12.384H8.007C3.591 76 0 72.422 0 68.01v-8.017C0 55.58 3.585 52 8.007 52h9.505a47.712 47.712 0 015.134-12.383l-6.724-6.725c-3.123-3.122-3.132-8.191-.011-11.312l5.668-5.669c3.12-3.12 8.186-3.116 11.313.01l6.724 6.725c3.82-2.257 7.98-4 12.384-5.134V8.007C52 3.591 55.578 0 59.992 0h8.016C72.42 0 76 3.585 76 8.007v9.505a47.712 47.712 0 0112.384 5.134l6.724-6.724c3.123-3.123 8.192-3.132 11.313-.01l5.668 5.668c3.12 3.12 3.116 8.186-.01 11.312l-6.725 6.725c2.257 3.82 4 7.979 5.134 12.383h9.505c4.416 0 8.007 3.578 8.007 7.992v8.017c0 4.411-3.585 7.991-8.007 7.991h-9.505zM64 96c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32z\"/></svg>"
},
"$:/core/images/paint": {
"title": "$:/core/images/paint",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-paint tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M83.527 76.19C90.43 69.287 91.892 59 87.91 50.665l37.903-37.902c2.919-2.92 2.913-7.659 0-10.572a7.474 7.474 0 00-10.572 0L77.338 40.093c-8.335-3.982-18.622-2.521-25.526 4.383l31.715 31.715zm-2.643 2.644L49.169 47.119S8.506 81.243 0 80.282c0 0 3.782 5.592 6.827 8.039 14.024-5.69 37.326-24.6 37.326-24.6l.661.66S19.45 90.222 9.18 92.047c1.222 1.44 4.354 4.053 6.247 5.776 5.417-1.488 34.733-28.57 34.733-28.57l.661.66-32.407 31.022 5.285 5.286L56.106 75.2l.662.66s-27.864 30.536-28.684 32.432c0 0 6.032 6.853 7.569 7.824.702-2.836 27.884-33.485 27.884-33.485l.661.66s-20.597 23.755-24.964 36.732c3.21 3.549 7.5 5.137 10.926 6.298-2.19-11.817 30.724-47.487 30.724-47.487z\"/></svg>"
},
"$:/core/images/palette": {
"title": "$:/core/images/palette",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-palette tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M80.247 39.182a93.52 93.52 0 00-16.228-1.4C28.662 37.781 0 57.131 0 81.002c0 9.642 4.676 18.546 12.58 25.735C23.504 91.19 26.34 72.395 36.89 63.562c15.183-12.713 26.538-7.828 26.538-7.828l16.82-16.552zm26.535 9.655c13.049 7.913 21.257 19.392 21.257 32.166 0 9.35.519 17.411-11.874 25.08-10.797 6.681-3.824-6.536-11.844-10.898s-19.946 1.308-18.213 7.906c3.2 12.181 19.422 11.455 6.314 16.658-13.107 5.202-18.202 4.476-28.403 4.476-7.821 0-15.315-.947-22.243-2.68 9.844-4.197 27.88-12.539 33.354-19.456C82.788 92.409 87.37 80 83.324 72.484c-.194-.359 11.215-11.668 23.458-23.647zM1.134 123.867l-.66.002c33.479-14.94 22.161-64.226 58.818-64.226.317 1.418.644 2.944 1.062 4.494-25.907-4.166-23.567 48.031-59.22 59.73zm.713-.007c38.872-.506 78.152-22.347 78.152-44.813-9.27 0-14.073-3.48-16.816-7.942-16.597-7.003-30.365 45.715-61.336 52.755zm65.351-64.008c-4.45 4.115 4.886 16.433 11.318 11.318l45.27-45.27c11.317-11.318 0-22.635-11.318-11.318-11.317 11.318-33.518 34.405-45.27 45.27z\"/></svg>"
},
"$:/core/images/permalink-button": {
"title": "$:/core/images/permalink-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-permalink-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M80.483 48l-7.387 32h-25.58l7.388-32h25.58zm3.694-16l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L100.598 32h3.403c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8h-7.096l-7.387 32H104c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8H85.824l-5.624 24.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L69.402 96h-25.58L38.2 120.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L27.402 96h-3.403C19.59 96 16 92.418 16 88c0-4.41 3.581-8 8-8h7.096l7.387-32H24C19.59 48 16 44.418 16 40c0-4.41 3.581-8 8-8h18.177l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L58.598 32h25.58z\"/></svg>"
},
"$:/core/images/permaview-button": {
"title": "$:/core/images/permaview-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-permaview-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M81.483 48l-1.846 8h-5.58l1.847-8h5.58zm3.694-16l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L101.598 32h2.403c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8h-6.096l-1.847 8h7.944c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8H92.364l-1.846 8H104c4.41 0 7.999 3.582 7.999 8 0 4.41-3.581 8-8 8H86.824l-5.624 24.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L70.402 96h-5.58L59.2 120.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L48.402 96h-5.58L37.2 120.358c-.993 4.303-5.29 6.996-9.596 6.002-4.296-.992-6.988-5.293-5.994-9.602L26.402 96h-2.403C19.59 96 16 92.418 16 88c0-4.41 3.581-8 8-8h6.096l1.847-8h-7.944C19.59 72 16 68.418 16 64c0-4.41 3.581-8 8-8h11.637l1.846-8H24C19.59 48 16 44.418 16 40c0-4.41 3.581-8 8-8h17.177l5.624-24.358c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L57.598 32h5.58L68.8 7.642c.993-4.303 5.29-6.996 9.596-6.002 4.296.992 6.988 5.293 5.994 9.602L79.598 32h5.58zM53.904 48l-1.847 8h5.58l1.846-8h-5.579zm22.039 24l-1.847 8h-5.58l1.847-8h5.58zm-27.58 0l-1.846 8h5.579l1.847-8h-5.58z\"/></svg>"
},
"$:/core/images/picture": {
"title": "$:/core/images/picture",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-picture tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M112 68.233v-48.23A4.001 4.001 0 00107.997 16H20.003A4.001 4.001 0 0016 20.003v38.31l9.241-14.593c2.8-4.422 9.023-5.008 12.6-1.186l18.247 20.613 13.687-6.407a8 8 0 018.903 1.492 264.97 264.97 0 002.92 2.739 249.44 249.44 0 006.798 6.066 166.5 166.5 0 002.106 1.778c2.108 1.747 3.967 3.188 5.482 4.237.748.518 1.383.92 2.044 1.33.444.117 1.046.144 1.809.05 1.873-.233 4.238-1.144 6.723-2.547a36.016 36.016 0 003.205-2.044c.558-.4.93-.686 1.07-.802.376-.31.765-.577 1.165-.806zM0 8.007A8.01 8.01 0 018.007 0h111.986A8.01 8.01 0 01128 8.007v111.986a8.01 8.01 0 01-8.007 8.007H8.007A8.01 8.01 0 010 119.993V8.007zM95 42a8 8 0 100-16 8 8 0 000 16zM32 76c15.859 4.83 20.035 7.244 20.035 12S32 95.471 32 102.347c0 6.876 1.285 4.99 1.285 9.653H68s-13.685-6.625-13.685-10.8c0-7.665 10.615-8.34 10.615-13.2 0-7.357-14.078-8.833-32.93-12z\"/></svg>"
},
"$:/core/images/plugin-generic-language": {
"title": "$:/core/images/plugin-generic-language",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M61.207 68.137c-4.324 2.795-6.999 6.656-6.999 10.921 0 7.906 9.19 14.424 21.042 15.336 2.162 3.902 8.598 6.785 16.318 7.01-5.126-1.125-9.117-3.742-10.62-7.01C92.805 93.487 102 86.967 102 79.059c0-8.53-10.699-15.445-23.896-15.445-6.599 0-12.572 1.729-16.897 4.524zm12.794-14.158c-4.324 2.795-10.298 4.524-16.897 4.524-2.619 0-5.14-.272-7.497-.775-3.312 2.25-8.383 3.69-14.067 3.69l-.255-.002c4.119-.892 7.511-2.747 9.478-5.13-6.925-2.704-11.555-7.617-11.555-13.228 0-8.53 10.699-15.445 23.896-15.445C70.301 27.613 81 34.528 81 43.058c0 4.265-2.675 8.126-6.999 10.921zM64 0l54.56 32v64L64 128 9.44 96V32L64 0z\"/></svg>"
},
"$:/core/images/plugin-generic-plugin": {
"title": "$:/core/images/plugin-generic-plugin",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M40.397 76.446V95.34h14.12l-.001-.005a6.912 6.912 0 005.364-11.593l.046-.023a6.912 6.912 0 119.979.526l.086.055a6.914 6.914 0 004.408 10.948l-.023.092h21.32V75.568l-.15.038a6.912 6.912 0 00-11.593-5.364l-.022-.046a6.912 6.912 0 11.526-9.979l.055-.086a6.914 6.914 0 0010.948-4.408c.079.018.158.038.236.059v-15.74h-21.32l.023-.094a6.914 6.914 0 01-4.408-10.947 10.23 10.23 0 00-.086-.055 6.912 6.912 0 10-9.979-.526l-.046.023a6.912 6.912 0 01-5.364 11.593l.001.005h-14.12v12.847A6.912 6.912 0 0129.5 59.843l-.054.086a6.912 6.912 0 10-.526 9.979l.023.046a6.912 6.912 0 0111.455 6.492zM64 0l54.56 32v64L64 128 9.44 96V32L64 0z\"/></svg>"
},
"$:/core/images/plugin-generic-theme": {
"title": "$:/core/images/plugin-generic-theme",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M29.408 91.472L51.469 69.41l-.004-.005a2.22 2.22 0 01.004-3.146c.87-.87 2.281-.872 3.147-.005l9.465 9.464a2.22 2.22 0 01-.005 3.147c-.87.87-2.28.871-3.147.005l-.005-.005-22.061 22.062a6.686 6.686 0 11-9.455-9.455zM60.802 66.38c-2.436-2.704-4.465-5.091-5.817-6.869-6.855-9.014-10.313-4.268-14.226 0-3.913 4.268 1.03 7.726-2.683 10.741-3.713 3.015-3.484 4.06-9.752-1.455-6.267-5.516-6.7-7.034-3.823-10.181 2.877-3.147 5.281 1.808 11.159-3.785 5.877-5.593.94-10.55.94-10.55s12.237-25.014 28.588-23.167c16.351 1.848-6.186-2.392-11.792 17.226-2.4 8.4.447 6.42 4.998 9.968 1.394 1.086 6.03 4.401 11.794 8.685l20.677-20.676 1.615-4.766 7.84-4.689 3.151 3.152-4.688 7.84-4.766 1.615-20.224 20.223c12.663 9.547 28.312 22.146 28.312 26.709 0 7.217-3.071 11.526-9.535 9.164-4.693-1.715-18.768-15.192-28.753-25.897l-2.893 2.893-3.151-3.152 3.029-3.029zM63.953 0l54.56 32v64l-54.56 32-54.56-32V32l54.56-32z\"/></svg>"
},
"$:/core/images/preview-closed": {
"title": "$:/core/images/preview-closed",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-preview-closed tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M.088 64a7.144 7.144 0 001.378 5.458C16.246 88.818 39.17 100.414 64 100.414c24.83 0 47.753-11.596 62.534-30.956A7.144 7.144 0 00127.912 64C110.582 78.416 88.304 87.086 64 87.086 39.696 87.086 17.418 78.416.088 64z\"/><rect width=\"4\" height=\"16\" x=\"62\" y=\"96\" rx=\"4\"/><rect width=\"4\" height=\"16\" x=\"78\" y=\"93\" rx=\"4\" transform=\"rotate(-5 80 101)\"/><rect width=\"4\" height=\"16\" x=\"46\" y=\"93\" rx=\"4\" transform=\"rotate(5 48 101)\"/><rect width=\"4\" height=\"16\" x=\"30\" y=\"88\" rx=\"4\" transform=\"rotate(10 32 96)\"/><rect width=\"4\" height=\"16\" x=\"94\" y=\"88\" rx=\"4\" transform=\"rotate(-10 96 96)\"/><rect width=\"4\" height=\"16\" x=\"110\" y=\"80\" rx=\"4\" transform=\"rotate(-20 112 88)\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"80\" rx=\"4\" transform=\"rotate(20 16 88)\"/></g></svg>"
},
"$:/core/images/preview-open": {
"title": "$:/core/images/preview-open",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-preview-open tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M64.11 99.588c-24.83 0-47.754-11.596-62.534-30.957a7.148 7.148 0 010-8.675C16.356 40.596 39.28 29 64.11 29c24.83 0 47.753 11.596 62.534 30.956a7.148 7.148 0 010 8.675c-14.78 19.36-37.703 30.957-62.534 30.957zm46.104-32.007c1.44-1.524 1.44-3.638 0-5.162C99.326 50.9 82.439 44 64.147 44S28.968 50.9 18.08 62.42c-1.44 1.523-1.44 3.637 0 5.16C28.968 79.1 45.855 86 64.147 86s35.179-6.9 46.067-18.42z\"/><path d=\"M63.5 88C76.479 88 87 77.479 87 64.5S76.479 41 63.5 41 40 51.521 40 64.5 50.521 88 63.5 88z\"/></g></svg>"
},
"$:/core/images/print-button": {
"title": "$:/core/images/print-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-print-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M112 71V30.5h-.032c-.035-2-.816-3.99-2.343-5.516L86.998 2.357A7.978 7.978 0 0081 .02V0H24a8 8 0 00-8 8v63h8V8h57v14.5c0 4.422 3.582 8 8 8h15V71h8z\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"36\" rx=\"4\"/><rect width=\"64\" height=\"8\" x=\"32\" y=\"52\" rx=\"4\"/><rect width=\"40\" height=\"8\" x=\"32\" y=\"20\" rx=\"4\"/><path d=\"M0 80.005C0 71.165 7.156 64 16 64h96c8.836 0 16 7.155 16 16.005v31.99c0 8.84-7.156 16.005-16 16.005H16c-8.836 0-16-7.155-16-16.005v-31.99zM104 96a8 8 0 100-16 8 8 0 000 16z\"/></g></svg>"
},
"$:/core/images/quote": {
"title": "$:/core/images/quote",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-quote tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M51.219 117.713V62.199H27.427c0-8.891 1.683-16.401 5.047-22.53 3.365-6.127 9.613-10.754 18.745-13.878V2c-7.45.961-14.36 3.184-20.728 6.669-6.368 3.484-11.835 7.87-16.401 13.157C9.524 27.113 5.98 33.241 3.456 40.21.933 47.18-.21 54.63.03 62.56v55.153H51.22zm76.781 0V62.199h-23.791c0-8.891 1.682-16.401 5.046-22.53 3.365-6.127 9.613-10.754 18.745-13.878V2c-7.45.961-14.359 3.184-20.727 6.669-6.369 3.484-11.836 7.87-16.402 13.157-4.566 5.287-8.11 11.415-10.634 18.384-2.523 6.97-3.665 14.42-3.424 22.35v55.153H128z\"/></svg>"
},
"$:/core/images/refresh-button": {
"title": "$:/core/images/refresh-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-refresh-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M106.369 39.433c10.16 20.879 6.57 46.764-10.771 64.106-21.87 21.87-57.327 21.87-79.196 0-21.87-21.87-21.87-57.326 0-79.196a8 8 0 1111.314 11.314c-15.621 15.62-15.621 40.947 0 56.568 15.62 15.621 40.947 15.621 56.568 0C97.72 78.79 99.6 58.175 89.924 42.73l-6.44 12.264a8 8 0 11-14.166-7.437L84.435 18.76a8 8 0 0110.838-3.345l28.873 15.345a8 8 0 11-7.51 14.129l-10.267-5.457zm-8.222-12.368c-.167-.19-.336-.38-.506-.57l.96-.296-.454.866z\"/></svg>"
},
"$:/core/images/right-arrow": {
"title": "$:/core/images/right-arrow",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-right-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M99.069 64.173c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l50.382-50.382-50.382-50.382a7.92 7.92 0 010-11.195c3.086-3.085 8.104-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.316 5.595z\"/></svg>"
},
"$:/core/images/rotate-left": {
"title": "$:/core/images/rotate-left",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-rotate-left tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"32\" height=\"80\" rx=\"8\"/><rect width=\"80\" height=\"32\" x=\"48\" y=\"96\" rx=\"8\"/><path d=\"M61.32 36.65c19.743 2.45 35.023 19.287 35.023 39.693a4 4 0 01-8 0c0-15.663-11.254-28.698-26.117-31.46l3.916 3.916a4 4 0 11-5.657 5.657L49.172 43.142a4 4 0 010-5.657l11.313-11.313a4 4 0 115.657 5.656l-4.821 4.822z\"/></g></svg>"
},
"$:/core/images/save-button": {
"title": "$:/core/images/save-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-save-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M120.783 34.33c4.641 8.862 7.266 18.948 7.266 29.646 0 35.347-28.653 64-64 64-35.346 0-64-28.653-64-64 0-35.346 28.654-64 64-64 18.808 0 35.72 8.113 47.43 21.03l2.68-2.68c3.13-3.13 8.197-3.132 11.321-.008 3.118 3.118 3.121 8.193-.007 11.32l-4.69 4.691zm-12.058 12.058a47.876 47.876 0 013.324 17.588c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48c14.39 0 27.3 6.332 36.098 16.362L58.941 73.544 41.976 56.578c-3.127-3.127-8.201-3.123-11.32-.005-3.123 3.124-3.119 8.194.006 11.319l22.617 22.617a7.992 7.992 0 005.659 2.347c2.05 0 4.101-.783 5.667-2.349l44.12-44.12z\"/></svg>"
},
"$:/core/images/size": {
"title": "$:/core/images/size",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-size tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M92.343 26l-9.171 9.172a4 4 0 105.656 5.656l16-16a4 4 0 000-5.656l-16-16a4 4 0 10-5.656 5.656L92.343 18H22a4 4 0 00-4 4v70.343l-9.172-9.171a4 4 0 10-5.656 5.656l16 16a4 4 0 005.656 0l16-16a4 4 0 10-5.656-5.656L26 92.343V22l-4 4h70.343zM112 52v64l4-4H52a4 4 0 100 8h64a4 4 0 004-4V52a4 4 0 10-8 0z\"/></svg>"
},
"$:/core/images/spiral": {
"title": "$:/core/images/spiral",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-spiral tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M64.534 68.348c3.39 0 6.097-2.62 6.476-5.968l-4.755-.538 4.75.583c.377-3.07-1.194-6.054-3.89-7.78-2.757-1.773-6.34-2.01-9.566-.7-3.46 1.403-6.14 4.392-7.35 8.148l-.01.026c-1.3 4.08-.72 8.64 1.58 12.52 2.5 4.2 6.77 7.2 11.76 8.27 5.37 1.15 11.11-.05 15.83-3.31 5.04-3.51 8.46-9.02 9.45-15.3 1.05-6.7-.72-13.63-4.92-19.19l.02.02c-4.42-5.93-11.2-9.82-18.78-10.78-7.96-1.01-16.13 1.31-22.59 6.43-6.81 5.39-11.18 13.41-12.11 22.26-.98 9.27 1.87 18.65 7.93 26.02 6.32 7.69 15.6 12.56 25.74 13.48 10.54.96 21.15-2.42 29.45-9.4l.01-.01c8.58-7.25 13.94-17.78 14.86-29.21.94-11.84-2.96-23.69-10.86-32.9-8.19-9.5-19.95-15.36-32.69-16.27-13.16-.94-26.24 3.49-36.34 12.34l.01-.01c-10.41 9.08-16.78 22.1-17.68 36.15-.93 14.44 4.03 28.77 13.79 39.78 10.03 11.32 24.28 18.2 39.6 19.09 15.73.92 31.31-4.56 43.24-15.234 12.23-10.954 19.61-26.44 20.5-43.074a4.785 4.785 0 00-4.52-5.03 4.778 4.778 0 00-5.03 4.52c-.75 14.1-7 27.2-17.33 36.45-10.03 8.98-23.11 13.58-36.3 12.81-12.79-.75-24.67-6.48-33-15.89-8.07-9.11-12.17-20.94-11.41-32.827.74-11.52 5.942-22.15 14.43-29.54l.01-.01c8.18-7.17 18.74-10.75 29.35-9.998 10.21.726 19.6 5.41 26.11 12.96 6.24 7.273 9.32 16.61 8.573 25.894-.718 8.9-4.88 17.064-11.504 22.66l.01-.007c-6.36 5.342-14.44 7.92-22.425 7.19-7.604-.68-14.52-4.314-19.21-10.027-4.44-5.4-6.517-12.23-5.806-18.94.67-6.3 3.76-11.977 8.54-15.766 4.46-3.54 10.05-5.128 15.44-4.44 5.03.63 9.46 3.18 12.32 7.01l.02.024c2.65 3.5 3.75 7.814 3.1 11.92-.59 3.71-2.58 6.925-5.45 8.924-2.56 1.767-5.61 2.403-8.38 1.81-2.42-.516-4.42-1.92-5.53-3.79-.93-1.56-1.15-3.3-.69-4.75l-4.56-1.446L59.325 65c.36-1.12 1.068-1.905 1.84-2.22.25-.103.48-.14.668-.13.06.006.11.015.14.025.01 0 .01 0-.01-.01a1.047 1.047 0 01-.264-.332c-.15-.29-.23-.678-.18-1.11l-.005.04c.15-1.332 1.38-2.523 3.035-2.523-2.65 0-4.79 2.144-4.79 4.787s2.14 4.785 4.78 4.785z\"/></svg>"
},
"$:/core/images/stamp": {
"title": "$:/core/images/stamp",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-stamp tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M49.733 64H16.01C11.584 64 8 67.583 8 72.003V97h112V72.003A8 8 0 00111.99 64H78.267A22.813 22.813 0 0175.5 53.077c0-6.475 2.687-12.324 7.009-16.497A22.818 22.818 0 0087 22.952C87 10.276 76.703 0 64 0S41 10.276 41 22.952c0 5.103 1.669 9.817 4.491 13.628 4.322 4.173 7.009 10.022 7.009 16.497 0 3.954-1.002 7.675-2.767 10.923zM8 104h112v8H8v-8z\"/></svg>"
},
"$:/core/images/star-filled": {
"title": "$:/core/images/star-filled",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-star-filled tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M61.836 96.823l37.327 27.287c2.72 1.99 6.379-.69 5.343-3.912L90.29 75.988l-1.26 3.91 37.285-27.345c2.718-1.993 1.32-6.327-2.041-6.33l-46.113-.036 3.3 2.416L67.176 4.416c-1.04-3.221-5.563-3.221-6.604 0L46.29 48.603l3.3-2.416-46.113.036c-3.362.003-4.759 4.337-2.04 6.33L38.72 79.898l-1.26-3.91-14.216 44.21c-1.036 3.223 2.622 5.901 5.343 3.912l37.326-27.287h-4.078z\"/></svg>"
},
"$:/core/images/storyview-classic": {
"title": "$:/core/images/storyview-classic",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-storyview-classic tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16C19.581 16 16 19.578 16 23.992v16.016C16 44.422 19.588 48 24 48h80c4.419 0 8-3.578 8-7.992V23.992c0-4.414-3.588-7.992-8-7.992H24zm0 48C19.581 64 16 67.59 16 72c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24zm0 32C19.581 96 16 99.59 16 104c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24z\"/></svg>"
},
"$:/core/images/storyview-pop": {
"title": "$:/core/images/storyview-pop",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-storyview-pop tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16C19.581 16 16 19.578 16 23.992v16.016C16 44.422 19.588 48 24 48h80c4.419 0 8-3.578 8-7.992V23.992c0-4.414-3.588-7.992-8-7.992H24zm-7.99 40C11.587 56 8 59.578 8 63.992v16.016C8 84.422 11.584 88 16.01 88h95.98c4.424 0 8.01-3.578 8.01-7.992V63.992c0-4.414-3.584-7.992-8.01-7.992H16.01zM24 96C19.581 96 16 99.59 16 104c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24zm0-32C19.581 64 16 67.59 16 72c0 4.418 3.588 8 8 8h80c4.419 0 8-3.59 8-8 0-4.418-3.588-8-8-8H24z\"/></svg>"
},
"$:/core/images/storyview-zoomin": {
"title": "$:/core/images/storyview-zoomin",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-storyview-zoomin tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M8.007 0A8.01 8.01 0 000 8.007v111.986A8.01 8.01 0 008.007 128h111.986a8.01 8.01 0 008.007-8.007V8.007A8.01 8.01 0 00119.993 0H8.007zm15.992 16A8 8 0 0016 24.009V71.99C16 76.414 19.588 80 24 80h80a8 8 0 008-8.009V24.01c0-4.423-3.588-8.009-8-8.009H24z\"/></svg>"
},
"$:/core/images/strikethrough": {
"title": "$:/core/images/strikethrough",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-strikethrough tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M92.794 38.726h15.422c-.229-6.74-1.514-12.538-3.856-17.393-2.342-4.855-5.54-8.881-9.596-12.08-4.055-3.199-8.767-5.54-14.136-7.025C75.258.743 69.433 0 63.15 0a62.76 62.76 0 00-16.364 2.142C41.474 3.57 36.733 5.74 32.564 8.653c-4.17 2.913-7.511 6.626-10.025 11.138-2.513 4.512-3.77 9.853-3.77 16.022 0 5.597 1.115 10.252 3.342 13.965 2.228 3.712 5.198 6.74 8.91 9.081 3.713 2.342 7.911 4.227 12.595 5.655a194.641 194.641 0 0014.308 3.77c4.855 1.085 9.624 2.142 14.308 3.17 4.683 1.028 8.881 2.37 12.594 4.027 3.713 1.656 6.683 3.798 8.91 6.425 2.228 2.628 3.342 6.055 3.342 10.281 0 4.456-.914 8.111-2.742 10.967a19.953 19.953 0 01-7.197 6.768c-2.97 1.657-6.311 2.828-10.024 3.513a60.771 60.771 0 01-11.052 1.028c-4.57 0-9.025-.571-13.366-1.713-4.34-1.143-8.139-2.913-11.394-5.312-3.256-2.4-5.884-5.455-7.883-9.168-1.999-3.712-2.998-8.139-2.998-13.28H15c0 7.426 1.342 13.852 4.027 19.278 2.684 5.426 6.34 9.881 10.966 13.365 4.627 3.484 9.996 6.083 16.107 7.797 6.112 1.713 12.595 2.57 19.449 2.57 5.597 0 11.223-.657 16.878-1.97 5.655-1.314 10.767-3.428 15.336-6.34 4.57-2.914 8.31-6.683 11.224-11.31 2.913-4.626 4.37-10.195 4.37-16.707 0-6.054-1.115-11.08-3.342-15.079-2.228-3.998-5.198-7.31-8.91-9.938-3.713-2.627-7.911-4.712-12.595-6.254a170.83 170.83 0 00-14.308-4.027 549.669 549.669 0 00-14.308-3.17c-4.683-.971-8.881-2.2-12.594-3.684-3.713-1.485-6.683-3.399-8.91-5.74-2.228-2.342-3.342-5.398-3.342-9.168 0-3.998.771-7.34 2.313-10.024 1.543-2.685 3.599-4.826 6.17-6.426 2.57-1.599 5.51-2.741 8.824-3.427a49.767 49.767 0 0110.11-1.028c8.453 0 15.393 1.97 20.819 5.912 5.426 3.94 8.596 10.31 9.51 19.106z\"/><path d=\"M5 54h118v16H5z\"/></g></svg>"
},
"$:/core/images/subscript": {
"title": "$:/core/images/subscript",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-subscript tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M2.272 16h19.91l21.649 33.675L66.414 16h18.708L53.585 61.969l33.809 49.443H67.082L43.296 74.93l-24.187 36.48H0L33.808 61.97 2.272 16zM127.91 128.412H85.328c.059-5.168 1.306-9.681 3.741-13.542 2.435-3.86 5.761-7.216 9.978-10.066a112.388 112.388 0 016.325-4.321 50.09 50.09 0 006.058-4.499c1.841-1.603 3.356-3.34 4.543-5.211 1.188-1.871 1.812-4.024 1.871-6.46 0-1.128-.133-2.33-.4-3.607a9.545 9.545 0 00-1.56-3.564c-.772-1.098-1.84-2.019-3.207-2.761-1.366-.743-3.148-1.114-5.345-1.114-2.02 0-3.697.4-5.033 1.203-1.337.801-2.406 1.9-3.208 3.296-.801 1.396-1.395 3.044-1.781 4.944-.386 1.9-.609 3.95-.668 6.147H86.486c0-3.445.46-6.637 1.38-9.577.921-2.94 2.302-5.478 4.143-7.617 1.841-2.138 4.083-3.815 6.726-5.033 2.643-1.217 5.716-1.826 9.22-1.826 3.802 0 6.979.623 9.533 1.87 2.554 1.248 4.617 2.822 6.191 4.722 1.574 1.9 2.688 3.965 3.341 6.192.653 2.227.98 4.35.98 6.37 0 2.494-.386 4.75-1.158 6.77a21.803 21.803 0 01-3.118 5.568 31.516 31.516 0 01-4.454 4.677 66.788 66.788 0 01-5.167 4.009 139.198 139.198 0 01-5.346 3.563 79.237 79.237 0 00-4.944 3.386c-1.514 1.128-2.836 2.3-3.964 3.518-1.129 1.218-1.9 2.51-2.317 3.876h30.379v9.087z\"/></svg>"
},
"$:/core/images/superscript": {
"title": "$:/core/images/superscript",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-superscript tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M2.272 16h19.91l21.649 33.675L66.414 16h18.708L53.585 61.969l33.809 49.443H67.082L43.296 74.93l-24.187 36.48H0L33.808 61.97 2.272 16zM127.91 63.412H85.328c.059-5.168 1.306-9.681 3.741-13.542 2.435-3.86 5.761-7.216 9.978-10.066a112.388 112.388 0 016.325-4.321 50.09 50.09 0 006.058-4.499c1.841-1.603 3.356-3.34 4.543-5.211 1.188-1.871 1.812-4.024 1.871-6.46 0-1.128-.133-2.33-.4-3.607a9.545 9.545 0 00-1.56-3.564c-.772-1.098-1.84-2.019-3.207-2.761-1.366-.743-3.148-1.114-5.345-1.114-2.02 0-3.697.4-5.033 1.203-1.337.801-2.406 1.9-3.208 3.296-.801 1.396-1.395 3.044-1.781 4.944-.386 1.9-.609 3.95-.668 6.147H86.486c0-3.445.46-6.637 1.38-9.577.921-2.94 2.302-5.478 4.143-7.617 1.841-2.138 4.083-3.815 6.726-5.033 2.643-1.217 5.716-1.826 9.22-1.826 3.802 0 6.979.623 9.533 1.87 2.554 1.248 4.617 2.822 6.191 4.722 1.574 1.9 2.688 3.965 3.341 6.192.653 2.227.98 4.35.98 6.37 0 2.494-.386 4.75-1.158 6.77a21.803 21.803 0 01-3.118 5.568 31.516 31.516 0 01-4.454 4.677 66.788 66.788 0 01-5.167 4.009 139.198 139.198 0 01-5.346 3.563 79.237 79.237 0 00-4.944 3.386c-1.514 1.128-2.836 2.3-3.964 3.518-1.129 1.218-1.9 2.51-2.317 3.876h30.379v9.087z\"/></svg>"
},
"$:/core/images/tag-button": {
"title": "$:/core/images/tag-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-tag-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M18.164 47.66l.004 4.105c.003 3.823 2.19 9.097 4.885 11.792l61.85 61.85c2.697 2.697 7.068 2.69 9.769-.01L125.767 94.3a6.903 6.903 0 00.01-9.77L63.928 22.683c-2.697-2.697-7.976-4.88-11.796-4.881l-27.076-.007a6.902 6.902 0 00-6.91 6.91l.008 9.96.287.033c3.73.411 8.489-.044 13.365-1.153a9.702 9.702 0 0111.14-3.662l.291-.13.128.285a9.7 9.7 0 013.3 2.17c3.796 3.796 3.801 9.945.012 13.734-3.618 3.618-9.386 3.777-13.204.482-5.365 1.122-10.674 1.596-15.309 1.237z\"/><path d=\"M47.633 39.532l.023.051c-9.689 4.356-21.584 6.799-30.396 5.828C5.273 44.089-1.028 36.43 2.443 24.078 5.562 12.976 14.3 4.361 24.047 1.548c10.68-3.083 19.749 1.968 19.749 13.225h-8.623c0-4.859-3.078-6.573-8.735-4.94-6.91 1.995-13.392 8.383-15.694 16.577-1.915 6.818.417 9.653 7.46 10.43 7.126.785 17.531-1.352 25.917-5.121l.027.06.036-.017c1.76-.758 6.266 6.549 3.524 7.74a2.8 2.8 0 01-.075.03z\"/></g></svg>"
},
"$:/core/images/theme-button": {
"title": "$:/core/images/theme-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-theme-button tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M55.854 66.945a122.626 122.626 0 01-3.9-4.819c-11.064-14.548-16.645-6.888-22.96 0-6.315 6.888 1.664 12.47-4.33 17.335-5.993 4.866-5.623 6.552-15.737-2.35-10.115-8.9-10.815-11.351-6.172-16.43 4.644-5.08 8.524 2.918 18.01-6.108 9.485-9.026 1.517-17.026 1.517-17.026S42.03-2.824 68.42.157c26.39 2.982-9.984-3.86-19.031 27.801-3.874 13.556.72 10.362 8.066 16.087 1.707 1.33 6.428 4.732 12.671 9.318-6.129 5.879-11.157 10.669-14.273 13.582zm11.641 12.947c16.013 17.036 37.742 37.726 45.117 40.42 10.432 3.813 15.388-3.141 15.388-14.79 0-7.151-23.83-26.542-43.924-41.769-7.408 7.156-13.376 12.953-16.58 16.139z\"/><path d=\"M11.069 109.828L46.31 74.587a3.56 3.56 0 115.037-5.032l15.098 15.098a3.56 3.56 0 11-5.032 5.037l-35.24 35.241c-4.171 4.17-10.933 4.17-15.104 0-4.17-4.17-4.17-10.933 0-15.103zM124.344 6.622l5.034 5.034-7.49 12.524-7.613 2.58L61.413 79.62l-5.034-5.034 52.861-52.862 2.58-7.614 12.524-7.49z\"/></g></svg>"
},
"$:/core/images/timestamp-off": {
"title": "$:/core/images/timestamp-off",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-timestamp-off tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10a5 5 0 010-10H66.69a5 5 0 015 5c.006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M58.25 35.88c-18.777 0-33.998 15.224-33.998 33.998 0 18.773 15.22 34.002 33.998 34.002 18.784 0 34.002-15.23 34.002-34.002 0-18.774-15.218-33.998-34.002-33.998zm-3.03 50.123H44.196v-34H55.22v34zm16.976 0H61.17v-34h11.025v34z\"/></g></svg>"
},
"$:/core/images/timestamp-on": {
"title": "$:/core/images/timestamp-on",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-timestamp-on tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10a5 5 0 010-10H66.69a5 5 0 015 5c.006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M13.41 27.178a5.005 5.005 0 01-7.045-.613 5.008 5.008 0 01.616-7.047l9.95-8.348a5 5 0 016.429 7.661l-9.95 8.348zm89.573 0a5.005 5.005 0 007.045-.613 5.008 5.008 0 00-.616-7.047l-9.95-8.348a5 5 0 00-6.428 7.661l9.95 8.348zM65.097 71.072c0 3.826-3.09 6.928-6.897 6.928-3.804.006-6.9-3.102-6.903-6.928 0 0 4.76-39.072 6.903-39.072s6.897 39.072 6.897 39.072z\"/></g></svg>"
},
"$:/core/images/tip": {
"title": "$:/core/images/tip",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-tip tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 128.242c35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64-35.346 0-64 28.654-64 64 0 35.346 28.654 64 64 64zm11.936-36.789c-.624 4.129-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349C54.33 94.05 58.824 95.82 64 95.82c5.175 0 9.67-1.769 11.936-4.366zm0 4.492c-.624 4.13-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349 2.266 2.597 6.76 4.366 11.936 4.366 5.175 0 9.67-1.769 11.936-4.366zm0 4.456c-.624 4.129-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349 2.266 2.597 6.76 4.366 11.936 4.366 5.175 0 9.67-1.769 11.936-4.366zm0 4.492c-.624 4.13-5.73 7.349-11.936 7.349-6.206 0-11.312-3.22-11.936-7.349 2.266 2.597 6.76 4.366 11.936 4.366 5.175 0 9.67-1.769 11.936-4.366zM64.3 24.242c11.618 0 23.699 7.82 23.699 24.2S75.92 71.754 75.92 83.576c0 5.873-5.868 9.26-11.92 9.26s-12.027-3.006-12.027-9.26C51.973 71.147 40 65.47 40 48.442s12.683-24.2 24.301-24.2z\"/></svg>"
},
"$:/core/images/transcludify": {
"title": "$:/core/images/transcludify",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-transcludify-button tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M0 59.482c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 002.75-.932 6.762 6.762 0 002.306-1.907c.651-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 00-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 00-2.75-1.02C1.36 67.377.591 67.288 0 67.288v-7.806zm24.66 0c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 002.75-.932 6.762 6.762 0 002.306-1.907c.65-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 00-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 00-2.75-1.02c-.946-.177-1.715-.266-2.306-.266v-7.806zm43.965-3.538L80.6 52.041l2.306 7.097-12.063 3.903 7.628 10.378-6.12 4.435-7.63-10.467-7.45 10.201-5.943-4.524 7.628-10.023-12.152-4.17 2.306-7.096 12.064 4.17V43.347h7.451v12.596zm34.425 11.344c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 00-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 00.71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 00-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 002.262 2.084 8.868 8.868 0 002.75 1.02c.946.177 1.745.266 2.395.266v7.806zm24.66 0c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 00-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 00.71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 00-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 002.262 2.084 8.868 8.868 0 002.75 1.02c.946.177 1.745.266 2.395.266v7.806z\"/></svg>"
},
"$:/core/images/twitter": {
"title": "$:/core/images/twitter",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-twitter tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M41.626 115.803A73.376 73.376 0 012 104.235c2.022.238 4.08.36 6.166.36 12.111 0 23.258-4.117 32.105-11.023-11.312-.208-20.859-7.653-24.148-17.883a25.98 25.98 0 0011.674-.441C15.971 72.881 7.061 62.474 7.061 49.997c0-.108 0-.216.002-.323a25.824 25.824 0 0011.709 3.22c-6.936-4.617-11.5-12.5-11.5-21.433 0-4.719 1.274-9.142 3.5-12.945 12.75 15.579 31.797 25.83 53.281 26.904-.44-1.884-.67-3.85-.67-5.868 0-14.22 11.575-25.75 25.852-25.75a25.865 25.865 0 0118.869 8.132 51.892 51.892 0 0016.415-6.248c-1.93 6.012-6.029 11.059-11.366 14.246A51.844 51.844 0 00128 25.878a52.428 52.428 0 01-12.9 13.33c.05 1.104.075 2.214.075 3.33 0 34.028-26 73.265-73.549 73.265\"/></svg>"
},
"$:/core/images/underline": {
"title": "$:/core/images/underline",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-underline tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M7 117.421h114.248V128H7v-10.579zm97.871-18.525V0h-16.26v55.856c0 4.463-.605 8.576-1.816 12.338-1.212 3.762-3.03 7.046-5.452 9.851-2.423 2.806-5.452 4.974-9.086 6.504-3.635 1.53-7.939 2.296-12.912 2.296-6.25 0-11.159-1.786-14.73-5.356-3.57-3.571-5.356-8.417-5.356-14.538V0H23v65.038c0 5.356.542 10.234 1.626 14.633 1.084 4.4 2.965 8.194 5.643 11.382 2.678 3.188 6.185 5.643 10.52 7.365 4.337 1.721 9.756 2.582 16.26 2.582 7.27 0 13.582-1.435 18.938-4.304 5.356-2.87 9.755-7.365 13.199-13.486h.382v15.686h15.303z\"/></svg>"
},
"$:/core/images/unfold-all-button": {
"title": "$:/core/images/unfold-all-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-unfold-all tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><rect width=\"128\" height=\"16\" y=\"64\" rx=\"8\"/><path d=\"M63.945 60.624c-2.05 0-4.101-.78-5.666-2.345L35.662 35.662c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.192-3.122 11.319.005L63.94 41.314l16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L69.603 58.279a7.986 7.986 0 01-5.663 2.346zM64.004 124.565c-2.05 0-4.102-.78-5.666-2.345L35.721 99.603c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.191-3.122 11.318.005L64 105.255l16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L69.662 122.22a7.986 7.986 0 01-5.663 2.346z\"/></g></svg>"
},
"$:/core/images/unfold-button": {
"title": "$:/core/images/unfold-button",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-unfold tc-image-button\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"128\" height=\"16\" rx=\"8\"/><path d=\"M63.945 63.624c-2.05 0-4.101-.78-5.666-2.345L35.662 38.662c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.192-3.122 11.319.005L63.94 44.314l16.966-16.966c3.124-3.124 8.194-3.129 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319L69.603 61.279a7.986 7.986 0 01-5.663 2.346zM64.004 105.682c-2.05.001-4.102-.78-5.666-2.344L35.721 80.721c-3.125-3.125-3.13-8.195-.005-11.319 3.118-3.118 8.191-3.122 11.318.005L64 86.373l16.966-16.966c3.124-3.125 8.194-3.13 11.318-.005 3.118 3.118 3.122 8.192-.005 11.319l-22.617 22.617a7.986 7.986 0 01-5.663 2.346z\"/></g></svg>"
},
"$:/core/images/unlocked-padlock": {
"title": "$:/core/images/unlocked-padlock",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-unlocked-padlock tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M48.627 64H105v32.01C105 113.674 90.674 128 73.001 128H56C38.318 128 24 113.677 24 96.01V64h6.136c-10.455-12.651-27.364-35.788-4.3-55.142 24.636-20.672 45.835 4.353 55.777 16.201 9.943 11.85-2.676 22.437-12.457 9.892-9.78-12.545-21.167-24.146-33.207-14.043-12.041 10.104-1.757 22.36 8.813 34.958 2.467 2.94 3.641 5.732 3.865 8.134zm19.105 28.364A8.503 8.503 0 0064.5 76a8.5 8.5 0 00-3.498 16.25l-5.095 22.77H72.8l-5.07-22.656z\"/></svg>"
},
"$:/core/images/up-arrow": {
"title": "$:/core/images/up-arrow",
"created": "20150316000544368",
"modified": "20150316000831867",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-up-arrow tc-image-button\" viewBox=\"0 0 128 128\"><path d=\"M63.892.281c2.027 0 4.054.77 5.6 2.316l55.98 55.98a7.92 7.92 0 010 11.196c-3.086 3.085-8.104 3.092-11.196 0L63.894 19.393 13.513 69.774a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l55.98-55.98A7.892 7.892 0 0163.893.28z\"/></svg>"
},
"$:/core/images/video": {
"title": "$:/core/images/video",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-video tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M64 12c-34.91 0-55.273 2.917-58.182 5.833C2.91 20.75 0 41.167 0 64.5c0 23.333 2.91 43.75 5.818 46.667C8.728 114.083 29.091 117 64 117c34.91 0 55.273-2.917 58.182-5.833C125.09 108.25 128 87.833 128 64.5c0-23.333-2.91-43.75-5.818-46.667C119.272 14.917 98.909 12 64 12zm-9.084 32.618c-3.813-2.542-6.905-.879-6.905 3.698v31.368c0 4.585 3.099 6.235 6.905 3.698l22.168-14.779c3.813-2.542 3.806-6.669 0-9.206L54.916 44.618z\"/></svg>"
},
"$:/core/images/warning": {
"title": "$:/core/images/warning",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" class=\"tc-image-warning tc-image-button\" viewBox=\"0 0 128 128\"><path fill-rule=\"evenodd\" d=\"M57.072 11c3.079-5.333 10.777-5.333 13.856 0l55.426 96c3.079 5.333-.77 12-6.928 12H8.574c-6.158 0-10.007-6.667-6.928-12l55.426-96zM64 37c-4.418 0-8 3.582-8 7.994v28.012C56 77.421 59.59 81 64 81c4.418 0 8-3.582 8-7.994V44.994C72 40.579 68.41 37 64 37zm0 67a8 8 0 100-16 8 8 0 000 16z\"/></svg>"
},
"$:/language/Buttons/AdvancedSearch/Caption": {
"title": "$:/language/Buttons/AdvancedSearch/Caption",
"text": "advanced search"
},
"$:/language/Buttons/AdvancedSearch/Hint": {
"title": "$:/language/Buttons/AdvancedSearch/Hint",
"text": "Advanced search"
},
"$:/language/Buttons/Cancel/Caption": {
"title": "$:/language/Buttons/Cancel/Caption",
"text": "cancel"
},
"$:/language/Buttons/Cancel/Hint": {
"title": "$:/language/Buttons/Cancel/Hint",
"text": "Discard changes to this tiddler"
},
"$:/language/Buttons/Clone/Caption": {
"title": "$:/language/Buttons/Clone/Caption",
"text": "clone"
},
"$:/language/Buttons/Clone/Hint": {
"title": "$:/language/Buttons/Clone/Hint",
"text": "Clone this tiddler"
},
"$:/language/Buttons/Close/Caption": {
"title": "$:/language/Buttons/Close/Caption",
"text": "close"
},
"$:/language/Buttons/Close/Hint": {
"title": "$:/language/Buttons/Close/Hint",
"text": "Close this tiddler"
},
"$:/language/Buttons/CloseAll/Caption": {
"title": "$:/language/Buttons/CloseAll/Caption",
"text": "close all"
},
"$:/language/Buttons/CloseAll/Hint": {
"title": "$:/language/Buttons/CloseAll/Hint",
"text": "Close all tiddlers"
},
"$:/language/Buttons/CloseOthers/Caption": {
"title": "$:/language/Buttons/CloseOthers/Caption",
"text": "close others"
},
"$:/language/Buttons/CloseOthers/Hint": {
"title": "$:/language/Buttons/CloseOthers/Hint",
"text": "Close other tiddlers"
},
"$:/language/Buttons/ControlPanel/Caption": {
"title": "$:/language/Buttons/ControlPanel/Caption",
"text": "control panel"
},
"$:/language/Buttons/ControlPanel/Hint": {
"title": "$:/language/Buttons/ControlPanel/Hint",
"text": "Open control panel"
},
"$:/language/Buttons/CopyToClipboard/Caption": {
"title": "$:/language/Buttons/CopyToClipboard/Caption",
"text": "copy to clipboard"
},
"$:/language/Buttons/CopyToClipboard/Hint": {
"title": "$:/language/Buttons/CopyToClipboard/Hint",
"text": "Copy this text to the clipboard"
},
"$:/language/Buttons/Delete/Caption": {
"title": "$:/language/Buttons/Delete/Caption",
"text": "delete"
},
"$:/language/Buttons/Delete/Hint": {
"title": "$:/language/Buttons/Delete/Hint",
"text": "Delete this tiddler"
},
"$:/language/Buttons/Edit/Caption": {
"title": "$:/language/Buttons/Edit/Caption",
"text": "edit"
},
"$:/language/Buttons/Edit/Hint": {
"title": "$:/language/Buttons/Edit/Hint",
"text": "Edit this tiddler"
},
"$:/language/Buttons/Encryption/Caption": {
"title": "$:/language/Buttons/Encryption/Caption",
"text": "encryption"
},
"$:/language/Buttons/Encryption/Hint": {
"title": "$:/language/Buttons/Encryption/Hint",
"text": "Set or clear a password for saving this wiki"
},
"$:/language/Buttons/Encryption/ClearPassword/Caption": {
"title": "$:/language/Buttons/Encryption/ClearPassword/Caption",
"text": "clear password"
},
"$:/language/Buttons/Encryption/ClearPassword/Hint": {
"title": "$:/language/Buttons/Encryption/ClearPassword/Hint",
"text": "Clear the password and save this wiki without encryption"
},
"$:/language/Buttons/Encryption/SetPassword/Caption": {
"title": "$:/language/Buttons/Encryption/SetPassword/Caption",
"text": "set password"
},
"$:/language/Buttons/Encryption/SetPassword/Hint": {
"title": "$:/language/Buttons/Encryption/SetPassword/Hint",
"text": "Set a password for saving this wiki with encryption"
},
"$:/language/Buttons/ExportPage/Caption": {
"title": "$:/language/Buttons/ExportPage/Caption",
"text": "export all"
},
"$:/language/Buttons/ExportPage/Hint": {
"title": "$:/language/Buttons/ExportPage/Hint",
"text": "Export all tiddlers"
},
"$:/language/Buttons/ExportTiddler/Caption": {
"title": "$:/language/Buttons/ExportTiddler/Caption",
"text": "export tiddler"
},
"$:/language/Buttons/ExportTiddler/Hint": {
"title": "$:/language/Buttons/ExportTiddler/Hint",
"text": "Export tiddler"
},
"$:/language/Buttons/ExportTiddlers/Caption": {
"title": "$:/language/Buttons/ExportTiddlers/Caption",
"text": "export tiddlers"
},
"$:/language/Buttons/ExportTiddlers/Hint": {
"title": "$:/language/Buttons/ExportTiddlers/Hint",
"text": "Export tiddlers"
},
"$:/language/Buttons/SidebarSearch/Hint": {
"title": "$:/language/Buttons/SidebarSearch/Hint",
"text": "Select the sidebar search field"
},
"$:/language/Buttons/Fold/Caption": {
"title": "$:/language/Buttons/Fold/Caption",
"text": "fold tiddler"
},
"$:/language/Buttons/Fold/Hint": {
"title": "$:/language/Buttons/Fold/Hint",
"text": "Fold the body of this tiddler"
},
"$:/language/Buttons/Fold/FoldBar/Caption": {
"title": "$:/language/Buttons/Fold/FoldBar/Caption",
"text": "fold-bar"
},
"$:/language/Buttons/Fold/FoldBar/Hint": {
"title": "$:/language/Buttons/Fold/FoldBar/Hint",
"text": "Optional bars to fold and unfold tiddlers"
},
"$:/language/Buttons/Unfold/Caption": {
"title": "$:/language/Buttons/Unfold/Caption",
"text": "unfold tiddler"
},
"$:/language/Buttons/Unfold/Hint": {
"title": "$:/language/Buttons/Unfold/Hint",
"text": "Unfold the body of this tiddler"
},
"$:/language/Buttons/FoldOthers/Caption": {
"title": "$:/language/Buttons/FoldOthers/Caption",
"text": "fold other tiddlers"
},
"$:/language/Buttons/FoldOthers/Hint": {
"title": "$:/language/Buttons/FoldOthers/Hint",
"text": "Fold the bodies of other opened tiddlers"
},
"$:/language/Buttons/FoldAll/Caption": {
"title": "$:/language/Buttons/FoldAll/Caption",
"text": "fold all tiddlers"
},
"$:/language/Buttons/FoldAll/Hint": {
"title": "$:/language/Buttons/FoldAll/Hint",
"text": "Fold the bodies of all opened tiddlers"
},
"$:/language/Buttons/UnfoldAll/Caption": {
"title": "$:/language/Buttons/UnfoldAll/Caption",
"text": "unfold all tiddlers"
},
"$:/language/Buttons/UnfoldAll/Hint": {
"title": "$:/language/Buttons/UnfoldAll/Hint",
"text": "Unfold the bodies of all opened tiddlers"
},
"$:/language/Buttons/FullScreen/Caption": {
"title": "$:/language/Buttons/FullScreen/Caption",
"text": "full-screen"
},
"$:/language/Buttons/FullScreen/Hint": {
"title": "$:/language/Buttons/FullScreen/Hint",
"text": "Enter or leave full-screen mode"
},
"$:/language/Buttons/Help/Caption": {
"title": "$:/language/Buttons/Help/Caption",
"text": "help"
},
"$:/language/Buttons/Help/Hint": {
"title": "$:/language/Buttons/Help/Hint",
"text": "Show help panel"
},
"$:/language/Buttons/Import/Caption": {
"title": "$:/language/Buttons/Import/Caption",
"text": "import"
},
"$:/language/Buttons/Import/Hint": {
"title": "$:/language/Buttons/Import/Hint",
"text": "Import many types of file including text, image, TiddlyWiki or JSON"
},
"$:/language/Buttons/Info/Caption": {
"title": "$:/language/Buttons/Info/Caption",
"text": "info"
},
"$:/language/Buttons/Info/Hint": {
"title": "$:/language/Buttons/Info/Hint",
"text": "Show information for this tiddler"
},
"$:/language/Buttons/Home/Caption": {
"title": "$:/language/Buttons/Home/Caption",
"text": "home"
},
"$:/language/Buttons/Home/Hint": {
"title": "$:/language/Buttons/Home/Hint",
"text": "Open the default tiddlers"
},
"$:/language/Buttons/Language/Caption": {
"title": "$:/language/Buttons/Language/Caption",
"text": "language"
},
"$:/language/Buttons/Language/Hint": {
"title": "$:/language/Buttons/Language/Hint",
"text": "Choose the user interface language"
},
"$:/language/Buttons/Manager/Caption": {
"title": "$:/language/Buttons/Manager/Caption",
"text": "tiddler manager"
},
"$:/language/Buttons/Manager/Hint": {
"title": "$:/language/Buttons/Manager/Hint",
"text": "Open tiddler manager"
},
"$:/language/Buttons/More/Caption": {
"title": "$:/language/Buttons/More/Caption",
"text": "more"
},
"$:/language/Buttons/More/Hint": {
"title": "$:/language/Buttons/More/Hint",
"text": "More actions"
},
"$:/language/Buttons/NewHere/Caption": {
"title": "$:/language/Buttons/NewHere/Caption",
"text": "new here"
},
"$:/language/Buttons/NewHere/Hint": {
"title": "$:/language/Buttons/NewHere/Hint",
"text": "Create a new tiddler tagged with this one"
},
"$:/language/Buttons/NewJournal/Caption": {
"title": "$:/language/Buttons/NewJournal/Caption",
"text": "new journal"
},
"$:/language/Buttons/NewJournal/Hint": {
"title": "$:/language/Buttons/NewJournal/Hint",
"text": "Create a new journal tiddler"
},
"$:/language/Buttons/NewJournalHere/Caption": {
"title": "$:/language/Buttons/NewJournalHere/Caption",
"text": "new journal here"
},
"$:/language/Buttons/NewJournalHere/Hint": {
"title": "$:/language/Buttons/NewJournalHere/Hint",
"text": "Create a new journal tiddler tagged with this one"
},
"$:/language/Buttons/NewImage/Caption": {
"title": "$:/language/Buttons/NewImage/Caption",
"text": "new image"
},
"$:/language/Buttons/NewImage/Hint": {
"title": "$:/language/Buttons/NewImage/Hint",
"text": "Create a new image tiddler"
},
"$:/language/Buttons/NewMarkdown/Caption": {
"title": "$:/language/Buttons/NewMarkdown/Caption",
"text": "new Markdown tiddler"
},
"$:/language/Buttons/NewMarkdown/Hint": {
"title": "$:/language/Buttons/NewMarkdown/Hint",
"text": "Create a new Markdown tiddler"
},
"$:/language/Buttons/NewTiddler/Caption": {
"title": "$:/language/Buttons/NewTiddler/Caption",
"text": "new tiddler"
},
"$:/language/Buttons/NewTiddler/Hint": {
"title": "$:/language/Buttons/NewTiddler/Hint",
"text": "Create a new tiddler"
},
"$:/language/Buttons/OpenWindow/Caption": {
"title": "$:/language/Buttons/OpenWindow/Caption",
"text": "open in new window"
},
"$:/language/Buttons/OpenWindow/Hint": {
"title": "$:/language/Buttons/OpenWindow/Hint",
"text": "Open tiddler in new window"
},
"$:/language/Buttons/Palette/Caption": {
"title": "$:/language/Buttons/Palette/Caption",
"text": "palette"
},
"$:/language/Buttons/Palette/Hint": {
"title": "$:/language/Buttons/Palette/Hint",
"text": "Choose the colour palette"
},
"$:/language/Buttons/Permalink/Caption": {
"title": "$:/language/Buttons/Permalink/Caption",
"text": "permalink"
},
"$:/language/Buttons/Permalink/Hint": {
"title": "$:/language/Buttons/Permalink/Hint",
"text": "Set browser address bar to a direct link to this tiddler"
},
"$:/language/Buttons/Permaview/Caption": {
"title": "$:/language/Buttons/Permaview/Caption",
"text": "permaview"
},
"$:/language/Buttons/Permaview/Hint": {
"title": "$:/language/Buttons/Permaview/Hint",
"text": "Set browser address bar to a direct link to all the tiddlers in this story"
},
"$:/language/Buttons/Print/Caption": {
"title": "$:/language/Buttons/Print/Caption",
"text": "print page"
},
"$:/language/Buttons/Print/Hint": {
"title": "$:/language/Buttons/Print/Hint",
"text": "Print the current page"
},
"$:/language/Buttons/Refresh/Caption": {
"title": "$:/language/Buttons/Refresh/Caption",
"text": "refresh"
},
"$:/language/Buttons/Refresh/Hint": {
"title": "$:/language/Buttons/Refresh/Hint",
"text": "Perform a full refresh of the wiki"
},
"$:/language/Buttons/Save/Caption": {
"title": "$:/language/Buttons/Save/Caption",
"text": "ok"
},
"$:/language/Buttons/Save/Hint": {
"title": "$:/language/Buttons/Save/Hint",
"text": "Confirm changes to this tiddler"
},
"$:/language/Buttons/SaveWiki/Caption": {
"title": "$:/language/Buttons/SaveWiki/Caption",
"text": "save changes"
},
"$:/language/Buttons/SaveWiki/Hint": {
"title": "$:/language/Buttons/SaveWiki/Hint",
"text": "Save changes"
},
"$:/language/Buttons/StoryView/Caption": {
"title": "$:/language/Buttons/StoryView/Caption",
"text": "storyview"
},
"$:/language/Buttons/StoryView/Hint": {
"title": "$:/language/Buttons/StoryView/Hint",
"text": "Choose the story visualisation"
},
"$:/language/Buttons/HideSideBar/Caption": {
"title": "$:/language/Buttons/HideSideBar/Caption",
"text": "hide sidebar"
},
"$:/language/Buttons/HideSideBar/Hint": {
"title": "$:/language/Buttons/HideSideBar/Hint",
"text": "Hide sidebar"
},
"$:/language/Buttons/ShowSideBar/Caption": {
"title": "$:/language/Buttons/ShowSideBar/Caption",
"text": "show sidebar"
},
"$:/language/Buttons/ShowSideBar/Hint": {
"title": "$:/language/Buttons/ShowSideBar/Hint",
"text": "Show sidebar"
},
"$:/language/Buttons/TagManager/Caption": {
"title": "$:/language/Buttons/TagManager/Caption",
"text": "tag manager"
},
"$:/language/Buttons/TagManager/Hint": {
"title": "$:/language/Buttons/TagManager/Hint",
"text": "Open tag manager"
},
"$:/language/Buttons/Timestamp/Caption": {
"title": "$:/language/Buttons/Timestamp/Caption",
"text": "timestamps"
},
"$:/language/Buttons/Timestamp/Hint": {
"title": "$:/language/Buttons/Timestamp/Hint",
"text": "Choose whether modifications update timestamps"
},
"$:/language/Buttons/Timestamp/On/Caption": {
"title": "$:/language/Buttons/Timestamp/On/Caption",
"text": "timestamps are on"
},
"$:/language/Buttons/Timestamp/On/Hint": {
"title": "$:/language/Buttons/Timestamp/On/Hint",
"text": "Update timestamps when tiddlers are modified"
},
"$:/language/Buttons/Timestamp/Off/Caption": {
"title": "$:/language/Buttons/Timestamp/Off/Caption",
"text": "timestamps are off"
},
"$:/language/Buttons/Timestamp/Off/Hint": {
"title": "$:/language/Buttons/Timestamp/Off/Hint",
"text": "Don't update timestamps when tiddlers are modified"
},
"$:/language/Buttons/Theme/Caption": {
"title": "$:/language/Buttons/Theme/Caption",
"text": "theme"
},
"$:/language/Buttons/Theme/Hint": {
"title": "$:/language/Buttons/Theme/Hint",
"text": "Choose the display theme"
},
"$:/language/Buttons/Bold/Caption": {
"title": "$:/language/Buttons/Bold/Caption",
"text": "bold"
},
"$:/language/Buttons/Bold/Hint": {
"title": "$:/language/Buttons/Bold/Hint",
"text": "Apply bold formatting to selection"
},
"$:/language/Buttons/Clear/Caption": {
"title": "$:/language/Buttons/Clear/Caption",
"text": "clear"
},
"$:/language/Buttons/Clear/Hint": {
"title": "$:/language/Buttons/Clear/Hint",
"text": "Clear image to solid colour"
},
"$:/language/Buttons/EditorHeight/Caption": {
"title": "$:/language/Buttons/EditorHeight/Caption",
"text": "editor height"
},
"$:/language/Buttons/EditorHeight/Caption/Auto": {
"title": "$:/language/Buttons/EditorHeight/Caption/Auto",
"text": "Automatically adjust height to fit content"
},
"$:/language/Buttons/EditorHeight/Caption/Fixed": {
"title": "$:/language/Buttons/EditorHeight/Caption/Fixed",
"text": "Fixed height:"
},
"$:/language/Buttons/EditorHeight/Hint": {
"title": "$:/language/Buttons/EditorHeight/Hint",
"text": "Choose the height of the text editor"
},
"$:/language/Buttons/Excise/Caption": {
"title": "$:/language/Buttons/Excise/Caption",
"text": "excise"
},
"$:/language/Buttons/Excise/Caption/Excise": {
"title": "$:/language/Buttons/Excise/Caption/Excise",
"text": "Perform excision"
},
"$:/language/Buttons/Excise/Caption/MacroName": {
"title": "$:/language/Buttons/Excise/Caption/MacroName",
"text": "Macro name:"
},
"$:/language/Buttons/Excise/Caption/NewTitle": {
"title": "$:/language/Buttons/Excise/Caption/NewTitle",
"text": "Title of new tiddler:"
},
"$:/language/Buttons/Excise/Caption/Replace": {
"title": "$:/language/Buttons/Excise/Caption/Replace",
"text": "Replace excised text with:"
},
"$:/language/Buttons/Excise/Caption/Replace/Macro": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Macro",
"text": "macro"
},
"$:/language/Buttons/Excise/Caption/Replace/Link": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Link",
"text": "link"
},
"$:/language/Buttons/Excise/Caption/Replace/Transclusion": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Transclusion",
"text": "transclusion"
},
"$:/language/Buttons/Excise/Caption/Tag": {
"title": "$:/language/Buttons/Excise/Caption/Tag",
"text": "Tag new tiddler with the title of this tiddler"
},
"$:/language/Buttons/Excise/Caption/TiddlerExists": {
"title": "$:/language/Buttons/Excise/Caption/TiddlerExists",
"text": "Warning: tiddler already exists"
},
"$:/language/Buttons/Excise/Hint": {
"title": "$:/language/Buttons/Excise/Hint",
"text": "Excise the selected text into a new tiddler"
},
"$:/language/Buttons/Heading1/Caption": {
"title": "$:/language/Buttons/Heading1/Caption",
"text": "heading 1"
},
"$:/language/Buttons/Heading1/Hint": {
"title": "$:/language/Buttons/Heading1/Hint",
"text": "Apply heading level 1 formatting to lines containing selection"
},
"$:/language/Buttons/Heading2/Caption": {
"title": "$:/language/Buttons/Heading2/Caption",
"text": "heading 2"
},
"$:/language/Buttons/Heading2/Hint": {
"title": "$:/language/Buttons/Heading2/Hint",
"text": "Apply heading level 2 formatting to lines containing selection"
},
"$:/language/Buttons/Heading3/Caption": {
"title": "$:/language/Buttons/Heading3/Caption",
"text": "heading 3"
},
"$:/language/Buttons/Heading3/Hint": {
"title": "$:/language/Buttons/Heading3/Hint",
"text": "Apply heading level 3 formatting to lines containing selection"
},
"$:/language/Buttons/Heading4/Caption": {
"title": "$:/language/Buttons/Heading4/Caption",
"text": "heading 4"
},
"$:/language/Buttons/Heading4/Hint": {
"title": "$:/language/Buttons/Heading4/Hint",
"text": "Apply heading level 4 formatting to lines containing selection"
},
"$:/language/Buttons/Heading5/Caption": {
"title": "$:/language/Buttons/Heading5/Caption",
"text": "heading 5"
},
"$:/language/Buttons/Heading5/Hint": {
"title": "$:/language/Buttons/Heading5/Hint",
"text": "Apply heading level 5 formatting to lines containing selection"
},
"$:/language/Buttons/Heading6/Caption": {
"title": "$:/language/Buttons/Heading6/Caption",
"text": "heading 6"
},
"$:/language/Buttons/Heading6/Hint": {
"title": "$:/language/Buttons/Heading6/Hint",
"text": "Apply heading level 6 formatting to lines containing selection"
},
"$:/language/Buttons/Italic/Caption": {
"title": "$:/language/Buttons/Italic/Caption",
"text": "italic"
},
"$:/language/Buttons/Italic/Hint": {
"title": "$:/language/Buttons/Italic/Hint",
"text": "Apply italic formatting to selection"
},
"$:/language/Buttons/LineWidth/Caption": {
"title": "$:/language/Buttons/LineWidth/Caption",
"text": "line width"
},
"$:/language/Buttons/LineWidth/Hint": {
"title": "$:/language/Buttons/LineWidth/Hint",
"text": "Set line width for painting"
},
"$:/language/Buttons/Link/Caption": {
"title": "$:/language/Buttons/Link/Caption",
"text": "link"
},
"$:/language/Buttons/Link/Hint": {
"title": "$:/language/Buttons/Link/Hint",
"text": "Create wikitext link"
},
"$:/language/Buttons/Linkify/Caption": {
"title": "$:/language/Buttons/Linkify/Caption",
"text": "wikilink"
},
"$:/language/Buttons/Linkify/Hint": {
"title": "$:/language/Buttons/Linkify/Hint",
"text": "Wrap selection in square brackets"
},
"$:/language/Buttons/ListBullet/Caption": {
"title": "$:/language/Buttons/ListBullet/Caption",
"text": "bulleted list"
},
"$:/language/Buttons/ListBullet/Hint": {
"title": "$:/language/Buttons/ListBullet/Hint",
"text": "Apply bulleted list formatting to lines containing selection"
},
"$:/language/Buttons/ListNumber/Caption": {
"title": "$:/language/Buttons/ListNumber/Caption",
"text": "numbered list"
},
"$:/language/Buttons/ListNumber/Hint": {
"title": "$:/language/Buttons/ListNumber/Hint",
"text": "Apply numbered list formatting to lines containing selection"
},
"$:/language/Buttons/MonoBlock/Caption": {
"title": "$:/language/Buttons/MonoBlock/Caption",
"text": "monospaced block"
},
"$:/language/Buttons/MonoBlock/Hint": {
"title": "$:/language/Buttons/MonoBlock/Hint",
"text": "Apply monospaced block formatting to lines containing selection"
},
"$:/language/Buttons/MonoLine/Caption": {
"title": "$:/language/Buttons/MonoLine/Caption",
"text": "monospaced"
},
"$:/language/Buttons/MonoLine/Hint": {
"title": "$:/language/Buttons/MonoLine/Hint",
"text": "Apply monospaced character formatting to selection"
},
"$:/language/Buttons/Opacity/Caption": {
"title": "$:/language/Buttons/Opacity/Caption",
"text": "opacity"
},
"$:/language/Buttons/Opacity/Hint": {
"title": "$:/language/Buttons/Opacity/Hint",
"text": "Set painting opacity"
},
"$:/language/Buttons/Paint/Caption": {
"title": "$:/language/Buttons/Paint/Caption",
"text": "paint colour"
},
"$:/language/Buttons/Paint/Hint": {
"title": "$:/language/Buttons/Paint/Hint",
"text": "Set painting colour"
},
"$:/language/Buttons/Picture/Caption": {
"title": "$:/language/Buttons/Picture/Caption",
"text": "picture"
},
"$:/language/Buttons/Picture/Hint": {
"title": "$:/language/Buttons/Picture/Hint",
"text": "Insert picture"
},
"$:/language/Buttons/Preview/Caption": {
"title": "$:/language/Buttons/Preview/Caption",
"text": "preview"
},
"$:/language/Buttons/Preview/Hint": {
"title": "$:/language/Buttons/Preview/Hint",
"text": "Show preview pane"
},
"$:/language/Buttons/PreviewType/Caption": {
"title": "$:/language/Buttons/PreviewType/Caption",
"text": "preview type"
},
"$:/language/Buttons/PreviewType/Hint": {
"title": "$:/language/Buttons/PreviewType/Hint",
"text": "Choose preview type"
},
"$:/language/Buttons/Quote/Caption": {
"title": "$:/language/Buttons/Quote/Caption",
"text": "quote"
},
"$:/language/Buttons/Quote/Hint": {
"title": "$:/language/Buttons/Quote/Hint",
"text": "Apply quoted text formatting to lines containing selection"
},
"$:/language/Buttons/RotateLeft/Caption": {
"title": "$:/language/Buttons/RotateLeft/Caption",
"text": "rotate left"
},
"$:/language/Buttons/RotateLeft/Hint": {
"title": "$:/language/Buttons/RotateLeft/Hint",
"text": "Rotate image left by 90 degrees"
},
"$:/language/Buttons/Size/Caption": {
"title": "$:/language/Buttons/Size/Caption",
"text": "image size"
},
"$:/language/Buttons/Size/Caption/Height": {
"title": "$:/language/Buttons/Size/Caption/Height",
"text": "Height:"
},
"$:/language/Buttons/Size/Caption/Resize": {
"title": "$:/language/Buttons/Size/Caption/Resize",
"text": "Resize image"
},
"$:/language/Buttons/Size/Caption/Width": {
"title": "$:/language/Buttons/Size/Caption/Width",
"text": "Width:"
},
"$:/language/Buttons/Size/Hint": {
"title": "$:/language/Buttons/Size/Hint",
"text": "Set image size"
},
"$:/language/Buttons/Stamp/Caption": {
"title": "$:/language/Buttons/Stamp/Caption",
"text": "stamp"
},
"$:/language/Buttons/Stamp/Caption/New": {
"title": "$:/language/Buttons/Stamp/Caption/New",
"text": "Add your own"
},
"$:/language/Buttons/Stamp/Hint": {
"title": "$:/language/Buttons/Stamp/Hint",
"text": "Insert a preconfigured snippet of text"
},
"$:/language/Buttons/Stamp/New/Title": {
"title": "$:/language/Buttons/Stamp/New/Title",
"text": "Name as shown in menu"
},
"$:/language/Buttons/Stamp/New/Text": {
"title": "$:/language/Buttons/Stamp/New/Text",
"text": "Text of snippet. (Remember to add a descriptive title in the caption field)."
},
"$:/language/Buttons/Strikethrough/Caption": {
"title": "$:/language/Buttons/Strikethrough/Caption",
"text": "strikethrough"
},
"$:/language/Buttons/Strikethrough/Hint": {
"title": "$:/language/Buttons/Strikethrough/Hint",
"text": "Apply strikethrough formatting to selection"
},
"$:/language/Buttons/Subscript/Caption": {
"title": "$:/language/Buttons/Subscript/Caption",
"text": "subscript"
},
"$:/language/Buttons/Subscript/Hint": {
"title": "$:/language/Buttons/Subscript/Hint",
"text": "Apply subscript formatting to selection"
},
"$:/language/Buttons/Superscript/Caption": {
"title": "$:/language/Buttons/Superscript/Caption",
"text": "superscript"
},
"$:/language/Buttons/Superscript/Hint": {
"title": "$:/language/Buttons/Superscript/Hint",
"text": "Apply superscript formatting to selection"
},
"$:/language/Buttons/ToggleSidebar/Hint": {
"title": "$:/language/Buttons/ToggleSidebar/Hint",
"text": "Toggle the sidebar visibility"
},
"$:/language/Buttons/Transcludify/Caption": {
"title": "$:/language/Buttons/Transcludify/Caption",
"text": "transclusion"
},
"$:/language/Buttons/Transcludify/Hint": {
"title": "$:/language/Buttons/Transcludify/Hint",
"text": "Wrap selection in curly brackets"
},
"$:/language/Buttons/Underline/Caption": {
"title": "$:/language/Buttons/Underline/Caption",
"text": "underline"
},
"$:/language/Buttons/Underline/Hint": {
"title": "$:/language/Buttons/Underline/Hint",
"text": "Apply underline formatting to selection"
},
"$:/language/ControlPanel/Advanced/Caption": {
"title": "$:/language/ControlPanel/Advanced/Caption",
"text": "Advanced"
},
"$:/language/ControlPanel/Advanced/Hint": {
"title": "$:/language/ControlPanel/Advanced/Hint",
"text": "Internal information about this TiddlyWiki"
},
"$:/language/ControlPanel/Appearance/Caption": {
"title": "$:/language/ControlPanel/Appearance/Caption",
"text": "Appearance"
},
"$:/language/ControlPanel/Appearance/Hint": {
"title": "$:/language/ControlPanel/Appearance/Hint",
"text": "Ways to customise the appearance of your TiddlyWiki."
},
"$:/language/ControlPanel/Basics/AnimDuration/Prompt": {
"title": "$:/language/ControlPanel/Basics/AnimDuration/Prompt",
"text": "Animation duration"
},
"$:/language/ControlPanel/Basics/AutoFocus/Prompt": {
"title": "$:/language/ControlPanel/Basics/AutoFocus/Prompt",
"text": "Default focus field for new tiddlers"
},
"$:/language/ControlPanel/Basics/Caption": {
"title": "$:/language/ControlPanel/Basics/Caption",
"text": "Basics"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint",
"text": "Use [[double square brackets]] for titles with spaces. Or you can choose to <$button set=\"$:/DefaultTiddlers\" setTo=\"[list[$:/StoryList]]\">retain story ordering</$button>"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt",
"text": "Default tiddlers"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint",
"text": "Choose which tiddlers are displayed at startup"
},
"$:/language/ControlPanel/Basics/Language/Prompt": {
"title": "$:/language/ControlPanel/Basics/Language/Prompt",
"text": "Hello! Current language:"
},
"$:/language/ControlPanel/Basics/NewJournal/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt",
"text": "Title of new journal tiddlers"
},
"$:/language/ControlPanel/Basics/NewJournal/Text/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt",
"text": "Text for new journal tiddlers"
},
"$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt",
"text": "Tags for new journal tiddlers"
},
"$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt",
"text": "Title of new tiddlers"
},
"$:/language/ControlPanel/Basics/NewTiddler/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewTiddler/Tags/Prompt",
"text": "Tags for new tiddlers"
},
"$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt",
"text": "Number of overridden shadow tiddlers"
},
"$:/language/ControlPanel/Basics/RemoveTags": {
"title": "$:/language/ControlPanel/Basics/RemoveTags",
"text": "Update to current format"
},
"$:/language/ControlPanel/Basics/RemoveTags/Hint": {
"title": "$:/language/ControlPanel/Basics/RemoveTags/Hint",
"text": "Update the tags configuration to the latest format"
},
"$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt",
"text": "Number of shadow tiddlers"
},
"$:/language/ControlPanel/Basics/Subtitle/Prompt": {
"title": "$:/language/ControlPanel/Basics/Subtitle/Prompt",
"text": "Subtitle"
},
"$:/language/ControlPanel/Basics/SystemTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt",
"text": "Number of system tiddlers"
},
"$:/language/ControlPanel/Basics/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/Tags/Prompt",
"text": "Number of tags"
},
"$:/language/ControlPanel/Basics/Tiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/Tiddlers/Prompt",
"text": "Number of tiddlers"
},
"$:/language/ControlPanel/Basics/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/Title/Prompt",
"text": "Title of this ~TiddlyWiki"
},
"$:/language/ControlPanel/Basics/Username/Prompt": {
"title": "$:/language/ControlPanel/Basics/Username/Prompt",
"text": "Username for signing edits"
},
"$:/language/ControlPanel/Basics/Version/Prompt": {
"title": "$:/language/ControlPanel/Basics/Version/Prompt",
"text": "~TiddlyWiki version"
},
"$:/language/ControlPanel/EditorTypes/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Caption",
"text": "Editor Types"
},
"$:/language/ControlPanel/EditorTypes/Editor/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Editor/Caption",
"text": "Editor"
},
"$:/language/ControlPanel/EditorTypes/Hint": {
"title": "$:/language/ControlPanel/EditorTypes/Hint",
"text": "These tiddlers determine which editor is used to edit specific tiddler types."
},
"$:/language/ControlPanel/EditorTypes/Type/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Type/Caption",
"text": "Type"
},
"$:/language/ControlPanel/Info/Caption": {
"title": "$:/language/ControlPanel/Info/Caption",
"text": "Info"
},
"$:/language/ControlPanel/Info/Hint": {
"title": "$:/language/ControlPanel/Info/Hint",
"text": "Information about this TiddlyWiki"
},
"$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt",
"text": "Type shortcut here"
},
"$:/language/ControlPanel/KeyboardShortcuts/Add/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption",
"text": "add shortcut"
},
"$:/language/ControlPanel/KeyboardShortcuts/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Caption",
"text": "Keyboard Shortcuts"
},
"$:/language/ControlPanel/KeyboardShortcuts/Hint": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Hint",
"text": "Manage keyboard shortcut assignments"
},
"$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption",
"text": "No keyboard shortcuts assigned"
},
"$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint",
"text": "remove keyboard shortcut"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/All": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/All",
"text": "All platforms"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac",
"text": "Macintosh platform only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac",
"text": "Non-Macintosh platforms only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux",
"text": "Linux platform only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux",
"text": "Non-Linux platforms only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows",
"text": "Windows platform only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows",
"text": "Non-Windows platforms only"
},
"$:/language/ControlPanel/LayoutSwitcher/Caption": {
"title": "$:/language/ControlPanel/LayoutSwitcher/Caption",
"text": "Layout"
},
"$:/language/ControlPanel/LoadedModules/Caption": {
"title": "$:/language/ControlPanel/LoadedModules/Caption",
"text": "Loaded Modules"
},
"$:/language/ControlPanel/LoadedModules/Hint": {
"title": "$:/language/ControlPanel/LoadedModules/Hint",
"text": "These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process."
},
"$:/language/ControlPanel/Palette/Caption": {
"title": "$:/language/ControlPanel/Palette/Caption",
"text": "Palette"
},
"$:/language/ControlPanel/Palette/Editor/Clone/Caption": {
"title": "$:/language/ControlPanel/Palette/Editor/Clone/Caption",
"text": "clone"
},
"$:/language/ControlPanel/Palette/Editor/Clone/Prompt": {
"title": "$:/language/ControlPanel/Palette/Editor/Clone/Prompt",
"text": "It is recommended that you clone this shadow palette before editing it"
},
"$:/language/ControlPanel/Palette/Editor/Delete/Hint": {
"title": "$:/language/ControlPanel/Palette/Editor/Delete/Hint",
"text": "delete this entry from the current palette"
},
"$:/language/ControlPanel/Palette/Editor/Names/External/Show": {
"title": "$:/language/ControlPanel/Palette/Editor/Names/External/Show",
"text": "Show color names that are not part of the current palette"
},
"$:/language/ControlPanel/Palette/Editor/Prompt/Modified": {
"title": "$:/language/ControlPanel/Palette/Editor/Prompt/Modified",
"text": "This shadow palette has been modified"
},
"$:/language/ControlPanel/Palette/Editor/Prompt": {
"title": "$:/language/ControlPanel/Palette/Editor/Prompt",
"text": "Editing"
},
"$:/language/ControlPanel/Palette/Editor/Reset/Caption": {
"title": "$:/language/ControlPanel/Palette/Editor/Reset/Caption",
"text": "reset"
},
"$:/language/ControlPanel/Palette/HideEditor/Caption": {
"title": "$:/language/ControlPanel/Palette/HideEditor/Caption",
"text": "hide editor"
},
"$:/language/ControlPanel/Palette/Prompt": {
"title": "$:/language/ControlPanel/Palette/Prompt",
"text": "Current palette:"
},
"$:/language/ControlPanel/Palette/ShowEditor/Caption": {
"title": "$:/language/ControlPanel/Palette/ShowEditor/Caption",
"text": "show editor"
},
"$:/language/ControlPanel/Parsing/Caption": {
"title": "$:/language/ControlPanel/Parsing/Caption",
"text": "Parsing"
},
"$:/language/ControlPanel/Parsing/Hint": {
"title": "$:/language/ControlPanel/Parsing/Hint",
"text": "Here you can globally disable/enable wiki parser rules. For changes to take effect, save and reload your wiki. Disabling certain parser rules can prevent <$text text=\"TiddlyWiki\"/> from functioning correctly. Use [[safe mode|https://tiddlywiki.com/#SafeMode]] to restore normal operation."
},
"$:/language/ControlPanel/Parsing/Block/Caption": {
"title": "$:/language/ControlPanel/Parsing/Block/Caption",
"text": "Block Parse Rules"
},
"$:/language/ControlPanel/Parsing/Inline/Caption": {
"title": "$:/language/ControlPanel/Parsing/Inline/Caption",
"text": "Inline Parse Rules"
},
"$:/language/ControlPanel/Parsing/Pragma/Caption": {
"title": "$:/language/ControlPanel/Parsing/Pragma/Caption",
"text": "Pragma Parse Rules"
},
"$:/language/ControlPanel/Plugins/Add/Caption": {
"title": "$:/language/ControlPanel/Plugins/Add/Caption",
"text": "Get more plugins"
},
"$:/language/ControlPanel/Plugins/Add/Hint": {
"title": "$:/language/ControlPanel/Plugins/Add/Hint",
"text": "Install plugins from the official library"
},
"$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint": {
"title": "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint",
"text": "This plugin is already installed at version <$text text=<<installedVersion>>/>"
},
"$:/language/ControlPanel/Plugins/AlsoRequires": {
"title": "$:/language/ControlPanel/Plugins/AlsoRequires",
"text": "Also requires:"
},
"$:/language/ControlPanel/Plugins/Caption": {
"title": "$:/language/ControlPanel/Plugins/Caption",
"text": "Plugins"
},
"$:/language/ControlPanel/Plugins/Disable/Caption": {
"title": "$:/language/ControlPanel/Plugins/Disable/Caption",
"text": "disable"
},
"$:/language/ControlPanel/Plugins/Disable/Hint": {
"title": "$:/language/ControlPanel/Plugins/Disable/Hint",
"text": "Disable this plugin when reloading page"
},
"$:/language/ControlPanel/Plugins/Disabled/Status": {
"title": "$:/language/ControlPanel/Plugins/Disabled/Status",
"text": "(disabled)"
},
"$:/language/ControlPanel/Plugins/Downgrade/Caption": {
"title": "$:/language/ControlPanel/Plugins/Downgrade/Caption",
"text": "downgrade"
},
"$:/language/ControlPanel/Plugins/Empty/Hint": {
"title": "$:/language/ControlPanel/Plugins/Empty/Hint",
"text": "None"
},
"$:/language/ControlPanel/Plugins/Enable/Caption": {
"title": "$:/language/ControlPanel/Plugins/Enable/Caption",
"text": "enable"
},
"$:/language/ControlPanel/Plugins/Enable/Hint": {
"title": "$:/language/ControlPanel/Plugins/Enable/Hint",
"text": "Enable this plugin when reloading page"
},
"$:/language/ControlPanel/Plugins/Install/Caption": {
"title": "$:/language/ControlPanel/Plugins/Install/Caption",
"text": "install"
},
"$:/language/ControlPanel/Plugins/Installed/Hint": {
"title": "$:/language/ControlPanel/Plugins/Installed/Hint",
"text": "Currently installed plugins:"
},
"$:/language/ControlPanel/Plugins/Languages/Caption": {
"title": "$:/language/ControlPanel/Plugins/Languages/Caption",
"text": "Languages"
},
"$:/language/ControlPanel/Plugins/Languages/Hint": {
"title": "$:/language/ControlPanel/Plugins/Languages/Hint",
"text": "Language pack plugins"
},
"$:/language/ControlPanel/Plugins/NoInfoFound/Hint": {
"title": "$:/language/ControlPanel/Plugins/NoInfoFound/Hint",
"text": "No ''\"<$text text=<<currentTab>>/>\"'' found"
},
"$:/language/ControlPanel/Plugins/NotInstalled/Hint": {
"title": "$:/language/ControlPanel/Plugins/NotInstalled/Hint",
"text": "This plugin is not currently installed"
},
"$:/language/ControlPanel/Plugins/OpenPluginLibrary": {
"title": "$:/language/ControlPanel/Plugins/OpenPluginLibrary",
"text": "open plugin library"
},
"$:/language/ControlPanel/Plugins/ClosePluginLibrary": {
"title": "$:/language/ControlPanel/Plugins/ClosePluginLibrary",
"text": "close plugin library"
},
"$:/language/ControlPanel/Plugins/PluginWillRequireReload": {
"title": "$:/language/ControlPanel/Plugins/PluginWillRequireReload",
"text": "(requires reload)"
},
"$:/language/ControlPanel/Plugins/Plugins/Caption": {
"title": "$:/language/ControlPanel/Plugins/Plugins/Caption",
"text": "Plugins"
},
"$:/language/ControlPanel/Plugins/Plugins/Hint": {
"title": "$:/language/ControlPanel/Plugins/Plugins/Hint",
"text": "Plugins"
},
"$:/language/ControlPanel/Plugins/Reinstall/Caption": {
"title": "$:/language/ControlPanel/Plugins/Reinstall/Caption",
"text": "reinstall"
},
"$:/language/ControlPanel/Plugins/Themes/Caption": {
"title": "$:/language/ControlPanel/Plugins/Themes/Caption",
"text": "Themes"
},
"$:/language/ControlPanel/Plugins/Themes/Hint": {
"title": "$:/language/ControlPanel/Plugins/Themes/Hint",
"text": "Theme plugins"
},
"$:/language/ControlPanel/Plugins/Update/Caption": {
"title": "$:/language/ControlPanel/Plugins/Update/Caption",
"text": "update"
},
"$:/language/ControlPanel/Plugins/Updates/Caption": {
"title": "$:/language/ControlPanel/Plugins/Updates/Caption",
"text": "Updates"
},
"$:/language/ControlPanel/Plugins/Updates/Hint": {
"title": "$:/language/ControlPanel/Plugins/Updates/Hint",
"text": "Available updates to installed plugins"
},
"$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption": {
"title": "$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption",
"text": "Update <<update-count>> plugins"
},
"$:/language/ControlPanel/Plugins/SubPluginPrompt": {
"title": "$:/language/ControlPanel/Plugins/SubPluginPrompt",
"text": "With <<count>> sub-plugins available"
},
"$:/language/ControlPanel/Saving/Caption": {
"title": "$:/language/ControlPanel/Saving/Caption",
"text": "Saving"
},
"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description",
"text": "Permit automatic saving for the download saver"
},
"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint",
"text": "Enable Autosave for Download Saver"
},
"$:/language/ControlPanel/Saving/DownloadSaver/Caption": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/Caption",
"text": "Download Saver"
},
"$:/language/ControlPanel/Saving/DownloadSaver/Hint": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/Hint",
"text": "These settings apply to the HTML5-compatible download saver"
},
"$:/language/ControlPanel/Saving/General/Caption": {
"title": "$:/language/ControlPanel/Saving/General/Caption",
"text": "General"
},
"$:/language/ControlPanel/Saving/General/Hint": {
"title": "$:/language/ControlPanel/Saving/General/Hint",
"text": "These settings apply to all the loaded savers"
},
"$:/language/ControlPanel/Saving/Hint": {
"title": "$:/language/ControlPanel/Saving/Hint",
"text": "Settings used for saving the entire TiddlyWiki as a single file via a saver module"
},
"$:/language/ControlPanel/Saving/GitService/Branch": {
"title": "$:/language/ControlPanel/Saving/GitService/Branch",
"text": "Target branch for saving"
},
"$:/language/ControlPanel/Saving/GitService/CommitMessage": {
"title": "$:/language/ControlPanel/Saving/GitService/CommitMessage",
"text": "Saved by TiddlyWiki"
},
"$:/language/ControlPanel/Saving/GitService/Description": {
"title": "$:/language/ControlPanel/Saving/GitService/Description",
"text": "These settings are only used when saving to <<service-name>>"
},
"$:/language/ControlPanel/Saving/GitService/Filename": {
"title": "$:/language/ControlPanel/Saving/GitService/Filename",
"text": "Filename of target file (e.g. `index.html`)"
},
"$:/language/ControlPanel/Saving/GitService/Path": {
"title": "$:/language/ControlPanel/Saving/GitService/Path",
"text": "Path to target file (e.g. `/wiki/`)"
},
"$:/language/ControlPanel/Saving/GitService/Repo": {
"title": "$:/language/ControlPanel/Saving/GitService/Repo",
"text": "Target repository (e.g. `Jermolene/TiddlyWiki5`)"
},
"$:/language/ControlPanel/Saving/GitService/ServerURL": {
"title": "$:/language/ControlPanel/Saving/GitService/ServerURL",
"text": "Server API URL"
},
"$:/language/ControlPanel/Saving/GitService/UserName": {
"title": "$:/language/ControlPanel/Saving/GitService/UserName",
"text": "Username"
},
"$:/language/ControlPanel/Saving/GitService/GitHub/Caption": {
"title": "$:/language/ControlPanel/Saving/GitService/GitHub/Caption",
"text": "~GitHub Saver"
},
"$:/language/ControlPanel/Saving/GitService/GitHub/Password": {
"title": "$:/language/ControlPanel/Saving/GitService/GitHub/Password",
"text": "Password, OAUTH token, or personal access token (see [[GitHub help page|https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line]] for details)"
},
"$:/language/ControlPanel/Saving/GitService/GitLab/Caption": {
"title": "$:/language/ControlPanel/Saving/GitService/GitLab/Caption",
"text": "~GitLab Saver"
},
"$:/language/ControlPanel/Saving/GitService/GitLab/Password": {
"title": "$:/language/ControlPanel/Saving/GitService/GitLab/Password",
"text": "Personal access token for API (see [[GitLab help page|https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html]] for details)"
},
"$:/language/ControlPanel/Saving/GitService/Gitea/Caption": {
"title": "$:/language/ControlPanel/Saving/GitService/Gitea/Caption",
"text": "Gitea Saver"
},
"$:/language/ControlPanel/Saving/GitService/Gitea/Password": {
"title": "$:/language/ControlPanel/Saving/GitService/Gitea/Password",
"text": "Personal access token for API (via Gitea’s web interface: `Settings | Applications | Generate New Token`)"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading",
"text": "Advanced Settings"
},
"$:/language/ControlPanel/Saving/TiddlySpot/BackupDir": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir",
"text": "Backup Directory"
},
"$:/language/ControlPanel/Saving/TiddlySpot/ControlPanel": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ControlPanel",
"text": "~TiddlySpot Control Panel"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Backups": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Backups",
"text": "Backups"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Caption": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Caption",
"text": "~TiddlySpot Saver"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Description": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Description",
"text": "These settings are only used when saving to http://tiddlyspot.com or a compatible remote server"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Filename": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Filename",
"text": "Upload Filename"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Heading": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Heading",
"text": "~TiddlySpot"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Hint": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Hint",
"text": "//The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.//"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Password": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Password",
"text": "Password"
},
"$:/language/ControlPanel/Saving/TiddlySpot/ReadOnly": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ReadOnly",
"text": "The ~TiddlySpot service is currently only available in read-only form. Please see http://tiddlyspot.com/ for the latest details. The ~TiddlySpot saver can still be used to save to compatible servers."
},
"$:/language/ControlPanel/Saving/TiddlySpot/ServerURL": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL",
"text": "Server URL"
},
"$:/language/ControlPanel/Saving/TiddlySpot/UploadDir": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir",
"text": "Upload Directory"
},
"$:/language/ControlPanel/Saving/TiddlySpot/UserName": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/UserName",
"text": "Wiki Name"
},
"$:/language/ControlPanel/Settings/AutoSave/Caption": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Caption",
"text": "Autosave"
},
"$:/language/ControlPanel/Settings/AutoSave/Disabled/Description": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description",
"text": "Do not save changes automatically"
},
"$:/language/ControlPanel/Settings/AutoSave/Enabled/Description": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description",
"text": "Save changes automatically"
},
"$:/language/ControlPanel/Settings/AutoSave/Hint": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Hint",
"text": "Attempt to automatically save changes during editing when using a supporting saver"
},
"$:/language/ControlPanel/Settings/CamelCase/Caption": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Caption",
"text": "Camel Case Wiki Links"
},
"$:/language/ControlPanel/Settings/CamelCase/Hint": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Hint",
"text": "You can globally disable automatic linking of ~CamelCase phrases. Requires reload to take effect"
},
"$:/language/ControlPanel/Settings/CamelCase/Description": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Description",
"text": "Enable automatic ~CamelCase linking"
},
"$:/language/ControlPanel/Settings/Caption": {
"title": "$:/language/ControlPanel/Settings/Caption",
"text": "Settings"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Caption": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Caption",
"text": "Editor Toolbar"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Hint": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Hint",
"text": "Enable or disable the editor toolbar:"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Description": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Description",
"text": "Show editor toolbar"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Caption": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Caption",
"text": "Tiddler Info Panel Mode"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Hint": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Hint",
"text": "Control when the tiddler info panel closes:"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description",
"text": "Tiddler info panel closes automatically"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description",
"text": "Tiddler info panel stays open until explicitly closed"
},
"$:/language/ControlPanel/Settings/Hint": {
"title": "$:/language/ControlPanel/Settings/Hint",
"text": "These settings let you customise the behaviour of TiddlyWiki."
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption",
"text": "Navigation Address Bar"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint",
"text": "Behaviour of the browser address bar when navigating to a tiddler:"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description",
"text": "Do not update the address bar"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description",
"text": "Include the target tiddler"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description",
"text": "Include the target tiddler and the current story sequence"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Caption",
"text": "Navigation History"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Hint",
"text": "Update browser history when navigating to a tiddler:"
},
"$:/language/ControlPanel/Settings/NavigationHistory/No/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/No/Description",
"text": "Do not update history"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description",
"text": "Update history"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption",
"text": "Permalink/permaview Mode"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint",
"text": "Choose how permalink/permaview is handled:"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description",
"text": "Copy permalink/permaview URL to clipboard"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description",
"text": "Update address bar with permalink/permaview URL"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption",
"text": "Performance Instrumentation"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint",
"text": "Displays performance statistics in the browser developer console. Requires reload to take effect"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description",
"text": "Enable performance instrumentation"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption",
"text": "Toolbar Button Style"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint",
"text": "Choose the style for toolbar buttons:"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless",
"text": "Borderless"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed",
"text": "Boxed"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded",
"text": "Rounded"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Caption": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Caption",
"text": "Toolbar Buttons"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Hint": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Hint",
"text": "Default toolbar button appearance:"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description",
"text": "Include icon"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description",
"text": "Include text"
},
"$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption": {
"title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption",
"text": "Default Sidebar Tab"
},
"$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint": {
"title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint",
"text": "Specify which sidebar tab is displayed by default"
},
"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption": {
"title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption",
"text": "Default More Sidebar Tab"
},
"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint": {
"title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint",
"text": "Specify which More sidebar tab is displayed by default"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/Caption": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption",
"text": "Tiddler Opening Behaviour"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint",
"text": "Navigation from //within// the story river"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint",
"text": "Navigation from //outside// the story river"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove",
"text": "Open above the current tiddler"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow",
"text": "Open below the current tiddler"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop",
"text": "Open at the top of the story river"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom",
"text": "Open at the bottom of the story river"
},
"$:/language/ControlPanel/Settings/TitleLinks/Caption": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Caption",
"text": "Tiddler Titles"
},
"$:/language/ControlPanel/Settings/TitleLinks/Hint": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Hint",
"text": "Optionally display tiddler titles as links"
},
"$:/language/ControlPanel/Settings/TitleLinks/No/Description": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/No/Description",
"text": "Do not display tiddler titles as links"
},
"$:/language/ControlPanel/Settings/TitleLinks/Yes/Description": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description",
"text": "Display tiddler titles as links"
},
"$:/language/ControlPanel/Settings/MissingLinks/Caption": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Caption",
"text": "Wiki Links"
},
"$:/language/ControlPanel/Settings/MissingLinks/Hint": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Hint",
"text": "Choose whether to link to tiddlers that do not exist yet"
},
"$:/language/ControlPanel/Settings/MissingLinks/Description": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Description",
"text": "Enable links to missing tiddlers"
},
"$:/language/ControlPanel/StoryView/Caption": {
"title": "$:/language/ControlPanel/StoryView/Caption",
"text": "Story View"
},
"$:/language/ControlPanel/StoryView/Prompt": {
"title": "$:/language/ControlPanel/StoryView/Prompt",
"text": "Current view:"
},
"$:/language/ControlPanel/Stylesheets/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Caption",
"text": "Stylesheets"
},
"$:/language/ControlPanel/Stylesheets/Expand/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Expand/Caption",
"text": "Expand All"
},
"$:/language/ControlPanel/Stylesheets/Hint": {
"title": "$:/language/ControlPanel/Stylesheets/Hint",
"text": "This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag \"$:/tags/Stylesheet\">>"
},
"$:/language/ControlPanel/Stylesheets/Restore/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Restore/Caption",
"text": "Restore"
},
"$:/language/ControlPanel/Theme/Caption": {
"title": "$:/language/ControlPanel/Theme/Caption",
"text": "Theme"
},
"$:/language/ControlPanel/Theme/Prompt": {
"title": "$:/language/ControlPanel/Theme/Prompt",
"text": "Current theme:"
},
"$:/language/ControlPanel/TiddlerFields/Caption": {
"title": "$:/language/ControlPanel/TiddlerFields/Caption",
"text": "Tiddler Fields"
},
"$:/language/ControlPanel/TiddlerFields/Hint": {
"title": "$:/language/ControlPanel/TiddlerFields/Hint",
"text": "This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers)."
},
"$:/language/ControlPanel/Toolbars/Caption": {
"title": "$:/language/ControlPanel/Toolbars/Caption",
"text": "Toolbars"
},
"$:/language/ControlPanel/Toolbars/EditToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/EditToolbar/Caption",
"text": "Edit Toolbar"
},
"$:/language/ControlPanel/Toolbars/EditToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/EditToolbar/Hint",
"text": "Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Toolbars/Hint": {
"title": "$:/language/ControlPanel/Toolbars/Hint",
"text": "Select which toolbar buttons are displayed"
},
"$:/language/ControlPanel/Toolbars/PageControls/Caption": {
"title": "$:/language/ControlPanel/Toolbars/PageControls/Caption",
"text": "Page Toolbar"
},
"$:/language/ControlPanel/Toolbars/PageControls/Hint": {
"title": "$:/language/ControlPanel/Toolbars/PageControls/Hint",
"text": "Choose which buttons are displayed on the main page toolbar. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Toolbars/EditorToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption",
"text": "Editor Toolbar"
},
"$:/language/ControlPanel/Toolbars/EditorToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint",
"text": "Choose which buttons are displayed in the editor toolbar. Note that some buttons will only appear when editing tiddlers of a certain type. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Toolbars/ViewToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption",
"text": "View Toolbar"
},
"$:/language/ControlPanel/Toolbars/ViewToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint",
"text": "Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Tools/Download/Full/Caption": {
"title": "$:/language/ControlPanel/Tools/Download/Full/Caption",
"text": "Download full wiki"
},
"$:/language/Date/DaySuffix/1": {
"title": "$:/language/Date/DaySuffix/1",
"text": "st"
},
"$:/language/Date/DaySuffix/2": {
"title": "$:/language/Date/DaySuffix/2",
"text": "nd"
},
"$:/language/Date/DaySuffix/3": {
"title": "$:/language/Date/DaySuffix/3",
"text": "rd"
},
"$:/language/Date/DaySuffix/4": {
"title": "$:/language/Date/DaySuffix/4",
"text": "th"
},
"$:/language/Date/DaySuffix/5": {
"title": "$:/language/Date/DaySuffix/5",
"text": "th"
},
"$:/language/Date/DaySuffix/6": {
"title": "$:/language/Date/DaySuffix/6",
"text": "th"
},
"$:/language/Date/DaySuffix/7": {
"title": "$:/language/Date/DaySuffix/7",
"text": "th"
},
"$:/language/Date/DaySuffix/8": {
"title": "$:/language/Date/DaySuffix/8",
"text": "th"
},
"$:/language/Date/DaySuffix/9": {
"title": "$:/language/Date/DaySuffix/9",
"text": "th"
},
"$:/language/Date/DaySuffix/10": {
"title": "$:/language/Date/DaySuffix/10",
"text": "th"
},
"$:/language/Date/DaySuffix/11": {
"title": "$:/language/Date/DaySuffix/11",
"text": "th"
},
"$:/language/Date/DaySuffix/12": {
"title": "$:/language/Date/DaySuffix/12",
"text": "th"
},
"$:/language/Date/DaySuffix/13": {
"title": "$:/language/Date/DaySuffix/13",
"text": "th"
},
"$:/language/Date/DaySuffix/14": {
"title": "$:/language/Date/DaySuffix/14",
"text": "th"
},
"$:/language/Date/DaySuffix/15": {
"title": "$:/language/Date/DaySuffix/15",
"text": "th"
},
"$:/language/Date/DaySuffix/16": {
"title": "$:/language/Date/DaySuffix/16",
"text": "th"
},
"$:/language/Date/DaySuffix/17": {
"title": "$:/language/Date/DaySuffix/17",
"text": "th"
},
"$:/language/Date/DaySuffix/18": {
"title": "$:/language/Date/DaySuffix/18",
"text": "th"
},
"$:/language/Date/DaySuffix/19": {
"title": "$:/language/Date/DaySuffix/19",
"text": "th"
},
"$:/language/Date/DaySuffix/20": {
"title": "$:/language/Date/DaySuffix/20",
"text": "th"
},
"$:/language/Date/DaySuffix/21": {
"title": "$:/language/Date/DaySuffix/21",
"text": "st"
},
"$:/language/Date/DaySuffix/22": {
"title": "$:/language/Date/DaySuffix/22",
"text": "nd"
},
"$:/language/Date/DaySuffix/23": {
"title": "$:/language/Date/DaySuffix/23",
"text": "rd"
},
"$:/language/Date/DaySuffix/24": {
"title": "$:/language/Date/DaySuffix/24",
"text": "th"
},
"$:/language/Date/DaySuffix/25": {
"title": "$:/language/Date/DaySuffix/25",
"text": "th"
},
"$:/language/Date/DaySuffix/26": {
"title": "$:/language/Date/DaySuffix/26",
"text": "th"
},
"$:/language/Date/DaySuffix/27": {
"title": "$:/language/Date/DaySuffix/27",
"text": "th"
},
"$:/language/Date/DaySuffix/28": {
"title": "$:/language/Date/DaySuffix/28",
"text": "th"
},
"$:/language/Date/DaySuffix/29": {
"title": "$:/language/Date/DaySuffix/29",
"text": "th"
},
"$:/language/Date/DaySuffix/30": {
"title": "$:/language/Date/DaySuffix/30",
"text": "th"
},
"$:/language/Date/DaySuffix/31": {
"title": "$:/language/Date/DaySuffix/31",
"text": "st"
},
"$:/language/Date/Long/Day/0": {
"title": "$:/language/Date/Long/Day/0",
"text": "Sunday"
},
"$:/language/Date/Long/Day/1": {
"title": "$:/language/Date/Long/Day/1",
"text": "Monday"
},
"$:/language/Date/Long/Day/2": {
"title": "$:/language/Date/Long/Day/2",
"text": "Tuesday"
},
"$:/language/Date/Long/Day/3": {
"title": "$:/language/Date/Long/Day/3",
"text": "Wednesday"
},
"$:/language/Date/Long/Day/4": {
"title": "$:/language/Date/Long/Day/4",
"text": "Thursday"
},
"$:/language/Date/Long/Day/5": {
"title": "$:/language/Date/Long/Day/5",
"text": "Friday"
},
"$:/language/Date/Long/Day/6": {
"title": "$:/language/Date/Long/Day/6",
"text": "Saturday"
},
"$:/language/Date/Long/Month/1": {
"title": "$:/language/Date/Long/Month/1",
"text": "January"
},
"$:/language/Date/Long/Month/2": {
"title": "$:/language/Date/Long/Month/2",
"text": "February"
},
"$:/language/Date/Long/Month/3": {
"title": "$:/language/Date/Long/Month/3",
"text": "March"
},
"$:/language/Date/Long/Month/4": {
"title": "$:/language/Date/Long/Month/4",
"text": "April"
},
"$:/language/Date/Long/Month/5": {
"title": "$:/language/Date/Long/Month/5",
"text": "May"
},
"$:/language/Date/Long/Month/6": {
"title": "$:/language/Date/Long/Month/6",
"text": "June"
},
"$:/language/Date/Long/Month/7": {
"title": "$:/language/Date/Long/Month/7",
"text": "July"
},
"$:/language/Date/Long/Month/8": {
"title": "$:/language/Date/Long/Month/8",
"text": "August"
},
"$:/language/Date/Long/Month/9": {
"title": "$:/language/Date/Long/Month/9",
"text": "September"
},
"$:/language/Date/Long/Month/10": {
"title": "$:/language/Date/Long/Month/10",
"text": "October"
},
"$:/language/Date/Long/Month/11": {
"title": "$:/language/Date/Long/Month/11",
"text": "November"
},
"$:/language/Date/Long/Month/12": {
"title": "$:/language/Date/Long/Month/12",
"text": "December"
},
"$:/language/Date/Period/am": {
"title": "$:/language/Date/Period/am",
"text": "am"
},
"$:/language/Date/Period/pm": {
"title": "$:/language/Date/Period/pm",
"text": "pm"
},
"$:/language/Date/Short/Day/0": {
"title": "$:/language/Date/Short/Day/0",
"text": "Sun"
},
"$:/language/Date/Short/Day/1": {
"title": "$:/language/Date/Short/Day/1",
"text": "Mon"
},
"$:/language/Date/Short/Day/2": {
"title": "$:/language/Date/Short/Day/2",
"text": "Tue"
},
"$:/language/Date/Short/Day/3": {
"title": "$:/language/Date/Short/Day/3",
"text": "Wed"
},
"$:/language/Date/Short/Day/4": {
"title": "$:/language/Date/Short/Day/4",
"text": "Thu"
},
"$:/language/Date/Short/Day/5": {
"title": "$:/language/Date/Short/Day/5",
"text": "Fri"
},
"$:/language/Date/Short/Day/6": {
"title": "$:/language/Date/Short/Day/6",
"text": "Sat"
},
"$:/language/Date/Short/Month/1": {
"title": "$:/language/Date/Short/Month/1",
"text": "Jan"
},
"$:/language/Date/Short/Month/2": {
"title": "$:/language/Date/Short/Month/2",
"text": "Feb"
},
"$:/language/Date/Short/Month/3": {
"title": "$:/language/Date/Short/Month/3",
"text": "Mar"
},
"$:/language/Date/Short/Month/4": {
"title": "$:/language/Date/Short/Month/4",
"text": "Apr"
},
"$:/language/Date/Short/Month/5": {
"title": "$:/language/Date/Short/Month/5",
"text": "May"
},
"$:/language/Date/Short/Month/6": {
"title": "$:/language/Date/Short/Month/6",
"text": "Jun"
},
"$:/language/Date/Short/Month/7": {
"title": "$:/language/Date/Short/Month/7",
"text": "Jul"
},
"$:/language/Date/Short/Month/8": {
"title": "$:/language/Date/Short/Month/8",
"text": "Aug"
},
"$:/language/Date/Short/Month/9": {
"title": "$:/language/Date/Short/Month/9",
"text": "Sep"
},
"$:/language/Date/Short/Month/10": {
"title": "$:/language/Date/Short/Month/10",
"text": "Oct"
},
"$:/language/Date/Short/Month/11": {
"title": "$:/language/Date/Short/Month/11",
"text": "Nov"
},
"$:/language/Date/Short/Month/12": {
"title": "$:/language/Date/Short/Month/12",
"text": "Dec"
},
"$:/language/RelativeDate/Future/Days": {
"title": "$:/language/RelativeDate/Future/Days",
"text": "<<period>> days from now"
},
"$:/language/RelativeDate/Future/Hours": {
"title": "$:/language/RelativeDate/Future/Hours",
"text": "<<period>> hours from now"
},
"$:/language/RelativeDate/Future/Minutes": {
"title": "$:/language/RelativeDate/Future/Minutes",
"text": "<<period>> minutes from now"
},
"$:/language/RelativeDate/Future/Months": {
"title": "$:/language/RelativeDate/Future/Months",
"text": "<<period>> months from now"
},
"$:/language/RelativeDate/Future/Second": {
"title": "$:/language/RelativeDate/Future/Second",
"text": "1 second from now"
},
"$:/language/RelativeDate/Future/Seconds": {
"title": "$:/language/RelativeDate/Future/Seconds",
"text": "<<period>> seconds from now"
},
"$:/language/RelativeDate/Future/Years": {
"title": "$:/language/RelativeDate/Future/Years",
"text": "<<period>> years from now"
},
"$:/language/RelativeDate/Past/Days": {
"title": "$:/language/RelativeDate/Past/Days",
"text": "<<period>> days ago"
},
"$:/language/RelativeDate/Past/Hours": {
"title": "$:/language/RelativeDate/Past/Hours",
"text": "<<period>> hours ago"
},
"$:/language/RelativeDate/Past/Minutes": {
"title": "$:/language/RelativeDate/Past/Minutes",
"text": "<<period>> minutes ago"
},
"$:/language/RelativeDate/Past/Months": {
"title": "$:/language/RelativeDate/Past/Months",
"text": "<<period>> months ago"
},
"$:/language/RelativeDate/Past/Second": {
"title": "$:/language/RelativeDate/Past/Second",
"text": "1 second ago"
},
"$:/language/RelativeDate/Past/Seconds": {
"title": "$:/language/RelativeDate/Past/Seconds",
"text": "<<period>> seconds ago"
},
"$:/language/RelativeDate/Past/Years": {
"title": "$:/language/RelativeDate/Past/Years",
"text": "<<period>> years ago"
},
"$:/language/Docs/ModuleTypes/allfilteroperator": {
"title": "$:/language/Docs/ModuleTypes/allfilteroperator",
"text": "A sub-operator for the ''all'' filter operator."
},
"$:/language/Docs/ModuleTypes/animation": {
"title": "$:/language/Docs/ModuleTypes/animation",
"text": "Animations that may be used with the RevealWidget."
},
"$:/language/Docs/ModuleTypes/authenticator": {
"title": "$:/language/Docs/ModuleTypes/authenticator",
"text": "Defines how requests are authenticated by the built-in HTTP server."
},
"$:/language/Docs/ModuleTypes/bitmapeditoroperation": {
"title": "$:/language/Docs/ModuleTypes/bitmapeditoroperation",
"text": "A bitmap editor toolbar operation."
},
"$:/language/Docs/ModuleTypes/command": {
"title": "$:/language/Docs/ModuleTypes/command",
"text": "Commands that can be executed under Node.js."
},
"$:/language/Docs/ModuleTypes/config": {
"title": "$:/language/Docs/ModuleTypes/config",
"text": "Data to be inserted into `$tw.config`."
},
"$:/language/Docs/ModuleTypes/filteroperator": {
"title": "$:/language/Docs/ModuleTypes/filteroperator",
"text": "Individual filter operator methods."
},
"$:/language/Docs/ModuleTypes/global": {
"title": "$:/language/Docs/ModuleTypes/global",
"text": "Global data to be inserted into `$tw`."
},
"$:/language/Docs/ModuleTypes/info": {
"title": "$:/language/Docs/ModuleTypes/info",
"text": "Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin."
},
"$:/language/Docs/ModuleTypes/isfilteroperator": {
"title": "$:/language/Docs/ModuleTypes/isfilteroperator",
"text": "Operands for the ''is'' filter operator."
},
"$:/language/Docs/ModuleTypes/library": {
"title": "$:/language/Docs/ModuleTypes/library",
"text": "Generic module type for general purpose JavaScript modules."
},
"$:/language/Docs/ModuleTypes/macro": {
"title": "$:/language/Docs/ModuleTypes/macro",
"text": "JavaScript macro definitions."
},
"$:/language/Docs/ModuleTypes/parser": {
"title": "$:/language/Docs/ModuleTypes/parser",
"text": "Parsers for different content types."
},
"$:/language/Docs/ModuleTypes/route": {
"title": "$:/language/Docs/ModuleTypes/route",
"text": "Defines how individual URL patterns are handled by the built-in HTTP server."
},
"$:/language/Docs/ModuleTypes/saver": {
"title": "$:/language/Docs/ModuleTypes/saver",
"text": "Savers handle different methods for saving files from the browser."
},
"$:/language/Docs/ModuleTypes/startup": {
"title": "$:/language/Docs/ModuleTypes/startup",
"text": "Startup functions."
},
"$:/language/Docs/ModuleTypes/storyview": {
"title": "$:/language/Docs/ModuleTypes/storyview",
"text": "Story views customise the animation and behaviour of list widgets."
},
"$:/language/Docs/ModuleTypes/texteditoroperation": {
"title": "$:/language/Docs/ModuleTypes/texteditoroperation",
"text": "A text editor toolbar operation."
},
"$:/language/Docs/ModuleTypes/tiddlerdeserializer": {
"title": "$:/language/Docs/ModuleTypes/tiddlerdeserializer",
"text": "Converts different content types into tiddlers."
},
"$:/language/Docs/ModuleTypes/tiddlerfield": {
"title": "$:/language/Docs/ModuleTypes/tiddlerfield",
"text": "Defines the behaviour of an individual tiddler field."
},
"$:/language/Docs/ModuleTypes/tiddlermethod": {
"title": "$:/language/Docs/ModuleTypes/tiddlermethod",
"text": "Adds methods to the `$tw.Tiddler` prototype."
},
"$:/language/Docs/ModuleTypes/upgrader": {
"title": "$:/language/Docs/ModuleTypes/upgrader",
"text": "Applies upgrade processing to tiddlers during an upgrade/import."
},
"$:/language/Docs/ModuleTypes/utils": {
"title": "$:/language/Docs/ModuleTypes/utils",
"text": "Adds methods to `$tw.utils`."
},
"$:/language/Docs/ModuleTypes/utils-node": {
"title": "$:/language/Docs/ModuleTypes/utils-node",
"text": "Adds Node.js-specific methods to `$tw.utils`."
},
"$:/language/Docs/ModuleTypes/widget": {
"title": "$:/language/Docs/ModuleTypes/widget",
"text": "Widgets encapsulate DOM rendering and refreshing."
},
"$:/language/Docs/ModuleTypes/wikimethod": {
"title": "$:/language/Docs/ModuleTypes/wikimethod",
"text": "Adds methods to `$tw.Wiki`."
},
"$:/language/Docs/ModuleTypes/wikirule": {
"title": "$:/language/Docs/ModuleTypes/wikirule",
"text": "Individual parser rules for the main WikiText parser."
},
"$:/language/Docs/PaletteColours/alert-background": {
"title": "$:/language/Docs/PaletteColours/alert-background",
"text": "Alert background"
},
"$:/language/Docs/PaletteColours/alert-border": {
"title": "$:/language/Docs/PaletteColours/alert-border",
"text": "Alert border"
},
"$:/language/Docs/PaletteColours/alert-highlight": {
"title": "$:/language/Docs/PaletteColours/alert-highlight",
"text": "Alert highlight"
},
"$:/language/Docs/PaletteColours/alert-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/alert-muted-foreground",
"text": "Alert muted foreground"
},
"$:/language/Docs/PaletteColours/background": {
"title": "$:/language/Docs/PaletteColours/background",
"text": "General background"
},
"$:/language/Docs/PaletteColours/blockquote-bar": {
"title": "$:/language/Docs/PaletteColours/blockquote-bar",
"text": "Blockquote bar"
},
"$:/language/Docs/PaletteColours/button-background": {
"title": "$:/language/Docs/PaletteColours/button-background",
"text": "Default button background"
},
"$:/language/Docs/PaletteColours/button-border": {
"title": "$:/language/Docs/PaletteColours/button-border",
"text": "Default button border"
},
"$:/language/Docs/PaletteColours/button-foreground": {
"title": "$:/language/Docs/PaletteColours/button-foreground",
"text": "Default button foreground"
},
"$:/language/Docs/PaletteColours/dirty-indicator": {
"title": "$:/language/Docs/PaletteColours/dirty-indicator",
"text": "Unsaved changes indicator"
},
"$:/language/Docs/PaletteColours/code-background": {
"title": "$:/language/Docs/PaletteColours/code-background",
"text": "Code background"
},
"$:/language/Docs/PaletteColours/code-border": {
"title": "$:/language/Docs/PaletteColours/code-border",
"text": "Code border"
},
"$:/language/Docs/PaletteColours/code-foreground": {
"title": "$:/language/Docs/PaletteColours/code-foreground",
"text": "Code foreground"
},
"$:/language/Docs/PaletteColours/download-background": {
"title": "$:/language/Docs/PaletteColours/download-background",
"text": "Download button background"
},
"$:/language/Docs/PaletteColours/download-foreground": {
"title": "$:/language/Docs/PaletteColours/download-foreground",
"text": "Download button foreground"
},
"$:/language/Docs/PaletteColours/dragger-background": {
"title": "$:/language/Docs/PaletteColours/dragger-background",
"text": "Dragger background"
},
"$:/language/Docs/PaletteColours/dragger-foreground": {
"title": "$:/language/Docs/PaletteColours/dragger-foreground",
"text": "Dragger foreground"
},
"$:/language/Docs/PaletteColours/dropdown-background": {
"title": "$:/language/Docs/PaletteColours/dropdown-background",
"text": "Dropdown background"
},
"$:/language/Docs/PaletteColours/dropdown-border": {
"title": "$:/language/Docs/PaletteColours/dropdown-border",
"text": "Dropdown border"
},
"$:/language/Docs/PaletteColours/dropdown-tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/dropdown-tab-background-selected",
"text": "Dropdown tab background for selected tabs"
},
"$:/language/Docs/PaletteColours/dropdown-tab-background": {
"title": "$:/language/Docs/PaletteColours/dropdown-tab-background",
"text": "Dropdown tab background"
},
"$:/language/Docs/PaletteColours/dropzone-background": {
"title": "$:/language/Docs/PaletteColours/dropzone-background",
"text": "Dropzone background"
},
"$:/language/Docs/PaletteColours/external-link-background-hover": {
"title": "$:/language/Docs/PaletteColours/external-link-background-hover",
"text": "External link background hover"
},
"$:/language/Docs/PaletteColours/external-link-background-visited": {
"title": "$:/language/Docs/PaletteColours/external-link-background-visited",
"text": "External link background visited"
},
"$:/language/Docs/PaletteColours/external-link-background": {
"title": "$:/language/Docs/PaletteColours/external-link-background",
"text": "External link background"
},
"$:/language/Docs/PaletteColours/external-link-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground-hover",
"text": "External link foreground hover"
},
"$:/language/Docs/PaletteColours/external-link-foreground-visited": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground-visited",
"text": "External link foreground visited"
},
"$:/language/Docs/PaletteColours/external-link-foreground": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground",
"text": "External link foreground"
},
"$:/language/Docs/PaletteColours/foreground": {
"title": "$:/language/Docs/PaletteColours/foreground",
"text": "General foreground"
},
"$:/language/Docs/PaletteColours/menubar-background": {
"title": "$:/language/Docs/PaletteColours/menubar-background",
"text": "Menu bar background"
},
"$:/language/Docs/PaletteColours/menubar-foreground": {
"title": "$:/language/Docs/PaletteColours/menubar-foreground",
"text": "Menu bar foreground"
},
"$:/language/Docs/PaletteColours/message-background": {
"title": "$:/language/Docs/PaletteColours/message-background",
"text": "Message box background"
},
"$:/language/Docs/PaletteColours/message-border": {
"title": "$:/language/Docs/PaletteColours/message-border",
"text": "Message box border"
},
"$:/language/Docs/PaletteColours/message-foreground": {
"title": "$:/language/Docs/PaletteColours/message-foreground",
"text": "Message box foreground"
},
"$:/language/Docs/PaletteColours/modal-backdrop": {
"title": "$:/language/Docs/PaletteColours/modal-backdrop",
"text": "Modal backdrop"
},
"$:/language/Docs/PaletteColours/modal-background": {
"title": "$:/language/Docs/PaletteColours/modal-background",
"text": "Modal background"
},
"$:/language/Docs/PaletteColours/modal-border": {
"title": "$:/language/Docs/PaletteColours/modal-border",
"text": "Modal border"
},
"$:/language/Docs/PaletteColours/modal-footer-background": {
"title": "$:/language/Docs/PaletteColours/modal-footer-background",
"text": "Modal footer background"
},
"$:/language/Docs/PaletteColours/modal-footer-border": {
"title": "$:/language/Docs/PaletteColours/modal-footer-border",
"text": "Modal footer border"
},
"$:/language/Docs/PaletteColours/modal-header-border": {
"title": "$:/language/Docs/PaletteColours/modal-header-border",
"text": "Modal header border"
},
"$:/language/Docs/PaletteColours/muted-foreground": {
"title": "$:/language/Docs/PaletteColours/muted-foreground",
"text": "General muted foreground"
},
"$:/language/Docs/PaletteColours/notification-background": {
"title": "$:/language/Docs/PaletteColours/notification-background",
"text": "Notification background"
},
"$:/language/Docs/PaletteColours/notification-border": {
"title": "$:/language/Docs/PaletteColours/notification-border",
"text": "Notification border"
},
"$:/language/Docs/PaletteColours/page-background": {
"title": "$:/language/Docs/PaletteColours/page-background",
"text": "Page background"
},
"$:/language/Docs/PaletteColours/pre-background": {
"title": "$:/language/Docs/PaletteColours/pre-background",
"text": "Preformatted code background"
},
"$:/language/Docs/PaletteColours/pre-border": {
"title": "$:/language/Docs/PaletteColours/pre-border",
"text": "Preformatted code border"
},
"$:/language/Docs/PaletteColours/primary": {
"title": "$:/language/Docs/PaletteColours/primary",
"text": "General primary"
},
"$:/language/Docs/PaletteColours/select-tag-background": {
"title": "$:/language/Docs/PaletteColours/select-tag-background",
"text": "`<select>` element background"
},
"$:/language/Docs/PaletteColours/select-tag-foreground": {
"title": "$:/language/Docs/PaletteColours/select-tag-foreground",
"text": "`<select>` element text"
},
"$:/language/Docs/PaletteColours/sidebar-button-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-button-foreground",
"text": "Sidebar button foreground"
},
"$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover",
"text": "Sidebar controls foreground hover"
},
"$:/language/Docs/PaletteColours/sidebar-controls-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground",
"text": "Sidebar controls foreground"
},
"$:/language/Docs/PaletteColours/sidebar-foreground-shadow": {
"title": "$:/language/Docs/PaletteColours/sidebar-foreground-shadow",
"text": "Sidebar foreground shadow"
},
"$:/language/Docs/PaletteColours/sidebar-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-foreground",
"text": "Sidebar foreground"
},
"$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover",
"text": "Sidebar muted foreground hover"
},
"$:/language/Docs/PaletteColours/sidebar-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground",
"text": "Sidebar muted foreground"
},
"$:/language/Docs/PaletteColours/sidebar-tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-background-selected",
"text": "Sidebar tab background for selected tabs"
},
"$:/language/Docs/PaletteColours/sidebar-tab-background": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-background",
"text": "Sidebar tab background"
},
"$:/language/Docs/PaletteColours/sidebar-tab-border-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-border-selected",
"text": "Sidebar tab border for selected tabs"
},
"$:/language/Docs/PaletteColours/sidebar-tab-border": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-border",
"text": "Sidebar tab border"
},
"$:/language/Docs/PaletteColours/sidebar-tab-divider": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-divider",
"text": "Sidebar tab divider"
},
"$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected",
"text": "Sidebar tab foreground for selected tabs"
},
"$:/language/Docs/PaletteColours/sidebar-tab-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground",
"text": "Sidebar tab foreground"
},
"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover",
"text": "Sidebar tiddler link foreground hover"
},
"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground",
"text": "Sidebar tiddler link foreground"
},
"$:/language/Docs/PaletteColours/site-title-foreground": {
"title": "$:/language/Docs/PaletteColours/site-title-foreground",
"text": "Site title foreground"
},
"$:/language/Docs/PaletteColours/static-alert-foreground": {
"title": "$:/language/Docs/PaletteColours/static-alert-foreground",
"text": "Static alert foreground"
},
"$:/language/Docs/PaletteColours/tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/tab-background-selected",
"text": "Tab background for selected tabs"
},
"$:/language/Docs/PaletteColours/tab-background": {
"title": "$:/language/Docs/PaletteColours/tab-background",
"text": "Tab background"
},
"$:/language/Docs/PaletteColours/tab-border-selected": {
"title": "$:/language/Docs/PaletteColours/tab-border-selected",
"text": "Tab border for selected tabs"
},
"$:/language/Docs/PaletteColours/tab-border": {
"title": "$:/language/Docs/PaletteColours/tab-border",
"text": "Tab border"
},
"$:/language/Docs/PaletteColours/tab-divider": {
"title": "$:/language/Docs/PaletteColours/tab-divider",
"text": "Tab divider"
},
"$:/language/Docs/PaletteColours/tab-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/tab-foreground-selected",
"text": "Tab foreground for selected tabs"
},
"$:/language/Docs/PaletteColours/tab-foreground": {
"title": "$:/language/Docs/PaletteColours/tab-foreground",
"text": "Tab foreground"
},
"$:/language/Docs/PaletteColours/table-border": {
"title": "$:/language/Docs/PaletteColours/table-border",
"text": "Table border"
},
"$:/language/Docs/PaletteColours/table-footer-background": {
"title": "$:/language/Docs/PaletteColours/table-footer-background",
"text": "Table footer background"
},
"$:/language/Docs/PaletteColours/table-header-background": {
"title": "$:/language/Docs/PaletteColours/table-header-background",
"text": "Table header background"
},
"$:/language/Docs/PaletteColours/tag-background": {
"title": "$:/language/Docs/PaletteColours/tag-background",
"text": "Tag background"
},
"$:/language/Docs/PaletteColours/tag-foreground": {
"title": "$:/language/Docs/PaletteColours/tag-foreground",
"text": "Tag foreground"
},
"$:/language/Docs/PaletteColours/tiddler-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-background",
"text": "Tiddler background"
},
"$:/language/Docs/PaletteColours/tiddler-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-border",
"text": "Tiddler border"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover",
"text": "Tiddler controls foreground hover"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected",
"text": "Tiddler controls foreground for selected controls"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground",
"text": "Tiddler controls foreground"
},
"$:/language/Docs/PaletteColours/tiddler-editor-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-background",
"text": "Tiddler editor background"
},
"$:/language/Docs/PaletteColours/tiddler-editor-border-image": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-border-image",
"text": "Tiddler editor border image"
},
"$:/language/Docs/PaletteColours/tiddler-editor-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-border",
"text": "Tiddler editor border"
},
"$:/language/Docs/PaletteColours/tiddler-editor-fields-even": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-even",
"text": "Tiddler editor background for even fields"
},
"$:/language/Docs/PaletteColours/tiddler-editor-fields-odd": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd",
"text": "Tiddler editor background for odd fields"
},
"$:/language/Docs/PaletteColours/tiddler-info-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-background",
"text": "Tiddler info panel background"
},
"$:/language/Docs/PaletteColours/tiddler-info-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-border",
"text": "Tiddler info panel border"
},
"$:/language/Docs/PaletteColours/tiddler-info-tab-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-tab-background",
"text": "Tiddler info panel tab background"
},
"$:/language/Docs/PaletteColours/tiddler-link-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-link-background",
"text": "Tiddler link background"
},
"$:/language/Docs/PaletteColours/tiddler-link-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-link-foreground",
"text": "Tiddler link foreground"
},
"$:/language/Docs/PaletteColours/tiddler-subtitle-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground",
"text": "Tiddler subtitle foreground"
},
"$:/language/Docs/PaletteColours/tiddler-title-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-title-foreground",
"text": "Tiddler title foreground"
},
"$:/language/Docs/PaletteColours/toolbar-new-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-new-button",
"text": "Toolbar 'new tiddler' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-options-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-options-button",
"text": "Toolbar 'options' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-save-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-save-button",
"text": "Toolbar 'save' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-info-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-info-button",
"text": "Toolbar 'info' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-edit-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-edit-button",
"text": "Toolbar 'edit' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-close-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-close-button",
"text": "Toolbar 'close' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-delete-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-delete-button",
"text": "Toolbar 'delete' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-cancel-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-cancel-button",
"text": "Toolbar 'cancel' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-done-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-done-button",
"text": "Toolbar 'done' button foreground"
},
"$:/language/Docs/PaletteColours/untagged-background": {
"title": "$:/language/Docs/PaletteColours/untagged-background",
"text": "Untagged pill background"
},
"$:/language/Docs/PaletteColours/very-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/very-muted-foreground",
"text": "Very muted foreground"
},
"$:/language/EditTemplate/Body/External/Hint": {
"title": "$:/language/EditTemplate/Body/External/Hint",
"text": "This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself"
},
"$:/language/EditTemplate/Body/Placeholder": {
"title": "$:/language/EditTemplate/Body/Placeholder",
"text": "Type the text for this tiddler"
},
"$:/language/EditTemplate/Body/Preview/Type/Output": {
"title": "$:/language/EditTemplate/Body/Preview/Type/Output",
"text": "output"
},
"$:/language/EditTemplate/Field/Remove/Caption": {
"title": "$:/language/EditTemplate/Field/Remove/Caption",
"text": "remove field"
},
"$:/language/EditTemplate/Field/Remove/Hint": {
"title": "$:/language/EditTemplate/Field/Remove/Hint",
"text": "Remove field"
},
"$:/language/EditTemplate/Field/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Field/Dropdown/Caption",
"text": "field list"
},
"$:/language/EditTemplate/Field/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Field/Dropdown/Hint",
"text": "Show field list"
},
"$:/language/EditTemplate/Fields/Add/Button": {
"title": "$:/language/EditTemplate/Fields/Add/Button",
"text": "add"
},
"$:/language/EditTemplate/Fields/Add/Button/Hint": {
"title": "$:/language/EditTemplate/Fields/Add/Button/Hint",
"text": "Add the new field to the tiddler"
},
"$:/language/EditTemplate/Fields/Add/Name/Placeholder": {
"title": "$:/language/EditTemplate/Fields/Add/Name/Placeholder",
"text": "field name"
},
"$:/language/EditTemplate/Fields/Add/Prompt": {
"title": "$:/language/EditTemplate/Fields/Add/Prompt",
"text": "Add a new field:"
},
"$:/language/EditTemplate/Fields/Add/Value/Placeholder": {
"title": "$:/language/EditTemplate/Fields/Add/Value/Placeholder",
"text": "field value"
},
"$:/language/EditTemplate/Fields/Add/Dropdown/System": {
"title": "$:/language/EditTemplate/Fields/Add/Dropdown/System",
"text": "System fields"
},
"$:/language/EditTemplate/Fields/Add/Dropdown/User": {
"title": "$:/language/EditTemplate/Fields/Add/Dropdown/User",
"text": "User fields"
},
"$:/language/EditTemplate/Shadow/Warning": {
"title": "$:/language/EditTemplate/Shadow/Warning",
"text": "This is a shadow tiddler. Any changes you make will override the default version from the plugin <<pluginLink>>"
},
"$:/language/EditTemplate/Shadow/OverriddenWarning": {
"title": "$:/language/EditTemplate/Shadow/OverriddenWarning",
"text": "This is a modified shadow tiddler. You can revert to the default version in the plugin <<pluginLink>> by deleting this tiddler"
},
"$:/language/EditTemplate/Tags/Add/Button": {
"title": "$:/language/EditTemplate/Tags/Add/Button",
"text": "add"
},
"$:/language/EditTemplate/Tags/Add/Button/Hint": {
"title": "$:/language/EditTemplate/Tags/Add/Button/Hint",
"text": "add tag"
},
"$:/language/EditTemplate/Tags/Add/Placeholder": {
"title": "$:/language/EditTemplate/Tags/Add/Placeholder",
"text": "tag name"
},
"$:/language/EditTemplate/Tags/ClearInput/Caption": {
"title": "$:/language/EditTemplate/Tags/ClearInput/Caption",
"text": "clear input"
},
"$:/language/EditTemplate/Tags/ClearInput/Hint": {
"title": "$:/language/EditTemplate/Tags/ClearInput/Hint",
"text": "Clear tag input"
},
"$:/language/EditTemplate/Tags/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Tags/Dropdown/Caption",
"text": "tag list"
},
"$:/language/EditTemplate/Tags/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Tags/Dropdown/Hint",
"text": "Show tag list"
},
"$:/language/EditTemplate/Title/BadCharacterWarning": {
"title": "$:/language/EditTemplate/Title/BadCharacterWarning",
"text": "Warning: avoid using any of the characters <<bad-chars>> in tiddler titles"
},
"$:/language/EditTemplate/Title/Exists/Prompt": {
"title": "$:/language/EditTemplate/Title/Exists/Prompt",
"text": "Target tiddler already exists"
},
"$:/language/EditTemplate/Title/Relink/Prompt": {
"title": "$:/language/EditTemplate/Title/Relink/Prompt",
"text": "Update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' in the //tags// and //list// fields of other tiddlers"
},
"$:/language/EditTemplate/Title/References/Prompt": {
"title": "$:/language/EditTemplate/Title/References/Prompt",
"text": "The following references to this tiddler will not be automatically updated:"
},
"$:/language/EditTemplate/Type/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Type/Dropdown/Caption",
"text": "content type list"
},
"$:/language/EditTemplate/Type/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Type/Dropdown/Hint",
"text": "Show content type list"
},
"$:/language/EditTemplate/Type/Delete/Caption": {
"title": "$:/language/EditTemplate/Type/Delete/Caption",
"text": "delete content type"
},
"$:/language/EditTemplate/Type/Delete/Hint": {
"title": "$:/language/EditTemplate/Type/Delete/Hint",
"text": "Delete content type"
},
"$:/language/EditTemplate/Type/Placeholder": {
"title": "$:/language/EditTemplate/Type/Placeholder",
"text": "content type"
},
"$:/language/EditTemplate/Type/Prompt": {
"title": "$:/language/EditTemplate/Type/Prompt",
"text": "Type:"
},
"$:/language/Exporters/StaticRiver": {
"title": "$:/language/Exporters/StaticRiver",
"text": "Static HTML"
},
"$:/language/Exporters/JsonFile": {
"title": "$:/language/Exporters/JsonFile",
"text": "JSON file"
},
"$:/language/Exporters/CsvFile": {
"title": "$:/language/Exporters/CsvFile",
"text": "CSV file"
},
"$:/language/Exporters/TidFile": {
"title": "$:/language/Exporters/TidFile",
"text": "\".tid\" file"
},
"$:/language/Docs/Fields/_canonical_uri": {
"title": "$:/language/Docs/Fields/_canonical_uri",
"text": "The full URI of an external image tiddler"
},
"$:/language/Docs/Fields/bag": {
"title": "$:/language/Docs/Fields/bag",
"text": "The name of the bag from which a tiddler came"
},
"$:/language/Docs/Fields/caption": {
"title": "$:/language/Docs/Fields/caption",
"text": "The text to be displayed on a tab or button"
},
"$:/language/Docs/Fields/color": {
"title": "$:/language/Docs/Fields/color",
"text": "The CSS color value associated with a tiddler"
},
"$:/language/Docs/Fields/component": {
"title": "$:/language/Docs/Fields/component",
"text": "The name of the component responsible for an [[alert tiddler|AlertMechanism]]"
},
"$:/language/Docs/Fields/current-tiddler": {
"title": "$:/language/Docs/Fields/current-tiddler",
"text": "Used to cache the top tiddler in a [[history list|HistoryMechanism]]"
},
"$:/language/Docs/Fields/created": {
"title": "$:/language/Docs/Fields/created",
"text": "The date a tiddler was created"
},
"$:/language/Docs/Fields/creator": {
"title": "$:/language/Docs/Fields/creator",
"text": "The name of the person who created a tiddler"
},
"$:/language/Docs/Fields/dependents": {
"title": "$:/language/Docs/Fields/dependents",
"text": "For a plugin, lists the dependent plugin titles"
},
"$:/language/Docs/Fields/description": {
"title": "$:/language/Docs/Fields/description",
"text": "The descriptive text for a plugin, or a modal dialogue"
},
"$:/language/Docs/Fields/draft.of": {
"title": "$:/language/Docs/Fields/draft.of",
"text": "For draft tiddlers, contains the title of the tiddler of which this is a draft"
},
"$:/language/Docs/Fields/draft.title": {
"title": "$:/language/Docs/Fields/draft.title",
"text": "For draft tiddlers, contains the proposed new title of the tiddler"
},
"$:/language/Docs/Fields/footer": {
"title": "$:/language/Docs/Fields/footer",
"text": "The footer text for a wizard"
},
"$:/language/Docs/Fields/hide-body": {
"title": "$:/language/Docs/Fields/hide-body",
"text": "The view template will hide bodies of tiddlers if set to: ''yes''"
},
"$:/language/Docs/Fields/icon": {
"title": "$:/language/Docs/Fields/icon",
"text": "The title of the tiddler containing the icon associated with a tiddler"
},
"$:/language/Docs/Fields/library": {
"title": "$:/language/Docs/Fields/library",
"text": "Indicates that a tiddler should be saved as a JavaScript library if set to: ''yes''"
},
"$:/language/Docs/Fields/list": {
"title": "$:/language/Docs/Fields/list",
"text": "An ordered list of tiddler titles associated with a tiddler"
},
"$:/language/Docs/Fields/list-before": {
"title": "$:/language/Docs/Fields/list-before",
"text": "If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty"
},
"$:/language/Docs/Fields/list-after": {
"title": "$:/language/Docs/Fields/list-after",
"text": "If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty"
},
"$:/language/Docs/Fields/modified": {
"title": "$:/language/Docs/Fields/modified",
"text": "The date and time at which a tiddler was last modified"
},
"$:/language/Docs/Fields/modifier": {
"title": "$:/language/Docs/Fields/modifier",
"text": "The tiddler title associated with the person who last modified a tiddler"
},
"$:/language/Docs/Fields/name": {
"title": "$:/language/Docs/Fields/name",
"text": "The human readable name associated with a plugin tiddler"
},
"$:/language/Docs/Fields/plugin-priority": {
"title": "$:/language/Docs/Fields/plugin-priority",
"text": "A numerical value indicating the priority of a plugin tiddler"
},
"$:/language/Docs/Fields/plugin-type": {
"title": "$:/language/Docs/Fields/plugin-type",
"text": "The type of plugin in a plugin tiddler"
},
"$:/language/Docs/Fields/revision": {
"title": "$:/language/Docs/Fields/revision",
"text": "The revision of the tiddler held at the server"
},
"$:/language/Docs/Fields/released": {
"title": "$:/language/Docs/Fields/released",
"text": "Date of a TiddlyWiki release"
},
"$:/language/Docs/Fields/source": {
"title": "$:/language/Docs/Fields/source",
"text": "The source URL associated with a tiddler"
},
"$:/language/Docs/Fields/subtitle": {
"title": "$:/language/Docs/Fields/subtitle",
"text": "The subtitle text for a wizard"
},
"$:/language/Docs/Fields/tags": {
"title": "$:/language/Docs/Fields/tags",
"text": "A list of tags associated with a tiddler"
},
"$:/language/Docs/Fields/text": {
"title": "$:/language/Docs/Fields/text",
"text": "The body text of a tiddler"
},
"$:/language/Docs/Fields/throttle.refresh": {
"title": "$:/language/Docs/Fields/throttle.refresh",
"text": "If present, throttles refreshes of this tiddler"
},
"$:/language/Docs/Fields/title": {
"title": "$:/language/Docs/Fields/title",
"text": "The unique name of a tiddler"
},
"$:/language/Docs/Fields/toc-link": {
"title": "$:/language/Docs/Fields/toc-link",
"text": "Suppresses the tiddler's link in a Table of Contents tree if set to: ''no''"
},
"$:/language/Docs/Fields/type": {
"title": "$:/language/Docs/Fields/type",
"text": "The content type of a tiddler"
},
"$:/language/Docs/Fields/version": {
"title": "$:/language/Docs/Fields/version",
"text": "Version information for a plugin"
},
"$:/language/Docs/Fields/_is_skinny": {
"title": "$:/language/Docs/Fields/_is_skinny",
"text": "If present, indicates that the tiddler text field must be loaded from the server"
},
"$:/language/Filters/AllTiddlers": {
"title": "$:/language/Filters/AllTiddlers",
"text": "All tiddlers except system tiddlers"
},
"$:/language/Filters/RecentSystemTiddlers": {
"title": "$:/language/Filters/RecentSystemTiddlers",
"text": "Recently modified tiddlers, including system tiddlers"
},
"$:/language/Filters/RecentTiddlers": {
"title": "$:/language/Filters/RecentTiddlers",
"text": "Recently modified tiddlers"
},
"$:/language/Filters/AllTags": {
"title": "$:/language/Filters/AllTags",
"text": "All tags except system tags"
},
"$:/language/Filters/Missing": {
"title": "$:/language/Filters/Missing",
"text": "Missing tiddlers"
},
"$:/language/Filters/Drafts": {
"title": "$:/language/Filters/Drafts",
"text": "Draft tiddlers"
},
"$:/language/Filters/Orphans": {
"title": "$:/language/Filters/Orphans",
"text": "Orphan tiddlers"
},
"$:/language/Filters/SystemTiddlers": {
"title": "$:/language/Filters/SystemTiddlers",
"text": "System tiddlers"
},
"$:/language/Filters/ShadowTiddlers": {
"title": "$:/language/Filters/ShadowTiddlers",
"text": "Shadow tiddlers"
},
"$:/language/Filters/OverriddenShadowTiddlers": {
"title": "$:/language/Filters/OverriddenShadowTiddlers",
"text": "Overridden shadow tiddlers"
},
"$:/language/Filters/SessionTiddlers": {
"title": "$:/language/Filters/SessionTiddlers",
"text": "Tiddlers modified since the wiki was loaded"
},
"$:/language/Filters/SystemTags": {
"title": "$:/language/Filters/SystemTags",
"text": "System tags"
},
"$:/language/Filters/StoryList": {
"title": "$:/language/Filters/StoryList",
"text": "Tiddlers in the story river, excluding <$text text=\"$:/AdvancedSearch\"/>"
},
"$:/language/Filters/TypedTiddlers": {
"title": "$:/language/Filters/TypedTiddlers",
"text": "Non wiki-text tiddlers"
},
"GettingStarted": {
"title": "GettingStarted",
"text": "\\define lingo-base() $:/language/ControlPanel/Basics/\nWelcome to ~TiddlyWiki and the ~TiddlyWiki community\n\nBefore you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details\n\n!! Set up this ~TiddlyWiki\n\n<div class=\"tc-control-panel\">\n\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n</div>\n\nSee the [[control panel|$:/ControlPanel]] for more options.\n"
},
"$:/language/Help/build": {
"title": "$:/language/Help/build",
"description": "Automatically run configured commands",
"text": "Build the specified build targets for the current wiki. If no build targets are specified then all available targets will be built.\n\n```\n--build <target> [<target> ...]\n```\n\nBuild targets are defined in the `tiddlywiki.info` file of a wiki folder.\n\n"
},
"$:/language/Help/clearpassword": {
"title": "$:/language/Help/clearpassword",
"description": "Clear a password for subsequent crypto operations",
"text": "Clear the password for subsequent crypto operations\n\n```\n--clearpassword\n```\n"
},
"$:/language/Help/default": {
"title": "$:/language/Help/default",
"text": "\\define commandTitle()\n$:/language/Help/$(command)$\n\\end\n```\nusage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]\n```\n\nAvailable commands:\n\n<ul>\n<$list filter=\"[commands[]sort[title]]\" variable=\"command\">\n<li><$link to=<<commandTitle>>><$macrocall $name=\"command\" $type=\"text/plain\" $output=\"text/plain\"/></$link>: <$transclude tiddler=<<commandTitle>> field=\"description\"/></li>\n</$list>\n</ul>\n\nTo get detailed help on a command:\n\n```\ntiddlywiki --help <command>\n```\n"
},
"$:/language/Help/deletetiddlers": {
"title": "$:/language/Help/deletetiddlers",
"description": "Deletes a group of tiddlers",
"text": "<<.from-version \"5.1.20\">> Deletes a group of tiddlers identified by a filter.\n\n```\n--deletetiddlers <filter>\n```\n"
},
"$:/language/Help/editions": {
"title": "$:/language/Help/editions",
"description": "Lists the available editions of TiddlyWiki",
"text": "Lists the names and descriptions of the available editions. You can create a new wiki of a specified edition with the `--init` command.\n\n```\n--editions\n```\n"
},
"$:/language/Help/fetch": {
"title": "$:/language/Help/fetch",
"description": "Fetch tiddlers from wiki by URL",
"text": "Fetch one or more files over HTTP/HTTPS, and import the tiddlers matching a filter, optionally transforming the incoming titles.\n\n```\n--fetch file <url> <import-filter> <transform-filter>\n--fetch files <url-filter> <import-filter> <transform-filter>\n--fetch raw-file <url> <transform-filter>\n--fetch raw-files <url-filter> <transform-filter>\n```\n\nThe \"file\" and \"files\" variants fetch the specified files and attempt to import the tiddlers within them (the same processing as if the files were dragged into the browser window). The \"raw-file\" and \"raw-files\" variants fetch the specified files and then store the raw file data in tiddlers, without applying the import logic.\n\nWith the \"file\" and \"raw-file\" variants only a single file is fetched and the first parameter is the URL of the file to read.\n\nWith the \"files\" and \"raw-files\" variants, multiple files are fetched and the first parameter is a filter yielding a list of URLs of the files to read. For example, given a set of tiddlers tagged \"remote-server\" that have a field \"url\" the filter `[tag[remote-server]get[url]]` will retrieve all the available URLs.\n\nFor the \"file\" and \"files\" variants, the `<import-filter>` parameter specifies a filter determining which tiddlers are imported. It defaults to `[all[tiddlers]]` if not provided.\n\nFor all variants, the `<transform-filter>` parameter specifies an optional filter that transforms the titles of the imported tiddlers. For example, `[addprefix[$:/myimports/]]` would add the prefix `$:/myimports/` to each title.\n\nPreceding the `--fetch` command with `--verbose` will output progress information during the import.\n\nNote that TiddlyWiki will not fetch an older version of an already loaded plugin.\n\nThe following example retrieves all the non-system tiddlers from https://tiddlywiki.com and saves them to a JSON file:\n\n```\ntiddlywiki --verbose --fetch file \"https://tiddlywiki.com/\" \"[!is[system]]\" \"\" --rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[!is[system]]\"\n```\n\nThe following example retrieves the \"favicon\" file from tiddlywiki.com and saves it in a file called \"output.ico\". Note that the intermediate tiddler \"Icon Tiddler\" is quoted in the \"--fetch\" command because it is being used as a transformation filter to replace the default title, while there are no quotes for the \"--savetiddler\" command because it is being used directly as a title.\n\n```\ntiddlywiki --verbose --fetch raw-file \"https://tiddlywiki.com/favicon.ico\" \"[[Icon Tiddler]]\" --savetiddler \"Icon Tiddler\" output.ico\n```\n\n"
},
"$:/language/Help/help": {
"title": "$:/language/Help/help",
"description": "Display help for TiddlyWiki commands",
"text": "Displays help text for a command:\n\n```\n--help [<command>]\n```\n\nIf the command name is omitted then a list of available commands is displayed.\n"
},
"$:/language/Help/import": {
"title": "$:/language/Help/import",
"description": "Import tiddlers from a file",
"text": "Import tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The deserializer must be explicitly specified, unlike the `load` command which infers the deserializer from the file extension.\n\n```\n--import <filepath> <deserializer> [<title>] [<encoding>]\n```\n\nThe deserializers in the core include:\n\n* application/javascript\n* application/json\n* application/x-tiddler\n* application/x-tiddler-html-div\n* application/x-tiddlers\n* text/html\n* text/plain\n\nThe title of the imported tiddler defaults to the filename.\n\nThe encoding defaults to \"utf8\", but can be \"base64\" for importing binary files.\n\nNote that TiddlyWiki will not import an older version of an already loaded plugin.\n"
},
"$:/language/Help/init": {
"title": "$:/language/Help/init",
"description": "Initialise a new wiki folder",
"text": "Initialise an empty [[WikiFolder|WikiFolders]] with a copy of the specified edition.\n\n```\n--init <edition> [<edition> ...]\n```\n\nFor example:\n\n```\ntiddlywiki ./MyWikiFolder --init empty\n```\n\nNote:\n\n* The wiki folder directory will be created if necessary\n* The \"edition\" defaults to ''empty''\n* The init command will fail if the wiki folder is not empty\n* The init command removes any `includeWikis` definitions in the edition's `tiddlywiki.info` file\n* When multiple editions are specified, editions initialised later will overwrite any files shared with earlier editions (so, the final `tiddlywiki.info` file will be copied from the last edition)\n* `--editions` returns a list of available editions\n"
},
"$:/language/Help/listen": {
"title": "$:/language/Help/listen",
"description": "Provides an HTTP server interface to TiddlyWiki",
"text": "Serves a wiki over HTTP.\n\nThe listen command uses NamedCommandParameters:\n\n```\n--listen [<name>=<value>]...\n```\n\nAll parameters are optional with safe defaults, and can be specified in any order. The recognised parameters are:\n\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''credentials'' - pathname of credentials CSV file (relative to wiki folder)\n* ''anon-username'' - the username for signing edits for anonymous users\n* ''username'' - optional username for basic authentication\n* ''password'' - optional password for basic authentication\n* ''authenticated-user-header'' - optional name of header to be used for trusted authentication\n* ''readers'' - comma separated list of principals allowed to read from this wiki\n* ''writers'' - comma separated list of principals allowed to write to this wiki\n* ''csrf-disable'' - set to \"yes\" to disable CSRF checks (defaults to \"no\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''tls-cert'' - pathname of TLS certificate file (relative to wiki folder)\n* ''tls-key'' - pathname of TLS key file (relative to wiki folder)\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n* ''gzip'' - set to \"yes\" to enable gzip compression for some http endpoints (defaults to \"no\")\n\nFor information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\n"
},
"$:/language/Help/load": {
"title": "$:/language/Help/load",
"description": "Load tiddlers from a file",
"text": "Load tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The processing applied to incoming files is determined by the file extension. Use the alternative `import` command if you need to specify the deserializer and encoding explicitly.\n\n```\n--load <filepath> [noerror]\n--load <dirpath> [noerror]\n```\n\nBy default, the load command raises an error if no tiddlers are found. The error can be suppressed by providing the optional \"noerror\" parameter.\n\nTo load tiddlers from an encrypted TiddlyWiki file you should first specify the password with the PasswordCommand. For example:\n\n```\ntiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html\n```\n\nNote that TiddlyWiki will not load an older version of an already loaded plugin.\n"
},
"$:/language/Help/makelibrary": {
"title": "$:/language/Help/makelibrary",
"description": "Construct library plugin required by upgrade process",
"text": "Constructs the `$:/UpgradeLibrary` tiddler for the upgrade process.\n\nThe upgrade library is formatted as an ordinary plugin tiddler with the plugin type `library`. It contains a copy of each of the plugins, themes and language packs available within the TiddlyWiki5 repository.\n\nThis command is intended for internal use; it is only relevant to users constructing a custom upgrade procedure.\n\n```\n--makelibrary <title>\n```\n\nThe title argument defaults to `$:/UpgradeLibrary`.\n"
},
"$:/language/Help/notfound": {
"title": "$:/language/Help/notfound",
"text": "No such help item"
},
"$:/language/Help/output": {
"title": "$:/language/Help/output",
"description": "Set the base output directory for subsequent commands",
"text": "Sets the base output directory for subsequent commands. The default output directory is the `output` subdirectory of the edition directory.\n\n```\n--output <pathname>\n```\n\nIf the specified pathname is relative then it is resolved relative to the current working directory. For example `--output .` sets the output directory to the current working directory.\n\n"
},
"$:/language/Help/password": {
"title": "$:/language/Help/password",
"description": "Set a password for subsequent crypto operations",
"text": "Set a password for subsequent crypto operations\n\n```\n--password <password>\n```\n\n''Note'': This should not be used for serving TiddlyWiki with password protection. Instead, see the password option under the [[ServerCommand]].\n"
},
"$:/language/Help/render": {
"title": "$:/language/Help/render",
"description": "Renders individual tiddlers to files",
"text": "Render individual tiddlers identified by a filter and save the results to the specified files.\n\nOptionally, the title of a template tiddler can be specified. In this case, instead of directly rendering each tiddler, the template tiddler is rendered with the \"currentTiddler\" variable set to the title of the tiddler that is being rendered.\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [<name>] [<value>]\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be rendered\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]addsuffix[.html]]`, which uses the unchanged tiddler title as the filename\n* ''render-type'': Optional render type: `text/html` (the default) returns the full HTML text and `text/plain` just returns the text content (ie it ignores HTML tags and other unprintable material)\n* ''template'': Optional template through which each tiddler is rendered\n* ''name'': Name of optional variable\n* ''value'': Value of optional variable\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When referring to a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--render \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being rendered, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--render` command is a more flexible replacement for both the `--rendertiddler` and `--rendertiddlers` commands, which are deprecated\n\nExamples:\n\n* `--render \"[!is[system]]\" \"[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]\"` -- renders all non-system tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles and the extension HTML\n\n"
},
"$:/language/Help/rendertiddler": {
"title": "$:/language/Help/rendertiddler",
"description": "Render an individual tiddler as a specified ContentType",
"text": "(Note: The `--rendertiddler` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender an individual tiddler as a specified ContentType, defaulting to `text/html` and save it to the specified filename.\n\nOptionally the title of a template tiddler can be specified, in which case the template tiddler is rendered with the \"currentTiddler\" variable set to the tiddler that is being rendered (the first parameter value).\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--rendertiddler <title> <filename> [<type>] [<template>] [<name>] [<value>]\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n\nFor example, the following command saves all tiddlers matching the filter `[tag[done]]` to a JSON file titled `output.json` by employing the core template `$:/core/templates/exporters/JsonFile`.\n\n```\n--rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[tag[done]]\"\n```\n"
},
"$:/language/Help/rendertiddlers": {
"title": "$:/language/Help/rendertiddlers",
"description": "Render tiddlers matching a filter to a specified ContentType",
"text": "(Note: The `--rendertiddlers` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).\n\n```\n--rendertiddlers '<filter>' <template> <pathname> [<type>] [<extension>] [\"noclean\"]\n```\n\nFor example:\n\n```\n--rendertiddlers '[!is[system]]' $:/core/templates/static.tiddler.html ./static text/plain\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny files in the target directory are deleted unless the ''noclean'' flag is specified. The target directory is recursively created if it is missing.\n"
},
"$:/language/Help/save": {
"title": "$:/language/Help/save",
"description": "Saves individual raw tiddlers to files",
"text": "Saves individual tiddlers identified by a filter in their raw text or binary format to the specified files.\n\n```\n--save <tiddler-filter> <filename-filter>\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be saved\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]]`, which uses the unchanged tiddler title as the filename\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When saving a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--save \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being saved, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--save` command is a more flexible replacement for both the `--savetiddler` and `--savetiddlers` commands, which are deprecated\n\nExamples:\n\n* `--save \"[!is[system]is[image]]\" \"[encodeuricomponent[]addprefix[tiddlers/]]\"` -- saves all non-system image tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles\n"
},
"$:/language/Help/savetiddler": {
"title": "$:/language/Help/savetiddler",
"description": "Saves a raw tiddler to a file",
"text": "(Note: The `--savetiddler` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves an individual tiddler in its raw text or binary format to the specified filename.\n\n```\n--savetiddler <title> <filename>\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n"
},
"$:/language/Help/savetiddlers": {
"title": "$:/language/Help/savetiddlers",
"description": "Saves a group of raw tiddlers to a directory",
"text": "(Note: The `--savetiddlers` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves a group of tiddlers in their raw text or binary format to the specified directory.\n\n```\n--savetiddlers <filter> <pathname> [\"noclean\"]\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nThe output directory is cleared of existing files before saving the specified files. The deletion can be disabled by specifying the ''noclean'' flag.\n\nAny missing directories in the pathname are automatically created.\n"
},
"$:/language/Help/savewikifolder": {
"title": "$:/language/Help/savewikifolder",
"description": "Saves a wiki to a new wiki folder",
"text": "<<.from-version \"5.1.20\">> Saves the current wiki as a wiki folder, including tiddlers, plugins and configuration:\n\n```\n--savewikifolder <wikifolderpath> [<filter>]\n```\n\n* The target wiki folder must be empty or non-existent\n* The filter specifies which tiddlers should be included. It is optional, defaulting to `[all[tiddlers]]`\n* Plugins from the official plugin library are replaced with references to those plugins in the `tiddlywiki.info` file\n* Custom plugins are unpacked into their own folder\n\nA common usage is to convert a TiddlyWiki HTML file into a wiki folder:\n\n```\ntiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder\n```\n"
},
"$:/language/Help/server": {
"title": "$:/language/Help/server",
"description": "Provides an HTTP server interface to TiddlyWiki (deprecated in favour of the new listen command)",
"text": "Legacy command to serve a wiki over HTTP.\n\n```\n--server <port> <root-tiddler> <root-render-type> <root-serve-type> <username> <password> <host> <path-prefix> <debug-level>\n```\n\nThe parameters are:\n\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''username'' - the default username for signing edits\n* ''password'' - optional password for basic authentication\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n\nIf the password parameter is specified then the browser will prompt the user for the username and password. Note that the password is transmitted in plain text so this implementation should only be used on a trusted network or over HTTPS.\n\nFor example:\n\n```\n--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n\nThe username and password can be specified as empty strings if you need to set the hostname or pathprefix and don't want to require a password.\n\n\n```\n--server 8080 $:/core/save/all text/plain text/html \"\" \"\" 192.168.0.245\n```\n\nUsing an address like this exposes your system to the local network. For information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\nTo run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port. It can be useful to use an environment variable to pass the port number to the Node.js process. This example references an environment variable called \"MY_PORT_NUMBER\":\n\n```\n--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n"
},
"$:/language/Help/setfield": {
"title": "$:/language/Help/setfield",
"description": "Prepares external tiddlers for use",
"text": "//Note that this command is experimental and may change or be replaced before being finalised//\n\nSets the specified field of a group of tiddlers to the result of wikifying a template tiddler with the `currentTiddler` variable set to the tiddler.\n\n```\n--setfield <filter> <fieldname> <templatetitle> <rendertype>\n```\n\nThe parameters are:\n\n* ''filter'' - filter identifying the tiddlers to be affected\n* ''fieldname'' - the field to modify (defaults to \"text\")\n* ''templatetitle'' - the tiddler to wikify into the specified field. If blank or missing then the specified field is deleted\n* ''rendertype'' - the text type to render (defaults to \"text/plain\"; \"text/html\" can be used to include HTML tags)\n"
},
"$:/language/Help/unpackplugin": {
"title": "$:/language/Help/unpackplugin",
"description": "Unpack the payload tiddlers from a plugin",
"text": "Extract the payload tiddlers from a plugin, creating them as ordinary tiddlers:\n\n```\n--unpackplugin <title>\n```\n"
},
"$:/language/Help/verbose": {
"title": "$:/language/Help/verbose",
"description": "Triggers verbose output mode",
"text": "Triggers verbose output, useful for debugging\n\n```\n--verbose\n```\n"
},
"$:/language/Help/version": {
"title": "$:/language/Help/version",
"description": "Displays the version number of TiddlyWiki",
"text": "Displays the version number of TiddlyWiki.\n\n```\n--version\n```\n"
},
"$:/language/Import/Imported/Hint": {
"title": "$:/language/Import/Imported/Hint",
"text": "The following tiddlers were imported:"
},
"$:/language/Import/Listing/Cancel/Caption": {
"title": "$:/language/Import/Listing/Cancel/Caption",
"text": "Cancel"
},
"$:/language/Import/Listing/Hint": {
"title": "$:/language/Import/Listing/Hint",
"text": "These tiddlers are ready to import:"
},
"$:/language/Import/Listing/Import/Caption": {
"title": "$:/language/Import/Listing/Import/Caption",
"text": "Import"
},
"$:/language/Import/Listing/Select/Caption": {
"title": "$:/language/Import/Listing/Select/Caption",
"text": "Select"
},
"$:/language/Import/Listing/Status/Caption": {
"title": "$:/language/Import/Listing/Status/Caption",
"text": "Status"
},
"$:/language/Import/Listing/Title/Caption": {
"title": "$:/language/Import/Listing/Title/Caption",
"text": "Title"
},
"$:/language/Import/Listing/Preview": {
"title": "$:/language/Import/Listing/Preview",
"text": "Preview:"
},
"$:/language/Import/Listing/Preview/Text": {
"title": "$:/language/Import/Listing/Preview/Text",
"text": "Text"
},
"$:/language/Import/Listing/Preview/TextRaw": {
"title": "$:/language/Import/Listing/Preview/TextRaw",
"text": "Text (Raw)"
},
"$:/language/Import/Listing/Preview/Fields": {
"title": "$:/language/Import/Listing/Preview/Fields",
"text": "Fields"
},
"$:/language/Import/Listing/Preview/Diff": {
"title": "$:/language/Import/Listing/Preview/Diff",
"text": "Diff"
},
"$:/language/Import/Listing/Preview/DiffFields": {
"title": "$:/language/Import/Listing/Preview/DiffFields",
"text": "Diff (Fields)"
},
"$:/language/Import/Listing/Rename/Tooltip": {
"title": "$:/language/Import/Listing/Rename/Tooltip",
"text": "Rename tiddler before importing"
},
"$:/language/Import/Listing/Rename/Prompt": {
"title": "$:/language/Import/Listing/Rename/Prompt",
"text": "Rename to:"
},
"$:/language/Import/Listing/Rename/ConfirmRename": {
"title": "$:/language/Import/Listing/Rename/ConfirmRename",
"text": "Rename tiddler"
},
"$:/language/Import/Listing/Rename/CancelRename": {
"title": "$:/language/Import/Listing/Rename/CancelRename",
"text": "Cancel"
},
"$:/language/Import/Listing/Rename/OverwriteWarning": {
"title": "$:/language/Import/Listing/Rename/OverwriteWarning",
"text": "A tiddler with this title already exists."
},
"$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible": {
"title": "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible",
"text": "Blocked incompatible or obsolete plugin."
},
"$:/language/Import/Upgrader/Plugins/Suppressed/Version": {
"title": "$:/language/Import/Upgrader/Plugins/Suppressed/Version",
"text": "Blocked plugin (due to incoming <<incoming>> not being newer than existing <<existing>>)."
},
"$:/language/Import/Upgrader/Plugins/Upgraded": {
"title": "$:/language/Import/Upgrader/Plugins/Upgraded",
"text": "Upgraded plugin from <<incoming>> to <<upgraded>>."
},
"$:/language/Import/Upgrader/State/Suppressed": {
"title": "$:/language/Import/Upgrader/State/Suppressed",
"text": "Blocked temporary state tiddler."
},
"$:/language/Import/Upgrader/System/Suppressed": {
"title": "$:/language/Import/Upgrader/System/Suppressed",
"text": "Blocked system tiddler."
},
"$:/language/Import/Upgrader/System/Warning": {
"title": "$:/language/Import/Upgrader/System/Warning",
"text": "Core module tiddler."
},
"$:/language/Import/Upgrader/System/Alert": {
"title": "$:/language/Import/Upgrader/System/Alert",
"text": "You are about to import a tiddler that will overwrite a core module tiddler. This is not recommended as it may make the system unstable."
},
"$:/language/Import/Upgrader/ThemeTweaks/Created": {
"title": "$:/language/Import/Upgrader/ThemeTweaks/Created",
"text": "Migrated theme tweak from <$text text=<<from>>/>."
},
"$:/language/AboveStory/ClassicPlugin/Warning": {
"title": "$:/language/AboveStory/ClassicPlugin/Warning",
"text": "It looks like you are trying to load a plugin designed for ~TiddlyWiki Classic. Please note that [[these plugins do not work with TiddlyWiki version 5.x.x|https://tiddlywiki.com/#TiddlyWikiClassic]]. ~TiddlyWiki Classic plugins detected:"
},
"$:/language/BinaryWarning/Prompt": {
"title": "$:/language/BinaryWarning/Prompt",
"text": "This tiddler contains binary data"
},
"$:/language/ClassicWarning/Hint": {
"title": "$:/language/ClassicWarning/Hint",
"text": "This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See https://tiddlywiki.com/static/Upgrading.html for more details."
},
"$:/language/ClassicWarning/Upgrade/Caption": {
"title": "$:/language/ClassicWarning/Upgrade/Caption",
"text": "upgrade"
},
"$:/language/CloseAll/Button": {
"title": "$:/language/CloseAll/Button",
"text": "close all"
},
"$:/language/ColourPicker/Recent": {
"title": "$:/language/ColourPicker/Recent",
"text": "Recent:"
},
"$:/language/ConfirmCancelTiddler": {
"title": "$:/language/ConfirmCancelTiddler",
"text": "Do you wish to discard changes to the tiddler \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmDeleteTiddler": {
"title": "$:/language/ConfirmDeleteTiddler",
"text": "Do you wish to delete the tiddler \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmOverwriteTiddler": {
"title": "$:/language/ConfirmOverwriteTiddler",
"text": "Do you wish to overwrite the tiddler \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmEditShadowTiddler": {
"title": "$:/language/ConfirmEditShadowTiddler",
"text": "You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmAction": {
"title": "$:/language/ConfirmAction",
"text": "Do you wish to proceed?"
},
"$:/language/Count": {
"title": "$:/language/Count",
"text": "count"
},
"$:/language/DefaultNewTiddlerTitle": {
"title": "$:/language/DefaultNewTiddlerTitle",
"text": "New Tiddler"
},
"$:/language/Diffs/CountMessage": {
"title": "$:/language/Diffs/CountMessage",
"text": "<<diff-count>> differences"
},
"$:/language/DropMessage": {
"title": "$:/language/DropMessage",
"text": "Drop here (or use the 'Escape' key to cancel)"
},
"$:/language/Encryption/Cancel": {
"title": "$:/language/Encryption/Cancel",
"text": "Cancel"
},
"$:/language/Encryption/ConfirmClearPassword": {
"title": "$:/language/Encryption/ConfirmClearPassword",
"text": "Do you wish to clear the password? This will remove the encryption applied when saving this wiki"
},
"$:/language/Encryption/PromptSetPassword": {
"title": "$:/language/Encryption/PromptSetPassword",
"text": "Set a new password for this TiddlyWiki"
},
"$:/language/Encryption/Username": {
"title": "$:/language/Encryption/Username",
"text": "Username"
},
"$:/language/Encryption/Password": {
"title": "$:/language/Encryption/Password",
"text": "Password"
},
"$:/language/Encryption/RepeatPassword": {
"title": "$:/language/Encryption/RepeatPassword",
"text": "Repeat password"
},
"$:/language/Encryption/PasswordNoMatch": {
"title": "$:/language/Encryption/PasswordNoMatch",
"text": "Passwords do not match"
},
"$:/language/Encryption/SetPassword": {
"title": "$:/language/Encryption/SetPassword",
"text": "Set password"
},
"$:/language/Error/Caption": {
"title": "$:/language/Error/Caption",
"text": "Error"
},
"$:/language/Error/EditConflict": {
"title": "$:/language/Error/EditConflict",
"text": "File changed on server"
},
"$:/language/Error/Filter": {
"title": "$:/language/Error/Filter",
"text": "Filter error"
},
"$:/language/Error/FilterSyntax": {
"title": "$:/language/Error/FilterSyntax",
"text": "Syntax error in filter expression"
},
"$:/language/Error/FilterRunPrefix": {
"title": "$:/language/Error/FilterRunPrefix",
"text": "Filter Error: Unknown prefix for filter run"
},
"$:/language/Error/IsFilterOperator": {
"title": "$:/language/Error/IsFilterOperator",
"text": "Filter Error: Unknown operand for the 'is' filter operator"
},
"$:/language/Error/FormatFilterOperator": {
"title": "$:/language/Error/FormatFilterOperator",
"text": "Filter Error: Unknown suffix for the 'format' filter operator"
},
"$:/language/Error/LoadingPluginLibrary": {
"title": "$:/language/Error/LoadingPluginLibrary",
"text": "Error loading plugin library"
},
"$:/language/Error/NetworkErrorAlert": {
"title": "$:/language/Error/NetworkErrorAlert",
"text": "`<h2>''Network Error''</h2>It looks like the connection to the server has been lost. This may indicate a problem with your network connection. Please attempt to restore network connectivity before continuing.<br><br>''Any unsaved changes will be automatically synchronised when connectivity is restored''.`"
},
"$:/language/Error/RecursiveTransclusion": {
"title": "$:/language/Error/RecursiveTransclusion",
"text": "Recursive transclusion error in transclude widget"
},
"$:/language/Error/RetrievingSkinny": {
"title": "$:/language/Error/RetrievingSkinny",
"text": "Error retrieving skinny tiddler list"
},
"$:/language/Error/SavingToTWEdit": {
"title": "$:/language/Error/SavingToTWEdit",
"text": "Error saving to TWEdit"
},
"$:/language/Error/WhileSaving": {
"title": "$:/language/Error/WhileSaving",
"text": "Error while saving"
},
"$:/language/Error/XMLHttpRequest": {
"title": "$:/language/Error/XMLHttpRequest",
"text": "XMLHttpRequest error code"
},
"$:/language/InternalJavaScriptError/Title": {
"title": "$:/language/InternalJavaScriptError/Title",
"text": "Internal JavaScript Error"
},
"$:/language/InternalJavaScriptError/Hint": {
"title": "$:/language/InternalJavaScriptError/Hint",
"text": "Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser"
},
"$:/language/InvalidFieldName": {
"title": "$:/language/InvalidFieldName",
"text": "Illegal characters in field name \"<$text text=<<fieldName>>/>\". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)"
},
"$:/language/LayoutSwitcher/Description": {
"title": "$:/language/LayoutSwitcher/Description",
"text": "Open the layout switcher"
},
"$:/language/LazyLoadingWarning": {
"title": "$:/language/LazyLoadingWarning",
"text": "<p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>"
},
"$:/language/LoginToTiddlySpace": {
"title": "$:/language/LoginToTiddlySpace",
"text": "Login to TiddlySpace"
},
"$:/language/Manager/Controls/FilterByTag/None": {
"title": "$:/language/Manager/Controls/FilterByTag/None",
"text": "(none)"
},
"$:/language/Manager/Controls/FilterByTag/Prompt": {
"title": "$:/language/Manager/Controls/FilterByTag/Prompt",
"text": "Filter by tag:"
},
"$:/language/Manager/Controls/Order/Prompt": {
"title": "$:/language/Manager/Controls/Order/Prompt",
"text": "Reverse order"
},
"$:/language/Manager/Controls/Search/Placeholder": {
"title": "$:/language/Manager/Controls/Search/Placeholder",
"text": "Search"
},
"$:/language/Manager/Controls/Search/Prompt": {
"title": "$:/language/Manager/Controls/Search/Prompt",
"text": "Search:"
},
"$:/language/Manager/Controls/Show/Option/Tags": {
"title": "$:/language/Manager/Controls/Show/Option/Tags",
"text": "tags"
},
"$:/language/Manager/Controls/Show/Option/Tiddlers": {
"title": "$:/language/Manager/Controls/Show/Option/Tiddlers",
"text": "tiddlers"
},
"$:/language/Manager/Controls/Show/Prompt": {
"title": "$:/language/Manager/Controls/Show/Prompt",
"text": "Show:"
},
"$:/language/Manager/Controls/Sort/Prompt": {
"title": "$:/language/Manager/Controls/Sort/Prompt",
"text": "Sort by:"
},
"$:/language/Manager/Item/Colour": {
"title": "$:/language/Manager/Item/Colour",
"text": "Colour"
},
"$:/language/Manager/Item/Fields": {
"title": "$:/language/Manager/Item/Fields",
"text": "Fields"
},
"$:/language/Manager/Item/Icon/None": {
"title": "$:/language/Manager/Item/Icon/None",
"text": "(none)"
},
"$:/language/Manager/Item/Icon": {
"title": "$:/language/Manager/Item/Icon",
"text": "Icon"
},
"$:/language/Manager/Item/RawText": {
"title": "$:/language/Manager/Item/RawText",
"text": "Raw text"
},
"$:/language/Manager/Item/Tags": {
"title": "$:/language/Manager/Item/Tags",
"text": "Tags"
},
"$:/language/Manager/Item/Tools": {
"title": "$:/language/Manager/Item/Tools",
"text": "Tools"
},
"$:/language/Manager/Item/WikifiedText": {
"title": "$:/language/Manager/Item/WikifiedText",
"text": "Wikified text"
},
"$:/language/MissingTiddler/Hint": {
"title": "$:/language/MissingTiddler/Hint",
"text": "Missing tiddler \"<$text text=<<currentTiddler>>/>\" -- click {{||$:/core/ui/Buttons/edit}} to create"
},
"$:/language/No": {
"title": "$:/language/No",
"text": "No"
},
"$:/language/OfficialPluginLibrary": {
"title": "$:/language/OfficialPluginLibrary",
"text": "Official ~TiddlyWiki Plugin Library"
},
"$:/language/OfficialPluginLibrary/Hint": {
"title": "$:/language/OfficialPluginLibrary/Hint",
"text": "The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team."
},
"$:/language/PageTemplate/Description": {
"title": "$:/language/PageTemplate/Description",
"text": "the default ~TiddlyWiki layout"
},
"$:/language/PageTemplate/Name": {
"title": "$:/language/PageTemplate/Name",
"text": "Default ~PageTemplate"
},
"$:/language/PluginReloadWarning": {
"title": "$:/language/PluginReloadWarning",
"text": "Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to ~JavaScript plugins to take effect"
},
"$:/language/RecentChanges/DateFormat": {
"title": "$:/language/RecentChanges/DateFormat",
"text": "DDth MMM YYYY"
},
"$:/language/Shortcuts/Input/AdvancedSearch/Hint": {
"title": "$:/language/Shortcuts/Input/AdvancedSearch/Hint",
"text": "Open the ~AdvancedSearch panel from within the sidebar search field"
},
"$:/language/Shortcuts/Input/Accept/Hint": {
"title": "$:/language/Shortcuts/Input/Accept/Hint",
"text": "Accept the selected item"
},
"$:/language/Shortcuts/Input/AcceptVariant/Hint": {
"title": "$:/language/Shortcuts/Input/AcceptVariant/Hint",
"text": "Accept the selected item (variant)"
},
"$:/language/Shortcuts/Input/Cancel/Hint": {
"title": "$:/language/Shortcuts/Input/Cancel/Hint",
"text": "Clear the input field"
},
"$:/language/Shortcuts/Input/Down/Hint": {
"title": "$:/language/Shortcuts/Input/Down/Hint",
"text": "Select the next item"
},
"$:/language/Shortcuts/Input/Tab-Left/Hint": {
"title": "$:/language/Shortcuts/Input/Tab-Left/Hint",
"text": "Select the previous Tab"
},
"$:/language/Shortcuts/Input/Tab-Right/Hint": {
"title": "$:/language/Shortcuts/Input/Tab-Right/Hint",
"text": "Select the next Tab"
},
"$:/language/Shortcuts/Input/Up/Hint": {
"title": "$:/language/Shortcuts/Input/Up/Hint",
"text": "Select the previous item"
},
"$:/language/Shortcuts/SidebarLayout/Hint": {
"title": "$:/language/Shortcuts/SidebarLayout/Hint",
"text": "Change the sidebar layout"
},
"$:/language/Switcher/Subtitle/theme": {
"title": "$:/language/Switcher/Subtitle/theme",
"text": "Switch Theme"
},
"$:/language/Switcher/Subtitle/layout": {
"title": "$:/language/Switcher/Subtitle/layout",
"text": "Switch Layout"
},
"$:/language/Switcher/Subtitle/language": {
"title": "$:/language/Switcher/Subtitle/language",
"text": "Switch Language"
},
"$:/language/Switcher/Subtitle/palette": {
"title": "$:/language/Switcher/Subtitle/palette",
"text": "Switch Palette"
},
"$:/language/SystemTiddler/Tooltip": {
"title": "$:/language/SystemTiddler/Tooltip",
"text": "This is a system tiddler"
},
"$:/language/SystemTiddlers/Include/Prompt": {
"title": "$:/language/SystemTiddlers/Include/Prompt",
"text": "Include system tiddlers"
},
"$:/language/TagManager/Colour/Heading": {
"title": "$:/language/TagManager/Colour/Heading",
"text": "Colour"
},
"$:/language/TagManager/Count/Heading": {
"title": "$:/language/TagManager/Count/Heading",
"text": "Count"
},
"$:/language/TagManager/Icon/Heading": {
"title": "$:/language/TagManager/Icon/Heading",
"text": "Icon"
},
"$:/language/TagManager/Icons/None": {
"title": "$:/language/TagManager/Icons/None",
"text": "None"
},
"$:/language/TagManager/Info/Heading": {
"title": "$:/language/TagManager/Info/Heading",
"text": "Info"
},
"$:/language/TagManager/Tag/Heading": {
"title": "$:/language/TagManager/Tag/Heading",
"text": "Tag"
},
"$:/language/Tiddler/DateFormat": {
"title": "$:/language/Tiddler/DateFormat",
"text": "DDth MMM YYYY at hh12:0mmam"
},
"$:/language/UnsavedChangesWarning": {
"title": "$:/language/UnsavedChangesWarning",
"text": "You have unsaved changes in TiddlyWiki"
},
"$:/language/Yes": {
"title": "$:/language/Yes",
"text": "Yes"
},
"$:/language/Modals/Download": {
"title": "$:/language/Modals/Download",
"subtitle": "Download changes",
"footer": "<$button message=\"tm-close-tiddler\">Close</$button>",
"help": "https://tiddlywiki.com/static/DownloadingChanges.html",
"text": "Your browser only supports manual saving.\n\nTo save your modified wiki, right click on the download link below and select \"Download file\" or \"Save file\", and then choose the folder and filename.\n\n//You can marginally speed things up by clicking the link with the control key (Windows) or the options/alt key (Mac OS X). You will not be prompted for the folder or filename, but your browser is likely to give it an unrecognisable name -- you may need to rename the file to include an `.html` extension before you can do anything useful with it.//\n\nOn smartphones that do not allow files to be downloaded you can instead bookmark the link, and then sync your bookmarks to a desktop computer from where the wiki can be saved normally.\n"
},
"$:/language/Modals/SaveInstructions": {
"title": "$:/language/Modals/SaveInstructions",
"subtitle": "Save your work",
"footer": "<$button message=\"tm-close-tiddler\">Close</$button>",
"help": "https://tiddlywiki.com/static/SavingChanges.html",
"text": "Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.\n\n!!! Desktop browsers\n\n# Select ''Save As'' from the ''File'' menu\n# Choose a filename and location\n#* Some browsers also require you to explicitly specify the file saving format as ''Webpage, HTML only'' or similar\n# Close this tab\n\n!!! Smartphone browsers\n\n# Create a bookmark to this page\n#* If you've got iCloud or Google Sync set up then the bookmark will automatically sync to your desktop where you can open it and save it as above\n# Close this tab\n\n//If you open the bookmark again in Mobile Safari you will see this message again. If you want to go ahead and use the file, just click the ''close'' button below//\n"
},
"$:/config/NewJournal/Title": {
"title": "$:/config/NewJournal/Title",
"text": "DDth MMM YYYY"
},
"$:/config/NewJournal/Text": {
"title": "$:/config/NewJournal/Text",
"text": ""
},
"$:/config/NewJournal/Tags": {
"title": "$:/config/NewJournal/Tags",
"text": "Journal\n"
},
"$:/language/Notifications/Save/Done": {
"title": "$:/language/Notifications/Save/Done",
"text": "Saved wiki"
},
"$:/language/Notifications/Save/Starting": {
"title": "$:/language/Notifications/Save/Starting",
"text": "Starting to save wiki"
},
"$:/language/Notifications/CopiedToClipboard/Succeeded": {
"title": "$:/language/Notifications/CopiedToClipboard/Succeeded",
"text": "Copied to clipboard!"
},
"$:/language/Notifications/CopiedToClipboard/Failed": {
"title": "$:/language/Notifications/CopiedToClipboard/Failed",
"text": "Failed to copy to clipboard!"
},
"$:/language/Search/DefaultResults/Caption": {
"title": "$:/language/Search/DefaultResults/Caption",
"text": "List"
},
"$:/language/Search/Filter/Caption": {
"title": "$:/language/Search/Filter/Caption",
"text": "Filter"
},
"$:/language/Search/Filter/Hint": {
"title": "$:/language/Search/Filter/Hint",
"text": "Search via a [[filter expression|https://tiddlywiki.com/static/Filters.html]]"
},
"$:/language/Search/Filter/Matches": {
"title": "$:/language/Search/Filter/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/Matches": {
"title": "$:/language/Search/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/Matches/All": {
"title": "$:/language/Search/Matches/All",
"text": "All matches:"
},
"$:/language/Search/Matches/Title": {
"title": "$:/language/Search/Matches/Title",
"text": "Title matches:"
},
"$:/language/Search/Search": {
"title": "$:/language/Search/Search",
"text": "Search"
},
"$:/language/Search/Search/TooShort": {
"title": "$:/language/Search/Search/TooShort",
"text": "Search text too short"
},
"$:/language/Search/Shadows/Caption": {
"title": "$:/language/Search/Shadows/Caption",
"text": "Shadows"
},
"$:/language/Search/Shadows/Hint": {
"title": "$:/language/Search/Shadows/Hint",
"text": "Search for shadow tiddlers"
},
"$:/language/Search/Shadows/Matches": {
"title": "$:/language/Search/Shadows/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/Standard/Caption": {
"title": "$:/language/Search/Standard/Caption",
"text": "Standard"
},
"$:/language/Search/Standard/Hint": {
"title": "$:/language/Search/Standard/Hint",
"text": "Search for standard tiddlers"
},
"$:/language/Search/Standard/Matches": {
"title": "$:/language/Search/Standard/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/System/Caption": {
"title": "$:/language/Search/System/Caption",
"text": "System"
},
"$:/language/Search/System/Hint": {
"title": "$:/language/Search/System/Hint",
"text": "Search for system tiddlers"
},
"$:/language/Search/System/Matches": {
"title": "$:/language/Search/System/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/SideBar/All/Caption": {
"title": "$:/language/SideBar/All/Caption",
"text": "All"
},
"$:/language/SideBar/Contents/Caption": {
"title": "$:/language/SideBar/Contents/Caption",
"text": "Contents"
},
"$:/language/SideBar/Drafts/Caption": {
"title": "$:/language/SideBar/Drafts/Caption",
"text": "Drafts"
},
"$:/language/SideBar/Explorer/Caption": {
"title": "$:/language/SideBar/Explorer/Caption",
"text": "Explorer"
},
"$:/language/SideBar/Missing/Caption": {
"title": "$:/language/SideBar/Missing/Caption",
"text": "Missing"
},
"$:/language/SideBar/More/Caption": {
"title": "$:/language/SideBar/More/Caption",
"text": "More"
},
"$:/language/SideBar/Open/Caption": {
"title": "$:/language/SideBar/Open/Caption",
"text": "Open"
},
"$:/language/SideBar/Orphans/Caption": {
"title": "$:/language/SideBar/Orphans/Caption",
"text": "Orphans"
},
"$:/language/SideBar/Recent/Caption": {
"title": "$:/language/SideBar/Recent/Caption",
"text": "Recent"
},
"$:/language/SideBar/Shadows/Caption": {
"title": "$:/language/SideBar/Shadows/Caption",
"text": "Shadows"
},
"$:/language/SideBar/System/Caption": {
"title": "$:/language/SideBar/System/Caption",
"text": "System"
},
"$:/language/SideBar/Tags/Caption": {
"title": "$:/language/SideBar/Tags/Caption",
"text": "Tags"
},
"$:/language/SideBar/Tags/Untagged/Caption": {
"title": "$:/language/SideBar/Tags/Untagged/Caption",
"text": "untagged"
},
"$:/language/SideBar/Tools/Caption": {
"title": "$:/language/SideBar/Tools/Caption",
"text": "Tools"
},
"$:/language/SideBar/Types/Caption": {
"title": "$:/language/SideBar/Types/Caption",
"text": "Types"
},
"$:/SiteSubtitle": {
"title": "$:/SiteSubtitle",
"text": "a non-linear personal web notebook"
},
"$:/SiteTitle": {
"title": "$:/SiteTitle",
"text": "My ~TiddlyWiki"
},
"$:/language/Snippets/ListByTag": {
"title": "$:/language/Snippets/ListByTag",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "List of tiddlers by tag",
"text": "<<list-links \"[tag[task]sort[title]]\">>\n"
},
"$:/language/Snippets/MacroDefinition": {
"title": "$:/language/Snippets/MacroDefinition",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "Macro definition",
"text": "\\define macroName(param1:\"default value\",param2)\nText of the macro\n\\end\n"
},
"$:/language/Snippets/Table4x3": {
"title": "$:/language/Snippets/Table4x3",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "Table with 4 columns by 3 rows",
"text": "|! |!Alpha |!Beta |!Gamma |!Delta |\n|!One | | | | |\n|!Two | | | | |\n|!Three | | | | |\n"
},
"$:/language/Snippets/TableOfContents": {
"title": "$:/language/Snippets/TableOfContents",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "Table of Contents",
"text": "<div class=\"tc-table-of-contents\">\n\n<<toc-selective-expandable 'TableOfContents'>>\n\n</div>"
},
"$:/language/ThemeTweaks/ThemeTweaks": {
"title": "$:/language/ThemeTweaks/ThemeTweaks",
"text": "Theme Tweaks"
},
"$:/language/ThemeTweaks/ThemeTweaks/Hint": {
"title": "$:/language/ThemeTweaks/ThemeTweaks/Hint",
"text": "You can tweak certain aspects of the ''Vanilla'' theme."
},
"$:/language/ThemeTweaks/Options": {
"title": "$:/language/ThemeTweaks/Options",
"text": "Options"
},
"$:/language/ThemeTweaks/Options/SidebarLayout": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout",
"text": "Sidebar layout"
},
"$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid",
"text": "Fixed story, fluid sidebar"
},
"$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed",
"text": "Fluid story, fixed sidebar"
},
"$:/language/ThemeTweaks/Options/StickyTitles": {
"title": "$:/language/ThemeTweaks/Options/StickyTitles",
"text": "Sticky titles"
},
"$:/language/ThemeTweaks/Options/StickyTitles/Hint": {
"title": "$:/language/ThemeTweaks/Options/StickyTitles/Hint",
"text": "Causes tiddler titles to \"stick\" to the top of the browser window"
},
"$:/language/ThemeTweaks/Options/CodeWrapping": {
"title": "$:/language/ThemeTweaks/Options/CodeWrapping",
"text": "Wrap long lines in code blocks"
},
"$:/language/ThemeTweaks/Settings": {
"title": "$:/language/ThemeTweaks/Settings",
"text": "Settings"
},
"$:/language/ThemeTweaks/Settings/FontFamily": {
"title": "$:/language/ThemeTweaks/Settings/FontFamily",
"text": "Font family"
},
"$:/language/ThemeTweaks/Settings/CodeFontFamily": {
"title": "$:/language/ThemeTweaks/Settings/CodeFontFamily",
"text": "Code font family"
},
"$:/language/ThemeTweaks/Settings/EditorFontFamily": {
"title": "$:/language/ThemeTweaks/Settings/EditorFontFamily",
"text": "Editor font family"
},
"$:/language/ThemeTweaks/Settings/BackgroundImage": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImage",
"text": "Page background image"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment",
"text": "Page background image attachment"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll",
"text": "Scroll with tiddlers"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed",
"text": "Fixed to window"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize",
"text": "Page background image size"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto",
"text": "Auto"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover",
"text": "Cover"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain",
"text": "Contain"
},
"$:/language/ThemeTweaks/Metrics": {
"title": "$:/language/ThemeTweaks/Metrics",
"text": "Sizes"
},
"$:/language/ThemeTweaks/Metrics/FontSize": {
"title": "$:/language/ThemeTweaks/Metrics/FontSize",
"text": "Font size"
},
"$:/language/ThemeTweaks/Metrics/LineHeight": {
"title": "$:/language/ThemeTweaks/Metrics/LineHeight",
"text": "Line height"
},
"$:/language/ThemeTweaks/Metrics/BodyFontSize": {
"title": "$:/language/ThemeTweaks/Metrics/BodyFontSize",
"text": "Font size for tiddler body"
},
"$:/language/ThemeTweaks/Metrics/BodyLineHeight": {
"title": "$:/language/ThemeTweaks/Metrics/BodyLineHeight",
"text": "Line height for tiddler body"
},
"$:/language/ThemeTweaks/Metrics/StoryLeft": {
"title": "$:/language/ThemeTweaks/Metrics/StoryLeft",
"text": "Story left position"
},
"$:/language/ThemeTweaks/Metrics/StoryLeft/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint",
"text": "how far the left margin of the story river<br>(tiddler area) is from the left of the page"
},
"$:/language/ThemeTweaks/Metrics/StoryTop": {
"title": "$:/language/ThemeTweaks/Metrics/StoryTop",
"text": "Story top position"
},
"$:/language/ThemeTweaks/Metrics/StoryTop/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryTop/Hint",
"text": "how far the top margin of the story river<br>is from the top of the page"
},
"$:/language/ThemeTweaks/Metrics/StoryRight": {
"title": "$:/language/ThemeTweaks/Metrics/StoryRight",
"text": "Story right"
},
"$:/language/ThemeTweaks/Metrics/StoryRight/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryRight/Hint",
"text": "how far the left margin of the sidebar <br>is from the left of the page"
},
"$:/language/ThemeTweaks/Metrics/StoryWidth": {
"title": "$:/language/ThemeTweaks/Metrics/StoryWidth",
"text": "Story width"
},
"$:/language/ThemeTweaks/Metrics/StoryWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint",
"text": "the overall width of the story river"
},
"$:/language/ThemeTweaks/Metrics/TiddlerWidth": {
"title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth",
"text": "Tiddler width"
},
"$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint",
"text": "within the story river"
},
"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint",
"text": "Sidebar breakpoint"
},
"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint",
"text": "the minimum page width at which the story<br>river and sidebar will appear side by side"
},
"$:/language/ThemeTweaks/Metrics/SidebarWidth": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarWidth",
"text": "Sidebar width"
},
"$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint",
"text": "the width of the sidebar in fluid-fixed layout"
},
"$:/language/TiddlerInfo/Advanced/Caption": {
"title": "$:/language/TiddlerInfo/Advanced/Caption",
"text": "Advanced"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint",
"text": "none"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Heading": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading",
"text": "Plugin Details"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint",
"text": "This plugin contains the following shadow tiddlers:"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading",
"text": "Shadow Status"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint",
"text": "The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is not a shadow tiddler"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint",
"text": "The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source",
"text": "It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint",
"text": "It is overridden by an ordinary tiddler"
},
"$:/language/TiddlerInfo/Fields/Caption": {
"title": "$:/language/TiddlerInfo/Fields/Caption",
"text": "Fields"
},
"$:/language/TiddlerInfo/List/Caption": {
"title": "$:/language/TiddlerInfo/List/Caption",
"text": "List"
},
"$:/language/TiddlerInfo/List/Empty": {
"title": "$:/language/TiddlerInfo/List/Empty",
"text": "This tiddler does not have a list"
},
"$:/language/TiddlerInfo/Listed/Caption": {
"title": "$:/language/TiddlerInfo/Listed/Caption",
"text": "Listed"
},
"$:/language/TiddlerInfo/Listed/Empty": {
"title": "$:/language/TiddlerInfo/Listed/Empty",
"text": "This tiddler is not listed by any others"
},
"$:/language/TiddlerInfo/References/Caption": {
"title": "$:/language/TiddlerInfo/References/Caption",
"text": "Backlinks"
},
"$:/language/TiddlerInfo/References/Empty": {
"title": "$:/language/TiddlerInfo/References/Empty",
"text": "No tiddlers link to this one"
},
"$:/language/TiddlerInfo/Tagging/Caption": {
"title": "$:/language/TiddlerInfo/Tagging/Caption",
"text": "Tagging"
},
"$:/language/TiddlerInfo/Tagging/Empty": {
"title": "$:/language/TiddlerInfo/Tagging/Empty",
"text": "No tiddlers are tagged with this one"
},
"$:/language/TiddlerInfo/Tools/Caption": {
"title": "$:/language/TiddlerInfo/Tools/Caption",
"text": "Tools"
},
"$:/language/Docs/Types/application/javascript": {
"title": "$:/language/Docs/Types/application/javascript",
"description": "JavaScript code",
"name": "application/javascript",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/application/json": {
"title": "$:/language/Docs/Types/application/json",
"description": "JSON data",
"name": "application/json",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/application/x-tiddler-dictionary": {
"title": "$:/language/Docs/Types/application/x-tiddler-dictionary",
"description": "Data dictionary",
"name": "application/x-tiddler-dictionary",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/image/gif": {
"title": "$:/language/Docs/Types/image/gif",
"description": "GIF image",
"name": "image/gif",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/jpeg": {
"title": "$:/language/Docs/Types/image/jpeg",
"description": "JPEG image",
"name": "image/jpeg",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/png": {
"title": "$:/language/Docs/Types/image/png",
"description": "PNG image",
"name": "image/png",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/svg+xml": {
"title": "$:/language/Docs/Types/image/svg+xml",
"description": "Structured Vector Graphics image",
"name": "image/svg+xml",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/x-icon": {
"title": "$:/language/Docs/Types/image/x-icon",
"description": "ICO format icon file",
"name": "image/x-icon",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/text/css": {
"title": "$:/language/Docs/Types/text/css",
"description": "Static stylesheet",
"name": "text/css",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/text/html": {
"title": "$:/language/Docs/Types/text/html",
"description": "HTML markup",
"name": "text/html",
"group": "Text",
"group-sort": "0"
},
"$:/language/Docs/Types/text/plain": {
"title": "$:/language/Docs/Types/text/plain",
"description": "Plain text",
"name": "text/plain",
"group": "Text",
"group-sort": "0"
},
"$:/language/Docs/Types/text/vnd.tiddlywiki": {
"title": "$:/language/Docs/Types/text/vnd.tiddlywiki",
"description": "TiddlyWiki 5",
"name": "text/vnd.tiddlywiki",
"group": "Text",
"group-sort": "0"
},
"$:/language/Docs/Types/text/x-tiddlywiki": {
"title": "$:/language/Docs/Types/text/x-tiddlywiki",
"description": "TiddlyWiki Classic",
"name": "text/x-tiddlywiki",
"group": "Text",
"group-sort": "0"
},
"$:/languages/en-GB/icon": {
"title": "$:/languages/en-GB/icon",
"type": "image/svg+xml",
"text": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 60 30\" width=\"1200\" height=\"600\">\n<clipPath id=\"t\">\n\t<path d=\"M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z\"/>\n</clipPath>\n<path d=\"M0,0 v30 h60 v-30 z\" fill=\"#00247d\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" stroke=\"#fff\" stroke-width=\"6\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" clip-path=\"url(#t)\" stroke=\"#cf142b\" stroke-width=\"4\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#fff\" stroke-width=\"10\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#cf142b\" stroke-width=\"6\"/>\n</svg>\n"
},
"$:/languages/en-GB": {
"title": "$:/languages/en-GB",
"name": "en-GB",
"description": "English (British)",
"author": "JeremyRuston",
"core-version": ">=5.0.0\"",
"text": "Stub pseudo-plugin for the default language"
},
"$:/core/modules/commander.js": {
"title": "$:/core/modules/commander.js",
"text": "/*\\\ntitle: $:/core/modules/commander.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Commander class is a command interpreter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a sequence of commands\n\tcommandTokens: an array of command string tokens\n\twiki: reference to the wiki store object\n\tstreams: {output:, error:}, each of which has a write(string) method\n\tcallback: a callback invoked as callback(err) where err is null if there was no error\n*/\nvar Commander = function(commandTokens,callback,wiki,streams) {\n\tvar path = require(\"path\");\n\tthis.commandTokens = commandTokens;\n\tthis.nextToken = 0;\n\tthis.callback = callback;\n\tthis.wiki = wiki;\n\tthis.streams = streams;\n\tthis.outputPath = path.resolve($tw.boot.wikiPath,$tw.config.wikiOutputSubDir);\n};\n\n/*\nLog a string if verbose flag is set\n*/\nCommander.prototype.log = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str + \"\\n\");\n\t}\n};\n\n/*\nWrite a string if verbose flag is set\n*/\nCommander.prototype.write = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str);\n\t}\n};\n\n/*\nAdd a string of tokens to the command queue\n*/\nCommander.prototype.addCommandTokens = function(commandTokens) {\n\tvar params = commandTokens.slice(0);\n\tparams.unshift(0);\n\tparams.unshift(this.nextToken);\n\tArray.prototype.splice.apply(this.commandTokens,params);\n};\n\n/*\nExecute the sequence of commands and invoke a callback on completion\n*/\nCommander.prototype.execute = function() {\n\tthis.executeNextCommand();\n};\n\n/*\nExecute the next command in the sequence\n*/\nCommander.prototype.executeNextCommand = function() {\n\tvar self = this;\n\t// Invoke the callback if there are no more commands\n\tif(this.nextToken >= this.commandTokens.length) {\n\t\tthis.callback(null);\n\t} else {\n\t\t// Get and check the command token\n\t\tvar commandName = this.commandTokens[this.nextToken++];\n\t\tif(commandName.substr(0,2) !== \"--\") {\n\t\t\tthis.callback(\"Missing command: \" + commandName);\n\t\t} else {\n\t\t\tcommandName = commandName.substr(2); // Trim off the --\n\t\t\t// Accumulate the parameters to the command\n\t\t\tvar params = [];\n\t\t\twhile(this.nextToken < this.commandTokens.length && \n\t\t\t\tthis.commandTokens[this.nextToken].substr(0,2) !== \"--\") {\n\t\t\t\tparams.push(this.commandTokens[this.nextToken++]);\n\t\t\t}\n\t\t\t// Get the command info\n\t\t\tvar command = $tw.commands[commandName],\n\t\t\t\tc,err;\n\t\t\tif(!command) {\n\t\t\t\tthis.callback(\"Unknown command: \" + commandName);\n\t\t\t} else {\n\t\t\t\tif(this.verbose) {\n\t\t\t\t\tthis.streams.output.write(\"Executing command: \" + commandName + \" \" + params.join(\" \") + \"\\n\");\n\t\t\t\t}\n\t\t\t\t// Parse named parameters if required\n\t\t\t\tif(command.info.namedParameterMode) {\n\t\t\t\t\tparams = this.extractNamedParameters(params,command.info.mandatoryParameters);\n\t\t\t\t\tif(typeof params === \"string\") {\n\t\t\t\t\t\treturn this.callback(params);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(command.info.synchronous) {\n\t\t\t\t\t// Synchronous command\n\t\t\t\t\tc = new command.Command(params,this);\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.executeNextCommand();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Asynchronous command\n\t\t\t\t\tc = new command.Command(params,this,function(err) {\n\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\tself.callback(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.executeNextCommand();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nGiven an array of parameter strings `params` in name:value format, and an array of mandatory parameter names in `mandatoryParameters`, returns a hashmap of values or a string if error\n*/\nCommander.prototype.extractNamedParameters = function(params,mandatoryParameters) {\n\tmandatoryParameters = mandatoryParameters || [];\n\tvar errors = [],\n\t\tparamsByName = Object.create(null);\n\t// Extract the parameters\n\t$tw.utils.each(params,function(param) {\n\t\tvar index = param.indexOf(\"=\");\n\t\tif(index < 1) {\n\t\t\terrors.push(\"malformed named parameter: '\" + param + \"'\");\n\t\t}\n\t\tparamsByName[param.slice(0,index)] = $tw.utils.trim(param.slice(index+1));\n\t});\n\t// Check the mandatory parameters are present\n\t$tw.utils.each(mandatoryParameters,function(mandatoryParameter) {\n\t\tif(!$tw.utils.hop(paramsByName,mandatoryParameter)) {\n\t\t\terrors.push(\"missing mandatory parameter: '\" + mandatoryParameter + \"'\");\n\t\t}\n\t});\n\t// Return any errors\n\tif(errors.length > 0) {\n\t\treturn errors.join(\" and\\n\");\n\t} else {\n\t\treturn paramsByName;\t\t\n\t}\n};\n\nCommander.initCommands = function(moduleType) {\n\tmoduleType = moduleType || \"command\";\n\t$tw.commands = {};\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tvar c = $tw.commands[module.info.name] = {};\n\t\t// Add the methods defined by the module\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\tc[f] = module[f];\n\t\t\t}\n\t\t}\n\t});\n};\n\nexports.Commander = Commander;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/commands/build.js": {
"title": "$:/core/modules/commands/build.js",
"text": "/*\\\ntitle: $:/core/modules/commands/build.js\ntype: application/javascript\nmodule-type: command\n\nCommand to build a build target\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"build\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\t// Get the build targets defined in the wiki\n\tvar buildTargets = $tw.boot.wikiInfo.build;\n\tif(!buildTargets) {\n\t\treturn \"No build targets defined\";\n\t}\n\t// Loop through each of the specified targets\n\tvar targets;\n\tif(this.params.length > 0) {\n\t\ttargets = this.params;\n\t} else {\n\t\ttargets = Object.keys(buildTargets);\n\t}\n\tfor(var targetIndex=0; targetIndex<targets.length; targetIndex++) {\n\t\tvar target = targets[targetIndex],\n\t\t\tcommands = buildTargets[target];\n\t\tif(!commands) {\n\t\t\treturn \"Build target '\" + target + \"' not found\";\n\t\t}\n\t\t// Add the commands to the queue\n\t\tthis.commander.addCommandTokens(commands);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/clearpassword.js": {
"title": "$:/core/modules/commands/clearpassword.js",
"text": "/*\\\ntitle: $:/core/modules/commands/clearpassword.js\ntype: application/javascript\nmodule-type: command\n\nClear password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"clearpassword\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\t$tw.crypto.setPassword(null);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/deletetiddlers.js": {
"title": "$:/core/modules/commands/deletetiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/deletetiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to delete tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"deletetiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filter\";\n\t}\n\tvar self = this,\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\twiki.deleteTiddler(title);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/editions.js": {
"title": "$:/core/modules/commands/editions.js",
"text": "/*\\\ntitle: $:/core/modules/commands/editions.js\ntype: application/javascript\nmodule-type: command\n\nCommand to list the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"editions\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\t// Output the list\n\tthis.commander.streams.output.write(\"Available editions:\\n\\n\");\n\tvar editionInfo = $tw.utils.getEditionInfo();\n\t$tw.utils.each(editionInfo,function(info,name) {\n\t\tself.commander.streams.output.write(\" \" + name + \": \" + info.description + \"\\n\");\n\t});\n\tthis.commander.streams.output.write(\"\\n\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/fetch.js": {
"title": "$:/core/modules/commands/fetch.js",
"text": "/*\\\ntitle: $:/core/modules/commands/fetch.js\ntype: application/javascript\nmodule-type: command\n\nCommands to fetch external tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"fetch\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing subcommand and url\";\n\t}\n\tswitch(this.params[0]) {\n\t\tcase \"raw-file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turl: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turl: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"raw-files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t}\n\treturn null;\n};\n\nCommand.prototype.fetchFiles = function(options) {\n\tvar self = this;\n\t// Get the list of URLs\n\tvar urls;\n\tif(options.url) {\n\t\turls = [options.url]\n\t} else if(options.urlFilter) {\n\t\turls = this.commander.wiki.filterTiddlers(options.urlFilter);\n\t} else {\n\t\treturn \"Missing URL\";\n\t}\n\t// Process each URL in turn\n\tvar next = 0;\n\tvar getNextFile = function(err) {\n\t\tif(err) {\n\t\t\treturn options.callback(err);\n\t\t}\n\t\tif(next < urls.length) {\n\t\t\tself.fetchFile(urls[next++],options,getNextFile);\n\t\t} else {\n\t\t\toptions.callback(null);\n\t\t}\n\t};\n\tgetNextFile(null);\n\t// Success\n\treturn null;\n};\n\nCommand.prototype.fetchFile = function(url,options,callback,redirectCount) {\n\tif(redirectCount > 10) {\n\t\treturn callback(\"Error too many redirects retrieving \" + url);\n\t}\n\tvar self = this,\n\t\tlib = url.substr(0,8) === \"https://\" ? require(\"https\") : require(\"http\");\n\tlib.get(url).on(\"response\",function(response) {\n\t var type = (response.headers[\"content-type\"] || \"\").split(\";\")[0],\n\t \tdata = [];\n\t self.commander.write(\"Reading \" + url + \": \");\n\t response.on(\"data\",function(chunk) {\n\t data.push(chunk);\n\t self.commander.write(\".\");\n\t });\n\t response.on(\"end\",function() {\n\t self.commander.write(\"\\n\");\n\t if(response.statusCode === 200) {\n\t\t self.processBody(Buffer.concat(data),type,options,url);\n\t\t callback(null);\n\t } else {\n\t \tif(response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {\n\t \t\treturn self.fetchFile(response.headers.location,options,callback,redirectCount + 1);\n\t \t} else {\n\t\t \treturn callback(\"Error \" + response.statusCode + \" retrieving \" + url)\t \t\t\n\t \t}\n\t }\n\t \t});\n\t \tresponse.on(\"error\",function(e) {\n\t\t\tconsole.log(\"Error on GET request: \" + e);\n\t\t\tcallback(e);\n\t \t});\n\t});\n\treturn null;\n};\n\nCommand.prototype.processBody = function(body,type,options,url) {\n\tvar self = this;\n\t// Collect the tiddlers in a wiki\n\tvar incomingWiki = new $tw.Wiki();\n\tif(options.raw) {\n\t\tvar typeInfo = type ? $tw.config.contentTypeInfo[type] : null,\n\t\t\tencoding = typeInfo ? typeInfo.encoding : \"utf8\";\n\t\tincomingWiki.addTiddler(new $tw.Tiddler({\n\t\t\ttitle: url,\n\t\t\ttype: type,\n\t\t\ttext: body.toString(encoding)\n\t\t}));\n\t} else {\n\t\t// Deserialise the file to extract the tiddlers\n\t\tvar tiddlers = this.commander.wiki.deserializeTiddlers(type || \"text/html\",body.toString(\"utf8\"),{});\n\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\tincomingWiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t});\n\t}\n\t// Filter the tiddlers to select the ones we want\n\tvar filteredTitles = incomingWiki.filterTiddlers(options.importFilter || \"[all[tiddlers]]\");\n\t// Import the selected tiddlers\n\tvar count = 0;\n\tincomingWiki.each(function(tiddler,title) {\n\t\tif(filteredTitles.indexOf(title) !== -1) {\n\t\t\tvar newTiddler;\n\t\t\tif(options.transformFilter) {\n\t\t\t\tvar transformedTitle = (incomingWiki.filterTiddlers(options.transformFilter,null,self.commander.wiki.makeTiddlerIterator([title])) || [\"\"])[0];\n\t\t\t\tif(transformedTitle) {\n\t\t\t\t\tself.commander.log(\"Importing \" + title + \" as \" + transformedTitle)\n\t\t\t\t\tnewTiddler = new $tw.Tiddler(tiddler,{title: transformedTitle});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.commander.log(\"Importing \" + title)\n\t\t\t\tnewTiddler = tiddler;\n\t\t\t}\n\t\t\tself.commander.wiki.importTiddler(newTiddler);\n\t\t\tcount++;\n\t\t}\n\t});\n\tself.commander.log(\"Imported \" + count + \" tiddlers\")\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/help.js": {
"title": "$:/core/modules/commands/help.js",
"text": "/*\\\ntitle: $:/core/modules/commands/help.js\ntype: application/javascript\nmodule-type: command\n\nHelp command\n\n\\*/\n(function(){\n\n/*jshint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"help\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar subhelp = this.params[0] || \"default\",\n\t\thelpBase = \"$:/language/Help/\",\n\t\ttext;\n\tif(!this.commander.wiki.getTiddler(helpBase + subhelp)) {\n\t\tsubhelp = \"notfound\";\n\t}\n\t// Wikify the help as formatted text (ie block elements generate newlines)\n\ttext = this.commander.wiki.renderTiddler(\"text/plain-formatted\",helpBase + subhelp);\n\t// Remove any leading linebreaks\n\ttext = text.replace(/^(\\r?\\n)*/g,\"\");\n\tthis.commander.streams.output.write(text);\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/import.js": {
"title": "$:/core/modules/commands/import.js",
"text": "/*\\\ntitle: $:/core/modules/commands/import.js\ntype: application/javascript\nmodule-type: command\n\nCommand to import tiddlers from a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"import\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 2) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar filename = self.params[0],\n\t\tdeserializer = self.params[1],\n\t\ttitle = self.params[2] || filename,\n\t\tencoding = self.params[3] || \"utf8\",\n\t\ttext = fs.readFileSync(filename,encoding),\n\t\ttiddlers = this.commander.wiki.deserializeTiddlers(null,text,{title: title},{deserializer: deserializer});\n\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t});\n\tthis.commander.log(tiddlers.length + \" tiddler(s) imported\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/init.js": {
"title": "$:/core/modules/commands/init.js",
"text": "/*\\\ntitle: $:/core/modules/commands/init.js\ntype: application/javascript\nmodule-type: command\n\nCommand to initialise an empty wiki folder\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"init\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\t// Check that we don't already have a valid wiki folder\n\tif($tw.boot.wikiTiddlersPath || ($tw.utils.isDirectory($tw.boot.wikiPath) && !$tw.utils.isDirectoryEmpty($tw.boot.wikiPath))) {\n\t\treturn \"Wiki folder is not empty\";\n\t}\n\t// Loop through each of the specified editions\n\tvar editions = this.params.length > 0 ? this.params : [\"empty\"];\n\tfor(var editionIndex=0; editionIndex<editions.length; editionIndex++) {\n\t\tvar editionName = editions[editionIndex];\n\t\t// Check the edition exists\n\t\tvar editionPath = $tw.findLibraryItem(editionName,$tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar));\n\t\tif(!$tw.utils.isDirectory(editionPath)) {\n\t\t\treturn \"Edition '\" + editionName + \"' not found\";\n\t\t}\n\t\t// Copy the edition content\n\t\tvar err = $tw.utils.copyDirectory(editionPath,$tw.boot.wikiPath);\n\t\tif(!err) {\n\t\t\tthis.commander.streams.output.write(\"Copied edition '\" + editionName + \"' to \" + $tw.boot.wikiPath + \"\\n\");\n\t\t} else {\n\t\t\treturn err;\n\t\t}\n\t}\n\t// Tweak the tiddlywiki.info to remove any included wikis\n\tvar packagePath = $tw.boot.wikiPath + \"/tiddlywiki.info\",\n\t\tpackageJson = JSON.parse(fs.readFileSync(packagePath));\n\tdelete packageJson.includeWikis;\n\tfs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/listen.js": {
"title": "$:/core/modules/commands/listen.js",
"text": "/*\\\ntitle: $:/core/modules/commands/listen.js\ntype: application/javascript\nmodule-type: command\n\nListen for HTTP requests and serve tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"listen\",\n\tsynchronous: true,\n\tnamedParameterMode: true,\n\tmandatoryParameters: [],\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: self.params\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/load.js": {
"title": "$:/core/modules/commands/load.js",
"text": "/*\\\ntitle: $:/core/modules/commands/load.js\ntype: application/javascript\nmodule-type: command\n\nCommand to load tiddlers from a file or directory\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"load\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar tiddlers = $tw.loadTiddlersFromPath(self.params[0]),\n\t\tcount = 0;\n\t$tw.utils.each(tiddlers,function(tiddlerInfo) {\n\t\t$tw.utils.each(tiddlerInfo.tiddlers,function(tiddler) {\n\t\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t\t\tcount++;\n\t\t});\n\t});\n\tif(!count && self.params[1] !== \"noerror\") {\n\t\tself.callback(\"No tiddlers found in file \\\"\" + self.params[0] + \"\\\"\");\n\t} else {\n\t\tself.callback(null);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/makelibrary.js": {
"title": "$:/core/modules/commands/makelibrary.js",
"text": "/*\\\ntitle: $:/core/modules/commands/makelibrary.js\ntype: application/javascript\nmodule-type: command\n\nCommand to pack all of the plugins in the library into a plugin tiddler of type \"library\"\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"makelibrary\",\n\tsynchronous: true\n};\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar wiki = this.commander.wiki,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tupgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,\n\t\ttiddlers = {};\n\t// Collect up the library plugins\n\tvar collectPlugins = function(folder) {\n\t\t\tvar pluginFolders = $tw.utils.getSubdirectories(folder) || [];\n\t\t\tfor(var p=0; p<pluginFolders.length; p++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {\n\t\t\t\t\tpluginFields = $tw.loadPluginFolder(path.resolve(folder,\"./\" + pluginFolders[p]));\n\t\t\t\t\tif(pluginFields && pluginFields.title) {\n\t\t\t\t\t\ttiddlers[pluginFields.title] = pluginFields;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tcollectPublisherPlugins = function(folder) {\n\t\t\tvar publisherFolders = $tw.utils.getSubdirectories(folder) || [];\n\t\t\tfor(var t=0; t<publisherFolders.length; t++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {\n\t\t\t\t\tcollectPlugins(path.resolve(folder,\"./\" + publisherFolders[t]));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,$tw.config.pluginsEnvVar),collectPublisherPlugins);\n\t$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,$tw.config.themesEnvVar),collectPublisherPlugins);\n\t$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,$tw.config.languagesEnvVar),collectPlugins);\n\t// Save the upgrade library tiddler\n\tvar pluginFields = {\n\t\ttitle: upgradeLibraryTitle,\n\t\ttype: \"application/json\",\n\t\t\"plugin-type\": \"library\",\n\t\t\"text\": JSON.stringify({tiddlers: tiddlers})\n\t};\n\twiki.addTiddler(new $tw.Tiddler(pluginFields));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/output.js": {
"title": "$:/core/modules/commands/output.js",
"text": "/*\\\ntitle: $:/core/modules/commands/output.js\ntype: application/javascript\nmodule-type: command\n\nCommand to set the default output location (defaults to current working directory)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"output\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing output path\";\n\t}\n\tthis.commander.outputPath = path.resolve(process.cwd(),this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/password.js": {
"title": "$:/core/modules/commands/password.js",
"text": "/*\\\ntitle: $:/core/modules/commands/password.js\ntype: application/javascript\nmodule-type: command\n\nSave password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"password\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing password\";\n\t}\n\t$tw.crypto.setPassword(this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/render.js": {
"title": "$:/core/modules/commands/render.js",
"text": "/*\\\ntitle: $:/core/modules/commands/render.js\ntype: application/javascript\nmodule-type: command\n\nRender individual tiddlers and save the results to the specified files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"render\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing tiddler filter\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\ttiddlerFilter = this.params[0],\n\t\tfilenameFilter = this.params[1] || \"[is[tiddler]addsuffix[.html]]\",\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tvarName = this.params[4],\n\t\tvarValue = this.params[5],\n\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template || title),\n\t\t\tvariables = {currentTiddler: title};\n\t\tif(varName) {\n\t\t\tvariables[varName] = varValue || \"\";\n\t\t}\n\t\tvar widgetNode = wiki.makeWidget(parser,{variables: variables}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\tfilepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);\n\t\tif(self.commander.verbose) {\n\t\t\tconsole.log(\"Rendering \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t}\n\t\t$tw.utils.createFileDirectories(filepath);\n\t\tfs.writeFileSync(filepath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/rendertiddler.js": {
"title": "$:/core/modules/commands/rendertiddler.js",
"text": "/*\\\ntitle: $:/core/modules/commands/rendertiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render a tiddler and save it to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"rendertiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tname = this.params[4],\n\t\tvalue = this.params[5],\n\t\tvariables = {};\n\t$tw.utils.createFileDirectories(filename);\n\tif(template) {\n\t\tvariables.currentTiddler = title;\n\t\ttitle = template;\n\t}\n\tif(name && value) {\n\t\tvariables[name] = value;\n\t}\n\tfs.writeFile(filename,this.commander.wiki.renderTiddler(type,title,{variables: variables}),\"utf8\",function(err) {\n\t\tself.callback(err);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/rendertiddlers.js": {
"title": "$:/core/modules/commands/rendertiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/rendertiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"rendertiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\ttemplate = this.params[1],\n\t\toutputPath = this.commander.outputPath,\n\t\tpathname = path.resolve(outputPath,this.params[2]),\t\t\n\t\ttype = this.params[3] || \"text/html\",\n\t\textension = this.params[4] || \".html\",\n\t\tdeleteDirectory = (this.params[5] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template),\n\t\t\twidgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\texportPath = null;\n\t\tif($tw.utils.hop($tw.macros,\"tv-get-export-path\")) {\n\t\t\tvar macroPath = $tw.macros[\"tv-get-export-path\"].run.apply(self,[title]);\n\t\t\tif(macroPath) {\n\t\t\t\texportPath = path.resolve(outputPath,macroPath + extension);\n\t\t\t}\n\t\t}\n\t\tvar finalPath = exportPath || path.resolve(pathname,encodeURIComponent(title) + extension);\n\t\t$tw.utils.createFileDirectories(finalPath);\n\t\tfs.writeFileSync(finalPath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/save.js": {
"title": "$:/core/modules/commands/save.js",
"text": "/*\\\ntitle: $:/core/modules/commands/save.js\ntype: application/javascript\nmodule-type: command\n\nSaves individual tiddlers in their raw text or binary format to the specified files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"save\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename filter\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\ttiddlerFilter = this.params[0],\n\t\tfilenameFilter = this.params[1] || \"[is[tiddler]]\",\n\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);\n\t\tif(self.commander.verbose) {\n\t\t\tconsole.log(\"Saving \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t}\n\t\t$tw.utils.createFileDirectories(filepath);\n\t\tfs.writeFileSync(filepath,tiddler.fields.text,contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savelibrarytiddlers.js": {
"title": "$:/core/modules/commands/savelibrarytiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savelibrarytiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the subtiddlers of a bundle tiddler as a series of JSON files\n\n--savelibrarytiddlers <tiddler> <tiddler-filter> <pathname> <skinnylisting>\n\nThe tiddler identifies the bundle tiddler that contains the subtiddlers.\n\nThe tiddler filter specifies the plugins to be included.\n\nThe pathname specifies the pathname to the folder in which the JSON files should be saved. The filename is the URL encoded title of the subtiddler.\n\nThe skinnylisting specifies the title of the tiddler to which a JSON catalogue of the subtiddlers will be saved. The JSON file contains the same data as the bundle tiddler but with the `text` field removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savelibrarytiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tcontainerTitle = this.params[0],\n\t\tfilter = this.params[1],\n\t\tbasepath = this.params[2],\n\t\tskinnyListTitle = this.params[3];\n\t// Get the container tiddler as data\n\tvar containerData = self.commander.wiki.getTiddlerDataCached(containerTitle,undefined);\n\tif(!containerData) {\n\t\treturn \"'\" + containerTitle + \"' is not a tiddler bundle\";\n\t}\n\t// Filter the list of plugins\n\tvar pluginList = [];\n\t$tw.utils.each(containerData.tiddlers,function(tiddler,title) {\n\t\tpluginList.push(title);\n\t});\n\tvar filteredPluginList;\n\tif(filter) {\n\t\tfilteredPluginList = self.commander.wiki.filterTiddlers(filter,null,self.commander.wiki.makeTiddlerIterator(pluginList));\n\t} else {\n\t\tfilteredPluginList = pluginList;\n\t}\n\t// Iterate through the plugins\n\tvar skinnyList = [];\n\t$tw.utils.each(filteredPluginList,function(title) {\n\t\tvar tiddler = containerData.tiddlers[title];\n\t\t// Save each JSON file and collect the skinny data\n\t\tvar pathname = path.resolve(self.commander.outputPath,basepath + encodeURIComponent(title) + \".json\");\n\t\t$tw.utils.createFileDirectories(pathname);\n\t\tfs.writeFileSync(pathname,JSON.stringify(tiddler),\"utf8\");\n\t\t// Collect the skinny list data\n\t\tvar pluginTiddlers = JSON.parse(tiddler.text),\n\t\t\treadmeContent = (pluginTiddlers.tiddlers[title + \"/readme\"] || {}).text,\n\t\t\tdoesRequireReload = !!self.commander.wiki.doesPluginInfoRequireReload(pluginTiddlers),\n\t\t\ticonTiddler = pluginTiddlers.tiddlers[title + \"/icon\"] || {},\n\t\t\ticonType = iconTiddler.type,\n\t\t\ticonText = iconTiddler.text,\n\t\t\ticonContent;\n\t\tif(iconType && iconText) {\n\t\t\ticonContent = $tw.utils.makeDataUri(iconText,iconType);\n\t\t}\n\t\tskinnyList.push($tw.utils.extend({},tiddler,{\n\t\t\ttext: undefined,\n\t\t\treadme: readmeContent,\n\t\t\t\"requires-reload\": doesRequireReload ? \"yes\" : \"no\",\n\t\t\ticon: iconContent\n\t\t}));\n\t});\n\t// Save the catalogue tiddler\n\tif(skinnyListTitle) {\n\t\tself.commander.wiki.setTiddlerData(skinnyListTitle,skinnyList);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savetiddler.js": {
"title": "$:/core/modules/commands/savetiddler.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savetiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the content of a tiddler to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savetiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttiddler = this.commander.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar type = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"};\n\t\t$tw.utils.createFileDirectories(filename);\n\t\tfs.writeFile(filename,tiddler.fields.text,contentTypeInfo.encoding,function(err) {\n\t\t\tself.callback(err);\n\t\t});\n\t} else {\n\t\treturn \"Missing tiddler: \" + title;\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savetiddlers.js": {
"title": "$:/core/modules/commands/savetiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savetiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"savetiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tpathname = path.resolve(this.commander.outputPath,this.params[1]),\n\t\tdeleteDirectory = (this.params[2] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.createDirectory(pathname);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilename = path.resolve(pathname,encodeURIComponent(title));\n\t\tfs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savewikifolder.js": {
"title": "$:/core/modules/commands/savewikifolder.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savewikifolder.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the current wiki as a wiki folder\n\n--savewikifolder <wikifolderpath> [<filter>]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savewikifolder\",\n\tsynchronous: true\n};\n\nvar fs,path;\nif($tw.node) {\n\tfs = require(\"fs\");\n\tpath = require(\"path\");\n}\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing wiki folder path\";\n\t}\n\tvar wikifoldermaker = new WikiFolderMaker(this.params[0],this.params[1],this.commander);\n\treturn wikifoldermaker.save();\n};\n\nfunction WikiFolderMaker(wikiFolderPath,wikiFilter,commander) {\n\tthis.wikiFolderPath = wikiFolderPath;\n\tthis.wikiFilter = wikiFilter || \"[all[tiddlers]]\";\n\tthis.commander = commander;\n\tthis.wiki = commander.wiki;\n\tthis.savedPaths = []; // So that we can detect filename clashes\n}\n\nWikiFolderMaker.prototype.log = function(str) {\n\tif(this.commander.verbose) {\n\t\tconsole.log(str);\n\t}\n};\n\nWikiFolderMaker.prototype.tiddlersToIgnore = [\n\t\"$:/boot/boot.css\",\n\t\"$:/boot/boot.js\",\n\t\"$:/boot/bootprefix.js\",\n\t\"$:/core\",\n\t\"$:/library/sjcl.js\",\n\t\"$:/temp/info-plugin\"\n];\n\n/*\nReturns null if successful, or an error string if there was an error\n*/\nWikiFolderMaker.prototype.save = function() {\n\tvar self = this;\n\t// Check that the output directory doesn't exist\n\tif(fs.existsSync(this.wikiFolderPath) && !$tw.utils.isDirectoryEmpty(this.wikiFolderPath)) {\n\t\treturn \"The unpackwiki command requires that the output wiki folder be empty\";\n\t}\n\t// Get the tiddlers from the source wiki\n\tvar tiddlerTitles = this.wiki.filterTiddlers(this.wikiFilter);\n\t// Initialise a new tiddlwiki.info file\n\tvar newWikiInfo = {};\n\t// Process each incoming tiddler in turn\n\t$tw.utils.each(tiddlerTitles,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tif(self.tiddlersToIgnore.indexOf(title) !== -1) {\n\t\t\t\t// Ignore the core plugin and the ephemeral info plugin\n\t\t\t\tself.log(\"Ignoring tiddler: \" + title);\n\t\t\t} else {\n\t\t\t\tvar type = tiddler.fields.type,\n\t\t\t\t\tpluginType = tiddler.fields[\"plugin-type\"];\n\t\t\t\tif(type === \"application/json\" && pluginType) {\n\t\t\t\t\t// Plugin tiddler\n\t\t\t\t\tvar libraryDetails = self.findPluginInLibrary(title);\n\t\t\t\t\tif(libraryDetails) {\n\t\t\t\t\t\t// A plugin from the core library\n\t\t\t\t\t\tself.log(\"Adding built-in plugin: \" + libraryDetails.name);\n\t\t\t\t\t\tnewWikiInfo[libraryDetails.type] = newWikiInfo[libraryDetails.type] || [];\n\t\t\t\t\t\t$tw.utils.pushTop(newWikiInfo[libraryDetails.type],libraryDetails.name);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// A custom plugin\n\t\t\t\t\t\tself.log(\"Processing custom plugin: \" + title);\n\t\t\t\t\t\tself.saveCustomPlugin(tiddler);\n\t\t\t\t\t}\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\t// Ordinary tiddler\n\t\t\t\t\tself.saveTiddler(\"tiddlers\",tiddler);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t// Save the tiddlywiki.info file\n\tthis.saveJSONFile(\"tiddlywiki.info\",newWikiInfo);\n\tself.log(\"Writing tiddlywiki.info: \" + JSON.stringify(newWikiInfo,null,$tw.config.preferences.jsonSpaces));\n\treturn null;\n};\n\n/*\nTest whether the specified tiddler is a plugin in the plugin library\n*/\nWikiFolderMaker.prototype.findPluginInLibrary = function(title) {\n\tvar parts = title.split(\"/\"),\n\t\tpluginPath, type, name;\n\tif(parts[0] === \"$:\") {\n\t\tif(parts[1] === \"languages\" && parts.length === 3) {\n\t\t\tpluginPath = \"languages\" + path.sep + parts[2];\n\t\t\ttype = parts[1];\n\t\t\tname = parts[2];\n\t\t} else if(parts[1] === \"plugins\" || parts[1] === \"themes\" && parts.length === 4) {\n\t\t\tpluginPath = parts[1] + path.sep + parts[2] + path.sep + parts[3];\n\t\t\ttype = parts[1];\n\t\t\tname = parts[2] + \"/\" + parts[3];\n\t\t}\n\t}\n\tif(pluginPath && type && name) {\n\t\tpluginPath = path.resolve($tw.boot.bootPath,\"..\",pluginPath);\n\t\tif(fs.existsSync(pluginPath)) {\n\t\t\treturn {\n\t\t\t\tpluginPath: pluginPath,\n\t\t\t\ttype: type,\n\t\t\t\tname: name\n\t\t\t};\n\t\t}\n\t}\n\treturn false;\n};\n\nWikiFolderMaker.prototype.saveCustomPlugin = function(pluginTiddler) {\n\tvar self = this,\n\t\tpluginTitle = pluginTiddler.fields.title,\n\t\ttitleParts = pluginTitle.split(\"/\"),\n\t\tdirectory = $tw.utils.generateTiddlerFilepath(titleParts[titleParts.length - 1],{\n\t\t\tdirectory: path.resolve(this.wikiFolderPath,pluginTiddler.fields[\"plugin-type\"] + \"s\")\n\t\t}),\n\t\tpluginInfo = pluginTiddler.getFieldStrings({exclude: [\"text\",\"type\"]});\n\tthis.saveJSONFile(directory + path.sep + \"plugin.info\",pluginInfo);\n\tself.log(\"Writing \" + directory + path.sep + \"plugin.info: \" + JSON.stringify(pluginInfo,null,$tw.config.preferences.jsonSpaces));\n\tvar pluginTiddlers = JSON.parse(pluginTiddler.fields.text).tiddlers; // A hashmap of tiddlers in the plugin\n\t$tw.utils.each(pluginTiddlers,function(tiddler) {\n\t\tself.saveTiddler(directory,new $tw.Tiddler(tiddler));\n\t});\n};\n\nWikiFolderMaker.prototype.saveTiddler = function(directory,tiddler) {\n\tvar fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{\n\t\tdirectory: path.resolve(this.wikiFolderPath,directory),\n\t\twiki: this.wiki\n\t});\n\t$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);\n};\n\nWikiFolderMaker.prototype.saveJSONFile = function(filename,json) {\n\tthis.saveTextFile(filename,JSON.stringify(json,null,$tw.config.preferences.jsonSpaces));\n};\n\nWikiFolderMaker.prototype.saveTextFile = function(filename,data) {\n\tthis.saveFile(filename,\"utf8\",data);\n};\n\nWikiFolderMaker.prototype.saveFile = function(filename,encoding,data) {\n\tvar filepath = path.resolve(this.wikiFolderPath,filename);\n\t$tw.utils.createFileDirectories(filepath);\n\tfs.writeFileSync(filepath,data,encoding);\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/server.js": {
"title": "$:/core/modules/commands/server.js",
"text": "/*\\\ntitle: $:/core/modules/commands/server.js\ntype: application/javascript\nmodule-type: command\n\nDeprecated legacy command for serving tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"server\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: {\n\t\t\tport: this.params[0],\n\t\t\thost: this.params[6],\n\t\t\t\"root-tiddler\": this.params[1],\n\t\t\t\"root-render-type\": this.params[2],\n\t\t\t\"root-serve-type\": this.params[3],\n\t\t\tusername: this.params[4],\n\t\t\tpassword: this.params[5],\n\t\t\t\"path-prefix\": this.params[7],\n\t\t\t\"debug-level\": this.params[8]\n\t\t}\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/setfield.js": {
"title": "$:/core/modules/commands/setfield.js",
"text": "/*\\\ntitle: $:/core/modules/commands/setfield.js\ntype: application/javascript\nmodule-type: command\n\nCommand to modify selected tiddlers to set a field to the text of a template tiddler that has been wikified with the selected tiddler as the current tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"setfield\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 4) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar self = this,\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tfieldname = this.params[1] || \"text\",\n\t\ttemplatetitle = this.params[2],\n\t\trendertype = this.params[3] || \"text/plain\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(templatetitle),\n\t\t\tnewFields = {},\n\t\t\ttiddler = wiki.getTiddler(title);\n\t\tif(parser) {\n\t\t\tvar widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}});\n\t\t\tvar container = $tw.fakeDocument.createElement(\"div\");\n\t\t\twidgetNode.render(container,null);\n\t\t\tnewFields[fieldname] = rendertype === \"text/html\" ? container.innerHTML : container.textContent;\n\t\t} else {\n\t\t\tnewFields[fieldname] = undefined;\n\t\t}\n\t\twiki.addTiddler(new $tw.Tiddler(tiddler,newFields));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/unpackplugin.js": {
"title": "$:/core/modules/commands/unpackplugin.js",
"text": "/*\\\ntitle: $:/core/modules/commands/unpackplugin.js\ntype: application/javascript\nmodule-type: command\n\nCommand to extract the shadow tiddlers from within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"unpackplugin\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing plugin name\";\n\t}\n\tvar self = this,\n\t\ttitle = this.params[0],\n\t\tpluginData = this.commander.wiki.getTiddlerDataCached(title);\n\tif(!pluginData) {\n\t\treturn \"Plugin '\" + title + \"' not found\";\n\t}\n\t$tw.utils.each(pluginData.tiddlers,function(tiddler) {\n\t\tself.commander.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/verbose.js": {
"title": "$:/core/modules/commands/verbose.js",
"text": "/*\\\ntitle: $:/core/modules/commands/verbose.js\ntype: application/javascript\nmodule-type: command\n\nVerbose command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"verbose\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.verbose = true;\n\t// Output the boot message log\n\tthis.commander.streams.output.write(\"Boot log:\\n \" + $tw.boot.logMessages.join(\"\\n \") + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/version.js": {
"title": "$:/core/modules/commands/version.js",
"text": "/*\\\ntitle: $:/core/modules/commands/version.js\ntype: application/javascript\nmodule-type: command\n\nVersion command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"version\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.streams.output.write($tw.version + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/config.js": {
"title": "$:/core/modules/config.js",
"text": "/*\\\ntitle: $:/core/modules/config.js\ntype: application/javascript\nmodule-type: config\n\nCore configuration constants\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.preferences = {};\n\nexports.preferences.notificationDuration = 3 * 1000;\nexports.preferences.jsonSpaces = 4;\n\nexports.textPrimitives = {\n\tupperLetter: \"[A-Z\\u00c0-\\u00d6\\u00d8-\\u00de\\u0150\\u0170]\",\n\tlowerLetter: \"[a-z\\u00df-\\u00f6\\u00f8-\\u00ff\\u0151\\u0171]\",\n\tanyLetter: \"[A-Za-z0-9\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\",\n\tblockPrefixLetters:\t\"[A-Za-z0-9-_\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\"\n};\n\nexports.textPrimitives.unWikiLink = \"~\";\nexports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + \"+\" +\n\texports.textPrimitives.lowerLetter + \"+\" +\n\texports.textPrimitives.upperLetter +\n\texports.textPrimitives.anyLetter + \"*\";\n\nexports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };\n\nexports.htmlVoidElements = \"area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr\".split(\",\");\n\nexports.htmlBlockElements = \"address,article,aside,audio,blockquote,canvas,dd,div,dl,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,noscript,ol,output,p,pre,section,table,tfoot,ul,video\".split(\",\");\n\nexports.htmlUnsafeElements = \"script\".split(\",\");\n\n})();\n",
"type": "application/javascript",
"module-type": "config"
},
"$:/core/modules/deserializers.js": {
"title": "$:/core/modules/deserializers.js",
"text": "/*\\\ntitle: $:/core/modules/deserializers.js\ntype: application/javascript\nmodule-type: tiddlerdeserializer\n\nFunctions to deserialise tiddlers from a block of text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nUtility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:\n\n<div title=\"Title\" creator=\"JoeBloggs\" modifier=\"JoeBloggs\" created=\"201102111106\" modified=\"201102111310\" tags=\"myTag [[my long tag]]\">\n<pre>The text of the tiddler (without the expected HTML encoding).\n</pre>\n</div>\n\nNote that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.\n\nWhen these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.\n*/\nvar parseTiddlerDiv = function(text /* [,fields] */) {\n\t// Slot together the default results\n\tvar result = {};\n\tif(arguments.length > 1) {\n\t\tfor(var f=1; f<arguments.length; f++) {\n\t\t\tvar fields = arguments[f];\n\t\t\tfor(var t in fields) {\n\t\t\t\tresult[t] = fields[t];\t\t\n\t\t\t}\n\t\t}\n\t}\n\t// Parse the DIV body\n\tvar startRegExp = /^\\s*<div\\s+([^>]*)>(\\s*<pre>)?/gi,\n\t\tendRegExp,\n\t\tmatch = startRegExp.exec(text);\n\tif(match) {\n\t\t// Old-style DIVs don't have the <pre> tag\n\t\tif(match[2]) {\n\t\t\tendRegExp = /<\\/pre>\\s*<\\/div>\\s*$/gi;\n\t\t} else {\n\t\t\tendRegExp = /<\\/div>\\s*$/gi;\n\t\t}\n\t\tvar endMatch = endRegExp.exec(text);\n\t\tif(endMatch) {\n\t\t\t// Extract the text\n\t\t\tresult.text = text.substring(match.index + match[0].length,endMatch.index);\n\t\t\t// Process the attributes\n\t\t\tvar attrRegExp = /\\s*([^=\\s]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/gi,\n\t\t\t\tattrMatch;\n\t\t\tdo {\n\t\t\t\tattrMatch = attrRegExp.exec(match[1]);\n\t\t\t\tif(attrMatch) {\n\t\t\t\t\tvar name = attrMatch[1];\n\t\t\t\t\tvar value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];\n\t\t\t\t\tresult[name] = value;\n\t\t\t\t}\n\t\t\t} while(attrMatch);\n\t\t\treturn result;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports[\"application/x-tiddler-html-div\"] = function(text,fields) {\n\treturn [parseTiddlerDiv(text,fields)];\n};\n\nexports[\"application/json\"] = function(text,fields) {\n\tvar incoming,\n\t\tresults = [];\n\ttry {\n\t\tincoming = JSON.parse(text);\n\t} catch(e) {\n\t\tincoming = [{\n\t\t\ttitle: \"JSON error: \" + e,\n\t\t\ttext: \"\"\n\t\t}]\n\t}\n\tif(!$tw.utils.isArray(incoming)) {\n\t\tincoming = [incoming];\n\t}\n\tfor(var t=0; t<incoming.length; t++) {\n\t\tvar incomingFields = incoming[t],\n\t\t\tfields = {};\n\t\tfor(var f in incomingFields) {\n\t\t\tif(typeof incomingFields[f] === \"string\") {\n\t\t\t\tfields[f] = incomingFields[f];\n\t\t\t}\n\t\t}\n\t\tresults.push(fields);\n\t}\n\treturn results;\n};\n\n/*\nParse an HTML file into tiddlers. There are three possibilities:\n# A TiddlyWiki classic HTML file containing `text/x-tiddlywiki` tiddlers\n# A TiddlyWiki5 HTML file containing `text/vnd.tiddlywiki` tiddlers\n# An ordinary HTML file\n*/\nexports[\"text/html\"] = function(text,fields) {\n\t// Check if we've got a store area\n\tvar storeAreaMarkerRegExp = /<div id=[\"']?storeArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\tmatch = storeAreaMarkerRegExp.exec(text);\n\tif(match) {\n\t\t// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file\n\t\t// First read the normal tiddlers\n\t\tvar results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);\n\t\t// Then any system tiddlers\n\t\tvar systemAreaMarkerRegExp = /<div id=[\"']?systemArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\t\tsysMatch = systemAreaMarkerRegExp.exec(text);\n\t\tif(sysMatch) {\n\t\t\tresults.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));\n\t\t}\n\t\treturn results;\n\t} else {\n\t\t// Check whether we've got an encrypted file\n\t\tvar encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedStoreArea) {\n\t\t\t// If so, attempt to decrypt it using the current password\n\t\t\treturn $tw.utils.decryptStoreArea(encryptedStoreArea);\n\t\t} else {\n\t\t\t// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler\n\t\t\treturn deserializeHtmlFile(text,fields);\n\t\t}\n\t}\n};\n\nfunction deserializeHtmlFile(text,fields) {\n\tvar result = {};\n\t$tw.utils.each(fields,function(value,name) {\n\t\tresult[name] = value;\n\t});\n\tresult.text = text;\n\tresult.type = \"text/html\";\n\treturn [result];\n}\n\nfunction deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {\n\tvar results = [],\n\t\tendOfDivRegExp = /(<\\/div>\\s*)/gi,\n\t\tstartPos = storeAreaEnd,\n\t\tdefaultType = isTiddlyWiki5 ? undefined : \"text/x-tiddlywiki\";\n\tendOfDivRegExp.lastIndex = startPos;\n\tvar match = endOfDivRegExp.exec(text);\n\twhile(match) {\n\t\tvar endPos = endOfDivRegExp.lastIndex,\n\t\t\ttiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});\n\t\tif(!tiddlerFields) {\n\t\t\tbreak;\n\t\t}\n\t\t$tw.utils.each(tiddlerFields,function(value,name) {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttiddlerFields[name] = $tw.utils.htmlDecode(value);\n\t\t\t}\n\t\t});\n\t\tif(tiddlerFields.text !== null) {\n\t\t\tresults.push(tiddlerFields);\n\t\t}\n\t\tstartPos = endPos;\n\t\tmatch = endOfDivRegExp.exec(text);\n\t}\n\treturn results;\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "tiddlerdeserializer"
},
"$:/core/modules/editor/engines/framed.js": {
"title": "$:/core/modules/editor/engines/framed.js",
"text": "/*\\\ntitle: $:/core/modules/editor/engines/framed.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea within an iframe. This is done so that the selection is preserved even when clicking away from the textarea\n\n\\*/\n(function(){\n\n/*jslint node: true,browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction FramedEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Create our hidden dummy text area for reading styles\n\tthis.dummyTextArea = this.widget.document.createElement(\"textarea\");\n\tif(this.widget.editClass) {\n\t\tthis.dummyTextArea.className = this.widget.editClass;\n\t}\n\tthis.dummyTextArea.setAttribute(\"hidden\",\"true\");\n\tthis.parentNode.insertBefore(this.dummyTextArea,this.nextSibling);\n\tthis.widget.domNodes.push(this.dummyTextArea);\n\t// Create the iframe\n\tthis.iframeNode = this.widget.document.createElement(\"iframe\");\n\tthis.parentNode.insertBefore(this.iframeNode,this.nextSibling);\n\tthis.iframeDoc = this.iframeNode.contentWindow.document;\n\t// (Firefox requires us to put some empty content in the iframe)\n\tthis.iframeDoc.open();\n\tthis.iframeDoc.write(\"\");\n\tthis.iframeDoc.close();\n\t// Style the iframe\n\tthis.iframeNode.className = this.dummyTextArea.className;\n\tthis.iframeNode.style.border = \"none\";\n\tthis.iframeNode.style.padding = \"0\";\n\tthis.iframeNode.style.resize = \"none\";\n\tthis.iframeDoc.body.style.margin = \"0\";\n\tthis.iframeDoc.body.style.padding = \"0\";\n\tthis.widget.domNodes.push(this.iframeNode);\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.iframeDoc.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.iframeDoc.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editTabIndex) {\n\t\tthis.iframeNode.setAttribute(\"tabindex\",this.widget.editTabIndex);\n\t}\n\tif(this.widget.editAutoComplete) {\n\t\tthis.domNode.setAttribute(\"autocomplete\",this.widget.editAutoComplete);\n\t}\n\tif(this.widget.isDisabled === \"yes\") {\n\t\tthis.domNode.setAttribute(\"disabled\",true);\n\t}\t\n\t// Copy the styles from the dummy textarea\n\tthis.copyStyles();\n\t// Add event listeners\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"click\",handlerObject: this,handlerMethod: \"handleClickEvent\"},\n\t\t{name: \"input\",handlerObject: this,handlerMethod: \"handleInputEvent\"},\n\t\t{name: \"keydown\",handlerObject: this.widget,handlerMethod: \"handleKeydownEvent\"},\n\t\t{name: \"focus\",handlerObject: this,handlerMethod: \"handleFocusEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.iframeDoc.body.appendChild(this.domNode);\n}\n\n/*\nCopy styles from the dummy text area to the textarea in the iframe\n*/\nFramedEngine.prototype.copyStyles = function() {\n\t// Copy all styles\n\t$tw.utils.copyStyles(this.dummyTextArea,this.domNode);\n\t// Override the ones that should not be set the same as the dummy textarea\n\tthis.domNode.style.display = \"block\";\n\tthis.domNode.style.width = \"100%\";\n\tthis.domNode.style.margin = \"0\";\n\t// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour\n\tthis.domNode.style[\"-webkit-text-fill-color\"] = \"currentcolor\";\n};\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nFramedEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode) {\n\t\t\tthis.updateDomNodeText(text);\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nUpdate the DomNode with the new text\n*/\nFramedEngine.prototype.updateDomNodeText = function(text) {\n\tthis.domNode.value = text;\n};\n\n/*\nGet the text of the engine\n*/\nFramedEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nFramedEngine.prototype.fixHeight = function() {\n\t// Make sure styles are updated\n\tthis.copyStyles();\n\t// Adjust height\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tvar newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t\tthis.iframeNode.style.height = (newHeight + 14) + \"px\"; // +14 for the border on the textarea\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t\tthis.iframeNode.style.height = (fixedHeight + 14) + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nFramedEngine.prototype.focus = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a focus event\n*/\nFramedEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editCancelPopups) {\n\t\t$tw.popup.cancel(0);\t\n\t}\n};\n\n/*\nHandle a click\n*/\nFramedEngine.prototype.handleClickEvent = function(event) {\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nFramedEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\tif(this.widget.editInputActions) {\n\t\tthis.widget.invokeActionString(this.widget.editInputActions);\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nFramedEngine.prototype.createTextOperation = function() {\n\tvar operation = {\n\t\ttext: this.domNode.value,\n\t\tselStart: this.domNode.selectionStart,\n\t\tselEnd: this.domNode.selectionEnd,\n\t\tcutStart: null,\n\t\tcutEnd: null,\n\t\treplacement: null,\n\t\tnewSelStart: null,\n\t\tnewSelEnd: null\n\t};\n\toperation.selection = operation.text.substring(operation.selStart,operation.selEnd);\n\treturn operation;\n};\n\n/*\nExecute a text operation\n*/\nFramedEngine.prototype.executeTextOperation = function(operation) {\n\t// Perform the required changes to the text area and the underlying tiddler\n\tvar newText = operation.text;\n\tif(operation.replacement !== null) {\n\t\tnewText = operation.text.substring(0,operation.cutStart) + operation.replacement + operation.text.substring(operation.cutEnd);\n\t\t// Attempt to use a execCommand to modify the value of the control\n\t\tif(this.iframeDoc.queryCommandSupported(\"insertText\") && this.iframeDoc.queryCommandSupported(\"delete\") && !$tw.browser.isFirefox) {\n\t\t\tthis.domNode.focus();\n\t\t\tthis.domNode.setSelectionRange(operation.cutStart,operation.cutEnd);\n\t\t\tif(operation.replacement === \"\") {\n\t\t\t\tthis.iframeDoc.execCommand(\"delete\",false,\"\");\n\t\t\t} else {\n\t\t\t\tthis.iframeDoc.execCommand(\"insertText\",false,operation.replacement);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.domNode.value = newText;\n\t\t}\n\t\tthis.domNode.focus();\n\t\tthis.domNode.setSelectionRange(operation.newSelStart,operation.newSelEnd);\n\t}\n\tthis.domNode.focus();\n\treturn newText;\n};\n\nexports.FramedEngine = FramedEngine;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/editor/engines/simple.js": {
"title": "$:/core/modules/editor/engines/simple.js",
"text": "/*\\\ntitle: $:/core/modules/editor/engines/simple.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction SimpleEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.widget.document.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.widget.document.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editClass) {\n\t\tthis.domNode.className = this.widget.editClass;\n\t}\n\tif(this.widget.editTabIndex) {\n\t\tthis.domNode.setAttribute(\"tabindex\",this.widget.editTabIndex);\n\t}\n\tif(this.widget.editAutoComplete) {\n\t\tthis.domNode.setAttribute(\"autocomplete\",this.widget.editAutoComplete);\n\t}\n\tif(this.widget.isDisabled === \"yes\") {\n\t\tthis.domNode.setAttribute(\"disabled\",true);\n\t}\n\t// Add an input event handler\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"focus\", handlerObject: this, handlerMethod: \"handleFocusEvent\"},\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleInputEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.parentNode.insertBefore(this.domNode,this.nextSibling);\n\tthis.widget.domNodes.push(this.domNode);\n}\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nSimpleEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode || text === \"\") {\n\t\t\tthis.updateDomNodeText(text);\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nUpdate the DomNode with the new text\n*/\nSimpleEngine.prototype.updateDomNodeText = function(text) {\n\tthis.domNode.value = text;\n};\n\n/*\nGet the text of the engine\n*/\nSimpleEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nSimpleEngine.prototype.fixHeight = function() {\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\t$tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nSimpleEngine.prototype.focus = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nSimpleEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\tif(this.widget.editInputActions) {\n\t\tthis.widget.invokeActionString(this.widget.editInputActions);\n\t}\n\treturn true;\n};\n\n/*\nHandle a dom \"focus\" event\n*/\nSimpleEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editCancelPopups) {\n\t\t$tw.popup.cancel(0);\n\t}\n\tif(this.widget.editFocusPopup) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNode,\n\t\t\ttitle: this.widget.editFocusPopup,\n\t\t\twiki: this.widget.wiki,\n\t\t\tforce: true\n\t\t});\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nSimpleEngine.prototype.createTextOperation = function() {\n\treturn null;\n};\n\n/*\nExecute a text operation\n*/\nSimpleEngine.prototype.executeTextOperation = function(operation) {\n};\n\nexports.SimpleEngine = SimpleEngine;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/editor/factory.js": {
"title": "$:/core/modules/editor/factory.js",
"text": "/*\\\ntitle: $:/core/modules/editor/factory.js\ntype: application/javascript\nmodule-type: library\n\nFactory for constructing text editor widgets with specified engines for the toolbar and non-toolbar cases\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEFAULT_MIN_TEXT_AREA_HEIGHT = \"100px\"; // Minimum height of textareas in pixels\n\n// Configuration tiddlers\nvar HEIGHT_MODE_TITLE = \"$:/config/TextEditor/EditorHeight/Mode\";\nvar ENABLE_TOOLBAR_TITLE = \"$:/config/TextEditor/EnableToolbar\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nfunction editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {\n\n\tvar EditTextWidget = function(parseTreeNode,options) {\n\t\t// Initialise the editor operations if they've not been done already\n\t\tif(!this.editorOperations) {\n\t\t\tEditTextWidget.prototype.editorOperations = {};\n\t\t\t$tw.modules.applyMethods(\"texteditoroperation\",this.editorOperations);\n\t\t}\n\t\tthis.initialise(parseTreeNode,options);\n\t};\n\n\t/*\n\tInherit from the base widget class\n\t*/\n\tEditTextWidget.prototype = new Widget();\n\n\t/*\n\tRender this widget into the DOM\n\t*/\n\tEditTextWidget.prototype.render = function(parent,nextSibling) {\n\t\t// Save the parent dom node\n\t\tthis.parentDomNode = parent;\n\t\t// Compute our attributes\n\t\tthis.computeAttributes();\n\t\t// Execute our logic\n\t\tthis.execute();\n\t\t// Create the wrapper for the toolbar and render its content\n\t\tif(this.editShowToolbar) {\n\t\t\tthis.toolbarNode = this.document.createElement(\"div\");\n\t\t\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\t\t\tparent.insertBefore(this.toolbarNode,nextSibling);\n\t\t\tthis.renderChildren(this.toolbarNode,null);\n\t\t\tthis.domNodes.push(this.toolbarNode);\n\t\t}\n\t\t// Create our element\n\t\tvar editInfo = this.getEditInfo(),\n\t\t\tEngine = this.editShowToolbar ? toolbarEngine : nonToolbarEngine;\n\t\tthis.engine = new Engine({\n\t\t\t\twidget: this,\n\t\t\t\tvalue: editInfo.value,\n\t\t\t\ttype: editInfo.type,\n\t\t\t\tparentNode: parent,\n\t\t\t\tnextSibling: nextSibling\n\t\t\t});\n\t\t// Call the postRender hook\n\t\tif(this.postRender) {\n\t\t\tthis.postRender();\n\t\t}\n\t\t// Fix height\n\t\tthis.engine.fixHeight();\n\t\t// Focus if required\n\t\tif(this.editFocus === \"true\" || this.editFocus === \"yes\") {\n\t\t\tthis.engine.focus();\n\t\t}\n\t\t// Add widget message listeners\n\t\tthis.addEventListeners([\n\t\t\t{type: \"tm-edit-text-operation\", handler: \"handleEditTextOperationMessage\"}\n\t\t]);\n\t};\n\n\t/*\n\tGet the tiddler being edited and current value\n\t*/\n\tEditTextWidget.prototype.getEditInfo = function() {\n\t\t// Get the edit value\n\t\tvar self = this,\n\t\t\tvalue,\n\t\t\ttype = \"text/plain\",\n\t\t\tupdate;\n\t\tif(this.editIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.editTitle,this.editIndex,this.editDefault);\n\t\t\tupdate = function(value) {\n\t\t\t\tvar data = self.wiki.getTiddlerData(self.editTitle,{});\n\t\t\t\tif(data[self.editIndex] !== value) {\n\t\t\t\t\tdata[self.editIndex] = value;\n\t\t\t\t\tself.wiki.setTiddlerData(self.editTitle,data);\n\t\t\t\t}\n\t\t\t};\n\t\t} else {\n\t\t\t// Get the current tiddler and the field name\n\t\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\t\tif(tiddler) {\n\t\t\t\t// If we've got a tiddler, the value to display is the field string value\n\t\t\t\tvalue = tiddler.getFieldString(this.editField);\n\t\t\t\tif(this.editField === \"text\") {\n\t\t\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise, we need to construct a default value for the editor\n\t\t\t\tswitch(this.editField) {\n\t\t\t\t\tcase \"text\":\n\t\t\t\t\t\tvalue = \"Type the text for the tiddler '\" + this.editTitle + \"'\";\n\t\t\t\t\t\ttype = \"text/vnd.tiddlywiki\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tvalue = this.editTitle;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvalue = \"\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(this.editDefault !== undefined) {\n\t\t\t\t\tvalue = this.editDefault;\n\t\t\t\t}\n\t\t\t}\n\t\t\tupdate = function(value) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(self.editTitle),\n\t\t\t\t\tupdateFields = {\n\t\t\t\t\t\ttitle: self.editTitle\n\t\t\t\t\t};\n\t\t\t\tupdateFields[self.editField] = value;\n\t\t\t\tself.wiki.addTiddler(new $tw.Tiddler(self.wiki.getCreationFields(),tiddler,updateFields,self.wiki.getModificationFields()));\n\t\t\t};\n\t\t}\n\t\tif(this.editType) {\n\t\t\ttype = this.editType;\n\t\t}\n\t\treturn {value: value || \"\", type: type, update: update};\n\t};\n\n\t/*\n\tHandle an edit text operation message from the toolbar\n\t*/\n\tEditTextWidget.prototype.handleEditTextOperationMessage = function(event) {\n\t\t// Prepare information about the operation\n\t\tvar operation = this.engine.createTextOperation();\n\t\t// Invoke the handler for the selected operation\n\t\tvar handler = this.editorOperations[event.param];\n\t\tif(handler) {\n\t\t\thandler.call(this,event,operation);\n\t\t}\n\t\t// Execute the operation via the engine\n\t\tvar newText = this.engine.executeTextOperation(operation);\n\t\t// Fix the tiddler height and save changes\n\t\tthis.engine.fixHeight();\n\t\tthis.saveChanges(newText);\n\t};\n\n\t/*\n\tCompute the internal state of the widget\n\t*/\n\tEditTextWidget.prototype.execute = function() {\n\t\t// Get our parameters\n\t\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t\tthis.editField = this.getAttribute(\"field\",\"text\");\n\t\tthis.editIndex = this.getAttribute(\"index\");\n\t\tthis.editDefault = this.getAttribute(\"default\");\n\t\tthis.editClass = this.getAttribute(\"class\");\n\t\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\t\tthis.editSize = this.getAttribute(\"size\");\n\t\tthis.editRows = this.getAttribute(\"rows\");\n\t\tthis.editAutoHeight = this.wiki.getTiddlerText(HEIGHT_MODE_TITLE,\"auto\");\n\t\tthis.editAutoHeight = this.getAttribute(\"autoHeight\",this.editAutoHeight === \"auto\" ? \"yes\" : \"no\") === \"yes\";\n\t\tthis.editMinHeight = this.getAttribute(\"minHeight\",DEFAULT_MIN_TEXT_AREA_HEIGHT);\n\t\tthis.editFocusPopup = this.getAttribute(\"focusPopup\");\n\t\tthis.editFocus = this.getAttribute(\"focus\");\n\t\tthis.editTabIndex = this.getAttribute(\"tabindex\");\n\t\tthis.editCancelPopups = this.getAttribute(\"cancelPopups\",\"\") === \"yes\";\n\t\tthis.editInputActions = this.getAttribute(\"inputActions\");\n\t\tthis.editRefreshTitle = this.getAttribute(\"refreshTitle\");\n\t\tthis.editAutoComplete = this.getAttribute(\"autocomplete\");\n\t\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t\t// Get the default editor element tag and type\n\t\tvar tag,type;\n\t\tif(this.editField === \"text\") {\n\t\t\ttag = \"textarea\";\n\t\t} else {\n\t\t\ttag = \"input\";\n\t\t\tvar fieldModule = $tw.Tiddler.fieldModules[this.editField];\n\t\t\tif(fieldModule && fieldModule.editTag) {\n\t\t\t\ttag = fieldModule.editTag;\n\t\t\t}\n\t\t\tif(fieldModule && fieldModule.editType) {\n\t\t\t\ttype = fieldModule.editType;\n\t\t\t}\n\t\t\ttype = type || \"text\";\n\t\t}\n\t\t// Get the rest of our parameters\n\t\tthis.editTag = this.getAttribute(\"tag\",tag) || \"input\";\n\t\tthis.editType = this.getAttribute(\"type\",type);\n\t\t// Make the child widgets\n\t\tthis.makeChildWidgets();\n\t\t// Determine whether to show the toolbar\n\t\tthis.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,\"yes\");\n\t\tthis.editShowToolbar = (this.editShowToolbar === \"yes\") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);\n\t};\n\n\t/*\n\tSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n\t*/\n\tEditTextWidget.prototype.refresh = function(changedTiddlers) {\n\t\tvar changedAttributes = this.computeAttributes();\n\t\t// Completely rerender if any of our attributes have changed\n\t\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE] || changedAttributes.disabled) {\n\t\t\tthis.refreshSelf();\n\t\t\treturn true;\n\t\t} else if (changedTiddlers[this.editRefreshTitle]) {\n\t\t\tthis.engine.updateDomNodeText(this.getEditInfo().value);\n\t\t} else if(changedTiddlers[this.editTitle]) {\n\t\t\tvar editInfo = this.getEditInfo();\n\t\t\tthis.updateEditor(editInfo.value,editInfo.type);\n\t\t}\n\t\tthis.engine.fixHeight();\n\t\tif(this.editShowToolbar) {\n\t\t\treturn this.refreshChildren(changedTiddlers);\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\t/*\n\tUpdate the editor with new text. This method is separate from updateEditorDomNode()\n\tso that subclasses can override updateEditor() and still use updateEditorDomNode()\n\t*/\n\tEditTextWidget.prototype.updateEditor = function(text,type) {\n\t\tthis.updateEditorDomNode(text,type);\n\t};\n\n\t/*\n\tUpdate the editor dom node with new text\n\t*/\n\tEditTextWidget.prototype.updateEditorDomNode = function(text,type) {\n\t\tthis.engine.setText(text,type);\n\t};\n\n\t/*\n\tSave changes back to the tiddler store\n\t*/\n\tEditTextWidget.prototype.saveChanges = function(text) {\n\t\tvar editInfo = this.getEditInfo();\n\t\tif(text !== editInfo.value) {\n\t\t\teditInfo.update(text);\n\t\t}\n\t};\n\n\t/*\n\tHandle a dom \"keydown\" event, which we'll bubble up to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.handleKeydownEvent = function(event) {\n\t\t// Check for a keyboard shortcut\n\t\tif(this.toolbarNode) {\n\t\t\tvar shortcutElements = this.toolbarNode.querySelectorAll(\"[data-tw-keyboard-shortcut]\");\n\t\t\tfor(var index=0; index<shortcutElements.length; index++) {\n\t\t\t\tvar el = shortcutElements[index],\n\t\t\t\t\tshortcutData = el.getAttribute(\"data-tw-keyboard-shortcut\"),\n\t\t\t\t\tkeyInfoArray = $tw.keyboardManager.parseKeyDescriptors(shortcutData,{\n\t\t\t\t\t\twiki: this.wiki\n\t\t\t\t\t});\n\t\t\t\tif($tw.keyboardManager.checkKeyDescriptors(event,keyInfoArray)) {\n\t\t\t\t\tvar clickEvent = this.document.createEvent(\"Events\");\n\t\t\t\t clickEvent.initEvent(\"click\",true,false);\n\t\t\t\t el.dispatchEvent(clickEvent);\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Propogate the event to the container\n\t\tif(this.propogateKeydownEvent(event)) {\n\t\t\t// Ignore the keydown if it was already handled\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\treturn true;\n\t\t}\n\t\t// Otherwise, process the keydown normally\n\t\treturn false;\n\t};\n\n\t/*\n\tPropogate keydown events to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.propogateKeydownEvent = function(event) {\n\t\tvar newEvent = this.document.createEventObject ? this.document.createEventObject() : this.document.createEvent(\"Events\");\n\t\tif(newEvent.initEvent) {\n\t\t\tnewEvent.initEvent(\"keydown\", true, true);\n\t\t}\n\t\tnewEvent.keyCode = event.keyCode;\n\t\tnewEvent.which = event.which;\n\t\tnewEvent.metaKey = event.metaKey;\n\t\tnewEvent.ctrlKey = event.ctrlKey;\n\t\tnewEvent.altKey = event.altKey;\n\t\tnewEvent.shiftKey = event.shiftKey;\n\t\treturn !this.parentDomNode.dispatchEvent(newEvent);\n\t};\n\n\treturn EditTextWidget;\n\n}\n\nexports.editTextWidgetFactory = editTextWidgetFactory;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/editor/operations/bitmap/clear.js": {
"title": "$:/core/modules/editor/operations/bitmap/clear.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/clear.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to clear the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"clear\"] = function(event) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.globalAlpha = 1;\n\tctx.fillStyle = event.paramObject.colour || \"white\";\n\tctx.fillRect(0,0,this.canvasDomNode.width,this.canvasDomNode.height);\n\t// Save changes\n\tthis.strokeEnd();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "bitmapeditoroperation"
},
"$:/core/modules/editor/operations/bitmap/resize.js": {
"title": "$:/core/modules/editor/operations/bitmap/resize.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/resize.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to resize the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"resize\"] = function(event) {\n\t// Get the new width\n\tvar newWidth = parseInt(event.paramObject.width || this.canvasDomNode.width,10),\n\t\tnewHeight = parseInt(event.paramObject.height || this.canvasDomNode.height,10);\n\t// Update if necessary\n\tif(newWidth > 0 && newHeight > 0 && !(newWidth === this.currCanvas.width && newHeight === this.currCanvas.height)) {\n\t\tthis.changeCanvasSize(newWidth,newHeight);\n\t}\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "bitmapeditoroperation"
},
"$:/core/modules/editor/operations/bitmap/rotate-left.js": {
"title": "$:/core/modules/editor/operations/bitmap/rotate-left.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/rotate-left.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to rotate the image left by 90 degrees\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"rotate-left\"] = function(event) {\n\t// Rotate the canvas left by 90 degrees\n\tthis.rotateCanvasLeft();\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "bitmapeditoroperation"
},
"$:/core/modules/editor/operations/text/excise.js": {
"title": "$:/core/modules/editor/operations/text/excise.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/excise.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to excise the selection to a new tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"excise\"] = function(event,operation) {\n\tvar editTiddler = this.wiki.getTiddler(this.editTitle),\n\t\teditTiddlerTitle = this.editTitle;\n\tif(editTiddler && editTiddler.fields[\"draft.of\"]) {\n\t\teditTiddlerTitle = editTiddler.fields[\"draft.of\"];\n\t}\n\tvar excisionTitle = event.paramObject.title || this.wiki.generateNewTitle(\"New Excision\");\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\tthis.wiki.getModificationFields(),\n\t\t{\n\t\t\ttitle: excisionTitle,\n\t\t\ttext: operation.selection,\n\t\t\ttags: event.paramObject.tagnew === \"yes\" ? [editTiddlerTitle] : []\n\t\t}\n\t));\n\toperation.replacement = excisionTitle;\n\tswitch(event.paramObject.type || \"transclude\") {\n\t\tcase \"transclude\":\n\t\t\toperation.replacement = \"{{\" + operation.replacement+ \"}}\";\n\t\t\tbreak;\n\t\tcase \"link\":\n\t\t\toperation.replacement = \"[[\" + operation.replacement+ \"]]\";\n\t\t\tbreak;\n\t\tcase \"macro\":\n\t\t\toperation.replacement = \"<<\" + (event.paramObject.macro || \"translink\") + \" \\\"\\\"\\\"\" + operation.replacement + \"\\\"\\\"\\\">>\";\n\t\t\tbreak;\n\t}\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/make-link.js": {
"title": "$:/core/modules/editor/operations/text/make-link.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/make-link.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to make a link\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"make-link\"] = function(event,operation) {\n\tif(operation.selection) {\n\t\toperation.replacement = \"[[\" + operation.selection + \"|\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t} else {\n\t\toperation.replacement = \"[[\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t}\n\toperation.newSelStart = operation.selStart + operation.replacement.length;\n\toperation.newSelEnd = operation.newSelStart;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/prefix-lines.js": {
"title": "$:/core/modules/editor/operations/text/prefix-lines.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/prefix-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to add a prefix to the selected lines\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"prefix-lines\"] = function(event,operation) {\n\tvar targetCount = parseInt(event.paramObject.count + \"\",10);\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Compose the required prefix\n\tvar prefix = $tw.utils.repeat(event.paramObject.character,targetCount);\n\t// Process each line\n\tvar lines = operation.text.substring(operation.cutStart,operation.cutEnd).split(/\\r?\\n/mg);\n\t$tw.utils.each(lines,function(line,index) {\n\t\t// Remove and count any existing prefix characters\n\t\tvar count = 0;\n\t\twhile(line.charAt(0) === event.paramObject.character) {\n\t\t\tline = line.substring(1);\n\t\t\tcount++;\n\t\t}\n\t\t// Remove any whitespace\n\t\twhile(line.charAt(0) === \" \") {\n\t\t\tline = line.substring(1);\n\t\t}\n\t\t// We're done if we removed the exact required prefix, otherwise add it\n\t\tif(count !== targetCount) {\n\t\t\t// Apply the prefix\n\t\t\tline = prefix + \" \" + line;\n\t\t}\n\t\t// Save the modified line\n\t\tlines[index] = line;\n\t});\n\t// Stitch the replacement text together and set the selection\n\toperation.replacement = lines.join(\"\\n\");\n\tif(lines.length === 1) {\n\t\toperation.newSelStart = operation.cutStart + operation.replacement.length;\n\t\toperation.newSelEnd = operation.newSelStart;\n\t} else {\n\t\toperation.newSelStart = operation.cutStart;\n\t\toperation.newSelEnd = operation.newSelStart + operation.replacement.length;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/replace-all.js": {
"title": "$:/core/modules/editor/operations/text/replace-all.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/replace-all.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the entire text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-all\"] = function(event,operation) {\n\toperation.cutStart = 0;\n\toperation.cutEnd = operation.text.length;\n\toperation.replacement = event.paramObject.text;\n\toperation.newSelStart = 0;\n\toperation.newSelEnd = operation.replacement.length;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/replace-selection.js": {
"title": "$:/core/modules/editor/operations/text/replace-selection.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/replace-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the selection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-selection\"] = function(event,operation) {\n\toperation.replacement = event.paramObject.text;\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/save-selection.js": {
"title": "$:/core/modules/editor/operations/text/save-selection.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/save-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to save the current selection in a specified tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"save-selection\"] = function(event,operation) {\n\tvar tiddler = event.paramObject.tiddler,\n\t\tfield = event.paramObject.field || \"text\";\n\tif(tiddler && field) {\n\t\tthis.wiki.setText(tiddler,field,null,operation.text.substring(operation.selStart,operation.selEnd));\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/wrap-lines.js": {
"title": "$:/core/modules/editor/operations/text/wrap-lines.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selected lines with a prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-lines\"] = function(event,operation) {\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Add the prefix and suffix\n\toperation.replacement = event.paramObject.prefix + \"\\n\" +\n\t\t\t\toperation.text.substring(operation.cutStart,operation.cutEnd) + \"\\n\" +\n\t\t\t\tevent.paramObject.suffix + \"\\n\";\n\toperation.newSelStart = operation.cutStart + event.paramObject.prefix.length + 1;\n\toperation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/wrap-selection.js": {
"title": "$:/core/modules/editor/operations/text/wrap-selection.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selection with the specified prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-selection\"] = function(event,operation) {\n\tif(operation.selStart === operation.selEnd) {\n\t\t// No selection; check if we're within the prefix/suffix\n\t\tif(operation.text.substring(operation.selStart - event.paramObject.prefix.length,operation.selStart + event.paramObject.suffix.length) === event.paramObject.prefix + event.paramObject.suffix) {\n\t\t\t// Remove the prefix and suffix\n\t\t\toperation.cutStart = operation.selStart - event.paramObject.prefix.length;\n\t\t\toperation.cutEnd = operation.selEnd + event.paramObject.suffix.length;\n\t\t\toperation.replacement = \"\";\n\t\t\toperation.newSelStart = operation.cutStart;\n\t\t\toperation.newSelEnd = operation.newSelStart;\n\t\t} else {\n\t\t\t// Wrap the cursor instead\n\t\t\toperation.cutStart = operation.selStart;\n\t\t\toperation.cutEnd = operation.selEnd;\n\t\t\toperation.replacement = event.paramObject.prefix + event.paramObject.suffix;\n\t\t\toperation.newSelStart = operation.selStart + event.paramObject.prefix.length;\n\t\t\toperation.newSelEnd = operation.newSelStart;\n\t\t}\n\t} else if(operation.text.substring(operation.selStart,operation.selStart + event.paramObject.prefix.length) === event.paramObject.prefix && operation.text.substring(operation.selEnd - event.paramObject.suffix.length,operation.selEnd) === event.paramObject.suffix) {\n\t\t// Prefix and suffix are already present, so remove them\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.replacement = operation.selection.substring(event.paramObject.prefix.length,operation.selection.length - event.paramObject.suffix.length);\n\t\toperation.newSelStart = operation.selStart;\n\t\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n\t} else {\n\t\t// Add the prefix and suffix\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.replacement = event.paramObject.prefix + operation.selection + event.paramObject.suffix;\n\t\toperation.newSelStart = operation.selStart;\n\t\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/filterrunprefixes/all.js": {
"title": "$:/core/modules/filterrunprefixes/all.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/all.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nUnion of sets without de-duplication.\nEquivalent to = filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.all = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tresults.push.apply(results, operationSubFunction(source,widget));\n\t};\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/and.js": {
"title": "$:/core/modules/filterrunprefixes/and.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/and.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nIntersection of sets.\nEquivalent to + filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.and = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\t// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved\n\t\tsource = options.wiki.makeTiddlerIterator(results.toArray());\n\t\tresults.clear();\n\t\tresults.pushTop(operationSubFunction(source,widget));\n\t};\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/else.js": {
"title": "$:/core/modules/filterrunprefixes/else.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/else.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nEquivalent to ~ filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.else = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tif(results.length === 0) {\n\t\t\t// Main result so far is empty\n\t\t\tresults.pushTop(operationSubFunction(source,widget));\n\t\t}\n\t};\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/except.js": {
"title": "$:/core/modules/filterrunprefixes/except.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/except.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nDifference of sets.\nEquivalent to - filter run prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.except = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tresults.remove(operationSubFunction(source,widget));\n\t};\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/filter.js": {
"title": "$:/core/modules/filterrunprefixes/filter.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/filter.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.filter = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length > 0) {\n\t\t\tvar resultsToRemove = [];\n\t\t\tresults.each(function(result) {\n\t\t\t\tvar filtered = operationSubFunction(options.wiki.makeTiddlerIterator([result]),widget);\n\t\t\t\tif(filtered.length === 0) {\n\t\t\t\t\tresultsToRemove.push(result);\n\t\t\t\t}\n\t\t\t});\n\t\t\tresults.remove(resultsToRemove);\n\t\t}\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/intersection.js": {
"title": "$:/core/modules/filterrunprefixes/intersection.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/intersection.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.intersection = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tif(results.length !== 0) {\n\t\t\tvar secondRunResults = operationSubFunction(source,widget);\n\t\t\tvar firstRunResults = results.toArray();\n\t\t\tresults.clear();\n\t\t\t$tw.utils.each(firstRunResults,function(title) {\n\t\t\t\tif(secondRunResults.indexOf(title) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/or.js": {
"title": "$:/core/modules/filterrunprefixes/or.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/or.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\nEquivalent to a filter run with no prefix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.or = function(operationSubFunction) {\n\treturn function(results,source,widget) {\n\t\tresults.pushTop(operationSubFunction(source,widget));\n\t};\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filterrunprefixes/reduce.js": {
"title": "$:/core/modules/filterrunprefixes/reduce.js",
"text": "/*\\\ntitle: $:/core/modules/filterrunprefixes/reduce.js\ntype: application/javascript\nmodule-type: filterrunprefix\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter prefix function\n*/\nexports.reduce = function(operationSubFunction,options) {\n\treturn function(results,source,widget) {\n\t\tif(results.length > 0) {\n\t\t\tvar accumulator = \"\";\n\t\t\tvar index = 0;\n\t\t\tresults.each(function(title) {\n\t\t\t\tvar list = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{\n\t\t\t\t\t\tgetVariable: function(name) {\n\t\t\t\t\t\t\tswitch(name) {\n\t\t\t\t\t\t\t\tcase \"currentTiddler\":\n\t\t\t\t\t\t\t\t\treturn \"\" + title;\n\t\t\t\t\t\t\t\tcase \"accumulator\":\n\t\t\t\t\t\t\t\t\treturn \"\" + accumulator;\n\t\t\t\t\t\t\t\tcase \"index\":\n\t\t\t\t\t\t\t\t\treturn \"\" + index;\n\t\t\t\t\t\t\t\tcase \"revIndex\":\n\t\t\t\t\t\t\t\t\treturn \"\" + (results.length - 1 - index);\n\t\t\t\t\t\t\t\tcase \"length\":\n\t\t\t\t\t\t\t\t\treturn \"\" + results.length;\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\treturn widget.getVariable(name);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\tif(list.length > 0) {\n\t\t\t\t\taccumulator = \"\" + list[0];\n\t\t\t\t}\n\t\t\t\t++index;\n\t\t\t});\n\t\t\tresults.clear();\n\t\t\tresults.push(accumulator);\t\n\t\t}\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filterrunprefix"
},
"$:/core/modules/filters/addprefix.js": {
"title": "$:/core/modules/filters/addprefix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/addprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a prefix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(operator.operand + title);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/addsuffix.js": {
"title": "$:/core/modules/filters/addsuffix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/addsuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a suffix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addsuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title + operator.operand);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/after.js": {
"title": "$:/core/modules/filters/after.js",
"text": "/*\\\ntitle: $:/core/modules/filters/after.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is after the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.after = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index === -1 || index > (results.length - 2)) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index + 1]];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/all/current.js": {
"title": "$:/core/modules/filters/all/current.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/current.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar currTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(currTiddlerTitle) {\n\t\treturn [currTiddlerTitle];\n\t} else {\n\t\treturn [];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/missing.js": {
"title": "$:/core/modules/filters/all/missing.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/missing.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\treturn options.wiki.getMissingTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/orphans.js": {
"title": "$:/core/modules/filters/all/orphans.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/orphans.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[orphans]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphans = function(source,prefix,options) {\n\treturn options.wiki.getOrphanTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/shadows.js": {
"title": "$:/core/modules/filters/all/shadows.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/shadows.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[shadows]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadows = function(source,prefix,options) {\n\treturn options.wiki.allShadowTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/tags.js": {
"title": "$:/core/modules/filters/all/tags.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/tags.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tags]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,prefix,options) {\n\treturn Object.keys(options.wiki.getTagMap());\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/tiddlers.js": {
"title": "$:/core/modules/filters/all/tiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/tiddlers.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddlers = function(source,prefix,options) {\n\treturn options.wiki.allTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all.js": {
"title": "$:/core/modules/filters/all.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for selecting tiddlers\n\n[all[shadows+tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar allFilterOperators;\n\nfunction getAllFilterOperators() {\n\tif(!allFilterOperators) {\n\t\tallFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"allfilteroperator\",allFilterOperators);\n\t}\n\treturn allFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.all = function(source,operator,options) {\n\t// Get our suboperators\n\tvar allFilterOperators = getAllFilterOperators();\n\t// Cycle through the suboperators accumulating their results\n\tvar results = [],\n\t\tsubops = operator.operand.split(\"+\");\n\t// Check for common optimisations\n\tif(subops.length === 1 && subops[0] === \"\") {\n\t\treturn source;\n\t} else if(subops.length === 1 && subops[0] === \"tiddlers\") {\n\t\treturn options.wiki.each;\n\t} else if(subops.length === 1 && subops[0] === \"shadows\") {\n\t\treturn options.wiki.eachShadow;\n\t} else if(subops.length === 2 && subops[0] === \"tiddlers\" && subops[1] === \"shadows\") {\n\t\treturn options.wiki.eachTiddlerPlusShadows;\n\t} else if(subops.length === 2 && subops[0] === \"shadows\" && subops[1] === \"tiddlers\") {\n\t\treturn options.wiki.eachShadowPlusTiddlers;\n\t}\n\t// Do it the hard way\n\tfor(var t=0; t<subops.length; t++) {\n\t\tvar subop = allFilterOperators[subops[t]];\n\t\tif(subop) {\n\t\t\t$tw.utils.pushTop(results,subop(source,operator.prefix,options));\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/backlinks.js": {
"title": "$:/core/modules/filters/backlinks.js",
"text": "/*\\\ntitle: $:/core/modules/filters/backlinks.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the backlinks from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.backlinks = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/before.js": {
"title": "$:/core/modules/filters/before.js",
"text": "/*\\\ntitle: $:/core/modules/filters/before.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is before the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.before = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index <= 0) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index - 1]];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/commands.js": {
"title": "$:/core/modules/filters/commands.js",
"text": "/*\\\ntitle: $:/core/modules/filters/commands.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the commands available in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.commands = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.commands,function(commandInfo,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/compare.js": {
"title": "$:/core/modules/filters/compare.js",
"text": "/*\\\ntitle: $:/core/modules/filters/compare.js\ntype: application/javascript\nmodule-type: filteroperator\n\nGeneral purpose comparison operator\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.compare = function(source,operator,options) {\n\tvar suffixes = operator.suffixes || [],\n\t\ttype = (suffixes[0] || [])[0],\n\t\tmode = (suffixes[1] || [])[0],\n\t\ttypeFn = $tw.utils.makeCompareFunction(type,{defaultType: \"number\"}),\n\t\tmodeFn = modes[mode] || modes.eq,\n\t\tinvert = operator.prefix === \"!\",\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tif(modeFn(typeFn(title,operator.operand)) !== invert) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\nvar modes = {\n\t\"eq\": function(value) {return value === 0;},\n\t\"ne\": function(value) {return value !== 0;},\n\t\"gteq\": function(value) {return value >= 0;},\n\t\"gt\": function(value) {return value > 0;},\n\t\"lteq\": function(value) {return value <= 0;},\n\t\"lt\": function(value) {return value < 0;}\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/contains.js": {
"title": "$:/core/modules/filters/contains.js",
"text": "/*\\\ntitle: $:/core/modules/filters/contains.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for finding values in array fields\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.contains = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || \"list\").toLowerCase();\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/count.js": {
"title": "$:/core/modules/filters/count.js",
"text": "/*\\\ntitle: $:/core/modules/filters/count.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the number of entries in the current list.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.count = function(source,operator,options) {\n\tvar count = 0;\n\tsource(function(tiddler,title) {\n\t\tcount++;\n\t});\n\treturn [count + \"\"];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/days.js": {
"title": "$:/core/modules/filters/days.js",
"text": "/*\\\ntitle: $:/core/modules/filters/days.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a specified date field within a specified date interval.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.days = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\tdayInterval = (parseInt(operator.operand,10)||0),\n\t\tdayIntervalSign = $tw.utils.sign(dayInterval),\n\t\ttargetTimeStamp = (new Date()).setHours(0,0,0,0) + 1000*60*60*24*dayInterval,\n\t\tisWithinDays = function(dateField) {\n\t\t\tvar sign = $tw.utils.sign(targetTimeStamp - (new Date(dateField)).setHours(0,0,0,0));\n\t\t\treturn sign === 0 || sign === dayIntervalSign;\n\t\t};\n\n\tif(operator.prefix === \"!\") {\n\t\ttargetTimeStamp = targetTimeStamp - 1000*60*60*24*dayIntervalSign;\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(!isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/duplicateslugs.js": {
"title": "$:/core/modules/filters/duplicateslugs.js",
"text": "/*\\\ntitle: $:/core/modules/filters/duplicateslugs.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter function for [duplicateslugs[]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.duplicateslugs = function(source,operator,options) {\n\tvar slugs = Object.create(null), // Hashmap by slug of title, replaced with \"true\" if the duplicate title has already been output\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tvar slug = options.wiki.slugify(title);\n\t\tif(slug in slugs) {\n\t\t\tif(slugs[slug] !== true) {\n\t\t\t\tresults.push(slugs[slug]);\n\t\t\t\tslugs[slug] = true;\n\t\t\t}\n\t\t\tresults.push(title);\n\t\t} else {\n\t\t\tslugs[slug] = title;\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/each.js": {
"title": "$:/core/modules/filters/each.js",
"text": "/*\\\ntitle: $:/core/modules/filters/each.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique value of the specified field.\nWith suffix \"list\", selects all tiddlers that are values in a specified list field.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.each = function(source,operator,options) {\n\tvar results =[] ,\n\tvalue,values = {},\n\tfield = operator.operand || \"title\";\n\tif(operator.suffix === \"value\" && field === \"title\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(values,title)) {\n\t\t\t\tvalues[title] = true;\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else if(operator.suffix !== \"list-item\") {\n\t\tif(field === \"title\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && !$tw.utils.hop(values,title)) {\n\t\t\t\t\tvalues[title] = true;\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvalue = tiddler.getFieldString(field);\n\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\t$tw.utils.each(\n\t\t\t\t\toptions.wiki.getTiddlerList(title,field),\n\t\t\t\t\tfunction(value) {\n\t\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\t\tresults.push(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/eachday.js": {
"title": "$:/core/modules/filters/eachday.js",
"text": "/*\\\ntitle: $:/core/modules/filters/eachday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique day covered by the specified date field\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.eachday = function(source,operator,options) {\n\tvar results = [],\n\t\tvalues = [],\n\t\tfieldName = operator.operand || \"modified\";\n\t// Function to convert a date/time to a date integer\n\tvar toDate = function(value) {\n\t\tvalue = (new Date(value)).setHours(0,0,0,0);\n\t\treturn value+0;\n\t};\n\tsource(function(tiddler,title) {\n\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\tvar value = toDate($tw.utils.parseDate(tiddler.fields[fieldName]));\n\t\t\tif(values.indexOf(value) === -1) {\n\t\t\t\tvalues.push(value);\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/editiondescription.js": {
"title": "$:/core/modules/filters/editiondescription.js",
"text": "/*\\\ntitle: $:/core/modules/filters/editiondescription.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the descriptions of the specified edition names\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editiondescription = function(source,operator,options) {\n\tvar results = [];\n\tif($tw.node) {\n\t\tvar editionInfo = $tw.utils.getEditionInfo();\n\t\tif(editionInfo) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif($tw.utils.hop(editionInfo,title)) {\n\t\t\t\t\tresults.push(editionInfo[title].description || \"\");\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/editions.js": {
"title": "$:/core/modules/filters/editions.js",
"text": "/*\\\ntitle: $:/core/modules/filters/editions.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the available editions in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editions = function(source,operator,options) {\n\tvar results = [];\n\tif($tw.node) {\n\t\tvar editionInfo = $tw.utils.getEditionInfo();\n\t\tif(editionInfo) {\n\t\t\t$tw.utils.each(editionInfo,function(info,name) {\n\t\t\t\tresults.push(name);\n\t\t\t});\n\t\t}\n\t\tresults.sort();\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/else.js": {
"title": "$:/core/modules/filters/else.js",
"text": "/*\\\ntitle: $:/core/modules/filters/else.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing an empty input list with a constant, passing a non-empty input list straight through\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.else = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tif(results.length === 0) {\n\t\treturn [operator.operand];\n\t} else {\n\t\treturn results;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/decodeuricomponent.js": {
"title": "$:/core/modules/filters/decodeuricomponent.js",
"text": "/*\\\ntitle: $:/core/modules/filters/decodeuricomponent.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for applying decodeURIComponent() to each item.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter functions\n*/\n\nexports.decodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = title;\n\t\ttry {\n\t\t\tvalue = decodeURIComponent(title);\n\t\t} catch(e) {\n\t\t}\n\t\tresults.push(value);\n\t});\n\treturn results;\n};\n\nexports.encodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURIComponent(title));\n\t});\n\treturn results;\n};\n\nexports.decodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = title;\n\t\ttry {\n\t\t\tvalue = decodeURI(title);\n\t\t} catch(e) {\n\t\t}\n\t\tresults.push(value);\n\t});\n\treturn results;\n};\n\nexports.encodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURI(title));\n\t});\n\treturn results;\n};\n\nexports.decodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlDecode(title));\n\t});\n\treturn results;\n};\n\nexports.encodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlEncode(title));\n\t});\n\treturn results;\n};\n\nexports.stringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.stringify(title,(operator.suffix === \"rawunicode\")));\n\t});\n\treturn results;\n};\n\nexports.jsonstringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.jsonStringify(title,(operator.suffix === \"rawunicode\")));\n\t});\n\treturn results;\n};\n\nexports.escaperegexp = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.escapeRegExp(title));\n\t});\n\treturn results;\n};\n\nexports.escapecss = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t// escape any character with a special meaning in CSS using CSS.escape()\n\t\tresults.push(CSS.escape(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/enlist.js": {
"title": "$:/core/modules/filters/enlist.js",
"text": "/*\\\ntitle: $:/core/modules/filters/enlist.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand parsed as a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.enlist = function(source,operator,options) {\n\tvar allowDuplicates = false;\n\tswitch(operator.suffix) {\n\t\tcase \"raw\":\n\t\t\tallowDuplicates = true;\n\t\t\tbreak;\n\t\tcase \"dedupe\":\n\t\t\tallowDuplicates = false;\n\t\t\tbreak;\n\t}\n\tvar list = $tw.utils.parseStringArray(operator.operand,allowDuplicates);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/field.js": {
"title": "$:/core/modules/filters/field.js",
"text": "/*\\\ntitle: $:/core/modules/filters/field.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.field = function(source,operator,options) {\n\tvar results = [],indexedResults,\n\t\tfieldname = (operator.suffix || operator.operator || \"title\").toLowerCase();\n\tif(operator.prefix === \"!\") {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text !== operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !!operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tif(source.byField && operator.operand) {\n\t\t\t\tindexedResults = source.byField(fieldname,operator.operand);\n\t\t\t\tif(indexedResults) {\n\t\t\t\t\treturn indexedResults\n\t\t\t\t}\n\t\t\t}\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text === operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/fields.js": {
"title": "$:/core/modules/filters/fields.js",
"text": "/*\\\ntitle: $:/core/modules/filters/fields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.fields = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName,\n\t\tsuffixes = (operator.suffixes || [])[0] || [],\n\t\toperand = $tw.utils.parseStringArray(operator.operand);\n\t\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tif(suffixes.indexOf(\"include\") !== -1) {\n\t\t\t\tfor(fieldName in tiddler.fields) {\n\t\t\t\t\t(operand.indexOf(fieldName) !== -1) ? $tw.utils.pushTop(results,fieldName) : \"\";\n\t\t\t\t}\n\t\t\t} else if (suffixes.indexOf(\"exclude\") !== -1) {\n\t\t\t\tfor(fieldName in tiddler.fields) {\n\t\t\t\t\t(operand.indexOf(fieldName) !== -1) ? \"\" : $tw.utils.pushTop(results,fieldName);\n\t\t\t\t}\n\t\t\t} // else if\n\t\t\telse {\n\t\t\t\tfor(fieldName in tiddler.fields) {\n\t\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t\t}\n\t\t\t} // else\n\t\t} // if (tiddler)\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/filter.js": {
"title": "$:/core/modules/filters/filter.js",
"text": "/*\\\ntitle: $:/core/modules/filters/filter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning those input titles that pass a subfilter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.filter = function(source,operator,options) {\n\tvar filterFn = options.wiki.compileFilter(operator.operand),\n\t\tresults = [],\n\t\ttarget = operator.prefix !== \"!\";\n\tsource(function(tiddler,title) {\n\t\tvar list = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]));\n\t\tif((list.length > 0) === target) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/format/date.js": {
"title": "$:/core/modules/filters/format/date.js",
"text": "/*\\\ntitle: $:/core/modules/filters/format/date.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.date = function(source,operand,options) {\n\tvar results = [];\t\n\tsource(function(tiddler,title) {\n\t\tvar value = $tw.utils.parseDate(title);\n\t\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\t\tresults.push($tw.utils.formatDateString(value,operand || \"YYYY MM DD 0hh:0mm\"));\n\t\t}\n\t});\t\n\treturn results;\n};\n\n})();",
"type": "application/javascript",
"module-type": "formatfilteroperator"
},
"$:/core/modules/filters/format/relativedate.js": {
"title": "$:/core/modules/filters/format/relativedate.js",
"text": "/*\\\ntitle: $:/core/modules/filters/format/relativedate.js\ntype: application/javascript\nmodule-type: formatfilteroperator\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.relativedate = function(source,operand,options) {\n\tvar results = [];\t\n\tsource(function(tiddler,title) {\n\t\tvar value = $tw.utils.parseDate(title);\n\t\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\t\tresults.push($tw.utils.getRelativeDate((new Date()) - (new Date(value))).description);\n\t\t}\n\t});\t\n\treturn results;\n};\n\n})();",
"type": "application/javascript",
"module-type": "formatfilteroperator"
},
"$:/core/modules/filters/format.js": {
"title": "$:/core/modules/filters/format.js",
"text": "/*\\\ntitle: $:/core/modules/filters/format.js\ntype: application/javascript\nmodule-type: filteroperator\nFilter operator for formatting strings\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar formatFilterOperators;\n\nfunction getFormatFilterOperators() {\n\tif(!formatFilterOperators) {\n\t\tformatFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"formatfilteroperator\",formatFilterOperators);\n\t}\n\treturn formatFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.format = function(source,operator,options) {\n\t// Dispatch to the correct formatfilteroperator\n\tvar formatFilterOperators = getFormatFilterOperators();\n\tif(operator.suffix) {\n\t\tvar formatFilterOperator = formatFilterOperators[operator.suffix];\n\t\tif(formatFilterOperator) {\n\t\t\treturn formatFilterOperator(source,operator.operand,options);\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/FormatFilterOperator\")];\n\t\t}\n\t} else {\n\t\t// Return all unchanged if the suffix is missing\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t}\n};\n\n})();",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/get.js": {
"title": "$:/core/modules/filters/get.js",
"text": "/*\\\ntitle: $:/core/modules/filters/get.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing tiddler titles by the value of the field specified in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.get = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tvar value = tiddler.getFieldString(operator.operand);\n\t\t\tif(value) {\n\t\t\t\tresults.push(value);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/getindex.js": {
"title": "$:/core/modules/filters/getindex.js",
"text": "/*\\\ntitle: $:/core/modules/filters/getindex.js\ntype: application/javascript\nmodule-type: filteroperator\n\nreturns the value at a given index of datatiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.getindex = function(source,operator,options) {\n\tvar data,title,results = [];\n\tif(operator.operand){\n\t\tsource(function(tiddler,title) {\n\t\t\ttitle = tiddler ? tiddler.fields.title : title;\n\t\t\tdata = options.wiki.extractTiddlerDataItem(tiddler,operator.operand);\n\t\t\tif(data) {\n\t\t\t\tresults.push(data);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/getvariable.js": {
"title": "$:/core/modules/filters/getvariable.js",
"text": "/*\\\ntitle: $:/core/modules/filters/getvariable.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing input values by the value of the variable with the same name, or blank if the variable is missing\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.getvariable = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.widget.getVariable(title) || \"\");\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/has.js": {
"title": "$:/core/modules/filters/has.js",
"text": "/*\\\ntitle: $:/core/modules/filters/has.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a tiddler has the specified field or index\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.has = function(source,operator,options) {\n\tvar results = [],\n\t\tinvert = operator.prefix === \"!\";\n\n\tif(operator.suffix === \"field\") {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand)))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\telse if(operator.suffix === \"index\") {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || (tiddler && (!$tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(options.wiki.getTiddlerDataCached(tiddler,Object.create(null)),operator.operand)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\telse {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand].length === 0)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && (tiddler.fields[operator.operand].length !== 0)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\t\t\t\t\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/haschanged.js": {
"title": "$:/core/modules/filters/haschanged.js",
"text": "/*\\\ntitle: $:/core/modules/filters/haschanged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returns tiddlers from the list that have a non-zero changecount.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.haschanged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) === 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) > 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/indexes.js": {
"title": "$:/core/modules/filters/indexes.js",
"text": "/*\\\ntitle: $:/core/modules/filters/indexes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the indexes of a data tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.indexes = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = options.wiki.getTiddlerDataCached(title);\n\t\tif(data) {\n\t\t\t$tw.utils.pushTop(results,Object.keys(data));\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/insertbefore.js": {
"title": "$:/core/modules/filters/insertbefore.js",
"text": "/*\\\ntitle: $:/core/modules/filters/insertbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nInsert an item before another item in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.insertbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar target = options.widget && options.widget.getVariable(operator.suffix || \"currentTiddler\");\n\tif(target !== operator.operand) {\n\t\t// Remove the entry from the list if it is present\n\t\tvar pos = results.indexOf(operator.operand);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,1);\n\t\t}\n\t\t// Insert the entry before the target marker\n\t\tpos = results.indexOf(target);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,0,operator.operand);\n\t\t} else {\n\t\t\tresults.push(operator.operand);\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/is/binary.js": {
"title": "$:/core/modules/filters/is/binary.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/binary.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[binary]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.binary = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isBinaryTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isBinaryTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/blank.js": {
"title": "$:/core/modules/filters/is/blank.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/blank.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[blank]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.blank = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!title) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/current.js": {
"title": "$:/core/modules/filters/is/current.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/current.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar results = [],\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title !== currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title === currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/draft.js": {
"title": "$:/core/modules/filters/is/draft.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/draft.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[draft]] analagous to [has[draft.of]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.draft = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!tiddler || !$tw.utils.hop(tiddler.fields,\"draft.of\")) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,\"draft.of\") && (tiddler.fields[\"draft.of\"].length !== 0)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\t\t\t\t\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/image.js": {
"title": "$:/core/modules/filters/is/image.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/image.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[image]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.image = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/missing.js": {
"title": "$:/core/modules/filters/is/missing.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/missing.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/orphan.js": {
"title": "$:/core/modules/filters/is/orphan.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/orphan.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[orphan]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphan = function(source,prefix,options) {\n\tvar results = [],\n\t\torphanTitles = options.wiki.getOrphanTitles();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) !== -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/shadow.js": {
"title": "$:/core/modules/filters/is/shadow.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/shadow.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[shadow]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadow = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/system.js": {
"title": "$:/core/modules/filters/is/system.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/system.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[system]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.system = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/tag.js": {
"title": "$:/core/modules/filters/is/tag.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/tag.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tag]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,prefix,options) {\n\tvar results = [],\n\t\ttagMap = options.wiki.getTagMap();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif($tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/tiddler.js": {
"title": "$:/core/modules/filters/is/tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/tiddler.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tiddler]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddler = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/variable.js": {
"title": "$:/core/modules/filters/is/variable.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/variable.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[variable]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.variable = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!(title in options.widget.variables)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title in options.widget.variables) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is.js": {
"title": "$:/core/modules/filters/is.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking tiddler properties\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar isFilterOperators;\n\nfunction getIsFilterOperators() {\n\tif(!isFilterOperators) {\n\t\tisFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"isfilteroperator\",isFilterOperators);\n\t}\n\treturn isFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.is = function(source,operator,options) {\n\t// Dispatch to the correct isfilteroperator\n\tvar isFilterOperators = getIsFilterOperators();\n\tif(operator.operand) {\n\t\tvar isFilterOperator = isFilterOperators[operator.operand];\n\t\tif(isFilterOperator) {\n\t\t\treturn isFilterOperator(source,operator.prefix,options);\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/IsFilterOperator\")];\n\t\t}\n\t} else {\n\t\t// Return all tiddlers if the operand is missing\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t}\n};\n\n})();",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/limit.js": {
"title": "$:/core/modules/filters/limit.js",
"text": "/*\\\ntitle: $:/core/modules/filters/limit.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for chopping the results to a specified maximum number of entries\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.limit = function(source,operator,options) {\n\tvar results = [];\n\t// Convert to an array\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\t// Slice the array if necessary\n\tvar limit = Math.min(results.length,parseInt(operator.operand,10));\n\tif(operator.prefix === \"!\") {\n\t\tresults = results.slice(-limit);\n\t} else {\n\t\tresults = results.slice(0,limit);\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/links.js": {
"title": "$:/core/modules/filters/links.js",
"text": "/*\\\ntitle: $:/core/modules/filters/links.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the links from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.links = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlerLinks(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/list.js": {
"title": "$:/core/modules/filters/list.js",
"text": "/*\\\ntitle: $:/core/modules/filters/list.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddlers whose title is listed in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.list = function(source,operator,options) {\n\tvar results = [],\n\t\ttr = $tw.utils.parseTextReference(operator.operand),\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\"),\n\t\tlist = options.wiki.getTiddlerList(tr.title || currTiddlerTitle,tr.field,tr.index);\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults = list;\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/listed.js": {
"title": "$:/core/modules/filters/listed.js",
"text": "/*\\\ntitle: $:/core/modules/filters/listed.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that have the selected tiddlers in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.listed = function(source,operator,options) {\n\tvar field = operator.operand || \"list\",\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.findListingsOfTiddler(title,field));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/listops.js": {
"title": "$:/core/modules/filters/listops.js",
"text": "/*\\\ntitle: $:/core/modules/filters/listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for manipulating the current selection list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.order = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.operand.toLowerCase() === \"reverse\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.unshift(title);\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t}\n\treturn results;\n};\n\n/*\nReverse list\n*/\nexports.reverse = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.unshift(title);\n\t});\n\treturn results;\n};\n\n/*\nFirst entry/entries in list\n*/\nexports.first = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,count);\n};\n\n/*\nLast entry/entries in list\n*/\nexports.last = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(-count);\n};\n\n/*\nAll but the first entry/entries of the list\n*/\nexports.rest = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count);\n};\nexports.butfirst = exports.rest;\nexports.bf = exports.rest;\n\n/*\nAll but the last entry/entries of the list\n*/\nexports.butlast = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,-count);\n};\nexports.bl = exports.butlast;\n\n/*\nThe nth member of the list\n*/\nexports.nth = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count - 1,count);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/lookup.js": {
"title": "$:/core/modules/filters/lookup.js",
"text": "/*\\\ntitle: $:/core/modules/filters/lookup.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that looks up values via a title prefix\n\n[lookup:<field>[<prefix>]]\n\nPrepends the prefix to the selected items and returns the specified field value\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.lookup = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.wiki.getTiddlerText(operator.operand + title) || operator.suffix);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/match.js": {
"title": "$:/core/modules/filters/match.js",
"text": "/*\\\ntitle: $:/core/modules/filters/match.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title matches a string\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.match = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = (operator.suffixes || [])[0] || [];\n\tif(suffixes.indexOf(\"caseinsensitive\") !== -1) {\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase() !== (operator.operand || \"\").toLowerCase()) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title.toLowerCase() === (operator.operand || \"\").toLowerCase()) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.prefix === \"!\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title !== operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(title === operator.operand) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/math.js": {
"title": "$:/core/modules/filters/math.js",
"text": "/*\\\ntitle: $:/core/modules/filters/math.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for math. Unary/binary operators work on each item in turn, and return a new item list.\n\nSum/product/maxall/minall operate on the entire list, returning a single item.\n\nNote that strings are converted to numbers automatically. Trailing non-digits are ignored.\n\n* \"\" converts to 0\n* \"12kk\" converts to 12\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.negate = makeNumericBinaryOperator(\n\tfunction(a) {return -a}\n);\n\nexports.abs = makeNumericBinaryOperator(\n\tfunction(a) {return Math.abs(a)}\n);\n\nexports.ceil = makeNumericBinaryOperator(\n\tfunction(a) {return Math.ceil(a)}\n);\n\nexports.floor = makeNumericBinaryOperator(\n\tfunction(a) {return Math.floor(a)}\n);\n\nexports.round = makeNumericBinaryOperator(\n\tfunction(a) {return Math.round(a)}\n);\n\nexports.trunc = makeNumericBinaryOperator(\n\tfunction(a) {return Math.trunc(a)}\n);\n\nexports.untrunc = makeNumericBinaryOperator(\n\tfunction(a) {return Math.ceil(Math.abs(a)) * Math.sign(a)}\n);\n\nexports.sign = makeNumericBinaryOperator(\n\tfunction(a) {return Math.sign(a)}\n);\n\nexports.add = makeNumericBinaryOperator(\n\tfunction(a,b) {return a + b;}\n);\n\nexports.subtract = makeNumericBinaryOperator(\n\tfunction(a,b) {return a - b;}\n);\n\nexports.multiply = makeNumericBinaryOperator(\n\tfunction(a,b) {return a * b;}\n);\n\nexports.divide = makeNumericBinaryOperator(\n\tfunction(a,b) {return a / b;}\n);\n\nexports.remainder = makeNumericBinaryOperator(\n\tfunction(a,b) {return a % b;}\n);\n\nexports.max = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.max(a,b);}\n);\n\nexports.min = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.min(a,b);}\n);\n\nexports.fixed = makeNumericBinaryOperator(\n\tfunction(a,b) {return Number.prototype.toFixed.call(a,Math.min(Math.max(b,0),100));}\n);\n\nexports.precision = makeNumericBinaryOperator(\n\tfunction(a,b) {return Number.prototype.toPrecision.call(a,Math.min(Math.max(b,1),100));}\n);\n\nexports.exponential = makeNumericBinaryOperator(\n\tfunction(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));}\n);\n\nexports.power = makeNumericBinaryOperator(\n\tfunction(a,b) {return Math.pow(a,b);}\n);\n\nexports.log = makeNumericBinaryOperator(\n\tfunction(a,b) {\n\t\tif(b) {\n\t\t\treturn Math.log(a)/Math.log(b);\n\t\t} else {\n\t\t\treturn Math.log(a);\n\t\t}\n\t}\n);\n\nexports.sum = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator + value},\n\t0 // Initial value\n);\n\nexports.product = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return accumulator * value},\n\t1 // Initial value\n);\n\nexports.maxall = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return Math.max(accumulator,value)},\n\t-Infinity // Initial value\n);\n\nexports.minall = makeNumericReducingOperator(\n\tfunction(accumulator,value) {return Math.min(accumulator,value)},\n\tInfinity // Initial value\n);\n\nfunction makeNumericBinaryOperator(fnCalc) {\n\treturn function(source,operator,options) {\n\t\tvar result = [],\n\t\t\tnumOperand = $tw.utils.parseNumber(operator.operand);\n\t\tsource(function(tiddler,title) {\n\t\t\tresult.push($tw.utils.stringifyNumber(fnCalc($tw.utils.parseNumber(title),numOperand)));\n\t\t});\n\t\treturn result;\n\t};\n}\n\nfunction makeNumericReducingOperator(fnCalc,initialValue) {\n\tinitialValue = initialValue || 0;\n\treturn function(source,operator,options) {\n\t\tvar result = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresult.push(title);\n\t\t});\n\t\treturn [$tw.utils.stringifyNumber(result.reduce(function(accumulator,currentValue) {\n\t\t\treturn fnCalc(accumulator,$tw.utils.parseNumber(currentValue));\n\t\t},initialValue))];\n\t};\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/minlength.js": {
"title": "$:/core/modules/filters/minlength.js",
"text": "/*\\\ntitle: $:/core/modules/filters/minlength.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for filtering out titles that don't meet the minimum length in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.minlength = function(source,operator,options) {\n\tvar results = [],\n\t\tminLength = parseInt(operator.operand || \"\",10) || 0;\n\tsource(function(tiddler,title) {\n\t\tif(title.length >= minLength) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/modules.js": {
"title": "$:/core/modules/filters/modules.js",
"text": "/*\\\ntitle: $:/core/modules/filters/modules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the modules of a given type in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.modules = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {\n\t\t\tresults.push(moduleName);\n\t\t});\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/moduletypes.js": {
"title": "$:/core/modules/filters/moduletypes.js",
"text": "/*\\\ntitle: $:/core/modules/filters/moduletypes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the module types in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.moduletypes = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.modules.types,function(moduleInfo,type) {\n\t\tresults.push(type);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/next.js": {
"title": "$:/core/modules/filters/next.js",
"text": "/*\\\ntitle: $:/core/modules/filters/next.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs next in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.next = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch++;\n\t\tif(match > 0 && match < list.length) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/plugintiddlers.js": {
"title": "$:/core/modules/filters/plugintiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/filters/plugintiddlers.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the shadow tiddlers within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.plugintiddlers = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerDataCached(title,{tiddlers:[]});\n\t\tif(pluginInfo && pluginInfo.tiddlers) {\n\t\t\t$tw.utils.each(pluginInfo.tiddlers,function(fields,title) {\n\t\t\t\tresults.push(title);\n\t\t\t});\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/prefix.js": {
"title": "$:/core/modules/filters/prefix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/prefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title starts with a prefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.prefix = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/previous.js": {
"title": "$:/core/modules/filters/previous.js",
"text": "/*\\\ntitle: $:/core/modules/filters/previous.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs immediately prior in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.previous = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch--;\n\t\tif(match >= 0) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/range.js": {
"title": "$:/core/modules/filters/range.js",
"text": "/*\\\ntitle: $:/core/modules/filters/range.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for generating a numeric range.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.range = function(source,operator,options) {\n\tvar results = [];\n\t// Split the operand into numbers delimited by these symbols\n\tvar parts = operator.operand.split(/[,:;]/g),\n\t\tbeg, end, inc, i, fixed = 0;\n\tfor (i=0; i<parts.length; i++) {\n\t\t// Validate real number\n\t\tif(!/^\\s*[+-]?((\\d+(\\.\\d*)?)|(\\.\\d+))\\s*$/.test(parts[i])) {\n\t\t\treturn [\"range: bad number \\\"\" + parts[i] + \"\\\"\"];\n\t\t}\n\t\t// Count digits; the most precise number determines decimal places in output.\n\t\tvar frac = /\\.\\d+/.exec(parts[i]);\n\t\tif(frac) {\n\t\t\tfixed = Math.max(fixed,frac[0].length-1);\n\t\t}\n\t\tparts[i] = parseFloat(parts[i]);\n\t}\n\tswitch(parts.length) {\n\t\tcase 1:\n\t\t\tend = parts[0];\n\t\t\tif (end >= 1) {\n\t\t\t\tbeg = 1;\n\t\t\t}\n\t\t\telse if (end <= -1) {\n\t\t\t\tbeg = -1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = Math.abs(parts[2]);\n\t\t\tbreak;\n\t}\n\tif(inc === 0) {\n\t\treturn [\"range: increment 0 causes infinite loop\"];\n\t}\n\t// May need to count backwards\n\tvar direction = ((end < beg) ? -1 : 1);\n\tinc *= direction;\n\t// Estimate number of resulting elements\n\tif((end - beg) / inc > 10000) {\n\t\treturn [\"range: too many steps (over 10K)\"];\n\t}\n\t// Avoid rounding error on last step\n\tend += direction * 0.5 * Math.pow(0.1,fixed);\n\tvar safety = 10010;\n\t// Enumerate the range\n\tif (end<beg) {\n\t\tfor(i=beg; i>end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor(i=beg; i<end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif(safety<0) {\n\t\treturn [\"range: unexpectedly large output\"];\n\t}\n\t// Reverse?\n\tif(operator.prefix === \"!\") {\n\t\tresults.reverse();\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/reduce.js": {
"title": "$:/core/modules/filters/reduce.js",
"text": "/*\\\ntitle: $:/core/modules/filters/reduce.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator evaluates a subfilter for each item, making the running total available in the variable `accumulator`, and the current index available in the variable `index`\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.reduce = function(source,operator,options) {\n\t// Accumulate the list\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\t// Run the filter over each item\n\tvar filterFn = options.wiki.compileFilter(operator.operand),\n\t\taccumulator = operator.operands[1] || \"\";\n\tfor(var index=0; index<results.length; index++) {\n\t\tvar title = results[index],\n\t\t\tlist = filterFn.call(options.wiki,options.wiki.makeTiddlerIterator([title]),{\n\t\t\t\tgetVariable: function(name) {\n\t\t\t\t\tswitch(name) {\n\t\t\t\t\t\tcase \"currentTiddler\":\n\t\t\t\t\t\t\treturn \"\" + title;\n\t\t\t\t\t\tcase \"accumulator\":\n\t\t\t\t\t\t\treturn \"\" + accumulator;\n\t\t\t\t\t\tcase \"index\":\n\t\t\t\t\t\t\treturn \"\" + index;\n\t\t\t\t\t\tcase \"revIndex\":\n\t\t\t\t\t\t\treturn \"\" + (results.length - 1 - index);\n\t\t\t\t\t\tcase \"length\":\n\t\t\t\t\t\t\treturn \"\" + results.length;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn options.widget.getVariable(name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\tif(list.length > 0) {\n\t\t\taccumulator = \"\" + list[0];\n\t\t}\n\t}\n\tif(results.length > 0) {\n\t\treturn [accumulator];\n\t} else {\n\t\treturn [];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/regexp.js": {
"title": "$:/core/modules/filters/regexp.js",
"text": "/*\\\ntitle: $:/core/modules/filters/regexp.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for regexp matching\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.regexp = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || \"title\").toLowerCase(),\n\t\tregexpString, regexp, flags = \"\", match,\n\t\tgetFieldString = function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\treturn tiddler.getFieldString(fieldname);\n\t\t\t} else if(fieldname === \"title\") {\n\t\t\t\treturn title;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\t// Process flags and construct regexp\n\tregexpString = operator.operand;\n\tmatch = /^\\(\\?([gim]+)\\)/.exec(regexpString);\n\tif(match) {\n\t\tflags = match[1];\n\t\tregexpString = regexpString.substr(match[0].length);\n\t} else {\n\t\tmatch = /\\(\\?([gim]+)\\)$/.exec(regexpString);\n\t\tif(match) {\n\t\t\tflags = match[1];\n\t\t\tregexpString = regexpString.substr(0,regexpString.length - match[0].length);\n\t\t}\n\t}\n\ttry {\n\t\tregexp = new RegExp(regexpString,flags);\n\t} catch(e) {\n\t\treturn [\"\" + e];\n\t}\n\t// Process the incoming tiddlers\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/removeprefix.js": {
"title": "$:/core/modules/filters/removeprefix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/removeprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a prefix from each title in the list. Titles that do not start with the prefix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removeprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\tresults.push(title.substr(operator.operand.length));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/removesuffix.js": {
"title": "$:/core/modules/filters/removesuffix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/removesuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a suffix from each title in the list. Titles that do not end with the suffix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removesuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title && title.substr(-operator.operand.length) === operator.operand) {\n\t\t\tresults.push(title.substr(0,title.length - operator.operand.length));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/sameday.js": {
"title": "$:/core/modules/filters/sameday.js",
"text": "/*\\\ntitle: $:/core/modules/filters/sameday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a modified date field on the same day as the provided value.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sameday = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\ttargetDate = (new Date($tw.utils.parseDate(operator.operand))).setHours(0,0,0,0);\n\t// Function to convert a date/time to a date integer\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tif(tiddler.getFieldDay(fieldName) === targetDate) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/search.js": {
"title": "$:/core/modules/filters/search.js",
"text": "/*\\\ntitle: $:/core/modules/filters/search.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for searching for the text in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.search = function(source,operator,options) {\n\tvar invert = operator.prefix === \"!\";\n\tif(operator.suffixes) {\n\t\tvar hasFlag = function(flag) {\n\t\t\t\treturn (operator.suffixes[1] || []).indexOf(flag) !== -1;\n\t\t\t},\n\t\t\texcludeFields = false,\n\t\t\tfieldList = operator.suffixes[0] || [],\n\t\t\tfirstField = fieldList[0] || \"\", \n\t\t\tfirstChar = firstField.charAt(0),\n\t\t\tfields;\n\t\tif(firstChar === \"-\") {\n\t\t\tfields = [firstField.slice(1)].concat(fieldList.slice(1));\n\t\t\texcludeFields = true;\n\t\t} else if(fieldList[0] === \"*\"){\n\t\t\tfields = [];\n\t\t\texcludeFields = true;\n\t\t} else {\n\t\t\tfields = fieldList.slice(0);\n\t\t}\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert,\n\t\t\tfield: fields,\n\t\t\texcludeField: excludeFields,\n\t\t\tcaseSensitive: hasFlag(\"casesensitive\"),\n\t\t\tliteral: hasFlag(\"literal\"),\n\t\t\twhitespace: hasFlag(\"whitespace\"),\n\t\t\tanchored: hasFlag(\"anchored\"),\n\t\t\tregexp: hasFlag(\"regexp\"),\n\t\t\twords: hasFlag(\"words\")\n\t\t});\n\t} else {\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert\n\t\t});\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/shadowsource.js": {
"title": "$:/core/modules/filters/shadowsource.js",
"text": "/*\\\ntitle: $:/core/modules/filters/shadowsource.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the source plugins for shadow tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadowsource = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar source = options.wiki.getShadowSource(title);\n\t\tif(source) {\n\t\t\t$tw.utils.pushTop(results,source);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/slugify.js": {
"title": "$:/core/modules/filters/slugify.js",
"text": "/*\\\ntitle: $:/core/modules/filters/slugify.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for slugifying a tiddler title\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.slugify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.wiki.slugify(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/sort.js": {
"title": "$:/core/modules/filters/sort.js",
"text": "/*\\\ntitle: $:/core/modules/filters/sort.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for sorting\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,false);\n\treturn results;\n};\n\nexports.nsort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,true);\n\treturn results;\n};\n\nexports.sortan = function(source, operator, options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results, operator.operand || \"title\", operator.prefix === \"!\",false,false,true);\n\treturn results;\n};\n\nexports.sortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,false);\n\treturn results;\n};\n\nexports.nsortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,true);\n\treturn results;\n};\n\nvar prepare_results = function (source) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/sortsub.js": {
"title": "$:/core/modules/filters/sortsub.js",
"text": "/*\\\ntitle: $:/core/modules/filters/sortsub.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for sorting by a subfilter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sortsub = function(source,operator,options) {\n\t// Compile the subfilter\n\tvar filterFn = options.wiki.compileFilter(operator.operand);\n\t// Collect the input titles and the corresponding sort keys\n\tvar inputTitles = [],\n\t\tsortKeys = [];\n\tsource(function(tiddler,title) {\n\t\tinputTitles.push(title);\n\t\tvar r = filterFn.call(options.wiki,function(iterator) {\n\t\t\titerator(options.wiki.getTiddler(title),title);\n\t\t},{\n\t\t\tgetVariable: function(name) {\n\t\t\t\tif(name === \"currentTiddler\") {\n\t\t\t\t\treturn title;\n\t\t\t\t} else {\n\t\t\t\t\treturn options.widget.getVariable(name);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tsortKeys.push(r[0] || \"\");\n\t});\n\t// Rather than sorting the titles array, we'll sort the indexes so that we can consult both arrays\n\tvar indexes = new Array(inputTitles.length);\n\tfor(var t=0; t<inputTitles.length; t++) {\n\t\tindexes[t] = t;\n\t}\n\t// Sort the indexes\n\tvar compareFn = $tw.utils.makeCompareFunction(operator.suffix,{defaultType: \"string\",invert: operator.prefix === \"!\"});\n\tindexes = indexes.sort(function(a,b) {\n\t\treturn compareFn(sortKeys[a],sortKeys[b]);\n\t});\n\t// Make the results array in order\n\tvar results = [];\n\t$tw.utils.each(indexes,function(index) {\n\t\tresults.push(inputTitles[index]);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/splitbefore.js": {
"title": "$:/core/modules/filters/splitbefore.js",
"text": "/*\\\ntitle: $:/core/modules/filters/splitbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that splits each result on the first occurance of the specified separator and returns the unique values.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.splitbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar parts = title.split(operator.operand);\n\t\tif(parts.length === 1) {\n\t\t\t$tw.utils.pushTop(results,parts[0]);\n\t\t} else {\n\t\t\t$tw.utils.pushTop(results,parts[0] + operator.operand);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/storyviews.js": {
"title": "$:/core/modules/filters/storyviews.js",
"text": "/*\\\ntitle: $:/core/modules/filters/storyviews.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the story views in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.storyviews = function(source,operator,options) {\n\tvar results = [],\n\t\tstoryviews = {};\n\t$tw.modules.applyMethods(\"storyview\",storyviews);\n\t$tw.utils.each(storyviews,function(info,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/strings.js": {
"title": "$:/core/modules/filters/strings.js",
"text": "/*\\\ntitle: $:/core/modules/filters/strings.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for strings. Unary/binary operators work on each item in turn, and return a new item list.\n\nSum/product/maxall/minall operate on the entire list, returning a single item.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.length = makeStringBinaryOperator(\n\tfunction(a) {return [\"\" + (\"\" + a).length];}\n);\n\nexports.uppercase = makeStringBinaryOperator(\n\tfunction(a) {return [(\"\" + a).toUpperCase()];}\n);\n\nexports.lowercase = makeStringBinaryOperator(\n\tfunction(a) {return [(\"\" + a).toLowerCase()];}\n);\n\nexports.sentencecase = makeStringBinaryOperator(\n\tfunction(a) {return [$tw.utils.toSentenceCase(a)];}\n);\n\nexports.titlecase = makeStringBinaryOperator(\n\tfunction(a) {return [$tw.utils.toTitleCase(a)];}\n);\n\nexports.trim = function(source,operator,options) {\n\tvar result = [],\n\t\tsuffix = operator.suffix || \"\",\n\t\toperand = (operator.operand || \"\"),\n\t\tfnCalc;\n\tif(suffix === \"prefix\") {\n\t\tfnCalc = function(a,b) {return [$tw.utils.trimPrefix(a,b)];}\n\t} else if(suffix === \"suffix\") {\n\t\tfnCalc = function(a,b) {return [$tw.utils.trimSuffix(a,b)];}\n\t} else {\n\t\tif(operand === \"\") {\n\t\t\tfnCalc = function(a) {return [$tw.utils.trim(a)];}\n\t\t} else {\n\t\t\tfnCalc = function(a,b) {return [$tw.utils.trimSuffix($tw.utils.trimPrefix(a,b),b)];}\n\t\t}\n\t}\n\tsource(function(tiddler,title) {\n\t\tArray.prototype.push.apply(result,fnCalc(title,operand));\n\t});\n\treturn result;\n};\n\nexports.split = makeStringBinaryOperator(\n\tfunction(a,b) {return (\"\" + a).split(b);}\n);\n\nexports[\"enlist-input\"] = makeStringBinaryOperator(\n\tfunction(a,o,s) {return $tw.utils.parseStringArray(\"\" + a,(s === \"raw\"));}\n);\n\nexports.join = makeStringReducingOperator(\n\tfunction(accumulator,value,operand) {\n\t\tif(accumulator === null) {\n\t\t\treturn value;\n\t\t} else {\n\t\t\treturn accumulator + operand + value;\n\t\t}\n\t},null\n);\n\nfunction makeStringBinaryOperator(fnCalc) {\n\treturn function(source,operator,options) {\n\t\tvar result = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tArray.prototype.push.apply(result,fnCalc(title,operator.operand || \"\",operator.suffix || \"\"));\n\t\t});\n\t\treturn result;\n\t};\n}\n\nfunction makeStringReducingOperator(fnCalc,initialValue) {\n\treturn function(source,operator,options) {\n\t\tvar result = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresult.push(title);\n\t\t});\n\t\tif(result.length === 0) {\n\t\t\treturn [];\n\t\t}\n\t\treturn [result.reduce(function(accumulator,currentValue) {\n\t\t\treturn fnCalc(accumulator,currentValue,operator.operand || \"\");\n\t\t},initialValue) || \"\"];\n\t};\n}\n\nexports.splitregexp = function(source,operator,options) {\n\tvar result = [],\n\t\tsuffix = operator.suffix || \"\",\n\t\tflags = (suffix.indexOf(\"m\") !== -1 ? \"m\" : \"\") + (suffix.indexOf(\"i\") !== -1 ? \"i\" : \"\"),\n\t\tregExp;\n\ttry {\n\t\tregExp = new RegExp(operator.operand || \"\",flags);\t\t\n\t} catch(ex) {\n\t\treturn [\"RegExp error: \" + ex];\n\t}\n\tsource(function(tiddler,title) {\n\t\tArray.prototype.push.apply(result,title.split(regExp));\n\t});\t\t\n\treturn result;\n};\n\nexports[\"search-replace\"] = function(source,operator,options) {\n\tvar results = [],\n\t\tsuffixes = operator.suffixes || [],\n\t\tflagSuffix = (suffixes[0] ? (suffixes[0][0] || \"\") : \"\"),\n\t\tflags = (flagSuffix.indexOf(\"g\") !== -1 ? \"g\" : \"\") + (flagSuffix.indexOf(\"i\") !== -1 ? \"i\" : \"\"),\n\t\tisRegExp = (suffixes[1] && suffixes[1][0] === \"regexp\") ? true : false,\n\t\tsearchTerm,\n\t\tregExp;\n\t\n\tsource(function(tiddler,title) {\n\t\tif(title && (operator.operands.length > 1)) {\n\t\t\t//Escape regexp characters if the operand is not a regular expression\n\t\t\tsearchTerm = isRegExp ? operator.operand : $tw.utils.escapeRegExp(operator.operand);\n\t\t\ttry {\n\t\t\t\tregExp = new RegExp(searchTerm,flags);\n\t\t\t} catch(ex) {\n\t\t\t\treturn [\"RegExp error: \" + ex];\n\t\t\t}\n\t\t\tresults.push(\n\t\t\t\ttitle.replace(regExp,operator.operands[1])\n\t\t\t);\n\t\t} else {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\nexports.pad = function(source,operator,options) {\n\tvar results = [],\n\t\ttargetLength = operator.operand ? parseInt(operator.operand) : 0,\n\t\tfill = operator.operands[1] || \"0\";\n\n\tsource(function(tiddler,title) {\n\t\tif(title && title.length) {\n\t\t\tif(title.length >= targetLength) {\n\t\t\t\tresults.push(title);\n\t\t\t} else {\n\t\t\t\tvar padString = \"\",\n\t\t\t\t\tpadStringLength = targetLength - title.length;\n\t\t\t\twhile (padStringLength > padString.length) {\n\t\t\t\t\tpadString += fill;\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t//make sure we do not exceed the specified length\n\t\t\t\tpadString = padString.slice(0,padStringLength);\n\t\t\t\tif(operator.suffix && (operator.suffix === \"suffix\")) {\n\t\t\t\t\ttitle = title + padString;\n\t\t\t\t} else {\n\t\t\t\t\ttitle = padString + title;\n\t\t\t\t}\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/subfilter.js": {
"title": "$:/core/modules/filters/subfilter.js",
"text": "/*\\\ntitle: $:/core/modules/filters/subfilter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand evaluated as a filter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subfilter = function(source,operator,options) {\n\tvar list = options.wiki.filterTiddlers(operator.operand,options.widget,source);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/subtiddlerfields.js": {
"title": "$:/core/modules/filters/subtiddlerfields.js",
"text": "/*\\\ntitle: $:/core/modules/filters/subtiddlerfields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected subtiddlers of the plugin named in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subtiddlerfields = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar subtiddler = options.wiki.getSubTiddler(operator.operand,title);\n\t\tif(subtiddler) {\n\t\t\tfor(var fieldName in subtiddler.fields) {\n\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/suffix.js": {
"title": "$:/core/modules/filters/suffix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/suffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title ends with a suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.suffix = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(-operator.operand.length) !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(-operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/tag.js": {
"title": "$:/core/modules/filters/tag.js",
"text": "/*\\\ntitle: $:/core/modules/filters/tag.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking for the presence of a tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,operator,options) {\n\tvar results = [],indexedResults;\n\tif((operator.suffix || \"\").toLowerCase() === \"strict\" && !operator.operand) {\n\t\t// New semantics:\n\t\t// Always return copy of input if operator.operand is missing\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t} else {\n\t\t// Old semantics:\n\t\tvar tiddlers;\n\t\tif(operator.prefix === \"!\") {\n\t\t\t// Returns a copy of the input if operator.operand is missing\n\t\t\ttiddlers = options.wiki.getTiddlersWithTag(operator.operand);\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddlers.indexOf(title) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// Returns empty results if operator.operand is missing\n\t\t\tif(source.byTag) {\n\t\t\t\tindexedResults = source.byTag(operator.operand);\n\t\t\t\tif(indexedResults) {\n\t\t\t\t\treturn indexedResults;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttiddlers = options.wiki.getTiddlersWithTag(operator.operand);\n\t\t\t\tsource(function(tiddler,title) {\n\t\t\t\t\tif(tiddlers.indexOf(title) !== -1) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tresults = options.wiki.sortByList(results,operator.operand);\n\t\t\t}\n\t\t}\t\t\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/tagging.js": {
"title": "$:/core/modules/filters/tagging.js",
"text": "/*\\\ntitle: $:/core/modules/filters/tagging.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that are tagged with the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tagging = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/tags.js": {
"title": "$:/core/modules/filters/tags.js",
"text": "/*\\\ntitle: $:/core/modules/filters/tags.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the tags of the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,operator,options) {\n\tvar tags = {};\n\tsource(function(tiddler,title) {\n\t\tvar t, length;\n\t\tif(tiddler && tiddler.fields.tags) {\n\t\t\tfor(t=0, length=tiddler.fields.tags.length; t<length; t++) {\n\t\t\t\ttags[tiddler.fields.tags[t]] = true;\n\t\t\t}\n\t\t}\n\t});\n\treturn Object.keys(tags);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/then.js": {
"title": "$:/core/modules/filters/then.js",
"text": "/*\\\ntitle: $:/core/modules/filters/then.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing any titles with a constant\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.then = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(operator.operand);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/title.js": {
"title": "$:/core/modules/filters/title.js",
"text": "/*\\\ntitle: $:/core/modules/filters/title.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing title fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.title = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields.title !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults.push(operator.operand);\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/untagged.js": {
"title": "$:/core/modules/filters/untagged.js",
"text": "/*\\\ntitle: $:/core/modules/filters/untagged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the selected tiddlers that are untagged\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.untagged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) {\n\t\t\t\t$tw.utils.pushTop(results,title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!tiddler || !tiddler.hasField(\"tags\") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {\n\t\t\t\t$tw.utils.pushTop(results,title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/variables.js": {
"title": "$:/core/modules/filters/variables.js",
"text": "/*\\\ntitle: $:/core/modules/filters/variables.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the active variables\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.variables = function(source,operator,options) {\n\tvar names = [];\n\tfor(var variable in options.widget.variables) {\n\t\tnames.push(variable);\n\t}\n\treturn names.sort();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/wikiparserrules.js": {
"title": "$:/core/modules/filters/wikiparserrules.js",
"text": "/*\\\ntitle: $:/core/modules/filters/wikiparserrules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the wiki parser rules in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.wikiparserrules = function(source,operator,options) {\n\tvar results = [],\n\t\toperand = operator.operand;\n\t$tw.utils.each($tw.modules.types.wikirule,function(mod) {\n\t\tvar exp = mod.exports;\n\t\tif(!operand || exp.types[operand]) {\n\t\t\tresults.push(exp.name);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/x-listops.js": {
"title": "$:/core/modules/filters/x-listops.js",
"text": "/*\\\ntitle: $:/core/modules/filters/x-listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nExtended filter operators to manipulate the current list.\n\n\\*/\n(function () {\n\n\t/*jslint node: true, browser: true */\n\t/*global $tw: false */\n\t\"use strict\";\n\n\t/*\n\tFetch titles from the current list\n\t*/\n\tvar prepare_results = function (source) {\n\tvar results = [];\n\t\tsource(function (tiddler, title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t};\n\n\t/*\n\tMoves a number of items from the tail of the current list before the item named in the operand\n\t*/\n\texports.putbefore = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn (index === -1) ?\n\t\t\tresults.slice(0, -1) :\n\t\t\tresults.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));\n\t};\n\n\t/*\n\tMoves a number of items from the tail of the current list after the item named in the operand\n\t*/\n\texports.putafter = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn (index === -1) ?\n\t\t\tresults.slice(0, -1) :\n\t\t\tresults.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n\t};\n\n\t/*\n\tReplaces the item named in the operand with a number of items from the tail of the current list\n\t*/\n\texports.replace = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn (index === -1) ?\n\t\t\tresults.slice(0, -count) :\n\t\t\tresults.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n\t};\n\n\t/*\n\tMoves a number of items from the tail of the current list to the head of the list\n\t*/\n\texports.putfirst = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn results.slice(-count).concat(results.slice(0, -count));\n\t};\n\n\t/*\n\tMoves a number of items from the head of the current list to the tail of the list\n\t*/\n\texports.putlast = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1);\n\t\treturn results.slice(count).concat(results.slice(0, count));\n\t};\n\n\t/*\n\tMoves the item named in the operand a number of places forward or backward in the list\n\t*/\n\texports.move = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,1),\n\t\t\tmarker = results.splice(index, 1),\n\t\t\toffset = (index + count) > 0 ? index + count : 0;\n\t\treturn results.slice(0, offset).concat(marker).concat(results.slice(offset));\n\t};\n\n\t/*\n\tReturns the items from the current list that are after the item named in the operand\n\t*/\n\texports.allafter = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand);\n\t\treturn (index === -1) ? [] :\n\t\t\t(operator.suffix) ? results.slice(index) :\n\t\t\tresults.slice(index + 1);\n\t};\n\n\t/*\n\tReturns the items from the current list that are before the item named in the operand\n\t*/\n\texports.allbefore = function (source, operator) {\n\t\tvar results = prepare_results(source),\n\t\t\tindex = results.indexOf(operator.operand);\n\t\treturn (index === -1) ? [] :\n\t\t\t(operator.suffix) ? results.slice(0, index + 1) :\n\t\t\tresults.slice(0, index);\n\t};\n\n\t/*\n\tAppends the items listed in the operand array to the tail of the current list\n\t*/\n\texports.append = function (source, operator) {\n\t\tvar append = $tw.utils.parseStringArray(operator.operand, \"true\"),\n\t\t\tresults = prepare_results(source),\n\t\t\tcount = parseInt(operator.suffix) || append.length;\n\t\treturn (append.length === 0) ? results :\n\t\t\t(operator.prefix) ? results.concat(append.slice(-count)) :\n\t\t\tresults.concat(append.slice(0, count));\n\t};\n\n\t/*\n\tPrepends the items listed in the operand array to the head of the current list\n\t*/\n\texports.prepend = function (source, operator) {\n\t\tvar prepend = $tw.utils.parseStringArray(operator.operand, \"true\"),\n\t\t\tresults = prepare_results(source),\n\t\t\tcount = $tw.utils.getInt(operator.suffix,prepend.length);\n\t\treturn (prepend.length === 0) ? results :\n\t\t\t(operator.prefix) ? prepend.slice(-count).concat(results) :\n\t\t\tprepend.slice(0, count).concat(results);\n\t};\n\n\t/*\n\tReturns all items from the current list except the items listed in the operand array\n\t*/\n\texports.remove = function (source, operator) {\n\t\tvar array = $tw.utils.parseStringArray(operator.operand, \"true\"),\n\t\t\tresults = prepare_results(source),\n\t\t\tcount = parseInt(operator.suffix) || array.length,\n\t\t\tp,\n\t\t\tlen,\n\t\t\tindex;\n\t\tlen = array.length - 1;\n\t\tfor (p = 0; p < count; ++p) {\n\t\t\tif (operator.prefix) {\n\t\t\t\tindex = results.indexOf(array[len - p]);\n\t\t\t} else {\n\t\t\t\tindex = results.indexOf(array[p]);\n\t\t\t}\n\t\t\tif (index !== -1) {\n\t\t\t\tresults.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t};\n\n\t/*\n\tReturns all items from the current list sorted in the order of the items in the operand array\n\t*/\n\texports.sortby = function (source, operator) {\n\t\tvar results = prepare_results(source);\n\t\tif (!results || results.length < 2) {\n\t\t\treturn results;\n\t\t}\n\t\tvar lookup = $tw.utils.parseStringArray(operator.operand, \"true\");\n\t\tresults.sort(function (a, b) {\n\t\t\treturn lookup.indexOf(a) - lookup.indexOf(b);\n\t\t});\n\t\treturn results;\n\t};\n\n\t/*\n\tRemoves all duplicate items from the current list\n\t*/\n\texports.unique = function (source, operator) {\n\t\tvar results = prepare_results(source);\n\t\tvar set = results.reduce(function (a, b) {\n\t\t\tif (a.indexOf(b) < 0) {\n\t\t\t\ta.push(b);\n\t\t\t}\n\t\t\treturn a;\n\t\t}, []);\n\t\treturn set;\n\t};\n\n\tvar cycleValueInArray = function(results,operands,stepSize) {\n\t\tvar resultsIndex,\n\t\t\tstep = stepSize || 1,\n\t\t\ti = 0,\n\t\t\topLength = operands.length,\n\t\t\tnextOperandIndex;\t\t\n\t\tfor(i; i < opLength; i++) {\n\t\t\tresultsIndex = results.indexOf(operands[i]);\n\t\t\tif(resultsIndex !== -1) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(resultsIndex !== -1) {\n\t\t\ti = i + step;\n\t\t\tnextOperandIndex = (i < opLength ? i : i - opLength);\n\t\t\tif(operands.length > 1) {\n\t\t\t\tresults.splice(resultsIndex,1,operands[nextOperandIndex]);\n\t\t\t} else {\n\t\t\t\tresults.splice(resultsIndex,1);\n\t\t\t}\n\t\t} else {\n\t\t\tresults.push(operands[0]);\n\t\t}\n\t\treturn results;\t\t\n\t}\n\n\t/*\n\tToggles an item in the current list.\n\t*/\t\n\texports.toggle = function(source,operator) {\n\t\treturn cycleValueInArray(prepare_results(source),operator.operands);\n\t}\n\n\texports.cycle = function(source,operator) {\n\t\tvar results = prepare_results(source),\n\t\t\toperands = (operator.operand.length ? $tw.utils.parseStringArray(operator.operand, \"true\") : [\"\"]),\n\t\t\tstep = $tw.utils.getInt(operator.operands[1]||\"\",1);\n\t\tif(step < 0) {\n\t\t\toperands.reverse();\n\t\t\tstep = Math.abs(step);\n\t\t}\t\n\t\treturn cycleValueInArray(results,operands,step);\n\t}\n\t\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters.js": {
"title": "$:/core/modules/filters.js",
"text": "/*\\\ntitle: $:/core/modules/filters.js\ntype: application/javascript\nmodule-type: wikimethod\n\nAdds tiddler filtering methods to the $tw.Wiki object.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParses an operation (i.e. a run) within a filter string\n\toperators: Array of array of operator nodes into which results should be inserted\n\tfilterString: filter string\n\tp: start position within the string\nReturns the new start position, after the parsed operation\n*/\nfunction parseFilterOperation(operators,filterString,p) {\n\tvar nextBracketPos, operator;\n\t// Skip the starting square bracket\n\tif(filterString.charAt(p++) !== \"[\") {\n\t\tthrow \"Missing [ in filter expression\";\n\t}\n\t// Process each operator in turn\n\tdo {\n\t\toperator = {};\n\t\t// Check for an operator prefix\n\t\tif(filterString.charAt(p) === \"!\") {\n\t\t\toperator.prefix = filterString.charAt(p++);\n\t\t}\n\t\t// Get the operator name\n\t\tnextBracketPos = filterString.substring(p).search(/[\\[\\{<\\/]/);\n\t\tif(nextBracketPos === -1) {\n\t\t\tthrow \"Missing [ in filter expression\";\n\t\t}\n\t\tnextBracketPos += p;\n\t\tvar bracket = filterString.charAt(nextBracketPos);\n\t\toperator.operator = filterString.substring(p,nextBracketPos);\n\t\t// Any suffix?\n\t\tvar colon = operator.operator.indexOf(':');\n\t\tif(colon > -1) {\n\t\t\t// The raw suffix for older filters\n\t\t\toperator.suffix = operator.operator.substring(colon + 1);\n\t\t\toperator.operator = operator.operator.substring(0,colon) || \"field\";\n\t\t\t// The processed suffix for newer filters\n\t\t\toperator.suffixes = [];\n\t\t\t$tw.utils.each(operator.suffix.split(\":\"),function(subsuffix) {\n\t\t\t\toperator.suffixes.push([]);\n\t\t\t\t$tw.utils.each(subsuffix.split(\",\"),function(entry) {\n\t\t\t\t\tentry = $tw.utils.trim(entry);\n\t\t\t\t\tif(entry) {\n\t\t\t\t\t\toperator.suffixes[operator.suffixes.length - 1].push(entry); \n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\t// Empty operator means: title\n\t\telse if(operator.operator === \"\") {\n\t\t\toperator.operator = \"title\";\n\t\t}\n\t\toperator.operands = [];\n\t\tfunction parseOperand(bracketType) {\n\t\t\tvar operand = {};\n\t\t\tswitch (bracketType) {\n\t\t\t\tcase \"{\": // Curly brackets\n\t\t\t\t\toperand.indirect = true;\n\t\t\t\t\tnextBracketPos = filterString.indexOf(\"}\",p);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"[\": // Square brackets\n\t\t\t\t\tnextBracketPos = filterString.indexOf(\"]\",p);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"<\": // Angle brackets\n\t\t\t\t\toperand.variable = true;\n\t\t\t\t\tnextBracketPos = filterString.indexOf(\">\",p);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"/\": // regexp brackets\n\t\t\t\t\tvar rex = /^((?:[^\\\\\\/]*|\\\\.)*)\\/(?:\\(([mygi]+)\\))?/g,\n\t\t\t\t\t\trexMatch = rex.exec(filterString.substring(p));\n\t\t\t\t\tif(rexMatch) {\n\t\t\t\t\t\toperator.regexp = new RegExp(rexMatch[1], rexMatch[2]);\n\t// DEPRECATION WARNING\n\tconsole.log(\"WARNING: Filter\",operator.operator,\"has a deprecated regexp operand\",operator.regexp);\n\t\t\t\t\t\tnextBracketPos = p + rex.lastIndex - 1;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthrow \"Unterminated regular expression in filter expression\";\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(nextBracketPos === -1) {\n\t\t\t\tthrow \"Missing closing bracket in filter expression\";\n\t\t\t}\n\t\t\tif(!operator.regexp) {\n\t\t\t\toperand.text = filterString.substring(p,nextBracketPos);\n\t\t\t\toperator.operands.push(operand);\n\t\t\t}\n\t\t\tp = nextBracketPos + 1;\n\t\t}\n\t\t\n\t\tp = nextBracketPos + 1;\n\t\tparseOperand(bracket);\n\t\t\n\t\t// Check for multiple operands\n\t\twhile(filterString.charAt(p) === \",\") {\n\t\t\tp++;\n\t\t\tif(/^[\\[\\{<\\/]/.test(filterString.substring(p))) {\n\t\t\t\tnextBracketPos = p;\n\t\t\t\tp++;\n\t\t\t\tparseOperand(filterString.charAt(nextBracketPos));\n\t\t\t} else {\n\t\t\t\tthrow \"Missing [ in filter expression\";\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Push this operator\n\t\toperators.push(operator);\n\t} while(filterString.charAt(p) !== \"]\");\n\t// Skip the ending square bracket\n\tif(filterString.charAt(p++) !== \"]\") {\n\t\tthrow \"Missing ] in filter expression\";\n\t}\n\t// Return the parsing position\n\treturn p;\n}\n\n/*\nParse a filter string\n*/\nexports.parseFilter = function(filterString) {\n\tfilterString = filterString || \"\";\n\tvar results = [], // Array of arrays of operator nodes {operator:,operand:}\n\t\tp = 0, // Current position in the filter string\n\t\tmatch;\n\tvar whitespaceRegExp = /(\\s+)/mg,\n\t\toperandRegExp = /((?:\\+|\\-|~|=|\\:(\\w+))?)(?:(\\[)|(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s\\[\\]]+))/mg;\n\twhile(p < filterString.length) {\n\t\t// Skip any whitespace\n\t\twhitespaceRegExp.lastIndex = p;\n\t\tmatch = whitespaceRegExp.exec(filterString);\n\t\tif(match && match.index === p) {\n\t\t\tp = p + match[0].length;\n\t\t}\n\t\t// Match the start of the operation\n\t\tif(p < filterString.length) {\n\t\t\toperandRegExp.lastIndex = p;\n\t\t\tmatch = operandRegExp.exec(filterString);\n\t\t\tif(!match || match.index !== p) {\n\t\t\t\tthrow $tw.language.getString(\"Error/FilterSyntax\");\n\t\t\t}\n\t\t\tvar operation = {\n\t\t\t\tprefix: \"\",\n\t\t\t\toperators: []\n\t\t\t};\n\t\t\tif(match[1]) {\n\t\t\t\toperation.prefix = match[1];\n\t\t\t\tp = p + operation.prefix.length;\n\t\t\t\tif(match[2]) {\n\t\t\t\t\toperation.namedPrefix = match[2];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(match[3]) { // Opening square bracket\n\t\t\t\tp = parseFilterOperation(operation.operators,filterString,p);\n\t\t\t} else {\n\t\t\t\tp = match.index + match[0].length;\n\t\t\t}\n\t\t\tif(match[4] || match[5] || match[6]) { // Double quoted string, single quoted string or unquoted title\n\t\t\t\toperation.operators.push(\n\t\t\t\t\t{operator: \"title\", operands: [{text: match[4] || match[5] || match[6]}]}\n\t\t\t\t);\n\t\t\t}\n\t\t\tresults.push(operation);\n\t\t}\n\t}\n\treturn results;\n};\n\nexports.getFilterOperators = function() {\n\tif(!this.filterOperators) {\n\t\t$tw.Wiki.prototype.filterOperators = {};\n\t\t$tw.modules.applyMethods(\"filteroperator\",this.filterOperators);\n\t}\n\treturn this.filterOperators;\n};\n\nexports.getFilterRunPrefixes = function() {\n\tif(!this.filterRunPrefixes) {\n\t\t$tw.Wiki.prototype.filterRunPrefixes = {};\n\t\t$tw.modules.applyMethods(\"filterrunprefix\",this.filterRunPrefixes);\n\t}\n\treturn this.filterRunPrefixes;\n}\n\nexports.filterTiddlers = function(filterString,widget,source) {\n\tvar fn = this.compileFilter(filterString);\n\treturn fn.call(this,source,widget);\n};\n\n/*\nCompile a filter into a function with the signature fn(source,widget) where:\nsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\nwidget: an optional widget node for retrieving the current tiddler etc.\n*/\nexports.compileFilter = function(filterString) {\n\tvar filterParseTree;\n\ttry {\n\t\tfilterParseTree = this.parseFilter(filterString);\n\t} catch(e) {\n\t\treturn function(source,widget) {\n\t\t\treturn [$tw.language.getString(\"Error/Filter\") + \": \" + e];\n\t\t};\n\t}\n\t// Get the hashmap of filter operator functions\n\tvar filterOperators = this.getFilterOperators();\n\t// Assemble array of functions, one for each operation\n\tvar operationFunctions = [];\n\t// Step through the operations\n\tvar self = this;\n\t$tw.utils.each(filterParseTree,function(operation) {\n\t\t// Create a function for the chain of operators in the operation\n\t\tvar operationSubFunction = function(source,widget) {\n\t\t\tvar accumulator = source,\n\t\t\t\tresults = [],\n\t\t\t\tcurrTiddlerTitle = widget && widget.getVariable(\"currentTiddler\");\n\t\t\t$tw.utils.each(operation.operators,function(operator) {\n\t\t\t\tvar operands = [],\n\t\t\t\t\toperatorFunction;\n\t\t\t\tif(!operator.operator) {\n\t\t\t\t\toperatorFunction = filterOperators.title;\n\t\t\t\t} else if(!filterOperators[operator.operator]) {\n\t\t\t\t\toperatorFunction = filterOperators.field;\n\t\t\t\t} else {\n\t\t\t\t\toperatorFunction = filterOperators[operator.operator];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t$tw.utils.each(operator.operands,function(operand) {\n\t\t\t\t\tif(operand.indirect) {\n\t\t\t\t\t\toperand.value = self.getTextReference(operand.text,\"\",currTiddlerTitle);\n\t\t\t\t\t} else if(operand.variable) {\n\t\t\t\t\t\toperand.value = widget.getVariable(operand.text,{defaultValue: \"\"});\n\t\t\t\t\t} else {\n\t\t\t\t\t\toperand.value = operand.text;\n\t\t\t\t\t}\n\t\t\t\t\toperands.push(operand.value);\n\t\t\t\t});\n\n\t\t\t\t// Invoke the appropriate filteroperator module\n\t\t\t\tresults = operatorFunction(accumulator,{\n\t\t\t\t\t\t\toperator: operator.operator,\n\t\t\t\t\t\t\toperand: operands.length > 0 ? operands[0] : undefined,\n\t\t\t\t\t\t\toperands: operands,\n\t\t\t\t\t\t\tprefix: operator.prefix,\n\t\t\t\t\t\t\tsuffix: operator.suffix,\n\t\t\t\t\t\t\tsuffixes: operator.suffixes,\n\t\t\t\t\t\t\tregexp: operator.regexp\n\t\t\t\t\t\t},{\n\t\t\t\t\t\t\twiki: self,\n\t\t\t\t\t\t\twidget: widget\n\t\t\t\t\t\t});\n\t\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\t\taccumulator = self.makeTiddlerIterator(results);\n\t\t\t\t} else {\n\t\t\t\t\taccumulator = results;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\treturn results;\n\t\t\t} else {\n\t\t\t\tvar resultArray = [];\n\t\t\t\tresults(function(tiddler,title) {\n\t\t\t\t\tresultArray.push(title);\n\t\t\t\t});\n\t\t\t\treturn resultArray;\n\t\t\t}\n\t\t};\n\t\tvar filterRunPrefixes = self.getFilterRunPrefixes();\n\t\t// Wrap the operator functions in a wrapper function that depends on the prefix\n\t\toperationFunctions.push((function() {\n\t\t\tvar options = {wiki: self};\n\t\t\tswitch(operation.prefix || \"\") {\n\t\t\t\tcase \"\": // No prefix means that the operation is unioned into the result\n\t\t\t\t\treturn filterRunPrefixes[\"or\"](operationSubFunction, options);\n\t\t\t\tcase \"=\": // The results of the operation are pushed into the result without deduplication\n\t\t\t\t\treturn filterRunPrefixes[\"all\"](operationSubFunction, options);\n\t\t\t\tcase \"-\": // The results of this operation are removed from the main result\n\t\t\t\t\treturn filterRunPrefixes[\"except\"](operationSubFunction, options);\n\t\t\t\tcase \"+\": // This operation is applied to the main results so far\n\t\t\t\t\treturn filterRunPrefixes[\"and\"](operationSubFunction, options);\n\t\t\t\tcase \"~\": // This operation is unioned into the result only if the main result so far is empty\n\t\t\t\t\treturn filterRunPrefixes[\"else\"](operationSubFunction, options);\n\t\t\t\tdefault: \n\t\t\t\t\tif(operation.namedPrefix && filterRunPrefixes[operation.namedPrefix]) {\n\t\t\t\t\t\treturn filterRunPrefixes[operation.namedPrefix](operationSubFunction, options);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t\tresults.clear();\n\t\t\t\t\t\t\tresults.push($tw.language.getString(\"Error/FilterRunPrefix\"));\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t}\n\t\t})());\n\t});\n\t// Return a function that applies the operations to a source iterator of tiddler titles\n\treturn $tw.perf.measure(\"filter: \" + filterString,function filterFunction(source,widget) {\n\t\tif(!source) {\n\t\t\tsource = self.each;\n\t\t} else if(typeof source === \"object\") { // Array or hashmap\n\t\t\tsource = self.makeTiddlerIterator(source);\n\t\t}\n\t\tvar results = new $tw.utils.LinkedList();\n\t\t$tw.utils.each(operationFunctions,function(operationFunction) {\n\t\t\toperationFunction(results,source,widget);\n\t\t});\n\t\treturn results.toArray();\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikimethod"
},
"$:/core/modules/indexers/backlinks-indexer.js": {
"title": "$:/core/modules/indexers/backlinks-indexer.js",
"text": "/*\\\ntitle: $:/core/modules/indexers/backlinks-indexer.js\ntype: application/javascript\nmodule-type: indexer\n\nIndexes the tiddlers' backlinks\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global modules: false */\n\"use strict\";\n\n\nfunction BacklinksIndexer(wiki) {\n\tthis.wiki = wiki;\n}\n\nBacklinksIndexer.prototype.init = function() {\n\tthis.index = null;\n}\n\nBacklinksIndexer.prototype.rebuild = function() {\n\tthis.index = null;\n}\n\nBacklinksIndexer.prototype._getLinks = function(tiddler) {\n\tvar parser = this.wiki.parseText(tiddler.fields.type, tiddler.fields.text, {});\n\tif(parser) {\n\t\treturn this.wiki.extractLinks(parser.tree);\n\t}\n\treturn [];\n}\n\nBacklinksIndexer.prototype.update = function(updateDescriptor) {\n\tif(!this.index) {\n\t\treturn;\n\t}\n\tvar newLinks = [],\n\t oldLinks = [],\n\t self = this;\n\tif(updateDescriptor.old.exists) {\n\t\toldLinks = this._getLinks(updateDescriptor.old.tiddler);\n\t}\n\tif(updateDescriptor.new.exists) {\n\t\tnewLinks = this._getLinks(updateDescriptor.new.tiddler);\n\t}\n\n\t$tw.utils.each(oldLinks,function(link) {\n\t\tif(self.index[link]) {\n\t\t\tdelete self.index[link][updateDescriptor.old.tiddler.fields.title];\n\t\t}\n\t});\n\t$tw.utils.each(newLinks,function(link) {\n\t\tif(!self.index[link]) {\n\t\t\tself.index[link] = Object.create(null);\n\t\t}\n\t\tself.index[link][updateDescriptor.new.tiddler.fields.title] = true;\n\t});\n}\n\nBacklinksIndexer.prototype.lookup = function(title) {\n\tif(!this.index) {\n\t\tthis.index = Object.create(null);\n\t\tvar self = this;\n\t\tthis.wiki.forEachTiddler(function(title,tiddler) {\n\t\t\tvar links = self._getLinks(tiddler);\n\t\t\t$tw.utils.each(links, function(link) {\n\t\t\t\tif(!self.index[link]) {\n\t\t\t\t\tself.index[link] = Object.create(null);\n\t\t\t\t}\n\t\t\t\tself.index[link][title] = true;\n\t\t\t});\n\t\t});\n\t}\n\tif(this.index[title]) {\n\t\treturn Object.keys(this.index[title]);\n\t} else {\n\t\treturn [];\n\t}\n}\n\nexports.BacklinksIndexer = BacklinksIndexer;\n\n})();\n",
"type": "application/javascript",
"module-type": "indexer"
},
"$:/core/modules/indexers/field-indexer.js": {
"title": "$:/core/modules/indexers/field-indexer.js",
"text": "/*\\\ntitle: $:/core/modules/indexers/field-indexer.js\ntype: application/javascript\nmodule-type: indexer\n\nIndexes the tiddlers with each field value\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global modules: false */\n\"use strict\";\n\nvar DEFAULT_MAXIMUM_INDEXED_VALUE_LENGTH = 128;\n\nfunction FieldIndexer(wiki) {\n\tthis.wiki = wiki;\n}\n\nFieldIndexer.prototype.init = function() {\n\tthis.index = null;\n\tthis.maxIndexedValueLength = DEFAULT_MAXIMUM_INDEXED_VALUE_LENGTH;\n\tthis.addIndexMethods();\n}\n\n// Provided for testing\nFieldIndexer.prototype.setMaxIndexedValueLength = function(length) {\n\tthis.index = null;\n\tthis.maxIndexedValueLength = length;\n};\n\nFieldIndexer.prototype.addIndexMethods = function() {\n\tvar self = this;\n\tthis.wiki.each.byField = function(name,value) {\n\t\tvar titles = self.wiki.allTitles(),\n\t\t\tlookup = self.lookup(name,value);\n\t\treturn lookup && lookup.filter(function(title) {\n\t\t\treturn titles.indexOf(title) !== -1;\n\t\t});\n\t};\n\tthis.wiki.eachShadow.byField = function(name,value) {\n\t\tvar titles = self.wiki.allShadowTitles(),\n\t\t\tlookup = self.lookup(name,value);\n\t\treturn lookup && lookup.filter(function(title) {\n\t\t\treturn titles.indexOf(title) !== -1;\n\t\t});\n\t};\n\tthis.wiki.eachTiddlerPlusShadows.byField = function(name,value) {\n\t\tvar lookup = self.lookup(name,value);\n\t\treturn lookup ? lookup.slice(0) : null;\n\t};\n\tthis.wiki.eachShadowPlusTiddlers.byField = function(name,value) {\n\t\tvar lookup = self.lookup(name,value);\n\t\treturn lookup ? lookup.slice(0) : null;\n\t};\n};\n\n/*\nTear down and then rebuild the index as if all tiddlers have changed\n*/\nFieldIndexer.prototype.rebuild = function() {\n\t// Invalidate the index so that it will be rebuilt when it is next used\n\tthis.index = null;\n};\n\n/*\nBuild the index for a particular field\n*/\nFieldIndexer.prototype.buildIndexForField = function(name) {\n\tvar self = this;\n\t// Hashmap by field name of hashmap by field value of array of tiddler titles\n\tthis.index = this.index || Object.create(null);\n\tthis.index[name] = Object.create(null);\n\tvar baseIndex = this.index[name];\n\t// Update the index for each tiddler\n\tthis.wiki.eachTiddlerPlusShadows(function(tiddler,title) {\n\t\tif(name in tiddler.fields) {\n\t\t\tvar value = tiddler.getFieldString(name);\n\t\t\t// Skip any values above the maximum length\n\t\t\tif(value.length < self.maxIndexedValueLength) {\n\t\t\t\tbaseIndex[value] = baseIndex[value] || [];\n\t\t\t\tbaseIndex[value].push(title);\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nUpdate the index in the light of a tiddler value changing; note that the title must be identical. (Renames are handled as a separate delete and create)\nupdateDescriptor: {old: {tiddler: <tiddler>, shadow: <boolean>, exists: <boolean>},new: {tiddler: <tiddler>, shadow: <boolean>, exists: <boolean>}}\n*/\nFieldIndexer.prototype.update = function(updateDescriptor) {\n\tvar self = this;\n\t// Don't do anything if the index hasn't been built yet\n\tif(this.index === null) {\n\t\treturn;\n\t}\n\t// Remove the old tiddler from the index\n\tif(updateDescriptor.old.tiddler) {\n\t\t$tw.utils.each(this.index,function(indexEntry,name) {\n\t\t\tif(name in updateDescriptor.old.tiddler.fields) {\n\t\t\t\tvar value = updateDescriptor.old.tiddler.getFieldString(name),\n\t\t\t\t\ttiddlerList = indexEntry[value];\n\t\t\t\tif(tiddlerList) {\n\t\t\t\t\tvar index = tiddlerList.indexOf(updateDescriptor.old.tiddler.fields.title);\n\t\t\t\t\tif(index !== -1) {\n\t\t\t\t\t\ttiddlerList.splice(index,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t// Add the new tiddler to the index\n\tif(updateDescriptor[\"new\"].tiddler) {\n\t\t$tw.utils.each(this.index,function(indexEntry,name) {\n\t\t\tif(name in updateDescriptor[\"new\"].tiddler.fields) {\n\t\t\t\tvar value = updateDescriptor[\"new\"].tiddler.getFieldString(name);\n\t\t\t\tif(value.length < self.maxIndexedValueLength) {\n\t\t\t\t\tindexEntry[value] = indexEntry[value] || [];\n\t\t\t\t\tindexEntry[value].push(updateDescriptor[\"new\"].tiddler.fields.title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\t\t\n\t}\n};\n\n// Lookup the given field returning a list of tiddler titles\nFieldIndexer.prototype.lookup = function(name,value) {\n\t// Fail the lookup if the value is too long\n\tif(value.length >= this.maxIndexedValueLength) {\n\t\treturn null;\n\t}\n\t// Update the index if it has yet to be built\n\tif(this.index === null || !this.index[name]) {\n\t\tthis.buildIndexForField(name);\n\t}\n\treturn this.index[name][value] || [];\n};\n\nexports.FieldIndexer = FieldIndexer;\n\n})();\n",
"type": "application/javascript",
"module-type": "indexer"
},
"$:/core/modules/indexers/tag-indexer.js": {
"title": "$:/core/modules/indexers/tag-indexer.js",
"text": "/*\\\ntitle: $:/core/modules/indexers/tag-indexer.js\ntype: application/javascript\nmodule-type: indexer\n\nIndexes the tiddlers with each tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global modules: false */\n\"use strict\";\n\nfunction TagIndexer(wiki) {\n\tthis.wiki = wiki;\n}\n\nTagIndexer.prototype.init = function() {\n\tthis.subIndexers = [\n\t\tnew TagSubIndexer(this,\"each\"),\n\t\tnew TagSubIndexer(this,\"eachShadow\"),\n\t\tnew TagSubIndexer(this,\"eachTiddlerPlusShadows\"),\n\t\tnew TagSubIndexer(this,\"eachShadowPlusTiddlers\")\n\t];\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.addIndexMethod();\n\t});\n};\n\nTagIndexer.prototype.rebuild = function() {\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.rebuild();\n\t});\n};\n\nTagIndexer.prototype.update = function(updateDescriptor) {\n\t$tw.utils.each(this.subIndexers,function(subIndexer) {\n\t\tsubIndexer.update(updateDescriptor);\n\t});\n};\n\nfunction TagSubIndexer(indexer,iteratorMethod) {\n\tthis.indexer = indexer;\n\tthis.iteratorMethod = iteratorMethod;\n\tthis.index = null; // Hashmap of tag title to {isSorted: bool, titles: [array]} or null if not yet initialised\n}\n\nTagSubIndexer.prototype.addIndexMethod = function() {\n\tvar self = this;\n\tthis.indexer.wiki[this.iteratorMethod].byTag = function(tag) {\n\t\treturn self.lookup(tag).slice(0);\n\t};\n};\n\nTagSubIndexer.prototype.rebuild = function() {\n\tvar self = this;\n\t// Hashmap by tag of array of {isSorted:, titles:[]}\n\tthis.index = Object.create(null);\n\t// Add all the tags\n\tthis.indexer.wiki[this.iteratorMethod](function(tiddler,title) {\n\t\t$tw.utils.each(tiddler.fields.tags,function(tag) {\n\t\t\tif(!self.index[tag]) {\n\t\t\t\tself.index[tag] = {isSorted: false, titles: [title]};\n\t\t\t} else {\n\t\t\t\tself.index[tag].titles.push(title);\n\t\t\t}\n\t\t});\t\t\n\t});\n};\n\nTagSubIndexer.prototype.update = function(updateDescriptor) {\n\tthis.index = null;\n};\n\nTagSubIndexer.prototype.lookup = function(tag) {\n\t// Update the index if it has yet to be built\n\tif(this.index === null) {\n\t\tthis.rebuild();\n\t}\n\tvar indexRecord = this.index[tag];\n\tif(indexRecord) {\n\t\tif(!indexRecord.isSorted) {\n\t\t\tif(this.indexer.wiki.sortByList) {\n\t\t\t\tindexRecord.titles = this.indexer.wiki.sortByList(indexRecord.titles,tag);\n\t\t\t}\t\t\t\n\t\t\tindexRecord.isSorted = true;\n\t\t}\n\t\treturn indexRecord.titles;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n\nexports.TagIndexer = TagIndexer;\n\n})();\n",
"type": "application/javascript",
"module-type": "indexer"
},
"$:/core/modules/info/platform.js": {
"title": "$:/core/modules/info/platform.js",
"text": "/*\\\ntitle: $:/core/modules/info/platform.js\ntype: application/javascript\nmodule-type: info\n\nInitialise basic platform $:/info/ tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {\n\tvar mapBoolean = function(value) {return value ? \"yes\" : \"no\";},\n\t\tinfoTiddlerFields = [];\n\t// Basics\n\tinfoTiddlerFields.push({title: \"$:/info/browser\", text: mapBoolean(!!$tw.browser)});\n\tinfoTiddlerFields.push({title: \"$:/info/node\", text: mapBoolean(!!$tw.node)});\n\tinfoTiddlerFields.push({title: \"$:/info/startup-timestamp\", text: $tw.utils.stringifyDate(new Date())});\n\tif($tw.browser) {\n\t\t// Document location\n\t\tvar setLocationProperty = function(name,value) {\n\t\t\t\tinfoTiddlerFields.push({title: \"$:/info/url/\" + name, text: value});\t\t\t\n\t\t\t},\n\t\t\tlocation = document.location;\n\t\tsetLocationProperty(\"full\", (location.toString()).split(\"#\")[0]);\n\t\tsetLocationProperty(\"host\", location.host);\n\t\tsetLocationProperty(\"hostname\", location.hostname);\n\t\tsetLocationProperty(\"protocol\", location.protocol);\n\t\tsetLocationProperty(\"port\", location.port);\n\t\tsetLocationProperty(\"pathname\", location.pathname);\n\t\tsetLocationProperty(\"search\", location.search);\n\t\tsetLocationProperty(\"origin\", location.origin);\n\t\t// Screen size\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/width\", text: window.screen.width.toString()});\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/height\", text: window.screen.height.toString()});\n \t\t// Dark mode through event listener on MediaQueryList\n \t\tvar mqList = window.matchMedia(\"(prefers-color-scheme: dark)\"),\n \t\t\tgetDarkModeTiddler = function() {return {title: \"$:/info/darkmode\", text: mqList.matches ? \"yes\" : \"no\"};};\n \t\tinfoTiddlerFields.push(getDarkModeTiddler());\n \t\tmqList.addListener(function(event) {\n \t\t\tupdateInfoTiddlersCallback([getDarkModeTiddler()]);\n \t\t});\n\t\t// Language\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/language\", text: navigator.language || \"\"});\n\t}\n\treturn infoTiddlerFields;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "info"
},
"$:/core/modules/keyboard.js": {
"title": "$:/core/modules/keyboard.js",
"text": "/*\\\ntitle: $:/core/modules/keyboard.js\ntype: application/javascript\nmodule-type: global\n\nKeyboard handling utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar namedKeys = {\n\t\"cancel\": 3,\n\t\"help\": 6,\n\t\"backspace\": 8,\n\t\"tab\": 9,\n\t\"clear\": 12,\n\t\"return\": 13,\n\t\"enter\": 13,\n\t\"pause\": 19,\n\t\"escape\": 27,\n\t\"space\": 32,\n\t\"page_up\": 33,\n\t\"page_down\": 34,\n\t\"end\": 35,\n\t\"home\": 36,\n\t\"left\": 37,\n\t\"up\": 38,\n\t\"right\": 39,\n\t\"down\": 40,\n\t\"printscreen\": 44,\n\t\"insert\": 45,\n\t\"delete\": 46,\n\t\"0\": 48,\n\t\"1\": 49,\n\t\"2\": 50,\n\t\"3\": 51,\n\t\"4\": 52,\n\t\"5\": 53,\n\t\"6\": 54,\n\t\"7\": 55,\n\t\"8\": 56,\n\t\"9\": 57,\n\t\"firefoxsemicolon\": 59,\n\t\"firefoxequals\": 61,\n\t\"a\": 65,\n\t\"b\": 66,\n\t\"c\": 67,\n\t\"d\": 68,\n\t\"e\": 69,\n\t\"f\": 70,\n\t\"g\": 71,\n\t\"h\": 72,\n\t\"i\": 73,\n\t\"j\": 74,\n\t\"k\": 75,\n\t\"l\": 76,\n\t\"m\": 77,\n\t\"n\": 78,\n\t\"o\": 79,\n\t\"p\": 80,\n\t\"q\": 81,\n\t\"r\": 82,\n\t\"s\": 83,\n\t\"t\": 84,\n\t\"u\": 85,\n\t\"v\": 86,\n\t\"w\": 87,\n\t\"x\": 88,\n\t\"y\": 89,\n\t\"z\": 90,\n\t\"numpad0\": 96,\n\t\"numpad1\": 97,\n\t\"numpad2\": 98,\n\t\"numpad3\": 99,\n\t\"numpad4\": 100,\n\t\"numpad5\": 101,\n\t\"numpad6\": 102,\n\t\"numpad7\": 103,\n\t\"numpad8\": 104,\n\t\"numpad9\": 105,\n\t\"multiply\": 106,\n\t\"add\": 107,\n\t\"separator\": 108,\n\t\"subtract\": 109,\n\t\"decimal\": 110,\n\t\"divide\": 111,\n\t\"f1\": 112,\n\t\"f2\": 113,\n\t\"f3\": 114,\n\t\"f4\": 115,\n\t\"f5\": 116,\n\t\"f6\": 117,\n\t\"f7\": 118,\n\t\"f8\": 119,\n\t\"f9\": 120,\n\t\"f10\": 121,\n\t\"f11\": 122,\n\t\"f12\": 123,\n\t\"f13\": 124,\n\t\"f14\": 125,\n\t\"f15\": 126,\n\t\"f16\": 127,\n\t\"f17\": 128,\n\t\"f18\": 129,\n\t\"f19\": 130,\n\t\"f20\": 131,\n\t\"f21\": 132,\n\t\"f22\": 133,\n\t\"f23\": 134,\n\t\"f24\": 135,\n\t\"firefoxminus\": 173,\n\t\"semicolon\": 186,\n\t\"equals\": 187,\n\t\"comma\": 188,\n\t\"dash\": 189,\n\t\"period\": 190,\n\t\"slash\": 191,\n\t\"backquote\": 192,\n\t\"openbracket\": 219,\n\t\"backslash\": 220,\n\t\"closebracket\": 221,\n\t\"quote\": 222\n};\n\nfunction KeyboardManager(options) {\n\tvar self = this;\n\toptions = options || \"\";\n\t// Save the named key hashmap\n\tthis.namedKeys = namedKeys;\n\t// Create a reverse mapping of code to keyname\n\tthis.keyNames = [];\n\t$tw.utils.each(namedKeys,function(keyCode,name) {\n\t\tself.keyNames[keyCode] = name.substr(0,1).toUpperCase() + name.substr(1);\n\t});\n\t// Save the platform-specific name of the \"meta\" key\n\tthis.metaKeyName = $tw.platform.isMac ? \"cmd-\" : \"win-\";\n\tthis.shortcutKeysList = [], // Stores the shortcut-key descriptors\n\tthis.shortcutActionList = [], // Stores the corresponding action strings\n\tthis.shortcutParsedList = []; // Stores the parsed key descriptors\n\tthis.lookupNames = [\"shortcuts\"];\n\tthis.lookupNames.push($tw.platform.isMac ? \"shortcuts-mac\" : \"shortcuts-not-mac\")\n\tthis.lookupNames.push($tw.platform.isWindows ? \"shortcuts-windows\" : \"shortcuts-not-windows\");\n\tthis.lookupNames.push($tw.platform.isLinux ? \"shortcuts-linux\" : \"shortcuts-not-linux\");\n\tthis.updateShortcutLists(this.getShortcutTiddlerList());\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tself.handleShortcutChanges(changes);\n\t});\n}\n\n/*\nReturn an array of keycodes for the modifier keys ctrl, shift, alt, meta\n*/\nKeyboardManager.prototype.getModifierKeys = function() {\n\treturn [\n\t\t16, // Shift\n\t\t17, // Ctrl\n\t\t18, // Alt\n\t\t20, // CAPS LOCK\n\t\t91, // Meta (left)\n\t\t93, // Meta (right)\n\t\t224 // Meta (Firefox)\n\t]\n};\n\n/*\nParses a key descriptor into the structure:\n{\n\tkeyCode: numeric keycode\n\tshiftKey: boolean\n\taltKey: boolean\n\tctrlKey: boolean\n\tmetaKey: boolean\n}\nKey descriptors have the following format:\n\tctrl+enter\n\tctrl+shift+alt+A\n*/\nKeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor) {\n\tvar components = keyDescriptor.split(/\\+|\\-/),\n\t\tinfo = {\n\t\t\tkeyCode: 0,\n\t\t\tshiftKey: false,\n\t\t\taltKey: false,\n\t\t\tctrlKey: false,\n\t\t\tmetaKey: false\n\t\t};\n\tfor(var t=0; t<components.length; t++) {\n\t\tvar s = components[t].toLowerCase(),\n\t\t\tc = s.charCodeAt(0);\n\t\t// Look for modifier keys\n\t\tif(s === \"ctrl\") {\n\t\t\tinfo.ctrlKey = true;\n\t\t} else if(s === \"shift\") {\n\t\t\tinfo.shiftKey = true;\n\t\t} else if(s === \"alt\") {\n\t\t\tinfo.altKey = true;\n\t\t} else if(s === \"meta\" || s === \"cmd\" || s === \"win\") {\n\t\t\tinfo.metaKey = true;\n\t\t}\n\t\t// Replace named keys with their code\n\t\tif(this.namedKeys[s]) {\n\t\t\tinfo.keyCode = this.namedKeys[s];\n\t\t}\n\t}\n\tif(info.keyCode) {\n\t\treturn info;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nParse a list of key descriptors into an array of keyInfo objects. The key descriptors can be passed as an array of strings or a space separated string\n*/\nKeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options) {\n\tvar self = this;\n\toptions = options || {};\n\toptions.stack = options.stack || [];\n\tvar wiki = options.wiki || $tw.wiki;\n\tif(typeof keyDescriptors === \"string\" && keyDescriptors === \"\") {\n\t\treturn [];\n\t}\n\tif(!$tw.utils.isArray(keyDescriptors)) {\n\t\tkeyDescriptors = keyDescriptors.split(\" \");\n\t}\n\tvar result = [];\n\t$tw.utils.each(keyDescriptors,function(keyDescriptor) {\n\t\t// Look for a named shortcut\n\t\tif(keyDescriptor.substr(0,2) === \"((\" && keyDescriptor.substr(-2,2) === \"))\") {\n\t\t\tif(options.stack.indexOf(keyDescriptor) === -1) {\n\t\t\t\toptions.stack.push(keyDescriptor);\n\t\t\t\tvar name = keyDescriptor.substring(2,keyDescriptor.length - 2),\n\t\t\t\t\tlookupName = function(configName) {\n\t\t\t\t\t\tvar keyDescriptors = wiki.getTiddlerText(\"$:/config/\" + configName + \"/\" + name);\n\t\t\t\t\t\tif(keyDescriptors) {\n\t\t\t\t\t\t\tresult.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options));\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t$tw.utils.each(self.lookupNames,function(platformDescriptor) {\n\t\t\t\t\tlookupName(platformDescriptor);\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tresult.push(self.parseKeyDescriptor(keyDescriptor));\n\t\t}\n\t});\n\treturn result;\n};\n\nKeyboardManager.prototype.getPrintableShortcuts = function(keyInfoArray) {\n\tvar self = this,\n\t\tresult = [];\n\t$tw.utils.each(keyInfoArray,function(keyInfo) {\n\t\tif(keyInfo) {\n\t\t\tresult.push((keyInfo.ctrlKey ? \"ctrl-\" : \"\") + \n\t\t\t\t (keyInfo.shiftKey ? \"shift-\" : \"\") + \n\t\t\t\t (keyInfo.altKey ? \"alt-\" : \"\") + \n\t\t\t\t (keyInfo.metaKey ? self.metaKeyName : \"\") + \n\t\t\t\t (self.keyNames[keyInfo.keyCode]));\n\t\t}\n\t});\n\treturn result;\n}\n\nKeyboardManager.prototype.checkKeyDescriptor = function(event,keyInfo) {\n\treturn keyInfo &&\n\t\t\tevent.keyCode === keyInfo.keyCode && \n\t\t\tevent.shiftKey === keyInfo.shiftKey && \n\t\t\tevent.altKey === keyInfo.altKey && \n\t\t\tevent.ctrlKey === keyInfo.ctrlKey && \n\t\t\tevent.metaKey === keyInfo.metaKey;\n};\n\nKeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {\n\tfor(var t=0; t<keyInfoArray.length; t++) {\n\t\tif(this.checkKeyDescriptor(event,keyInfoArray[t])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.getEventModifierKeyDescriptor = function(event) {\n\treturn event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey ? \"ctrl\" : \n\t\tevent.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey ? \"shift\" : \n\t\tevent.ctrlKey && event.shiftKey && !event.altKey && !event.metaKey ? \"ctrl-shift\" : \n\t\tevent.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey ? \"alt\" : \n\t\tevent.altKey && event.shiftKey && !event.ctrlKey && !event.metaKey ? \"alt-shift\" : \n\t\tevent.altKey && event.ctrlKey && !event.shiftKey && !event.metaKey ? \"ctrl-alt\" : \n\t\tevent.altKey && event.shiftKey && event.ctrlKey && !event.metaKey ? \"ctrl-alt-shift\" : \n\t\tevent.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey ? \"meta\" : \n\t\tevent.metaKey && event.ctrlKey && !event.shiftKey && !event.altKey ? \"meta-ctrl\" :\n\t\tevent.metaKey && event.ctrlKey && event.shiftKey && !event.altKey ? \"meta-ctrl-shift\" :\n\t\tevent.metaKey && event.ctrlKey & event.shiftKey && event.altKey ? \"meta-ctrl-alt-shift\" : \"normal\";\n};\n\nKeyboardManager.prototype.getShortcutTiddlerList = function() {\n\treturn $tw.wiki.getTiddlersWithTag(\"$:/tags/KeyboardShortcut\");\n};\n\nKeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {\n\tthis.shortcutTiddlers = tiddlerList;\n\tfor(var i=0; i<tiddlerList.length; i++) {\n\t\tvar title = tiddlerList[i],\n\t\t\ttiddlerFields = $tw.wiki.getTiddler(title).fields;\n\t\tthis.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;\n\t\tthis.shortcutActionList[i] = tiddlerFields.text;\n\t\tthis.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;\n\t}\n};\n\nKeyboardManager.prototype.handleKeydownEvent = function(event) {\n\tvar key, action;\n\tfor(var i=0; i<this.shortcutTiddlers.length; i++) {\n\t\tif(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {\n\t\t\tkey = this.shortcutParsedList[i];\n\t\t\taction = this.shortcutActionList[i];\n\t\t}\n\t}\n\tif(key !== undefined) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\t$tw.rootWidget.invokeActionString(action,$tw.rootWidget);\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.detectNewShortcuts = function(changedTiddlers) {\n\tvar shortcutConfigTiddlers = [],\n\t\thandled = false;\n\t$tw.utils.each(this.lookupNames,function(platformDescriptor) {\n\t\tvar descriptorString = \"$:/config/\" + platformDescriptor + \"/\";\n\t\tObject.keys(changedTiddlers).forEach(function(configTiddler) {\n\t\t\tvar configString = configTiddler.substr(0, configTiddler.lastIndexOf(\"/\") + 1);\n\t\t\tif(configString === descriptorString) {\n\t\t\t\tshortcutConfigTiddlers.push(configTiddler);\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t});\n\t});\n\tif(handled) {\n\t\treturn $tw.utils.hopArray(changedTiddlers,shortcutConfigTiddlers);\n\t} else {\n\t\treturn false;\n\t}\n};\n\nKeyboardManager.prototype.handleShortcutChanges = function(changedTiddlers) {\n\tvar newList = this.getShortcutTiddlerList();\n\tvar hasChanged = $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers) ? true :\n\t\t($tw.utils.hopArray(changedTiddlers,newList) ? true :\n\t\t(this.detectNewShortcuts(changedTiddlers))\n\t);\n\t// Re-cache shortcuts if something changed\n\tif(hasChanged) {\n\t\tthis.updateShortcutLists(newList);\n\t}\n};\n\nexports.KeyboardManager = KeyboardManager;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/language.js": {
"title": "$:/core/modules/language.js",
"text": "/*\\\ntitle: $:/core/modules/language.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Language() manages translateable strings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate an instance of the language manager. Options include:\nwiki: wiki from which to retrieve translation tiddlers\n*/\nfunction Language(options) {\n\toptions = options || \"\";\n\tthis.wiki = options.wiki || $tw.wiki;\n}\n\n/*\nReturn a wikified translateable string. The title is automatically prefixed with \"$:/language/\"\nOptions include:\nvariables: optional hashmap of variables to supply to the language wikification\n*/\nLanguage.prototype.getString = function(title,options) {\n\toptions = options || {};\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.renderTiddler(\"text/plain\",title,{variables: options.variables});\n};\n\n/*\nReturn a raw, unwikified translateable string. The title is automatically prefixed with \"$:/language/\"\n*/\nLanguage.prototype.getRawString = function(title) {\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.getTiddlerText(title);\n};\n\nexports.Language = Language;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/macros/changecount.js": {
"title": "$:/core/modules/macros/changecount.js",
"text": "/*\\\ntitle: $:/core/modules/macros/changecount.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the changecount for the current tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"changecount\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn this.wiki.getChangeCount(this.getVariable(\"currentTiddler\")) + \"\";\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/contrastcolour.js": {
"title": "$:/core/modules/macros/contrastcolour.js",
"text": "/*\\\ntitle: $:/core/modules/macros/contrastcolour.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to choose which of two colours has the highest contrast with a base colour\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"contrastcolour\";\n\nexports.params = [\n\t{name: \"target\"},\n\t{name: \"fallbackTarget\"},\n\t{name: \"colourA\"},\n\t{name: \"colourB\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(target,fallbackTarget,colourA,colourB) {\n\tvar rgbTarget = $tw.utils.parseCSSColor(target) || $tw.utils.parseCSSColor(fallbackTarget);\n\tif(!rgbTarget) {\n\t\treturn colourA;\n\t}\n\tvar rgbColourA = $tw.utils.parseCSSColor(colourA),\n\t\trgbColourB = $tw.utils.parseCSSColor(colourB);\n\tif(rgbColourA && !rgbColourB) {\n\t\treturn rgbColourA;\n\t}\n\tif(rgbColourB && !rgbColourA) {\n\t\treturn rgbColourB;\n\t}\n\tif(!rgbColourA && !rgbColourB) {\n\t\t// If neither colour is readable, return a crude inverse of the target\n\t\treturn [255 - rgbTarget[0],255 - rgbTarget[1],255 - rgbTarget[2],rgbTarget[3]];\n\t}\n\t// Colour brightness formula derived from http://www.w3.org/WAI/ER/WD-AERT/#color-contrast\n\tvar brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,\n\t\tbrightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,\n\t\tbrightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;\n\treturn Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/csvtiddlers.js": {
"title": "$:/core/modules/macros/csvtiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/macros/csvtiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to CSV\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"csvtiddlers\";\n\nexports.params = [\n\t{name: \"filter\"},\n\t{name: \"format\"},\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter,format) {\n\tvar self = this,\n\t\ttiddlers = this.wiki.filterTiddlers(filter),\n\t\ttiddler,\n\t\tfields = [],\n\t\tt,f;\n\t// Collect all the fields\n\tfor(t=0;t<tiddlers.length; t++) {\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\tfor(f in tiddler.fields) {\n\t\t\tif(fields.indexOf(f) === -1) {\n\t\t\t\tfields.push(f);\n\t\t\t}\n\t\t}\n\t}\n\t// Sort the fields and bring the standard ones to the front\n\tfields.sort();\n\t\"title text modified modifier created creator\".split(\" \").reverse().forEach(function(value,index) {\n\t\tvar p = fields.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tfields.splice(p,1);\n\t\t\tfields.unshift(value)\n\t\t}\n\t});\n\t// Output the column headings\n\tvar output = [], row = [];\n\tfields.forEach(function(value) {\n\t\trow.push(quoteAndEscape(value))\n\t});\n\toutput.push(row.join(\",\"));\n\t// Output each tiddler\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\trow = [];\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\t\tfor(f=0; f<fields.length; f++) {\n\t\t\t\trow.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || \"\" : \"\"));\n\t\t\t}\n\t\toutput.push(row.join(\",\"));\n\t}\n\treturn output.join(\"\\n\");\n};\n\nfunction quoteAndEscape(value) {\n\treturn \"\\\"\" + value.replace(/\"/mg,\"\\\"\\\"\") + \"\\\"\";\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/displayshortcuts.js": {
"title": "$:/core/modules/macros/displayshortcuts.js",
"text": "/*\\\ntitle: $:/core/modules/macros/displayshortcuts.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to display a list of keyboard shortcuts in human readable form. Notably, it resolves named shortcuts like `((bold))` to the underlying keystrokes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"displayshortcuts\";\n\nexports.params = [\n\t{name: \"shortcuts\"},\n\t{name: \"prefix\"},\n\t{name: \"separator\"},\n\t{name: \"suffix\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(shortcuts,prefix,separator,suffix) {\n\tvar shortcutArray = $tw.keyboardManager.getPrintableShortcuts($tw.keyboardManager.parseKeyDescriptors(shortcuts,{\n\t\twiki: this.wiki\n\t}));\n\tif(shortcutArray.length > 0) {\n\t\tshortcutArray.sort(function(a,b) {\n\t\t return a.toLowerCase().localeCompare(b.toLowerCase());\n\t\t})\n\t\treturn prefix + shortcutArray.join(separator) + suffix;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/jsontiddler.js": {
"title": "$:/core/modules/macros/jsontiddler.js",
"text": "/*\\\ntitle: $:/core/modules/macros/jsontiddler.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output a single tiddler to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddler\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\ttitle = title || this.getVariable(\"currentTiddler\");\n\tvar tiddler = !!title && this.wiki.getTiddler(title),\n\t\tfields = new Object();\n\tif(tiddler) {\n\t\tfor(var field in tiddler.fields) {\n\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t}\n\t}\n\treturn JSON.stringify(fields,null,$tw.config.preferences.jsonSpaces);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/jsontiddlers.js": {
"title": "$:/core/modules/macros/jsontiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/macros/jsontiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddlers\";\n\nexports.params = [\n\t{name: \"filter\"},\n\t{name: \"spaces\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter,spaces) {\n\treturn this.wiki.getTiddlersAsJson(filter,$tw.utils.parseInt(spaces));\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/makedatauri.js": {
"title": "$:/core/modules/macros/makedatauri.js",
"text": "/*\\\ntitle: $:/core/modules/macros/makedatauri.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to convert a string of text to a data URI\n\n<<makedatauri text:\"Text to be converted\" type:\"text/vnd.tiddlywiki\">>\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"makedatauri\";\n\nexports.params = [\n\t{name: \"text\"},\n\t{name: \"type\"},\n\t{name: \"_canonical_uri\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(text,type,_canonical_uri) {\n\treturn $tw.utils.makeDataUri(text,type,_canonical_uri);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/now.js": {
"title": "$:/core/modules/macros/now.js",
"text": "/*\\\ntitle: $:/core/modules/macros/now.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return a formatted version of the current time\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"now\";\n\nexports.params = [\n\t{name: \"format\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(format) {\n\treturn $tw.utils.formatDateString(new Date(),format || \"0hh:0mm, DDth MMM YYYY\");\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/qualify.js": {
"title": "$:/core/modules/macros/qualify.js",
"text": "/*\\\ntitle: $:/core/modules/macros/qualify.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to qualify a state tiddler title according\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"qualify\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\treturn title + \"-\" + this.getStateQualifier();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/resolvepath.js": {
"title": "$:/core/modules/macros/resolvepath.js",
"text": "/*\\\ntitle: $:/core/modules/macros/resolvepath.js\ntype: application/javascript\nmodule-type: macro\n\nResolves a relative path for an absolute rootpath.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"resolvepath\";\n\nexports.params = [\n\t{name: \"source\"},\n\t{name: \"root\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(source, root) {\n\treturn $tw.utils.resolvePath(source, root);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/unusedtitle.js": {
"title": "$:/core/modules/macros/unusedtitle.js",
"text": "/*\\\ntitle: $:/core/modules/macros/unusedtitle.js\ntype: application/javascript\nmodule-type: macro\nMacro to return a new title that is unused in the wiki. It can be given a name as a base.\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"unusedtitle\";\n\nexports.params = [\n\t{name: \"baseName\"},\n\t{name: \"options\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(baseName, options) {\n\tif(!baseName) {\n\t\tbaseName = $tw.language.getString(\"DefaultNewTiddlerTitle\");\n\t}\n\treturn this.wiki.generateNewTitle(baseName, options);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/version.js": {
"title": "$:/core/modules/macros/version.js",
"text": "/*\\\ntitle: $:/core/modules/macros/version.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the TiddlyWiki core version number\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"version\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn $tw.version;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/parsers/audioparser.js": {
"title": "$:/core/modules/parsers/audioparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/audioparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe audio parser parses an audio tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar AudioParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"audio\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"},\n\t\t\t\tstyle: {type: \"string\", value: \"width: 100%; object-fit: contain\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"audio/ogg\"] = AudioParser;\nexports[\"audio/mpeg\"] = AudioParser;\nexports[\"audio/mp3\"] = AudioParser;\nexports[\"audio/mp4\"] = AudioParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/binaryparser.js": {
"title": "$:/core/modules/parsers/binaryparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/binaryparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe binary parser parses a binary tiddler into a warning message and download link\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\nvar EXPORT_BUTTON_IMAGE = \"$:/core/images/export-button\";\n\nvar BinaryParser = function(type,text,options) {\n\t// Transclude the binary data tiddler warning message\n\tvar warn = {\n\t\ttype: \"element\",\n\t\ttag: \"p\",\n\t\tchildren: [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Create download link based on binary tiddler title\n\tvar link = {\n\t\ttype: \"element\",\n\t\ttag: \"a\",\n\t\tattributes: {\n\t\t\ttitle: {type: \"indirect\", textReference: \"!!title\"},\n\t\t\tdownload: {type: \"indirect\", textReference: \"!!title\"}\n\t\t},\n\t\tchildren: [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: EXPORT_BUTTON_IMAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Set the link href to external or internal data URI\n\tif(options._canonical_uri) {\n\t\tlink.attributes.href = {\n\t\t\ttype: \"string\", \n\t\t\tvalue: options._canonical_uri\n\t\t};\n\t} else if(text) {\n\t\tlink.attributes.href = {\n\t\t\ttype: \"string\", \n\t\t\tvalue: \"data:\" + type + \";base64,\" + text\n\t\t};\n\t}\n\t// Combine warning message and download link in a div\n\tvar element = {\n\t\ttype: \"element\",\n\t\ttag: \"div\",\n\t\tattributes: {\n\t\t\tclass: {type: \"string\", value: \"tc-binary-warning\"}\n\t\t},\n\t\tchildren: [warn, link]\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"application/octet-stream\"] = BinaryParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/csvparser.js": {
"title": "$:/core/modules/parsers/csvparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/csvparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe CSV text parser processes CSV files into a table wrapped in a scrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar CsvParser = function(type,text,options) {\n\t// Table framework\n\tthis.tree = [{\n\t\t\"type\": \"scrollable\", \"children\": [{\n\t\t\t\"type\": \"element\", \"tag\": \"table\", \"children\": [{\n\t\t\t\t\"type\": \"element\", \"tag\": \"tbody\", \"children\": []\n\t\t\t}], \"attributes\": {\n\t\t\t\t\"class\": {\"type\": \"string\", \"value\": \"tc-csv-table\"}\n\t\t\t}\n\t\t}]\n\t}];\n\t// Split the text into lines\n\tvar lines = text.split(/\\r?\\n/mg),\n\t\ttag = \"th\";\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar lineText = lines[line];\n\t\tif(lineText) {\n\t\t\tvar row = {\n\t\t\t\t\t\"type\": \"element\", \"tag\": \"tr\", \"children\": []\n\t\t\t\t};\n\t\t\tvar columns = lineText.split(\",\");\n\t\t\tfor(var column=0; column<columns.length; column++) {\n\t\t\t\trow.children.push({\n\t\t\t\t\t\t\"type\": \"element\", \"tag\": tag, \"children\": [{\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": columns[column]\n\t\t\t\t\t\t}]\n\t\t\t\t\t});\n\t\t\t}\n\t\t\ttag = \"td\";\n\t\t\tthis.tree[0].children[0].children[0].children.push(row);\n\t\t}\n\t}\n};\n\nexports[\"text/csv\"] = CsvParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/htmlparser.js": {
"title": "$:/core/modules/parsers/htmlparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/htmlparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe HTML parser displays text as raw HTML\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HtmlParser = function(type,text,options) {\n\tvar src;\n\tif(options._canonical_uri) {\n\t\tsrc = options._canonical_uri;\n\t} else if(text) {\n\t\tsrc = \"data:text/html;charset=utf-8,\" + encodeURIComponent(text);\n\t}\n\tthis.tree = [{\n\t\ttype: \"element\",\n\t\ttag: \"iframe\",\n\t\tattributes: {\n\t\t\tsrc: {type: \"string\", value: src},\n\t\t\tsandbox: {type: \"string\", value: \"\"}\n\t\t}\n\t}];\n};\n\nexports[\"text/html\"] = HtmlParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/imageparser.js": {
"title": "$:/core/modules/parsers/imageparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/imageparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe image parser parses an image into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"img\",\n\t\t\tattributes: {}\n\t\t};\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\tif(type === \"image/svg+xml\" || type === \".svg\") {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:image/svg+xml,\" + encodeURIComponent(text)};\n\t\t} else {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t\t}\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"image/svg+xml\"] = ImageParser;\nexports[\"image/jpg\"] = ImageParser;\nexports[\"image/jpeg\"] = ImageParser;\nexports[\"image/png\"] = ImageParser;\nexports[\"image/gif\"] = ImageParser;\nexports[\"image/webp\"] = ImageParser;\nexports[\"image/heic\"] = ImageParser;\nexports[\"image/heif\"] = ImageParser;\nexports[\"image/x-icon\"] = ImageParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/utils/parseutils.js": {
"title": "$:/core/modules/utils/parseutils.js",
"text": "/*\\\ntitle: $:/core/modules/utils/parseutils.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions concerned with parsing text into tokens.\n\nMost functions have the following pattern:\n\n* The parameters are:\n** `source`: the source string being parsed\n** `pos`: the current parse position within the string\n** Any further parameters are used to identify the token that is being parsed\n* The return value is:\n** null if the token was not found at the specified position\n** an object representing the token with the following standard fields:\n*** `type`: string indicating the type of the token\n*** `start`: start position of the token in the source string\n*** `end`: end position of the token in the source string\n*** Any further fields required to describe the token\n\nThe exception is `skipWhiteSpace`, which just returns the position after the whitespace.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for a whitespace token. Returns null if not found, otherwise returns {type: \"whitespace\", start:, end:,}\n*/\nexports.parseWhiteSpace = function(source,pos) {\n\tvar p = pos,c;\n\twhile(true) {\n\t\tc = source.charAt(p);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tp++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\tif(p === pos) {\n\t\treturn null;\n\t} else {\n\t\treturn {\n\t\t\ttype: \"whitespace\",\n\t\t\tstart: pos,\n\t\t\tend: p\n\t\t}\n\t}\n};\n\n/*\nConvenience wrapper for parseWhiteSpace. Returns the position after the whitespace\n*/\nexports.skipWhiteSpace = function(source,pos) {\n\tvar c;\n\twhile(true) {\n\t\tc = source.charAt(pos);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tpos++;\n\t\t} else {\n\t\t\treturn pos;\n\t\t}\n\t}\n};\n\n/*\nLook for a given string token. Returns null if not found, otherwise returns {type: \"token\", value:, start:, end:,}\n*/\nexports.parseTokenString = function(source,pos,token) {\n\tvar match = source.indexOf(token,pos) === pos;\n\tif(match) {\n\t\treturn {\n\t\t\ttype: \"token\",\n\t\t\tvalue: token,\n\t\t\tstart: pos,\n\t\t\tend: pos + token.length\n\t\t};\n\t}\n\treturn null;\n};\n\n/*\nLook for a token matching a regex. Returns null if not found, otherwise returns {type: \"regexp\", match:, start:, end:,}\n*/\nexports.parseTokenRegExp = function(source,pos,reToken) {\n\tvar node = {\n\t\ttype: \"regexp\",\n\t\tstart: pos\n\t};\n\treToken.lastIndex = pos;\n\tnode.match = reToken.exec(source);\n\tif(node.match && node.match.index === pos) {\n\t\tnode.end = pos + node.match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a string literal. Returns null if not found, otherwise returns {type: \"string\", value:, start:, end:,}\n*/\nexports.parseStringLiteral = function(source,pos) {\n\tvar node = {\n\t\ttype: \"string\",\n\t\tstart: pos\n\t};\n\tvar reString = /(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\")|(?:'([^']*)')/g;\n\treString.lastIndex = pos;\n\tvar match = reString.exec(source);\n\tif(match && match.index === pos) {\n\t\tnode.value = match[1] !== undefined ? match[1] :(\n\t\t\tmatch[2] !== undefined ? match[2] : match[3] \n\t\t\t\t\t);\n\t\tnode.end = pos + match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a macro invocation parameter. Returns null if not found, or {type: \"macro-parameter\", name:, value:, start:, end:}\n*/\nexports.parseMacroParameter = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macro-parameter\",\n\t\tstart: pos\n\t};\n\t// Define our regexp\n\tvar reMacroParameter = /(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\\s>\"'=]+)))/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the parameter\n\tvar token = $tw.utils.parseTokenRegExp(source,pos,reMacroParameter);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the parameter details\n\tnode.value = token.match[2] !== undefined ? token.match[2] : (\n\t\t\t\t\ttoken.match[3] !== undefined ? token.match[3] : (\n\t\t\t\t\t\ttoken.match[4] !== undefined ? token.match[4] : (\n\t\t\t\t\t\t\ttoken.match[5] !== undefined ? token.match[5] : (\n\t\t\t\t\t\t\t\ttoken.match[6] !== undefined ? token.match[6] : (\n\t\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t);\n\tif(token.match[1]) {\n\t\tnode.name = token.match[1];\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for a macro invocation. Returns null if not found, or {type: \"macrocall\", name:, parameters:, start:, end:}\n*/\nexports.parseMacroInvocation = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macrocall\",\n\t\tstart: pos,\n\t\tparams: []\n\t};\n\t// Define our regexps\n\tvar reMacroName = /([^\\s>\"'=]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double less than sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"<<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the macro name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reMacroName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Process parameters\n\tvar parameter = $tw.utils.parseMacroParameter(source,pos);\n\twhile(parameter) {\n\t\tnode.params.push(parameter);\n\t\tpos = parameter.end;\n\t\t// Get the next parameter\n\t\tparameter = $tw.utils.parseMacroParameter(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">>\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for an HTML attribute definition. Returns null if not found, otherwise returns {type: \"attribute\", name:, valueType: \"string|indirect|macro\", value:, start:, end:,}\n*/\nexports.parseAttribute = function(source,pos) {\n\tvar node = {\n\t\tstart: pos\n\t};\n\t// Define our regexps\n\tvar reAttributeName = /([^\\/\\s>\"'=]+)/g,\n\t\treUnquotedAttribute = /([^\\/\\s<>\"'=]+)/g,\n\t\treFilteredValue = /\\{\\{\\{(.+?)\\}\\}\\}/g,\n\t\treIndirectValue = /\\{\\{([^\\}]+)\\}\\}/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the attribute name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reAttributeName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for an equals sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"=\");\n\tif(token) {\n\t\tpos = token.end;\n\t\t// Skip whitespace\n\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t// Look for a string literal\n\t\tvar stringLiteral = $tw.utils.parseStringLiteral(source,pos);\n\t\tif(stringLiteral) {\n\t\t\tpos = stringLiteral.end;\n\t\t\tnode.type = \"string\";\n\t\t\tnode.value = stringLiteral.value;\n\t\t} else {\n\t\t\t// Look for a filtered value\n\t\t\tvar filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);\n\t\t\tif(filteredValue) {\n\t\t\t\tpos = filteredValue.end;\n\t\t\t\tnode.type = \"filtered\";\n\t\t\t\tnode.filter = filteredValue.match[1];\n\t\t\t} else {\n\t\t\t\t// Look for an indirect value\n\t\t\t\tvar indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);\n\t\t\t\tif(indirectValue) {\n\t\t\t\t\tpos = indirectValue.end;\n\t\t\t\t\tnode.type = \"indirect\";\n\t\t\t\t\tnode.textReference = indirectValue.match[1];\n\t\t\t\t} else {\n\t\t\t\t\t// Look for a unquoted value\n\t\t\t\t\tvar unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);\n\t\t\t\t\tif(unquotedValue) {\n\t\t\t\t\t\tpos = unquotedValue.end;\n\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\tnode.value = unquotedValue.match[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Look for a macro invocation value\n\t\t\t\t\t\tvar macroInvocation = $tw.utils.parseMacroInvocation(source,pos);\n\t\t\t\t\t\tif(macroInvocation) {\n\t\t\t\t\t\t\tpos = macroInvocation.end;\n\t\t\t\t\t\t\tnode.type = \"macro\";\n\t\t\t\t\t\t\tnode.value = macroInvocation;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\t\tnode.value = \"true\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnode.type = \"string\";\n\t\tnode.value = \"true\";\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/parsers/pdfparser.js": {
"title": "$:/core/modules/parsers/pdfparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/pdfparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe PDF parser embeds a PDF viewer\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"embed\",\n\t\t\tattributes: {}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:application/pdf;base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"application/pdf\"] = ImageParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/textparser.js": {
"title": "$:/core/modules/parsers/textparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/textparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe plain text parser processes blocks of source text into a degenerate parse tree consisting of a single text node\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar TextParser = function(type,text,options) {\n\tthis.tree = [{\n\t\ttype: \"codeblock\",\n\t\tattributes: {\n\t\t\tcode: {type: \"string\", value: text},\n\t\t\tlanguage: {type: \"string\", value: type}\n\t\t}\n\t}];\n};\n\nexports[\"text/plain\"] = TextParser;\nexports[\"text/x-tiddlywiki\"] = TextParser;\nexports[\"application/javascript\"] = TextParser;\nexports[\"application/json\"] = TextParser;\nexports[\"text/css\"] = TextParser;\nexports[\"application/x-tiddler-dictionary\"] = TextParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/videoparser.js": {
"title": "$:/core/modules/parsers/videoparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/videoparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe video parser parses a video tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar VideoParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"video\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"},\n\t\t\t\tstyle: {type: \"string\", value: \"width: 100%; object-fit: contain\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"video/ogg\"] = VideoParser;\nexports[\"video/webm\"] = VideoParser;\nexports[\"video/mp4\"] = VideoParser;\nexports[\"video/quicktime\"] = VideoParser;\n\n})();\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/wikiparser/rules/codeblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/codeblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for code blocks. For example:\n\n```\n\t```\n\tThis text will not be //wikified//\n\t```\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match and get language if defined\n\tthis.matchRegExp = /```([\\w-]*)\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\\r?\\n```$)/mg;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Return the $codeblock widget\n\treturn [{\n\t\t\ttype: \"codeblock\",\n\t\t\tattributes: {\n\t\t\t\t\tcode: {type: \"string\", value: text},\n\t\t\t\t\tlanguage: {type: \"string\", value: this.match[1]}\n\t\t\t}\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/codeinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/codeinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for code runs. For example:\n\n```\n\tThis is a `code run`.\n\tThis is another ``code run``\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(``?)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar reEnd = new RegExp(this.match[1], \"mg\");\n\t// Look for the end marker\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the text\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"code\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: text\n\t\t}]\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/commentblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/commentblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = startPos + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/commentinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/commentinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = startPos + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/dash.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/dash.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/dash.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for dashes. For example:\n\n```\nThis is an en-dash: --\n\nThis is an em-dash: ---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"dash\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{2,3}(?!-)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar dash = this.match[0].length === 2 ? \"–\" : \"—\";\n\treturn [{\n\t\ttype: \"entity\",\n\t\tentity: dash\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/bold.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - bold. For example:\n\n```\n\tThis is ''bold'' text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except bold \n\\rules only bold \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"bold\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /''/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/''/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strong\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/italic.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - italic. For example:\n\n```\n\tThis is //italic// text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except italic\n\\rules only italic\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"italic\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\/\\//mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\/\\//mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"em\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - strikethrough. For example:\n\n```\n\tThis is ~~strikethrough~~ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except strikethrough \n\\rules only strikethrough \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"strikethrough\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~~/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/~~/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strike\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - subscript. For example:\n\n```\n\tThis is ,,subscript,, text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except subscript \n\\rules only subscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"subscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /,,/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/,,/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sub\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - superscript. For example:\n\n```\n\tThis is ^^superscript^^ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except superscript \n\\rules only superscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"superscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\^\\^/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\^\\^/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sup\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - underscore. For example:\n\n```\n\tThis is __underscore__ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except underscore \n\\rules only underscore\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"underscore\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /__/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/__/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"u\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/entity.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/entity.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/entity.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML entities. For example:\n\n```\n\tThis is a copyright symbol: ©\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"entity\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(&#?[a-zA-Z0-9]{2,8};)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar entityString = this.match[1];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Return the entity\n\treturn [{type: \"entity\", entity: this.match[0]}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/extlink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/extlink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/extlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\nAn external link: https://www.tiddlywiki.com/\n\nA suppressed external link: ~http://www.tiddlyspace.com/\n```\n\nExternal links can be suppressed by preceding them with `~`.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"extlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~?(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(this.match[0].substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: this.match[0].substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: this.match[0]},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: this.match[0]\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter}\n\t\t},\n\t\tisBlock: true\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \")};\n\t}\n\treturn [node];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter}\n\t\t}\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \")};\n\t}\n\treturn [node];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for marking areas with hard line breaks. For example:\n\n```\n\"\"\"\nThis is some text\nThat is set like\nIt is a Poem\nWhen it is\nClearly\nNot\n\"\"\"\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"hardlinebreaks\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\"\"\"(?:\\r?\\n)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\"\"\")|(\\r?\\n)/mg,\n\t\ttree = [],\n\t\tmatch;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tdo {\n\t\t// Parse the run up to the terminator\n\t\ttree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false}));\n\t\t// Redo the terminator match\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tmatch = reEnd.exec(this.parser.source);\n\t\tif(match) {\n\t\t\tthis.parser.pos = reEnd.lastIndex;\n\t\t\t// Add a line break if the terminator was a line break\n\t\t\tif(match[2]) {\n\t\t\t\ttree.push({type: \"element\", tag: \"br\"});\n\t\t\t}\n\t\t}\n\t} while(match && !match[1]);\n\t// Return the nodes\n\treturn tree;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/heading.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/heading.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/heading.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for headings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"heading\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(!{1,6})/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar headingLevel = this.match[1].length;\n\t// Move past the !s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse any classes, whitespace and then the heading itself\n\tvar classes = this.parser.parseClasses();\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// Return the heading\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"h\" + headingLevel, \n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: classes.join(\" \")}\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/horizrule.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/horizrule.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/horizrule.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for rules. For example:\n\n```\n---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"horizrule\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{3,}\\r?(?:\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\treturn [{type: \"element\", tag: \"hr\"}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/html.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/html.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/html.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for HTML elements and widgets. For example:\n\n{{{\n<aside>\nThis is an HTML5 aside element\n</aside>\n\n<$slider target=\"MyTiddler\">\nThis is a widget invocation\n</$slider>\n\n}}}\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"html\";\nexports.types = {inline: true, block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextTag = this.findNextTag(this.parser.source,startPos,{\n\t\trequireLineBreak: this.is.block\n\t});\n\treturn this.nextTag ? this.nextTag.start : undefined;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Retrieve the most recent match so that recursive calls don't overwrite it\n\tvar tag = this.nextTag;\n\tthis.nextTag = null;\n\t// Advance the parser position to past the tag\n\tthis.parser.pos = tag.end;\n\t// Check for an immediately following double linebreak\n\tvar hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t// Set whether we're in block mode\n\ttag.isBlock = this.is.block || hasLineBreak;\n\t// Parse the body if we need to\n\tif(!tag.isSelfClosing && $tw.config.htmlVoidElements.indexOf(tag.tag) === -1) {\n\t\t\tvar reEndString = \"</\" + $tw.utils.escapeRegExp(tag.tag) + \">\",\n\t\t\t\treEnd = new RegExp(\"(\" + reEndString + \")\",\"mg\");\n\t\tif(hasLineBreak) {\n\t\t\ttag.children = this.parser.parseBlocks(reEndString);\n\t\t} else {\n\t\t\ttag.children = this.parser.parseInlineRun(reEnd);\n\t\t}\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tvar endMatch = reEnd.exec(this.parser.source);\n\t\tif(endMatch && endMatch.index === this.parser.pos) {\n\t\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t\t}\n\t}\n\t// Return the tag\n\treturn [tag];\n};\n\n/*\nLook for an HTML tag. Returns null if not found, otherwise returns {type: \"element\", name:, attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseTag = function(source,pos,options) {\n\toptions = options || {};\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Define our regexps\n\tvar reTagName = /([a-zA-Z0-9\\-\\$]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a less than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\"<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the tag name\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,reTagName);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tnode.tag = token.match[1];\n\tif(node.tag.slice(1).indexOf(\"$\") !== -1) {\n\t\treturn null;\n\t}\n\tif(node.tag.charAt(0) === \"$\") {\n\t\tnode.type = node.tag.substr(1);\n\t}\n\tpos = token.end;\n\t// Check that the tag is terminated by a space, / or >\n\tif(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === \"/\") && !(source.charAt(pos) === \">\") ) {\n\t\treturn null;\n\t}\n\t// Process attributes\n\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\twhile(attribute) {\n\t\tnode.attributes[attribute.name] = attribute;\n\t\tpos = attribute.end;\n\t\t// Get the next attribute\n\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a closing slash\n\ttoken = $tw.utils.parseTokenString(source,pos,\"/\");\n\tif(token) {\n\t\tpos = token.end;\n\t\tnode.isSelfClosing = true;\n\t}\n\t// Look for a greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Check for a required line break\n\tif(options.requireLineBreak) {\n\t\ttoken = $tw.utils.parseTokenRegExp(source,pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t\tif(!token) {\n\t\t\treturn null;\n\t\t}\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\nexports.findNextTag = function(source,pos,options) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /<([a-zA-Z\\-\\$]+)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseTag(source,match.index,options);\n\t\t// Return success\n\t\tif(tag && this.isLegalTag(tag)) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\nexports.isLegalTag = function(tag) {\n\t// Widgets are always OK\n\tif(tag.type !== \"element\") {\n\t\treturn true;\n\t// If it's an HTML tag that starts with a dash then it's not legal\n\t} else if(tag.tag.charAt(0) === \"-\") {\n\t\treturn false;\n\t} else {\n\t\t// Otherwise it's OK\n\t\treturn true;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/image.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/image.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/image.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for embedding images. For example:\n\n```\n[img[https://tiddlywiki.com/fractalveg.jpg]]\n[img width=23 height=24 [https://tiddlywiki.com/fractalveg.jpg]]\n[img width={{!!width}} height={{!!height}} [https://tiddlywiki.com/fractalveg.jpg]]\n[img[Description of image|https://tiddlywiki.com/fractalveg.jpg]]\n[img[TiddlerTitle]]\n[img[Description of image|TiddlerTitle]]\n```\n\nGenerates the `<$image>` widget.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"image\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextImage = this.findNextImage(this.parser.source,startPos);\n\treturn this.nextImage ? this.nextImage.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextImage.end;\n\tvar node = {\n\t\ttype: \"image\",\n\t\tattributes: this.nextImage.attributes\n\t};\n\treturn [node];\n};\n\n/*\nFind the next image from the current position\n*/\nexports.findNextImage = function(source,pos) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /(\\[img)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseImage(source,match.index);\n\t\t// Return success\n\t\tif(tag) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an image at the specified position. Returns null if not found, otherwise returns {type: \"image\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseImage = function(source,pos) {\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"image\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[img`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[img\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Process attributes\n\tif(source.charAt(pos) !== \"[\") {\n\t\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\t\twhile(attribute) {\n\t\t\tnode.attributes[attribute.name] = attribute;\n\t\t\tpos = attribute.end;\n\t\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t\tif(source.charAt(pos) !== \"[\") {\n\t\t\t\t// Get the next attribute\n\t\t\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t\t\t} else {\n\t\t\t\tattribute = null;\n\t\t\t}\n\t\t}\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[` after the attributes\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the source up to the terminating `]]`\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\\]]*?)\\|)?([^\\]]+?)\\]\\]/g);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\tif(token.match[1]) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: token.match[1].trim()};\n\t}\n\tnode.attributes.source = {type: \"string\", value: (token.match[2] || \"\").trim()};\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/import.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/import.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/import.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for importing variable definitions\n\n```\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"import\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\import[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the filter terminated by a line break\n\tvar reMatch = /(.*)(\\r?\\n)|$/mg;\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\tthis.parser.pos = reMatch.lastIndex;\n\t// Parse tree nodes to return\n\treturn [{\n\t\ttype: \"importvariables\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: match[1]}\n\t\t},\n\t\tchildren: []\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/list.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/list.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/list.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for lists. For example:\n\n```\n* This is an unordered list\n* It has two items\n\n# This is a numbered list\n## With a subitem\n# And a third item\n\n; This is a term that is being defined\n: This is the definition of that term\n```\n\nNote that lists can be nested arbitrarily:\n\n```\n#** One\n#* Two\n#** Three\n#**** Four\n#**# Five\n#**## Six\n## Seven\n### Eight\n## Nine\n```\n\nA CSS class can be applied to a list item as follows:\n\n```\n* List item one\n*.active List item two has the class `active`\n* List item three\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"list\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /([\\*#;:>]+)/mg;\n};\n\nvar listTypes = {\n\t\"*\": {listTag: \"ul\", itemTag: \"li\"},\n\t\"#\": {listTag: \"ol\", itemTag: \"li\"},\n\t\";\": {listTag: \"dl\", itemTag: \"dt\"},\n\t\":\": {listTag: \"dl\", itemTag: \"dd\"},\n\t\">\": {listTag: \"blockquote\", itemTag: \"div\"}\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Array of parse tree nodes for the previous row of the list\n\tvar listStack = [];\n\t// Cycle through the items in the list\n\twhile(true) {\n\t\t// Match the list marker\n\t\tvar reMatch = /([\\*#;:>]+)/mg;\n\t\treMatch.lastIndex = this.parser.pos;\n\t\tvar match = reMatch.exec(this.parser.source);\n\t\tif(!match || match.index !== this.parser.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check whether the list type of the top level matches\n\t\tvar listInfo = listTypes[match[0].charAt(0)];\n\t\tif(listStack.length > 0 && listStack[0].tag !== listInfo.listTag) {\n\t\t\tbreak;\n\t\t}\n\t\t// Move past the list marker\n\t\tthis.parser.pos = match.index + match[0].length;\n\t\t// Walk through the list markers for the current row\n\t\tfor(var t=0; t<match[0].length; t++) {\n\t\t\tlistInfo = listTypes[match[0].charAt(t)];\n\t\t\t// Remove any stacked up element if we can't re-use it because the list type doesn't match\n\t\t\tif(listStack.length > t && listStack[t].tag !== listInfo.listTag) {\n\t\t\t\tlistStack.splice(t,listStack.length - t);\n\t\t\t}\n\t\t\t// Construct the list element or reuse the previous one at this level\n\t\t\tif(listStack.length <= t) {\n\t\t\t\tvar listElement = {type: \"element\", tag: listInfo.listTag, children: [\n\t\t\t\t\t{type: \"element\", tag: listInfo.itemTag, children: []}\n\t\t\t\t]};\n\t\t\t\t// Link this list element into the last child item of the parent list item\n\t\t\t\tif(t) {\n\t\t\t\t\tvar prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];\n\t\t\t\t\tprevListItem.children.push(listElement);\n\t\t\t\t}\n\t\t\t\t// Save this element in the stack\n\t\t\t\tlistStack[t] = listElement;\n\t\t\t} else if(t === (match[0].length - 1)) {\n\t\t\t\tlistStack[t].children.push({type: \"element\", tag: listInfo.itemTag, children: []});\n\t\t\t}\n\t\t}\n\t\tif(listStack.length > match[0].length) {\n\t\t\tlistStack.splice(match[0].length,listStack.length - match[0].length);\n\t\t}\n\t\t// Process the body of the list item into the last list item\n\t\tvar lastListChildren = listStack[listStack.length-1].children,\n\t\t\tlastListItem = lastListChildren[lastListChildren.length-1],\n\t\t\tclasses = this.parser.parseClasses();\n\t\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\t\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t\tlastListItem.children.push.apply(lastListItem.children,tree);\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(\" \"));\n\t\t}\n\t\t// Consume any whitespace following the list item\n\t\tthis.parser.skipWhitespace();\n\t}\n\t// Return the root element of the list\n\treturn [listStack[0]];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/macrocallblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/macrocallblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for block macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /<<([^>\\s]+)(?:\\s*)((?:[^>]|(?:>(?!>)))*?)>>(?:\\r?\\n|$)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar macroName = this.match[1],\n\t\tparamString = this.match[2];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn [{\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params,\n\t\tisBlock: true\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/macrocallinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/macrocallinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /<<([^\\s>]+)\\s*([\\s\\S]*?)>>/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar macroName = this.match[1],\n\t\tparamString = this.match[2];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5]|| paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn [{\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/macrodef.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/macrodef.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrodef.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for macro definitions\n\n```\n\\define name(param:defaultvalue,param2:defaultvalue)\ndefinition text, including $param$ markers\n\\end\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrodef\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\define\\s+([^(\\s]+)\\(\\s*([^)]*)\\)(\\s*\\r?\\n)?/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the macro name and parameters\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the parameters\n\tvar paramString = this.match[2],\n\t\tparams = [];\n\tif(paramString !== \"\") {\n\t\tvar reParam = /\\s*([A-Za-z0-9\\-_]+)(?:\\s*:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))?/mg,\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\twhile(paramMatch) {\n\t\t\t// Save the parameter details\n\t\t\tvar paramInfo = {name: paramMatch[1]},\n\t\t\t\tdefaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6];\n\t\t\tif(defaultValue) {\n\t\t\t\tparamInfo[\"default\"] = defaultValue;\n\t\t\t}\n\t\t\tparams.push(paramInfo);\n\t\t\t// Look for the next parameter\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\t}\n\t}\n\t// Is this a multiline definition?\n\tvar reEnd;\n\tif(this.match[3]) {\n\t\t// If so, the end of the body is marked with \\end\n\t\treEnd = /(\\r?\\n\\\\end[^\\S\\n\\r]*(?:$|\\r?\\n))/mg;\n\t} else {\n\t\t// Otherwise, the end of the definition is marked by the end of the line\n\t\treEnd = /($|\\r?\\n)/mg;\n\t\t// Move past any whitespace\n\t\tthis.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);\n\t}\n\t// Find the end of the definition\n\treEnd.lastIndex = this.parser.pos;\n\tvar text,\n\t\tendMatch = reEnd.exec(this.parser.source);\n\tif(endMatch) {\n\t\ttext = this.parser.source.substring(this.parser.pos,endMatch.index);\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t} else {\n\t\t// We didn't find the end of the definition, so we'll make it blank\n\t\ttext = \"\";\n\t}\n\t// Save the macro definition\n\treturn [{\n\t\ttype: \"set\",\n\t\tattributes: {\n\t\t\tname: {type: \"string\", value: this.match[1]},\n\t\t\tvalue: {type: \"string\", value: text}\n\t\t},\n\t\tchildren: [],\n\t\tparams: params,\n\t\tisMacroDefinition: true\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/prettyextlink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/prettyextlink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettyextlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\n[ext[https://tiddlywiki.com/fractalveg.jpg]]\n[ext[Tooltip|https://tiddlywiki.com/fractalveg.jpg]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettyextlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextLink = this.findNextLink(this.parser.source,startPos);\n\treturn this.nextLink ? this.nextLink.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextLink.end;\n\treturn [this.nextLink];\n};\n\n/*\nFind the next link from the current position\n*/\nexports.findNextLink = function(source,pos) {\n\t// A regexp for finding candidate links\n\tvar reLookahead = /(\\[ext\\[)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a link\n\t\tvar link = this.parseLink(source,match.index);\n\t\t// Return success\n\t\tif(link) {\n\t\t\treturn link;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an link at the specified position. Returns null if not found, otherwise returns {type: \"element\", tag: \"a\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseLink = function(source,pos) {\n\tvar token,\n\t\ttextNode = {\n\t\t\ttype: \"text\"\n\t\t},\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tstart: pos,\n\t\t\tattributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t},\n\t\t\tchildren: [textNode]\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[ext[`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[ext[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Look ahead for the terminating `]]`\n\tvar closePos = source.indexOf(\"]]\",pos);\n\tif(closePos === -1) {\n\t\treturn null;\n\t}\n\t// Look for a `|` separating the tooltip\n\tvar splitPos = source.indexOf(\"|\",pos);\n\tif(splitPos === -1 || splitPos > closePos) {\n\t\tsplitPos = null;\n\t}\n\t// Pull out the tooltip and URL\n\tvar tooltip, URL;\n\tif(splitPos) {\n\t\tURL = source.substring(splitPos + 1,closePos).trim();\n\t\ttextNode.text = source.substring(pos,splitPos).trim();\n\t} else {\n\t\tURL = source.substring(pos,closePos).trim();\n\t\ttextNode.text = URL;\n\t}\n\tnode.attributes.href = {type: \"string\", value: URL};\n\tnode.attributes.target = {type: \"string\", value: \"_blank\"};\n\tnode.attributes.rel = {type: \"string\", value: \"noopener noreferrer\"};\n\t// Update the end position\n\tnode.end = closePos + 2;\n\treturn node;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/prettylink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/prettylink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettylink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for pretty links. For example:\n\n```\n[[Introduction]]\n\n[[Link description|TiddlerTitle]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettylink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\[\\[(.*?)(?:\\|(.*?))?\\]\\]/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Process the link\n\tvar text = this.match[1],\n\t\tlink = this.match[2] || text;\n\tif($tw.utils.isLinkExternal(link)) {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: link},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: link}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/quoteblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/quoteblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/quoteblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for quote blocks. For example:\n\n```\n\t<<<.optionalClass(es) optional cited from\n\ta quote\n\t<<<\n\t\n\t<<<.optionalClass(es)\n\ta quote\n\t<<< optional cited from\n```\n\nQuotes can be quoted by putting more <s\n\n```\n\t<<<\n\tQuote Level 1\n\t\n\t<<<<\n\tQuoteLevel 2\n\t<<<<\n\t\n\t<<<\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"quoteblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(<<<+)/mg;\n};\n\nexports.parse = function() {\n\tvar classes = [\"tc-quote\"];\n\t// Get all the details of the match\n\tvar reEndString = \"^\" + this.match[1] + \"(?!<)\";\n\t// Move past the <s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\n\t// Parse any classes, whitespace and then the optional cite itself\n\tclasses.push.apply(classes, this.parser.parseClasses());\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar cite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// before handling the cite, parse the body of the quote\n\tvar tree= this.parser.parseBlocks(reEndString);\n\t// If we got a cite, put it before the text\n\tif(cite.length > 0) {\n\t\ttree.unshift({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite\n\t\t});\n\t}\n\t// Parse any optional cite\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tcite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// If we got a cite, push it\n\tif(cite.length > 0) {\n\t\ttree.push({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite\n\t\t});\n\t}\n\t// Return the blockquote element\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"blockquote\",\n\t\tattributes: {\n\t\t\tclass: { type: \"string\", value: classes.join(\" \") },\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/rules.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/rules.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/rules.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for rules specifications\n\n```\n\\rules except ruleone ruletwo rulethree\n\\rules only ruleone ruletwo rulethree\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"rules\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\rules[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\tif(tokens.length > 0) {\n\t\tthis.parser.amendRules(tokens[0],tokens.slice(1));\n\t}\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/styleblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/styleblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for assigning styles and classes to paragraphs and other blocks. For example:\n\n```\n@@.myClass\n@@background-color:red;\nThis paragraph will have the CSS class `myClass`.\n\n* The `<ul>` around this list will also have the class `myClass`\n* List item 2\n\n@@\n```\n\nNote that classes and styles can be mixed subject to the rule that styles must precede classes. For example\n\n```\n@@.myFirstClass.mySecondClass\n@@width:100px;.myThirdClass\nThis is a paragraph\n@@\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(?:\\.([^\\r\\n\\s]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEndString = \"^@@(?:\\\\r?\\\\n)?\";\n\tvar classes = [], styles = [];\n\tdo {\n\t\t// Get the class and style\n\t\tif(this.match[1]) {\n\t\t\tstyles.push(this.match[1]);\n\t\t}\n\t\tif(this.match[2]) {\n\t\t\tclasses.push(this.match[2].split(\".\").join(\" \"));\n\t\t}\n\t\t// Move past the match\n\t\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\t// Look for another line of classes and styles\n\t\tthis.match = this.matchRegExp.exec(this.parser.source);\n\t} while(this.match && this.match.index === this.parser.pos);\n\t// Parse the body\n\tvar tree = this.parser.parseBlocks(reEndString);\n\tfor(var t=0; t<tree.length; t++) {\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(tree[t],classes.join(\" \"));\n\t\t}\n\t\tif(styles.length > 0) {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(tree[t],\"style\",styles.join(\"\"));\n\t\t}\n\t}\n\treturn tree;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/styleinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/styleinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for assigning styles and classes to inline runs. For example:\n\n```\n@@.myClass This is some text with a class@@\n@@background-color:red;This is some text with a background colour@@\n@@width:100px;.myClass This is some text with a class and a width@@\n```\n\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(\\.(?:[^\\r\\n\\s]+)\\s+)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /@@/g;\n\t// Get the styles and class\n\tvar stylesString = this.match[1],\n\t\tclassString = this.match[2] ? this.match[2].split(\".\").join(\" \") : undefined;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the run up to the terminator\n\tvar tree = this.parser.parseInlineRun(reEnd,{eatTerminator: true});\n\t// Return the classed span\n\tvar node = {\n\t\ttype: \"element\",\n\t\ttag: \"span\",\n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: \"tc-inline-style\"}\n\t\t},\n\t\tchildren: tree\n\t};\n\tif(classString) {\n\t\t$tw.utils.addClassToParseTreeNode(node,classString);\n\t}\n\tif(stylesString) {\n\t\t$tw.utils.addAttributeToParseTreeNode(node,\"style\",stylesString);\n\t}\n\treturn [node];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/syslink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/syslink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/syslink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for system tiddler links.\nCan be suppressed preceding them with `~`.\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"syslink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp(\n\t\t\"~?\\\\$:\\\\/[\" +\n\t\t$tw.config.textPrimitives.anyLetter.substr(1,$tw.config.textPrimitives.anyLetter.length - 2) +\n\t\t\"\\/._-]+\",\n\t\t\"mg\"\n\t);\n};\n\nexports.parse = function() {\n\tvar match = this.match[0];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(match.substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: match.substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: match}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: match\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/table.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/table.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/table.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for tables.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"table\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\|(?:[^\\n]*)\\|(?:[fhck]?)\\r?(?:\\n|$)/mg;\n};\n\nvar processRow = function(prevColumns) {\n\tvar cellRegExp = /(?:\\|([^\\n\\|]*)\\|)|(\\|[fhck]?\\r?(?:\\n|$))/mg,\n\t\tcellTermRegExp = /((?:\\x20*)\\|)/mg,\n\t\ttree = [],\n\t\tcol = 0,\n\t\tcolSpanCount = 1,\n\t\tprevCell,\n\t\tvAlign;\n\t// Match a single cell\n\tcellRegExp.lastIndex = this.parser.pos;\n\tvar cellMatch = cellRegExp.exec(this.parser.source);\n\twhile(cellMatch && cellMatch.index === this.parser.pos) {\n\t\tif(cellMatch[1] === \"~\") {\n\t\t\t// Rowspan\n\t\t\tvar last = prevColumns[col];\n\t\t\tif(last) {\n\t\t\t\tlast.rowSpanCount++;\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"rowspan\",last.rowSpanCount);\n\t\t\t\tvAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,\"valign\",\"center\");\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"valign\",vAlign);\n\t\t\t\tif(colSpanCount > 1) {\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"colspan\",colSpanCount);\n\t\t\t\t\tcolSpanCount = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \">\") {\n\t\t\t// Colspan\n\t\t\tcolSpanCount++;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \"<\" && prevCell) {\n\t\t\tcolSpanCount = 1 + $tw.utils.getAttributeValueFromParseTreeNode(prevCell,\"colspan\",1);\n\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\tcolSpanCount = 1;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[2]) {\n\t\t\t// End of row\n\t\t\tif(prevCell && colSpanCount > 1) {\n\t\t\t\tif(prevCell.attributes && prevCell.attributes && prevCell.attributes.colspan) {\n\t\t\t\t\t\tcolSpanCount += prevCell.attributes.colspan.value;\n\t\t\t\t} else {\n\t\t\t\t\tcolSpanCount -= 1;\n\t\t\t\t}\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\t}\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t// For ordinary cells, step beyond the opening `|`\n\t\t\tthis.parser.pos++;\n\t\t\t// Look for a space at the start of the cell\n\t\t\tvar spaceLeft = false;\n\t\t\tvAlign = null;\n\t\t\tif(this.parser.source.substr(this.parser.pos).search(/^\\^([^\\^]|\\^\\^)/) === 0) {\n\t\t\t\tvAlign = \"top\";\n\t\t\t} else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) {\n\t\t\t\tvAlign = \"bottom\";\n\t\t\t}\n\t\t\tif(vAlign) {\n\t\t\t\tthis.parser.pos++;\n\t\t\t}\n\t\t\tvar chr = this.parser.source.substr(this.parser.pos,1);\n\t\t\twhile(chr === \" \") {\n\t\t\t\tspaceLeft = true;\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tchr = this.parser.source.substr(this.parser.pos,1);\n\t\t\t}\n\t\t\t// Check whether this is a heading cell\n\t\t\tvar cell;\n\t\t\tif(chr === \"!\") {\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tcell = {type: \"element\", tag: \"th\", children: []};\n\t\t\t} else {\n\t\t\t\tcell = {type: \"element\", tag: \"td\", children: []};\n\t\t\t}\n\t\t\ttree.push(cell);\n\t\t\t// Record information about this cell\n\t\t\tprevCell = cell;\n\t\t\tprevColumns[col] = {rowSpanCount:1,element:cell};\n\t\t\t// Check for a colspan\n\t\t\tif(colSpanCount > 1) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"colspan\",colSpanCount);\n\t\t\t\tcolSpanCount = 1;\n\t\t\t}\n\t\t\t// Parse the cell\n\t\t\tcell.children = this.parser.parseInlineRun(cellTermRegExp,{eatTerminator: true});\n\t\t\t// Set the alignment for the cell\n\t\t\tif(vAlign) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"valign\",vAlign);\n\t\t\t}\n\t\t\tif(this.parser.source.substr(this.parser.pos - 2,1) === \" \") { // spaceRight\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",spaceLeft ? \"center\" : \"left\");\n\t\t\t} else if(spaceLeft) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",\"right\");\n\t\t\t}\n\t\t\t// Move back to the closing `|`\n\t\t\tthis.parser.pos--;\n\t\t}\n\t\tcol++;\n\t\tcellRegExp.lastIndex = this.parser.pos;\n\t\tcellMatch = cellRegExp.exec(this.parser.source);\n\t}\n\treturn tree;\n};\n\nexports.parse = function() {\n\tvar rowContainerTypes = {\"c\":\"caption\", \"h\":\"thead\", \"\":\"tbody\", \"f\":\"tfoot\"},\n\t\ttable = {type: \"element\", tag: \"table\", children: []},\n\t\trowRegExp = /^\\|([^\\n]*)\\|([fhck]?)\\r?(?:\\n|$)/mg,\n\t\trowTermRegExp = /(\\|(?:[fhck]?)\\r?(?:\\n|$))/mg,\n\t\tprevColumns = [],\n\t\tcurrRowType,\n\t\trowContainer,\n\t\trowCount = 0;\n\t// Match the row\n\trowRegExp.lastIndex = this.parser.pos;\n\tvar rowMatch = rowRegExp.exec(this.parser.source);\n\twhile(rowMatch && rowMatch.index === this.parser.pos) {\n\t\tvar rowType = rowMatch[2];\n\t\t// Check if it is a class assignment\n\t\tif(rowType === \"k\") {\n\t\t\t$tw.utils.addClassToParseTreeNode(table,rowMatch[1]);\n\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t} else {\n\t\t\t// Otherwise, create a new row if this one is of a different type\n\t\t\tif(rowType !== currRowType) {\n\t\t\t\trowContainer = {type: \"element\", tag: rowContainerTypes[rowType], children: []};\n\t\t\t\ttable.children.push(rowContainer);\n\t\t\t\tcurrRowType = rowType;\n\t\t\t}\n\t\t\t// Is this a caption row?\n\t\t\tif(currRowType === \"c\") {\n\t\t\t\t// If so, move past the opening `|` of the row\n\t\t\t\tthis.parser.pos++;\n\t\t\t\t// Move the caption to the first row if it isn't already\n\t\t\t\tif(table.children.length !== 1) {\n\t\t\t\t\ttable.children.pop(); // Take rowContainer out of the children array\n\t\t\t\t\ttable.children.splice(0,0,rowContainer); // Insert it at the bottom\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t// Set the alignment - TODO: figure out why TW did this\n//\t\t\t\trowContainer.attributes.align = rowCount === 0 ? \"top\" : \"bottom\";\n\t\t\t\t// Parse the caption\n\t\t\t\trowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true});\n\t\t\t} else {\n\t\t\t\t// Create the row\n\t\t\t\tvar theRow = {type: \"element\", tag: \"tr\", children: []};\n\t\t\t\t$tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? \"oddRow\" : \"evenRow\");\n\t\t\t\trowContainer.children.push(theRow);\n\t\t\t\t// Process the row\n\t\t\t\ttheRow.children = processRow.call(this,prevColumns);\n\t\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t\t\t// Increment the row count\n\t\t\t\trowCount++;\n\t\t\t}\n\t\t}\n\t\trowMatch = rowRegExp.exec(this.parser.source);\n\t}\n\treturn [table];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/transcludeblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/transcludeblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]);\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {},\n\t\t\tisBlock: true\n\t\t};\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tisBlock: true,\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes.field = {type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes.index = {type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/transcludeinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/transcludeinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]);\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {}\n\t\t};\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes.field = {type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes.index = {type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/typedblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/typedblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/typedblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for typed blocks. For example:\n\n```\n$$$.js\nThis will be rendered as JavaScript\n$$$\n\n$$$.svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"150\" height=\"100\">\n <circle cx=\"100\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\" />\n</svg>\n$$$\n\n$$$text/vnd.tiddlywiki>text/html\nThis will be rendered as an //HTML representation// of WikiText\n$$$\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.name = \"typedblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\$\\$\\$([^ >\\r\\n]*)(?: *> *([^ \\r\\n]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /\\r?\\n\\$\\$\\$\\r?(?:\\n|$)/mg;\n\t// Save the type\n\tvar parseType = this.match[1],\n\t\trenderType = this.match[2];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Parse the block according to the specified type\n\tvar parser = this.parser.wiki.parseText(parseType,text,{defaultType: \"text/plain\"});\n\t// If there's no render type, just return the parse tree\n\tif(!renderType) {\n\t\treturn parser.tree;\n\t} else {\n\t\t// Otherwise, render to the rendertype and return in a <PRE> tag\n\t\tvar widgetNode = this.parser.wiki.makeWidget(parser),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\ttext = renderType === \"text/html\" ? container.innerHTML : container.textContent;\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"pre\",\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: text\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/whitespace.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/whitespace.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/whitespace.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for whitespace specifications\n\n```\n\\whitespace trim\n\\whitespace notrim\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"whitespace\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\whitespace[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\t$tw.utils.each(tokens,function(token) {\n\t\tswitch(token) {\n\t\t\tcase \"trim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = true;\n\t\t\t\tbreak;\n\t\t\tcase \"notrim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = false;\n\t\t\t\tbreak;\n\t\t}\n\t});\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/wikilink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/wikilink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikilink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for wiki links. For example:\n\n```\nAWikiLink\nAnotherLink\n~SuppressedLink\n```\n\nPrecede a camel case word with `~` to prevent it from being recognised as a link.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"wikilink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + \"?\" + $tw.config.textPrimitives.wikiLink,\"mg\");\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get the details of the match\n\tvar linkText = this.match[0];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// If the link starts with the unwikilink character then just output it as plain text\n\tif(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {\n\t\treturn [{type: \"text\", text: linkText.substr(1)}];\n\t}\n\t// If the link has been preceded with a blocked letter then don't treat it as a link\n\tif(this.match.index > 0) {\n\t\tvar preRegExp = new RegExp($tw.config.textPrimitives.blockPrefixLetters,\"mg\");\n\t\tpreRegExp.lastIndex = this.match.index-1;\n\t\tvar preMatch = preRegExp.exec(this.parser.source);\n\t\tif(preMatch && preMatch.index === this.match.index-1) {\n\t\t\treturn [{type: \"text\", text: linkText}];\n\t\t}\n\t}\n\treturn [{\n\t\ttype: \"link\",\n\t\tattributes: {\n\t\t\tto: {type: \"string\", value: linkText}\n\t\t},\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: linkText\n\t\t}]\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/wikiparser.js": {
"title": "$:/core/modules/parsers/wikiparser/wikiparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/wikiparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe wiki text parser processes blocks of source text into a parse tree.\n\nThe parse tree is made up of nested arrays of these JavaScript objects:\n\n\t{type: \"element\", tag: <string>, attributes: {}, children: []} - an HTML element\n\t{type: \"text\", text: <string>} - a text node\n\t{type: \"entity\", value: <string>} - an entity\n\t{type: \"raw\", html: <string>} - raw HTML\n\nAttributes are stored as hashmaps of the following objects:\n\n\t{type: \"string\", value: <string>} - literal string\n\t{type: \"indirect\", textReference: <textReference>} - indirect through a text reference\n\t{type: \"macro\", macro: <TBD>} - indirect through a macro invocation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar WikiParser = function(type,text,options) {\n\tthis.wiki = options.wiki;\n\tvar self = this;\n\t// Check for an externally linked tiddler\n\tif($tw.browser && (text || \"\") === \"\" && options._canonical_uri) {\n\t\tthis.loadRemoteTiddler(options._canonical_uri);\n\t\ttext = $tw.language.getRawString(\"LazyLoadingWarning\");\n\t}\n\t// Initialise the classes if we don't have them already\n\tif(!this.pragmaRuleClasses) {\n\t\tWikiParser.prototype.pragmaRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"pragma\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.pragmaRuleClasses,\"$:/config/WikiParserRules/Pragmas/\");\n\t}\n\tif(!this.blockRuleClasses) {\n\t\tWikiParser.prototype.blockRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"block\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.blockRuleClasses,\"$:/config/WikiParserRules/Block/\");\n\t}\n\tif(!this.inlineRuleClasses) {\n\t\tWikiParser.prototype.inlineRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"inline\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.inlineRuleClasses,\"$:/config/WikiParserRules/Inline/\");\n\t}\n\t// Save the parse text\n\tthis.type = type || \"text/vnd.tiddlywiki\";\n\tthis.source = text || \"\";\n\tthis.sourceLength = this.source.length;\n\t// Flag for ignoring whitespace\n\tthis.configTrimWhiteSpace = false;\n\t// Set current parse position\n\tthis.pos = 0;\n\t// Instantiate the pragma parse rules\n\tthis.pragmaRules = this.instantiateRules(this.pragmaRuleClasses,\"pragma\",0);\n\t// Instantiate the parser block and inline rules\n\tthis.blockRules = this.instantiateRules(this.blockRuleClasses,\"block\",0);\n\tthis.inlineRules = this.instantiateRules(this.inlineRuleClasses,\"inline\",0);\n\t// Parse any pragmas\n\tthis.tree = [];\n\tvar topBranch = this.parsePragmas();\n\t// Parse the text into inline runs or blocks\n\tif(options.parseAsInline) {\n\t\ttopBranch.push.apply(topBranch,this.parseInlineRun());\n\t} else {\n\t\ttopBranch.push.apply(topBranch,this.parseBlocks());\n\t}\n\t// Return the parse tree\n};\n\n/*\n*/\nWikiParser.prototype.loadRemoteTiddler = function(url) {\n\tvar self = this;\n\t$tw.utils.httpRequest({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tcallback: function(err,data) {\n\t\t\tif(!err) {\n\t\t\t\tvar tiddlers = self.wiki.deserializeTiddlers(\".tid\",data,self.wiki.getCreationFields());\n\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\ttiddler[\"_canonical_uri\"] = url;\n\t\t\t\t});\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tself.wiki.addTiddlers(tiddlers);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\n*/\nWikiParser.prototype.setupRules = function(proto,configPrefix) {\n\tvar self = this;\n\tif(!$tw.safemode) {\n\t\t$tw.utils.each(proto,function(object,name) {\n\t\t\tif(self.wiki.getTiddlerText(configPrefix + name,\"enable\") !== \"enable\") {\n\t\t\t\tdelete proto[name];\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nInstantiate an array of parse rules\n*/\nWikiParser.prototype.instantiateRules = function(classes,type,startPos) {\n\tvar rulesInfo = [],\n\t\tself = this;\n\t$tw.utils.each(classes,function(RuleClass) {\n\t\t// Instantiate the rule\n\t\tvar rule = new RuleClass(self);\n\t\trule.is = {};\n\t\trule.is[type] = true;\n\t\trule.init(self);\n\t\tvar matchIndex = rule.findNextMatch(startPos);\n\t\tif(matchIndex !== undefined) {\n\t\t\trulesInfo.push({\n\t\t\t\trule: rule,\n\t\t\t\tmatchIndex: matchIndex\n\t\t\t});\n\t\t}\n\t});\n\treturn rulesInfo;\n};\n\n/*\nSkip any whitespace at the current position. Options are:\n\ttreatNewlinesAsNonWhitespace: true if newlines are NOT to be treated as whitespace\n*/\nWikiParser.prototype.skipWhitespace = function(options) {\n\toptions = options || {};\n\tvar whitespaceRegExp = options.treatNewlinesAsNonWhitespace ? /([^\\S\\n]+)/mg : /(\\s+)/mg;\n\twhitespaceRegExp.lastIndex = this.pos;\n\tvar whitespaceMatch = whitespaceRegExp.exec(this.source);\n\tif(whitespaceMatch && whitespaceMatch.index === this.pos) {\n\t\tthis.pos = whitespaceRegExp.lastIndex;\n\t}\n};\n\n/*\nGet the next match out of an array of parse rule instances\n*/\nWikiParser.prototype.findNextMatch = function(rules,startPos) {\n\t// Find the best matching rule by finding the closest match position\n\tvar matchingRule,\n\t\tmatchingRulePos = this.sourceLength;\n\t// Step through each rule\n\tfor(var t=0; t<rules.length; t++) {\n\t\tvar ruleInfo = rules[t];\n\t\t// Ask the rule to get the next match if we've moved past the current one\n\t\tif(ruleInfo.matchIndex !== undefined && ruleInfo.matchIndex < startPos) {\n\t\t\truleInfo.matchIndex = ruleInfo.rule.findNextMatch(startPos);\n\t\t}\n\t\t// Adopt this match if it's closer than the current best match\n\t\tif(ruleInfo.matchIndex !== undefined && ruleInfo.matchIndex <= matchingRulePos) {\n\t\t\tmatchingRule = ruleInfo;\n\t\t\tmatchingRulePos = ruleInfo.matchIndex;\n\t\t}\n\t}\n\treturn matchingRule;\n};\n\n/*\nParse any pragmas at the beginning of a block of parse text\n*/\nWikiParser.prototype.parsePragmas = function() {\n\tvar currentTreeBranch = this.tree;\n\twhile(true) {\n\t\t// Skip whitespace\n\t\tthis.skipWhitespace();\n\t\t// Check for the end of the text\n\t\tif(this.pos >= this.sourceLength) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check if we've arrived at a pragma rule match\n\t\tvar nextMatch = this.findNextMatch(this.pragmaRules,this.pos);\n\t\t// If not, just exit\n\t\tif(!nextMatch || nextMatch.matchIndex !== this.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the pragma rule\n\t\tvar subTree = nextMatch.rule.parse();\n\t\tif(subTree.length > 0) {\n\t\t\t// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment\n\t\t\tcurrentTreeBranch.push.apply(currentTreeBranch,subTree);\n\t\t\tsubTree[0].children = [];\n\t\t\tcurrentTreeBranch = subTree[0].children;\n\t\t}\n\t}\n\treturn currentTreeBranch;\n};\n\n/*\nParse a block from the current position\n\tterminatorRegExpString: optional regular expression string that identifies the end of plain paragraphs. Must not include capturing parenthesis\n*/\nWikiParser.prototype.parseBlock = function(terminatorRegExpString) {\n\tvar terminatorRegExp = terminatorRegExpString ? new RegExp(\"(\" + terminatorRegExpString + \"|\\\\r?\\\\n\\\\r?\\\\n)\",\"mg\") : /(\\r?\\n\\r?\\n)/mg;\n\tthis.skipWhitespace();\n\tif(this.pos >= this.sourceLength) {\n\t\treturn [];\n\t}\n\t// Look for a block rule that applies at the current position\n\tvar nextMatch = this.findNextMatch(this.blockRules,this.pos);\n\tif(nextMatch && nextMatch.matchIndex === this.pos) {\n\t\treturn nextMatch.rule.parse();\n\t}\n\t// Treat it as a paragraph if we didn't find a block rule\n\treturn [{type: \"element\", tag: \"p\", children: this.parseInlineRun(terminatorRegExp)}];\n};\n\n/*\nParse a series of blocks of text until a terminating regexp is encountered or the end of the text\n\tterminatorRegExpString: terminating regular expression\n*/\nWikiParser.prototype.parseBlocks = function(terminatorRegExpString) {\n\tif(terminatorRegExpString) {\n\t\treturn this.parseBlocksTerminated(terminatorRegExpString);\n\t} else {\n\t\treturn this.parseBlocksUnterminated();\n\t}\n};\n\n/*\nParse a block from the current position to the end of the text\n*/\nWikiParser.prototype.parseBlocksUnterminated = function() {\n\tvar tree = [];\n\twhile(this.pos < this.sourceLength) {\n\t\ttree.push.apply(tree,this.parseBlock());\n\t}\n\treturn tree;\n};\n\n/*\nParse blocks of text until a terminating regexp is encountered\n*/\nWikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {\n\tvar terminatorRegExp = new RegExp(\"(\" + terminatorRegExpString + \")\",\"mg\"),\n\t\ttree = [];\n\t// Skip any whitespace\n\tthis.skipWhitespace();\n\t// Check if we've got the end marker\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar match = terminatorRegExp.exec(this.source);\n\t// Parse the text into blocks\n\twhile(this.pos < this.sourceLength && !(match && match.index === this.pos)) {\n\t\tvar blocks = this.parseBlock(terminatorRegExpString);\n\t\ttree.push.apply(tree,blocks);\n\t\t// Skip any whitespace\n\t\tthis.skipWhitespace();\n\t\t// Check if we've got the end marker\n\t\tterminatorRegExp.lastIndex = this.pos;\n\t\tmatch = terminatorRegExp.exec(this.source);\n\t}\n\tif(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t}\n\treturn tree;\n};\n\n/*\nParse a run of text at the current position\n\tterminatorRegExp: a regexp at which to stop the run\n\toptions: see below\nOptions available:\n\teatTerminator: move the parse position past any encountered terminator (default false)\n*/\nWikiParser.prototype.parseInlineRun = function(terminatorRegExp,options) {\n\tif(terminatorRegExp) {\n\t\treturn this.parseInlineRunTerminated(terminatorRegExp,options);\n\t} else {\n\t\treturn this.parseInlineRunUnterminated(options);\n\t}\n};\n\nWikiParser.prototype.parseInlineRunUnterminated = function(options) {\n\tvar tree = [];\n\t// Find the next occurrence of an inline rule\n\tvar nextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around the matches until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && nextMatch) {\n\t\t// Process the text preceding the run rule\n\t\tif(nextMatch.matchIndex > this.pos) {\n\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,nextMatch.matchIndex));\n\t\t\tthis.pos = nextMatch.matchIndex;\n\t\t}\n\t\t// Process the run rule\n\t\ttree.push.apply(tree,nextMatch.rule.parse());\n\t\t// Look for the next run rule\n\t\tnextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos));\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\nWikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {\n\toptions = options || {};\n\tvar tree = [];\n\t// Find the next occurrence of the terminator\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\t// Find the next occurrence of a inlinerule\n\tvar inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && (terminatorMatch || inlineRuleMatch)) {\n\t\t// Return if we've found the terminator, and it precedes any inline rule match\n\t\tif(terminatorMatch) {\n\t\t\tif(!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {\n\t\t\t\tif(terminatorMatch.index > this.pos) {\n\t\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,terminatorMatch.index));\n\t\t\t\t}\n\t\t\t\tthis.pos = terminatorMatch.index;\n\t\t\t\tif(options.eatTerminator) {\n\t\t\t\t\tthis.pos += terminatorMatch[0].length;\n\t\t\t\t}\n\t\t\t\treturn tree;\n\t\t\t}\n\t\t}\n\t\t// Process any inline rule, along with the text preceding it\n\t\tif(inlineRuleMatch) {\n\t\t\t// Preceding text\n\t\t\tif(inlineRuleMatch.matchIndex > this.pos) {\n\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,inlineRuleMatch.matchIndex));\n\t\t\t\tthis.pos = inlineRuleMatch.matchIndex;\n\t\t\t}\n\t\t\t// Process the inline rule\n\t\t\ttree.push.apply(tree,inlineRuleMatch.rule.parse());\n\t\t\t// Look for the next inline rule\n\t\t\tinlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t\t\t// Look for the next terminator match\n\t\t\tterminatorRegExp.lastIndex = this.pos;\n\t\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\t}\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos));\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\n/*\nPush a text widget onto an array, respecting the configTrimWhiteSpace setting\n*/\nWikiParser.prototype.pushTextWidget = function(array,text) {\n\tif(this.configTrimWhiteSpace) {\n\t\ttext = $tw.utils.trim(text);\n\t}\n\tif(text) {\n\t\tarray.push({type: \"text\", text: text});\t\t\n\t}\n};\n\n/*\nParse zero or more class specifiers `.classname`\n*/\nWikiParser.prototype.parseClasses = function() {\n\tvar classRegExp = /\\.([^\\s\\.]+)/mg,\n\t\tclassNames = [];\n\tclassRegExp.lastIndex = this.pos;\n\tvar match = classRegExp.exec(this.source);\n\twhile(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t\tclassNames.push(match[1]);\n\t\tmatch = classRegExp.exec(this.source);\n\t}\n\treturn classNames;\n};\n\n/*\nAmend the rules used by this instance of the parser\n\ttype: `only` keeps just the named rules, `except` keeps all but the named rules\n\tnames: array of rule names\n*/\nWikiParser.prototype.amendRules = function(type,names) {\n\tnames = names || [];\n\t// Define the filter function\n\tvar target;\n\tif(type === \"only\") {\n\t\ttarget = true;\n\t} else if(type === \"except\") {\n\t\ttarget = false;\n\t} else {\n\t\treturn;\n\t}\n\t// Define a function to process each of our rule arrays\n\tvar processRuleArray = function(ruleArray) {\n\t\tfor(var t=ruleArray.length-1; t>=0; t--) {\n\t\t\tif((names.indexOf(ruleArray[t].rule.name) === -1) === target) {\n\t\t\t\truleArray.splice(t,1);\n\t\t\t}\n\t\t}\n\t};\n\t// Process each rule array\n\tprocessRuleArray(this.pragmaRules);\n\tprocessRuleArray(this.blockRules);\n\tprocessRuleArray(this.inlineRules);\n};\n\nexports[\"text/vnd.tiddlywiki\"] = WikiParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/wikiparser/rules/wikirulebase.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/wikirulebase.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikirulebase.js\ntype: application/javascript\nmodule-type: global\n\nBase class for wiki parser rules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nThis constructor is always overridden with a blank constructor, and so shouldn't be used\n*/\nvar WikiRuleBase = function() {\n};\n\n/*\nTo be overridden by individual rules\n*/\nWikiRuleBase.prototype.init = function(parser) {\n\tthis.parser = parser;\n};\n\n/*\nDefault implementation of findNextMatch uses RegExp matching\n*/\nWikiRuleBase.prototype.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\treturn this.match ? this.match.index : undefined;\n};\n\nexports.WikiRuleBase = WikiRuleBase;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/pluginswitcher.js": {
"title": "$:/core/modules/pluginswitcher.js",
"text": "/*\\\ntitle: $:/core/modules/pluginswitcher.js\ntype: application/javascript\nmodule-type: global\n\nManages switching plugins for themes and languages.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\noptions:\nwiki: wiki store to be used\npluginType: type of plugin to be switched\ncontrollerTitle: title of tiddler used to control switching of this resource\ndefaultPlugins: array of default plugins to be used if nominated plugin isn't found\nonSwitch: callback when plugin is switched (single parameter is array of plugin titles)\n*/\nfunction PluginSwitcher(options) {\n\tthis.wiki = options.wiki;\n\tthis.pluginType = options.pluginType;\n\tthis.controllerTitle = options.controllerTitle;\n\tthis.defaultPlugins = options.defaultPlugins || [];\n\tthis.onSwitch = options.onSwitch;\n\t// Switch to the current plugin\n\tthis.switchPlugins();\n\t// Listen for changes to the selected plugin\n\tvar self = this;\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,self.controllerTitle)) {\n\t\t\tself.switchPlugins();\n\t\t}\n\t});\n}\n\nPluginSwitcher.prototype.switchPlugins = function() {\n\t// Get the name of the current theme\n\tvar selectedPluginTitle = this.wiki.getTiddlerText(this.controllerTitle);\n\t// If it doesn't exist, then fallback to one of the default themes\n\tvar index = 0;\n\twhile(!this.wiki.getTiddler(selectedPluginTitle) && index < this.defaultPlugins.length) {\n\t\tselectedPluginTitle = this.defaultPlugins[index++];\n\t}\n\t// Accumulate the titles of the plugins that we need to load\n\tvar plugins = [],\n\t\tself = this,\n\t\taccumulatePlugin = function(title) {\n\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\tif(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {\n\t\t\t\tplugins.push(title);\n\t\t\t\tvar pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),\n\t\t\t\t\tdependents = $tw.utils.parseStringArray(tiddler.fields.dependents || \"\");\n\t\t\t\t$tw.utils.each(dependents,function(title) {\n\t\t\t\t\taccumulatePlugin(title);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\taccumulatePlugin(selectedPluginTitle);\n\t// Read the plugin info for the incoming plugins\n\tvar changes = $tw.wiki.readPluginInfo(plugins);\n\t// Unregister any existing theme tiddlers\n\tvar unregisteredTiddlers = $tw.wiki.unregisterPluginTiddlers(this.pluginType);\n\t// Register any new theme tiddlers\n\tvar registeredTiddlers = $tw.wiki.registerPluginTiddlers(this.pluginType,plugins);\n\t// Unpack the current theme tiddlers\n\t$tw.wiki.unpackPluginTiddlers();\n\t// Call the switch handler\n\tif(this.onSwitch) {\n\t\tthis.onSwitch(plugins);\n\t}\n};\n\nexports.PluginSwitcher = PluginSwitcher;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/saver-handler.js": {
"title": "$:/core/modules/saver-handler.js",
"text": "/*\\\ntitle: $:/core/modules/saver-handler.js\ntype: application/javascript\nmodule-type: global\n\nThe saver handler tracks changes to the store and handles saving the entire wiki via saver modules.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInstantiate the saver handler with the following options:\nwiki: wiki to be synced\ndirtyTracking: true if dirty tracking should be performed\n*/\nfunction SaverHandler(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\tthis.dirtyTracking = options.dirtyTracking;\n\tthis.preloadDirty = options.preloadDirty || [];\n\tthis.pendingAutoSave = false;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"saver-handler\");\n\t// Initialise our savers\n\tif($tw.browser) {\n\t\tthis.initSavers();\n\t}\n\t// Only do dirty tracking if required\n\tif($tw.browser && this.dirtyTracking) {\n\t\t// Compile the dirty tiddler filter\n\t\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t\t// Count of changes that have not yet been saved\n\t\tvar filteredChanges = self.filterFn.call(self.wiki,function(iterator) {\n\t\t\t\t$tw.utils.each(self.preloadDirty,function(title) {\n\t\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\t\titerator(tiddler,title);\n\t\t\t\t});\n\t\t});\n\t\tthis.numChanges = filteredChanges.length;\n\t\t// Listen out for changes to tiddlers\n\t\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\t\t// Filter the changes so that we only count changes to tiddlers that we care about\n\t\t\tvar filteredChanges = self.filterFn.call(self.wiki,function(iterator) {\n\t\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\t\titerator(tiddler,title);\n\t\t\t\t});\n\t\t\t});\n\t\t\t// Adjust the number of changes\n\t\t\tself.numChanges += filteredChanges.length;\n\t\t\tself.updateDirtyStatus();\n\t\t\t// Do any autosave if one is pending and there's no more change events\n\t\t\tif(self.pendingAutoSave && self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tself.pendingAutoSave = false;\n\t\t\t}\n\t\t});\n\t\t// Listen for the autosave event\n\t\t$tw.rootWidget.addEventListener(\"tm-auto-save-wiki\",function(event) {\n\t\t\t// Do the autosave unless there are outstanding tiddler change events\n\t\t\tif(self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise put ourselves in the \"pending autosave\" state and wait for the change event before we do the autosave\n\t\t\t\tself.pendingAutoSave = true;\n\t\t\t}\n\t\t});\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t}\n\t// Install the save action handlers\n\tif($tw.browser) {\n\t\t$tw.rootWidget.addEventListener(\"tm-save-wiki\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-download-file\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\tmethod: \"download\",\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t}\n}\n\nSaverHandler.prototype.titleSyncFilter = \"$:/config/SaverFilter\";\nSaverHandler.prototype.titleAutoSave = \"$:/config/AutoSave\";\nSaverHandler.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\n\n/*\nSelect the appropriate saver modules and set them up\n*/\nSaverHandler.prototype.initSavers = function(moduleType) {\n\tmoduleType = moduleType || \"saver\";\n\t// Instantiate the available savers\n\tthis.savers = [];\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tif(module.canSave(self)) {\n\t\t\tself.savers.push(module.create(self.wiki));\n\t\t}\n\t});\n\t// Sort the savers into priority order\n\tthis.savers.sort(function(a,b) {\n\t\tif(a.info.priority < b.info.priority) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(a.info.priority > b.info.priority) {\n\t\t\t\treturn +1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nSave the wiki contents. Options are:\n\tmethod: \"save\", \"autosave\" or \"download\"\n\ttemplate: the tiddler containing the template to save\n\tdownloadType: the content type for the saved file\n*/\nSaverHandler.prototype.saveWiki = function(options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tmethod = options.method || \"save\";\n\t// Ignore autosave if disabled\n\tif(method === \"autosave\" && ($tw.config.disableAutoSave || this.wiki.getTiddlerText(this.titleAutoSave,\"yes\") !== \"yes\")) {\n\t\treturn false;\n\t}\n\tvar\tvariables = options.variables || {},\n\t\ttemplate = options.template || \"$:/core/save/all\",\n\t\tdownloadType = options.downloadType || \"text/plain\",\n\t\ttext = this.wiki.renderTiddler(downloadType,template,options),\n\t\tcallback = function(err) {\n\t\t\tif(err) {\n\t\t\t\talert($tw.language.getString(\"Error/WhileSaving\") + \":\\n\\n\" + err);\n\t\t\t} else {\n\t\t\t\t// Clear the task queue if we're saving (rather than downloading)\n\t\t\t\tif(method !== \"download\") {\n\t\t\t\t\tself.numChanges = 0;\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t}\n\t\t\t\t$tw.notifier.display(self.titleSavedNotification);\n\t\t\t\tif(options.callback) {\n\t\t\t\t\toptions.callback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t// Call the highest priority saver that supports this method\n\tfor(var t=this.savers.length-1; t>=0; t--) {\n\t\tvar saver = this.savers[t];\n\t\tif(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback,{variables: {filename: variables.filename}})) {\n\t\t\tthis.logger.log(\"Saving wiki with method\",method,\"through saver\",saver.info.name);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSaverHandler.prototype.isDirty = function() {\n\treturn this.numChanges > 0;\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSaverHandler.prototype.updateDirtyStatus = function() {\n\tvar self = this;\n\tif($tw.browser) {\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",this.isDirty());\n\t\t$tw.utils.each($tw.windows,function(win) {\n\t\t\t$tw.utils.toggleClass(win.document.body,\"tc-dirty\",self.isDirty());\n\t\t});\n\t}\n};\n\nexports.SaverHandler = SaverHandler;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/savers/andtidwiki.js": {
"title": "$:/core/modules/savers/andtidwiki.js",
"text": "/*\\\ntitle: $:/core/modules/savers/andtidwiki.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the AndTidWiki Android app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar AndTidWiki = function(wiki) {\n};\n\nAndTidWiki.prototype.save = function(text,method,callback,options) {\n\tvar filename = options && options.variables ? options.variables.filename : null;\n\tif (method === \"download\") {\n\t\t// Support download\n\t\tif (window.twi.saveDownload) {\n\t\t\ttry {\n\t\t\t\twindow.twi.saveDownload(text,filename);\n\t\t\t} catch(err) {\n\t\t\t\tif (err.message === \"Method not found\") {\n\t\t\t\t\twindow.twi.saveDownload(text);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvar link = document.createElement(\"a\");\n\t\t\tlink.setAttribute(\"href\",\"data:text/plain,\" + encodeURIComponent(text));\n\t\t\tif (filename) {\n\t\t\t link.setAttribute(\"download\",filename);\n\t\t\t}\n\t\t\tdocument.body.appendChild(link);\n\t\t\tlink.click();\n\t\t\tdocument.body.removeChild(link);\n\t\t}\n\t} else if (window.twi.saveWiki) {\n\t\t// Direct save in Tiddloid\n\t\twindow.twi.saveWiki(text);\n\t} else {\n\t\t// Get the pathname of this document\n\t\tvar pathname = decodeURIComponent(document.location.toString().split(\"#\")[0]);\n\t\t// Strip the file://\n\t\tif(pathname.indexOf(\"file://\") === 0) {\n\t\t\tpathname = pathname.substr(7);\n\t\t}\n\t\t// Strip any query or location part\n\t\tvar p = pathname.indexOf(\"?\");\n\t\tif(p !== -1) {\n\t\t\tpathname = pathname.substr(0,p);\n\t\t}\n\t\tp = pathname.indexOf(\"#\");\n\t\tif(p !== -1) {\n\t\t\tpathname = pathname.substr(0,p);\n\t\t}\n\t\t// Save the file\n\t\twindow.twi.saveFile(pathname,text);\n\t}\n\t// Call the callback\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nAndTidWiki.prototype.info = {\n\tname: \"andtidwiki\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.twi && !!window.twi.saveFile;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new AndTidWiki(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/beaker.js": {
"title": "$:/core/modules/savers/beaker.js",
"text": "/*\\\ntitle: $:/core/modules/savers/beaker.js\ntype: application/javascript\nmodule-type: saver\n\nSaves files using the Beaker browser's (https://beakerbrowser.com) Dat protocol (https://datproject.org/)\nCompatible with beaker >= V0.7.2\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet up the saver\n*/\nvar BeakerSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nBeakerSaver.prototype.save = function(text,method,callback) {\n\tvar dat = new DatArchive(\"\" + window.location),\n\t\tpathname = (\"\" + window.location.pathname).split(\"#\")[0];\n\tdat.stat(pathname).then(function(value) {\n\t\tif(value.isDirectory()) {\n\t\t\tpathname = pathname + \"/index.html\";\n\t\t}\n\t\tdat.writeFile(pathname,text,\"utf8\").then(function(value) {\n\t\t\tcallback(null);\n\t\t},function(reason) {\n\t\t\tcallback(\"Beaker Saver Write Error: \" + reason);\n\t\t});\n\t},function(reason) {\n\t\tcallback(\"Beaker Saver Stat Error: \" + reason);\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nBeakerSaver.prototype.info = {\n\tname: \"beaker\",\n\tpriority: 3000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.DatArchive && location.protocol===\"dat:\";\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new BeakerSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/custom.js": {
"title": "$:/core/modules/savers/custom.js",
"text": "/*\\\ntitle: $:/core/modules/savers/custom.js\ntype: application/javascript\nmodule-type: saver\n\nLooks for `window.$tw.customSaver` first on the current window, then\non the parent window (of an iframe). If present, the saver must define\n\tsave: function(text,method,callback) { ... }\nand the saver may define\n\tpriority: number\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar findSaver = function(window) {\n\ttry {\n\t\treturn window && window.$tw && window.$tw.customSaver;\n\t} catch (err) {\n\t\t// Catching the exception is the most reliable way to detect cross-origin iframe errors.\n\t\t// For example, instead of saying that `window.parent.$tw` is undefined, Firefox will throw\n\t\t// Uncaught DOMException: Permission denied to access property \"$tw\" on cross-origin object\n\t\tconsole.log({ msg: \"custom saver is disabled\", reason: err });\n\t\treturn null;\n\t}\n}\nvar saver = findSaver(window) || findSaver(window.parent) || {};\n\nvar CustomSaver = function(wiki) {\n};\n\nCustomSaver.prototype.save = function(text,method,callback) {\n\treturn saver.save(text, method, callback);\n};\n\n/*\nInformation about this saver\n*/\nCustomSaver.prototype.info = {\n\tname: \"custom\",\n\tpriority: saver.priority || 4000,\n\tcapabilities: [\"save\",\"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!(saver.save);\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new CustomSaver(wiki);\n};\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/download.js": {
"title": "$:/core/modules/savers/download.js",
"text": "/*\\\ntitle: $:/core/modules/savers/download.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar DownloadSaver = function(wiki) {\n};\n\nDownloadSaver.prototype.save = function(text,method,callback,options) {\n\toptions = options || {};\n\t// Get the current filename\n\tvar filename = options.variables.filename;\n\tif(!filename) {\n\t\tvar p = document.location.pathname.lastIndexOf(\"/\");\n\t\tif(p !== -1) {\n\t\t\t// We decode the pathname because document.location is URL encoded by the browser\n\t\t\tfilename = decodeURIComponent(document.location.pathname.substr(p+1));\n\t\t}\n\t}\n\tif(!filename) {\n\t\tfilename = \"tiddlywiki.html\";\n\t}\n\t// Set up the link\n\tvar link = document.createElement(\"a\");\n\tif(Blob !== undefined) {\n\t\tvar blob = new Blob([text], {type: \"text/html\"});\n\t\tlink.setAttribute(\"href\", URL.createObjectURL(blob));\n\t} else {\n\t\tlink.setAttribute(\"href\",\"data:text/html,\" + encodeURIComponent(text));\n\t}\n\tlink.setAttribute(\"download\",filename);\n\tdocument.body.appendChild(link);\n\tlink.click();\n\tdocument.body.removeChild(link);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nDownloadSaver.prototype.info = {\n\tname: \"download\",\n\tpriority: 100\n};\n\nObject.defineProperty(DownloadSaver.prototype.info, \"capabilities\", {\n\tget: function() {\n\t\tvar capabilities = [\"save\", \"download\"];\n\t\tif(($tw.wiki.getTextReference(\"$:/config/DownloadSaver/AutoSave\") || \"\").toLowerCase() === \"yes\") {\n\t\t\tcapabilities.push(\"autosave\");\n\t\t}\n\t\treturn capabilities;\n\t}\n});\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn document.createElement(\"a\").download !== undefined;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new DownloadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/fsosaver.js": {
"title": "$:/core/modules/savers/fsosaver.js",
"text": "/*\\\ntitle: $:/core/modules/savers/fsosaver.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via MS FileSystemObject ActiveXObject\n\nNote: Since TiddlyWiki's markup contains the MOTW, the FileSystemObject normally won't be available. \nHowever, if the wiki is loaded as an .HTA file (Windows HTML Applications) then the FSO can be used.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar FSOSaver = function(wiki) {\n};\n\nFSOSaver.prototype.save = function(text,method,callback) {\n\t// Get the pathname of this document\n\tvar pathname = unescape(document.location.pathname);\n\t// Test for a Windows path of the form /x:\\blah...\n\tif(/^\\/[A-Z]\\:\\\\[^\\\\]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t} else if(document.location.hostname !== \"\" && /^\\/\\\\[^\\\\]+\\\\[^\\\\]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t\t// reconstruct UNC path\n\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t} else {\n\t\treturn false;\n\t}\n\t// Save the file (as UTF-16)\n\tvar fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\tvar file = fso.OpenTextFile(pathname,2,-1,-1);\n\tfile.Write(text);\n\tfile.Close();\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nFSOSaver.prototype.info = {\n\tname: \"FSOSaver\",\n\tpriority: 120,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\ttry {\n\t\treturn (window.location.protocol === \"file:\") && !!(new ActiveXObject(\"Scripting.FileSystemObject\"));\n\t} catch(e) { return false; }\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new FSOSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/gitea.js": {
"title": "$:/core/modules/savers/gitea.js",
"text": "/*\\\ntitle: $:/core/modules/savers/gitea.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by pushing a commit to the gitea\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar GiteaSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nGiteaSaver.prototype.save = function(text,method,callback) {\n\tvar self = this,\n\t\tusername = this.wiki.getTiddlerText(\"$:/Gitea/Username\"),\n\t\tpassword = $tw.utils.getPassword(\"Gitea\"),\n\t\trepo = this.wiki.getTiddlerText(\"$:/Gitea/Repo\"),\n\t\tpath = this.wiki.getTiddlerText(\"$:/Gitea/Path\",\"\"),\n\t\tfilename = this.wiki.getTiddlerText(\"$:/Gitea/Filename\"),\n\t\tbranch = this.wiki.getTiddlerText(\"$:/Gitea/Branch\") || \"master\",\n\t\tendpoint = this.wiki.getTiddlerText(\"$:/Gitea/ServerURL\") || \"https://gitea\",\n\t\theaders = {\n\t\t\t\"Accept\": \"application/json\",\n\t\t\t\"Content-Type\": \"application/json;charset=UTF-8\",\n\t\t\t\"Authorization\": \"token \" + password\n\t\t};\n\t// Bail if we don't have everything we need\n\tif(!username || !password || !repo || !filename) {\n\t\treturn false;\n\t}\n\t// Make sure the path start and ends with a slash\n\tif(path.substring(0,1) !== \"/\") {\n\t\tpath = \"/\" + path;\n\t}\n\tif(path.substring(path.length - 1) !== \"/\") {\n\t\tpath = path + \"/\";\n\t}\n\t// Compose the base URI\n\tvar uri = endpoint + \"/repos/\" + repo + \"/contents\" + path;\n\t// Perform a get request to get the details (inc shas) of files in the same path as our file\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"GET\",\n\t\theaders: headers,\n\t\tdata: {\n\t\t\tref: branch\n\t\t},\n\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\tvar getResponseData,sha = \"\";\n\t\t\tif(err && xhr.status !== 404) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar use_put = true;\n\t\t\tif(xhr.status !== 404) {\n\t\t\t\tgetResponseData = JSON.parse(getResponseDataJson);\n\t\t\t\t$tw.utils.each(getResponseData,function(details) {\n\t\t\t\t\tif(details.name === filename) {\n\t\t\t\t\t\tsha = details.sha;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif(sha === \"\"){\n\t\t\t\t\tuse_put = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar data = {\n\t\t\t\tmessage: $tw.language.getRawString(\"ControlPanel/Saving/GitService/CommitMessage\"),\n\t\t\t\tcontent: $tw.utils.base64Encode(text),\n\t\t\t\tsha: sha\n\t\t\t};\n\t\t\t$tw.utils.httpRequest({\n\t\t\t\turl: endpoint + \"/repos/\" + repo + \"/branches/\" + branch,\n\t\t\t\ttype: \"GET\",\n\t\t\t\theaders: headers,\n\t\t\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\t\t\tif(xhr.status === 404) {\n\t\t\t\t\t\tcallback(\"Please ensure the branch in the Gitea repo exists\");\n\t\t\t\t\t}else{\n\t\t\t\t\t\tdata[\"branch\"] = branch;\n\t\t\t\t\t\tself.upload(uri + filename, use_put?\"PUT\":\"POST\", headers, data, callback);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\treturn true;\n};\n\nGiteaSaver.prototype.upload = function(uri,method,headers,data,callback) {\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: method,\n\t\theaders: headers,\n\t\tdata: JSON.stringify(data),\n\t\tcallback: function(err,putResponseDataJson,xhr) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar putResponseData = JSON.parse(putResponseDataJson);\n\t\t\tcallback(null);\n\t\t}\n\t});\n};\n\n/*\nInformation about this saver\n*/\nGiteaSaver.prototype.info = {\n\tname: \"Gitea\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new GiteaSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/github.js": {
"title": "$:/core/modules/savers/github.js",
"text": "/*\\\ntitle: $:/core/modules/savers/github.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by pushing a commit to the GitHub v3 REST API\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar GitHubSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nGitHubSaver.prototype.save = function(text,method,callback) {\n\tvar self = this,\n\t\tusername = this.wiki.getTiddlerText(\"$:/GitHub/Username\"),\n\t\tpassword = $tw.utils.getPassword(\"github\"),\n\t\trepo = this.wiki.getTiddlerText(\"$:/GitHub/Repo\"),\n\t\tpath = this.wiki.getTiddlerText(\"$:/GitHub/Path\",\"\"),\n\t\tfilename = this.wiki.getTiddlerText(\"$:/GitHub/Filename\"),\n\t\tbranch = this.wiki.getTiddlerText(\"$:/GitHub/Branch\") || \"main\",\n\t\tendpoint = this.wiki.getTiddlerText(\"$:/GitHub/ServerURL\") || \"https://api.github.com\",\n\t\theaders = {\n\t\t\t\"Accept\": \"application/vnd.github.v3+json\",\n\t\t\t\"Content-Type\": \"application/json;charset=UTF-8\",\n\t\t\t\"Authorization\": \"Basic \" + window.btoa(username + \":\" + password),\n\t\t\t\"If-None-Match\": \"\"\n\t\t};\n\t// Bail if we don't have everything we need\n\tif(!username || !password || !repo || !filename) {\n\t\treturn false;\n\t}\n\t// Make sure the path start and ends with a slash\n\tif(path.substring(0,1) !== \"/\") {\n\t\tpath = \"/\" + path;\n\t}\n\tif(path.substring(path.length - 1) !== \"/\") {\n\t\tpath = path + \"/\";\n\t}\n\t// Compose the base URI\n\tvar uri = endpoint + \"/repos/\" + repo + \"/contents\" + path;\n\t// Perform a get request to get the details (inc shas) of files in the same path as our file\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"GET\",\n\t\theaders: headers,\n\t\tdata: {\n\t\t\tref: branch\n\t\t},\n\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\tvar getResponseData,sha = \"\";\n\t\t\tif(err && xhr.status !== 404) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tif(xhr.status !== 404) {\n\t\t\t\tgetResponseData = JSON.parse(getResponseDataJson);\n\t\t\t\t$tw.utils.each(getResponseData,function(details) {\n\t\t\t\t\tif(details.name === filename) {\n\t\t\t\t\t\tsha = details.sha;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tvar data = {\n\t\t\t\tmessage: $tw.language.getRawString(\"ControlPanel/Saving/GitService/CommitMessage\"),\n\t\t\t\tcontent: $tw.utils.base64Encode(text),\n\t\t\t\tbranch: branch,\n\t\t\t\tsha: sha\n\t\t\t};\n\t\t\t// Perform a PUT request to save the file\n\t\t\t$tw.utils.httpRequest({\n\t\t\t\turl: uri + filename,\n\t\t\t\ttype: \"PUT\",\n\t\t\t\theaders: headers,\n\t\t\t\tdata: JSON.stringify(data),\n\t\t\t\tcallback: function(err,putResponseDataJson,xhr) {\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\tvar putResponseData = JSON.parse(putResponseDataJson);\n\t\t\t\t\tcallback(null);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nGitHubSaver.prototype.info = {\n\tname: \"github\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new GitHubSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/gitlab.js": {
"title": "$:/core/modules/savers/gitlab.js",
"text": "/*\\\ntitle: $:/core/modules/savers/gitlab.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by pushing a commit to the GitLab REST API\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: true */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar GitLabSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nGitLabSaver.prototype.save = function(text,method,callback) {\n\t/* See https://docs.gitlab.com/ee/api/repository_files.html */\n\tvar self = this,\n\t\tusername = this.wiki.getTiddlerText(\"$:/GitLab/Username\"),\n\t\tpassword = $tw.utils.getPassword(\"gitlab\"),\n\t\trepo = this.wiki.getTiddlerText(\"$:/GitLab/Repo\"),\n\t\tpath = this.wiki.getTiddlerText(\"$:/GitLab/Path\",\"\"),\n\t\tfilename = this.wiki.getTiddlerText(\"$:/GitLab/Filename\"),\n\t\tbranch = this.wiki.getTiddlerText(\"$:/GitLab/Branch\") || \"master\",\n\t\tendpoint = this.wiki.getTiddlerText(\"$:/GitLab/ServerURL\") || \"https://gitlab.com/api/v4\",\n\t\theaders = {\n\t\t\t\"Content-Type\": \"application/json;charset=UTF-8\",\n\t\t\t\"Private-Token\": password\n\t\t};\n\t// Bail if we don't have everything we need\n\tif(!username || !password || !repo || !filename) {\n\t\treturn false;\n\t}\n\t// Make sure the path start and ends with a slash\n\tif(path.substring(0,1) !== \"/\") {\n\t\tpath = \"/\" + path;\n\t}\n\tif(path.substring(path.length - 1) !== \"/\") {\n\t\tpath = path + \"/\";\n\t}\n\t// Compose the base URI\n\tvar uri = endpoint + \"/projects/\" + encodeURIComponent(repo) + \"/repository/\";\n\t// Perform a get request to get the details (inc shas) of files in the same path as our file\n\t$tw.utils.httpRequest({\n\t\turl: uri + \"tree/?path=\" + encodeURIComponent(path.replace(/^\\/+|\\/$/g, '')) + \"&branch=\" + encodeURIComponent(branch.replace(/^\\/+|\\/$/g, '')),\n\t\ttype: \"GET\",\n\t\theaders: headers,\n\t\tcallback: function(err,getResponseDataJson,xhr) {\n\t\t\tvar getResponseData,sha = \"\";\n\t\t\tif(err && xhr.status !== 404) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tvar requestType = \"POST\";\n\t\t\tif(xhr.status !== 404) {\n\t\t\t\tgetResponseData = JSON.parse(getResponseDataJson);\n\t\t\t\t$tw.utils.each(getResponseData,function(details) {\n\t\t\t\t\tif(details.name === filename) {\n\t\t\t\t\t\trequestType = \"PUT\";\n\t\t\t\t\t\tsha = details.sha;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tvar data = {\n\t\t\t\tcommit_message: $tw.language.getRawString(\"ControlPanel/Saving/GitService/CommitMessage\"),\n\t\t\t\tcontent: text,\n\t\t\t\tbranch: branch,\n\t\t\t\tsha: sha\n\t\t\t};\n\t\t\t// Perform a request to save the file\n\t\t\t$tw.utils.httpRequest({\n\t\t\t\turl: uri + \"files/\" + encodeURIComponent(path.replace(/^\\/+/, '') + filename),\n\t\t\t\ttype: requestType,\n\t\t\t\theaders: headers,\n\t\t\t\tdata: JSON.stringify(data),\n\t\t\t\tcallback: function(err,putResponseDataJson,xhr) {\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\tvar putResponseData = JSON.parse(putResponseDataJson);\n\t\t\t\t\tcallback(null);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nGitLabSaver.prototype.info = {\n\tname: \"gitlab\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new GitLabSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/hyperdrive.js": {
"title": "$:/core/modules/savers/hyperdrive.js",
"text": "/*\\\ntitle: $:/core/modules/savers/hyperdrive.js\ntype: application/javascript\nmodule-type: saver\n\nSaves files using the Hyperdrive Protocol (https://hypercore-protocol.org/#hyperdrive) Beaker browser beta-1.0 and later (https://beakerbrowser.com)\nCompatible with beaker >= V1.0.0\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet up the saver\n*/\nvar HyperdriveSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nHyperdriveSaver.prototype.save = function(text,method,callback) {\n\tvar dat = beaker.hyperdrive.drive(\"\" + window.location),\n\t\tpathname = (\"\" + window.location.pathname).split(\"#\")[0];\n\tdat.stat(pathname).then(function(value) {\n\t\tif(value.isDirectory()) {\n\t\t\tpathname = pathname + \"/index.html\";\n\t\t}\n\t\tdat.writeFile(pathname,text,\"utf8\").then(function(value) {\n\t\t\tcallback(null);\n\t\t},function(reason) {\n\t\t\tcallback(\"Hyperdrive Saver Write Error: \" + reason);\n\t\t});\n\t},function(reason) {\n\t\tcallback(\"Hyperdrive Saver Stat Error: \" + reason);\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nHyperdriveSaver.prototype.info = {\n\tname: \"beaker-1.x\",\n\tpriority: 3000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.beaker && !!beaker.hyperdrive && location.protocol===\"hyper:\";\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new HyperdriveSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/manualdownload.js": {
"title": "$:/core/modules/savers/manualdownload.js",
"text": "/*\\\ntitle: $:/core/modules/savers/manualdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Title of the tiddler containing the download message\nvar downloadInstructionsTitle = \"$:/language/Modals/Download\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar ManualDownloadSaver = function(wiki) {\n};\n\nManualDownloadSaver.prototype.save = function(text,method,callback) {\n\t$tw.modal.display(downloadInstructionsTitle,{\n\t\tdownloadLink: \"data:text/html,\" + encodeURIComponent(text)\n\t});\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nManualDownloadSaver.prototype.info = {\n\tname: \"manualdownload\",\n\tpriority: 0,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new ManualDownloadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/msdownload.js": {
"title": "$:/core/modules/savers/msdownload.js",
"text": "/*\\\ntitle: $:/core/modules/savers/msdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via window.navigator.msSaveBlob()\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar MsDownloadSaver = function(wiki) {\n};\n\nMsDownloadSaver.prototype.save = function(text,method,callback) {\n\t// Get the current filename\n\tvar filename = \"tiddlywiki.html\",\n\t\tp = document.location.pathname.lastIndexOf(\"/\");\n\tif(p !== -1) {\n\t\tfilename = document.location.pathname.substr(p+1);\n\t}\n\t// Set up the link\n\tvar blob = new Blob([text], {type: \"text/html\"});\n\twindow.navigator.msSaveBlob(blob,filename);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nMsDownloadSaver.prototype.info = {\n\tname: \"msdownload\",\n\tpriority: 110,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.navigator.msSaveBlob;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new MsDownloadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/put.js": {
"title": "$:/core/modules/savers/put.js",
"text": "/*\\\ntitle: $:/core/modules/savers/put.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by performing a PUT request to the server\n\nWorks with any server which accepts a PUT request\nto the current URL, such as a WebDAV server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRetrieve ETag if available\n*/\nvar retrieveETag = function(self) {\n\tvar headers = {\n\t\tAccept: \"*/*;charset=UTF-8\"\n\t};\n\t$tw.utils.httpRequest({\n\t\turl: self.uri(),\n\t\ttype: \"HEAD\",\n\t\theaders: headers,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar etag = xhr.getResponseHeader(\"ETag\");\n\t\t\tif(!etag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tself.etag = etag.replace(/^W\\//,\"\");\n\t\t}\n\t});\n};\n\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar PutSaver = function(wiki) {\n\tthis.wiki = wiki;\n\tvar self = this;\n\tvar uri = this.uri();\n\t// Async server probe. Until probe finishes, save will fail fast\n\t// See also https://github.com/Jermolene/TiddlyWiki5/issues/2276\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"OPTIONS\",\n\t\tcallback: function(err,data,xhr) {\n\t\t\t// Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1\n\t\t\tif(!err) {\n\t\t\t\tself.serverAcceptsPuts = xhr.status === 200 && !!xhr.getResponseHeader(\"dav\");\n\t\t\t}\n\t\t}\n\t});\n\tretrieveETag(this);\n};\n\nPutSaver.prototype.uri = function() {\n\treturn document.location.toString().split(\"#\")[0];\n};\n\n// TODO: in case of edit conflict\n// Prompt: Do you want to save over this? Y/N\n// Merging would be ideal, and may be possible using future generic merge flow\nPutSaver.prototype.save = function(text,method,callback) {\n\tif(!this.serverAcceptsPuts) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tvar headers = {\n\t\t\"Content-Type\": \"text/html;charset=UTF-8\"\n\t};\n\tif(this.etag) {\n\t\theaders[\"If-Match\"] = this.etag;\n\t}\n\t$tw.utils.httpRequest({\n\t\turl: this.uri(),\n\t\ttype: \"PUT\",\n\t\theaders: headers,\n\t\tdata: text,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\t// response is textual: \"XMLHttpRequest error code: 412\"\n\t\t\t\tvar status = Number(err.substring(err.indexOf(':') + 2, err.length))\n\t\t\t\tif(status === 412) { // edit conflict\n\t\t\t\t\tvar message = $tw.language.getString(\"Error/EditConflict\");\n\t\t\t\t\tcallback(message);\n\t\t\t\t} else {\n\t\t\t\t\tcallback(err); // fail\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.etag = xhr.getResponseHeader(\"ETag\");\n\t\t\t\tif(self.etag == null) {\n\t\t\t\t\tretrieveETag(self);\n\t\t\t\t}\n\t\t\t\tcallback(null); // success\n\t\t\t}\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nPutSaver.prototype.info = {\n\tname: \"put\",\n\tpriority: 2000,\n\tcapabilities: [\"save\",\"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn /^https?:/.test(location.protocol);\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new PutSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/tiddlyfox.js": {
"title": "$:/core/modules/savers/tiddlyfox.js",
"text": "/*\\\ntitle: $:/core/modules/savers/tiddlyfox.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TiddlyFox file extension\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TiddlyFoxSaver = function(wiki) {\n};\n\nTiddlyFoxSaver.prototype.save = function(text,method,callback) {\n\tvar messageBox = document.getElementById(\"tiddlyfox-message-box\");\n\tif(messageBox) {\n\t\t// Get the pathname of this document\n\t\tvar pathname = document.location.toString().split(\"#\")[0];\n\t\t// Replace file://localhost/ with file:///\n\t\tif(pathname.indexOf(\"file://localhost/\") === 0) {\n\t\t\tpathname = \"file://\" + pathname.substr(16);\n\t\t}\n\t\t// Windows path file:///x:/blah/blah --> x:\\blah\\blah\n\t\tif(/^file\\:\\/\\/\\/[A-Z]\\:\\//i.test(pathname)) {\n\t\t\t// Remove the leading slash and convert slashes to backslashes\n\t\t\tpathname = pathname.substr(8).replace(/\\//g,\"\\\\\");\n\t\t// Firefox Windows network path file://///server/share/blah/blah --> //server/share/blah/blah\n\t\t} else if(pathname.indexOf(\"file://///\") === 0) {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(10)).replace(/\\//g,\"\\\\\");\n\t\t// Mac/Unix local path file:///path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:///\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(7));\n\t\t// Mac/Unix local path file:/path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:/\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(5));\n\t\t// Otherwise Windows networth path file://server/share/path/path --> \\\\server\\share\\path\\path\n\t\t} else {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(7)).replace(new RegExp(\"/\",\"g\"),\"\\\\\");\n\t\t}\n\t\t// Create the message element and put it in the message box\n\t\tvar message = document.createElement(\"div\");\n\t\tmessage.setAttribute(\"data-tiddlyfox-path\",decodeURIComponent(pathname));\n\t\tmessage.setAttribute(\"data-tiddlyfox-content\",text);\n\t\tmessageBox.appendChild(message);\n\t\t// Add an event handler for when the file has been saved\n\t\tmessage.addEventListener(\"tiddlyfox-have-saved-file\",function(event) {\n\t\t\tcallback(null);\n\t\t}, false);\n\t\t// Create and dispatch the custom event to the extension\n\t\tvar event = document.createEvent(\"Events\");\n\t\tevent.initEvent(\"tiddlyfox-save-file\",true,false);\n\t\tmessage.dispatchEvent(event);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyFoxSaver.prototype.info = {\n\tname: \"tiddlyfox\",\n\tpriority: 1500,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyFoxSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/tiddlyie.js": {
"title": "$:/core/modules/savers/tiddlyie.js",
"text": "/*\\\ntitle: $:/core/modules/savers/tiddlyie.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via Internet Explorer BHO extenion (TiddlyIE)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar TiddlyIESaver = function(wiki) {\n};\n\nTiddlyIESaver.prototype.save = function(text,method,callback) {\n\t// Check existence of TiddlyIE BHO extension (note: only works after document is complete)\n\tif(typeof(window.TiddlyIE) != \"undefined\") {\n\t\t// Get the pathname of this document\n\t\tvar pathname = unescape(document.location.pathname);\n\t\t// Test for a Windows path of the form /x:/blah...\n\t\tif(/^\\/[A-Z]\\:\\/[^\\/]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+ (is this better?: ^/[a-z]:/[^/]+(/[^/]+)*\\.[^/]+ )\n\t\t\t// Remove the leading slash\n\t\t\tpathname = pathname.substr(1);\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t} else if(document.hostname !== \"\" && /^\\/[^\\/]+\\/[^\\/]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t\t// reconstruct UNC path\n\t\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t\t} else return false;\n\t\t// Prompt the user to save the file\n\t\twindow.TiddlyIE.save(pathname, text);\n\t\t// Callback that we succeeded\n\t\tcallback(null);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyIESaver.prototype.info = {\n\tname: \"tiddlyiesaver\",\n\tpriority: 1500,\n\tcapabilities: [\"save\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn (window.location.protocol === \"file:\");\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyIESaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/twedit.js": {
"title": "$:/core/modules/savers/twedit.js",
"text": "/*\\\ntitle: $:/core/modules/savers/twedit.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TWEdit iOS app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TWEditSaver = function(wiki) {\n};\n\nTWEditSaver.prototype.save = function(text,method,callback) {\n\t// Bail if we're not running under TWEdit\n\tif(typeof DeviceInfo !== \"object\") {\n\t\treturn false;\n\t}\n\t// Get the pathname of this document\n\tvar pathname = decodeURIComponent(document.location.pathname);\n\t// Strip any query or location part\n\tvar p = pathname.indexOf(\"?\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\tp = pathname.indexOf(\"#\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\t// Remove the leading \"/Documents\" from path\n\tvar prefix = \"/Documents\";\n\tif(pathname.indexOf(prefix) === 0) {\n\t\tpathname = pathname.substr(prefix.length);\n\t}\n\t// Error handler\n\tvar errorHandler = function(event) {\n\t\t// Error\n\t\tcallback($tw.language.getString(\"Error/SavingToTWEdit\") + \": \" + event.target.error.code);\n\t};\n\t// Get the file system\n\twindow.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) {\n\t\t// Now we've got the filesystem, get the fileEntry\n\t\tfileSystem.root.getFile(pathname, {create: true}, function(fileEntry) {\n\t\t\t// Now we've got the fileEntry, create the writer\n\t\t\tfileEntry.createWriter(function(writer) {\n\t\t\t\twriter.onerror = errorHandler;\n\t\t\t\twriter.onwrite = function() {\n\t\t\t\t\tcallback(null);\n\t\t\t\t};\n\t\t\t\twriter.position = 0;\n\t\t\t\twriter.write(text);\n\t\t\t},errorHandler);\n\t\t}, errorHandler);\n\t}, errorHandler);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nTWEditSaver.prototype.info = {\n\tname: \"twedit\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TWEditSaver(wiki);\n};\n\n/////////////////////////// Hack\n// HACK: This ensures that TWEdit recognises us as a TiddlyWiki document\nif($tw.browser) {\n\twindow.version = {title: \"TiddlyWiki\"};\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/upload.js": {
"title": "$:/core/modules/savers/upload.js",
"text": "/*\\\ntitle: $:/core/modules/savers/upload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via upload to a server.\n\nDesigned to be compatible with BidiX's UploadPlugin at http://tiddlywiki.bidix.info/#UploadPlugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar UploadSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nUploadSaver.prototype.save = function(text,method,callback) {\n\t// Get the various parameters we need\n\tvar backupDir = this.wiki.getTextReference(\"$:/UploadBackupDir\") || \".\",\n\t\tusername = this.wiki.getTextReference(\"$:/UploadName\"),\n\t\tpassword = $tw.utils.getPassword(\"upload\"),\n\t\tuploadDir = this.wiki.getTextReference(\"$:/UploadDir\") || \".\",\n\t\tuploadFilename = this.wiki.getTextReference(\"$:/UploadFilename\") || \"index.html\",\n\t\turl = this.wiki.getTextReference(\"$:/UploadURL\");\n\t// Bail out if we don't have the bits we need\n\tif(!username || username.toString().trim() === \"\" || !password || password.toString().trim() === \"\") {\n\t\treturn false;\n\t}\n\t// Construct the url if not provided\n\tif(!url) {\n\t\turl = \"http://\" + username + \".tiddlyspot.com/store.cgi\";\n\t}\n\t// Assemble the header\n\tvar boundary = \"---------------------------\" + \"AaB03x\";\t\n\tvar uploadFormName = \"UploadPlugin\";\n\tvar head = [];\n\thead.push(\"--\" + boundary + \"\\r\\nContent-disposition: form-data; name=\\\"UploadPlugin\\\"\\r\\n\");\n\thead.push(\"backupDir=\" + backupDir + \";user=\" + username + \";password=\" + password + \";uploaddir=\" + uploadDir + \";;\"); \n\thead.push(\"\\r\\n\" + \"--\" + boundary);\n\thead.push(\"Content-disposition: form-data; name=\\\"userfile\\\"; filename=\\\"\" + uploadFilename + \"\\\"\");\n\thead.push(\"Content-Type: text/html;charset=UTF-8\");\n\thead.push(\"Content-Length: \" + text.length + \"\\r\\n\");\n\thead.push(\"\");\n\t// Assemble the tail and the data itself\n\tvar tail = \"\\r\\n--\" + boundary + \"--\\r\\n\",\n\t\tdata = head.join(\"\\r\\n\") + text + tail;\n\t// Do the HTTP post\n\tvar http = new XMLHttpRequest();\n\thttp.open(\"POST\",url,true,username,password);\n\thttp.setRequestHeader(\"Content-Type\",\"multipart/form-data; charset=UTF-8; boundary=\" + boundary);\n\thttp.onreadystatechange = function() {\n\t\tif(http.readyState == 4 && http.status == 200) {\n\t\t\tif(http.responseText.substr(0,4) === \"0 - \") {\n\t\t\t\tcallback(null);\n\t\t\t} else {\n\t\t\t\tcallback(http.responseText);\n\t\t\t}\n\t\t}\n\t};\n\ttry {\n\t\thttp.send(data);\n\t} catch(ex) {\n\t\treturn callback($tw.language.getString(\"Error/Caption\") + \":\" + ex);\n\t}\n\t$tw.notifier.display(\"$:/language/Notifications/Save/Starting\");\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nUploadSaver.prototype.info = {\n\tname: \"upload\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new UploadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/server/authenticators/basic.js": {
"title": "$:/core/modules/server/authenticators/basic.js",
"text": "/*\\\ntitle: $:/core/modules/server/authenticators/basic.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for WWW basic authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\");\n}\n\nfunction BasicAuthenticator(server) {\n\tthis.server = server;\n\tthis.credentialsData = [];\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nBasicAuthenticator.prototype.init = function() {\n\t// Read the credentials data\n\tthis.credentialsFilepath = this.server.get(\"credentials\");\n\tif(this.credentialsFilepath) {\n\t\tvar resolveCredentialsFilepath = path.resolve(this.server.boot.wikiPath,this.credentialsFilepath);\n\t\tif(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {\n\t\t\tvar credentialsText = fs.readFileSync(resolveCredentialsFilepath,\"utf8\"),\n\t\t\t\tcredentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);\n\t\t\tif(typeof credentialsData === \"string\") {\n\t\t\t\treturn \"Error: \" + credentialsData + \" reading credentials from '\" + resolveCredentialsFilepath + \"'\";\n\t\t\t} else {\n\t\t\t\tthis.credentialsData = credentialsData;\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"Error: Unable to load user credentials from '\" + resolveCredentialsFilepath + \"'\";\n\t\t}\n\t}\n\t// Add the hardcoded username and password if specified\n\tif(this.server.get(\"username\") && this.server.get(\"password\")) {\n\t\tthis.credentialsData = this.credentialsData || [];\n\t\tthis.credentialsData.push({\n\t\t\tusername: this.server.get(\"username\"),\n\t\t\tpassword: this.server.get(\"password\")\n\t\t});\n\t}\n\treturn this.credentialsData.length > 0;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nBasicAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Extract the incoming username and password from the request\n\tvar header = request.headers.authorization || \"\";\n\tif(!header && state.allowAnon) {\n\t\t// If there's no header and anonymous access is allowed then we don't set authenticatedUsername\n\t\treturn true;\n\t}\n\tvar token = header.split(/\\s+/).pop() || \"\",\n\t\tauth = $tw.utils.base64Decode(token),\n\t\tparts = auth.split(/:/),\n\t\tincomingUsername = parts[0],\n\t\tincomingPassword = parts[1];\n\t// Check that at least one of the credentials matches\n\tvar matchingCredentials = this.credentialsData.find(function(credential) {\n\t\treturn credential.username === incomingUsername && credential.password === incomingPassword;\n\t});\n\tif(matchingCredentials) {\n\t\t// If so, add the authenticated username to the request state\n\t\tstate.authenticatedUsername = incomingUsername;\n\t\treturn true;\n\t} else {\n\t\t// If not, return an authentication challenge\n\t\tresponse.writeHead(401,\"Authentication required\",{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\n\t\treturn false;\n\t}\n};\n\nexports.AuthenticatorClass = BasicAuthenticator;\n\n})();\n",
"type": "application/javascript",
"module-type": "authenticator"
},
"$:/core/modules/server/authenticators/header.js": {
"title": "$:/core/modules/server/authenticators/header.js",
"text": "/*\\\ntitle: $:/core/modules/server/authenticators/header.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for trusted header authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction HeaderAuthenticator(server) {\n\tthis.server = server;\n\tthis.header = server.get(\"authenticated-user-header\") ? server.get(\"authenticated-user-header\").toLowerCase() : undefined;\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nHeaderAuthenticator.prototype.init = function() {\n\treturn !!this.header;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nHeaderAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Otherwise, authenticate as the username in the specified header\n\tvar username = request.headers[this.header];\n\tif(!username && !state.allowAnon) {\n\t\tresponse.writeHead(401,\"Authorization header required to login to '\" + state.server.servername + \"'\");\n\t\tresponse.end();\n\t\treturn false;\n\t} else {\n\t\t// authenticatedUsername will be undefined for anonymous users\n\t\tstate.authenticatedUsername = username;\n\t\treturn true;\n\t}\n};\n\nexports.AuthenticatorClass = HeaderAuthenticator;\n\n})();\n",
"type": "application/javascript",
"module-type": "authenticator"
},
"$:/core/modules/server/routes/delete-tiddler.js": {
"title": "$:/core/modules/server/routes/delete-tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/delete-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nDELETE /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"DELETE\";\n\nexports.path = /^\\/bags\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]);\n\tstate.wiki.deleteTiddler(title);\n\tresponse.writeHead(204, \"OK\", {\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-favicon.js": {
"title": "$:/core/modules/server/routes/get-favicon.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-favicon.js\ntype: application/javascript\nmodule-type: route\n\nGET /favicon.ico\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/favicon.ico$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"image/x-icon\"});\n\tvar buffer = state.wiki.getTiddlerText(\"$:/favicon.ico\",\"\");\n\tresponse.end(buffer,\"base64\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-file.js": {
"title": "$:/core/modules/server/routes/get-file.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-file.js\ntype: application/javascript\nmodule-type: route\n\nGET /files/:filepath\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/files\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar path = require(\"path\"),\n\t\tfs = require(\"fs\"),\n\t\tutil = require(\"util\"),\n\t\tsuppliedFilename = decodeURIComponent(state.params[0]),\n\t\tfilename = path.resolve(state.boot.wikiPath,\"files\",suppliedFilename),\n\t\textension = path.extname(filename);\n\tfs.readFile(filename,function(err,content) {\n\t\tvar status,content,type = \"text/plain\";\n\t\tif(err) {\n\t\t\tconsole.log(\"Error accessing file \" + filename + \": \" + err.toString());\n\t\t\tstatus = 404;\n\t\t\tcontent = \"File '\" + suppliedFilename + \"' not found\";\n\t\t} else {\n\t\t\tstatus = 200;\n\t\t\tcontent = content;\n\t\t\ttype = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : \"application/octet-stream\");\n\t\t}\n\t\tresponse.writeHead(status,{\n\t\t\t\"Content-Type\": type\n\t\t});\n\t\tresponse.end(content);\n\t});\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-index.js": {
"title": "$:/core/modules/server/routes/get-index.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-index.js\ntype: application/javascript\nmodule-type: route\n\nGET /\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar zlib = require(\"zlib\");\n\nexports.method = \"GET\";\n\nexports.path = /^\\/$/;\n\nexports.handler = function(request,response,state) {\n\tvar acceptEncoding = request.headers[\"accept-encoding\"];\n\tif(!acceptEncoding) {\n\t\tacceptEncoding = \"\";\n\t}\n\tvar text = state.wiki.renderTiddler(state.server.get(\"root-render-type\"),state.server.get(\"root-tiddler\")),\n\t\tresponseHeaders = {\n\t\t\"Content-Type\": state.server.get(\"root-serve-type\")\n\t};\n\t/*\n\tIf the gzip=yes flag for `listen` is set, check if the user agent permits\n\tcompression. If so, compress our response. Note that we use the synchronous\n\tfunctions from zlib to stay in the imperative style. The current `Server`\n\tdoesn't depend on this, and we may just as well use the async versions.\n\t*/\n\tif(state.server.enableGzip) {\n\t\tif (/\\bdeflate\\b/.test(acceptEncoding)) {\n\t\t\tresponseHeaders[\"Content-Encoding\"] = \"deflate\";\n\t\t\ttext = zlib.deflateSync(text);\n\t\t} else if (/\\bgzip\\b/.test(acceptEncoding)) {\n\t\t\tresponseHeaders[\"Content-Encoding\"] = \"gzip\";\n\t\t\ttext = zlib.gzipSync(text);\n\t\t}\n\t}\n\tresponse.writeHead(200,responseHeaders);\n\tresponse.end(text);\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-login-basic.js": {
"title": "$:/core/modules/server/routes/get-login-basic.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-login-basic.js\ntype: application/javascript\nmodule-type: route\n\nGET /login-basic -- force a Basic Authentication challenge\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/login-basic$/;\n\nexports.handler = function(request,response,state) {\n\tif(!state.authenticatedUsername) {\n\t\t// Challenge if there's no username\n\t\tresponse.writeHead(401,{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\t\t\n\t} else {\n\t\t// Redirect to the root wiki if login worked\n\t\tresponse.writeHead(302,{\n\t\t\tLocation: \"/\"\n\t\t});\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-status.js": {
"title": "$:/core/modules/server/routes/get-status.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-status.js\ntype: application/javascript\nmodule-type: route\n\nGET /status\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/status$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\tvar text = JSON.stringify({\n\t\tusername: state.authenticatedUsername || state.server.get(\"anon-username\") || \"\",\n\t\tanonymous: !state.authenticatedUsername,\n\t\tread_only: !state.server.isAuthorized(\"writers\",state.authenticatedUsername),\n\t\tspace: {\n\t\t\trecipe: \"default\"\n\t\t},\n\t\ttiddlywiki_version: $tw.version\n\t});\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-tiddler-html.js": {
"title": "$:/core/modules/server/routes/get-tiddler-html.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddler-html.js\ntype: application/javascript\nmodule-type: route\n\nGET /:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/([^\\/]+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar renderType = tiddler.getFieldString(\"_render_type\"),\n\t\t\trenderTemplate = tiddler.getFieldString(\"_render_template\");\n\t\t// Tiddler fields '_render_type' and '_render_template' overwrite\n\t\t// system wide settings for render type and template\n\t\tif(state.wiki.isSystemTiddler(title)) {\n\t\t\trenderType = renderType || state.server.get(\"system-tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"system-tiddler-render-template\");\n\t\t} else {\n\t\t\trenderType = renderType || state.server.get(\"tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"tiddler-render-template\");\n\t\t}\n\t\tvar text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});\n\t\t// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS\n\t\tresponse.writeHead(200);\n\t\tresponse.end(text,\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-tiddler.js": {
"title": "$:/core/modules/server/routes/get-tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title),\n\t\ttiddlerFields = {},\n\t\tknownFields = [\n\t\t\t\"bag\", \"created\", \"creator\", \"modified\", \"modifier\", \"permissions\", \"recipe\", \"revision\", \"tags\", \"text\", \"title\", \"type\", \"uri\"\n\t\t];\n\tif(tiddler) {\n\t\t$tw.utils.each(tiddler.fields,function(field,name) {\n\t\t\tvar value = tiddler.getFieldString(name);\n\t\t\tif(knownFields.indexOf(name) !== -1) {\n\t\t\t\ttiddlerFields[name] = value;\n\t\t\t} else {\n\t\t\t\ttiddlerFields.fields = tiddlerFields.fields || {};\n\t\t\t\ttiddlerFields.fields[name] = value;\n\t\t\t}\n\t\t});\n\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\ttiddlerFields.bag = \"default\";\n\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\t\tresponse.end(JSON.stringify(tiddlerFields),\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-tiddlers-json.js": {
"title": "$:/core/modules/server/routes/get-tiddlers-json.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddlers-json.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers.json?filter=<filter>\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEFAULT_FILTER = \"[all[tiddlers]!is[system]sort[title]]\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers.json$/;\n\nexports.handler = function(request,response,state) {\n\tvar filter = state.queryParameters.filter || DEFAULT_FILTER;\n\tif(state.wiki.getTiddlerText(\"$:/config/Server/AllowAllExternalFilters\") !== \"yes\") {\n\t\tif(state.wiki.getTiddlerText(\"$:/config/Server/ExternalFilters/\" + filter) !== \"yes\") {\n\t\t\tconsole.log(\"Blocked attempt to GET /recipes/default/tiddlers.json with filter: \" + filter);\n\t\t\tresponse.writeHead(403);\n\t\t\tresponse.end();\n\t\t\treturn;\n\t\t}\n\t}\n\tif(state.wiki.getTiddlerText(\"$:/config/SyncSystemTiddlersFromServer\") === \"no\") {\n\t\tfilter += \"+[!is[system]]\";\n\t}\n\tvar excludeFields = (state.queryParameters.exclude || \"text\").split(\",\"),\n\t\ttitles = state.wiki.filterTiddlers(filter);\n\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\tvar tiddlers = [];\n\t$tw.utils.each(titles,function(title) {\n\t\tvar tiddler = state.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tvar tiddlerFields = tiddler.getFieldStrings({exclude: excludeFields});\n\t\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\t\ttiddlers.push(tiddlerFields);\n\t\t}\n\t});\n\tvar text = JSON.stringify(tiddlers);\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/put-tiddler.js": {
"title": "$:/core/modules/server/routes/put-tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/put-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nPUT /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"PUT\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\tfields = JSON.parse(state.data);\n\t// Pull up any subfields in the `fields` object\n\tif(fields.fields) {\n\t\t$tw.utils.each(fields.fields,function(field,name) {\n\t\t\tfields[name] = field;\n\t\t});\n\t\tdelete fields.fields;\n\t}\n\t// Remove any revision field\n\tif(fields.revision) {\n\t\tdelete fields.revision;\n\t}\n\tstate.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title},state.wiki.getModificationFields()));\n\tvar changeCount = state.wiki.getChangeCount(title).toString();\n\tresponse.writeHead(204, \"OK\",{\n\t\tEtag: \"\\\"default/\" + encodeURIComponent(title) + \"/\" + changeCount + \":\\\"\",\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/server.js": {
"title": "$:/core/modules/server/server.js",
"text": "/*\\\ntitle: $:/core/modules/server/server.js\ntype: application/javascript\nmodule-type: library\n\nServe tiddlers over http\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\"),\n\t\tquerystring = require(\"querystring\");\n}\n\n/*\nA simple HTTP server with regexp-based routes\noptions: variables - optional hashmap of variables to set (a misnomer - they are really constant parameters)\n\t\t routes - optional array of routes to use\n\t\t wiki - reference to wiki object\n*/\nfunction Server(options) {\n\tvar self = this;\n\tthis.routes = options.routes || [];\n\tthis.authenticators = options.authenticators || [];\n\tthis.wiki = options.wiki;\n\tthis.boot = options.boot || $tw.boot;\n\tthis.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText(\"$:/SiteTitle\") || \"TiddlyWiki5\");\n\t// Initialise the variables\n\tthis.variables = $tw.utils.extend({},this.defaultVariables);\n\tif(options.variables) {\n\t\tfor(var variable in options.variables) {\n\t\t\tif(options.variables[variable]) {\n\t\t\t\tthis.variables[variable] = options.variables[variable];\n\t\t\t}\n\t\t}\t\t\n\t}\n\t$tw.utils.extend({},this.defaultVariables,options.variables);\n\t// Initialise CSRF\n\tthis.csrfDisable = this.get(\"csrf-disable\") === \"yes\";\n\t// Initialize Gzip compression\n\tthis.enableGzip = this.get(\"gzip\") === \"yes\";\n\t// Initialise authorization\n\tvar authorizedUserName = (this.get(\"username\") && this.get(\"password\")) ? this.get(\"username\") : \"(anon)\";\n\tthis.authorizationPrincipals = {\n\t\treaders: (this.get(\"readers\") || authorizedUserName).split(\",\").map($tw.utils.trim),\n\t\twriters: (this.get(\"writers\") || authorizedUserName).split(\",\").map($tw.utils.trim)\n\t}\n\t// Load and initialise authenticators\n\t$tw.modules.forEachModuleOfType(\"authenticator\", function(title,authenticatorDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addAuthenticator(authenticatorDefinition.AuthenticatorClass);\n\t});\n\t// Load route handlers\n\t$tw.modules.forEachModuleOfType(\"route\", function(title,routeDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addRoute(routeDefinition);\n\t});\n\t// Initialise the http vs https\n\tthis.listenOptions = null;\n\tthis.protocol = \"http\";\n\tvar tlsKeyFilepath = this.get(\"tls-key\"),\n\t\ttlsCertFilepath = this.get(\"tls-cert\");\n\tif(tlsCertFilepath && tlsKeyFilepath) {\n\t\tthis.listenOptions = {\n\t\t\tkey: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsKeyFilepath),\"utf8\"),\n\t\t\tcert: fs.readFileSync(path.resolve(this.boot.wikiPath,tlsCertFilepath),\"utf8\")\n\t\t};\n\t\tthis.protocol = \"https\";\n\t}\n\tthis.transport = require(this.protocol);\n}\n\nServer.prototype.defaultVariables = {\n\tport: \"8080\",\n\thost: \"127.0.0.1\",\n\t\"root-tiddler\": \"$:/core/save/all\",\n\t\"root-render-type\": \"text/plain\",\n\t\"root-serve-type\": \"text/html\",\n\t\"tiddler-render-type\": \"text/html\",\n\t\"tiddler-render-template\": \"$:/core/templates/server/static.tiddler.html\",\n\t\"system-tiddler-render-type\": \"text/plain\",\n\t\"system-tiddler-render-template\": \"$:/core/templates/wikified-tiddler\",\n\t\"debug-level\": \"none\",\n\t\"gzip\": \"no\"\n};\n\nServer.prototype.get = function(name) {\n\treturn this.variables[name];\n};\n\nServer.prototype.addRoute = function(route) {\n\tthis.routes.push(route);\n};\n\nServer.prototype.addAuthenticator = function(AuthenticatorClass) {\n\t// Instantiate and initialise the authenticator\n\tvar authenticator = new AuthenticatorClass(this),\n\t\tresult = authenticator.init();\n\tif(typeof result === \"string\") {\n\t\t$tw.utils.error(\"Error: \" + result);\n\t} else if(result) {\n\t\t// Only use the authenticator if it initialised successfully\n\t\tthis.authenticators.push(authenticator);\n\t}\n};\n\nServer.prototype.findMatchingRoute = function(request,state) {\n\tfor(var t=0; t<this.routes.length; t++) {\n\t\tvar potentialRoute = this.routes[t],\n\t\t\tpathRegExp = potentialRoute.path,\n\t\t\tpathname = state.urlInfo.pathname,\n\t\t\tmatch;\n\t\tif(state.pathPrefix) {\n\t\t\tif(pathname.substr(0,state.pathPrefix.length) === state.pathPrefix) {\n\t\t\t\tpathname = pathname.substr(state.pathPrefix.length) || \"/\";\n\t\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t\t} else {\n\t\t\t\tmatch = false;\n\t\t\t}\n\t\t} else {\n\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t}\n\t\tif(match && request.method === potentialRoute.method) {\n\t\t\tstate.params = [];\n\t\t\tfor(var p=1; p<match.length; p++) {\n\t\t\t\tstate.params.push(match[p]);\n\t\t\t}\n\t\t\treturn potentialRoute;\n\t\t}\n\t}\n\treturn null;\n};\n\nServer.prototype.methodMappings = {\n\t\"GET\": \"readers\",\n\t\"OPTIONS\": \"readers\",\n\t\"HEAD\": \"readers\",\n\t\"PUT\": \"writers\",\n\t\"POST\": \"writers\",\n\t\"DELETE\": \"writers\"\n};\n\n/*\nCheck whether a given user is authorized for the specified authorizationType (\"readers\" or \"writers\"). Pass null or undefined as the username to check for anonymous access\n*/\nServer.prototype.isAuthorized = function(authorizationType,username) {\n\tvar principals = this.authorizationPrincipals[authorizationType] || [];\n\treturn principals.indexOf(\"(anon)\") !== -1 || (username && (principals.indexOf(\"(authenticated)\") !== -1 || principals.indexOf(username) !== -1));\n}\n\nServer.prototype.requestHandler = function(request,response,options) {\n\toptions = options || {};\n\t// Compose the state object\n\tvar self = this;\n\tvar state = {};\n\tstate.wiki = options.wiki || self.wiki;\n\tstate.boot = options.boot || self.boot;\n\tstate.server = self;\n\tstate.urlInfo = url.parse(request.url);\n\tstate.queryParameters = querystring.parse(state.urlInfo.query);\n\tstate.pathPrefix = options.pathPrefix || this.get(\"path-prefix\") || \"\";\n\t// Get the principals authorized to access this resource\n\tvar authorizationType = this.methodMappings[request.method] || \"readers\";\n\t// Check for the CSRF header if this is a write\n\tif(!this.csrfDisable && authorizationType === \"writers\" && request.headers[\"x-requested-with\"] !== \"TiddlyWiki\") {\n\t\tresponse.writeHead(403,\"'X-Requested-With' header required to login to '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\t\t\n\t}\n\t// Check whether anonymous access is granted\n\tstate.allowAnon = this.isAuthorized(authorizationType,null);\n\t// Authenticate with the first active authenticator\n\tif(this.authenticators.length > 0) {\n\t\tif(!this.authenticators[0].authenticateRequest(request,response,state)) {\n\t\t\t// Bail if we failed (the authenticator will have sent the response)\n\t\t\treturn;\n\t\t}\t\t\n\t}\n\t// Authorize with the authenticated username\n\tif(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {\n\t\tresponse.writeHead(401,\"'\" + state.authenticatedUsername + \"' is not authorized to access '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Find the route that matches this path\n\tvar route = self.findMatchingRoute(request,state);\n\t// Optionally output debug info\n\tif(self.get(\"debug-level\") !== \"none\") {\n\t\tconsole.log(\"Request path:\",JSON.stringify(state.urlInfo));\n\t\tconsole.log(\"Request headers:\",JSON.stringify(request.headers));\n\t\tconsole.log(\"authenticatedUsername:\",state.authenticatedUsername);\n\t}\n\t// Return a 404 if we didn't find a route\n\tif(!route) {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Receive the request body if necessary and hand off to the route handler\n\tif(route.bodyFormat === \"stream\" || request.method === \"GET\" || request.method === \"HEAD\") {\n\t\t// Let the route handle the request stream itself\n\t\troute.handler(request,response,state);\n\t} else if(route.bodyFormat === \"string\" || !route.bodyFormat) {\n\t\t// Set the encoding for the incoming request\n\t\trequest.setEncoding(\"utf8\");\n\t\tvar data = \"\";\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata += chunk.toString();\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = data;\n\t\t\troute.handler(request,response,state);\n\t\t});\n\t} else if(route.bodyFormat === \"buffer\") {\n\t\tvar data = [];\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata.push(chunk);\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = Buffer.concat(data);\n\t\t\troute.handler(request,response,state);\n\t\t})\n\t} else {\n\t\tresponse.writeHead(400,\"Invalid bodyFormat \" + route.bodyFormat + \" in route \" + route.method + \" \" + route.path.source);\n\t\tresponse.end();\n\t}\n};\n\n/*\nListen for requests\nport: optional port number (falls back to value of \"port\" variable)\nhost: optional host address (falls back to value of \"host\" variable)\nprefix: optional prefix (falls back to value of \"path-prefix\" variable)\n*/\nServer.prototype.listen = function(port,host,prefix) {\n\tvar self = this;\n\t// Handle defaults for port and host\n\tport = port || this.get(\"port\");\n\thost = host || this.get(\"host\");\n\tprefix = prefix || this.get(\"path-prefix\") || \"\";\n\t// Check for the port being a string and look it up as an environment variable\n\tif(parseInt(port,10).toString() !== port) {\n\t\tport = process.env[port] || 8080;\n\t}\n\t// Warn if required plugins are missing\n\tif(!this.wiki.getTiddler(\"$:/plugins/tiddlywiki/tiddlyweb\") || !this.wiki.getTiddler(\"$:/plugins/tiddlywiki/filesystem\")) {\n\t\t$tw.utils.warning(\"Warning: Plugins required for client-server operation (\\\"tiddlywiki/filesystem\\\" and \\\"tiddlywiki/tiddlyweb\\\") are missing from tiddlywiki.info file\");\n\t}\n\t// Create the server\n\tvar server;\n\tif(this.listenOptions) {\n\t\tserver = this.transport.createServer(this.listenOptions,this.requestHandler.bind(this));\n\t} else {\n\t\tserver = this.transport.createServer(this.requestHandler.bind(this));\n\t}\n\t// Display the port number after we've started listening (the port number might have been specified as zero, in which case we will get an assigned port)\n\tserver.on(\"listening\",function() {\n\t\tvar address = server.address();\n\t\t$tw.utils.log(\"Serving on \" + self.protocol + \"://\" + address.address + \":\" + address.port + prefix,\"brown/orange\");\n\t\t$tw.utils.log(\"(press ctrl-C to exit)\",\"red\");\n\t});\n\t// Listen\n\treturn server.listen(port,host);\n};\n\nexports.Server = Server;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/browser-messaging.js": {
"title": "$:/core/modules/browser-messaging.js",
"text": "/*\\\ntitle: $:/core/modules/browser-messaging.js\ntype: application/javascript\nmodule-type: startup\n\nBrowser message handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"browser-messaging\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n/*\nLoad a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used\n*/\nfunction loadIFrame(url,callback) {\n\t// Check if iframe already exists\n\tvar iframeInfo = $tw.browserMessaging.iframeInfoMap[url];\n\tif(iframeInfo) {\n\t\t// We've already got the iframe\n\t\tcallback(null,iframeInfo);\n\t} else {\n\t\t// Create the iframe and save it in the list\n\t\tvar iframe = document.createElement(\"iframe\");\n\t\tiframeInfo = {\n\t\t\turl: url,\n\t\t\tstatus: \"loading\",\n\t\t\tdomNode: iframe\n\t\t};\n\t\t$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;\n\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t// Add the iframe to the DOM and hide it\n\t\tiframe.style.display = \"none\";\n\t\tiframe.setAttribute(\"library\",\"true\");\n\t\tdocument.body.appendChild(iframe);\n\t\t// Set up onload\n\t\tiframe.onload = function() {\n\t\t\tiframeInfo.status = \"loaded\";\n\t\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t\tcallback(null,iframeInfo);\n\t\t};\n\t\tiframe.onerror = function() {\n\t\t\tcallback(\"Cannot load iframe\");\n\t\t};\n\t\ttry {\n\t\t\tiframe.src = url;\n\t\t} catch(ex) {\n\t\t\tcallback(ex);\n\t\t}\n\t}\n}\n\n/*\nUnload library iframe for given url\n*/\nfunction unloadIFrame(url){\n\t$tw.utils.each(document.getElementsByTagName('iframe'), function(iframe) {\n\t\tif(iframe.getAttribute(\"library\") === \"true\" &&\n\t\t iframe.getAttribute(\"src\") === url) {\n\t\t\tiframe.parentNode.removeChild(iframe);\n\t\t}\n\t});\n}\n\nfunction saveIFrameInfoTiddler(iframeInfo) {\n\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),{\n\t\ttitle: \"$:/temp/ServerConnection/\" + iframeInfo.url,\n\t\ttext: iframeInfo.status,\n\t\ttags: [\"$:/tags/ServerConnection\"],\n\t\turl: iframeInfo.url\n\t},$tw.wiki.getModificationFields()));\n}\n\nexports.startup = function() {\n\t// Initialise the store of iframes we've created\n\t$tw.browserMessaging = {\n\t\tiframeInfoMap: {} // Hashmap by URL of {url:,status:\"loading/loaded\",domNode:}\n\t};\n\t// Listen for widget messages to control loading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\tif(url) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers.json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-info\",\n\t\t\t\t\t\t\tinfoTitlePrefix: paramObject.infoTitlePrefix || \"$:/temp/RemoteAssetInfo/\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for widget messages to control unloading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-unload-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\t$tw.browserMessaging.iframeInfoMap[url] = undefined;\n\t\tif(url) {\n\t\t\tunloadIFrame(url);\n\t\t\t$tw.utils.each(\n\t\t\t\t$tw.wiki.filterTiddlers(\"[[$:/temp/ServerConnection/\" + url + \"]] [prefix[$:/temp/RemoteAssetInfo/\" + url + \"/]]\"),\n\t\t\t\tfunction(title) {\n\t\t\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-from-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url,\n\t\t\ttitle = paramObject.title;\n\t\tif(url && title) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers/\" + encodeURIComponent(title) + \".json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-tiddler\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for window messages from other windows\n\twindow.addEventListener(\"message\",function listener(event){\n\t\t// console.log(\"browser-messaging: \",document.location.toString())\n\t\t// console.log(\"browser-messaging: Received message from\",event.origin);\n\t\t// console.log(\"browser-messaging: Message content\",event.data);\n\t\tswitch(event.data.verb) {\n\t\t\tcase \"GET-RESPONSE\":\n\t\t\t\tif(event.data.status.charAt(0) === \"2\") {\n\t\t\t\t\tif(event.data.cookies) {\n\t\t\t\t\t\tif(event.data.cookies.type === \"save-info\") {\n\t\t\t\t\t\t\tvar tiddlers = JSON.parse(event.data.body);\n\t\t\t\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\t\t\t\t\ttitle: event.data.cookies.infoTitlePrefix + event.data.cookies.url + \"/\" + tiddler.title,\n\t\t\t\t\t\t\t\t\t\"original-title\": tiddler.title,\n\t\t\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\t\t\ttype: \"text/vnd.tiddlywiki\",\n\t\t\t\t\t\t\t\t\t\"original-type\": tiddler.type,\n\t\t\t\t\t\t\t\t\t\"plugin-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-plugin-type\": tiddler[\"plugin-type\"],\n\t\t\t\t\t\t\t\t\t\"module-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-module-type\": tiddler[\"module-type\"],\n\t\t\t\t\t\t\t\t\ttags: [\"$:/tags/RemoteAssetInfo\"],\n\t\t\t\t\t\t\t\t\t\"original-tags\": $tw.utils.stringifyList(tiddler.tags || []),\n\t\t\t\t\t\t\t\t\t\"server-url\": event.data.cookies.url\n\t\t\t\t\t\t\t\t},$tw.wiki.getModificationFields()));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if(event.data.cookies.type === \"save-tiddler\") {\n\t\t\t\t\t\t\tvar tiddler = JSON.parse(event.data.body);\n\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t},false);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/commands.js": {
"title": "$:/core/modules/startup/commands.js",
"text": "/*\\\ntitle: $:/core/modules/startup/commands.js\ntype: application/javascript\nmodule-type: startup\n\nCommand processing\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"commands\";\nexports.platforms = [\"node\"];\nexports.after = [\"story\"];\nexports.synchronous = false;\n\nexports.startup = function(callback) {\n\t// On the server, start a commander with the command line arguments\n\tvar commander = new $tw.Commander(\n\t\t$tw.boot.argv,\n\t\tfunction(err) {\n\t\t\tif(err) {\n\t\t\t\treturn $tw.utils.error(\"Error: \" + err);\n\t\t\t}\n\t\t\tcallback();\n\t\t},\n\t\t$tw.wiki,\n\t\t{output: process.stdout, error: process.stderr}\n\t);\n\tcommander.execute();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/CSSescape.js": {
"title": "$:/core/modules/startup/CSSescape.js",
"text": "/*\\\ntitle: $:/core/modules/startup/CSSescape.js\ntype: application/javascript\nmodule-type: startup\n\nPolyfill for CSS.escape()\n\n\\*/\n(function(root,factory){\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"css-escape\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n/*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */\n// https://github.com/umdjs/umd/blob/master/returnExports.js\nexports.startup = factory(root);\n}(typeof global != 'undefined' ? global : this, function(root) {\n\n\tif (root.CSS && root.CSS.escape) {\n\t\treturn;\n\t}\n\n\t// https://drafts.csswg.org/cssom/#serialize-an-identifier\n\tvar cssEscape = function(value) {\n\t\tif (arguments.length == 0) {\n\t\t\tthrow new TypeError('`CSS.escape` requires an argument.');\n\t\t}\n\t\tvar string = String(value);\n\t\tvar length = string.length;\n\t\tvar index = -1;\n\t\tvar codeUnit;\n\t\tvar result = '';\n\t\tvar firstCodeUnit = string.charCodeAt(0);\n\t\twhile (++index < length) {\n\t\t\tcodeUnit = string.charCodeAt(index);\n\t\t\t// Note: there’s no need to special-case astral symbols, surrogate\n\t\t\t// pairs, or lone surrogates.\n\n\t\t\t// If the character is NULL (U+0000), then the REPLACEMENT CHARACTER\n\t\t\t// (U+FFFD).\n\t\t\tif (codeUnit == 0x0000) {\n\t\t\t\tresult += '\\uFFFD';\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t// If the character is in the range [\\1-\\1F] (U+0001 to U+001F) or is\n\t\t\t\t// U+007F, […]\n\t\t\t\t(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||\n\t\t\t\t// If the character is the first character and is in the range [0-9]\n\t\t\t\t// (U+0030 to U+0039), […]\n\t\t\t\t(index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||\n\t\t\t\t// If the character is the second character and is in the range [0-9]\n\t\t\t\t// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]\n\t\t\t\t(\n\t\t\t\t\tindex == 1 &&\n\t\t\t\t\tcodeUnit >= 0x0030 && codeUnit <= 0x0039 &&\n\t\t\t\t\tfirstCodeUnit == 0x002D\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\t// https://drafts.csswg.org/cssom/#escape-a-character-as-code-point\n\t\t\t\tresult += '\\\\' + codeUnit.toString(16) + ' ';\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t// If the character is the first character and is a `-` (U+002D), and\n\t\t\t\t// there is no second character, […]\n\t\t\t\tindex == 0 &&\n\t\t\t\tlength == 1 &&\n\t\t\t\tcodeUnit == 0x002D\n\t\t\t) {\n\t\t\t\tresult += '\\\\' + string.charAt(index);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If the character is not handled by one of the above rules and is\n\t\t\t// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or\n\t\t\t// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to\n\t\t\t// U+005A), or [a-z] (U+0061 to U+007A), […]\n\t\t\tif (\n\t\t\t\tcodeUnit >= 0x0080 ||\n\t\t\t\tcodeUnit == 0x002D ||\n\t\t\t\tcodeUnit == 0x005F ||\n\t\t\t\tcodeUnit >= 0x0030 && codeUnit <= 0x0039 ||\n\t\t\t\tcodeUnit >= 0x0041 && codeUnit <= 0x005A ||\n\t\t\t\tcodeUnit >= 0x0061 && codeUnit <= 0x007A\n\t\t\t) {\n\t\t\t\t// the character itself\n\t\t\t\tresult += string.charAt(index);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Otherwise, the escaped character.\n\t\t\t// https://drafts.csswg.org/cssom/#escape-a-character\n\t\t\tresult += '\\\\' + string.charAt(index);\n\n\t\t}\n\t\treturn result;\n\t};\n\n\tif (!root.CSS) {\n\t\troot.CSS = {};\n\t}\n\n\troot.CSS.escape = cssEscape;\n\n}));\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/favicon.js": {
"title": "$:/core/modules/startup/favicon.js",
"text": "/*\\\ntitle: $:/core/modules/startup/favicon.js\ntype: application/javascript\nmodule-type: startup\n\nFavicon handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"favicon\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\t\t\n// Favicon tiddler\nvar FAVICON_TITLE = \"$:/favicon.ico\";\n\nexports.startup = function() {\n\t// Set up the favicon\n\tsetFavicon();\n\t// Reset the favicon when the tiddler changes\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,FAVICON_TITLE)) {\n\t\t\tsetFavicon();\n\t\t}\n\t});\n};\n\nfunction setFavicon() {\n\tvar tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);\n\tif(tiddler) {\n\t\tvar faviconLink = document.getElementById(\"faviconLink\");\n\t\tfaviconLink.setAttribute(\"href\",$tw.utils.makeDataUri(tiddler.fields.text,tiddler.fields.type,tiddler.fields._canonical_uri));\n\t}\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/info.js": {
"title": "$:/core/modules/startup/info.js",
"text": "/*\\\ntitle: $:/core/modules/startup/info.js\ntype: application/javascript\nmodule-type: startup\n\nInitialise $:/info tiddlers via $:/temp/info-plugin pseudo-plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"info\";\nexports.before = [\"startup\"];\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\nvar TITLE_INFO_PLUGIN = \"$:/temp/info-plugin\";\n\nexports.startup = function() {\n\t// Function to bake the info plugin with new tiddlers\n\tvar updateInfoPlugin = function(tiddlerFieldsArray) {\n\t\t// Get the existing tiddlers\n\t\tvar json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}});\n\t\t// Add the new ones\n\t\t$tw.utils.each(tiddlerFieldsArray,function(fields) {\n\t\t\tif(fields && fields.title) {\n\t\t\t\tjson.tiddlers[fields.title] = fields;\n\t\t\t}\n\t\t});\n\t\t// Bake the info tiddlers into a plugin. We use the non-standard plugin-type \"info\" because ordinary plugins are only registered asynchronously after being loaded dynamically\n\t\tvar fields = {\n\t\t\ttitle: TITLE_INFO_PLUGIN,\n\t\t\ttype: \"application/json\",\n\t\t\t\"plugin-type\": \"info\",\n\t\t\ttext: JSON.stringify(json,null,$tw.config.preferences.jsonSpaces)\n\t\t};\n\t\t$tw.wiki.addTiddler(new $tw.Tiddler(fields));\n\n\t};\n\t// Collect up the info tiddlers\n\tvar tiddlerFieldsArray = [];\n\t// Give each info module a chance to provide as many info tiddlers as they want as an array, and give them a callback for dynamically updating them\n\t$tw.modules.forEachModuleOfType(\"info\",function(title,moduleExports) {\n\t\tif(moduleExports && moduleExports.getInfoTiddlerFields) {\n\t\t\tArray.prototype.push.apply(tiddlerFieldsArray,moduleExports.getInfoTiddlerFields(updateInfoPlugin));\n\t\t}\n\t});\n\tupdateInfoPlugin(tiddlerFieldsArray);\n\tvar changes = $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);\n\t$tw.wiki.registerPluginTiddlers(\"info\",[TITLE_INFO_PLUGIN]);\n\t$tw.wiki.unpackPluginTiddlers();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/load-modules.js": {
"title": "$:/core/modules/startup/load-modules.js",
"text": "/*\\\ntitle: $:/core/modules/startup/load-modules.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"load-modules\";\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Load modules\n\t$tw.modules.applyMethods(\"utils\",$tw.utils);\n\tif($tw.node) {\n\t\t$tw.modules.applyMethods(\"utils-node\",$tw.utils);\n\t}\n\t$tw.modules.applyMethods(\"global\",$tw);\n\t$tw.modules.applyMethods(\"config\",$tw.config);\n\t$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap(\"tiddlerfield\");\n\t$tw.modules.applyMethods(\"tiddlermethod\",$tw.Tiddler.prototype);\n\t$tw.modules.applyMethods(\"wikimethod\",$tw.Wiki.prototype);\n\t$tw.wiki.addIndexersToWiki();\n\t$tw.modules.applyMethods(\"tiddlerdeserializer\",$tw.Wiki.tiddlerDeserializerModules);\n\t$tw.macros = $tw.modules.getModulesByTypeAsHashmap(\"macro\");\n\t$tw.wiki.initParsers();\n\t$tw.Commander.initCommands();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/password.js": {
"title": "$:/core/modules/startup/password.js",
"text": "/*\\\ntitle: $:/core/modules/startup/password.js\ntype: application/javascript\nmodule-type: startup\n\nPassword handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"password\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t$tw.rootWidget.addEventListener(\"tm-set-password\",function(event) {\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: $tw.language.getString(\"Encryption/PromptSetPassword\"),\n\t\t\tnoUserName: true,\n\t\t\tsubmitText: $tw.language.getString(\"Encryption/SetPassword\"),\n\t\t\tcanCancel: true,\n\t\t\trepeatPassword: true,\n\t\t\tcallback: function(data) {\n\t\t\t\tif(data) {\n\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t}\n\t\t\t\treturn true; // Get rid of the password prompt\n\t\t\t}\n\t\t});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-clear-password\",function(event) {\n\t\tif($tw.browser) {\n\t\t\tif(!confirm($tw.language.getString(\"Encryption/ConfirmClearPassword\"))) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t$tw.crypto.setPassword(null);\n\t});\n\t// Ensure that $:/isEncrypted is maintained properly\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,\"$:/isEncrypted\")) {\n\t\t\t$tw.crypto.updateCryptoStateTiddler();\n\t\t}\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/plugins.js": {
"title": "$:/core/modules/startup/plugins.js",
"text": "/*\\\ntitle: $:/core/modules/startup/plugins.js\ntype: application/javascript\nmodule-type: startup\n\nStartup logic concerned with managing plugins\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"plugins\";\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\nvar TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE = \"$:/status/RequireReloadDueToPluginChange\";\n\nvar PREFIX_CONFIG_REGISTER_PLUGIN_TYPE = \"$:/config/RegisterPluginType/\";\n\nexports.startup = function() {\n\t$tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: \"no\"});\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t// Work out which of the changed tiddlers are plugins that we need to reregister\n\t\tvar changesToProcess = [],\n\t\t\trequireReloadDueToPluginChange = false;\n\t\t$tw.utils.each(Object.keys(changes),function(title) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title),\n\t\t\t\trequiresReload = $tw.wiki.doesPluginRequireReload(title);\n\t\t\tif(requiresReload) {\n\t\t\t\trequireReloadDueToPluginChange = true;\n\t\t\t} else if(tiddler) {\n\t\t\t\tvar pluginType = tiddler.fields[\"plugin-type\"];\n\t\t\t\tif($tw.wiki.getTiddlerText(PREFIX_CONFIG_REGISTER_PLUGIN_TYPE + (tiddler.fields[\"plugin-type\"] || \"\"),\"no\") === \"yes\") {\n\t\t\t\t\tchangesToProcess.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t// Issue warning if any of the tiddlers require a reload\n\t\tif(requireReloadDueToPluginChange) {\n\t\t\t$tw.wiki.addTiddler({title: TITLE_REQUIRE_RELOAD_DUE_TO_PLUGIN_CHANGE,text: \"yes\"});\n\t\t}\n\t\t// Read or delete the plugin info of the changed tiddlers\n\t\tif(changesToProcess.length > 0) {\n\t\t\tvar changes = $tw.wiki.readPluginInfo(changesToProcess);\n\t\t\tif(changes.modifiedPlugins.length > 0 || changes.deletedPlugins.length > 0) {\n\t\t\t\tvar changedShadowTiddlers = {};\n\t\t\t\t// Collect the shadow tiddlers of any deleted plugins\n\t\t\t\t$tw.utils.each(changes.deletedPlugins,function(pluginTitle) {\n\t\t\t\t\tvar pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);\n\t\t\t\t\tif(pluginInfo) {\n\t\t\t\t\t\t$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {\n\t\t\t\t\t\t\tchangedShadowTiddlers[title] = true;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Collect the shadow tiddlers of any modified plugins\n\t\t\t\t$tw.utils.each(changes.modifiedPlugins,function(pluginTitle) {\n\t\t\t\t\tvar pluginInfo = $tw.wiki.getPluginInfo(pluginTitle);\n\t\t\t\t\tif(pluginInfo) {\n\t\t\t\t\t\t$tw.utils.each(Object.keys(pluginInfo.tiddlers),function(title) {\n\t\t\t\t\t\t\tchangedShadowTiddlers[title] = false;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// (Re-)register any modified plugins\n\t\t\t\t$tw.wiki.registerPluginTiddlers(null,changes.modifiedPlugins);\n\t\t\t\t// Unregister any deleted plugins\n\t\t\t\t$tw.wiki.unregisterPluginTiddlers(null,changes.deletedPlugins);\n\t\t\t\t// Unpack the shadow tiddlers\n\t\t\t\t$tw.wiki.unpackPluginTiddlers();\n\t\t\t\t// Queue change events for the changed shadow tiddlers\n\t\t\t\t$tw.utils.each(Object.keys(changedShadowTiddlers),function(title) {\n\t\t\t\t\t$tw.wiki.enqueueTiddlerEvent(title,changedShadowTiddlers[title]);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/render.js": {
"title": "$:/core/modules/startup/render.js",
"text": "/*\\\ntitle: $:/core/modules/startup/render.js\ntype: application/javascript\nmodule-type: startup\n\nTitle, stylesheet and page rendering\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"render\";\nexports.platforms = [\"browser\"];\nexports.after = [\"story\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar PAGE_TITLE_TITLE = \"$:/core/wiki/title\";\nvar PAGE_STYLESHEET_TITLE = \"$:/core/ui/PageStylesheet\";\nvar PAGE_TEMPLATE_TITLE = \"$:/core/ui/RootTemplate\";\n\n// Time (in ms) that we defer refreshing changes to draft tiddlers\nvar DRAFT_TIDDLER_TIMEOUT_TITLE = \"$:/config/Drafts/TypingTimeout\";\nvar THROTTLE_REFRESH_TIMEOUT = 400;\n\nexports.startup = function() {\n\t// Set up the title\n\t$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE,{document: $tw.fakeDocument, parseAsInline: true});\n\t$tw.titleContainer = $tw.fakeDocument.createElement(\"div\");\n\t$tw.titleWidgetNode.render($tw.titleContainer,null);\n\tdocument.title = $tw.titleContainer.textContent;\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.titleWidgetNode.refresh(changes,$tw.titleContainer,null)) {\n\t\t\tdocument.title = $tw.titleContainer.textContent;\n\t\t}\n\t});\n\t// Set up the styles\n\t$tw.styleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_STYLESHEET_TITLE,{document: $tw.fakeDocument});\n\t$tw.styleContainer = $tw.fakeDocument.createElement(\"style\");\n\t$tw.styleWidgetNode.render($tw.styleContainer,null);\n\t$tw.styleElement = document.createElement(\"style\");\n\t$tw.styleElement.innerHTML = $tw.styleContainer.textContent;\n\tdocument.head.insertBefore($tw.styleElement,document.head.firstChild);\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"styleRefresh\",function(changes) {\n\t\tif($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {\n\t\t\t$tw.styleElement.innerHTML = $tw.styleContainer.textContent;\n\t\t}\n\t}));\n\t// Display the $:/core/ui/PageTemplate tiddler to kick off the display\n\t$tw.perf.report(\"mainRender\",function() {\n\t\t$tw.pageWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TEMPLATE_TITLE,{document: document, parentWidget: $tw.rootWidget, recursionMarker: \"no\"});\n\t\t$tw.pageContainer = document.createElement(\"div\");\n\t\t$tw.utils.addClass($tw.pageContainer,\"tc-page-container-wrapper\");\n\t\tdocument.body.insertBefore($tw.pageContainer,document.body.firstChild);\n\t\t$tw.pageWidgetNode.render($tw.pageContainer,null);\n \t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t})();\n\t// Remove any splash screen elements\n\tvar removeList = document.querySelectorAll(\".tc-remove-when-wiki-loaded\");\n\t$tw.utils.each(removeList,function(removeItem) {\n\t\tif(removeItem.parentNode) {\n\t\t\tremoveItem.parentNode.removeChild(removeItem);\n\t\t}\n\t});\n\t// Prepare refresh mechanism\n\tvar deferredChanges = Object.create(null),\n\t\ttimerId;\n\tfunction refresh() {\n\t\t// Process the refresh\n\t\t$tw.hooks.invokeHook(\"th-page-refreshing\");\n\t\t$tw.pageWidgetNode.refresh(deferredChanges);\n\t\tdeferredChanges = Object.create(null);\n\t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t}\n\t// Add the change event handler\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"mainRefresh\",function(changes) {\n\t\t// Check if only tiddlers that are throttled have changed\n\t\tvar onlyThrottledTiddlersHaveChanged = true;\n\t\tfor(var title in changes) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\tif(!tiddler || !(tiddler.hasField(\"draft.of\") || tiddler.hasField(\"throttle.refresh\"))) {\n\t\t\t\tonlyThrottledTiddlersHaveChanged = false;\n\t\t\t}\n\t\t}\n\t\t// Defer the change if only drafts have changed\n\t\tif(timerId) {\n\t\t\tclearTimeout(timerId);\n\t\t}\n\t\ttimerId = null;\n\t\tif(onlyThrottledTiddlersHaveChanged) {\n\t\t\tvar timeout = parseInt($tw.wiki.getTiddlerText(DRAFT_TIDDLER_TIMEOUT_TITLE,\"\"),10);\n\t\t\tif(isNaN(timeout)) {\n\t\t\t\ttimeout = THROTTLE_REFRESH_TIMEOUT;\n\t\t\t}\n\t\t\ttimerId = setTimeout(refresh,timeout);\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t} else {\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t\trefresh();\n\t\t}\n\t}));\n\t// Fix up the link between the root widget and the page container\n\t$tw.rootWidget.domNodes = [$tw.pageContainer];\n\t$tw.rootWidget.children = [$tw.pageWidgetNode];\n\t// Run any post-render startup actions\n\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction/PostRender\");\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/rootwidget.js": {
"title": "$:/core/modules/startup/rootwidget.js",
"text": "/*\\\ntitle: $:/core/modules/startup/rootwidget.js\ntype: application/javascript\nmodule-type: startup\n\nSetup the root widget and the core root widget handlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"rootwidget\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.before = [\"story\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Install the modal message mechanism\n\t$tw.modal = new $tw.utils.Modal($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-modal\",function(event) {\n\t\t$tw.modal.display(event.param,{variables: event.paramObject, event: event});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-show-switcher\",function(event) {\n\t\t$tw.modal.display(\"$:/core/ui/SwitcherModal\",{variables: event.paramObject, event: event});\n\t});\t\n\t// Install the notification mechanism\n\t$tw.notifier = new $tw.utils.Notifier($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-notify\",function(event) {\n\t\t$tw.notifier.display(event.param,{variables: event.paramObject});\n\t});\n\t// Install the copy-to-clipboard mechanism\n\t$tw.rootWidget.addEventListener(\"tm-copy-to-clipboard\",function(event) {\n\t\t$tw.utils.copyToClipboard(event.param);\n\t});\n\t// Install the tm-focus-selector message\n\t$tw.rootWidget.addEventListener(\"tm-focus-selector\",function(event) {\n\t\tvar selector = event.param || \"\",\n\t\t\telement;\n\t\ttry {\n\t\t\telement = document.querySelector(selector);\n\t\t} catch(e) {\n\t\t\tconsole.log(\"Error in selector: \",selector)\n\t\t}\n\t\tif(element && element.focus) {\n\t\t\telement.focus(event.paramObject);\n\t\t}\n\t});\n\t// Install the scroller\n\t$tw.pageScroller = new $tw.utils.PageScroller();\n\t$tw.rootWidget.addEventListener(\"tm-scroll\",function(event) {\n\t\t$tw.pageScroller.handleEvent(event);\n\t});\n\tvar fullscreen = $tw.utils.getFullScreenApis();\n\tif(fullscreen) {\n\t\t$tw.rootWidget.addEventListener(\"tm-full-screen\",function(event) {\n\t\t\tvar fullScreenDocument = event.event ? event.event.target.ownerDocument : document;\n\t\t\tif(event.param === \"enter\") {\n\t\t\t\tfullScreenDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t} else if(event.param === \"exit\") {\n\t\t\t\tfullScreenDocument[fullscreen._exitFullscreen]();\n\t\t\t} else {\n\t\t\t\tif(fullScreenDocument[fullscreen._fullscreenElement]) {\n\t\t\t\t\tfullScreenDocument[fullscreen._exitFullscreen]();\n\t\t\t\t} else {\n\t\t\t\t\tfullScreenDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n\t// If we're being viewed on a data: URI then give instructions for how to save\n\tif(document.location.protocol === \"data:\") {\n\t\t$tw.rootWidget.dispatchEvent({\n\t\t\ttype: \"tm-modal\",\n\t\t\tparam: \"$:/language/Modals/SaveInstructions\"\n\t\t});\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup.js": {
"title": "$:/core/modules/startup.js",
"text": "/*\\\ntitle: $:/core/modules/startup.js\ntype: application/javascript\nmodule-type: startup\n\nMiscellaneous startup logic for both the client and server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"startup\";\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\n// Set to `true` to enable performance instrumentation\nvar PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = \"$:/config/Performance/Instrumentation\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.startup = function() {\n\tvar modules,n,m,f;\n\t// Minimal browser detection\n\tif($tw.browser) {\n\t\t$tw.browser.isIE = (/msie|trident/i.test(navigator.userAgent));\n\t\t$tw.browser.isFirefox = !!document.mozFullScreenEnabled;\n\t}\n\t// Platform detection\n\t$tw.platform = {};\n\tif($tw.browser) {\n\t\t$tw.platform.isMac = /Mac/.test(navigator.platform);\n\t\t$tw.platform.isWindows = /win/i.test(navigator.platform);\n\t\t$tw.platform.isLinux = /Linux/i.test(navigator.platform);\n\t} else {\n\t\tswitch(require(\"os\").platform()) {\n\t\t\tcase \"darwin\":\n\t\t\t\t$tw.platform.isMac = true;\n\t\t\t\tbreak;\n\t\t\tcase \"win32\":\n\t\t\t\t$tw.platform.isWindows = true;\n\t\t\t\tbreak;\n\t\t\tcase \"freebsd\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t\tcase \"linux\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t// Initialise version\n\t$tw.version = $tw.utils.extractVersionInfo();\n\t// Set up the performance framework\n\t$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,\"no\") === \"yes\");\n\t// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers\n\t$tw.rootWidget = new widget.widget({\n\t\ttype: \"widget\",\n\t\tchildren: []\n\t},{\n\t\twiki: $tw.wiki,\n\t\tdocument: $tw.browser ? document : $tw.fakeDocument\n\t});\n\t// Execute any startup actions\n\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction\");\n\tif($tw.browser) {\n\t\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction/Browser\");\t\t\n\t}\n\tif($tw.node) {\n\t\t$tw.rootWidget.invokeActionsByTag(\"$:/tags/StartupAction/Node\");\t\t\n\t}\n\t// Kick off the language manager and switcher\n\t$tw.language = new $tw.Language();\n\t$tw.languageSwitcher = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"language\",\n\t\tcontrollerTitle: \"$:/language\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/languages/en-GB\"\n\t\t],\n\t\tonSwitch: function(plugins) {\n\t\t\tif($tw.browser) {\n\t\t\t\tvar pluginTiddler = $tw.wiki.getTiddler(plugins[0]);\n\t\t\t\tif(pluginTiddler) {\n\t\t\t\t\tdocument.documentElement.setAttribute(\"dir\",pluginTiddler.getFieldString(\"text-direction\") || \"auto\");\n\t\t\t\t} else {\n\t\t\t\t\tdocument.documentElement.removeAttribute(\"dir\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t// Kick off the theme manager\n\t$tw.themeManager = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"theme\",\n\t\tcontrollerTitle: \"$:/theme\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/themes/tiddlywiki/snowwhite\",\n\t\t\t\"$:/themes/tiddlywiki/vanilla\"\n\t\t]\n\t});\n\t// Kick off the keyboard manager\n\t$tw.keyboardManager = new $tw.KeyboardManager();\n\t// Listen for shortcuts\n\tif($tw.browser) {\n\t\t$tw.utils.addEventListeners(document,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t}]);\n\t}\n\t// Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup\n\t$tw.wiki.clearTiddlerEventQueue();\n\t// Find a working syncadaptor\n\t$tw.syncadaptor = undefined;\n\t$tw.modules.forEachModuleOfType(\"syncadaptor\",function(title,module) {\n\t\tif(!$tw.syncadaptor && module.adaptorClass) {\n\t\t\t$tw.syncadaptor = new module.adaptorClass({wiki: $tw.wiki});\n\t\t}\n\t});\n\t// Set up the syncer object if we've got a syncadaptor\n\tif($tw.syncadaptor) {\n\t\t$tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor});\n\t}\n\t// Setup the saver handler\n\t$tw.saverHandler = new $tw.SaverHandler({\n\t\twiki: $tw.wiki,\n\t\tdirtyTracking: !$tw.syncadaptor,\n\t\tpreloadDirty: $tw.boot.preloadDirty || []\n\t});\n\t// Host-specific startup\n\tif($tw.browser) {\n\t\t// Install the popup manager\n\t\t$tw.popup = new $tw.utils.Popup();\n\t\t// Install the animator\n\t\t$tw.anim = new $tw.utils.Animator();\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/story.js": {
"title": "$:/core/modules/startup/story.js",
"text": "/*\\\ntitle: $:/core/modules/startup/story.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"story\";\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar DEFAULT_STORY_TITLE = \"$:/StoryList\";\nvar DEFAULT_HISTORY_TITLE = \"$:/HistoryList\";\n\n// Default tiddlers\nvar DEFAULT_TIDDLERS_TITLE = \"$:/DefaultTiddlers\";\n\n// Config\nvar CONFIG_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/UpdateAddressBar\"; // Can be \"no\", \"permalink\", \"permaview\"\nvar CONFIG_UPDATE_HISTORY = \"$:/config/Navigation/UpdateHistory\"; // Can be \"yes\" or \"no\"\nvar CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD = \"$:/config/Navigation/Permalinkview/CopyToClipboard\"; // Can be \"yes\" (default) or \"no\"\nvar CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/Permalinkview/UpdateAddressBar\"; // Can be \"yes\" (default) or \"no\"\n\n\n// Links to help, if there is no param\nvar HELP_OPEN_EXTERNAL_WINDOW = \"http://tiddlywiki.com/#WidgetMessage%3A%20tm-open-external-window\";\n\nexports.startup = function() {\n\t// Open startup tiddlers\n\topenStartupTiddlers({\n\t\tdisableHistory: $tw.boot.disableStartupNavigation\n\t});\n\tif($tw.browser) {\n\t\t// Set up location hash update\n\t\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t\tif($tw.utils.hop(changes,DEFAULT_STORY_TITLE) || $tw.utils.hop(changes,DEFAULT_HISTORY_TITLE)) {\n\t\t\t\tupdateLocationHash({\n\t\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_UPDATE_ADDRESS_BAR,\"permaview\").trim(),\n\t\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim()\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t// Listen for changes to the browser location hash\n\t\twindow.addEventListener(\"hashchange\",function() {\n\t\t\tvar hash = $tw.utils.getLocationHash();\n\t\t\tif(hash !== $tw.locationHash) {\n\t\t\t\t$tw.locationHash = hash;\n\t\t\t\topenStartupTiddlers({defaultToCurrentStory: true});\n\t\t\t}\n\t\t},false);\n\t\t// Listen for the tm-browser-refresh message\n\t\t$tw.rootWidget.addEventListener(\"tm-browser-refresh\",function(event) {\n\t\t\twindow.location.reload(true);\n\t\t});\n\t\t// Listen for tm-open-external-window message\n\t\t$tw.rootWidget.addEventListener(\"tm-open-external-window\",function(event) {\n\t\t\tvar paramObject = event.paramObject || {},\n\t\t\t\tstrUrl = event.param || HELP_OPEN_EXTERNAL_WINDOW,\n\t\t\t\tstrWindowName = paramObject.windowName,\n\t\t\t\tstrWindowFeatures = paramObject.windowFeatures;\n\t\t\twindow.open(strUrl, strWindowName, strWindowFeatures);\n\t\t});\n\t\t// Listen for the tm-print message\n\t\t$tw.rootWidget.addEventListener(\"tm-print\",function(event) {\n\t\t\t(event.event.view || window).print();\n\t\t});\n\t\t// Listen for the tm-home message\n\t\t$tw.rootWidget.addEventListener(\"tm-home\",function(event) {\n\t\t\twindow.location.hash = \"\";\n\t\t\tvar storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE),\n\t\t\t\tstoryList = $tw.wiki.filterTiddlers(storyFilter);\n\t\t\t//invoke any hooks that might change the default story list\n\t\t\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t\t\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t\t\tif(storyList[0]) {\n\t\t\t\t$tw.wiki.addToHistory(storyList[0]);\n\t\t\t}\n\t\t});\n\t\t// Listen for the tm-permalink message\n\t\t$tw.rootWidget.addEventListener(\"tm-permalink\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\"\n\t\t\t});\n\t\t});\n\t\t// Listen for the tm-permaview message\n\t\t$tw.rootWidget.addEventListener(\"tm-permaview\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\"\n\t\t\t});\t\t\t\t\n\t\t});\n\t}\n};\n\n/*\nProcess the location hash to open the specified tiddlers. Options:\ndisableHistory: if true $:/History is NOT updated\ndefaultToCurrentStory: If true, the current story is retained as the default, instead of opening the default tiddlers\n*/\nfunction openStartupTiddlers(options) {\n\toptions = options || {};\n\t// Work out the target tiddler and the story filter. \"null\" means \"unspecified\"\n\tvar target = null,\n\t\tstoryFilter = null;\n\tif($tw.locationHash.length > 1) {\n\t\tvar hash = $tw.locationHash.substr(1),\n\t\t\tsplit = hash.indexOf(\":\");\n\t\tif(split === -1) {\n\t\t\ttarget = decodeURIComponent(hash.trim());\n\t\t} else {\n\t\t\ttarget = decodeURIComponent(hash.substr(0,split).trim());\n\t\t\tstoryFilter = decodeURIComponent(hash.substr(split + 1).trim());\n\t\t}\n\t}\n\t// If the story wasn't specified use the current tiddlers or a blank story\n\tif(storyFilter === null) {\n\t\tif(options.defaultToCurrentStory) {\n\t\t\tvar currStoryList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE);\n\t\t\tstoryFilter = $tw.utils.stringifyList(currStoryList);\n\t\t} else {\n\t\t\tif(target && target !== \"\") {\n\t\t\t\tstoryFilter = \"\";\n\t\t\t} else {\n\t\t\t\tstoryFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE);\n\t\t\t}\n\t\t}\n\t}\n\t// Process the story filter to get the story list\n\tvar storyList = $tw.wiki.filterTiddlers(storyFilter);\n\t// Invoke any hooks that want to change the default story list\n\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t// If the target tiddler isn't included then splice it in at the top\n\tif(target && storyList.indexOf(target) === -1) {\n\t\tstoryList.unshift(target);\n\t}\n\t// Save the story list\n\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t// Update history\n\tvar story = new $tw.Story({\n\t\twiki: $tw.wiki,\n\t\tstoryTitle: DEFAULT_STORY_TITLE,\n\t\thistoryTitle: DEFAULT_HISTORY_TITLE\n\t});\n\tif(!options.disableHistory) {\n\t\t// If a target tiddler was specified add it to the history stack\n\t\tif(target && target !== \"\") {\n\t\t\t// The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present\n\t\t\tif(target.indexOf(\"[[\") === 0 && target.substr(-2) === \"]]\") {\n\t\t\t\ttarget = target.substr(2,target.length - 4);\n\t\t\t}\n\t\t\tstory.addToHistory(target);\n\t\t} else if(storyList.length > 0) {\n\t\t\tstory.addToHistory(storyList[0]);\n\t\t}\t\t\n\t}\n}\n\n/*\noptions: See below\noptions.updateAddressBar: \"permalink\", \"permaview\" or \"no\" (defaults to \"permaview\")\noptions.updateHistory: \"yes\" or \"no\" (defaults to \"no\")\noptions.copyToClipboard: \"permalink\", \"permaview\" or \"no\" (defaults to \"no\")\noptions.targetTiddler: optional title of target tiddler for permalink\n*/\nfunction updateLocationHash(options) {\n\t// Get the story and the history stack\n\tvar storyList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE),\n\t\thistoryList = $tw.wiki.getTiddlerData(DEFAULT_HISTORY_TITLE,[]),\n\t\ttargetTiddler = \"\";\n\tif(options.targetTiddler) {\n\t\ttargetTiddler = options.targetTiddler;\n\t} else {\n\t\t// The target tiddler is the one at the top of the stack\n\t\tif(historyList.length > 0) {\n\t\t\ttargetTiddler = historyList[historyList.length-1].title;\n\t\t}\n\t\t// Blank the target tiddler if it isn't present in the story\n\t\tif(storyList.indexOf(targetTiddler) === -1) {\n\t\t\ttargetTiddler = \"\";\n\t\t}\n\t}\n\t// Assemble the location hash\n\tswitch(options.updateAddressBar) {\n\t\tcase \"permalink\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler);\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList));\n\t\t\tbreak;\n\t}\n\t// Copy URL to the clipboard\n\tswitch(options.copyToClipboard) {\n\t\tcase \"permalink\":\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler));\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList)));\n\t\t\tbreak;\n\t}\n\t// Only change the location hash if we must, thus avoiding unnecessary onhashchange events\n\tif($tw.utils.getLocationHash() !== $tw.locationHash) {\n\t\tif(options.updateHistory === \"yes\") {\n\t\t\t// Assign the location hash so that history is updated\n\t\t\twindow.location.hash = $tw.locationHash;\n\t\t} else {\n\t\t\t// We use replace so that browser history isn't affected\n\t\t\twindow.location.replace(window.location.toString().split(\"#\")[0] + $tw.locationHash);\n\t\t}\n\t}\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/windows.js": {
"title": "$:/core/modules/startup/windows.js",
"text": "/*\\\ntitle: $:/core/modules/startup/windows.js\ntype: application/javascript\nmodule-type: startup\n\nSetup root widget handlers for the messages concerned with opening external browser windows\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"windows\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Global to keep track of open windows (hashmap by title)\n$tw.windows = {};\n\nexports.startup = function() {\n\t// Handle open window message\n\t$tw.rootWidget.addEventListener(\"tm-open-window\",function(event) {\n\t\t// Get the parameters\n\t\tvar refreshHandler,\n\t\t\ttitle = event.param || event.tiddlerTitle,\n\t\t\tparamObject = event.paramObject || {},\n\t\t\twindowTitle = paramObject.windowTitle || title,\n\t\t\ttemplate = paramObject.template || \"$:/core/templates/single.tiddler.window\",\n\t\t\twidth = paramObject.width || \"700\",\n\t\t\theight = paramObject.height || \"600\",\n\t\t\tvariables = $tw.utils.extend({},paramObject,{currentTiddler: title});\n\t\t// Open the window\n\t\tvar srcWindow,\n\t\t srcDocument;\n\t\t// In case that popup blockers deny opening a new window\n\t\ttry {\n\t\t\tsrcWindow = window.open(\"\",\"external-\" + title,\"scrollbars,width=\" + width + \",height=\" + height),\n\t\t\tsrcDocument = srcWindow.document;\n\t\t}\n\t\tcatch(e) {\n\t\t\treturn;\n\t\t}\n\t\t$tw.windows[title] = srcWindow;\n\t\t// Check for reopening the same window\n\t\tif(srcWindow.haveInitialisedWindow) {\n\t\t\treturn;\n\t\t}\n\t\t// Initialise the document\n\t\tsrcDocument.write(\"<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>\");\n\t\tsrcDocument.close();\n\t\tsrcDocument.title = windowTitle;\n\t\tsrcWindow.addEventListener(\"beforeunload\",function(event) {\n\t\t\tdelete $tw.windows[title];\n\t\t\t$tw.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t},false);\n\t\t// Set up the styles\n\t\tvar styleWidgetNode = $tw.wiki.makeTranscludeWidget(\"$:/core/ui/PageStylesheet\",{\n\t\t\t\tdocument: $tw.fakeDocument,\n\t\t\t\tvariables: variables,\n\t\t\t\timportPageMacros: true}),\n\t\t\tstyleContainer = $tw.fakeDocument.createElement(\"style\");\n\t\tstyleWidgetNode.render(styleContainer,null);\n\t\tvar styleElement = srcDocument.createElement(\"style\");\n\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\tsrcDocument.head.insertBefore(styleElement,srcDocument.head.firstChild);\n\t\t// Render the text of the tiddler\n\t\tvar parser = $tw.wiki.parseTiddler(template),\n\t\t\twidgetNode = $tw.wiki.makeWidget(parser,{document: srcDocument, parentWidget: $tw.rootWidget, variables: variables});\n\t\twidgetNode.render(srcDocument.body,srcDocument.body.firstChild);\n\t\t// Function to handle refreshes\n\t\trefreshHandler = function(changes) {\n\t\t\tif(styleWidgetNode.refresh(changes,styleContainer,null)) {\n\t\t\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\t\t}\n\t\t\twidgetNode.refresh(changes);\n\t\t};\n\t\t$tw.wiki.addEventListener(\"change\",refreshHandler);\n\t\t// Listen for keyboard shortcuts\n\t\t$tw.utils.addEventListeners(srcDocument,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t}]);\n\t\tsrcWindow.document.documentElement.addEventListener(\"click\",$tw.popup,true);\n\t\tsrcWindow.haveInitialisedWindow = true;\n\t});\n\t// Close open windows when unloading main window\n\t$tw.addUnloadTask(function() {\n\t\t$tw.utils.each($tw.windows,function(win) {\n\t\t\twin.close();\n\t\t});\n\t});\n\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/story.js": {
"title": "$:/core/modules/story.js",
"text": "/*\\\ntitle: $:/core/modules/story.js\ntype: application/javascript\nmodule-type: global\n\nLightweight object for managing interactions with the story and history lists.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nConstruct Story object with options:\nwiki: reference to wiki object to use to resolve tiddler titles\nstoryTitle: title of story list tiddler\nhistoryTitle: title of history list tiddler\n*/\nfunction Story(options) {\n\toptions = options || {};\n\tthis.wiki = options.wiki || $tw.wiki;\n\tthis.storyTitle = options.storyTitle || \"$:/StoryList\";\n\tthis.historyTitle = options.historyTitle || \"$:/HistoryList\";\n};\n\nStory.prototype.navigateTiddler = function(navigateTo,navigateFromTitle,navigateFromClientRect) {\n\tthis.addToStory(navigateTo,navigateFromTitle);\n\tthis.addToHistory(navigateTo,navigateFromClientRect);\n};\n\nStory.prototype.getStoryList = function() {\n\treturn this.wiki.getTiddlerList(this.storyTitle) || [];\n};\n\nStory.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {\n\toptions = options || {};\n\tvar storyList = this.getStoryList();\n\t// See if the tiddler is already there\n\tvar slot = storyList.indexOf(navigateTo);\n\t// Quit if it already exists in the story river\n\tif(slot >= 0) {\n\t\treturn;\n\t}\n\t// First we try to find the position of the story element we navigated from\n\tvar fromIndex = storyList.indexOf(navigateFromTitle);\n\tif(fromIndex >= 0) {\n\t\t// The tiddler is added from inside the river\n\t\t// Determine where to insert the tiddler; Fallback is \"below\"\n\t\tswitch(options.openLinkFromInsideRiver) {\n\t\t\tcase \"top\":\n\t\t\t\tslot = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"bottom\":\n\t\t\t\tslot = storyList.length;\n\t\t\t\tbreak;\n\t\t\tcase \"above\":\n\t\t\t\tslot = fromIndex;\n\t\t\t\tbreak;\n\t\t\tcase \"below\": // Intentional fall-through\n\t\t\tdefault:\n\t\t\t\tslot = fromIndex + 1;\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\t// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is \"top\"\n\t\tif(options.openLinkFromOutsideRiver === \"bottom\") {\n\t\t\t// Insert at bottom\n\t\t\tslot = storyList.length;\n\t\t} else {\n\t\t\t// Insert at top\n\t\t\tslot = 0;\n\t\t}\n\t}\n\t// Add the tiddler\n\tstoryList.splice(slot,0,navigateTo);\n\t// Save the story\n\tthis.saveStoryList(storyList);\n};\n\nStory.prototype.saveStoryList = function(storyList) {\n\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\t{title: this.storyTitle},\n\t\tstoryTiddler,\n\t\t{list: storyList},\n\t\tthis.wiki.getModificationFields()\n\t));\n};\n\nStory.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {\n\tvar titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];\n\t// Add a new record to the top of the history stack\n\tvar historyList = this.wiki.getTiddlerData(this.historyTitle,[]);\n\t$tw.utils.each(titles,function(title) {\n\t\thistoryList.push({title: title, fromPageRect: navigateFromClientRect});\n\t});\n\tthis.wiki.setTiddlerData(this.historyTitle,historyList,{\"current-tiddler\": titles[titles.length-1]});\n};\n\nStory.prototype.storyCloseTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCloseAllTiddlers = function() {\n// TBD\n};\n\nStory.prototype.storyCloseOtherTiddlers = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyEditTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyDeleteTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storySaveTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCancelTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyNewTiddler = function(targetTitle) {\n// TBD\n};\n\nexports.Story = Story;\n\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/storyviews/classic.js": {
"title": "$:/core/modules/storyviews/classic.js",
"text": "/*\\\ntitle: $:/core/modules/storyviews/classic.js\ntype: application/javascript\nmodule-type: storyview\n\nViews the story as a linear sequence\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ClassicStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nClassicStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar duration = $tw.utils.getAnimationDuration()\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\tif(duration) {\n\t\t// Scroll the node into view\n\t\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\t\n\t} else {\n\t\ttargetElement.scrollIntoView();\n\t}\n};\n\nClassicStoryView.prototype.insert = function(widget) {\n\tvar duration = $tw.utils.getAnimationDuration();\n\tif(duration) {\n\t\tvar targetElement = widget.findFirstDomNode();\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!(targetElement instanceof Element)) {\n\t\t\treturn;\n\t\t}\n\t\t// Get the current height of the tiddler\n\t\tvar computedStyle = window.getComputedStyle(targetElement),\n\t\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t\t// Reset the margin once the transition is over\n\t\tsetTimeout(function() {\n\t\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t\t{transition: \"none\"},\n\t\t\t\t{marginBottom: \"\"}\n\t\t\t]);\n\t\t},duration);\n\t\t// Set up the initial position of the element\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t\t{opacity: \"0.0\"}\n\t\t]);\n\t\t$tw.utils.forceLayout(targetElement);\n\t\t// Transition to the final position\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t\t{opacity: \"1.0\"}\n\t]);\n\t}\n};\n\nClassicStoryView.prototype.remove = function(widget) {\n\tvar duration = $tw.utils.getAnimationDuration();\n\tif(duration) {\n\t\tvar targetElement = widget.findFirstDomNode(),\n\t\t\tremoveElement = function() {\n\t\t\t\twidget.removeChildDomNodes();\n\t\t\t};\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!(targetElement instanceof Element)) {\n\t\t\tremoveElement();\n\t\t\treturn;\n\t\t}\n\t\t// Get the current height of the tiddler\n\t\tvar currWidth = targetElement.offsetWidth,\n\t\t\tcomputedStyle = window.getComputedStyle(targetElement),\n\t\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t\t// Remove the dom nodes of the widget at the end of the transition\n\t\tsetTimeout(removeElement,duration);\n\t\t// Animate the closure\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{transform: \"translateX(0px)\"},\n\t\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t\t{opacity: \"1.0\"}\n\t\t]);\n\t\t$tw.utils.forceLayout(targetElement);\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\t\"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t\t{transform: \"translateX(-\" + currWidth + \"px)\"},\n\t\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t\t{opacity: \"0.0\"}\n\t\t]);\n\t} else {\n\t\twidget.removeChildDomNodes();\n\t}\n};\n\nexports.classic = ClassicStoryView;\n\n})();",
"type": "application/javascript",
"module-type": "storyview"
},
"$:/core/modules/storyviews/pop.js": {
"title": "$:/core/modules/storyviews/pop.js",
"text": "/*\\\ntitle: $:/core/modules/storyviews/pop.js\ntype: application/javascript\nmodule-type: storyview\n\nAnimates list insertions and removals\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar PopStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nPopStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nPopStoryView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Reset once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{transform: \"none\"}\n\t\t]);\n\t\t$tw.utils.setStyle(widget.document.body,[\n\t\t\t{\"overflow-x\": \"\"}\n\t\t]);\n\t},duration);\n\t// Prevent the page from overscrolling due to the zoom factor\n\t$tw.utils.setStyle(widget.document.body,[\n\t\t{\"overflow-x\": \"hidden\"}\n\t]);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(2)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t// Transition to the final position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n};\n\nPopStoryView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\tif(targetElement && targetElement.parentNode) {\n\t\t\t\twidget.removeChildDomNodes();\n\t\t\t}\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Remove the element at the end of the transition\n\tsetTimeout(removeElement,duration);\n\t// Animate the closure\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(0.1)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n};\n\nexports.pop = PopStoryView;\n\n})();\n",
"type": "application/javascript",
"module-type": "storyview"
},
"$:/core/modules/storyviews/zoomin.js": {
"title": "$:/core/modules/storyviews/zoomin.js",
"text": "/*\\\ntitle: $:/core/modules/storyviews/zoomin.js\ntype: application/javascript\nmodule-type: storyview\n\nZooms between individual tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ZoominListView = function(listWidget) {\n\tvar self = this;\n\tthis.listWidget = listWidget;\n\t// Get the index of the tiddler that is at the top of the history\n\tvar history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),\n\t\ttargetTiddler;\n\tif(history.length > 0) {\n\t\ttargetTiddler = history[history.length-1].title;\n\t}\n\t// Make all the tiddlers position absolute, and hide all but the top (or first) one\n\t$tw.utils.each(this.listWidget.children,function(itemWidget,index) {\n\t\tvar domNode = itemWidget.findFirstDomNode();\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!(domNode instanceof Element)) {\n\t\t\treturn;\n\t\t}\n\t\tif((targetTiddler && targetTiddler !== itemWidget.parseTreeNode.itemTitle) || (!targetTiddler && index)) {\n\t\t\tdomNode.style.display = \"none\";\n\t\t} else {\n\t\t\tself.currentTiddlerDomNode = domNode;\n\t\t}\n\t\t$tw.utils.addClass(domNode,\"tc-storyview-zoomin-tiddler\");\n\t});\n};\n\nZoominListView.prototype.navigateTo = function(historyInfo) {\n\tvar duration = $tw.utils.getAnimationDuration(),\n\t\tlistElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Make the new tiddler be position absolute and visible so that we can measure it\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"0 0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t// Get the position of the source node, or use the centre of the window as the source position\n\tvar sourceBounds = historyInfo.fromPageRect || {\n\t\t\tleft: window.innerWidth/2 - 2,\n\t\t\ttop: window.innerHeight/2 - 2,\n\t\t\twidth: window.innerWidth/8,\n\t\t\theight: window.innerHeight/8\n\t\t};\n\t// Try to find the title node in the target tiddler\n\tvar titleDomNode = findTitleDomNode(listItemWidget) || listItemWidget.findFirstDomNode(),\n\t\tzoomBounds = titleDomNode.getBoundingClientRect();\n\t// Compute the transform for the target tiddler to make the title lie over the source rectange\n\tvar targetBounds = targetElement.getBoundingClientRect(),\n\t\tscale = sourceBounds.width / zoomBounds.width,\n\t\tx = sourceBounds.left - targetBounds.left - (zoomBounds.left - targetBounds.left) * scale,\n\t\ty = sourceBounds.top - targetBounds.top - (zoomBounds.top - targetBounds.top) * scale;\n\t// Transform the target tiddler to its starting position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(targetElement);\n\t// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first\n\tvar self = this,\n\t\tprevCurrentTiddler = this.currentTiddlerDomNode;\n\tthis.currentTiddlerDomNode = targetElement;\n\t// Transform the target tiddler to its natural size\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{zIndex: \"500\"},\n\t]);\n\t// Transform the previous tiddler out of the way and then hide it\n\tif(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {\n\t\tscale = zoomBounds.width / sourceBounds.width;\n\t\tx = zoomBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;\n\t\ty = zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;\n\t\t$tw.utils.setStyle(prevCurrentTiddler,[\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transformOrigin: \"0 0\"},\n\t\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"},\n\t\t\t{zIndex: \"0\"}\n\t\t]);\n\t\t// Hide the tiddler when the transition has finished\n\t\tsetTimeout(function() {\n\t\t\tif(self.currentTiddlerDomNode !== prevCurrentTiddler) {\n\t\t\t\tprevCurrentTiddler.style.display = \"none\";\n\t\t\t}\n\t\t},duration);\n\t}\n\t// Scroll the target into view\n//\t$tw.pageScroller.scrollIntoView(targetElement);\n};\n\n/*\nFind the first child DOM node of a widget that has the class \"tc-title\"\n*/\nfunction findTitleDomNode(widget,targetClass) {\n\ttargetClass = targetClass || \"tc-title\";\n\tvar domNode = widget.findFirstDomNode();\n\tif(domNode && domNode.querySelector) {\n\t\treturn domNode.querySelector(\".\" + targetClass);\n\t}\n\treturn null;\n}\n\nZoominListView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Make the newly inserted node position absolute and hidden\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"none\"}\n\t]);\n};\n\nZoominListView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\twidget.removeChildDomNodes();\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Abandon if hidden\n\tif(targetElement.style.display != \"block\" ) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Set up the tiddler that is being closed\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\t// We'll move back to the previous or next element in the story\n\tvar toWidget = widget.previousSibling();\n\tif(!toWidget) {\n\t\ttoWidget = widget.nextSibling();\n\t}\n\tvar toWidgetDomNode = toWidget && toWidget.findFirstDomNode();\n\t// Set up the tiddler we're moving back in\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.addClass(toWidgetDomNode,\"tc-storyview-zoomin-tiddler\");\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{display: \"block\"},\n\t\t\t{transformOrigin: \"50% 50%\"},\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(10)\"},\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0\"},\n\t\t\t{zIndex: \"500\"}\n\t\t]);\n\t\tthis.currentTiddlerDomNode = toWidgetDomNode;\n\t}\n\t// Animate them both\n\t// Force layout\n\t$tw.utils.forceLayout(this.listWidget.parentDomNode);\n\t// First, the tiddler we're closing\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(0.1)\"},\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"0\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\tsetTimeout(removeElement,duration);\n\t// Now the tiddler we're going back to\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t\t{opacity: \"1\"}\n\t\t]);\n\t}\n\treturn true; // Indicate that we'll delete the DOM node\n};\n\nexports.zoomin = ZoominListView;\n\n})();\n",
"type": "application/javascript",
"module-type": "storyview"
},
"$:/core/modules/syncer.js": {
"title": "$:/core/modules/syncer.js",
"text": "/*\\\ntitle: $:/core/modules/syncer.js\ntype: application/javascript\nmodule-type: global\n\nThe syncer tracks changes to the store and synchronises them to a remote data store represented as a \"sync adaptor\"\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDefaults\n*/\nSyncer.prototype.titleIsLoggedIn = \"$:/status/IsLoggedIn\";\nSyncer.prototype.titleIsAnonymous = \"$:/status/IsAnonymous\";\nSyncer.prototype.titleIsReadOnly = \"$:/status/IsReadOnly\";\nSyncer.prototype.titleUserName = \"$:/status/UserName\";\nSyncer.prototype.titleSyncFilter = \"$:/config/SyncFilter\";\nSyncer.prototype.titleSyncPollingInterval = \"$:/config/SyncPollingInterval\";\nSyncer.prototype.titleSyncDisableLazyLoading = \"$:/config/SyncDisableLazyLoading\";\nSyncer.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\nSyncer.prototype.titleSyncThrottleInterval = \"$:/config/SyncThrottleInterval\";\nSyncer.prototype.taskTimerInterval = 1 * 1000; // Interval for sync timer\nSyncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...\nSyncer.prototype.errorRetryInterval = 5 * 1000; // Interval to retry after an error\nSyncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s\nSyncer.prototype.pollTimerInterval = 60 * 1000; // Interval for polling for changes from the adaptor\n\n/*\nInstantiate the syncer with the following options:\nsyncadaptor: reference to syncadaptor to be used\nwiki: wiki to be synced\n*/\nfunction Syncer(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\t// Save parameters\n\tthis.syncadaptor = options.syncadaptor;\n\tthis.disableUI = !!options.disableUI;\n\tthis.titleIsLoggedIn = options.titleIsLoggedIn || this.titleIsLoggedIn;\n\tthis.titleUserName = options.titleUserName || this.titleUserName;\n\tthis.titleSyncFilter = options.titleSyncFilter || this.titleSyncFilter;\n\tthis.titleSavedNotification = options.titleSavedNotification || this.titleSavedNotification;\n\tthis.taskTimerInterval = options.taskTimerInterval || this.taskTimerInterval;\n\tthis.throttleInterval = options.throttleInterval || parseInt(this.wiki.getTiddlerText(this.titleSyncThrottleInterval,\"\"),10) || this.throttleInterval;\n\tthis.errorRetryInterval = options.errorRetryInterval || this.errorRetryInterval;\n\tthis.fallbackInterval = options.fallbackInterval || this.fallbackInterval;\n\tthis.pollTimerInterval = options.pollTimerInterval || parseInt(this.wiki.getTiddlerText(this.titleSyncPollingInterval,\"\"),10) || this.pollTimerInterval;\n\tthis.logging = \"logging\" in options ? options.logging : true;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"syncer\" + ($tw.browser ? \"-browser\" : \"\") + ($tw.node ? \"-server\" : \"\") + (this.syncadaptor.name ? (\"-\" + this.syncadaptor.name) : \"\"),{\n\t\tcolour: \"cyan\",\n\t\tenable: this.logging,\n\t\tsaveHistory: true\n\t});\n\t// Make another logger for connection errors\n\tthis.loggerConnection = new $tw.utils.Logger(\"syncer\" + ($tw.browser ? \"-browser\" : \"\") + ($tw.node ? \"-server\" : \"\") + (this.syncadaptor.name ? (\"-\" + this.syncadaptor.name) : \"\") + \"-connection\",{\n\t\tcolour: \"cyan\",\n\t\tenable: this.logging\n\t});\n\t// Ask the syncadaptor to use the main logger\n\tif(this.syncadaptor.setLoggerSaveBuffer) {\n\t\tthis.syncadaptor.setLoggerSaveBuffer(this.logger);\n\t}\n\t// Compile the dirty tiddler filter\n\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t// Record information for known tiddlers\n\tthis.readTiddlerInfo();\n\tthis.titlesToBeLoaded = {}; // Hashmap of titles of tiddlers that need loading from the server\n\tthis.titlesHaveBeenLazyLoaded = {}; // Hashmap of titles of tiddlers that have already been lazily loaded from the server\n\t// Timers\n\tthis.taskTimerId = null; // Timer for task dispatch\n\tthis.pollTimerId = null; // Timer for polling server\n\t// Number of outstanding requests\n\tthis.numTasksInProgress = 0;\n\t// Listen out for changes to tiddlers\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\t// Filter the changes to just include ones that are being synced\n\t\tvar filteredChanges = self.getSyncedTiddlers(function(callback) {\n\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\tvar tiddler = self.wiki.tiddlerExists(title) && self.wiki.getTiddler(title);\n\t\t\t\tcallback(tiddler,title);\n\t\t\t});\n\t\t});\n\t\tif(filteredChanges.length > 0) {\n\t\t\tself.processTaskQueue();\n\t\t} else {\n\t\t\t// Look for deletions of tiddlers we're already syncing\t\n\t\t\tvar outstandingDeletion = false\n\t\t\t$tw.utils.each(changes,function(change,title,object) {\n\t\t\t\tif(change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) {\n\t\t\t\t\toutstandingDeletion = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(outstandingDeletion) {\n\t\t\t\tself.processTaskQueue();\n\t\t\t}\n\t\t}\n\t});\n\t// Browser event handlers\n\tif($tw.browser && !this.disableUI) {\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t\t// Listen out for login/logout/refresh events in the browser\n\t\t$tw.rootWidget.addEventListener(\"tm-login\",function(event) {\n\t\t\tvar username = event && event.paramObject && event.paramObject.username,\n\t\t\t\tpassword = event && event.paramObject && event.paramObject.password;\n\t\t\tif(username && password) {\n\t\t\t\t// Login with username and password\n\t\t\t\tself.login(username,password,function() {});\n\t\t\t} else {\n\t\t\t\t// No username and password, so we display a prompt\n\t\t\t\tself.handleLoginEvent();\t\t\t\t\n\t\t\t}\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-logout\",function() {\n\t\t\tself.handleLogoutEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-server-refresh\",function() {\n\t\t\tself.handleRefreshEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-copy-syncer-logs-to-clipboard\",function() {\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getSystemInfo() + \"\\n\\nLog:\\n\" + self.logger.getBuffer());\n\t\t});\n\t}\n\t// Listen out for lazyLoad events\n\tif(!this.disableUI && this.wiki.getTiddlerText(this.titleSyncDisableLazyLoading) !== \"yes\") {\n\t\tthis.wiki.addEventListener(\"lazyLoad\",function(title) {\n\t\t\tself.handleLazyLoadEvent(title);\n\t\t});\t\t\n\t}\n\t// Get the login status\n\tthis.getStatus(function(err,isLoggedIn) {\n\t\t// Do a sync from the server\n\t\tself.syncFromServer();\n\t});\n}\n\n/*\nShow a generic network error alert\n*/\nSyncer.prototype.displayError = function(msg,err) {\n\tif(err === ($tw.language.getString(\"Error/XMLHttpRequest\") + \": 0\")) {\n\t\tthis.loggerConnection.alert($tw.language.getString(\"Error/NetworkErrorAlert\"));\n\t\tthis.logger.log(msg + \":\",err);\n\t} else {\n\t\tthis.logger.alert(msg + \":\",err);\n\t}\n};\n\n/*\nReturn an array of the tiddler titles that are subjected to syncing\n*/\nSyncer.prototype.getSyncedTiddlers = function(source) {\n\treturn this.filterFn.call(this.wiki,source);\n};\n\n/*\nReturn an array of the tiddler titles that are subjected to syncing\n*/\nSyncer.prototype.getTiddlerRevision = function(title) {\n\tif(this.syncadaptor && this.syncadaptor.getTiddlerRevision) {\n\t\treturn this.syncadaptor.getTiddlerRevision(title);\n\t} else {\n\t\treturn this.wiki.getTiddler(title).fields.revision;\t\n\t} \n};\n\n/*\nRead (or re-read) the latest tiddler info from the store\n*/\nSyncer.prototype.readTiddlerInfo = function() {\n\t// Hashmap by title of {revision:,changeCount:,adaptorInfo:}\n\t// \"revision\" is the revision of the tiddler last seen on the server, and \"changecount\" is the corresponding local changecount\n\tthis.tiddlerInfo = {};\n\t// Record information for known tiddlers\n\tvar self = this,\n\t\ttiddlers = this.getSyncedTiddlers();\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tif(tiddler) {\n\t\t\tself.tiddlerInfo[title] = {\n\t\t\t\trevision: self.getTiddlerRevision(title),\n\t\t\t\tadaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),\n\t\t\t\tchangeCount: self.wiki.getChangeCount(title)\n\t\t\t};\n\t\t}\n\t});\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSyncer.prototype.isDirty = function() {\n\tthis.logger.log(\"Checking dirty status\");\n\t// Check tiddlers that are in the store and included in the filter function\n\tvar titles = this.getSyncedTiddlers();\n\tfor(var index=0; index<titles.length; index++) {\n\t\tvar title = titles[index],\n\t\t\ttiddlerInfo = this.tiddlerInfo[title];\n\t\tif(this.wiki.tiddlerExists(title)) {\n\t\t\tif(tiddlerInfo) {\n\t\t\t\t// If the tiddler is known on the server and has been modified locally then it needs to be saved to the server\n\t\t\t\tif(this.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If the tiddler isn't known on the server then it needs to be saved to the server\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\t// Check tiddlers that are known from the server but not currently in the store\n\ttitles = Object.keys(this.tiddlerInfo);\n\tfor(index=0; index<titles.length; index++) {\n\t\tif(!this.wiki.tiddlerExists(titles[index])) {\n\t\t\t// There must be a pending delete\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSyncer.prototype.updateDirtyStatus = function() {\n\tif($tw.browser && !this.disableUI) {\n\t\tvar dirty = this.isDirty();\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",dirty);\n\t\tif(!dirty) {\n\t\t\tthis.loggerConnection.clearAlerts();\n\t\t}\n\t}\n};\n\n/*\nSave an incoming tiddler in the store, and updates the associated tiddlerInfo\n*/\nSyncer.prototype.storeTiddler = function(tiddlerFields) {\n\t// Save the tiddler\n\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\tthis.wiki.addTiddler(tiddler);\n\t// Save the tiddler revision and changeCount details\n\tthis.tiddlerInfo[tiddlerFields.title] = {\n\t\trevision: this.getTiddlerRevision(tiddlerFields.title),\n\t\tadaptorInfo: this.syncadaptor.getTiddlerInfo(tiddler),\n\t\tchangeCount: this.wiki.getChangeCount(tiddlerFields.title)\n\t};\n};\n\nSyncer.prototype.getStatus = function(callback) {\n\tvar self = this;\n\t// Check if the adaptor supports getStatus()\n\tif(this.syncadaptor && this.syncadaptor.getStatus) {\n\t\t// Mark us as not logged in\n\t\tthis.wiki.addTiddler({title: this.titleIsLoggedIn,text: \"no\"});\n\t\t// Get login status\n\t\tthis.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous) {\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert(err);\n\t\t\t} else {\n\t\t\t\t// Set the various status tiddlers\n\t\t\t\tself.wiki.addTiddler({title: self.titleIsReadOnly,text: isReadOnly ? \"yes\" : \"no\"});\n\t\t\t\tself.wiki.addTiddler({title: self.titleIsAnonymous,text: isAnonymous ? \"yes\" : \"no\"});\n\t\t\t\tself.wiki.addTiddler({title: self.titleIsLoggedIn,text: isLoggedIn ? \"yes\" : \"no\"});\n\t\t\t\tif(isLoggedIn) {\n\t\t\t\t\tself.wiki.addTiddler({title: self.titleUserName,text: username || \"\"});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Invoke the callback\n\t\t\tif(callback) {\n\t\t\t\tcallback(err,isLoggedIn,username);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tcallback(null,true,\"UNAUTHENTICATED\");\n\t}\n};\n\n/*\nSynchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date\n*/\nSyncer.prototype.syncFromServer = function() {\n\tvar self = this,\n\t\tcancelNextSync = function() {\n\t\t\tif(self.pollTimerId) {\n\t\t\t\tclearTimeout(self.pollTimerId);\n\t\t\t\tself.pollTimerId = null;\n\t\t\t}\n\t\t},\n\t\ttriggerNextSync = function() {\n\t\t\tself.pollTimerId = setTimeout(function() {\n\t\t\t\tself.pollTimerId = null;\n\t\t\t\tself.syncFromServer.call(self);\n\t\t\t},self.pollTimerInterval);\n\t\t},\n\t\tsyncSystemFromServer = (self.wiki.getTiddlerText(\"$:/config/SyncSystemTiddlersFromServer\") === \"yes\" ? true : false);\n\tif(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) {\n\t\tthis.logger.log(\"Retrieving updated tiddler list\");\n\t\tcancelNextSync();\n\t\tthis.syncadaptor.getUpdatedTiddlers(self,function(err,updates) {\n\t\t\ttriggerNextSync();\n\t\t\tif(err) {\n\t\t\t\tself.displayError($tw.language.getString(\"Error/RetrievingSkinny\"),err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(updates) {\n\t\t\t\t$tw.utils.each(updates.modifications,function(title) {\n\t\t\t\t\tself.titlesToBeLoaded[title] = true;\n\t\t\t\t});\n\t\t\t\t$tw.utils.each(updates.deletions,function(title) {\n\t\t\t\t\tif(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {\n\t\t\t\t\t\tdelete self.tiddlerInfo[title];\n\t\t\t\t\t\tself.logger.log(\"Deleting tiddler missing from server:\",title);\n\t\t\t\t\t\tself.wiki.deleteTiddler(title);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif(updates.modifications.length > 0 || updates.deletions.length > 0) {\n\t\t\t\t\tself.processTaskQueue();\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t});\n\t} else if(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {\n\t\tthis.logger.log(\"Retrieving skinny tiddler list\");\n\t\tcancelNextSync();\n\t\tthis.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {\n\t\t\ttriggerNextSync();\n\t\t\t// Check for errors\n\t\t\tif(err) {\n\t\t\t\tself.displayError($tw.language.getString(\"Error/RetrievingSkinny\"),err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Keep track of which tiddlers we already know about have been reported this time\n\t\t\tvar previousTitles = Object.keys(self.tiddlerInfo);\n\t\t\t// Process each incoming tiddler\n\t\t\tfor(var t=0; t<tiddlers.length; t++) {\n\t\t\t\t// Get the incoming tiddler fields, and the existing tiddler\n\t\t\t\tvar tiddlerFields = tiddlers[t],\n\t\t\t\t\tincomingRevision = tiddlerFields.revision + \"\",\n\t\t\t\t\ttiddler = self.wiki.tiddlerExists(tiddlerFields.title) && self.wiki.getTiddler(tiddlerFields.title),\n\t\t\t\t\ttiddlerInfo = self.tiddlerInfo[tiddlerFields.title],\n\t\t\t\t\tcurrRevision = tiddlerInfo ? tiddlerInfo.revision : null,\n\t\t\t\t\tindexInPreviousTitles = previousTitles.indexOf(tiddlerFields.title);\n\t\t\t\tif(indexInPreviousTitles !== -1) {\n\t\t\t\t\tpreviousTitles.splice(indexInPreviousTitles,1);\n\t\t\t\t}\n\t\t\t\t// Ignore the incoming tiddler if it's the same as the revision we've already got\n\t\t\t\tif(currRevision !== incomingRevision) {\n\t\t\t\t\t// Only load the skinny version if we don't already have a fat version of the tiddler\n\t\t\t\t\tif(!tiddler || tiddler.fields.text === undefined) {\n\t\t\t\t\t\tself.storeTiddler(tiddlerFields);\n\t\t\t\t\t}\n\t\t\t\t\t// Do a full load of this tiddler\n\t\t\t\t\tself.titlesToBeLoaded[tiddlerFields.title] = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Delete any tiddlers that were previously reported but missing this time\n\t\t\t$tw.utils.each(previousTitles,function(title) {\n\t\t\t\tif(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {\n\t\t\t\t\tdelete self.tiddlerInfo[title];\n\t\t\t\t\tself.logger.log(\"Deleting tiddler missing from server:\",title);\n\t\t\t\t\tself.wiki.deleteTiddler(title);\n\t\t\t\t}\n\t\t\t});\n\t\t\tself.processTaskQueue();\n\t\t});\n\t}\n};\n\n/*\nForce load a tiddler from the server\n*/\nSyncer.prototype.enqueueLoadTiddler = function(title) {\n\tthis.titlesToBeLoaded[title] = true;\n\tthis.processTaskQueue();\n};\n\n/*\nLazily load a skinny tiddler if we can\n*/\nSyncer.prototype.handleLazyLoadEvent = function(title) {\n\t// Ignore if the syncadaptor doesn't handle it\n\tif(!this.syncadaptor.supportsLazyLoading) {\n\t\treturn;\n\t}\n\t// Don't lazy load the same tiddler twice\n\tif(!this.titlesHaveBeenLazyLoaded[title]) {\n\t\t// Don't lazy load if the tiddler isn't included in the sync filter\n\t\tif(this.getSyncedTiddlers().indexOf(title) !== -1) {\n\t\t\t// Mark the tiddler as needing loading, and having already been lazily loaded\n\t\t\tthis.titlesToBeLoaded[title] = true;\n\t\t\tthis.titlesHaveBeenLazyLoaded[title] = true;\n\t\t}\n\t}\n};\n\n/*\nDispay a password prompt and allow the user to login\n*/\nSyncer.prototype.handleLoginEvent = function() {\n\tvar self = this;\n\tthis.getStatus(function(err,isLoggedIn,username) {\n\t\tif(!err && !isLoggedIn) {\n\t\t\tif(self.syncadaptor && self.syncadaptor.displayLoginPrompt) {\n\t\t\t\tself.syncadaptor.displayLoginPrompt(self);\n\t\t\t} else {\n\t\t\t\tself.displayLoginPrompt();\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nDispay a password prompt\n*/\nSyncer.prototype.displayLoginPrompt = function() {\n\tvar self = this;\n\tvar promptInfo = $tw.passwordPrompt.createPrompt({\n\t\tserviceName: $tw.language.getString(\"LoginToTiddlySpace\"),\n\t\tcallback: function(data) {\n\t\t\tself.login(data.username,data.password,function(err,isLoggedIn) {\n\t\t\t\tself.syncFromServer();\n\t\t\t});\n\t\t\treturn true; // Get rid of the password prompt\n\t\t}\n\t});\n};\n\n/*\nAttempt to login to TiddlyWeb.\n\tusername: username\n\tpassword: password\n\tcallback: invoked with arguments (err,isLoggedIn)\n*/\nSyncer.prototype.login = function(username,password,callback) {\n\tthis.logger.log(\"Attempting to login as\",username);\n\tvar self = this;\n\tif(this.syncadaptor.login) {\n\t\tthis.syncadaptor.login(username,password,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.getStatus(function(err,isLoggedIn,username) {\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback(err,isLoggedIn);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else {\n\t\tcallback(null,true);\n\t}\n};\n\n/*\nAttempt to log out of TiddlyWeb\n*/\nSyncer.prototype.handleLogoutEvent = function() {\n\tthis.logger.log(\"Attempting to logout\");\n\tvar self = this;\n\tif(this.syncadaptor.logout) {\n\t\tthis.syncadaptor.logout(function(err) {\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert(err);\n\t\t\t} else {\n\t\t\t\tself.getStatus();\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nImmediately refresh from the server\n*/\nSyncer.prototype.handleRefreshEvent = function() {\n\tthis.syncFromServer();\n};\n\n/*\nProcess the next task\n*/\nSyncer.prototype.processTaskQueue = function() {\n\tvar self = this;\n\t// Only process a task if the sync adaptor is fully initialised and we're not already performing\n\t// a task. If we are already performing a task then we'll dispatch the next one when it completes\n\tif((!this.syncadaptor.isReady || this.syncadaptor.isReady()) && this.numTasksInProgress === 0) {\n\t\t// Choose the next task to perform\n\t\tvar task = this.chooseNextTask();\n\t\t// Perform the task if we had one\n\t\tif(typeof task === \"object\" && task !== null) {\n\t\t\tthis.numTasksInProgress += 1;\n\t\t\ttask.run(function(err) {\n\t\t\t\tself.numTasksInProgress -= 1;\n\t\t\t\tif(err) {\n\t\t\t\t\tself.displayError(\"Sync error while processing \" + task.type + \" of '\" + task.title + \"'\",err);\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t\tself.triggerTimeout(self.errorRetryInterval);\n\t\t\t\t} else {\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t\t// Process the next task\n\t\t\t\t\tself.processTaskQueue.call(self);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// No task is ready so update the status\n\t\t\tthis.updateDirtyStatus();\n\t\t\t// And trigger a timeout if there is a pending task\n\t\t\tif(task === true) {\n\t\t\t\tthis.triggerTimeout();\t\t\t\t\n\t\t\t}\n\t\t}\n\t} else {\n\t\tthis.updateDirtyStatus();\t\t\n\t}\n};\n\nSyncer.prototype.triggerTimeout = function(interval) {\n\tvar self = this;\n\tif(!this.taskTimerId) {\n\t\tthis.taskTimerId = setTimeout(function() {\n\t\t\tself.taskTimerId = null;\n\t\t\tself.processTaskQueue.call(self);\n\t\t},interval || self.taskTimerInterval);\n\t}\n};\n\n/*\nChoose the next sync task. We prioritise saves, then deletes, then loads from the server\n\nReturns either a task object, null if there's no upcoming tasks, or the boolean true if there are pending tasks that aren't yet due\n*/\nSyncer.prototype.chooseNextTask = function() {\n\tvar thresholdLastSaved = (new Date()) - this.throttleInterval,\n\t\thavePending = null;\n\t// First we look for tiddlers that have been modified locally and need saving back to the server\n\tvar titles = this.getSyncedTiddlers();\n\tfor(var index=0; index<titles.length; index++) {\n\t\tvar title = titles[index],\n\t\t\ttiddler = this.wiki.tiddlerExists(title) && this.wiki.getTiddler(title),\n\t\t\ttiddlerInfo = this.tiddlerInfo[title];\n\t\tif(tiddler) {\n\t\t\t// If the tiddler is not known on the server, or has been modified locally no more recently than the threshold then it needs to be saved to the server\n\t\t\tvar hasChanged = !tiddlerInfo || this.wiki.getChangeCount(title) > tiddlerInfo.changeCount,\n\t\t\t\tisReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;\n\t\t\tif(hasChanged) {\n\t\t\t\tif(isReadyToSave) {\n\t\t\t\t\treturn new SaveTiddlerTask(this,title); \t\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\thavePending = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Second, we check tiddlers that are known from the server but not currently in the store, and so need deleting on the server\n\ttitles = Object.keys(this.tiddlerInfo);\n\tfor(index=0; index<titles.length; index++) {\n\t\ttitle = titles[index];\n\t\ttiddlerInfo = this.tiddlerInfo[title];\n\t\ttiddler = this.wiki.tiddlerExists(title) && this.wiki.getTiddler(title);\n\t\tif(!tiddler) {\n\t\t\treturn new DeleteTiddlerTask(this,title);\n\t\t}\n\t}\n\t// Check for tiddlers that need loading\n\ttitle = Object.keys(this.titlesToBeLoaded)[0];\n\tif(title) {\n\t\tdelete this.titlesToBeLoaded[title];\n\t\treturn new LoadTiddlerTask(this,title);\n\t}\n\t// No tasks are ready\n\treturn havePending;\n};\n\nfunction SaveTiddlerTask(syncer,title) {\n\tthis.syncer = syncer;\n\tthis.title = title;\n\tthis.type = \"save\";\n}\n\nSaveTiddlerTask.prototype.run = function(callback) {\n\tvar self = this,\n\t\tchangeCount = this.syncer.wiki.getChangeCount(this.title),\n\t\ttiddler = this.syncer.wiki.tiddlerExists(this.title) && this.syncer.wiki.getTiddler(this.title);\n\tthis.syncer.logger.log(\"Dispatching 'save' task:\",this.title);\n\tif(tiddler) {\n\t\tthis.syncer.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {\n\t\t\t// If there's an error, exit without changing any internal state\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\t// Adjust the info stored about this tiddler\n\t\t\tself.syncer.tiddlerInfo[self.title] = {\n\t\t\t\tchangeCount: changeCount,\n\t\t\t\tadaptorInfo: adaptorInfo,\n\t\t\t\trevision: revision,\n\t\t\t\ttimestampLastSaved: new Date()\n\t\t\t};\n\t\t\t// Invoke the callback\n\t\t\tcallback(null);\n\t\t},{\n\t\t\ttiddlerInfo: self.syncer.tiddlerInfo[self.title]\n\t\t});\n\t} else {\n\t\tthis.syncer.logger.log(\" Not Dispatching 'save' task:\",this.title,\"tiddler does not exist\");\n\t\t$tw.utils.nextTick(callback(null));\n\t}\n};\n\nfunction DeleteTiddlerTask(syncer,title) {\n\tthis.syncer = syncer;\n\tthis.title = title;\n\tthis.type = \"delete\";\n}\n\nDeleteTiddlerTask.prototype.run = function(callback) {\n\tvar self = this;\n\tthis.syncer.logger.log(\"Dispatching 'delete' task:\",this.title);\n\tthis.syncer.syncadaptor.deleteTiddler(this.title,function(err) {\n\t\t// If there's an error, exit without changing any internal state\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\t// Remove the info stored about this tiddler\n\t\tdelete self.syncer.tiddlerInfo[self.title];\n\t\tif($tw.boot.files){\n\t\t\t// Remove the tiddler from $tw.boot.files\n\t\t\tdelete $tw.boot.files[self.title];\n\t\t}\n\t\t// Invoke the callback\n\t\tcallback(null);\n\t},{\n\t\ttiddlerInfo: self.syncer.tiddlerInfo[this.title]\n\t});\n};\n\nfunction LoadTiddlerTask(syncer,title) {\n\tthis.syncer = syncer;\n\tthis.title = title;\n\tthis.type = \"load\";\n}\n\nLoadTiddlerTask.prototype.run = function(callback) {\n\tvar self = this;\n\tthis.syncer.logger.log(\"Dispatching 'load' task:\",this.title);\n\tthis.syncer.syncadaptor.loadTiddler(this.title,function(err,tiddlerFields) {\n\t\t// If there's an error, exit without changing any internal state\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\t// Update the info stored about this tiddler\n\t\tif(tiddlerFields) {\n\t\t\tself.syncer.storeTiddler(tiddlerFields);\n\t\t}\n\t\t// Invoke the callback\n\t\tcallback(null);\n\t});\n};\n\nexports.Syncer = Syncer;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/tiddler.js": {
"title": "$:/core/modules/tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/tiddler.js\ntype: application/javascript\nmodule-type: tiddlermethod\n\nExtension methods for the $tw.Tiddler object (constructor and methods required at boot time are in boot/boot.js)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.hasTag = function(tag) {\n\treturn this.fields.tags && this.fields.tags.indexOf(tag) !== -1;\n};\n\nexports.isPlugin = function() {\n\treturn this.fields.type === \"application/json\" && this.hasField(\"plugin-type\");\n};\n\nexports.isDraft = function() {\n\treturn this.hasField(\"draft.of\");\n};\n\nexports.getFieldString = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn \"\";\n\t}\n\t// Parse the field with the associated module (if any)\n\tvar fieldModule = $tw.Tiddler.fieldModules[field];\n\tif(fieldModule && fieldModule.stringify) {\n\t\treturn fieldModule.stringify.call(this,value);\n\t} else {\n\t\treturn value.toString();\n\t}\n};\n\n/*\nGet the value of a field as a list\n*/\nexports.getFieldList = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn [];\n\t}\n\treturn $tw.utils.parseStringArray(value);\n};\n\n/*\nGet all the fields as a hashmap of strings. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStrings = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [];\n\tvar fields = {};\n\tfor(var field in this.fields) {\n\t\tif($tw.utils.hop(this.fields,field)) {\n\t\t\tif(exclude.indexOf(field) === -1) {\n\t\t\t\tfields[field] = this.getFieldString(field);\n\t\t\t}\n\t\t}\n\t}\n\treturn fields;\n};\n\n/*\nGet all the fields as a name:value block. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStringBlock = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [],\n\t\tfields = Object.keys(this.fields).sort(),\n\t\tresult = [];\n\tfor(var t=0; t<fields.length; t++) {\n\t\tvar field = fields[t];\n\t\tif(exclude.indexOf(field) === -1) {\n\t\t\tresult.push(field + \": \" + this.getFieldString(field));\n\t\t}\n\t}\n\treturn result.join(\"\\n\");\n};\n\nexports.getFieldDay = function(field) {\n\tif(this.cache && this.cache.day && $tw.utils.hop(this.cache.day,field) ) {\n\t\treturn this.cache.day[field];\n\t}\n\tvar day = \"\";\n\tif(this.fields[field]) {\n\t\tday = (new Date($tw.utils.parseDate(this.fields[field]))).setHours(0,0,0,0);\n\t}\n\tthis.cache.day = this.cache.day || {};\n\tthis.cache.day[field] = day;\n\treturn day;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "tiddlermethod"
},
"$:/core/modules/upgraders/plugins.js": {
"title": "$:/core/modules/upgraders/plugins.js",
"text": "/*\\\ntitle: $:/core/modules/upgraders/plugins.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that checks that plugins are newer than any already installed version\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar BLOCKED_PLUGINS = {\n\t\"$:/themes/tiddlywiki/stickytitles\": {\n\t\tversions: [\"*\"]\n\t},\n\t\"$:/plugins/tiddlywiki/fullscreen\": {\n\t\tversions: [\"*\"]\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {},\n\t\tupgradeLibrary,\n\t\tgetLibraryTiddler = function(title) {\n\t\t\tif(!upgradeLibrary) {\n\t\t\t\tupgradeLibrary = wiki.getTiddlerData(UPGRADE_LIBRARY_TITLE,{});\n\t\t\t\tupgradeLibrary.tiddlers = upgradeLibrary.tiddlers || {};\n\t\t\t}\n\t\t\treturn upgradeLibrary.tiddlers[title];\n\t\t};\n\n\t// Go through all the incoming tiddlers\n\t$tw.utils.each(titles,function(title) {\n\t\tvar incomingTiddler = tiddlers[title];\n\t\t// Check if we're dealing with a plugin\n\t\tif(incomingTiddler && incomingTiddler[\"plugin-type\"]) {\n\t\t\t// Check whether the plugin contains JS modules\n\t\t\tvar requiresReload = wiki.doesPluginInfoRequireReload(JSON.parse(incomingTiddler.text)) ? (wiki.getTiddlerText(\"$:/language/ControlPanel/Plugins/PluginWillRequireReload\") + \" \") : \"\";\n\t\t\tmessages[title] = requiresReload;\n\t\t\tif(incomingTiddler.version) {\n\t\t\t\t// Upgrade the incoming plugin if it is in the upgrade library\n\t\t\t\tvar libraryTiddler = getLibraryTiddler(title);\n\t\t\t\tif(libraryTiddler && libraryTiddler[\"plugin-type\"] && libraryTiddler.version) {\n\t\t\t\t\ttiddlers[title] = libraryTiddler;\n\t\t\t\t\tmessages[title] = requiresReload + $tw.language.getString(\"Import/Upgrader/Plugins/Upgraded\",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Suppress the incoming plugin if it is older than the currently installed one\n\t\t\t\tvar existingTiddler = wiki.getTiddler(title);\n\t\t\t\tif(existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t\t\t\t// Reject the incoming plugin by blanking all its fields\n\t\t\t\t\tif($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {\n\t\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Version\",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Check whether the plugin is on the blocked list\n\t\t\tvar blockInfo = BLOCKED_PLUGINS[title];\n\t\t\tif(blockInfo) {\n\t\t\t\tif(blockInfo.versions.indexOf(\"*\") !== -1 || (incomingTiddler.version && blockInfo.versions.indexOf(incomingTiddler.version) !== -1)) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Incompatible\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "upgrader"
},
"$:/core/modules/upgraders/system.js": {
"title": "$:/core/modules/upgraders/system.js",
"text": "/*\\\ntitle: $:/core/modules/upgraders/system.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that suppresses certain system tiddlers that shouldn't be imported\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DONT_IMPORT_LIST = [\"$:/StoryList\",\"$:/HistoryList\"],\n\tDONT_IMPORT_PREFIX_LIST = [\"$:/temp/\",\"$:/state/\",\"$:/Import\"],\n\tWARN_IMPORT_PREFIX_LIST = [\"$:/core/modules/\"];\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {},\n\t\tshowAlert = false;\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tif(DONT_IMPORT_LIST.indexOf(title) !== -1) {\n\t\t\ttiddlers[title] = Object.create(null);\n\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/System/Suppressed\");\n\t\t} else {\n\t\t\tfor(var t=0; t<DONT_IMPORT_PREFIX_LIST.length; t++) {\n\t\t\t\tvar prefix = DONT_IMPORT_PREFIX_LIST[t];\n\t\t\t\tif(title.substr(0,prefix.length) === prefix) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/State/Suppressed\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor(var t=0; t<WARN_IMPORT_PREFIX_LIST.length; t++) {\n\t\t\t\tvar prefix = WARN_IMPORT_PREFIX_LIST[t];\n\t\t\t\tif(title.substr(0,prefix.length) === prefix && wiki.isShadowTiddler(title)) {\n\t\t\t\t\tshowAlert = true;\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/System/Warning\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\tif(showAlert) {\n\t\tvar logger = new $tw.utils.Logger(\"import\");\n\t\tlogger.alert($tw.language.getString(\"Import/Upgrader/System/Alert\"));\n\t}\n\treturn messages;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "upgrader"
},
"$:/core/modules/upgraders/themetweaks.js": {
"title": "$:/core/modules/upgraders/themetweaks.js",
"text": "/*\\\ntitle: $:/core/modules/upgraders/themetweaks.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that handles the change in theme tweak storage introduced in 5.0.14-beta.\n\nPreviously, theme tweaks were stored in two data tiddlers:\n\n* $:/themes/tiddlywiki/vanilla/metrics\n* $:/themes/tiddlywiki/vanilla/settings\n\nNow, each tweak is stored in its own separate tiddler.\n\nThis upgrader copies any values from the old format to the new. The old data tiddlers are not deleted in case they have been used to store additional indexes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar MAPPINGS = {\n\t\"$:/themes/tiddlywiki/vanilla/metrics\": {\n\t\t\"fontsize\": \"$:/themes/tiddlywiki/vanilla/metrics/fontsize\",\n\t\t\"lineheight\": \"$:/themes/tiddlywiki/vanilla/metrics/lineheight\",\n\t\t\"storyleft\": \"$:/themes/tiddlywiki/vanilla/metrics/storyleft\",\n\t\t\"storytop\": \"$:/themes/tiddlywiki/vanilla/metrics/storytop\",\n\t\t\"storyright\": \"$:/themes/tiddlywiki/vanilla/metrics/storyright\",\n\t\t\"storywidth\": \"$:/themes/tiddlywiki/vanilla/metrics/storywidth\",\n\t\t\"tiddlerwidth\": \"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"\n\t},\n\t\"$:/themes/tiddlywiki/vanilla/settings\": {\n\t\t\"fontfamily\": \"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tvar mapping = MAPPINGS[title];\n\t\tif(mapping) {\n\t\t\tvar tiddler = new $tw.Tiddler(tiddlers[title]),\n\t\t\t\ttiddlerData = wiki.getTiddlerDataCached(tiddler,{});\n\t\t\tfor(var index in mapping) {\n\t\t\t\tvar mappedTitle = mapping[index];\n\t\t\t\tif(!tiddlers[mappedTitle] || tiddlers[mappedTitle].title !== mappedTitle) {\n\t\t\t\t\ttiddlers[mappedTitle] = {\n\t\t\t\t\t\ttitle: mappedTitle,\n\t\t\t\t\t\ttext: tiddlerData[index]\n\t\t\t\t\t};\n\t\t\t\t\tmessages[mappedTitle] = $tw.language.getString(\"Import/Upgrader/ThemeTweaks/Created\",{variables: {\n\t\t\t\t\t\tfrom: title + \"##\" + index\n\t\t\t\t\t}});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "upgrader"
},
"$:/core/modules/utils/base64-utf8/base64-utf8.module.js": {
"text": "(function(){// From https://gist.github.com/Nijikokun/5192472\n//\n// UTF8 Module\n//\n// Cleaner and modularized utf-8 encoding and decoding library for javascript.\n//\n// copyright: MIT\n// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com\n!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&\"function\"===o.define&&o.define.amd?define(\"utf8\",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if(\"string\"!=typeof r)return r;r=r.replace(/\\r\\n/g,\"\\n\");for(var e,o=\"\",t=0;t<r.length;t++)if((e=r.charCodeAt(t))<128)o+=String.fromCharCode(e);else if(e>127&&e<2048)o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128);else if(e>55295&&e<57344&&r.length>t+1){var i=e,n=r.charCodeAt(t+1);t++;var d=65536+(i-55296<<10|n-56320);o+=String.fromCharCode(d>>18|240),o+=String.fromCharCode(d>>12&63|128),o+=String.fromCharCode(d>>6&63|128),o+=String.fromCharCode(63&d|128)}else o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128);return o},decode:function(r){if(\"string\"!=typeof r)return r;for(var e=\"\",o=0,t=0;o<r.length;)if((t=r.charCodeAt(o))<128)e+=String.fromCharCode(t),o++;else if(t>191&&t<224)e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2;else if(t>223&&t<240)e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3;else{var i=(7&t)<<18|(63&r.charCodeAt(o+1))<<12|(63&r.charCodeAt(o+2))<<6|63&r.charCodeAt(o+3);e+=String.fromCharCode(55296+(i-65536>>10))+String.fromCharCode(56320+(i-65536&1023)),o+=4}return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var i=0;i<t.length;i++)o[t[i]]=o.require(t[i]);o.module.exports=e.apply(o)}else void 0!==o.define&&\"function\"===o.define&&o.define.amd?define(\"base64\",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";return{encode:function(r){if(void 0===e)throw{error:\"MissingMethod\",message:\"UTF8 Module is missing.\"};if(\"string\"!=typeof r)return r;r=e.encode(r);for(var t,i,n,d,f,a,h,C=\"\",c=0;c<r.length;)d=(t=r.charCodeAt(c++))>>2,f=(3&t)<<4|(i=r.charCodeAt(c++))>>4,a=(15&i)<<2|(n=r.charCodeAt(c++))>>6,h=63&n,isNaN(i)?a=h=64:isNaN(n)&&(h=64),C+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return C},decode:function(r){if(void 0===e)throw{error:\"MissingMethod\",message:\"UTF8 Module is missing.\"};if(\"string\"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\\+\\/\\=]/g,\"\");for(var t,i,n,d,f,a,h=\"\",C=0;C<r.length;)t=o.indexOf(r.charAt(C++))<<2|(d=o.indexOf(r.charAt(C++)))>>4,i=(15&d)<<4|(f=o.indexOf(r.charAt(C++)))>>2,n=(3&f)<<6|(a=o.indexOf(r.charAt(C++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(i)),64!=a&&(h+=String.fromCharCode(n));return e.decode(h)}}},this,[\"utf8\"]);}).call(exports);",
"type": "application/javascript",
"title": "$:/core/modules/utils/base64-utf8/base64-utf8.module.js",
"module-type": "library"
},
"$:/core/modules/utils/crypto.js": {
"title": "$:/core/modules/utils/crypto.js",
"text": "/*\\\ntitle: $:/core/modules/utils/crypto.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions related to crypto.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for an encrypted store area in the text of a TiddlyWiki file\n*/\nexports.extractEncryptedStoreArea = function(text) {\n\tvar encryptedStoreAreaStartMarker = \"<pre id=\\\"encryptedStoreArea\\\" type=\\\"text/plain\\\" style=\\\"display:none;\\\">\",\n\t\tencryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker);\n\tif(encryptedStoreAreaStart !== -1) {\n\t\tvar encryptedStoreAreaEnd = text.indexOf(\"</pre>\",encryptedStoreAreaStart);\n\t\tif(encryptedStoreAreaEnd !== -1) {\n\t\t\treturn $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If the password is not provided then the password in the password store will be used\n*/\nexports.decryptStoreArea = function(encryptedStoreArea,password) {\n\tvar decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);\n\tif(decryptedText) {\n\t\tvar json = JSON.parse(decryptedText),\n\t\t\ttiddlers = [];\n\t\tfor(var title in json) {\n\t\t\tif(title !== \"$:/isEncrypted\") {\n\t\t\t\ttiddlers.push(json[title]);\n\t\t\t}\n\t\t}\n\t\treturn tiddlers;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If that fails, the user is prompted for a password.\nencryptedStoreArea: text of the TiddlyWiki encrypted store area\ncallback: function(tiddlers) called with the array of decrypted tiddlers\n\nThe following configuration settings are supported:\n\n$tw.config.usePasswordVault: causes any password entered by the user to also be put into the system password vault\n*/\nexports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback,options) {\n\t// Try to decrypt with the current password\n\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);\n\tif(tiddlers) {\n\t\tcallback(tiddlers);\n\t} else {\n\t\t// Prompt for a new password and keep trying\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: \"Enter a password to decrypt the imported TiddlyWiki\",\n\t\t\tnoUserName: true,\n\t\t\tcanCancel: true,\n\t\t\tsubmitText: \"Decrypt\",\n\t\t\tcallback: function(data) {\n\t\t\t\t// Exit if the user cancelled\n\t\t\t\tif(!data) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Attempt to decrypt the tiddlers\n\t\t\t\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea,data.password);\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tif($tw.config.usePasswordVault) {\n\t\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t\t}\n\t\t\t\t\tcallback(tiddlers);\n\t\t\t\t\t// Exit and remove the password prompt\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\t// We didn't decrypt everything, so continue to prompt for password\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/csv.js": {
"title": "$:/core/modules/utils/csv.js",
"text": "/*\\\ntitle: $:/core/modules/utils/csv.js\ntype: application/javascript\nmodule-type: utils\n\nA barebones CSV parser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a CSV string with a header row and return an array of hashmaps.\n*/\nexports.parseCsvStringWithHeader = function(text,options) {\n\toptions = options || {};\n\tvar separator = options.separator || \",\",\n\t\trows = text.split(/\\r?\\n/mg).map(function(row) {\n\t\t\treturn $tw.utils.trim(row);\n\t\t}).filter(function(row) {\n\t\t\treturn row !== \"\";\n\t\t});\n\tif(rows.length < 1) {\n\t\treturn \"Missing header row\";\n\t}\n\tvar headings = rows[0].split(separator),\n\t\tresults = [];\n\tfor(var row=1; row<rows.length; row++) {\n\t\tvar columns = rows[row].split(separator),\n\t\t\tcolumnResult = Object.create(null);\n\t\tif(columns.length !== headings.length) {\n\t\t\treturn \"Malformed CSV row '\" + rows[row] + \"'\";\n\t\t}\n\t\tfor(var column=0; column<columns.length; column++) {\n\t\t\tvar columnName = headings[column];\n\t\t\tcolumnResult[columnName] = $tw.utils.trim(columns[column] || \"\");\n\t\t}\n\t\tresults.push(columnResult);\t\t\t\n\t}\n\treturn results;\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/diff-match-patch/diff_match_patch.js": {
"text": "(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;\ndiff_match_patch.prototype.diff_main=function(a,b,c,d){\"undefined\"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error(\"Null input. (diff_main)\");if(a==b)return a?[[DIFF_EQUAL,a]]:[];\"undefined\"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,\nb,e,d);c&&a.unshift([DIFF_EQUAL,c]);g&&a.push([DIFF_EQUAL,g]);this.diff_cleanupMerge(a);return a};\ndiff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[DIFF_INSERT,b]];if(!b)return[[DIFF_DELETE,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[DIFF_INSERT,e.substring(0,g)],[DIFF_EQUAL,f],[DIFF_INSERT,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=DIFF_DELETE),c):1==f.length?[[DIFF_DELETE,a],[DIFF_INSERT,b]]:(e=this.diff_halfMatch_(a,b))?(b=e[1],f=e[3],a=e[4],e=this.diff_main(e[0],e[2],c,d),c=this.diff_main(b,f,c,d),e.concat([[DIFF_EQUAL,\na]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,d):this.diff_bisect_(a,b,d)};\ndiff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([DIFF_EQUAL,\"\"]);for(var e=d=b=0,f=\"\",g=\"\";b<a.length;){switch(a[b][0]){case DIFF_INSERT:e++;g+=a[b][1];break;case DIFF_DELETE:d++;f+=a[b][1];break;case DIFF_EQUAL:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=\nd.length}d=e=0;g=f=\"\"}b++}a.pop();return a};\ndiff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=2*f,h=Array(g),l=Array(g),k=0;k<g;k++)h[k]=-1,l[k]=-1;h[f+1]=0;l[f+1]=0;k=d-e;for(var m=0!=k%2,p=0,x=0,w=0,q=0,t=0;t<f&&!((new Date).getTime()>c);t++){for(var v=-t+p;v<=t-x;v+=2){var n=f+v;var r=v==-t||v!=t&&h[n-1]<h[n+1]?h[n+1]:h[n-1]+1;for(var y=r-v;r<d&&y<e&&a.charAt(r)==b.charAt(y);)r++,y++;h[n]=r;if(r>d)x+=2;else if(y>e)p+=2;else if(m&&(n=f+k-v,0<=n&&n<g&&-1!=l[n])){var u=d-l[n];if(r>=\nu)return this.diff_bisectSplit_(a,b,r,y,c)}}for(v=-t+w;v<=t-q;v+=2){n=f+v;u=v==-t||v!=t&&l[n-1]<l[n+1]?l[n+1]:l[n-1]+1;for(r=u-v;u<d&&r<e&&a.charAt(d-u-1)==b.charAt(e-r-1);)u++,r++;l[n]=u;if(u>d)q+=2;else if(r>e)w+=2;else if(!m&&(n=f+k-v,0<=n&&n<g&&-1!=h[n]&&(r=h[n],y=f+r-n,u=d-u,r>=u)))return this.diff_bisectSplit_(a,b,r,y,c)}}return[[DIFF_DELETE,a],[DIFF_INSERT,b]]};\ndiff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};\ndiff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b=\"\",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf(\"\\n\",c);-1==f&&(f=a.length-1);var h=a.substring(c,f+1);c=f+1;(e.hasOwnProperty?e.hasOwnProperty(h):void 0!==e[h])?b+=String.fromCharCode(e[h]):(b+=String.fromCharCode(g),e[h]=g,d[g++]=h)}return b}var d=[],e={};d[0]=\"\";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};\ndiff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join(\"\")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;d=0;for(var e=1;;){var f=a.substring(c-e);f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};\ndiff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g=\"\",h,k,l,m;-1!=(e=b.indexOf(d,e+1));){var p=f.diff_commonPrefix(a.substring(c),b.substring(e)),u=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<u+p&&(g=b.substring(e-u,e)+b.substring(e,e+p),h=a.substring(0,c-u),k=a.substring(c+p),l=b.substring(0,e-u),m=b.substring(e+p))}return 2*g.length>=a.length?[h,k,l,m,g]:null}if(0>=this.Diff_Timeout)return null;\nvar d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4));d=c(d,e,Math.ceil(d.length/2));if(g||d)g=d?g?g[4].length>d[4].length?g:d:d:g;else return null;if(a.length>b.length){d=g[0];e=g[1];var h=g[2];var l=g[3]}else h=g[0],l=g[1],d=g[2],e=g[3];return[d,e,h,l,g[4]]};\ndiff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,l=0,k=0;f<a.length;)a[f][0]==DIFF_EQUAL?(c[d++]=f,g=l,h=k,k=l=0,e=a[f][1]):(a[f][0]==DIFF_INSERT?l+=a[f][1].length:k+=a[f][1].length,e&&e.length<=Math.max(g,h)&&e.length<=Math.max(l,k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,d--,f=0<d?c[d-1]:-1,k=l=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(a[f-1][0]==\nDIFF_DELETE&&a[f][0]==DIFF_INSERT){b=a[f-1][1];c=a[f][1];d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[DIFF_EQUAL,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[DIFF_EQUAL,b.substring(0,e)]),a[f-1][0]=DIFF_INSERT,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=DIFF_DELETE,a[f+1][1]=b.substring(e),f++;f++}f++}};\ndiff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_);c=g&&c.match(diff_match_patch.linebreakRegex_);d=h&&d.match(diff_match_patch.linebreakRegex_);var k=c&&a.match(diff_match_patch.blanklineEndRegex_),l=d&&b.match(diff_match_patch.blanklineStartRegex_);\nreturn k||l?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(a[c-1][0]==DIFF_EQUAL&&a[c+1][0]==DIFF_EQUAL){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g){var h=e.substring(e.length-g);d=d.substring(0,d.length-g);e=h+e.substring(0,e.length-g);f=h+f}g=d;h=e;for(var l=f,k=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){d+=e.charAt(0);e=e.substring(1)+f.charAt(0);f=f.substring(1);var m=b(d,e)+b(e,f);m>=k&&(k=m,g=d,h=e,l=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-\n1,1),c--),a[c][1]=h,l?a[c+1][1]=l:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\\s/;diff_match_patch.linebreakRegex_=/[\\r\\n]/;diff_match_patch.blanklineEndRegex_=/\\n\\r?\\n$/;diff_match_patch.blanklineStartRegex_=/^\\r?\\n\\r?\\n/;\ndiff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,l=!1,k=!1;f<a.length;)a[f][0]==DIFF_EQUAL?(a[f][1].length<this.Diff_EditCost&&(l||k)?(c[d++]=f,g=l,h=k,e=a[f][1]):(d=0,e=null),l=k=!1):(a[f][0]==DIFF_DELETE?k=!0:l=!0,e&&(g&&h&&l&&k||e.length<this.Diff_EditCost/2&&3==g+h+l+k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,e=null,g&&h?(l=k=!0,d=0):(d--,f=0<d?c[d-1]:-1,l=k=!1),b=!0)),f++;b&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([DIFF_EQUAL,\"\"]);for(var b=0,c=0,d=0,e=\"\",f=\"\",g;b<a.length;)switch(a[b][0]){case DIFF_INSERT:d++;f+=a[b][1];b++;break;case DIFF_DELETE:c++;e+=a[b][1];b++;break;case DIFF_EQUAL:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&a[b-c-d-1][0]==DIFF_EQUAL?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[DIFF_EQUAL,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-\ng)+a[b][1],f=f.substring(0,f.length-g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[DIFF_INSERT,f]):0===d?a.splice(b-c,c+d,[DIFF_DELETE,e]):a.splice(b-c-d,c+d,[DIFF_DELETE,e],[DIFF_INSERT,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&a[b-1][0]==DIFF_EQUAL?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=\"\"}\"\"===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)a[b-1][0]==DIFF_EQUAL&&a[b+1][0]==DIFF_EQUAL&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,\na[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){a[g][0]!==DIFF_INSERT&&(c+=a[g][1].length);a[g][0]!==DIFF_DELETE&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&a[g][0]===DIFF_DELETE?f:f+(b-e)};\ndiff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\\n/g,g=0;g<a.length;g++){var h=a[g][0],l=a[g][1].replace(c,\"&\").replace(d,\"<\").replace(e,\">\").replace(f,\"¶<br>\");switch(h){case DIFF_INSERT:b[g]='<ins style=\"background:#e6ffe6;\">'+l+\"</ins>\";break;case DIFF_DELETE:b[g]='<del style=\"background:#ffe6e6;\">'+l+\"</del>\";break;case DIFF_EQUAL:b[g]=\"<span>\"+l+\"</span>\"}}return b.join(\"\")};\ndiff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_INSERT&&(b[c]=a[c][1]);return b.join(\"\")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_DELETE&&(b[c]=a[c][1]);return b.join(\"\")};\ndiff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][1];switch(a[e][0]){case DIFF_INSERT:c+=f.length;break;case DIFF_DELETE:d+=f.length;break;case DIFF_EQUAL:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};\ndiff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case DIFF_INSERT:b[c]=\"+\"+encodeURI(a[c][1]);break;case DIFF_DELETE:b[c]=\"-\"+a[c][1].length;break;case DIFF_EQUAL:b[c]=\"=\"+a[c][1].length}return b.join(\"\\t\").replace(/%20/g,\" \")};\ndiff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case \"+\":try{c[d++]=[DIFF_INSERT,decodeURI(h)]}catch(k){throw Error(\"Illegal escape in diff_fromDelta: \"+h);}break;case \"-\":case \"=\":var l=parseInt(h,10);if(isNaN(l)||0>l)throw Error(\"Invalid number in diff_fromDelta: \"+h);h=a.substring(e,e+=l);\"=\"==f[g].charAt(0)?c[d++]=[DIFF_EQUAL,h]:c[d++]=[DIFF_DELETE,h];break;default:if(f[g])throw Error(\"Invalid diff operation in diff_fromDelta: \"+\nf[g]);}}if(e!=a.length)throw Error(\"Delta length (\"+e+\") does not equal source text length (\"+a.length+\").\");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error(\"Null input. (match_main)\");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};\ndiff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return f.Match_Distance?e+g/f.Match_Distance:g?1:e}if(b.length>this.Match_MaxBits)throw Error(\"Pattern too long for this browser.\");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));var l=1<<b.length-1;h=-1;for(var k,m,p=b.length+a.length,x,w=0;w<b.length;w++){k=0;for(m=p;k<m;)d(w,\nc+m)<=g?k=m:p=m,m=Math.floor((p-k)/2+k);p=m;k=Math.max(1,c-m+1);var q=Math.min(c+m,a.length)+b.length;m=Array(q+2);for(m[q+1]=(1<<w)-1;q>=k;q--){var t=e[a.charAt(q-1)];m[q]=0===w?(m[q+1]<<1|1)&t:(m[q+1]<<1|1)&t|(x[q+1]|x[q])<<1|1|x[q+1];if(m[q]&l&&(t=d(w,q-1),t<=g))if(g=t,h=q-1,h>c)k=Math.max(1,2*c-h);else break}if(d(w+1,c)>g)break;x=m}return h};\ndiff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};\ndiff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([DIFF_EQUAL,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([DIFF_EQUAL,d]);a.start1-=c.length;a.start2-=\nc.length;a.length1+=c.length+d.length;a.length2+=c.length+d.length}};\ndiff_match_patch.prototype.patch_make=function(a,b,c){if(\"string\"==typeof a&&\"string\"==typeof b&&\"undefined\"==typeof c){var d=a;b=this.diff_main(d,b,!0);2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b))}else if(a&&\"object\"==typeof a&&\"undefined\"==typeof b&&\"undefined\"==typeof c)b=a,d=this.diff_text1(b);else if(\"string\"==typeof a&&b&&\"object\"==typeof b&&\"undefined\"==typeof c)d=a;else if(\"string\"==typeof a&&\"string\"==typeof b&&c&&\"object\"==typeof c)d=a,b=c;else throw Error(\"Unknown call format to patch_make.\");\nif(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,l=0;l<b.length;l++){var k=b[l][0],m=b[l][1];e||k===DIFF_EQUAL||(a.start1=f,a.start2=g);switch(k){case DIFF_INSERT:a.diffs[e++]=b[l];a.length2+=m.length;d=d.substring(0,g)+m+d.substring(g);break;case DIFF_DELETE:a.length1+=m.length;a.diffs[e++]=b[l];d=d.substring(0,g)+d.substring(g+m.length);break;case DIFF_EQUAL:m.length<=2*this.Patch_Margin&&e&&b.length!=l+1?(a.diffs[e++]=b[l],a.length1+=m.length,a.length2+=m.length):\nm.length>=2*this.Patch_Margin&&e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}k!==DIFF_INSERT&&(f+=m.length);k!==DIFF_DELETE&&(g+=m.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};\ndiff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};\ndiff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),l=-1;if(h.length>this.Match_MaxBits){var k=this.match_main(b,h.substring(0,this.Match_MaxBits),g);-1!=k&&(l=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==l||k>=l)&&(k=-1)}else k=this.match_main(b,h,\ng);if(-1==k)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=k-g,g=-1==l?b.substring(k,k+h.length):b.substring(k,l+this.Match_MaxBits),h==g)b=b.substring(0,k)+this.diff_text2(a[f].diffs)+b.substring(k+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);h=0;var m;for(l=0;l<a[f].diffs.length;l++){var p=a[f].diffs[l];p[0]!==DIFF_EQUAL&&(m=this.diff_xIndex(g,h));p[0]===\nDIFF_INSERT?b=b.substring(0,k+m)+p[1]+b.substring(k+m):p[0]===DIFF_DELETE&&(b=b.substring(0,k+m)+b.substring(k+this.diff_xIndex(g,h+p[1].length)));p[0]!==DIFF_DELETE&&(h+=p[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};\ndiff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c=\"\",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;d=a[0];var e=d.diffs;if(0==e.length||e[0][0]!=DIFF_EQUAL)e.unshift([DIFF_EQUAL,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||e[e.length-\n1][0]!=DIFF_EQUAL?(e.push([DIFF_EQUAL,c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};\ndiff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g=\"\";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,l=!0;h.start1=e-g.length;h.start2=f-g.length;\"\"!==g&&(h.length1=h.length2=g.length,h.diffs.push([DIFF_EQUAL,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){g=d.diffs[0][0];var k=d.diffs[0][1];g===DIFF_INSERT?(h.length2+=k.length,f+=k.length,h.diffs.push(d.diffs.shift()),\nl=!1):g===DIFF_DELETE&&1==h.diffs.length&&h.diffs[0][0]==DIFF_EQUAL&&k.length>2*b?(h.length1+=k.length,e+=k.length,l=!1,h.diffs.push([g,k]),d.diffs.shift()):(k=k.substring(0,b-h.length1-this.Patch_Margin),h.length1+=k.length,e+=k.length,g===DIFF_EQUAL?(h.length2+=k.length,f+=k.length):l=!1,h.diffs.push([g,k]),k==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(k.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);k=this.diff_text1(d.diffs).substring(0,\nthis.Patch_Margin);\"\"!==k&&(h.length1+=k.length,h.length2+=k.length,0!==h.diffs.length&&h.diffs[h.diffs.length-1][0]===DIFF_EQUAL?h.diffs[h.diffs.length-1][1]+=k:h.diffs.push([DIFF_EQUAL,k]));l||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join(\"\")};\ndiff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split(\"\\n\");for(var c=0,d=/^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error(\"Invalid patch string: \"+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);\"\"===e[2]?(f.start1--,f.length1=1):\"0\"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);\"\"===e[4]?(f.start2--,f.length2=1):\"0\"==e[4]?f.length2=0:(f.start2--,f.length2=\nparseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error(\"Illegal escape in patch_fromText: \"+g);}if(\"-\"==e)f.diffs.push([DIFF_DELETE,g]);else if(\"+\"==e)f.diffs.push([DIFF_INSERT,g]);else if(\" \"==e)f.diffs.push([DIFF_EQUAL,g]);else if(\"@\"==e)break;else if(\"\"!==e)throw Error('Invalid patch mode \"'+e+'\" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};\ndiff_match_patch.patch_obj.prototype.toString=function(){for(var a=[\"@@ -\"+(0===this.length1?this.start1+\",0\":1==this.length1?this.start1+1:this.start1+1+\",\"+this.length1)+\" +\"+(0===this.length2?this.start2+\",0\":1==this.length2?this.start2+1:this.start2+1+\",\"+this.length2)+\" @@\\n\"],b,c=0;c<this.diffs.length;c++){switch(this.diffs[c][0]){case DIFF_INSERT:b=\"+\";break;case DIFF_DELETE:b=\"-\";break;case DIFF_EQUAL:b=\" \"}a[c+1]=b+encodeURI(this.diffs[c][1])+\"\\n\"}return a.join(\"\").replace(/%20/g,\" \")};\nthis.diff_match_patch=diff_match_patch;this.DIFF_DELETE=DIFF_DELETE;this.DIFF_INSERT=DIFF_INSERT;this.DIFF_EQUAL=DIFF_EQUAL;\n}).call(exports);",
"type": "application/javascript",
"title": "$:/core/modules/utils/diff-match-patch/diff_match_patch.js",
"module-type": "library"
},
"$:/core/modules/utils/dom/animations/slide.js": {
"title": "$:/core/modules/utils/dom/animations/slide.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/animations/slide.js\ntype: application/javascript\nmodule-type: animation\n\nA simple slide animation that varies the height of the element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction slideOpen(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration();\n\t// Get the current height of the domNode\n\tvar computedStyle = window.getComputedStyle(domNode),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrPaddingBottom = parseInt(computedStyle.paddingBottom,10),\n\t\tcurrPaddingTop = parseInt(computedStyle.paddingTop,10),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Reset the margin once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"none\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{marginTop: currMarginTop + \"px\"},\n\t\t{paddingBottom: currPaddingBottom + \"px\"},\n\t\t{paddingTop: currPaddingTop + \"px\"},\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n}\n\nfunction slideClosed(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration(),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Clear the properties we've set when the animation is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n}\n\nexports.slide = {\n\topen: slideOpen,\n\tclose: slideClosed\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "animation"
},
"$:/core/modules/utils/dom/animator.js": {
"title": "$:/core/modules/utils/dom/animator.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/animator.js\ntype: application/javascript\nmodule-type: utils\n\nOrchestrates animations and transitions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Animator() {\n\t// Get the registered animation modules\n\tthis.animations = {};\n\t$tw.modules.applyMethods(\"animation\",this.animations);\n}\n\nAnimator.prototype.perform = function(type,domNode,options) {\n\toptions = options || {};\n\t// Find an animation that can handle this type\n\tvar chosenAnimation;\n\t$tw.utils.each(this.animations,function(animation,name) {\n\t\tif($tw.utils.hop(animation,type)) {\n\t\t\tchosenAnimation = animation[type];\n\t\t}\n\t});\n\tif(!chosenAnimation) {\n\t\tchosenAnimation = function(domNode,options) {\n\t\t\tif(options.callback) {\n\t\t\t\toptions.callback();\n\t\t\t}\n\t\t};\n\t}\n\t// Call the animation\n\tchosenAnimation(domNode,options);\n};\n\nexports.Animator = Animator;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/browser.js": {
"title": "$:/core/modules/utils/dom/browser.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/browser.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser feature detection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet style properties of an element\n\telement: dom node\n\tstyles: ordered array of {name: value} pairs\n*/\nexports.setStyle = function(element,styles) {\n\tif(element.nodeType === 1) { // Element.ELEMENT_NODE\n\t\tfor(var t=0; t<styles.length; t++) {\n\t\t\tfor(var styleName in styles[t]) {\n\t\t\t\telement.style[$tw.utils.convertStyleNameToPropertyName(styleName)] = styles[t][styleName];\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nConverts a standard CSS property name into the local browser-specific equivalent. For example:\n\t\"background-color\" --> \"backgroundColor\"\n\t\"transition\" --> \"webkitTransition\"\n*/\n\nvar styleNameCache = {}; // We'll cache the style name conversions\n\nexports.convertStyleNameToPropertyName = function(styleName) {\n\t// Return from the cache if we can\n\tif(styleNameCache[styleName]) {\n\t\treturn styleNameCache[styleName];\n\t}\n\t// Convert it by first removing any hyphens\n\tvar propertyName = $tw.utils.unHyphenateCss(styleName);\n\t// Then check if it needs a prefix\n\tif($tw.browser && document.body.style[propertyName] === undefined) {\n\t\tvar prefixes = [\"O\",\"MS\",\"Moz\",\"webkit\"];\n\t\tfor(var t=0; t<prefixes.length; t++) {\n\t\t\tvar prefixedName = prefixes[t] + propertyName.substr(0,1).toUpperCase() + propertyName.substr(1);\n\t\t\tif(document.body.style[prefixedName] !== undefined) {\n\t\t\t\tpropertyName = prefixedName;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\t// Put it in the cache too\n\tstyleNameCache[styleName] = propertyName;\n\treturn propertyName;\n};\n\n/*\nConverts a JS format CSS property name back into the dashed form used in CSS declarations. For example:\n\t\"backgroundColor\" --> \"background-color\"\n\t\"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.convertPropertyNameToStyleName = function(propertyName) {\n\t// Rehyphenate the name\n\tvar styleName = $tw.utils.hyphenateCss(propertyName);\n\t// If there's a webkit prefix, add a dash (other browsers have uppercase prefixes, and so get the dash automatically)\n\tif(styleName.indexOf(\"webkit\") === 0) {\n\t\tstyleName = \"-\" + styleName;\n\t} else if(styleName.indexOf(\"-m-s\") === 0) {\n\t\tstyleName = \"-ms\" + styleName.substr(4);\n\t}\n\treturn styleName;\n};\n\n/*\nRound trip a stylename to a property name and back again. For example:\n\t\"transform\" --> \"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.roundTripPropertyName = function(propertyName) {\n\treturn $tw.utils.convertPropertyNameToStyleName($tw.utils.convertStyleNameToPropertyName(propertyName));\n};\n\n/*\nConverts a standard event name into the local browser specific equivalent. For example:\n\t\"animationEnd\" --> \"webkitAnimationEnd\"\n*/\n\nvar eventNameCache = {}; // We'll cache the conversions\n\nvar eventNameMappings = {\n\t\"transitionEnd\": {\n\t\tcorrespondingCssProperty: \"transition\",\n\t\tmappings: {\n\t\t\ttransition: \"transitionend\",\n\t\t\tOTransition: \"oTransitionEnd\",\n\t\t\tMSTransition: \"msTransitionEnd\",\n\t\t\tMozTransition: \"transitionend\",\n\t\t\twebkitTransition: \"webkitTransitionEnd\"\n\t\t}\n\t},\n\t\"animationEnd\": {\n\t\tcorrespondingCssProperty: \"animation\",\n\t\tmappings: {\n\t\t\tanimation: \"animationend\",\n\t\t\tOAnimation: \"oAnimationEnd\",\n\t\t\tMSAnimation: \"msAnimationEnd\",\n\t\t\tMozAnimation: \"animationend\",\n\t\t\twebkitAnimation: \"webkitAnimationEnd\"\n\t\t}\n\t}\n};\n\nexports.convertEventName = function(eventName) {\n\tif(eventNameCache[eventName]) {\n\t\treturn eventNameCache[eventName];\n\t}\n\tvar newEventName = eventName,\n\t\tmappings = eventNameMappings[eventName];\n\tif(mappings) {\n\t\tvar convertedProperty = $tw.utils.convertStyleNameToPropertyName(mappings.correspondingCssProperty);\n\t\tif(mappings.mappings[convertedProperty]) {\n\t\t\tnewEventName = mappings.mappings[convertedProperty];\n\t\t}\n\t}\n\t// Put it in the cache too\n\teventNameCache[eventName] = newEventName;\n\treturn newEventName;\n};\n\n/*\nReturn the names of the fullscreen APIs\n*/\nexports.getFullScreenApis = function() {\n\tvar d = document,\n\t\tdb = d.body,\n\t\tresult = {\n\t\t\"_requestFullscreen\": db.webkitRequestFullscreen !== undefined ? \"webkitRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.mozRequestFullScreen !== undefined ? \"mozRequestFullScreen\" :\n\t\t\t\t\t\t\tdb.msRequestFullscreen !== undefined ? \"msRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.requestFullscreen !== undefined ? \"requestFullscreen\" : \"\",\n\t\t\"_exitFullscreen\": d.webkitExitFullscreen !== undefined ? \"webkitExitFullscreen\" :\n\t\t\t\t\t\t\td.mozCancelFullScreen !== undefined ? \"mozCancelFullScreen\" :\n\t\t\t\t\t\t\td.msExitFullscreen !== undefined ? \"msExitFullscreen\" :\n\t\t\t\t\t\t\td.exitFullscreen !== undefined ? \"exitFullscreen\" : \"\",\n\t\t\"_fullscreenElement\": d.webkitFullscreenElement !== undefined ? \"webkitFullscreenElement\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozFullScreenElement\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"msFullscreenElement\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenElement\" : \"\",\n\t\t\"_fullscreenChange\": d.webkitFullscreenElement !== undefined ? \"webkitfullscreenchange\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozfullscreenchange\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"MSFullscreenChange\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenchange\" : \"\"\n\t};\n\tif(!result._requestFullscreen || !result._exitFullscreen || !result._fullscreenElement || !result._fullscreenChange) {\n\t\treturn null;\n\t} else {\n\t\treturn result;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/csscolorparser.js": {
"title": "$:/core/modules/utils/dom/csscolorparser.js",
"text": "// (c) Dean McNamee <dean@gmail.com>, 2012.\n//\n// https://github.com/deanm/css-color-parser-js\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\n// http://www.w3.org/TR/css3-color/\nvar kCSSColorTable = {\n \"transparent\": [0,0,0,0], \"aliceblue\": [240,248,255,1],\n \"antiquewhite\": [250,235,215,1], \"aqua\": [0,255,255,1],\n \"aquamarine\": [127,255,212,1], \"azure\": [240,255,255,1],\n \"beige\": [245,245,220,1], \"bisque\": [255,228,196,1],\n \"black\": [0,0,0,1], \"blanchedalmond\": [255,235,205,1],\n \"blue\": [0,0,255,1], \"blueviolet\": [138,43,226,1],\n \"brown\": [165,42,42,1], \"burlywood\": [222,184,135,1],\n \"cadetblue\": [95,158,160,1], \"chartreuse\": [127,255,0,1],\n \"chocolate\": [210,105,30,1], \"coral\": [255,127,80,1],\n \"cornflowerblue\": [100,149,237,1], \"cornsilk\": [255,248,220,1],\n \"crimson\": [220,20,60,1], \"cyan\": [0,255,255,1],\n \"darkblue\": [0,0,139,1], \"darkcyan\": [0,139,139,1],\n \"darkgoldenrod\": [184,134,11,1], \"darkgray\": [169,169,169,1],\n \"darkgreen\": [0,100,0,1], \"darkgrey\": [169,169,169,1],\n \"darkkhaki\": [189,183,107,1], \"darkmagenta\": [139,0,139,1],\n \"darkolivegreen\": [85,107,47,1], \"darkorange\": [255,140,0,1],\n \"darkorchid\": [153,50,204,1], \"darkred\": [139,0,0,1],\n \"darksalmon\": [233,150,122,1], \"darkseagreen\": [143,188,143,1],\n \"darkslateblue\": [72,61,139,1], \"darkslategray\": [47,79,79,1],\n \"darkslategrey\": [47,79,79,1], \"darkturquoise\": [0,206,209,1],\n \"darkviolet\": [148,0,211,1], \"deeppink\": [255,20,147,1],\n \"deepskyblue\": [0,191,255,1], \"dimgray\": [105,105,105,1],\n \"dimgrey\": [105,105,105,1], \"dodgerblue\": [30,144,255,1],\n \"firebrick\": [178,34,34,1], \"floralwhite\": [255,250,240,1],\n \"forestgreen\": [34,139,34,1], \"fuchsia\": [255,0,255,1],\n \"gainsboro\": [220,220,220,1], \"ghostwhite\": [248,248,255,1],\n \"gold\": [255,215,0,1], \"goldenrod\": [218,165,32,1],\n \"gray\": [128,128,128,1], \"green\": [0,128,0,1],\n \"greenyellow\": [173,255,47,1], \"grey\": [128,128,128,1],\n \"honeydew\": [240,255,240,1], \"hotpink\": [255,105,180,1],\n \"indianred\": [205,92,92,1], \"indigo\": [75,0,130,1],\n \"ivory\": [255,255,240,1], \"khaki\": [240,230,140,1],\n \"lavender\": [230,230,250,1], \"lavenderblush\": [255,240,245,1],\n \"lawngreen\": [124,252,0,1], \"lemonchiffon\": [255,250,205,1],\n \"lightblue\": [173,216,230,1], \"lightcoral\": [240,128,128,1],\n \"lightcyan\": [224,255,255,1], \"lightgoldenrodyellow\": [250,250,210,1],\n \"lightgray\": [211,211,211,1], \"lightgreen\": [144,238,144,1],\n \"lightgrey\": [211,211,211,1], \"lightpink\": [255,182,193,1],\n \"lightsalmon\": [255,160,122,1], \"lightseagreen\": [32,178,170,1],\n \"lightskyblue\": [135,206,250,1], \"lightslategray\": [119,136,153,1],\n \"lightslategrey\": [119,136,153,1], \"lightsteelblue\": [176,196,222,1],\n \"lightyellow\": [255,255,224,1], \"lime\": [0,255,0,1],\n \"limegreen\": [50,205,50,1], \"linen\": [250,240,230,1],\n \"magenta\": [255,0,255,1], \"maroon\": [128,0,0,1],\n \"mediumaquamarine\": [102,205,170,1], \"mediumblue\": [0,0,205,1],\n \"mediumorchid\": [186,85,211,1], \"mediumpurple\": [147,112,219,1],\n \"mediumseagreen\": [60,179,113,1], \"mediumslateblue\": [123,104,238,1],\n \"mediumspringgreen\": [0,250,154,1], \"mediumturquoise\": [72,209,204,1],\n \"mediumvioletred\": [199,21,133,1], \"midnightblue\": [25,25,112,1],\n \"mintcream\": [245,255,250,1], \"mistyrose\": [255,228,225,1],\n \"moccasin\": [255,228,181,1], \"navajowhite\": [255,222,173,1],\n \"navy\": [0,0,128,1], \"oldlace\": [253,245,230,1],\n \"olive\": [128,128,0,1], \"olivedrab\": [107,142,35,1],\n \"orange\": [255,165,0,1], \"orangered\": [255,69,0,1],\n \"orchid\": [218,112,214,1], \"palegoldenrod\": [238,232,170,1],\n \"palegreen\": [152,251,152,1], \"paleturquoise\": [175,238,238,1],\n \"palevioletred\": [219,112,147,1], \"papayawhip\": [255,239,213,1],\n \"peachpuff\": [255,218,185,1], \"peru\": [205,133,63,1],\n \"pink\": [255,192,203,1], \"plum\": [221,160,221,1],\n \"powderblue\": [176,224,230,1], \"purple\": [128,0,128,1],\n \"red\": [255,0,0,1], \"rosybrown\": [188,143,143,1],\n \"royalblue\": [65,105,225,1], \"saddlebrown\": [139,69,19,1],\n \"salmon\": [250,128,114,1], \"sandybrown\": [244,164,96,1],\n \"seagreen\": [46,139,87,1], \"seashell\": [255,245,238,1],\n \"sienna\": [160,82,45,1], \"silver\": [192,192,192,1],\n \"skyblue\": [135,206,235,1], \"slateblue\": [106,90,205,1],\n \"slategray\": [112,128,144,1], \"slategrey\": [112,128,144,1],\n \"snow\": [255,250,250,1], \"springgreen\": [0,255,127,1],\n \"steelblue\": [70,130,180,1], \"tan\": [210,180,140,1],\n \"teal\": [0,128,128,1], \"thistle\": [216,191,216,1],\n \"tomato\": [255,99,71,1], \"turquoise\": [64,224,208,1],\n \"violet\": [238,130,238,1], \"wheat\": [245,222,179,1],\n \"white\": [255,255,255,1], \"whitesmoke\": [245,245,245,1],\n \"yellow\": [255,255,0,1], \"yellowgreen\": [154,205,50,1]}\n\nfunction clamp_css_byte(i) { // Clamp to integer 0 .. 255.\n i = Math.round(i); // Seems to be what Chrome does (vs truncation).\n return i < 0 ? 0 : i > 255 ? 255 : i;\n}\n\nfunction clamp_css_float(f) { // Clamp to float 0.0 .. 1.0.\n return f < 0 ? 0 : f > 1 ? 1 : f;\n}\n\nfunction parse_css_int(str) { // int or percentage.\n if (str[str.length - 1] === '%')\n return clamp_css_byte(parseFloat(str) / 100 * 255);\n return clamp_css_byte(parseInt(str));\n}\n\nfunction parse_css_float(str) { // float or percentage.\n if (str[str.length - 1] === '%')\n return clamp_css_float(parseFloat(str) / 100);\n return clamp_css_float(parseFloat(str));\n}\n\nfunction css_hue_to_rgb(m1, m2, h) {\n if (h < 0) h += 1;\n else if (h > 1) h -= 1;\n\n if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;\n if (h * 2 < 1) return m2;\n if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;\n return m1;\n}\n\nfunction parseCSSColor(css_str) {\n // Remove all whitespace, not compliant, but should just be more accepting.\n var str = css_str.replace(/ /g, '').toLowerCase();\n\n // Color keywords (and transparent) lookup.\n if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup.\n\n // #abc and #abc123 syntax.\n if (str[0] === '#') {\n if (str.length === 4) {\n var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.\n if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN.\n return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),\n (iv & 0xf0) | ((iv & 0xf0) >> 4),\n (iv & 0xf) | ((iv & 0xf) << 4),\n 1];\n } else if (str.length === 7) {\n var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.\n if (!(iv >= 0 && iv <= 0xffffff)) return null; // Covers NaN.\n return [(iv & 0xff0000) >> 16,\n (iv & 0xff00) >> 8,\n iv & 0xff,\n 1];\n }\n\n return null;\n }\n\n var op = str.indexOf('('), ep = str.indexOf(')');\n if (op !== -1 && ep + 1 === str.length) {\n var fname = str.substr(0, op);\n var params = str.substr(op+1, ep-(op+1)).split(',');\n var alpha = 1; // To allow case fallthrough.\n switch (fname) {\n case 'rgba':\n if (params.length !== 4) return null;\n alpha = parse_css_float(params.pop());\n // Fall through.\n case 'rgb':\n if (params.length !== 3) return null;\n return [parse_css_int(params[0]),\n parse_css_int(params[1]),\n parse_css_int(params[2]),\n alpha];\n case 'hsla':\n if (params.length !== 4) return null;\n alpha = parse_css_float(params.pop());\n // Fall through.\n case 'hsl':\n if (params.length !== 3) return null;\n var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360; // 0 .. 1\n // NOTE(deanm): According to the CSS spec s/l should only be\n // percentages, but we don't bother and let float or percentage.\n var s = parse_css_float(params[1]);\n var l = parse_css_float(params[2]);\n var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n var m1 = l * 2 - m2;\n return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),\n clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),\n clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),\n alpha];\n default:\n return null;\n }\n }\n\n return null;\n}\n\ntry { exports.parseCSSColor = parseCSSColor } catch(e) { }\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom.js": {
"title": "$:/core/modules/utils/dom.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static DOM-related utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDetermines whether element 'a' contains element 'b'\nCode thanks to John Resig, http://ejohn.org/blog/comparing-document-position/\n*/\nexports.domContains = function(a,b) {\n\treturn a.contains ?\n\t\ta !== b && a.contains(b) :\n\t\t!!(a.compareDocumentPosition(b) & 16);\n};\n\nexports.removeChildren = function(node) {\n\twhile(node.hasChildNodes()) {\n\t\tnode.removeChild(node.firstChild);\n\t}\n};\n\nexports.hasClass = function(el,className) {\n\treturn el && el.hasAttribute && el.hasAttribute(\"class\") && el.getAttribute(\"class\").split(\" \").indexOf(className) !== -1;\n};\n\nexports.addClass = function(el,className) {\n\tvar c = (el.getAttribute(\"class\") || \"\").split(\" \");\n\tif(c.indexOf(className) === -1) {\n\t\tc.push(className);\n\t\tel.setAttribute(\"class\",c.join(\" \"));\n\t}\n};\n\nexports.removeClass = function(el,className) {\n\tvar c = (el.getAttribute(\"class\") || \"\").split(\" \"),\n\t\tp = c.indexOf(className);\n\tif(p !== -1) {\n\t\tc.splice(p,1);\n\t\tel.setAttribute(\"class\",c.join(\" \"));\n\t}\n};\n\nexports.toggleClass = function(el,className,status) {\n\tif(status === undefined) {\n\t\tstatus = !exports.hasClass(el,className);\n\t}\n\tif(status) {\n\t\texports.addClass(el,className);\n\t} else {\n\t\texports.removeClass(el,className);\n\t}\n};\n\n/*\nGet the first parent element that has scrollbars or use the body as fallback.\n*/\nexports.getScrollContainer = function(el) {\n\tvar doc = el.ownerDocument;\n\twhile(el.parentNode) {\t\n\t\tel = el.parentNode;\n\t\tif(el.scrollTop) {\n\t\t\treturn el;\n\t\t}\n\t}\n\treturn doc.body;\n};\n\n/*\nGet the scroll position of the viewport\nReturns:\n\t{\n\t\tx: horizontal scroll position in pixels,\n\t\ty: vertical scroll position in pixels\n\t}\n*/\nexports.getScrollPosition = function(srcWindow) {\n\tvar scrollWindow = srcWindow || window;\n\tif(\"scrollX\" in scrollWindow) {\n\t\treturn {x: scrollWindow.scrollX, y: scrollWindow.scrollY};\n\t} else {\n\t\treturn {x: scrollWindow.document.documentElement.scrollLeft, y: scrollWindow.document.documentElement.scrollTop};\n\t}\n};\n\n/*\nAdjust the height of a textarea to fit its content, preserving scroll position, and return the height\n*/\nexports.resizeTextAreaToFit = function(domNode,minHeight) {\n\t// Get the scroll container and register the current scroll position\n\tvar container = $tw.utils.getScrollContainer(domNode),\n\t\tscrollTop = container.scrollTop;\n // Measure the specified minimum height\n\tdomNode.style.height = minHeight;\n\tvar measuredHeight = domNode.offsetHeight || parseInt(minHeight,10);\n\t// Set its height to auto so that it snaps to the correct height\n\tdomNode.style.height = \"auto\";\n\t// Calculate the revised height\n\tvar newHeight = Math.max(domNode.scrollHeight + domNode.offsetHeight - domNode.clientHeight,measuredHeight);\n\t// Only try to change the height if it has changed\n\tif(newHeight !== domNode.offsetHeight) {\n\t\tdomNode.style.height = newHeight + \"px\";\n\t\t// Make sure that the dimensions of the textarea are recalculated\n\t\t$tw.utils.forceLayout(domNode);\n\t\t// Set the container to the position we registered at the beginning\n\t\tcontainer.scrollTop = scrollTop;\n\t}\n\treturn newHeight;\n};\n\n/*\nGets the bounding rectangle of an element in absolute page coordinates\n*/\nexports.getBoundingPageRect = function(element) {\n\tvar scrollPos = $tw.utils.getScrollPosition(element.ownerDocument.defaultView),\n\t\tclientRect = element.getBoundingClientRect();\n\treturn {\n\t\tleft: clientRect.left + scrollPos.x,\n\t\twidth: clientRect.width,\n\t\tright: clientRect.right + scrollPos.x,\n\t\ttop: clientRect.top + scrollPos.y,\n\t\theight: clientRect.height,\n\t\tbottom: clientRect.bottom + scrollPos.y\n\t};\n};\n\n/*\nSaves a named password in the browser\n*/\nexports.savePassword = function(name,password) {\n\tvar done = false;\n\ttry {\n\t\twindow.localStorage.setItem(\"tw5-password-\" + name,password);\n\t\tdone = true;\n\t} catch(e) {\n\t}\n\tif(!done) {\n\t\t$tw.savedPasswords = $tw.savedPasswords || Object.create(null);\n\t\t$tw.savedPasswords[name] = password;\n\t}\n};\n\n/*\nRetrieve a named password from the browser\n*/\nexports.getPassword = function(name) {\n\tvar value;\n\ttry {\n\t\tvalue = window.localStorage.getItem(\"tw5-password-\" + name);\n\t} catch(e) {\n\t}\n\tif(value !== undefined) {\n\t\treturn value;\n\t} else {\n\t\treturn ($tw.savedPasswords || Object.create(null))[name] || \"\";\n\t}\n};\n\n/*\nForce layout of a dom node and its descendents\n*/\nexports.forceLayout = function(element) {\n\tvar dummy = element.offsetWidth;\n};\n\n/*\nPulse an element for debugging purposes\n*/\nexports.pulseElement = function(element) {\n\t// Event handler to remove the class at the end\n\telement.addEventListener($tw.browser.animationEnd,function handler(event) {\n\t\telement.removeEventListener($tw.browser.animationEnd,handler,false);\n\t\t$tw.utils.removeClass(element,\"pulse\");\n\t},false);\n\t// Apply the pulse class\n\t$tw.utils.removeClass(element,\"pulse\");\n\t$tw.utils.forceLayout(element);\n\t$tw.utils.addClass(element,\"pulse\");\n};\n\n/*\nAttach specified event handlers to a DOM node\ndomNode: where to attach the event handlers\nevents: array of event handlers to be added (see below)\nEach entry in the events array is an object with these properties:\nhandlerFunction: optional event handler function\nhandlerObject: optional event handler object\nhandlerMethod: optionally specifies object handler method name (defaults to `handleEvent`)\n*/\nexports.addEventListeners = function(domNode,events) {\n\t$tw.utils.each(events,function(eventInfo) {\n\t\tvar handler;\n\t\tif(eventInfo.handlerFunction) {\n\t\t\thandler = eventInfo.handlerFunction;\n\t\t} else if(eventInfo.handlerObject) {\n\t\t\tif(eventInfo.handlerMethod) {\n\t\t\t\thandler = function(event) {\n\t\t\t\t\teventInfo.handlerObject[eventInfo.handlerMethod].call(eventInfo.handlerObject,event);\n\t\t\t\t};\t\n\t\t\t} else {\n\t\t\t\thandler = eventInfo.handlerObject;\n\t\t\t}\n\t\t}\n\t\tdomNode.addEventListener(eventInfo.name,handler,false);\n\t});\n};\n\n/*\nGet the computed styles applied to an element as an array of strings of individual CSS properties\n*/\nexports.getComputedStyles = function(domNode) {\n\tvar textAreaStyles = window.getComputedStyle(domNode,null),\n\t\tstyleDefs = [],\n\t\tname;\n\tfor(var t=0; t<textAreaStyles.length; t++) {\n\t\tname = textAreaStyles[t];\n\t\tstyleDefs.push(name + \": \" + textAreaStyles.getPropertyValue(name) + \";\");\n\t}\n\treturn styleDefs;\n};\n\n/*\nApply a set of styles passed as an array of strings of individual CSS properties\n*/\nexports.setStyles = function(domNode,styleDefs) {\n\tdomNode.style.cssText = styleDefs.join(\"\");\n};\n\n/*\nCopy the computed styles from a source element to a destination element\n*/\nexports.copyStyles = function(srcDomNode,dstDomNode) {\n\t$tw.utils.setStyles(dstDomNode,$tw.utils.getComputedStyles(srcDomNode));\n};\n\n/*\nCopy plain text to the clipboard on browsers that support it\n*/\nexports.copyToClipboard = function(text,options) {\n\toptions = options || {};\n\tvar textArea = document.createElement(\"textarea\");\n\ttextArea.style.position = \"fixed\";\n\ttextArea.style.top = 0;\n\ttextArea.style.left = 0;\n\ttextArea.style.fontSize = \"12pt\";\n\ttextArea.style.width = \"2em\";\n\ttextArea.style.height = \"2em\";\n\ttextArea.style.padding = 0;\n\ttextArea.style.border = \"none\";\n\ttextArea.style.outline = \"none\";\n\ttextArea.style.boxShadow = \"none\";\n\ttextArea.style.background = \"transparent\";\n\ttextArea.value = text;\n\tdocument.body.appendChild(textArea);\n\ttextArea.select();\n\ttextArea.setSelectionRange(0,text.length);\n\tvar succeeded = false;\n\ttry {\n\t\tsucceeded = document.execCommand(\"copy\");\n\t} catch (err) {\n\t}\n\tif(!options.doNotNotify) {\n\t\t$tw.notifier.display(succeeded ? \"$:/language/Notifications/CopiedToClipboard/Succeeded\" : \"$:/language/Notifications/CopiedToClipboard/Failed\");\n\t}\n\tdocument.body.removeChild(textArea);\n};\n\nexports.getLocationPath = function() {\n\treturn window.location.toString().split(\"#\")[0];\n};\n\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/dragndrop.js": {
"title": "$:/core/modules/utils/dom/dragndrop.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/dragndrop.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser data transfer utilities, used with the clipboard and drag and drop\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOptions:\n\ndomNode: dom node to make draggable\ndragImageType: \"pill\" or \"dom\"\ndragTiddlerFn: optional function to retrieve the title of tiddler to drag\ndragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag\nwidget: widget to use as the contect for the filter\n*/\nexports.makeDraggable = function(options) {\n\tvar dragImageType = options.dragImageType || \"dom\",\n\t\tdragImage,\n\t\tdomNode = options.domNode;\n\t// Make the dom node draggable (not necessary for anchor tags)\n\tif((domNode.tagName || \"\").toLowerCase() !== \"a\") {\n\t\tdomNode.setAttribute(\"draggable\",\"true\");\t\t\n\t}\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragstart\", handlerFunction: function(event) {\n\t\t\tif(event.dataTransfer === undefined) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Collect the tiddlers being dragged\n\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t \tstartActions = options.startActions;\n\t\t\tif(dragFilter) {\n\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t}\n\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t// Check that we've something to drag\n\t\t\tif(titles.length > 0 && event.target === domNode) {\n\t\t\t\t// Mark the drag in progress\n\t\t\t\t$tw.dragInProgress = domNode;\n\t\t\t\t// Set the dragging class on the element being dragged\n\t\t\t\t$tw.utils.addClass(event.target,\"tc-dragging\");\n\t\t\t\t// Invoke drag-start actions if given\n\t\t\t\tif(startActions !== undefined) {\n\t\t\t\t\toptions.widget.invokeActionString(startActions,options.widget,event,{actionTiddler: titleString});\n\t\t\t\t}\n\t\t\t\t// Create the drag image elements\n\t\t\t\tdragImage = options.widget.document.createElement(\"div\");\n\t\t\t\tdragImage.className = \"tc-tiddler-dragger\";\n\t\t\t\tvar inner = options.widget.document.createElement(\"div\");\n\t\t\t\tinner.className = \"tc-tiddler-dragger-inner\";\n\t\t\t\tinner.appendChild(options.widget.document.createTextNode(\n\t\t\t\t\ttitles.length === 1 ? \n\t\t\t\t\t\ttitles[0] :\n\t\t\t\t\t\ttitles.length + \" tiddlers\"\n\t\t\t\t));\n\t\t\t\tdragImage.appendChild(inner);\n\t\t\t\toptions.widget.document.body.appendChild(dragImage);\n\t\t\t\t// Set the data transfer properties\n\t\t\t\tvar dataTransfer = event.dataTransfer;\n\t\t\t\t// Set up the image\n\t\t\t\tdataTransfer.effectAllowed = \"all\";\n\t\t\t\tif(dataTransfer.setDragImage) {\n\t\t\t\t\tif(dragImageType === \"pill\") {\n\t\t\t\t\t\tdataTransfer.setDragImage(dragImage.firstChild,-16,-16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar r = domNode.getBoundingClientRect();\n\t\t\t\t\t\tdataTransfer.setDragImage(domNode,event.clientX-r.left,event.clientY-r.top);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Set up the data transfer\n\t\t\t\tif(dataTransfer.clearData) {\n\t\t\t\t\tdataTransfer.clearData();\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tvar jsonData = [];\n\t\t\t\tif(titles.length > 1) {\n\t\t\t\t\ttitles.forEach(function(title) {\n\t\t\t\t\t\tjsonData.push(options.widget.wiki.getTiddlerAsJson(title));\n\t\t\t\t\t});\n\t\t\t\t\tjsonData = \"[\" + jsonData.join(\",\") + \"]\";\n\t\t\t\t} else {\n\t\t\t\t\tjsonData = options.widget.wiki.getTiddlerAsJson(titles[0]);\n\t\t\t\t}\n\t\t\t\t// IE doesn't like these content types\n\t\t\t\tif(!$tw.browser.isIE) {\n\t\t\t\t\tdataTransfer.setData(\"text/vnd.tiddler\",jsonData);\n\t\t\t\t\tdataTransfer.setData(\"text/plain\",titleString);\n\t\t\t\t\tdataTransfer.setData(\"text/x-moz-url\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\t}\n\t\t\t\tdataTransfer.setData(\"URL\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\tdataTransfer.setData(\"Text\",titleString);\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t\treturn false;\n\t\t}},\n\t\t{name: \"dragend\", handlerFunction: function(event) {\n\t\t\tif(event.target === domNode) {\n\t\t\t\t// Collect the tiddlers being dragged\n\t\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t \t\tendActions = options.endActions;\n\t\t\t\tif(dragFilter) {\n\t\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t\t}\n\t\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t\t$tw.dragInProgress = null;\n\t\t\t\t// Invoke drag-end actions if given\n\t\t\t\tif(endActions !== undefined) {\n\t\t\t\t\toptions.widget.invokeActionString(endActions,options.widget,event,{actionTiddler: titleString});\n\t\t\t\t}\n\t\t\t\t// Remove the dragging class on the element being dragged\n\t\t\t\t$tw.utils.removeClass(event.target,\"tc-dragging\");\n\t\t\t\t// Delete the drag image element\n\t\t\t\tif(dragImage) {\n\t\t\t\t\tdragImage.parentNode.removeChild(dragImage);\n\t\t\t\t\tdragImage = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}}\n\t]);\n};\n\nexports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {\n\t// Try each provided data type in turn\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Available data types:\");\n\t\tfor(var type=0; type<dataTransfer.types.length; type++) {\n\t\t\tconsole.log(\"type\",dataTransfer.types[type],dataTransfer.getData(dataTransfer.types[type]))\n\t\t}\n\t}\n\tfor(var t=0; t<importDataTypes.length; t++) {\n\t\tif(!$tw.browser.isIE || importDataTypes[t].IECompatible) {\n\t\t\t// Get the data\n\t\t\tvar dataType = importDataTypes[t];\n\t\t\t\tvar data = dataTransfer.getData(dataType.type);\n\t\t\t// Import the tiddlers in the data\n\t\t\tif(data !== \"\" && data !== null) {\n\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\tconsole.log(\"Importing data type '\" + dataType.type + \"', data: '\" + data + \"'\")\n\t\t\t\t}\n\t\t\t\tvar tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);\n\t\t\t\tcallback(tiddlerFields);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar importDataTypes = [\n\t{type: \"text/vnd.tiddler\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn parseJSONTiddlers(data,fallbackTitle);\n\t}},\n\t{type: \"URL\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = decodeURIComponent(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/x-moz-url\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = decodeURIComponent(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/html\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/plain\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"Text\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/uri-list\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}}\n];\n\nfunction parseJSONTiddlers(json,fallbackTitle) {\n\tvar data = JSON.parse(json);\n\tif(!$tw.utils.isArray(data)) {\n\t\tdata = [data];\n\t}\n\tdata.forEach(function(fields) {\n\t\tfields.title = fields.title || fallbackTitle;\n\t});\n\treturn data;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/http.js": {
"title": "$:/core/modules/utils/dom/http.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/http.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser HTTP support\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nA quick and dirty HTTP function; to be refactored later. Options are:\n\turl: URL to retrieve\n\theaders: hashmap of headers to send\n\ttype: GET, PUT, POST etc\n\tcallback: function invoked with (err,data,xhr)\n\treturnProp: string name of the property to return as first argument of callback\n*/\nexports.httpRequest = function(options) {\n\tvar type = options.type || \"GET\",\n\t\turl = options.url,\n\t\theaders = options.headers || {accept: \"application/json\"},\n\t\thasHeader = function(targetHeader) {\n\t\t\ttargetHeader = targetHeader.toLowerCase();\n\t\t\tvar result = false;\n\t\t\t$tw.utils.each(headers,function(header,headerTitle,object) {\n\t\t\t\tif(headerTitle.toLowerCase() === targetHeader) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn result;\n\t\t},\n\t\treturnProp = options.returnProp || \"responseText\",\n\t\trequest = new XMLHttpRequest(),\n\t\tdata = \"\",\n\t\tf,results;\n\t// Massage the data hashmap into a string\n\tif(options.data) {\n\t\tif(typeof options.data === \"string\") { // Already a string\n\t\t\tdata = options.data;\n\t\t} else { // A hashmap of strings\n\t\t\tresults = [];\n\t\t\t$tw.utils.each(options.data,function(dataItem,dataItemTitle) {\n\t\t\t\tresults.push(dataItemTitle + \"=\" + encodeURIComponent(dataItem));\n\t\t\t});\n\t\t\tif(type === \"GET\" || type === \"HEAD\") {\n\t\t\t\turl += \"?\" + results.join(\"&\");\n\t\t\t} else {\n\t\t\t\tdata = results.join(\"&\");\n\t\t\t}\n\t\t}\n\t}\n\t// Set up the state change handler\n\trequest.onreadystatechange = function() {\n\t\tif(this.readyState === 4) {\n\t\t\tif(this.status === 200 || this.status === 201 || this.status === 204) {\n\t\t\t\t// Success!\n\t\t\t\toptions.callback(null,this[returnProp],this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t// Something went wrong\n\t\toptions.callback($tw.language.getString(\"Error/XMLHttpRequest\") + \": \" + this.status,null,this);\n\t\t}\n\t};\n\t// Make the request\n\trequest.open(type,url,true);\n\tif(headers) {\n\t\t$tw.utils.each(headers,function(header,headerTitle,object) {\n\t\t\trequest.setRequestHeader(headerTitle,header);\n\t\t});\n\t}\n\tif(data && !hasHeader(\"Content-Type\")) {\n\t\trequest.setRequestHeader(\"Content-Type\",\"application/x-www-form-urlencoded; charset=UTF-8\");\n\t}\n\tif(!hasHeader(\"X-Requested-With\")) {\n\t\trequest.setRequestHeader(\"X-Requested-With\",\"TiddlyWiki\");\n\t}\n\ttry {\n\t\trequest.send(data);\n\t} catch(e) {\n\t\toptions.callback(e,null,this);\n\t}\n\treturn request;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/keyboard.js": {
"title": "$:/core/modules/utils/dom/keyboard.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/keyboard.js\ntype: application/javascript\nmodule-type: utils\n\nKeyboard utilities; now deprecated. Instead, use $tw.keyboardManager\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n[\"parseKeyDescriptor\",\"checkKeyDescriptor\"].forEach(function(method) {\n\texports[method] = function() {\n\t\tif($tw.keyboardManager) {\n\t\t\treturn $tw.keyboardManager[method].apply($tw.keyboardManager,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\treturn null\n\t\t}\n\t};\n});\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/modal.js": {
"title": "$:/core/modules/utils/dom/modal.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/modal.js\ntype: application/javascript\nmodule-type: utils\n\nModal message mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\nvar navigator = require(\"$:/core/modules/widgets/navigator.js\");\n\nvar Modal = function(wiki) {\n\tthis.wiki = wiki;\n\tthis.modalCount = 0;\n};\n\n/*\nDisplay a modal dialogue\n\ttitle: Title of tiddler to display\n\toptions: see below\nOptions include:\n\tdownloadLink: Text of a big download link to include\n*/\nModal.prototype.display = function(title,options) {\n\toptions = options || {};\n\tthis.srcDocument = options.variables && (options.variables.rootwindow === \"true\" ||\n\t\t\t\toptions.variables.rootwindow === \"yes\") ? document :\n\t\t\t\t(options.event.event && options.event.event.target ? options.event.event.target.ownerDocument : document);\n\tthis.srcWindow = this.srcDocument.defaultView;\n\tvar self = this,\n\t\trefreshHandler,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\ttiddler = this.wiki.getTiddler(title);\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Create the variables\n\tvar variables = $tw.utils.extend({\n\t\t\tcurrentTiddler: title,\n\t\t\t\"tv-story-list\": (options.event && options.event.widget ? options.event.widget.getVariable(\"tv-story-list\") : \"\"),\n\t\t\t\"tv-history-list\": (options.event && options.event.widget ? options.event.widget.getVariable(\"tv-history-list\") : \"\")\n\t\t},options.variables);\n\n\t// Create the wrapper divs\n\tvar wrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalBackdrop = this.srcDocument.createElement(\"div\"),\n\t\tmodalWrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalHeader = this.srcDocument.createElement(\"div\"),\n\t\theaderTitle = this.srcDocument.createElement(\"h3\"),\n\t\tmodalBody = this.srcDocument.createElement(\"div\"),\n\t\tmodalLink = this.srcDocument.createElement(\"a\"),\n\t\tmodalFooter = this.srcDocument.createElement(\"div\"),\n\t\tmodalFooterHelp = this.srcDocument.createElement(\"span\"),\n\t\tmodalFooterButtons = this.srcDocument.createElement(\"span\");\n\t// Up the modal count and adjust the body class\n\tthis.modalCount++;\n\tthis.adjustPageClass();\n\t// Add classes\n\t$tw.utils.addClass(wrapper,\"tc-modal-wrapper\");\n\tif(tiddler.fields && tiddler.fields.class) {\n\t\t$tw.utils.addClass(wrapper,tiddler.fields.class);\n\t}\n\t$tw.utils.addClass(modalBackdrop,\"tc-modal-backdrop\");\n\t$tw.utils.addClass(modalWrapper,\"tc-modal\");\n\t$tw.utils.addClass(modalHeader,\"tc-modal-header\");\n\t$tw.utils.addClass(modalBody,\"tc-modal-body\");\n\t$tw.utils.addClass(modalFooter,\"tc-modal-footer\");\n\t// Join them together\n\twrapper.appendChild(modalBackdrop);\n\twrapper.appendChild(modalWrapper);\n\tmodalHeader.appendChild(headerTitle);\n\tmodalWrapper.appendChild(modalHeader);\n\tmodalWrapper.appendChild(modalBody);\n\tmodalFooter.appendChild(modalFooterHelp);\n\tmodalFooter.appendChild(modalFooterButtons);\n\tmodalWrapper.appendChild(modalFooter);\n\tvar navigatorTree = {\n\t\t\"type\": \"navigator\",\n\t\t\"attributes\": {\n\t\t\t\"story\": {\n\t\t\t\t\"name\": \"story\",\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"value\": variables[\"tv-story-list\"]\n\t\t\t},\n\t\t\t\"history\": {\n\t\t\t\t\"name\": \"history\",\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"value\": variables[\"tv-history-list\"]\n\t\t\t}\n\t\t},\n\t\t\"tag\": \"$navigator\",\n\t\t\"isBlock\": true,\n\t\t\"children\": []\n\t};\n\tvar navigatorWidgetNode = new navigator.navigator(navigatorTree, {\n\t\twiki: this.wiki,\n\t\tdocument : this.srcDocument,\n\t\tparentWidget: $tw.rootWidget\n\t});\n\tnavigatorWidgetNode.render(modalBody,null);\n\t\n\t// Render the title of the message\n\tvar headerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"subtitle\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\tattributes: {\n\t\t\t\ttext: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title\n\t\t}}}],\n\t\tparentWidget: navigatorWidgetNode,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\theaderWidgetNode.render(headerTitle,null);\n\t// Render the body of the message\n\tvar bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: navigatorWidgetNode,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\n\tbodyWidgetNode.render(modalBody,null);\n\t// Setup the link if present\n\tif(options.downloadLink) {\n\t\tmodalLink.href = options.downloadLink;\n\t\tmodalLink.appendChild(this.srcDocument.createTextNode(\"Right-click to save changes\"));\n\t\tmodalBody.appendChild(modalLink);\n\t}\n\t// Render the footer of the message\n\tif(tiddler.fields && tiddler.fields.help) {\n\t\tvar link = this.srcDocument.createElement(\"a\");\n\t\tlink.setAttribute(\"href\",tiddler.fields.help);\n\t\tlink.setAttribute(\"target\",\"_blank\");\n\t\tlink.setAttribute(\"rel\",\"noopener noreferrer\");\n\t\tlink.appendChild(this.srcDocument.createTextNode(\"Help\"));\n\t\tmodalFooterHelp.appendChild(link);\n\t\tmodalFooterHelp.style.float = \"left\";\n\t}\n\tvar footerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"footer\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"button\",\n\t\t\tattributes: {\n\t\t\t\tmessage: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: \"tm-close-tiddler\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\tattributes: {\n\t\t\t\t\ttext: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tvalue: $tw.language.getString(\"Buttons/Close/Caption\")\n\t\t\t}}}\n\t\t]}],\n\t\tparentWidget: navigatorWidgetNode,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\tfooterWidgetNode.render(modalFooterButtons,null);\n\t// Set up the refresh handler\n\trefreshHandler = function(changes) {\n\t\theaderWidgetNode.refresh(changes,modalHeader,null);\n\t\tbodyWidgetNode.refresh(changes,modalBody,null);\n\t\tfooterWidgetNode.refresh(changes,modalFooterButtons,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Add the close event handler\n\tvar closeHandler = function(event) {\n\t\t// Remove our refresh handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Decrease the modal count and adjust the body class\n\t\tself.modalCount--;\n\t\tself.adjustPageClass();\n\t\t// Force layout and animate the modal message away\n\t\t$tw.utils.forceLayout(modalBackdrop);\n\t\t$tw.utils.forceLayout(modalWrapper);\n\t\t$tw.utils.setStyle(modalBackdrop,[\n\t\t\t{opacity: \"0\"}\n\t\t]);\n\t\t$tw.utils.setStyle(modalWrapper,[\n\t\t\t{transform: \"translateY(\" + self.srcWindow.innerHeight + \"px)\"}\n\t\t]);\n\t\t// Set up an event for the transition end\n\t\tself.srcWindow.setTimeout(function() {\n\t\t\tif(wrapper.parentNode) {\n\t\t\t\t// Remove the modal message from the DOM\n\t\t\t\tself.srcDocument.body.removeChild(wrapper);\n\t\t\t}\n\t\t},duration);\n\t\t// Don't let anyone else handle the tm-close-tiddler message\n\t\treturn false;\n\t};\n\theaderWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tbodyWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tfooterWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\t// Set the initial styles for the message\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-this.srcWindow.innerHeight) + \"px)\"}\n\t]);\n\t// Put the message into the document\n\tthis.srcDocument.body.appendChild(wrapper);\n\t// Set up animation for the styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{transition: \"opacity \" + duration + \"ms ease-out\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(modalBackdrop);\n\t$tw.utils.forceLayout(modalWrapper);\n\t// Set final animated styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0.7\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n};\n\nModal.prototype.adjustPageClass = function() {\n\tvar windowContainer = $tw.pageContainer ? ($tw.pageContainer === this.srcDocument.body.firstChild ? $tw.pageContainer : this.srcDocument.body.firstChild) : null;\n\tif(windowContainer) {\n\t\t$tw.utils.toggleClass(windowContainer,\"tc-modal-displayed\",this.modalCount > 0);\n\t}\n};\n\nexports.Modal = Modal;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/notifier.js": {
"title": "$:/core/modules/utils/dom/notifier.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/notifier.js\ntype: application/javascript\nmodule-type: utils\n\nNotifier mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar Notifier = function(wiki) {\n\tthis.wiki = wiki;\n};\n\n/*\nDisplay a notification\n\ttitle: Title of tiddler containing the notification text\n\toptions: see below\nOptions include:\n*/\nNotifier.prototype.display = function(title,options) {\n\toptions = options || {};\n\t// Create the wrapper divs\n\tvar self = this,\n\t\tnotification = document.createElement(\"div\"),\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\trefreshHandler;\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Add classes\n\t$tw.utils.addClass(notification,\"tc-notification\");\n\t// Create the variables\n\tvar variables = $tw.utils.extend({currentTiddler: title},options.variables);\n\t// Render the body of the notification\n\tvar widgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: document,\n\t\tvariables: variables,\n\t\timportPageMacros: true});\n\twidgetNode.render(notification,null);\n\trefreshHandler = function(changes) {\n\t\twidgetNode.refresh(changes,notification,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Set the initial styles for the notification\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"0\"},\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-window.innerHeight) + \"px)\"},\n\t\t{transition: \"opacity \" + duration + \"ms ease-out, \" + $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Add the notification to the DOM\n\tdocument.body.appendChild(notification);\n\t// Force layout\n\t$tw.utils.forceLayout(notification);\n\t// Set final animated styles\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n\t// Set a timer to remove the notification\n\twindow.setTimeout(function() {\n\t\t// Remove our change event handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Force layout and animate the notification away\n\t\t$tw.utils.forceLayout(notification);\n\t\t$tw.utils.setStyle(notification,[\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transform: \"translateX(\" + (notification.offsetWidth) + \"px)\"}\n\t\t]);\n\t\t// Remove the modal message from the DOM once the transition ends\n\t\tsetTimeout(function() {\n\t\t\tif(notification.parentNode) {\n\t\t\t\tdocument.body.removeChild(notification);\n\t\t\t}\n\t\t},duration);\n\t},$tw.config.preferences.notificationDuration);\n};\n\nexports.Notifier = Notifier;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/popup.js": {
"title": "$:/core/modules/utils/dom/popup.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/popup.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Popup object prototype that manages popups in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreates a Popup object with these options:\n\trootElement: the DOM element to which the popup zapper should be attached\n*/\nvar Popup = function(options) {\n\toptions = options || {};\n\tthis.rootElement = options.rootElement || document.documentElement;\n\tthis.popups = []; // Array of {title:,wiki:,domNode:} objects\n};\n\n/*\nTrigger a popup open or closed. Parameters are in a hashmap:\n\ttitle: title of the tiddler where the popup details are stored\n\tdomNode: dom node to which the popup will be positioned (one of domNode or domNodeRect is required)\n\tdomNodeRect: rectangle to which the popup will be positioned\n\twiki: wiki\n\tforce: if specified, forces the popup state to true or false (instead of toggling it)\n\tfloating: if true, skips registering the popup, meaning that it will need manually clearing\n*/\nPopup.prototype.triggerPopup = function(options) {\n\t// Check if this popup is already active\n\tvar index = this.findPopup(options.title);\n\t// Compute the new state\n\tvar state = index === -1;\n\tif(options.force !== undefined) {\n\t\tstate = options.force;\n\t}\n\t// Show or cancel the popup according to the new state\n\tif(state) {\n\t\tthis.show(options);\n\t} else {\n\t\tthis.cancel(index);\n\t}\n};\n\nPopup.prototype.findPopup = function(title) {\n\tvar index = -1;\n\tfor(var t=0; t<this.popups.length; t++) {\n\t\tif(this.popups[t].title === title) {\n\t\t\tindex = t;\n\t\t}\n\t}\n\treturn index;\n};\n\nPopup.prototype.handleEvent = function(event) {\n\tif(event.type === \"click\") {\n\t\t// Find out what was clicked on\n\t\tvar info = this.popupInfo(event.target),\n\t\t\tcancelLevel = info.popupLevel - 1;\n\t\t// Don't remove the level that was clicked on if we clicked on a handle\n\t\tif(info.isHandle) {\n\t\t\tcancelLevel++;\n\t\t}\n\t\t// Cancel\n\t\tthis.cancel(cancelLevel);\n\t}\n};\n\n/*\nFind the popup level containing a DOM node. Returns:\npopupLevel: count of the number of nested popups containing the specified element\nisHandle: true if the specified element is within a popup handle\n*/\nPopup.prototype.popupInfo = function(domNode) {\n\tvar isHandle = false,\n\t\tpopupCount = 0,\n\t\tnode = domNode;\n\t// First check ancestors to see if we're within a popup handle\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup-handle\")) {\n\t\t\tisHandle = true;\n\t\t\tpopupCount++;\n\t\t}\n\t\tif($tw.utils.hasClass(node,\"tc-popup-keep\")) {\n\t\t\tisHandle = true;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\t// Then count the number of ancestor popups\n\tnode = domNode;\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup\")) {\n\t\t\tpopupCount++;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\tvar info = {\n\t\tpopupLevel: popupCount,\n\t\tisHandle: isHandle\n\t};\n\treturn info;\n};\n\n/*\nDisplay a popup by adding it to the stack\n*/\nPopup.prototype.show = function(options) {\n\t// Find out what was clicked on\n\tvar info = this.popupInfo(options.domNode);\n\t// Cancel any higher level popups\n\tthis.cancel(info.popupLevel);\n\n\t// Store the popup details if not already there\n\tif(!options.floating && this.findPopup(options.title) === -1) {\n\t\tthis.popups.push({\n\t\t\ttitle: options.title,\n\t\t\twiki: options.wiki,\n\t\t\tdomNode: options.domNode,\n\t\t\tnoStateReference: options.noStateReference\n\t\t});\n\t}\n\t// Set the state tiddler\n\tvar rect;\n\tif(options.domNodeRect) {\n\t\trect = options.domNodeRect;\n\t} else {\n\t\trect = {\n\t\t\tleft: options.domNode.offsetLeft,\n\t\t\ttop: options.domNode.offsetTop,\n\t\t\twidth: options.domNode.offsetWidth,\n\t\t\theight: options.domNode.offsetHeight\n\t\t};\n\t}\n\tvar popupRect = \"(\" + rect.left + \",\" + rect.top + \",\" + \n\t\t\t\trect.width + \",\" + rect.height + \")\";\n\tif(options.noStateReference) {\n\t\toptions.wiki.setText(options.title,\"text\",undefined,popupRect);\n\t} else {\n\t\toptions.wiki.setTextReference(options.title,popupRect);\n\t}\n\t// Add the click handler if we have any popups\n\tif(this.popups.length > 0) {\n\t\tthis.rootElement.addEventListener(\"click\",this,true);\t\t\n\t}\n};\n\n/*\nCancel all popups at or above a specified level or DOM node\nlevel: popup level to cancel (0 cancels all popups)\n*/\nPopup.prototype.cancel = function(level) {\n\tvar numPopups = this.popups.length;\n\tlevel = Math.max(0,Math.min(level,numPopups));\n\tfor(var t=level; t<numPopups; t++) {\n\t\tvar popup = this.popups.pop();\n\t\tif(popup.title) {\n\t\t\tif(popup.noStateReference) {\n\t\t\t\tpopup.wiki.deleteTiddler(popup.title);\n\t\t\t} else {\n\t\t\t\tpopup.wiki.deleteTiddler($tw.utils.parseTextReference(popup.title).title);\n \t\t}\n\t\t}\n\t}\n\tif(this.popups.length === 0) {\n\t\tthis.rootElement.removeEventListener(\"click\",this,false);\n\t}\n};\n\n/*\nReturns true if the specified title and text identifies an active popup\n*/\nPopup.prototype.readPopupState = function(text) {\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/;\n\treturn popupLocationRegExp.test(text);\n};\n\nexports.Popup = Popup;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/scroller.js": {
"title": "$:/core/modules/utils/dom/scroller.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/scroller.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Scroller object prototype that manages scrolling in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nEvent handler for when the `tm-scroll` event hits the document body\n*/\nvar PageScroller = function() {\n\tthis.idRequestFrame = null;\n\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\twindow.webkitRequestAnimationFrame ||\n\t\twindow.mozRequestAnimationFrame ||\n\t\tfunction(callback) {\n\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t};\n\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\twindow.webkitCancelAnimationFrame ||\n\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\twindow.mozCancelAnimationFrame ||\n\t\twindow.mozCancelRequestAnimationFrame ||\n\t\tfunction(id) {\n\t\t\twindow.clearTimeout(id);\n\t\t};\n};\n\nPageScroller.prototype.isScrolling = function() {\n\treturn this.idRequestFrame !== null;\n}\n\nPageScroller.prototype.cancelScroll = function(srcWindow) {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(srcWindow,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle an event\n*/\nPageScroller.prototype.handleEvent = function(event) {\n\tif(event.type === \"tm-scroll\") {\n\t\tif(event.paramObject && event.paramObject.selector) {\n\t\t\tthis.scrollSelectorIntoView(null,event.paramObject.selector);\n\t\t} else {\n\t\t\tthis.scrollIntoView(event.target);\t\t\t\n\t\t}\n\t\treturn false; // Event was handled\n\t}\n\treturn true;\n};\n\n/*\nHandle a scroll event hitting the page document\n*/\nPageScroller.prototype.scrollIntoView = function(element,callback) {\n\tvar self = this,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t srcWindow = element ? element.ownerDocument.defaultView : window;\n\t// Now get ready to scroll the body\n\tthis.cancelScroll(srcWindow);\n\tthis.startTime = Date.now();\n\t// Get the height of any position:fixed toolbars\n\tvar toolbar = srcWindow.document.querySelector(\".tc-adjust-top-of-scroll\"),\n\t\toffset = 0;\n\tif(toolbar) {\n\t\toffset = toolbar.offsetHeight;\n\t}\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar getBounds = function() {\n\t\t\tvar clientBounds = typeof callback === 'function' ? callback() : element.getBoundingClientRect(),\n\t\t\t\tscrollPosition = $tw.utils.getScrollPosition(srcWindow);\n\t\t\treturn {\n\t\t\t\tleft: clientBounds.left + scrollPosition.x,\n\t\t\t\ttop: clientBounds.top + scrollPosition.y - offset,\n\t\t\t\twidth: clientBounds.width,\n\t\t\t\theight: clientBounds.height\n\t\t\t};\n\t\t},\n\t\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\t\t// targetPos/targetSize - position and size of the target element\n\t\t// currentPos/currentSize - position and size of the current scroll viewport\n\t\t// returns: new position of the scroll viewport\n\t\tgetEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\tvar newPos = targetPos;\n\t\t\t// If we are scrolling within 50 pixels of the top/left then snap to zero\n\t\t\tif(newPos < 50) {\n\t\t\t\tnewPos = 0;\n\t\t\t}\n\t\t\treturn newPos;\n\t\t},\n\t\tdrawFrame = function drawFrame() {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\t\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll(srcWindow);\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tvar scrollPosition = $tw.utils.getScrollPosition(srcWindow),\n\t\t\t\tbounds = getBounds(),\n\t\t\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,srcWindow.innerWidth),\n\t\t\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,srcWindow.innerHeight);\n\t\t\tsrcWindow.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t);\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);\n\t\t\t}\n\t\t};\n\tdrawFrame();\n};\n\nPageScroller.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {\n\tbaseElement = baseElement || document.body;\n\tvar element = baseElement.querySelector(selector);\n\tif(element) {\n\t\tthis.scrollIntoView(element,callback);\t\t\n\t}\n};\n\nexports.PageScroller = PageScroller;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/edition-info.js": {
"title": "$:/core/modules/utils/edition-info.js",
"text": "/*\\\ntitle: $:/core/modules/utils/edition-info.js\ntype: application/javascript\nmodule-type: utils-node\n\nInformation about the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\nvar editionInfo;\n\nexports.getEditionInfo = function() {\n\tif(!editionInfo) {\n\t\t// Enumerate the edition paths\n\t\tvar editionPaths = $tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar);\n\t\teditionInfo = {};\n\t\tfor(var editionIndex=0; editionIndex<editionPaths.length; editionIndex++) {\n\t\t\tvar editionPath = editionPaths[editionIndex];\n\t\t\t// Enumerate the folders\n\t\t\tvar entries = fs.readdirSync(editionPath);\n\t\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\t\tvar entry = entries[entryIndex];\n\t\t\t\t// Check if directories have a valid tiddlywiki.info\n\t\t\t\tif(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {\n\t\t\t\t\tvar info;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tinfo = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,\"tiddlywiki.info\"),\"utf8\"));\n\t\t\t\t\t} catch(ex) {\n\t\t\t\t\t}\n\t\t\t\t\tif(info) {\n\t\t\t\t\t\teditionInfo[entry] = info;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn editionInfo;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils-node"
},
"$:/core/modules/utils/fakedom.js": {
"title": "$:/core/modules/utils/fakedom.js",
"text": "/*\\\ntitle: $:/core/modules/utils/fakedom.js\ntype: application/javascript\nmodule-type: global\n\nA barebones implementation of DOM interfaces needed by the rendering mechanism.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Sequence number used to enable us to track objects for testing\nvar sequenceNumber = null;\n\nvar bumpSequenceNumber = function(object) {\n\tif(sequenceNumber !== null) {\n\t\tobject.sequenceNumber = sequenceNumber++;\n\t}\n};\n\nvar TW_Node = function (){\n\tthrow TypeError(\"Illegal constructor\");\n};\n\nObject.defineProperty(TW_Node.prototype, 'ELEMENT_NODE', {\n\tget: function() {\n\t\treturn 1;\n\t}\n});\n\nObject.defineProperty(TW_Node.prototype, 'TEXT_NODE', {\n\tget: function() {\n\t\treturn 3;\n\t}\n});\n\nvar TW_TextNode = function(text) {\n\tbumpSequenceNumber(this);\n\tthis.textContent = text + \"\";\n};\n\nTW_TextNode.prototype = Object.create(TW_Node.prototype);\n\nObject.defineProperty(TW_TextNode.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn this.TEXT_NODE;\n\t}\n});\n\nObject.defineProperty(TW_TextNode.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\treturn this.textContent.replace(/(\\r?\\n)/g,\"\");\n\t}\n});\n\nvar TW_Element = function(tag,namespace) {\n\tbumpSequenceNumber(this);\n\tthis.isTiddlyWikiFakeDom = true;\n\tthis.tag = tag;\n\tthis.attributes = {};\n\tthis.isRaw = false;\n\tthis.children = [];\n\tthis._style = {};\n\tthis.namespaceURI = namespace || \"http://www.w3.org/1999/xhtml\";\n};\n\nTW_Element.prototype = Object.create(TW_Node.prototype);\n\nObject.defineProperty(TW_Element.prototype, \"style\", {\n\tget: function() {\n\t\treturn this._style;\n\t},\n\tset: function(str) {\n\t\tvar self = this;\n\t\tstr = str || \"\";\n\t\t$tw.utils.each(str.split(\";\"),function(declaration) {\n\t\t\tvar parts = declaration.split(\":\"),\n\t\t\t\tname = $tw.utils.trim(parts[0]),\n\t\t\t\tvalue = $tw.utils.trim(parts[1]);\n\t\t\tif(name && value) {\n\t\t\t\tself._style[$tw.utils.convertStyleNameToPropertyName(name)] = value;\n\t\t\t}\n\t\t});\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn this.ELEMENT_NODE;\n\t}\n});\n\nTW_Element.prototype.getAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot getAttribute on a raw TW_Element\";\n\t}\n\treturn this.attributes[name];\n};\n\nTW_Element.prototype.setAttribute = function(name,value) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot setAttribute on a raw TW_Element\";\n\t}\n\tthis.attributes[name] = value + \"\";\n};\n\nTW_Element.prototype.setAttributeNS = function(namespace,name,value) {\n\tthis.setAttribute(name,value);\n};\n\nTW_Element.prototype.removeAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot removeAttribute on a raw TW_Element\";\n\t}\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\tdelete this.attributes[name];\n\t}\n};\n\nTW_Element.prototype.appendChild = function(node) {\n\tthis.children.push(node);\n\tnode.parentNode = this;\n};\n\nTW_Element.prototype.insertBefore = function(node,nextSibling) {\n\tif(nextSibling) {\n\t\tvar p = this.children.indexOf(nextSibling);\n\t\tif(p !== -1) {\n\t\t\tthis.children.splice(p,0,node);\n\t\t\tnode.parentNode = this;\n\t\t} else {\n\t\t\tthis.appendChild(node);\n\t\t}\n\t} else {\n\t\tthis.appendChild(node);\n\t}\n};\n\nTW_Element.prototype.removeChild = function(node) {\n\tvar p = this.children.indexOf(node);\n\tif(p !== -1) {\n\t\tthis.children.splice(p,1);\n\t}\n};\n\nTW_Element.prototype.hasChildNodes = function() {\n\treturn !!this.children.length;\n};\n\nObject.defineProperty(TW_Element.prototype, \"childNodes\", {\n\tget: function() {\n\t\treturn this.children;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"firstChild\", {\n\tget: function() {\n\t\treturn this.children[0];\n\t}\n});\n\nTW_Element.prototype.addEventListener = function(type,listener,useCapture) {\n\t// Do nothing\n};\n\nObject.defineProperty(TW_Element.prototype, \"tagName\", {\n\tget: function() {\n\t\treturn this.tag || \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"className\", {\n\tget: function() {\n\t\treturn this.attributes[\"class\"] || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes[\"class\"] = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"value\", {\n\tget: function() {\n\t\treturn this.attributes.value || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes.value = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"outerHTML\", {\n\tget: function() {\n\t\tvar output = [],attr,a,v;\n\t\toutput.push(\"<\",this.tag);\n\t\tif(this.attributes) {\n\t\t\tattr = [];\n\t\t\tfor(a in this.attributes) {\n\t\t\t\tattr.push(a);\n\t\t\t}\n\t\t\tattr.sort();\n\t\t\tfor(a=0; a<attr.length; a++) {\n\t\t\t\tv = this.attributes[attr[a]];\n\t\t\t\tif(v !== undefined) {\n\t\t\t\t\toutput.push(\" \",attr[a],\"=\\\"\",$tw.utils.htmlEncode(v),\"\\\"\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(this._style) {\n\t\t\tvar style = [];\n\t\t\tfor(var s in this._style) {\n\t\t\t\tstyle.push($tw.utils.convertPropertyNameToStyleName(s) + \":\" + this._style[s] + \";\");\n\t\t\t}\n\t\t\tif(style.length > 0) {\n\t\t\t\toutput.push(\" style=\\\"\",style.join(\"\"),\"\\\"\");\n\t\t\t}\n\t\t}\n\t\toutput.push(\">\");\n\t\tif($tw.config.htmlVoidElements.indexOf(this.tag) === -1) {\n\t\t\toutput.push(this.innerHTML);\n\t\t\toutput.push(\"</\",this.tag,\">\");\n\t\t}\n\t\treturn output.join(\"\");\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"innerHTML\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn this.rawHTML;\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tif(node instanceof TW_Element) {\n\t\t\t\t\tb.push(node.outerHTML);\n\t\t\t\t} else if(node instanceof TW_TextNode) {\n\t\t\t\t\tb.push($tw.utils.htmlEncode(node.textContent));\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.isRaw = true;\n\t\tthis.rawHTML = value;\n\t\tthis.rawTextContent = null;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textInnerHTML\", {\n\tset: function(value) {\n\t\tif(this.isRaw) {\n\t\t\tthis.rawTextContent = value;\n\t\t} else {\n\t\t\tthrow \"Cannot set textInnerHTML of a non-raw TW_Element\";\n\t\t}\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\tif(this.rawTextContent === null) {\n\t\t\t\treturn \"\";\n\t\t\t} else {\n\t\t\t\treturn this.rawTextContent;\n\t\t\t}\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.textContent);\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.children = [new TW_TextNode(value)];\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn \"\";\n\t\t} else {\n\t\t\tvar b = [],\n\t\t\t\tisBlock = $tw.config.htmlBlockElements.indexOf(this.tag) !== -1;\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\tif(this.tag === \"li\") {\n\t\t\t\tb.push(\"* \");\n\t\t\t}\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.formattedTextContent);\n\t\t\t});\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\treturn b.join(\"\");\n\t\t}\n\t}\n});\n\nvar document = {\n\tsetSequenceNumber: function(value) {\n\t\tsequenceNumber = value;\n\t},\n\tcreateElementNS: function(namespace,tag) {\n\t\treturn new TW_Element(tag,namespace);\n\t},\n\tcreateElement: function(tag) {\n\t\treturn new TW_Element(tag);\n\t},\n\tcreateTextNode: function(text) {\n\t\treturn new TW_TextNode(text);\n\t},\n\tcompatMode: \"CSS1Compat\", // For KaTeX to know that we're not a browser in quirks mode\n\tisTiddlyWikiFakeDom: true\n};\n\nexports.fakeDocument = document;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/utils/filesystem.js": {
"title": "$:/core/modules/utils/filesystem.js",
"text": "/*\\\ntitle: $:/core/modules/utils/filesystem.js\ntype: application/javascript\nmodule-type: utils-node\n\nFile system utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\n/*\nReturn the subdirectories of a path\n*/\nexports.getSubdirectories = function(dirPath) {\n\tif(!$tw.utils.isDirectory(dirPath)) {\n\t\treturn null;\n\t}\n\tvar subdirs = [];\n\t$tw.utils.each(fs.readdirSync(dirPath),function(item) {\n\t\tif($tw.utils.isDirectory(path.resolve(dirPath,item))) {\n\t\t\tsubdirs.push(item);\n\t\t}\n\t});\n\treturn subdirs;\n}\n\n/*\nRecursively (and synchronously) copy a directory and all its content\n*/\nexports.copyDirectory = function(srcPath,dstPath) {\n\t// Remove any trailing path separators\n\tsrcPath = path.resolve($tw.utils.removeTrailingSeparator(srcPath));\n\tdstPath = path.resolve($tw.utils.removeTrailingSeparator(dstPath));\n\t// Check that neither director is within the other\n\tif(srcPath.substring(0,dstPath.length) === dstPath || dstPath.substring(0,srcPath.length) === srcPath) {\n\t\treturn \"Cannot copy nested directories\";\n\t}\n\t// Create the destination directory\n\tvar err = $tw.utils.createDirectory(dstPath);\n\tif(err) {\n\t\treturn err;\n\t}\n\t// Function to copy a folder full of files\n\tvar copy = function(srcPath,dstPath) {\n\t\tvar srcStats = fs.lstatSync(srcPath),\n\t\t\tdstExists = fs.existsSync(dstPath);\n\t\tif(srcStats.isFile()) {\n\t\t\t$tw.utils.copyFile(srcPath,dstPath);\n\t\t} else if(srcStats.isDirectory()) {\n\t\t\tvar items = fs.readdirSync(srcPath);\n\t\t\tfor(var t=0; t<items.length; t++) {\n\t\t\t\tvar item = items[t],\n\t\t\t\t\terr = copy(srcPath + path.sep + item,dstPath + path.sep + item);\n\t\t\t\tif(err) {\n\t\t\t\t\treturn err;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\tcopy(srcPath,dstPath);\n\treturn null;\n};\n\n/*\nCopy a file\n*/\nvar FILE_BUFFER_LENGTH = 64 * 1024,\n\tfileBuffer;\n\nexports.copyFile = function(srcPath,dstPath) {\n\t// Create buffer if required\n\tif(!fileBuffer) {\n\t\tfileBuffer = Buffer.alloc(FILE_BUFFER_LENGTH);\n\t}\n\t// Create any directories in the destination\n\t$tw.utils.createDirectory(path.dirname(dstPath));\n\t// Copy the file\n\tvar srcFile = fs.openSync(srcPath,\"r\"),\n\t\tdstFile = fs.openSync(dstPath,\"w\"),\n\t\tbytesRead = 1,\n\t\tpos = 0;\n\twhile (bytesRead > 0) {\n\t\tbytesRead = fs.readSync(srcFile,fileBuffer,0,FILE_BUFFER_LENGTH,pos);\n\t\tfs.writeSync(dstFile,fileBuffer,0,bytesRead);\n\t\tpos += bytesRead;\n\t}\n\tfs.closeSync(srcFile);\n\tfs.closeSync(dstFile);\n\treturn null;\n};\n\n/*\nRemove trailing path separator\n*/\nexports.removeTrailingSeparator = function(dirPath) {\n\tvar len = dirPath.length;\n\tif(dirPath.charAt(len-1) === path.sep) {\n\t\tdirPath = dirPath.substr(0,len-1);\n\t}\n\treturn dirPath;\n};\n\n/*\nRecursively create a directory\n*/\nexports.createDirectory = function(dirPath) {\n\tif(dirPath.substr(dirPath.length-1,1) !== path.sep) {\n\t\tdirPath = dirPath + path.sep;\n\t}\n\tvar pos = 1;\n\tpos = dirPath.indexOf(path.sep,pos);\n\twhile(pos !== -1) {\n\t\tvar subDirPath = dirPath.substr(0,pos);\n\t\tif(!$tw.utils.isDirectory(subDirPath)) {\n\t\t\ttry {\n\t\t\t\tfs.mkdirSync(subDirPath);\n\t\t\t} catch(e) {\n\t\t\t\treturn \"Error creating directory '\" + subDirPath + \"'\";\n\t\t\t}\n\t\t}\n\t\tpos = dirPath.indexOf(path.sep,pos + 1);\n\t}\n\treturn null;\n};\n\n/*\nRecursively create directories needed to contain a specified file\n*/\nexports.createFileDirectories = function(filePath) {\n\treturn $tw.utils.createDirectory(path.dirname(filePath));\n};\n\n/*\nRecursively delete a directory\n*/\nexports.deleteDirectory = function(dirPath) {\n\tif(fs.existsSync(dirPath)) {\n\t\tvar entries = fs.readdirSync(dirPath);\n\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\tvar currPath = dirPath + path.sep + entries[entryIndex];\n\t\t\tif(fs.lstatSync(currPath).isDirectory()) {\n\t\t\t\t$tw.utils.deleteDirectory(currPath);\n\t\t\t} else {\n\t\t\t\tfs.unlinkSync(currPath);\n\t\t\t}\n\t\t}\n\tfs.rmdirSync(dirPath);\n\t}\n\treturn null;\n};\n\n/*\nCheck if a path identifies a directory\n*/\nexports.isDirectory = function(dirPath) {\n\treturn fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n};\n\n/*\nCheck if a path identifies a directory that is empty\n*/\nexports.isDirectoryEmpty = function(dirPath) {\n\tif(!$tw.utils.isDirectory(dirPath)) {\n\t\treturn false;\n\t}\n\tvar files = fs.readdirSync(dirPath),\n\t\tempty = true;\n\t$tw.utils.each(files,function(file,index) {\n\t\tif(file.charAt(0) !== \".\") {\n\t\t\tempty = false;\n\t\t}\n\t});\n\treturn empty;\n};\n\n/*\nRecursively delete a tree of empty directories\n*/\nexports.deleteEmptyDirs = function(dirpath,callback) {\n\tvar self = this;\n\tfs.readdir(dirpath,function(err,files) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\tif(files.length > 0) {\n\t\t\treturn callback(null);\n\t\t}\n\t\tfs.rmdir(dirpath,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.deleteEmptyDirs(path.dirname(dirpath),callback);\n\t\t});\n\t});\n};\n\n/*\nCreate a fileInfo object for saving a tiddler:\n\tfilepath: the absolute path to the file containing the tiddler\n\ttype: the type of the tiddler file on disk (NOT the type of the tiddler)\n\thasMetaFile: true if the file also has a companion .meta file\n\tisEditableFile: true if the tiddler was loaded via non-standard options & marked editable\nOptions include:\n\tdirectory: absolute path of root directory to which we are saving\n\tpathFilters: optional array of filters to be used to generate the base path\n\textFilters: optional array of filters to be used to generate the base path\n\twiki: optional wiki for evaluating the pathFilters,\n\tfileInfo: an existing fileInfo to check against\n\toriginalpath: a preferred filepath if no pathFilters match\n*/\nexports.generateTiddlerFileInfo = function(tiddler,options) {\n\tvar fileInfo = {}, metaExt;\n\t// Propagate the isEditableFile flag\n\tif(options.fileInfo) {\n\t\tfileInfo.isEditableFile = options.fileInfo.isEditableFile || false;\n\t}\n\t// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace\n\tvar hasUnsafeFields = false;\n\t$tw.utils.each(tiddler.getFieldStrings(),function(value,fieldName) {\n\t\tif(fieldName !== \"text\") {\n\t\t\thasUnsafeFields = hasUnsafeFields || /[\\x00-\\x1F]/mg.test(value);\n\t\t\thasUnsafeFields = hasUnsafeFields || ($tw.utils.trim(value) !== value);\n\t\t}\n\t});\n\t// Check for field values \n\tif(hasUnsafeFields) {\n\t\t// Save as a JSON file\n\t\tfileInfo.type = \"application/json\";\n\t\tfileInfo.hasMetaFile = false;\n\t} else {\n\t\t// Save as a .tid or a text/binary file plus a .meta file\n\t\tvar tiddlerType = tiddler.fields.type || \"text/vnd.tiddlywiki\";\n\t\tif(tiddlerType === \"text/vnd.tiddlywiki\") {\n\t\t\t// Save as a .tid file\n\t\t\tfileInfo.type = \"application/x-tiddler\";\n\t\t\tfileInfo.hasMetaFile = false;\n\t\t} else {\n\t\t\t// Save as a text/binary file and a .meta file\n\t\t\tfileInfo.type = tiddlerType;\n\t\t\tfileInfo.hasMetaFile = true;\n\t\t}\n\t\tif(options.extFilters) {\n\t\t\t// Check for extension override\n\t\t\tmetaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{\n\t\t\t\textFilters: options.extFilters,\n\t\t\t\twiki: options.wiki\n\t\t\t});\n\t\t\tif(metaExt){\n\t\t\t\tif(metaExt === \".tid\") {\n\t\t\t\t\t// Overriding to the .tid extension needs special handling\n\t\t\t\t\tfileInfo.type = \"application/x-tiddler\";\n\t\t\t\t\tfileInfo.hasMetaFile = false;\n\t\t\t\t} else if (metaExt === \".json\") {\n\t\t\t\t\t// Overriding to the .json extension needs special handling\n\t\t\t\t\tfileInfo.type = \"application/json\";\n\t\t\t\t\tfileInfo.hasMetaFile = false;\n\t\t\t\t} else {\n\t\t\t\t\t//If the new type matches a known extention, use that MIME type's encoding\n\t\t\t\t\tvar extInfo = $tw.utils.getFileExtensionInfo(metaExt);\n\t\t\t\t\tfileInfo.type = extInfo ? extInfo.type : null;\n\t\t\t\t\tfileInfo.encoding = $tw.utils.getTypeEncoding(metaExt);\n\t\t\t\t\tfileInfo.hasMetaFile = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Take the file extension from the tiddler content type or metaExt\n\tvar contentTypeInfo = $tw.config.contentTypeInfo[fileInfo.type] || {extension: \"\"};\n\t// Generate the filepath\n\tfileInfo.filepath = $tw.utils.generateTiddlerFilepath(tiddler.fields.title,{\n\t\textension: metaExt || contentTypeInfo.extension,\n\t\tdirectory: options.directory,\n\t\tpathFilters: options.pathFilters,\n\t\twiki: options.wiki,\n\t\tfileInfo: options.fileInfo,\n\t\toriginalpath: options.originalpath\n\t});\n\treturn fileInfo;\n};\n\n/*\nGenerate the file extension for saving a tiddler\nOptions include:\n\textFilters: optional array of filters to be used to generate the extention\n\twiki: optional wiki for evaluating the extFilters\n*/\nexports.generateTiddlerExtension = function(title,options) {\n\tvar self = this,\n\t\textension;\n\t// Check if any of the extFilters applies\n\tif(options.extFilters && options.wiki) { \n\t\t$tw.utils.each(options.extFilters,function(filter) {\n\t\t\tif(!extension) {\n\t\t\t\tvar source = options.wiki.makeTiddlerIterator([title]),\n\t\t\t\t\tresult = options.wiki.filterTiddlers(filter,null,source);\n\t\t\t\tif(result.length > 0) {\n\t\t\t\t\textension = result[0];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn extension;\n};\n\n/*\nGenerate the filepath for saving a tiddler\nOptions include:\n\textension: file extension to be added the finished filepath\n\tdirectory: absolute path of root directory to which we are saving\n\tpathFilters: optional array of filters to be used to generate the base path\n\twiki: optional wiki for evaluating the pathFilters\n\tfileInfo: an existing fileInfo object to check against\n*/\nexports.generateTiddlerFilepath = function(title,options) {\n\tvar self = this,\n\t\tdirectory = options.directory || \"\",\n\t\textension = options.extension || \"\",\n\t\toriginalpath = options.originalpath || \"\",\n\t\tfilepath;\t\n\t// Check if any of the pathFilters applies\n\tif(options.pathFilters && options.wiki) {\n\t\t$tw.utils.each(options.pathFilters,function(filter) {\n\t\t\tif(!filepath) {\n\t\t\t\tvar source = options.wiki.makeTiddlerIterator([title]),\n\t\t\t\t\tresult = options.wiki.filterTiddlers(filter,null,source);\n\t\t\t\tif(result.length > 0) {\n\t\t\t\t\tfilepath = result[0];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tif(!filepath && originalpath !== \"\") {\n\t\t//Use the originalpath without the extension\n\t\tvar ext = path.extname(originalpath);\n\t\tfilepath = originalpath.substring(0,originalpath.length - ext.length);\n\t} else if(!filepath) {\n\t\tfilepath = title;\n\t\t// If the filepath already ends in the extension then remove it\n\t\tif(filepath.substring(filepath.length - extension.length) === extension) {\n\t\t\tfilepath = filepath.substring(0,filepath.length - extension.length);\n\t\t}\n\t\t// Remove any forward or backward slashes so we don't create directories\n\t\tfilepath = filepath.replace(/\\/|\\\\/g,\"_\");\n\t}\n\t//If the path does not start with \".\" or \"..\" and a path seperator, then\n\tif(!/^\\.{1,2}[/\\\\]/g.test(filepath)) {\n\t\t// Don't let the filename start with any dots because such files are invisible on *nix\n\t\tfilepath = filepath.replace(/^\\.+/g,\"_\");\n\t}\n\t// Remove any characters that can't be used in cross-platform filenames\n\tfilepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\\:|\\\"|\\||\\?|\\*|\\^/g,\"_\"));\n\t// Truncate the filename if it is too long\n\tif(filepath.length > 200) {\n\t\tfilepath = filepath.substr(0,200);\n\t}\n\t// If the resulting filename is blank (eg because the title is just punctuation characters)\n\tif(!filepath) {\n\t\t// ...then just use the character codes of the title\n\t\tfilepath = \"\";\t\n\t\t$tw.utils.each(title.split(\"\"),function(char) {\n\t\t\tif(filepath) {\n\t\t\t\tfilepath += \"-\";\n\t\t\t}\n\t\t\tfilepath += char.charCodeAt(0).toString();\n\t\t});\n\t}\n\t// Add a uniquifier if the file already exists\n\tvar fullPath, oldPath = (options.fileInfo) ? options.fileInfo.filepath : undefined,\n\t\tcount = 0;\n\tdo {\n\t\tfullPath = path.resolve(directory,filepath + (count ? \"_\" + count : \"\") + extension);\n\t\tif(oldPath && oldPath == fullPath) {\n\t\t\tbreak;\n\t\t}\n\t\tcount++;\n\t} while(fs.existsSync(fullPath));\n\t// If the last write failed with an error, or if path does not start with:\n\t//\tthe resolved options.directory, the resolved wikiPath directory, or the wikiTiddlersPath directory, \n\t//\tthen encodeURIComponent() and resolve to tiddler directory\n\tvar newPath = fullPath,\n\t\tencode = (options.fileInfo || {writeError: false}).writeError == true;\n\tif(!encode){\n\t\tencode = !(fullPath.indexOf(path.resolve(directory)) == 0 ||\n\t\t\tfullPath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 ||\n\t\t\tfullPath.indexOf($tw.boot.wikiTiddlersPath) == 0);\n\t\t}\n\tif(encode){\n\t\tfullPath = path.resolve(directory, encodeURIComponent(fullPath));\n\t}\n\t// Call hook to allow plugins to modify the final path\n\tfullPath = $tw.hooks.invokeHook(\"th-make-tiddler-path\", newPath, fullPath);\n\t// Return the full path to the file\n\treturn fullPath;\n};\n\n/*\nSave a tiddler to a file described by the fileInfo:\n\tfilepath: the absolute path to the file containing the tiddler\n\ttype: the type of the tiddler file (NOT the type of the tiddler)\n\thasMetaFile: true if the file also has a companion .meta file\n*/\nexports.saveTiddlerToFile = function(tiddler,fileInfo,callback) {\n\t$tw.utils.createDirectory(path.dirname(fileInfo.filepath));\n\tif(fileInfo.hasMetaFile) {\n\t\t// Save the tiddler as a separate body and meta file\n\t\tvar typeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/plain\"] || {encoding: \"utf8\"};\n\t\tfs.writeFile(fileInfo.filepath,tiddler.fields.text,typeInfo.encoding,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tfs.writeFile(fileInfo.filepath + \".meta\",tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}),\"utf8\",callback);\n\t\t});\n\t} else {\n\t\t// Save the tiddler as a self contained templated file\n\t\tif(fileInfo.type === \"application/x-tiddler\") {\n\t\t\tfs.writeFile(fileInfo.filepath,tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}) + (!!tiddler.fields.text ? \"\\n\\n\" + tiddler.fields.text : \"\"),\"utf8\",callback);\n\t\t} else {\n\t\t\tfs.writeFile(fileInfo.filepath,JSON.stringify([tiddler.getFieldStrings({exclude: [\"bag\"]})],null,$tw.config.preferences.jsonSpaces),\"utf8\",callback);\n\t\t}\n\t}\n};\n\n/*\nSave a tiddler to a file described by the fileInfo:\n\tfilepath: the absolute path to the file containing the tiddler\n\ttype: the type of the tiddler file (NOT the type of the tiddler)\n\thasMetaFile: true if the file also has a companion .meta file\n*/\nexports.saveTiddlerToFileSync = function(tiddler,fileInfo) {\n\t$tw.utils.createDirectory(path.dirname(fileInfo.filepath));\n\tif(fileInfo.hasMetaFile) {\n\t\t// Save the tiddler as a separate body and meta file\n\t\tvar typeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/plain\"] || {encoding: \"utf8\"};\n\t\tfs.writeFileSync(fileInfo.filepath,tiddler.fields.text,typeInfo.encoding);\n\t\tfs.writeFileSync(fileInfo.filepath + \".meta\",tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}),\"utf8\");\n\t} else {\n\t\t// Save the tiddler as a self contained templated file\n\t\tif(fileInfo.type === \"application/x-tiddler\") {\n\t\t\tfs.writeFileSync(fileInfo.filepath,tiddler.getFieldStringBlock({exclude: [\"text\",\"bag\"]}) + (!!tiddler.fields.text ? \"\\n\\n\" + tiddler.fields.text : \"\"),\"utf8\");\n\t\t} else {\n\t\t\tfs.writeFileSync(fileInfo.filepath,JSON.stringify([tiddler.getFieldStrings({exclude: [\"bag\"]})],null,$tw.config.preferences.jsonSpaces),\"utf8\");\n\t\t}\n\t}\n};\n\n/*\nDelete a file described by the fileInfo if it exits\n*/\nexports.deleteTiddlerFile = function(fileInfo, callback) {\n\t//Only attempt to delete files that exist on disk\n\tif(!fileInfo.filepath || !fs.existsSync(fileInfo.filepath)) {\n\t\treturn callback(null);\n\t}\n\t// Delete the file\n\tfs.unlink(fileInfo.filepath,function(err) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\t\n\t\t// Delete the metafile if present\n\t\tif(fileInfo.hasMetaFile && fs.existsSync(fileInfo.filepath + \".meta\")) {\n\t\t\tfs.unlink(fileInfo.filepath + \".meta\",function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\treturn $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),callback);\n\t\t\t});\n\t\t} else {\n\t\t\treturn $tw.utils.deleteEmptyDirs(path.dirname(fileInfo.filepath),callback);\n\t\t}\n\t});\n};\n\n/*\nCleanup old files on disk, by comparing the options values:\n\tadaptorInfo from $tw.syncer.tiddlerInfo\n\tbootInfo from $tw.boot.files\n*/\nexports.cleanupTiddlerFiles = function(options, callback) {\n\tvar adaptorInfo = options.adaptorInfo || {},\n\tbootInfo = options.bootInfo || {},\n\ttitle = options.title || \"undefined\";\n\tif(adaptorInfo.filepath && bootInfo.filepath && adaptorInfo.filepath !== bootInfo.filepath) {\n\t\treturn $tw.utils.deleteTiddlerFile(adaptorInfo, function(err){\n\t\t\tif(err) {\n\t\t\t\tif ((err.code == \"EPERM\" || err.code == \"EACCES\") && err.syscall == \"unlink\") {\n\t\t\t\t\t// Error deleting the previous file on disk, should fail gracefully\n\t\t\t\t\t$tw.syncer.displayError(\"Server desynchronized. Error cleaning up previous file for tiddler: \"+title, err);\n\t\t\t\t\treturn callback(null);\n\t\t\t\t} else {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn callback(null);\n\t\t});\n\t} else {\n\t\treturn callback(null);\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils-node"
},
"$:/core/modules/utils/linkedlist.js": {
"title": "$:/core/modules/utils/linkedlist.js",
"text": "/*\\\nmodule-type: utils\ntitle: $:/core/modules/utils/linkedlist.js\ntype: application/javascript\n\nThis is a doubly-linked indexed list intended for manipulation, particularly\npushTop, which it does with significantly better performance than an array.\n\n\\*/\n(function(){\n\nfunction LinkedList() {\n\tthis.clear();\n};\n\nLinkedList.prototype.clear = function() {\n\tthis.index = Object.create(null);\n\t// LinkedList performs the duty of both the head and tail node\n\tthis.next = this;\n\tthis.prev = this;\n\tthis.length = 0;\n};\n\nLinkedList.prototype.remove = function(value) {\n\tif($tw.utils.isArray(value)) {\n\t\tfor(var t=0; t<value.length; t++) {\n\t\t\t_removeOne(this,value[t]);\n\t\t}\n\t} else {\n\t\t_removeOne(this,value);\n\t}\n};\n\nLinkedList.prototype.push = function(/* values */) {\n\tfor(var i = 0; i < arguments.length; i++) {\n\t\tvar value = arguments[i];\n\t\tvar node = {value: value};\n\t\tvar preexistingNode = this.index[value];\n\t\t_linkToEnd(this,node);\n\t\tif(preexistingNode) {\n\t\t\t// We want to keep pointing to the first instance, but we want\n\t\t\t// to have that instance (or chain of instances) point to the\n\t\t\t// new one.\n\t\t\twhile (preexistingNode.copy) {\n\t\t\t\tpreexistingNode = preexistingNode.copy;\n\t\t\t}\n\t\t\tpreexistingNode.copy = node;\n\t\t} else {\n\t\t\tthis.index[value] = node;\n\t\t}\n\t}\n};\n\nLinkedList.prototype.pushTop = function(value) {\n\tif($tw.utils.isArray(value)) {\n\t\tfor(var t=0; t<value.length; t++) {\n\t\t\t_removeOne(this,value[t]);\n\t\t}\n\t\tthis.push.apply(this,value);\n\t} else {\n\t\tvar node = _removeOne(this,value);\n\t\tif(!node) {\n\t\t\tnode = {value: value};\n\t\t\tthis.index[value] = node;\n\t\t} else {\n\t\t\t// Put this node at the end of the copy chain.\n\t\t\tvar preexistingNode = node;\n\t\t\twhile(preexistingNode.copy) {\n\t\t\t\tpreexistingNode = preexistingNode.copy;\n\t\t\t}\n\t\t\t// The order of these three statements is important,\n\t\t\t// because sometimes preexistingNode == node.\n\t\t\tpreexistingNode.copy = node;\n\t\t\tthis.index[value] = node.copy;\n\t\t\tnode.copy = undefined;\n\t\t}\n\t\t_linkToEnd(this,node);\n\t}\n};\n\nLinkedList.prototype.each = function(callback) {\n\tfor(var ptr = this.next; ptr !== this; ptr = ptr.next) {\n\t\tcallback(ptr.value);\n\t}\n};\n\nLinkedList.prototype.toArray = function() {\n\tvar output = [];\n\tfor(var ptr = this.next; ptr !== this; ptr = ptr.next) {\n\t\toutput.push(ptr.value);\n\t}\n\treturn output;\n};\n\nfunction _removeOne(list,value) {\n\tvar node = list.index[value];\n\tif(node) {\n\t\tnode.prev.next = node.next;\n\t\tnode.next.prev = node.prev;\n\t\tlist.length -= 1;\n\t\t// Point index to the next instance of the same value, maybe nothing.\n\t\tlist.index[value] = node.copy;\n\t}\n\treturn node;\n};\n\nfunction _linkToEnd(list,node) {\n\t// Sticks the given node onto the end of the list.\n\tlist.prev.next = node;\n\tnode.prev = list.prev;\n\tlist.prev = node;\n\tnode.next = list;\n\tlist.length += 1;\n};\n\nexports.LinkedList = LinkedList;\n\n})();\n",
"module-type": "utils",
"type": "application/javascript"
},
"$:/core/modules/utils/logger.js": {
"title": "$:/core/modules/utils/logger.js",
"text": "/*\\\ntitle: $:/core/modules/utils/logger.js\ntype: application/javascript\nmodule-type: utils\n\nA basic logging implementation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ALERT_TAG = \"$:/tags/Alert\";\n\n/*\nMake a new logger\n*/\nfunction Logger(componentName,options) {\n\toptions = options || {};\n\tthis.componentName = componentName || \"\";\n\tthis.colour = options.colour || \"white\";\n\tthis.enable = \"enable\" in options ? options.enable : true;\n\tthis.save = \"save\" in options ? options.save : true;\n\tthis.saveLimit = options.saveLimit || 100 * 1024;\n\tthis.saveBufferLogger = this;\n\tthis.buffer = \"\";\n\tthis.alertCount = 0;\n}\n\nLogger.prototype.setSaveBuffer = function(logger) {\n\tthis.saveBufferLogger = logger;\n};\n\n/*\nLog a message\n*/\nLogger.prototype.log = function(/* args */) {\n\tvar self = this;\n\tif(this.enable) {\n\t\tif(this.saveBufferLogger.save) {\n\t\t\tthis.saveBufferLogger.buffer += $tw.utils.formatDateString(new Date(),\"YYYY MM DD 0hh:0mm:0ss.0XXX\") + \":\";\n\t\t\t$tw.utils.each(Array.prototype.slice.call(arguments,0),function(arg,index) {\n\t\t\t\tself.saveBufferLogger.buffer += \" \" + arg;\n\t\t\t});\n\t\t\tthis.saveBufferLogger.buffer += \"\\n\";\n\t\t\tthis.saveBufferLogger.buffer = this.saveBufferLogger.buffer.slice(-this.saveBufferLogger.saveLimit);\t\t\t\n\t\t}\n\t\tif(console !== undefined && console.log !== undefined) {\n\t\t\treturn Function.apply.call(console.log, console, [$tw.utils.terminalColour(this.colour),this.componentName + \":\"].concat(Array.prototype.slice.call(arguments,0)).concat($tw.utils.terminalColour()));\n\t\t}\n\t} \n};\n\n/*\nRead the message buffer\n*/\nLogger.prototype.getBuffer = function() {\n\treturn this.saveBufferLogger.buffer;\n};\n\n/*\nLog a structure as a table\n*/\nLogger.prototype.table = function(value) {\n\t(console.table || console.log)(value);\n};\n\n/*\nAlert a message\n*/\nLogger.prototype.alert = function(/* args */) {\n\tif(this.enable) {\n\t\t// Prepare the text of the alert\n\t\tvar text = Array.prototype.join.call(arguments,\" \");\n\t\t// Create alert tiddlers in the browser\n\t\tif($tw.browser) {\n\t\t\t// Check if there is an existing alert with the same text and the same component\n\t\t\tvar existingAlerts = $tw.wiki.getTiddlersWithTag(ALERT_TAG),\n\t\t\t\talertFields,\n\t\t\t\texistingCount,\n\t\t\t\tself = this;\n\t\t\t$tw.utils.each(existingAlerts,function(title) {\n\t\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\t\tif(tiddler.fields.text === text && tiddler.fields.component === self.componentName && tiddler.fields.modified && (!alertFields || tiddler.fields.modified < alertFields.modified)) {\n\t\t\t\t\t\talertFields = $tw.utils.extend({},tiddler.fields);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(alertFields) {\n\t\t\t\texistingCount = alertFields.count || 1;\n\t\t\t} else {\n\t\t\t\talertFields = {\n\t\t\t\t\ttitle: $tw.wiki.generateNewTitle(\"$:/temp/alerts/alert\",{prefix: \"\"}),\n\t\t\t\t\ttext: text,\n\t\t\t\t\ttags: [ALERT_TAG],\n\t\t\t\t\tcomponent: this.componentName\n\t\t\t\t};\n\t\t\t\texistingCount = 0;\n\t\t\t\tthis.alertCount += 1;\n\t\t\t}\n\t\t\talertFields.modified = new Date();\n\t\t\tif(++existingCount > 1) {\n\t\t\t\talertFields.count = existingCount;\n\t\t\t} else {\n\t\t\t\talertFields.count = undefined;\n\t\t\t}\n\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(alertFields));\n\t\t\t// Log the alert as well\n\t\t\tthis.log.apply(this,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\t// Print an orange message to the console if not in the browser\n\t\t\tconsole.error(\"\\x1b[1;33m\" + text + \"\\x1b[0m\");\n\t\t}\t\t\n\t}\n};\n\n/*\nClear outstanding alerts\n*/\nLogger.prototype.clearAlerts = function() {\n\tvar self = this;\n\tif($tw.browser && this.alertCount > 0) {\n\t\t$tw.utils.each($tw.wiki.getTiddlersWithTag(ALERT_TAG),function(title) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\tif(tiddler.fields.component === self.componentName) {\n\t\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t\t}\n\t\t});\n\t\tthis.alertCount = 0;\n\t}\n};\n\nexports.Logger = Logger;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/parsetree.js": {
"title": "$:/core/modules/utils/parsetree.js",
"text": "/*\\\ntitle: $:/core/modules/utils/parsetree.js\ntype: application/javascript\nmodule-type: utils\n\nParse tree utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.addAttributeToParseTreeNode = function(node,name,value) {\n\tnode.attributes = node.attributes || {};\n\tnode.attributes[name] = {type: \"string\", value: value};\n};\n\nexports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {\n\tif(node.attributes && node.attributes[name] && node.attributes[name].value !== undefined) {\n\t\treturn node.attributes[name].value;\n\t}\n\treturn defaultValue;\n};\n\nexports.addClassToParseTreeNode = function(node,classString) {\n\tvar classes = [];\n\tnode.attributes = node.attributes || {};\n\tnode.attributes[\"class\"] = node.attributes[\"class\"] || {type: \"string\", value: \"\"};\n\tif(node.attributes[\"class\"].type === \"string\") {\n\t\tif(node.attributes[\"class\"].value !== \"\") {\n\t\t\tclasses = node.attributes[\"class\"].value.split(\" \");\n\t\t}\n\t\tif(classString !== \"\") {\n\t\t\t$tw.utils.pushTop(classes,classString.split(\" \"));\n\t\t}\n\t\tnode.attributes[\"class\"].value = classes.join(\" \");\n\t}\n};\n\nexports.addStyleToParseTreeNode = function(node,name,value) {\n\t\tnode.attributes = node.attributes || {};\n\t\tnode.attributes.style = node.attributes.style || {type: \"string\", value: \"\"};\n\t\tif(node.attributes.style.type === \"string\") {\n\t\t\tnode.attributes.style.value += name + \":\" + value + \";\";\n\t\t}\n};\n\nexports.findParseTreeNode = function(nodeArray,search) {\n\tfor(var t=0; t<nodeArray.length; t++) {\n\t\tif(nodeArray[t].type === search.type && nodeArray[t].tag === search.tag) {\n\t\t\treturn nodeArray[t];\n\t\t}\n\t}\n\treturn undefined;\n};\n\n/*\nHelper to get the text of a parse tree node or array of nodes\n*/\nexports.getParseTreeText = function getParseTreeText(tree) {\n\tvar output = [];\n\tif($tw.utils.isArray(tree)) {\n\t\t$tw.utils.each(tree,function(node) {\n\t\t\toutput.push(getParseTreeText(node));\n\t\t});\n\t} else {\n\t\tif(tree.type === \"text\") {\n\t\t\toutput.push(tree.text);\n\t\t}\n\t\tif(tree.children) {\n\t\t\treturn getParseTreeText(tree.children);\n\t\t}\n\t}\n\treturn output.join(\"\");\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/performance.js": {
"title": "$:/core/modules/utils/performance.js",
"text": "/*\\\ntitle: $:/core/modules/utils/performance.js\ntype: application/javascript\nmodule-type: global\n\nPerformance measurement.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Performance(enabled) {\n\tthis.enabled = !!enabled;\n\tthis.measures = {}; // Hashmap by measurement name of {time:, invocations:}\n\tthis.logger = new $tw.utils.Logger(\"performance\");\n\tthis.showGreeting();\n}\n\nPerformance.prototype.showGreeting = function() {\n\tif($tw.browser) {\n\t\tthis.logger.log(\"Execute $tw.perf.log(); to see filter execution timings\");\t\t\n\t}\n};\n\n/*\nWrap performance reporting around a top level function\n*/\nPerformance.prototype.report = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments);\n\t\t\tself.logger.log(name + \": \" + $tw.utils.timer(startTime).toFixed(2) + \"ms\");\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\nPerformance.prototype.log = function() {\n\tvar self = this,\n\t\ttotalTime = 0,\n\t\torderedMeasures = Object.keys(this.measures).sort(function(a,b) {\n\t\t\tif(self.measures[a].time > self.measures[b].time) {\n\t\t\t\treturn -1;\n\t\t\t} else if (self.measures[a].time < self.measures[b].time) {\n\t\t\t\treturn + 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t});\n\t$tw.utils.each(orderedMeasures,function(name) {\n\t\ttotalTime += self.measures[name].time;\n\t});\n\tvar results = []\n\t$tw.utils.each(orderedMeasures,function(name) {\n\t\tvar measure = self.measures[name];\n\t\tresults.push({name: name,invocations: measure.invocations, avgTime: measure.time / measure.invocations, totalTime: measure.time, percentTime: (measure.time / totalTime) * 100})\n\t});\n\tself.logger.table(results);\n};\n\n/*\nWrap performance measurements around a subfunction\n*/\nPerformance.prototype.measure = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments);\n\t\t\tif(!(name in self.measures)) {\n\t\t\t\tself.measures[name] = {time: 0, invocations: 0};\n\t\t\t}\n\t\t\tself.measures[name].time += $tw.utils.timer(startTime);\n\t\t\tself.measures[name].invocations++;\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\nexports.Performance = Performance;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/utils/pluginmaker.js": {
"title": "$:/core/modules/utils/pluginmaker.js",
"text": "/*\\\ntitle: $:/core/modules/utils/pluginmaker.js\ntype: application/javascript\nmodule-type: utils\n\nA quick and dirty way to pack up plugins within the browser.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRepack a plugin, and then delete any non-shadow payload tiddlers\n*/\nexports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {\n\tadditionalTiddlers = additionalTiddlers || [];\n\texcludeTiddlers = excludeTiddlers || [];\n\t// Get the plugin tiddler\n\tvar pluginTiddler = $tw.wiki.getTiddler(title);\n\tif(!pluginTiddler) {\n\t\tthrow \"No such tiddler as \" + title;\n\t}\n\t// Extract the JSON\n\tvar jsonPluginTiddler;\n\ttry {\n\t\tjsonPluginTiddler = JSON.parse(pluginTiddler.fields.text);\n\t} catch(e) {\n\t\tthrow \"Cannot parse plugin tiddler \" + title + \"\\n\" + $tw.language.getString(\"Error/Caption\") + \": \" + e;\n\t}\n\t// Get the list of tiddlers\n\tvar tiddlers = Object.keys(jsonPluginTiddler.tiddlers);\n\t// Add the additional tiddlers\n\t$tw.utils.pushTop(tiddlers,additionalTiddlers);\n\t// Remove any excluded tiddlers\n\tfor(var t=tiddlers.length-1; t>=0; t--) {\n\t\tif(excludeTiddlers.indexOf(tiddlers[t]) !== -1) {\n\t\t\ttiddlers.splice(t,1);\n\t\t}\n\t}\n\t// Pack up the tiddlers into a block of JSON\n\tvar plugins = {};\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = $tw.wiki.getTiddler(title),\n\t\t\tfields = {};\n\t\t$tw.utils.each(tiddler.fields,function (value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\tplugins[title] = fields;\n\t});\n\t// Retrieve and bump the version number\n\tvar pluginVersion = $tw.utils.parseVersion(pluginTiddler.getFieldString(\"version\") || \"0.0.0\") || {\n\t\t\tmajor: \"0\",\n\t\t\tminor: \"0\",\n\t\t\tpatch: \"0\"\n\t\t};\n\tpluginVersion.patch++;\n\tvar version = pluginVersion.major + \".\" + pluginVersion.minor + \".\" + pluginVersion.patch;\n\tif(pluginVersion.prerelease) {\n\t\tversion += \"-\" + pluginVersion.prerelease;\n\t}\n\tif(pluginVersion.build) {\n\t\tversion += \"+\" + pluginVersion.build;\n\t}\n\t// Save the tiddler\n\t$tw.wiki.addTiddler(new $tw.Tiddler(pluginTiddler,{text: JSON.stringify({tiddlers: plugins},null,4), version: version}));\n\t// Delete any non-shadow constituent tiddlers\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tif($tw.wiki.tiddlerExists(title)) {\n\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t}\n\t});\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t// Return a heartwarming confirmation\n\treturn \"Plugin \" + title + \" successfully saved\";\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/transliterate.js": {
"title": "$:/core/modules/utils/transliterate.js",
"text": "/*\\\ntitle: $:/core/modules/utils/transliterate.js\ntype: application/javascript\nmodule-type: utils\n\nTransliteration static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nTransliterate string to ASCII\n\n(Some pairs taken from http://semplicewebsites.com/removing-accents-javascript)\n*/\nexports.transliterationPairs = {\n\t\"Á\":\"A\",\n\t\"Ă\":\"A\",\n\t\"Ắ\":\"A\",\n\t\"Ặ\":\"A\",\n\t\"Ằ\":\"A\",\n\t\"Ẳ\":\"A\",\n\t\"Ẵ\":\"A\",\n\t\"Ǎ\":\"A\",\n\t\"Â\":\"A\",\n\t\"Ấ\":\"A\",\n\t\"Ậ\":\"A\",\n\t\"Ầ\":\"A\",\n\t\"Ẩ\":\"A\",\n\t\"Ẫ\":\"A\",\n\t\"Ä\":\"A\",\n\t\"Ǟ\":\"A\",\n\t\"Ȧ\":\"A\",\n\t\"Ǡ\":\"A\",\n\t\"Ạ\":\"A\",\n\t\"Ȁ\":\"A\",\n\t\"À\":\"A\",\n\t\"Ả\":\"A\",\n\t\"Ȃ\":\"A\",\n\t\"Ā\":\"A\",\n\t\"Ą\":\"A\",\n\t\"Å\":\"A\",\n\t\"Ǻ\":\"A\",\n\t\"Ḁ\":\"A\",\n\t\"Ⱥ\":\"A\",\n\t\"Ã\":\"A\",\n\t\"Ꜳ\":\"AA\",\n\t\"Æ\":\"AE\",\n\t\"Ǽ\":\"AE\",\n\t\"Ǣ\":\"AE\",\n\t\"Ꜵ\":\"AO\",\n\t\"Ꜷ\":\"AU\",\n\t\"Ꜹ\":\"AV\",\n\t\"Ꜻ\":\"AV\",\n\t\"Ꜽ\":\"AY\",\n\t\"Ḃ\":\"B\",\n\t\"Ḅ\":\"B\",\n\t\"Ɓ\":\"B\",\n\t\"Ḇ\":\"B\",\n\t\"Ƀ\":\"B\",\n\t\"Ƃ\":\"B\",\n\t\"Ć\":\"C\",\n\t\"Č\":\"C\",\n\t\"Ç\":\"C\",\n\t\"Ḉ\":\"C\",\n\t\"Ĉ\":\"C\",\n\t\"Ċ\":\"C\",\n\t\"Ƈ\":\"C\",\n\t\"Ȼ\":\"C\",\n\t\"Ď\":\"D\",\n\t\"Ḑ\":\"D\",\n\t\"Ḓ\":\"D\",\n\t\"Ḋ\":\"D\",\n\t\"Ḍ\":\"D\",\n\t\"Ɗ\":\"D\",\n\t\"Ḏ\":\"D\",\n\t\"Dz\":\"D\",\n\t\"Dž\":\"D\",\n\t\"Đ\":\"D\",\n\t\"Ƌ\":\"D\",\n\t\"DZ\":\"DZ\",\n\t\"DŽ\":\"DZ\",\n\t\"É\":\"E\",\n\t\"Ĕ\":\"E\",\n\t\"Ě\":\"E\",\n\t\"Ȩ\":\"E\",\n\t\"Ḝ\":\"E\",\n\t\"Ê\":\"E\",\n\t\"Ế\":\"E\",\n\t\"Ệ\":\"E\",\n\t\"Ề\":\"E\",\n\t\"Ể\":\"E\",\n\t\"Ễ\":\"E\",\n\t\"Ḙ\":\"E\",\n\t\"Ë\":\"E\",\n\t\"Ė\":\"E\",\n\t\"Ẹ\":\"E\",\n\t\"Ȅ\":\"E\",\n\t\"È\":\"E\",\n\t\"Ẻ\":\"E\",\n\t\"Ȇ\":\"E\",\n\t\"Ē\":\"E\",\n\t\"Ḗ\":\"E\",\n\t\"Ḕ\":\"E\",\n\t\"Ę\":\"E\",\n\t\"Ɇ\":\"E\",\n\t\"Ẽ\":\"E\",\n\t\"Ḛ\":\"E\",\n\t\"Ꝫ\":\"ET\",\n\t\"Ḟ\":\"F\",\n\t\"Ƒ\":\"F\",\n\t\"Ǵ\":\"G\",\n\t\"Ğ\":\"G\",\n\t\"Ǧ\":\"G\",\n\t\"Ģ\":\"G\",\n\t\"Ĝ\":\"G\",\n\t\"Ġ\":\"G\",\n\t\"Ɠ\":\"G\",\n\t\"Ḡ\":\"G\",\n\t\"Ǥ\":\"G\",\n\t\"Ḫ\":\"H\",\n\t\"Ȟ\":\"H\",\n\t\"Ḩ\":\"H\",\n\t\"Ĥ\":\"H\",\n\t\"Ⱨ\":\"H\",\n\t\"Ḧ\":\"H\",\n\t\"Ḣ\":\"H\",\n\t\"Ḥ\":\"H\",\n\t\"Ħ\":\"H\",\n\t\"Í\":\"I\",\n\t\"Ĭ\":\"I\",\n\t\"Ǐ\":\"I\",\n\t\"Î\":\"I\",\n\t\"Ï\":\"I\",\n\t\"Ḯ\":\"I\",\n\t\"İ\":\"I\",\n\t\"Ị\":\"I\",\n\t\"Ȉ\":\"I\",\n\t\"Ì\":\"I\",\n\t\"Ỉ\":\"I\",\n\t\"Ȋ\":\"I\",\n\t\"Ī\":\"I\",\n\t\"Į\":\"I\",\n\t\"Ɨ\":\"I\",\n\t\"Ĩ\":\"I\",\n\t\"Ḭ\":\"I\",\n\t\"Ꝺ\":\"D\",\n\t\"Ꝼ\":\"F\",\n\t\"Ᵹ\":\"G\",\n\t\"Ꞃ\":\"R\",\n\t\"Ꞅ\":\"S\",\n\t\"Ꞇ\":\"T\",\n\t\"Ꝭ\":\"IS\",\n\t\"Ĵ\":\"J\",\n\t\"Ɉ\":\"J\",\n\t\"Ḱ\":\"K\",\n\t\"Ǩ\":\"K\",\n\t\"Ķ\":\"K\",\n\t\"Ⱪ\":\"K\",\n\t\"Ꝃ\":\"K\",\n\t\"Ḳ\":\"K\",\n\t\"Ƙ\":\"K\",\n\t\"Ḵ\":\"K\",\n\t\"Ꝁ\":\"K\",\n\t\"Ꝅ\":\"K\",\n\t\"Ĺ\":\"L\",\n\t\"Ƚ\":\"L\",\n\t\"Ľ\":\"L\",\n\t\"Ļ\":\"L\",\n\t\"Ḽ\":\"L\",\n\t\"Ḷ\":\"L\",\n\t\"Ḹ\":\"L\",\n\t\"Ⱡ\":\"L\",\n\t\"Ꝉ\":\"L\",\n\t\"Ḻ\":\"L\",\n\t\"Ŀ\":\"L\",\n\t\"Ɫ\":\"L\",\n\t\"Lj\":\"L\",\n\t\"Ł\":\"L\",\n\t\"LJ\":\"LJ\",\n\t\"Ḿ\":\"M\",\n\t\"Ṁ\":\"M\",\n\t\"Ṃ\":\"M\",\n\t\"Ɱ\":\"M\",\n\t\"Ń\":\"N\",\n\t\"Ň\":\"N\",\n\t\"Ņ\":\"N\",\n\t\"Ṋ\":\"N\",\n\t\"Ṅ\":\"N\",\n\t\"Ṇ\":\"N\",\n\t\"Ǹ\":\"N\",\n\t\"Ɲ\":\"N\",\n\t\"Ṉ\":\"N\",\n\t\"Ƞ\":\"N\",\n\t\"Nj\":\"N\",\n\t\"Ñ\":\"N\",\n\t\"NJ\":\"NJ\",\n\t\"Ó\":\"O\",\n\t\"Ŏ\":\"O\",\n\t\"Ǒ\":\"O\",\n\t\"Ô\":\"O\",\n\t\"Ố\":\"O\",\n\t\"Ộ\":\"O\",\n\t\"Ồ\":\"O\",\n\t\"Ổ\":\"O\",\n\t\"Ỗ\":\"O\",\n\t\"Ö\":\"O\",\n\t\"Ȫ\":\"O\",\n\t\"Ȯ\":\"O\",\n\t\"Ȱ\":\"O\",\n\t\"Ọ\":\"O\",\n\t\"Ő\":\"O\",\n\t\"Ȍ\":\"O\",\n\t\"Ò\":\"O\",\n\t\"Ỏ\":\"O\",\n\t\"Ơ\":\"O\",\n\t\"Ớ\":\"O\",\n\t\"Ợ\":\"O\",\n\t\"Ờ\":\"O\",\n\t\"Ở\":\"O\",\n\t\"Ỡ\":\"O\",\n\t\"Ȏ\":\"O\",\n\t\"Ꝋ\":\"O\",\n\t\"Ꝍ\":\"O\",\n\t\"Ō\":\"O\",\n\t\"Ṓ\":\"O\",\n\t\"Ṑ\":\"O\",\n\t\"Ɵ\":\"O\",\n\t\"Ǫ\":\"O\",\n\t\"Ǭ\":\"O\",\n\t\"Ø\":\"O\",\n\t\"Ǿ\":\"O\",\n\t\"Õ\":\"O\",\n\t\"Ṍ\":\"O\",\n\t\"Ṏ\":\"O\",\n\t\"Ȭ\":\"O\",\n\t\"Ƣ\":\"OI\",\n\t\"Ꝏ\":\"OO\",\n\t\"Ɛ\":\"E\",\n\t\"Ɔ\":\"O\",\n\t\"Ȣ\":\"OU\",\n\t\"Ṕ\":\"P\",\n\t\"Ṗ\":\"P\",\n\t\"Ꝓ\":\"P\",\n\t\"Ƥ\":\"P\",\n\t\"Ꝕ\":\"P\",\n\t\"Ᵽ\":\"P\",\n\t\"Ꝑ\":\"P\",\n\t\"Ꝙ\":\"Q\",\n\t\"Ꝗ\":\"Q\",\n\t\"Ŕ\":\"R\",\n\t\"Ř\":\"R\",\n\t\"Ŗ\":\"R\",\n\t\"Ṙ\":\"R\",\n\t\"Ṛ\":\"R\",\n\t\"Ṝ\":\"R\",\n\t\"Ȑ\":\"R\",\n\t\"Ȓ\":\"R\",\n\t\"Ṟ\":\"R\",\n\t\"Ɍ\":\"R\",\n\t\"Ɽ\":\"R\",\n\t\"Ꜿ\":\"C\",\n\t\"Ǝ\":\"E\",\n\t\"Ś\":\"S\",\n\t\"Ṥ\":\"S\",\n\t\"Š\":\"S\",\n\t\"Ṧ\":\"S\",\n\t\"Ş\":\"S\",\n\t\"Ŝ\":\"S\",\n\t\"Ș\":\"S\",\n\t\"Ṡ\":\"S\",\n\t\"Ṣ\":\"S\",\n\t\"Ṩ\":\"S\",\n\t\"Ť\":\"T\",\n\t\"Ţ\":\"T\",\n\t\"Ṱ\":\"T\",\n\t\"Ț\":\"T\",\n\t\"Ⱦ\":\"T\",\n\t\"Ṫ\":\"T\",\n\t\"Ṭ\":\"T\",\n\t\"Ƭ\":\"T\",\n\t\"Ṯ\":\"T\",\n\t\"Ʈ\":\"T\",\n\t\"Ŧ\":\"T\",\n\t\"Ɐ\":\"A\",\n\t\"Ꞁ\":\"L\",\n\t\"Ɯ\":\"M\",\n\t\"Ʌ\":\"V\",\n\t\"Ꜩ\":\"TZ\",\n\t\"Ú\":\"U\",\n\t\"Ŭ\":\"U\",\n\t\"Ǔ\":\"U\",\n\t\"Û\":\"U\",\n\t\"Ṷ\":\"U\",\n\t\"Ü\":\"U\",\n\t\"Ǘ\":\"U\",\n\t\"Ǚ\":\"U\",\n\t\"Ǜ\":\"U\",\n\t\"Ǖ\":\"U\",\n\t\"Ṳ\":\"U\",\n\t\"Ụ\":\"U\",\n\t\"Ű\":\"U\",\n\t\"Ȕ\":\"U\",\n\t\"Ù\":\"U\",\n\t\"Ủ\":\"U\",\n\t\"Ư\":\"U\",\n\t\"Ứ\":\"U\",\n\t\"Ự\":\"U\",\n\t\"Ừ\":\"U\",\n\t\"Ử\":\"U\",\n\t\"Ữ\":\"U\",\n\t\"Ȗ\":\"U\",\n\t\"Ū\":\"U\",\n\t\"Ṻ\":\"U\",\n\t\"Ų\":\"U\",\n\t\"Ů\":\"U\",\n\t\"Ũ\":\"U\",\n\t\"Ṹ\":\"U\",\n\t\"Ṵ\":\"U\",\n\t\"Ꝟ\":\"V\",\n\t\"Ṿ\":\"V\",\n\t\"Ʋ\":\"V\",\n\t\"Ṽ\":\"V\",\n\t\"Ꝡ\":\"VY\",\n\t\"Ẃ\":\"W\",\n\t\"Ŵ\":\"W\",\n\t\"Ẅ\":\"W\",\n\t\"Ẇ\":\"W\",\n\t\"Ẉ\":\"W\",\n\t\"Ẁ\":\"W\",\n\t\"Ⱳ\":\"W\",\n\t\"Ẍ\":\"X\",\n\t\"Ẋ\":\"X\",\n\t\"Ý\":\"Y\",\n\t\"Ŷ\":\"Y\",\n\t\"Ÿ\":\"Y\",\n\t\"Ẏ\":\"Y\",\n\t\"Ỵ\":\"Y\",\n\t\"Ỳ\":\"Y\",\n\t\"Ƴ\":\"Y\",\n\t\"Ỷ\":\"Y\",\n\t\"Ỿ\":\"Y\",\n\t\"Ȳ\":\"Y\",\n\t\"Ɏ\":\"Y\",\n\t\"Ỹ\":\"Y\",\n\t\"Ź\":\"Z\",\n\t\"Ž\":\"Z\",\n\t\"Ẑ\":\"Z\",\n\t\"Ⱬ\":\"Z\",\n\t\"Ż\":\"Z\",\n\t\"Ẓ\":\"Z\",\n\t\"Ȥ\":\"Z\",\n\t\"Ẕ\":\"Z\",\n\t\"Ƶ\":\"Z\",\n\t\"IJ\":\"IJ\",\n\t\"Œ\":\"OE\",\n\t\"ᴀ\":\"A\",\n\t\"ᴁ\":\"AE\",\n\t\"ʙ\":\"B\",\n\t\"ᴃ\":\"B\",\n\t\"ᴄ\":\"C\",\n\t\"ᴅ\":\"D\",\n\t\"ᴇ\":\"E\",\n\t\"ꜰ\":\"F\",\n\t\"ɢ\":\"G\",\n\t\"ʛ\":\"G\",\n\t\"ʜ\":\"H\",\n\t\"ɪ\":\"I\",\n\t\"ʁ\":\"R\",\n\t\"ᴊ\":\"J\",\n\t\"ᴋ\":\"K\",\n\t\"ʟ\":\"L\",\n\t\"ᴌ\":\"L\",\n\t\"ᴍ\":\"M\",\n\t\"ɴ\":\"N\",\n\t\"ᴏ\":\"O\",\n\t\"ɶ\":\"OE\",\n\t\"ᴐ\":\"O\",\n\t\"ᴕ\":\"OU\",\n\t\"ᴘ\":\"P\",\n\t\"ʀ\":\"R\",\n\t\"ᴎ\":\"N\",\n\t\"ᴙ\":\"R\",\n\t\"ꜱ\":\"S\",\n\t\"ᴛ\":\"T\",\n\t\"ⱻ\":\"E\",\n\t\"ᴚ\":\"R\",\n\t\"ᴜ\":\"U\",\n\t\"ᴠ\":\"V\",\n\t\"ᴡ\":\"W\",\n\t\"ʏ\":\"Y\",\n\t\"ᴢ\":\"Z\",\n\t\"á\":\"a\",\n\t\"ă\":\"a\",\n\t\"ắ\":\"a\",\n\t\"ặ\":\"a\",\n\t\"ằ\":\"a\",\n\t\"ẳ\":\"a\",\n\t\"ẵ\":\"a\",\n\t\"ǎ\":\"a\",\n\t\"â\":\"a\",\n\t\"ấ\":\"a\",\n\t\"ậ\":\"a\",\n\t\"ầ\":\"a\",\n\t\"ẩ\":\"a\",\n\t\"ẫ\":\"a\",\n\t\"ä\":\"a\",\n\t\"ǟ\":\"a\",\n\t\"ȧ\":\"a\",\n\t\"ǡ\":\"a\",\n\t\"ạ\":\"a\",\n\t\"ȁ\":\"a\",\n\t\"à\":\"a\",\n\t\"ả\":\"a\",\n\t\"ȃ\":\"a\",\n\t\"ā\":\"a\",\n\t\"ą\":\"a\",\n\t\"ᶏ\":\"a\",\n\t\"ẚ\":\"a\",\n\t\"å\":\"a\",\n\t\"ǻ\":\"a\",\n\t\"ḁ\":\"a\",\n\t\"ⱥ\":\"a\",\n\t\"ã\":\"a\",\n\t\"ꜳ\":\"aa\",\n\t\"æ\":\"ae\",\n\t\"ǽ\":\"ae\",\n\t\"ǣ\":\"ae\",\n\t\"ꜵ\":\"ao\",\n\t\"ꜷ\":\"au\",\n\t\"ꜹ\":\"av\",\n\t\"ꜻ\":\"av\",\n\t\"ꜽ\":\"ay\",\n\t\"ḃ\":\"b\",\n\t\"ḅ\":\"b\",\n\t\"ɓ\":\"b\",\n\t\"ḇ\":\"b\",\n\t\"ᵬ\":\"b\",\n\t\"ᶀ\":\"b\",\n\t\"ƀ\":\"b\",\n\t\"ƃ\":\"b\",\n\t\"ɵ\":\"o\",\n\t\"ć\":\"c\",\n\t\"č\":\"c\",\n\t\"ç\":\"c\",\n\t\"ḉ\":\"c\",\n\t\"ĉ\":\"c\",\n\t\"ɕ\":\"c\",\n\t\"ċ\":\"c\",\n\t\"ƈ\":\"c\",\n\t\"ȼ\":\"c\",\n\t\"ď\":\"d\",\n\t\"ḑ\":\"d\",\n\t\"ḓ\":\"d\",\n\t\"ȡ\":\"d\",\n\t\"ḋ\":\"d\",\n\t\"ḍ\":\"d\",\n\t\"ɗ\":\"d\",\n\t\"ᶑ\":\"d\",\n\t\"ḏ\":\"d\",\n\t\"ᵭ\":\"d\",\n\t\"ᶁ\":\"d\",\n\t\"đ\":\"d\",\n\t\"ɖ\":\"d\",\n\t\"ƌ\":\"d\",\n\t\"ı\":\"i\",\n\t\"ȷ\":\"j\",\n\t\"ɟ\":\"j\",\n\t\"ʄ\":\"j\",\n\t\"dz\":\"dz\",\n\t\"dž\":\"dz\",\n\t\"é\":\"e\",\n\t\"ĕ\":\"e\",\n\t\"ě\":\"e\",\n\t\"ȩ\":\"e\",\n\t\"ḝ\":\"e\",\n\t\"ê\":\"e\",\n\t\"ế\":\"e\",\n\t\"ệ\":\"e\",\n\t\"ề\":\"e\",\n\t\"ể\":\"e\",\n\t\"ễ\":\"e\",\n\t\"ḙ\":\"e\",\n\t\"ë\":\"e\",\n\t\"ė\":\"e\",\n\t\"ẹ\":\"e\",\n\t\"ȅ\":\"e\",\n\t\"è\":\"e\",\n\t\"ẻ\":\"e\",\n\t\"ȇ\":\"e\",\n\t\"ē\":\"e\",\n\t\"ḗ\":\"e\",\n\t\"ḕ\":\"e\",\n\t\"ⱸ\":\"e\",\n\t\"ę\":\"e\",\n\t\"ᶒ\":\"e\",\n\t\"ɇ\":\"e\",\n\t\"ẽ\":\"e\",\n\t\"ḛ\":\"e\",\n\t\"ꝫ\":\"et\",\n\t\"ḟ\":\"f\",\n\t\"ƒ\":\"f\",\n\t\"ᵮ\":\"f\",\n\t\"ᶂ\":\"f\",\n\t\"ǵ\":\"g\",\n\t\"ğ\":\"g\",\n\t\"ǧ\":\"g\",\n\t\"ģ\":\"g\",\n\t\"ĝ\":\"g\",\n\t\"ġ\":\"g\",\n\t\"ɠ\":\"g\",\n\t\"ḡ\":\"g\",\n\t\"ᶃ\":\"g\",\n\t\"ǥ\":\"g\",\n\t\"ḫ\":\"h\",\n\t\"ȟ\":\"h\",\n\t\"ḩ\":\"h\",\n\t\"ĥ\":\"h\",\n\t\"ⱨ\":\"h\",\n\t\"ḧ\":\"h\",\n\t\"ḣ\":\"h\",\n\t\"ḥ\":\"h\",\n\t\"ɦ\":\"h\",\n\t\"ẖ\":\"h\",\n\t\"ħ\":\"h\",\n\t\"ƕ\":\"hv\",\n\t\"í\":\"i\",\n\t\"ĭ\":\"i\",\n\t\"ǐ\":\"i\",\n\t\"î\":\"i\",\n\t\"ï\":\"i\",\n\t\"ḯ\":\"i\",\n\t\"ị\":\"i\",\n\t\"ȉ\":\"i\",\n\t\"ì\":\"i\",\n\t\"ỉ\":\"i\",\n\t\"ȋ\":\"i\",\n\t\"ī\":\"i\",\n\t\"į\":\"i\",\n\t\"ᶖ\":\"i\",\n\t\"ɨ\":\"i\",\n\t\"ĩ\":\"i\",\n\t\"ḭ\":\"i\",\n\t\"ꝺ\":\"d\",\n\t\"ꝼ\":\"f\",\n\t\"ᵹ\":\"g\",\n\t\"ꞃ\":\"r\",\n\t\"ꞅ\":\"s\",\n\t\"ꞇ\":\"t\",\n\t\"ꝭ\":\"is\",\n\t\"ǰ\":\"j\",\n\t\"ĵ\":\"j\",\n\t\"ʝ\":\"j\",\n\t\"ɉ\":\"j\",\n\t\"ḱ\":\"k\",\n\t\"ǩ\":\"k\",\n\t\"ķ\":\"k\",\n\t\"ⱪ\":\"k\",\n\t\"ꝃ\":\"k\",\n\t\"ḳ\":\"k\",\n\t\"ƙ\":\"k\",\n\t\"ḵ\":\"k\",\n\t\"ᶄ\":\"k\",\n\t\"ꝁ\":\"k\",\n\t\"ꝅ\":\"k\",\n\t\"ĺ\":\"l\",\n\t\"ƚ\":\"l\",\n\t\"ɬ\":\"l\",\n\t\"ľ\":\"l\",\n\t\"ļ\":\"l\",\n\t\"ḽ\":\"l\",\n\t\"ȴ\":\"l\",\n\t\"ḷ\":\"l\",\n\t\"ḹ\":\"l\",\n\t\"ⱡ\":\"l\",\n\t\"ꝉ\":\"l\",\n\t\"ḻ\":\"l\",\n\t\"ŀ\":\"l\",\n\t\"ɫ\":\"l\",\n\t\"ᶅ\":\"l\",\n\t\"ɭ\":\"l\",\n\t\"ł\":\"l\",\n\t\"lj\":\"lj\",\n\t\"ſ\":\"s\",\n\t\"ẜ\":\"s\",\n\t\"ẛ\":\"s\",\n\t\"ẝ\":\"s\",\n\t\"ḿ\":\"m\",\n\t\"ṁ\":\"m\",\n\t\"ṃ\":\"m\",\n\t\"ɱ\":\"m\",\n\t\"ᵯ\":\"m\",\n\t\"ᶆ\":\"m\",\n\t\"ń\":\"n\",\n\t\"ň\":\"n\",\n\t\"ņ\":\"n\",\n\t\"ṋ\":\"n\",\n\t\"ȵ\":\"n\",\n\t\"ṅ\":\"n\",\n\t\"ṇ\":\"n\",\n\t\"ǹ\":\"n\",\n\t\"ɲ\":\"n\",\n\t\"ṉ\":\"n\",\n\t\"ƞ\":\"n\",\n\t\"ᵰ\":\"n\",\n\t\"ᶇ\":\"n\",\n\t\"ɳ\":\"n\",\n\t\"ñ\":\"n\",\n\t\"nj\":\"nj\",\n\t\"ó\":\"o\",\n\t\"ŏ\":\"o\",\n\t\"ǒ\":\"o\",\n\t\"ô\":\"o\",\n\t\"ố\":\"o\",\n\t\"ộ\":\"o\",\n\t\"ồ\":\"o\",\n\t\"ổ\":\"o\",\n\t\"ỗ\":\"o\",\n\t\"ö\":\"o\",\n\t\"ȫ\":\"o\",\n\t\"ȯ\":\"o\",\n\t\"ȱ\":\"o\",\n\t\"ọ\":\"o\",\n\t\"ő\":\"o\",\n\t\"ȍ\":\"o\",\n\t\"ò\":\"o\",\n\t\"ỏ\":\"o\",\n\t\"ơ\":\"o\",\n\t\"ớ\":\"o\",\n\t\"ợ\":\"o\",\n\t\"ờ\":\"o\",\n\t\"ở\":\"o\",\n\t\"ỡ\":\"o\",\n\t\"ȏ\":\"o\",\n\t\"ꝋ\":\"o\",\n\t\"ꝍ\":\"o\",\n\t\"ⱺ\":\"o\",\n\t\"ō\":\"o\",\n\t\"ṓ\":\"o\",\n\t\"ṑ\":\"o\",\n\t\"ǫ\":\"o\",\n\t\"ǭ\":\"o\",\n\t\"ø\":\"o\",\n\t\"ǿ\":\"o\",\n\t\"õ\":\"o\",\n\t\"ṍ\":\"o\",\n\t\"ṏ\":\"o\",\n\t\"ȭ\":\"o\",\n\t\"ƣ\":\"oi\",\n\t\"ꝏ\":\"oo\",\n\t\"ɛ\":\"e\",\n\t\"ᶓ\":\"e\",\n\t\"ɔ\":\"o\",\n\t\"ᶗ\":\"o\",\n\t\"ȣ\":\"ou\",\n\t\"ṕ\":\"p\",\n\t\"ṗ\":\"p\",\n\t\"ꝓ\":\"p\",\n\t\"ƥ\":\"p\",\n\t\"ᵱ\":\"p\",\n\t\"ᶈ\":\"p\",\n\t\"ꝕ\":\"p\",\n\t\"ᵽ\":\"p\",\n\t\"ꝑ\":\"p\",\n\t\"ꝙ\":\"q\",\n\t\"ʠ\":\"q\",\n\t\"ɋ\":\"q\",\n\t\"ꝗ\":\"q\",\n\t\"ŕ\":\"r\",\n\t\"ř\":\"r\",\n\t\"ŗ\":\"r\",\n\t\"ṙ\":\"r\",\n\t\"ṛ\":\"r\",\n\t\"ṝ\":\"r\",\n\t\"ȑ\":\"r\",\n\t\"ɾ\":\"r\",\n\t\"ᵳ\":\"r\",\n\t\"ȓ\":\"r\",\n\t\"ṟ\":\"r\",\n\t\"ɼ\":\"r\",\n\t\"ᵲ\":\"r\",\n\t\"ᶉ\":\"r\",\n\t\"ɍ\":\"r\",\n\t\"ɽ\":\"r\",\n\t\"ↄ\":\"c\",\n\t\"ꜿ\":\"c\",\n\t\"ɘ\":\"e\",\n\t\"ɿ\":\"r\",\n\t\"ś\":\"s\",\n\t\"ṥ\":\"s\",\n\t\"š\":\"s\",\n\t\"ṧ\":\"s\",\n\t\"ş\":\"s\",\n\t\"ŝ\":\"s\",\n\t\"ș\":\"s\",\n\t\"ṡ\":\"s\",\n\t\"ṣ\":\"s\",\n\t\"ṩ\":\"s\",\n\t\"ʂ\":\"s\",\n\t\"ᵴ\":\"s\",\n\t\"ᶊ\":\"s\",\n\t\"ȿ\":\"s\",\n\t\"ɡ\":\"g\",\n\t\"ᴑ\":\"o\",\n\t\"ᴓ\":\"o\",\n\t\"ᴝ\":\"u\",\n\t\"ť\":\"t\",\n\t\"ţ\":\"t\",\n\t\"ṱ\":\"t\",\n\t\"ț\":\"t\",\n\t\"ȶ\":\"t\",\n\t\"ẗ\":\"t\",\n\t\"ⱦ\":\"t\",\n\t\"ṫ\":\"t\",\n\t\"ṭ\":\"t\",\n\t\"ƭ\":\"t\",\n\t\"ṯ\":\"t\",\n\t\"ᵵ\":\"t\",\n\t\"ƫ\":\"t\",\n\t\"ʈ\":\"t\",\n\t\"ŧ\":\"t\",\n\t\"ᵺ\":\"th\",\n\t\"ɐ\":\"a\",\n\t\"ᴂ\":\"ae\",\n\t\"ǝ\":\"e\",\n\t\"ᵷ\":\"g\",\n\t\"ɥ\":\"h\",\n\t\"ʮ\":\"h\",\n\t\"ʯ\":\"h\",\n\t\"ᴉ\":\"i\",\n\t\"ʞ\":\"k\",\n\t\"ꞁ\":\"l\",\n\t\"ɯ\":\"m\",\n\t\"ɰ\":\"m\",\n\t\"ᴔ\":\"oe\",\n\t\"ɹ\":\"r\",\n\t\"ɻ\":\"r\",\n\t\"ɺ\":\"r\",\n\t\"ⱹ\":\"r\",\n\t\"ʇ\":\"t\",\n\t\"ʌ\":\"v\",\n\t\"ʍ\":\"w\",\n\t\"ʎ\":\"y\",\n\t\"ꜩ\":\"tz\",\n\t\"ú\":\"u\",\n\t\"ŭ\":\"u\",\n\t\"ǔ\":\"u\",\n\t\"û\":\"u\",\n\t\"ṷ\":\"u\",\n\t\"ü\":\"u\",\n\t\"ǘ\":\"u\",\n\t\"ǚ\":\"u\",\n\t\"ǜ\":\"u\",\n\t\"ǖ\":\"u\",\n\t\"ṳ\":\"u\",\n\t\"ụ\":\"u\",\n\t\"ű\":\"u\",\n\t\"ȕ\":\"u\",\n\t\"ù\":\"u\",\n\t\"ủ\":\"u\",\n\t\"ư\":\"u\",\n\t\"ứ\":\"u\",\n\t\"ự\":\"u\",\n\t\"ừ\":\"u\",\n\t\"ử\":\"u\",\n\t\"ữ\":\"u\",\n\t\"ȗ\":\"u\",\n\t\"ū\":\"u\",\n\t\"ṻ\":\"u\",\n\t\"ų\":\"u\",\n\t\"ᶙ\":\"u\",\n\t\"ů\":\"u\",\n\t\"ũ\":\"u\",\n\t\"ṹ\":\"u\",\n\t\"ṵ\":\"u\",\n\t\"ᵫ\":\"ue\",\n\t\"ꝸ\":\"um\",\n\t\"ⱴ\":\"v\",\n\t\"ꝟ\":\"v\",\n\t\"ṿ\":\"v\",\n\t\"ʋ\":\"v\",\n\t\"ᶌ\":\"v\",\n\t\"ⱱ\":\"v\",\n\t\"ṽ\":\"v\",\n\t\"ꝡ\":\"vy\",\n\t\"ẃ\":\"w\",\n\t\"ŵ\":\"w\",\n\t\"ẅ\":\"w\",\n\t\"ẇ\":\"w\",\n\t\"ẉ\":\"w\",\n\t\"ẁ\":\"w\",\n\t\"ⱳ\":\"w\",\n\t\"ẘ\":\"w\",\n\t\"ẍ\":\"x\",\n\t\"ẋ\":\"x\",\n\t\"ᶍ\":\"x\",\n\t\"ý\":\"y\",\n\t\"ŷ\":\"y\",\n\t\"ÿ\":\"y\",\n\t\"ẏ\":\"y\",\n\t\"ỵ\":\"y\",\n\t\"ỳ\":\"y\",\n\t\"ƴ\":\"y\",\n\t\"ỷ\":\"y\",\n\t\"ỿ\":\"y\",\n\t\"ȳ\":\"y\",\n\t\"ẙ\":\"y\",\n\t\"ɏ\":\"y\",\n\t\"ỹ\":\"y\",\n\t\"ź\":\"z\",\n\t\"ž\":\"z\",\n\t\"ẑ\":\"z\",\n\t\"ʑ\":\"z\",\n\t\"ⱬ\":\"z\",\n\t\"ż\":\"z\",\n\t\"ẓ\":\"z\",\n\t\"ȥ\":\"z\",\n\t\"ẕ\":\"z\",\n\t\"ᵶ\":\"z\",\n\t\"ᶎ\":\"z\",\n\t\"ʐ\":\"z\",\n\t\"ƶ\":\"z\",\n\t\"ɀ\":\"z\",\n\t\"ff\":\"ff\",\n\t\"ffi\":\"ffi\",\n\t\"ffl\":\"ffl\",\n\t\"fi\":\"fi\",\n\t\"fl\":\"fl\",\n\t\"ij\":\"ij\",\n\t\"œ\":\"oe\",\n\t\"st\":\"st\",\n\t\"ₐ\":\"a\",\n\t\"ₑ\":\"e\",\n\t\"ᵢ\":\"i\",\n\t\"ⱼ\":\"j\",\n\t\"ₒ\":\"o\",\n\t\"ᵣ\":\"r\",\n\t\"ᵤ\":\"u\",\n\t\"ᵥ\":\"v\",\n\t\"ₓ\":\"x\",\n\t\"Ё\":\"YO\",\n\t\"Й\":\"I\",\n\t\"Ц\":\"TS\",\n\t\"У\":\"U\",\n\t\"К\":\"K\",\n\t\"Е\":\"E\",\n\t\"Н\":\"N\",\n\t\"Г\":\"G\",\n\t\"Ш\":\"SH\",\n\t\"Щ\":\"SCH\",\n\t\"З\":\"Z\",\n\t\"Х\":\"H\",\n\t\"Ъ\":\"'\",\n\t\"ё\":\"yo\",\n\t\"й\":\"i\",\n\t\"ц\":\"ts\",\n\t\"у\":\"u\",\n\t\"к\":\"k\",\n\t\"е\":\"e\",\n\t\"н\":\"n\",\n\t\"г\":\"g\",\n\t\"ш\":\"sh\",\n\t\"щ\":\"sch\",\n\t\"з\":\"z\",\n\t\"х\":\"h\",\n\t\"ъ\":\"'\",\n\t\"Ф\":\"F\",\n\t\"Ы\":\"I\",\n\t\"В\":\"V\",\n\t\"А\":\"a\",\n\t\"П\":\"P\",\n\t\"Р\":\"R\",\n\t\"О\":\"O\",\n\t\"Л\":\"L\",\n\t\"Д\":\"D\",\n\t\"Ж\":\"ZH\",\n\t\"Э\":\"E\",\n\t\"ф\":\"f\",\n\t\"ы\":\"i\",\n\t\"в\":\"v\",\n\t\"а\":\"a\",\n\t\"п\":\"p\",\n\t\"р\":\"r\",\n\t\"о\":\"o\",\n\t\"л\":\"l\",\n\t\"д\":\"d\",\n\t\"ж\":\"zh\",\n\t\"э\":\"e\",\n\t\"Я\":\"Ya\",\n\t\"Ч\":\"CH\",\n\t\"С\":\"S\",\n\t\"М\":\"M\",\n\t\"И\":\"I\",\n\t\"Т\":\"T\",\n\t\"Ь\":\"'\",\n\t\"Б\":\"B\",\n\t\"Ю\":\"YU\",\n\t\"я\":\"ya\",\n\t\"ч\":\"ch\",\n\t\"с\":\"s\",\n\t\"м\":\"m\",\n\t\"и\":\"i\",\n\t\"т\":\"t\",\n\t\"ь\":\"'\",\n\t\"б\":\"b\",\n\t\"ю\":\"yu\"\n};\n\nexports.transliterate = function(str) {\n\treturn str.replace(/[^A-Za-z0-9\\[\\] ]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || ch\n\t});\n};\n\nexports.transliterateToSafeASCII = function(str) {\n\treturn str.replace(/[^\\x00-\\x7F]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || \"\"\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/utils.js": {
"title": "$:/core/modules/utils/utils.js",
"text": "/*\\\ntitle: $:/core/modules/utils/utils.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar base64utf8 = require(\"$:/core/modules/utils/base64-utf8/base64-utf8.module.js\");\n\n/*\nDisplay a message, in colour if we're on a terminal\n*/\nexports.log = function(text,colour) {\n\tconsole.log($tw.node ? exports.terminalColour(colour) + text + exports.terminalColour() : text);\n};\n\nexports.terminalColour = function(colour) {\n\tif(!$tw.browser && $tw.node && process.stdout.isTTY) {\n\t\tif(colour) {\n\t\t\tvar code = exports.terminalColourLookup[colour];\n\t\t\tif(code) {\n\t\t\t\treturn \"\\x1b[\" + code + \"m\";\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"\\x1b[0m\"; // Cancel colour\n\t\t}\n\t}\n\treturn \"\";\n};\n\nexports.terminalColourLookup = {\n\t\"black\": \"0;30\",\n\t\"red\": \"0;31\",\n\t\"green\": \"0;32\",\n\t\"brown/orange\": \"0;33\",\n\t\"blue\": \"0;34\",\n\t\"purple\": \"0;35\",\n\t\"cyan\": \"0;36\",\n\t\"light gray\": \"0;37\"\n};\n\n/*\nDisplay a warning, in colour if we're on a terminal\n*/\nexports.warning = function(text) {\n\texports.log(text,\"brown/orange\");\n};\n\n/*\nLog a table of name: value pairs\n*/\nexports.logTable = function(data) {\n\tif(console.table) {\n\t\tconsole.table(data);\n\t} else {\n\t\t$tw.utils.each(data,function(value,name) {\n\t\t\tconsole.log(name + \": \" + value);\n\t\t});\n\t}\n}\n\n/*\nReturn the integer represented by the str (string).\nReturn the dflt (default) parameter if str is not a base-10 number.\n*/\nexports.getInt = function(str,deflt) {\n\tvar i = parseInt(str,10);\n\treturn isNaN(i) ? deflt : i;\n}\n\n/*\nRepeatedly replaces a substring within a string. Like String.prototype.replace, but without any of the default special handling of $ sequences in the replace string\n*/\nexports.replaceString = function(text,search,replace) {\n\treturn text.replace(search,function() {\n\t\treturn replace;\n\t});\n};\n\n/*\nRepeats a string\n*/\nexports.repeat = function(str,count) {\n\tvar result = \"\";\n\tfor(var t=0;t<count;t++) {\n\t\tresult += str;\n\t}\n\treturn result;\n};\n\n/*\nTrim whitespace from the start and end of a string\nThanks to Steven Levithan, http://blog.stevenlevithan.com/archives/faster-trim-javascript\n*/\nexports.trim = function(str) {\n\tif(typeof str === \"string\") {\n\t\treturn str.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n\t} else {\n\t\treturn str;\n\t}\n};\n\nexports.trimPrefix = function(str,unwanted) {\n\tif(typeof str === \"string\" && typeof unwanted === \"string\") {\n\t\tif(unwanted === \"\") {\n\t\t\treturn str.replace(/^\\s\\s*/, '');\n\t\t} else {\n\t\t\t// Safely regexp-escape the unwanted text\n\t\t\tunwanted = unwanted.replace(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t\t\tvar regex = new RegExp('^(' + unwanted + ')+');\n\t\t\treturn str.replace(regex, '');\n\t\t}\n\t} else {\n\t\treturn str;\n\t}\n};\n\nexports.trimSuffix = function(str,unwanted) {\n\tif(typeof str === \"string\" && typeof unwanted === \"string\") {\n\t\tif(unwanted === \"\") {\n\t\t\treturn str.replace(/\\s\\s*$/, '');\n\t\t} else {\n\t\t\t// Safely regexp-escape the unwanted text\n\t\t\tunwanted = unwanted.replace(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t\t\tvar regex = new RegExp('(' + unwanted + ')+$');\n\t\t\treturn str.replace(regex, '');\n\t\t}\n\t} else {\n\t\treturn str;\n\t}\n};\n\n/*\nConvert a string to sentence case (ie capitalise first letter)\n*/\nexports.toSentenceCase = function(str) {\n\treturn (str || \"\").replace(/^\\S/, function(c) {return c.toUpperCase();});\n}\n\n/*\nConvert a string to title case (ie capitalise each initial letter)\n*/\nexports.toTitleCase = function(str) {\n\treturn (str || \"\").replace(/(^|\\s)\\S/g, function(c) {return c.toUpperCase();});\n}\n\t\n/*\nFind the line break preceding a given position in a string\nReturns position immediately after that line break, or the start of the string\n*/\nexports.findPrecedingLineBreak = function(text,pos) {\n\tvar result = text.lastIndexOf(\"\\n\",pos - 1);\n\tif(result === -1) {\n\t\tresult = 0;\n\t} else {\n\t\tresult++;\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nFind the line break following a given position in a string\n*/\nexports.findFollowingLineBreak = function(text,pos) {\n\t// Cut to just past the following line break, or to the end of the text\n\tvar result = text.indexOf(\"\\n\",pos);\n\tif(result === -1) {\n\t\tresult = text.length;\n\t} else {\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nReturn the number of keys in an object\n*/\nexports.count = function(object) {\n\treturn Object.keys(object || {}).length;\n};\n\n/*\nDetermine whether an array-item is an object-property\n*/\nexports.hopArray = function(object,array) {\n\tfor(var i=0; i<array.length; i++) {\n\t\tif($tw.utils.hop(object,array[i])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nRemove entries from an array\n\tarray: array to modify\n\tvalue: a single value to remove, or an array of values to remove\n*/\nexports.removeArrayEntries = function(array,value) {\n\tvar t,p;\n\tif($tw.utils.isArray(value)) {\n\t\tfor(t=0; t<value.length; t++) {\n\t\t\tp = array.indexOf(value[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tarray.splice(p,1);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tp = array.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tarray.splice(p,1);\n\t\t}\n\t}\n};\n\n/*\nCheck whether any members of a hashmap are present in another hashmap\n*/\nexports.checkDependencies = function(dependencies,changes) {\n\tvar hit = false;\n\t$tw.utils.each(changes,function(change,title) {\n\t\tif($tw.utils.hop(dependencies,title)) {\n\t\t\thit = true;\n\t\t}\n\t});\n\treturn hit;\n};\n\nexports.extend = function(object /* [, src] */) {\n\t$tw.utils.each(Array.prototype.slice.call(arguments, 1), function(source) {\n\t\tif(source) {\n\t\t\tfor(var property in source) {\n\t\t\t\tobject[property] = source[property];\n\t\t\t}\n\t\t}\n\t});\n\treturn object;\n};\n\nexports.deepCopy = function(object) {\n\tvar result,t;\n\tif($tw.utils.isArray(object)) {\n\t\t// Copy arrays\n\t\tresult = object.slice(0);\n\t} else if(typeof object === \"object\") {\n\t\tresult = {};\n\t\tfor(t in object) {\n\t\t\tif(object[t] !== undefined) {\n\t\t\t\tresult[t] = $tw.utils.deepCopy(object[t]);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tresult = object;\n\t}\n\treturn result;\n};\n\nexports.extendDeepCopy = function(object,extendedProperties) {\n\tvar result = $tw.utils.deepCopy(object),t;\n\tfor(t in extendedProperties) {\n\t\tif(extendedProperties[t] !== undefined) {\n\t\t\tresult[t] = $tw.utils.deepCopy(extendedProperties[t]);\n\t\t}\n\t}\n\treturn result;\n};\n\nexports.deepFreeze = function deepFreeze(object) {\n\tvar property, key;\n\tif(object) {\n\t\tObject.freeze(object);\n\t\tfor(key in object) {\n\t\t\tproperty = object[key];\n\t\t\tif($tw.utils.hop(object,key) && (typeof property === \"object\") && !Object.isFrozen(property)) {\n\t\t\t\tdeepFreeze(property);\n\t\t\t}\n\t\t}\n\t}\n};\n\nexports.slowInSlowOut = function(t) {\n\treturn (1 - ((Math.cos(t * Math.PI) + 1) / 2));\n};\n\nexports.formatDateString = function(date,template) {\n\tvar result = \"\",\n\t\tt = template,\n\t\tmatches = [\n\t\t\t[/^0hh12/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getHours12(date));\n\t\t\t}],\n\t\t\t[/^wYYYY/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getYearForWeekNo(date),4);\n\t\t\t}],\n\t\t\t[/^hh12/, function() {\n\t\t\t\treturn $tw.utils.getHours12(date);\n\t\t\t}],\n\t\t\t[/^DDth/, function() {\n\t\t\t\treturn date.getDate() + $tw.utils.getDaySuffix(date);\n\t\t\t}],\n\t\t\t[/^YYYY/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getFullYear(),4);\n\t\t\t}],\n\t\t\t[/^aYYYY/, function() {\n\t\t\t\treturn $tw.utils.pad(Math.abs(date.getFullYear()),4);\n\t\t\t}],\n\t\t\t[/^\\{era:([^,\\|}]*)\\|([^}\\|]*)\\|([^}]*)\\}/, function(match) {\n\t\t\t\tvar year = date.getFullYear();\n\t\t\t\treturn year === 0 ? match[2] : (year < 0 ? match[1] : match[3]);\n\t\t\t}],\n\t\t\t[/^0hh/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getHours());\n\t\t\t}],\n\t\t\t[/^0mm/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMinutes());\n\t\t\t}],\n\t\t\t[/^0ss/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getSeconds());\n\t\t\t}],\n\t\t\t[/^0XXX/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMilliseconds(),3);\n\t\t\t}],\n\t\t\t[/^0DD/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getDate());\n\t\t\t}],\n\t\t\t[/^0MM/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMonth()+1);\n\t\t\t}],\n\t\t\t[/^0WW/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getWeek(date));\n\t\t\t}],\n\t\t\t[/^ddd/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^mmm/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^DDD/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^MMM/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^TZD/, function() {\n\t\t\t\tvar tz = date.getTimezoneOffset(),\n\t\t\t\tatz = Math.abs(tz);\n\t\t\t\treturn (tz < 0 ? '+' : '-') + $tw.utils.pad(Math.floor(atz / 60)) + ':' + $tw.utils.pad(atz % 60);\n\t\t\t}],\n\t\t\t[/^wYY/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getYearForWeekNo(date) - 2000);\n\t\t\t}],\n\t\t\t[/^[ap]m/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toLowerCase();\n\t\t\t}],\n\t\t\t[/^hh/, function() {\n\t\t\t\treturn date.getHours();\n\t\t\t}],\n\t\t\t[/^mm/, function() {\n\t\t\t\treturn date.getMinutes();\n\t\t\t}],\n\t\t\t[/^ss/, function() {\n\t\t\t\treturn date.getSeconds();\n\t\t\t}],\n\t\t\t[/^XXX/, function() {\n\t\t\t\treturn date.getMilliseconds();\n\t\t\t}],\n\t\t\t[/^[AP]M/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toUpperCase();\n\t\t\t}],\n\t\t\t[/^DD/, function() {\n\t\t\t\treturn date.getDate();\n\t\t\t}],\n\t\t\t[/^MM/, function() {\n\t\t\t\treturn date.getMonth() + 1;\n\t\t\t}],\n\t\t\t[/^WW/, function() {\n\t\t\t\treturn $tw.utils.getWeek(date);\n\t\t\t}],\n\t\t\t[/^YY/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getFullYear() - 2000);\n\t\t\t}]\n\t\t];\n\t// If the user wants everything in UTC, shift the datestamp\n\t// Optimize for format string that essentially means\n\t// 'return raw UTC (tiddlywiki style) date string.'\n\tif(t.indexOf(\"[UTC]\") == 0 ) {\n\t\tif(t == \"[UTC]YYYY0MM0DD0hh0mm0ssXXX\")\n\t\t\treturn $tw.utils.stringifyDate(new Date());\n\t\tvar offset = date.getTimezoneOffset() ; // in minutes\n\t\tdate = new Date(date.getTime()+offset*60*1000) ;\n\t\tt = t.substr(5) ;\n\t}\n\twhile(t.length){\n\t\tvar matchString = \"\";\n\t\t$tw.utils.each(matches, function(m) {\n\t\t\tvar match = m[0].exec(t);\n\t\t\tif(match) {\n\t\t\t\tmatchString = m[1].call(null,match);\n\t\t\t\tt = t.substr(match[0].length);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif(matchString) {\n\t\t\tresult += matchString;\n\t\t} else {\n\t\t\tresult += t.charAt(0);\n\t\t\tt = t.substr(1);\n\t\t}\n\t}\n\tresult = result.replace(/\\\\(.)/g,\"$1\");\n\treturn result;\n};\n\nexports.getAmPm = function(date) {\n\treturn $tw.language.getString(\"Date/Period/\" + (date.getHours() >= 12 ? \"pm\" : \"am\"));\n};\n\nexports.getDaySuffix = function(date) {\n\treturn $tw.language.getString(\"Date/DaySuffix/\" + date.getDate());\n};\n\nexports.getWeek = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week to calculate weekNo\n\tvar x = new Date(dt.getFullYear(),0,1);\n\tvar n = Math.floor((dt.getTime() - x.getTime()) / 86400000);\n\treturn Math.floor(n / 7) + 1;\n};\n\nexports.getYearForWeekNo = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week\n\treturn dt.getFullYear();\n};\n\nexports.getHours12 = function(date) {\n\tvar h = date.getHours();\n\treturn h > 12 ? h-12 : ( h > 0 ? h : 12 );\n};\n\n/*\nConvert a date delta in milliseconds into a string representation of \"23 seconds ago\", \"27 minutes ago\" etc.\n\tdelta: delta in milliseconds\nReturns an object with these members:\n\tdescription: string describing the delta period\n\tupdatePeriod: time in millisecond until the string will be inaccurate\n*/\nexports.getRelativeDate = function(delta) {\n\tvar futurep = false;\n\tif(delta < 0) {\n\t\tdelta = -1 * delta;\n\t\tfuturep = true;\n\t}\n\tvar units = [\n\t\t{name: \"Years\", duration: 365 * 24 * 60 * 60 * 1000},\n\t\t{name: \"Months\", duration: (365/12) * 24 * 60 * 60 * 1000},\n\t\t{name: \"Days\", duration: 24 * 60 * 60 * 1000},\n\t\t{name: \"Hours\", duration: 60 * 60 * 1000},\n\t\t{name: \"Minutes\", duration: 60 * 1000},\n\t\t{name: \"Seconds\", duration: 1000}\n\t];\n\tfor(var t=0; t<units.length; t++) {\n\t\tvar result = Math.floor(delta / units[t].duration);\n\t\tif(result >= 2) {\n\t\t\treturn {\n\t\t\t\tdelta: delta,\n\t\t\t\tdescription: $tw.language.getString(\n\t\t\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/\" + units[t].name,\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{period: result.toString()}\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tupdatePeriod: units[t].duration\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tdelta: delta,\n\t\tdescription: $tw.language.getString(\n\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/Second\",\n\t\t\t{variables:\n\t\t\t\t{period: \"1\"}\n\t\t\t}\n\t\t),\n\t\tupdatePeriod: 1000\n\t};\n};\n\n// Convert & to \"&\", < to \"<\", > to \">\", \" to \""\"\nexports.htmlEncode = function(s) {\n\tif(s) {\n\t\treturn s.toString().replace(/&/mg,\"&\").replace(/</mg,\"<\").replace(/>/mg,\">\").replace(/\\\"/mg,\""\");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n// Converts all HTML entities to their character equivalents\nexports.entityDecode = function(s) {\n\tvar converter = String.fromCodePoint || String.fromCharCode,\n\t\te = s.substr(1,s.length-2), // Strip the & and the ;\n\t\tc;\n\tif(e.charAt(0) === \"#\") {\n\t\tif(e.charAt(1) === \"x\" || e.charAt(1) === \"X\") {\n\t\t\tc = parseInt(e.substr(2),16);\n\t\t} else {\n\t\t\tc = parseInt(e.substr(1),10);\n\t\t}\n\t\tif(isNaN(c)) {\n\t\t\treturn s;\n\t\t} else {\n\t\t\treturn converter(c);\n\t\t}\n\t} else {\n\t\tc = $tw.config.htmlEntities[e];\n\t\tif(c) {\n\t\t\treturn converter(c);\n\t\t} else {\n\t\t\treturn s; // Couldn't convert it as an entity, just return it raw\n\t\t}\n\t}\n};\n\nexports.unescapeLineBreaks = function(s) {\n\treturn s.replace(/\\\\n/mg,\"\\n\").replace(/\\\\b/mg,\" \").replace(/\\\\s/mg,\"\\\\\").replace(/\\r/mg,\"\");\n};\n\n/*\n * Returns an escape sequence for given character. Uses \\x for characters <=\n * 0xFF to save space, \\u for the rest.\n *\n * The code needs to be in sync with th code template in the compilation\n * function for \"action\" nodes.\n */\n// Copied from peg.js, thanks to David Majda\nexports.escape = function(ch) {\n\tvar charCode = ch.charCodeAt(0);\n\tif(charCode <= 0xFF) {\n\t\treturn '\\\\x' + $tw.utils.pad(charCode.toString(16).toUpperCase());\n\t} else {\n\t\treturn '\\\\u' + $tw.utils.pad(charCode.toString(16).toUpperCase(),4);\n\t}\n};\n\n// Turns a string into a legal JavaScript string\n// Copied from peg.js, thanks to David Majda\nexports.stringify = function(s, rawUnicode) {\n\t/*\n\t* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string\n\t* literal except for the closing quote character, backslash, carriage return,\n\t* line separator, paragraph separator, and line feed. Any character may\n\t* appear in the form of an escape sequence.\n\t*\n\t* For portability, we also escape all non-ASCII characters.\n\t*/\n\tvar regex = rawUnicode ? /[\\x00-\\x1f]/g : /[\\x00-\\x1f\\x80-\\uFFFF]/g;\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\') // backslash\n\t\t.replace(/\"/g, '\\\\\"') // double quote character\n\t\t.replace(/'/g, \"\\\\'\") // single quote character\n\t\t.replace(/\\r/g, '\\\\r') // carriage return\n\t\t.replace(/\\n/g, '\\\\n') // line feed\n\t\t.replace(regex, exports.escape); // non-ASCII characters\n};\n\n// Turns a string into a legal JSON string\n// Derived from peg.js, thanks to David Majda\nexports.jsonStringify = function(s, rawUnicode) {\n\t// See http://www.json.org/\n\tvar regex = rawUnicode ? /[\\x00-\\x1f]/g : /[\\x00-\\x1f\\x80-\\uFFFF]/g;\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\') // backslash\n\t\t.replace(/\"/g, '\\\\\"') // double quote character\n\t\t.replace(/\\r/g, '\\\\r') // carriage return\n\t\t.replace(/\\n/g, '\\\\n') // line feed\n\t\t.replace(/\\x08/g, '\\\\b') // backspace\n\t\t.replace(/\\x0c/g, '\\\\f') // formfeed\n\t\t.replace(/\\t/g, '\\\\t') // tab\n\t\t.replace(regex,function(s) {\n\t\t\treturn '\\\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4);\n\t\t}); // non-ASCII characters\n};\n\n/*\nEscape the RegExp special characters with a preceding backslash\n*/\nexports.escapeRegExp = function(s) {\n return s.replace(/[\\-\\/\\\\\\^\\$\\*\\+\\?\\.\\(\\)\\|\\[\\]\\{\\}]/g, '\\\\$&');\n};\n\n// Checks whether a link target is external, i.e. not a tiddler title\nexports.isLinkExternal = function(to) {\n\tvar externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/i;\n\treturn externalRegExp.test(to);\n};\n\nexports.nextTick = function(fn) {\n/*global window: false */\n\tif(typeof process === \"undefined\") {\n\t\t// Apparently it would be faster to use postMessage - http://dbaron.org/log/20100309-faster-timeouts\n\t\twindow.setTimeout(fn,4);\n\t} else {\n\t\tprocess.nextTick(fn);\n\t}\n};\n\n/*\nConvert a hyphenated CSS property name into a camel case one\n*/\nexports.unHyphenateCss = function(propName) {\n\treturn propName.replace(/-([a-z])/gi, function(match0,match1) {\n\t\treturn match1.toUpperCase();\n\t});\n};\n\n/*\nConvert a camelcase CSS property name into a dashed one (\"backgroundColor\" --> \"background-color\")\n*/\nexports.hyphenateCss = function(propName) {\n\treturn propName.replace(/([A-Z])/g, function(match0,match1) {\n\t\treturn \"-\" + match1.toLowerCase();\n\t});\n};\n\n/*\nParse a text reference of one of these forms:\n* title\n* !!field\n* title!!field\n* title##index\n* etc\nReturns an object with the following fields, all optional:\n* title: tiddler title\n* field: tiddler field name\n* index: JSON property index\n*/\nexports.parseTextReference = function(textRef) {\n\t// Separate out the title, field name and/or JSON indices\n\tvar reTextRef = /(?:(.*?)!!(.+))|(?:(.*?)##(.+))|(.*)/mg,\n\t\tmatch = reTextRef.exec(textRef),\n\t\tresult = {};\n\tif(match && reTextRef.lastIndex === textRef.length) {\n\t\t// Return the parts\n\t\tif(match[1]) {\n\t\t\tresult.title = match[1];\n\t\t}\n\t\tif(match[2]) {\n\t\t\tresult.field = match[2];\n\t\t}\n\t\tif(match[3]) {\n\t\t\tresult.title = match[3];\n\t\t}\n\t\tif(match[4]) {\n\t\t\tresult.index = match[4];\n\t\t}\n\t\tif(match[5]) {\n\t\t\tresult.title = match[5];\n\t\t}\n\t} else {\n\t\t// If we couldn't parse it\n\t\tresult.title = textRef\n\t}\n\treturn result;\n};\n\n/*\nChecks whether a string is a valid fieldname\n*/\nexports.isValidFieldName = function(name) {\n\tif(!name || typeof name !== \"string\") {\n\t\treturn false;\n\t}\n\tname = name.toLowerCase().trim();\n\tvar fieldValidatorRegEx = /^[a-z0-9\\-\\._]+$/mg;\n\treturn fieldValidatorRegEx.test(name);\n};\n\n/*\nExtract the version number from the meta tag or from the boot file\n*/\n\n// Browser version\nexports.extractVersionInfo = function() {\n\tif($tw.packageInfo) {\n\t\treturn $tw.packageInfo.version;\n\t} else {\n\t\tvar metatags = document.getElementsByTagName(\"meta\");\n\t\tfor(var t=0; t<metatags.length; t++) {\n\t\t\tvar m = metatags[t];\n\t\t\tif(m.name === \"tiddlywiki-version\") {\n\t\t\t\treturn m.content;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the animation duration in ms\n*/\nexports.getAnimationDuration = function() {\n\treturn parseInt($tw.wiki.getTiddlerText(\"$:/config/AnimationDuration\",\"400\"),10) || 0;\n};\n\n/*\nHash a string to a number\nDerived from http://stackoverflow.com/a/15710692\n*/\nexports.hashString = function(str) {\n\treturn str.split(\"\").reduce(function(a,b) {\n\t\ta = ((a << 5) - a) + b.charCodeAt(0);\n\t\treturn a & a;\n\t},0);\n};\n\n/*\nDecode a base64 string\n*/\nexports.base64Decode = function(string64) {\n\treturn base64utf8.base64.decode.call(base64utf8,string64);\n};\n\n/*\nEncode a string to base64\n*/\nexports.base64Encode = function(string64) {\n\treturn base64utf8.base64.encode.call(base64utf8,string64);\n};\n\n/*\nConvert a hashmap into a tiddler dictionary format sequence of name:value pairs\n*/\nexports.makeTiddlerDictionary = function(data) {\n\tvar output = [];\n\tfor(var name in data) {\n\t\toutput.push(name + \": \" + data[name]);\n\t}\n\treturn output.join(\"\\n\");\n};\n\n/*\nHigh resolution microsecond timer for profiling\n*/\nexports.timer = function(base) {\n\tvar m;\n\tif($tw.node) {\n\t\tvar r = process.hrtime();\n\t\tm = r[0] * 1e3 + (r[1] / 1e6);\n\t} else if(window.performance) {\n\t\tm = performance.now();\n\t} else {\n\t\tm = Date.now();\n\t}\n\tif(typeof base !== \"undefined\") {\n\t\tm = m - base;\n\t}\n\treturn m;\n};\n\n/*\nConvert text and content type to a data URI\n*/\nexports.makeDataUri = function(text,type,_canonical_uri) {\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar typeInfo = $tw.config.contentTypeInfo[type] || $tw.config.contentTypeInfo[\"text/plain\"],\n\t\tisBase64 = typeInfo.encoding === \"base64\",\n\t\tparts = [];\n\tif(_canonical_uri) {\n\t\tparts.push(_canonical_uri);\n\t} else {\n\t\tparts.push(\"data:\");\n\t\tparts.push(type);\n\t\tparts.push(isBase64 ? \";base64\" : \"\");\n\t\tparts.push(\",\");\n\t\tparts.push(isBase64 ? text : encodeURIComponent(text));\t\t\n\t}\n\treturn parts.join(\"\");\n};\n\n/*\nUseful for finding out the fully escaped CSS selector equivalent to a given tag. For example:\n\n$tw.utils.tagToCssSelector(\"$:/tags/Stylesheet\") --> tc-tagged-\\%24\\%3A\\%2Ftags\\%2FStylesheet\n*/\nexports.tagToCssSelector = function(tagName) {\n\treturn \"tc-tagged-\" + encodeURIComponent(tagName).replace(/[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^`{\\|}~,]/mg,function(c) {\n\t\treturn \"\\\\\" + c;\n\t});\n};\n\n/*\nIE does not have sign function\n*/\nexports.sign = Math.sign || function(x) {\n\tx = +x; // convert to a number\n\tif (x === 0 || isNaN(x)) {\n\t\treturn x;\n\t}\n\treturn x > 0 ? 1 : -1;\n};\n\n/*\nIE does not have an endsWith function\n*/\nexports.strEndsWith = function(str,ending,position) {\n\tif(str.endsWith) {\n\t\treturn str.endsWith(ending,position);\n\t} else {\n\t\tif (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > str.length) {\n\t\t\tposition = str.length;\n\t\t}\n\t\tposition -= ending.length;\n\t\tvar lastIndex = str.indexOf(ending, position);\n\t\treturn lastIndex !== -1 && lastIndex === position;\n\t}\n};\n\n/*\nReturn system information useful for debugging\n*/\nexports.getSystemInfo = function(str,ending,position) {\n\tvar results = [],\n\t\tsave = function(desc,value) {\n\t\t\tresults.push(desc + \": \" + value);\n\t\t};\n\tif($tw.browser) {\n\t\tsave(\"User Agent\",navigator.userAgent);\n\t\tsave(\"Online Status\",window.navigator.onLine);\n\t}\n\tif($tw.node) {\n\t\tsave(\"Node Version\",process.version);\n\t}\n\treturn results.join(\"\\n\");\n};\n\nexports.parseNumber = function(str) {\n\treturn parseFloat(str) || 0;\n};\n\nexports.parseInt = function(str) {\n\treturn parseInt(str,10) || 0;\n};\n\nexports.stringifyNumber = function(num) {\n\treturn num + \"\";\n};\n\nexports.makeCompareFunction = function(type,options) {\n\toptions = options || {};\n\tvar gt = options.invert ? -1 : +1,\n\t\tlt = options.invert ? +1 : -1,\n\t\tcompare = function(a,b) {\n\t\t\tif(a > b) {\n\t\t\t\treturn gt ;\n\t\t\t} else if(a < b) {\n\t\t\t\treturn lt;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\ttypes = {\n\t\t\t\"number\": function(a,b) {\n\t\t\t\treturn compare($tw.utils.parseNumber(a),$tw.utils.parseNumber(b));\n\t\t\t},\n\t\t\t\"integer\": function(a,b) {\n\t\t\t\treturn compare($tw.utils.parseInt(a),$tw.utils.parseInt(b));\n\t\t\t},\n\t\t\t\"string\": function(a,b) {\n\t\t\t\treturn compare(\"\" + a,\"\" +b);\n\t\t\t},\n\t\t\t\"date\": function(a,b) {\n\t\t\t\tvar dateA = $tw.utils.parseDate(a),\n\t\t\t\t\tdateB = $tw.utils.parseDate(b);\n\t\t\t\tif(!isFinite(dateA)) {\n\t\t\t\t\tdateA = new Date(0);\n\t\t\t\t}\n\t\t\t\tif(!isFinite(dateB)) {\n\t\t\t\t\tdateB = new Date(0);\n\t\t\t\t}\n\t\t\t\treturn compare(dateA,dateB);\n\t\t\t},\n\t\t\t\"version\": function(a,b) {\n\t\t\t\treturn $tw.utils.compareVersions(a,b);\n\t\t\t}\n\t\t};\n\treturn (types[type] || types[options.defaultType] || types.number);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/widgets/action-confirm.js": {
"title": "$:/core/modules/widgets/action-confirm.js",
"text": "/*\\\n\ntitle: $:/core/modules/widgets/action-confirm.js\ntype: application/javascript\nmodule-type: widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ConfirmWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nConfirmWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nConfirmWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.parentDomNode = parent;\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nConfirmWidget.prototype.execute = function() {\n\tthis.message = this.getAttribute(\"$message\",$tw.language.getString(\"ConfirmAction\"));\n\tthis.prompt = (this.getAttribute(\"$prompt\",\"yes\") == \"no\" ? false : true);\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nConfirmWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$message\"] || changedAttributes[\"$prompt\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nConfirmWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar invokeActions = true,\n\t\thandled = true;\n\tif(this.prompt) {\n\t\tinvokeActions = confirm(this.message);\n\t}\n\tif(invokeActions) {\n\t\thandled = this.invokeActions(triggeringWidget,event);\n\t}\n\treturn handled;\n};\n\nConfirmWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nexports[\"action-confirm\"] = ConfirmWidget;\n\n})();",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-createtiddler.js": {
"title": "$:/core/modules/widgets/action-createtiddler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-createtiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to create a new tiddler with a unique name and specified fields.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw:false, require:false, exports:false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CreateTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCreateTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCreateTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nCreateTiddlerWidget.prototype.execute = function() {\n\tthis.actionBaseTitle = this.getAttribute(\"$basetitle\");\n\tthis.hasBase = !!this.actionBaseTitle;\n\tthis.actionSaveTitle = this.getAttribute(\"$savetitle\");\n\tthis.actionSaveDraftTitle = this.getAttribute(\"$savedrafttitle\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n\t//Following params are new since 5.1.22\n\tthis.actionTemplate = this.getAttribute(\"$template\");\n\tthis.useTemplate = !!this.actionTemplate;\n\tthis.actionOverwrite = this.getAttribute(\"$overwrite\",\"no\");\n\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nCreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nCreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar title = this.wiki.getTiddlerText(\"$:/language/DefaultNewTiddlerTitle\"), // Get the initial new-tiddler title\n\t\tfields = {},\n\t\tcreationFields,\n\t\tmodificationFields;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tfields[name] = attribute;\n\t\t}\n\t});\n\tif(this.actionTimestamp) {\n\t\tcreationFields = this.wiki.getCreationFields();\n\t\tmodificationFields = this.wiki.getModificationFields();\n\t}\n\tif(this.hasBase && this.actionOverwrite === \"no\") {\n\t\ttitle = this.wiki.generateNewTitle(this.actionBaseTitle);\n\t} else if (this.hasBase && this.actionOverwrite === \"yes\") {\n\t\ttitle = this.actionBaseTitle\n\t}\n\t// NO $basetitle BUT $template parameter is available\n\t// the title MUST be unique, otherwise the template would be overwritten\n\tif (!this.hasBase && this.useTemplate) {\n\t\ttitle = this.wiki.generateNewTitle(this.actionTemplate);\n\t} else if (!this.hasBase && !this.useTemplate) {\n\t\t// If NO $basetitle AND NO $template use initial title\n\t\t// DON'T overwrite any stuff\n\t\ttitle = this.wiki.generateNewTitle(title);\n\t}\n\tvar templateTiddler = this.wiki.getTiddler(this.actionTemplate) || {};\n\tvar tiddler = this.wiki.addTiddler(new $tw.Tiddler(templateTiddler.fields,creationFields,fields,modificationFields,{title: title}));\n\tif(this.actionSaveTitle) {\n\t\tthis.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable(\"currentTiddler\"));\n\t}\n\tif(this.actionSaveDraftTitle) {\n\t\tthis.wiki.setTextReference(this.actionSaveDraftTitle,this.wiki.generateDraftTitle(title),this.getVariable(\"currentTiddler\"));\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-createtiddler\"] = CreateTiddlerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-deletefield.js": {
"title": "$:/core/modules/widgets/action-deletefield.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-deletefield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete fields of a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\ttiddler = this.wiki.getTiddler(self.actionTiddler),\n\t\tremoveFields = {},\n\t\thasChanged = false;\n\tif(this.actionField && tiddler) {\n\t\tremoveFields[this.actionField] = undefined;\n\t\tif(this.actionField in tiddler.fields) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(tiddler) {\n\t\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\t\tif(name.charAt(0) !== \"$\" && name !== \"title\") {\n\t\t\t\tremoveFields[name] = undefined;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t});\n\t\tif(hasChanged) {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields()));\t\t\t\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletefield\"] = DeleteFieldWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-deletetiddler.js": {
"title": "$:/core/modules/widgets/action-deletetiddler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-deletetiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteTiddlerWidget.prototype.execute = function() {\n\tthis.actionFilter = this.getAttribute(\"$filter\");\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$filter\"] || changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar tiddlers = [];\n\tif(this.actionFilter) {\n\t\ttiddlers = this.wiki.filterTiddlers(this.actionFilter,this);\n\t}\n\tif(this.actionTiddler) {\n\t\ttiddlers.push(this.actionTiddler);\n\t}\n\tfor(var t=0; t<tiddlers.length; t++) {\n\t\tthis.wiki.deleteTiddler(tiddlers[t]);\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletetiddler\"] = DeleteTiddlerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-listops.js": {
"title": "$:/core/modules/widgets/action-listops.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-listops.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to apply list operations to any tiddler field (defaults to the 'list' field of the current tiddler)\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar ActionListopsWidget = function(parseTreeNode, options) {\n\tthis.initialise(parseTreeNode, options);\n};\n/**\n * Inherit from the base widget class\n */\nActionListopsWidget.prototype = new Widget();\n/**\n * Render this widget into the DOM\n */\nActionListopsWidget.prototype.render = function(parent, nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n/**\n * Compute the internal state of the widget\n */\nActionListopsWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.target = this.getAttribute(\"$tiddler\", this.getVariable(\n\t\t\"currentTiddler\"));\n\tthis.filter = this.getAttribute(\"$filter\");\n\tthis.subfilter = this.getAttribute(\"$subfilter\");\n\tthis.listField = this.getAttribute(\"$field\", \"list\");\n\tthis.listIndex = this.getAttribute(\"$index\");\n\tthis.filtertags = this.getAttribute(\"$tags\");\n};\n/**\n * \tRefresh the widget by ensuring our attributes are up to date\n */\nActionListopsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.$tiddler || changedAttributes.$filter ||\n\t\tchangedAttributes.$subfilter || changedAttributes.$field ||\n\t\tchangedAttributes.$index || changedAttributes.$tags) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n/**\n * \tInvoke the action associated with this widget\n */\nActionListopsWidget.prototype.invokeAction = function(triggeringWidget,\n\tevent) {\n\t//Apply the specified filters to the lists\n\tvar field = this.listField,\n\t\tindex,\n\t\ttype = \"!!\",\n\t\tlist = this.listField;\n\tif(this.listIndex) {\n\t\tfield = undefined;\n\t\tindex = this.listIndex;\n\t\ttype = \"##\";\n\t\tlist = this.listIndex;\n\t}\n\tif(this.filter) {\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(this.filter, this)));\n\t}\n\tif(this.subfilter) {\n\t\tvar subfilter = \"[list[\" + this.target + type + list + \"]] \" + this.subfilter;\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(subfilter, this)));\n\t}\n\tif(this.filtertags) {\n\t\tvar tiddler = this.wiki.getTiddler(this.target),\n\t\t\toldtags = tiddler ? (tiddler.fields.tags || []).slice(0) : [],\n\t\t\ttagfilter = \"[list[\" + this.target + \"!!tags]] \" + this.filtertags,\n\t\t\tnewtags = this.wiki.filterTiddlers(tagfilter,this);\n\t\tif($tw.utils.stringifyList(oldtags.sort()) !== $tw.utils.stringifyList(newtags.sort())) {\n\t\t\tthis.wiki.setText(this.target,\"tags\",undefined,$tw.utils.stringifyList(newtags));\t\t\t\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-listops\"] = ActionListopsWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-log.js": {
"title": "$:/core/modules/widgets/action-log.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-log.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to log debug messages\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LogWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLogWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLogWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\nLogWidget.prototype.execute = function(){\n\tthis.message = this.getAttribute(\"$$message\",\"debug\");\n\tthis.logAll = this.getAttribute(\"$$all\",\"no\") === \"yes\" ? true : false;\n\tthis.filter = this.getAttribute(\"$$filter\");\n}\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nLogWidget.prototype.refresh = function(changedTiddlers) {\n\tthis.refreshSelf();\n\treturn true;\n};\n\n/*\nInvoke the action associated with this widget\n*/\nLogWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tthis.log();\n\treturn true; // Action was invoked\n};\n\nLogWidget.prototype.log = function() {\n\tvar data = {},\n\t\tdataCount,\n\t\tallVars = {},\n\t\tfilteredVars;\n\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.substring(0,2) !== \"$$\") {\n\t\t\tdata[name] = attribute;\n\t\t}\t\t\n\t});\n\n\tfor(var v in this.variables) {\n\t\tallVars[v] = this.getVariable(v,{defaultValue:\"\"});\n\t}\t\n\tif(this.filter) {\n\t\tfilteredVars = this.wiki.compileFilter(this.filter).call(this.wiki,this.wiki.makeTiddlerIterator(allVars));\n\t\t$tw.utils.each(filteredVars,function(name) {\n\t\t\tdata[name] = allVars[name];\n\t\t});\t\t\n\t}\n\tdataCount = $tw.utils.count(data);\n\n\tconsole.group(this.message);\n\tif(dataCount > 0) {\n\t\t$tw.utils.logTable(data);\n\t}\n\tif(this.logAll || !dataCount) {\n\t\tconsole.groupCollapsed(\"All variables\");\n\t\t$tw.utils.logTable(allVars);\n\t\tconsole.groupEnd();\n\t}\n\tconsole.groupEnd();\n}\n\nexports[\"action-log\"] = LogWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-navigate.js": {
"title": "$:/core/modules/widgets/action-navigate.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-navigate.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to navigate to a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigateWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigateWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigateWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigateWidget.prototype.execute = function() {\n\tthis.actionTo = this.getAttribute(\"$to\");\n\tthis.actionScroll = this.getAttribute(\"$scroll\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nNavigateWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$to\"] || changedAttributes[\"$scroll\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nNavigateWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tevent = event || {};\n\tvar bounds = triggeringWidget && triggeringWidget.getBoundingClientRect && triggeringWidget.getBoundingClientRect(),\n\t\tsuppressNavigation = event.metaKey || event.ctrlKey || (event.button === 1);\n\tif(this.actionScroll === \"yes\") {\n\t\tsuppressNavigation = false;\n\t} else if(this.actionScroll === \"no\") {\n\t\tsuppressNavigation = true;\n\t}\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.actionTo === undefined ? this.getVariable(\"currentTiddler\") : this.actionTo,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: triggeringWidget,\n\t\tnavigateFromClientRect: bounds && { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: suppressNavigation\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-navigate\"] = NavigateWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-popup.js": {
"title": "$:/core/modules/widgets/action-popup.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-popup.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to trigger a popup.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ActionPopupWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nActionPopupWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nActionPopupWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nActionPopupWidget.prototype.execute = function() {\n\tthis.actionState = this.getAttribute(\"$state\");\n\tthis.actionCoords = this.getAttribute(\"$coords\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nActionPopupWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$state\"] || changedAttributes[\"$coords\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\t// Trigger the popup\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/,\n\t\tmatch = popupLocationRegExp.exec(this.actionCoords || \"\");\n\tif(match) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: null,\n\t\t\tdomNodeRect: {\n\t\t\t\tleft: parseFloat(match[1]),\n\t\t\t\ttop: parseFloat(match[2]),\n\t\t\t\twidth: parseFloat(match[3]),\n\t\t\t\theight: parseFloat(match[4])\n\t\t\t},\n\t\t\ttitle: this.actionState,\n\t\t\twiki: this.wiki\n\t\t});\n\t} else {\n\t\t$tw.popup.cancel(0);\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-popup\"] = ActionPopupWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-sendmessage.js": {
"title": "$:/core/modules/widgets/action-sendmessage.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-sendmessage.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to send a message\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SendMessageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSendMessageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSendMessageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSendMessageWidget.prototype.execute = function() {\n\tthis.actionMessage = this.getAttribute(\"$message\");\n\tthis.actionParam = this.getAttribute(\"$param\");\n\tthis.actionName = this.getAttribute(\"$name\");\n\tthis.actionValue = this.getAttribute(\"$value\",\"\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSendMessageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\t// Get the string parameter\n\tvar param = this.actionParam;\n\t// Assemble the attributes as a hashmap\n\tvar paramObject = Object.create(null);\n\tvar count = 0;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparamObject[name] = attribute;\n\t\t\tcount++;\n\t\t}\n\t});\n\t// Add name/value pair if present\n\tif(this.actionName) {\n\t\tparamObject[this.actionName] = this.actionValue;\n\t}\n\t// Dispatch the message\n\tthis.dispatchEvent({\n\t\ttype: this.actionMessage,\n\t\tparam: param,\n\t\tparamObject: paramObject,\n\t\ttiddlerTitle: this.getVariable(\"currentTiddler\"),\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tevent: event\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-sendmessage\"] = SendMessageWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-setfield.js": {
"title": "$:/core/modules/widgets/action-setfield.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-setfield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to set a single field or index on a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n\tthis.actionIndex = this.getAttribute(\"$index\");\n\tthis.actionValue = this.getAttribute(\"$value\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSetFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"] || changedAttributes[\"$field\"] || changedAttributes[\"$index\"] || changedAttributes[\"$value\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\toptions = {};\n\toptions.suppressTimestamp = !this.actionTimestamp;\n\tif((typeof this.actionField == \"string\") || (typeof this.actionIndex == \"string\") || (typeof this.actionValue == \"string\")) {\n\t\tthis.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue,options);\n\t}\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tself.wiki.setText(self.actionTiddler,name,undefined,attribute,options);\n\t\t}\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-setfield\"] = SetFieldWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/browse.js": {
"title": "$:/core/modules/widgets/browse.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/browse.js\ntype: application/javascript\nmodule-type: widget\n\nBrowse widget for browsing for files to import\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar BrowseWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nBrowseWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nBrowseWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"file\");\n\tif(this.browseMultiple) {\n\t\tdomNode.setAttribute(\"multiple\",\"multiple\");\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\t// Nw.js supports \"nwsaveas\" to force a \"save as\" dialogue that allows a new or existing file to be selected\n\tif(this.nwsaveas) {\n\t\tdomNode.setAttribute(\"nwsaveas\",this.nwsaveas);\n\t}\n\tif(this.accept) {\n\t\tdomNode.setAttribute(\"accept\",this.accept);\n\t}\n\t// Nw.js supports \"webkitdirectory\" and \"nwdirectory\" to allow a directory to be selected\n\tif(this.webkitdirectory) {\n\t\tdomNode.setAttribute(\"webkitdirectory\",this.webkitdirectory);\n\t}\n\tif(this.nwdirectory) {\n\t\tdomNode.setAttribute(\"nwdirectory\",this.nwdirectory);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"change\",function (event) {\n\t\tif(self.message) {\n\t\t\tself.dispatchEvent({type: self.message, param: self.param, files: event.target.files});\n\t\t} else {\n\t\t\tself.wiki.readFiles(event.target.files,{\n\t\t\t\tcallback: function(tiddlerFieldsArray) {\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t\t\t},\n\t\t\t\tdeserializer: self.deserializer\n\t\t\t});\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nBrowseWidget.prototype.execute = function() {\n\tthis.browseMultiple = this.getAttribute(\"multiple\");\n\tthis.deserializer = this.getAttribute(\"deserializer\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.nwsaveas = this.getAttribute(\"nwsaveas\");\n\tthis.accept = this.getAttribute(\"accept\");\n\tthis.webkitdirectory = this.getAttribute(\"webkitdirectory\");\n\tthis.nwdirectory = this.getAttribute(\"nwdirectory\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nBrowseWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.browse = BrowseWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/button.js": {
"title": "$:/core/modules/widgets/button.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/button.js\ntype: application/javascript\nmodule-type: widget\n\nButton widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ButtonWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nButtonWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nButtonWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this,\n\t\ttag = \"button\",\n\t\tdomNode;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tif(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {\n\t\ttag = this.buttonTag;\n\t}\n\tdomNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\t// Assign classes\n\tvar classes = this[\"class\"].split(\" \") || [],\n\t\tisPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();\n\tif(this.selectedClass) {\n\t\tif((this.set || this.setTitle) && this.setTo && this.isSelected()) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t\tif(isPoppedUp) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t}\n\tif(isPoppedUp) {\n\t\t$tw.utils.pushTop(classes,\"tc-popup-handle\");\n\t}\n\tdomNode.className = classes.join(\" \");\n\t// Assign other attributes\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Set the tabindex\n\tif(this.tabIndex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.tabIndex);\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tdomNode.setAttribute(\"disabled\",true);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"click\",function (event) {\n\t\tvar handled = false;\n\t\tif(self.invokeActions(self,event)) {\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.to) {\n\t\t\tself.navigateTo(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.message) {\n\t\t\tself.dispatchMessage(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.popup || self.popupTitle) {\n\t\t\tself.triggerPopup(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.set || self.setTitle) {\n\t\t\tself.setTiddler();\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.actions) {\n\t\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\tself.invokeActionString(self.actions,self,event,{modifier: modifierKey});\n\t\t}\n\t\tif(handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\treturn handled;\n\t},false);\n\t// Make it draggable if required\n\tif(this.dragTiddler || this.dragFilter) {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.dragTiddler;},\n\t\t\tdragFilterFn: function() {return self.dragFilter;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nWe don't allow actions to propagate because we trigger actions ourselves\n*/\nButtonWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nButtonWidget.prototype.getBoundingClientRect = function() {\n\treturn this.domNodes[0].getBoundingClientRect();\n};\n\nButtonWidget.prototype.isSelected = function() {\n return this.setTitle ? (this.setField ? this.wiki.getTiddler(this.setTitle).getFieldString(this.setField) === this.setTo :\n\t\t(this.setIndex ? this.wiki.extractTiddlerDataItem(this.setTitle,this.setIndex) === this.setTo :\n\t\t\tthis.wiki.getTiddlerText(this.setTitle))) || this.defaultSetValue || this.getVariable(\"currentTiddler\") :\n\t\tthis.wiki.getTextReference(this.set,this.defaultSetValue,this.getVariable(\"currentTiddler\")) === this.setTo;\n};\n\nButtonWidget.prototype.isPoppedUp = function() {\n\tvar tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);\n\tvar result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;\n\treturn result;\n};\n\nButtonWidget.prototype.navigateTo = function(event) {\n\tvar bounds = this.getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tevent: event\n\t});\n};\n\nButtonWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\"), event: event});\n};\n\nButtonWidget.prototype.triggerPopup = function(event) {\n\tif(this.popupTitle) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\ttitle: this.popupTitle,\n\t\t\twiki: this.wiki,\n\t\t\tnoStateReference: true\n\t\t});\n\t} else {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\ttitle: this.popup,\n\t\t\twiki: this.wiki\n\t\t});\n\t}\n};\n\nButtonWidget.prototype.setTiddler = function() {\n\tif(this.setTitle) {\n\t\tthis.setField ? this.wiki.setText(this.setTitle,this.setField,undefined,this.setTo) :\n\t\t\t\t(this.setIndex ? this.wiki.setText(this.setTitle,undefined,this.setIndex,this.setTo) :\n\t\t\t\tthis.wiki.setText(this.setTitle,\"text\",undefined,this.setTo));\n\t} else {\n\t\tthis.wiki.setTextReference(this.set,this.setTo,this.getVariable(\"currentTiddler\"));\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nButtonWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.to = this.getAttribute(\"to\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.set = this.getAttribute(\"set\");\n\tthis.setTo = this.getAttribute(\"setTo\");\n\tthis.popup = this.getAttribute(\"popup\");\n\tthis.hover = this.getAttribute(\"hover\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.style = this.getAttribute(\"style\");\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tthis.selectedClass = this.getAttribute(\"selectedClass\");\n\tthis.defaultSetValue = this.getAttribute(\"default\",\"\");\n\tthis.buttonTag = this.getAttribute(\"tag\");\n\tthis.dragTiddler = this.getAttribute(\"dragTiddler\");\n\tthis.dragFilter = this.getAttribute(\"dragFilter\");\n\tthis.setTitle = this.getAttribute(\"setTitle\");\n\tthis.setField = this.getAttribute(\"setField\");\n\tthis.setIndex = this.getAttribute(\"setIndex\");\n\tthis.popupTitle = this.getAttribute(\"popupTitle\");\n\tthis.tabIndex = this.getAttribute(\"tabindex\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nButtonWidget.prototype.updateDomNodeClasses = function() {\n\tvar domNodeClasses = this.domNode.className.split(\" \"),\n\t\toldClasses = this.class.split(\" \"),\n\t\tnewClasses;\t\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tnewClasses = this.class.split(\" \");\n\t//Remove classes assigned from the old value of class attribute\n\t$tw.utils.each(oldClasses,function(oldClass){\n\t\tvar i = domNodeClasses.indexOf(oldClass);\n\t\tif(i !== -1) {\n\t\t\tdomNodeClasses.splice(i,1);\n\t\t}\n\t});\n\t//Add new classes from updated class attribute.\n\t$tw.utils.pushTop(domNodeClasses,newClasses);\n\tthis.domNode.className = domNodeClasses.join(\" \");\n}\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nButtonWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedAttributes[\"class\"]) {\n\t\tthis.updateDomNodeClasses();\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.button = ButtonWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/checkbox.js": {
"title": "$:/core/modules/widgets/checkbox.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/checkbox.js\ntype: application/javascript\nmodule-type: widget\n\nCheckbox widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CheckboxWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCheckboxWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCheckboxWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",this.checkboxClass);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"checkbox\");\n\tif(this.getValue()) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tthis.inputDomNode.setAttribute(\"disabled\",true);\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nCheckboxWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.checkboxTitle);\n\tif(tiddler) {\n\t\tif(this.checkboxTag) {\n\t\t\tif(this.checkboxInvertTag) {\n\t\t\t\treturn !tiddler.hasTag(this.checkboxTag);\n\t\t\t} else {\n\t\t\t\treturn tiddler.hasTag(this.checkboxTag);\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tvar value;\n\t\t\tif($tw.utils.hop(tiddler.fields,this.checkboxField)) {\n\t\t\t\tvalue = tiddler.fields[this.checkboxField] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = this.checkboxDefault || \"\";\n\t\t\t}\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxIndex) {\n\t\t\tvar value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || \"\");\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif(this.checkboxTag) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tif(this.checkboxDefault === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(this.checkboxDefault === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nCheckboxWidget.prototype.handleChangeEvent = function(event) {\n\tvar checked = this.inputDomNode.checked,\n\t\ttiddler = this.wiki.getTiddler(this.checkboxTitle),\n\t\tfallbackFields = {text: \"\"},\n\t\tnewFields = {title: this.checkboxTitle},\n\t\thasChanged = false,\n\t\ttagCheck = false,\n\t\thasTag = tiddler && tiddler.hasTag(this.checkboxTag),\n\t\tvalue = checked ? this.checkboxChecked : this.checkboxUnchecked;\n\tif(this.checkboxTag && this.checkboxInvertTag === \"yes\") {\n\t\ttagCheck = hasTag === checked;\n\t} else {\n\t\ttagCheck = hasTag !== checked;\n\t}\n\t// Set the tag if specified\n\tif(this.checkboxTag && (!tiddler || tagCheck)) {\n\t\tnewFields.tags = tiddler ? (tiddler.fields.tags || []).slice(0) : [];\n\t\tvar pos = newFields.tags.indexOf(this.checkboxTag);\n\t\tif(pos !== -1) {\n\t\t\tnewFields.tags.splice(pos,1);\n\t\t}\n\t\tif(this.checkboxInvertTag === \"yes\" && !checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t} else if(this.checkboxInvertTag !== \"yes\" && checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t}\n\t\thasChanged = true;\n\t}\n\t// Set the field if specified\n\tif(this.checkboxField) {\n\t\tif(!tiddler || tiddler.fields[this.checkboxField] !== value) {\n\t\t\tnewFields[this.checkboxField] = value;\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\t// Set the index if specified\n\tif(this.checkboxIndex) {\n\t\tvar indexValue = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxIndex);\n\t\tif(!tiddler || indexValue !== value) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(hasChanged) {\n\t\tif(this.checkboxIndex) {\n\t\t\tthis.wiki.setText(this.checkboxTitle,\"\",this.checkboxIndex,value);\n\t\t} else {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),fallbackFields,tiddler,newFields,this.wiki.getModificationFields()));\n\t\t}\n\t}\n\t// Trigger actions\n\tif(this.checkboxActions) {\n\t\tthis.invokeActionString(this.checkboxActions,this,event);\n\t}\n\tif(this.checkboxCheckActions && checked) {\n\t\tthis.invokeActionString(this.checkboxCheckActions,this,event);\n\t}\n\tif(this.checkboxUncheckActions && !checked) {\n\t\tthis.invokeActionString(this.checkboxUncheckActions,this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCheckboxWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.checkboxActions = this.getAttribute(\"actions\");\n\tthis.checkboxCheckActions = this.getAttribute(\"checkactions\");\n\tthis.checkboxUncheckActions = this.getAttribute(\"uncheckactions\");\n\tthis.checkboxTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.checkboxTag = this.getAttribute(\"tag\");\n\tthis.checkboxField = this.getAttribute(\"field\");\n\tthis.checkboxIndex = this.getAttribute(\"index\");\n\tthis.checkboxChecked = this.getAttribute(\"checked\");\n\tthis.checkboxUnchecked = this.getAttribute(\"unchecked\");\n\tthis.checkboxDefault = this.getAttribute(\"default\");\n\tthis.checkboxClass = this.getAttribute(\"class\",\"\");\n\tthis.checkboxInvertTag = this.getAttribute(\"invertTag\",\"\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCheckboxWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.disabled) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.checkboxTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue();\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.checkbox = CheckboxWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/codeblock.js": {
"title": "$:/core/modules/widgets/codeblock.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/codeblock.js\ntype: application/javascript\nmodule-type: widget\n\nCode block node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CodeBlockWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCodeBlockWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCodeBlockWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar codeNode = this.document.createElement(\"code\"),\n\t\tdomNode = this.document.createElement(\"pre\");\n\tcodeNode.appendChild(this.document.createTextNode(this.getAttribute(\"code\")));\n\tdomNode.appendChild(codeNode);\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n\tif(this.postRender) {\n\t\tthis.postRender();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCodeBlockWidget.prototype.execute = function() {\n\tthis.language = this.getAttribute(\"language\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCodeBlockWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.codeblock = CodeBlockWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/count.js": {
"title": "$:/core/modules/widgets/count.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/count.js\ntype: application/javascript\nmodule-type: widget\n\nCount widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CountWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCountWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCountWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.currentCount);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nCountWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Execute the filter\n\tif(this.filter) {\n\t\tthis.currentCount = this.wiki.filterTiddlers(this.filter,this).length;\n\t} else {\n\t\tthis.currentCount = \"0\";\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCountWidget.prototype.refresh = function(changedTiddlers) {\n\t// Re-execute the filter to get the count\n\tthis.computeAttributes();\n\tvar oldCount = this.currentCount;\n\tthis.execute();\n\tif(this.currentCount !== oldCount) {\n\t\t// Regenerate and rerender the widget and replace the existing DOM node\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n\n};\n\nexports.count = CountWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/diff-text.js": {
"title": "$:/core/modules/widgets/diff-text.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/diff-text.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display a diff between two texts\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget,\n\tdmp = require(\"$:/core/modules/utils/diff-match-patch/diff_match_patch.js\");\n\nvar DiffTextWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDiffTextWidget.prototype = new Widget();\n\nDiffTextWidget.prototype.invisibleCharacters = {\n\t\"\\n\": \"↩︎\\n\",\n\t\"\\r\": \"⇠\",\n\t\"\\t\": \"⇥\\t\"\n};\n\n/*\nRender this widget into the DOM\n*/\nDiffTextWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create the diff\n\tvar dmpObject = new dmp.diff_match_patch(),\n\t\tdiffs = dmpObject.diff_main(this.getAttribute(\"source\"),this.getAttribute(\"dest\"));\n\t// Apply required cleanup\n\tswitch(this.getAttribute(\"cleanup\",\"semantic\")) {\n\t\tcase \"none\":\n\t\t\t// No cleanup\n\t\t\tbreak;\n\t\tcase \"efficiency\":\n\t\t\tdmpObject.diff_cleanupEfficiency(diffs);\n\t\t\tbreak;\n\t\tdefault: // case \"semantic\"\n\t\t\tdmpObject.diff_cleanupSemantic(diffs);\n\t\t\tbreak;\n\t}\n\t// Create the elements\n\tvar domContainer = this.document.createElement(\"div\"), \n\t\tdomDiff = this.createDiffDom(diffs);\n\tparent.insertBefore(domContainer,nextSibling);\n\t// Set variables\n\tthis.setVariable(\"diff-count\",diffs.reduce(function(acc,diff) {\n\t\tif(diff[0] !== dmp.DIFF_EQUAL) {\n\t\t\tacc++;\n\t\t}\n\t\treturn acc;\n\t},0).toString());\n\t// Render child widgets\n\tthis.renderChildren(domContainer,null);\n\t// Render the diff\n\tdomContainer.appendChild(domDiff);\n\t// Save our container\n\tthis.domNodes.push(domContainer);\n};\n\n/*\nCreate DOM elements representing a list of diffs\n*/\nDiffTextWidget.prototype.createDiffDom = function(diffs) {\n\tvar self = this;\n\t// Create the element and assign the attributes\n\tvar domPre = this.document.createElement(\"pre\"),\n\t\tdomCode = this.document.createElement(\"code\");\n\t$tw.utils.each(diffs,function(diff) {\n\t\tvar tag = diff[0] === dmp.DIFF_INSERT ? \"ins\" : (diff[0] === dmp.DIFF_DELETE ? \"del\" : \"span\"),\n\t\t\tclassName = diff[0] === dmp.DIFF_INSERT ? \"tc-diff-insert\" : (diff[0] === dmp.DIFF_DELETE ? \"tc-diff-delete\" : \"tc-diff-equal\"),\n\t\t\tdom = self.document.createElement(tag),\n\t\t\ttext = diff[1],\n\t\t\tcurrPos = 0,\n\t\t\tre = /([\\x00-\\x1F])/mg,\n\t\t\tmatch = re.exec(text),\n\t\t\tspan,\n\t\t\tprintable;\n\t\tdom.className = className;\n\t\twhile(match) {\n\t\t\tif(currPos < match.index) {\n\t\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos,match.index)));\n\t\t\t}\n\t\t\tspan = self.document.createElement(\"span\");\n\t\t\tspan.className = \"tc-diff-invisible\";\n\t\t\tprintable = self.invisibleCharacters[match[0]] || (\"[0x\" + match[0].charCodeAt(0).toString(16) + \"]\");\n\t\t\tspan.appendChild(self.document.createTextNode(printable));\n\t\t\tdom.appendChild(span);\n\t\t\tcurrPos = match.index + match[0].length;\n\t\t\tmatch = re.exec(text);\n\t\t}\n\t\tif(currPos < text.length) {\n\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos)));\n\t\t}\n\t\tdomCode.appendChild(dom);\n\t});\n\tdomPre.appendChild(domCode);\n\treturn domPre;\n};\n\n/*\nCompute the internal state of the widget\n*/\nDiffTextWidget.prototype.execute = function() {\n\t// Make child widgets\n\tvar parseTreeNodes;\n\tif(this.parseTreeNode && this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\tparseTreeNodes = this.parseTreeNode.children;\n\t} else {\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: \"$:/language/Diffs/CountMessage\"}\n\t\t\t}\n\t\t}];\n\t}\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDiffTextWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.dest || changedAttributes.cleanup) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports[\"diff-text\"] = DiffTextWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/draggable.js": {
"title": "$:/core/modules/widgets/draggable.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/draggable.js\ntype: application/javascript\nmodule-type: widget\n\nDraggable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DraggableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDraggableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDraggableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Sanitise the specified tag\n\tvar tag = this.draggableTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"div\";\n\t}\n\t// Create our element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = [\"tc-draggable\"];\n\tif(this.draggableClasses) {\n\t\tclasses.push(this.draggableClasses);\n\t}\n\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t// Add event handlers\n\t$tw.utils.makeDraggable({\n\t\tdomNode: domNode,\n\t\tdragTiddlerFn: function() {return self.getAttribute(\"tiddler\");},\n\t\tdragFilterFn: function() {return self.getAttribute(\"filter\");},\n\t\tstartActions: self.startActions,\n\t\tendActions: self.endActions,\n\t\twidget: this\n\t});\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nDraggableWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.draggableTag = this.getAttribute(\"tag\",\"div\");\n\tthis.draggableClasses = this.getAttribute(\"class\");\n\tthis.startActions = this.getAttribute(\"startactions\");\n\tthis.endActions = this.getAttribute(\"endactions\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDraggableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tag || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.draggable = DraggableWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/droppable.js": {
"title": "$:/core/modules/widgets/droppable.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/droppable.js\ntype: application/javascript\nmodule-type: widget\n\nDroppable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DroppableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDroppableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDroppableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this,\n\t\ttag = this.parseTreeNode.isBlock ? \"div\" : \"span\",\n\t\tdomNode;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tif(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {\n\t\ttag = this.droppableTag;\n\t}\n\t// Create element and assign classes\n\tdomNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\tthis.assignDomNodeClasses();\n\t// Add event handlers\n\tif(this.droppableEnable) {\n\t\t$tw.utils.addEventListeners(domNode,[\n\t\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"}\n\t\t]);\t\t\n\t} else {\n\t\t$tw.utils.addClass(this.domNode,this.disabledClass);\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDroppableWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDroppableWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally. The hacky second condition is to resolve a problem with Firefox whereby there is an erroneous dragenter event if the node being dragged is within the dropzone\n\tif(this.currentlyEntered.length === 0 || (this.currentlyEntered.length === 1 && this.currentlyEntered[0] === $tw.dragInProgress)) {\n\t\tthis.currentlyEntered = [];\n\t\tif(this.domNodes[0]) {\n\t\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t\t}\n\t}\n};\n\nDroppableWidget.prototype.handleDragEnterEvent = function(event) {\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragOverEvent = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\t// Set the drop effect\n\tevent.dataTransfer.dropEffect = this.droppableEffect;\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragLeaveEvent = function(event) {\n\tthis.leaveDrag(event);\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDropEvent = function(event) {\n\tvar self = this;\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\tvar dataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Try to import the various data types we understand\n\t$tw.utils.importDataTransfer(dataTransfer,null,function(fieldsArray) {\n\t\tfieldsArray.forEach(function(fields) {\n\t\t\tself.performActions(fields.title || fields.text,event);\n\t\t});\n\t});\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.performActions = function(title,event) {\n\tif(this.droppableActions) {\n\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\tthis.invokeActionString(this.droppableActions,this,event,{actionTiddler: title, modifier: modifierKey});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDroppableWidget.prototype.execute = function() {\n\tthis.droppableActions = this.getAttribute(\"actions\");\n\tthis.droppableEffect = this.getAttribute(\"effect\",\"copy\");\n\tthis.droppableTag = this.getAttribute(\"tag\");\n\tthis.droppableEnable = (this.getAttribute(\"enable\") || \"yes\") === \"yes\";\n\tthis.disabledClass = this.getAttribute(\"disabledClass\",\"\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nDroppableWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-droppable\");\n\tthis.domNode.className = classes.join(\" \");\t\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDroppableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tag || changedAttributes.enable || changedAttributes.disabledClass || changedAttributes.actions || changedAttributes.effect) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedAttributes[\"class\"]) {\n\t\tthis.assignDomNodeClasses();\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.droppable = DroppableWidget;\n\n})();",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/dropzone.js": {
"title": "$:/core/modules/widgets/dropzone.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/dropzone.js\ntype: application/javascript\nmodule-type: widget\n\nDropzone widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DropZoneWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDropZoneWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDropZoneWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"div\");\n\tdomNode.className = this.dropzoneClass || \"tc-dropzone\";\n\t// Add event handlers\n\tif(this.dropzoneEnable) {\n\t\t$tw.utils.addEventListeners(domNode,[\n\t\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"},\n\t\t\t{name: \"paste\", handlerObject: this, handlerMethod: \"handlePasteEvent\"},\n\t\t\t{name: \"dragend\", handlerObject: this, handlerMethod: \"handleDragEndEvent\"}\n\t\t]);\t\t\n\t}\n\tdomNode.addEventListener(\"click\",function (event) {\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDropZoneWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDropZoneWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally\n\tif(this.currentlyEntered.length === 0) {\n\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t}\n};\n\nDropZoneWidget.prototype.handleDragEnterEvent = function(event) {\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handleDragOverEvent = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\tevent.dataTransfer.dropEffect = \"copy\"; // Explicitly show this is a copy\n};\n\nDropZoneWidget.prototype.handleDragLeaveEvent = function(event) {\n\tthis.leaveDrag(event);\n};\n\nDropZoneWidget.prototype.handleDragEndEvent = function(event) {\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDropZoneWidget.prototype.handleDropEvent = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});\n\t\t};\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tvar self = this,\n\t\tdataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Import any files in the drop\n\tvar numFiles = 0;\n\tif(dataTransfer.files) {\n\t\tnumFiles = this.wiki.readFiles(dataTransfer.files,{\n\t\t\tcallback: readFileCallback,\n\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t});\n\t}\n\t// Try to import the various data types we understand\n\tif(numFiles === 0) {\n\t\t$tw.utils.importDataTransfer(dataTransfer,this.wiki.generateNewTitle(\"Untitled\"),readFileCallback);\n\t}\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handlePasteEvent = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});\n\t\t};\n\t// Let the browser handle it if we're in a textarea or input box\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {\n\t\tvar self = this,\n\t\t\titems = event.clipboardData.items;\n\t\t// Enumerate the clipboard items\n\t\tfor(var t = 0; t<items.length; t++) {\n\t\t\tvar item = items[t];\n\t\t\tif(item.kind === \"file\") {\n\t\t\t\t// Import any files\n\t\t\t\tthis.wiki.readFile(item.getAsFile(),{\n\t\t\t\t\tcallback: readFileCallback,\n\t\t\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t\t\t});\n\t\t\t} else if(item.kind === \"string\") {\n\t\t\t\t// Create tiddlers from string items\n\t\t\t\tvar type = item.type;\n\t\t\t\titem.getAsString(function(str) {\n\t\t\t\t\tvar tiddlerFields = {\n\t\t\t\t\t\ttitle: self.wiki.generateNewTitle(\"Untitled\"),\n\t\t\t\t\t\ttext: str,\n\t\t\t\t\t\ttype: type\n\t\t\t\t\t};\n\t\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\t\tconsole.log(\"Importing string '\" + str + \"', type: '\" + type + \"'\");\n\t\t\t\t\t}\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify([tiddlerFields]), autoOpenOnImport: self.autoOpenOnImport, importTitle: self.importTitle});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t// Tell the browser that we've handled the paste\n\t\tevent.stopPropagation();\n\t\tevent.preventDefault();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDropZoneWidget.prototype.execute = function() {\n\tthis.dropzoneClass = this.getAttribute(\"class\");\n\tthis.dropzoneDeserializer = this.getAttribute(\"deserializer\");\n\tthis.dropzoneEnable = (this.getAttribute(\"enable\") || \"yes\") === \"yes\";\n\tthis.autoOpenOnImport = this.getAttribute(\"autoOpenOnImport\");\n\tthis.importTitle = this.getAttribute(\"importTitle\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDropZoneWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.enable || changedAttributes.autoOpenOnImport || changedAttributes.importTitle || changedAttributes.deserializer || changedAttributes.class) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.dropzone = DropZoneWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-binary.js": {
"title": "$:/core/modules/widgets/edit-binary.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-binary.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-binary widget; placeholder for editing binary tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\nvar EXPORT_BUTTON_IMAGE = \"$:/core/images/export-button\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBinaryWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBinaryWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBinaryWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBinaryWidget.prototype.execute = function() {\n\t// Get our parameters\n\tvar editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tvar tiddler = this.wiki.getTiddler(editTitle);\n\tvar type = tiddler.fields.type;\n\tvar text = tiddler.fields.text;\n\t// Transclude the binary data tiddler warning message\n\tvar warn = {\n\t\ttype: \"element\",\n\t\ttag: \"p\",\n\t\tchildren: [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Create download link based on draft tiddler title\n\tvar link = {\n\t\ttype: \"element\",\n\t\ttag: \"a\",\n\t\tattributes: {\n\t\t\ttitle: {type: \"indirect\", textReference: \"!!draft.title\"},\n\t\t\tdownload: {type: \"indirect\", textReference: \"!!draft.title\"}\n\t\t},\n\t\tchildren: [{\n\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: EXPORT_BUTTON_IMAGE}\n\t\t\t}\n\t\t}]\n\t};\n\t// Set the link href to internal data URI (no external)\n\tif(text) {\n\t\tlink.attributes.href = {\n\t\t\ttype: \"string\", \n\t\t\tvalue: \"data:\" + type + \";base64,\" + text\n\t\t};\n\t}\n\t// Combine warning message and download link in a div\n\tvar element = {\n\t\ttype: \"element\",\n\t\ttag: \"div\",\n\t\tattributes: {\n\t\t\tclass: {type: \"string\", value: \"tc-binary-warning\"}\n\t\t},\n\t\tchildren: [warn, link]\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets([element]);\n};\n\n/*\nRefresh by refreshing our child widget\n*/\nEditBinaryWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"edit-binary\"] = EditBinaryWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-bitmap.js": {
"title": "$:/core/modules/widgets/edit-bitmap.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-bitmap.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-bitmap widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Default image sizes\nvar DEFAULT_IMAGE_WIDTH = 600,\n\tDEFAULT_IMAGE_HEIGHT = 370,\n\tDEFAULT_IMAGE_TYPE = \"image/png\";\n\n// Configuration tiddlers\nvar LINE_WIDTH_TITLE = \"$:/config/BitmapEditor/LineWidth\",\n\tLINE_COLOUR_TITLE = \"$:/config/BitmapEditor/Colour\",\n\tLINE_OPACITY_TITLE = \"$:/config/BitmapEditor/Opacity\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBitmapWidget = function(parseTreeNode,options) {\n\t// Initialise the editor operations if they've not been done already\n\tif(!this.editorOperations) {\n\t\tEditBitmapWidget.prototype.editorOperations = {};\n\t\t$tw.modules.applyMethods(\"bitmapeditoroperation\",this.editorOperations);\n\t}\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBitmapWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBitmapWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create the wrapper for the toolbar and render its content\n\tthis.toolbarNode = this.document.createElement(\"div\");\n\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\tparent.insertBefore(this.toolbarNode,nextSibling);\n\tthis.domNodes.push(this.toolbarNode);\n\t// Create the on-screen canvas\n\tthis.canvasDomNode = $tw.utils.domMaker(\"canvas\",{\n\t\tdocument: this.document,\n\t\t\"class\":\"tc-edit-bitmapeditor\",\n\t\teventListeners: [{\n\t\t\tname: \"touchstart\", handlerObject: this, handlerMethod: \"handleTouchStartEvent\"\n\t\t},{\n\t\t\tname: \"touchmove\", handlerObject: this, handlerMethod: \"handleTouchMoveEvent\"\n\t\t},{\n\t\t\tname: \"touchend\", handlerObject: this, handlerMethod: \"handleTouchEndEvent\"\n\t\t},{\n\t\t\tname: \"mousedown\", handlerObject: this, handlerMethod: \"handleMouseDownEvent\"\n\t\t},{\n\t\t\tname: \"mousemove\", handlerObject: this, handlerMethod: \"handleMouseMoveEvent\"\n\t\t},{\n\t\t\tname: \"mouseup\", handlerObject: this, handlerMethod: \"handleMouseUpEvent\"\n\t\t}]\n\t});\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Render toolbar child widgets\n\tthis.renderChildren(this.toolbarNode,null);\n\t// // Insert the elements into the DOM\n\tparent.insertBefore(this.canvasDomNode,nextSibling);\n\tthis.domNodes.push(this.canvasDomNode);\n\t// Load the image into the canvas\n\tif($tw.browser) {\n\t\tthis.loadCanvas();\n\t}\n\t// Add widget message listeners\n\tthis.addEventListeners([\n\t\t{type: \"tm-edit-bitmap-operation\", handler: \"handleEditBitmapOperationMessage\"}\n\t]);\n};\n\n/*\nHandle an edit bitmap operation message from the toolbar\n*/\nEditBitmapWidget.prototype.handleEditBitmapOperationMessage = function(event) {\n\t// Invoke the handler\n\tvar handler = this.editorOperations[event.param];\n\tif(handler) {\n\t\thandler.call(this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBitmapWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nJust refresh the toolbar\n*/\nEditBitmapWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nSet the bitmap size variables and refresh the toolbar\n*/\nEditBitmapWidget.prototype.refreshToolbar = function() {\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Refresh each of our child widgets\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\tchildWidget.refreshSelf();\n\t});\n};\n\nEditBitmapWidget.prototype.loadCanvas = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle),\n\t\tcurrImage = new Image();\n\t// Set up event handlers for loading the image\n\tvar self = this;\n\tcurrImage.onload = function() {\n\t\t// Copy the image to the on-screen canvas\n\t\tself.initCanvas(self.canvasDomNode,currImage.width,currImage.height,currImage);\n\t\t// And also copy the current bitmap to the off-screen canvas\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,currImage.width,currImage.height,currImage);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\tcurrImage.onerror = function() {\n\t\t// Set the on-screen canvas size and clear it\n\t\tself.initCanvas(self.canvasDomNode,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the off-screen canvas size and clear it\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\t// Get the current bitmap into an image object\n\tif(tiddler && tiddler.fields.type && tiddler.fields.text) {\n\t\tcurrImage.src = \"data:\" + tiddler.fields.type + \";base64,\" + tiddler.fields.text;\t\t\n\t} else {\n\t\tcurrImage.width = DEFAULT_IMAGE_WIDTH;\n\t\tcurrImage.height = DEFAULT_IMAGE_HEIGHT;\n\t\tcurrImage.onerror();\n\t}\n};\n\nEditBitmapWidget.prototype.initCanvas = function(canvas,width,height,image) {\n\tcanvas.width = width;\n\tcanvas.height = height;\n\tvar ctx = canvas.getContext(\"2d\");\n\tif(image) {\n\t\tctx.drawImage(image,0,0);\n\t} else {\n\t\tctx.fillStyle = \"#fff\";\n\t\tctx.fillRect(0,0,canvas.width,canvas.height);\n\t}\n};\n\n/*\n** Change the size of the canvas, preserving the current image\n*/\nEditBitmapWidget.prototype.changeCanvasSize = function(newWidth,newHeight) {\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\");\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\n/*\n** Rotate the canvas left by 90 degrees\n*/\nEditBitmapWidget.prototype.rotateCanvasLeft = function() {\n\t// Get the current size of the image\n\tvar origWidth = this.currCanvas.width,\n\t\torigHeight = this.currCanvas.height;\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\"),\n\t\tnewWidth = origHeight,\n\t\tnewHeight = origWidth;\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.save();\n\tctx.translate(newWidth / 2,newHeight / 2);\n\tctx.rotate(-Math.PI / 2);\n\tctx.drawImage(this.currCanvas,-origWidth / 2,-origHeight / 2);\n\tctx.restore();\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\nEditBitmapWidget.prototype.handleTouchStartEvent = function(event) {\n\tthis.brushDown = true;\n\tthis.strokeStart(event.touches[0].clientX,event.touches[0].clientY);\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.touches[0].clientX,event.touches[0].clientY);\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchEndEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseDownEvent = function(event) {\n\tthis.strokeStart(event.clientX,event.clientY);\n\tthis.brushDown = true;\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.clientX,event.clientY);\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.handleMouseUpEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.adjustCoordinates = function(x,y) {\n\tvar canvasRect = this.canvasDomNode.getBoundingClientRect(),\n\t\tscale = this.canvasDomNode.width/canvasRect.width;\n\treturn {x: (x - canvasRect.left) * scale, y: (y - canvasRect.top) * scale};\n};\n\nEditBitmapWidget.prototype.strokeStart = function(x,y) {\n\t// Start off a new stroke\n\tthis.stroke = [this.adjustCoordinates(x,y)];\n};\n\nEditBitmapWidget.prototype.strokeMove = function(x,y) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\"),\n\t\tt;\n\t// Add the new position to the end of the stroke\n\tthis.stroke.push(this.adjustCoordinates(x,y));\n\t// Redraw the previous image\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Render the stroke\n\tctx.globalAlpha = parseFloat(this.wiki.getTiddlerText(LINE_OPACITY_TITLE,\"1.0\"));\n\tctx.strokeStyle = this.wiki.getTiddlerText(LINE_COLOUR_TITLE,\"#ff0\");\n\tctx.lineWidth = parseFloat(this.wiki.getTiddlerText(LINE_WIDTH_TITLE,\"3\"));\n\tctx.lineCap = \"round\";\n\tctx.lineJoin = \"round\";\n\tctx.beginPath();\n\tctx.moveTo(this.stroke[0].x,this.stroke[0].y);\n\tfor(t=1; t<this.stroke.length-1; t++) {\n\t\tvar s1 = this.stroke[t],\n\t\t\ts2 = this.stroke[t-1],\n\t\t\ttx = (s1.x + s2.x)/2,\n\t\t\tty = (s1.y + s2.y)/2;\n\t\tctx.quadraticCurveTo(s2.x,s2.y,tx,ty);\n\t}\n\tctx.stroke();\n};\n\nEditBitmapWidget.prototype.strokeEnd = function() {\n\t// Copy the bitmap to the off-screen canvas\n\tvar ctx = this.currCanvas.getContext(\"2d\");\n\tctx.drawImage(this.canvasDomNode,0,0);\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\nEditBitmapWidget.prototype.saveChanges = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle) || new $tw.Tiddler({title: this.editTitle,type: DEFAULT_IMAGE_TYPE});\n\t// data URIs look like \"data:<type>;base64,<text>\"\n\tvar dataURL = this.canvasDomNode.toDataURL(tiddler.fields.type),\n\t\tposColon = dataURL.indexOf(\":\"),\n\t\tposSemiColon = dataURL.indexOf(\";\"),\n\t\tposComma = dataURL.indexOf(\",\"),\n\t\ttype = dataURL.substring(posColon+1,posSemiColon),\n\t\ttext = dataURL.substring(posComma+1);\n\tvar update = {type: type, text: text};\n\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getModificationFields(),tiddler,update,this.wiki.getCreationFields()));\n};\n\nexports[\"edit-bitmap\"] = EditBitmapWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-shortcut.js": {
"title": "$:/core/modules/widgets/edit-shortcut.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-shortcut.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display an editable keyboard shortcut\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditShortcutWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditShortcutWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditShortcutWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.inputNode = this.document.createElement(\"input\");\n\t// Assign classes\n\tif(this.shortcutClass) {\n\t\tthis.inputNode.className = this.shortcutClass;\t\t\n\t}\n\t// Assign other attributes\n\tif(this.shortcutStyle) {\n\t\tthis.inputNode.setAttribute(\"style\",this.shortcutStyle);\n\t}\n\tif(this.shortcutTooltip) {\n\t\tthis.inputNode.setAttribute(\"title\",this.shortcutTooltip);\n\t}\n\tif(this.shortcutPlaceholder) {\n\t\tthis.inputNode.setAttribute(\"placeholder\",this.shortcutPlaceholder);\n\t}\n\tif(this.shortcutAriaLabel) {\n\t\tthis.inputNode.setAttribute(\"aria-label\",this.shortcutAriaLabel);\n\t}\n\t// Assign the current shortcut\n\tthis.updateInputNode();\n\t// Add event handlers\n\t$tw.utils.addEventListeners(this.inputNode,[\n\t\t{name: \"keydown\", handlerObject: this, handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Link into the DOM\n\tparent.insertBefore(this.inputNode,nextSibling);\n\tthis.domNodes.push(this.inputNode);\n\t// Focus the input Node if focus === \"yes\" or focus === \"true\"\n\tif(this.shortcutFocus === \"yes\" || this.shortcutFocus === \"true\") {\n\t\tthis.focus();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditShortcutWidget.prototype.execute = function() {\n\tthis.shortcutTiddler = this.getAttribute(\"tiddler\");\n\tthis.shortcutField = this.getAttribute(\"field\");\n\tthis.shortcutIndex = this.getAttribute(\"index\");\n\tthis.shortcutPlaceholder = this.getAttribute(\"placeholder\");\n\tthis.shortcutDefault = this.getAttribute(\"default\",\"\");\n\tthis.shortcutClass = this.getAttribute(\"class\");\n\tthis.shortcutStyle = this.getAttribute(\"style\");\n\tthis.shortcutTooltip = this.getAttribute(\"tooltip\");\n\tthis.shortcutAriaLabel = this.getAttribute(\"aria-label\");\n\tthis.shortcutFocus = this.getAttribute(\"focus\");\n};\n\n/*\nUpdate the value of the input node\n*/\nEditShortcutWidget.prototype.updateInputNode = function() {\n\tif(this.shortcutField) {\n\t\tvar tiddler = this.wiki.getTiddler(this.shortcutTiddler);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,this.shortcutField)) {\n\t\t\tthis.inputNode.value = tiddler.getFieldString(this.shortcutField);\n\t\t} else {\n\t\t\tthis.inputNode.value = this.shortcutDefault;\n\t\t}\n\t} else if(this.shortcutIndex) {\n\t\tthis.inputNode.value = this.wiki.extractTiddlerDataItem(this.shortcutTiddler,this.shortcutIndex,this.shortcutDefault);\n\t} else {\n\t\tthis.inputNode.value = this.wiki.getTiddlerText(this.shortcutTiddler,this.shortcutDefault);\n\t}\n};\n\n/*\nHandle a dom \"keydown\" event\n*/\nEditShortcutWidget.prototype.handleKeydownEvent = function(event) {\n\t// Ignore shift, ctrl, meta, alt\n\tif(event.keyCode && $tw.keyboardManager.getModifierKeys().indexOf(event.keyCode) === -1) {\n\t\t// Get the shortcut text representation\n\t\tvar value = $tw.keyboardManager.getPrintableShortcuts([{\n\t\t\tctrlKey: event.ctrlKey,\n\t\t\tshiftKey: event.shiftKey,\n\t\t\taltKey: event.altKey,\n\t\t\tmetaKey: event.metaKey,\n\t\t\tkeyCode: event.keyCode\n\t\t}]);\n\t\tif(value.length > 0) {\n\t\t\tthis.wiki.setText(this.shortcutTiddler,this.shortcutField,this.shortcutIndex,value[0]);\n\t\t}\n\t\t// Ignore the keydown if it was already handled\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn true;\t\t\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nfocus the input node\n*/\nEditShortcutWidget.prototype.focus = function() {\n\tif(this.inputNode.focus && this.inputNode.select) {\n\t\tthis.inputNode.focus();\n\t\tthis.inputNode.select();\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget needed re-rendering\n*/\nEditShortcutWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.placeholder || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.style || changedAttributes.tooltip || changedAttributes[\"aria-label\"] || changedAttributes.focus) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedTiddlers[this.shortcutTiddler]) {\n\t\tthis.updateInputNode();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports[\"edit-shortcut\"] = EditShortcutWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-text.js": {
"title": "$:/core/modules/widgets/edit-text.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-text.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-text widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar editTextWidgetFactory = require(\"$:/core/modules/editor/factory.js\").editTextWidgetFactory,\n\tFramedEngine = require(\"$:/core/modules/editor/engines/framed.js\").FramedEngine,\n\tSimpleEngine = require(\"$:/core/modules/editor/engines/simple.js\").SimpleEngine;\n\nexports[\"edit-text\"] = editTextWidgetFactory(FramedEngine,SimpleEngine);\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit.js": {
"title": "$:/core/modules/widgets/edit.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit.js\ntype: application/javascript\nmodule-type: widget\n\nEdit widget is a meta-widget chooses the appropriate actual editting widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n// Mappings from content type to editor type are stored in tiddlers with this prefix\nvar EDITOR_MAPPING_PREFIX = \"$:/config/EditorTypeMappings/\";\n\n/*\nCompute the internal state of the widget\n*/\nEditWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.editField = this.getAttribute(\"field\",\"text\");\n\tthis.editIndex = this.getAttribute(\"index\");\n\tthis.editClass = this.getAttribute(\"class\");\n\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\tthis.editTabIndex = this.getAttribute(\"tabindex\");\n\tthis.editFocus = this.getAttribute(\"focus\",\"\");\n\tthis.editCancelPopups = this.getAttribute(\"cancelPopups\",\"\");\n\tthis.editInputActions = this.getAttribute(\"inputActions\");\n\tthis.editRefreshTitle = this.getAttribute(\"refreshTitle\");\n\tthis.editAutoComplete = this.getAttribute(\"autocomplete\");\n\t// Choose the appropriate edit widget\n\tthis.editorType = this.getEditorType();\n\t// Make the child widgets\n\tthis.makeChildWidgets([{\n\t\ttype: \"edit-\" + this.editorType,\n\t\tattributes: this.parseTreeNode.attributes,\n\t\tchildren: this.parseTreeNode.children\n\t}]);\n};\n\nEditWidget.prototype.getEditorType = function() {\n\t// Get the content type of the thing we're editing\n\tvar type;\n\tif(this.editField === \"text\") {\n\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\tif(tiddler) {\n\t\t\ttype = tiddler.fields.type;\n\t\t}\n\t}\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar editorType = this.wiki.getTiddlerText(EDITOR_MAPPING_PREFIX + type);\n\tif(!editorType) {\n\t\tvar typeInfo = $tw.config.contentTypeInfo[type];\n\t\tif(typeInfo && typeInfo.encoding === \"base64\") {\n\t\t\teditorType = \"binary\";\n\t\t} else {\n\t\t\teditorType = \"text\";\n\t\t}\n\t}\n\treturn editorType;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEditWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh if an attribute has changed, or the type associated with the target tiddler has changed\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.tabindex || changedAttributes.cancelPopups || changedAttributes.inputActions || changedAttributes.refreshTitle || changedAttributes.autocomplete || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.edit = EditWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/element.js": {
"title": "$:/core/modules/widgets/element.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/element.js\ntype: application/javascript\nmodule-type: widget\n\nElement widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ElementWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nElementWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nElementWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\t// Neuter blacklisted elements\n\tthis.tag = this.parseTreeNode.tag;\n\tif($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {\n\t\tthis.tag = \"safe-\" + this.tag;\n\t}\n\t// Adjust headings by the current base level\n\tvar headingLevel = [\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\"].indexOf(this.tag);\n\tif(headingLevel !== -1) {\n\t\tvar baseLevel = parseInt(this.getVariable(\"tv-adjust-heading-level\",\"0\"),10) || 0;\n\t\theadingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);\n\t\tthis.tag = \"h\" + headingLevel;\n\t}\n\t// Select the namespace for the tag\n\tvar tagNamespaces = {\n\t\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\t\tmath: \"http://www.w3.org/1998/Math/MathML\",\n\t\t\tbody: \"http://www.w3.org/1999/xhtml\"\n\t\t};\n\tthis.namespace = tagNamespaces[this.tag];\n\tif(this.namespace) {\n\t\tthis.setVariable(\"namespace\",this.namespace);\n\t} else {\n\t\tthis.namespace = this.getVariable(\"namespace\",{defaultValue: \"http://www.w3.org/1999/xhtml\"});\n\t}\n\t// Invoke the th-rendering-element hook\n\tvar parseTreeNodes = $tw.hooks.invokeHook(\"th-rendering-element\",null,this);\n\tthis.isReplaced = !!parseTreeNodes;\n\tif(parseTreeNodes) {\n\t\t// Use the parse tree nodes provided by the hook\n\t\tthis.makeChildWidgets(parseTreeNodes);\n\t\tthis.renderChildren(this.parentDomNode,null);\n\t\treturn;\n\t}\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n\t// Create the DOM node and render children\n\tvar domNode = this.document.createElementNS(this.namespace,this.tag);\n\tthis.assignAttributes(domNode,{excludeEventAttributes: true});\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nElementWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\thasChangedAttributes = $tw.utils.count(changedAttributes) > 0;\n\tif(hasChangedAttributes) {\n\t\tif(!this.isReplaced) {\n\t\t\t// Update our attributes\n\t\t\tthis.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});\t\t\t\n\t\t} else {\n\t\t\t// If we were replaced then completely refresh ourselves\n\t\t\treturn this.refreshSelf();\n\t\t}\n\t}\n\treturn this.refreshChildren(changedTiddlers) || hasChangedAttributes;\n};\n\nexports.element = ElementWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/encrypt.js": {
"title": "$:/core/modules/widgets/encrypt.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/encrypt.js\ntype: application/javascript\nmodule-type: widget\n\nEncrypt widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EncryptWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEncryptWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEncryptWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.encryptedText);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEncryptWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\",\"[!is[system]]\");\n\t// Encrypt the filtered tiddlers\n\tvar tiddlers = this.wiki.filterTiddlers(this.filter),\n\t\tjson = {},\n\t\tself = this;\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title),\n\t\t\tjsonTiddler = {};\n\t\tfor(var f in tiddler.fields) {\n\t\t\tjsonTiddler[f] = tiddler.getFieldString(f);\n\t\t}\n\t\tjson[title] = jsonTiddler;\n\t});\n\tthis.encryptedText = $tw.utils.htmlEncode($tw.crypto.encrypt(JSON.stringify(json)));\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEncryptWidget.prototype.refresh = function(changedTiddlers) {\n\t// We don't need to worry about refreshing because the encrypt widget isn't for interactive use\n\treturn false;\n};\n\nexports.encrypt = EncryptWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/entity.js": {
"title": "$:/core/modules/widgets/entity.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/entity.js\ntype: application/javascript\nmodule-type: widget\n\nHTML entity widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EntityWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEntityWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEntityWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar entityString = this.getAttribute(\"entity\",this.parseTreeNode.entity || \"\"),\n\t\ttextNode = this.document.createTextNode($tw.utils.entityDecode(entityString));\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEntityWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEntityWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.entity) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.entity = EntityWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/eventcatcher.js": {
"title": "$:/core/modules/widgets/eventcatcher.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/eventcatcher.js\ntype: application/javascript\nmodule-type: widget\n\nEvent handler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EventWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEventWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEventWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.elementTag && $tw.config.htmlUnsafeElements.indexOf(this.elementTag) === -1) {\n\t\ttag = this.elementTag;\n\t}\t\n\tvar domNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\t// Assign classes\n\tthis.assignDomNodeClasses();\t\n\t// Add our event handler\n\t$tw.utils.each(this.types,function(type) {\n\t\tdomNode.addEventListener(type,function(event) {\n\t\t\tvar selector = self.getAttribute(\"selector\"),\n\t\t\t\tactions = self.getAttribute(\"actions-\"+type),\n\t\t\t\tselectedNode = event.target,\n\t\t\t\tselectedNodeRect,\n\t\t\t\tcatcherNodeRect,\n\t\t\t\tvariables = {};\n\t\t\tif(selector) {\n\t\t\t\t// Search ancestors for a node that matches the selector\n\t\t\t\twhile(!selectedNode.matches(selector) && selectedNode !== domNode) {\n\t\t\t\t\tselectedNode = selectedNode.parentNode;\n\t\t\t\t}\n\t\t\t\t// If we found one, copy the attributes as variables, otherwise exit\n\t\t\t\tif(selectedNode.matches(selector)) {\n\t\t\t\t\t$tw.utils.each(selectedNode.attributes,function(attribute) {\n\t\t\t\t\t\tvariables[\"dom-\" + attribute.name] = attribute.value.toString();\n\t\t\t\t\t});\n\t\t\t\t\t//Add a variable with a popup coordinate string for the selected node\n\t\t\t\t\tvariables[\"tv-popup-coords\"] = \"(\" + selectedNode.offsetLeft + \",\" + selectedNode.offsetTop +\",\" + selectedNode.offsetWidth + \",\" + selectedNode.offsetHeight + \")\";\n\t\t\t\t\t\n\t\t\t\t\t//Add variables for offset of selected node\n\t\t\t\t\tvariables[\"tv-selectednode-posx\"] = selectedNode.offsetLeft.toString();\n\t\t\t\t\tvariables[\"tv-selectednode-posy\"] = selectedNode.offsetTop.toString();\n\t\t\t\t\tvariables[\"tv-selectednode-width\"] = selectedNode.offsetWidth.toString();\n\t\t\t\t\tvariables[\"tv-selectednode-height\"] = selectedNode.offsetHeight.toString();\n\n\t\t\t\t\t//Add variables for event X and Y position relative to selected node\n\t\t\t\t\tselectedNodeRect = selectedNode.getBoundingClientRect();\t\t\t\t\n\t\t\t\t\tvariables[\"event-fromselected-posx\"] = (event.clientX - selectedNodeRect.left).toString();\n\t\t\t\t\tvariables[\"event-fromselected-posy\"] = (event.clientY - selectedNodeRect.top).toString();\n\n\t\t\t\t\t//Add variables for event X and Y position relative to event catcher node\n\t\t\t\t\tcatcherNodeRect = self.domNode.getBoundingClientRect();\n\t\t\t\t\tvariables[\"event-fromcatcher-posx\"] = (event.clientX - catcherNodeRect.left).toString();\n\t\t\t\t\tvariables[\"event-fromcatcher-posy\"] = (event.clientY - catcherNodeRect.top).toString();\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Execute our actions with the variables\n\t\t\tif(actions) {\n\t\t\t\t// Add a variable for the modifier key\n\t\t\t\tvariables.modifier = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\t\t// Add a variable for the mouse button\n\t\t\t\tif(\"button\" in event) {\n\t\t\t\t\tif(event.button === 0) {\n\t\t\t\t\t\tvariables[\"event-mousebutton\"] = \"left\";\n\t\t\t\t\t} else if(event.button === 1) {\n\t\t\t\t\t\tvariables[\"event-mousebutton\"] = \"middle\";\n\t\t\t\t\t} else if(event.button === 2) {\n\t\t\t\t\t\tvariables[\"event-mousebutton\"] = \"right\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvariables[\"event-type\"] = event.type.toString();\n\t\t\t\tif(typeof event.detail === \"object\" && !!event.detail) {\n\t\t\t\t\t$tw.utils.each(event.detail,function(detailValue,detail) {\n\t\t\t\t\t\tvariables[\"event-detail-\" + detail] = detailValue.toString();\n\t\t\t\t\t});\n\t\t\t\t} else if(!!event.detail) {\n\t\t\t\t\tvariables[\"event-detail\"] = event.detail.toString();\n\t\t\t\t}\n\t\t\t\tself.invokeActionString(actions,self,event,variables);\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},false);\n\t});\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEventWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Get attributes that require a refresh on change\n\tthis.types = this.getAttribute(\"events\",\"\").split(\" \");\n\tthis.elementTag = this.getAttribute(\"tag\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\nEventWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-eventcatcher\");\n\tthis.domNode.className = classes.join(\" \");\t\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEventWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"events\"] || changedAttributes[\"tag\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedAttributes[\"class\"]) {\n\t\tthis.assignDomNodeClasses();\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.eventcatcher = EventWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/fieldmangler.js": {
"title": "$:/core/modules/widgets/fieldmangler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/fieldmangler.js\ntype: application/javascript\nmodule-type: widget\n\nField mangler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldManglerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-remove-field\", handler: \"handleRemoveFieldEvent\"},\n\t\t{type: \"tm-add-field\", handler: \"handleAddFieldEvent\"},\n\t\t{type: \"tm-remove-tag\", handler: \"handleRemoveTagEvent\"},\n\t\t{type: \"tm-add-tag\", handler: \"handleAddTagEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldManglerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldManglerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldManglerWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.mangleTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldManglerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nFieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tdeletion = {};\n\tdeletion[event.param] = undefined;\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,deletion));\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleAddFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\taddition = this.wiki.getModificationFields(),\n\t\thadInvalidFieldName = false,\n\t\taddField = function(name,value) {\n\t\t\tvar trimmedName = name.toLowerCase().trim();\n\t\t\tif(!$tw.utils.isValidFieldName(trimmedName)) {\n\t\t\t\tif(!hadInvalidFieldName) {\n\t\t\t\t\talert($tw.language.getString(\n\t\t\t\t\t\t\"InvalidFieldName\",\n\t\t\t\t\t\t{variables:\n\t\t\t\t\t\t\t{fieldName: trimmedName}\n\t\t\t\t\t\t}\n\t\t\t\t\t));\n\t\t\t\t\thadInvalidFieldName = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif(!value && tiddler) {\n\t\t\t\t\tvalue = tiddler.fields[trimmedName];\n\t\t\t\t}\n\t\t\t\taddition[trimmedName] = value || \"\";\n\t\t\t}\n\t\t\treturn;\n\t\t};\n\taddition.title = this.mangleTitle;\n\tif(typeof event.param === \"string\") {\n\t\taddField(event.param,\"\");\n\t}\n\tif(typeof event.paramObject === \"object\") {\n\t\tfor(var name in event.paramObject) {\n\t\t\taddField(name,event.paramObject[name]);\n\t\t}\n\t}\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && tiddler.fields.tags) {\n\t\tvar p = tiddler.fields.tags.indexOf(event.param);\n\t\tif(p !== -1) {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\tmodification.tags.splice(p,1);\n\t\t\tif(modification.tags.length === 0) {\n\t\t\t\tmodification.tags = undefined;\n\t\t\t}\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\n\t\t}\n\t}\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleAddTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && typeof event.param === \"string\") {\n\t\tvar tag = event.param.trim();\n\t\tif(tag !== \"\") {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\t$tw.utils.pushTop(modification.tags,tag);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\t\t\t\n\t\t}\n\t} else if(typeof event.param === \"string\" && event.param.trim() !== \"\" && this.mangleTitle.trim() !== \"\") {\n\t\tvar tag = [];\n\t\ttag.push(event.param.trim());\n\t\tthis.wiki.addTiddler(new $tw.Tiddler({title: this.mangleTitle, tags: tag},modification));\n\t}\n\treturn true;\n};\n\nexports.fieldmangler = FieldManglerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/fields.js": {
"title": "$:/core/modules/widgets/fields.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/fields.js\ntype: application/javascript\nmodule-type: widget\n\nFields widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldsWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldsWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldsWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.template = this.getAttribute(\"template\");\n\tthis.sort = this.getAttribute(\"sort\",\"yes\") === \"yes\";\n\tthis.sortReverse = this.getAttribute(\"sortReverse\",\"no\") === \"yes\";\n\tthis.exclude = this.getAttribute(\"exclude\");\n\tthis.include = this.getAttribute(\"include\",null);\n\tthis.stripTitlePrefix = this.getAttribute(\"stripTitlePrefix\",\"no\") === \"yes\";\n\t// Get the value to display\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\n\t// Get the inclusion and exclusion list\n\tvar excludeArr = (this.exclude) ? this.exclude.split(\" \") : [\"text\"];\n\t// Include takes precedence\n\tvar includeArr = (this.include) ? this.include.split(\" \") : null;\n\n\t// Compose the template\n\tvar text = [];\n\tif(this.template && tiddler) {\n\t\tvar fields = [];\n\t\tif (includeArr) { // Include takes precedence\n\t\t\tfor(var i=0; i<includeArr.length; i++) {\n\t\t\t\tif(tiddler.fields[includeArr[i]]) {\n\t\t\t\t\tfields.push(includeArr[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor(var fieldName in tiddler.fields) {\n\t\t\t\tif(excludeArr.indexOf(fieldName) === -1) {\n\t\t\t\t\tfields.push(fieldName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.sort) fields.sort();\n\t\tif (this.sortReverse) fields.reverse();\n\t\tfor(var f=0, fmax=fields.length; f<fmax; f++) {\n\t\t\tfieldName = fields[f];\n\t\t\tvar row = this.template,\n\t\t\t\tvalue = tiddler.getFieldString(fieldName);\n\t\t\tif(this.stripTitlePrefix && fieldName === \"title\") {\n\t\t\t\tvar reStrip = /^\\{[^\\}]+\\}(.+)/mg,\n\t\t\t\t\treMatch = reStrip.exec(value);\n\t\t\t\tif(reMatch) {\n\t\t\t\t\tvalue = reMatch[1];\n\t\t\t\t}\n\t\t\t}\n\t\t\trow = $tw.utils.replaceString(row,\"$name$\",fieldName);\n\t\t\trow = $tw.utils.replaceString(row,\"$value$\",value);\n\t\t\trow = $tw.utils.replaceString(row,\"$encoded_value$\",$tw.utils.htmlEncode(value));\n\t\t\ttext.push(row);\n\t\t}\n\t}\n\tthis.text = text.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif( changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude ||\n\t\tchangedAttributes.include || changedAttributes.sort || changedAttributes.sortReverse ||\n\t\tchangedTiddlers[this.tiddlerTitle] || changedAttributes.stripTitlePrefix) {\n\t\t\tthis.refreshSelf();\n\t\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\nexports.fields = FieldsWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/image.js": {
"title": "$:/core/modules/widgets/image.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/image.js\ntype: application/javascript\nmodule-type: widget\n\nThe image widget displays an image referenced with an external URI or with a local tiddler title.\n\n```\n<$image src=\"TiddlerTitle\" width=\"320\" height=\"400\" class=\"classnames\">\n```\n\nThe image source can be the title of an existing tiddler or the URL of an external image.\n\nExternal images always generate an HTML `<img>` tag.\n\nTiddlers that have a _canonical_uri field generate an HTML `<img>` tag with the src attribute containing the URI.\n\nTiddlers that contain image data generate an HTML `<img>` tag with the src attribute containing a base64 representation of the image.\n\nTiddlers that contain wikitext could be rendered to a DIV of the usual size of a tiddler, and then transformed to the size requested.\n\nThe width and height attributes are interpreted as a number of pixels, and do not need to include the \"px\" suffix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\t// Determine what type of image it is\n\tvar tag = \"img\", src = \"\",\n\t\ttiddler = this.wiki.getTiddler(this.imageSource);\n\tif(!tiddler) {\n\t\t// The source isn't the title of a tiddler, so we'll assume it's a URL\n\t\tsrc = this.getVariable(\"tv-get-export-image-link\",{params: [{name: \"src\",value: this.imageSource}],defaultValue: this.imageSource});\n\t} else {\n\t\t// Check if it is an image tiddler\n\t\tif(this.wiki.isImageTiddler(this.imageSource)) {\n\t\t\tvar type = tiddler.fields.type,\n\t\t\t\ttext = tiddler.fields.text,\n\t\t\t\t_canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t// If the tiddler has body text then it doesn't need to be lazily loaded\n\t\t\tif(text) {\n\t\t\t\t// Render the appropriate element for the image type\n\t\t\t\tswitch(type) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = \"data:application/pdf;base64,\" + text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = \"data:image/svg+xml,\" + encodeURIComponent(text);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = \"data:\" + type + \";base64,\" + text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else if(_canonical_uri) {\n\t\t\t\tswitch(type) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\t\n\t\t\t} else {\n\t\t\t\t// Just trigger loading of the tiddler\n\t\t\t\tthis.wiki.getTiddlerText(this.imageSource);\n\t\t\t}\n\t\t}\n\t}\n\t// Create the element and assign the attributes\n\tvar domNode = this.document.createElement(tag);\n\tdomNode.setAttribute(\"src\",src);\n\tif(this.imageClass) {\n\t\tdomNode.setAttribute(\"class\",this.imageClass);\t\t\n\t}\n\tif(this.imageWidth) {\n\t\tdomNode.setAttribute(\"width\",this.imageWidth);\n\t}\n\tif(this.imageHeight) {\n\t\tdomNode.setAttribute(\"height\",this.imageHeight);\n\t}\n\tif(this.imageTooltip) {\n\t\tdomNode.setAttribute(\"title\",this.imageTooltip);\t\t\n\t}\n\tif(this.imageAlt) {\n\t\tdomNode.setAttribute(\"alt\",this.imageAlt);\t\t\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImageWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.imageSource = this.getAttribute(\"source\");\n\tthis.imageWidth = this.getAttribute(\"width\");\n\tthis.imageHeight = this.getAttribute(\"height\");\n\tthis.imageClass = this.getAttribute(\"class\");\n\tthis.imageTooltip = this.getAttribute(\"tooltip\");\n\tthis.imageAlt = this.getAttribute(\"alt\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes[\"class\"] || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\t\n\t}\n};\n\nexports.image = ImageWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/importvariables.js": {
"title": "$:/core/modules/widgets/importvariables.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/importvariables.js\ntype: application/javascript\nmodule-type: widget\n\nImport variable definitions from other tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImportVariablesWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImportVariablesWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImportVariablesWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImportVariablesWidget.prototype.execute = function(tiddlerList) {\n\tvar widgetPointer = this;\n\t// Got to flush all the accumulated variables\n\tthis.variables = new this.variablesConstructor();\n\t// Get our parameters\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Compute the filter\n\tthis.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);\n\t// Accumulate the <$set> widgets from each tiddler\n\t$tw.utils.each(this.tiddlerList,function(title) {\n\t\tvar parser = widgetPointer.wiki.parseTiddler(title);\n\t\tif(parser) {\n\t\t\tvar parseTreeNode = parser.tree[0];\n\t\t\twhile(parseTreeNode && parseTreeNode.type === \"set\") {\n\t\t\t\tvar node = {\n\t\t\t\t\ttype: \"set\",\n\t\t\t\t\tattributes: parseTreeNode.attributes,\n\t\t\t\t\tparams: parseTreeNode.params,\n\t\t\t\t\tisMacroDefinition: parseTreeNode.isMacroDefinition\n\t\t\t\t};\n\t\t\t\tif (parseTreeNode.isMacroDefinition) {\n\t\t\t\t\t// Macro definitions can be folded into\n\t\t\t\t\t// current widget instead of adding\n\t\t\t\t\t// another link to the chain.\n\t\t\t\t\tvar widget = widgetPointer.makeChildWidget(node);\n\t\t\t\t\twidget.computeAttributes();\n\t\t\t\t\twidget.execute();\n\t\t\t\t\t// We SHALLOW copy over all variables\n\t\t\t\t\t// in widget. We can't use\n\t\t\t\t\t// $tw.utils.assign, because that copies\n\t\t\t\t\t// up the prototype chain, which we\n\t\t\t\t\t// don't want.\n\t\t\t\t\t$tw.utils.each(Object.keys(widget.variables), function(key) {\n\t\t\t\t\t\twidgetPointer.variables[key] = widget.variables[key];\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\twidgetPointer.children = [widgetPointer.makeChildWidget(node)];\n\t\t\t\t\t// No more regenerating children for\n\t\t\t\t\t// this widget. If it needs to refresh,\n\t\t\t\t\t// it'll do so along with the the whole\n\t\t\t\t\t// importvariable tree.\n\t\t\t\t\tif (widgetPointer != this) {\n\t\t\t\t\t\twidgetPointer.makeChildWidgets = function(){};\n\t\t\t\t\t}\n\t\t\t\t\twidgetPointer = widgetPointer.children[0];\n\t\t\t\t}\n\t\t\t\tparseTreeNode = parseTreeNode.children && parseTreeNode.children[0];\n\t\t\t}\n\t\t} \n\t});\n\n\tif (widgetPointer != this) {\n\t\twidgetPointer.parseTreeNode.children = this.parseTreeNode.children;\n\t} else {\n\t\twidgetPointer.makeChildWidgets();\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImportVariablesWidget.prototype.refresh = function(changedTiddlers) {\n\t// Recompute our attributes and the filter list\n\tvar changedAttributes = this.computeAttributes(),\n\t\ttiddlerList = this.wiki.filterTiddlers(this.getAttribute(\"filter\"),this);\n\t// Refresh if the filter has changed, or the list of tiddlers has changed, or any of the tiddlers in the list has changed\n\tfunction haveListedTiddlersChanged() {\n\t\tvar changed = false;\n\t\ttiddlerList.forEach(function(title) {\n\t\t\tif(changedTiddlers[title]) {\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t});\n\t\treturn changed;\n\t}\n\tif(changedAttributes.filter || !$tw.utils.isArrayEqual(this.tiddlerList,tiddlerList) || haveListedTiddlersChanged()) {\n\t\t// Compute the filter\n\t\tthis.removeChildDomNodes();\n\t\tthis.execute(tiddlerList);\n\t\tthis.renderChildren(this.parentDomNode,this.findNextSiblingDomNode());\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.importvariables = ImportVariablesWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/keyboard.js": {
"title": "$:/core/modules/widgets/keyboard.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/keyboard.js\ntype: application/javascript\nmodule-type: widget\n\nKeyboard shortcut widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar KeyboardWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nKeyboardWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nKeyboardWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.tag && $tw.config.htmlUnsafeElements.indexOf(this.tag) === -1) {\n\t\ttag = this.tag;\n\t}\n\t// Create element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = (this[\"class\"] || \"\").split(\" \");\n\tclasses.push(\"tc-keyboard\");\n\tdomNode.className = classes.join(\" \");\n\t// Add a keyboard event handler\n\tdomNode.addEventListener(\"keydown\",function (event) {\n\t\tif($tw.keyboardManager.checkKeyDescriptors(event,self.keyInfoArray)) {\n\t\t\tvar handled = self.invokeActions(self,event);\n\t\t\tif(self.actions) {\n\t\t\t\tself.invokeActionString(self.actions,self,event);\n\t\t\t}\n\t\t\tself.dispatchMessage(event);\n\t\t\tif(handled || self.actions || self.message) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nKeyboardWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\")});\n};\n\n/*\nCompute the internal state of the widget\n*/\nKeyboardWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\",\"\");\n\tthis.message = this.getAttribute(\"message\",\"\");\n\tthis.param = this.getAttribute(\"param\",\"\");\n\tthis.key = this.getAttribute(\"key\",\"\");\n\tthis.tag = this.getAttribute(\"tag\",\"\");\n\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tif(this.key.substr(0,2) === \"((\" && this.key.substr(-2,2) === \"))\") {\n\t\tthis.shortcutTiddlers = [];\n\t\tvar name = this.key.substring(2,this.key.length -2);\n\t\t$tw.utils.each($tw.keyboardManager.lookupNames,function(platformDescriptor) {\n\t\t\tself.shortcutTiddlers.push(\"$:/config/\" + platformDescriptor + \"/\" + name);\n\t\t});\n\t}\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nKeyboardWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes[\"class\"] || changedAttributes.tag) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\t// Update the keyInfoArray if one of its shortcut-config-tiddlers has changed\n\tif(this.shortcutTiddlers && $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers)) {\n\t\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.keyboard = KeyboardWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/link.js": {
"title": "$:/core/modules/widgets/link.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/link.js\ntype: application/javascript\nmodule-type: widget\n\nLink widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the value of the tv-wikilinks configuration macro\n\tvar wikiLinksMacro = this.getVariable(\"tv-wikilinks\"),\n\t\tuseWikiLinks = wikiLinksMacro ? (wikiLinksMacro.trim() !== \"no\") : true,\n\t\tmissingLinksEnabled = !(this.hideMissingLinks && this.isMissing && !this.isShadow);\n\t// Render the link if required\n\tif(useWikiLinks && missingLinksEnabled) {\n\t\tthis.renderLink(parent,nextSibling);\n\t} else {\n\t\t// Just insert the link text\n\t\tvar domNode = this.document.createElement(\"span\");\n\t\tparent.insertBefore(domNode,nextSibling);\n\t\tthis.renderChildren(domNode,null);\n\t\tthis.domNodes.push(domNode);\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.renderLink = function(parent,nextSibling) {\n\tvar self = this;\n\t// Sanitise the specified tag\n\tvar tag = this.linkTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"a\";\n\t}\n\t// Create our element\n\tvar namespace = this.getVariable(\"namespace\",{defaultValue: \"http://www.w3.org/1999/xhtml\"}),\n\t\tdomNode = this.document.createElementNS(namespace,tag);\n\t// Assign classes\n\tvar classes = [];\n\tif(this.overrideClasses === undefined) {\n\t\tclasses.push(\"tc-tiddlylink\");\n\t\tif(this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-shadow\");\n\t\t}\n\t\tif(this.isMissing && !this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-missing\");\n\t\t} else {\n\t\t\tif(!this.isMissing) {\n\t\t\t\tclasses.push(\"tc-tiddlylink-resolves\");\n\t\t\t}\n\t\t}\n\t\tif(this.linkClasses) {\n\t\t\tclasses.push(this.linkClasses);\t\t\t\n\t\t}\n\t} else if(this.overrideClasses !== \"\") {\n\t\tclasses.push(this.overrideClasses)\n\t}\n\tif(classes.length > 0) {\n\t\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t}\n\t// Set an href\n\tvar wikilinkTransformFilter = this.getVariable(\"tv-filter-export-link\"),\n\t\twikiLinkText;\n\tif(wikilinkTransformFilter) {\n\t\t// Use the filter to construct the href\n\t\twikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {\n\t\t\titerator(self.wiki.getTiddler(self.to),self.to)\n\t\t})[0];\n\t} else {\n\t\t// Expand the tv-wikilink-template variable to construct the href\n\t\tvar wikiLinkTemplateMacro = this.getVariable(\"tv-wikilink-template\"),\n\t\t\twikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : \"#$uri_encoded$\";\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,\"$uri_encoded$\",encodeURIComponent(this.to));\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkText,\"$uri_doubleencoded$\",encodeURIComponent(encodeURIComponent(this.to)));\n\t}\n\t// Override with the value of tv-get-export-link if defined\n\twikiLinkText = this.getVariable(\"tv-get-export-link\",{params: [{name: \"to\",value: this.to}],defaultValue: wikiLinkText});\n\tif(tag === \"a\") {\n\t\tvar namespaceHref = (namespace === \"http://www.w3.org/2000/svg\") ? \"http://www.w3.org/1999/xlink\" : undefined;\n\t\tdomNode.setAttributeNS(namespaceHref,\"href\",wikiLinkText);\n\t}\n\t// Set the tabindex\n\tif(this.tabIndex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.tabIndex);\n\t}\n\t// Set the tooltip\n\t// HACK: Performance issues with re-parsing the tooltip prevent us defaulting the tooltip to \"<$transclude field='tooltip'><$transclude field='title'/></$transclude>\"\n\tvar tooltipWikiText = this.tooltip || this.getVariable(\"tv-wikilink-tooltip\");\n\tif(tooltipWikiText) {\n\t\tvar tooltipText = this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",tooltipWikiText,{\n\t\t\t\tparseAsInline: true,\n\t\t\t\tvariables: {\n\t\t\t\t\tcurrentTiddler: this.to\n\t\t\t\t},\n\t\t\t\tparentWidget: this\n\t\t\t});\n\t\tdomNode.setAttribute(\"title\",tooltipText);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"click\", handlerObject: this, handlerMethod: \"handleClickEvent\"},\n\t]);\n\t// Make the link draggable if required\n\tif(this.draggable === \"yes\") {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.to;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nLinkWidget.prototype.handleClickEvent = function(event) {\n\t// Send the click on its way as a navigate event\n\tvar bounds = this.domNodes[0].getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tmetaKey: event.metaKey,\n\t\tctrlKey: event.ctrlKey,\n\t\taltKey: event.altKey,\n\t\tshiftKey: event.shiftKey,\n\t\tevent: event\n\t});\n\tif(this.domNodes[0].hasAttribute(\"href\")) {\n\t\tevent.preventDefault();\n\t}\n\tevent.stopPropagation();\n\treturn false;\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.to = this.getAttribute(\"to\",this.getVariable(\"currentTiddler\"));\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.linkClasses = this.getAttribute(\"class\");\n\tthis.overrideClasses = this.getAttribute(\"overrideClass\");\n\tthis.tabIndex = this.getAttribute(\"tabindex\");\n\tthis.draggable = this.getAttribute(\"draggable\",\"yes\");\n\tthis.linkTag = this.getAttribute(\"tag\",\"a\");\n\t// Determine the link characteristics\n\tthis.isMissing = !this.wiki.tiddlerExists(this.to);\n\tthis.isShadow = this.wiki.isShadowTiddler(this.to);\n\tthis.hideMissingLinks = (this.getVariable(\"tv-show-missing-links\") || \"yes\") === \"no\";\n\t// Make the child widgets\n\tvar templateTree;\n\tif(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\ttemplateTree = this.parseTreeNode.children;\n\t} else {\n\t\t// Default template is a link to the title\n\t\ttemplateTree = [{type: \"text\", text: this.to}];\n\t}\n\tthis.makeChildWidgets(templateTree);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedTiddlers[this.to] || changedAttributes[\"aria-label\"] || changedAttributes.tooltip) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.link = LinkWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/linkcatcher.js": {
"title": "$:/core/modules/widgets/linkcatcher.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/linkcatcher.js\ntype: application/javascript\nmodule-type: widget\n\nLinkcatcher widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkCatcherWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkCatcherWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkCatcherWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkCatcherWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.catchTo = this.getAttribute(\"to\");\n\tthis.catchMessage = this.getAttribute(\"message\");\n\tthis.catchSet = this.getAttribute(\"set\");\n\tthis.catchSetTo = this.getAttribute(\"setTo\");\n\tthis.catchActions = this.getAttribute(\"actions\");\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n\t// When executing actions we avoid trapping navigate events, so that we don't trigger ourselves recursively\n\tthis.executingActions = false;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkCatcherWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedAttributes.message || changedAttributes.set || changedAttributes.setTo) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\n/*\nHandle a tm-navigate event\n*/\nLinkCatcherWidget.prototype.handleNavigateEvent = function(event) {\n\tif(!this.executingActions) {\n\t\t// Execute the actions\n\t\tif(this.catchTo) {\n\t\t\tthis.wiki.setTextReference(this.catchTo,event.navigateTo,this.getVariable(\"currentTiddler\"));\n\t\t}\n\t\tif(this.catchMessage && this.parentWidget) {\n\t\t\tthis.parentWidget.dispatchEvent({\n\t\t\t\ttype: this.catchMessage,\n\t\t\t\tparam: event.navigateTo,\n\t\t\t\tnavigateTo: event.navigateTo\n\t\t\t});\n\t\t}\n\t\tif(this.catchSet) {\n\t\t\tvar tiddler = this.wiki.getTiddler(this.catchSet);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: this.catchSet, text: this.catchSetTo}));\n\t\t}\n\t\tif(this.catchActions) {\n\t\t\tthis.executingActions = true;\n\t\t\tvar modifierKey = $tw.keyboardManager.getEventModifierKeyDescriptor(event);\n\t\t\tthis.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo, modifier: modifierKey});\n\t\t\tthis.executingActions = false;\n\t\t}\n\t} else {\n\t\t// This is a navigate event generated by the actions of this linkcatcher, so we don't trap it again, but just pass it to the parent\n\t\tthis.parentWidget.dispatchEvent({\n\t\t\ttype: \"tm-navigate\",\n\t\t\tparam: event.navigateTo,\n\t\t\tnavigateTo: event.navigateTo\n\t\t});\n\t}\n\treturn false;\n};\n\nexports.linkcatcher = LinkCatcherWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/list.js": {
"title": "$:/core/modules/widgets/list.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/list.js\ntype: application/javascript\nmodule-type: widget\n\nList and list item widgets\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\n/*\nThe list widget creates list element sub-widgets that reach back into the list widget for their configuration\n*/\n\nvar ListWidget = function(parseTreeNode,options) {\n\t// Initialise the storyviews if they've not been done already\n\tif(!this.storyViews) {\n\t\tListWidget.prototype.storyViews = {};\n\t\t$tw.modules.applyMethods(\"storyview\",this.storyViews);\n\t}\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\t// Construct the storyview\n\tvar StoryView = this.storyViews[this.storyViewName];\n\tif(this.storyViewName && !StoryView) {\n\t\tStoryView = this.storyViews[\"classic\"];\n\t}\n\tif(StoryView && !this.document.isTiddlyWikiFakeDom) {\n\t\tthis.storyview = new StoryView(this);\n\t} else {\n\t\tthis.storyview = null;\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nListWidget.prototype.execute = function() {\n\t// Get our attributes\n\tthis.template = this.getAttribute(\"template\");\n\tthis.editTemplate = this.getAttribute(\"editTemplate\");\n\tthis.variableName = this.getAttribute(\"variable\",\"currentTiddler\");\n\tthis.storyViewName = this.getAttribute(\"storyview\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\t// Compose the list elements\n\tthis.list = this.getTiddlerList();\n\tvar members = [],\n\t\tself = this;\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\tmembers = this.getEmptyMessage();\n\t} else {\n\t\t$tw.utils.each(this.list,function(title,index) {\n\t\t\tmembers.push(self.makeItemTemplate(title));\n\t\t});\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(members);\n\t// Clear the last history\n\tthis.history = [];\n};\n\nListWidget.prototype.getTiddlerList = function() {\n\tvar defaultFilter = \"[!is[system]sort[title]]\";\n\treturn this.wiki.filterTiddlers(this.getAttribute(\"filter\",defaultFilter),this);\n};\n\nListWidget.prototype.getEmptyMessage = function() {\n\tvar parser,\n\t\temptyMessage = this.getAttribute(\"emptyMessage\",\"\");\n\t// this.wiki.parseText() calls \n\t// new Parser(..), which should only be done, if needed, because it's heavy!\n\tif (emptyMessage === \"\") {\n\t\treturn [];\n\t}\n\tparser = this.wiki.parseText(\"text/vnd.tiddlywiki\",emptyMessage,{parseAsInline: true});\n\tif(parser) {\n\t\treturn parser.tree;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n/*\nCompose the template for a list item\n*/\nListWidget.prototype.makeItemTemplate = function(title) {\n\t// Check if the tiddler is a draft\n\tvar tiddler = this.wiki.getTiddler(title),\n\t\tisDraft = tiddler && tiddler.hasField(\"draft.of\"),\n\t\ttemplate = this.template,\n\t\ttemplateTree;\n\tif(isDraft && this.editTemplate) {\n\t\ttemplate = this.editTemplate;\n\t}\n\t// Compose the transclusion of the template\n\tif(template) {\n\t\ttemplateTree = [{type: \"transclude\", attributes: {tiddler: {type: \"string\", value: template}}}];\n\t} else {\n\t\tif(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\t\ttemplateTree = this.parseTreeNode.children;\n\t\t} else {\n\t\t\t// Default template is a link to the title\n\t\t\ttemplateTree = [{type: \"element\", tag: this.parseTreeNode.isBlock ? \"div\" : \"span\", children: [{type: \"link\", attributes: {to: {type: \"string\", value: title}}, children: [\n\t\t\t\t\t{type: \"text\", text: title}\n\t\t\t]}]}];\n\t\t}\n\t}\n\t// Return the list item\n\treturn {type: \"listitem\", itemTitle: title, variableName: this.variableName, children: templateTree};\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tresult;\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshStart) {\n\t\tthis.storyview.refreshStart(changedTiddlers,changedAttributes);\n\t}\n\t// Completely refresh if any of our attributes have changed\n\tif(changedAttributes.filter || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\tresult = true;\n\t} else {\n\t\t// Handle any changes to the list\n\t\tresult = this.handleListChanges(changedTiddlers);\n\t\t// Handle any changes to the history stack\n\t\tif(this.historyTitle && changedTiddlers[this.historyTitle]) {\n\t\t\tthis.handleHistoryChanges();\n\t\t}\n\t}\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshEnd) {\n\t\tthis.storyview.refreshEnd(changedTiddlers,changedAttributes);\n\t}\n\treturn result;\n};\n\n/*\nHandle any changes to the history list\n*/\nListWidget.prototype.handleHistoryChanges = function() {\n\t// Get the history data\n\tvar newHistory = this.wiki.getTiddlerDataCached(this.historyTitle,[]);\n\t// Ignore any entries of the history that match the previous history\n\tvar entry = 0;\n\twhile(entry < newHistory.length && entry < this.history.length && newHistory[entry].title === this.history[entry].title) {\n\t\tentry++;\n\t}\n\t// Navigate forwards to each of the new tiddlers\n\twhile(entry < newHistory.length) {\n\t\tif(this.storyview && this.storyview.navigateTo) {\n\t\t\tthis.storyview.navigateTo(newHistory[entry]);\n\t\t}\n\t\tentry++;\n\t}\n\t// Update the history\n\tthis.history = newHistory;\n};\n\n/*\nProcess any changes to the list\n*/\nListWidget.prototype.handleListChanges = function(changedTiddlers) {\n\t// Get the new list\n\tvar prevList = this.list;\n\tthis.list = this.getTiddlerList();\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\t// Check if it was empty before\n\t\tif(prevList.length === 0) {\n\t\t\t// If so, just refresh the empty message\n\t\t\treturn this.refreshChildren(changedTiddlers);\n\t\t} else {\n\t\t\t// Replace the previous content with the empty message\n\t\t\tfor(t=this.children.length-1; t>=0; t--) {\n\t\t\t\tthis.removeListItem(t);\n\t\t\t}\n\t\t\tvar nextSibling = this.findNextSiblingDomNode();\n\t\t\tthis.makeChildWidgets(this.getEmptyMessage());\n\t\t\tthis.renderChildren(this.parentDomNode,nextSibling);\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\t// If the list was empty then we need to remove the empty message\n\t\tif(prevList.length === 0) {\n\t\t\tthis.removeChildDomNodes();\n\t\t\tthis.children = [];\n\t\t}\n\t\t// Cycle through the list, inserting and removing list items as needed\n\t\tvar hasRefreshed = false;\n\t\tfor(var t=0; t<this.list.length; t++) {\n\t\t\tvar index = this.findListItem(t,this.list[t]);\n\t\t\tif(index === undefined) {\n\t\t\t\t// The list item must be inserted\n\t\t\t\tthis.insertListItem(t,this.list[t]);\n\t\t\t\thasRefreshed = true;\n\t\t\t} else {\n\t\t\t\t// There are intervening list items that must be removed\n\t\t\t\tfor(var n=index-1; n>=t; n--) {\n\t\t\t\t\tthis.removeListItem(n);\n\t\t\t\t\thasRefreshed = true;\n\t\t\t\t}\n\t\t\t\t// Refresh the item we're reusing\n\t\t\t\tvar refreshed = this.children[t].refresh(changedTiddlers);\n\t\t\t\thasRefreshed = hasRefreshed || refreshed;\n\t\t\t}\n\t\t}\n\t\t// Remove any left over items\n\t\tfor(t=this.children.length-1; t>=this.list.length; t--) {\n\t\t\tthis.removeListItem(t);\n\t\t\thasRefreshed = true;\n\t\t}\n\t\treturn hasRefreshed;\n\t}\n};\n\n/*\nFind the list item with a given title, starting from a specified position\n*/\nListWidget.prototype.findListItem = function(startIndex,title) {\n\twhile(startIndex < this.children.length) {\n\t\tif(this.children[startIndex].parseTreeNode.itemTitle === title) {\n\t\t\treturn startIndex;\n\t\t}\n\t\tstartIndex++;\n\t}\n\treturn undefined;\n};\n\n/*\nInsert a new list item at the specified index\n*/\nListWidget.prototype.insertListItem = function(index,title) {\n\t// Create, insert and render the new child widgets\n\tvar widget = this.makeChildWidget(this.makeItemTemplate(title));\n\twidget.parentDomNode = this.parentDomNode; // Hack to enable findNextSiblingDomNode() to work\n\tthis.children.splice(index,0,widget);\n\tvar nextSibling = widget.findNextSiblingDomNode();\n\twidget.render(this.parentDomNode,nextSibling);\n\t// Animate the insertion if required\n\tif(this.storyview && this.storyview.insert) {\n\t\tthis.storyview.insert(widget);\n\t}\n\treturn true;\n};\n\n/*\nRemove the specified list item\n*/\nListWidget.prototype.removeListItem = function(index) {\n\tvar widget = this.children[index];\n\t// Animate the removal if required\n\tif(this.storyview && this.storyview.remove) {\n\t\tthis.storyview.remove(widget);\n\t} else {\n\t\twidget.removeChildDomNodes();\n\t}\n\t// Remove the child widget\n\tthis.children.splice(index,1);\n};\n\nexports.list = ListWidget;\n\nvar ListItemWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListItemWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListItemWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nListItemWidget.prototype.execute = function() {\n\t// Set the current list item title\n\tthis.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListItemWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.listitem = ListItemWidget;\n\n})();",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/log.js": {
"title": "$:/core/modules/widgets/log.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/log.js\ntype: application/javascript\nmodule-type: widget-subclass\n\nWidget to log debug messages\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.baseClass = \"action-log\";\n\nexports.name = \"log\";\n\nexports.constructor = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n}\n\nexports.prototype = {};\n\nexports.prototype.render = function(event) {\n\tObject.getPrototypeOf(Object.getPrototypeOf(this)).render.call(this,event);\t\n\tObject.getPrototypeOf(Object.getPrototypeOf(this)).log.call(this);\n}\n\n})();",
"type": "application/javascript",
"module-type": "widget-subclass"
},
"$:/core/modules/widgets/macrocall.js": {
"title": "$:/core/modules/widgets/macrocall.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/macrocall.js\ntype: application/javascript\nmodule-type: widget\n\nMacrocall widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar MacroCallWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nMacroCallWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nMacroCallWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nMacroCallWidget.prototype.execute = function() {\n\t// Get the parse type if specified\n\tthis.parseType = this.getAttribute(\"$type\",\"text/vnd.tiddlywiki\");\n\tthis.renderOutput = this.getAttribute(\"$output\",\"text/html\");\n\t// Merge together the parameters specified in the parse tree with the specified attributes\n\tvar params = this.parseTreeNode.params ? this.parseTreeNode.params.slice(0) : [];\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparams.push({name: name, value: attribute});\t\t\t\n\t\t}\n\t});\n\t// Get the macro value\n\tvar macroName = this.parseTreeNode.name || this.getAttribute(\"$name\"),\n\t\tvariableInfo = this.getVariableInfo(macroName,{params: params}),\n\t\ttext = variableInfo.text,\n\t\tparseTreeNodes;\n\t// Are we rendering to HTML?\n\tif(this.renderOutput === \"text/html\") {\n\t\t// If so we'll return the parsed macro\n\t\t// Check if we've already cached parsing this macro\n\t\tvar mode = this.parseTreeNode.isBlock ? \"blockParser\" : \"inlineParser\",\n\t\t\tparser;\n\t\tif(variableInfo.srcVariable && variableInfo.srcVariable[mode]) {\n\t\t\tparser = variableInfo.srcVariable[mode];\n\t\t} else {\n\t\t\tparser = this.wiki.parseText(this.parseType,text,\n\t\t\t\t\t\t\t\t{parseAsInline: !this.parseTreeNode.isBlock});\n\t\t\tif(variableInfo.isCacheable && variableInfo.srcVariable) {\n\t\t\t\tvariableInfo.srcVariable[mode] = parser;\n\t\t\t}\n\t\t}\n\t\tvar parseTreeNodes = parser ? parser.tree : [];\n\t\t// Wrap the parse tree in a vars widget assigning the parameters to variables named \"__paramname__\"\n\t\tvar attributes = {};\n\t\t$tw.utils.each(variableInfo.params,function(param) {\n\t\t\tvar name = \"__\" + param.name + \"__\";\n\t\t\tattributes[name] = {\n\t\t\t\tname: name,\n\t\t\t\ttype: \"string\",\n\t\t\t\tvalue: param.value\n\t\t\t};\n\t\t});\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"vars\",\n\t\t\tattributes: attributes,\n\t\t\tchildren: parseTreeNodes\n\t\t}];\n\t} else if(this.renderOutput === \"text/raw\") {\n\t\tparseTreeNodes = [{type: \"text\", text: text}];\n\t} else {\n\t\t// Otherwise, we'll render the text\n\t\tvar plainText = this.wiki.renderText(\"text/plain\",this.parseType,text,{parentWidget: this});\n\t\tparseTreeNodes = [{type: \"text\", text: plainText}];\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nMacroCallWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\t// Rerender ourselves\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.macrocall = MacroCallWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/navigator.js": {
"title": "$:/core/modules/widgets/navigator.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/navigator.js\ntype: application/javascript\nmodule-type: widget\n\nNavigator widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar IMPORT_TITLE = \"$:/Import\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigatorWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"},\n\t\t{type: \"tm-edit-tiddler\", handler: \"handleEditTiddlerEvent\"},\n\t\t{type: \"tm-delete-tiddler\", handler: \"handleDeleteTiddlerEvent\"},\n\t\t{type: \"tm-save-tiddler\", handler: \"handleSaveTiddlerEvent\"},\n\t\t{type: \"tm-cancel-tiddler\", handler: \"handleCancelTiddlerEvent\"},\n\t\t{type: \"tm-close-tiddler\", handler: \"handleCloseTiddlerEvent\"},\n\t\t{type: \"tm-close-all-tiddlers\", handler: \"handleCloseAllTiddlersEvent\"},\n\t\t{type: \"tm-close-other-tiddlers\", handler: \"handleCloseOtherTiddlersEvent\"},\n\t\t{type: \"tm-new-tiddler\", handler: \"handleNewTiddlerEvent\"},\n\t\t{type: \"tm-import-tiddlers\", handler: \"handleImportTiddlersEvent\"},\n\t\t{type: \"tm-perform-import\", handler: \"handlePerformImportEvent\"},\n\t\t{type: \"tm-fold-tiddler\", handler: \"handleFoldTiddlerEvent\"},\n\t\t{type: \"tm-fold-other-tiddlers\", handler: \"handleFoldOtherTiddlersEvent\"},\n\t\t{type: \"tm-fold-all-tiddlers\", handler: \"handleFoldAllTiddlersEvent\"},\n\t\t{type: \"tm-unfold-all-tiddlers\", handler: \"handleUnfoldAllTiddlersEvent\"},\n\t\t{type: \"tm-rename-tiddler\", handler: \"handleRenameTiddlerEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigatorWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigatorWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigatorWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.storyTitle = this.getAttribute(\"story\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\tthis.setVariable(\"tv-story-list\",this.storyTitle);\n\tthis.setVariable(\"tv-history-list\",this.historyTitle);\n\tthis.story = new $tw.Story({\n\t\twiki: this.wiki,\n\t\tstoryTitle: this.storyTitle,\n\t\thistoryTitle: this.historyTitle\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nNavigatorWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.story || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nNavigatorWidget.prototype.getStoryList = function() {\n\treturn this.storyTitle ? this.wiki.getTiddlerList(this.storyTitle) : null;\n};\n\nNavigatorWidget.prototype.saveStoryList = function(storyList) {\n\tif(this.storyTitle) {\n\t\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\t\t{title: this.storyTitle},\n\t\t\tstoryTiddler,\n\t\t\t{list: storyList}\n\t\t));\t\t\n\t}\n};\n\nNavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {\n\tif(storyList) {\n\t\tvar p = storyList.indexOf(title);\n\t\twhile(p !== -1) {\n\t\t\tstoryList.splice(p,1);\n\t\t\tp = storyList.indexOf(title);\n\t\t}\t\t\n\t}\n};\n\nNavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {\n\tif(storyList) {\n\t\tvar pos = storyList.indexOf(oldTitle);\n\t\tif(pos !== -1) {\n\t\t\tstoryList[pos] = newTitle;\n\t\t\tdo {\n\t\t\t\tpos = storyList.indexOf(oldTitle,pos + 1);\n\t\t\t\tif(pos !== -1) {\n\t\t\t\t\tstoryList.splice(pos,1);\n\t\t\t\t}\n\t\t\t} while(pos !== -1);\n\t\t} else {\n\t\t\tstoryList.splice(0,0,newTitle);\n\t\t}\t\t\n\t}\n};\n\nNavigatorWidget.prototype.addToStory = function(title,fromTitle) {\n\tif(this.storyTitle) {\n\t\tthis.story.addToStory(title,fromTitle,{\n\t\t\topenLinkFromInsideRiver: this.getAttribute(\"openLinkFromInsideRiver\",\"top\"),\n\t\t\topenLinkFromOutsideRiver: this.getAttribute(\"openLinkFromOutsideRiver\",\"top\")\n\t\t});\n\t}\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\n*/\nNavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {\n\tthis.story.addToHistory(title,fromPageRect,this.historyTitle);\n};\n\n/*\nHandle a tm-navigate event\n*/\nNavigatorWidget.prototype.handleNavigateEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-navigating\",event);\n\tif(event.navigateTo) {\n\t\tthis.addToStory(event.navigateTo,event.navigateFromTitle);\n\t\tif(!event.navigateSuppressNavigation) {\n\t\t\tthis.addToHistory(event.navigateTo,event.navigateFromClientRect);\n\t\t}\n\t}\n\treturn false;\n};\n\n// Close a specified tiddler\nNavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\tstoryList = this.getStoryList();\n\t// Look for tiddlers with this title to close\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\treturn false;\n};\n\n// Close all tiddlers\nNavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) {\n\tthis.saveStoryList([]);\n\treturn false;\n};\n\n// Close other tiddlers\nNavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle;\n\tthis.saveStoryList([title]);\n\treturn false;\n};\n\n// Place a tiddler in edit mode\nNavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {\n\tvar editTiddler = $tw.hooks.invokeHook(\"th-editing-tiddler\",event);\n\tif(!editTiddler) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tfunction isUnmodifiedShadow(title) {\n\t\treturn self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title);\n\t}\n\tfunction confirmEditShadow(title) {\n\t\treturn confirm($tw.language.getString(\n\t\t\t\"ConfirmEditShadowTiddler\",\n\t\t\t{variables:\n\t\t\t\t{title: title}\n\t\t\t}\n\t\t));\n\t}\n\tvar title = event.param || event.tiddlerTitle;\n\tif(isUnmodifiedShadow(title) && !confirmEditShadow(title)) {\n\t\treturn false;\n\t}\n\t// Replace the specified tiddler with a draft in edit mode\n\tvar draftTiddler = this.makeDraftTiddler(title);\n\t// Update the story and history if required\n\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\tvar draftTitle = draftTiddler.fields.title,\n\t\t\tstoryList = this.getStoryList();\n\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\tthis.saveStoryList(storyList);\n\t\treturn false;\n\t}\n};\n\n// Delete a tiddler\nNavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {\n\t// Get the tiddler we're deleting\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList(),\n\t\toriginalTitle = tiddler ? tiddler.fields[\"draft.of\"] : \"\",\n\t\toriginalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,\n\t\tconfirmationTitle;\n\tif(!tiddler) {\n\t\treturn false;\n\t}\n\t// Check if the tiddler we're deleting is in draft mode\n\tif(originalTitle) {\n\t\t// If so, we'll prompt for confirmation referencing the original tiddler\n\t\tconfirmationTitle = originalTitle;\n\t} else {\n\t\t// If not a draft, then prompt for confirmation referencing the specified tiddler\n\t\tconfirmationTitle = title;\n\t}\n\t// Seek confirmation\n\tif((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || \"\") !== \"\") && !confirm($tw.language.getString(\n\t\t\t\t\"ConfirmDeleteTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: confirmationTitle}\n\t\t\t\t}\n\t\t\t))) {\n\t\treturn false;\n\t}\n\t// Delete the original tiddler\n\tif(originalTitle) {\n\t\tif(originalTiddler) {\n\t\t\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",originalTiddler);\n\t\t}\n\t\tthis.wiki.deleteTiddler(originalTitle);\n\t\tthis.removeTitleFromStory(storyList,originalTitle);\n\t}\n\t// Invoke the hook function and delete this tiddler\n\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",tiddler);\n\tthis.wiki.deleteTiddler(title);\n\t// Remove the closed tiddler from the story\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\treturn false;\n};\n\n/*\nCreate/reuse the draft tiddler for a given title\n*/\nNavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {\n\t// See if there is already a draft tiddler for this tiddler\n\tvar draftTitle = this.wiki.findDraft(targetTitle);\n\tif(draftTitle) {\n\t\treturn this.wiki.getTiddler(draftTitle);\n\t}\n\t// Get the current value of the tiddler we're editing\n\tvar tiddler = this.wiki.getTiddler(targetTitle);\n\t// Save the initial value of the draft tiddler\n\tdraftTitle = this.generateDraftTitle(targetTitle);\n\tvar draftTiddler = new $tw.Tiddler({\n\t\t\t\ttext: \"\",\n\t\t\t},\n\t\t\ttiddler,\n\t\t\t{\n\t\t\t\ttitle: draftTitle,\n\t\t\t\t\"draft.title\": targetTitle,\n\t\t\t\t\"draft.of\": targetTitle\n\t\t\t},\n\t\t\tthis.wiki.getModificationFields()\n\t\t);\n\tthis.wiki.addTiddler(draftTiddler);\n\treturn draftTiddler;\n};\n\n/*\nGenerate a title for the draft of a given tiddler\n*/\nNavigatorWidget.prototype.generateDraftTitle = function(title) {\n\treturn this.wiki.generateDraftTitle(title);\n};\n\n// Take a tiddler out of edit mode, saving the changes\nNavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList();\n\t// Replace the original tiddler with the draft\n\tif(tiddler) {\n\t\tvar draftTitle = (tiddler.fields[\"draft.title\"] || \"\").trim(),\n\t\t\tdraftOf = (tiddler.fields[\"draft.of\"] || \"\").trim();\n\t\tif(draftTitle) {\n\t\t\tvar isRename = draftOf !== draftTitle,\n\t\t\t\tisConfirmed = true;\n\t\t\tif(isRename && this.wiki.tiddlerExists(draftTitle)) {\n\t\t\t\tisConfirmed = confirm($tw.language.getString(\n\t\t\t\t\t\"ConfirmOverwriteTiddler\",\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{title: draftTitle}\n\t\t\t\t\t}\n\t\t\t\t));\n\t\t\t}\n\t\t\tif(isConfirmed) {\n\t\t\t\t// Create the new tiddler and pass it through the th-saving-tiddler hook\n\t\t\t\tvar newTiddler = new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\ttitle: draftTitle,\n\t\t\t\t\t\"draft.title\": undefined,\n\t\t\t\t\t\"draft.of\": undefined\n\t\t\t\t},this.wiki.getModificationFields());\n\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-saving-tiddler\",newTiddler,tiddler);\n\t\t\t\tthis.wiki.addTiddler(newTiddler);\n\t\t\t\t// If enabled, relink references to renamed tiddler\n\t\t\t\tvar shouldRelink = this.getAttribute(\"relinkOnRename\",\"no\").toLowerCase().trim() === \"yes\";\n\t\t\t\tif(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {\n\t\t\t\t\tthis.wiki.relinkTiddler(draftOf,draftTitle);\n\t\t\t\t}\n\t\t\t\t// Remove the draft tiddler\n\t\t\t\tthis.wiki.deleteTiddler(title);\n\t\t\t\t// Remove the original tiddler if we're renaming it\n\t\t\t\tif(isRename) {\n\t\t\t\t\tthis.wiki.deleteTiddler(draftOf);\n\t\t\t\t}\n\t\t\t\t// #2381 always remove new title & old\n\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\tthis.removeTitleFromStory(storyList,draftOf);\n\t\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\t\t// Replace the draft in the story with the original\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\t\t\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\t\t\t\tif(draftTitle !== this.storyTitle) {\n\t\t\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Trigger an autosave\n\t\t\t\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Take a tiddler out of edit mode without saving the changes\nNavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-cancelling-tiddler\", event);\n\t// Flip the specified tiddler from draft back to the original\n\tvar draftTitle = event.param || event.tiddlerTitle,\n\t\tdraftTiddler = this.wiki.getTiddler(draftTitle),\n\t\toriginalTitle = draftTiddler && draftTiddler.fields[\"draft.of\"];\n\tif(draftTiddler && originalTitle) {\n\t\t// Ask for confirmation if the tiddler text has changed\n\t\tvar isConfirmed = true,\n\t\t\toriginalTiddler = this.wiki.getTiddler(originalTitle),\n\t\t\tstoryList = this.getStoryList();\n\t\tif(this.wiki.isDraftModified(draftTitle)) {\n\t\t\tisConfirmed = confirm($tw.language.getString(\n\t\t\t\t\"ConfirmCancelTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: draftTitle}\n\t\t\t\t}\n\t\t\t));\n\t\t}\n\t\t// Remove the draft tiddler\n\t\tif(isConfirmed) {\n\t\t\tthis.wiki.deleteTiddler(draftTitle);\n\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\tif(originalTiddler) {\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);\n\t\t\t\t\tthis.addToHistory(originalTitle,event.navigateFromClientRect);\n\t\t\t\t} else {\n\t\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\t}\n\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Create a new draft tiddler\n// event.param can either be the title of a template tiddler, or a hashmap of fields.\n//\n// The title of the newly created tiddler follows these rules:\n// * If a hashmap was used and a title field was specified, use that title\n// * If a hashmap was used without a title field, use a default title, if necessary making it unique with a numeric suffix\n// * If a template tiddler was used, use the title of the template, if necessary making it unique with a numeric suffix\n//\n// If a draft of the target tiddler already exists then it is reused\nNavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-new-tiddler\", event);\n\t// Get the story details\n\tvar storyList = this.getStoryList(),\n\t\ttemplateTiddler, additionalFields, title, draftTitle, existingTiddler;\n\t// Get the template tiddler (if any)\n\tif(typeof event.param === \"string\") {\n\t\t// Get the template tiddler\n\t\ttemplateTiddler = this.wiki.getTiddler(event.param);\n\t\t// Generate a new title\n\t\ttitle = this.wiki.generateNewTitle(event.param || $tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t}\n\t// Get the specified additional fields\n\tif(typeof event.paramObject === \"object\") {\n\t\tadditionalFields = event.paramObject;\n\t}\n\tif(typeof event.param === \"object\") { // Backwards compatibility with 5.1.3\n\t\tadditionalFields = event.param;\n\t}\n\tif(additionalFields && additionalFields.title) {\n\t\ttitle = additionalFields.title;\n\t}\n\t// Make a copy of the additional fields excluding any blank ones\n\tvar filteredAdditionalFields = $tw.utils.extend({},additionalFields);\n\tObject.keys(filteredAdditionalFields).forEach(function(fieldName) {\n\t\tif(filteredAdditionalFields[fieldName] === \"\") {\n\t\t\tdelete filteredAdditionalFields[fieldName];\n\t\t}\n\t});\n\t// Generate a title if we don't have one\n\ttitle = title || this.wiki.generateNewTitle($tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t// Find any existing draft for this tiddler\n\tdraftTitle = this.wiki.findDraft(title);\n\t// Pull in any existing tiddler\n\tif(draftTitle) {\n\t\texistingTiddler = this.wiki.getTiddler(draftTitle);\n\t} else {\n\t\tdraftTitle = this.generateDraftTitle(title);\n\t\texistingTiddler = this.wiki.getTiddler(title);\n\t}\n\t// Merge the tags\n\tvar mergedTags = [];\n\tif(existingTiddler && existingTiddler.fields.tags) {\n\t\t$tw.utils.pushTop(mergedTags,existingTiddler.fields.tags);\n\t}\n\tif(additionalFields && additionalFields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,$tw.utils.parseStringArray(additionalFields.tags));\n\t}\n\tif(templateTiddler && templateTiddler.fields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,templateTiddler.fields.tags);\n\t}\n\t// Save the draft tiddler\n\tvar draftTiddler = new $tw.Tiddler({\n\t\t\ttext: \"\",\n\t\t\t\"draft.title\": title\n\t\t},\n\t\ttemplateTiddler,\n\t\tadditionalFields,\n\t\tthis.wiki.getCreationFields(),\n\t\texistingTiddler,\n\t\tfilteredAdditionalFields,\n\t\t{\n\t\t\ttitle: draftTitle,\n\t\t\t\"draft.of\": title,\n\t\t\ttags: mergedTags\n\t\t},this.wiki.getModificationFields());\n\tthis.wiki.addTiddler(draftTiddler);\n\t// Update the story to insert the new draft at the top and remove any existing tiddler\n\tif(storyList && storyList.indexOf(draftTitle) === -1) {\n\t\tvar slot = storyList.indexOf(event.navigateFromTitle);\n\t\tif(slot === -1) {\n\t\t\tslot = this.getAttribute(\"openLinkFromOutsideRiver\",\"top\") === \"bottom\" ? storyList.length - 1 : slot;\n\t\t}\n\t\tstoryList.splice(slot + 1,0,draftTitle);\n\t}\n\tif(storyList && storyList.indexOf(title) !== -1) {\n\t\tstoryList.splice(storyList.indexOf(title),1);\n\t}\n\tthis.saveStoryList(storyList);\n\t// Add a new record to the top of the history stack\n\tthis.addToHistory(draftTitle);\n\treturn false;\n};\n\n// Import JSON tiddlers into a pending import tiddler\nNavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {\n\t// Get the tiddlers\n\tvar tiddlers = [];\n\ttry {\n\t\ttiddlers = JSON.parse(event.param);\n\t} catch(e) {\n\t}\n\t// Get the current $:/Import tiddler\n\tvar importTitle = event.importTitle ? event.importTitle : IMPORT_TITLE,\n\t\timportTiddler = this.wiki.getTiddler(importTitle),\n\t\timportData = this.wiki.getTiddlerData(importTitle,{}),\n\t\tnewFields = new Object({\n\t\t\ttitle: importTitle,\n\t\t\ttype: \"application/json\",\n\t\t\t\"plugin-type\": \"import\",\n\t\t\t\"status\": \"pending\"\n\t\t}),\n\t\tincomingTiddlers = [];\n\t// Process each tiddler\n\timportData.tiddlers = importData.tiddlers || {};\n\t$tw.utils.each(tiddlers,function(tiddlerFields) {\n\t\ttiddlerFields.title = $tw.utils.trim(tiddlerFields.title);\n\t\tvar title = tiddlerFields.title;\n\t\tif(title) {\n\t\t\tincomingTiddlers.push(title);\n\t\t\timportData.tiddlers[title] = tiddlerFields;\n\t\t}\n\t});\n\t// Give the active upgrader modules a chance to process the incoming tiddlers\n\tvar messages = this.wiki.invokeUpgraders(incomingTiddlers,importData.tiddlers);\n\t$tw.utils.each(messages,function(message,title) {\n\t\tnewFields[\"message-\" + title] = message;\n\t});\n\t// Deselect any suppressed tiddlers\n\t$tw.utils.each(importData.tiddlers,function(tiddler,title) {\n\t\tif($tw.utils.count(tiddler) === 0) {\n\t\t\tnewFields[\"selection-\" + title] = \"unchecked\";\n\t\t\tnewFields[\"suppressed-\" + title] = \"yes\";\n\t\t}\n\t});\n\t// Save the $:/Import tiddler\n\tnewFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);\n\tthis.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));\n\t// Update the story and history details\n\tvar autoOpenOnImport = event.autoOpenOnImport ? event.autoOpenOnImport : this.getVariable(\"tv-auto-open-on-import\"); \n\tif(autoOpenOnImport !== \"no\") {\n\t\tvar storyList = this.getStoryList(),\n\t\t\thistory = [];\n\t\t// Add it to the story\n\t\tif(storyList && storyList.indexOf(importTitle) === -1) {\n\t\t\tstoryList.unshift(importTitle);\n\t\t}\n\t\t// And to history\n\t\thistory.push(importTitle);\n\t\t// Save the updated story and history\n\t\tthis.saveStoryList(storyList);\n\t\tthis.addToHistory(history);\n\t}\n\treturn false;\n};\n\n//\nNavigatorWidget.prototype.handlePerformImportEvent = function(event) {\n\tvar self = this,\n\t\timportTiddler = this.wiki.getTiddler(event.param),\n\t\timportData = this.wiki.getTiddlerDataCached(event.param,{tiddlers: {}}),\n\t\timportReport = [];\n\t// Add the tiddlers to the store\n\timportReport.push($tw.language.getString(\"Import/Imported/Hint\") + \"\\n\");\n\t$tw.utils.each(importData.tiddlers,function(tiddlerFields) {\n\t\tvar title = tiddlerFields.title;\n\t\tif(title && importTiddler && importTiddler.fields[\"selection-\" + title] !== \"unchecked\") {\n\t\t\tif($tw.utils.hop(importTiddler.fields,[\"rename-\" + title])) {\n\t\t\t\tvar tiddler = new $tw.Tiddler(tiddlerFields,{title : importTiddler.fields[\"rename-\" + title]});\n\t\t\t} else {\n\t\t\t\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\t\t\t}\n\t\t\ttiddler = $tw.hooks.invokeHook(\"th-importing-tiddler\",tiddler);\n\t\t\tself.wiki.addTiddler(tiddler);\n\t\t\timportReport.push(\"# [[\" + tiddler.fields.title + \"]]\");\n\t\t}\n\t});\n\t// Replace the $:/Import tiddler with an import report\n\tthis.wiki.addTiddler(new $tw.Tiddler({\n\t\ttitle: event.param,\n\t\ttext: importReport.join(\"\\n\"),\n\t\t\"status\": \"complete\"\n\t}));\n\t// Navigate to the $:/Import tiddler\n\tthis.addToHistory([event.param]);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n};\n\nNavigatorWidget.prototype.handleFoldTiddlerEvent = function(event) {\n\tvar paramObject = event.paramObject || {};\n\tif(paramObject.foldedState) {\n\t\tvar foldedState = this.wiki.getTiddlerText(paramObject.foldedState,\"show\") === \"show\" ? \"hide\" : \"show\";\n\t\tthis.wiki.setText(paramObject.foldedState,\"text\",null,foldedState);\n\t}\n};\n\nNavigatorWidget.prototype.handleFoldOtherTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,event.param === title ? \"show\" : \"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleFoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix || \"$:/state/folded/\";\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"show\");\n\t});\n};\n\nNavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {\n\tvar options = {},\n\t\tparamObject = event.paramObject || {},\n\t\tfrom = paramObject.from || event.tiddlerTitle,\n\t\tto = paramObject.to;\n\toptions.dontRenameInTags = (paramObject.renameInTags === \"false\" || paramObject.renameInTags === \"no\") ? true : false;\n\toptions.dontRenameInLists = (paramObject.renameInLists === \"false\" || paramObject.renameInLists === \"no\") ? true : false;\n\tthis.wiki.renameTiddler(from,to,options);\n};\n\nexports.navigator = NavigatorWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/password.js": {
"title": "$:/core/modules/widgets/password.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/password.js\ntype: application/javascript\nmodule-type: widget\n\nPassword widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar PasswordWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nPasswordWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nPasswordWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the current password\n\tvar password = $tw.browser ? $tw.utils.getPassword(this.passwordName) || \"\" : \"\";\n\t// Create our element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"password\");\n\tdomNode.setAttribute(\"value\",password);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nPasswordWidget.prototype.handleChangeEvent = function(event) {\n\tvar password = this.domNodes[0].value;\n\treturn $tw.utils.savePassword(this.passwordName,password);\n};\n\n/*\nCompute the internal state of the widget\n*/\nPasswordWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.passwordName = this.getAttribute(\"name\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nPasswordWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.password = PasswordWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/qualify.js": {
"title": "$:/core/modules/widgets/qualify.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/qualify.js\ntype: application/javascript\nmodule-type: widget\n\nQualify text to a variable \n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar QualifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nQualifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nQualifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nQualifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.qualifyName = this.getAttribute(\"name\");\n\tthis.qualifyTitle = this.getAttribute(\"title\");\n\t// Set context variable\n\tif(this.qualifyName) {\n\t\tthis.setVariable(this.qualifyName,this.qualifyTitle + \"-\" + this.getStateQualifier());\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nQualifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.title) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.qualify = QualifyWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/radio.js": {
"title": "$:/core/modules/widgets/radio.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/radio.js\ntype: application/javascript\nmodule-type: widget\n\nSet a field or index at a given tiddler via radio buttons\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar RadioWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRadioWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRadioWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tvar isChecked = this.getValue() === this.radioValue;\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",\n\t\t\"tc-radio \" + this.radioClass + (isChecked ? \" tc-radio-selected\" : \"\")\n\t);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"radio\");\n\tif(isChecked) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tthis.inputDomNode.setAttribute(\"disabled\",true);\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nRadioWidget.prototype.getValue = function() {\n\tvar value,\n\t\ttiddler = this.wiki.getTiddler(this.radioTitle);\n\tif (this.radioIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex);\n\t} else {\n\t\tvalue = tiddler && tiddler.getFieldString(this.radioField);\n\t}\n\treturn value;\n};\n\nRadioWidget.prototype.setValue = function() {\n\tif(this.radioIndex) {\n\t\tthis.wiki.setText(this.radioTitle,\"\",this.radioIndex,this.radioValue);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.radioTitle),\n\t\t\taddition = {};\n\t\taddition[this.radioField] = this.radioValue;\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),{title: this.radioTitle},tiddler,addition,this.wiki.getModificationFields()));\n\t}\n};\n\nRadioWidget.prototype.handleChangeEvent = function(event) {\n\tif(this.inputDomNode.checked) {\n\t\tthis.setValue();\n\t}\n\t// Trigger actions\n\tif(this.radioActions) {\n\t\tthis.invokeActionString(this.radioActions,this,event,{\"actionValue\": this.radioValue});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRadioWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.radioTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.radioField = this.getAttribute(\"field\",\"text\");\n\tthis.radioIndex = this.getAttribute(\"index\");\n\tthis.radioValue = this.getAttribute(\"value\");\n\tthis.radioClass = this.getAttribute(\"class\",\"\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\tthis.radioActions = this.getAttribute(\"actions\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRadioWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(($tw.utils.count(changedAttributes) > 0) || changedTiddlers[this.radioTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.radio = RadioWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/range.js": {
"title": "$:/core/modules/widgets/range.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/range.js\ntype: application/javascript\nmodule-type: widget\n\nRange widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RangeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRangeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRangeWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"range\");\n\tthis.inputDomNode.setAttribute(\"class\",this.elementClass);\n\tif(this.minValue){\n\t\tthis.inputDomNode.setAttribute(\"min\", this.minValue);\n\t}\n\tif(this.maxValue){\n\t\tthis.inputDomNode.setAttribute(\"max\", this.maxValue);\n\t}\n\tif(this.increment){\n\t\tthis.inputDomNode.setAttribute(\"step\", this.increment);\n\t}\n\tif(this.isDisabled === \"yes\") {\n\t\tthis.inputDomNode.setAttribute(\"disabled\",true);\n\t}\n\tthis.inputDomNode.value = this.getValue();\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name:\"mousedown\", handlerObject:this, handlerMethod:\"handleMouseDownEvent\"},\n\t\t{name:\"mouseup\", handlerObject:this, handlerMethod:\"handleMouseUpEvent\"},\n\t\t{name:\"change\", handlerObject:this, handlerMethod:\"handleChangeEvent\"},\n\t\t{name:\"input\", handlerObject:this, handlerMethod:\"handleInputEvent\"},\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.inputDomNode,nextSibling);\n\tthis.domNodes.push(this.inputDomNode);\n};\n\nRangeWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle),\n\t\tfieldName = this.tiddlerField,\n\t\tvalue = this.defaultValue;\n\tif(tiddler) {\n\t\tif(this.tiddlerIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(tiddler,this.tiddlerIndex,this.defaultValue);\n\t\t} else {\n\t\t\tif($tw.utils.hop(tiddler.fields,fieldName)) {\n\t\t\t\tvalue = tiddler.fields[fieldName] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = this.defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n\nRangeWidget.prototype.getActionVariables = function(options) {\n\toptions = options || {};\n\tvar hasChanged = (this.startValue !== this.inputDomNode.value) ? \"yes\" : \"no\";\n\t// Trigger actions. Use variables = {key:value, key:value ...}\n\t// the \"value\" is needed.\n\treturn $tw.utils.extend({\"actionValue\": this.inputDomNode.value, \"actionValueHasChanged\": hasChanged}, options);\n}\n\n// actionsStart\nRangeWidget.prototype.handleMouseDownEvent = function(event) {\n\tthis.mouseDown = true; // TODO remove once IE is gone.\n\tthis.startValue = this.inputDomNode.value; // TODO remove this line once IE is gone!\n\tthis.handleEvent(event);\n\t// Trigger actions\n\tif(this.actionsMouseDown) {\n\t\tvar variables = this.getActionVariables() // TODO this line will go into the function call below.\n\t\tthis.invokeActionString(this.actionsMouseDown,this,event,variables);\n\t}\n}\n\n// actionsStop\nRangeWidget.prototype.handleMouseUpEvent = function(event) {\n\tthis.mouseDown = false; // TODO remove once IE is gone.\n\tthis.handleEvent(event);\n\t// Trigger actions\n\tif(this.actionsMouseUp) {\n\t\tvar variables = this.getActionVariables()\n\t\tthis.invokeActionString(this.actionsMouseUp,this,event,variables);\n\t}\n\t// TODO remove the following if() once IE is gone!\n\tif ($tw.browser.isIE) {\n\t\tif (this.startValue !== this.inputDomNode.value) {\n\t\t\tthis.handleChangeEvent(event);\n\t\t\tthis.startValue = this.inputDomNode.value;\n\t\t}\n\t}\n}\n\nRangeWidget.prototype.handleChangeEvent = function(event) {\n\tif (this.mouseDown) { // TODO refactor this function once IE is gone.\n\t\tthis.handleInputEvent(event);\n\t}\n};\n\nRangeWidget.prototype.handleInputEvent = function(event) {\n\tthis.handleEvent(event);\n\t// Trigger actions\n\tif(this.actionsInput) {\n\t\t// \"tiddler\" parameter may be missing. See .execute() below\n\t\tvar variables = this.getActionVariables({\"actionValueHasChanged\": \"yes\"}) // TODO this line will go into the function call below.\n\t\tthis.invokeActionString(this.actionsInput,this,event,variables);\n\t}\n};\n\nRangeWidget.prototype.handleEvent = function(event) {\n\tif(this.getValue() !== this.inputDomNode.value) {\n\t\tif(this.tiddlerIndex) {\n\t\t\tthis.wiki.setText(this.tiddlerTitle,\"\",this.tiddlerIndex,this.inputDomNode.value);\n\t\t} else {\n\t\t\tthis.wiki.setText(this.tiddlerTitle,this.tiddlerField,null,this.inputDomNode.value);\n\t\t}\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRangeWidget.prototype.execute = function() {\n\t// TODO remove the next 1 lines once IE is gone!\n\tthis.mouseUp = true; // Needed for IE10\n\t// Get the parameters from the attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.tiddlerField = this.getAttribute(\"field\",\"text\");\n\tthis.tiddlerIndex = this.getAttribute(\"index\");\n\tthis.minValue = this.getAttribute(\"min\");\n\tthis.maxValue = this.getAttribute(\"max\");\n\tthis.increment = this.getAttribute(\"increment\");\n\tthis.defaultValue = this.getAttribute(\"default\",\"\");\n\tthis.elementClass = this.getAttribute(\"class\",\"\");\n\tthis.isDisabled = this.getAttribute(\"disabled\",\"no\");\n\t// Actions since 5.1.23\n\t// Next 2 only fire once!\n\tthis.actionsMouseDown = this.getAttribute(\"actionsStart\",\"\");\n\tthis.actionsMouseUp = this.getAttribute(\"actionsStop\",\"\");\n\t// Input fires very often!\n\tthis.actionsInput = this.getAttribute(\"actions\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRangeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.tiddlerTitle]) {\n\t\t\tvar value = this.getValue();\n\t\t\tif(this.inputDomNode.value !== value) {\n\t\t\t\tthis.inputDomNode.value = value;\n\t\t\t}\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.range = RangeWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/raw.js": {
"title": "$:/core/modules/widgets/raw.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/raw.js\ntype: application/javascript\nmodule-type: widget\n\nRaw widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RawWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRawWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRawWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tvar div = this.document.createElement(\"div\");\n\tdiv.innerHTML=this.parseTreeNode.html;\n\tparent.insertBefore(div,nextSibling);\n\tthis.domNodes.push(div);\t\n};\n\n/*\nCompute the internal state of the widget\n*/\nRawWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRawWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.raw = RawWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/reveal.js": {
"title": "$:/core/modules/widgets/reveal.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/reveal.js\ntype: application/javascript\nmodule-type: widget\n\nReveal widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RevealWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRevealWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRevealWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.revealTag && $tw.config.htmlUnsafeElements.indexOf(this.revealTag) === -1) {\n\t\ttag = this.revealTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\tthis.domNode = domNode;\n\tthis.assignDomNodeClasses();\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\t}\n\tif(!this.isOpen) {\n\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t}\n\tthis.domNodes.push(domNode);\n};\n\nRevealWidget.prototype.positionPopup = function(domNode) {\n\tdomNode.style.position = \"absolute\";\n\tdomNode.style.zIndex = \"1000\";\n\tvar left,top;\n\tswitch(this.position) {\n\t\tcase \"left\":\n\t\t\tleft = this.popup.left - domNode.offsetWidth;\n\t\t\ttop = this.popup.top;\n\t\t\tbreak;\n\t\tcase \"above\":\n\t\t\tleft = this.popup.left;\n\t\t\ttop = this.popup.top - domNode.offsetHeight;\n\t\t\tbreak;\n\t\tcase \"aboveright\":\n\t\t\tleft = this.popup.left + this.popup.width;\n\t\t\ttop = this.popup.top + this.popup.height - domNode.offsetHeight;\n\t\t\tbreak;\n\t\tcase \"belowright\":\n\t\t\tleft = this.popup.left + this.popup.width;\n\t\t\ttop = this.popup.top + this.popup.height;\n\t\t\tbreak;\t\t\t\n\t\tcase \"right\":\n\t\t\tleft = this.popup.left + this.popup.width;\n\t\t\ttop = this.popup.top;\n\t\t\tbreak;\n\t\tcase \"belowleft\":\n\t\t\tleft = this.popup.left + this.popup.width - domNode.offsetWidth;\n\t\t\ttop = this.popup.top + this.popup.height;\n\t\t\tbreak;\n\t\tcase \"aboveleft\":\n\t\t\tleft = this.popup.left - domNode.offsetWidth;\n\t\t\ttop = this.popup.top - domNode.offsetHeight;\n\t\t\tbreak;\t\t\t\n\t\tdefault: // Below\n\t\t\tleft = this.popup.left;\n\t\t\ttop = this.popup.top + this.popup.height;\n\t\t\tbreak;\n\t}\n\tif(!this.positionAllowNegative) {\n\t\tleft = Math.max(0,left);\n\t\ttop = Math.max(0,top);\n\t}\n\tdomNode.style.left = left + \"px\";\n\tdomNode.style.top = top + \"px\";\n};\n\n/*\nCompute the internal state of the widget\n*/\nRevealWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.state = this.getAttribute(\"state\");\n\tthis.revealTag = this.getAttribute(\"tag\");\n\tthis.type = this.getAttribute(\"type\");\n\tthis.text = this.getAttribute(\"text\");\n\tthis.position = this.getAttribute(\"position\");\n\tthis.positionAllowNegative = this.getAttribute(\"positionAllowNegative\") === \"yes\";\n\t// class attribute handled in assignDomNodeClasses()\n\tthis.style = this.getAttribute(\"style\",\"\");\n\tthis[\"default\"] = this.getAttribute(\"default\",\"\");\n\tthis.animate = this.getAttribute(\"animate\",\"no\");\n\tthis.retain = this.getAttribute(\"retain\",\"no\");\n\tthis.openAnimation = this.animate === \"no\" ? undefined : \"open\";\n\tthis.closeAnimation = this.animate === \"no\" ? undefined : \"close\";\n\tthis.updatePopupPosition = this.getAttribute(\"updatePopupPosition\",\"no\") === \"yes\";\n\t// Compute the title of the state tiddler and read it\n\tthis.stateTiddlerTitle = this.state;\n\tthis.stateTitle = this.getAttribute(\"stateTitle\");\n\tthis.stateField = this.getAttribute(\"stateField\");\n\tthis.stateIndex = this.getAttribute(\"stateIndex\");\n\tthis.readState();\n\t// Construct the child widgets\n\tvar childNodes = this.isOpen ? this.parseTreeNode.children : [];\n\tthis.hasChildNodes = this.isOpen;\n\tthis.makeChildWidgets(childNodes);\n};\n\n/*\nRead the state tiddler\n*/\nRevealWidget.prototype.readState = function() {\n\t// Read the information from the state tiddler\n\tvar state,\n\t defaultState = this[\"default\"];\n\tif(this.stateTitle) {\n\t\tvar stateTitleTiddler = this.wiki.getTiddler(this.stateTitle);\n\t\tif(this.stateField) {\n\t\t\tstate = stateTitleTiddler ? stateTitleTiddler.getFieldString(this.stateField) || defaultState : defaultState;\n\t\t} else if(this.stateIndex) {\n\t\t\tstate = stateTitleTiddler ? this.wiki.extractTiddlerDataItem(this.stateTitle,this.stateIndex) || defaultState : defaultState;\n\t\t} else if(stateTitleTiddler) {\n\t\t\tstate = this.wiki.getTiddlerText(this.stateTitle) || defaultState;\n\t\t} else {\n\t\t\tstate = defaultState;\n\t\t}\n\t} else {\n\t\tstate = this.stateTiddlerTitle ? this.wiki.getTextReference(this.state,this[\"default\"],this.getVariable(\"currentTiddler\")) : this[\"default\"];\n\t}\n\tif(state === null) {\n\t\tstate = this[\"default\"];\n\t}\n\tswitch(this.type) {\n\t\tcase \"popup\":\n\t\t\tthis.readPopupState(state);\n\t\t\tbreak;\n\t\tcase \"match\":\n\t\t\tthis.isOpen = this.text === state;\n\t\t\tbreak;\n\t\tcase \"nomatch\":\n\t\t\tthis.isOpen = this.text !== state;\n\t\t\tbreak;\n\t\tcase \"lt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t\tcase \"gt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"lteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"gteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t}\n};\n\nRevealWidget.prototype.compareStateText = function(state) {\n\treturn state.localeCompare(this.text,undefined,{numeric: true,sensitivity: \"case\"});\n};\n\nRevealWidget.prototype.readPopupState = function(state) {\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/,\n\t\tmatch = popupLocationRegExp.exec(state);\n\t// Check if the state matches the location regexp\n\tif(match) {\n\t\t// If so, we're open\n\t\tthis.isOpen = true;\n\t\t// Get the location\n\t\tthis.popup = {\n\t\t\tleft: parseFloat(match[1]),\n\t\t\ttop: parseFloat(match[2]),\n\t\t\twidth: parseFloat(match[3]),\n\t\t\theight: parseFloat(match[4])\n\t\t};\n\t} else {\n\t\t// If not, we're closed\n\t\tthis.isOpen = false;\n\t}\n};\n\nRevealWidget.prototype.assignDomNodeClasses = function() {\n\tvar classes = this.getAttribute(\"class\",\"\").split(\" \");\n\tclasses.push(\"tc-reveal\");\n\tthis.domNode.className = classes.join(\" \");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRevealWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.state || changedAttributes.type || changedAttributes.text || changedAttributes.position || changedAttributes.positionAllowNegative || changedAttributes[\"default\"] || changedAttributes.animate || changedAttributes.stateTitle || changedAttributes.stateField || changedAttributes.stateIndex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar currentlyOpen = this.isOpen;\n\t\tthis.readState();\n\t\tif(this.isOpen !== currentlyOpen) {\n\t\t\tif(this.retain === \"yes\") {\n\t\t\t\tthis.updateState();\n\t\t\t} else {\n\t\t\t\tthis.refreshSelf();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else if(this.type === \"popup\" && this.updatePopupPosition && (changedTiddlers[this.state] || changedTiddlers[this.stateTitle])) {\n\t\t\tthis.positionPopup(this.domNode);\n\t\t}\n\t\tif(changedAttributes.style) {\n\t\t\tthis.domNode.style = this.getAttribute(\"style\",\"\");\n\t\t}\n\t\tif(changedAttributes[\"class\"]) {\n\t\t\tthis.assignDomNodeClasses();\n\t\t}\t\t\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\n/*\nCalled by refresh() to dynamically show or hide the content\n*/\nRevealWidget.prototype.updateState = function() {\n\tvar self = this;\n\t// Read the current state\n\tthis.readState();\n\t// Construct the child nodes if needed\n\tvar domNode = this.domNodes[0];\n\tif(this.isOpen && !this.hasChildNodes) {\n\t\tthis.hasChildNodes = true;\n\t\tthis.makeChildWidgets(this.parseTreeNode.children);\n\t\tthis.renderChildren(domNode,null);\n\t}\n\t// Animate our DOM node\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\n\t}\n\tif(this.isOpen) {\n\t\tdomNode.removeAttribute(\"hidden\");\n $tw.anim.perform(this.openAnimation,domNode);\n\t} else {\n\t\t$tw.anim.perform(this.closeAnimation,domNode,{callback: function() {\n\t\t\t//make sure that the state hasn't changed during the close animation\n\t\t\tself.readState()\n\t\t\tif(!self.isOpen) {\n\t\t\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t\t\t}\n\t\t}});\n\t}\n};\n\nexports.reveal = RevealWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/scrollable.js": {
"title": "$:/core/modules/widgets/scrollable.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/scrollable.js\ntype: application/javascript\nmodule-type: widget\n\nScrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ScrollableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.scaleFactor = 1;\n\tthis.addEventListeners([\n\t\t{type: \"tm-scroll\", handler: \"handleScrollEvent\"}\n\t]);\n\tif($tw.browser) {\n\t\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t\t};\n\t\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\twindow.mozCancelRequestAnimationFrame ||\n\t\t\tfunction(id) {\n\t\t\t\twindow.clearTimeout(id);\n\t\t\t};\n\t}\n};\n\n/*\nInherit from the base widget class\n*/\nScrollableWidget.prototype = new Widget();\n\nScrollableWidget.prototype.cancelScroll = function() {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(window,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle a scroll event\n*/\nScrollableWidget.prototype.handleScrollEvent = function(event) {\n\t// Pass the scroll event through if our offsetsize is larger than our scrollsize\n\tif(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === \"yes\") {\n\t\treturn true;\n\t}\n\tif(event.paramObject && event.paramObject.selector) {\n\t\tthis.scrollSelectorIntoView(null,event.paramObject.selector);\n\t} else {\n\t\tthis.scrollIntoView(event.target);\t\t\t\n\t}\n\treturn false; // Handled event\n};\n\n/*\nScroll an element into view\n*/\nScrollableWidget.prototype.scrollIntoView = function(element) {\n\tvar duration = $tw.utils.getAnimationDuration(),\n\tsrcWindow = element ? element.ownerDocument.defaultView : window;\n\tthis.cancelScroll();\n\tthis.startTime = Date.now();\n\tvar scrollPosition = {\n\t\tx: this.outerDomNode.scrollLeft,\n\t\ty: this.outerDomNode.scrollTop\n\t};\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar scrollableBounds = this.outerDomNode.getBoundingClientRect(),\n\t\tclientTargetBounds = element.getBoundingClientRect(),\n\t\tbounds = {\n\t\t\tleft: clientTargetBounds.left + scrollPosition.x - scrollableBounds.left,\n\t\t\ttop: clientTargetBounds.top + scrollPosition.y - scrollableBounds.top,\n\t\t\twidth: clientTargetBounds.width,\n\t\t\theight: clientTargetBounds.height\n\t\t};\n\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\tvar getEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\t// If the target is already visible then stay where we are\n\t\t\tif(targetPos >= currentPos && (targetPos + targetSize) <= (currentPos + currentSize)) {\n\t\t\t\treturn currentPos;\n\t\t\t// If the target is above/left of the current view, then scroll to its top/left\n\t\t\t} else if(targetPos <= currentPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// If the target is smaller than the window and the scroll position is too far up, then scroll till the target is at the bottom of the window\n\t\t\t} else if(targetSize < currentSize && currentPos < (targetPos + targetSize - currentSize)) {\n\t\t\t\treturn targetPos + targetSize - currentSize;\n\t\t\t// If the target is big, then just scroll to the top\n\t\t\t} else if(currentPos < targetPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// Otherwise, stay where we are\n\t\t\t} else {\n\t\t\t\treturn currentPos;\n\t\t\t}\n\t\t},\n\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,this.outerDomNode.offsetWidth),\n\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,this.outerDomNode.offsetHeight);\n\t// Only scroll if necessary\n\tif(endX !== scrollPosition.x || endY !== scrollPosition.y) {\n\t\tvar self = this,\n\t\t\tdrawFrame;\n\t\tdrawFrame = function () {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\t\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll();\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tself.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;\n\t\t\tself.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);\n\t\t\t}\n\t\t};\n\t\tdrawFrame();\n\t}\n};\n\nScrollableWidget.prototype.scrollSelectorIntoView = function(baseElement,selector,callback) {\n\tbaseElement = baseElement || document.body;\n\tvar element = baseElement.querySelector(selector);\n\tif(element) {\n\t\tthis.scrollIntoView(element,callback);\t\t\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nScrollableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create elements\n\tthis.outerDomNode = this.document.createElement(\"div\");\n\t$tw.utils.setStyle(this.outerDomNode,[\n\t\t{overflowY: \"auto\"},\n\t\t{overflowX: \"auto\"},\n\t\t{webkitOverflowScrolling: \"touch\"}\n\t]);\n\tthis.innerDomNode = this.document.createElement(\"div\");\n\tthis.outerDomNode.appendChild(this.innerDomNode);\n\t// Assign classes\n\tthis.outerDomNode.className = this[\"class\"] || \"\";\n\t// Insert element\n\tparent.insertBefore(this.outerDomNode,nextSibling);\n\tthis.renderChildren(this.innerDomNode,null);\n\tthis.domNodes.push(this.outerDomNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nScrollableWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.fallthrough = this.getAttribute(\"fallthrough\",\"yes\");\n\tthis[\"class\"] = this.getAttribute(\"class\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nScrollableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.scrollable = ScrollableWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/select.js": {
"title": "$:/core/modules/widgets/select.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/select.js\ntype: application/javascript\nmodule-type: widget\n\nSelect widget:\n\n```\n<$select tiddler=\"MyTiddler\" field=\"text\">\n<$list filter=\"[tag[chapter]]\">\n<option value=<<currentTiddler>>>\n<$view field=\"description\"/>\n</option>\n</$list>\n</$select>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SelectWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSelectWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSelectWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\tthis.setSelectValue();\n\t$tw.utils.addEventListeners(this.getSelectDomNode(),[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n};\n\n/*\nHandle a change event\n*/\nSelectWidget.prototype.handleChangeEvent = function(event) {\n\t// Get the new value and assign it to the tiddler\n\tif(this.selectMultiple == false) {\n\t\tvar value = this.getSelectDomNode().value;\n\t} else {\n\t\tvar value = this.getSelectValues()\n\t\t\t\tvalue = $tw.utils.stringifyList(value);\n\t}\n\tthis.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);\n\t// Trigger actions\n\tif(this.selectActions) {\n\t\tthis.invokeActionString(this.selectActions,this,event);\n\t}\n};\n\n/*\nIf necessary, set the value of the select element to the current value\n*/\nSelectWidget.prototype.setSelectValue = function() {\n\tvar value = this.selectDefault;\n\t// Get the value\n\tif(this.selectIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.selectTitle,this.selectIndex,value);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.selectTitle);\n\t\tif(tiddler) {\n\t\t\tif(this.selectField === \"text\") {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.selectTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.selectField)) {\n\t\t\t\t\tvalue = tiddler.getFieldString(this.selectField);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.selectField === \"title\") {\n\t\t\t\tvalue = this.selectTitle;\n\t\t\t}\n\t\t}\n\t}\n\t// Assign it to the select element if it's different than the current value\n\tif (this.selectMultiple) {\n\t\tvalue = value === undefined ? \"\" : value;\n\t\tvar select = this.getSelectDomNode();\n\t\tvar values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);\n\t\tfor(var i=0; i < select.children.length; i++){\n\t\t\tselect.children[i].selected = values.indexOf(select.children[i].value) !== -1\n\t\t}\n\t} else {\n\t\tvar domNode = this.getSelectDomNode();\n\t\tif(domNode.value !== value) {\n\t\t\tdomNode.value = value;\n\t\t}\n\t}\n};\n\n/*\nGet the DOM node of the select element\n*/\nSelectWidget.prototype.getSelectDomNode = function() {\n\treturn this.children[0].domNodes[0];\n};\n\n// Return an array of the selected opion values\n// select is an HTML select element\nSelectWidget.prototype.getSelectValues = function() {\n\tvar select, result, options, opt;\n\tselect = this.getSelectDomNode();\n\tresult = [];\n\toptions = select && select.options;\n\tfor (var i=0; i<options.length; i++) {\n\t\topt = options[i];\n\t\tif (opt.selected) {\n\t\t\tresult.push(opt.value || opt.text);\n\t\t}\n\t}\n\treturn result;\n}\n\n/*\nCompute the internal state of the widget\n*/\nSelectWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.selectActions = this.getAttribute(\"actions\");\n\tthis.selectTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.selectField = this.getAttribute(\"field\",\"text\");\n\tthis.selectIndex = this.getAttribute(\"index\");\n\tthis.selectClass = this.getAttribute(\"class\");\n\tthis.selectDefault = this.getAttribute(\"default\");\n\tthis.selectMultiple = this.getAttribute(\"multiple\", false);\n\tthis.selectSize = this.getAttribute(\"size\");\n\tthis.selectTooltip = this.getAttribute(\"tooltip\");\n\t// Make the child widgets\n\tvar selectNode = {\n\t\ttype: \"element\",\n\t\ttag: \"select\",\n\t\tchildren: this.parseTreeNode.children\n\t};\n\tif(this.selectClass) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"class\",this.selectClass);\n\t}\n\tif(this.selectMultiple) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"multiple\",\"multiple\");\n\t}\n\tif(this.selectSize) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"size\",this.selectSize);\n\t}\n\tif(this.selectTooltip) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"title\",this.selectTooltip);\n\t}\n\tthis.makeChildWidgets([selectNode]);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSelectWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// If we're using a different tiddler/field/index then completely refresh ourselves\n\tif(changedAttributes.selectTitle || changedAttributes.selectField || changedAttributes.selectIndex || changedAttributes.selectTooltip) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t// If the target tiddler value has changed, just update setting and refresh the children\n\t} else {\n\t\tvar childrenRefreshed = this.refreshChildren(changedTiddlers);\n\t\tif(changedTiddlers[this.selectTitle] || childrenRefreshed) {\n\t\t\tthis.setSelectValue();\n\t\t} \n\t\treturn childrenRefreshed;\n\t}\n};\n\nexports.select = SelectWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/set.js": {
"title": "$:/core/modules/widgets/set.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/set.js\ntype: application/javascript\nmodule-type: widget\n\nSet variable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.setName = this.getAttribute(\"name\",\"currentTiddler\");\n\tthis.setFilter = this.getAttribute(\"filter\");\n\tthis.setSelect = this.getAttribute(\"select\");\n\tthis.setTiddler = this.getAttribute(\"tiddler\");\n\tthis.setSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.setField = this.getAttribute(\"field\");\n\tthis.setIndex = this.getAttribute(\"index\");\n\tthis.setValue = this.getAttribute(\"value\");\n\tthis.setEmptyValue = this.getAttribute(\"emptyValue\");\n\t// Set context variable\n\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nGet the value to be assigned\n*/\nSetWidget.prototype.getValue = function() {\n\tvar value = this.setValue;\n\tif(this.setTiddler) {\n\t\tvar tiddler;\n\t\tif(this.setSubTiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.setTiddler,this.setSubTiddler);\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.setTiddler);\t\t\t\n\t\t}\n\t\tif(!tiddler) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t} else if(this.setField) {\n\t\t\tvalue = tiddler.getFieldString(this.setField) || this.setEmptyValue;\n\t\t} else if(this.setIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.setTiddler,this.setIndex,this.setEmptyValue);\n\t\t} else {\n\t\t\tvalue = tiddler.fields.text || this.setEmptyValue ;\n\t\t}\n\t} else if(this.setFilter) {\n\t\tvar results = this.wiki.filterTiddlers(this.setFilter,this);\n\t\tif(this.setValue == null) {\n\t\t\tvar select;\n\t\t\tif(this.setSelect) {\n\t\t\t\tselect = parseInt(this.setSelect,10);\n\t\t\t}\n\t\t\tif(select !== undefined) {\n\t\t\t\tvalue = results[select] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = $tw.utils.stringifyList(results);\t\t\t\n\t\t\t}\n\t\t}\n\t\tif(results.length === 0 && this.setEmptyValue !== undefined) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t}\n\t} else if(!value && this.setEmptyValue) {\n\t\tvalue = this.setEmptyValue;\n\t}\n\treturn value || \"\";\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSetWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.filter || changedAttributes.select || changedAttributes.tiddler || (this.setTiddler && changedTiddlers[this.setTiddler]) || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes.emptyValue ||\n\t (this.setFilter && this.getValue() != this.variables[this.setName].value)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.setvariable = SetWidget;\nexports.set = SetWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/text.js": {
"title": "$:/core/modules/widgets/text.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/text.js\ntype: application/javascript\nmodule-type: widget\n\nText node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TextNodeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTextNodeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTextNodeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar text = this.getAttribute(\"text\",this.parseTreeNode.text || \"\");\n\ttext = text.replace(/\\r/mg,\"\");\n\tvar textNode = this.document.createTextNode(text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTextNodeWidget.prototype.execute = function() {\n\t// Nothing to do for a text node\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTextNodeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.text) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.text = TextNodeWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/tiddler.js": {
"title": "$:/core/modules/widgets/tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/tiddler.js\ntype: application/javascript\nmodule-type: widget\n\nTiddler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTiddlerWidget.prototype.execute = function() {\n\tthis.tiddlerState = this.computeTiddlerState();\n\tthis.setVariable(\"currentTiddler\",this.tiddlerState.currentTiddler);\n\tthis.setVariable(\"missingTiddlerClass\",this.tiddlerState.missingTiddlerClass);\n\tthis.setVariable(\"shadowTiddlerClass\",this.tiddlerState.shadowTiddlerClass);\n\tthis.setVariable(\"systemTiddlerClass\",this.tiddlerState.systemTiddlerClass);\n\tthis.setVariable(\"tiddlerTagClasses\",this.tiddlerState.tiddlerTagClasses);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nCompute the tiddler state flags\n*/\nTiddlerWidget.prototype.computeTiddlerState = function() {\n\t// Get our parameters\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Compute the state\n\tvar state = {\n\t\tcurrentTiddler: this.tiddlerTitle || \"\",\n\t\tmissingTiddlerClass: (this.wiki.tiddlerExists(this.tiddlerTitle) || this.wiki.isShadowTiddler(this.tiddlerTitle)) ? \"tc-tiddler-exists\" : \"tc-tiddler-missing\",\n\t\tshadowTiddlerClass: this.wiki.isShadowTiddler(this.tiddlerTitle) ? \"tc-tiddler-shadow\" : \"\",\n\t\tsystemTiddlerClass: this.wiki.isSystemTiddler(this.tiddlerTitle) ? \"tc-tiddler-system\" : \"\",\n\t\ttiddlerTagClasses: this.getTagClasses()\n\t};\n\t// Compute a simple hash to make it easier to detect changes\n\tstate.hash = state.currentTiddler + state.missingTiddlerClass + state.shadowTiddlerClass + state.systemTiddlerClass + state.tiddlerTagClasses;\n\treturn state;\n};\n\n/*\nCreate a string of CSS classes derived from the tags of the current tiddler\n*/\nTiddlerWidget.prototype.getTagClasses = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\tif(tiddler) {\n\t\tvar tags = [];\n\t\t$tw.utils.each(tiddler.fields.tags,function(tag) {\n\t\t\ttags.push(\"tc-tagged-\" + encodeURIComponent(tag));\n\t\t});\n\t\treturn tags.join(\" \");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tnewTiddlerState = this.computeTiddlerState();\n\tif(changedAttributes.tiddler || newTiddlerState.hash !== this.tiddlerState.hash) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.tiddler = TiddlerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/transclude.js": {
"title": "$:/core/modules/widgets/transclude.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/transclude.js\ntype: application/javascript\nmodule-type: widget\n\nTransclude widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TranscludeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTranscludeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTranscludeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTranscludeWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.transcludeTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.transcludeSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.transcludeField = this.getAttribute(\"field\");\n\tthis.transcludeIndex = this.getAttribute(\"index\");\n\tthis.transcludeMode = this.getAttribute(\"mode\");\n\tthis.recursionMarker = this.getAttribute(\"recursionMarker\",\"yes\");\n\t// Parse the text reference\n\tvar parseAsInline = !this.parseTreeNode.isBlock;\n\tif(this.transcludeMode === \"inline\") {\n\t\tparseAsInline = true;\n\t} else if(this.transcludeMode === \"block\") {\n\t\tparseAsInline = false;\n\t}\n\tvar parser = this.wiki.parseTextReference(\n\t\t\t\t\t\tthis.transcludeTitle,\n\t\t\t\t\t\tthis.transcludeField,\n\t\t\t\t\t\tthis.transcludeIndex,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparseAsInline: parseAsInline,\n\t\t\t\t\t\t\tsubTiddler: this.transcludeSubTiddler\n\t\t\t\t\t\t}),\n\t\tparseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;\n\t// Set context variables for recursion detection\n\tvar recursionMarker = this.makeRecursionMarker();\n\tif(this.recursionMarker === \"yes\") {\n\t\tthis.setVariable(\"transclusion\",recursionMarker);\n\t}\n\t// Check for recursion\n\tif(parser) {\n\t\tif(this.parentWidget && this.parentWidget.hasVariable(\"transclusion\",recursionMarker)) {\n\t\t\tparseTreeNodes = [{type: \"element\", tag: \"span\", attributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-error\"}\n\t\t\t}, children: [\n\t\t\t\t{type: \"text\", text: $tw.language.getString(\"Error/RecursiveTransclusion\")}\n\t\t\t]}];\n\t\t}\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nCompose a string comprising the title, field and/or index to identify this transclusion for recursion detection\n*/\nTranscludeWidget.prototype.makeRecursionMarker = function() {\n\tvar output = [];\n\toutput.push(\"{\");\n\toutput.push(this.getVariable(\"currentTiddler\",{defaultValue: \"\"}));\n\toutput.push(\"|\");\n\toutput.push(this.transcludeTitle || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeField || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeIndex || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeSubTiddler || \"\");\n\toutput.push(\"}\");\n\treturn output.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTranscludeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.transclude = TranscludeWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/vars.js": {
"title": "$:/core/modules/widgets/vars.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/vars.js\ntype: application/javascript\nmodule-type: widget\n\nThis widget allows multiple variables to be set in one go:\n\n```\n\\define helloworld() Hello world!\n<$vars greeting=\"Hi\" me={{!!title}} sentence=<<helloworld>>>\n <<greeting>>! I am <<me>> and I say: <<sentence>>\n</$vars>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar VarsWidget = function(parseTreeNode,options) {\n\t// Call the constructor\n\tWidget.call(this);\n\t// Initialise\t\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nVarsWidget.prototype = Object.create(Widget.prototype);\n\n/*\nRender this widget into the DOM\n*/\nVarsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nVarsWidget.prototype.execute = function() {\n\t// Parse variables\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(val,key) {\n\t\tif(key.charAt(0) !== \"$\") {\n\t\t\tself.setVariable(key,val);\n\t\t}\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nVarsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"vars\"] = VarsWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/view.js": {
"title": "$:/core/modules/widgets/view.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/view.js\ntype: application/javascript\nmodule-type: widget\n\nView widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ViewWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nViewWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nViewWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tif(this.text) {\n\t\tvar textNode = this.document.createTextNode(this.text);\n\t\tparent.insertBefore(textNode,nextSibling);\n\t\tthis.domNodes.push(textNode);\n\t} else {\n\t\tthis.makeChildWidgets();\n\t\tthis.renderChildren(parent,nextSibling);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nViewWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.viewTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.viewSubtiddler = this.getAttribute(\"subtiddler\");\n\tthis.viewField = this.getAttribute(\"field\",\"text\");\n\tthis.viewIndex = this.getAttribute(\"index\");\n\tthis.viewFormat = this.getAttribute(\"format\",\"text\");\n\tthis.viewTemplate = this.getAttribute(\"template\",\"\");\n\tthis.viewMode = this.getAttribute(\"mode\",\"block\");\n\tswitch(this.viewFormat) {\n\t\tcase \"htmlwikified\":\n\t\t\tthis.text = this.getValueAsHtmlWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"plainwikified\":\n\t\t\tthis.text = this.getValueAsPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencodedplainwikified\":\n\t\t\tthis.text = this.getValueAsHtmlEncodedPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencoded\":\n\t\t\tthis.text = this.getValueAsHtmlEncoded();\n\t\t\tbreak;\n\t\tcase \"urlencoded\":\n\t\t\tthis.text = this.getValueAsUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"doubleurlencoded\":\n\t\t\tthis.text = this.getValueAsDoubleUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"date\":\n\t\t\tthis.text = this.getValueAsDate(this.viewTemplate);\n\t\t\tbreak;\n\t\tcase \"relativedate\":\n\t\t\tthis.text = this.getValueAsRelativeDate();\n\t\t\tbreak;\n\t\tcase \"stripcomments\":\n\t\t\tthis.text = this.getValueAsStrippedComments();\n\t\t\tbreak;\n\t\tcase \"jsencoded\":\n\t\t\tthis.text = this.getValueAsJsEncoded();\n\t\t\tbreak;\n\t\tdefault: // \"text\"\n\t\t\tthis.text = this.getValueAsText();\n\t\t\tbreak;\n\t}\n};\n\n/*\nThe various formatter functions are baked into this widget for the moment. Eventually they will be replaced by macro functions\n*/\n\n/*\nRetrieve the value of the widget. Options are:\nasString: Optionally return the value as a string\n*/\nViewWidget.prototype.getValue = function(options) {\n\toptions = options || {};\n\tvar value = options.asString ? \"\" : undefined;\n\tif(this.viewIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.viewTitle,this.viewIndex);\n\t} else {\n\t\tvar tiddler;\n\t\tif(this.viewSubtiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.viewTitle,this.viewSubtiddler);\t\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.viewTitle);\n\t\t}\n\t\tif(tiddler) {\n\t\t\tif(this.viewField === \"text\" && !this.viewSubtiddler) {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.viewTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.viewField)) {\n\t\t\t\t\tif(options.asString) {\n\t\t\t\t\t\tvalue = tiddler.getFieldString(this.viewField);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue = tiddler.fields[this.viewField];\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.viewField === \"title\") {\n\t\t\t\tvalue = this.viewTitle;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n\nViewWidget.prototype.getValueAsText = function() {\n\treturn this.getValue({asString: true});\n};\n\nViewWidget.prototype.getValueAsHtmlWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/html\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsPlainWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsHtmlEncodedPlainWikified = function(mode) {\n\treturn $tw.utils.htmlEncode(this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t}));\n};\n\nViewWidget.prototype.getValueAsHtmlEncoded = function() {\n\treturn $tw.utils.htmlEncode(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsUrlEncoded = function() {\n\treturn encodeURIComponent(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {\n\treturn encodeURIComponent(encodeURIComponent(this.getValueAsText()));\n};\n\nViewWidget.prototype.getValueAsDate = function(format) {\n\tformat = format || \"YYYY MM DD 0hh:0mm\";\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.formatDateString(value,format);\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsRelativeDate = function(format) {\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.getRelativeDate((new Date()) - (new Date(value))).description;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsStrippedComments = function() {\n\tvar lines = this.getValueAsText().split(\"\\n\"),\n\t\tout = [];\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar text = lines[line];\n\t\tif(!/^\\s*\\/\\/#/.test(text)) {\n\t\t\tout.push(text);\n\t\t}\n\t}\n\treturn out.join(\"\\n\");\n};\n\nViewWidget.prototype.getValueAsJsEncoded = function() {\n\treturn $tw.utils.stringify(this.getValueAsText());\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nViewWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.template || changedAttributes.format || changedTiddlers[this.viewTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.view = ViewWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/widget.js": {
"title": "$:/core/modules/widgets/widget.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/widget.js\ntype: application/javascript\nmodule-type: widget\n\nWidget base class\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate a widget object for a parse tree node\n\tparseTreeNode: reference to the parse tree node to be rendered\n\toptions: see below\nOptions include:\n\twiki: mandatory reference to wiki associated with this render tree\n\tparentWidget: optional reference to a parent renderer node for the context chain\n\tdocument: optional document object to use instead of global document\n*/\nvar Widget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInitialise widget properties. These steps are pulled out of the constructor so that we can reuse them in subclasses\n*/\nWidget.prototype.initialise = function(parseTreeNode,options) {\n\t// Bail if parseTreeNode is undefined, meaning that the widget constructor was called without any arguments so that it can be subclassed\n\tif(parseTreeNode === undefined) {\n\t\treturn;\n\t}\n\toptions = options || {};\n\t// Save widget info\n\tthis.parseTreeNode = parseTreeNode;\n\tthis.wiki = options.wiki;\n\tthis.parentWidget = options.parentWidget;\n\tthis.variablesConstructor = function() {};\n\tthis.variablesConstructor.prototype = this.parentWidget ? this.parentWidget.variables : {};\n\tthis.variables = new this.variablesConstructor();\n\tthis.document = options.document;\n\tthis.attributes = {};\n\tthis.children = [];\n\tthis.domNodes = [];\n\tthis.eventListeners = {};\n\t// Hashmap of the widget classes\n\tif(!this.widgetClasses) {\n\t\t// Get widget classes\n\t\tWidget.prototype.widgetClasses = $tw.modules.applyMethods(\"widget\");\n\t\t// Process any subclasses\n\t\t$tw.modules.forEachModuleOfType(\"widget-subclass\",function(title,module) {\n\t\t\tif(module.baseClass) {\n\t\t\t\tvar baseClass = Widget.prototype.widgetClasses[module.baseClass];\n\t\t\t\tif(!baseClass) {\n\t\t\t\t\tthrow \"Module '\" + title + \"' is attemping to extend a non-existent base class '\" + module.baseClass + \"'\";\n\t\t\t\t}\n\t\t\t\tvar subClass = module.constructor;\n\t\t\t\tsubClass.prototype = new baseClass();\n\t\t\t\t$tw.utils.extend(subClass.prototype,module.prototype);\n\t\t\t\tWidget.prototype.widgetClasses[module.name || module.baseClass] = subClass;\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWidget.prototype.execute = function() {\n\tthis.makeChildWidgets();\n};\n\n/*\nSet the value of a context variable\nname: name of the variable\nvalue: value of the variable\nparams: array of {name:, default:} for each parameter\nisMacroDefinition: true if the variable is set via a \\define macro pragma (and hence should have variable substitution performed)\n*/\nWidget.prototype.setVariable = function(name,value,params,isMacroDefinition) {\n\tthis.variables[name] = {value: value, params: params, isMacroDefinition: !!isMacroDefinition};\n};\n\n/*\nGet the prevailing value of a context variable\nname: name of variable\noptions: see below\nOptions include\nparams: array of {name:, value:} for each parameter\ndefaultValue: default value if the variable is not defined\n\nReturns an object with the following fields:\n\nparams: array of {name:,value:} of parameters passed to wikitext variables\ntext: text of variable, with parameters properly substituted\n*/\nWidget.prototype.getVariableInfo = function(name,options) {\n\toptions = options || {};\n\tvar actualParams = options.params || [],\n\t\tparentWidget = this.parentWidget;\n\t// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)\n\tif(parentWidget && name in parentWidget.variables) {\n\t\tvar variable = parentWidget.variables[name],\n\t\t\toriginalValue = variable.value,\n\t\t\tvalue = originalValue,\n\t\t\tparams = this.resolveVariableParameters(variable.params,actualParams);\n\t\t// Substitute any parameters specified in the definition\n\t\t$tw.utils.each(params,function(param) {\n\t\t\tvalue = $tw.utils.replaceString(value,new RegExp(\"\\\\$\" + $tw.utils.escapeRegExp(param.name) + \"\\\\$\",\"mg\"),param.value);\n\t\t});\n\t\t// Only substitute variable references if this variable was defined with the \\define pragma\n\t\tif(variable.isMacroDefinition) {\n\t\t\tvalue = this.substituteVariableReferences(value);\t\t\t\n\t\t}\n\t\treturn {\n\t\t\ttext: value,\n\t\t\tparams: params,\n\t\t\tsrcVariable: variable,\n\t\t\tisCacheable: originalValue === value\n\t\t};\n\t}\n\t// If the variable doesn't exist in the parent widget then look for a macro module\n\treturn {\n\t\ttext: this.evaluateMacroModule(name,actualParams,options.defaultValue)\n\t};\n};\n\n/*\nSimplified version of getVariableInfo() that just returns the text\n*/\nWidget.prototype.getVariable = function(name,options) {\n\treturn this.getVariableInfo(name,options).text;\n};\n\nWidget.prototype.resolveVariableParameters = function(formalParams,actualParams) {\n\tformalParams = formalParams || [];\n\tactualParams = actualParams || [];\n\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\tparamInfo, paramValue,\n\t\tresults = [];\n\t// Step through each of the parameters in the macro definition\n\tfor(var p=0; p<formalParams.length; p++) {\n\t\t// Check if we've got a macro call parameter with the same name\n\t\tparamInfo = formalParams[p];\n\t\tparamValue = undefined;\n\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t}\n\t\t}\n\t\t// If not, use the next available anonymous macro call parameter\n\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\tnextAnonParameter++;\n\t\t}\n\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t}\n\t\t// If we've still not got a value, use the default, if any\n\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t// Store the parameter name and value\n\t\tresults.push({name: paramInfo.name, value: paramValue});\n\t}\n\treturn results;\n};\n\nWidget.prototype.substituteVariableReferences = function(text) {\n\tvar self = this;\n\treturn (text || \"\").replace(/\\$\\(([^\\)\\$]+)\\)\\$/g,function(match,p1,offset,string) {\n\t\treturn self.getVariable(p1,{defaultValue: \"\"});\n\t});\n};\n\nWidget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue) {\n\tif($tw.utils.hop($tw.macros,name)) {\n\t\tvar macro = $tw.macros[name],\n\t\t\targs = [];\n\t\tif(macro.params.length > 0) {\n\t\t\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\t\t\tparamInfo, paramValue;\n\t\t\t// Step through each of the parameters in the macro definition\n\t\t\tfor(var p=0; p<macro.params.length; p++) {\n\t\t\t\t// Check if we've got a macro call parameter with the same name\n\t\t\t\tparamInfo = macro.params[p];\n\t\t\t\tparamValue = undefined;\n\t\t\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If not, use the next available anonymous macro call parameter\n\t\t\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\t\t\tnextAnonParameter++;\n\t\t\t\t}\n\t\t\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t\t\t}\n\t\t\t\t// If we've still not got a value, use the default, if any\n\t\t\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t\t\t// Save the parameter\n\t\t\t\targs.push(paramValue);\n\t\t\t}\n\t\t}\n\t\telse for(var i=0; i<actualParams.length; ++i) {\n\t\t\targs.push(actualParams[i].value);\n\t\t}\n\t\treturn (macro.run.apply(this,args) || \"\").toString();\n\t} else {\n\t\treturn defaultValue;\n\t}\n};\n\n/*\nCheck whether a given context variable value exists in the parent chain\n*/\nWidget.prototype.hasVariable = function(name,value) {\n\tvar node = this;\n\twhile(node) {\n\t\tif($tw.utils.hop(node.variables,name) && node.variables[name].value === value) {\n\t\t\treturn true;\n\t\t}\n\t\tnode = node.parentWidget;\n\t}\n\treturn false;\n};\n\n/*\nConstruct a qualifying string based on a hash of concatenating the values of a given variable in the parent chain\n*/\nWidget.prototype.getStateQualifier = function(name) {\n\tthis.qualifiers = this.qualifiers || Object.create(null);\n\tname = name || \"transclusion\";\n\tif(this.qualifiers[name]) {\n\t\treturn this.qualifiers[name];\n\t} else {\n\t\tvar output = [],\n\t\t\tnode = this;\n\t\twhile(node && node.parentWidget) {\n\t\t\tif($tw.utils.hop(node.parentWidget.variables,name)) {\n\t\t\t\toutput.push(node.getVariable(name));\n\t\t\t}\n\t\t\tnode = node.parentWidget;\n\t\t}\n\t\tvar value = $tw.utils.hashString(output.join(\"\"));\n\t\tthis.qualifiers[name] = value;\n\t\treturn value;\n\t}\n};\n\n/*\nCompute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed\n*/\nWidget.prototype.computeAttributes = function() {\n\tvar changedAttributes = {},\n\t\tself = this,\n\t\tvalue;\n\t$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {\n\t\tif(attribute.type === \"filtered\") {\n\t\t\tvalue = self.wiki.filterTiddlers(attribute.filter,self)[0] || \"\";\n\t\t} else if(attribute.type === \"indirect\") {\n\t\t\tvalue = self.wiki.getTextReference(attribute.textReference,\"\",self.getVariable(\"currentTiddler\"));\n\t\t} else if(attribute.type === \"macro\") {\n\t\t\tvalue = self.getVariable(attribute.value.name,{params: attribute.value.params});\n\t\t} else { // String attribute\n\t\t\tvalue = attribute.value;\n\t\t}\n\t\t// Check whether the attribute has changed\n\t\tif(self.attributes[name] !== value) {\n\t\t\tself.attributes[name] = value;\n\t\t\tchangedAttributes[name] = true;\n\t\t}\n\t});\n\treturn changedAttributes;\n};\n\n/*\nCheck for the presence of an attribute\n*/\nWidget.prototype.hasAttribute = function(name) {\n\treturn $tw.utils.hop(this.attributes,name);\n};\n\n/*\nGet the value of an attribute\n*/\nWidget.prototype.getAttribute = function(name,defaultText) {\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\treturn this.attributes[name];\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nAssign the computed attributes of the widget to a domNode\noptions include:\nexcludeEventAttributes: ignores attributes whose name begins with \"on\"\n*/\nWidget.prototype.assignAttributes = function(domNode,options) {\n\toptions = options || {};\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(v,a) {\n\t\t// Check exclusions\n\t\tif(options.excludeEventAttributes && a.substr(0,2) === \"on\") {\n\t\t\tv = undefined;\n\t\t}\n\t\tif(v !== undefined) {\n\t\t\tvar b = a.split(\":\");\n\t\t\t// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)\n\t\t\ttry {\n\t\t\t\tif (b.length == 2 && b[0] == \"xlink\"){\n\t\t\t\t\tdomNode.setAttributeNS(\"http://www.w3.org/1999/xlink\",b[1],v);\n\t\t\t\t} else {\n\t\t\t\t\tdomNode.setAttributeNS(null,a,v);\n\t\t\t\t}\n\t\t\t} catch(e) {\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nMake child widgets correspondng to specified parseTreeNodes\n*/\nWidget.prototype.makeChildWidgets = function(parseTreeNodes) {\n\tthis.children = [];\n\tvar self = this;\n\t$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {\n\t\tself.children.push(self.makeChildWidget(childNode));\n\t});\n};\n\n/*\nConstruct the widget object for a parse tree node\n*/\nWidget.prototype.makeChildWidget = function(parseTreeNode) {\n\tvar WidgetClass = this.widgetClasses[parseTreeNode.type];\n\tif(!WidgetClass) {\n\t\tWidgetClass = this.widgetClasses.text;\n\t\tparseTreeNode = {type: \"text\", text: \"Undefined widget '\" + parseTreeNode.type + \"'\"};\n\t}\n\treturn new WidgetClass(parseTreeNode,{\n\t\twiki: this.wiki,\n\t\tvariables: {},\n\t\tparentWidget: this,\n\t\tdocument: this.document\n\t});\n};\n\n/*\nGet the next sibling of this widget\n*/\nWidget.prototype.nextSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index < this.parentWidget.children.length-1) {\n\t\t\treturn this.parentWidget.children[index+1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the previous sibling of this widget\n*/\nWidget.prototype.previousSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index > 0) {\n\t\t\treturn this.parentWidget.children[index-1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRender the children of this widget into the DOM\n*/\nWidget.prototype.renderChildren = function(parent,nextSibling) {\n\tvar children = this.children;\n\tfor(var i = 0; i < children.length; i++) {\n\t\tchildren[i].render(parent,nextSibling);\n\t};\n};\n\n/*\nAdd a list of event listeners from an array [{type:,handler:},...]\n*/\nWidget.prototype.addEventListeners = function(listeners) {\n\tvar self = this;\n\t$tw.utils.each(listeners,function(listenerInfo) {\n\t\tself.addEventListener(listenerInfo.type,listenerInfo.handler);\n\t});\n};\n\n/*\nAdd an event listener\n*/\nWidget.prototype.addEventListener = function(type,handler) {\n\tvar self = this;\n\tif(typeof handler === \"string\") { // The handler is a method name on this widget\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn self[handler].call(self,event);\n\t\t};\n\t} else { // The handler is a function\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn handler.call(self,event);\n\t\t};\n\t}\n};\n\n/*\nDispatch an event to a widget. If the widget doesn't handle the event then it is also dispatched to the parent widget\n*/\nWidget.prototype.dispatchEvent = function(event) {\n\tevent.widget = event.widget || this;\n\t// Dispatch the event if this widget handles it\n\tvar listener = this.eventListeners[event.type];\n\tif(listener) {\n\t\t// Don't propagate the event if the listener returned false\n\t\tif(!listener(event)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Dispatch the event to the parent widget\n\tif(this.parentWidget) {\n\t\treturn this.parentWidget.dispatchEvent(event);\n\t}\n\treturn true;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nRebuild a previously rendered widget\n*/\nWidget.prototype.refreshSelf = function() {\n\tvar nextSibling = this.findNextSiblingDomNode();\n\tthis.removeChildDomNodes();\n\tthis.render(this.parentDomNode,nextSibling);\n};\n\n/*\nRefresh all the children of a widget\n*/\nWidget.prototype.refreshChildren = function(changedTiddlers) {\n\tvar children = this.children,\n\t\trefreshed = false;\n\tfor (var i = 0; i < children.length; i++) {\n\t\trefreshed = children[i].refresh(changedTiddlers) || refreshed;\n\t}\n\treturn refreshed;\n};\n\n/*\nFind the next sibling in the DOM to this widget. This is done by scanning the widget tree through all next siblings and their descendents that share the same parent DOM node\n*/\nWidget.prototype.findNextSiblingDomNode = function(startIndex) {\n\t// Refer to this widget by its index within its parents children\n\tvar parent = this.parentWidget,\n\t\tindex = startIndex !== undefined ? startIndex : parent.children.indexOf(this);\nif(index === -1) {\n\tthrow \"node not found in parents children\";\n}\n\t// Look for a DOM node in the later siblings\n\twhile(++index < parent.children.length) {\n\t\tvar domNode = parent.children[index].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\t// Go back and look for later siblings of our parent if it has the same parent dom node\n\tvar grandParent = parent.parentWidget;\n\tif(grandParent && parent.parentDomNode === this.parentDomNode) {\n\t\tindex = grandParent.children.indexOf(parent);\n\t\tif(index !== -1) {\n\t\t\treturn parent.findNextSiblingDomNode(index);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nFind the first DOM node generated by a widget or its children\n*/\nWidget.prototype.findFirstDomNode = function() {\n\t// Return the first dom node of this widget, if we've got one\n\tif(this.domNodes.length > 0) {\n\t\treturn this.domNodes[0];\n\t}\n\t// Otherwise, recursively call our children\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar domNode = this.children[t].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRemove any DOM nodes created by this widget or its children\n*/\nWidget.prototype.removeChildDomNodes = function() {\n\t// If this widget has directly created DOM nodes, delete them and exit. This assumes that any child widgets are contained within the created DOM nodes, which would normally be the case\n\tif(this.domNodes.length > 0) {\n\t\t$tw.utils.each(this.domNodes,function(domNode) {\n\t\t\tdomNode.parentNode.removeChild(domNode);\n\t\t});\n\t\tthis.domNodes = [];\n\t} else {\n\t\t// Otherwise, ask the child widgets to delete their DOM nodes\n\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\tchildWidget.removeChildDomNodes();\n\t\t});\n\t}\n};\n\n/*\nInvoke the action widgets that are descendents of the current widget.\n*/\nWidget.prototype.invokeActions = function(triggeringWidget,event) {\n\tvar handled = false;\n\t// For each child widget\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar child = this.children[t];\n\t\t// Invoke the child if it is an action widget\n\t\tif(child.invokeAction) {\n\t\t\tchild.refreshSelf();\n\t\t\tif(child.invokeAction(triggeringWidget,event)) {\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t}\n\t\t// Propagate through through the child if it permits it\n\t\tif(child.allowActionPropagation() && child.invokeActions(triggeringWidget,event)) {\n\t\t\thandled = true;\n\t\t}\n\t}\n\treturn handled;\n};\n\n/*\nInvoke the action widgets defined in a string\n*/\nWidget.prototype.invokeActionString = function(actions,triggeringWidget,event,variables) {\n\tactions = actions || \"\";\n\tvar parser = this.wiki.parseText(\"text/vnd.tiddlywiki\",actions,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document\n\t\t}),\n\t\twidgetNode = this.wiki.makeWidget(parser,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document,\n\t\t\tvariables: variables\n\t\t});\n\tvar container = this.document.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn widgetNode.invokeActions(this,event);\n};\n\n/*\nExecute action tiddlers by tag\n*/\nWidget.prototype.invokeActionsByTag = function(tag,event,variables) {\n\tvar self = this;\n\t$tw.utils.each(self.wiki.filterTiddlers(\"[all[shadows+tiddlers]tag[\" + tag + \"]!has[draft.of]]\"),function(title) {\n\t\tself.invokeActionString(self.wiki.getTiddlerText(title),self,event,variables);\n\t});\n};\n\nWidget.prototype.allowActionPropagation = function() {\n\treturn true;\n};\n\nexports.widget = Widget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/wikify.js": {
"title": "$:/core/modules/widgets/wikify.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/wikify.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to wikify text into a variable\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar WikifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nWikifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nWikifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWikifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.wikifyName = this.getAttribute(\"name\");\n\tthis.wikifyText = this.getAttribute(\"text\");\n\tthis.wikifyType = this.getAttribute(\"type\");\n\tthis.wikifyMode = this.getAttribute(\"mode\",\"block\");\n\tthis.wikifyOutput = this.getAttribute(\"output\",\"text\");\n\t// Create the parse tree\n\tthis.wikifyParser = this.wiki.parseText(this.wikifyType,this.wikifyText,{\n\t\t\tparseAsInline: this.wikifyMode === \"inline\"\n\t\t});\n\t// Create the widget tree \n\tthis.wikifyWidgetNode = this.wiki.makeWidget(this.wikifyParser,{\n\t\t\tdocument: $tw.fakeDocument,\n\t\t\tparentWidget: this\n\t\t});\n\t// Render the widget tree to the container\n\tthis.wikifyContainer = $tw.fakeDocument.createElement(\"div\");\n\tthis.wikifyWidgetNode.render(this.wikifyContainer,null);\n\tthis.wikifyResult = this.getResult();\n\t// Set context variable\n\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nReturn the result string\n*/\nWikifyWidget.prototype.getResult = function() {\n\tvar result;\n\tswitch(this.wikifyOutput) {\n\t\tcase \"text\":\n\t\t\tresult = this.wikifyContainer.textContent;\n\t\t\tbreak;\n\t\tcase \"formattedtext\":\n\t\t\tresult = this.wikifyContainer.formattedTextContent;\n\t\t\tbreak;\n\t\tcase \"html\":\n\t\t\tresult = this.wikifyContainer.innerHTML;\n\t\t\tbreak;\n\t\tcase \"parsetree\":\n\t\t\tresult = JSON.stringify(this.wikifyParser.tree,0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t\tcase \"widgettree\":\n\t\t\tresult = JSON.stringify(this.getWidgetTree(),0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t}\n\treturn result;\n};\n\n/*\nReturn a string of the widget tree\n*/\nWikifyWidget.prototype.getWidgetTree = function() {\n\tvar copyNode = function(widgetNode,resultNode) {\n\t\t\tvar type = widgetNode.parseTreeNode.type;\n\t\t\tresultNode.type = type;\n\t\t\tswitch(type) {\n\t\t\t\tcase \"element\":\n\t\t\t\t\tresultNode.tag = widgetNode.parseTreeNode.tag;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"text\":\n\t\t\t\t\tresultNode.text = widgetNode.parseTreeNode.text;\n\t\t\t\t\tbreak;\t\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.attributes || {}).length > 0) {\n\t\t\t\tresultNode.attributes = {};\n\t\t\t\t$tw.utils.each(widgetNode.attributes,function(attr,attrName) {\n\t\t\t\t\tresultNode.attributes[attrName] = widgetNode.getAttribute(attrName);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.children || {}).length > 0) {\n\t\t\t\tresultNode.children = [];\n\t\t\t\t$tw.utils.each(widgetNode.children,function(widgetChildNode) {\n\t\t\t\t\tvar node = {};\n\t\t\t\t\tresultNode.children.push(node);\n\t\t\t\t\tcopyNode(widgetChildNode,node);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tresults = {};\n\tcopyNode(this.wikifyWidgetNode,results);\n\treturn results;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWikifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh ourselves entirely if any of our attributes have changed\n\tif(changedAttributes.name || changedAttributes.text || changedAttributes.type || changedAttributes.mode || changedAttributes.output) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\t// Refresh the widget tree\n\t\tif(this.wikifyWidgetNode.refresh(changedTiddlers)) {\n\t\t\t// Check if there was any change\n\t\t\tvar result = this.getResult();\n\t\t\tif(result !== this.wikifyResult) {\n\t\t\t\t// If so, save the change\n\t\t\t\tthis.wikifyResult = result;\n\t\t\t\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t\t\t\t// Refresh each of our child widgets\n\t\t\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\t\t\tchildWidget.refreshSelf();\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t// Just refresh the children\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.wikify = WikifyWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/wiki-bulkops.js": {
"title": "$:/core/modules/wiki-bulkops.js",
"text": "/*\\\ntitle: $:/core/modules/wiki-bulkops.js\ntype: application/javascript\nmodule-type: wikimethod\n\nBulk tiddler operations such as rename.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRename a tiddler, and relink any tags or lists that reference it.\n*/\nfunction renameTiddler(fromTitle,toTitle,options) {\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\t// Rename the tiddler itself\n\t\tvar oldTiddler = this.getTiddler(fromTitle),\n\t\t\tnewTiddler = new $tw.Tiddler(oldTiddler,{title: toTitle},this.getModificationFields());\n\t\tnewTiddler = $tw.hooks.invokeHook(\"th-renaming-tiddler\",newTiddler,oldTiddler);\n\t\tthis.addTiddler(newTiddler);\n\t\tthis.deleteTiddler(fromTitle);\n\t\t// Rename any tags or lists that reference it\n\t\tthis.relinkTiddler(fromTitle,toTitle,options)\n\t}\n}\n\n/*\nRelink any tags or lists that reference a given tiddler\n*/\nfunction relinkTiddler(fromTitle,toTitle,options) {\n\tvar self = this;\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\tthis.each(function(tiddler,title) {\n\t\t\tvar type = tiddler.fields.type || \"\";\n\t\t\t// Don't touch plugins or JavaScript modules\n\t\t\tif(!tiddler.fields[\"plugin-type\"] && type !== \"application/javascript\") {\n\t\t\t\tvar tags = tiddler.fields.tags ? tiddler.fields.tags.slice(0) : undefined,\n\t\t\t\t\tlist = tiddler.fields.list ? tiddler.fields.list.slice(0) : undefined,\n\t\t\t\t\tisModified = false;\n\t\t\t\tif(!options.dontRenameInTags) {\n\t\t\t\t\t// Rename tags\n\t\t\t\t\t$tw.utils.each(tags,function (title,index) {\n\t\t\t\t\t\tif(title === fromTitle) {\nconsole.log(\"Renaming tag '\" + tags[index] + \"' to '\" + toTitle + \"' of tiddler '\" + tiddler.fields.title + \"'\");\n\t\t\t\t\t\t\ttags[index] = toTitle;\n\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(!options.dontRenameInLists) {\n\t\t\t\t\t// Rename lists\n\t\t\t\t\t$tw.utils.each(list,function (title,index) {\n\t\t\t\t\t\tif(title === fromTitle) {\nconsole.log(\"Renaming list item '\" + list[index] + \"' to '\" + toTitle + \"' of tiddler '\" + tiddler.fields.title + \"'\");\n\t\t\t\t\t\t\tlist[index] = toTitle;\n\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(isModified) {\n\t\t\t\t\tvar newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields())\n\t\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-relinking-tiddler\",newTiddler,tiddler);\n\t\t\t\t\tself.addTiddler(newTiddler);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\nexports.renameTiddler = renameTiddler;\nexports.relinkTiddler = relinkTiddler;\n\n})();\n",
"type": "application/javascript",
"module-type": "wikimethod"
},
"$:/core/modules/wiki.js": {
"title": "$:/core/modules/wiki.js",
"text": "/*\\\ntitle: $:/core/modules/wiki.js\ntype: application/javascript\nmodule-type: wikimethod\n\nExtension methods for the $tw.Wiki object\n\nAdds the following properties to the wiki object:\n\n* `eventListeners` is a hashmap by type of arrays of listener functions\n* `changedTiddlers` is a hashmap describing changes to named tiddlers since wiki change events were last dispatched. Each entry is a hashmap containing two fields:\n\tmodified: true/false\n\tdeleted: true/false\n* `changeCount` is a hashmap by tiddler title containing a numerical index that starts at zero and is incremented each time a tiddler is created changed or deleted\n* `caches` is a hashmap by tiddler title containing a further hashmap of named cache objects. Caches are automatically cleared when a tiddler is modified or deleted\n* `globalCache` is a hashmap by cache name of cache objects that are cleared whenever any tiddler change occurs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar USER_NAME_TITLE = \"$:/status/UserName\",\n\tTIMESTAMP_DISABLE_TITLE = \"$:/config/TimestampDisable\";\n\n/*\nAdd available indexers to this wiki\n*/\nexports.addIndexersToWiki = function() {\n\tvar self = this;\n\t$tw.utils.each($tw.modules.applyMethods(\"indexer\"),function(Indexer,name) {\n\t\tself.addIndexer(new Indexer(self),name);\n\t});\n};\n\n/*\nGet the value of a text reference. Text references can have any of these forms:\n\t<tiddlertitle>\n\t<tiddlertitle>!!<fieldname>\n\t!!<fieldname> - specifies a field of the current tiddlers\n\t<tiddlertitle>##<index>\n*/\nexports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tif(tr.field) {\n\t\tvar tiddler = this.getTiddler(title);\n\t\tif(tr.field === \"title\") { // Special case so we can return the title of a non-existent tiddler\n\t\t\treturn title;\n\t\t} else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\treturn tiddler.getFieldString(tr.field);\n\t\t} else {\n\t\t\treturn defaultText;\n\t\t}\n\t} else if(tr.index) {\n\t\treturn this.extractTiddlerDataItem(title,tr.index,defaultText);\n\t} else {\n\t\treturn this.getTiddlerText(title,defaultText);\n\t}\n};\n\nexports.setTextReference = function(textRef,value,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tthis.setText(title,tr.field,tr.index,value);\n};\n\nexports.setText = function(title,field,index,value,options) {\n\toptions = options || {};\n\tvar creationFields = options.suppressTimestamp ? {} : this.getCreationFields(),\n\t\tmodificationFields = options.suppressTimestamp ? {} : this.getModificationFields();\n\t// Check if it is a reference to a tiddler field\n\tif(index) {\n\t\tvar data = this.getTiddlerData(title,Object.create(null));\n\t\tif(value !== undefined) {\n\t\t\tdata[index] = value;\n\t\t} else {\n\t\t\tdelete data[index];\n\t\t}\n\t\tthis.setTiddlerData(title,data,modificationFields);\n\t} else {\n\t\tvar tiddler = this.getTiddler(title),\n\t\t\tfields = {title: title};\n\t\tfields[field || \"text\"] = value;\n\t\tthis.addTiddler(new $tw.Tiddler(creationFields,tiddler,fields,modificationFields));\n\t}\n};\n\nexports.deleteTextReference = function(textRef,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle,tiddler,fields;\n\t// Check if it is a reference to a tiddler\n\tif(tr.title && !tr.field) {\n\t\tthis.deleteTiddler(tr.title);\n\t// Else check for a field reference\n\t} else if(tr.field) {\n\t\ttitle = tr.title || currTiddlerTitle;\n\t\ttiddler = this.getTiddler(title);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\tfields = Object.create(null);\n\t\t\tfields[tr.field] = undefined;\n\t\t\tthis.addTiddler(new $tw.Tiddler(tiddler,fields,this.getModificationFields()));\n\t\t}\n\t}\n};\n\nexports.addEventListener = function(type,listener) {\n\tthis.eventListeners = this.eventListeners || {};\n\tthis.eventListeners[type] = this.eventListeners[type] || [];\n\tthis.eventListeners[type].push(listener);\t\n};\n\nexports.removeEventListener = function(type,listener) {\n\tvar listeners = this.eventListeners[type];\n\tif(listeners) {\n\t\tvar p = listeners.indexOf(listener);\n\t\tif(p !== -1) {\n\t\t\tlisteners.splice(p,1);\n\t\t}\n\t}\n};\n\nexports.dispatchEvent = function(type /*, args */) {\n\tvar args = Array.prototype.slice.call(arguments,1),\n\t\tlisteners = this.eventListeners[type];\n\tif(listeners) {\n\t\tfor(var p=0; p<listeners.length; p++) {\n\t\t\tvar listener = listeners[p];\n\t\t\tlistener.apply(listener,args);\n\t\t}\n\t}\n};\n\n/*\nCauses a tiddler to be marked as changed, incrementing the change count, and triggers event handlers.\nThis method should be called after the changes it describes have been made to the wiki.tiddlers[] array.\n\ttitle: Title of tiddler\n\tisDeleted: defaults to false (meaning the tiddler has been created or modified),\n\t\ttrue if the tiddler has been deleted\n*/\nexports.enqueueTiddlerEvent = function(title,isDeleted) {\n\t// Record the touch in the list of changed tiddlers\n\tthis.changedTiddlers = this.changedTiddlers || Object.create(null);\n\tthis.changedTiddlers[title] = this.changedTiddlers[title] || Object.create(null);\n\tthis.changedTiddlers[title][isDeleted ? \"deleted\" : \"modified\"] = true;\n\t// Increment the change count\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\tthis.changeCount[title]++;\n\t} else {\n\t\tthis.changeCount[title] = 1;\n\t}\n\t// Trigger events\n\tthis.eventListeners = this.eventListeners || {};\n\tif(!this.eventsTriggered) {\n\t\tvar self = this;\n\t\t$tw.utils.nextTick(function() {\n\t\t\tvar changes = self.changedTiddlers;\n\t\t\tself.changedTiddlers = Object.create(null);\n\t\t\tself.eventsTriggered = false;\n\t\t\tif($tw.utils.count(changes) > 0) {\n\t\t\t\tself.dispatchEvent(\"change\",changes);\n\t\t\t}\n\t\t});\n\t\tthis.eventsTriggered = true;\n\t}\n};\n\nexports.getSizeOfTiddlerEventQueue = function() {\n\treturn $tw.utils.count(this.changedTiddlers);\n};\n\nexports.clearTiddlerEventQueue = function() {\n\tthis.changedTiddlers = Object.create(null);\n\tthis.changeCount = Object.create(null);\n};\n\nexports.getChangeCount = function(title) {\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\treturn this.changeCount[title];\n\t} else {\n\t\treturn 0;\n\t}\n};\n\n/*\nGenerate an unused title from the specified base\n*/\nexports.generateNewTitle = function(baseTitle,options) {\n\toptions = options || {};\n\tvar c = 0,\n\t\ttitle = baseTitle;\n\twhile(this.tiddlerExists(title) || this.isShadowTiddler(title) || this.findDraft(title)) {\n\t\ttitle = baseTitle + \n\t\t\t(options.prefix || \" \") + \n\t\t\t(++c);\n\t}\n\treturn title;\n};\n\nexports.isSystemTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/\") === 0;\n};\n\nexports.isTemporaryTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/temp/\") === 0;\n};\n\nexports.isImageTiddler = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\t\t\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/vnd.tiddlywiki\"];\n\t\treturn !!contentTypeInfo && contentTypeInfo.flags.indexOf(\"image\") !== -1;\n\t} else {\n\t\treturn null;\n\t}\n};\n\nexports.isBinaryTiddler = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\t\t\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/vnd.tiddlywiki\"];\n\t\treturn !!contentTypeInfo && contentTypeInfo.encoding === \"base64\";\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLike addTiddler() except it will silently reject any plugin tiddlers that are older than the currently loaded version. Returns true if the tiddler was imported\n*/\nexports.importTiddler = function(tiddler) {\n\tvar existingTiddler = this.getTiddler(tiddler.fields.title);\n\t// Check if we're dealing with a plugin\n\tif(tiddler && tiddler.hasField(\"plugin-type\") && tiddler.hasField(\"version\") && existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t// Reject the incoming plugin if it is older\n\t\tif(!$tw.utils.checkVersions(tiddler.fields.version,existingTiddler.fields.version)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Fall through to adding the tiddler\n\tthis.addTiddler(tiddler);\n\treturn true;\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is created\n*/\nexports.getCreationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = {\n\t\t\t\tcreated: new Date()\n\t\t\t},\n\t\t\tcreator = this.getTiddlerText(USER_NAME_TITLE);\n\t\tif(creator) {\n\t\t\tfields.creator = creator;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is modified\n*/\nexports.getModificationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = Object.create(null),\n\t\t\tmodifier = this.getTiddlerText(USER_NAME_TITLE);\n\t\tfields.modified = new Date();\n\t\tif(modifier) {\n\t\t\tfields.modifier = modifier;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a sorted array of tiddler titles. Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.getTiddlers = function(options) {\n\toptions = options || Object.create(null);\n\tvar self = this,\n\t\tsortField = options.sortField || \"title\",\n\t\ttiddlers = [], t, titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tif(options.includeSystem || !self.isSystemTiddler(title)) {\n\t\t\tif(!options.excludeTag || !tiddler.hasTag(options.excludeTag)) {\n\t\t\t\ttiddlers.push(tiddler);\n\t\t\t}\n\t\t}\n\t});\n\ttiddlers.sort(function(a,b) {\n\t\tvar aa = a.fields[sortField].toLowerCase() || \"\",\n\t\t\tbb = b.fields[sortField].toLowerCase() || \"\";\n\t\tif(aa < bb) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(aa > bb) {\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\tfor(t=0; t<tiddlers.length; t++) {\n\t\ttitles.push(tiddlers[t].fields.title);\n\t}\n\treturn titles;\n};\n\nexports.countTiddlers = function(excludeTag) {\n\tvar tiddlers = this.getTiddlers({excludeTag: excludeTag});\n\treturn $tw.utils.count(tiddlers);\n};\n\n/*\nReturns a function iterator(callback) that iterates through the specified titles, and invokes the callback with callback(tiddler,title)\n*/\nexports.makeTiddlerIterator = function(titles) {\n\tvar self = this;\n\tif(!$tw.utils.isArray(titles)) {\n\t\ttitles = Object.keys(titles);\n\t} else {\n\t\ttitles = titles.slice(0);\n\t}\n\treturn function(callback) {\n\t\ttitles.forEach(function(title) {\n\t\t\tcallback(self.getTiddler(title),title);\n\t\t});\n\t};\n};\n\n/*\nSort an array of tiddler titles by a specified field\n\ttitles: array of titles (sorted in place)\n\tsortField: name of field to sort by\n\tisDescending: true if the sort should be descending\n\tisCaseSensitive: true if the sort should consider upper and lower case letters to be different\n*/\nexports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {\n\tvar self = this;\n\ttitles.sort(function(a,b) {\n\t\tvar x,y,\n\t\t\tcompareNumbers = function(x,y) {\n\t\t\t\tvar result = \n\t\t\t\t\tisNaN(x) && !isNaN(y) ? (isDescending ? -1 : 1) :\n\t\t\t\t\t!isNaN(x) && isNaN(y) ? (isDescending ? 1 : -1) :\n\t\t\t\t\t\t\t\t\t\t\t(isDescending ? y - x : x - y);\n\t\t\t\treturn result;\n\t\t\t};\n\t\tif(sortField !== \"title\") {\n\t\t\tvar tiddlerA = self.getTiddler(a),\n\t\t\t\ttiddlerB = self.getTiddler(b);\n\t\t\tif(tiddlerA) {\n\t\t\t\ta = tiddlerA.fields[sortField] || \"\";\n\t\t\t} else {\n\t\t\t\ta = \"\";\n\t\t\t}\n\t\t\tif(tiddlerB) {\n\t\t\t\tb = tiddlerB.fields[sortField] || \"\";\n\t\t\t} else {\n\t\t\t\tb = \"\";\n\t\t\t}\n\t\t}\n\t\tx = Number(a);\n\t\ty = Number(b);\n\t\tif(isNumeric && (!isNaN(x) || !isNaN(y))) {\n\t\t\treturn compareNumbers(x,y);\n\t\t} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {\n\t\t\treturn isDescending ? b - a : a - b;\n\t\t} else if(isAlphaNumeric) {\n\t\t\treturn isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: \"base\"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: \"base\"});\n\t\t} else {\n\t\t\ta = String(a);\n\t\t\tb = String(b);\n\t\t\tif(!isCaseSensitive) {\n\t\t\t\ta = a.toLowerCase();\n\t\t\t\tb = b.toLowerCase();\n\t\t\t}\n\t\t\treturn isDescending ? b.localeCompare(a) : a.localeCompare(b);\n\t\t}\n\t});\n};\n\n/*\nFor every tiddler invoke a callback(title,tiddler) with `this` set to the wiki object. Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.forEachTiddler = function(/* [options,]callback */) {\n\tvar arg = 0,\n\t\toptions = arguments.length >= 2 ? arguments[arg++] : {},\n\t\tcallback = arguments[arg++],\n\t\ttitles = this.getTiddlers(options),\n\t\tt, tiddler;\n\tfor(t=0; t<titles.length; t++) {\n\t\ttiddler = this.getTiddler(titles[t]);\n\t\tif(tiddler) {\n\t\t\tcallback.call(this,tiddler.fields.title,tiddler);\n\t\t}\n\t}\n};\n\n/*\nReturn an array of tiddler titles that are directly linked within the given parse tree\n */\nexports.extractLinks = function(parseTreeRoot) {\n\t// Count up the links\n\tvar links = [],\n\t\tcheckParseTree = function(parseTree) {\n\t\t\tfor(var t=0; t<parseTree.length; t++) {\n\t\t\t\tvar parseTreeNode = parseTree[t];\n\t\t\t\tif(parseTreeNode.type === \"link\" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === \"string\") {\n\t\t\t\t\tvar value = parseTreeNode.attributes.to.value;\n\t\t\t\t\tif(links.indexOf(value) === -1) {\n\t\t\t\t\t\tlinks.push(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(parseTreeNode.children) {\n\t\t\t\t\tcheckParseTree(parseTreeNode.children);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\tcheckParseTree(parseTreeRoot);\n\treturn links;\n};\n\n/*\nReturn an array of tiddler titles that are directly linked from the specified tiddler\n*/\nexports.getTiddlerLinks = function(title) {\n\tvar self = this;\n\t// We'll cache the links so they only get computed if the tiddler changes\n\treturn this.getCacheForTiddler(title,\"links\",function() {\n\t\t// Parse the tiddler\n\t\tvar parser = self.parseTiddler(title);\n\t\tif(parser) {\n\t\t\treturn self.extractLinks(parser.tree);\n\t\t}\n\t\treturn [];\n\t});\n};\n\n/*\nReturn an array of tiddler titles that link to the specified tiddler\n*/\nexports.getTiddlerBacklinks = function(targetTitle) {\n\tvar self = this,\n\t\tbacklinksIndexer = this.getIndexer(\"BacklinksIndexer\"),\n\t\tbacklinks = backlinksIndexer && backlinksIndexer.lookup(targetTitle);\n\n\tif(!backlinks) {\n\t\tbacklinks = [];\n\t\tthis.forEachTiddler(function(title,tiddler) {\n\t\t\tvar links = self.getTiddlerLinks(title);\n\t\t\tif(links.indexOf(targetTitle) !== -1) {\n\t\t\t\tbacklinks.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn backlinks;\n};\n\n/*\nReturn a hashmap of tiddler titles that are referenced but not defined. Each value is the number of times the missing tiddler is referenced\n*/\nexports.getMissingTitles = function() {\n\tvar self = this,\n\t\tmissing = [];\n// We should cache the missing tiddler list, even if we recreate it every time any tiddler is modified\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tif((!self.tiddlerExists(link) && !self.isShadowTiddler(link)) && missing.indexOf(link) === -1) {\n\t\t\t\tmissing.push(link);\n\t\t\t}\n\t\t});\n\t});\n\treturn missing;\n};\n\nexports.getOrphanTitles = function() {\n\tvar self = this,\n\t\torphans = this.getTiddlers();\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tvar p = orphans.indexOf(link);\n\t\t\tif(p !== -1) {\n\t\t\t\torphans.splice(p,1);\n\t\t\t}\n\t\t});\n\t});\n\treturn orphans; // Todo\n};\n\n/*\nRetrieves a list of the tiddler titles that are tagged with a given tag\n*/\nexports.getTiddlersWithTag = function(tag) {\n\t// Try to use the indexer\n\tvar self = this,\n\t\ttagIndexer = this.getIndexer(\"TagIndexer\"),\n\t\tresults = tagIndexer && tagIndexer.subIndexers[3].lookup(tag);\n\tif(!results) {\n\t\t// If not available, perform a manual scan\n\t\tresults = this.getGlobalCache(\"taglist-\" + tag,function() {\n\t\t\tvar tagmap = self.getTagMap();\n\t\t\treturn self.sortByList(tagmap[tag],tag);\n\t\t});\n\t}\n\treturn results;\n};\n\n/*\nGet a hashmap by tag of arrays of tiddler titles\n*/\nexports.getTagMap = function() {\n\tvar self = this;\n\treturn this.getGlobalCache(\"tagmap\",function() {\n\t\tvar tags = Object.create(null),\n\t\t\tstoreTags = function(tagArray,title) {\n\t\t\t\tif(tagArray) {\n\t\t\t\t\tfor(var index=0; index<tagArray.length; index++) {\n\t\t\t\t\t\tvar tag = tagArray[index];\n\t\t\t\t\t\tif($tw.utils.hop(tags,tag)) {\n\t\t\t\t\t\t\ttags[tag].push(title);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttags[tag] = [title];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\ttitle, tiddler;\n\t\t// Collect up all the tags\n\t\tself.eachShadow(function(tiddler,title) {\n\t\t\tif(!self.tiddlerExists(title)) {\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t\t}\n\t\t});\n\t\tself.each(function(tiddler,title) {\n\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t});\n\t\treturn tags;\n\t});\n};\n\n/*\nLookup a given tiddler and return a list of all the tiddlers that include it in the specified list field\n*/\nexports.findListingsOfTiddler = function(targetTitle,fieldName) {\n\tfieldName = fieldName || \"list\";\n\tvar titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tvar list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);\n\t\tif(list && list.indexOf(targetTitle) !== -1) {\n\t\t\ttitles.push(title);\n\t\t}\n\t});\n\treturn titles;\n};\n\n/*\nSorts an array of tiddler titles according to an ordered list\n*/\nexports.sortByList = function(array,listTitle) {\n\tvar self = this,\n\t\treplacedTitles = Object.create(null);\n\t// Given a title, this function will place it in the correct location\n\t// within titles.\n\tfunction moveItemInList(title) {\n\t\tif(!$tw.utils.hop(replacedTitles, title)) {\n\t\t\treplacedTitles[title] = true;\n\t\t\tvar newPos = -1,\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\tif(tiddler) {\n\t\t\t\tvar beforeTitle = tiddler.fields[\"list-before\"],\n\t\t\t\t\tafterTitle = tiddler.fields[\"list-after\"];\n\t\t\t\tif(beforeTitle === \"\") {\n\t\t\t\t\tnewPos = 0;\n\t\t\t\t} else if(afterTitle === \"\") {\n\t\t\t\t\tnewPos = titles.length;\n\t\t\t\t} else if(beforeTitle) {\n\t\t\t\t\t// if this title is placed relative\n\t\t\t\t\t// to another title, make sure that\n\t\t\t\t\t// title is placed before we place\n\t\t\t\t\t// this one.\n\t\t\t\t\tmoveItemInList(beforeTitle);\n\t\t\t\t\tnewPos = titles.indexOf(beforeTitle);\n\t\t\t\t} else if(afterTitle) {\n\t\t\t\t\t// Same deal\n\t\t\t\t\tmoveItemInList(afterTitle);\n\t\t\t\t\tnewPos = titles.indexOf(afterTitle);\n\t\t\t\t\tif(newPos >= 0) {\n\t\t\t\t\t\t++newPos;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If a new position is specified, let's move it\n\t\t\t\tif (newPos !== -1) {\n\t\t\t\t\t// get its current Pos, and make sure\n\t\t\t\t\t// sure that it's _actually_ in the list\n\t\t\t\t\t// and that it would _actually_ move\n\t\t\t\t\t// (#4275) We don't bother calling\n\t\t\t\t\t// indexOf unless we have a new\n\t\t\t\t\t// position to work with\n\t\t\t\t\tvar currPos = titles.indexOf(title);\n\t\t\t\t\tif(currPos >= 0 && newPos !== currPos) {\n\t\t\t\t\t\t// move it!\n\t\t\t\t\t\ttitles.splice(currPos,1);\n\t\t\t\t\t\tif(newPos >= currPos) {\n\t\t\t\t\t\t\tnewPos--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitles.splice(newPos,0,title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvar list = this.getTiddlerList(listTitle);\n\tif(!array || array.length === 0) {\n\t\treturn [];\n\t} else {\n\t\tvar titles = [], t, title;\n\t\t// First place any entries that are present in the list\n\t\tfor(t=0; t<list.length; t++) {\n\t\t\ttitle = list[t];\n\t\t\tif(array.indexOf(title) !== -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Then place any remaining entries\n\t\tfor(t=0; t<array.length; t++) {\n\t\t\ttitle = array[t];\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Finally obey the list-before and list-after fields of each tiddler in turn\n\t\tvar sortedTitles = titles.slice(0);\n\t\tfor(t=0; t<sortedTitles.length; t++) {\n\t\t\ttitle = sortedTitles[t];\n\t\t\tmoveItemInList(title);\n\t\t}\n\t\treturn titles;\n\t}\n};\n\nexports.getSubTiddler = function(title,subTiddlerTitle) {\n\tvar bundleInfo = this.getPluginInfo(title) || this.getTiddlerDataCached(title);\n\tif(bundleInfo && bundleInfo.tiddlers) {\n\t\tvar subTiddler = bundleInfo.tiddlers[subTiddlerTitle];\n\t\tif(subTiddler) {\n\t\t\treturn new $tw.Tiddler(subTiddler);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRetrieve a tiddler as a JSON string of the fields\n*/\nexports.getTiddlerAsJson = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\tvar fields = Object.create(null);\n\t\t$tw.utils.each(tiddler.fields,function(value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\treturn JSON.stringify(fields);\n\t} else {\n\t\treturn JSON.stringify({title: title});\n\t}\n};\n\nexports.getTiddlersAsJson = function(filter,spaces) {\n\tvar tiddlers = this.filterTiddlers(filter),\n\t\tspaces = (spaces === undefined) ? $tw.config.preferences.jsonSpaces : spaces,\n\t\tdata = [];\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\tvar tiddler = this.getTiddler(tiddlers[t]);\n\t\tif(tiddler) {\n\t\t\tvar fields = new Object();\n\t\t\tfor(var field in tiddler.fields) {\n\t\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t\t}\n\t\t\tdata.push(fields);\n\t\t}\n\t}\n\treturn JSON.stringify(data,null,spaces);\n};\n\n/*\nGet the content of a tiddler as a JavaScript object. How this is done depends on the type of the tiddler:\n\napplication/json: the tiddler JSON is parsed into an object\napplication/x-tiddler-dictionary: the tiddler is parsed as sequence of name:value pairs\n\nOther types currently just return null.\n\ntitleOrTiddler: string tiddler title or a tiddler object\ndefaultData: default data to be returned if the tiddler is missing or doesn't contain data\n\nNote that the same value is returned for repeated calls for the same tiddler data. The value is frozen to prevent modification; otherwise modifications would be visible to all callers\n*/\nexports.getTiddlerDataCached = function(titleOrTiddler,defaultData) {\n\tvar self = this,\n\t\ttiddler = titleOrTiddler;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\t\n\t}\n\tif(tiddler) {\n\t\treturn this.getCacheForTiddler(tiddler.fields.title,\"data\",function() {\n\t\t\t// Return the frozen value\n\t\t\tvar value = self.getTiddlerData(tiddler.fields.title,undefined);\n\t\t\t$tw.utils.deepFreeze(value);\n\t\t\treturn value;\n\t\t}) || defaultData;\n\t} else {\n\t\treturn defaultData;\n\t}\n};\n\n/*\nAlternative, uncached version of getTiddlerDataCached(). The return value can be mutated freely and reused\n*/\nexports.getTiddlerData = function(titleOrTiddler,defaultData) {\n\tvar tiddler = titleOrTiddler,\n\t\tdata;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\t\n\t}\n\tif(tiddler && tiddler.fields.text) {\n\t\tswitch(tiddler.fields.type) {\n\t\t\tcase \"application/json\":\n\t\t\t\t// JSON tiddler\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(tiddler.fields.text);\n\t\t\t\t} catch(ex) {\n\t\t\t\t\treturn defaultData;\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\tcase \"application/x-tiddler-dictionary\":\n\t\t\t\treturn $tw.utils.parseFields(tiddler.fields.text);\n\t\t}\n\t}\n\treturn defaultData;\n};\n\n/*\nExtract an indexed field from within a data tiddler\n*/\nexports.extractTiddlerDataItem = function(titleOrTiddler,index,defaultText) {\n\tvar data = this.getTiddlerDataCached(titleOrTiddler,Object.create(null)),\n\t\ttext;\n\tif(data && $tw.utils.hop(data,index)) {\n\t\ttext = data[index];\n\t}\n\tif(typeof text === \"string\" || typeof text === \"number\") {\n\t\treturn text.toString();\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nSet a tiddlers content to a JavaScript object. Currently this is done by setting the tiddler's type to \"application/json\" and setting the text to the JSON text of the data.\ntitle: title of tiddler\ndata: object that can be serialised to JSON\nfields: optional hashmap of additional tiddler fields to be set\n*/\nexports.setTiddlerData = function(title,data,fields) {\n\tvar existingTiddler = this.getTiddler(title),\n\t\tnewFields = {\n\t\t\ttitle: title\n\t};\n\tif(existingTiddler && existingTiddler.fields.type === \"application/x-tiddler-dictionary\") {\n\t\tnewFields.text = $tw.utils.makeTiddlerDictionary(data);\n\t} else {\n\t\tnewFields.type = \"application/json\";\n\t\tnewFields.text = JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);\n\t}\n\tthis.addTiddler(new $tw.Tiddler(this.getCreationFields(),existingTiddler,fields,newFields,this.getModificationFields()));\n};\n\n/*\nReturn the content of a tiddler as an array containing each line\n*/\nexports.getTiddlerList = function(title,field,index) {\n\tif(index) {\n\t\treturn $tw.utils.parseStringArray(this.extractTiddlerDataItem(title,index,\"\"));\n\t}\n\tfield = field || \"list\";\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\treturn ($tw.utils.parseStringArray(tiddler.fields[field]) || []).slice(0);\n\t}\n\treturn [];\n};\n\n// Return a named global cache object. Global cache objects are cleared whenever a tiddler change occurs\nexports.getGlobalCache = function(cacheName,initializer) {\n\tthis.globalCache = this.globalCache || Object.create(null);\n\tif($tw.utils.hop(this.globalCache,cacheName)) {\n\t\treturn this.globalCache[cacheName];\n\t} else {\n\t\tthis.globalCache[cacheName] = initializer();\n\t\treturn this.globalCache[cacheName];\n\t}\n};\n\nexports.clearGlobalCache = function() {\n\tthis.globalCache = Object.create(null);\n};\n\n// Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it\nexports.getCacheForTiddler = function(title,cacheName,initializer) {\n\tthis.caches = this.caches || Object.create(null);\n\tvar caches = this.caches[title];\n\tif(caches && caches[cacheName]) {\n\t\treturn caches[cacheName];\n\t} else {\n\t\tif(!caches) {\n\t\t\tcaches = Object.create(null);\n\t\t\tthis.caches[title] = caches;\n\t\t}\n\t\tcaches[cacheName] = initializer();\n\t\treturn caches[cacheName];\n\t}\n};\n\n// Clear all caches associated with a particular tiddler, or, if the title is null, clear all the caches for all the tiddlers\nexports.clearCache = function(title) {\n\tif(title) {\n\t\tthis.caches = this.caches || Object.create(null);\n\t\tif($tw.utils.hop(this.caches,title)) {\n\t\t\tdelete this.caches[title];\n\t\t}\n\t} else {\n\t\tthis.caches = Object.create(null);\n\t}\n};\n\nexports.initParsers = function(moduleType) {\n\t// Install the parser modules\n\t$tw.Wiki.parsers = {};\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(\"parser\",function(title,module) {\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\t$tw.Wiki.parsers[f] = module[f]; // Store the parser class\n\t\t\t}\n\t\t}\n\t});\n\t// Use the generic binary parser for any binary types not registered so far\n\tif($tw.Wiki.parsers[\"application/octet-stream\"]) {\n\t\tObject.keys($tw.config.contentTypeInfo).forEach(function(type) {\n\t\t\tif(!$tw.utils.hop($tw.Wiki.parsers,type) && $tw.config.contentTypeInfo[type].encoding === \"base64\") {\n\t\t\t\t$tw.Wiki.parsers[type] = $tw.Wiki.parsers[\"application/octet-stream\"];\n\t\t\t}\n\t\t});\t\t\n\t}\n};\n\n/*\nParse a block of text of a specified MIME type\n\ttype: content type of text to be parsed\n\ttext: text\n\toptions: see below\nOptions include:\n\tparseAsInline: if true, the text of the tiddler will be parsed as an inline run\n\t_canonical_uri: optional string of the canonical URI of this content\n*/\nexports.parseText = function(type,text,options) {\n\ttext = text || \"\";\n\toptions = options || {};\n\t// Select a parser\n\tvar Parser = $tw.Wiki.parsers[type];\n\tif(!Parser && $tw.utils.getFileExtensionInfo(type)) {\n\t\tParser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];\n\t}\n\tif(!Parser) {\n\t\tParser = $tw.Wiki.parsers[options.defaultType || \"text/vnd.tiddlywiki\"];\n\t}\n\tif(!Parser) {\n\t\treturn null;\n\t}\n\t// Return the parser instance\n\treturn new Parser(type,text,{\n\t\tparseAsInline: options.parseAsInline,\n\t\twiki: this,\n\t\t_canonical_uri: options._canonical_uri\n\t});\n};\n\n/*\nParse a tiddler according to its MIME type\n*/\nexports.parseTiddler = function(title,options) {\n\toptions = $tw.utils.extend({},options);\n\tvar cacheType = options.parseAsInline ? \"inlineParseTree\" : \"blockParseTree\",\n\t\ttiddler = this.getTiddler(title),\n\t\tself = this;\n\treturn tiddler ? this.getCacheForTiddler(title,cacheType,function() {\n\t\t\tif(tiddler.hasField(\"_canonical_uri\")) {\n\t\t\t\toptions._canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t}\n\t\t\treturn self.parseText(tiddler.fields.type,tiddler.fields.text,options);\n\t\t}) : null;\n};\n\nexports.parseTextReference = function(title,field,index,options) {\n\tvar tiddler,text;\n\tif(options.subTiddler) {\n\t\ttiddler = this.getSubTiddler(title,options.subTiddler);\n\t} else {\n\t\ttiddler = this.getTiddler(title);\n\t\tif(field === \"text\" || (!field && !index)) {\n\t\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\t\treturn this.parseTiddler(title,options);\n\t\t}\n\t}\n\tif(field === \"text\" || (!field && !index)) {\n\t\tif(tiddler && tiddler.fields) {\n\t\t\treturn this.parseText(tiddler.fields.type,tiddler.fields.text,options);\t\t\t\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t} else if(field) {\n\t\tif(field === \"title\") {\n\t\t\ttext = title;\n\t\t} else {\n\t\t\tif(!tiddler || !tiddler.hasField(field)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\ttext = tiddler.fields[field];\n\t\t}\n\t\treturn this.parseText(\"text/vnd.tiddlywiki\",text.toString(),options);\n\t} else if(index) {\n\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\ttext = this.extractTiddlerDataItem(tiddler,index,undefined);\n\t\tif(text === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\treturn this.parseText(\"text/vnd.tiddlywiki\",text,options);\n\t}\n};\n\n/*\nMake a widget tree for a parse tree\nparser: parser object\noptions: see below\nOptions include:\ndocument: optional document to use\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.makeWidget = function(parser,options) {\n\toptions = options || {};\n\tvar widgetNode = {\n\t\t\ttype: \"widget\",\n\t\t\tchildren: []\n\t\t},\n\t\tcurrWidgetNode = widgetNode;\n\t// Create set variable widgets for each variable\n\t$tw.utils.each(options.variables,function(value,name) {\n\t\tvar setVariableWidget = {\n\t\t\ttype: \"set\",\n\t\t\tattributes: {\n\t\t\t\tname: {type: \"string\", value: name},\n\t\t\t\tvalue: {type: \"string\", value: value}\n\t\t\t},\n\t\t\tchildren: []\n\t\t};\n\t\tcurrWidgetNode.children = [setVariableWidget];\n\t\tcurrWidgetNode = setVariableWidget;\n\t});\n\t// Add in the supplied parse tree nodes\n\tcurrWidgetNode.children = parser ? parser.tree : [];\n\t// Create the widget\n\treturn new widget.widget(widgetNode,{\n\t\twiki: this,\n\t\tdocument: options.document || $tw.fakeDocument,\n\t\tparentWidget: options.parentWidget\n\t});\n};\n\n/*\nMake a widget tree for transclusion\ntitle: target tiddler title\noptions: as for wiki.makeWidget() plus:\noptions.field: optional field to transclude (defaults to \"text\")\noptions.mode: transclusion mode \"inline\" or \"block\"\noptions.recursionMarker : optional flag to set a recursion marker, defaults to \"yes\"\noptions.children: optional array of children for the transclude widget\noptions.importVariables: optional importvariables filter string for macros to be included\noptions.importPageMacros: optional boolean; if true, equivalent to passing \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\" to options.importVariables\n*/\nexports.makeTranscludeWidget = function(title,options) {\n\toptions = options || {};\n\tvar parseTreeDiv = {tree: [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"div\",\n\t\t\tchildren: []}]},\n\t\tparseTreeImportVariables = {\n\t\t\ttype: \"importvariables\",\n\t\t\tattributes: {\n\t\t\t\tfilter: {\n\t\t\t\t\tname: \"filter\",\n\t\t\t\t\ttype: \"string\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tisBlock: false,\n\t\t\tchildren: []},\n\t\tparseTreeTransclude = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\trecursionMarker: {\n\t\t\t\t\tname: \"recursionMarker\",\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: options.recursionMarker || \"yes\"\n\t\t\t\t\t},\n\t\t\t\ttiddler: {\n\t\t\t\t\tname: \"tiddler\",\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title\n\t\t\t\t}\n\t\t\t},\n\t\t\tisBlock: !options.parseAsInline};\n\tif(options.importVariables || options.importPageMacros) {\n\t\tif(options.importVariables) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = options.importVariables;\n\t\t} else if(options.importPageMacros) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\";\n\t\t}\n\t\tparseTreeDiv.tree[0].children.push(parseTreeImportVariables);\n\t\tparseTreeImportVariables.children.push(parseTreeTransclude);\n\t} else {\n\t\tparseTreeDiv.tree[0].children.push(parseTreeTransclude);\n\t}\n\tif(options.field) {\n\t\tparseTreeTransclude.attributes.field = {type: \"string\", value: options.field};\n\t}\n\tif(options.mode) {\n\t\tparseTreeTransclude.attributes.mode = {type: \"string\", value: options.mode};\n\t}\n\tif(options.children) {\n\t\tparseTreeTransclude.children = options.children;\n\t}\n\treturn this.makeWidget(parseTreeDiv,options);\n};\n\n/*\nParse text in a specified format and render it into another format\n\toutputType: content type for the output\n\ttextType: content type of the input text\n\ttext: input text\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderText = function(outputType,textType,text,options) {\n\toptions = options || {};\n\tvar parser = this.parseText(textType,text,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : container.textContent;\n};\n\n/*\nParse text from a tiddler and render it into another format\n\toutputType: content type for the output\n\ttitle: title of the tiddler to be rendered\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderTiddler = function(outputType,title,options) {\n\toptions = options || {};\n\tvar parser = this.parseTiddler(title,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : (outputType === \"text/plain-formatted\" ? container.formattedTextContent : container.textContent);\n};\n\n/*\nReturn an array of tiddler titles that match a search string\n\ttext: The text string to search for\n\toptions: see below\nOptions available:\n\tsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\n\texclude: An array of tiddler titles to exclude from the search\n\tinvert: If true returns tiddlers that do not contain the specified string\n\tcaseSensitive: If true forces a case sensitive search\n\tfield: If specified, restricts the search to the specified field, or an array of field names\n\tanchored: If true, forces all but regexp searches to be anchored to the start of text\n\texcludeField: If true, the field options are inverted to specify the fields that are not to be searched\n\tThe search mode is determined by the first of these boolean flags to be true\n\t\tliteral: searches for literal string\n\t\twhitespace: same as literal except runs of whitespace are treated as a single space\n\t\tregexp: treats the search term as a regular expression\n\t\twords: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering\n*/\nexports.search = function(text,options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tt,\n\t\tinvert = !!options.invert;\n\t// Convert the search string into a regexp for each term\n\tvar terms, searchTermsRegExps,\n\t\tflags = options.caseSensitive ? \"\" : \"i\",\n\t\tanchor = options.anchored ? \"^\" : \"\";\n\tif(options.literal) {\n\t\tif(text.length === 0) {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + anchor + $tw.utils.escapeRegExp(text) + \")\",flags)];\n\t\t}\n\t} else if(options.whitespace) {\n\t\tterms = [];\n\t\t$tw.utils.each(text.split(/\\s+/g),function(term) {\n\t\t\tif(term) {\n\t\t\t\tterms.push($tw.utils.escapeRegExp(term));\n\t\t\t}\n\t\t});\n\t\tsearchTermsRegExps = [new RegExp(\"(\" + anchor + terms.join(\"\\\\s+\") + \")\",flags)];\n\t} else if(options.regexp) {\n\t\ttry {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + text + \")\",flags)];\t\t\t\n\t\t} catch(e) {\n\t\t\tsearchTermsRegExps = null;\n\t\t\tconsole.log(\"Regexp error parsing /(\" + text + \")/\" + flags + \": \",e);\n\t\t}\n\t} else {\n\t\tterms = text.split(/ +/);\n\t\tif(terms.length === 1 && terms[0] === \"\") {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [];\n\t\t\tfor(t=0; t<terms.length; t++) {\n\t\t\t\tsearchTermsRegExps.push(new RegExp(\"(\" + anchor + $tw.utils.escapeRegExp(terms[t]) + \")\",flags));\n\t\t\t}\n\t\t}\n\t}\n\t// Accumulate the array of fields to be searched or excluded from the search\n\tvar fields = [];\n\tif(options.field) {\n\t\tif($tw.utils.isArray(options.field)) {\n\t\t\t$tw.utils.each(options.field,function(fieldName) {\n\t\t\t\tif(fieldName) {\n\t\t\t\t\tfields.push(fieldName);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tfields.push(options.field);\n\t\t}\n\t}\n\t// Use default fields if none specified and we're not excluding fields (excluding fields with an empty field array is the same as searching all fields)\n\tif(fields.length === 0 && !options.excludeField) {\n\t\tfields.push(\"title\");\n\t\tfields.push(\"tags\");\n\t\tfields.push(\"text\");\n\t}\n\t// Function to check a given tiddler for the search term\n\tvar searchTiddler = function(title) {\n\t\tif(!searchTermsRegExps) {\n\t\t\treturn true;\n\t\t}\n\t\tvar notYetFound = searchTermsRegExps.slice();\n\n\t\tvar tiddler = self.getTiddler(title);\n\t\tif(!tiddler) {\n\t\t\ttiddler = new $tw.Tiddler({title: title, text: \"\", type: \"text/vnd.tiddlywiki\"});\n\t\t}\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type] || $tw.config.contentTypeInfo[\"text/vnd.tiddlywiki\"],\n\t\t\tsearchFields;\n\t\t// Get the list of fields we're searching\n\t\tif(options.excludeField) {\n\t\t\tsearchFields = Object.keys(tiddler.fields);\n\t\t\t$tw.utils.each(fields,function(fieldName) {\n\t\t\t\tvar p = searchFields.indexOf(fieldName);\n\t\t\t\tif(p !== -1) {\n\t\t\t\t\tsearchFields.splice(p,1);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsearchFields = fields;\n\t\t}\n\t\tfor(var fieldIndex=0; notYetFound.length>0 && fieldIndex<searchFields.length; fieldIndex++) {\n\t\t\t// Don't search the text field if the content type is binary\n\t\t\tvar fieldName = searchFields[fieldIndex];\n\t\t\tif(fieldName === \"text\" && contentTypeInfo.encoding !== \"utf8\") {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar str = tiddler.fields[fieldName],\n\t\t\t\tt;\n\t\t\tif(str) {\n\t\t\t\tif($tw.utils.isArray(str)) {\n\t\t\t\t\t// If the field value is an array, test each regexp against each field array entry and fail if each regexp doesn't match at least one field array entry\n\t\t\t\t\tfor(var s=0; s<str.length; s++) {\n\t\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\t\tif(notYetFound[t].test(str[s])) {\n\t\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the field isn't an array, force it to a string and test each regexp against it and fail if any do not match\n\t\t\t\t\tstr = tiddler.getFieldString(fieldName);\n\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\tif(notYetFound[t].test(str)) {\n\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn notYetFound.length == 0;\n\t};\n\t// Loop through all the tiddlers doing the search\n\tvar results = [],\n\t\tsource = options.source || this.each;\n\tsource(function(tiddler,title) {\n\t\tif(searchTiddler(title) !== options.invert) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\t// Remove any of the results we have to exclude\n\tif(options.exclude) {\n\t\tfor(t=0; t<options.exclude.length; t++) {\n\t\t\tvar p = results.indexOf(options.exclude[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tresults.splice(p,1);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n/*\nTrigger a load for a tiddler if it is skinny. Returns the text, or undefined if the tiddler is missing, null if the tiddler is being lazily loaded.\n*/\nexports.getTiddlerText = function(title,defaultText) {\n\tvar tiddler = this.getTiddler(title);\n\t// Return undefined if the tiddler isn't found\n\tif(!tiddler) {\n\t\treturn defaultText;\n\t}\n\tif(!tiddler.hasField(\"_is_skinny\")) {\n\t\t// Just return the text if we've got it\n\t\treturn tiddler.fields.text || \"\";\n\t} else {\n\t\t// Tell any listeners about the need to lazily load this tiddler\n\t\tthis.dispatchEvent(\"lazyLoad\",title);\n\t\t// Indicate that the text is being loaded\n\t\treturn null;\n\t}\n};\n\n/*\nCheck whether the text of a tiddler matches a given value. By default, the comparison is case insensitive, and any spaces at either end of the tiddler text is trimmed\n*/\nexports.checkTiddlerText = function(title,targetText,options) {\n\toptions = options || {};\n\tvar text = this.getTiddlerText(title,\"\");\n\tif(!options.noTrim) {\n\t\ttext = text.trim();\n\t}\n\tif(!options.caseSensitive) {\n\t\ttext = text.toLowerCase();\n\t\ttargetText = targetText.toLowerCase();\n\t}\n\treturn text === targetText;\n}\n\n/*\nRead an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read\n*/\nexports.readFiles = function(files,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\tvar result = [],\n\t\toutstanding = files.length,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tresult.push.apply(result,tiddlerFieldsArray);\n\t\t\tif(--outstanding === 0) {\n\t\t\t\tcallback(result);\n\t\t\t}\n\t\t};\n\tfor(var f=0; f<files.length; f++) {\n\t\tthis.readFile(files[f],$tw.utils.extend({},options,{callback: readFileCallback}));\n\t}\n\treturn files.length;\n};\n\n/*\nRead a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFile = function(file,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\t// Get the type, falling back to the filename extension\n\tvar self = this,\n\t\ttype = file.type;\n\tif(type === \"\" || !type) {\n\t\tvar dotPos = file.name.lastIndexOf(\".\");\n\t\tif(dotPos !== -1) {\n\t\t\tvar fileExtensionInfo = $tw.utils.getFileExtensionInfo(file.name.substr(dotPos));\n\t\t\tif(fileExtensionInfo) {\n\t\t\t\ttype = fileExtensionInfo.type;\n\t\t\t}\n\t\t}\n\t}\n\t// Figure out if we're reading a binary file\n\tvar contentTypeInfo = $tw.config.contentTypeInfo[type],\n\t\tisBinary = contentTypeInfo ? contentTypeInfo.encoding === \"base64\" : false;\n\t// Log some debugging information\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Importing file '\" + file.name + \"', type: '\" + type + \"', isBinary: \" + isBinary);\n\t}\n\t// Give the hook a chance to process the drag\n\tif($tw.hooks.invokeHook(\"th-importing-file\",{\n\t\tfile: file,\n\t\ttype: type,\n\t\tisBinary: isBinary,\n\t\tcallback: callback\n\t}) !== true) {\n\t\tthis.readFileContent(file,type,isBinary,options.deserializer,callback);\n\t}\n};\n\n/*\nLower level utility to read the content of a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFileContent = function(file,type,isBinary,deserializer,callback) {\n\tvar self = this;\n\t// Create the FileReader\n\tvar reader = new FileReader();\n\t// Onload\n\treader.onload = function(event) {\n\t\tvar text = event.target.result,\n\t\t\ttiddlerFields = {title: file.name || \"Untitled\"};\n\t\tif(isBinary) {\n\t\t\tvar commaPos = text.indexOf(\",\");\n\t\t\tif(commaPos !== -1) {\n\t\t\t\ttext = text.substr(commaPos + 1);\n\t\t\t}\n\t\t}\n\t\t// Check whether this is an encrypted TiddlyWiki file\n\t\tvar encryptedJson = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedJson) {\n\t\t\t// If so, attempt to decrypt it with the current password\n\t\t\t$tw.utils.decryptStoreAreaInteractive(encryptedJson,function(tiddlers) {\n\t\t\t\tcallback(tiddlers);\n\t\t\t});\n\t\t} else {\n\t\t\t// Otherwise, just try to deserialise any tiddlers in the file\n\t\t\tcallback(self.deserializeTiddlers(type,text,tiddlerFields,{deserializer: deserializer}));\n\t\t}\n\t};\n\t// Kick off the read\n\tif(isBinary) {\n\t\treader.readAsDataURL(file);\n\t} else {\n\t\treader.readAsText(file);\n\t}\n};\n\n/*\nFind any existing draft of a specified tiddler\n*/\nexports.findDraft = function(targetTitle) {\n\tvar draftTitle = undefined;\n\tthis.forEachTiddler({includeSystem: true},function(title,tiddler) {\n\t\tif(tiddler.fields[\"draft.title\"] && tiddler.fields[\"draft.of\"] === targetTitle) {\n\t\t\tdraftTitle = title;\n\t\t}\n\t});\n\treturn draftTitle;\n}\n\n/*\nCheck whether the specified draft tiddler has been modified.\nIf the original tiddler doesn't exist, create a vanilla tiddler variable,\nto check if additional fields have been added.\n*/\nexports.isDraftModified = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(!tiddler.isDraft()) {\n\t\treturn false;\n\t}\n\tvar ignoredFields = [\"created\", \"modified\", \"title\", \"draft.title\", \"draft.of\"],\n\t\torigTiddler = this.getTiddler(tiddler.fields[\"draft.of\"]) || new $tw.Tiddler({text:\"\", tags:[]}),\n\t\ttitleModified = tiddler.fields[\"draft.title\"] !== tiddler.fields[\"draft.of\"];\n\treturn titleModified || !tiddler.isEqual(origTiddler,ignoredFields);\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\nhistoryTitle: title of history tiddler (defaults to $:/HistoryList)\n*/\nexports.addToHistory = function(title,fromPageRect,historyTitle) {\n\tvar story = new $tw.Story({wiki: this, historyTitle: historyTitle});\n\tstory.addToHistory(title,fromPageRect);\t\n\tconsole.log(\"$tw.wiki.addToHistory() is deprecated since V5.1.23! Use the this.story.addToHistory() from the story-object!\")\n};\n\n/*\nAdd a new tiddler to the story river\ntitle: a title string or an array of title strings\nfromTitle: the title of the tiddler from which the navigation originated\nstoryTitle: title of story tiddler (defaults to $:/StoryList)\noptions: see story.js\n*/\nexports.addToStory = function(title,fromTitle,storyTitle,options) {\n\tvar story = new $tw.Story({wiki: this, storyTitle: storyTitle});\n\tstory.addToStory(title,fromTitle,options);\n\tconsole.log(\"$tw.wiki.addToStory() is deprecated since V5.1.23! Use the this.story.addToStory() from the story-object!\")\n};\n\n/*\nGenerate a title for the draft of a given tiddler\n*/\nexports.generateDraftTitle = function(title) {\n\tvar c = 0,\n\t\tdraftTitle,\n\t\tusername = this.getTiddlerText(\"$:/status/UserName\"),\n\t\tattribution = username ? \" by \" + username : \"\";\n\tdo {\n\t\tdraftTitle = \"Draft \" + (c ? (c + 1) + \" \" : \"\") + \"of '\" + title + \"'\" + attribution;\n\t\tc++;\n\t} while(this.tiddlerExists(draftTitle));\n\treturn draftTitle;\n};\n\n/*\nInvoke the available upgrader modules\ntitles: array of tiddler titles to be processed\ntiddlers: hashmap by title of tiddler fields of pending import tiddlers. These can be modified by the upgraders. An entry with no fields indicates a tiddler that was pending import has been suppressed. When entries are added to the pending import the tiddlers hashmap may have entries that are not present in the titles array\nReturns a hashmap of messages keyed by tiddler title.\n*/\nexports.invokeUpgraders = function(titles,tiddlers) {\n\t// Collect up the available upgrader modules\n\tvar self = this;\n\tif(!this.upgraderModules) {\n\t\tthis.upgraderModules = [];\n\t\t$tw.modules.forEachModuleOfType(\"upgrader\",function(title,module) {\n\t\t\tif(module.upgrade) {\n\t\t\t\tself.upgraderModules.push(module);\n\t\t\t}\n\t\t});\n\t}\n\t// Invoke each upgrader in turn\n\tvar messages = {};\n\tfor(var t=0; t<this.upgraderModules.length; t++) {\n\t\tvar upgrader = this.upgraderModules[t],\n\t\t\tupgraderMessages = upgrader.upgrade(this,titles,tiddlers);\n\t\t$tw.utils.extend(messages,upgraderMessages);\n\t}\n\treturn messages;\n};\n\n// Determine whether a plugin by title is dynamically loadable\nexports.doesPluginRequireReload = function(title) {\n\treturn this.doesPluginInfoRequireReload(this.getPluginInfo(title) || this.getTiddlerDataCached(title));\n};\n\n// Determine whether a plugin info structure is dynamically loadable\nexports.doesPluginInfoRequireReload = function(pluginInfo) {\n\tif(pluginInfo) {\n\t\tvar foundModule = false;\n\t\t$tw.utils.each(pluginInfo.tiddlers,function(tiddler) {\n\t\t\tif(tiddler.type === \"application/javascript\" && $tw.utils.hop(tiddler,\"module-type\")) {\n\t\t\t\tfoundModule = true;\n\t\t\t}\n\t\t});\n\t\treturn foundModule;\n\t} else {\n\t\treturn null;\n\t}\n};\n\nexports.slugify = function(title,options) {\n\tvar tiddler = this.getTiddler(title),\n\t\tslug;\n\tif(tiddler && tiddler.fields.slug) {\n\t\tslug = tiddler.fields.slug;\n\t} else {\n\t\tslug = $tw.utils.transliterate(title.toString().toLowerCase()) // Replace diacritics with basic lowercase ASCII\n\t\t\t.replace(/\\s+/g,\"-\") // Replace spaces with -\n\t\t\t.replace(/[^\\w\\-\\.]+/g,\"\") // Remove all non-word chars except dash and dot\n\t\t\t.replace(/\\-\\-+/g,\"-\") // Replace multiple - with single -\n\t\t\t.replace(/^-+/,\"\") // Trim - from start of text\n\t\t\t.replace(/-+$/,\"\"); // Trim - from end of text\n\t}\n\t// If the resulting slug is blank (eg because the title is just punctuation characters)\n\tif(!slug) {\n\t\t// ...then just use the character codes of the title\n\t\tvar result = [];\n\t\t$tw.utils.each(title.split(\"\"),function(char) {\n\t\t\tresult.push(char.charCodeAt(0).toString());\n\t\t});\n\t\tslug = result.join(\"-\");\n\t}\n\treturn slug;\n};\n\n})();\n\n",
"type": "application/javascript",
"module-type": "wikimethod"
},
"$:/palettes/Blanca": {
"title": "$:/palettes/Blanca",
"name": "Blanca",
"description": "A clean white palette to let you focus",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #66cccc\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ffffff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #7897f3\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ccc\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #ffffff\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #7897f3\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #eeeeee\ntab-border-selected: #cccccc\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffeedd\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: #eee\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #ff9900\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/Blue": {
"title": "$:/palettes/Blue",
"name": "Blue",
"description": "A blue theme",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333353\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ddddff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #5959c0\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: #ccccdd\ntab-border-selected: #ccccdd\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #eeeeff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #666666\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #ffffff\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #ffffff\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #5959c0\ntoolbar-new-button: #5eb95e\ntoolbar-options-button: rgb(128, 88, 165)\ntoolbar-save-button: #0e90d2\ntoolbar-info-button: #0e90d2\ntoolbar-edit-button: rgb(243, 123, 29)\ntoolbar-close-button: #dd514c\ntoolbar-delete-button: #dd514c\ntoolbar-cancel-button: rgb(243, 123, 29)\ntoolbar-done-button: #5eb95e\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/Muted": {
"title": "$:/palettes/Muted",
"name": "Muted",
"description": "Bright tiddlers on a muted background",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #6f6f70\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #29a6ee\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #c2c1c2\nsidebar-foreground-shadow: rgba(255,255,255,0)\nsidebar-foreground: #d3d2d4\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #6f6f70\nsidebar-tab-background: #666667\nsidebar-tab-border-selected: #999\nsidebar-tab-border: #515151\nsidebar-tab-divider: #999\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: #999\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #d1d0d2\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #d5ad34\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/ContrastLight": {
"title": "$:/palettes/ContrastLight",
"name": "Contrast (Light)",
"description": "High contrast and unambiguous (light version)",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nforeground: #000\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #000\ntag-foreground: #fff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"
},
"$:/palettes/ContrastDark": {
"title": "$:/palettes/ContrastDark",
"name": "Contrast (Dark)",
"description": "High contrast and unambiguous (dark version)",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #000\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nforeground: #fff\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #fff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"
},
"$:/palettes/CupertinoDark": {
"title": "$:/palettes/CupertinoDark",
"tags": "$:/tags/Palette",
"name": "Cupertino Dark",
"description": "A macOS inspired dark palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #FF453A\nalert-border: #FF453A\nalert-highlight: #FFD60A\nalert-muted-foreground: <<colour muted-foreground>>\nbackground: #282828\nblockquote-bar: <<colour page-background>>\nbutton-foreground: <<colour background>>\ncode-background: <<colour pre-background>>\ncode-border: <<colour pre-border>>\ncode-foreground: rgba(255, 255, 255, 0.54)\ndirty-indicator: #FF453A\ndownload-background: <<colour primary>>\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour tiddler-info-background>>\ndropdown-border: <<colour dropdown-background>>\ndropdown-tab-background-selected: #3F638B\ndropdown-tab-background: #323232\ndropzone-background: #30D158\nexternal-link-background-hover: transparent\nexternal-link-background-visited: transparent\nexternal-link-background: transparent\nexternal-link-foreground-hover: \nexternal-link-foreground-visited: #BF5AF2\nexternal-link-foreground: #32D74B\nforeground: #FFFFFF\nmenubar-background: #464646\nmenubar-foreground: #ffffff\nmessage-background: <<colour background>>\nmessage-border: <<colour very-muted-foreground>>\nmessage-foreground: rgba(255, 255, 255, 0.54)\nmodal-backdrop: <<colour page-background>>\nmodal-background: <<colour background>>\nmodal-border: <<colour very-muted-foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour background>>\nmodal-header-border: <<colour very-muted-foreground>>\nmuted-foreground: #98989D\nnotification-background: <<colour dropdown-background>>\nnotification-border: <<colour dropdown-background>>\npage-background: #323232\npre-background: #464646\npre-border: transparent\nprimary: #0A84FF\nselect-tag-background: <<colour background>>\nselect-tag-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour background>>\nsidebar-controls-foreground-hover: #FF9F0A\nsidebar-controls-foreground: #8E8E93\nsidebar-foreground-shadow: transparent\nsidebar-foreground: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground-hover: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground: rgba(255, 255, 255, 0.38)\nsidebar-tab-background-selected: #3F638B\nsidebar-tab-background: <<colour background>>\nsidebar-tab-border-selected: <<colour background>>\nsidebar-tab-border: <<colour background>>\nsidebar-tab-divider: <<colour background>>\nsidebar-tab-foreground-selected: rgba(255, 255, 255, 0.87)\nsidebar-tab-foreground: rgba(255, 255, 255, 0.54)\nsidebar-tiddler-link-foreground-hover: rgba(255, 255, 255, 0.7)\nsidebar-tiddler-link-foreground: rgba(255, 255, 255, 0.54)\nsite-title-foreground: #ffffff\nstatic-alert-foreground: #B4B4B4\ntab-background-selected: #3F638B\ntab-background: <<colour page-background>>\ntab-border-selected: <<colour page-background>>\ntab-border: <<colour page-background>>\ntab-divider: <<colour page-background>>\ntab-foreground-selected: rgba(255, 255, 255, 0.87)\ntab-foreground: rgba(255, 255, 255, 0.54)\ntable-border: #464646\ntable-footer-background: <<colour tiddler-editor-fields-odd>>\ntable-header-background: <<colour tiddler-editor-fields-even>>\ntag-background: #48484A\ntag-foreground: #323232\ntiddler-background: <<colour background>>\ntiddler-border: transparent\ntiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground: #48484A\ntiddler-editor-background: transparent\ntiddler-editor-border-image: \ntiddler-editor-border: rgba(255, 255, 255, 0.08)\ntiddler-editor-fields-even: rgba(255, 255, 255, 0.1)\ntiddler-editor-fields-odd: rgba(255, 255, 255, 0.04)\ntiddler-info-background: #1E1E1E\ntiddler-info-border: #1E1E1E\ntiddler-info-tab-background: #3F638B\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour muted-foreground>>\ntiddler-title-foreground: #FFFFFF\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour very-muted-foreground>>\nvery-muted-foreground: #464646\nselection-background: #3F638B\nselection-foreground: #ffffff\nwikilist-background: <<colour page-background>>\nwikilist-button-background: #3F638B\nwikilist-button-foreground: <<colour foreground>>\nwikilist-button-open: #32D74B\nwikilist-button-open-hover: #32D74B\nwikilist-button-reveal: #0A84FF\nwikilist-button-reveal-hover: #0A84FF\nwikilist-button-remove: #FF453A\nwikilist-button-remove-hover: #FF453A\nwikilist-droplink-dragover: #32D74B\nwikilist-item: <<colour background>>\nwikilist-toolbar-background: <<colour background>>\nwikilist-title: <<colour foreground>>\nwikilist-title-svg: <<colour foreground>>\nwikilist-toolbar-foreground: <<colour foreground>>\nwikilist-url: <<colour muted-foreground>>\n"
},
"$:/palettes/DarkPhotos": {
"title": "$:/palettes/DarkPhotos",
"created": "20150402111612188",
"description": "Good with dark photo backgrounds",
"modified": "20150402112344080",
"name": "DarkPhotos",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: \nbutton-foreground: \nbutton-border: \ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #ddd\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #336438\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #ccf\nsidebar-controls-foreground: #fff\nsidebar-foreground-shadow: rgba(0,0,0, 0.5)\nsidebar-foreground: #fff\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #eee\nsidebar-tab-background-selected: rgba(255,255,255, 0.8)\nsidebar-tab-background: rgba(255,255,255, 0.4)\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: rgba(255,255,255, 0.2)\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #aaf\nsidebar-tiddler-link-foreground: #ddf\nsite-title-foreground: #fff\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/DesertSand": {
"title": "$:/palettes/DesertSand",
"tags": "$:/tags/Palette",
"name": "Desert Sand",
"description": "A desert sand palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #E9E0C7\nblockquote-bar: <<colour muted-foreground>>\nbutton-foreground: <<colour foreground>>\ncode-background: #F3EDDF\ncode-border: #C3BAA1\ncode-foreground: #ab3250\ndiff-delete-background: #bd8b8b\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #91c093\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #ad3434\ndownload-background: #6ca16c\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #E9E0C7\ndropdown-tab-background: #BAB29C\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #313163\nexternal-link-foreground: #555592\nforeground: #2D2A23\nmenubar-background: #CDC2A6\nmenubar-foreground: #5A5446\nmessage-background: #ECE5CF\nmessage-border: #D6CBAA\nmessage-foreground: #5f6e7d\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #8A8885\nmodal-footer-background: #CDC2A6\nmodal-footer-border: #9D998E\nmodal-header-border: #9D998E\nmuted-foreground: #9D998E\nnotification-background: #F0E9D7\nnotification-border: #939189\npage-background: #e0d3af\npre-background: #D6CBAA\npre-border: #CDC2A6\nprimary: #5B6F55\nselection-background: #9D947B\nselection-foreground: <<colour foreground>>\nselect-tag-background: #F0E9D7\nselect-tag-foreground: #2D2A23\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #2D2A23\nsidebar-controls-foreground: #867F69\nsidebar-foreground-shadow: transparent\nsidebar-foreground: #867F69\nsidebar-muted-foreground-hover: #706A58\nsidebar-muted-foreground: #B3A98C\nsidebar-tab-background-selected: #e0d3af\nsidebar-tab-background: #A6A193\nsidebar-tab-border-selected: #C3BAA1\nsidebar-tab-border: #C3BAA1\nsidebar-tab-divider: #CDC2A6\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: #2D2A23\nsidebar-tiddler-link-foreground-hover: #433F35\nsidebar-tiddler-link-foreground: #706A58\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #A6A193\ntab-background-selected: #E9E0C7\ntab-background: #A6A193\ntab-border-selected: #C3BAA1\ntab-border: #C3BAA1\ntab-divider: #CDC2A6\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #2D2A23\ntable-border: #9D998E\ntable-footer-background: #8A8885\ntable-header-background: #B0AA98\ntag-background: #706A58\ntag-foreground: #E3D7B7\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #9D947B\ntiddler-controls-foreground-selected: #706A58\ntiddler-controls-foreground: #C3BAA1\ntiddler-editor-background: #E9E0C7\ntiddler-editor-border-image: #A6A193\ntiddler-editor-border: #A6A193\ntiddler-editor-fields-even: #D6CBAA\ntiddler-editor-fields-odd: #C3BAA1\ntiddler-info-background: #E3D7B7\ntiddler-info-border: #BAB29C\ntiddler-info-tab-background: #E9E0C7\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #867F69\ntiddler-title-foreground: #374464\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #8A8885\nvery-muted-foreground: #CDC2A6\nwikilist-background: <<colour page-background>>\nwikilist-item: #CDC2A6\nwikilist-info: #161512\nwikilist-title: #433F35\nwikilist-title-svg: <<colour wikilist-title>>\nwikilist-url: #706A58\nwikilist-button-open: #7db66a\nwikilist-button-open-hover: #56a556\nwikilist-button-reveal: #5a6c9e\nwikilist-button-reveal-hover: #454591\nwikilist-button-remove: #bc5972\nwikilist-button-remove-hover: #814040\nwikilist-toolbar-background: #CDC2A6\nwikilist-toolbar-foreground: #2D2A23\nwikilist-droplink-dragover: rgba(255,192,192,0.5)\nwikilist-button-background: #A6A193\nwikilist-button-foreground: #161512\n"
},
"$:/palettes/GruvboxDark": {
"title": "$:/palettes/GruvboxDark",
"name": "Gruvbox Dark",
"description": "Retro groove color scheme",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"license": "https://github.com/morhetz/gruvbox",
"text": "alert-background: #cc241d\nalert-border: #cc241d\nalert-highlight: #d79921\nalert-muted-foreground: #504945\nbackground: #3c3836\nblockquote-bar: <<colour muted-foreground>>\nbutton-foreground: <<colour page-background>>\ncode-background: #504945\ncode-border: #504945\ncode-foreground: #fb4934\ndiff-delete-background: #fb4934\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #b8bb26\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #fb4934\ndownload-background: #b8bb26\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: #665c54\ndropdown-border: <<colour background>>\ndropdown-tab-background-selected: #ebdbb2\ndropdown-tab-background: #665c54\ndropzone-background: #98971a\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #d3869b\nexternal-link-foreground: #8ec07c\nforeground: #fbf1c7\nmenubar-background: #504945\nmenubar-foreground: <<colour foreground>>\nmessage-background: #83a598\nmessage-border: #83a598\nmessage-foreground: #3c3836\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #504945\nmodal-footer-background: #3c3836\nmodal-footer-border: #3c3836\nmodal-header-border: #3c3836\nmuted-foreground: #d5c4a1\nnotification-background: <<colour primary>>\nnotification-border: <<colour primary>>\npage-background: #282828\npre-background: #504945\npre-border: #504945\nprimary: #d79921\nselect-tag-background: #665c54\nselect-tag-foreground: <<colour foreground>>\nselection-background: #458588\nselection-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour page-background>>\nsidebar-controls-foreground-hover: #7c6f64\nsidebar-controls-foreground: #504945\nsidebar-foreground-shadow: transparent\nsidebar-foreground: #fbf1c7\nsidebar-muted-foreground-hover: #7c6f64\nsidebar-muted-foreground: #504945\nsidebar-tab-background-selected: #bdae93\nsidebar-tab-background: #3c3836\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: #bdae93\nsidebar-tab-divider: <<colour page-background>>\nsidebar-tab-foreground-selected: #282828\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #458588\nsidebar-tiddler-link-foreground: #98971a\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #B48EAD\ntab-background-selected: #ebdbb2\ntab-background: #665c54\ntab-border-selected: #665c54\ntab-border: #665c54\ntab-divider: #bdae93\ntab-foreground-selected: #282828\ntab-foreground: #ebdbb2\ntable-border: #7c6f64\ntable-footer-background: #665c54\ntable-header-background: #504945\ntag-background: #d3869b\ntag-foreground: #282828\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #7c6f64\ntiddler-controls-foreground-selected: <<colour primary>>\ntiddler-controls-foreground: #665c54\ntiddler-editor-background: #32302f\ntiddler-editor-border-image: #282828\ntiddler-editor-border: #282828\ntiddler-editor-fields-even: #504945\ntiddler-editor-fields-odd: #7c6f64\ntiddler-info-background: #32302f\ntiddler-info-border: #ebdbb2\ntiddler-info-tab-background: #ebdbb2\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #7c6f64\ntiddler-title-foreground: #a89984\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #504945\nvery-muted-foreground: #bdae93\nwikilist-background: <<colour page-background>>\nwikilist-button-background: #acacac\nwikilist-button-foreground: <<colour button-foreground>>\nwikilist-item: <<colour background>>\nwikilist-toolbar-background: <<colour background>>\nwikilist-toolbar-foreground: <<colour foreground>>\nwikilist-title: <<colour foreground>>\nwikilist-title-svg: <<colour wikilist-title>>\nwikilist-url: <<colour muted-foreground>>\nwikilist-button-open-hover: <<colour primary>>\nwikilist-button-open: <<colour dropzone-background>>\nwikilist-button-remove: <<colour dirty-indicator>>\nwikilist-button-remove-hover: <<colour alert-background>>\nwikilist-droplink-dragover: <<colour dropzone-background>>\nwikilist-button-reveal: <<colour sidebar-tiddler-link-foreground-hover>>\nwikilist-button-reveal-hover: <<colour message-background>>\n"
},
"$:/palettes/Nord": {
"title": "$:/palettes/Nord",
"name": "Nord",
"description": "An arctic, north-bluish color palette.",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"license": "MIT, arcticicestudio, https://github.com/arcticicestudio/nord/blob/develop/LICENSE.md",
"text": "alert-background: #D08770\nalert-border: #D08770\nalert-highlight: #B48EAD\nalert-muted-foreground: #4C566A\nbackground: #3b4252\nblockquote-bar: <<colour muted-foreground>>\nbutton-foreground: <<colour page-background>>\ncode-background: #2E3440\ncode-border: #2E3440\ncode-foreground: #BF616A\ndiff-delete-background: #BF616A\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #A3BE8C\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #BF616A\ndownload-background: #A3BE8C\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour background>>\ndropdown-tab-background-selected: #ECEFF4\ndropdown-tab-background: #4C566A\ndropzone-background: #A3BE8C\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #5E81AC\nexternal-link-foreground: #8FBCBB\nforeground: #d8dee9\nmenubar-background: #2E3440\nmenubar-foreground: #d8dee9\nmessage-background: #2E3440\nmessage-border: #2E3440\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #3b4252\nmodal-footer-background: #3b4252\nmodal-footer-border: #3b4252\nmodal-header-border: #3b4252\nmuted-foreground: #4C566A\nnotification-background: <<colour primary>>\nnotification-border: #EBCB8B\npage-background: #2e3440\npre-background: #2E3440\npre-border: #2E3440\nprimary: #5E81AC\nselect-tag-background: #3b4252\nselect-tag-foreground: <<colour foreground>>\nselection-background: #5E81AC\nselection-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour page-background>>\nsidebar-controls-foreground-hover: #D8DEE9\nsidebar-controls-foreground: #4C566A\nsidebar-foreground-shadow: transparent\nsidebar-foreground: #D8DEE9\nsidebar-muted-foreground-hover: #4C566A\nsidebar-muted-foreground: #4C566A\nsidebar-tab-background-selected: #ECEFF4\nsidebar-tab-background: #4C566A\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: #4C566A\nsidebar-tab-divider: <<colour page-background>>\nsidebar-tab-foreground-selected: #4C566A\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #A3BE8C\nsidebar-tiddler-link-foreground: #81A1C1\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #B48EAD\ntab-background-selected: #ECEFF4\ntab-background: #4C566A\ntab-border-selected: #4C566A\ntab-border: #4C566A\ntab-divider: #4C566A\ntab-foreground-selected: #4C566A\ntab-foreground: #D8DEE9\ntable-border: #4C566A\ntable-footer-background: #2e3440\ntable-header-background: #2e3440\ntag-background: #A3BE8C\ntag-foreground: #4C566A\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: \ntiddler-controls-foreground-selected: #EBCB8B\ntiddler-controls-foreground: #4C566A\ntiddler-editor-background: #2e3440\ntiddler-editor-border-image: #2e3440\ntiddler-editor-border: #3b4252\ntiddler-editor-fields-even: #2e3440\ntiddler-editor-fields-odd: #2e3440\ntiddler-info-background: #2e3440\ntiddler-info-border: #2e3440\ntiddler-info-tab-background: #2e3440\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #4C566A\ntiddler-title-foreground: #81A1C1\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #2d3038\nvery-muted-foreground: #2d3038\nwikilist-background: <<colour page-background>>\nwikilist-toolbar-background: <<colour background>>\nwikilist-item: <<colour background>>\nwikilist-title: <<colour foreground>>\nwikilist-info: <<colour muted-foreground>>\nwikilist-button-open: #A3BE8C\nwikilist-button-open-hover: #A3BE8C\nwikilist-button-reveal: #81A1C1\nwikilist-button-reveal-hover: #81A1C1\nwikilist-button-remove: #B48EAD\nwikilist-button-remove-hover: #B48EAD\n"
},
"$:/palettes/Rocker": {
"title": "$:/palettes/Rocker",
"name": "Rocker",
"description": "A dark theme",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #000\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #cc0000\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.0)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #000\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #ffbb99\nsidebar-tiddler-link-foreground: #cc0000\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffbb99\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #cc0000\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/SolarFlare": {
"title": "$:/palettes/SolarFlare",
"name": "Solar Flare",
"description": "Warm, relaxing earth colours",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": ": Background Tones\n\nbase03: #002b36\nbase02: #073642\n\n: Content Tones\n\nbase01: #586e75\nbase00: #657b83\nbase0: #839496\nbase1: #93a1a1\n\n: Background Tones\n\nbase2: #eee8d5\nbase3: #fdf6e3\n\n: Accent Colors\n\nyellow: #b58900\norange: #cb4b16\nred: #dc322f\nmagenta: #d33682\nviolet: #6c71c4\nblue: #268bd2\ncyan: #2aa198\ngreen: #859900\n\n: Additional Tones (RA)\n\nbase10: #c0c4bb\nviolet-muted: #7c81b0\nblue-muted: #4e7baa\n\nyellow-hot: #ffcc44\norange-hot: #eb6d20\nred-hot: #ff2222\nblue-hot: #2298ee\ngreen-hot: #98ee22\n\n: Palette\n\n: Do not use colour macro for background and foreground\nbackground: #fdf6e3\n download-foreground: <<colour background>>\n dragger-foreground: <<colour background>>\n dropdown-background: <<colour background>>\n modal-background: <<colour background>>\n sidebar-foreground-shadow: <<colour background>>\n tiddler-background: <<colour background>>\n tiddler-border: <<colour background>>\n tiddler-link-background: <<colour background>>\n tab-background-selected: <<colour background>>\n dropdown-tab-background-selected: <<colour tab-background-selected>>\nforeground: #657b83\n dragger-background: <<colour foreground>>\n tab-foreground: <<colour foreground>>\n tab-foreground-selected: <<colour tab-foreground>>\n sidebar-tab-foreground-selected: <<colour tab-foreground-selected>>\n sidebar-tab-foreground: <<colour tab-foreground>>\n sidebar-button-foreground: <<colour foreground>>\n sidebar-controls-foreground: <<colour foreground>>\n sidebar-foreground: <<colour foreground>>\n: base03\n: base02\n: base01\n alert-muted-foreground: <<colour base01>>\n: base00\n code-foreground: <<colour base00>>\n message-foreground: <<colour base00>>\n tag-foreground: <<colour base00>>\n: base0\n sidebar-tiddler-link-foreground: <<colour base0>>\n: base1\n muted-foreground: <<colour base1>>\n blockquote-bar: <<colour muted-foreground>>\n dropdown-border: <<colour muted-foreground>>\n sidebar-muted-foreground: <<colour muted-foreground>>\n tiddler-title-foreground: <<colour muted-foreground>>\n site-title-foreground: <<colour tiddler-title-foreground>>\n: base2\n modal-footer-background: <<colour base2>>\n page-background: <<colour base2>>\n modal-backdrop: <<colour page-background>>\n notification-background: <<colour page-background>>\n code-background: <<colour page-background>>\n code-border: <<colour code-background>>\n pre-background: <<colour page-background>>\n pre-border: <<colour pre-background>>\n sidebar-tab-background-selected: <<colour page-background>>\n table-header-background: <<colour base2>>\n tag-background: <<colour base2>>\n tiddler-editor-background: <<colour base2>>\n tiddler-info-background: <<colour base2>>\n tiddler-info-tab-background: <<colour base2>>\n tab-background: <<colour base2>>\n dropdown-tab-background: <<colour tab-background>>\n: base3\n alert-background: <<colour base3>>\n message-background: <<colour base3>>\n: yellow\n: orange\n: red\n: magenta\n alert-highlight: <<colour magenta>>\n: violet\n external-link-foreground: <<colour violet>>\n: blue\n: cyan\n: green\n: base10\n tiddler-controls-foreground: <<colour base10>>\n: violet-muted\n external-link-foreground-visited: <<colour violet-muted>>\n: blue-muted\n primary: <<colour blue-muted>>\n download-background: <<colour primary>>\n tiddler-link-foreground: <<colour primary>>\n\nalert-border: #b99e2f\ndirty-indicator: #ff0000\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nmessage-border: #cfd6e6\nmodal-border: #999999\nselect-tag-background:\nselect-tag-foreground:\nsidebar-controls-foreground-hover:\nsidebar-muted-foreground-hover:\nsidebar-tab-background: #ded8c5\nsidebar-tiddler-link-foreground-hover:\nstatic-alert-foreground: #aaaaaa\ntab-border: #cccccc\n modal-footer-border: <<colour tab-border>>\n modal-header-border: <<colour tab-border>>\n notification-border: <<colour tab-border>>\n sidebar-tab-border: <<colour tab-border>>\n tab-border-selected: <<colour tab-border>>\n sidebar-tab-border-selected: <<colour tab-border-selected>>\ntab-divider: #d8d8d8\n sidebar-tab-divider: <<colour tab-divider>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-border: #dddddd\ntiddler-subtitle-foreground: #c0c0c0\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/SolarizedDark": {
"title": "$:/palettes/SolarizedDark",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"description": "Precision dark colors for machines and people",
"license": "MIT, Ethan Schoonover, https://github.com/altercation/solarized/blob/master/LICENSE",
"name": "SolarizedDark",
"text": "alert-background: #073642\nalert-border: #93a1a1\nalert-highlight: #d33682\nalert-muted-foreground: #d33682\nbackground: #073642\nblockquote-bar: #d33682\nbutton-background: #073642\nbutton-border: #586e75\nbutton-foreground: #93a1a1\ncode-background: #073642\ncode-border: #586e75\ncode-foreground: #93a1a1\ndirty-indicator: inherit\ndownload-background: #859900\ndownload-foreground: #073642\ndragger-background: #073642\ndragger-foreground: #839496\ndropdown-background: #073642\ndropdown-border: #93a1a1\ndropdown-tab-background: #002b36\ndropdown-tab-background-selected: #073642\ndropzone-background: #859900\nexternal-link-background: inherit\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-foreground: #268bd2\nexternal-link-foreground-hover:\nexternal-link-foreground-visited: #268bd2\nforeground: #839496\nmessage-background: #002b36\nmessage-border: #586e75\nmessage-foreground: #839496\nmodal-backdrop: #657b83\nmodal-background: #002b36\nmodal-border: #586e75\nmodal-footer-background: #073642\nmodal-footer-border: #586e75\nmodal-header-border: #586e75\nmuted-foreground: #93a1a1\nnotification-background: #002b36\nnotification-border: #586e75\npage-background: #073642\npre-background: inherit\npre-border: #657b83\nprimary: #859900\nselect-tag-background: #002b36\nselect-tag-foreground: #839496\nsidebar-button-foreground: #93a1a1\nsidebar-controls-foreground: #93a1a1\nsidebar-controls-foreground-hover: #eee8d5\nsidebar-foreground: #93a1a1\nsidebar-foreground-shadow: transparent\nsidebar-muted-foreground: #839496\nsidebar-muted-foreground-hover: #93a1a1\nsidebar-tab-background: #002b36\nsidebar-tab-background-selected: #073642\nsidebar-tab-border: #073642\nsidebar-tab-border-selected: #839496\nsidebar-tab-divider: #002b36\nsidebar-tab-foreground: #657b83\nsidebar-tab-foreground-selected: #93a1a1\nsidebar-tiddler-link-foreground: #2aa198\nsidebar-tiddler-link-foreground-hover: #eee8d5\nsite-title-foreground: #d33682\nstatic-alert-foreground: #93a1a1\ntab-background: #073642\ntab-background-selected: #002b36\ntab-border: #586e75\ntab-border-selected: #93a1a1\ntab-divider: #93a1a1\ntab-foreground: #839496\ntab-foreground-selected: #93a1a1\ntable-border: #586e75\ntable-footer-background: #073642\ntable-header-background: #073642\ntag-background: #b58900\ntag-foreground: #002b36\ntiddler-background: #002b36\ntiddler-border: #586e75\ntiddler-controls-foreground: inherit\ntiddler-controls-foreground-hover: #d33682\ntiddler-controls-foreground-selected: #2aa198\ntiddler-editor-background: #002b36\ntiddler-editor-border: #073642\ntiddler-editor-border-image: #002b36\ntiddler-editor-fields-even: #002b36\ntiddler-editor-fields-odd: #073642\ntiddler-info-background: #073642\ntiddler-info-border: #657b83\ntiddler-info-tab-background: #002b36\ntiddler-link-background: #002b36\ntiddler-link-foreground: #2aa198\ntiddler-subtitle-foreground: #839496\ntiddler-title-foreground: #d33682\ntoolbar-cancel-button: #839496\ntoolbar-close-button: #839496\ntoolbar-delete-button: #dc322f\ntoolbar-done-button: #839496\ntoolbar-edit-button: #839496\ntoolbar-info-button: #839496\ntoolbar-new-button: #839496\ntoolbar-options-button: #839496\ntoolbar-save-button: inherit\nuntagged-background: #586e75\nvery-muted-foreground: #586e75\n"
},
"$:/palettes/SolarizedLight": {
"title": "$:/palettes/SolarizedLight",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"description": "Precision colors for machines and people",
"license": "MIT, Ethan Schoonover, https://github.com/altercation/solarized/blob/master/LICENSE",
"name": "SolarizedLight",
"text": "alert-background: #eee8d5\nalert-border: #586e75\nalert-highlight: #d33682\nalert-muted-foreground: #d33682\nbackground: #eee8d5\nblockquote-bar: #d33682\nbutton-background: #eee8d5\nbutton-border: #93a1a1\nbutton-foreground: #586e75\ncode-background: #eee8d5\ncode-border: #93a1a1\ncode-foreground: #586e75\ndirty-indicator: inherit\ndownload-background: #859900\ndownload-foreground: #eee8d5\ndragger-background: #eee8d5\ndragger-foreground: #657b83\ndropdown-background: #eee8d5\ndropdown-border: #586e75\ndropdown-tab-background: #fdf6e3\ndropdown-tab-background-selected: #eee8d5\ndropzone-background: #859900\nexternal-link-background: inherit\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-foreground: #268bd2\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #268bd2\nforeground: #657b83\nmessage-background: #fdf6e3\nmessage-border: #93a1a1\nmessage-foreground: #657b83\nmodal-backdrop: #839496\nmodal-background: #fdf6e3\nmodal-border: #93a1a1\nmodal-footer-background: #eee8d5\nmodal-footer-border: #93a1a1\nmodal-header-border: #93a1a1\nmuted-foreground: #586e75\nnotification-background: #fdf6e3\nnotification-border: #93a1a1\npage-background: #eee8d5\npre-background: #eee8d5\npre-border: #839496\nprimary: #859900\nselect-tag-background: #fdf6e3\nselect-tag-foreground: #657b83\nsidebar-button-foreground: #586e75\nsidebar-controls-foreground: #586e75\nsidebar-controls-foreground-hover: #d33682\nsidebar-foreground: #586e75\nsidebar-foreground-shadow: transparent\nsidebar-muted-foreground: #657b83\nsidebar-muted-foreground-hover: #586e75\nsidebar-tab-background: #fdf6e3\nsidebar-tab-background-selected: #eee8d5\nsidebar-tab-border: #eee8d5\nsidebar-tab-border-selected: #657b83\nsidebar-tab-divider: #fdf6e3\nsidebar-tab-foreground: #839496\nsidebar-tab-foreground-selected: #586e75\nsidebar-tiddler-link-foreground: #2aa198\nsidebar-tiddler-link-foreground-hover: #002b36\nsite-title-foreground: #d33682\nstatic-alert-foreground: #586e75\ntab-background: #eee8d5\ntab-background-selected: #fdf6e3\ntab-border: #93a1a1\ntab-border-selected: #586e75\ntab-divider: #586e75\ntab-foreground: #657b83\ntab-foreground-selected: #586e75\ntable-border: #93a1a1\ntable-footer-background: #eee8d5\ntable-header-background: #eee8d5\ntag-background: #b58900\ntag-foreground: #fdf6e3\ntiddler-background: #fdf6e3\ntiddler-border: #93a1a1\ntiddler-controls-foreground: inherit\ntiddler-controls-foreground-hover: #d33682\ntiddler-controls-foreground-selected: #2aa198\ntiddler-editor-background: #fdf6e3\ntiddler-editor-border: #eee8d5\ntiddler-editor-border-image: #fdf6e3\ntiddler-editor-fields-even: #fdf6e3\ntiddler-editor-fields-odd: #eee8d5\ntiddler-info-background: #eee8d5\ntiddler-info-border: #839496\ntiddler-info-tab-background: #fdf6e3\ntiddler-link-background: #fdf6e3\ntiddler-link-foreground: #2aa198\ntiddler-subtitle-foreground: #657b83\ntiddler-title-foreground: #d33682\ntoolbar-cancel-button: #657b83\ntoolbar-close-button: #657b83\ntoolbar-delete-button: #dc322f\ntoolbar-done-button: #657b83\ntoolbar-edit-button: #657b83\ntoolbar-info-button: #657b83\ntoolbar-new-button: #657b83\ntoolbar-options-button: #657b83\ntoolbar-save-button: inherit\nuntagged-background: #586e75\nvery-muted-foreground: #93a1a1\n"
},
"$:/palettes/SpartanDay": {
"title": "$:/palettes/SpartanDay",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"description": "Cold, spartan day colors",
"name": "Spartan Day",
"text": "alert-background: <<colour background>>\nalert-border: <<colour very-muted-foreground>>\nalert-highlight: <<colour very-muted-foreground>>\nalert-muted-foreground: <<colour muted-foreground>>\nbackground: #FAFAFA\nblockquote-bar: <<colour page-background>>\nbutton-background: transparent\nbutton-foreground: inherit\nbutton-border: <<colour tag-background>>\ncode-background: #ececec\ncode-border: #ececec\ncode-foreground: \ndirty-indicator: #c80000\ndownload-background: <<colour primary>>\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: #FFFFFF\ndropdown-border: <<colour dropdown-background>>\ndropdown-tab-background-selected: <<colour dropdown-background>>\ndropdown-tab-background: #F5F5F5\ndropzone-background: <<colour tag-background>>\nexternal-link-background-hover: transparent\nexternal-link-background-visited: transparent\nexternal-link-background: transparent\nexternal-link-foreground-hover: \nexternal-link-foreground-visited: \nexternal-link-foreground: \nforeground: rgba(0, 0, 0, 0.87)\nmessage-background: <<colour background>>\nmessage-border: <<colour very-muted-foreground>>\nmessage-foreground: rgba(0, 0, 0, 0.54)\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour very-muted-foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour very-muted-foreground>>\nmodal-header-border: <<colour very-muted-foreground>>\nmuted-foreground: rgba(0, 0, 0, 0.54)\nnotification-background: <<colour dropdown-background>>\nnotification-border: <<colour dropdown-background>>\npage-background: #f4f4f4\npre-background: #ececec\npre-border: #ececec\nprimary: #3949ab\nselect-tag-background: <<colour background>>\nselect-tag-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #aeaeae\nsidebar-controls-foreground: #c6c6c6\nsidebar-foreground-shadow: transparent\nsidebar-foreground: rgba(0, 0, 0, 0.54)\nsidebar-muted-foreground-hover: rgba(0, 0, 0, 0.54)\nsidebar-muted-foreground: rgba(0, 0, 0, 0.38)\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: transparent\nsidebar-tab-border-selected: <<colour table-border>>\nsidebar-tab-border: transparent\nsidebar-tab-divider: <<colour table-border>>\nsidebar-tab-foreground-selected: rgba(0, 0, 0, 0.87)\nsidebar-tab-foreground: rgba(0, 0, 0, 0.54)\nsidebar-tiddler-link-foreground-hover: rgba(0, 0, 0, 0.87)\nsidebar-tiddler-link-foreground: rgba(0, 0, 0, 0.54)\nsite-title-foreground: rgba(0, 0, 0, 0.87)\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: transparent\ntab-border-selected: <<colour table-border>>\ntab-border: transparent\ntab-divider: <<colour table-border>>\ntab-foreground-selected: rgba(0, 0, 0, 0.87)\ntab-foreground: rgba(0, 0, 0, 0.54)\ntable-border: #d8d8d8\ntable-footer-background: <<colour tiddler-editor-fields-odd>>\ntable-header-background: <<colour tiddler-editor-fields-even>>\ntag-background: #ec6\ntag-foreground: <<colour button-foreground>>\ntiddler-background: <<colour background>>\ntiddler-border: #f9f9f9\ntiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground: <<colour sidebar-controls-foreground>>\ntiddler-editor-background: transparent\ntiddler-editor-border-image: \ntiddler-editor-border: #e8e7e7\ntiddler-editor-fields-even: rgba(0, 0, 0, 0.1)\ntiddler-editor-fields-odd: rgba(0, 0, 0, 0.04)\ntiddler-info-background: #F5F5F5\ntiddler-info-border: #F5F5F5\ntiddler-info-tab-background: <<colour tiddler-editor-fields-odd>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour muted-foreground>>\ntiddler-title-foreground: #000000\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour very-muted-foreground>>\nvery-muted-foreground: rgba(0, 0, 0, 0.12)\n"
},
"$:/palettes/SpartanNight": {
"title": "$:/palettes/SpartanNight",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"description": "Dark spartan colors",
"name": "Spartan Night",
"text": "alert-background: <<colour background>>\nalert-border: <<colour very-muted-foreground>>\nalert-highlight: <<colour very-muted-foreground>>\nalert-muted-foreground: <<colour muted-foreground>>\nbackground: #303030\nblockquote-bar: <<colour page-background>>\nbutton-background: transparent\nbutton-foreground: inherit\nbutton-border: <<colour tag-background>>\ncode-background: <<colour pre-background>>\ncode-border: <<colour pre-border>>\ncode-foreground: rgba(255, 255, 255, 0.54)\ndirty-indicator: #c80000\ndownload-background: <<colour primary>>\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: #424242\ndropdown-border: <<colour dropdown-background>>\ndropdown-tab-background-selected: <<colour dropdown-background>>\ndropdown-tab-background: #050505\ndropzone-background: <<colour tag-background>>\nexternal-link-background-hover: transparent\nexternal-link-background-visited: transparent\nexternal-link-background: transparent\nexternal-link-foreground-hover: \nexternal-link-foreground-visited: #7c318c\nexternal-link-foreground: #9e3eb3\nforeground: rgba(255, 255, 255, 0.7)\nmessage-background: <<colour background>>\nmessage-border: <<colour very-muted-foreground>>\nmessage-foreground: rgba(255, 255, 255, 0.54)\nmodal-backdrop: <<colour page-background>>\nmodal-background: <<colour background>>\nmodal-border: <<colour very-muted-foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour background>>\nmodal-header-border: <<colour very-muted-foreground>>\nmuted-foreground: rgba(255, 255, 255, 0.54)\nnotification-background: <<colour dropdown-background>>\nnotification-border: <<colour dropdown-background>>\npage-background: #212121\npre-background: #2a2a2a\npre-border: transparent\nprimary: #5656f3\nselect-tag-background: <<colour background>>\nselect-tag-foreground: <<colour foreground>>\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #494949\nsidebar-controls-foreground: #5d5d5d\nsidebar-foreground-shadow: transparent\nsidebar-foreground: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground-hover: rgba(255, 255, 255, 0.54)\nsidebar-muted-foreground: rgba(255, 255, 255, 0.38)\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: transparent\nsidebar-tab-border-selected: <<colour table-border>>\nsidebar-tab-border: transparent\nsidebar-tab-divider: <<colour table-border>>\nsidebar-tab-foreground-selected: rgba(255, 255, 255, 0.87)\nsidebar-tab-foreground: rgba(255, 255, 255, 0.54)\nsidebar-tiddler-link-foreground-hover: rgba(255, 255, 255, 0.7)\nsidebar-tiddler-link-foreground: rgba(255, 255, 255, 0.54)\nsite-title-foreground: rgba(255, 255, 255, 0.7)\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: transparent\ntab-border-selected: <<colour table-border>>\ntab-border: transparent\ntab-divider: <<colour table-border>>\ntab-foreground-selected: rgba(255, 255, 255, 0.87)\ntab-foreground: rgba(255, 255, 255, 0.54)\ntable-border: #3a3a3a\ntable-footer-background: <<colour tiddler-editor-fields-odd>>\ntable-header-background: <<colour tiddler-editor-fields-even>>\ntag-background: #ec6\ntag-foreground: <<colour button-foreground>>\ntiddler-background: <<colour background>>\ntiddler-border: rgb(55,55,55)\ntiddler-controls-foreground-hover: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground-selected: <<colour sidebar-controls-foreground-hover>>\ntiddler-controls-foreground: <<colour sidebar-controls-foreground>>\ntiddler-editor-background: transparent\ntiddler-editor-border-image: \ntiddler-editor-border: rgba(255, 255, 255, 0.08)\ntiddler-editor-fields-even: rgba(255, 255, 255, 0.1)\ntiddler-editor-fields-odd: rgba(255, 255, 255, 0.04)\ntiddler-info-background: #454545\ntiddler-info-border: #454545\ntiddler-info-tab-background: <<colour tiddler-editor-fields-odd>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour muted-foreground>>\ntiddler-title-foreground: #FFFFFF\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour very-muted-foreground>>\nvery-muted-foreground: rgba(255, 255, 255, 0.12)\n"
},
"$:/palettes/Twilight": {
"title": "$:/palettes/Twilight",
"tags": "$:/tags/Palette",
"author": "Thomas Elmiger",
"type": "application/x-tiddler-dictionary",
"name": "Twilight",
"description": "Delightful, soft darkness.",
"text": "alert-background: rgb(255, 255, 102)\nalert-border: rgb(232, 232, 125)\nalert-highlight: rgb(255, 51, 51)\nalert-muted-foreground: rgb(224, 82, 82)\nbackground: rgb(38, 38, 38)\nblockquote-bar: rgba(240, 196, 117, 0.7)\nbutton-background: rgb(63, 63, 63)\nbutton-border: rgb(127, 127, 127)\nbutton-foreground: rgb(179, 179, 179)\ncode-background: rgba(0,0,0,0.03)\ncode-border: rgba(0,0,0,0.08)\ncode-foreground: rgb(255, 94, 94)\ndiff-delete-background: #ffc9c9\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #aaefad\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: rgb(255, 94, 94)\ndownload-background: #19a974\ndownload-foreground: rgb(38, 38, 38)\ndragger-background: rgb(179, 179, 179)\ndragger-foreground: rgb(38, 38, 38)\ndropdown-background: rgb(38, 38, 38)\ndropdown-border: rgb(255, 255, 255)\ndropdown-tab-background: rgba(0,0,0,.1)\ndropdown-tab-background-selected: rgba(255,255,255,1)\ndropzone-background: #9eebcf\nexternal-link-background: inherit\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-foreground: rgb(179, 179, 255)\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: rgb(153, 153, 255)\nforeground: rgb(179, 179, 179)\nmessage-background: <<colour tag-foreground>>\nmessage-border: #96ccff\nmessage-foreground: <<colour tag-background>>\nmodal-backdrop: rgb(179, 179, 179)\nmodal-background: rgb(38, 38, 38)\nmodal-border: rgba(0,0,0,.5)\nmodal-footer-background: #f4f4f4\nmodal-footer-border: rgba(0,0,0,.1)\nmodal-header-border: rgba(0,0,0,.2)\nmuted-foreground: rgb(255, 255, 255)\nnotification-background: <<colour tag-foreground>>\nnotification-border: <<colour tag-background>>\npage-background: rgb(26, 26, 26)\npre-background: rgb(25, 25, 25)\npre-border: rgba(0,0,0,.2)\nprimary: rgb(255, 201, 102)\nselect-tag-background: \nselect-tag-foreground: \nsidebar-button-foreground: rgb(179, 179, 179)\nsidebar-controls-foreground: rgb(153, 153, 153)\nsidebar-controls-foreground-hover: <<colour tiddler-controls-foreground-hover>>\nsidebar-foreground: rgb(141, 141, 141)\nsidebar-foreground-shadow: transparent\nsidebar-muted-foreground: rgba(0, 0, 0, 0.5)\nsidebar-muted-foreground-hover: rgb(141, 141, 141)\nsidebar-tab-background: rgba(141, 141, 141, 0.2)\nsidebar-tab-background-selected: rgb(26, 26, 26)\nsidebar-tab-border: rgb(127, 127, 127)\nsidebar-tab-border-selected: rgb(127, 127, 127)\nsidebar-tab-divider: rgb(127, 127, 127)\nsidebar-tab-foreground: rgb(179, 179, 179)\nsidebar-tab-foreground-selected: rgb(179, 179, 179)\nsidebar-tiddler-link-foreground: rgb(179, 179, 179)\nsidebar-tiddler-link-foreground-hover: rgb(115, 115, 115)\nsite-title-foreground: rgb(255, 201, 102)\nstatic-alert-foreground: rgba(0,0,0,.3)\ntab-background: rgba(0,0,0,0.125)\ntab-background-selected: rgb(38, 38, 38)\ntab-border: rgb(255, 201, 102)\ntab-border-selected: rgb(255, 201, 102)\ntab-divider: rgb(255, 201, 102)\ntab-foreground: rgb(179, 179, 179)\ntab-foreground-selected: rgb(179, 179, 179)\ntable-border: rgba(255,255,255,.3)\ntable-footer-background: rgba(0,0,0,.4)\ntable-header-background: rgba(0,0,0,.1)\ntag-background: rgb(255, 201, 102)\ntag-foreground: rgb(25, 25, 25)\ntiddler-background: rgb(38, 38, 38)\ntiddler-border: rgba(240, 196, 117, 0.7)\ntiddler-controls-foreground: rgb(128, 128, 128)\ntiddler-controls-foreground-hover: rgba(255, 255, 255, 0.8)\ntiddler-controls-foreground-selected: rgba(255, 255, 255, 0.9)\ntiddler-editor-background: rgb(33, 33, 33)\ntiddler-editor-border: rgb(63, 63, 63)\ntiddler-editor-border-image: rgb(25, 25, 25)\ntiddler-editor-fields-even: rgb(33, 33, 33)\ntiddler-editor-fields-odd: rgb(28, 28, 28)\ntiddler-info-background: rgb(43, 43, 43)\ntiddler-info-border: rgb(25, 25, 25)\ntiddler-info-tab-background: rgb(43, 43, 43)\ntiddler-link-background: rgb(38, 38, 38)\ntiddler-link-foreground: rgb(204, 204, 255)\ntiddler-subtitle-foreground: rgb(255, 255, 255)\ntiddler-title-foreground: rgb(255, 192, 76)\ntoolbar-cancel-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-done-button: \ntoolbar-edit-button: \ntoolbar-info-button: \ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \nuntagged-background: rgb(255, 255, 255)\nvery-muted-foreground: rgba(240, 196, 117, 0.7)\n"
},
"$:/palettes/Vanilla": {
"title": "$:/palettes/Vanilla",
"name": "Vanilla",
"description": "Pale and unobtrusive",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndiff-delete-background: #ffc9c9\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #aaefad\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #f4f4f4\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselection-background:\nselection-foreground:\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #aaaaaa\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #f4f4f4\nsidebar-tab-background: #e0e0e0\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: #e4e4e4\nsidebar-tab-foreground-selected:\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #999999\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\nwikilist-background: #e5e5e5\nwikilist-item: #fff\nwikilist-info: #000\nwikilist-title: #666\nwikilist-title-svg: <<colour wikilist-title>>\nwikilist-url: #aaa\nwikilist-button-open: #4fb82b\nwikilist-button-open-hover: green\nwikilist-button-reveal: #5778d8\nwikilist-button-reveal-hover: blue\nwikilist-button-remove: #d85778\nwikilist-button-remove-hover: red\nwikilist-toolbar-background: #d3d3d3\nwikilist-toolbar-foreground: #888\nwikilist-droplink-dragover: rgba(255,192,192,0.5)\nwikilist-button-background: #acacac\nwikilist-button-foreground: #000\n"
},
"$:/core/readme": {
"title": "$:/core/readme",
"text": "This plugin contains TiddlyWiki's core components, comprising:\n\n* JavaScript code modules\n* Icons\n* Templates needed to create TiddlyWiki's user interface\n* British English (''en-GB'') translations of the localisable strings used by the core\n"
},
"$:/library/sjcl.js/license": {
"title": "$:/library/sjcl.js/license",
"type": "text/plain",
"text": "SJCL is open. You can use, modify and redistribute it under a BSD\nlicense or under the GNU GPL, version 2.0.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/BSD-2-Clause\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/GPL-2.0\n\nThe Stanford Javascript Crypto Library (hosted here on GitHub) is a\nproject by the Stanford Computer Security Lab to build a secure,\npowerful, fast, small, easy-to-use, cross-browser library for\ncryptography in Javascript.\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University.\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation; either version 2 of the License, or (at your\noption) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\nPublic License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program; if not, write to the Free Software Foundation, Inc.,\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
},
"$:/core/templates/MOTW.html": {
"title": "$:/core/templates/MOTW.html",
"text": "\\rules only filteredtranscludeinline transcludeinline entity\n<!-- The following comment is called a MOTW comment and is necessary for the TiddlyIE Internet Explorer extension -->\n<!-- saved from url=(0021)https://tiddlywiki.com --> "
},
"$:/core/templates/alltiddlers.template.html": {
"title": "$:/core/templates/alltiddlers.template.html",
"type": "text/vnd.tiddlywiki-html",
"text": "<!-- This template is provided for backwards compatibility with older versions of TiddlyWiki -->\n\n<$set name=\"exportFilter\" value=\"[!is[system]sort[title]]\">\n\n{{$:/core/templates/exporters/StaticRiver}}\n\n</$set>\n"
},
"$:/core/templates/canonical-uri-external-image": {
"title": "$:/core/templates/canonical-uri-external-image",
"text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external images.\n\nChange the `./images/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./images/<$view field=\"title\" format=\"doubleurlencoded\"/>"
},
"$:/core/templates/canonical-uri-external-raw": {
"title": "$:/core/templates/canonical-uri-external-raw",
"text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external raw files that are stored in the same directory\n\n-->\n<$view field=\"title\" format=\"doubleurlencoded\"/>"
},
"$:/core/templates/canonical-uri-external-text": {
"title": "$:/core/templates/canonical-uri-external-text",
"text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external text files.\n\nChange the `./text/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./text/<$view field=\"title\" format=\"doubleurlencoded\"/>.tid"
},
"$:/core/templates/css-tiddler": {
"title": "$:/core/templates/css-tiddler",
"text": "<!--\n\nThis template is used for saving CSS tiddlers as a style tag with data attributes representing the tiddler fields.\n\n-->`<style`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/css\">`<$view field=\"text\" format=\"text\" />`</style>`"
},
"$:/core/templates/exporters/CsvFile": {
"title": "$:/core/templates/exporters/CsvFile",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/CsvFile}}",
"extension": ".csv",
"text": "<$macrocall $name=\"csvtiddlers\" filter=<<exportFilter>> format=\"quoted-comma-sep\" $output=\"text/raw\"/>\n"
},
"$:/core/templates/exporters/JsonFile": {
"title": "$:/core/templates/exporters/JsonFile",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/JsonFile}}",
"extension": ".json",
"text": "<$macrocall $name=\"jsontiddlers\" filter=<<exportFilter>> $output=\"text/raw\"/>\n"
},
"$:/core/templates/exporters/StaticRiver": {
"title": "$:/core/templates/exporters/StaticRiver",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/StaticRiver}}",
"extension": ".html",
"text": "\\define tv-wikilink-template() #$uri_encoded$\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n<section class=\"tc-story-river tc-static-story-river\">\n{{$:/core/templates/exporters/StaticRiver/Content||$:/core/templates/html-tiddler}}\n</section>\n</body>\n</html>\n"
},
"$:/core/templates/exporters/StaticRiver/Content": {
"title": "$:/core/templates/exporters/StaticRiver/Content",
"text": "\\define renderContent()\n{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<<renderContent>>\n"
},
"$:/core/templates/exporters/TidFile": {
"title": "$:/core/templates/exporters/TidFile",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/TidFile}}",
"extension": ".tid",
"condition": "[<count>compare:lte[1]]",
"text": "\\define renderContent()\n{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<<renderContent>>"
},
"$:/core/save/all-external-js": {
"title": "$:/core/save/all-external-js",
"text": "\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5-external-js.html}}\n"
},
"$:/core/templates/tiddlywiki5.js": {
"title": "$:/core/templates/tiddlywiki5.js",
"text": "\\rules only filteredtranscludeinline transcludeinline codeinline\n\n/*\n{{ $:/core/copyright.txt ||$:/core/templates/plain-text-tiddler}}\n`*/\n`<!--~~ Library modules ~~-->\n{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/plain-text-tiddler}}}\n<!--~~ Boot prefix ~~-->\n{{ $:/boot/bootprefix.js ||$:/core/templates/plain-text-tiddler}}\n<!--~~ Core plugin ~~-->\n{{$:/core/templates/tiddlywiki5.js/tiddlers}}\n<!--~~ Boot kernel ~~-->\n{{ $:/boot/boot.js ||$:/core/templates/plain-text-tiddler}}\n"
},
"$:/core/templates/tiddlywiki5.js/tiddlers": {
"title": "$:/core/templates/tiddlywiki5.js/tiddlers",
"text": "`\n$tw.preloadTiddlerArray(`<$text text=<<jsontiddlers \"[[$:/core]]\">>/>`);\n`\n"
},
"$:/core/templates/tiddlywiki5-external-js.html": {
"title": "$:/core/templates/tiddlywiki5-external-js.html",
"text": "\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n{{$:/core/templates/MOTW.html}}<html lang=\"`<$text text={{{ [{$:/language}get[name]] }}}/>`\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"{{$:/core/copyright.txt}}\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/core/wiki/rawmarkup]] [all[shadows+tiddlers]tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n{{$:/core/templates/static.area}}\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n{{$:/core/templates/store.area.template.html}}\n<!--~~ Raw markup for the bottom of the body section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}\n</body>\n<script src=\"%24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js\" onerror=\"alert('Error: Cannot load tiddlywiki.js');\"></script>\n</html>\n"
},
"$:/core/templates/html-div-skinny-tiddler": {
"title": "$:/core/templates/html-div-skinny-tiddler",
"text": "<!--\n\nThis template is a variant of $:/core/templates/html-div-tiddler used for saving skinny tiddlers (with no text field)\n\n-->`<div`<$fields template=' $name$=\"$encoded_value$\"'></$fields>`>\n<pre></pre>\n</div>`\n"
},
"$:/core/templates/html-div-tiddler": {
"title": "$:/core/templates/html-div-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as an HTML DIV tag with attributes representing the tiddler fields.\n\n-->`<div`<$fields template=' $name$=\"$encoded_value$\"'></$fields>`>\n<pre>`<$view field=\"text\" format=\"htmlencoded\" />`</pre>\n</div>`\n"
},
"$:/core/templates/html-tiddler": {
"title": "$:/core/templates/html-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as raw HTML\n\n--><$view field=\"text\" format=\"htmlwikified\" />"
},
"$:/core/templates/javascript-tiddler": {
"title": "$:/core/templates/javascript-tiddler",
"text": "<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields.\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\">`<$view field=\"text\" format=\"text\" />`</script>`"
},
"$:/core/templates/json-tiddler": {
"title": "$:/core/templates/json-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as raw JSON\n\n--><$text text=<<jsontiddler>>/>"
},
"$:/core/templates/module-tiddler": {
"title": "$:/core/templates/module-tiddler",
"text": "<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields. The body of the tiddler is wrapped in a call to the `$tw.modules.define` function in order to define the body of the tiddler as a module\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\" data-module=\"yes\">$tw.modules.define(\"`<$view field=\"title\" format=\"jsencoded\" />`\",\"`<$view field=\"module-type\" format=\"jsencoded\" />`\",function(module,exports,require) {`<$view field=\"text\" format=\"text\" />`});\n</script>`"
},
"$:/core/templates/plain-text-tiddler": {
"title": "$:/core/templates/plain-text-tiddler",
"text": "<$view field=\"text\" format=\"text\" />"
},
"$:/core/templates/raw-static-tiddler": {
"title": "$:/core/templates/raw-static-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as static HTML\n\n--><$view field=\"text\" format=\"plainwikified\" />"
},
"$:/core/save/all": {
"title": "$:/core/save/all",
"text": "\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/save/empty": {
"title": "$:/core/save/empty",
"text": "\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/save/lazy-all": {
"title": "$:/core/save/lazy-all",
"text": "\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] \n\\end\n\\define skinnySaveTiddlerFilter()\n[!is[system]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/save/lazy-images": {
"title": "$:/core/save/lazy-images",
"text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]] \n\\end\n\\define skinnySaveTiddlerFilter()\n[is[image]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/templates/server/static.sidebar.wikitext": {
"title": "$:/core/templates/server/static.sidebar.wikitext",
"text": "\\whitespace trim\n<div class=\"tc-sidebar-scrollable\" style=\"overflow: auto;\">\n<div class=\"tc-sidebar-header\">\n<h1 class=\"tc-site-title\">\n<$transclude tiddler=\"$:/SiteTitle\"/>\n</h1>\n<div class=\"tc-site-subtitle\">\n<$transclude tiddler=\"$:/SiteSubtitle\"/>\n</div>\n<h2>\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$list filter={{$:/DefaultTiddlers}}>\n<div class=\"tc-menu-list-subitem\">\n<$link><$text text=<<currentTiddler>>/></$link>\n</div>\n</$list>\n</div>\n<!-- Currently disabled the recent list as it is unweildy when the responsive narrow view kicks in\n<h2>\n{{$:/language/SideBar/Recent/Caption}}\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n</div>\n</div>\n</div>\n-->\n"
},
"$:/core/templates/server/static.tiddler.html": {
"title": "$:/core/templates/server/static.tiddler.html",
"text": "\\whitespace trim\n\\define tv-wikilink-template() $uri_encoded$\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content={{$:/core/templates/version}} />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"%24%3A%2Fcore%2Ftemplates%2Fstatic.template.css\">\n<title><$view field=\"caption\" format=\"plainwikified\"><$view field=\"title\"/></$view>: <$view tiddler=\"$:/core/wiki/title\" format=\"plainwikified\"/></title>\n</head>\n<body class=\"tc-body\">\n<$transclude tiddler=\"$:/core/templates/server/static.sidebar.wikitext\" mode=\"inline\"/>\n<section class=\"tc-story-river\">\n<div class=\"tc-tiddler-frame\">\n<$transclude tiddler=\"$:/core/templates/server/static.tiddler.wikitext\" mode=\"inline\"/>\n</div>\n</section>\n</body>\n</html>"
},
"$:/core/templates/server/static.tiddler.wikitext": {
"title": "$:/core/templates/server/static.tiddler.wikitext",
"text": "\\whitespace trim\n<div class=\"tc-tiddler-title\">\n<div class=\"tc-titlebar\">\n<h2><$text text=<<currentTiddler>>/></h2>\n</div>\n</div>\n<div class=\"tc-subtitle\">\n<$link to={{!!modifier}}>\n<$view field=\"modifier\"/>\n</$link> <$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n<div class=\"tc-tags-wrapper\">\n<$list filter=\"[all[current]tags[]sort[title]]\">\n<a href={{{ [<currentTiddler>encodeuricomponent[]] }}}>\n<$macrocall $name=\"tag-pill\" tag=<<currentTiddler>>/>\n</a>\n</$list>\n</div>\n<div class=\"tc-tiddler-body\">\n<$transclude mode=\"block\"/>\n</div>\n"
},
"$:/core/templates/single.tiddler.window": {
"title": "$:/core/templates/single.tiddler.window",
"text": "\\whitespace trim\n\\define containerClasses()\ntc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$vars\n\ttv-config-toolbar-icons={{$:/config/Toolbar/Icons}}\n\ttv-config-toolbar-text={{$:/config/Toolbar/Text}}\n\ttv-config-toolbar-class={{$:/config/Toolbar/ButtonClass}}\n\ttv-show-missing-links={{$:/config/MissingLinks}}\n\tstoryviewTitle={{$:/view}}\n\tlanguageTitle={{{ [{$:/language}get[name]] }}}>\n\n<div class=<<containerClasses>>>\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n\n<$transclude mode=\"block\"/>\n\n</$navigator>\n\n</div>\n\n</$vars>\n"
},
"$:/core/templates/split-recipe": {
"title": "$:/core/templates/split-recipe",
"text": "<$list filter=\"[!is[system]]\">\ntiddler: <$view field=\"title\" format=\"urlencoded\"/>.tid\n</$list>\n"
},
"$:/core/templates/static-tiddler": {
"title": "$:/core/templates/static-tiddler",
"text": "<a name=<<currentTiddler>>>\n<$transclude tiddler=\"$:/core/ui/ViewTemplate\"/>\n</a>"
},
"$:/core/templates/static.area": {
"title": "$:/core/templates/static.area",
"text": "<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawStaticContent]!has[draft.of]] ||$:/core/templates/raw-static-tiddler}}}\n{{$:/core/templates/static.content||$:/core/templates/html-tiddler}}\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\nThis file contains an encrypted ~TiddlyWiki. Enable ~JavaScript and enter the decryption password when prompted.\n</$reveal>\n<!-- ensure splash screen isn't shown when JS is disabled -->\n`<style>\n.tc-remove-when-wiki-loaded {display: none;}\n</style>`\n"
},
"$:/core/templates/static.content": {
"title": "$:/core/templates/static.content",
"text": "<!-- For Google, and people without JavaScript-->\nThis [[TiddlyWiki|https://tiddlywiki.com]] contains the following tiddlers:\n\n<ul>\n<$list filter=<<saveTiddlerFilter>>>\n<li><$view field=\"title\" format=\"text\"></$view></li>\n</$list>\n</ul>\n"
},
"$:/core/templates/static.template.css": {
"title": "$:/core/templates/static.template.css",
"text": "{{$:/boot/boot.css||$:/core/templates/plain-text-tiddler}}\n\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n"
},
"$:/core/templates/static.template.html": {
"title": "$:/core/templates/static.template.html",
"type": "text/vnd.tiddlywiki-html",
"text": "\\define tv-wikilink-template() static/$uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n{{$:/core/ui/PageTemplate||$:/core/templates/html-tiddler}}\n</body>\n</html>\n"
},
"$:/core/templates/static.tiddler.html": {
"title": "$:/core/templates/static.tiddler.html",
"text": "\\define tv-wikilink-template() $uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n`<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"static.css\">\n<title>`<$view field=\"caption\"><$view field=\"title\"/></$view>: {{$:/core/wiki/title}}`</title>\n</head>\n<body class=\"tc-body\">\n`{{$:/StaticBanner||$:/core/templates/html-tiddler}}`\n<section class=\"tc-story-river tc-static-story-river\">\n`<$view tiddler=\"$:/core/ui/ViewTemplate\" format=\"htmlwikified\"/>`\n</section>\n</body>\n</html>\n`\n"
},
"$:/core/templates/store.area.template.html": {
"title": "$:/core/templates/store.area.template.html",
"text": "<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n`<div id=\"storeArea\" style=\"display:none;\">`\n<$list filter=<<saveTiddlerFilter>> template=\"$:/core/templates/html-div-tiddler\"/>\n<$list filter={{{ [<skinnySaveTiddlerFilter>] }}} template=\"$:/core/templates/html-div-skinny-tiddler\"/>\n`</div>`\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n`<!--~~ Encrypted tiddlers ~~-->`\n`<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">`\n<$encrypt filter=<<saveTiddlerFilter>>/>\n`</pre>`\n</$reveal>"
},
"$:/core/templates/tid-tiddler": {
"title": "$:/core/templates/tid-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers in TiddlyWeb *.tid format\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>`\n`<$view field=\"text\" format=\"text\" />"
},
"$:/core/templates/tiddler-metadata": {
"title": "$:/core/templates/tiddler-metadata",
"text": "<!--\n\nThis template is used for saving tiddler metadata *.meta files\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>"
},
"$:/core/templates/tiddlywiki5.html": {
"title": "$:/core/templates/tiddlywiki5.html",
"text": "<$set name=\"saveTiddlerAndShadowsFilter\" filter=\"[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]\">\n`<!doctype html>\n`{{$:/core/templates/MOTW.html}}`<html lang=\"`<$text text={{{ [{$:/language}get[name]] }}}/>`\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n`{{{ [<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"`{{$:/core/copyright.txt}}`\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>`{{$:/core/wiki/title}}`</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n`{{$:/core/templates/static.area}}`\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n`{{$:/core/templates/store.area.template.html}}`\n<!--~~ Library modules ~~-->\n<div id=\"libraryModules\" style=\"display:none;\">\n`{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/javascript-tiddler}}}`\n</div>\n<!--~~ Boot kernel prologue ~~-->\n<div id=\"bootKernelPrefix\" style=\"display:none;\">\n`{{ $:/boot/bootprefix.js ||$:/core/templates/javascript-tiddler}}`\n</div>\n<!--~~ Boot kernel ~~-->\n<div id=\"bootKernel\" style=\"display:none;\">\n`{{ $:/boot/boot.js ||$:/core/templates/javascript-tiddler}}`\n</div>\n<!--~~ Raw markup for the bottom of the body section ~~-->\n`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`\n</body>\n</html>`\n"
},
"$:/core/templates/version": {
"title": "$:/core/templates/version",
"text": "<<version>>"
},
"$:/core/templates/wikified-tiddler": {
"title": "$:/core/templates/wikified-tiddler",
"text": "<$transclude />"
},
"$:/core/ui/AboveStory/tw2-plugin-check": {
"title": "$:/core/ui/AboveStory/tw2-plugin-check",
"tags": "$:/tags/AboveStory",
"text": "\\define lingo-base() $:/language/AboveStory/ClassicPlugin/\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]limit[1]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n<ul>\n\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]]\">\n\n<li>\n\n<$link><$view field=\"title\"/></$link>\n\n</li>\n\n</$list>\n\n</ul>\n\n</div>\n\n</$list>\n"
},
"$:/core/ui/Actions/new-image": {
"title": "$:/core/ui/Actions/new-image",
"tags": "$:/tags/Actions",
"description": "create a new image tiddler",
"text": "\\define get-type()\nimage/$(imageType)$\n\\end\n\\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$\n<$vars imageType={{$:/config/NewImageType}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}>\n<$action-sendmessage $message=\"tm-new-tiddler\" type=<<get-type>> tags=<<get-tags>>/>\n</$vars>\n"
},
"$:/core/ui/Actions/new-journal": {
"title": "$:/core/ui/Actions/new-journal",
"tags": "$:/tags/Actions",
"description": "create a new journal tiddler",
"text": "\\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$\n<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}>\n<$wikify name=\"journalTitle\" text=\"\"\"<$macrocall $name=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$reveal type=\"nomatch\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>\n</$reveal>\n<$reveal type=\"match\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<get-tags>> text=<<journalText>>/>\n</$reveal>\n</$wikify>\n</$vars>\n"
},
"$:/core/ui/Actions/new-tiddler": {
"title": "$:/core/ui/Actions/new-tiddler",
"tags": "$:/tags/Actions",
"description": "create a new empty tiddler",
"text": "\\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$\n<$vars textFieldTags={{$:/config/NewTiddler/Tags}} tagsFieldTags={{$:/config/NewTiddler/Tags!!tags}}>\n<$action-sendmessage $message=\"tm-new-tiddler\" tags=<<get-tags>>/>\n</$vars>\n"
},
"$:/core/ui/AdvancedSearch/Filter": {
"title": "$:/core/ui/AdvancedSearch/Filter",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/Filter/Caption}}",
"text": "\\define lingo-base() $:/language/Search/\n\\define set-next-input-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab--1498284803\" tag=\"$:/tags/AdvancedSearch\" beforeafter=\"$beforeafter$\" defaultState=\"$:/core/ui/AdvancedSearch/System\" actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define cancel-search-actions() <$list filter=\"[{$:/temp/advancedsearch/input}!match{$:/temp/advancedsearch}]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]\" />\"\"\"><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/></$list>\n\n\\define input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\n\n\\define input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\n\n<<lingo Filter/Hint>>\n\n<div class=\"tc-search tc-advanced-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">>>\n<$macrocall $name=\"keyboard-driven-input\" tiddler=\"$:/temp/advancedsearch/input\" storeTitle=\"$:/temp/advancedsearch\" \n\t\trefreshTitle=\"$:/temp/advancedsearch/refresh\" selectionStateTitle=\"$:/temp/advancedsearch/selected-item\" type=\"search\" \n\t\ttag=\"input\" focus={{$:/config/Search/AutoFocus}} configTiddlerFilter=\"[[$:/temp/advancedsearch]]\" firstSearchFilterField=\"text\" \n\t\tinputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>> \n\t\tinputCancelActions=<<cancel-search-actions>>/>\n</$keyboard>\n</$keyboard>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]\"><$transclude/></$list>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\n<div class=\"tc-search-results\">\n<<lingo Filter/Matches>>\n<$list filter={{$:/temp/advancedsearch}}>\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[[$:/temp/advancedsearch/selected-item]get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n</div>\n</$set>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\".tc-advanced-search input\"\"\" />\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button popup=<<qualify \"$:/state/filterDeleteDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/delete-button}}\n</$button>\n</$reveal>\n\n<$reveal state=<<qualify \"$:/state/filterDeleteDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<div class=\"tc-dropdown-item-plain\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\nAre you sure you wish to delete <<resultCount>> tiddler(s)?\n</$set>\n</div>\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn\">\n<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>\nDelete these tiddlers\n</$button>\n</div>\n</div>\n</div>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/filterDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</span>\n\n<$reveal state=<<qualify \"$:/state/filterDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher actions=\"\"\"<$action-setfield $tiddler=\"$:/temp/advancedsearch\" text=<<navigateTo>>/><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text=<<navigateTo>>/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/><$action-sendmessage $message=\"tm-focus-selector\" $param='.tc-advanced-search input' />\"\"\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Filter]]\"><$link to={{!!filter}}><$transclude field=\"description\"/></$link>\n</$list>\n</div>\n</div>\n</$linkcatcher>\n</$set>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/export": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/export",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$macrocall $name=\"exportButton\" exportFilter={{$:/temp/advancedsearch}} lingoBase=\"$:/language/Buttons/ExportTiddlers/\"/>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Shadows": {
"title": "$:/core/ui/AdvancedSearch/Shadows",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/Shadows/Caption}}",
"first-search-filter": "[all[shadows]search<userInput>sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]]",
"text": "\\define lingo-base() $:/language/Search/\n\n\\define set-next-input-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab--1498284803\" tag=\"$:/tags/AdvancedSearch\" beforeafter=\"$beforeafter$\" defaultState=\"$:/core/ui/AdvancedSearch/System\" actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define cancel-search-actions() <$list filter=\"[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]\" />\"\"\"><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/></$list><$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\".tc-advanced-search input\"\"\"/>\n\n\\define input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\n\n\\define input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\n\n<<lingo Shadows/Hint>>\n\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">>>\n<$macrocall $name=\"keyboard-driven-input\" tiddler=\"$:/temp/advancedsearch/input\" storeTitle=\"$:/temp/advancedsearch\"\n\t\trefreshTitle=\"$:/temp/advancedsearch/refresh\" selectionStateTitle=\"$:/temp/advancedsearch/selected-item\" type=\"search\"\n\t\ttag=\"input\" focus={{$:/config/Search/AutoFocus}} configTiddlerFilter=\"[[$:/core/ui/AdvancedSearch/Shadows]]\"\n\t\tinputCancelActions=<<cancel-search-actions>> inputAcceptActions=<<input-accept-actions>> \n\t\tinputAcceptVariantActions=<<input-accept-variant-actions>> filterMinLength={{$:/config/Search/MinLength}}/>\n</$keyboard>\n</$keyboard>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[all[shadows]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]]\"/>\"\"\">\n\n<div class=\"tc-search-results\">\n\n<<lingo Shadows/Matches>>\n\n<$list filter=\"[all[shadows]search{$:/temp/advancedsearch}sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]]\">\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[[$:/temp/advancedsearch/selected-item]get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Standard": {
"title": "$:/core/ui/AdvancedSearch/Standard",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/Standard/Caption}}",
"text": "\\define lingo-base() $:/language/Search/\n\\define set-next-input-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab--1498284803\" tag=\"$:/tags/AdvancedSearch\" beforeafter=\"$beforeafter$\" defaultState=\"$:/core/ui/AdvancedSearch/System\" actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define next-search-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/advancedsearch\" tag=\"$:/tags/SearchResults\" beforeafter=\"$beforeafter$\" defaultState={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/standard/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define cancel-search-actions() <$list filter=\"[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]\" />\"\"\"><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/></$list><$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\".tc-advanced-search input\"\"\"/>\n\n\\define input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\n\n\\define input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\n\n<<lingo Standard/Hint>>\n\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">>>\n<$keyboard key=\"shift-alt-Right\" actions=<<next-search-tab>>>\n<$keyboard key=\"shift-alt-Left\" actions=<<next-search-tab \"before\">>>\n<$macrocall $name=\"keyboard-driven-input\" tiddler=\"$:/temp/advancedsearch/input\" storeTitle=\"$:/temp/advancedsearch\"\n\t\trefreshTitle=\"$:/temp/advancedsearch/refresh\" selectionStateTitle=\"$:/temp/advancedsearch/selected-item\" type=\"search\"\n\t\ttag=\"input\" focus={{$:/config/Search/AutoFocus}} inputCancelActions=<<cancel-search-actions>> \n\t\tinputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>> \n\t\tconfigTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]\"\n\t\tfilterMinLength={{$:/config/Search/MinLength}}/>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$vars userInput={{{ [[$:/temp/advancedsearch]get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}} searchListState=\"$:/temp/advancedsearch/selected-item\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\" emptyMessage=\"\"\"\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\">\n<$transclude/>\n</$list>\n\"\"\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\" default={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/standard/currentTab\" text=<<currentTab>>/>\"\"\" explicitState=\"$:/state/tab/search-results/advancedsearch\" />\n</$list>\n</$vars>\n</$list>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/System": {
"title": "$:/core/ui/AdvancedSearch/System",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/System/Caption}}",
"first-search-filter": "[is[system]search<userInput>sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]",
"text": "\\define lingo-base() $:/language/Search/\n\\define set-next-input-tab(beforeafter:\"after\",stateTitle,tag,defaultState,currentTabTiddler) <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab--1498284803\" tag=\"$:/tags/AdvancedSearch\" beforeafter=\"$beforeafter$\" defaultState=\"$:/core/ui/AdvancedSearch/System\" actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define cancel-search-actions() <$list filter=\"[{$:/temp/advancedsearch}!match{$:/temp/advancedsearch/input}]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[[$:/temp/advancedsearch]] [[$:/temp/advancedsearch/input]] [[$:/temp/advancedsearch/selected-item]]\" />\"\"\"><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/advancedsearch}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/></$list><$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\".tc-advanced-search input\"\"\"/>\n\n\\define input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\n\n\\define input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\n\n<<lingo System/Hint>>\n\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">>>\n<$macrocall $name=\"keyboard-driven-input\" tiddler=\"$:/temp/advancedsearch/input\" storeTitle=\"$:/temp/advancedsearch\"\n\t\trefreshTitle=\"$:/temp/advancedsearch/refresh\" selectionStateTitle=\"$:/temp/advancedsearch/selected-item\"\n\t\ttype=\"search\" tag=\"input\" focus={{$:/config/Search/AutoFocus}} configTiddlerFilter=\"[[$:/core/ui/AdvancedSearch/System]]\"\n\t\tinputCancelActions=<<cancel-search-actions>> inputAcceptActions=<<input-accept-actions>> \n\t\tinputAcceptVariantActions=<<input-accept-variant-actions>> filterMinLength={{$:/config/Search/MinLength}}/>\n</$keyboard>\n</$keyboard>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[is[system]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]\"/>\"\"\">\n\n<div class=\"tc-search-results\">\n\n<<lingo System/Matches>>\n\n<$list filter=\"[is[system]search{$:/temp/advancedsearch}sort[title]limit[250]] -[[$:/temp/advancedsearch]] -[[$:/temp/advancedsearch/input]] -[[$:/temp/advancedsearch/selected-item]]\">\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[[$:/temp/advancedsearch/selected-item]get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
},
"$:/AdvancedSearch": {
"title": "$:/AdvancedSearch",
"icon": "$:/core/images/advanced-search-button",
"color": "#bbb",
"text": "<div class=\"tc-advanced-search\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]\" default=\"$:/core/ui/AdvancedSearch/System\" actions=\"\"\"<$action-setfield $tiddler=\"$:/state/advancedsearch/currentTab\" text=<<currentTab>>/>\"\"\" explicitState=\"$:/state/tab--1498284803\"/>\n</div>\n"
},
"$:/core/ui/AlertTemplate": {
"title": "$:/core/ui/AlertTemplate",
"text": "<div class=\"tc-alert\">\n<div class=\"tc-alert-toolbar\">\n<$button class=\"tc-btn-invisible\"><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/cancel-button}}</$button>\n</div>\n<div class=\"tc-alert-subtitle\">\n<$wikify name=\"format\" text=<<lingo Tiddler/DateFormat>>>\n<$view field=\"component\"/> - <$view field=\"modified\" format=\"date\" template=<<format>>/> <$reveal type=\"nomatch\" state=\"!!count\" text=\"\"><span class=\"tc-alert-highlight\">({{$:/language/Count}}: <$view field=\"count\"/>)</span></$reveal>\n</$wikify>\n</div>\n<div class=\"tc-alert-body\">\n\n<$transclude/>\n\n</div>\n</div>\n"
},
"$:/core/ui/BinaryWarning": {
"title": "$:/core/ui/BinaryWarning",
"text": "\\define lingo-base() $:/language/BinaryWarning/\n<<lingo Prompt>>\n"
},
"$:/core/ui/Components/plugin-info": {
"title": "$:/core/ui/Components/plugin-info",
"text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define popup-state-macro()\n$(qualified-state)$-$(currentTiddler)$\n\\end\n\n\\define tabs-state-macro()\n$(popup-state)$-$(pluginInfoType)$\n\\end\n\n\\define plugin-icon-title()\n$(currentTiddler)$/icon\n\\end\n\n\\define plugin-disable-title()\n$:/config/Plugins/Disabled/$(currentTiddler)$\n\\end\n\n\\define plugin-table-body(type,disabledMessage,default-popup-state)\n<div class=\"tc-plugin-info-chunk tc-plugin-info-toggle\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/chevron-right}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-icon\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>\n<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\n</$transclude>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-description\">\n<h1>\n''<$text text={{{ [<currentTiddler>get[name]] ~[<currentTiddler>split[/]last[1]] }}}/>'': <$view field=\"description\"><$view field=\"title\"/></$view> $disabledMessage$\n</h1>\n<h2>\n<$view field=\"title\"/>\n</h2>\n<h2>\n<div><em><$view field=\"version\"/></em></div>\n</h2>\n</div>\n\\end\n\n\\define plugin-info(type,default-popup-state)\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n<$link to={{!!title}} class=\"tc-plugin-info\">\n<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\">>\n</$link>\n</$reveal>\n<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n<$link to={{!!title}} class=\"tc-plugin-info tc-plugin-info-disabled\">\n<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\" disabledMessage:\"<$macrocall $name='lingo' title='Disabled/Status'/>\">>\n</$link>\n</$reveal>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>> default=\"\"\"$default-popup-state$\"\"\">\n<div class=\"tc-plugin-info-dropdown\">\n<div class=\"tc-plugin-info-dropdown-body\">\n<$list filter=\"[all[current]] -[[$:/core]]\">\n<div style=\"float:right;\">\n<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n<$button set=<<plugin-disable-title>> setTo=\"yes\" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>\n<<lingo Disable/Caption>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n<$button set=<<plugin-disable-title>> setTo=\"no\" tooltip={{$:/language/ControlPanel/Plugins/Enable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>\n<<lingo Enable/Caption>>\n</$button>\n</$reveal>\n</div>\n</$list>\n<$set name=\"tabsList\" filter=\"[<currentTiddler>list[]] contents\">\n<$macrocall $name=\"tabs\" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template=\"$:/core/ui/PluginInfo\"/>\n</$set>\n</div>\n</div>\n</$reveal>\n</$set>\n\\end\n\n<$macrocall $name=\"plugin-info\" type=<<plugin-type>> default-popup-state=<<default-popup-state>>/>\n"
},
"$:/core/ui/Components/tag-link": {
"title": "$:/core/ui/Components/tag-link",
"text": "<$link>\n<$set name=\"backgroundColor\" value={{!!color}}>\n<span style=<<tag-styles>> class=\"tc-tag-label\">\n<$view field=\"title\" format=\"text\"/>\n</span>\n</$set>\n</$link>"
},
"$:/core/ui/ControlPanel/Advanced": {
"title": "$:/core/ui/ControlPanel/Advanced",
"tags": "$:/tags/ControlPanel/Info",
"caption": "{{$:/language/ControlPanel/Advanced/Caption}}",
"text": "{{$:/language/ControlPanel/Advanced/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/TiddlerFields\" explicitState=\"$:/state/tab--959111941\"/>\n</div>\n"
},
"$:/core/ui/ControlPanel/Appearance": {
"title": "$:/core/ui/ControlPanel/Appearance",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Appearance/Caption}}",
"text": "{{$:/language/ControlPanel/Appearance/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Theme\" explicitState=\"$:/state/tab--1963855381\"/>\n</div>\n"
},
"$:/core/ui/ControlPanel/Basics": {
"title": "$:/core/ui/ControlPanel/Basics",
"tags": "$:/tags/ControlPanel/Info",
"caption": "{{$:/language/ControlPanel/Basics/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Basics/\n\n\\define show-filter-count(filter)\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $value=\"\"\"$filter$\"\"\"/>\n<$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" $value=\"\"\"$filter$\"\"\"/>\n<$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/>\n<$action-setfield $tiddler=\"$:/state/tab--1498284803\" $value=\"$:/core/ui/AdvancedSearch/Filter\"/>\n<$action-navigate $to=\"$:/AdvancedSearch\"/>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-advanced-search input\"/>\n''<$count filter=\"\"\"$filter$\"\"\"/>''\n{{$:/core/images/advanced-search-button}}\n</$button>\n\\end\n\n|<<lingo Version/Prompt>> |''<<version>>'' |\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/status/UserName\"><<lingo Username/Prompt>></$link> |<$edit-text tiddler=\"$:/status/UserName\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/AnimationDuration\"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler=\"$:/config/AnimationDuration\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\" class=\"tc-edit-texteditor\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n|<$link to=\"$:/language/DefaultNewTiddlerTitle\"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/language/DefaultNewTiddlerTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Title\"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/config/NewJournal/Title\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Text\"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler=\"$:/config/NewJournal/Text\" tag=\"textarea\" class=\"tc-edit-texteditor\" default=\"\"/> |\n|<$link to=\"$:/config/NewTiddler/Tags\"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler=\"$:/config/NewTiddler/Tags\" tagField=\"text\">{{||$:/core/ui/EditTemplate/tags}}<$list filter=\"[<currentTiddler>tags[]] +[limit[1]]\" variable=\"ignore\"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field=\"text\" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=\"\"/></$button></$list></$vars> |\n|<$link to=\"$:/config/NewJournal/Tags\"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler=\"$:/config/NewJournal/Tags\" tagField=\"text\">{{||$:/core/ui/EditTemplate/tags}}<$list filter=\"[<currentTiddler>tags[]] +[limit[1]]\" variable=\"ignore\"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field=\"text\" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=\"\"/></$button></$list></$vars> |\n|<$link to=\"$:/config/AutoFocus\"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} |\n|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |\n|<<lingo Tiddlers/Prompt>> |<<show-filter-count \"[!is[system]sort[title]]\">> |\n|<<lingo Tags/Prompt>> |<<show-filter-count \"[tags[]sort[title]]\">> |\n|<<lingo SystemTiddlers/Prompt>> |<<show-filter-count \"[is[system]sort[title]]\">> |\n|<<lingo ShadowTiddlers/Prompt>> |<<show-filter-count \"[all[shadows]sort[title]]\">> |\n|<<lingo OverriddenShadowTiddlers/Prompt>> |<<show-filter-count \"[is[tiddler]is[shadow]sort[title]]\">> |\n"
},
"$:/core/ui/ControlPanel/EditorTypes": {
"title": "$:/core/ui/ControlPanel/EditorTypes",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/EditorTypes/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/EditorTypes/\n\n<<lingo Hint>>\n\n<table>\n<tbody>\n<tr>\n<th><<lingo Type/Caption>></th>\n<th><<lingo Editor/Caption>></th>\n</tr>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/config/EditorTypeMappings/]sort[title]]\">\n<tr>\n<td>\n<$link>\n<$list filter=\"[all[current]removeprefix[$:/config/EditorTypeMappings/]]\">\n<$text text={{!!title}}/>\n</$list>\n</$link>\n</td>\n<td>\n<$view field=\"text\"/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ControlPanel/Info": {
"title": "$:/core/ui/ControlPanel/Info",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Info/Caption}}",
"text": "{{$:/language/ControlPanel/Info/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Info]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Basics\" explicitState=\"$:/state/tab--2112689675\"/>\n</div>\n"
},
"$:/core/ui/ControlPanel/KeyboardShortcuts": {
"title": "$:/core/ui/ControlPanel/KeyboardShortcuts",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/KeyboardShortcuts/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/KeyboardShortcuts/\n\n\\define new-shortcut(title)\n<div class=\"tc-dropdown-item-plain\">\n<$edit-shortcut tiddler=\"$title$\" placeholder={{$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt}} focus=\"true\" style=\"width:auto;\"/> <$button>\n<<lingo Add/Caption>>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"[{$title$}]\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"$title$\"\n/>\n</$button>\n</div>\n\\end\n\n\\define shortcut-list-item(caption)\n<td>\n</td>\n<td style=\"text-align:right;font-size:0.7em;\">\n<<lingo Platform/$caption$>>\n</td>\n<td>\n<div style=\"position:relative;\">\n<$button popup=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> class=\"tc-btn-invisible\">\n{{$:/core/images/edit-button}}\n</$button>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutTitle)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\n<$reveal state=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown tc-popup-keep\">\n<$list filter=\"[list[$(shortcutTitle)$!!text]sort[title]]\" variable=\"shortcut\" emptyMessage=\"\"\"\n<div class=\"tc-dropdown-item-plain\">\n//<<lingo NoShortcuts/Caption>>//\n</div>\n\"\"\">\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn-invisible\" tooltip={{$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint}}>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"+[remove<shortcut>]\"\n/>\n<small>{{$:/core/images/close-button}}</small>\n</$button>\n<kbd>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts=<<shortcut>>/>\n</kbd>\n</div>\n</$list>\n<hr/>\n<$macrocall $name=\"new-shortcut\" title=<<qualify \"$:/state/new-shortcut/$(shortcutTitle)$\">>/>\n</div>\n</div>\n</$reveal>\n</div>\n</td>\n\\end\n\n\\define shortcut-list(caption,prefix)\n<tr>\n<$list filter=\"[[$prefix$$(shortcutName)$]]\" variable=\"shortcutTitle\">\n<<shortcut-list-item \"$caption$\">>\n</$list>\n</tr>\n\\end\n\n\\define shortcut-editor()\n<<shortcut-list \"All\" \"$:/config/shortcuts/\">>\n<<shortcut-list \"Mac\" \"$:/config/shortcuts-mac/\">>\n<<shortcut-list \"NonMac\" \"$:/config/shortcuts-not-mac/\">>\n<<shortcut-list \"Linux\" \"$:/config/shortcuts-linux/\">>\n<<shortcut-list \"NonLinux\" \"$:/config/shortcuts-not-linux/\">>\n<<shortcut-list \"Windows\" \"$:/config/shortcuts-windows/\">>\n<<shortcut-list \"NonWindows\" \"$:/config/shortcuts-not-windows/\">>\n\\end\n\n\\define shortcut-preview()\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutPrefix)$$(shortcutName)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\\end\n\n\\define shortcut-item-inner()\n<tr>\n<td>\n<$reveal type=\"nomatch\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"open\"\n/>\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"close\"\n/>\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n''<$text text=<<shortcutName>>/>''\n</td>\n<td>\n<$transclude tiddler=\"$:/config/ShortcutInfo/$(shortcutName)$\"/>\n</td>\n<td>\n<$list filter=\"$:/config/shortcuts/ $:/config/shortcuts-mac/ $:/config/shortcuts-not-mac/ $:/config/shortcuts-linux/ $:/config/shortcuts-not-linux/ $:/config/shortcuts-windows/ $:/config/shortcuts-not-windows/\" variable=\"shortcutPrefix\">\n<<shortcut-preview>>\n</$list>\n</td>\n</tr>\n<$set name=\"dropdownState\" value={{$(dropdownStateTitle)$}}>\n<$list filter=\"[<dropdownState>match[open]]\" variable=\"listItem\">\n<<shortcut-editor>>\n</$list>\n</$set>\n\\end\n\n\\define shortcut-item()\n<$set name=\"dropdownStateTitle\" value=<<qualify \"$:/state/dropdown/keyboardshortcut/$(shortcutName)$\">>>\n<<shortcut-item-inner>>\n</$set>\n\\end\n\n<table>\n<tbody>\n<$list filter=\"[all[shadows+tiddlers]removeprefix[$:/config/ShortcutInfo/]]\" variable=\"shortcutName\">\n<<shortcut-item>>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ControlPanel/LoadedModules": {
"title": "$:/core/ui/ControlPanel/LoadedModules",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/LoadedModules/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n<<lingo LoadedModules/Hint>>\n\n{{$:/snippets/modules}}\n"
},
"$:/core/ui/ControlPanel/Modals/AddPlugins": {
"title": "$:/core/ui/ControlPanel/Modals/AddPlugins",
"subtitle": "{{$:/core/images/download-button}} {{$:/language/ControlPanel/Plugins/Add/Caption}}",
"text": "\\define install-plugin-actions()\n<$action-sendmessage $message=\"tm-load-plugin-from-library\" url={{!!url}} title={{$(assetInfo)$!!original-title}}/>\n<$set name=\"url\" value={{!!url}}>\n<$set name=\"currentTiddler\" value=<<assetInfo>>>\n<$list filter=\"[enlist{!!dependents}] [{!!parent-plugin}] +[sort[name]]\" variable=\"dependency\">\n<$action-sendmessage $message=\"tm-load-plugin-from-library\" url=<<url>> title=<<dependency>>/>\n</$list>\n</$set>\n</$set>\n\\end\n\n\\define install-plugin-button()\n<div>\n<$set name=\"libraryVersion\" value={{{ [<assetInfo>get[version]] }}}>\n<$set name=\"installedVersion\" value={{{ [<assetInfo>get[original-title]get[version]] }}}>\n<$set name=\"reinstall-type\" value={{{ [<libraryVersion>compare:version:eq<installedVersion>then[tc-reinstall]] [<libraryVersion>compare:version:gt<installedVersion>then[tc-reinstall-upgrade]] [<libraryVersion>compare:version:lt<installedVersion>then[tc-reinstall-downgrade]] }}}>\n<$button actions=<<install-plugin-actions>> class={{{ [<assetInfo>get[original-title]has[version]then<reinstall-type>] tc-btn-invisible tc-install-plugin +[join[ ]] }}}>\n{{$:/core/images/download-button}}\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"ignore\" emptyMessage=\"{{$:/language/ControlPanel/Plugins/Install/Caption}}\">\n<$list filter=\"[<libraryVersion>compare:version:gt<installedVersion>]\" variable=\"ignore\" emptyMessage=\"\"\"\n<$list filter=\"[<libraryVersion>compare:version:lt<installedVersion>]\" variable=\"ignore\" emptyMessage=\"{{$:/language/ControlPanel/Plugins/Reinstall/Caption}}\">\n{{$:/language/ControlPanel/Plugins/Downgrade/Caption}}\n</$list>\n\"\"\">\n{{$:/language/ControlPanel/Plugins/Update/Caption}}\n</$list>\n</$list>\n</$button>\n<div>\n</div>\n<$reveal stateTitle=<<assetInfo>> stateField=\"requires-reload\" type=\"match\" text=\"yes\">{{$:/language/ControlPanel/Plugins/PluginWillRequireReload}}</$reveal>\n</$set>\n</$set>\n</$set>\n</div>\n\\end\n\n\\define popup-state-macro()\n$:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$\n\\end\n\n\\define display-plugin-info(type)\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<div class=\"tc-plugin-info\">\n<div class=\"tc-plugin-info-chunk tc-plugin-info-toggle\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/chevron-right}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-icon\">\n<$list filter=\"[<assetInfo>has[icon]]\" emptyMessage=\"\"\"<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\"\"\">\n<img src={{$(assetInfo)$!!icon}}/>\n</$list>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-description\">\n<h1><strong><$text text={{{ [<assetInfo>get[name]] ~[<assetInfo>get[original-title]split[/]last[1]] }}}/></strong>: <$view tiddler=<<assetInfo>> field=\"description\"/></h1>\n<h2><$view tiddler=<<assetInfo>> field=\"original-title\"/></h2>\n<div><em><$view tiddler=<<assetInfo>> field=\"version\"/></em></div>\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"installedVersion\"><div><em>{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}</em></div></$list>\n</div>\n<div class=\"tc-plugin-info-chunk tc-plugin-info-buttons\">\n<<install-plugin-button>>\n</div>\n</div>\n<$set name=\"original-title\" value={{{ [<assetInfo>get[original-title]] }}}>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>>>\n<div class=\"tc-plugin-info-dropdown\">\n<$list filter=\"[enlist{!!dependents}] [<currentTiddler>get[parent-plugin]] +[limit[1]] ~[<assetInfo>get[original-title]!is[tiddler]]\" variable=\"ignore\">\n<div class=\"tc-plugin-info-dropdown-message\">\n<$list filter=\"[<assetInfo>get[original-title]!is[tiddler]]\">\n{{$:/language/ControlPanel/Plugins/NotInstalled/Hint}}\n</$list>\n<$set name=\"currentTiddler\" value=<<assetInfo>>>\n<$list filter=\"[enlist{!!dependents}] [<currentTiddler>get[parent-plugin]] +[limit[1]]\" variable=\"ignore\">\n<div>\n{{$:/language/ControlPanel/Plugins/AlsoRequires}}\n<$list filter=\"[enlist{!!dependents}] [{!!parent-plugin}] +[sort[name]]\" variable=\"dependency\">\n<$text text=<<dependency>>/>\n</$list>\n</div>\n</$list>\n</$set>\n</div>\n</$list>\n<div class=\"tc-plugin-info-dropdown-body\">\n<$transclude tiddler=<<assetInfo>> field=\"readme\" mode=\"block\"/>\n</div>\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>limit[1]]\" variable=\"ignore\">\n<div class=\"tc-plugin-info-sub-plugins\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>sort[name]]\" variable=\"assetInfo\">\n<<display-plugin-info \"$type$\">>\n</$list>\n</div>\n</$list>\n</div>\n</$reveal>\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>limit[1]]\" variable=\"ignore\">\n<$reveal type=\"nomatch\" text=\"yes\" state=<<popup-state>> tag=\"div\" class=\"tc-plugin-info-sub-plugin-indicator\">\n<$wikify name=\"count\" text=\"\"\"<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]has[parent-plugin]parent-plugin<original-title>]\"/>\"\"\">\n<$button class=\"tc-btn-invisible\" set=<<popup-state>> setTo=\"yes\">\n{{$:/language/ControlPanel/Plugins/SubPluginPrompt}}\n</$button>\n</$wikify>\n</$reveal>\n</$list>\n</$set>\n</$set>\n\\end\n\n\\define load-plugin-library-button()\n<$list filter=\"[<currentTiddler>get[enabled]else[yes]match[yes]]\" variable=\"ignore\">\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-load-plugin-library\" url={{!!url}} infoTitlePrefix=\"$:/temp/RemoteAssetInfo/\"/>\n{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Plugins/OpenPluginLibrary}}\n</$button>\n</$list>\n\\end\n\n\\define display-server-assets(type)\n{{$:/language/Search/Search}}: <$edit-text tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" default=\"\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n<div class=\"tc-plugin-library-listing\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]search:author,description,original-title,readme,title{$:/temp/RemoteAssetSearch/$(currentTiddler)$}sort[name]]\" variable=\"assetInfo\">\n<$list filter=\"[[$:/temp/RemoteAssetSearch/$(currentTiddler)$]has[text]] ~[<assetInfo>!has[parent-plugin]]\" variable=\"ignore\"><!-- Hide sub-plugins if we're not searching -->\n<<display-plugin-info \"$type$\">>\n</$list>\n</$list>\n</div>\n\\end\n\n\\define display-server-connection()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/ServerConnection]suffix{!!url}]\" variable=\"connectionTiddler\" emptyMessage=<<load-plugin-library-button>>>\n\n<$set name=\"transclusion\" value=<<connectionTiddler>>>\n\n<<tabs \"[[$:/core/ui/ControlPanel/Plugins/Add/Updates]] [[$:/core/ui/ControlPanel/Plugins/Add/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Add/Themes]] [[$:/core/ui/ControlPanel/Plugins/Add/Languages]]\" \"$:/core/ui/ControlPanel/Plugins/Add/Plugins\">>\n\n</$set>\n\n</$list>\n\\end\n\n\\define close-library-button()\n<$reveal type='nomatch' state='$:/temp/ServerConnection/$(PluginLibraryURL)$' text=''>\n<$button class='tc-btn-big-green'>\n<$action-sendmessage $message=\"tm-unload-plugin-library\" url={{!!url}}/>\n{{$:/core/images/chevron-left}} {{$:/language/ControlPanel/Plugins/ClosePluginLibrary}}\n<$action-deletetiddler $filter=\"[prefix[$:/temp/ServerConnection/$(PluginLibraryURL)$]][prefix[$:/temp/RemoteAssetInfo/$(PluginLibraryURL)$]]\"/>\n</$button>\n</$reveal>\n\\end\n\n\\define plugin-library-listing()\n<div class=\"tc-tab-set\">\n<$set name=\"defaultTab\" value={{{ [all[tiddlers+shadows]tag[$:/tags/PluginLibrary]] }}}>\n<div class=\"tc-tab-buttons\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/PluginLibrary]]\">\n<$button set=<<qualify \"$:/state/addplugins/tab\">> setTo=<<currentTiddler>> default=<<defaultTab>> selectedClass=\"tc-tab-selected\">\n<$set name=\"tv-wikilinks\" value=\"no\">\n<$transclude field=\"caption\"/>\n</$set>\n</$button>\n</$list>\n</div>\n<div class=\"tc-tab-divider\"/>\n<div class=\"tc-tab-content\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/PluginLibrary]]\">\n<$reveal type=\"match\" state=<<qualify \"$:/state/addplugins/tab\">> text=<<currentTiddler>> default=<<defaultTab>>>\n<h2><$link><$transclude field=\"caption\"><$view field=\"title\"/></$transclude></$link></h2>\n//<$view field=\"url\"/>//\n<$transclude mode=\"block\"/>\n<$set name=PluginLibraryURL value={{!!url}}>\n<<close-library-button>>\n</$set>\n<<display-server-connection>>\n</$reveal>\n</$list>\n</div>\n</$set>\n</div>\n\\end\n\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<div>\n<<plugin-library-listing>>\n</div>\n"
},
"$:/core/ui/ControlPanel/Palette": {
"title": "$:/core/ui/ControlPanel/Palette",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/Palette/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Palette/\n\n{{$:/snippets/paletteswitcher}}\n\n<$reveal type=\"nomatch\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"yes\"><<lingo ShowEditor/Caption>></$button>\n\n</$reveal>\n\n<$reveal type=\"match\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"no\"><<lingo HideEditor/Caption>></$button>\n{{$:/PaletteManager}}\n\n</$reveal>\n\n"
},
"$:/core/ui/ControlPanel/Parsing": {
"title": "$:/core/ui/ControlPanel/Parsing",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/Parsing/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Parsing/\n\n\\define toggle(Type)\n<$checkbox\ntiddler=\"\"\"$:/config/WikiParserRules/$Type$/$(rule)$\"\"\"\nfield=\"text\"\nchecked=\"enable\"\nunchecked=\"disable\"\ndefault=\"enable\">\n<<rule>>\n</$checkbox>\n\\end\n\n\\define rules(type,Type)\n<$list filter=\"[wikiparserrules[$type$]]\" variable=\"rule\">\n<dd><<toggle $Type$>></dd>\n</$list>\n\\end\n\n<<lingo Hint>>\n\n<dl>\n<dt><<lingo Pragma/Caption>></dt>\n<<rules pragma Pragma>>\n<dt><<lingo Inline/Caption>></dt>\n<<rules inline Inline>>\n<dt><<lingo Block/Caption>></dt>\n<<rules block Block>>\n</dl>"
},
"$:/core/ui/ControlPanel/Plugins/Add/Languages": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Languages",
"caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[language]]\"/>)",
"text": "<<display-server-assets language>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Add/Plugins": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[plugin]]\"/>)",
"text": "<<display-server-assets plugin>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Add/Themes": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Themes",
"caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[theme]]\"/>)",
"text": "<<display-server-assets theme>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Add/Updates": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Updates",
"caption": "<$importvariables filter=\"$:/core/ui/ControlPanel/Plugins/Add/Updates\">{{$:/language/ControlPanel/Plugins/Updates/Caption}} (<<update-count>>)</$importvariables>",
"text": "\\define each-updateable-plugin(body)\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}sort[title]]\" variable=\"assetInfo\">\n<$set name=\"libraryVersion\" value={{{ [<assetInfo>get[version]] }}}>\n<$list filter=\"[<assetInfo>get[original-title]has[version]!version<libraryVersion>]\" variable=\"ignore\">\n<$set name=\"installedVersion\" value={{{ [<assetInfo>get[original-title]get[version]] }}}>\n<$list filter=\"[<installedversion>!match<libraryVersion>]\" variable=\"ignore\">\n$body$\n</$list>\n</$set>\n</$list>\n</$set>\n</$list>\n\\end\n\n\\define update-all-actions()\n<$macrocall $name=\"each-updateable-plugin\" body=\"\"\"\n<<install-plugin-actions>>\n\"\"\"/>\n\\end\n\n\\define update-count()\n<$wikify name=\"count-filter\" text=<<each-updateable-plugin \"[[<$text text=<<assetInfo>>/>]]\">>><$count filter=<<count-filter>>/></$wikify>\n\\end\n\n<$button actions=<<update-all-actions>> class=\"tc-btn-invisible tc-install-plugin tc-reinstall-upgrade\">\n{{$:/core/images/download-button}} {{||$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption}}\n</$button>\n\n<div class=\"tc-plugin-library-listing\">\n<$macrocall $name=\"each-updateable-plugin\" body=\"\"\"\n<$macrocall $name=\"display-plugin-info\" type={{{ [<assetInfo>get[original-plugin-type]] }}}/>\n\"\"\"/>\n</div>\n"
},
"$:/core/ui/ControlPanel/Plugins/AddPlugins": {
"title": "$:/core/ui/ControlPanel/Plugins/AddPlugins",
"text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n<$button message=\"tm-modal\" param=\"$:/core/ui/ControlPanel/Modals/AddPlugins\" tooltip={{$:/language/ControlPanel/Plugins/Add/Hint}} class=\"tc-btn-big-green tc-primary-btn\">\n{{$:/core/images/download-button}} <<lingo Add/Caption>>\n</$button>\n"
},
"$:/core/ui/ControlPanel/Plugins/Installed/Languages": {
"title": "$:/core/ui/ControlPanel/Plugins/Installed/Languages",
"caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[language]]\"/>)",
"text": "<<plugin-table language>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Installed/Plugins": {
"title": "$:/core/ui/ControlPanel/Plugins/Installed/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[plugin]]\"/>)",
"text": "<<plugin-table plugin>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Installed/Themes": {
"title": "$:/core/ui/ControlPanel/Plugins/Installed/Themes",
"caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[theme]]\"/>)",
"text": "<<plugin-table theme>>\n"
},
"$:/core/ui/ControlPanel/Plugins": {
"title": "$:/core/ui/ControlPanel/Plugins",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Plugins/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define plugin-table(type)\n<$set name=\"plugin-type\" value=\"\"\"$type$\"\"\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n<$list filter=\"[!has[draft.of]plugin-type[$type$]sort[name]]\" emptyMessage=<<lingo \"Empty/Hint\">> template=\"$:/core/ui/Components/plugin-info\"/>\n</$set>\n</$set>\n\\end\n\n{{$:/core/ui/ControlPanel/Plugins/AddPlugins}}\n\n<<lingo Installed/Hint>>\n\n<$macrocall $name=\"tabs\" tabsList=\"[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]\" default=\"$:/core/ui/ControlPanel/Plugins/Installed/Plugins\" explicitState=\"$:/state/tab--86143343\"/>\n"
},
"$:/core/ui/ControlPanel/Saving/DownloadSaver": {
"title": "$:/core/ui/ControlPanel/Saving/DownloadSaver",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/DownloadSaver/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/DownloadSaver/\n\n<<lingo Hint>>\n\n!! <$link to=\"$:/config/DownloadSaver/AutoSave\"><<lingo AutoSave/Hint>></$link>\n\n<$checkbox tiddler=\"$:/config/DownloadSaver/AutoSave\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <<lingo AutoSave/Description>> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Saving/General": {
"title": "$:/core/ui/ControlPanel/Saving/General",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/General/Caption}}",
"list-before": "",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/\n\n{{$:/language/ControlPanel/Saving/General/Hint}}\n\n!! <$link to=\"$:/config/AutoSave\"><<lingo AutoSave/Caption>></$link>\n\n<<lingo AutoSave/Hint>>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"yes\"> <<lingo AutoSave/Enabled/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"no\"> <<lingo AutoSave/Disabled/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Saving/GitHub": {
"title": "$:/core/ui/ControlPanel/Saving/GitHub",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/GitService/GitHub/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/GitService/\n\\define service-name() ~GitHub\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/GitHub/Username\" default=\"\" tag=\"input\"/> |\n|<<lingo GitHub/Password>> |<$password name=\"github\"/> |\n|<<lingo Repo>> |<$edit-text tiddler=\"$:/GitHub/Repo\" default=\"\" tag=\"input\"/> |\n|<<lingo Branch>> |<$edit-text tiddler=\"$:/GitHub/Branch\" default=\"master\" tag=\"input\"/> |\n|<<lingo Path>> |<$edit-text tiddler=\"$:/GitHub/Path\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/GitHub/Filename\" default=\"\" tag=\"input\"/> |\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/GitHub/ServerURL\" default=\"https://api.github.com\" tag=\"input\"/> |"
},
"$:/core/ui/ControlPanel/Saving/GitLab": {
"title": "$:/core/ui/ControlPanel/Saving/GitLab",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/GitService/GitLab/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/GitService/\n\\define service-name() ~GitLab\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/GitLab/Username\" default=\"\" tag=\"input\"/> |\n|<<lingo GitLab/Password>> |<$password name=\"gitlab\"/> |\n|<<lingo Repo>> |<$edit-text tiddler=\"$:/GitLab/Repo\" default=\"\" tag=\"input\"/> |\n|<<lingo Branch>> |<$edit-text tiddler=\"$:/GitLab/Branch\" default=\"master\" tag=\"input\"/> |\n|<<lingo Path>> |<$edit-text tiddler=\"$:/GitLab/Path\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/GitLab/Filename\" default=\"\" tag=\"input\"/> |\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/GitLab/ServerURL\" default=\"https://gitlab.com/api/v4\" tag=\"input\"/> |"
},
"$:/core/ui/ControlPanel/Saving/TiddlySpot": {
"title": "$:/core/ui/ControlPanel/Saving/TiddlySpot",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/TiddlySpot/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/TiddlySpot/\n\n\\define siteURL(path)\nhttp://$(userName)$.tiddlyspot.com/$path$/\n\\end\n\\define siteLink(path)\n<$reveal type=\"nomatch\" state=\"$:/UploadName\" text=\"\">\n<$set name=\"userName\" value={{$:/UploadName}}>\n<$reveal type=\"match\" state=\"$:/UploadURL\" text=\"\">\n<<siteURL $path$>>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/UploadURL\" text=\"\">\n<$macrocall $name=resolvePath source={{$:/UploadBackupDir}} root={{$:/UploadURL}}>>\n</$reveal>\n</$set>\n</$reveal>\n\\end\n\n<div class=\"tc-message-box\">\n\n<<lingo ReadOnly>>\n\n</div>\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/UploadName\" default=\"\" tag=\"input\"/> |\n|<<lingo Password>> |<$password name=\"upload\"/> |\n|<<lingo Backups>> |<<siteLink backup>> |\n|<<lingo ControlPanel>> |<<siteLink controlpanel>> |\n\n''<<lingo Advanced/Heading>>''\n\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/UploadURL\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/UploadFilename\" default=\"index.html\" tag=\"input\"/> |\n|<<lingo UploadDir>> |<$edit-text tiddler=\"$:/UploadDir\" default=\".\" tag=\"input\"/> |\n|<<lingo BackupDir>> |<$edit-text tiddler=\"$:/UploadBackupDir\" default=\".\" tag=\"input\"/> |\n\n<<lingo TiddlySpot/Hint>>\n"
},
"$:/core/ui/ControlPanel/Saving/Gitea": {
"title": "$:/core/ui/ControlPanel/Saving/Gitea",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/GitService/Gitea/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/GitService/\n\\define service-name() ~Gitea\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/Gitea/Username\" default=\"\" tag=\"input\"/> |\n|<<lingo Gitea/Password>> |<$password name=\"Gitea\"/> |\n|<<lingo Repo>> |<$edit-text tiddler=\"$:/Gitea/Repo\" default=\"\" tag=\"input\"/> |\n|<<lingo Branch>> |<$edit-text tiddler=\"$:/Gitea/Branch\" default=\"master\" tag=\"input\"/> |\n|<<lingo Path>> |<$edit-text tiddler=\"$:/Gitea/Path\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/Gitea/Filename\" default=\"\" tag=\"input\"/> |\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/Gitea/ServerURL\" default=\"https://gitea/api/v1\" tag=\"input\"/> |\n"
},
"$:/core/ui/ControlPanel/Saving": {
"title": "$:/core/ui/ControlPanel/Saving",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Saving/Caption}}",
"text": "{{$:/language/ControlPanel/Saving/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Saving]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Saving/General\" explicitState=\"$:/state/tab-2065006209\"/>\n</div>\n"
},
"$:/core/buttonstyles/Borderless": {
"title": "$:/core/buttonstyles/Borderless",
"tags": "$:/tags/ToolbarButtonStyle",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless}}",
"text": "tc-btn-invisible"
},
"$:/core/buttonstyles/Boxed": {
"title": "$:/core/buttonstyles/Boxed",
"tags": "$:/tags/ToolbarButtonStyle",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed}}",
"text": "tc-btn-boxed"
},
"$:/core/buttonstyles/Rounded": {
"title": "$:/core/buttonstyles/Rounded",
"tags": "$:/tags/ToolbarButtonStyle",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded}}",
"text": "tc-btn-rounded"
},
"$:/core/ui/ControlPanel/Settings/CamelCase": {
"title": "$:/core/ui/ControlPanel/Settings/CamelCase",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/CamelCase/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/CamelCase/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/WikiParserRules/Inline/wikilink\" field=\"text\" checked=\"enable\" unchecked=\"disable\" default=\"enable\"> <$link to=\"$:/config/WikiParserRules/Inline/wikilink\"><<lingo Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab": {
"title": "$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab",
"caption": "{{$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption}}",
"tags": "$:/tags/ControlPanel/Settings",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/DefaultMoreSidebarTab/\n\n<$link to=\"$:/config/DefaultMoreSidebarTab\"><<lingo Hint>></$link>\n\n<$select tiddler=\"$:/config/DefaultMoreSidebarTab\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\">\n<option value=<<currentTiddler>>><$transclude field=\"caption\"><$text text=<<currentTiddler>>/></$transclude></option>\n</$list>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/DefaultSidebarTab": {
"title": "$:/core/ui/ControlPanel/Settings/DefaultSidebarTab",
"caption": "{{$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption}}",
"tags": "$:/tags/ControlPanel/Settings",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/DefaultSidebarTab/\n\n<$link to=\"$:/config/DefaultSidebarTab\"><<lingo Hint>></$link>\n\n<$select tiddler=\"$:/config/DefaultSidebarTab\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\">\n<option value=<<currentTiddler>>><$transclude field=\"caption\"><$text text=<<currentTiddler>>/></$transclude></option>\n</$list>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/EditorToolbar": {
"title": "$:/core/ui/ControlPanel/Settings/EditorToolbar",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/EditorToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/EditorToolbar/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/TextEditor/EnableToolbar\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/TextEditor/EnableToolbar\"><<lingo Description>></$link> </$checkbox>\n\n"
},
"$:/core/ui/ControlPanel/Settings/InfoPanelMode": {
"title": "$:/core/ui/ControlPanel/Settings/InfoPanelMode",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/InfoPanelMode/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/InfoPanelMode/\n<$link to=\"$:/config/TiddlerInfo/Mode\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"popup\"> <<lingo Popup/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"sticky\"> <<lingo Sticky/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/LinkToBehaviour": {
"title": "$:/core/ui/ControlPanel/Settings/LinkToBehaviour",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/LinkToBehaviour/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/LinkToBehaviour/\n\n<$link to=\"$:/config/Navigation/openLinkFromInsideRiver\"><<lingo \"InsideRiver/Hint\">></$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromInsideRiver\">\n <option value=\"above\"><<lingo \"OpenAbove\">></option>\n <option value=\"below\"><<lingo \"OpenBelow\">></option>\n <option value=\"top\"><<lingo \"OpenAtTop\">></option>\n <option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n\n<$link to=\"$:/config/Navigation/openLinkFromOutsideRiver\"><<lingo \"OutsideRiver/Hint\">></$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromOutsideRiver\">\n <option value=\"top\"><<lingo \"OpenAtTop\">></option>\n <option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/MissingLinks": {
"title": "$:/core/ui/ControlPanel/Settings/MissingLinks",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/MissingLinks/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/MissingLinks/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/MissingLinks\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/MissingLinks\"><<lingo Description>></$link> </$checkbox>\n\n"
},
"$:/core/ui/ControlPanel/Settings/NavigationAddressBar": {
"title": "$:/core/ui/ControlPanel/Settings/NavigationAddressBar",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/NavigationAddressBar/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationAddressBar/\n\n<$link to=\"$:/config/Navigation/UpdateAddressBar\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permaview\"> <<lingo Permaview/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permalink\"> <<lingo Permalink/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/NavigationHistory": {
"title": "$:/core/ui/ControlPanel/Settings/NavigationHistory",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/NavigationHistory/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationHistory/\n<$link to=\"$:/config/Navigation/UpdateHistory\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"yes\"> <<lingo Yes/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode": {
"title": "$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationPermalinkviewMode/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/CopyToClipboard\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Navigation/Permalinkview/CopyToClipboard\"><<lingo CopyToClipboard/Description>></$link> </$checkbox>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\"><<lingo UpdateAddressBar/Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation": {
"title": "$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/PerformanceInstrumentation/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Performance/Instrumentation\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Performance/Instrumentation\"><<lingo Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings/TitleLinks": {
"title": "$:/core/ui/ControlPanel/Settings/TitleLinks",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/TitleLinks/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/TitleLinks/\n<$link to=\"$:/config/Tiddlers/TitleLinks\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"yes\"> <<lingo Yes/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle": {
"title": "$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtonStyle/\n<$link to=\"$:/config/Toolbar/ButtonClass\"><<lingo \"Hint\">></$link>\n\n<$select tiddler=\"$:/config/Toolbar/ButtonClass\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ToolbarButtonStyle]]\">\n<option value={{!!text}}>{{!!caption}}</option>\n</$list>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/ToolbarButtons": {
"title": "$:/core/ui/ControlPanel/Settings/ToolbarButtons",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtons/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtons/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Icons\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Toolbar/Icons\"><<lingo Icons/Description>></$link> </$checkbox>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Text\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Toolbar/Text\"><<lingo Text/Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings": {
"title": "$:/core/ui/ControlPanel/Settings",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Settings/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/\n\n<<lingo Hint>>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]\">\n\n<div style=\"border-top:1px solid #eee;\">\n\n!! <$link><$transclude field=\"caption\"/></$link>\n\n<$transclude/>\n\n</div>\n\n</$list>\n"
},
"$:/core/ui/ControlPanel/StoryView": {
"title": "$:/core/ui/ControlPanel/StoryView",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/StoryView/Caption}}",
"text": "{{$:/snippets/viewswitcher}}\n"
},
"$:/core/ui/ControlPanel/Stylesheets": {
"title": "$:/core/ui/ControlPanel/Stylesheets",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/Stylesheets/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo Stylesheets/Hint>>\n\n{{$:/snippets/peek-stylesheets}}\n"
},
"$:/core/ui/ControlPanel/Theme": {
"title": "$:/core/ui/ControlPanel/Theme",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/Theme/Caption}}",
"text": "{{$:/snippets/themeswitcher}}\n"
},
"$:/core/ui/ControlPanel/TiddlerFields": {
"title": "$:/core/ui/ControlPanel/TiddlerFields",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/TiddlerFields/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo TiddlerFields/Hint>>\n\n{{$:/snippets/allfields}}"
},
"$:/core/ui/ControlPanel/Toolbars/EditToolbar": {
"title": "$:/core/ui/ControlPanel/Toolbars/EditToolbar",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/EditToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>"
},
"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate": {
"title": "$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate",
"text": "\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <span class=\"tc-icon-wrapper\"><$transclude tiddler={{!!icon}}/></span> <$transclude field=\"caption\"/> -- <i class=\"tc-muted\"><$transclude field=\"description\"/></i>\n</$draggable>\n"
},
"$:/core/ui/ControlPanel/Toolbars/EditorToolbar": {
"title": "$:/core/ui/ControlPanel/Toolbars/EditorToolbar",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/EditorToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditorToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditorToolbar/Hint}}\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditorToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate\"/>\n"
},
"$:/core/ui/ControlPanel/Toolbars/ItemTemplate": {
"title": "$:/core/ui/ControlPanel/Toolbars/ItemTemplate",
"text": "\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <span class=\"tc-icon-wrapper\"> <$transclude field=\"caption\"/> <i class=\"tc-muted\">-- <$transclude field=\"description\"/></i></span>\n</$draggable>\n"
},
"$:/core/ui/ControlPanel/Toolbars/PageControls": {
"title": "$:/core/ui/ControlPanel/Toolbars/PageControls",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/PageControls/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/PageControlButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/PageControls/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/PageControls\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/ControlPanel/Toolbars/ViewToolbar": {
"title": "$:/core/ui/ControlPanel/Toolbars/ViewToolbar",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/ViewToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/ViewToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/ViewToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/ViewToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/ControlPanel/Toolbars": {
"title": "$:/core/ui/ControlPanel/Toolbars",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/Toolbars/Caption}}",
"text": "{{$:/language/ControlPanel/Toolbars/Hint}}\n\n<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Toolbars]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Toolbars/ViewToolbar\" class=\"tc-vertical\" explicitState=\"$:/state/tabs/controlpanel/toolbars-1345989671\"/>\n</div>\n"
},
"$:/ControlPanel": {
"title": "$:/ControlPanel",
"icon": "$:/core/images/options-button",
"color": "#bbb",
"text": "<div class=\"tc-control-panel\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]\" default=\"$:/core/ui/ControlPanel/Info\" explicitState=\"$:/state/tab-1749438307\"/>\n</div>\n"
},
"$:/core/ui/DefaultSearchResultList": {
"title": "$:/core/ui/DefaultSearchResultList",
"tags": "$:/tags/SearchResults",
"caption": "{{$:/language/Search/DefaultResults/Caption}}",
"first-search-filter": "[!is[system]search:title<userInput>sort[title]limit[250]]",
"second-search-filter": "[!is[system]search<userInput>sort[title]limit[250]]",
"text": "\\define searchResultList()\n//<small>{{$:/language/Search/Matches/Title}}</small>//\n\n<$list filter=\"[<userInput>minlength[1]]\" variable=\"ignore\">\n<$list filter={{{ [<configTiddler>get[first-search-filter]] }}}>\n<span class={{{[<currentTiddler>addsuffix[-primaryList]] -[<searchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n</$list>\n\n//<small>{{$:/language/Search/Matches/All}}</small>//\n\n<$list filter=\"[<userInput>minlength[1]]\" variable=\"ignore\">\n<$list filter={{{ [<configTiddler>get[second-search-filter]] }}}>\n<span class={{{[<currentTiddler>addsuffix[-secondaryList]] -[<searchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</span>\n</$list>\n</$list>\n\n\\end\n<<searchResultList>>\n"
},
"$:/core/ui/EditTemplate/body/preview/diffs-current": {
"title": "$:/core/ui/EditTemplate/body/preview/diffs-current",
"tags": "$:/tags/EditPreview",
"caption": "differences from current",
"list-after": "$:/core/ui/EditTemplate/body/preview/output",
"text": "<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"
},
"$:/core/ui/EditTemplate/body/preview/diffs-shadow": {
"title": "$:/core/ui/EditTemplate/body/preview/diffs-shadow",
"tags": "$:/tags/EditPreview",
"caption": "differences from shadow (if any)",
"list-after": "$:/core/ui/EditTemplate/body/preview/output",
"text": "<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{{ [{!!draft.of}shadowsource[]] }}} sourceSubTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"
},
"$:/core/ui/EditTemplate/body/preview/output": {
"title": "$:/core/ui/EditTemplate/body/preview/output",
"tags": "$:/tags/EditPreview",
"caption": "{{$:/language/EditTemplate/Body/Preview/Type/Output}}",
"text": "\\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]\n<$set name=\"tv-tiddler-preview\" value=\"yes\">\n\n<$transclude />\n\n</$set>\n"
},
"$:/state/showeditpreview": {
"title": "$:/state/showeditpreview",
"text": "no"
},
"$:/core/ui/EditTemplate/body/editor": {
"title": "$:/core/ui/EditTemplate/body/editor",
"text": "<$edit\n\n field=\"text\"\n class=\"tc-edit-texteditor tc-edit-texteditor-body\"\n placeholder={{$:/language/EditTemplate/Body/Placeholder}}\n tabindex={{$:/config/EditTabIndex}}\n focus={{{ [{$:/config/AutoFocus}match[text]then[true]] ~[[false]] }}}\n cancelPopups=\"yes\"\n\n><$set\n\n name=\"targetTiddler\"\n value=<<currentTiddler>>\n\n><$list\n\n filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]]\"\n\n><$reveal\n\n type=\"nomatch\"\n state=<<config-visibility-title>>\n text=\"hide\"\n class=\"tc-text-editor-toolbar-item-wrapper\"\n\n><$transclude\n\n tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\"\n mode=\"inline\"\n\n/></$reveal></$list></$set></$edit>\n"
},
"$:/core/ui/EditTemplate/body/toolbar/button": {
"title": "$:/core/ui/EditTemplate/body/toolbar/button",
"text": "\\define toolbar-button-icon()\n<$list\n\n filter=\"[all[current]!has[custom-icon]]\"\n variable=\"no-custom-icon\"\n\n><$transclude\n\n tiddler={{!!icon}}\n\n/></$list>\n\\end\n\n\\define toolbar-button-tooltip()\n{{!!description}}<$macrocall $name=\"displayshortcuts\" $output=\"text/plain\" shortcuts={{!!shortcuts}} prefix=\"` - [\" separator=\"] [\" suffix=\"]`\"/>\n\\end\n\n\\define toolbar-button()\n<$list\n\n filter={{!!condition}}\n variable=\"list-condition\"\n\n><$wikify\n\n name=\"tooltip-text\"\n text=<<toolbar-button-tooltip>>\n mode=\"inline\"\n output=\"text\"\n\n><$list\n\n filter=\"[all[current]!has[dropdown]]\"\n variable=\"no-dropdown\"\n\n><$button\n\n class=\"tc-btn-invisible $(buttonClasses)$\"\n tooltip=<<tooltip-text>>\n actions={{!!actions}}\n\n><span\n\n data-tw-keyboard-shortcut={{!!shortcuts}}\n\n/><<toolbar-button-icon>><$transclude\n\n tiddler=<<currentTiddler>>\n field=\"text\"\n\n/></$button></$list><$list\n\n filter=\"[all[current]has[dropdown]]\"\n variable=\"dropdown\"\n\n><$set\n\n name=\"dropdown-state\"\n value=<<qualify \"$:/state/EditorToolbarDropdown\">>\n\n><$button\n\n popup=<<dropdown-state>>\n class=\"tc-popup-keep tc-btn-invisible $(buttonClasses)$\"\n selectedClass=\"tc-selected\"\n tooltip=<<tooltip-text>>\n actions={{!!actions}}\n\n><span\n\n data-tw-keyboard-shortcut={{!!shortcuts}}\n\n/><<toolbar-button-icon>><$transclude\n\n tiddler=<<currentTiddler>>\n field=\"text\"\n\n/></$button><$reveal\n\n state=<<dropdown-state>>\n type=\"popup\"\n position=\"below\"\n animate=\"yes\"\n tag=\"span\"\n\n><div\n\n class=\"tc-drop-down tc-popup-keep\"\n\n><$transclude\n\n tiddler={{!!dropdown}}\n mode=\"block\"\n\n/></div></$reveal></$set></$list></$wikify></$list>\n\\end\n\n\\define toolbar-button-outer()\n<$set\n\n name=\"buttonClasses\"\n value={{!!button-classes}}\n\n><<toolbar-button>></$set>\n\\end\n\n<<toolbar-button-outer>>"
},
"$:/core/ui/EditTemplate/body": {
"title": "$:/core/ui/EditTemplate/body",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/Body/\n\\define config-visibility-title()\n$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$\n\\end\n<$list filter=\"[all[current]has[_canonical_uri]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo External/Hint>>\n\n<a href={{!!_canonical_uri}}><$text text={{!!_canonical_uri}}/></a>\n\n<$edit-text field=\"_canonical_uri\" class=\"tc-edit-fields\" tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"></$edit-text>\n\n</div>\n\n</$list>\n\n<$list filter=\"[all[current]!has[_canonical_uri]]\">\n\n<$reveal state=\"$:/state/showeditpreview\" type=\"match\" text=\"yes\">\n\n<div class=\"tc-tiddler-preview\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n<div class=\"tc-tiddler-preview-preview\">\n\n<$transclude tiddler={{$:/state/editpreviewtype}} mode=\"inline\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/preview/output\" mode=\"inline\"/>\n\n</$transclude>\n\n</div>\n\n</div>\n\n</$reveal>\n\n<$reveal state=\"$:/state/showeditpreview\" type=\"nomatch\" text=\"yes\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n</$reveal>\n\n</$list>\n"
},
"$:/core/ui/EditTemplate/controls": {
"title": "$:/core/ui/EditTemplate/controls",
"tags": "$:/tags/EditTemplate",
"text": "\\define config-title()\n$:/config/EditToolbarButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-tiddler-title tc-tiddler-edit-title\">\n<$view field=\"title\"/>\n<span class=\"tc-tiddler-controls tc-titlebar\"><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]\" variable=\"listItem\"><$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"><$transclude tiddler=<<listItem>>/></$reveal></$list></span>\n<div style=\"clear: both;\"></div>\n</div>\n"
},
"$:/core/ui/EditTemplate/fields": {
"title": "$:/core/ui/EditTemplate/fields",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/\n\\define config-title()\n$:/config/EditTemplateFields/Visibility/$(currentField)$\n\\end\n\n\\define config-filter()\n[[hide]] -[title{$(config-title)$}]\n\\end\n\n\\define current-tiddler-new-field-selector()\n[data-tiddler-title=\"$(currentTiddlerCSSescaped)$\"] .tc-edit-field-add-name-wrapper input\n\\end\n\n\\define new-field-actions()\n<$action-sendmessage $message=\"tm-add-field\" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}}/>\n<$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]\"/>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=<<current-tiddler-new-field-selector>>/>\n\\end\n\n\\define delete-state-tiddlers() <$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [<storeTitle>] [<searchListState>]\"/>\n\n\\define cancel-search-actions-inner()\n<$list filter=\"[<storeTitle>has[text]] [<newFieldNameTiddler>has[text]]\" variable=\"ignore\" emptyMessage=\"\"\"<<cancel-delete-tiddler-actions \"cancel\">>\"\"\">\n<<delete-state-tiddlers>>\n</$list>\n\\end\n\n\\define cancel-search-actions()\n<$set name=\"userInput\" value={{{ [<storeTitle>get[text]] }}}>\n<$list filter=\"[<newFieldNameTiddler>get[text]!match<userInput>]\" emptyMessage=\"\"\"<<cancel-search-actions-inner>>\"\"\">\n<$action-setfield $tiddler=<<newFieldNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n</$list>\n</$set>\n\\end\n\n\\define new-field()\n<$vars name={{{ [<newFieldNameTiddler>get[text]] }}}>\n<$reveal type=\"nomatch\" text=\"\" default=<<name>>>\n<$button tooltip=<<lingo Fields/Add/Button/Hint>>>\n<$action-sendmessage $message=\"tm-add-field\"\n$name=<<name>>\n$value={{{ [<newFieldValueTiddler>get[text]] }}}/>\n<$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<storeTitle>] [<searchListState>]\"/>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" text=\"\" default=<<name>>>\n<$button>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n</$vars>\n\\end\n\\whitespace trim\n\n<div class=\"tc-edit-fields\">\n<table class={{{ [all[current]fields[]] :filter[lookup[$:/config/EditTemplateFields/Visibility/]!match[hide]] +[count[]!match[0]] +[then[tc-edit-fields]] ~[[tc-edit-fields tc-edit-fields-small]] }}}>\n<tbody>\n<$list filter=\"[all[current]fields[]] +[sort[title]]\" variable=\"currentField\" storyview=\"pop\">\n<$list filter=<<config-filter>> variable=\"temp\">\n<tr class=\"tc-edit-field\">\n<td class=\"tc-edit-field-name\">\n<$text text=<<currentField>>/>:</td>\n<td class=\"tc-edit-field-value\">\n<$keyboard key=\"((delete-field))\" actions=\"\"\"<$action-deletefield $field=<<currentField>>/><$set name=\"currentTiddlerCSSescaped\" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message=\"tm-focus-selector\" $param=<<current-tiddler-new-field-selector>>/></$set>\"\"\">\n<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"/>\n</$keyboard>\n</td>\n<td class=\"tc-edit-field-remove\">\n<$button class=\"tc-btn-invisible\" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>\n<$action-deletefield $field=<<currentField>>/><$set name=\"currentTiddlerCSSescaped\" value={{{ [<currentTiddler>escapecss[]] }}}><$action-sendmessage $message=\"tm-focus-selector\" $param=<<current-tiddler-new-field-selector>>/></$set>\n{{$:/core/images/delete-button}}\n</$button>\n</td>\n</tr>\n</$list>\n</$list>\n</tbody>\n</table>\n</div>\n\n<$fieldmangler>\n<div class=\"tc-edit-field-add\">\n<em class=\"tc-edit tc-big-gap-right\">\n<<lingo Fields/Add/Prompt>>\n</em>\n<$vars refreshTitle=<<qualify \"$:/temp/fieldname/refresh\">> storeTitle=<<newFieldNameInputTiddler>> searchListState=<<newFieldNameSelectionTiddler>>>\n<div class=\"tc-edit-field-add-name-wrapper\">\n<$macrocall $name=\"keyboard-driven-input\" tiddler=<<newFieldNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>\n\t\tselectionStateTitle=<<searchListState>> tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}}\n\t\tfocusPopup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-edit-texteditor tc-popup-handle\" tabindex={{$:/config/EditTabIndex}}\n\t\tfocus={{{ [{$:/config/AutoFocus}match[fields]then[true]] ~[[false]] }}} cancelPopups=\"yes\"\n\t\tconfigTiddlerFilter=\"[[$:/config/EditMode/fieldname-filter]]\" inputCancelActions=<<cancel-search-actions>> />\n<$button popup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown tc-small-gap\" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/field-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher to=<<newFieldNameTiddler>>>\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/User>>\n</div>\n<$set name=\"newFieldName\" value={{{ [<storeTitle>get[text]] }}}>\n<$list filter=\"[!is[shadow]!is[system]fields[]search:title<newFieldName>sort[]] -created -creator -draft.of -draft.title -modified -modifier -tags -text -title -type\" variable=\"currentField\">\n<$list filter=\"[<currentField>addsuffix[-primaryList]] -[<searchListState>get[text]]\" emptyMessage=\"\"\"<$link to=<<currentField>> class=\"tc-list-item-selected\"><$text text=<<currentField>>/></$link>\"\"\">\n<$link to=<<currentField>>>\n<$text text=<<currentField>>/>\n</$link>\n</$list>\n</$list>\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/System>>\n</div>\n<$list filter=\"[fields[]search:title<newFieldName>sort[]] -[!is[shadow]!is[system]fields[]]\" variable=\"currentField\">\n<$list filter=\"[<currentField>addsuffix[-secondaryList]] -[<searchListState>get[text]]\" emptyMessage=\"\"\"<$link to=<<currentField>> class=\"tc-list-item-selected\"><$text text=<<currentField>>/></$link>\"\"\">\n<$link to=<<currentField>>>\n<$text text=<<currentField>>/>\n</$link>\n</$list>\n</$list>\n</$set>\n</$linkcatcher>\n</$set>\n</div>\n</$reveal>\n</div>\n<span class=\"tc-edit-field-add-value tc-small-gap-right\">\n<$set name=\"currentTiddlerCSSescaped\" value={{{ [<currentTiddler>escapecss[]] }}}>\n<$keyboard key=\"((add-field))\" actions=<<new-field-actions>>>\n<$edit-text tiddler=<<newFieldValueTiddler>> tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} class=\"tc-edit-texteditor\" tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"/>\n</$keyboard>\n</$set>\n</span>\n<span class=\"tc-edit-field-add-button\">\n<$macrocall $name=\"new-field\"/>\n</span>\n</$vars>\n</div>\n</$fieldmangler>\n"
},
"$:/core/ui/EditTemplate/shadow": {
"title": "$:/core/ui/EditTemplate/shadow",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/Shadow/\n\\define pluginLinkBody()\n<$link to=\"\"\"$(pluginTitle)$\"\"\">\n<$text text=\"\"\"$(pluginTitle)$\"\"\"/>\n</$link>\n\\end\n<$list filter=\"[all[current]get[draft.of]is[shadow]!is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>\n\n<$list filter=\"[all[current]get[draft.of]is[shadow]is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo OverriddenWarning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>"
},
"$:/core/ui/EditTemplate/tags": {
"title": "$:/core/ui/EditTemplate/tags",
"tags": "$:/tags/EditTemplate",
"text": "\\whitespace trim\n\n\\define lingo-base() $:/language/EditTemplate/\n\n\\define tag-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n\\define tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:\"tags\")\n\\whitespace trim\n<$vars foregroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">> backgroundColor=\"\"\"$colour$\"\"\">\n<span style=<<tag-styles>> class=\"tc-tag-label tc-tag-list-item\">\n<$transclude tiddler=\"\"\"$icon$\"\"\"/><$view field=\"title\" format=\"text\" />\n<$button class=\"tc-btn-invisible tc-remove-tag-button\"><$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter=\"-[{!!title}]\"/>{{$:/core/images/close-button}}</$button>\n</span>\n</$vars>\n\\end\n\n\\define tag-body(colour,palette,icon,tagField:\"tags\")\n<$macrocall $name=\"tag-body-inner\" colour=\"\"\"$colour$\"\"\" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} icon=\"\"\"$icon$\"\"\" tagField=<<__tagField__>>/>\n\\end\n\n\\define edit-tags-template(tagField:\"tags\")\n\\whitespace trim\n<div class=\"tc-edit-tags\">\n<$list filter=\"[list[!!$tagField$]sort[title]]\" storyview=\"pop\">\n<$macrocall $name=\"tag-body\" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}} tagField=<<__tagField__>>/>\n</$list>\n<$vars tabIndex={{$:/config/EditTabIndex}} cancelPopups=\"yes\">\n<$macrocall $name=\"tag-picker\" tagField=<<__tagField__>>/>\n</$vars>\n</div>\n\\end\n<$set name=\"saveTiddler\" value=<<currentTiddler>>>\n<$macrocall $name=\"edit-tags-template\" tagField=<<tagField>>/>\n</$set>\n"
},
"$:/core/ui/EditTemplate/title": {
"title": "$:/core/ui/EditTemplate/title",
"tags": "$:/tags/EditTemplate",
"text": "<$edit-text field=\"draft.title\" class=\"tc-titlebar tc-edit-texteditor\" focus={{{ [{$:/config/AutoFocus}match[title]then[true]] ~[[false]] }}} tabindex={{$:/config/EditTabIndex}} cancelPopups=\"yes\"/>\n\n<$vars pattern=\"\"\"[\\|\\[\\]{}]\"\"\" bad-chars=\"\"\"`| [ ] { }`\"\"\">\n\n<$list filter=\"[all[current]regexp:draft.title<pattern>]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/BadCharacterWarning}}\n\n</div>\n\n</$list>\n\n</$vars>\n\n<$reveal state=\"!!draft.title\" type=\"nomatch\" text={{!!draft.of}} tag=\"div\">\n\n<$list filter=\"[{!!draft.title}!is[missing]]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/Exists/Prompt}}\n\n</div>\n\n</$list>\n\n<$list filter=\"[{!!draft.of}!is[missing]]\" variable=\"listItem\">\n\n<$vars fromTitle={{!!draft.of}} toTitle={{!!draft.title}}>\n\n<$checkbox tiddler=\"$:/config/RelinkOnRename\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> {{$:/language/EditTemplate/Title/Relink/Prompt}}</$checkbox>\n\n<$list filter=\"[title<fromTitle>backlinks[]limit[1]]\" variable=\"listItem\">\n\n<$vars stateTiddler=<<qualify \"$:/state/edit/references\">> >\n\n<$reveal type=\"nomatch\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"show\" class=\"tc-btn-invisible\">{{$:/core/images/right-arrow}} \n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"hide\" class=\"tc-btn-invisible\">{{$:/core/images/down-arrow}} \n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$tiddler tiddler=<<fromTitle>> >\n<$transclude tiddler=\"$:/core/ui/TiddlerInfo/References\"/>\n</$tiddler>\n</$reveal>\n\n</$vars>\n\n</$list>\n\n</$vars>\n\n</$list>\n\n</$reveal>\n"
},
"$:/core/ui/EditTemplate/type": {
"title": "$:/core/ui/EditTemplate/type",
"tags": "$:/tags/EditTemplate",
"first-search-filter": "[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]sort[description]sort[group-sort]removeprefix[$:/language/Docs/Types/]search<userInput>]",
"text": "\\define lingo-base() $:/language/EditTemplate/\n\\define input-cancel-actions() <$list filter=\"[<storeTitle>get[text]] [<currentTiddler>get[type]] +[limit[1]]\" emptyMessage=\"\"\"<<cancel-delete-tiddler-actions \"cancel\">>\"\"\"><$action-sendmessage $message=\"tm-remove-field\" $param=\"type\"/><$action-deletetiddler $filter=\"[<typeInputTiddler>] [<refreshTitle>] [<typeSelectionTiddler>]\"/></$list>\n\\whitespace trim\n<$set name=\"refreshTitle\" value=<<qualify \"$:/temp/type-search/refresh\">>>\n<div class=\"tc-edit-type-selector-wrapper\">\n<em class=\"tc-edit tc-big-gap-right\"><<lingo Type/Prompt>></em>\n<div class=\"tc-type-selector-dropdown-wrapper\">\n<div class=\"tc-type-selector\"><$fieldmangler>\n<$macrocall $name=\"keyboard-driven-input\" tiddler=<<currentTiddler>> storeTitle=<<typeInputTiddler>> refreshTitle=<<refreshTitle>> selectionStateTitle=<<typeSelectionTiddler>> field=\"type\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-edit-typeeditor tc-edit-texteditor tc-popup-handle\" tabindex={{$:/config/EditTabIndex}} focus={{{ [{$:/config/AutoFocus}match[type]then[true]] ~[[false]] }}} cancelPopups=\"yes\" configTiddlerFilter=\"[[$:/core/ui/EditTemplate/type]]\" inputCancelActions=<<input-cancel-actions>>/><$button popup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown tc-small-gap\" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$button message=\"tm-remove-field\" param=\"type\" class=\"tc-btn-invisible tc-btn-icon\" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}<$action-deletetiddler $filter=\"[<storeTitle>] [<refreshTitle>] [<selectionStateTitle>]\"/></$button>\n</$fieldmangler></div>\n\n<div class=\"tc-block-dropdown-wrapper\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$reveal state=<<qualify \"$:/state/popup/type-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$linkcatcher to=\"!!type\">\n<$list filter='[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]each[group]sort[group-sort]]'>\n<div class=\"tc-dropdown-item\">\n<$text text={{!!group}}/>\n</div>\n<$set name=\"userInput\" value={{{ [<typeInputTiddler>get[text]] }}}>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]] +[removeprefix[$:/language/Docs/Types/]] +[search<userInput>]\"><span class={{{ [<currentTiddler>addsuffix[-primaryList]] -[<typeSelectionTiddler>get[text]] +[then[]else[tc-list-item-selected]] }}}><$link to={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]get[name]] }}}><$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field=\"description\"/> (<$view tiddler={{{ [<currentTiddler>addprefix[$:/language/Docs/Types/]] }}} field=\"name\"/>)</$link></span>\n</$list>\n</$set>\n</$list>\n</$linkcatcher>\n</div>\n</$reveal>\n</$set>\n</div>\n</div>\n</div>\n</$set>\n"
},
"$:/core/ui/EditTemplate": {
"title": "$:/core/ui/EditTemplate",
"text": "\\define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter=\"[<newFieldNameTiddler>] [<newFieldValueTiddler>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]\"/>\n\\define save-tiddler-actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{{ [<newTagNameTiddler>get[text]] }}}/>\n<$action-sendmessage $message=\"tm-add-field\" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldValueTiddler>get[text]] }}}/>\n<<delete-edittemplate-state-tiddlers>>\n<$action-sendmessage $message=\"tm-save-tiddler\"/>\n\\end\n\\define cancel-delete-tiddler-actions(message)\n<<delete-edittemplate-state-tiddlers>>\n<$action-sendmessage $message=\"tm-$message$-tiddler\"/>\n\\end\n<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-edit-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>\n<$fieldmangler>\n<$vars storyTiddler=<<currentTiddler>> newTagNameTiddler=<<qualify \"$:/temp/NewTagName\">> newFieldNameTiddler=<<qualify \"$:/temp/NewFieldName\">> newFieldValueTiddler=<<qualify \"$:/temp/NewFieldValue\">> newFieldNameInputTiddler=<<qualify \"$:/temp/NewFieldName/input\">> newFieldNameSelectionTiddler=<<qualify \"$:/temp/NewFieldName/selected-item\">> newTagNameInputTiddler=<<qualify \"$:/temp/NewTagName/input\">> newTagNameSelectionTiddler=<<qualify \"$:/temp/NewTagName/selected-item\">> typeInputTiddler=<<qualify \"$:/temp/Type/input\">> typeSelectionTiddler=<<qualify \"$:/temp/Type/selected-item\">>>\n<$keyboard key=\"((cancel-edit-tiddler))\" actions=<<cancel-delete-tiddler-actions \"cancel\">>>\n<$keyboard key=\"((save-tiddler))\" actions=<<save-tiddler-actions>>>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]\" variable=\"listItem\">\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n<$transclude tiddler=<<listItem>>/>\n</$set>\n</$list>\n</$keyboard>\n</$keyboard>\n</$vars>\n</$fieldmangler>\n</div>\n"
},
"$:/core/ui/Buttons/cancel": {
"title": "$:/core/ui/Buttons/cancel",
"tags": "$:/tags/EditToolbar",
"caption": "{{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}}",
"description": "{{$:/language/Buttons/Cancel/Hint}}",
"text": "\\whitespace trim\n<$button actions=<<cancel-delete-tiddler-actions \"cancel\">> tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/cancel-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Cancel/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/core/ui/Buttons/delete": {
"title": "$:/core/ui/Buttons/delete",
"tags": "$:/tags/EditToolbar $:/tags/ViewToolbar",
"caption": "{{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}}",
"description": "{{$:/language/Buttons/Delete/Hint}}",
"text": "\\whitespace trim\n<$button actions=<<cancel-delete-tiddler-actions \"delete\">> tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/delete-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Delete/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/core/ui/Buttons/save": {
"title": "$:/core/ui/Buttons/save",
"tags": "$:/tags/EditToolbar",
"caption": "{{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}",
"description": "{{$:/language/Buttons/Save/Hint}}",
"text": "\\define save-tiddler-button()\n\\whitespace trim\n<$fieldmangler><$button tooltip={{$:/language/Buttons/Save/Hint}} aria-label={{$:/language/Buttons/Save/Caption}} class=<<tv-config-toolbar-class>>>\n<<save-tiddler-actions>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/done-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Save/Caption}}/></span>\n</$list>\n</$button></$fieldmangler>\n\\end\n<<save-tiddler-button>>\n"
},
"$:/core/ui/EditorToolbar/bold": {
"title": "$:/core/ui/EditorToolbar/bold",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/bold",
"caption": "{{$:/language/Buttons/Bold/Caption}}",
"description": "{{$:/language/Buttons/Bold/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((bold))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"''\"\n\tsuffix=\"''\"\n/>\n"
},
"$:/core/ui/EditorToolbar/clear-dropdown": {
"title": "$:/core/ui/EditorToolbar/clear-dropdown",
"text": "''{{$:/language/Buttons/Clear/Hint}}''\n\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"clear\"\n\tcolour=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n\n</div>\n"
},
"$:/core/ui/EditorToolbar/clear": {
"title": "$:/core/ui/EditorToolbar/clear",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/erase",
"caption": "{{$:/language/Buttons/Clear/Caption}}",
"description": "{{$:/language/Buttons/Clear/Hint}}",
"condition": "[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]",
"dropdown": "$:/core/ui/EditorToolbar/clear-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/editor-height-dropdown": {
"title": "$:/core/ui/EditorToolbar/editor-height-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/EditorHeight/\n''<<lingo Hint>>''\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"auto\"> {{$:/core/images/auto-height}} <<lingo Caption/Auto>></$radio>\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"fixed\"> {{$:/core/images/fixed-height}} <<lingo Caption/Fixed>> <$edit-text tag=\"input\" tiddler=\"$:/config/TextEditor/EditorHeight/Height\" default=\"100px\"/></$radio>\n"
},
"$:/core/ui/EditorToolbar/editor-height": {
"title": "$:/core/ui/EditorToolbar/editor-height",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/fixed-height",
"custom-icon": "yes",
"caption": "{{$:/language/Buttons/EditorHeight/Caption}}",
"description": "{{$:/language/Buttons/EditorHeight/Hint}}",
"condition": "[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]",
"dropdown": "$:/core/ui/EditorToolbar/editor-height-dropdown",
"text": "<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n{{$:/core/images/fixed-height}}\n</$reveal>\n<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n{{$:/core/images/auto-height}}\n</$reveal>\n"
},
"$:/core/ui/EditorToolbar/excise-dropdown": {
"title": "$:/core/ui/EditorToolbar/excise-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Excise/\n\n\\define body(config-title)\n''<<lingo Hint>>''\n\n<<lingo Caption/NewTitle>> <$edit-text tag=\"input\" tiddler=\"$config-title$/new-title\" default=\"\" focus=\"true\"/>\n\n<$set name=\"new-title\" value={{$config-title$/new-title}}>\n<$list filter=\"\"\"[<new-title>is[tiddler]]\"\"\">\n<div class=\"tc-error\">\n<<lingo Caption/TiddlerExists>>\n</div>\n</$list>\n</$set>\n\n<$checkbox tiddler=\"\"\"$config-title$/tagnew\"\"\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"false\"> <<lingo Caption/Tag>></$checkbox>\n\n<<lingo Caption/Replace>> <$select tiddler=\"\"\"$config-title$/type\"\"\" default=\"transclude\">\n<option value=\"link\"><<lingo Caption/Replace/Link>></option>\n<option value=\"transclude\"><<lingo Caption/Replace/Transclusion>></option>\n<option value=\"macro\"><<lingo Caption/Replace/Macro>></option>\n</$select>\n\n<$reveal state=\"\"\"$config-title$/type\"\"\" type=\"match\" text=\"macro\">\n<<lingo Caption/MacroName>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/macro-title\"\"\" default=\"translink\"/>\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"excise\"\n\ttitle={{$config-title$/new-title}}\n\ttype={{$config-title$/type}}\n\tmacro={{$config-title$/macro-title}}\n\ttagnew={{$config-title$/tagnew}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"$config-title$/new-title\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Excise>>\n</$button>\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Excise/\">>/>\n"
},
"$:/core/ui/EditorToolbar/excise": {
"title": "$:/core/ui/EditorToolbar/excise",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/excise",
"caption": "{{$:/language/Buttons/Excise/Caption}}",
"description": "{{$:/language/Buttons/Excise/Hint}}",
"condition": "[<targetTiddler>type[]] [<targetTiddler>type[text/vnd.tiddlywiki]] +[first[]]",
"shortcuts": "((excise))",
"dropdown": "$:/core/ui/EditorToolbar/excise-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/heading-1": {
"title": "$:/core/ui/EditorToolbar/heading-1",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-1",
"caption": "{{$:/language/Buttons/Heading1/Caption}}",
"description": "{{$:/language/Buttons/Heading1/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((heading-1))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"1\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-2": {
"title": "$:/core/ui/EditorToolbar/heading-2",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-2",
"caption": "{{$:/language/Buttons/Heading2/Caption}}",
"description": "{{$:/language/Buttons/Heading2/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-2))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"2\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-3": {
"title": "$:/core/ui/EditorToolbar/heading-3",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-3",
"caption": "{{$:/language/Buttons/Heading3/Caption}}",
"description": "{{$:/language/Buttons/Heading3/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-3))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"3\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-4": {
"title": "$:/core/ui/EditorToolbar/heading-4",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-4",
"caption": "{{$:/language/Buttons/Heading4/Caption}}",
"description": "{{$:/language/Buttons/Heading4/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-4))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"4\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-5": {
"title": "$:/core/ui/EditorToolbar/heading-5",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-5",
"caption": "{{$:/language/Buttons/Heading5/Caption}}",
"description": "{{$:/language/Buttons/Heading5/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-5))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"5\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-6": {
"title": "$:/core/ui/EditorToolbar/heading-6",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-6",
"caption": "{{$:/language/Buttons/Heading6/Caption}}",
"description": "{{$:/language/Buttons/Heading6/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-6))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"6\"\n/>\n"
},
"$:/core/ui/EditorToolbar/italic": {
"title": "$:/core/ui/EditorToolbar/italic",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/italic",
"caption": "{{$:/language/Buttons/Italic/Caption}}",
"description": "{{$:/language/Buttons/Italic/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((italic))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"//\"\n\tsuffix=\"//\"\n/>\n"
},
"$:/core/ui/EditorToolbar/line-width-dropdown": {
"title": "$:/core/ui/EditorToolbar/line-width-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/LineWidth/\n\n\\define toolbar-line-width-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(line-width)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/LineWidth\"\n\t$value=\"$(line-width)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; margin: 4px calc(80px - $(line-width)$); background-color: #000; width: calc(100px + $(line-width)$ * 2); height: $(line-width)$; border-radius: 120px; vertical-align: middle;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(line-width)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/LineWidth\" type=\"match\" text=\"\"\"$(line-width)$\"\"\" tag=\"span\">\n\n<$entity entity=\" \"/>\n\n<$entity entity=\"✓\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/LineWidths}} variable=\"line-width\">\n\n<<toolbar-line-width-inner>>\n\n</$list>\n"
},
"$:/core/ui/EditorToolbar/line-width": {
"title": "$:/core/ui/EditorToolbar/line-width",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/line-width",
"caption": "{{$:/language/Buttons/LineWidth/Caption}}",
"description": "{{$:/language/Buttons/LineWidth/Hint}}",
"condition": "[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]",
"dropdown": "$:/core/ui/EditorToolbar/line-width-dropdown",
"text": "<$text text={{$:/config/BitmapEditor/LineWidth}}/>\n"
},
"$:/core/ui/EditorToolbar/link-dropdown": {
"title": "$:/core/ui/EditorToolbar/link-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Link/\n\n\\define add-link-actions()\n<$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"make-link\" text={{$(linkTiddler)$}} />\n<$action-deletetiddler $filter=\"[<dropdown-state>] [<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]\"/>\n\\end\n\n\\define get-focus-selector() [data-tiddler-title=\"$(cssEscapedTitle)$\"] .tc-create-wikitext-link input\n\n\\define cancel-search-actions-inner()\n<$set name=\"userInput\" value={{{ [<storeTitle>get[text]] }}}><$list filter=\"[<searchTiddler>get[text]!match<userInput>]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[<searchTiddler>] [<linkTiddler>] [<storeTitle>] [<searchListState>]\"/>\"\"\"><$action-setfield $tiddler=<<searchTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/></$list></$set>\n\\end\n\n\\define cancel-search-actions() <$list filter=\"[<storeTitle>!has[text]] +[<searchTiddler>!has[text]]\" emptyMessage=\"\"\"<<cancel-search-actions-inner>>\"\"\"><$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"wrap-selection\" prefix=\"\" suffix=\"\"/></$list>\n\n\\define external-link()\n<$button class=\"tc-btn-invisible\" style=\"width: auto; display: inline-block; background-colour: inherit;\" actions=<<add-link-actions>>>\n{{$:/core/images/chevron-right}}\n</$button>\n\\end\n\n\\define set-next-input-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" beforeafter=\"$beforeafter$\" defaultState={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/search/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define body(config-title)\n''<<lingo Hint>>''\n\n<$vars searchTiddler=\"\"\"$config-title$/search\"\"\" linkTiddler=\"\"\"$config-title$/link\"\"\" linktext=\"\" searchListState=<<qualify \"$:/temp/link-search/selected-item\">> refreshTitle=<<qualify \"$:/temp/link-search/refresh\">> storeTitle=<<qualify \"$:/temp/link-search/input\">>>\n\n<$vars linkTiddler=<<searchTiddler>>>\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">> class=\"tc-create-wikitext-link\">\n<$macrocall $name=\"keyboard-driven-input\" tiddler=<<searchTiddler>> storeTitle=<<storeTitle>>\n\t\tselectionStateTitle=<<searchListState>> refreshTitle=<<refreshTitle>> type=\"search\" filterMinLength=\"1\"\n\t\ttag=\"input\" focus=\"true\" class=\"tc-popup-handle\" inputCancelActions=<<cancel-search-actions>> \n\t\tinputAcceptActions=<<add-link-actions>> placeholder={{$:/language/Search/Search}} default=\"\" \n\t\tconfigTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]\" />\n</$keyboard>\n</$keyboard>\n<$reveal tag=\"span\" state=<<storeTitle>> type=\"nomatch\" text=\"\">\n<<external-link>>\n<$button class=\"tc-btn-invisible\" style=\"width: auto; display: inline-block; background-colour: inherit;\">\n<<cancel-search-actions>><$set name=\"cssEscapedTitle\" value={{{ [<storyTiddler>escapecss[]] }}}><$action-sendmessage $message=\"tm-focus-selector\" $param=<<get-focus-selector>>/></$set>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</$vars>\n\n<$reveal tag=\"div\" state=<<storeTitle>> type=\"nomatch\" text=\"\">\n\n<$linkcatcher actions=<<add-link-actions>> to=<<linkTiddler>>>\n\n<$vars userInput={{{ [<storeTitle>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}}>\n\n{{$:/core/ui/SearchResults}}\n\n</$vars>\n\n</$linkcatcher>\n\n</$reveal>\n\n</$vars>\n\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Link/\">>/>\n"
},
"$:/core/ui/EditorToolbar/link": {
"title": "$:/core/ui/EditorToolbar/link",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/link",
"caption": "{{$:/language/Buttons/Link/Caption}}",
"description": "{{$:/language/Buttons/Link/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((link))",
"dropdown": "$:/core/ui/EditorToolbar/link-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/linkify": {
"title": "$:/core/ui/EditorToolbar/linkify",
"caption": "{{$:/language/Buttons/Linkify/Caption}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"description": "{{$:/language/Buttons/Linkify/Hint}}",
"icon": "$:/core/images/linkify",
"list-before": "$:/core/ui/EditorToolbar/mono-block",
"shortcuts": "((linkify))",
"tags": "$:/tags/EditorToolbar",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"[[\"\n\tsuffix=\"]]\"\n/>\n"
},
"$:/core/ui/EditorToolbar/list-bullet": {
"title": "$:/core/ui/EditorToolbar/list-bullet",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/list-bullet",
"caption": "{{$:/language/Buttons/ListBullet/Caption}}",
"description": "{{$:/language/Buttons/ListBullet/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((list-bullet))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"*\"\n\tcount=\"1\"\n/>\n"
},
"$:/core/ui/EditorToolbar/list-number": {
"title": "$:/core/ui/EditorToolbar/list-number",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/list-number",
"caption": "{{$:/language/Buttons/ListNumber/Caption}}",
"description": "{{$:/language/Buttons/ListNumber/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((list-number))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"1\"\n/>\n"
},
"$:/core/ui/EditorToolbar/mono-block": {
"title": "$:/core/ui/EditorToolbar/mono-block",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/mono-block",
"caption": "{{$:/language/Buttons/MonoBlock/Caption}}",
"description": "{{$:/language/Buttons/MonoBlock/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((mono-block))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n```\"\n\tsuffix=\"```\"\n/>\n"
},
"$:/core/ui/EditorToolbar/mono-line": {
"title": "$:/core/ui/EditorToolbar/mono-line",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/mono-line",
"caption": "{{$:/language/Buttons/MonoLine/Caption}}",
"description": "{{$:/language/Buttons/MonoLine/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((mono-line))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"`\"\n\tsuffix=\"`\"\n/>\n"
},
"$:/core/ui/EditorToolbar/more-dropdown": {
"title": "$:/core/ui/EditorToolbar/more-dropdown",
"text": "\\define config-title()\n$:/config/EditorToolbarButtons/Visibility/$(toolbarItem)$\n\\end\n\n\\define conditional-button()\n<$list filter={{$(toolbarItem)$!!condition}} variable=\"condition\">\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\" mode=\"inline\"/> <$transclude tiddler=<<toolbarItem>> field=\"description\"/>\n</$list>\n\\end\n\n<div class=\"tc-text-editor-toolbar-more\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]] -[[$:/core/ui/EditorToolbar/more]]\">\n<$reveal type=\"match\" state=<<config-visibility-title>> text=\"hide\" tag=\"div\">\n<<conditional-button>>\n</$reveal>\n</$list>\n</div>\n"
},
"$:/core/ui/EditorToolbar/more": {
"title": "$:/core/ui/EditorToolbar/more",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/down-arrow",
"caption": "{{$:/language/Buttons/More/Caption}}",
"description": "{{$:/language/Buttons/More/Hint}}",
"condition": "[<targetTiddler>]",
"dropdown": "$:/core/ui/EditorToolbar/more-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/opacity-dropdown": {
"title": "$:/core/ui/EditorToolbar/opacity-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Opacity/\n\n\\define toolbar-opacity-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(opacity)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Opacity\"\n\t$value=\"$(opacity)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(current-paint-colour)$; opacity: $(opacity)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(opacity)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/Opacity\" type=\"match\" text=\"\"\"$(opacity)$\"\"\" tag=\"span\">\n\n<$entity entity=\" \"/>\n\n<$entity entity=\"✓\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n\\define toolbar-opacity()\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/Opacities}} variable=\"opacity\">\n\n<<toolbar-opacity-inner>>\n\n</$list>\n\\end\n\n<$set name=\"current-paint-colour\" value={{$:/config/BitmapEditor/Colour}}>\n\n<$set name=\"current-opacity\" value={{$:/config/BitmapEditor/Opacity}}>\n\n<<toolbar-opacity>>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/EditorToolbar/opacity": {
"title": "$:/core/ui/EditorToolbar/opacity",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/opacity",
"caption": "{{$:/language/Buttons/Opacity/Caption}}",
"description": "{{$:/language/Buttons/Opacity/Hint}}",
"condition": "[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]",
"dropdown": "$:/core/ui/EditorToolbar/opacity-dropdown",
"text": "<$text text={{$:/config/BitmapEditor/Opacity}}/>\n"
},
"$:/core/ui/EditorToolbar/paint-dropdown": {
"title": "$:/core/ui/EditorToolbar/paint-dropdown",
"text": "''{{$:/language/Buttons/Paint/Hint}}''\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Colour\"\n\t$value=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"
},
"$:/core/ui/EditorToolbar/paint": {
"title": "$:/core/ui/EditorToolbar/paint",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/paint",
"caption": "{{$:/language/Buttons/Paint/Caption}}",
"description": "{{$:/language/Buttons/Paint/Hint}}",
"condition": "[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]",
"dropdown": "$:/core/ui/EditorToolbar/paint-dropdown",
"text": "\\define toolbar-paint()\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(colour-picker-value)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\\end\n<$set name=\"colour-picker-value\" value={{$:/config/BitmapEditor/Colour}}>\n<<toolbar-paint>>\n</$set>\n"
},
"$:/core/ui/EditorToolbar/picture-dropdown": {
"title": "$:/core/ui/EditorToolbar/picture-dropdown",
"text": "\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n''{{$:/language/Buttons/Picture/Hint}}''\n\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext=<<replacement-text>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"
},
"$:/core/ui/EditorToolbar/picture": {
"title": "$:/core/ui/EditorToolbar/picture",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/picture",
"caption": "{{$:/language/Buttons/Picture/Caption}}",
"description": "{{$:/language/Buttons/Picture/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((picture))",
"dropdown": "$:/core/ui/EditorToolbar/picture-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/preview-type-dropdown": {
"title": "$:/core/ui/EditorToolbar/preview-type-dropdown",
"text": "\\define preview-type-button()\n<$button tag=\"a\">\n\n<$action-setfield $tiddler=\"$:/state/editpreviewtype\" $value=\"$(previewType)$\"/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$transclude tiddler=<<previewType>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<previewType>> field=\"title\" mode=\"inline\"/>\n\n</$transclude> \n\n<$reveal tag=\"span\" state=\"$:/state/editpreviewtype\" type=\"match\" text=<<previewType>> default=\"$:/core/ui/EditTemplate/body/preview/output\">\n\n<$entity entity=\" \"/>\n\n<$entity entity=\"✓\"/>\n\n</$reveal>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]]\" variable=\"previewType\">\n\n<<preview-type-button>>\n\n</$list>\n"
},
"$:/core/ui/EditorToolbar/preview-type": {
"title": "$:/core/ui/EditorToolbar/preview-type",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/chevron-down",
"caption": "{{$:/language/Buttons/PreviewType/Caption}}",
"description": "{{$:/language/Buttons/PreviewType/Hint}}",
"condition": "[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]butfirst[]limit[1]]",
"button-classes": "tc-text-editor-toolbar-item-adjunct",
"dropdown": "$:/core/ui/EditorToolbar/preview-type-dropdown"
},
"$:/core/ui/EditorToolbar/preview": {
"title": "$:/core/ui/EditorToolbar/preview",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/preview-open",
"custom-icon": "yes",
"caption": "{{$:/language/Buttons/Preview/Caption}}",
"description": "{{$:/language/Buttons/Preview/Hint}}",
"condition": "[<targetTiddler>]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((preview))",
"text": "<$reveal state=\"$:/state/showeditpreview\" type=\"match\" text=\"yes\" tag=\"span\">\n{{$:/core/images/preview-open}}\n<$action-setfield $tiddler=\"$:/state/showeditpreview\" $value=\"no\"/>\n</$reveal>\n<$reveal state=\"$:/state/showeditpreview\" type=\"nomatch\" text=\"yes\" tag=\"span\">\n{{$:/core/images/preview-closed}}\n<$action-setfield $tiddler=\"$:/state/showeditpreview\" $value=\"yes\"/>\n</$reveal>\n"
},
"$:/core/ui/EditorToolbar/quote": {
"title": "$:/core/ui/EditorToolbar/quote",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/quote",
"caption": "{{$:/language/Buttons/Quote/Caption}}",
"description": "{{$:/language/Buttons/Quote/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((quote))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n<<<\"\n\tsuffix=\"<<<\"\n/>\n"
},
"$:/core/ui/EditorToolbar/rotate-left": {
"title": "$:/core/ui/EditorToolbar/rotate-left",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/rotate-left",
"caption": "{{$:/language/Buttons/RotateLeft/Caption}}",
"description": "{{$:/language/Buttons/RotateLeft/Hint}}",
"condition": "[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"rotate-left\"\n/>\n"
},
"$:/core/ui/EditorToolbar/size-dropdown": {
"title": "$:/core/ui/EditorToolbar/size-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Size/\n\n\\define toolbar-button-size-preset(config-title)\n<$set name=\"width\" filter=\"$(sizePair)$ +[first[]]\">\n\n<$set name=\"height\" filter=\"$(sizePair)$ +[last[]]\">\n\n<$button tag=\"a\">\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n\t$value=<<width>>\n/>\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n\t$value=<<height>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/presets-popup\"\"\"\n/>\n\n<$text text=<<width>>/> × <$text text=<<height>>/>\n\n</$button>\n\n</$set>\n\n</$set>\n\\end\n\n\\define toolbar-button-size(config-title)\n''{{$:/language/Buttons/Size/Hint}}''\n\n<<lingo Caption/Width>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-width\"\"\" default=<<tv-bitmap-editor-width>> focus=\"true\" size=\"8\"/> <<lingo Caption/Height>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-height\"\"\" default=<<tv-bitmap-editor-height>> size=\"8\"/> <$button popup=\"\"\"$config-title$/presets-popup\"\"\" class=\"tc-btn-invisible tc-popup-keep\" style=\"width: auto; display: inline-block; background-colour: inherit;\" selectedClass=\"tc-selected\">\n{{$:/core/images/down-arrow}}\n</$button>\n\n<$reveal tag=\"span\" state=\"\"\"$config-title$/presets-popup\"\"\" type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down tc-popup-keep\">\n\n<$list filter={{$:/config/BitmapEditor/ImageSizes}} variable=\"sizePair\">\n\n<$macrocall $name=\"toolbar-button-size-preset\" config-title=\"$config-title$\"/>\n\n</$list>\n\n</div>\n\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"resize\"\n\twidth={{$config-title$/new-width}}\n\theight={{$config-title$/new-height}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Resize>>\n</$button>\n\\end\n\n<$macrocall $name=\"toolbar-button-size\" config-title=<<qualify \"$:/state/Size/\">>/>\n"
},
"$:/core/ui/EditorToolbar/size": {
"title": "$:/core/ui/EditorToolbar/size",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/size",
"caption": "{{$:/language/Buttons/Size/Caption}}",
"description": "{{$:/language/Buttons/Size/Hint}}",
"condition": "[<targetTiddler>is[image]] -[<targetTiddler>type[image/svg+xml]]",
"dropdown": "$:/core/ui/EditorToolbar/size-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/stamp-dropdown": {
"title": "$:/core/ui/EditorToolbar/stamp-dropdown",
"text": "\\define toolbar-button-stamp-inner()\n<$button tag=\"a\">\n\n<$list filter=\"[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]]\">\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext={{$(snippetTitle)$}}\n/>\n\n</$list>\n\n\n<$list filter=\"[[$(snippetTitle)$]addsuffix[/prefix]is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]is[missing]] [[$(snippetTitle)$]addsuffix[/prefix]!is[missing]removesuffix[/prefix]addsuffix[/suffix]!is[missing]]\">\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix={{{ [[$(snippetTitle)$]addsuffix[/prefix]get[text]] }}}\nsuffix={{{ [[$(snippetTitle)$]addsuffix[/suffix]get[text]] }}}\n/>\n\n</$list>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$transclude tiddler=<<snippetTitle>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<snippetTitle>> field=\"title\" />\n\n</$transclude>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TextEditor/Snippet]!has[draft.of]sort[caption]]\" variable=\"snippetTitle\">\n\n<<toolbar-button-stamp-inner>>\n\n</$list>\n\n----\n\n<$button tag=\"a\">\n\n<$action-sendmessage\n\t$message=\"tm-new-tiddler\"\n\ttags=\"$:/tags/TextEditor/Snippet\"\n\tcaption={{$:/language/Buttons/Stamp/New/Title}}\n\ttext={{$:/language/Buttons/Stamp/New/Text}}\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<em>\n\n<$text text={{$:/language/Buttons/Stamp/Caption/New}}/>\n\n</em>\n\n</$button>\n"
},
"$:/core/ui/EditorToolbar/stamp": {
"title": "$:/core/ui/EditorToolbar/stamp",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/stamp",
"caption": "{{$:/language/Buttons/Stamp/Caption}}",
"description": "{{$:/language/Buttons/Stamp/Hint}}",
"condition": "[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] [<targetTiddler>get[type]match[application/javascript]] [<targetTiddler>get[type]match[application/json]] [<targetTiddler>get[type]match[application/x-tiddler-dictionary]] [<targetTiddler>get[type]match[image/svg+xml]] +[first[]]",
"shortcuts": "((stamp))",
"dropdown": "$:/core/ui/EditorToolbar/stamp-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/strikethrough": {
"title": "$:/core/ui/EditorToolbar/strikethrough",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/strikethrough",
"caption": "{{$:/language/Buttons/Strikethrough/Caption}}",
"description": "{{$:/language/Buttons/Strikethrough/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((strikethrough))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"~~\"\n\tsuffix=\"~~\"\n/>\n"
},
"$:/core/ui/EditorToolbar/subscript": {
"title": "$:/core/ui/EditorToolbar/subscript",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/subscript",
"caption": "{{$:/language/Buttons/Subscript/Caption}}",
"description": "{{$:/language/Buttons/Subscript/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((subscript))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\",,\"\n\tsuffix=\",,\"\n/>\n"
},
"$:/core/ui/EditorToolbar/superscript": {
"title": "$:/core/ui/EditorToolbar/superscript",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/superscript",
"caption": "{{$:/language/Buttons/Superscript/Caption}}",
"description": "{{$:/language/Buttons/Superscript/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((superscript))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"^^\"\n\tsuffix=\"^^\"\n/>\n"
},
"$:/core/ui/EditorToolbar/transcludify": {
"title": "$:/core/ui/EditorToolbar/transcludify",
"caption": "{{$:/language/Buttons/Transcludify/Caption}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"description": "{{$:/language/Buttons/Transcludify/Hint}}",
"icon": "$:/core/images/transcludify",
"list-before": "$:/core/ui/EditorToolbar/mono-block",
"shortcuts": "((transcludify))",
"tags": "$:/tags/EditorToolbar",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"{{\"\n\tsuffix=\"}}\"\n/>\n"
},
"$:/core/ui/EditorToolbar/underline": {
"title": "$:/core/ui/EditorToolbar/underline",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/underline",
"caption": "{{$:/language/Buttons/Underline/Caption}}",
"description": "{{$:/language/Buttons/Underline/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((underline))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"__\"\n\tsuffix=\"__\"\n/>\n"
},
"$:/core/Filters/AllTags": {
"title": "$:/core/Filters/AllTags",
"tags": "$:/tags/Filter",
"filter": "[tags[]!is[system]sort[title]]",
"description": "{{$:/language/Filters/AllTags}}",
"text": ""
},
"$:/core/Filters/AllTiddlers": {
"title": "$:/core/Filters/AllTiddlers",
"tags": "$:/tags/Filter",
"filter": "[!is[system]sort[title]]",
"description": "{{$:/language/Filters/AllTiddlers}}",
"text": ""
},
"$:/core/Filters/Drafts": {
"title": "$:/core/Filters/Drafts",
"tags": "$:/tags/Filter",
"filter": "[has[draft.of]sort[title]]",
"description": "{{$:/language/Filters/Drafts}}",
"text": ""
},
"$:/core/Filters/Missing": {
"title": "$:/core/Filters/Missing",
"tags": "$:/tags/Filter",
"filter": "[all[missing]sort[title]]",
"description": "{{$:/language/Filters/Missing}}",
"text": ""
},
"$:/core/Filters/Orphans": {
"title": "$:/core/Filters/Orphans",
"tags": "$:/tags/Filter",
"filter": "[all[orphans]sort[title]]",
"description": "{{$:/language/Filters/Orphans}}",
"text": ""
},
"$:/core/Filters/OverriddenShadowTiddlers": {
"title": "$:/core/Filters/OverriddenShadowTiddlers",
"tags": "$:/tags/Filter",
"filter": "[is[shadow]]",
"description": "{{$:/language/Filters/OverriddenShadowTiddlers}}",
"text": ""
},
"$:/core/Filters/RecentSystemTiddlers": {
"title": "$:/core/Filters/RecentSystemTiddlers",
"tags": "$:/tags/Filter",
"filter": "[has[modified]!sort[modified]limit[50]]",
"description": "{{$:/language/Filters/RecentSystemTiddlers}}",
"text": ""
},
"$:/core/Filters/RecentTiddlers": {
"title": "$:/core/Filters/RecentTiddlers",
"tags": "$:/tags/Filter",
"filter": "[!is[system]has[modified]!sort[modified]limit[50]]",
"description": "{{$:/language/Filters/RecentTiddlers}}",
"text": ""
},
"$:/core/Filters/SessionTiddlers": {
"title": "$:/core/Filters/SessionTiddlers",
"tags": "$:/tags/Filter",
"filter": "[haschanged[]]",
"description": "{{$:/language/Filters/SessionTiddlers}}",
"text": ""
},
"$:/core/Filters/ShadowTiddlers": {
"title": "$:/core/Filters/ShadowTiddlers",
"tags": "$:/tags/Filter",
"filter": "[all[shadows]sort[title]]",
"description": "{{$:/language/Filters/ShadowTiddlers}}",
"text": ""
},
"$:/core/Filters/StoryList": {
"title": "$:/core/Filters/StoryList",
"tags": "$:/tags/Filter",
"filter": "[list[$:/StoryList]] -$:/AdvancedSearch",
"description": "{{$:/language/Filters/StoryList}}",
"text": ""
},
"$:/core/Filters/SystemTags": {
"title": "$:/core/Filters/SystemTags",
"tags": "$:/tags/Filter",
"filter": "[all[shadows+tiddlers]tags[]is[system]sort[title]]",
"description": "{{$:/language/Filters/SystemTags}}",
"text": ""
},
"$:/core/Filters/SystemTiddlers": {
"title": "$:/core/Filters/SystemTiddlers",
"tags": "$:/tags/Filter",
"filter": "[is[system]sort[title]]",
"description": "{{$:/language/Filters/SystemTiddlers}}",
"text": ""
},
"$:/core/Filters/TypedTiddlers": {
"title": "$:/core/Filters/TypedTiddlers",
"tags": "$:/tags/Filter",
"filter": "[!is[system]has[type]each[type]sort[type]] -[type[text/vnd.tiddlywiki]]",
"description": "{{$:/language/Filters/TypedTiddlers}}",
"text": ""
},
"$:/core/ui/ImportListing": {
"title": "$:/core/ui/ImportListing",
"text": "\\define lingo-base() $:/language/Import/\n\n\\define messageField() message-$(payloadTiddler)$\n\n\\define payloadTitleFilter() [<currentTiddler>get<renameField>minlength[1]else<payloadTiddler>]\n\n\\define overWriteWarning()\n<$list filter=\"[<currentTiddler>!has<suppressedField>]\">\n<$text text={{{[subfilter<payloadTitleFilter>!is[tiddler]then[]] ~[<lingo-base>addsuffix[Listing/Rename/OverwriteWarning]get[text]]}}}/>\n</$list>\n\\end\n\n\\define selectionField() selection-$(payloadTiddler)$\n\n\\define renameField() rename-$(payloadTiddler)$\n\n\\define suppressedField() suppressed-$(payloadTiddler)$\n\n\\define newImportTitleTiddler() $:/temp/NewImportTitle-$(payloadTiddler)$\n\n\\define previewPopupState() $(currentTiddler)$!!popup-$(payloadTiddler)$\n\n\\define renameFieldState() $(currentTiddler)$!!state-rename-$(payloadTiddler)$\n\n\\define select-all-actions()\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<$action-setfield $field={{{ [<payloadTiddler>addprefix[selection-]] }}} $value={{$:/state/import/select-all}}/>\n</$list>\n\\end\n\n<table class=\"tc-import-table\">\n<tbody>\n<tr>\n<th align=\"left\">\n<$checkbox tiddler=\"$:/state/import/select-all\" field=\"text\" checked=\"checked\" unchecked=\"unchecked\" default=\"checked\" actions=<<select-all-actions>>>\n<<lingo Listing/Select/Caption>>\n</$checkbox>\n</th>\n<th>\n<<lingo Listing/Title/Caption>>\n</th>\n<th>\n<<lingo Listing/Status/Caption>>\n</th>\n</tr>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<tr class={{{[<currentTiddler>has<suppressedField>then[tc-row-disabled]] ~[subfilter<payloadTitleFilter>is[tiddler]then[tc-row-warning]] }}}>\n<td>\n<$checkbox field=<<selectionField>> checked=\"checked\" unchecked=\"unchecked\" default=\"checked\" disabled={{{[<currentTiddler>has<suppressedField>then[yes]else[no]]}}}/>\n</td>\n<td>\n<$reveal type=\"nomatch\" state=<<renameFieldState>> text=\"yes\" tag=\"div\">\n<$reveal type=\"nomatch\" state=<<previewPopupState>> text=\"yes\" tag=\"div\" class=\"tc-flex\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown tc-flex-grow-1 tc-word-break\" set=<<previewPopupState>> setTo=\"yes\" disabled={{{[<currentTiddler>has<suppressedField>then[yes]else[no]]}}}>\n<span class=\"tc-small-gap-right\">{{$:/core/images/right-arrow}}</span><$text text={{{[subfilter<payloadTitleFilter>]}}}/>\n</$button>\n<$list filter=\"[<currentTiddler>!has<suppressedField>]\"><$button class=\"tc-btn-invisible\" set=<<renameFieldState>> setTo=\"yes\" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/Tooltip]get[text]]}}}>{{$:/core/images/edit-button}}</$button></$list>\n</$reveal>\n<$reveal type=\"match\" state=<<previewPopupState>> text=\"yes\" tag=\"div\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<previewPopupState>> setTo=\"no\">\n<span class=\"tc-small-gap-right\">{{$:/core/images/down-arrow}}</span><$text text={{{[subfilter<payloadTitleFilter>]}}}/>\n</$button>\n</$reveal>\n</$reveal>\n<$reveal type=\"match\" state=<<renameFieldState>> text=\"yes\" tag=\"div\">\n<$text text={{{[<lingo-base>addsuffix[Listing/Rename/Prompt]get[text]]}}}/>\n</$reveal>\n</td>\n<td>\n<$view field=<<messageField>>/>\n<<overWriteWarning>>\n</td>\n</tr>\n<$reveal type=\"match\" state=<<renameFieldState>> text=\"yes\" tag=\"tr\">\n<td colspan=\"3\">\n<div class=\"tc-flex\">\n<$edit-text tiddler=<<newImportTitleTiddler>> default={{{[subfilter<payloadTitleFilter>]}}} tag=\"input\" class=\"tc-import-rename tc-flex-grow-1\"/><span class=\"tc-small-gap-left\"><$button class=\"tc-btn-invisible\" set=<<renameFieldState>> setTo=\"no\" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/CancelRename]get[text]]}}}>{{$:/core/images/close-button}}<$action-deletetiddler $tiddler=<<newImportTitleTiddler>>/></$button><span class=\"tc-small-gap-right\"/></span><$button class=\"tc-btn-invisible\" set=<<renameFieldState>> setTo=\"no\" tooltip={{{[<lingo-base>addsuffix[Listing/Rename/ConfirmRename]get[text]]}}}>{{$:/core/images/done-button}}<$action-setfield $field=<<renameField>> $value={{{[<newImportTitleTiddler>get[text]minlength[1]else<payloadTiddler>]}}} /><$action-deletetiddler $tiddler=<<newImportTitleTiddler>>/></$button>\n</div>\n</td>\n</$reveal>\n<tr>\n<td colspan=\"3\">\n<$reveal type=\"match\" text=\"yes\" state=<<previewPopupState>> tag=\"div\">\n<$list filter=\"[{$:/state/importpreviewtype}has[text]]\" variable=\"listItem\" emptyMessage={{$:/core/ui/ImportPreviews/Text}}>\n<$transclude tiddler={{$:/state/importpreviewtype}}/>\n</$list>\n</$reveal>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ImportPreviews/Diff": {
"title": "$:/core/ui/ImportPreviews/Diff",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/Diff}}",
"text": "<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>>/>\n"
},
"$:/core/ui/ImportPreviews/DiffFields": {
"title": "$:/core/ui/ImportPreviews/DiffFields",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/DiffFields}}",
"text": "<$macrocall $name=\"compareTiddlers\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>> exclude=\"text\"/>\n"
},
"$:/core/ui/ImportPreviews/Fields": {
"title": "$:/core/ui/ImportPreviews/Fields",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/Fields}}",
"text": "<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[<payloadTiddler>subtiddlerfields<currentTiddler>sort[]] -text\" variable=\"fieldName\">\n<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<fieldName>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<fieldName>> tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>>/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ImportPreviews/Text": {
"title": "$:/core/ui/ImportPreviews/Text",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/Text}}",
"text": "<$transclude tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> mode=\"block\"/>\n"
},
"$:/core/ui/ImportPreviews/TextRaw": {
"title": "$:/core/ui/ImportPreviews/TextRaw",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/TextRaw}}",
"text": "<pre><code><$view tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> /></code></pre>"
},
"$:/core/ui/KeyboardShortcuts/advanced-search": {
"title": "$:/core/ui/KeyboardShortcuts/advanced-search",
"tags": "$:/tags/KeyboardShortcut",
"key": "((advanced-search))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n<$action-navigate $to=\"$:/AdvancedSearch\"/>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\"[data-tiddler-title=\"$:/AdvancedSearch\"] .tc-search input\"\"\" preventScroll=\"true\"/>\n</$navigator>\n"
},
"$:/core/ui/KeyboardShortcuts/change-sidebar-layout": {
"title": "$:/core/ui/KeyboardShortcuts/change-sidebar-layout",
"tags": "$:/tags/KeyboardShortcut",
"key": "((change-sidebar-layout))",
"text": "<$list filter=\"[{$:/themes/tiddlywiki/vanilla/options/sidebarlayout}match[fixed-fluid]]\" \nemptyMessage=\"\"\"<$action-setfield $tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" text=\"fixed-fluid\"/>\"\"\">\n<$action-setfield $tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" text=\"fluid-fixed\"/>\n</$list>\n"
},
"$:/core/ui/KeyboardShortcuts/new-image": {
"title": "$:/core/ui/KeyboardShortcuts/new-image",
"tags": "$:/tags/KeyboardShortcut",
"key": "((new-image))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-image}}\n</$navigator>\n"
},
"$:/core/ui/KeyboardShortcuts/new-journal": {
"title": "$:/core/ui/KeyboardShortcuts/new-journal",
"tags": "$:/tags/KeyboardShortcut",
"key": "((new-journal))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-journal}}\n</$navigator>\n"
},
"$:/core/ui/KeyboardShortcuts/new-tiddler": {
"title": "$:/core/ui/KeyboardShortcuts/new-tiddler",
"tags": "$:/tags/KeyboardShortcut",
"key": "((new-tiddler))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-tiddler}}\n</$navigator>\n"
},
"$:/core/ui/KeyboardShortcuts/save-wiki": {
"title": "$:/core/ui/KeyboardShortcuts/save-wiki",
"tags": "$:/tags/KeyboardShortcut",
"key": "((save-wiki))",
"text": "<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-save-wiki\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n"
},
"$:/core/ui/KeyboardShortcuts/sidebar-search": {
"title": "$:/core/ui/KeyboardShortcuts/sidebar-search",
"tags": "$:/tags/KeyboardShortcut",
"key": "((sidebar-search))",
"text": "<$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-search input\"/>\n"
},
"$:/core/ui/KeyboardShortcuts/switcher": {
"title": "$:/core/ui/KeyboardShortcuts/switcher",
"tags": "$:/tags/KeyboardShortcut",
"key": "((layout-switcher))",
"text": "<$action-sendmessage $message=\"tm-show-switcher\" switch=\"layout\"/>"
},
"$:/core/ui/KeyboardShortcuts/toggle-sidebar": {
"title": "$:/core/ui/KeyboardShortcuts/toggle-sidebar",
"tags": "$:/tags/KeyboardShortcut",
"key": "((toggle-sidebar))",
"text": "<$list filter=\"[[$:/state/sidebar]is[missing]] [{$:/state/sidebar}removeprefix[yes]]\" emptyMessage=\"\"\"\n<$action-setfield $tiddler=\"$:/state/sidebar\" text=\"yes\"/>\n\"\"\">\n<$action-setfield $tiddler=\"$:/state/sidebar\" text=\"no\"/>\n</$list>\n"
},
"$:/snippets/LayoutSwitcher": {
"title": "$:/snippets/LayoutSwitcher",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/LayoutSwitcher/Caption}}",
"text": "<$linkcatcher to=\"$:/layout\">\n<div class=\"tc-chooser\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/Layout]] [[$:/core/ui/PageTemplate]] +[!is[draft]sort[name]]\">\n<$list filter=\"[{$:/layout}!has[text]]\" variable=\"ignore\" emptyMessage=\"\"\"\n<$set name=\"cls\" filter=\"[all[current]field:title{$:/layout}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$transclude field=\"name\"/>'' - <$transclude field=\"description\"/></$link></div>\n</$set>\n\"\"\">\n<$set name=\"cls\" filter=\"[all[current]field:title[$:/core/ui/PageTemplate]]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$transclude field=\"name\"/>'' - <$transclude field=\"description\"/></$link></div>\n</$set>\n</$list>\n</$list>\n</div>\n</$linkcatcher>\n"
},
"$:/core/ui/ListItemTemplate": {
"title": "$:/core/ui/ListItemTemplate",
"text": "<div class=\"tc-menu-list-item\">\n<$link />\n</div>"
},
"$:/Manager/ItemMain/Fields": {
"title": "$:/Manager/ItemMain/Fields",
"tags": "$:/tags/Manager/ItemMain",
"caption": "{{$:/language/Manager/Item/Fields}}",
"text": "<table>\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"
},
"$:/Manager/ItemMain/RawText": {
"title": "$:/Manager/ItemMain/RawText",
"tags": "$:/tags/Manager/ItemMain",
"caption": "{{$:/language/Manager/Item/RawText}}",
"text": "<pre><code><$view/></code></pre>\n"
},
"$:/Manager/ItemMain/WikifiedText": {
"title": "$:/Manager/ItemMain/WikifiedText",
"tags": "$:/tags/Manager/ItemMain",
"caption": "{{$:/language/Manager/Item/WikifiedText}}",
"text": "<$transclude mode=\"block\"/>\n"
},
"$:/Manager/ItemSidebar/Colour": {
"title": "$:/Manager/ItemSidebar/Colour",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Colour}}",
"text": "\\define swatch-styles()\nheight: 1em;\nbackground-color: $(colour)$\n\\end\n\n<$vars colour={{!!color}}>\n<p style=<<swatch-styles>>/>\n</$vars>\n<p>\n<$edit-text field=\"color\" tag=\"input\" type=\"color\"/> / <$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/>\n</p>\n"
},
"$:/Manager/ItemSidebar/Icon": {
"title": "$:/Manager/ItemSidebar/Icon",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Icon}}",
"text": "<p>\n<div class=\"tc-manager-icon-editor\">\n<$button popup=<<qualify \"$:/state/popup/image-picker\">> class=\"tc-btn-invisible\">\n<$transclude tiddler={{!!icon}}>\n{{$:/language/Manager/Item/Icon/None}}\n</$transclude>\n</$button>\n<div class=\"tc-block-dropdown-wrapper\" style=\"position: static;\">\n<$reveal state=<<qualify \"$:/state/popup/image-picker\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-popup\">\n<div class=\"tc-block-dropdown tc-popup-keep\" style=\"width: 80%; left: 10%; right: 10%; padding: 0.5em;\">\n<$macrocall $name=\"image-picker-include-tagged-images\" actions=\"\"\"\n<$action-setfield $field=\"icon\" $value=<<imageTitle>>/>\n<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/image-picker\">>/>\n\"\"\"/>\n</div>\n</$reveal>\n</div>\n</div>\n</p>\n"
},
"$:/Manager/ItemSidebar/Tags": {
"title": "$:/Manager/ItemSidebar/Tags",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Tags}}",
"text": "\\whitespace trim\n\\define tag-checkbox-actions()\n<$action-listops\n\t$tiddler=\"$:/config/Manager/RecentTags\"\n\t$subfilter=\"[<tag>] [list[$:/config/Manager/RecentTags]] +[limit[12]]\"\n/>\n\\end\n\n\\define tag-picker-actions()\n<<tag-checkbox-actions>>\n\\end\n\n<p>\n<$list filter=\"[all[current]tags[]] [list[$:/config/Manager/RecentTags]] +[sort[title]] \" variable=\"tag\" storyview=\"pop\">\n<div>\n<$checkbox tiddler=<<currentTiddler>> tag=<<tag>> actions=<<tag-checkbox-actions>>>\n<$macrocall $name=\"tag-pill\" tag=<<tag>>/>\n</$checkbox>\n</div>\n</$list>\n</p>\n<p>\n<$fieldmangler>\n<$macrocall $name=\"tag-picker\" actions=<<tag-picker-actions>>/>\n</$fieldmangler>\n</p>\n"
},
"$:/Manager/ItemSidebar/Tools": {
"title": "$:/Manager/ItemSidebar/Tools",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Tools}}",
"text": "<p>\n<$button to=<<currentTiddler>>>{{$:/core/images/link}} open</$button>\n</p>\n<p>\n<$button message=\"tm-edit-tiddler\" param=<<currentTiddler>>>{{$:/core/images/edit-button}} edit</$button>\n</p>\n"
},
"$:/Manager": {
"title": "$:/Manager",
"icon": "$:/core/images/list",
"color": "#bbb",
"text": "\\define lingo-base() $:/language/Manager/\n\n\\define list-item-content-item()\n<div class=\"tc-manager-list-item-content-item\">\n\t<$vars state-title=\"\"\"$:/state/popup/manager/item/$(listItem)$\"\"\">\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"hide\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/down-arrow}} <$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"nomatch\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"show\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/right-arrow}} <$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\" class=\"tc-manager-list-item-content-item-body\">\n\t\t\t<$transclude tiddler=<<listItem>>/>\n\t\t</$reveal>\n\t</$vars>\n</div>\n\\end\n\n<div class=\"tc-manager-wrapper\">\n\t<div class=\"tc-manager-controls\">\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Show/Prompt>> <$select tiddler=\"$:/config/Manager/Show\" default=\"tiddlers\">\n\t\t\t\t<option value=\"tiddlers\"><<lingo Controls/Show/Option/Tiddlers>></option>\n\t\t\t\t<option value=\"tags\"><<lingo Controls/Show/Option/Tags>></option>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Search/Prompt>> <$edit-text tiddler=\"$:/config/Manager/Filter\" tag=\"input\" default=\"\" placeholder={{$:/language/Manager/Controls/Search/Placeholder}}/>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/FilterByTag/Prompt>> <$select tiddler=\"$:/config/Manager/Tag\" default=\"\">\n\t\t\t\t<option value=\"\"><<lingo Controls/FilterByTag/None>></option>\n\t\t\t\t<$list filter=\"[!is{$:/config/Manager/System}tags[]!is[system]sort[title]]\" variable=\"tag\">\n\t\t\t\t\t<option value=<<tag>>><$text text=<<tag>>/></option>\n\t\t\t\t</$list>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Sort/Prompt>> <$select tiddler=\"$:/config/Manager/Sort\" default=\"title\">\n\t\t\t\t<optgroup label=\"Common\">\n\t\t\t\t\t<$list filter=\"title modified modifier created creator created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t\t<optgroup label=\"All\">\n\t\t\t\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}fields[]sort[title]] -title -modified -modifier -created -creator -created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t</$select>\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/Order\" field=\"text\" checked=\"reverse\" unchecked=\"forward\" default=\"forward\">\n\t\t\t\t<<lingo Controls/Order/Prompt>>\n\t\t\t</$checkbox>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/System\" field=\"text\" checked=\"\" unchecked=\"system\" default=\"system\">\n\t\t\t\t{{$:/language/SystemTiddlers/Include/Prompt}}\n\t\t\t</$checkbox>\n\t\t</div>\n\t</div>\n\t<div class=\"tc-manager-list\">\n\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}search{$:/config/Manager/Filter}tag:strict{$:/config/Manager/Tag}sort{$:/config/Manager/Sort}order{$:/config/Manager/Order}]\">\n\t\t\t<$vars transclusion=<<currentTiddler>>>\n\t\t\t\t<div style=\"tc-manager-list-item\">\n\t\t\t\t\t<$button popup=<<qualify \"$:/state/manager/popup\">> class=\"tc-btn-invisible tc-manager-list-item-heading\" selectedClass=\"tc-manager-list-item-heading-selected\">\n\t\t\t\t\t\t<$text text=<<currentTiddler>>/>\n\t\t\t\t\t</$button>\n\t\t\t\t\t<$reveal state=<<qualify \"$:/state/manager/popup\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-manager-list-item-content tc-popup-handle\">\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-tiddler\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemMain]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-sidebar\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemSidebar]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</$reveal>\n\t\t\t\t</div>\n\t\t\t</$vars>\n\t\t</$list>\n\t</div>\n</div>\n"
},
"$:/core/ui/MissingTemplate": {
"title": "$:/core/ui/MissingTemplate",
"text": "<div class=\"tc-tiddler-missing\">\n<$button popup=<<qualify \"$:/state/popup/missing\">> class=\"tc-btn-invisible tc-missing-tiddler-label\">\n<$view field=\"title\" format=\"text\" />\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/missing\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n<hr>\n<$list filter=\"[all[current]backlinks[]sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n</div>\n"
},
"$:/core/ui/MoreSideBar/All": {
"title": "$:/core/ui/MoreSideBar/All",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/All/Caption}}",
"text": "<$list filter={{$:/core/Filters/AllTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Drafts": {
"title": "$:/core/ui/MoreSideBar/Drafts",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Drafts/Caption}}",
"text": "<$list filter={{$:/core/Filters/Drafts!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Explorer": {
"title": "$:/core/ui/MoreSideBar/Explorer",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Explorer/Caption}}",
"text": "<<tree \"$:/\">>\n"
},
"$:/core/ui/MoreSideBar/Missing": {
"title": "$:/core/ui/MoreSideBar/Missing",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Missing/Caption}}",
"text": "<$list filter={{$:/core/Filters/Missing!!filter}} template=\"$:/core/ui/MissingTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Orphans": {
"title": "$:/core/ui/MoreSideBar/Orphans",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Orphans/Caption}}",
"text": "<$list filter={{$:/core/Filters/Orphans!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Plugins": {
"title": "$:/core/ui/MoreSideBar/Plugins",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/ControlPanel/Plugins/Caption}}",
"text": "\n{{$:/language/ControlPanel/Plugins/Installed/Hint}}\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar/Plugins]!has[draft.of]]\" default=\"$:/core/ui/MoreSideBar/Plugins/Plugins\" explicitState=\"$:/state/tab-1163638994\"/>\n"
},
"$:/core/ui/MoreSideBar/Recent": {
"title": "$:/core/ui/MoreSideBar/Recent",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Recent/Caption}}",
"text": "<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"
},
"$:/core/ui/MoreSideBar/Shadows": {
"title": "$:/core/ui/MoreSideBar/Shadows",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Shadows/Caption}}",
"text": "<$list filter={{$:/core/Filters/ShadowTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/System": {
"title": "$:/core/ui/MoreSideBar/System",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/System/Caption}}",
"text": "<$list filter={{$:/core/Filters/SystemTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Tags": {
"title": "$:/core/ui/MoreSideBar/Tags",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Tags/Caption}}",
"text": "<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n{{$:/core/ui/Buttons/tag-manager}}\n\n</$set>\n\n</$set>\n\n</$set>\n\n<$list filter={{$:/core/Filters/AllTags!!filter}}>\n\n<$transclude tiddler=\"$:/core/ui/TagTemplate\"/>\n\n</$list>\n\n<hr class=\"tc-untagged-separator\">\n\n{{$:/core/ui/UntaggedTemplate}}\n"
},
"$:/core/ui/MoreSideBar/Types": {
"title": "$:/core/ui/MoreSideBar/Types",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Types/Caption}}",
"text": "<$list filter={{$:/core/Filters/TypedTiddlers!!filter}}>\n<div class=\"tc-menu-list-item\">\n<$view field=\"type\"/>\n<$list filter=\"[type{!!type}!is[system]sort[title]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}><$view field=\"title\"/></$link>\n</div>\n</$list>\n</div>\n</$list>\n"
},
"$:/core/ui/MoreSideBar/Plugins/Languages": {
"title": "$:/core/ui/MoreSideBar/Plugins/Languages",
"tags": "$:/tags/MoreSideBar/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}}",
"text": "<$list filter=\"[!has[draft.of]plugin-type[language]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"
},
"$:/core/ui/MoreSideBar/Plugins/Plugins": {
"title": "$:/core/ui/MoreSideBar/Plugins/Plugins",
"tags": "$:/tags/MoreSideBar/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}}",
"text": "<$list filter=\"[!has[draft.of]plugin-type[plugin]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>\n"
},
"$:/core/ui/MoreSideBar/Plugins/Theme": {
"title": "$:/core/ui/MoreSideBar/Plugins/Theme",
"tags": "$:/tags/MoreSideBar/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}}",
"text": "<$list filter=\"[!has[draft.of]plugin-type[theme]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"
},
"$:/core/ui/Buttons/advanced-search": {
"title": "$:/core/ui/Buttons/advanced-search",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/advanced-search-button}} {{$:/language/Buttons/AdvancedSearch/Caption}}",
"description": "{{$:/language/Buttons/AdvancedSearch/Hint}}",
"text": "\\whitespace trim\n\\define advanced-search-button(class)\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/advanced-search-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/AdvancedSearch/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/AdvancedSearch]]\" emptyMessage=<<advanced-search-button>>>\n<<advanced-search-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/close-all": {
"title": "$:/core/ui/Buttons/close-all",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/close-all-button}} {{$:/language/Buttons/CloseAll/Caption}}",
"description": "{{$:/language/Buttons/CloseAll/Hint}}",
"text": "<$button message=\"tm-close-all-tiddlers\" tooltip={{$:/language/Buttons/CloseAll/Hint}} aria-label={{$:/language/Buttons/CloseAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/close-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/CloseAll/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/control-panel": {
"title": "$:/core/ui/Buttons/control-panel",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/options-button}} {{$:/language/Buttons/ControlPanel/Caption}}",
"description": "{{$:/language/Buttons/ControlPanel/Hint}}",
"text": "\\whitespace trim\n\\define control-panel-button(class)\n<$button to=\"$:/ControlPanel\" tooltip={{$:/language/Buttons/ControlPanel/Hint}} aria-label={{$:/language/Buttons/ControlPanel/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/options-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/ControlPanel/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/ControlPanel]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/encryption": {
"title": "$:/core/ui/Buttons/encryption",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/locked-padlock}} {{$:/language/Buttons/Encryption/Caption}}",
"description": "{{$:/language/Buttons/Encryption/Hint}}",
"text": "\\whitespace trim\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-clear-password\" tooltip={{$:/language/Buttons/Encryption/ClearPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/ClearPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/locked-padlock}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Encryption/ClearPassword/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-set-password\" tooltip={{$:/language/Buttons/Encryption/SetPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/SetPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/unlocked-padlock}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Encryption/SetPassword/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n"
},
"$:/core/ui/Buttons/export-page": {
"title": "$:/core/ui/Buttons/export-page",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/export-button}} {{$:/language/Buttons/ExportPage/Caption}}",
"description": "{{$:/language/Buttons/ExportPage/Hint}}",
"text": "<$macrocall $name=\"exportButton\" exportFilter=\"[!is[system]sort[title]]\" lingoBase=\"$:/language/Buttons/ExportPage/\"/>"
},
"$:/core/ui/Buttons/fold-all": {
"title": "$:/core/ui/Buttons/fold-all",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/fold-all-button}} {{$:/language/Buttons/FoldAll/Caption}}",
"description": "{{$:/language/Buttons/FoldAll/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/FoldAll/Hint}} aria-label={{$:/language/Buttons/FoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/FoldAll/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/full-screen": {
"title": "$:/core/ui/Buttons/full-screen",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/full-screen-button}} {{$:/language/Buttons/FullScreen/Caption}}",
"description": "{{$:/language/Buttons/FullScreen/Hint}}",
"text": "<$button message=\"tm-full-screen\" tooltip={{$:/language/Buttons/FullScreen/Hint}} aria-label={{$:/language/Buttons/FullScreen/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/full-screen-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/FullScreen/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/home": {
"title": "$:/core/ui/Buttons/home",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/home-button}} {{$:/language/Buttons/Home/Caption}}",
"description": "{{$:/language/Buttons/Home/Hint}}",
"text": "<$button message=\"tm-home\" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/home-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Home/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/import": {
"title": "$:/core/ui/Buttons/import",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/import-button}} {{$:/language/Buttons/Import/Caption}}",
"description": "{{$:/language/Buttons/Import/Hint}}",
"text": "<div class=\"tc-file-input-wrapper\">\n<$button tooltip={{$:/language/Buttons/Import/Hint}} aria-label={{$:/language/Buttons/Import/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/import-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Import/Caption}}/></span>\n</$list>\n</$button>\n<$browse tooltip={{$:/language/Buttons/Import/Hint}}/>\n</div>"
},
"$:/core/ui/Buttons/language": {
"title": "$:/core/ui/Buttons/language",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/globe}} {{$:/language/Buttons/Language/Caption}}",
"description": "{{$:/language/Buttons/Language/Hint}}",
"text": "\\whitespace trim\n\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/language\">> tooltip={{$:/language/Buttons/Language/Hint}} aria-label={{$:/language/Buttons/Language/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value={{$:/language}}>\n<$image source=<<flag-title>>/>\n</$set>\n</span>\n</$list>\n<$text text=\" \"/>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Language/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/language\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/languageswitcher}}\n</div>\n</$reveal>\n"
},
"$:/core/ui/Buttons/manager": {
"title": "$:/core/ui/Buttons/manager",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/list}} {{$:/language/Buttons/Manager/Caption}}",
"description": "{{$:/language/Buttons/Manager/Hint}}",
"text": "\\whitespace trim\n\\define manager-button(class)\n<$button to=\"$:/Manager\" tooltip={{$:/language/Buttons/Manager/Hint}} aria-label={{$:/language/Buttons/Manager/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/list}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Manager/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/Manager]]\" emptyMessage=<<manager-button>>>\n<<manager-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/more-page-actions": {
"title": "$:/core/ui/Buttons/more-page-actions",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}",
"description": "{{$:/language/Buttons/More/Hint}}",
"text": "\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/more\">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/down-arrow}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/More/Caption}}/></span>\n</$list>\n</$button><$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"below\" animate=\"yes\">\n\n<div class=\"tc-drop-down\">\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"tc-btn-invisible\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]] -[[$:/core/ui/Buttons/more-page-actions]]\" variable=\"listItem\">\n\n<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$set>\n\n</$reveal>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</div>\n\n</$reveal>"
},
"$:/core/ui/Buttons/new-image": {
"title": "$:/core/ui/Buttons/new-image",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/new-image-button}} {{$:/language/Buttons/NewImage/Caption}}",
"description": "{{$:/language/Buttons/NewImage/Hint}}",
"text": "\\whitespace trim\n<$button tooltip={{$:/language/Buttons/NewImage/Hint}} aria-label={{$:/language/Buttons/NewImage/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-image}}>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/new-image-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewImage/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/core/ui/Buttons/new-journal": {
"title": "$:/core/ui/Buttons/new-journal",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournal/Caption}}",
"description": "{{$:/language/Buttons/NewJournal/Hint}}",
"text": "\\whitespace trim\n\\define journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournal/Hint}} aria-label={{$:/language/Buttons/NewJournal/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-journal}}>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/new-journal-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewJournal/Caption}}/></span>\n</$list>\n</$button>\n\\end\n<<journalButton>>\n"
},
"$:/core/ui/Buttons/new-tiddler": {
"title": "$:/core/ui/Buttons/new-tiddler",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/new-button}} {{$:/language/Buttons/NewTiddler/Caption}}",
"description": "{{$:/language/Buttons/NewTiddler/Hint}}",
"text": "\\whitespace trim\n<$button actions={{$:/core/ui/Actions/new-tiddler}} tooltip={{$:/language/Buttons/NewTiddler/Hint}} aria-label={{$:/language/Buttons/NewTiddler/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/new-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewTiddler/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/core/ui/Buttons/palette": {
"title": "$:/core/ui/Buttons/palette",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/palette}} {{$:/language/Buttons/Palette/Caption}}",
"description": "{{$:/language/Buttons/Palette/Hint}}",
"text": "\\whitespace trim\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/palette\">> tooltip={{$:/language/Buttons/Palette/Hint}} aria-label={{$:/language/Buttons/Palette/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/palette}}\n</$list>\n<$text text=\" \"/>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Palette/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/palette\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\" style=\"font-size:0.7em;\">\n{{$:/snippets/paletteswitcher}}\n</div>\n</$reveal>\n"
},
"$:/core/ui/Buttons/print": {
"title": "$:/core/ui/Buttons/print",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/print-button}} {{$:/language/Buttons/Print/Caption}}",
"description": "{{$:/language/Buttons/Print/Hint}}",
"text": "<$button message=\"tm-print\" tooltip={{$:/language/Buttons/Print/Hint}} aria-label={{$:/language/Buttons/Print/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/print-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Print/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/refresh": {
"title": "$:/core/ui/Buttons/refresh",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/refresh-button}} {{$:/language/Buttons/Refresh/Caption}}",
"description": "{{$:/language/Buttons/Refresh/Hint}}",
"text": "<$button message=\"tm-browser-refresh\" tooltip={{$:/language/Buttons/Refresh/Hint}} aria-label={{$:/language/Buttons/Refresh/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/refresh-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Refresh/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/save-wiki": {
"title": "$:/core/ui/Buttons/save-wiki",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/save-button}} {{$:/language/Buttons/SaveWiki/Caption}}",
"description": "{{$:/language/Buttons/SaveWiki/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/SaveWiki/Hint}} aria-label={{$:/language/Buttons/SaveWiki/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-save-wiki\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n<span class=\"tc-dirty-indicator\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/save-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/SaveWiki/Caption}}/></span>\n</$list>\n</span>\n</$button>"
},
"$:/core/ui/Buttons/storyview": {
"title": "$:/core/ui/Buttons/storyview",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/storyview-classic}} {{$:/language/Buttons/StoryView/Caption}}",
"description": "{{$:/language/Buttons/StoryView/Hint}}",
"text": "\\whitespace trim\n\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/storyview\">> tooltip={{$:/language/Buttons/StoryView/Hint}} aria-label={{$:/language/Buttons/StoryView/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n<$set name=\"storyview\" value={{$:/view}}>\n<$transclude tiddler=<<icon>>/>\n</$set>\n</$list>\n<$text text=\" \"/>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/StoryView/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/storyview\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/viewswitcher}}\n</div>\n</$reveal>\n"
},
"$:/core/ui/Buttons/tag-manager": {
"title": "$:/core/ui/Buttons/tag-manager",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/tag-button}} {{$:/language/Buttons/TagManager/Caption}}",
"description": "{{$:/language/Buttons/TagManager/Hint}}",
"text": "\\whitespace trim\n\\define control-panel-button(class)\n<$button to=\"$:/TagManager\" tooltip={{$:/language/Buttons/TagManager/Hint}} aria-label={{$:/language/Buttons/TagManager/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/tag-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/TagManager/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/TagManager]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/theme": {
"title": "$:/core/ui/Buttons/theme",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/theme-button}} {{$:/language/Buttons/Theme/Caption}}",
"description": "{{$:/language/Buttons/Theme/Hint}}",
"text": "\\whitespace trim\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/theme\">> tooltip={{$:/language/Buttons/Theme/Hint}} aria-label={{$:/language/Buttons/Theme/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/theme-button}}\n</$list>\n<$text text=\" \"/>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Theme/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/theme\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$linkcatcher to=\"$:/theme\">\n{{$:/snippets/themeswitcher}}\n</$linkcatcher>\n</div>\n</$reveal>\n"
},
"$:/core/ui/Buttons/timestamp": {
"title": "$:/core/ui/Buttons/timestamp",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/timestamp-on}} {{$:/language/Buttons/Timestamp/Caption}}",
"description": "{{$:/language/Buttons/Timestamp/Hint}}",
"text": "\\whitespace trim\n<$reveal type=\"nomatch\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/On/Hint}} aria-label={{$:/language/Buttons/Timestamp/On/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"yes\"/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/timestamp-on}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Timestamp/On/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/Off/Hint}} aria-label={{$:/language/Buttons/Timestamp/Off/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"no\"/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/timestamp-off}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Timestamp/Off/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n"
},
"$:/core/ui/Buttons/unfold-all": {
"title": "$:/core/ui/Buttons/unfold-all",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/unfold-all-button}} {{$:/language/Buttons/UnfoldAll/Caption}}",
"description": "{{$:/language/Buttons/UnfoldAll/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/UnfoldAll/Hint}} aria-label={{$:/language/Buttons/UnfoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-unfold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\" variable=\"listItem\">\n{{$:/core/images/unfold-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/UnfoldAll/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/PageTemplate/pagecontrols": {
"title": "$:/core/ui/PageTemplate/pagecontrols",
"text": "\\whitespace trim\n\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-page-controls\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n<$set name=\"hidden\" value=<<config-title>>>\n<$list filter=\"[<hidden>!text[hide]]\" storyview=\"pop\" variable=\"ignore\">\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n</$set>\n</$list>\n</$set>\n</$list>\n</div>\n"
},
"$:/core/ui/PageStylesheet": {
"title": "$:/core/ui/PageStylesheet",
"text": "\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/PageTemplate/alerts": {
"title": "$:/core/ui/PageTemplate/alerts",
"tags": "$:/tags/PageTemplate",
"text": "<div class=\"tc-alerts\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Alert]!has[draft.of]]\" template=\"$:/core/ui/AlertTemplate\" storyview=\"pop\"/>\n\n</div>\n"
},
"$:/core/ui/PageTemplate/drafts": {
"title": "$:/core/ui/PageTemplate/drafts",
"tags": "$:/tags/PageTemplate",
"text": "\\whitespace trim\n<$reveal state=\"$:/status/IsReadOnly\" type=\"nomatch\" text=\"yes\" tag=\"div\" class=\"tc-drafts-list\">\n<$list filter=\"[has[draft.of]!sort[modified]] -[list[$:/StoryList]]\">\n<$link>\n{{$:/core/images/edit-button}} <$text text=<<currentTiddler>>/>\n</$link>\n</$list>\n</$reveal>\n"
},
"$:/core/ui/PageTemplate/pluginreloadwarning": {
"title": "$:/core/ui/PageTemplate/pluginreloadwarning",
"tags": "$:/tags/PageTemplate",
"text": "\\define lingo-base() $:/language/\n\n<$list filter=\"[{$:/status/RequireReloadDueToPluginChange}match[yes]]\">\n\n<$reveal type=\"nomatch\" state=\"$:/temp/HidePluginWarning\" text=\"yes\">\n\n<div class=\"tc-plugin-reload-warning\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<<lingo PluginReloadWarning>> <$button set=\"$:/temp/HidePluginWarning\" setTo=\"yes\" class=\"tc-btn-invisible\">{{$:/core/images/close-button}}</$button>\n\n</$set>\n\n</div>\n\n</$reveal>\n\n</$list>\n"
},
"$:/core/ui/PageTemplate/sidebar": {
"title": "$:/core/ui/PageTemplate/sidebar",
"tags": "$:/tags/PageTemplate",
"text": "\\whitespace trim\n\\define config-title()\n$:/config/SideBarSegments/Visibility/$(listItem)$\n\\end\n\n<$scrollable fallthrough=\"no\" class=\"tc-sidebar-scrollable\">\n\n<div class=\"tc-sidebar-header\">\n\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBarSegment]!has[draft.of]]\" variable=\"listItem\">\n\n<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\" tag=\"div\">\n\n<$transclude tiddler=<<listItem>> mode=\"block\"/>\n\n</$reveal>\n\n</$list>\n\n</$reveal>\n\n</div>\n\n</$scrollable>\n"
},
"$:/core/ui/PageTemplate/story": {
"title": "$:/core/ui/PageTemplate/story",
"tags": "$:/tags/PageTemplate",
"text": "\\whitespace trim\n<section class=\"tc-story-river\">\n\n<section class=\"story-backdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AboveStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n<$list filter=\"[list[$:/StoryList]]\" history=\"$:/HistoryList\" template={{$:/config/ui/ViewTemplate}} editTemplate={{$:/config/ui/EditTemplate}} storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>\n\n<section class=\"story-frontdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/BelowStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n</section>\n"
},
"$:/core/ui/PageTemplate/topleftbar": {
"title": "$:/core/ui/PageTemplate/topleftbar",
"tags": "$:/tags/PageTemplate",
"text": "<span class=\"tc-topbar tc-topbar-left\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopLeftBar]!has[draft.of]]\" variable=\"listItem\" storyview=\"pop\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"
},
"$:/core/ui/PageTemplate/toprightbar": {
"title": "$:/core/ui/PageTemplate/toprightbar",
"tags": "$:/tags/PageTemplate",
"text": "<span class=\"tc-topbar tc-topbar-right\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopRightBar]!has[draft.of]]\" variable=\"listItem\" storyview=\"pop\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"
},
"$:/core/ui/PageTemplate": {
"title": "$:/core/ui/PageTemplate",
"name": "{{$:/language/PageTemplate/Name}}",
"description": "{{$:/language/PageTemplate/Description}}",
"text": "\\whitespace trim\n\\define containerClasses()\ntc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$vars\n\ttv-config-toolbar-icons={{$:/config/Toolbar/Icons}}\n\ttv-config-toolbar-text={{$:/config/Toolbar/Text}}\n\ttv-config-toolbar-class={{$:/config/Toolbar/ButtonClass}}\n\ttv-enable-drag-and-drop={{$:/config/DragAndDrop/Enable}}\n\ttv-show-missing-links={{$:/config/MissingLinks}}\n\tstoryviewTitle={{$:/view}}\n\tlanguageTitle={{{ [{$:/language}get[name]] }}}>\n\n<div class=<<containerClasses>>>\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n\n<$dropzone enable=<<tv-enable-drag-and-drop>>>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>>/>\n\n</$list>\n\n</$dropzone>\n\n</$navigator>\n\n</div>\n\n</$vars>\n"
},
"$:/PaletteManager": {
"title": "$:/PaletteManager",
"text": "\\define lingo-base() $:/language/ControlPanel/Palette/Editor/\n\\define describePaletteColour(colour)\n<$transclude tiddler=\"$:/language/Docs/PaletteColours/$colour$\"><$text text=\"$colour$\"/></$transclude>\n\\end\n\\define edit-colour-placeholder()\n edit $(colourName)$\n\\end\n\\define colour-tooltip(showhide) $showhide$ editor for $(newColourName)$ \n\\define resolve-colour(macrocall)\n\\import $:/core/macros/utils\n\\whitespace trim\n<$wikify name=\"name\" text=\"\"\"$macrocall$\"\"\">\n<<name>>\n</$wikify>\n\\end\n\\define delete-colour-index-actions() <$action-setfield $index=<<colourName>>/>\n\\define palette-manager-colour-row-segment()\n\\whitespace trim\n<$edit-text index=<<colourName>> tag=\"input\" placeholder=<<edit-colour-placeholder>> default=\"\"/>\n<br>\n<$edit-text index=<<colourName>> type=\"color\" tag=\"input\" class=\"tc-palette-manager-colour-input\"/>\n<$list filter=\"[<currentTiddler>getindex<colourName>removeprefix[<<]removesuffix[>>]] [<currentTiddler>getindex<colourName>removeprefix[<$]removesuffix[/>]]\" variable=\"ignore\">\n<$set name=\"state\" value={{{ [[$:/state/palettemanager/]addsuffix<currentTiddler>addsuffix[/]addsuffix<colourName>] }}}>\n<$wikify name=\"newColourName\" text=\"\"\"<$macrocall $name=\"resolve-colour\" macrocall={{{ [<currentTiddler>getindex<colourName>] }}}/>\"\"\">\n<$reveal state=<<state>> type=\"nomatch\" text=\"show\">\n<$button tooltip=<<colour-tooltip show>> aria-label=<<colour-tooltip show>> class=\"tc-btn-invisible\" set=<<state>> setTo=\"show\">{{$:/core/images/down-arrow}}<$text text=<<newColourName>> class=\"tc-small-gap-left\"/></$button><br>\n</$reveal>\n<$reveal state=<<state>> type=\"match\" text=\"show\">\n<$button tooltip=<<colour-tooltip hide>> aria-label=<<colour-tooltip show>> class=\"tc-btn-invisible\" actions=\"\"\"<$action-deletetiddler $tiddler=<<state>>/>\"\"\">{{$:/core/images/up-arrow}}<$text text=<<newColourName>> class=\"tc-small-gap-left\"/></$button><br>\n</$reveal>\n<$reveal state=<<state>> type=\"match\" text=\"show\">\n<$set name=\"colourName\" value=<<newColourName>>>\n<br>\n<<palette-manager-colour-row-segment>>\n<br><br>\n</$set>\n</$reveal>\n</$wikify>\n</$set>\n</$list>\n\\end\n\\define palette-manager-colour-row()\n\\whitespace trim\n<tr>\n<td>\n<span style=\"float:right;\">\n<$button tooltip={{$:/language/ControlPanel/Palette/Editor/Delete/Hint}} aria-label=<<lingo Delete/Hint>> class=\"tc-btn-invisible\" actions=<<delete-colour-index-actions>>>\n{{$:/core/images/delete-button}}</$button>\n</span>\n''<$macrocall $name=\"describePaletteColour\" colour=<<colourName>>/>''<br/>\n<$macrocall $name=\"colourName\" $output=\"text/plain\"/>\n</td>\n<td>\n<<palette-manager-colour-row-segment>>\n</td>\n</tr>\n\\end\n\\define palette-manager-table()\n\\whitespace trim\n<table>\n<tbody>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Palette]indexes[]]\" variable=\"colourName\">\n<$list filter=\"[<currentTiddler>indexes[]removeprefix<colourName>suffix[]]\" variable=\"ignore\" emptyMessage=\"\"\"\n<$list filter=\"[{$:/state/palettemanager/showexternal}removeprefix[yes]suffix[]]\" variable=\"ignore\">\n<<palette-manager-colour-row>>\n</$list>\n\"\"\">\n<<palette-manager-colour-row>>\n</$list>\n</$list>\n</tbody>\n</table>\n\\end\n<$set name=\"currentTiddler\" value={{$:/palette}}>\n\n<<lingo Prompt>> <$link to={{$:/palette}}><$macrocall $name=\"currentTiddler\" $output=\"text/plain\"/></$link>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\" variable=\"listItem\">\n<<lingo Prompt/Modified>>\n<$button message=\"tm-delete-tiddler\" param={{$:/palette}}><<lingo Reset/Caption>></$button>\n</$list>\n\n<$list filter=\"[all[current]is[shadow]!is[tiddler]]\" variable=\"listItem\">\n<<lingo Clone/Prompt>>\n</$list>\n\n<$button message=\"tm-new-tiddler\" param={{$:/palette}}><<lingo Clone/Caption>></$button>\n\n<$checkbox tiddler=\"$:/state/palettemanager/showexternal\" field=\"text\" checked=\"yes\" unchecked=\"no\"><span class=\"tc-small-gap-left\"><<lingo Names/External/Show>></span></$checkbox>\n\n<<palette-manager-table>>\n"
},
"$:/core/ui/PluginInfo": {
"title": "$:/core/ui/PluginInfo",
"text": "\\define localised-info-tiddler-title()\n$(currentTiddler)$/$(languageTitle)$/$(currentTab)$\n\\end\n\\define info-tiddler-title()\n$(currentTiddler)$/$(currentTab)$\n\\end\n\\define default-tiddler-title()\n$:/core/ui/PluginInfo/Default/$(currentTab)$\n\\end\n<$transclude tiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<default-tiddler-title>> mode=\"block\">\n{{$:/language/ControlPanel/Plugin/NoInfoFound/Hint}}\n</$transclude>\n</$transclude>\n</$transclude>\n</$transclude>\n"
},
"$:/core/ui/PluginInfo/Default/contents": {
"title": "$:/core/ui/PluginInfo/Default/contents",
"text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link />\n</li>\n</$list>\n</ul>\n"
},
"$:/core/ui/PluginListItemTemplate": {
"title": "$:/core/ui/PluginListItemTemplate",
"text": "<div class=\"tc-menu-list-item\">\n<$link to={{!!title}}><$view field=\"description\"><$view field=\"title\"/></$view></$link>\n</div>"
},
"$:/core/ui/RootTemplate": {
"title": "$:/core/ui/RootTemplate",
"text": "<$transclude tiddler={{{ [{$:/layout}has[text]] ~[[$:/core/ui/PageTemplate]] }}} mode=\"inline\"/>\n\n"
},
"$:/core/ui/SearchResults": {
"title": "$:/core/ui/SearchResults",
"text": "<div class=\"tc-search-results\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\" emptyMessage=\"\"\"\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\"\"\">\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\" default={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/search/currentTab\" text=<<currentTab>>/>\"\"\" explicitState=\"$:/state/tab/search-results/sidebar\"/>\n\n</$list>\n\n</div>\n"
},
"$:/core/ui/SideBar/More": {
"title": "$:/core/ui/SideBar/More",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/More/Caption}}",
"text": "<div class=\"tc-more-sidebar\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\" default={{$:/config/DefaultMoreSidebarTab}} state=\"$:/state/tab/moresidebar\" class=\"tc-vertical tc-sidebar-tabs-more\" explicitState=\"$:/state/tab/moresidebar-1850697562\"/>\n</div>\n"
},
"$:/core/ui/SideBar/Open": {
"title": "$:/core/ui/SideBar/Open",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/Open/Caption}}",
"text": "\\whitespace trim\n\\define lingo-base() $:/language/CloseAll/\n\n\\define drop-actions()\n<$action-listops $tiddler=<<tv-story-list>> $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n\\end\n\n\\define placeholder()\n<div class=\"tc-droppable-placeholder\"/>\n\\end\n\n\\define droppable-item(button)\n\\whitespace trim\n<$droppable actions=<<drop-actions>> enable=<<tv-allow-drag-and-drop>>>\n<<placeholder>>\n<div>\n$button$\n</div>\n</$droppable>\n\\end\n\n<div class=\"tc-sidebar-tab-open\">\n<$list filter=\"[list<tv-story-list>]\" history=<<tv-history-list>> storyview=\"pop\">\n<div class=\"tc-sidebar-tab-open-item\">\n<$macrocall $name=\"droppable-item\" button=\"\"\"<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=\"tc-btn-invisible tc-btn-mini tc-small-gap-right\">{{$:/core/images/close-button}}</$button><$link to={{!!title}}><$view field=\"title\"/></$link>\"\"\"/>\n</div>\n</$list>\n<$tiddler tiddler=\"\">\n<div>\n<$macrocall $name=\"droppable-item\" button=\"\"\"<$button message=\"tm-close-all-tiddlers\" class=\"tc-btn-invisible tc-btn-mini\"><<lingo Button>></$button>\"\"\"/>\n</div>\n</$tiddler>\n</div>\n"
},
"$:/core/ui/SideBar/Recent": {
"title": "$:/core/ui/SideBar/Recent",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/Recent/Caption}}",
"text": "<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"
},
"$:/core/ui/SideBar/Tools": {
"title": "$:/core/ui/SideBar/Tools",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/Tools/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n\n<<lingo Basics/Version/Prompt>> <<version>>\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n\n<div style=\"position:relative;\" class={{{ [<listItem>encodeuricomponent[]addprefix[tc-btn-]] }}}>\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</div>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/SideBarLists": {
"title": "$:/core/ui/SideBarLists",
"text": "<$transclude tiddler=\"$:/core/ui/SideBarSegments/search\"/>\n\n<$transclude tiddler=\"$:/core/ui/SideBarSegments/tabs\"/>\n\n"
},
"$:/core/ui/SideBarSegments/page-controls": {
"title": "$:/core/ui/SideBarSegments/page-controls",
"tags": "$:/tags/SideBarSegment",
"text": "{{||$:/core/ui/PageTemplate/pagecontrols}}\n"
},
"$:/core/ui/SideBarSegments/search": {
"title": "$:/core/ui/SideBarSegments/search",
"tags": "$:/tags/SideBarSegment",
"text": "\\whitespace trim\n\n\\define count-popup-button()\n\\whitespace trim\n<$button popup=<<qualify \"$:/state/popup/search-dropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n<$list filter=\"[{$(searchTiddler)$}minlength{$:/config/Search/MinLength}limit[1]]\" variable=\"listItem\">\n<$vars userInput={{{ [<searchTiddler>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}} replaceRegexp=\"limit\\[\\d+\\]\">\n<$vars primaryListFilter={{{ [<configTiddler>get[first-search-filter]search-replace:g:regexp<replaceRegexp>,[]] }}} secondaryListFilter={{{ [<configTiddler>get[second-search-filter]search-replace:g:regexp<replaceRegexp>,[]] }}}>\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[subfilter<primaryListFilter>] [subfilter<secondaryListFilter>]\"/>\"\"\">\n{{$:/language/Search/Matches}}\n</$set>\n</$vars>\n</$vars>\n</$list>\n</$button>\n\\end\n\n\\define search-results-list()\n\\whitespace trim\n<$vars userInput={{$(searchTiddler)$}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}}>\n<$list filter=\"[<userInput>minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$tiddler tiddler=<<configTiddler>>>\n\n{{$:/core/ui/SearchResults}}\n\n</$tiddler>\n\n</$list>\n</$vars>\n\\end\n\n\\define cancel-search-actions() <$list filter=\"[<searchTiddler>get[text]!match{$:/temp/search}]\" emptyMessage=\"\"\"<$action-deletetiddler $filter=\"[[$:/temp/search]] [<searchTiddler>] [<searchListState>]\"/>\"\"\"><$action-setfield $tiddler=\"$:/temp/search\" text={{{ [<searchTiddler>get[text]] }}}/><$action-setfield $tiddler=\"$:/temp/search/refresh\" text=\"yes\"/></$list>\n\n\\define input-accept-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\"\"\"><$action-navigate $to={{{ [<__tiddler__>get[text]] }}}/></$list>\n\n\\define input-accept-variant-actions() <$list filter=\"[{$:/config/Search/NavigateOnEnter/enable}match[yes]]\" emptyMessage=\"\"\"<$list filter=\"[<__tiddler__>get[text]!is[missing]] ~[<__tiddler__>get[text]is[shadow]]\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\"\"\"><$list filter=\"[<__tiddler__>get[text]minlength[1]]\"><$action-sendmessage $message=\"tm-edit-tiddler\" $param={{{ [<__tiddler__>get[text]] }}}/></$list></$list>\n\n\\define set-next-input-tab(beforeafter:\"after\") <$macrocall $name=\"change-input-tab\" stateTitle=\"$:/state/tab/search-results/sidebar\" tag=\"$:/tags/SearchResults\" beforeafter=\"$beforeafter$\" defaultState={{$:/config/SearchResults/Default}} actions=\"\"\"<$action-setfield $tiddler=\"$:/state/search/currentTab\" text=<<nextTab>>/>\"\"\"/>\n\n\\define advanced-search-actions() <$action-setfield $tiddler=\"$:/temp/advancedsearch\" text={{$:/temp/search/input}}/><$action-setfield $tiddler=\"$:/temp/advancedsearch/input\" text={{$:/temp/search/input}}/><<delete-state-tiddlers>><$action-navigate $to=\"$:/AdvancedSearch\"/><$action-setfield $tiddler=\"$:/temp/advancedsearch/refresh\" text=\"yes\"/><$action-sendmessage $message=\"tm-focus-selector\" $param=\"\"\"[data-tiddler-title=\"$:/AdvancedSearch\"] .tc-search input\"\"\" preventScroll=\"true\"/><$action-deletetiddler $filter=\"$:/temp/search $:/temp/search/input $:/temp/search/refresh [<searchListState>]\"/>\n\n<div class=\"tc-sidebar-lists tc-sidebar-search\">\n\n<$vars editTiddler=\"$:/temp/search\" searchTiddler=\"$:/temp/search/input\" searchListState=<<qualify \"$:/state/search-list/selected-item\">>>\n<div class=\"tc-search\">\n<$keyboard key=\"((input-tab-right))\" actions=<<set-next-input-tab>>>\n<$keyboard key=\"((input-tab-left))\" actions=<<set-next-input-tab \"before\">>>\n<$keyboard key=\"((advanced-search-sidebar))\" actions=<<advanced-search-actions>>>\n<$macrocall $name=\"keyboard-driven-input\" tiddler=<<editTiddler>> storeTitle=<<searchTiddler>> \n\t\tselectionStateTitle=<<searchListState>> refreshTitle=\"$:/temp/search/refresh\" type=\"search\" \n\t\ttag=\"input\" focus={{$:/config/Search/AutoFocus}} focusPopup=<<qualify \"$:/state/popup/search-dropdown\">> \n\t\tclass=\"tc-popup-handle\" filterMinLength={{$:/config/Search/MinLength}} inputCancelActions=<<cancel-search-actions>> \n\t\tinputAcceptActions=<<input-accept-actions>> inputAcceptVariantActions=<<input-accept-variant-actions>> cancelPopups=\"yes\" \n\t\tconfigTiddlerFilter=\"[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]\"/>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n<$reveal state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n<<advanced-search-actions>>\n{{$:/core/images/advanced-search-button}}\n</$button>\n<$button class=\"tc-btn-invisible\">\n<<cancel-search-actions>><$action-sendmessage $message=\"tm-focus-selector\" $param=\".tc-search input\"/>\n{{$:/core/images/close-button}}\n</$button>\n<<count-popup-button>>\n</$reveal>\n<$reveal state=<<searchTiddler>> type=\"match\" text=\"\">\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/advanced-search-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown-wrapper\" state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown tc-search-drop-down tc-popup-handle\" state=<<qualify \"$:/state/popup/search-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n\n<<search-results-list>>\n\n</$reveal>\n\n</$reveal>\n\n</$vars>\n\n</div>\n"
},
"$:/core/ui/SideBarSegments/site-subtitle": {
"title": "$:/core/ui/SideBarSegments/site-subtitle",
"tags": "$:/tags/SideBarSegment",
"text": "<div class=\"tc-site-subtitle\">\n\n<$transclude tiddler=\"$:/SiteSubtitle\" mode=\"inline\"/>\n\n</div>\n"
},
"$:/core/ui/SideBarSegments/site-title": {
"title": "$:/core/ui/SideBarSegments/site-title",
"tags": "$:/tags/SideBarSegment",
"text": "<h1 class=\"tc-site-title\">\n\n<$transclude tiddler=\"$:/SiteTitle\" mode=\"inline\"/>\n\n</h1>\n"
},
"$:/core/ui/SideBarSegments/tabs": {
"title": "$:/core/ui/SideBarSegments/tabs",
"tags": "$:/tags/SideBarSegment",
"text": "<div class=\"tc-sidebar-lists tc-sidebar-tabs\">\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\" default={{$:/config/DefaultSidebarTab}} state=\"$:/state/tab/sidebar\" class=\"tc-sidebar-tabs-main\" explicitState=\"$:/state/tab/sidebar--595412856\"/>\n\n</div>\n"
},
"$:/core/ui/SwitcherModal": {
"title": "$:/core/ui/SwitcherModal",
"subtitle": "<$text text={{{[<switch>lookup[$:/language/Switcher/Subtitle/]]}}}/>",
"class": "tc-modal-centered",
"text": "<$tiddler tiddler={{{[<switch>lookup[$:/config/SwitcherTargets/]]}}}>\n\n\n<$transclude/>\n\n\n</$tiddler>"
},
"$:/TagManager": {
"title": "$:/TagManager",
"icon": "$:/core/images/tag-button",
"color": "#bbb",
"text": "\\define lingo-base() $:/language/TagManager/\n\\define iconEditorTab(type)\n\\whitespace trim\n<$link to=\"\"><<lingo Icons/None>></$link>\n<$list filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[sort[title]] +[$type$is[system]]\">\n<$link to={{!!title}}>\n<$transclude/> <$view field=\"title\"/>\n</$link>\n</$list>\n\\end\n\\define iconEditor(title)\n\\whitespace trim\n<div class=\"tc-drop-down-wrapper\">\n<$button popupTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal stateTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n<div class=\"tc-drop-down\">\n<$linkcatcher actions=\"\"\"<$action-setfield $tiddler=<<__title__>> icon=<<navigateTo>>/>\"\"\">\n<<iconEditorTab type:\"!\">>\n<hr/>\n<<iconEditorTab type:\"\">>\n</$linkcatcher>\n</div>\n</$reveal>\n</div>\n\\end\n\\define toggleButton(state)\n\\whitespace trim\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"closed\" default=\"closed\">\n<$button setTitle=<<__state__>> setTo=\"open\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n{{$:/core/images/info-button}}\n</$button>\n</$reveal>\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"open\" default=\"closed\">\n<$button setTitle=<<__state__>> setTo=\"closed\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n{{$:/core/images/info-button}}\n</$button>\n</$reveal>\n\\end\n\\whitespace trim\n<table class=\"tc-tag-manager-table\">\n<tbody>\n<tr>\n<th><<lingo Colour/Heading>></th>\n<th class=\"tc-tag-manager-tag\"><<lingo Tag/Heading>></th>\n<th><<lingo Count/Heading>></th>\n<th><<lingo Icon/Heading>></th>\n<th><<lingo Info/Heading>></th>\n</tr>\n<$list filter=\"[tags[]!is[system]sort[title]]\">\n<tr>\n<td><$edit-text field=\"color\" tag=\"input\" type=\"color\"/></td>\n<td>{{||$:/core/ui/TagTemplate}}</td>\n<td><$count filter=\"[all[current]tagging[]]\"/></td>\n<td>\n<$macrocall $name=\"iconEditor\" title={{!!title}}/>\n</td>\n<td>\n<$macrocall $name=\"toggleButton\" state={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} /> \n</td>\n</tr>\n<tr>\n<td></td>\n<td colspan=\"4\">\n<$reveal stateTitle={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} type=\"match\" text=\"open\" default=\"\">\n<table>\n<tbody>\n<tr><td><<lingo Colour/Heading>></td><td><$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/></td></tr>\n<tr><td><<lingo Icon/Heading>></td><td><$edit-text field=\"icon\" tag=\"input\" size=\"45\"/></td></tr>\n</tbody>\n</table>\n</$reveal>\n</td>\n</tr>\n</$list>\n<tr>\n<td></td>\n<td style=\"position:relative;\">\n{{$:/core/ui/UntaggedTemplate}}\n</td>\n<td>\n<small class=\"tc-menu-list-count\"><$count filter=\"[untagged[]!is[system]] -[tags[]]\"/></small>\n</td>\n<td></td>\n<td></td>\n</tr>\n</tbody>\n</table>\n"
},
"$:/core/ui/TagPickerTagTemplate": {
"title": "$:/core/ui/TagPickerTagTemplate",
"text": "\\whitespace trim\n<$button class=<<button-classes>> tag=\"a\" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}>\n<$list filter=\"[<saveTiddler>minlength[1]]\">\n<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter=\"[<tag>]\"/>\n</$list>\n<$set name=\"currentTiddlerCSSEscaped\" value={{{ [<saveTiddler>escapecss[]] }}}>\n<$action-sendmessage $message=\"tm-focus-selector\" $param=<<get-tagpicker-focus-selector>> preventScroll=\"true\"/>\n</$set>\n<<delete-tag-state-tiddlers>>\n<$list filter=\"[<refreshTitle>minlength[1]]\">\n<$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n</$list>\n<<actions>>\n<$set name=\"backgroundColor\" value={{!!color}}>\n<$wikify name=\"foregroundColor\" text=\"\"\"<$macrocall $name=\"contrastcolour\" target={{!!color}} fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>\"\"\">\n<span class=\"tc-tag-label tc-btn-invisible\" style=<<tag-pill-styles>>>\n<$transclude tiddler={{!!icon}}/><$view field=\"title\" format=\"text\"/>\n</span>\n</$wikify>\n</$set>\n</$button>\n"
},
"$:/core/ui/TagTemplate": {
"title": "$:/core/ui/TagTemplate",
"text": "\\whitespace trim\n<span class=\"tc-tag-list-item\">\n<$set name=\"transclusion\" value=<<currentTiddler>>>\n<$macrocall $name=\"tag-pill-body\" tag=<<currentTiddler>> icon={{!!icon}} colour={{!!color}} palette={{$:/palette}} element-tag=\"\"\"$button\"\"\" element-attributes=\"\"\"popup=<<qualify \"$:/state/popup/tag\">> dragFilter='[all[current]tagging[]]' tag='span'\"\"\"/>\n<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\" animate=\"yes\" class=\"tc-drop-down\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</$set>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TagDropdown]!has[draft.of]]\" variable=\"listItem\"> \n<$transclude tiddler=<<listItem>>/> \n</$list>\n<hr>\n<$macrocall $name=\"list-tagged-draggable\" tag=<<currentTiddler>>/>\n</$reveal>\n</$set>\n</span>\n"
},
"$:/core/ui/TiddlerFieldTemplate": {
"title": "$:/core/ui/TiddlerFieldTemplate",
"text": "<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<listItem>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<listItem>>/>\n</td>\n</tr>"
},
"$:/core/ui/TiddlerFields": {
"title": "$:/core/ui/TiddlerFields",
"text": "<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"
},
"$:/core/ui/TiddlerInfo/Advanced/PluginInfo": {
"title": "$:/core/ui/TiddlerInfo/Advanced/PluginInfo",
"tags": "$:/tags/TiddlerInfo/Advanced",
"text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n<$list filter=\"[all[current]has[plugin-type]]\">\n\n! <<lingo Heading>>\n\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</li>\n</$list>\n</ul>\n\n</$list>\n"
},
"$:/core/ui/TiddlerInfo/Advanced/ShadowInfo": {
"title": "$:/core/ui/TiddlerInfo/Advanced/ShadowInfo",
"tags": "$:/tags/TiddlerInfo/Advanced",
"text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/ShadowInfo/\n<$set name=\"infoTiddler\" value=<<currentTiddler>>>\n\n''<<lingo Heading>>''\n\n<$list filter=\"[all[current]!is[shadow]]\">\n\n<<lingo NotShadow/Hint>>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]]\">\n\n<<lingo Shadow/Hint>>\n\n<$list filter=\"[all[current]shadowsource[]]\">\n\n<$set name=\"pluginTiddler\" value=<<currentTiddler>>>\n<<lingo Shadow/Source>>\n</$set>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\">\n\n<<lingo OverriddenShadow/Hint>>\n\n</$list>\n\n\n</$list>\n</$set>\n"
},
"$:/core/ui/TiddlerInfo/Advanced": {
"title": "$:/core/ui/TiddlerInfo/Advanced",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Advanced/Caption}}",
"text": "<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo/Advanced]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>> mode=\"block\"/>\n</$list>\n"
},
"$:/core/ui/TiddlerInfo/Fields": {
"title": "$:/core/ui/TiddlerInfo/Fields",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Fields/Caption}}",
"text": "<$transclude tiddler=\"$:/core/ui/TiddlerFields\"/>\n"
},
"$:/core/ui/TiddlerInfo/List": {
"title": "$:/core/ui/TiddlerInfo/List",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/List/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[list{!!title}]\" emptyMessage=<<lingo List/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/TiddlerInfo/Listed": {
"title": "$:/core/ui/TiddlerInfo/Listed",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Listed/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]listed[]!is[system]]\" emptyMessage=<<lingo Listed/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/TiddlerInfo/References": {
"title": "$:/core/ui/TiddlerInfo/References",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/References/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]backlinks[]sort[title]]\" emptyMessage=<<lingo References/Empty>> template=\"$:/core/ui/ListItemTemplate\">\n</$list>"
},
"$:/core/ui/TiddlerInfo/Tagging": {
"title": "$:/core/ui/TiddlerInfo/Tagging",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Tagging/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]tagging[]]\" emptyMessage=<<lingo Tagging/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/TiddlerInfo/Tools": {
"title": "$:/core/ui/TiddlerInfo/Tools",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Tools/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\">\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/TiddlerInfo": {
"title": "$:/core/ui/TiddlerInfo",
"text": "<div style=\"position:relative;\">\n<div class=\"tc-tiddler-controls\" style=\"position:absolute;right:0;\">\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n</div>\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo]!has[draft.of]]\" default={{$:/config/TiddlerInfo/Default}}/>\n"
},
"$:/core/ui/TopBar/menu": {
"title": "$:/core/ui/TopBar/menu",
"tags": "$:/tags/TopRightBar",
"text": "<$list filter=\"[[$:/state/sidebar]get[text]] +[else[yes]!match[no]]\" variable=\"ignore\">\n<$button set=\"$:/state/sidebar\" setTo=\"no\" tooltip={{$:/language/Buttons/HideSideBar/Hint}} aria-label={{$:/language/Buttons/HideSideBar/Caption}} class=\"tc-btn-invisible tc-hide-sidebar-btn\">{{$:/core/images/chevron-right}}</$button>\n</$list>\n<$list filter=\"[[$:/state/sidebar]get[text]] +[else[yes]match[no]]\" variable=\"ignore\">\n<$button set=\"$:/state/sidebar\" setTo=\"yes\" tooltip={{$:/language/Buttons/ShowSideBar/Hint}} aria-label={{$:/language/Buttons/ShowSideBar/Caption}} class=\"tc-btn-invisible tc-show-sidebar-btn\">{{$:/core/images/chevron-left}}</$button>\n</$list>\n"
},
"$:/core/ui/UntaggedTemplate": {
"title": "$:/core/ui/UntaggedTemplate",
"text": "\\define lingo-base() $:/language/SideBar/\n<$button popup=<<qualify \"$:/state/popup/tag\">> class=\"tc-btn-invisible tc-untagged-label tc-tag-label\">\n<<lingo Tags/Untagged/Caption>>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\">\n<div class=\"tc-drop-down\">\n<$list filter=\"[untagged[]!is[system]] -[tags[]] +[sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/body": {
"title": "$:/core/ui/ViewTemplate/body",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal tag=\"div\" class=\"tc-tiddler-body\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[current]!has[plugin-type]!field:hide-body[yes]]\">\n\n<$transclude>\n\n<$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/>\n\n</$transclude>\n\n</$list>\n\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/classic": {
"title": "$:/core/ui/ViewTemplate/classic",
"tags": "$:/tags/ViewTemplate $:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/ClassicWarning/\n<$list filter=\"[all[current]type[text/x-tiddlywiki]]\">\n<div class=\"tc-message-box\">\n\n<<lingo Hint>>\n\n<$button set=\"!!type\" setTo=\"text/vnd.tiddlywiki\"><<lingo Upgrade/Caption>></$button>\n\n</div>\n</$list>\n"
},
"$:/core/ui/ViewTemplate/import": {
"title": "$:/core/ui/ViewTemplate/import",
"tags": "$:/tags/ViewTemplate",
"text": "\\define lingo-base() $:/language/Import/\n\n\\define buttons()\n<$button message=\"tm-delete-tiddler\" param=<<currentTiddler>>><<lingo Listing/Cancel/Caption>></$button>\n<$button message=\"tm-perform-import\" param=<<currentTiddler>>><<lingo Listing/Import/Caption>></$button>\n<<lingo Listing/Preview>> <$select tiddler=\"$:/state/importpreviewtype\" default=\"$:/core/ui/ImportPreviews/Text\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ImportPreview]!has[draft.of]]\">\n<option value=<<currentTiddler>>>{{!!caption}}</option>\n</$list>\n</$select>\n\\end\n\n<$list filter=\"[all[current]field:plugin-type[import]]\">\n\n<div class=\"tc-import\">\n\n<<lingo Listing/Hint>>\n\n<<buttons>>\n\n{{||$:/core/ui/ImportListing}}\n\n<<buttons>>\n\n</div>\n\n</$list>\n"
},
"$:/core/ui/ViewTemplate/plugin": {
"title": "$:/core/ui/ViewTemplate/plugin",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal tag=\"div\" class=\"tc-tiddler-plugin-info\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[current]has[plugin-type]] -[all[current]field:plugin-type[import]]\">\n<$set name=\"plugin-type\" value={{!!plugin-type}}>\n<$set name=\"default-popup-state\" value=\"yes\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n{{||$:/core/ui/Components/plugin-info}}\n</$set>\n</$set>\n</$set>\n</$list>\n</$reveal>"
},
"$:/core/ui/ViewTemplate/subtitle": {
"title": "$:/core/ui/ViewTemplate/subtitle",
"tags": "$:/tags/ViewTemplate",
"text": "\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-subtitle\">\n<$link to={{!!modifier}} />\n<$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/tags": {
"title": "$:/core/ui/ViewTemplate/tags",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-tags-wrapper\"><$list filter=\"[all[current]tags[]sort[title]]\" template=\"$:/core/ui/TagTemplate\" storyview=\"pop\"/></div>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/title": {
"title": "$:/core/ui/ViewTemplate/title",
"tags": "$:/tags/ViewTemplate",
"text": "\\whitespace trim\n\\define title-styles()\nfill:$(foregroundColor)$;\n\\end\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-tiddler-title\">\n<div class=\"tc-titlebar\">\n<span class=\"tc-tiddler-controls\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\"><$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"><$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>\n</span>\n<$set name=\"tv-wikilinks\" value={{$:/config/Tiddlers/TitleLinks}}>\n<$link>\n<$set name=\"foregroundColor\" value={{!!color}}>\n<$list filter=\"[all[current]has[icon]]~[[$:/config/DefaultTiddlerIcon]has[text]]\">\n<span class=\"tc-tiddler-title-icon\" style=<<title-styles>>>\n<$transclude tiddler={{!!icon}}>\n<$transclude tiddler={{$:/config/DefaultTiddlerIcon}}/>\n</$transclude>\n</span>\n</$list>\n</$set>\n<$list filter=\"[all[current]removeprefix[$:/]]\">\n<h2 class=\"tc-title\" title={{$:/language/SystemTiddler/Tooltip}}>\n<span class=\"tc-system-title-prefix\">$:/</span><$text text=<<currentTiddler>>/>\n</h2>\n</$list>\n<$list filter=\"[all[current]!prefix[$:/]]\">\n<h2 class=\"tc-title\">\n<$view field=\"title\"/>\n</h2>\n</$list>\n</$link>\n</$set>\n</div>\n\n<$reveal type=\"nomatch\" text=\"\" default=\"\" state=<<tiddlerInfoState>> class=\"tc-tiddler-info tc-popup-handle\" animate=\"yes\" retain=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]\" variable=\"listItem\"><$transclude tiddler=<<listItem>> mode=\"block\"/></$list>\n\n</$reveal>\n</div>"
},
"$:/core/ui/ViewTemplate/unfold": {
"title": "$:/core/ui/ViewTemplate/unfold",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal tag=\"div\" type=\"nomatch\" state=\"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar\" text=\"hide\">\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=\"tc-fold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-up}}\n</$button>\n</$reveal>\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"show\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=\"tc-unfold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate": {
"title": "$:/core/ui/ViewTemplate",
"text": "\\define folded-state()\n$:/state/folded/$(currentTiddler)$\n\\end\n\\define cancel-delete-tiddler-actions(message) <$action-sendmessage $message=\"tm-$message$-tiddler\"/>\n\\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]]\n<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify \"$:/state/popup/tiddler-info\">>><div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class={{{ tc-tiddler-frame tc-tiddler-view-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[shadow]is[tiddler]then[tc-tiddler-overridden-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]\" variable=\"listItem\"><$transclude tiddler=<<listItem>>/></$list>\n</div>\n</$vars>\n"
},
"$:/core/ui/Buttons/clone": {
"title": "$:/core/ui/Buttons/clone",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/clone-button}} {{$:/language/Buttons/Clone/Caption}}",
"description": "{{$:/language/Buttons/Clone/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-new-tiddler\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/Clone/Hint}} aria-label={{$:/language/Buttons/Clone/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/clone-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Clone/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/close-others": {
"title": "$:/core/ui/Buttons/close-others",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/close-others-button}} {{$:/language/Buttons/CloseOthers/Caption}}",
"description": "{{$:/language/Buttons/CloseOthers/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-close-other-tiddlers\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/CloseOthers/Hint}} aria-label={{$:/language/Buttons/CloseOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/close-others-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/CloseOthers/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/close": {
"title": "$:/core/ui/Buttons/close",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/close-button}} {{$:/language/Buttons/Close/Caption}}",
"description": "{{$:/language/Buttons/Close/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/close-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Close/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/edit": {
"title": "$:/core/ui/Buttons/edit",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/edit-button}} {{$:/language/Buttons/Edit/Caption}}",
"description": "{{$:/language/Buttons/Edit/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-edit-tiddler\" tooltip={{$:/language/Buttons/Edit/Hint}} aria-label={{$:/language/Buttons/Edit/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/edit-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Edit/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/export-tiddler": {
"title": "$:/core/ui/Buttons/export-tiddler",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/export-button}} {{$:/language/Buttons/ExportTiddler/Caption}}",
"description": "{{$:/language/Buttons/ExportTiddler/Hint}}",
"text": "\\define makeExportFilter()\n[[$(currentTiddler)$]]\n\\end\n<$macrocall $name=\"exportButton\" exportFilter=<<makeExportFilter>> lingoBase=\"$:/language/Buttons/ExportTiddler/\" baseFilename=<<currentTiddler>>/>"
},
"$:/core/ui/Buttons/fold-bar": {
"title": "$:/core/ui/Buttons/fold-bar",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/chevron-up}} {{$:/language/Buttons/Fold/FoldBar/Caption}}",
"description": "{{$:/language/Buttons/Fold/FoldBar/Hint}}",
"text": "<!-- This dummy toolbar button is here to allow visibility of the fold-bar to be controlled as if it were a toolbar button -->"
},
"$:/core/ui/Buttons/fold-others": {
"title": "$:/core/ui/Buttons/fold-others",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/fold-others-button}} {{$:/language/Buttons/FoldOthers/Caption}}",
"description": "{{$:/language/Buttons/FoldOthers/Hint}}",
"text": "\\whitespace trim\n<$button tooltip={{$:/language/Buttons/FoldOthers/Hint}} aria-label={{$:/language/Buttons/FoldOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-other-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-others-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/FoldOthers/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/fold": {
"title": "$:/core/ui/Buttons/fold",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/fold-button}} {{$:/language/Buttons/Fold/Caption}}",
"description": "{{$:/language/Buttons/Fold/Hint}}",
"text": "\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Fold/Caption}}/>\n</span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\" variable=\"listItem\">\n{{$:/core/images/unfold-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Unfold/Caption}}/>\n</span>\n</$list>\n</$button>\n</$reveal>\n"
},
"$:/core/ui/Buttons/info": {
"title": "$:/core/ui/Buttons/info",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/info-button}} {{$:/language/Buttons/Info/Caption}}",
"description": "{{$:/language/Buttons/Info/Hint}}",
"text": "\\whitespace trim\n\\define button-content()\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/info-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Info/Caption}}/>\n</span>\n</$list>\n\\end\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"popup\">\n<$button popup=<<tiddlerInfoState>> tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$reveal state=<<tiddlerInfoState>> type=\"match\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"yes\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=<<tiddlerInfoState>> type=\"nomatch\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n</$reveal>"
},
"$:/core/ui/Buttons/more-tiddler-actions": {
"title": "$:/core/ui/Buttons/more-tiddler-actions",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}",
"description": "{{$:/language/Buttons/More/Hint}}",
"text": "\\whitespace trim\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/more\">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/down-arrow}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/More/Caption}}/>\n</span>\n</$list>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down\">\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"tc-btn-invisible\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] -[[$:/core/ui/Buttons/more-tiddler-actions]]\" variable=\"listItem\">\n\n<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$set>\n\n</$reveal>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</div>\n\n</$reveal>"
},
"$:/core/ui/Buttons/new-here": {
"title": "$:/core/ui/Buttons/new-here",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/new-here-button}} {{$:/language/Buttons/NewHere/Caption}}",
"description": "{{$:/language/Buttons/NewHere/Hint}}",
"text": "\\whitespace trim\n\\define newHereActions()\n<$set name=\"tags\" filter=\"[<currentTiddler>] [{$:/config/NewTiddler/Tags}]\">\n<$action-sendmessage $message=\"tm-new-tiddler\" tags=<<tags>>/>\n</$set>\n\\end\n\\define newHereButton()\n<$button actions=<<newHereActions>> tooltip={{$:/language/Buttons/NewHere/Hint}} aria-label={{$:/language/Buttons/NewHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/new-here-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewHere/Caption}}/>\n</span>\n</$list>\n</$button>\n\\end\n<<newHereButton>>\n"
},
"$:/core/ui/Buttons/new-journal-here": {
"title": "$:/core/ui/Buttons/new-journal-here",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournalHere/Caption}}",
"description": "{{$:/language/Buttons/NewJournalHere/Hint}}",
"text": "\\whitespace trim\n\\define journalButtonTags()\n[[$(currentTiddlerTag)$]] $(journalTags)$\n\\end\n\\define journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"journalTitle\" text=\"\"\"<$macrocall $name=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalButtonTags>>/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/new-journal-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>\n</span>\n</$list>\n</$wikify>\n</$button>\n\\end\n<$set name=\"journalTitleTemplate\" value={{$:/config/NewJournal/Title}}>\n<$set name=\"journalTags\" value={{$:/config/NewJournal/Tags}}>\n<$set name=\"currentTiddlerTag\" value=<<currentTiddler>>>\n<<journalButton>>\n</$set>\n</$set>\n</$set>\n"
},
"$:/core/ui/Buttons/open-window": {
"title": "$:/core/ui/Buttons/open-window",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/open-window}} {{$:/language/Buttons/OpenWindow/Caption}}",
"description": "{{$:/language/Buttons/OpenWindow/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-open-window\" tooltip={{$:/language/Buttons/OpenWindow/Hint}} aria-label={{$:/language/Buttons/OpenWindow/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/open-window}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/OpenWindow/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/permalink": {
"title": "$:/core/ui/Buttons/permalink",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/permalink-button}} {{$:/language/Buttons/Permalink/Caption}}",
"description": "{{$:/language/Buttons/Permalink/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-permalink\" tooltip={{$:/language/Buttons/Permalink/Hint}} aria-label={{$:/language/Buttons/Permalink/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/permalink-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Permalink/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/permaview": {
"title": "$:/core/ui/Buttons/permaview",
"tags": "$:/tags/ViewToolbar $:/tags/PageControls",
"caption": "{{$:/core/images/permaview-button}} {{$:/language/Buttons/Permaview/Caption}}",
"description": "{{$:/language/Buttons/Permaview/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-permaview\" tooltip={{$:/language/Buttons/Permaview/Hint}} aria-label={{$:/language/Buttons/Permaview/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/permaview-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Permaview/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/DefaultTiddlers": {
"title": "$:/DefaultTiddlers",
"text": "GettingStarted\n"
},
"$:/temp/advancedsearch": {
"title": "$:/temp/advancedsearch",
"text": ""
},
"$:/snippets/allfields": {
"title": "$:/snippets/allfields",
"text": "\\define renderfield(title)\n<tr class=\"tc-view-field\"><td class=\"tc-view-field-name\">''$title$'':</td><td class=\"tc-view-field-value\">//{{$:/language/Docs/Fields/$title$}}//</td></tr>\n\\end\n<table class=\"tc-view-field-table\"><tbody><$list filter=\"[fields[]sort[title]]\" variable=\"listItem\"><$macrocall $name=\"renderfield\" title=<<listItem>>/></$list>\n</tbody></table>\n"
},
"$:/config/AnimationDuration": {
"title": "$:/config/AnimationDuration",
"text": "400"
},
"$:/config/AutoFocus": {
"title": "$:/config/AutoFocus",
"text": "title"
},
"$:/config/AutoSave": {
"title": "$:/config/AutoSave",
"text": "yes"
},
"$:/config/BitmapEditor/Colour": {
"title": "$:/config/BitmapEditor/Colour",
"text": "#444"
},
"$:/config/BitmapEditor/ImageSizes": {
"title": "$:/config/BitmapEditor/ImageSizes",
"text": "[[62px 100px]] [[100px 62px]] [[124px 200px]] [[200px 124px]] [[248px 400px]] [[371px 600px]] [[400px 248px]] [[556px 900px]] [[600px 371px]] [[742px 1200px]] [[900px 556px]] [[1200px 742px]]"
},
"$:/config/BitmapEditor/LineWidth": {
"title": "$:/config/BitmapEditor/LineWidth",
"text": "3px"
},
"$:/config/BitmapEditor/LineWidths": {
"title": "$:/config/BitmapEditor/LineWidths",
"text": "0.25px 0.5px 1px 2px 3px 4px 6px 8px 10px 16px 20px 28px 40px 56px 80px"
},
"$:/config/BitmapEditor/Opacities": {
"title": "$:/config/BitmapEditor/Opacities",
"text": "0.01 0.025 0.05 0.075 0.1 0.15 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
},
"$:/config/BitmapEditor/Opacity": {
"title": "$:/config/BitmapEditor/Opacity",
"text": "1.0"
},
"$:/config/DefaultMoreSidebarTab": {
"title": "$:/config/DefaultMoreSidebarTab",
"text": "$:/core/ui/MoreSideBar/Tags"
},
"$:/config/DefaultSidebarTab": {
"title": "$:/config/DefaultSidebarTab",
"text": "$:/core/ui/SideBar/Open"
},
"$:/config/DownloadSaver/AutoSave": {
"title": "$:/config/DownloadSaver/AutoSave",
"text": "no"
},
"$:/config/Drafts/TypingTimeout": {
"title": "$:/config/Drafts/TypingTimeout",
"text": "400"
},
"$:/config/EditMode/fieldname-filter": {
"title": "$:/config/EditMode/fieldname-filter",
"first-search-filter": "[!is[shadow]!is[system]fields[]search:title<userInput>sort[]] -created -creator -draft.of -draft.title -modified -modifier -tags -text -title -type",
"second-search-filter": "[fields[]search:title<userInput>sort[]] -[!is[shadow]!is[system]fields[]]"
},
"$:/config/EditTabIndex": {
"title": "$:/config/EditTabIndex",
"text": "1\n"
},
"$:/config/EditTemplateFields/Visibility/title": {
"title": "$:/config/EditTemplateFields/Visibility/title",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/tags": {
"title": "$:/config/EditTemplateFields/Visibility/tags",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/text": {
"title": "$:/config/EditTemplateFields/Visibility/text",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/creator": {
"title": "$:/config/EditTemplateFields/Visibility/creator",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/created": {
"title": "$:/config/EditTemplateFields/Visibility/created",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/modified": {
"title": "$:/config/EditTemplateFields/Visibility/modified",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/modifier": {
"title": "$:/config/EditTemplateFields/Visibility/modifier",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/type": {
"title": "$:/config/EditTemplateFields/Visibility/type",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/draft.title": {
"title": "$:/config/EditTemplateFields/Visibility/draft.title",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/draft.of": {
"title": "$:/config/EditTemplateFields/Visibility/draft.of",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/revision": {
"title": "$:/config/EditTemplateFields/Visibility/revision",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/bag": {
"title": "$:/config/EditTemplateFields/Visibility/bag",
"text": "hide"
},
"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4": {
"title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4",
"text": "hide"
},
"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5": {
"title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5",
"text": "hide"
},
"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6": {
"title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6",
"text": "hide"
},
"$:/config/EditorTypeMappings/image/gif": {
"title": "$:/config/EditorTypeMappings/image/gif",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/webp": {
"title": "$:/config/EditorTypeMappings/image/webp",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/heic": {
"title": "$:/config/EditorTypeMappings/image/heic",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/heif": {
"title": "$:/config/EditorTypeMappings/image/heif",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/jpeg": {
"title": "$:/config/EditorTypeMappings/image/jpeg",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/jpg": {
"title": "$:/config/EditorTypeMappings/image/jpg",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/png": {
"title": "$:/config/EditorTypeMappings/image/png",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/x-icon": {
"title": "$:/config/EditorTypeMappings/image/x-icon",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/text/vnd.tiddlywiki": {
"title": "$:/config/EditorTypeMappings/text/vnd.tiddlywiki",
"text": "text"
},
"$:/config/Manager/Show": {
"title": "$:/config/Manager/Show",
"text": "tiddlers"
},
"$:/config/Manager/Filter": {
"title": "$:/config/Manager/Filter",
"text": ""
},
"$:/config/Manager/Order": {
"title": "$:/config/Manager/Order",
"text": "forward"
},
"$:/config/Manager/Sort": {
"title": "$:/config/Manager/Sort",
"text": "title"
},
"$:/config/Manager/System": {
"title": "$:/config/Manager/System",
"text": "system"
},
"$:/config/Manager/Tag": {
"title": "$:/config/Manager/Tag",
"text": ""
},
"$:/state/popup/manager/item/$:/Manager/ItemMain/RawText": {
"title": "$:/state/popup/manager/item/$:/Manager/ItemMain/RawText",
"text": "hide"
},
"$:/config/MissingLinks": {
"title": "$:/config/MissingLinks",
"text": "yes"
},
"$:/config/Navigation/UpdateAddressBar": {
"title": "$:/config/Navigation/UpdateAddressBar",
"text": "no"
},
"$:/config/Navigation/UpdateHistory": {
"title": "$:/config/Navigation/UpdateHistory",
"text": "no"
},
"$:/config/NewImageType": {
"title": "$:/config/NewImageType",
"text": "jpeg"
},
"$:/config/OfficialPluginLibrary": {
"title": "$:/config/OfficialPluginLibrary",
"tags": "$:/tags/PluginLibrary",
"url": "https://tiddlywiki.com/library/v5.1.23/index.html",
"caption": "{{$:/language/OfficialPluginLibrary}}",
"text": "{{$:/language/OfficialPluginLibrary/Hint}}\n"
},
"$:/config/Navigation/openLinkFromInsideRiver": {
"title": "$:/config/Navigation/openLinkFromInsideRiver",
"text": "below"
},
"$:/config/Navigation/openLinkFromOutsideRiver": {
"title": "$:/config/Navigation/openLinkFromOutsideRiver",
"text": "top"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all",
"text": "hide"
},
"$:/config/Performance/Instrumentation": {
"title": "$:/config/Performance/Instrumentation",
"text": "no"
},
"$:/config/RegisterPluginType/plugin": {
"title": "$:/config/RegisterPluginType/plugin",
"text": "yes"
},
"$:/config/RegisterPluginType/theme": {
"title": "$:/config/RegisterPluginType/theme",
"text": "no"
},
"$:/config/RegisterPluginType/language": {
"title": "$:/config/RegisterPluginType/language",
"text": "no"
},
"$:/config/RegisterPluginType/info": {
"title": "$:/config/RegisterPluginType/info",
"text": "yes"
},
"$:/config/RegisterPluginType/import": {
"title": "$:/config/RegisterPluginType/import",
"text": "no"
},
"$:/config/SaveWikiButton/Template": {
"title": "$:/config/SaveWikiButton/Template",
"text": "$:/core/save/all"
},
"$:/config/SaverFilter": {
"title": "$:/config/SaverFilter",
"text": "[all[]] -[prefix[$:/HistoryList]] -[prefix[$:/StoryList]] -[status[pending]plugin-type[import]] -[[$:/isEncrypted]] -[[$:/UploadName]] -[prefix[$:/state/]] -[prefix[$:/temp/]]\n"
},
"$:/config/Search/AutoFocus": {
"title": "$:/config/Search/AutoFocus",
"text": "true"
},
"$:/config/Search/MinLength": {
"title": "$:/config/Search/MinLength",
"text": "3"
},
"$:/config/SearchResults/Default": {
"title": "$:/config/SearchResults/Default",
"text": "$:/core/ui/DefaultSearchResultList"
},
"$:/config/Server/ExternalFilters/[all[tiddlers]!is[system]sort[title]]": {
"title": "$:/config/Server/ExternalFilters/[all[tiddlers]!is[system]sort[title]]",
"text": "yes"
},
"$:/config/ShortcutInfo/add-field": {
"title": "$:/config/ShortcutInfo/add-field",
"text": "{{$:/language/EditTemplate/Fields/Add/Button/Hint}}"
},
"$:/config/ShortcutInfo/advanced-search": {
"title": "$:/config/ShortcutInfo/advanced-search",
"text": "{{$:/language/Buttons/AdvancedSearch/Hint}}"
},
"$:/config/ShortcutInfo/advanced-search-sidebar": {
"title": "$:/config/ShortcutInfo/advanced-search-sidebar",
"text": "{{$:/language/Shortcuts/Input/AdvancedSearch/Hint}}"
},
"$:/config/ShortcutInfo/bold": {
"title": "$:/config/ShortcutInfo/bold",
"text": "{{$:/language/Buttons/Bold/Hint}}"
},
"$:/config/ShortcutInfo/cancel-edit-tiddler": {
"title": "$:/config/ShortcutInfo/cancel-edit-tiddler",
"text": "{{$:/language/Buttons/Cancel/Hint}}"
},
"$:/config/ShortcutInfo/change-sidebar-layout": {
"title": "$:/config/ShortcutInfo/change-sidebar-layout",
"text": "{{$:/language/Shortcuts/SidebarLayout/Hint}}"
},
"$:/config/ShortcutInfo/delete-field": {
"title": "$:/config/ShortcutInfo/delete-field",
"text": "{{$:/language/EditTemplate/Field/Remove/Hint}}"
},
"$:/config/ShortcutInfo/excise": {
"title": "$:/config/ShortcutInfo/excise",
"text": "{{$:/language/Buttons/Excise/Hint}}"
},
"$:/config/ShortcutInfo/heading-1": {
"title": "$:/config/ShortcutInfo/heading-1",
"text": "{{$:/language/Buttons/Heading1/Hint}}"
},
"$:/config/ShortcutInfo/heading-2": {
"title": "$:/config/ShortcutInfo/heading-2",
"text": "{{$:/language/Buttons/Heading2/Hint}}"
},
"$:/config/ShortcutInfo/heading-3": {
"title": "$:/config/ShortcutInfo/heading-3",
"text": "{{$:/language/Buttons/Heading3/Hint}}"
},
"$:/config/ShortcutInfo/heading-4": {
"title": "$:/config/ShortcutInfo/heading-4",
"text": "{{$:/language/Buttons/Heading4/Hint}}"
},
"$:/config/ShortcutInfo/heading-5": {
"title": "$:/config/ShortcutInfo/heading-5",
"text": "{{$:/language/Buttons/Heading5/Hint}}"
},
"$:/config/ShortcutInfo/heading-6": {
"title": "$:/config/ShortcutInfo/heading-6",
"text": "{{$:/language/Buttons/Heading6/Hint}}"
},
"$:/config/ShortcutInfo/input-accept": {
"title": "$:/config/ShortcutInfo/input-accept",
"text": "{{$:/language/Shortcuts/Input/Accept/Hint}}"
},
"$:/config/ShortcutInfo/input-accept-variant": {
"title": "$:/config/ShortcutInfo/input-accept-variant",
"text": "{{$:/language/Shortcuts/Input/AcceptVariant/Hint}}"
},
"$:/config/ShortcutInfo/input-cancel": {
"title": "$:/config/ShortcutInfo/input-cancel",
"text": "{{$:/language/Shortcuts/Input/Cancel/Hint}}"
},
"$:/config/ShortcutInfo/input-down": {
"title": "$:/config/ShortcutInfo/input-down",
"text": "{{$:/language/Shortcuts/Input/Down/Hint}}"
},
"$:/config/ShortcutInfo/input-tab-left": {
"title": "$:/config/ShortcutInfo/input-tab-left",
"text": "{{$:/language/Shortcuts/Input/Tab-Left/Hint}}"
},
"$:/config/ShortcutInfo/input-tab-right": {
"title": "$:/config/ShortcutInfo/input-tab-right",
"text": "{{$:/language/Shortcuts/Input/Tab-Right/Hint}}"
},
"$:/config/ShortcutInfo/input-up": {
"title": "$:/config/ShortcutInfo/input-up",
"text": "{{$:/language/Shortcuts/Input/Up/Hint}}"
},
"$:/config/ShortcutInfo/italic": {
"title": "$:/config/ShortcutInfo/italic",
"text": "{{$:/language/Buttons/Italic/Hint}}"
},
"$:/config/ShortcutInfo/layout-switcher": {
"title": "$:/config/ShortcutInfo/layout-switcher",
"text": "{{$:/language/LayoutSwitcher/Description}}"
},
"$:/config/ShortcutInfo/link": {
"title": "$:/config/ShortcutInfo/link",
"text": "{{$:/language/Buttons/Link/Hint}}"
},
"$:/config/ShortcutInfo/linkify": {
"title": "$:/config/ShortcutInfo/linkify",
"text": "{{$:/language/Buttons/Linkify/Hint}}"
},
"$:/config/ShortcutInfo/list-bullet": {
"title": "$:/config/ShortcutInfo/list-bullet",
"text": "{{$:/language/Buttons/ListBullet/Hint}}"
},
"$:/config/ShortcutInfo/list-number": {
"title": "$:/config/ShortcutInfo/list-number",
"text": "{{$:/language/Buttons/ListNumber/Hint}}"
},
"$:/config/ShortcutInfo/mono-block": {
"title": "$:/config/ShortcutInfo/mono-block",
"text": "{{$:/language/Buttons/MonoBlock/Hint}}"
},
"$:/config/ShortcutInfo/mono-line": {
"title": "$:/config/ShortcutInfo/mono-line",
"text": "{{$:/language/Buttons/MonoLine/Hint}}"
},
"$:/config/ShortcutInfo/new-image": {
"title": "$:/config/ShortcutInfo/new-image",
"text": "{{$:/language/Buttons/NewImage/Hint}}"
},
"$:/config/ShortcutInfo/new-journal": {
"title": "$:/config/ShortcutInfo/new-journal",
"text": "{{$:/language/Buttons/NewJournal/Hint}}"
},
"$:/config/ShortcutInfo/new-tiddler": {
"title": "$:/config/ShortcutInfo/new-tiddler",
"text": "{{$:/language/Buttons/NewTiddler/Hint}}"
},
"$:/config/ShortcutInfo/picture": {
"title": "$:/config/ShortcutInfo/picture",
"text": "{{$:/language/Buttons/Picture/Hint}}"
},
"$:/config/ShortcutInfo/preview": {
"title": "$:/config/ShortcutInfo/preview",
"text": "{{$:/language/Buttons/Preview/Hint}}"
},
"$:/config/ShortcutInfo/quote": {
"title": "$:/config/ShortcutInfo/quote",
"text": "{{$:/language/Buttons/Quote/Hint}}"
},
"$:/config/ShortcutInfo/save-tiddler": {
"title": "$:/config/ShortcutInfo/save-tiddler",
"text": "{{$:/language/Buttons/Save/Hint}}"
},
"$:/config/ShortcutInfo/save-wiki": {
"title": "$:/config/ShortcutInfo/save-wiki",
"text": "{{$:/language/Buttons/SaveWiki/Hint}}"
},
"$:/config/ShortcutInfo/sidebar-search": {
"title": "$:/config/ShortcutInfo/sidebar-search",
"text": "{{$:/language/Buttons/SidebarSearch/Hint}}"
},
"$:/config/ShortcutInfo/stamp": {
"title": "$:/config/ShortcutInfo/stamp",
"text": "{{$:/language/Buttons/Stamp/Hint}}"
},
"$:/config/ShortcutInfo/strikethrough": {
"title": "$:/config/ShortcutInfo/strikethrough",
"text": "{{$:/language/Buttons/Strikethrough/Hint}}"
},
"$:/config/ShortcutInfo/subscript": {
"title": "$:/config/ShortcutInfo/subscript",
"text": "{{$:/language/Buttons/Subscript/Hint}}"
},
"$:/config/ShortcutInfo/superscript": {
"title": "$:/config/ShortcutInfo/superscript",
"text": "{{$:/language/Buttons/Superscript/Hint}}"
},
"$:/config/ShortcutInfo/toggle-sidebar": {
"title": "$:/config/ShortcutInfo/toggle-sidebar",
"text": "{{$:/language/Buttons/ToggleSidebar/Hint}}"
},
"$:/config/ShortcutInfo/transcludify": {
"title": "$:/config/ShortcutInfo/transcludify",
"text": "{{$:/language/Buttons/Transcludify/Hint}}"
},
"$:/config/ShortcutInfo/underline": {
"title": "$:/config/ShortcutInfo/underline",
"text": "{{$:/language/Buttons/Underline/Hint}}"
},
"$:/config/SwitcherTargets/layout": {
"title": "$:/config/SwitcherTargets/layout",
"text": "$:/snippets/LayoutSwitcher"
},
"$:/config/SwitcherTargets/language": {
"title": "$:/config/SwitcherTargets/language",
"text": "$:/snippets/languageswitcher"
},
"$:/config/SwitcherTargets/palette": {
"title": "$:/config/SwitcherTargets/palette",
"text": "$:/core/ui/ControlPanel/Palette"
},
"$:/config/SwitcherTargets/theme": {
"title": "$:/config/SwitcherTargets/theme",
"text": "$:/core/ui/ControlPanel/Theme"
},
"$:/config/SyncFilter": {
"title": "$:/config/SyncFilter",
"text": "[is[tiddler]] -[[$:/core]] -[[$:/library/sjcl.js]] -[prefix[$:/boot/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/isEncrypted]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]]\n"
},
"$:/config/SyncSystemTiddlersFromServer": {
"title": "$:/config/SyncSystemTiddlersFromServer",
"text": "no"
},
"$:/config/Tags/MinLength": {
"title": "$:/config/Tags/MinLength",
"text": "0"
},
"$:/config/TextEditor/EditorHeight/Height": {
"title": "$:/config/TextEditor/EditorHeight/Height",
"text": "400px"
},
"$:/config/TextEditor/EditorHeight/Mode": {
"title": "$:/config/TextEditor/EditorHeight/Mode",
"text": "auto"
},
"$:/config/TiddlerInfo/Default": {
"title": "$:/config/TiddlerInfo/Default",
"text": "$:/core/ui/TiddlerInfo/Fields"
},
"$:/config/TiddlerInfo/Mode": {
"title": "$:/config/TiddlerInfo/Mode",
"text": "popup"
},
"$:/config/Tiddlers/TitleLinks": {
"title": "$:/config/Tiddlers/TitleLinks",
"text": "no"
},
"$:/config/Toolbar/ButtonClass": {
"title": "$:/config/Toolbar/ButtonClass",
"text": "tc-btn-invisible"
},
"$:/config/Toolbar/Icons": {
"title": "$:/config/Toolbar/Icons",
"text": "yes"
},
"$:/config/Toolbar/Text": {
"title": "$:/config/Toolbar/Text",
"text": "no"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions",
"text": "show"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others",
"text": "hide"
},
"$:/config/shortcuts-mac/bold": {
"title": "$:/config/shortcuts-mac/bold",
"text": "meta-B"
},
"$:/config/shortcuts-mac/input-tab-left": {
"title": "$:/config/shortcuts-mac/input-tab-left",
"text": "ctrl-Left"
},
"$:/config/shortcuts-mac/input-tab-right": {
"title": "$:/config/shortcuts-mac/input-tab-right",
"text": "ctrl-Right"
},
"$:/config/shortcuts-mac/italic": {
"title": "$:/config/shortcuts-mac/italic",
"text": "meta-I"
},
"$:/config/shortcuts-mac/underline": {
"title": "$:/config/shortcuts-mac/underline",
"text": "meta-U"
},
"$:/config/shortcuts-mac/new-image": {
"title": "$:/config/shortcuts-mac/new-image",
"text": "ctrl-I"
},
"$:/config/shortcuts-mac/new-journal": {
"title": "$:/config/shortcuts-mac/new-journal",
"text": "ctrl-J"
},
"$:/config/shortcuts-mac/new-tiddler": {
"title": "$:/config/shortcuts-mac/new-tiddler",
"text": "ctrl-N"
},
"$:/config/shortcuts-mac/save-wiki": {
"title": "$:/config/shortcuts-mac/save-wiki",
"text": "meta-S"
},
"$:/config/shortcuts-not-mac/bold": {
"title": "$:/config/shortcuts-not-mac/bold",
"text": "ctrl-B"
},
"$:/config/shortcuts-not-mac/italic": {
"title": "$:/config/shortcuts-not-mac/italic",
"text": "ctrl-I"
},
"$:/config/shortcuts-not-mac/underline": {
"title": "$:/config/shortcuts-not-mac/underline",
"text": "ctrl-U"
},
"$:/config/shortcuts-not-mac/new-image": {
"title": "$:/config/shortcuts-not-mac/new-image",
"text": "alt-I"
},
"$:/config/shortcuts-not-mac/new-journal": {
"title": "$:/config/shortcuts-not-mac/new-journal",
"text": "alt-J"
},
"$:/config/shortcuts-not-mac/new-tiddler": {
"title": "$:/config/shortcuts-not-mac/new-tiddler",
"text": "alt-N"
},
"$:/config/shortcuts/add-field": {
"title": "$:/config/shortcuts/add-field",
"text": "enter"
},
"$:/config/shortcuts/advanced-search": {
"title": "$:/config/shortcuts/advanced-search",
"text": "ctrl-shift-A"
},
"$:/config/shortcuts/advanced-search-sidebar": {
"title": "$:/config/shortcuts/advanced-search-sidebar",
"text": "alt-Enter"
},
"$:/config/shortcuts/cancel-edit-tiddler": {
"title": "$:/config/shortcuts/cancel-edit-tiddler",
"text": "escape"
},
"$:/config/shortcuts/change-sidebar-layout": {
"title": "$:/config/shortcuts/change-sidebar-layout",
"text": "shift-alt-Down"
},
"$:/config/shortcuts/delete-field": {
"title": "$:/config/shortcuts/delete-field",
"text": "shift-alt-D"
},
"$:/config/shortcuts/excise": {
"title": "$:/config/shortcuts/excise",
"text": "ctrl-E"
},
"$:/config/shortcuts/sidebar-search": {
"title": "$:/config/shortcuts/sidebar-search",
"text": "ctrl-shift-F"
},
"$:/config/shortcuts/heading-1": {
"title": "$:/config/shortcuts/heading-1",
"text": "ctrl-1"
},
"$:/config/shortcuts/heading-2": {
"title": "$:/config/shortcuts/heading-2",
"text": "ctrl-2"
},
"$:/config/shortcuts/heading-3": {
"title": "$:/config/shortcuts/heading-3",
"text": "ctrl-3"
},
"$:/config/shortcuts/heading-4": {
"title": "$:/config/shortcuts/heading-4",
"text": "ctrl-4"
},
"$:/config/shortcuts/heading-5": {
"title": "$:/config/shortcuts/heading-5",
"text": "ctrl-5"
},
"$:/config/shortcuts/heading-6": {
"title": "$:/config/shortcuts/heading-6",
"text": "ctrl-6"
},
"$:/config/shortcuts/input-accept": {
"title": "$:/config/shortcuts/input-accept",
"text": "Enter"
},
"$:/config/shortcuts/input-accept-variant": {
"title": "$:/config/shortcuts/input-accept-variant",
"text": "ctrl-Enter"
},
"$:/config/shortcuts/input-cancel": {
"title": "$:/config/shortcuts/input-cancel",
"text": "Escape"
},
"$:/config/shortcuts/input-down": {
"title": "$:/config/shortcuts/input-down",
"text": "Down"
},
"$:/config/shortcuts/input-tab-left": {
"title": "$:/config/shortcuts/input-tab-left",
"text": "alt-Left"
},
"$:/config/shortcuts/input-tab-right": {
"title": "$:/config/shortcuts/input-tab-right",
"text": "alt-Right"
},
"$:/config/shortcuts/input-up": {
"title": "$:/config/shortcuts/input-up",
"text": "Up"
},
"$:/config/shortcuts/layout-switcher": {
"title": "$:/config/shortcuts/layout-switcher",
"text": "ctrl-shift-L"
},
"$:/config/shortcuts/link": {
"title": "$:/config/shortcuts/link",
"text": "ctrl-L"
},
"$:/config/shortcuts/linkify": {
"title": "$:/config/shortcuts/linkify",
"text": "alt-shift-L"
},
"$:/config/shortcuts/list-bullet": {
"title": "$:/config/shortcuts/list-bullet",
"text": "ctrl-shift-L"
},
"$:/config/shortcuts/list-number": {
"title": "$:/config/shortcuts/list-number",
"text": "ctrl-shift-N"
},
"$:/config/shortcuts/mono-block": {
"title": "$:/config/shortcuts/mono-block",
"text": "ctrl-shift-M"
},
"$:/config/shortcuts/mono-line": {
"title": "$:/config/shortcuts/mono-line",
"text": "ctrl-M"
},
"$:/config/shortcuts/picture": {
"title": "$:/config/shortcuts/picture",
"text": "ctrl-shift-I"
},
"$:/config/shortcuts/preview": {
"title": "$:/config/shortcuts/preview",
"text": "alt-P"
},
"$:/config/shortcuts/quote": {
"title": "$:/config/shortcuts/quote",
"text": "ctrl-Q"
},
"$:/config/shortcuts/save-tiddler": {
"title": "$:/config/shortcuts/save-tiddler",
"text": "ctrl+enter"
},
"$:/config/shortcuts/save-wiki": {
"title": "$:/config/shortcuts/save-wiki",
"text": "ctrl-S"
},
"$:/config/shortcuts/stamp": {
"title": "$:/config/shortcuts/stamp",
"text": "ctrl-S"
},
"$:/config/shortcuts/strikethrough": {
"title": "$:/config/shortcuts/strikethrough",
"text": "ctrl-T"
},
"$:/config/shortcuts/subscript": {
"title": "$:/config/shortcuts/subscript",
"text": "ctrl-shift-B"
},
"$:/config/shortcuts/superscript": {
"title": "$:/config/shortcuts/superscript",
"text": "ctrl-shift-P"
},
"$:/config/shortcuts/toggle-sidebar": {
"title": "$:/config/shortcuts/toggle-sidebar",
"text": "alt-shift-S"
},
"$:/config/shortcuts/transcludify": {
"title": "$:/config/shortcuts/transcludify",
"text": "alt-shift-T"
},
"$:/config/ui/EditTemplate": {
"title": "$:/config/ui/EditTemplate",
"text": "$:/core/ui/EditTemplate"
},
"$:/config/ui/ViewTemplate": {
"title": "$:/config/ui/ViewTemplate",
"text": "$:/core/ui/ViewTemplate"
},
"$:/config/WikiParserRules/Inline/wikilink": {
"title": "$:/config/WikiParserRules/Inline/wikilink",
"text": "enable"
},
"$:/snippets/currpalettepreview": {
"title": "$:/snippets/currpalettepreview",
"text": "\\define resolve-colour(macrocall)\n\\import $:/core/macros/utils\n\\whitespace trim\n<$wikify name=\"name\" text=\"\"\"$macrocall$\"\"\">\n<<name>>\n</$wikify>\n\\end\n\\define swatchStyle()\nbackground-color: $(swatchColour)$;\n\\end\n\\define swatch-inner()\n<$set name=\"swatchColour\" value={{##$(colourResolved)$}}>\n<$list filter=\"[<swatchColour>!prefix[<<colour ]!suffix[>>]]\" variable=\"ignore\">\n<div class=\"tc-swatch\" style=<<swatchStyle>> title=<<swatchTitle>>/>\n</$list>\n<$list filter=\"[<swatchColour>prefix[<<colour ]suffix[>>]]\" variable=\"ignore\">\n<$wikify name=\"colourResolved\" text=\"\"\"<$macrocall $name=\"resolve-colour\" macrocall=<<swatchColour>>/>\"\"\">\n<<swatch-inner>>\n</$wikify>\n</$list>\n</$set>\n\\end\n\\define swatch()\n<$set name=\"swatchColour\" value={{##$(colour)$}}>\n<$set name=\"swatchTitle\" value=<<colour>>>\n<$list filter=\"[<swatchColour>!prefix[<<colour ]!suffix[>>]]\" variable=\"ignore\">\n<div class=\"tc-swatch\" style=<<swatchStyle>> title=<<swatchTitle>>/>\n</$list>\n<$list filter=\"[<swatchColour>prefix[<<colour ]suffix[>>]]\" variable=\"ignore\">\n<$wikify name=\"colourResolved\" text=\"\"\"<$macrocall $name=\"resolve-colour\" macrocall=<<swatchColour>>/>\"\"\">\n<<swatch-inner>>\n</$wikify>\n</$list>\n</$set>\n</$set>\n\\end\n<div class=\"tc-swatches-horiz\"><$list filter=\"\nforeground\nbackground\nmuted-foreground\nprimary\npage-background\ntab-background\ntiddler-info-background\n\" variable=\"colour\"><<swatch>></$list></div>\n"
},
"$:/snippets/download-wiki-button": {
"title": "$:/snippets/download-wiki-button",
"text": "\\define lingo-base() $:/language/ControlPanel/Tools/Download/\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-download-file\" $param=\"$:/core/save/all\" filename=\"index.html\"/>\n<<lingo Full/Caption>> {{$:/core/images/save-button}}\n</$button>"
},
"$:/language": {
"title": "$:/language",
"text": "$:/languages/en-GB"
},
"$:/snippets/languageswitcher": {
"title": "$:/snippets/languageswitcher",
"text": "\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n\n<$linkcatcher to=\"$:/language\">\n<div class=\"tc-chooser tc-language-chooser\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[description]]\">\n<$set name=\"cls\" filter=\"[all[current]field:title{$:/language}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link>\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value=<<currentTiddler>>>\n<$transclude subtiddler=<<flag-title>>>\n<$list filter=\"[all[current]field:title[$:/languages/en-GB]]\">\n<$transclude tiddler=\"$:/languages/en-GB/icon\"/>\n</$list>\n</$transclude>\n</$set>\n</span>\n<$view field=\"description\">\n<$view field=\"name\">\n<$view field=\"title\"/>\n</$view>\n</$view>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
},
"$:/core/macros/CSS": {
"title": "$:/core/macros/CSS",
"tags": "$:/tags/Macro",
"text": "\\define colour(name)\n<$transclude tiddler={{$:/palette}} index=\"$name$\"><$transclude tiddler=\"$:/palettes/Vanilla\" index=\"$name$\"><$transclude tiddler=\"$:/config/DefaultColourMappings/$name$\"/></$transclude></$transclude>\n\\end\n\n\\define color(name)\n<<colour $name$>>\n\\end\n\n\\define box-shadow(shadow)\n``\n -webkit-box-shadow: $shadow$;\n -moz-box-shadow: $shadow$;\n box-shadow: $shadow$;\n``\n\\end\n\n\\define filter(filter)\n``\n -webkit-filter: $filter$;\n -moz-filter: $filter$;\n filter: $filter$;\n``\n\\end\n\n\\define transition(transition)\n``\n -webkit-transition: $transition$;\n -moz-transition: $transition$;\n transition: $transition$;\n``\n\\end\n\n\\define transform-origin(origin)\n``\n -webkit-transform-origin: $origin$;\n -moz-transform-origin: $origin$;\n transform-origin: $origin$;\n``\n\\end\n\n\\define background-linear-gradient(gradient)\n``\nbackground-image: linear-gradient($gradient$);\nbackground-image: -o-linear-gradient($gradient$);\nbackground-image: -moz-linear-gradient($gradient$);\nbackground-image: -webkit-linear-gradient($gradient$);\nbackground-image: -ms-linear-gradient($gradient$);\n``\n\\end\n\n\\define column-count(columns)\n``\n-moz-column-count: $columns$;\n-webkit-column-count: $columns$;\ncolumn-count: $columns$;\n``\n\\end\n\n\\define datauri(title)\n<$macrocall $name=\"makedatauri\" type={{$title$!!type}} text={{$title$}} _canonical_uri={{$title$!!_canonical_uri}}/>\n\\end\n\n\\define if-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\">$text$</$reveal>\n\\end\n\n\\define if-no-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">$text$</$reveal>\n\\end\n\n\\define if-background-attachment(text)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" type=\"nomatch\" text=\"\">$text$</$reveal>\n\\end\n"
},
"$:/core/macros/colour-picker": {
"title": "$:/core/macros/colour-picker",
"tags": "$:/tags/Macro",
"text": "\\define colour-picker-update-recent()\n<$action-listops\n\t$tiddler=\"$:/config/ColourPicker/Recent\"\n\t$subfilter=\"$(colour-picker-value)$ [list[$:/config/ColourPicker/Recent]remove[$(colour-picker-value)$]] +[limit[8]]\"\n/>\n\\end\n\n\\define colour-picker-inner(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(colour-picker-value)$\"\"\">\n\n$(colour-picker-update-recent)$\n\n$actions$\n\n<span style=\"display:inline-block; background-color: $(colour-picker-value)$; width: 100%; height: 100%; border-radius: 50%;\"/>\n\n</$button>\n\\end\n\n\\define colour-picker-recent-inner(actions)\n<$set name=\"colour-picker-value\" value=\"$(recentColour)$\">\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$set>\n\\end\n\n\\define colour-picker-recent(actions)\n{{$:/language/ColourPicker/Recent}} <$list filter=\"[list[$:/config/ColourPicker/Recent]]\" variable=\"recentColour\">\n<$macrocall $name=\"colour-picker-recent-inner\" actions=\"\"\"$actions$\"\"\"/></$list>\n\\end\n\n\\define colour-picker(actions)\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker-recent\" actions=\"\"\"$actions$\"\"\"/>\n\n---\n\n<$list filter=\"LightPink Pink Crimson LavenderBlush PaleVioletRed HotPink DeepPink MediumVioletRed Orchid Thistle Plum Violet Magenta Fuchsia DarkMagenta Purple MediumOrchid DarkViolet DarkOrchid Indigo BlueViolet MediumPurple MediumSlateBlue SlateBlue DarkSlateBlue Lavender GhostWhite Blue MediumBlue MidnightBlue DarkBlue Navy RoyalBlue CornflowerBlue LightSteelBlue LightSlateGrey SlateGrey DodgerBlue AliceBlue SteelBlue LightSkyBlue SkyBlue DeepSkyBlue LightBlue PowderBlue CadetBlue Azure LightCyan PaleTurquoise Cyan Aqua DarkTurquoise DarkSlateGrey DarkCyan Teal MediumTurquoise LightSeaGreen Turquoise Aquamarine MediumAquamarine MediumSpringGreen MintCream SpringGreen MediumSeaGreen SeaGreen Honeydew LightGreen PaleGreen DarkSeaGreen LimeGreen Lime ForestGreen Green DarkGreen Chartreuse LawnGreen GreenYellow DarkOliveGreen YellowGreen OliveDrab Beige LightGoldenrodYellow Ivory LightYellow Yellow Olive DarkKhaki LemonChiffon PaleGoldenrod Khaki Gold Cornsilk Goldenrod DarkGoldenrod FloralWhite OldLace Wheat Moccasin Orange PapayaWhip BlanchedAlmond NavajoWhite AntiqueWhite Tan BurlyWood Bisque DarkOrange Linen Peru PeachPuff SandyBrown Chocolate SaddleBrown Seashell Sienna LightSalmon Coral OrangeRed DarkSalmon Tomato MistyRose Salmon Snow LightCoral RosyBrown IndianRed Red Brown FireBrick DarkRed Maroon White WhiteSmoke Gainsboro LightGrey Silver DarkGrey Grey DimGrey Black\" variable=\"colour-picker-value\">\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$list>\n\n---\n\n<$edit-text tiddler=\"$:/config/ColourPicker/New\" tag=\"input\" default=\"\" placeholder=\"\"/>\n<$edit-text tiddler=\"$:/config/ColourPicker/New\" type=\"color\" tag=\"input\"/>\n<$set name=\"colour-picker-value\" value={{$:/config/ColourPicker/New}}>\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$set>\n\n</div>\n\n\\end\n"
},
"$:/core/macros/copy-to-clipboard": {
"title": "$:/core/macros/copy-to-clipboard",
"tags": "$:/tags/Macro",
"text": "\\define copy-to-clipboard(src,class:\"tc-btn-invisible\",style)\n<$button class=<<__class__>> style=<<__style__>> message=\"tm-copy-to-clipboard\" param=<<__src__>> tooltip={{$:/language/Buttons/CopyToClipboard/Hint}}>\n{{$:/core/images/copy-clipboard}} <$text text={{$:/language/Buttons/CopyToClipboard/Caption}}/>\n</$button>\n\\end\n\n\\define copy-to-clipboard-above-right(src,class:\"tc-btn-invisible\",style)\n<div style=\"position: relative;\">\n<div style=\"position: absolute; bottom: 0; right: 0;\">\n<$macrocall $name=\"copy-to-clipboard\" src=<<__src__>> class=<<__class__>> style=<<__style__>>/>\n</div>\n</div>\n\\end\n\n"
},
"$:/core/macros/diff": {
"title": "$:/core/macros/diff",
"tags": "$:/tags/Macro",
"text": "\\define compareTiddlerText(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle)\n<$set name=\"source\" tiddler=<<__sourceTiddlerTitle__>> subtiddler=<<__sourceSubTiddlerTitle__>>>\n<$set name=\"dest\" tiddler=<<__destTiddlerTitle__>> subtiddler=<<__destSubTiddlerTitle__>>>\n<$diff-text source=<<source>> dest=<<dest>>/>\n</$set>\n</$set>\n\\end\n\n\\define compareTiddlers(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle,exclude)\n<table class=\"tc-diff-tiddlers\">\n<tbody>\n<$set name=\"sourceFields\" filter=\"[<__sourceTiddlerTitle__>fields[]sort[]]\">\n<$set name=\"destFields\" filter=\"[<__destSubTiddlerTitle__>subtiddlerfields<__destTiddlerTitle__>sort[]]\">\n<$list filter=\"[enlist<sourceFields>] [enlist<destFields>] -[enlist<__exclude__>] +[sort[]]\" variable=\"fieldName\">\n<tr>\n<th>\n<$text text=<<fieldName>>/> \n</th>\n<td>\n<$set name=\"source\" tiddler=<<__sourceTiddlerTitle__>> subtiddler=<<__sourceSubTiddlerTitle__>> field=<<fieldName>>>\n<$set name=\"dest\" tiddler=<<__destTiddlerTitle__>> subtiddler=<<__destSubTiddlerTitle__>> field=<<fieldName>>>\n<$diff-text source=<<source>> dest=<<dest>>>\n</$diff-text>\n</$set>\n</$set>\n</td>\n</tr>\n</$list>\n</$set>\n</$set>\n</tbody>\n</table>\n\\end\n"
},
"$:/core/macros/dumpvariables": {
"title": "$:/core/macros/dumpvariables",
"tags": "$:/tags/Macro",
"text": "\\define dumpvariables()\n<ul>\n<$list filter=\"[variables[]]\" variable=\"varname\">\n<li>\n<strong><code><$text text=<<varname>>/></code></strong>:<br/>\n<$codeblock code={{{ [<varname>getvariable[]] }}}/>\n</li>\n</$list>\n</ul>\n\\end\n"
},
"$:/core/macros/export": {
"title": "$:/core/macros/export",
"tags": "$:/tags/Macro",
"text": "\\define exportButtonFilename(baseFilename)\n$baseFilename$$(extension)$\n\\end\n\n\\define exportButton(exportFilter:\"[!is[system]sort[title]]\",lingoBase,baseFilename:\"tiddlers\")\n<span class=\"tc-popup-keep\"><$button popup=<<qualify \"$:/state/popup/export\">> tooltip={{$lingoBase$Hint}} aria-label={{$lingoBase$Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/core/images/export-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$lingoBase$Caption}}/></span>\n</$list>\n</$button></span><$reveal state=<<qualify \"$:/state/popup/export\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$set name=\"count\" value={{{ [subfilter<__exportFilter__>count[]] }}}>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Exporter]]\">\n<$list filter=\"[<currentTiddler>has[condition]subfilter{!!condition}limit[1]] ~[<currentTiddler>!has[condition]then[true]]\" variable=\"ignore\">\n<$set name=\"extension\" value={{!!extension}}>\n<$button class=\"tc-btn-invisible\">\n<$action-sendmessage $message=\"tm-download-file\" $param=<<currentTiddler>> exportFilter=<<__exportFilter__>> filename=<<exportButtonFilename \"\"\"$baseFilename$\"\"\">>/>\n<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/export\">>/>\n<$transclude field=\"description\"/>\n</$button>\n</$set>\n</$list>\n</$list>\n</$set>\n</div>\n</$reveal>\n\\end\n"
},
"$:/core/macros/image-picker": {
"title": "$:/core/macros/image-picker",
"created": "20170715180840889",
"modified": "20170715180914005",
"tags": "$:/tags/Macro",
"type": "text/vnd.tiddlywiki",
"text": "\\define image-picker-thumbnail(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(imageTitle)$\"\"\">\n$actions$\n<$transclude tiddler=<<imageTitle>>/>\n</$button>\n\\end\n\n\\define image-picker-list(filter,actions)\n<$list filter=\"\"\"$filter$\"\"\" variable=\"imageTitle\">\n<$macrocall $name=\"image-picker-thumbnail\" actions=\"\"\"$actions$\"\"\"/>\n</$list>\n\\end\n\n\\define image-picker(actions,filter:\"[all[shadows+tiddlers]is[image]] -[type[application/pdf]] +[!has[draft.of]$subfilter$sort[title]]\",subfilter:\"\")\n<div class=\"tc-image-chooser\">\n<$vars state-system=<<qualify \"$:/state/image-picker/system\">>>\n<$checkbox tiddler=<<state-system>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"hide\">\n{{$:/language/SystemTiddlers/Include/Prompt}}\n</$checkbox>\n<$reveal state=<<state-system>> type=\"match\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$ +[!is[system]]\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</$reveal>\n<$reveal state=<<state-system>> type=\"nomatch\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</$reveal>\n</$vars>\n</div>\n\\end\n\n\\define image-picker-include-tagged-images(actions)\n<$macrocall $name=\"image-picker\" filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[!has[draft.of]sort[title]]\" actions=\"\"\"$actions$\"\"\"/>\n\\end\n"
},
"$:/core/macros/keyboard-driven-input": {
"title": "$:/core/macros/keyboard-driven-input",
"tags": "$:/tags/Macro",
"text": "\\define change-input-tab(stateTitle,tag,beforeafter,defaultState,actions)\n<$set name=\"tabsList\" filter=\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]]\">\n<$vars currentState={{{ [<__stateTitle__>!is[missing]get[text]] ~[<__defaultState__>] }}} firstTab={{{ [enlist<tabsList>nth[1]] }}} lastTab={{{ [enlist<tabsList>last[]] }}}>\n<$set name=\"nextTab\" value={{{ [all[shadows+tiddlers]tag<__tag__>!has[draft.of]$beforeafter$<currentState>] ~[[$beforeafter$]removeprefix[after]suffix[]addprefix<firstTab>] ~[[$beforeafter$]removeprefix[before]suffix[]addprefix<lastTab>] }}}>\n<$action-setfield $tiddler=<<__stateTitle__>> text=<<nextTab>>/>\n$actions$\n</$set>\n</$vars>\n</$set>\n\\end\n\n\\define keyboard-input-actions()\n<$list filter=\"[<__index__>match[]]\">\n<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>get<__field__>] }}}/>\n</$list>\n<$list filter=\"[<__index__>!match[]]\">\n<$action-setfield $tiddler=<<__storeTitle__>> text={{{ [<__tiddler__>getindex<__index__>] }}}/>\n</$list>\n\\end\n\n\\define input-next-actions-inner()\n<$list filter=\"[<nextItem>minlength[1]]\" variable=\"ignore\">\n<$action-setfield $tiddler=<<__selectionStateTitle__>> text=<<nextItem>>/>\n<$list filter=\"[<__index__>match[]]\">\n<$action-setfield $tiddler=<<__tiddler__>> $field=<<__field__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>\n</$list>\n<$list filter=\"[<__index__>!match[]]\">\n<$action-setfield $tiddler=<<__tiddler__>> $index=<<__index__>> $value={{{ [<nextItem>] +[splitregexp[(?:.(?!-))+$]] }}}/>\n</$list>\n<$action-setfield $tiddler=<<__refreshTitle__>> text=\"yes\"/>\n</$list>\n\\end\n\n\\define input-next-actions(afterOrBefore:\"after\",reverse:\"\")\n<$list filter=\"[<__storeTitle__>get[text]minlength<__filterMinLength__>] [<__filterMinLength__>match[0]] +[limit[1]]\" variable=\"ignore\">\n<$vars userInput={{{ [<__storeTitle__>get[text]] }}} selectedItem={{{ [<__selectionStateTitle__>get[text]] }}}>\n<$set name=\"configTiddler\" value={{{ [subfilter<__configTiddlerFilter__>] }}}>\n<$vars primaryListFilter={{{ [<configTiddler>get<__firstSearchFilterField__>] }}} secondaryListFilter={{{ [<configTiddler>get<__secondSearchFilterField__>] }}}>\n<$set name=\"filteredList\" filter=\"[subfilter<primaryListFilter>addsuffix[-primaryList]] =[subfilter<secondaryListFilter>addsuffix[-secondaryList]]\">\n<$vars nextItem={{{ [enlist<filteredList>$afterOrBefore$<selectedItem>] ~[enlist<filteredList>$reverse$nth[1]] }}} firstItem={{{ [enlist<filteredList>nth[1]] }}} lastItem={{{ [enlist<filteredList>last[]] }}}>\n<$list filter=\"[<selectedItem>match<firstItem>!match<lastItem>]\" variable=\"ignore\">\n<$set name=\"nextItem\" value={{{ [[$afterOrBefore$]match[before]then<userInput>addsuffix[-userInput]] ~[<nextItem>] }}}>\n<<input-next-actions-inner>>\n</$set>\n</$list>\n<$list filter=\"[<selectedItem>match<lastItem>!match<firstItem>]\" variable=\"ignore\">\n<$set name=\"nextItem\" value={{{ [[$afterOrBefore$]match[after]then<userInput>addsuffix[-userInput]] ~[<nextItem>] }}}>\n<<input-next-actions-inner>>\n</$set>\n</$list>\n<$list filter=\"[<selectedItem>match<firstItem>match<lastItem>]\" variable=\"ignore\">\n<$set name=\"nextItem\" value={{{ [<userInput>addsuffix[-userInput]] }}}>\n<<input-next-actions-inner>>\n</$set>\n</$list>\n<$list filter=\"[<selectedItem>!match<firstItem>!match<lastItem>]\" variable=\"ignore\">\n<<input-next-actions-inner>>\n</$list>\n</$vars>\n</$set>\n</$vars>\n</$set>\n</$vars>\n</$list>\n\\end\n\n\\define keyboard-driven-input(tiddler,storeTitle,field:\"text\",index:\"\",tag:\"input\",type,focus:\"\",inputAcceptActions,inputAcceptVariantActions,inputCancelActions,placeholder:\"\",default:\"\",class,focusPopup,rows,minHeight,tabindex,size,autoHeight,filterMinLength:\"0\",refreshTitle,selectionStateTitle,cancelPopups:\"\",configTiddlerFilter,firstSearchFilterField:\"first-search-filter\",secondSearchFilterField:\"second-search-filter\")\n\\whitespace trim\n<$keyboard key=\"((input-accept))\" actions=<<__inputAcceptActions__>>>\n<$keyboard key=\"((input-accept-variant))\" actions=<<__inputAcceptVariantActions__>>>\n<$keyboard key=\"((input-up))\" actions=<<input-next-actions \"before\" \"reverse[]\">>>\n<$keyboard key=\"((input-down))\" actions=<<input-next-actions>>>\n<$keyboard key=\"((input-cancel))\" actions=<<__inputCancelActions__>>>\n<$edit-text tiddler=<<__tiddler__>> field=<<__field__>> index=<<__index__>> \n\t\tinputActions=<<keyboard-input-actions>> tag=<<__tag__>> class=<<__class__>> \n\t\tplaceholder=<<__placeholder__>> default=<<__default__>> focusPopup=<<__focusPopup__>> \n\t\tfocus=<<__focus__>> type=<<__type__>> rows=<<__rows__>> minHeight=<<__minHeight__>> \n\t\ttabindex=<<__tabindex__>> size=<<__size__>> autoHeight=<<__autoHeight__>> \n\t\trefreshTitle=<<__refreshTitle__>> cancelPopups=<<__cancelPopups__>>/>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n</$keyboard>\n\\end\n"
},
"$:/core/macros/lingo": {
"title": "$:/core/macros/lingo",
"tags": "$:/tags/Macro",
"text": "\\define lingo-base()\n$:/language/\n\\end\n\n\\define lingo(title)\n{{$(lingo-base)$$title$}}\n\\end\n"
},
"$:/core/macros/list": {
"title": "$:/core/macros/list",
"tags": "$:/tags/Macro",
"text": "\\define list-links(filter,type:\"ul\",subtype:\"li\",class:\"\",emptyMessage)\n\\whitespace trim\n<$type$ class=\"$class$\">\n<$list filter=\"$filter$\" emptyMessage=<<__emptyMessage__>>>\n<$subtype$>\n<$link to={{!!title}}>\n<$transclude field=\"caption\">\n<$view field=\"title\"/>\n</$transclude>\n</$link>\n</$subtype$>\n</$list>\n</$type$>\n\\end\n\n\\define list-links-draggable-drop-actions()\n<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n\\end\n\n\\define list-links-draggable(tiddler,field:\"list\",type:\"ul\",subtype:\"li\",class:\"\",itemTemplate)\n\\whitespace trim\n<span class=\"tc-links-draggable-list\">\n<$vars targetTiddler=\"\"\"$tiddler$\"\"\" targetField=\"\"\"$field$\"\"\">\n<$type$ class=\"$class$\">\n<$list filter=\"[list[$tiddler$!!$field$]]\">\n<$droppable actions=<<list-links-draggable-drop-actions>> tag=\"\"\"$subtype$\"\"\" enable=<<tv-enable-drag-and-drop>>>\n<div class=\"tc-droppable-placeholder\"/>\n<div>\n<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n<$link to={{!!title}}>\n<$transclude field=\"caption\">\n<$view field=\"title\"/>\n</$transclude>\n</$link>\n</$transclude>\n</div>\n</$droppable>\n</$list>\n<$tiddler tiddler=\"\">\n<$droppable actions=<<list-links-draggable-drop-actions>> tag=\"div\" enable=<<tv-enable-drag-and-drop>>>\n<div class=\"tc-droppable-placeholder\">\n{{$:/core/images/blank}}\n</div>\n<div style=\"height:0.5em;\"/>\n</$droppable>\n</$tiddler>\n</$type$>\n</$vars>\n</span>\n\\end\n\n\\define list-tagged-draggable-drop-actions(tag)\n<!-- Save the current ordering of the tiddlers with this tag -->\n<$set name=\"order\" filter=\"[<__tag__>tagging[]]\">\n<!-- Remove any list-after or list-before fields from the tiddlers with this tag -->\n<$list filter=\"[<__tag__>tagging[]]\">\n<$action-deletefield $field=\"list-before\"/>\n<$action-deletefield $field=\"list-after\"/>\n</$list>\n<!-- Save the new order to the Tag Tiddler -->\n<$action-listops $tiddler=<<__tag__>> $field=\"list\" $filter=\"+[enlist<order>] +[insertbefore:currentTiddler<actionTiddler>]\"/>\n<!-- Make sure the newly added item has the right tag -->\n<!-- Removing this line makes dragging tags within the dropdown work as intended -->\n<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->\n<!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag -->\n<$list filter=\"[<actionTiddler>!contains:tags<__tag__>]\">\n<$fieldmangler tiddler=<<actionTiddler>>>\n<$action-sendmessage $message=\"tm-add-tag\" $param=<<__tag__>>/>\n</$fieldmangler>\n</$list>\n</$set>\n\\end\n\n\\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:\"div\",storyview:\"\")\n\\whitespace trim\n<span class=\"tc-tagged-draggable-list\">\n<$set name=\"tag\" value=<<__tag__>>>\n<$list filter=\"[<__tag__>tagging[]$subFilter$]\" emptyMessage=<<__emptyMessage__>> storyview=<<__storyview__>>>\n<$elementTag$ class=\"tc-menu-list-item\">\n<$droppable actions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\" enable=<<tv-enable-drag-and-drop>>>\n<$elementTag$ class=\"tc-droppable-placeholder\"/>\n<$elementTag$>\n<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</$transclude>\n</$elementTag$>\n</$droppable>\n</$elementTag$>\n</$list>\n<$tiddler tiddler=\"\">\n<$droppable actions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\" enable=<<tv-enable-drag-and-drop>>>\n<$elementTag$ class=\"tc-droppable-placeholder\"/>\n<$elementTag$ style=\"height:0.5em;\">\n</$elementTag$>\n</$droppable>\n</$tiddler>\n</$set>\n</span>\n\\end\n"
},
"$:/core/macros/tabs": {
"title": "$:/core/macros/tabs",
"tags": "$:/tags/Macro",
"text": "\\define tabs(tabsList,default,state:\"$:/state/tab\",class,template,buttonTemplate,retain,actions,explicitState)\n<$set name=\"qualifiedState\" value=<<qualify \"$state$\">>>\n<$vars tabsState={{{ [<__explicitState__>minlength[1]] ~[<qualifiedState>] }}}>\n<div class=\"tc-tab-set $class$\">\n<div class=\"tc-tab-buttons $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\" storyview=\"pop\"><$set name=\"save-currentTiddler\" value=<<currentTiddler>>><$tiddler tiddler=<<currentTab>>><$button set=<<tabsState>> setTo=<<currentTab>> default=\"$default$\" selectedClass=\"tc-tab-selected\" tooltip={{!!tooltip}}>\n<$tiddler tiddler=<<save-currentTiddler>>>\n<$set name=\"tv-wikilinks\" value=\"no\">\n<$transclude tiddler=\"$buttonTemplate$\" mode=\"inline\">\n<$transclude tiddler=<<currentTab>> field=\"caption\">\n<$macrocall $name=\"currentTab\" $type=\"text/plain\" $output=\"text/plain\"/>\n</$transclude>\n</$transclude>\n</$set></$tiddler>$actions$</$button></$tiddler></$set></$list>\n</div>\n<div class=\"tc-tab-divider $class$\"/>\n<div class=\"tc-tab-content $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\">\n\n<$reveal type=\"match\" state=<<tabsState>> text=<<currentTab>> default=\"$default$\" retain=\"\"\"$retain$\"\"\">\n\n<$transclude tiddler=\"$template$\" mode=\"block\">\n\n<$transclude tiddler=<<currentTab>> mode=\"block\"/>\n\n</$transclude>\n\n</$reveal>\n\n</$list>\n</div>\n</div>\n</$vars>\n</$set>\n\\end\n"
},
"$:/core/macros/tag-picker": {
"title": "$:/core/macros/tag-picker",
"tags": "$:/tags/Macro",
"first-search-filter": "[tags[]!is[system]search:title<userInput>sort[]]",
"second-search-filter": "[tags[]is[system]search:title<userInput>sort[]]",
"text": "\\define get-tagpicker-focus-selector() [data-tiddler-title=\"$(currentTiddlerCSSEscaped)$\"] .tc-add-tag-name input\n\n\\define delete-tag-state-tiddlers() <$action-deletetiddler $filter=\"[<newTagNameTiddler>] [<storeTitle>] [<tagSelectionState>]\"/>\n\n\\define add-tag-actions(actions,tagField:\"tags\")\n<$set name=\"tag\" value={{{ [<__tiddler__>get[text]] }}}>\n<$list filter=\"[<saveTiddler>!contains:$tagField$<tag>!match[]]\" variable=\"ignore\" emptyMessage=\"\"\"\n<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter=\"-[<tag>]\"/>\n\"\"\">\n<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter=\"[<tag>]\"/>\n$actions$\n</$list>\n</$set>\n<<delete-tag-state-tiddlers>>\n<$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n\\end\n\n\\define clear-tags-actions-inner()\n<$list filter=\"[<storeTitle>has[text]] [<newTagNameTiddler>has[text]]\" variable=\"ignore\" emptyMessage=\"\"\"<<cancel-delete-tiddler-actions \"cancel\">>\"\"\">\n<<delete-tag-state-tiddlers>>\n</$list>\n\\end\n\n\\define clear-tags-actions()\n<$set name=\"userInput\" value={{{ [<storeTitle>get[text]] }}}>\n<$list filter=\"[<newTagNameTiddler>get[text]!match<userInput>]\" emptyMessage=\"\"\"<<clear-tags-actions-inner>>\"\"\">\n<$action-setfield $tiddler=<<newTagNameTiddler>> text=<<userInput>>/><$action-setfield $tiddler=<<refreshTitle>> text=\"yes\"/>\n</$list>\n</$set>\n\\end\n\n\\define tag-picker-inner(actions,tagField:\"tags\")\n\\whitespace trim\n<$vars newTagNameInputTiddlerQualified=<<qualify \"$:/temp/NewTagName/input\">> newTagNameSelectionTiddlerQualified=<<qualify \"$:/temp/NewTagName/selected-item\">> fallbackTarget={{$(palette)$##tag-background}} colourA={{$(palette)$##foreground}} colourB={{$(palette)$##background}}>\n<$vars storeTitle={{{ [<newTagNameInputTiddler>!match[]] ~[<newTagNameInputTiddlerQualified>] }}} tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}>\n<$vars refreshTitle=<<qualify \"$:/temp/NewTagName/refresh\">> nonSystemTagsFilter=\"[tags[]!is[system]search:title<userInput>sort[]]\" systemTagsFilter=\"[tags[]is[system]search:title<userInput>sort[]]\">\n<div class=\"tc-edit-add-tag\">\n<div>\n<span class=\"tc-add-tag-name tc-small-gap-right\">\n<$macrocall $name=\"keyboard-driven-input\" tiddler=<<newTagNameTiddler>> storeTitle=<<storeTitle>> refreshTitle=<<refreshTitle>>\n\t\tselectionStateTitle=<<tagSelectionState>> inputAcceptActions=\"\"\"<$macrocall $name=\"add-tag-actions\" actions=<<__actions__>> tagField=<<__tagField__>>/>\"\"\"\n\t\tinputCancelActions=<<clear-tags-actions>> tag=\"input\" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}\n\t\tfocusPopup=<<qualify \"$:/state/popup/tags-auto-complete\">> class=\"tc-edit-texteditor tc-popup-handle\" tabindex=<<tabIndex>> \n\t\tfocus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}} filterMinLength={{$:/config/Tags/MinLength}} \n\t\tcancelPopups=<<cancelPopups>> configTiddlerFilter=\"[[$:/core/macros/tag-picker]]\"/>\n</span><$button popup=<<qualify \"$:/state/popup/tags-auto-complete\">> class=\"tc-btn-invisible tc-btn-dropdown\" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button><$reveal state=<<storeTitle>> type=\"nomatch\" text=\"\"><$button class=\"tc-btn-invisible tc-small-gap tc-btn-dropdown\" tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}} aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}>{{$:/core/images/close-button}}<<delete-tag-state-tiddlers>></$button></$reveal><span class=\"tc-add-tag-button tc-small-gap-left\">\n<$set name=\"tag\" value={{{ [<newTagNameTiddler>get[text]] }}}>\n<$button set=<<newTagNameTiddler>> setTo=\"\" class=\"\">\n<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter=\"[<tag>]\"/>\n$actions$\n<$set name=\"currentTiddlerCSSEscaped\" value={{{ [<saveTiddler>escapecss[]] }}}>\n<<delete-tag-state-tiddlers>><$action-sendmessage $message=\"tm-focus-selector\" $param=<<get-tagpicker-focus-selector>>/>\n</$set>\n{{$:/language/EditTemplate/Tags/Add/Button}}\n</$button>\n</$set>\n</span>\n</div>\n<div class=\"tc-block-dropdown-wrapper\">\n<$reveal state=<<qualify \"$:/state/popup/tags-auto-complete\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-block-tags-dropdown\">\n<$set name=\"userInput\" value={{{ [<storeTitle>get[text]] }}}>\n<$list filter=\"[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$list filter=<<nonSystemTagsFilter>> variable=\"tag\">\n<$list filter=\"[<tag>addsuffix[-primaryList]] -[<tagSelectionState>get[text]]\" emptyMessage=\"\"\"<$vars button-classes=\"tc-btn-invisible tc-tag-button-selected\" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>\"\"\">\n<$vars button-classes=\"tc-btn-invisible\" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>\n</$list>\n</$list></$list>\n<hr>\n<$list filter=\"[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$list filter=<<systemTagsFilter>> variable=\"tag\">\n<$list filter=\"[<tag>addsuffix[-secondaryList]] -[<tagSelectionState>get[text]]\" emptyMessage=\"\"\"<$vars button-classes=\"tc-btn-invisible tc-tag-button-selected\" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>\"\"\">\n<$vars button-classes=\"tc-btn-invisible\" actions=<<__actions__>> tagField=<<__tagField__>> currentTiddler=<<tag>>>{{||$:/core/ui/TagPickerTagTemplate}}</$vars>\n</$list>\n</$list></$list>\n</$set>\n</div>\n</$reveal>\n</div>\n</div>\n</$vars>\n</$vars>\n</$vars>\n\\end\n\\define tag-picker(actions,tagField:\"tags\")\n\\whitespace trim\n<$vars saveTiddler=<<currentTiddler>> palette={{$:/palette}}>\n<$list filter=\"[<newTagNameTiddler>match[]]\" emptyMessage=\"\"\"<$macrocall $name=\"tag-picker-inner\" actions=<<__actions__>> tagField=<<__tagField__>>/>\"\"\">\n<$set name=\"newTagNameTiddler\" value=<<qualify \"$:/temp/NewTagName\">>>\n<$macrocall $name=\"tag-picker-inner\" actions=<<__actions__>> tagField=<<__tagField__>>/>\n</$set>\n</$list>\n</$vars>\n\\end\n"
},
"$:/core/macros/tag": {
"title": "$:/core/macros/tag",
"tags": "$:/tags/Macro",
"text": "\\define tag-pill-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n\\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions)\n<$vars foregroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">> backgroundColor=\"\"\"$colour$\"\"\">\n<$element-tag$ $element-attributes$ class=\"tc-tag-label tc-btn-invisible\" style=<<tag-pill-styles>>>\n$actions$<$transclude tiddler=\"\"\"$icon$\"\"\"/><$view tiddler=<<__tag__>> field=\"title\" format=\"text\" />\n</$element-tag$>\n</$vars>\n\\end\n\n\\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)\n<$macrocall $name=\"tag-pill-inner\" tag=<<__tag__>> icon=\"\"\"$icon$\"\"\" colour=\"\"\"$colour$\"\"\" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag=\"\"\"$element-tag$\"\"\" element-attributes=\"\"\"$element-attributes$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n\\end\n\n\\define tag-pill(tag,element-tag:\"span\",element-attributes:\"\",actions:\"\")\n<span class=\"tc-tag-list-item\">\n<$macrocall $name=\"tag-pill-body\" tag=<<__tag__>> icon={{{ [<__tag__>get[icon]] }}} colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag=\"\"\"$element-tag$\"\"\" element-attributes=\"\"\"$element-attributes$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</span>\n\\end\n\n\\define tag(tag)\n{{$tag$||$:/core/ui/TagTemplate}}\n\\end\n"
},
"$:/core/macros/thumbnails": {
"title": "$:/core/macros/thumbnails",
"tags": "$:/tags/Macro",
"text": "\\define thumbnail(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<$link to=\"\"\"$link$\"\"\"><div class=\"tc-thumbnail-wrapper\">\n<div class=\"tc-thumbnail-image\" style=\"width:$width$px;height:$height$px;\"><$reveal type=\"nomatch\" text=\"\" default=\"\"\"$image$\"\"\" tag=\"div\" style=\"width:$width$px;height:$height$px;\">\n[img[$image$]]\n</$reveal><$reveal type=\"match\" text=\"\" default=\"\"\"$image$\"\"\" tag=\"div\" class=\"tc-thumbnail-background\" style=\"width:$width$px;height:$height$px;background-color:$background-color$;\"></$reveal></div><div class=\"tc-thumbnail-icon\" style=\"fill:$color$;color:$color$;\">\n$icon$\n</div><div class=\"tc-thumbnail-caption\">\n$caption$\n</div>\n</div></$link>\n\\end\n\n\\define thumbnail-right(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<div class=\"tc-thumbnail-right-wrapper\"><<thumbnail \"\"\"$link$\"\"\" \"\"\"$icon$\"\"\" \"\"\"$color$\"\"\" \"\"\"$background-color$\"\"\" \"\"\"$image$\"\"\" \"\"\"$caption$\"\"\" \"\"\"$width$\"\"\" \"\"\"$height$\"\"\">></div>\n\\end\n\n\\define list-thumbnails(filter,width:\"280\",height:\"157\")\n<$list filter=\"\"\"$filter$\"\"\"><$macrocall $name=\"thumbnail\" link={{!!link}} icon={{!!icon}} color={{!!color}} background-color={{!!background-color}} image={{!!image}} caption={{!!caption}} width=\"\"\"$width$\"\"\" height=\"\"\"$height$\"\"\"/></$list>\n\\end\n"
},
"$:/core/macros/timeline": {
"title": "$:/core/macros/timeline",
"created": "20141212105914482",
"modified": "20141212110330815",
"tags": "$:/tags/Macro",
"text": "\\define timeline-title()\n\\whitespace trim\n<!-- Override this macro with a global macro \n of the same name if you need to change \n how titles are displayed on the timeline \n -->\n<$view field=\"title\"/>\n\\end\n\\define timeline(limit:\"100\",format:\"DDth MMM YYYY\",subfilter:\"\",dateField:\"modified\")\n<div class=\"tc-timeline\">\n<$list filter=\"[!is[system]$subfilter$has[$dateField$]!sort[$dateField$]limit[$limit$]eachday[$dateField$]]\">\n<div class=\"tc-menu-list-item\">\n<$view field=\"$dateField$\" format=\"date\" template=\"$format$\"/>\n<$list filter=\"[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}><<timeline-title>></$link>\n</div>\n</$list>\n</div>\n</$list>\n</div>\n\\end\n"
},
"$:/core/macros/toc": {
"title": "$:/core/macros/toc",
"tags": "$:/tags/Macro",
"text": "\\define toc-caption()\n<$set name=\"tv-wikilinks\" value=\"no\">\n <$transclude field=\"caption\">\n <$view field=\"title\"/>\n </$transclude>\n</$set>\n\\end\n\n\\define toc-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<ol class=\"tc-toc\">\n <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n <$vars item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n <$set name=\"excluded\" filter=\"\"\"[enlist<__exclude__>] [<__tag__>]\"\"\">\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n <li class=<<toc-item-class>>>\n <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=\"<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><$view field='caption'><$view field='title'/></$view></$link>\">\n <<toc-caption>>\n </$list>\n <$macrocall $name=\"toc-body\" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n </li>\n </$set>\n </$set>\n </$vars>\n </$list>\n</ol>\n\\end\n\n\\define toc(tag,sort:\"\",itemClassFilter:\"\")\n<$macrocall $name=\"toc-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> />\n\\end\n\n\\define toc-linked-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n <li class=<<toc-item-class>>>\n <$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n </$button>\n </$reveal>\n <<toc-caption>>\n </$link>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n <li class=<<toc-item-class>>>\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-expandable-empty-message()\n<$macrocall $name=\"toc-linked-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-expandable(tag,sort:\"\",itemClassFilter:\"\",exclude,path)\n<$vars tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n <$set name=\"excluded\" filter=\"\"\"[enlist<__exclude__>] [<__tag__>]\"\"\">\n <ol class=\"tc-toc toc-expandable\">\n <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=<<toc-expandable-empty-message>> >\n <$macrocall $name=\"toc-unlinked-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"\"\"itemClassFilter\"\"\" exclude=<<excluded>> path=<<path>> />\n </$list>\n </$list>\n </ol>\n </$set>\n</$vars>\n\\end\n\n\\define toc-linked-selective-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\" >\n <li class=<<toc-item-class>>>\n <$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>\n <$list filter=\"[all[current]tagging[]$sort$limit[1]]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button>\">\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n </$button>\n </$reveal>\n </$list>\n <<toc-caption>>\n </$link>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-selective-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item-selected\" value=\"toc-item\">\n <li class=<<toc-item-class>>>\n <$list filter=\"[all[current]tagging[]$sort$limit[1]]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button> <$view field='caption'><$view field='title'/></$view>\">\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n </$list>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-selective-expandable-empty-message()\n<$macrocall $name=\"toc-linked-selective-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-selective-expandable(tag,sort:\"\",itemClassFilter,exclude,path)\n<$vars tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n <$set name=\"excluded\" filter=\"\"\"[enlist<__exclude__>] [<__tag__>]\"\"\">\n <ol class=\"tc-toc toc-selective-expandable\">\n <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n <$list filter=\"[all[current]toc-link[no]]\" variable=\"ignore\" emptyMessage=<<toc-selective-expandable-empty-message>> >\n <$macrocall $name=\"toc-unlinked-selective-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n </$list>\n </$list>\n </ol>\n </$set>\n</$vars>\n\\end\n\n\\define toc-tabbed-external-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\")\n<$tiddler tiddler={{{ [<__selectedTiddler__>get[text]] }}}>\n <div class=\"tc-tabbed-table-of-contents\">\n <$linkcatcher to=<<__selectedTiddler__>>>\n <div class=\"tc-table-of-contents\">\n <$macrocall $name=\"toc-selective-expandable\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"[all[current]] -[<__selectedTiddler__>get[text]]\"/>\n </div>\n </$linkcatcher>\n <div class=\"tc-tabbed-table-of-contents-content\">\n <$reveal stateTitle=<<__selectedTiddler__>> type=\"nomatch\" text=\"\">\n <$transclude mode=\"block\" tiddler=<<__template__>>>\n <h1><<toc-caption>></h1>\n <$transclude mode=\"block\">$missingText$</$transclude>\n </$transclude>\n </$reveal>\n <$reveal stateTitle=<<__selectedTiddler__>> type=\"match\" text=\"\">\n $unselectedText$\n </$reveal>\n </div>\n </div>\n</$tiddler>\n\\end\n\n\\define toc-tabbed-internal-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\")\n<$linkcatcher to=<<__selectedTiddler__>>>\n <$macrocall $name=\"toc-tabbed-external-nav\" tag=<<__tag__>> sort=<<__sort__>> selectedTiddler=<<__selectedTiddler__>> unselectedText=<<__unselectedText__>> missingText=<<__missingText__>> template=<<__template__>>/>\n</$linkcatcher>\n\\end\n\n"
},
"$:/core/macros/translink": {
"title": "$:/core/macros/translink",
"tags": "$:/tags/Macro",
"text": "\\define translink(title,mode:\"block\")\n<div style=\"border:1px solid #ccc; padding: 0.5em; background: black; foreground; white;\">\n<$link to=\"\"\"$title$\"\"\">\n<$text text=\"\"\"$title$\"\"\"/>\n</$link>\n<div style=\"border:1px solid #ccc; padding: 0.5em; background: white; foreground; black;\">\n<$transclude tiddler=\"\"\"$title$\"\"\" mode=\"$mode$\">\n\"<$text text=\"\"\"$title$\"\"\"/>\" is missing\n</$transclude>\n</div>\n</div>\n\\end\n"
},
"$:/core/macros/tree": {
"title": "$:/core/macros/tree",
"tags": "$:/tags/Macro",
"text": "\\define leaf-link(full-title,chunk,separator: \"/\")\n<$link to=<<__full-title__>>><$text text=<<__chunk__>>/></$link>\n\\end\n\n\\define leaf-node(prefix,chunk)\n<li>\n<$list filter=\"[<__prefix__>addsuffix<__chunk__>is[shadow]] [<__prefix__>addsuffix<__chunk__>is[tiddler]]\" variable=\"full-title\">\n<$list filter=\"[<full-title>removeprefix<__prefix__>]\" variable=\"chunk\">\n<span>{{$:/core/images/file}}</span> <$macrocall $name=\"leaf-link\" full-title=<<full-title>> chunk=<<chunk>>/>\n</$list>\n</$list>\n</li>\n\\end\n\n\\define branch-node(prefix,chunk,separator: \"/\")\n<li>\n<$set name=\"reveal-state\" value={{{ [[$:/state/tree/]addsuffix<__prefix__>addsuffix<__chunk__>] }}}>\n<$reveal type=\"nomatch\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"show\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}} <$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"hide\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}} <$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<span>(<$count filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>removeprefix<__chunk__>] -[<__prefix__>addsuffix<__chunk__>]\"/>)</span>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$macrocall $name=\"tree-node\" prefix={{{ [<__prefix__>addsuffix<__chunk__>] }}} separator=<<__separator__>>/>\n</$reveal>\n</$set>\n</li>\n\\end\n\n\\define tree-node(prefix,separator: \"/\")\n<ol>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore<__separator__>sort[]!suffix<__separator__>]\" variable=\"chunk\">\n<$macrocall $name=\"leaf-node\" prefix=<<__prefix__>> chunk=<<chunk>> separator=<<__separator__>>/>\n</$list>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore<__separator__>sort[]suffix<__separator__>]\" variable=\"chunk\">\n<$macrocall $name=\"branch-node\" prefix=<<__prefix__>> chunk=<<chunk>> separator=<<__separator__>>/>\n</$list>\n</ol>\n\\end\n\n\\define tree(prefix: \"$:/\",separator: \"/\")\n<div class=\"tc-tree\">\n<span><$text text=<<__prefix__>>/></span>\n<div>\n<$macrocall $name=\"tree-node\" prefix=<<__prefix__>> separator=<<__separator__>>/>\n</div>\n</div>\n\\end\n"
},
"$:/core/macros/utils": {
"title": "$:/core/macros/utils",
"text": "\\define colour(colour)\n$colour$\n\\end\n"
},
"$:/snippets/minifocusswitcher": {
"title": "$:/snippets/minifocusswitcher",
"text": "<$select tiddler=\"$:/config/AutoFocus\">\n<$list filter=\"title tags text type fields\">\n<option value=<<currentTiddler>>><<currentTiddler>></option>\n</$list>\n</$select>\n"
},
"$:/snippets/minilanguageswitcher": {
"title": "$:/snippets/minilanguageswitcher",
"text": "<$select tiddler=\"$:/language\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"description\"><$view field=\"name\"><$view field=\"title\"/></$view></$view></option>\n</$list>\n</$select>"
},
"$:/snippets/minithemeswitcher": {
"title": "$:/snippets/minithemeswitcher",
"text": "\\define lingo-base() $:/language/ControlPanel/Theme/\n<<lingo Prompt>> <$select tiddler=\"$:/theme\">\n<$list filter=\"[plugin-type[theme]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"name\"><$view field=\"title\"/></$view></option>\n</$list>\n</$select>"
},
"$:/snippets/modules": {
"title": "$:/snippets/modules",
"text": "\\define describeModuleType(type)\n{{$:/language/Docs/ModuleTypes/$type$}}\n\\end\n<$list filter=\"[moduletypes[]]\">\n\n!! <$macrocall $name=\"currentTiddler\" $type=\"text/plain\" $output=\"text/plain\"/>\n\n<$macrocall $name=\"describeModuleType\" type=<<currentTiddler>>/>\n\n<ul><$list filter=\"[all[current]modules[]]\"><li><$link><<currentTiddler>></$link>\n</li>\n</$list>\n</ul>\n</$list>\n"
},
"$:/palette": {
"title": "$:/palette",
"text": "$:/palettes/Vanilla"
},
"$:/snippets/paletteeditor": {
"title": "$:/snippets/paletteeditor",
"text": "<$transclude tiddler=\"$:/PaletteManager\"/>\n"
},
"$:/snippets/palettepreview": {
"title": "$:/snippets/palettepreview",
"text": "<$set name=\"currentTiddler\" value={{$:/palette}}>\n{{||$:/snippets/currpalettepreview}}\n</$set>\n"
},
"$:/snippets/paletteswitcher": {
"title": "$:/snippets/paletteswitcher",
"text": "<$linkcatcher to=\"$:/palette\">\n<div class=\"tc-chooser\"><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Palette]sort[name]]\"><$set name=\"cls\" filter=\"[all[current]prefix{$:/palette}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$view field=\"name\" format=\"text\"/>'' - <$view field=\"description\" format=\"text\"/>{{||$:/snippets/currpalettepreview}}</$link>\n</div></$set>\n</$list>\n</div>\n</$linkcatcher>\n"
},
"$:/snippets/peek-stylesheets": {
"title": "$:/snippets/peek-stylesheets",
"text": "\\define expandable-stylesheets-list()\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$vars state=<<qualify \"$:/state/peek-stylesheets/open/\">>>\n<$set name=\"state\" value={{{ [<state>addsuffix<currentTiddler>] }}}>\n<li>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"no\" class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"yes\" class=\"tc-btn-invisible\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"div\">\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</$reveal>\n</li>\n</$set>\n</$vars>\n</$list>\n</ol>\n\\end\n\n\\define stylesheets-list()\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<li>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</li>\n</$list>\n</ol>\n\\end\n\n<$vars modeState=<<qualify \"$:/state/peek-stylesheets/mode/\">>>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"expanded\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Stylesheets/Expand/Caption}}</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"restored\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-down}} {{$:/language/ControlPanel/Stylesheets/Restore/Caption}}</$button>\n</$reveal>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<expandable-stylesheets-list>>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<stylesheets-list>>\n</$reveal>\n\n</$vars>\n"
},
"$:/temp/search": {
"title": "$:/temp/search",
"text": ""
},
"$:/tags/AdvancedSearch": {
"title": "$:/tags/AdvancedSearch",
"list": "[[$:/core/ui/AdvancedSearch/Standard]] [[$:/core/ui/AdvancedSearch/System]] [[$:/core/ui/AdvancedSearch/Shadows]] [[$:/core/ui/AdvancedSearch/Filter]]"
},
"$:/tags/AdvancedSearch/FilterButton": {
"title": "$:/tags/AdvancedSearch/FilterButton",
"list": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown $:/core/ui/AdvancedSearch/Filter/FilterButtons/clear $:/core/ui/AdvancedSearch/Filter/FilterButtons/export $:/core/ui/AdvancedSearch/Filter/FilterButtons/delete"
},
"$:/tags/ControlPanel": {
"title": "$:/tags/ControlPanel",
"list": "$:/core/ui/ControlPanel/Info $:/core/ui/ControlPanel/Appearance $:/core/ui/ControlPanel/Settings $:/core/ui/ControlPanel/Saving $:/core/ui/ControlPanel/Plugins $:/core/ui/ControlPanel/Tools $:/core/ui/ControlPanel/Internals"
},
"$:/tags/ControlPanel/Info": {
"title": "$:/tags/ControlPanel/Info",
"list": "$:/core/ui/ControlPanel/Basics $:/core/ui/ControlPanel/Advanced"
},
"$:/tags/ControlPanel/Plugins": {
"title": "$:/tags/ControlPanel/Plugins",
"list": "[[$:/core/ui/ControlPanel/Plugins/Installed]] [[$:/core/ui/ControlPanel/Plugins/Add]]"
},
"$:/tags/EditTemplate": {
"title": "$:/tags/EditTemplate",
"list": "[[$:/core/ui/EditTemplate/controls]] [[$:/core/ui/EditTemplate/title]] [[$:/core/ui/EditTemplate/tags]] [[$:/core/ui/EditTemplate/shadow]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/EditTemplate/body]] [[$:/core/ui/EditTemplate/type]] [[$:/core/ui/EditTemplate/fields]]"
},
"$:/tags/EditToolbar": {
"title": "$:/tags/EditToolbar",
"list": "[[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/cancel]] [[$:/core/ui/Buttons/save]]"
},
"$:/tags/EditorToolbar": {
"title": "$:/tags/EditorToolbar",
"list": "$:/core/ui/EditorToolbar/paint $:/core/ui/EditorToolbar/opacity $:/core/ui/EditorToolbar/line-width $:/core/ui/EditorToolbar/rotate-left $:/core/ui/EditorToolbar/clear $:/core/ui/EditorToolbar/bold $:/core/ui/EditorToolbar/italic $:/core/ui/EditorToolbar/strikethrough $:/core/ui/EditorToolbar/underline $:/core/ui/EditorToolbar/superscript $:/core/ui/EditorToolbar/subscript $:/core/ui/EditorToolbar/mono-line $:/core/ui/EditorToolbar/mono-block $:/core/ui/EditorToolbar/quote $:/core/ui/EditorToolbar/list-bullet $:/core/ui/EditorToolbar/list-number $:/core/ui/EditorToolbar/heading-1 $:/core/ui/EditorToolbar/heading-2 $:/core/ui/EditorToolbar/heading-3 $:/core/ui/EditorToolbar/heading-4 $:/core/ui/EditorToolbar/heading-5 $:/core/ui/EditorToolbar/heading-6 $:/core/ui/EditorToolbar/link $:/core/ui/EditorToolbar/excise $:/core/ui/EditorToolbar/picture $:/core/ui/EditorToolbar/stamp $:/core/ui/EditorToolbar/size $:/core/ui/EditorToolbar/editor-height $:/core/ui/EditorToolbar/more $:/core/ui/EditorToolbar/preview $:/core/ui/EditorToolbar/preview-type"
},
"$:/tags/Manager/ItemMain": {
"title": "$:/tags/Manager/ItemMain",
"list": "$:/Manager/ItemMain/WikifiedText $:/Manager/ItemMain/RawText $:/Manager/ItemMain/Fields"
},
"$:/tags/Manager/ItemSidebar": {
"title": "$:/tags/Manager/ItemSidebar",
"list": "$:/Manager/ItemSidebar/Tags $:/Manager/ItemSidebar/Colour $:/Manager/ItemSidebar/Icon $:/Manager/ItemSidebar/Tools"
},
"$:/tags/MoreSideBar": {
"title": "$:/tags/MoreSideBar",
"list": "[[$:/core/ui/MoreSideBar/All]] [[$:/core/ui/MoreSideBar/Recent]] [[$:/core/ui/MoreSideBar/Tags]] [[$:/core/ui/MoreSideBar/Missing]] [[$:/core/ui/MoreSideBar/Drafts]] [[$:/core/ui/MoreSideBar/Orphans]] [[$:/core/ui/MoreSideBar/Types]] [[$:/core/ui/MoreSideBar/System]] [[$:/core/ui/MoreSideBar/Shadows]] [[$:/core/ui/MoreSideBar/Explorer]] [[$:/core/ui/MoreSideBar/Plugins]]",
"text": ""
},
"$:/tags/PageControls": {
"title": "$:/tags/PageControls",
"list": "[[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]"
},
"$:/tags/PageTemplate": {
"title": "$:/tags/PageTemplate",
"list": "[[$:/core/ui/PageTemplate/topleftbar]] [[$:/core/ui/PageTemplate/toprightbar]] [[$:/core/ui/PageTemplate/sidebar]] [[$:/core/ui/PageTemplate/story]] [[$:/core/ui/PageTemplate/alerts]]",
"text": ""
},
"$:/tags/PluginLibrary": {
"title": "$:/tags/PluginLibrary",
"list": "$:/config/OfficialPluginLibrary"
},
"$:/tags/SideBar": {
"title": "$:/tags/SideBar",
"list": "[[$:/core/ui/SideBar/Open]] [[$:/core/ui/SideBar/Recent]] [[$:/core/ui/SideBar/Tools]] [[$:/core/ui/SideBar/More]]",
"text": ""
},
"$:/tags/SideBarSegment": {
"title": "$:/tags/SideBarSegment",
"list": "[[$:/core/ui/SideBarSegments/site-title]] [[$:/core/ui/SideBarSegments/site-subtitle]] [[$:/core/ui/SideBarSegments/page-controls]] [[$:/core/ui/SideBarSegments/search]] [[$:/core/ui/SideBarSegments/tabs]]"
},
"$:/tags/TiddlerInfo": {
"title": "$:/tags/TiddlerInfo",
"list": "[[$:/core/ui/TiddlerInfo/Tools]] [[$:/core/ui/TiddlerInfo/References]] [[$:/core/ui/TiddlerInfo/Tagging]] [[$:/core/ui/TiddlerInfo/List]] [[$:/core/ui/TiddlerInfo/Listed]] [[$:/core/ui/TiddlerInfo/Fields]]",
"text": ""
},
"$:/tags/TiddlerInfo/Advanced": {
"title": "$:/tags/TiddlerInfo/Advanced",
"list": "[[$:/core/ui/TiddlerInfo/Advanced/ShadowInfo]] [[$:/core/ui/TiddlerInfo/Advanced/PluginInfo]]"
},
"$:/tags/ViewTemplate": {
"title": "$:/tags/ViewTemplate",
"list": "[[$:/core/ui/ViewTemplate/title]] [[$:/core/ui/ViewTemplate/unfold]] [[$:/core/ui/ViewTemplate/subtitle]] [[$:/core/ui/ViewTemplate/tags]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/ViewTemplate/body]]"
},
"$:/tags/ViewToolbar": {
"title": "$:/tags/ViewToolbar",
"list": "[[$:/core/ui/Buttons/more-tiddler-actions]] [[$:/core/ui/Buttons/info]] [[$:/core/ui/Buttons/new-here]] [[$:/core/ui/Buttons/new-journal-here]] [[$:/core/ui/Buttons/clone]] [[$:/core/ui/Buttons/export-tiddler]] [[$:/core/ui/Buttons/edit]] [[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/permalink]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/open-window]] [[$:/core/ui/Buttons/close-others]] [[$:/core/ui/Buttons/close]] [[$:/core/ui/Buttons/fold-others]] [[$:/core/ui/Buttons/fold]]"
},
"$:/snippets/themeswitcher": {
"title": "$:/snippets/themeswitcher",
"text": "<$linkcatcher to=\"$:/theme\">\n<div class=\"tc-chooser\"><$list filter=\"[plugin-type[theme]sort[title]]\"><$set name=\"cls\" filter=\"[all[current]field:title{$:/theme}] [[$:/theme]!has[text]addsuffix[s/tiddlywiki/vanilla]field:title<currentTiddler>] +[limit[1]]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$view field=\"name\" format=\"text\"/>'' <$view field=\"description\" format=\"text\"/></$link></div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
},
"$:/core/wiki/title": {
"title": "$:/core/wiki/title",
"text": "{{$:/SiteTitle}} --- {{$:/SiteSubtitle}}"
},
"$:/view": {
"title": "$:/view",
"text": "classic"
},
"$:/snippets/viewswitcher": {
"title": "$:/snippets/viewswitcher",
"text": "\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<$linkcatcher to=\"$:/view\">\n<div class=\"tc-chooser tc-viewswitcher\">\n<$list filter=\"[storyviews[]]\" variable=\"storyview\">\n<$set name=\"cls\" filter=\"[<storyview>prefix{$:/view}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link to=<<storyview>>><$transclude tiddler=<<icon>>/><$text text=<<storyview>>/></$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
}
}
}
/*\
title: $:/core/modules/filters/has.js
type: application/javascript
module-type: filteroperator
Filter operator for checking if a tiddler has the specified field
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.has = function(source,operator,options) {
var results = [],
invert = operator.prefix === "!";
if(operator.suffix === "field") {
if(invert) {
source(function(tiddler,title) {
if(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand)))) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand)) {
results.push(title);
}
});
}
} else {
if(invert) {
source(function(tiddler,title) {
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === "") || (tiddler.fields[operator.operand].length === 0)) {
results.push(title);
}
});
} else {
source(function(tiddler,title) {
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
results.push(title);
}
});
}
}
return results;
};
})();
\whitespace trim
<$reveal type="nomatch" stateTitle=<<folded-state>> text="hide" default="show">
<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=<<tv-config-toolbar-class>>>
<$action-sendmessage $message="tm-fold-tiddler" $param=<<currentTiddler>> foldedState=<<folded-state>>/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]" variable="listItem">
{{$:/core/images/fold-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text">
<$text text=" "/>
<$text text={{$:/language/Buttons/Fold/Caption}}/>
</span>
</$list>
</$button>
</$reveal>
<$reveal type="match" stateTitle=<<folded-state>> text="hide" default="show">
<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=<<tv-config-toolbar-class>>>
<$action-sendmessage $message="tm-fold-tiddler" $param=<<currentTiddler>> foldedState=<<folded-state>>/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]" variable="listItem">
{{$:/core/images/unfold-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text">
<$text text=" "/>
<$text text={{$:/language/Buttons/Unfold/Caption}}/>
</span>
</$list>
</$button>
</$reveal>
{{$:/snippets/viewswitcher}}
\define title-styles()
fill:$(foregroundColor)$;
\end
\define config-title()
$:/config/ViewToolbarButtons/Visibility/$(listItem)$
\end
<div class="tc-tiddler-title">
<div class="tc-titlebar">
<span class="tc-tiddler-controls">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]" variable="listItem"><$reveal type="nomatch" state=<<config-title>> text="hide"><$set name="tv-config-toolbar-class" filter="[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>
</span>
<$set name="tv-wikilinks" value={{$:/config/Tiddlers/TitleLinks}}>
<$link>
<$set name="foregroundColor" value={{!!color}}>
<span class="tc-tiddler-title-icon" style=<<title-styles>>>
<$transclude tiddler={{!!icon}}/>
</span>
</$set>
<$list filter="[all[current]removeprefix[$:/]]">
<h2 class="tc-title" title={{$:/language/SystemTiddler/Tooltip}}>
<span class="tc-system-title-prefix">$:/</span><$text text=<<currentTiddler>>/>
</h2>
</$list>
<$list filter="[all[current]!prefix[$:/]]">
<h2 class="tc-title">
<$view field="title"/>
</h2>
</$list>
</$link>
</$set>
</div>
<$reveal type="nomatch" text="" default="" state=<<tiddlerInfoState>> class="tc-tiddler-info tc-popup-handle" animate="yes" retain="yes">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]" variable="listItem"><$transclude tiddler=<<listItem>> mode="block"/></$list>
</$reveal>
</div>
[[todo]]
[tag[task]]
[[散文]]
[[短篇小说]]
[[中篇小说]]
下列条目已被导入:
# [[[冻结时间的疫情国家]]
# [[《喂自己影子吃饭的人》-阿根廷著名作家莱昂尼达斯·巴尔莱塔]]
# [[《地火》刘慈欣]]
# [[《没人说一句话》]]
# [[《罗曼蒂克消亡史》]]
# [[《趁生命气息逗留》--罗杰·泽拉兹尼]]
# [[【写作技术】多种结构的选择与搭建]]
# [[<星>阿瑟•克拉克]]
# [[20180125 子弹笔术 - 三个技巧把一件事情讲清楚 - 幕布]]
# [[2021 / 01 / 13 / 16:12:01 /]]
# [[2021 / 01 / 13 / 16:14:34 /]]
# [[2021 / 01 / 13 / 16:22:17 /]]
# [[2021 / 01 / 13 / 16:33:19 /]]
# [[2021 / 01 / 13 / 17:27:14 /]]
# [[2021 / 01 / 14 / 17:26:09 /]]
# [[2021 / 01 / 14 / 17:28:24 /]]
# [[2021 / 01 / 14 / 17:29:31 /]]
# [[2021 / 01 / 14 / 17:30:57 /]]
# [[2021 / 01 / 14 / 17:31:29 /]]
# [[2021 / 01 / 14 / 17:32:12 /]]
# [[2021 / 01 / 14 / 17:41:22 /]]
# [[2021 / 01 / 14 / 17:44:29 /]]
# [[2021 / 01 / 14 / 17:45:17 /]]
# [[2021 / 01 / 14 / 19:04:06 /]]
# [[2021 / 01 / 14 / 19:09:14 /]]
# [[2021 / 01 / 14 / 19:14:18 /]]
# [[2021 / 01 / 14 / 19:32:32 /]]
# [[2021 / 01 / 15 / 08:32:14 /]]
# [[2021 / 01 / 15 / 08:35:07 /]]
# [[2021 / 01 / 15 / 14:42:44 /]]
# [[2021 / 01 / 15 / 15:05:37 /]]
# [[2021 / 01 / 15 / 16:28:04 /]]
# [[2021 / 01 / 15 / 16:30:00 /]]
# [[2021 / 01 / 16 / 14:13:46 /]]
# [[2021 / 01 / 18 / 12:20:03 /]]
# [[2021 / 01 / 18 / 12:51:22 /]]
# [[2021 / 01 / 18 / 13:10:50 /]]
# [[2021 / 01 / 23 / 18:26:35 /]]
# [[2021 / 01 / 26 / 07:58:38 /]]
# [[2021 / 01 / 26 / 10:59:57 /]]
# [[2021 / 01 / 29 / 09:34:23 /]]
# [[2021 / 01 / 29 / 19:07:28 /]]
# [[2021 / 02 / 03 / 10:57:06 /]]
# [[2021 / 02 / 03 / 19:21:21 /]]
# [[2021 / 02 / 05 / 12:08:05 /]]
# [[2021 / 02 / 05 / 16:17:34 /]]
# [[2021 / 02 / 05 / 19:12:08 /]]
# [[2021 / 02 / 06 / 10:32:34 /]]
# [[20210109深耕散文课旁听笔记]]
# [[Adding a table of contents to the sidebar]]
# [[All my indexes]]
# [[All my tags]]
# [[APrincessofMars]]
# [[arm cpu 基板]]
# [[Autocompletion]]
# [[AutoHotkey]]
# [[Bookmarking with TidMarks]]
# [[CodeMirror]]
# [[Dashes in WikiText]]
# [[Definitions in WikiText]]
# [[Draft 2 of '2021 / 01 / 23 / 18:26:35 /']]
# [[Draft of '[冻结时间的疫情国家']]
# [[Draft of '2021 / 01 / 18 / 13:10:40 /']]
# [[Draft of '2021 / 01 / 18 / 13:10:50 /']]
# [[Draft of '2021 / 01 / 18 / 13:11:55 /']]
# [[Draft of '2021 / 01 / 23 / 18:26:35 /']]
# [[Draft of '发出噪音的电单车']]
# [[Draft of '用积蓄修路墩']]
# [[Draft of '路墩像人生跨不过的坎']]
# [[EdgarRiceBurroughs]]
# [[Evernote Import Report]]
# [[FileLocator]]
# [[Fleeting Notes 临时笔记]]
# [[FlyFishing]]
# [[FlyRod]]
# [[Formatting in WikiText]]
# [[GettingStarted]]
# [[GitHub]]
# [[Hard Linebreaks in WikiText]]
# [[HelloThere]]
# [[Home Assistant插件]]
# [[HTML Formatting]]
# [[HTML in WikiText]]
# [[Images in WikiText]]
# [[ImageWidget]]
# [[ImportingTiddlers]]
# [[JavaScript]]
# [[K星走狗-王晋康]]
# [[Linking in WikiText]]
# [[list-tagged-draggable Macro]]
# [[Lists in WikiText]]
# [[ListWidget]]
# [[Literature Notes 文献笔记]]
# [[Logseq:开源优雅的知识管理工具]]
# [[Markdown 中文文档-概述]]
# [[Markdown 語法說明]]
# [[New Tiddler]]
# [[Notion]]
# [[Obsidian]]
# [[ODROID-H2+]]
# [[ODROID-HC4]]
# [[Order of Tagged Tiddlers]]
# [[PARA模式]]
# [[Performance Instrumentation]]
# [[Permanent Notes 永久笔记]]
# [[PotPlayer]]
# [[Preserving open tiddlers at startup]]
# [[Project Notes 项目笔记]]
# [[RenameTags]]
# [[Roam Research]]
# [[RoamEdit]]
# [[RoamResearch]]
# [[Setting a favicon]]
# [[Tagging]]
# [[TarsTarkas]]
# [[task]]
# [[TaskManagementExample (Draggable)]]
# [[TaskManagementExample 4]]
# [[TaskManagementExampleDraggableTemplate]]
# [[test]]
# [[TiddlyBlink]]
# [[TiddlyDesktop]]
# [[TiddlyDrive Add-on for Google Drive by Joshua Stubbs]]
# [[TiddlyWiki]]
# [[TiddlyWiki Filter Expression:释放 TiddlyWiki 十倍威力的工具]]
# [[TiddlyWiki 创造内部链接的用法]]
# [[TiddlyWiki 增加预设文字的方法(Snippet)]]
# [[TiddlyWiki 实用宏(macro)copy-block-1]]
# [[TiddlyWiki 折腾记录——云端部署 - FSpark 's Starry Sky]]
# [[TiddlyWiki 教学:在每一个 Tiddler 上加入子分页链接]]
# [[TiddlyWiki 教学:在每一个 Tiddler 上加入自定义页面]]
# [[TiddlyWiki 是一个工具箱]]
# [[TiddlyWiki 是一个用户和开发人员的社区]]
# [[TiddlyWiki 是一种工具]]
# [[TiddlyWiki 的收集箱:TickTick]]
# [[TiddlyWiki 表格教学]]
# [[Title List]]
# [[todo]]
# [[todo20210113]]
# [[todo20210114]]
# [[Trilium]]
# [[Troubleshooting-stroll]]
# [[Untitled]]
# [[Untitled 1]]
# [[Welcome to Stroll]]
# [[WikiText]]
# [[WikiText中的硬换行符]]
# [[ZT:武汉某幸福中产家庭里一个狗,的波澜壮阔大计...]]
# [[一个人的村庄-刘亮程]]
# [[一只名叫Snowy的狗- 周晓枫]]
# [[一只特立独行的猪-理想国与哲人王 -王小波]]
# [[一日囚-柳文扬]]
# [[一边骑车一边发twitter]]
# [[一颗像里茨饭店那么大的钻石-菲茨杰拉德]]
# [[七重外壳-王晋康]]
# [[三岛由纪夫的写作与生活-余华]]
# [[下到小船里_九故事_塞林格]]
# [[下载.png]]
# [[世事如烟- 余华]]
# [[世界文明的河源-胡兰成]]
# [[中篇小说]]
# [[为什么没有音乐-余华]]
# [[为埃斯米而作:既有爱也有污秽凄苦_九故事_塞林格]]
# [[事件选择与信息扣押 - 知乎]]
# [[事实的运用-老舍]]
# [[人物 2,人物的复杂化]]
# [[人物1,人物从无到有]]
# [[人物的发展]]
# [[人物的描写-老舍]]
# [[人造美人-星新一]]
# [[今生今世的证据- 刘亮程]]
# [[从小白到入门-自建服务器部署家庭应用之各种教程-长期更新]]
# [[似水流年-王小波]]
# [[余光中]]
# [[余华]]
# [[余华:伊恩·麦克尤恩后遗症]]
# [[使用 TiddlyWiki 进行个人知识管理]]
# [[倾城-三毛]]
# [[免费派鸡的青年团]]
# [[全世界的人都知道我丢了-李娟]]
# [[关于小说-D.H.劳伦斯]]
# [[关于文学的语言问题-老舍]]
# [[养蜂人-王晋康]]
# [[内心之死-余华]]
# [[列出标签的写法]]
# [[刘亮程]]
# [[创作群像剧有哪些技巧? - 知乎]]
# [[初洗如婴-周晓枫]]
# [[匪兵甲和匪兵乙-三毛]]
# [[十八岁出门远行-余华]]
# [[南柯一梦-星新一]]
# [[博尔赫斯的现实- 余华]]
# [[卡夫卡和K-余华]]
# [[卡片笔记]]
# [[卢曼卡片法]]
# [[去告诉她们-柳文扬]]
# [[双向链接]]
# [[双帽先生-艾丽丝·门罗]]
# [[发作-艾丽丝·门罗]]
# [[发出噪音的电单车]]
# [[古老的旅店-星新一]]
# [[史蒂文 · 米尔豪瑟:1870 年的气球飞行]]
# [[叶思杏 意姑 - 副刊 文艺春秋]]
# [[否 定- 余华]]
# [[周晓枫]]
# [[呼吸——一个宇宙的毁灭-特德·姜]]
# [[命运中的热石头-洛朗·戈代]]
# [[喂——出来!-星新一]]
# [[嘴唇美丽而我的双眸澄碧_九故事_塞林格]]
# [[回忆我的姑母-杨绛]]
# [[在一条通往医院的马路旁]]
# [[垂釣睡眠-鍾怡雯]]
# [[外祖父悖论-柳文扬]]
# [[夜巡 - 帕特里克 · 莫迪亚诺]]
# [[天火-王晋康]]
# [[契诃夫的等待-余华]]
# [[奥兰治大街溜冰场的月亮-艾丽丝·门罗]]
# [[女人、金钱和美-星新一]]
# [[女身-翁菀君]]
# [[如何聪明地记笔记-提高写作、学习和思考能力的技巧]]
# [[如何评价《一颗像里茨饭店那么大的钻石》?]]
# [[如何避免写作中的用力过猛 附:拼接段落二 - 知乎]]
# [[如何阅读世界文学-赫尔曼·黑塞]]
# [[如果我在即将坠机的航班上睡着了-孔亚雷]]
# [[威廉·福克纳- 余华]]
# [[威格利大叔在康涅狄格州_九故事_塞林格]]
# [[娓娓与喋喋-余光中]]
# [[婚约-赫尔曼·黑塞]]
# [[孤独者之歌-赫尔曼·黑塞]]
# [[宁静悠长的下午时光- 李娟]]
# [[安妥我灵魂的这本书-贾平凹]]
# [[安纳克莱托·蒙罗纳斯——胡安·鲁尔福]]
# [[安装Home Assistant操作系统适当的安装选项]]
# [[寒风吹彻-刘亮程]]
# [[小姨娘-汪曾祺]]
# [[小说之未来为小说开刀或掷一颗炸弹118- D.H.劳伦斯]]
# [[就在跟爱斯基摩人开战之前_九故事_塞林格]]
# [[山鲁佐德的故事-余华]]
# [[巧用 Obsidian 把 “思维导图” 变成“双向链思维导图”]]
# [[市政府指示拆了]]
# [[布偶猫-周晓枫]]
# [[布尔加科夫与《大师和玛格丽特》-余华]]
# [[带上她的眼睛--刘慈欣]]
# [[常用]]
# [[康奈尔笔记系统]]
# [[建了又拆的铁路]]
# [[开你的大头会-余光中]]
# [[开卷如开芝麻门-余光中]]
# [[引发读者的“欲望” 附:拼接段落三 - 知乎]]
# [[张爱玲记- 胡兰成]]
# [[强劲的想象产生事实- 余华]]
# [[德 - 杜米埃史密斯的蓝色时期_九故事_塞林格]]
# [[忆我的弟弟汉斯-赫尔曼·黑塞]]
# [[怪胎-艾丽丝·门罗]]
# [[我-孔亚雷]]
# [[我为你洒下月光- 简媜]]
# [[我们在夜市里拜年]]
# [[我们如何获取信息,组织知识 - 少数派]]
# [[我怎样写《猫城记》-老舍]]
# [[我怎样写《骆驼祥子》-老舍]]
# [[我没有自己的名字- 余华]]
# [[我的 TiddlyWiki 个人任务管理系统]]
# [[我的四个假想敌-余光中]]
# [[我的阴阳两界-王小波]]
# [[托马斯·曼]]
# [[推理小说十二按<谋杀的简约之道>-雷蒙德·钱德勒]]
# [[故乡的野菜-汪曾祺]]
# [[散文]]
# [[文学和文学史-余华]]
# [[新条目 1]]
# [[新条目 2]]
# [[新条目 3]]
# [[方肯-主宰者]]
# [[方肯-装死的人不穿鞋]]
# [[无个性的男人-星新一]]
# [[无理之数-言叔夏]]
# [[日落了,却没人写诗_陈位昊]]
# [[昆明的雨-汪曾祺]]
# [[星新一]]
# [[景物的描写-老舍]]
# [[最后,TiddlyWiki 是一种哲学]]
# [[最后的铁匠-刘亮程]]
# [[最后的银河列车-刘育龙]]
# [[月下迷宫-尼尔·盖曼]]
# [[有双向链接的笔记]]
# [[有哪些能把人虐得肝疼的短篇小说?-爱故事推书]]
# [[有如候鸟-周晓枫]]
# [[朋友建议挖路坑]]
# [[木塔里甫的割礼- 刘亮程]]
# [[朱利安·巴恩斯:马茨·伊斯拉埃尔松的故事]]
# [[李娟]]
# [[杨嘉仁 行程——父后百行]]
# [[杰斯和美瑞白丝-艾丽丝·门罗]]
# [[林俊颖 / 最后的道别]]
# [[柳文扬]]
# [[栀子花-简媜]]
# [[梦里花落知多少-三毛]]
# [[欧美当代出色的短篇小说家有哪些?]]
# [[每日日记]]
# [[水星播种-王晋康]]
# [[水蛇腰-汪曾祺]]
# [[汪曾祺]]
# [[沉默的大多数-王小波]]
# [[沙漠奇遇--[俄] 伊·罗索霍瓦茨基]]
# [[沙田山居-余光中]]
# [[没有人是一个岛──想起了痖弦的「一九八○年」-余光中]]
# [[泡茶馆-汪曾祺]]
# [[浅忆黑色幽默小说]]
# [[海子《我请求:雨》]]
# [[海边理发店-荻原浩]]
# [[温暖和百感交集的旅程 余华]]
# [[潭施 假死 - 副刊 文艺春秋]]
# [[火山旅馆-孔亚雷]]
# [[火车事故 by 托马斯·曼]]
# [[爱情故事-余华]]
# [[爱斯基摩人-艾丽丝·门罗]]
# [[爱的进程 艾丽丝·门罗]]
# [[特里斯坦 by 托马斯·曼]]
# [[猫 - 伊恩·麦克尤恩]]
# [[王小波]]
# [[玩转 Obsidian | 基础设置篇]]
# [[环形叙事]]
# [[现代性的五副面孔:现代主义、先锋派、颓废、媚俗艺术、后现代主义 (名家文学讲坛) 后现代主义的手法及其意义]]
# [[现代性的五副面孔:现代主义、先锋派、颓废、媚俗艺术、后现代主义 (名家文学讲坛) 浪漫 “先锋派”:从政治到文化政治]]
# [[球球外传:一个时代和一只小狗的际遇-野夫]]
# [[理想国与哲人王-王小波]]
# [[琴瑟- 葛亮]]
# [[生活又开始了- 李娟]]
# [[用“卡片盒”写文章的具体步骤]]
# [[用积蓄修路墩]]
# [[画画的作家-伊塔洛·卡尔维诺]]
# [[病 -阿嗅-文艺春秋]]
# [[白山包-艾丽丝·门罗]]
# [[知识]]
# [[知识分子的不幸-王小波]]
# [[短篇小说]]
# [[短篇阅读 上班族的一日 by 陈映真]]
# [[短篇阅读 冷漠的人 by 马塞尔·埃梅 - MONO猫弄]]
# [[短篇阅读 奥玛变种蝶 by 林耀德 - MONO猫弄]]
# [[短篇阅读 岛 by 维多利亚·希斯洛普]]
# [[短篇阅读 暮色将至 by 赖香吟]]
# [[短篇阅读 活动中心 by 赖香吟 - MONO猫弄]]
# [[短篇阅读 灯泡拜伦的故事]]
# [[短篇阅读 盐 by 伊萨克·巴别尔]]
# [[短篇阅读 鞋带 by 多梅尼科·斯塔尔诺内]]
# [[祈祷之圈-艾丽丝·门罗]]
# [[离歌-周晓枫]]
# [[禽兽-周晓枫]]
# [[空中爆炸-余华]]
# [[空间知识溢出]]
# [[童话结构的借鉴方式 - 知乎专栏]]
# [[笑面人_九故事_塞林格]]
# [[简媜]]
# [[纪弦《火》]]
# [[线性笔记]]
# [[结构是什么 - 知乎]]
# [[老家-史铁生]]
# [[背影-三毛]]
# [[背影-朱自清]]
# [[胡兰成]]
# [[胡安·鲁尔福- 余华]]
# [[艾丽丝·门罗]]
# [[苔藓-艾丽丝·门罗]]
# [[菲雅尔塔的春天-纳博科夫短篇小说全集]]
# [[萝卜-汪曾祺]]
# [[蒙大拿的迈尔斯城-艾丽丝·门罗]]
# [[被窃的文件 -星新一]]
# [[西西弗的神话 - 阿尔贝·加缪]]
# [[言语与风格-老舍]]
# [[记忆像铁轨一样长-余光中]]
# [[记钱锺书与《围城》- 杨绛]]
# [[论环形叙事中的时间]]
# [[语法]]
# [[请你带我走-《邦查女孩》]]
# [[谈什·约·阿格农小说《在她风华正茂之年》的开头-阿摩司·奥兹]]
# [[谈加夫列尔·加西亚·马尔克斯的长篇小说-阿摩司·奥兹]]
# [[谈卡夫卡《乡村医生》的开头-阿摩司·奥兹]]
# [[谈契诃夫《罗特希尔德的小提琴》的开头-阿摩司·奥兹]]
# [[谈幽默-老舍]]
# [[谈果戈理《鼻子》的开头-阿摩司·奥兹]]
# [[谈萨·伊兹哈尔的长篇小说《米克达莫特》的开头-阿摩司·奥兹]]
# [[谈雷蒙德·卡佛的短篇小说《没人说一句话》的开头-阿摩司·奥兹]]
# [[豆腐-汪曾祺]]
# [[赫尔曼·黑塞]]
# [[走夜路请放声歌唱-李娟]]
# [[路墩像人生跨不过的坎]]
# [[轮流执政 -星新一]]
# [[达克效应]]
# [[迷失威尼斯 by 托马斯·曼]]
# [[逮香蕉鱼的最佳日子_九故事_塞林格]]
# [[道士塔- 余秋雨]]
# [[道德与小说- D.H.劳伦斯]]
# [[遗民老谭-野夫]]
# [[重新命名 Tiddler 很麻烦?ReLink 这个 Plugin 可以解决这个烦恼]]
# [[重访西敏寺-余光中]]
# [[野性之口-小松左京]]
# [[镜中人--作者:杰弗里·A·兰迪斯]]
# [[闪光的生命--柳文扬]]
# [[阳台-蔡晓玲]]
# [[阿丽阿德娜的石头 - 阿尔贝·加缪]]
# [[阿摩司·奥兹]]
# [[阿莱夫_博尔赫斯文集_博尔赫斯]]
# [[隔壁的女人-向田邦子]]
# [[难以觉察的树荫移动-阿摩司·奥兹]]
# [[难逃劫数-余华]]
# [[雨-孔亚雷]]
# [[雪夜-星新一]]
# [[雷蒙德·卡佛]]
# [[震惊了!我们一个同事是猩猩,今天被北京动物园的]]
# [[韭菜花-汪曾祺]]
# [[音乐,美术之类,跟写作有啥关系?(附:拼接段落一) - 知乎]]
# [[风雨天一阁-余秋雨]]
# [[饥饿的人们 by 托马斯·曼]]
# [[香港的旧书市-戴望舒]]
# [[马里奥和魔术师 by 托马斯·曼]]
# [[高 潮-余华]]
# [[鬼子进村-李洱]]
# [[黄昏里的男孩-余华]]
# [[黄金时代-王小波]]
# [[黎紫书 / 寻医记]]
# [[鼻子-芥川龙之介]]
Create a new tiddler that links to this one
Create a new journal tiddler that links to this one
{
"tiddlers": {
"$:/languages/zh-CN/icon": {
"title": "$:/languages/zh-CN/icon",
"type": "image/svg+xml",
"text": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1500\" height=\"1000\" viewBox=\"-5 -5 30 20\">\n<title>Flag of the People's Republic of China</title>\n<rect fill=\"#de2910\" x=\"-5\" y=\"-5\" width=\"30\" height=\"20\"/>\n<defs>\n<polygon id=\"s\" points=\"0,-513674 301930,415571 -488533,-158734 488533,-158734 -301930,415571\"\nfill=\"#ffde00\" transform=\"scale(0.0000019467600073)\"/>\n</defs>\n<use xlink:href=\"#s\" transform=\"scale(3)\"/>\n<use xlink:href=\"#s\" transform=\"translate(5,-3) rotate(-120.963756)\"/>\n<use xlink:href=\"#s\" transform=\"translate(7,-1) rotate(-98.130102)\"/>\n<use xlink:href=\"#s\" transform=\"translate(7,2) rotate(-74.054604)\"/>\n<use xlink:href=\"#s\" transform=\"translate(5,4) rotate(-51.3401917)\"/>\n</svg>\n"
}
}
}
{
"tiddlers": {
"$:/language/Buttons/AdvancedSearch/Caption": {
"title": "$:/language/Buttons/AdvancedSearch/Caption",
"text": "高级查找"
},
"$:/language/Buttons/AdvancedSearch/Hint": {
"title": "$:/language/Buttons/AdvancedSearch/Hint",
"text": "高级查找"
},
"$:/language/Buttons/Cancel/Caption": {
"title": "$:/language/Buttons/Cancel/Caption",
"text": "取消"
},
"$:/language/Buttons/Cancel/Hint": {
"title": "$:/language/Buttons/Cancel/Hint",
"text": "放弃对此条目的更改"
},
"$:/language/Buttons/Clone/Caption": {
"title": "$:/language/Buttons/Clone/Caption",
"text": "克隆"
},
"$:/language/Buttons/Clone/Hint": {
"title": "$:/language/Buttons/Clone/Hint",
"text": "克隆此条目"
},
"$:/language/Buttons/Close/Caption": {
"title": "$:/language/Buttons/Close/Caption",
"text": "关闭"
},
"$:/language/Buttons/Close/Hint": {
"title": "$:/language/Buttons/Close/Hint",
"text": "关闭此条目"
},
"$:/language/Buttons/CloseAll/Caption": {
"title": "$:/language/Buttons/CloseAll/Caption",
"text": "全部关闭"
},
"$:/language/Buttons/CloseAll/Hint": {
"title": "$:/language/Buttons/CloseAll/Hint",
"text": "关闭所有条目"
},
"$:/language/Buttons/CloseOthers/Caption": {
"title": "$:/language/Buttons/CloseOthers/Caption",
"text": "关闭其他"
},
"$:/language/Buttons/CloseOthers/Hint": {
"title": "$:/language/Buttons/CloseOthers/Hint",
"text": "关闭其他条目"
},
"$:/language/Buttons/ControlPanel/Caption": {
"title": "$:/language/Buttons/ControlPanel/Caption",
"text": "控制台"
},
"$:/language/Buttons/ControlPanel/Hint": {
"title": "$:/language/Buttons/ControlPanel/Hint",
"text": "开启控制台"
},
"$:/language/Buttons/CopyToClipboard/Caption": {
"title": "$:/language/Buttons/CopyToClipboard/Caption",
"text": "复制到剪贴板"
},
"$:/language/Buttons/CopyToClipboard/Hint": {
"title": "$:/language/Buttons/CopyToClipboard/Hint",
"text": "将此文本复制到剪贴板"
},
"$:/language/Buttons/Delete/Caption": {
"title": "$:/language/Buttons/Delete/Caption",
"text": "删除"
},
"$:/language/Buttons/Delete/Hint": {
"title": "$:/language/Buttons/Delete/Hint",
"text": "删除此条目"
},
"$:/language/Buttons/Edit/Caption": {
"title": "$:/language/Buttons/Edit/Caption",
"text": "编辑"
},
"$:/language/Buttons/Edit/Hint": {
"title": "$:/language/Buttons/Edit/Hint",
"text": "编辑此条目"
},
"$:/language/Buttons/Encryption/Caption": {
"title": "$:/language/Buttons/Encryption/Caption",
"text": "加密"
},
"$:/language/Buttons/Encryption/Hint": {
"title": "$:/language/Buttons/Encryption/Hint",
"text": "设置或清除保存此维基的密码"
},
"$:/language/Buttons/Encryption/ClearPassword/Caption": {
"title": "$:/language/Buttons/Encryption/ClearPassword/Caption",
"text": "清除密码"
},
"$:/language/Buttons/Encryption/ClearPassword/Hint": {
"title": "$:/language/Buttons/Encryption/ClearPassword/Hint",
"text": "清除密码且不加密保存此维基"
},
"$:/language/Buttons/Encryption/SetPassword/Caption": {
"title": "$:/language/Buttons/Encryption/SetPassword/Caption",
"text": "设置密码"
},
"$:/language/Buttons/Encryption/SetPassword/Hint": {
"title": "$:/language/Buttons/Encryption/SetPassword/Hint",
"text": "设置加密保存此维基的密码"
},
"$:/language/Buttons/ExportPage/Caption": {
"title": "$:/language/Buttons/ExportPage/Caption",
"text": "导出所有条目"
},
"$:/language/Buttons/ExportPage/Hint": {
"title": "$:/language/Buttons/ExportPage/Hint",
"text": "导出所有条目"
},
"$:/language/Buttons/ExportTiddler/Caption": {
"title": "$:/language/Buttons/ExportTiddler/Caption",
"text": "导出此条目"
},
"$:/language/Buttons/ExportTiddler/Hint": {
"title": "$:/language/Buttons/ExportTiddler/Hint",
"text": "导出此条目"
},
"$:/language/Buttons/ExportTiddlers/Caption": {
"title": "$:/language/Buttons/ExportTiddlers/Caption",
"text": "导出条目"
},
"$:/language/Buttons/ExportTiddlers/Hint": {
"title": "$:/language/Buttons/ExportTiddlers/Hint",
"text": "导出条目"
},
"$:/language/Buttons/SidebarSearch/Hint": {
"title": "$:/language/Buttons/SidebarSearch/Hint",
"text": "选择侧边栏的查找字段"
},
"$:/language/Buttons/Fold/Caption": {
"title": "$:/language/Buttons/Fold/Caption",
"text": "收合条目"
},
"$:/language/Buttons/Fold/Hint": {
"title": "$:/language/Buttons/Fold/Hint",
"text": "收合此条目的内容"
},
"$:/language/Buttons/Unfold/Caption": {
"title": "$:/language/Buttons/Unfold/Caption",
"text": "展开条目"
},
"$:/language/Buttons/Unfold/Hint": {
"title": "$:/language/Buttons/Unfold/Hint",
"text": "展开此条目的内容"
},
"$:/language/Buttons/FoldOthers/Caption": {
"title": "$:/language/Buttons/FoldOthers/Caption",
"text": "收合其他条目"
},
"$:/language/Buttons/FoldOthers/Hint": {
"title": "$:/language/Buttons/FoldOthers/Hint",
"text": "收合其他已开启条目的内容"
},
"$:/language/Buttons/FoldAll/Caption": {
"title": "$:/language/Buttons/FoldAll/Caption",
"text": "收合所有条目"
},
"$:/language/Buttons/FoldAll/Hint": {
"title": "$:/language/Buttons/FoldAll/Hint",
"text": "收合所有已开启条目的内容"
},
"$:/language/Buttons/Fold/FoldBar/Caption": {
"title": "$:/language/Buttons/Fold/FoldBar/Caption",
"text": "收合栏"
},
"$:/language/Buttons/Fold/FoldBar/Hint": {
"title": "$:/language/Buttons/Fold/FoldBar/Hint",
"text": "可选的收合与展开条目的长条按钮"
},
"$:/language/Buttons/UnfoldAll/Caption": {
"title": "$:/language/Buttons/UnfoldAll/Caption",
"text": "展开所有条目"
},
"$:/language/Buttons/UnfoldAll/Hint": {
"title": "$:/language/Buttons/UnfoldAll/Hint",
"text": "展开所有已开启条目的内容"
},
"$:/language/Buttons/FullScreen/Caption": {
"title": "$:/language/Buttons/FullScreen/Caption",
"text": "全屏幕"
},
"$:/language/Buttons/FullScreen/Hint": {
"title": "$:/language/Buttons/FullScreen/Hint",
"text": "进入或离开全屏模式"
},
"$:/language/Buttons/Help/Caption": {
"title": "$:/language/Buttons/Help/Caption",
"text": "帮助"
},
"$:/language/Buttons/Help/Hint": {
"title": "$:/language/Buttons/Help/Hint",
"text": "显示帮助面板"
},
"$:/language/Buttons/Home/Caption": {
"title": "$:/language/Buttons/Home/Caption",
"text": "首页"
},
"$:/language/Buttons/Home/Hint": {
"title": "$:/language/Buttons/Home/Hint",
"text": "开启首页条目"
},
"$:/language/Buttons/Import/Caption": {
"title": "$:/language/Buttons/Import/Caption",
"text": "导入"
},
"$:/language/Buttons/Import/Hint": {
"title": "$:/language/Buttons/Import/Hint",
"text": "导入许多类型的文件包括文本、图像、TiddlyWiki 或 JSON"
},
"$:/language/Buttons/Info/Caption": {
"title": "$:/language/Buttons/Info/Caption",
"text": "信息"
},
"$:/language/Buttons/Info/Hint": {
"title": "$:/language/Buttons/Info/Hint",
"text": "显示此条目的信息"
},
"$:/language/Buttons/Language/Caption": {
"title": "$:/language/Buttons/Language/Caption",
"text": "语言"
},
"$:/language/Buttons/Language/Hint": {
"title": "$:/language/Buttons/Language/Hint",
"text": "选择用户介面语言"
},
"$:/language/Buttons/Manager/Caption": {
"title": "$:/language/Buttons/Manager/Caption",
"text": "条目管理器"
},
"$:/language/Buttons/Manager/Hint": {
"title": "$:/language/Buttons/Manager/Hint",
"text": "开启条目管理器"
},
"$:/language/Buttons/More/Caption": {
"title": "$:/language/Buttons/More/Caption",
"text": "更多"
},
"$:/language/Buttons/More/Hint": {
"title": "$:/language/Buttons/More/Hint",
"text": "更多动作"
},
"$:/language/Buttons/NewHere/Caption": {
"title": "$:/language/Buttons/NewHere/Caption",
"text": "添加子条目"
},
"$:/language/Buttons/NewHere/Hint": {
"title": "$:/language/Buttons/NewHere/Hint",
"text": "创建一个标签为此条目名称的新条目"
},
"$:/language/Buttons/NewJournal/Caption": {
"title": "$:/language/Buttons/NewJournal/Caption",
"text": "添加日志"
},
"$:/language/Buttons/NewJournal/Hint": {
"title": "$:/language/Buttons/NewJournal/Hint",
"text": "创建一个新的日志条目"
},
"$:/language/Buttons/NewJournalHere/Caption": {
"title": "$:/language/Buttons/NewJournalHere/Caption",
"text": "添加子日志"
},
"$:/language/Buttons/NewJournalHere/Hint": {
"title": "$:/language/Buttons/NewJournalHere/Hint",
"text": "创建一个标签含此条目名称的新日志条目"
},
"$:/language/Buttons/NewImage/Caption": {
"title": "$:/language/Buttons/NewImage/Caption",
"text": "添加图像"
},
"$:/language/Buttons/NewImage/Hint": {
"title": "$:/language/Buttons/NewImage/Hint",
"text": "创建一个新的图像条目"
},
"$:/language/Buttons/NewMarkdown/Caption": {
"title": "$:/language/Buttons/NewMarkdown/Caption",
"text": "添加 Markdown 条目"
},
"$:/language/Buttons/NewMarkdown/Hint": {
"title": "$:/language/Buttons/NewMarkdown/Hint",
"text": "创建一个新的 Markdown 条目"
},
"$:/language/Buttons/NewTiddler/Caption": {
"title": "$:/language/Buttons/NewTiddler/Caption",
"text": "添加条目"
},
"$:/language/Buttons/NewTiddler/Hint": {
"title": "$:/language/Buttons/NewTiddler/Hint",
"text": "创建一个新的条目"
},
"$:/language/Buttons/OpenWindow/Caption": {
"title": "$:/language/Buttons/OpenWindow/Caption",
"text": "开启于新窗口"
},
"$:/language/Buttons/OpenWindow/Hint": {
"title": "$:/language/Buttons/OpenWindow/Hint",
"text": "在新窗口中开启条目"
},
"$:/language/Buttons/Palette/Caption": {
"title": "$:/language/Buttons/Palette/Caption",
"text": "调色板"
},
"$:/language/Buttons/Palette/Hint": {
"title": "$:/language/Buttons/Palette/Hint",
"text": "选择调色板"
},
"$:/language/Buttons/Permalink/Caption": {
"title": "$:/language/Buttons/Permalink/Caption",
"text": "引用链接"
},
"$:/language/Buttons/Permalink/Hint": {
"title": "$:/language/Buttons/Permalink/Hint",
"text": "设置浏览器网址栏为直接链接到此条目"
},
"$:/language/Buttons/Permaview/Caption": {
"title": "$:/language/Buttons/Permaview/Caption",
"text": "永久链接"
},
"$:/language/Buttons/Permaview/Hint": {
"title": "$:/language/Buttons/Permaview/Hint",
"text": "设置浏览器网址栏为直接链接到当前所有已开启条目"
},
"$:/language/Buttons/Print/Caption": {
"title": "$:/language/Buttons/Print/Caption",
"text": "打印页面"
},
"$:/language/Buttons/Print/Hint": {
"title": "$:/language/Buttons/Print/Hint",
"text": "打印当前页面"
},
"$:/language/Buttons/Refresh/Caption": {
"title": "$:/language/Buttons/Refresh/Caption",
"text": "刷新"
},
"$:/language/Buttons/Refresh/Hint": {
"title": "$:/language/Buttons/Refresh/Hint",
"text": "执行维基的完全刷新"
},
"$:/language/Buttons/Save/Caption": {
"title": "$:/language/Buttons/Save/Caption",
"text": "确定"
},
"$:/language/Buttons/Save/Hint": {
"title": "$:/language/Buttons/Save/Hint",
"text": "确定对此条目的更改"
},
"$:/language/Buttons/SaveWiki/Caption": {
"title": "$:/language/Buttons/SaveWiki/Caption",
"text": "保存变更"
},
"$:/language/Buttons/SaveWiki/Hint": {
"title": "$:/language/Buttons/SaveWiki/Hint",
"text": "保存变更"
},
"$:/language/Buttons/StoryView/Caption": {
"title": "$:/language/Buttons/StoryView/Caption",
"text": "查看模式"
},
"$:/language/Buttons/StoryView/Hint": {
"title": "$:/language/Buttons/StoryView/Hint",
"text": "选择查看条目的视觉效果"
},
"$:/language/Buttons/HideSideBar/Caption": {
"title": "$:/language/Buttons/HideSideBar/Caption",
"text": "隐藏侧边栏"
},
"$:/language/Buttons/HideSideBar/Hint": {
"title": "$:/language/Buttons/HideSideBar/Hint",
"text": "隐藏侧边栏"
},
"$:/language/Buttons/ShowSideBar/Caption": {
"title": "$:/language/Buttons/ShowSideBar/Caption",
"text": "显示侧边栏"
},
"$:/language/Buttons/ShowSideBar/Hint": {
"title": "$:/language/Buttons/ShowSideBar/Hint",
"text": "显示侧边栏"
},
"$:/language/Buttons/TagManager/Caption": {
"title": "$:/language/Buttons/TagManager/Caption",
"text": "标签管理"
},
"$:/language/Buttons/TagManager/Hint": {
"title": "$:/language/Buttons/TagManager/Hint",
"text": "标签管理"
},
"$:/language/Buttons/Timestamp/Caption": {
"title": "$:/language/Buttons/Timestamp/Caption",
"text": "时间戳记"
},
"$:/language/Buttons/Timestamp/Hint": {
"title": "$:/language/Buttons/Timestamp/Hint",
"text": "选择修改是否更新时间戳记"
},
"$:/language/Buttons/Timestamp/On/Caption": {
"title": "$:/language/Buttons/Timestamp/On/Caption",
"text": "时间戳记开启"
},
"$:/language/Buttons/Timestamp/On/Hint": {
"title": "$:/language/Buttons/Timestamp/On/Hint",
"text": "条目被修改时,更新时间戳记"
},
"$:/language/Buttons/Timestamp/Off/Caption": {
"title": "$:/language/Buttons/Timestamp/Off/Caption",
"text": "时间戳记关闭"
},
"$:/language/Buttons/Timestamp/Off/Hint": {
"title": "$:/language/Buttons/Timestamp/Off/Hint",
"text": "条目被修改时,不更新时间戳记"
},
"$:/language/Buttons/Theme/Caption": {
"title": "$:/language/Buttons/Theme/Caption",
"text": "布景主题"
},
"$:/language/Buttons/Theme/Hint": {
"title": "$:/language/Buttons/Theme/Hint",
"text": "选择布景主题"
},
"$:/language/Buttons/Bold/Caption": {
"title": "$:/language/Buttons/Bold/Caption",
"text": "粗体"
},
"$:/language/Buttons/Bold/Hint": {
"title": "$:/language/Buttons/Bold/Hint",
"text": "套用粗体格式于所选文本"
},
"$:/language/Buttons/Clear/Caption": {
"title": "$:/language/Buttons/Clear/Caption",
"text": "清除"
},
"$:/language/Buttons/Clear/Hint": {
"title": "$:/language/Buttons/Clear/Hint",
"text": "清除图像为纯色"
},
"$:/language/Buttons/EditorHeight/Caption": {
"title": "$:/language/Buttons/EditorHeight/Caption",
"text": "编辑器高度"
},
"$:/language/Buttons/EditorHeight/Caption/Auto": {
"title": "$:/language/Buttons/EditorHeight/Caption/Auto",
"text": "自动调整高度以适合内容"
},
"$:/language/Buttons/EditorHeight/Caption/Fixed": {
"title": "$:/language/Buttons/EditorHeight/Caption/Fixed",
"text": "固定高度︰"
},
"$:/language/Buttons/EditorHeight/Hint": {
"title": "$:/language/Buttons/EditorHeight/Hint",
"text": "选择文本编辑器的高度"
},
"$:/language/Buttons/Excise/Caption": {
"title": "$:/language/Buttons/Excise/Caption",
"text": "剪切"
},
"$:/language/Buttons/Excise/Caption/Excise": {
"title": "$:/language/Buttons/Excise/Caption/Excise",
"text": "执行剪切"
},
"$:/language/Buttons/Excise/Caption/MacroName": {
"title": "$:/language/Buttons/Excise/Caption/MacroName",
"text": "宏的名称︰"
},
"$:/language/Buttons/Excise/Caption/NewTitle": {
"title": "$:/language/Buttons/Excise/Caption/NewTitle",
"text": "新条目的名称︰"
},
"$:/language/Buttons/Excise/Caption/Replace": {
"title": "$:/language/Buttons/Excise/Caption/Replace",
"text": "替换剪切的文本为:"
},
"$:/language/Buttons/Excise/Caption/Replace/Macro": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Macro",
"text": "宏"
},
"$:/language/Buttons/Excise/Caption/Replace/Link": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Link",
"text": "链接"
},
"$:/language/Buttons/Excise/Caption/Replace/Transclusion": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Transclusion",
"text": "嵌入"
},
"$:/language/Buttons/Excise/Caption/Tag": {
"title": "$:/language/Buttons/Excise/Caption/Tag",
"text": "将新条目的标签设为此条目的名称"
},
"$:/language/Buttons/Excise/Caption/TiddlerExists": {
"title": "$:/language/Buttons/Excise/Caption/TiddlerExists",
"text": "警示:条目已经存在"
},
"$:/language/Buttons/Excise/Hint": {
"title": "$:/language/Buttons/Excise/Hint",
"text": "剪切所选文本到一个新条目"
},
"$:/language/Buttons/Heading1/Caption": {
"title": "$:/language/Buttons/Heading1/Caption",
"text": "标题 1"
},
"$:/language/Buttons/Heading1/Hint": {
"title": "$:/language/Buttons/Heading1/Hint",
"text": "套用标题级别 1 的格式于包含所选文本的列"
},
"$:/language/Buttons/Heading2/Caption": {
"title": "$:/language/Buttons/Heading2/Caption",
"text": "标题 2"
},
"$:/language/Buttons/Heading2/Hint": {
"title": "$:/language/Buttons/Heading2/Hint",
"text": "套用标题级别 2 的格式于包含所选文本的列"
},
"$:/language/Buttons/Heading3/Caption": {
"title": "$:/language/Buttons/Heading3/Caption",
"text": "标题 3"
},
"$:/language/Buttons/Heading3/Hint": {
"title": "$:/language/Buttons/Heading3/Hint",
"text": "套用标题级别 3 的格式于包含所选文本的列"
},
"$:/language/Buttons/Heading4/Caption": {
"title": "$:/language/Buttons/Heading4/Caption",
"text": "标题 4"
},
"$:/language/Buttons/Heading4/Hint": {
"title": "$:/language/Buttons/Heading4/Hint",
"text": "套用标题级别 4 的格式于包含所选文本的列"
},
"$:/language/Buttons/Heading5/Caption": {
"title": "$:/language/Buttons/Heading5/Caption",
"text": "标题 5"
},
"$:/language/Buttons/Heading5/Hint": {
"title": "$:/language/Buttons/Heading5/Hint",
"text": "套用标题级别 5 的格式于包含所选文本的列"
},
"$:/language/Buttons/Heading6/Caption": {
"title": "$:/language/Buttons/Heading6/Caption",
"text": "标题 6"
},
"$:/language/Buttons/Heading6/Hint": {
"title": "$:/language/Buttons/Heading6/Hint",
"text": "套用标题级别 6 的格式于包含所选文本的列"
},
"$:/language/Buttons/Italic/Caption": {
"title": "$:/language/Buttons/Italic/Caption",
"text": "斜体"
},
"$:/language/Buttons/Italic/Hint": {
"title": "$:/language/Buttons/Italic/Hint",
"text": "套用斜体格式于所选文本"
},
"$:/language/Buttons/LineWidth/Caption": {
"title": "$:/language/Buttons/LineWidth/Caption",
"text": "线宽"
},
"$:/language/Buttons/LineWidth/Hint": {
"title": "$:/language/Buttons/LineWidth/Hint",
"text": "设置绘画的线条宽度"
},
"$:/language/Buttons/Link/Caption": {
"title": "$:/language/Buttons/Link/Caption",
"text": "链接"
},
"$:/language/Buttons/Link/Hint": {
"title": "$:/language/Buttons/Link/Hint",
"text": "创建维基文字链接"
},
"$:/language/Buttons/Linkify/Caption": {
"title": "$:/language/Buttons/Linkify/Caption",
"text": "维基链接"
},
"$:/language/Buttons/Linkify/Hint": {
"title": "$:/language/Buttons/Linkify/Hint",
"text": "套用维基链接于所选文字"
},
"$:/language/Buttons/ListBullet/Caption": {
"title": "$:/language/Buttons/ListBullet/Caption",
"text": "符号清单"
},
"$:/language/Buttons/ListBullet/Hint": {
"title": "$:/language/Buttons/ListBullet/Hint",
"text": "套用符号清单格式于包含所选文本的列"
},
"$:/language/Buttons/ListNumber/Caption": {
"title": "$:/language/Buttons/ListNumber/Caption",
"text": "数字清单"
},
"$:/language/Buttons/ListNumber/Hint": {
"title": "$:/language/Buttons/ListNumber/Hint",
"text": "套用数字清单格式于包含所选文本的列"
},
"$:/language/Buttons/MonoBlock/Caption": {
"title": "$:/language/Buttons/MonoBlock/Caption",
"text": "等宽区块"
},
"$:/language/Buttons/MonoBlock/Hint": {
"title": "$:/language/Buttons/MonoBlock/Hint",
"text": "套用等宽区块格式于包含所选文本的列"
},
"$:/language/Buttons/MonoLine/Caption": {
"title": "$:/language/Buttons/MonoLine/Caption",
"text": "等宽"
},
"$:/language/Buttons/MonoLine/Hint": {
"title": "$:/language/Buttons/MonoLine/Hint",
"text": "套用等宽字符格式于所选文本"
},
"$:/language/Buttons/Opacity/Caption": {
"title": "$:/language/Buttons/Opacity/Caption",
"text": "不透明度"
},
"$:/language/Buttons/Opacity/Hint": {
"title": "$:/language/Buttons/Opacity/Hint",
"text": "设置绘画的不透明度"
},
"$:/language/Buttons/Paint/Caption": {
"title": "$:/language/Buttons/Paint/Caption",
"text": "绘画颜色"
},
"$:/language/Buttons/Paint/Hint": {
"title": "$:/language/Buttons/Paint/Hint",
"text": "设置绘画的颜色"
},
"$:/language/Buttons/Picture/Caption": {
"title": "$:/language/Buttons/Picture/Caption",
"text": "图片"
},
"$:/language/Buttons/Picture/Hint": {
"title": "$:/language/Buttons/Picture/Hint",
"text": "插入图片"
},
"$:/language/Buttons/Preview/Caption": {
"title": "$:/language/Buttons/Preview/Caption",
"text": "预览"
},
"$:/language/Buttons/Preview/Hint": {
"title": "$:/language/Buttons/Preview/Hint",
"text": "显示预览窗格"
},
"$:/language/Buttons/PreviewType/Caption": {
"title": "$:/language/Buttons/PreviewType/Caption",
"text": "预览类型"
},
"$:/language/Buttons/PreviewType/Hint": {
"title": "$:/language/Buttons/PreviewType/Hint",
"text": "选择预览类型"
},
"$:/language/Buttons/Quote/Caption": {
"title": "$:/language/Buttons/Quote/Caption",
"text": "引言"
},
"$:/language/Buttons/Quote/Hint": {
"title": "$:/language/Buttons/Quote/Hint",
"text": "套用引言文本格式于包含所选文本的列"
},
"$:/language/Buttons/RotateLeft/Caption": {
"title": "$:/language/Buttons/RotateLeft/Caption",
"text": "向左旋转"
},
"$:/language/Buttons/RotateLeft/Hint": {
"title": "$:/language/Buttons/RotateLeft/Hint",
"text": "图像向左旋转 90 度"
},
"$:/language/Buttons/Size/Caption": {
"title": "$:/language/Buttons/Size/Caption",
"text": "图像大小"
},
"$:/language/Buttons/Size/Caption/Height": {
"title": "$:/language/Buttons/Size/Caption/Height",
"text": "高度︰"
},
"$:/language/Buttons/Size/Caption/Resize": {
"title": "$:/language/Buttons/Size/Caption/Resize",
"text": "调整图像的大小"
},
"$:/language/Buttons/Size/Caption/Width": {
"title": "$:/language/Buttons/Size/Caption/Width",
"text": "宽度:"
},
"$:/language/Buttons/Size/Hint": {
"title": "$:/language/Buttons/Size/Hint",
"text": "设置图像的大小"
},
"$:/language/Buttons/Stamp/Caption": {
"title": "$:/language/Buttons/Stamp/Caption",
"text": "印记"
},
"$:/language/Buttons/Stamp/Caption/New": {
"title": "$:/language/Buttons/Stamp/Caption/New",
"text": "添加您自己的"
},
"$:/language/Buttons/Stamp/Hint": {
"title": "$:/language/Buttons/Stamp/Hint",
"text": "插入一个预配置的文本片段"
},
"$:/language/Buttons/Stamp/New/Title": {
"title": "$:/language/Buttons/Stamp/New/Title",
"text": "在选单中显示的标题"
},
"$:/language/Buttons/Stamp/New/Text": {
"title": "$:/language/Buttons/Stamp/New/Text",
"text": "片段的文本。(记得在 `caption` 栏位中添加一个说明性的标题)。"
},
"$:/language/Buttons/Strikethrough/Caption": {
"title": "$:/language/Buttons/Strikethrough/Caption",
"text": "删除线"
},
"$:/language/Buttons/Strikethrough/Hint": {
"title": "$:/language/Buttons/Strikethrough/Hint",
"text": "套用删除线格式于所选文本"
},
"$:/language/Buttons/Subscript/Caption": {
"title": "$:/language/Buttons/Subscript/Caption",
"text": "下标"
},
"$:/language/Buttons/Subscript/Hint": {
"title": "$:/language/Buttons/Subscript/Hint",
"text": "套用下标格式于所选文本"
},
"$:/language/Buttons/Superscript/Caption": {
"title": "$:/language/Buttons/Superscript/Caption",
"text": "上标"
},
"$:/language/Buttons/Superscript/Hint": {
"title": "$:/language/Buttons/Superscript/Hint",
"text": "套用上标格式于所选文本"
},
"$:/language/Buttons/ToggleSidebar/Hint": {
"title": "$:/language/Buttons/ToggleSidebar/Hint",
"text": "切换显示或隐藏侧边栏"
},
"$:/language/Buttons/Transcludify/Caption": {
"title": "$:/language/Buttons/Transcludify/Caption",
"text": "嵌入"
},
"$:/language/Buttons/Transcludify/Hint": {
"title": "$:/language/Buttons/Transcludify/Hint",
"text": "套用嵌入于所选文字"
},
"$:/language/Buttons/Underline/Caption": {
"title": "$:/language/Buttons/Underline/Caption",
"text": "下划线"
},
"$:/language/Buttons/Underline/Hint": {
"title": "$:/language/Buttons/Underline/Hint",
"text": "套用下划线格式于所选文本"
},
"$:/language/ControlPanel/Advanced/Caption": {
"title": "$:/language/ControlPanel/Advanced/Caption",
"text": "高级"
},
"$:/language/ControlPanel/Advanced/Hint": {
"title": "$:/language/ControlPanel/Advanced/Hint",
"text": "关于此 TiddlyWiki 的内部信息"
},
"$:/language/ControlPanel/Appearance/Caption": {
"title": "$:/language/ControlPanel/Appearance/Caption",
"text": "视觉外观"
},
"$:/language/ControlPanel/Appearance/Hint": {
"title": "$:/language/ControlPanel/Appearance/Hint",
"text": "定制您的 TiddlyWiki 外观。"
},
"$:/language/ControlPanel/Basics/AnimDuration/Prompt": {
"title": "$:/language/ControlPanel/Basics/AnimDuration/Prompt",
"text": "动画持续时间"
},
"$:/language/ControlPanel/Basics/AutoFocus/Prompt": {
"title": "$:/language/ControlPanel/Basics/AutoFocus/Prompt",
"text": "编辑条目时的默认自动停留栏位"
},
"$:/language/ControlPanel/Basics/Caption": {
"title": "$:/language/ControlPanel/Basics/Caption",
"text": "基本"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint",
"text": "标题含空白时请使用 [[双中括弧]],或者您可用 <$button set=\"$:/DefaultTiddlers\" setTo=\"[list[$:/StoryList]]\">保留开启中的条目顺序</$button>"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt",
"text": "首页"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint",
"text": "默认开启的条目"
},
"$:/language/ControlPanel/Basics/Language/Prompt": {
"title": "$:/language/ControlPanel/Basics/Language/Prompt",
"text": "您好!当前的语言:"
},
"$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt",
"text": "新日志条目的标签"
},
"$:/language/ControlPanel/Basics/NewJournal/Text/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt",
"text": "新日志条目的内容"
},
"$:/language/ControlPanel/Basics/NewJournal/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt",
"text": "新日志条目的名称"
},
"$:/language/ControlPanel/Basics/NewTiddler/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewTiddler/Tags/Prompt",
"text": "新条目的标签"
},
"$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt",
"text": "新条目的名称"
},
"$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt",
"text": "被覆盖的默认条目数量"
},
"$:/language/ControlPanel/Basics/RemoveTags": {
"title": "$:/language/ControlPanel/Basics/RemoveTags",
"text": "更新到当前格式"
},
"$:/language/ControlPanel/Basics/RemoveTags/Hint": {
"title": "$:/language/ControlPanel/Basics/RemoveTags/Hint",
"text": "将标签配置更新为最新格式"
},
"$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt",
"text": "默认条目数量"
},
"$:/language/ControlPanel/Basics/Subtitle/Prompt": {
"title": "$:/language/ControlPanel/Basics/Subtitle/Prompt",
"text": "副标题"
},
"$:/language/ControlPanel/Basics/SystemTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt",
"text": "系统条目数量"
},
"$:/language/ControlPanel/Basics/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/Tags/Prompt",
"text": "标签数量"
},
"$:/language/ControlPanel/Basics/Tiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/Tiddlers/Prompt",
"text": "一般条目数量"
},
"$:/language/ControlPanel/Basics/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/Title/Prompt",
"text": "标题"
},
"$:/language/ControlPanel/Basics/Username/Prompt": {
"title": "$:/language/ControlPanel/Basics/Username/Prompt",
"text": "编辑者署名"
},
"$:/language/ControlPanel/Basics/Version/Prompt": {
"title": "$:/language/ControlPanel/Basics/Version/Prompt",
"text": "~TiddlyWiki 版本"
},
"$:/language/ControlPanel/EditorTypes/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Caption",
"text": "编辑器类型"
},
"$:/language/ControlPanel/EditorTypes/Editor/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Editor/Caption",
"text": "编辑器"
},
"$:/language/ControlPanel/EditorTypes/Hint": {
"title": "$:/language/ControlPanel/EditorTypes/Hint",
"text": "这些条目决定使用哪个编辑器来编辑特定条目类型。"
},
"$:/language/ControlPanel/EditorTypes/Type/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Type/Caption",
"text": "类型"
},
"$:/language/ControlPanel/Info/Caption": {
"title": "$:/language/ControlPanel/Info/Caption",
"text": "信息"
},
"$:/language/ControlPanel/Info/Hint": {
"title": "$:/language/ControlPanel/Info/Hint",
"text": "有关此 TiddlyWiki 的信息"
},
"$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt",
"text": "在此输入快捷键"
},
"$:/language/ControlPanel/KeyboardShortcuts/Add/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption",
"text": "添加快捷键"
},
"$:/language/ControlPanel/KeyboardShortcuts/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Caption",
"text": "快捷键"
},
"$:/language/ControlPanel/KeyboardShortcuts/Hint": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Hint",
"text": "管理键盘快捷键分配"
},
"$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption",
"text": "尚无指定快捷键"
},
"$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint",
"text": "删除快捷键"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/All": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/All",
"text": "所有平台"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac",
"text": "仅 Macintosh 平台"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac",
"text": "仅非 Macintosh 平台"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux",
"text": "仅 Linux 平台"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux",
"text": "仅非 Linux 平台"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows",
"text": "仅 Windows 平台"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows",
"text": "仅非 Windows 平台"
},
"$:/language/ControlPanel/LayoutSwitcher/Caption": {
"title": "$:/language/ControlPanel/LayoutSwitcher/Caption",
"text": "布局"
},
"$:/language/ControlPanel/LoadedModules/Caption": {
"title": "$:/language/ControlPanel/LoadedModules/Caption",
"text": "已加载的模块"
},
"$:/language/ControlPanel/LoadedModules/Hint": {
"title": "$:/language/ControlPanel/LoadedModules/Hint",
"text": "这些是当前已加载的模块之源码条目。斜体的模块则无源码条目,通常是因为它们是在引导过程中设置。"
},
"$:/language/ControlPanel/Palette/Caption": {
"title": "$:/language/ControlPanel/Palette/Caption",
"text": "调色板"
},
"$:/language/ControlPanel/Palette/Editor/Clone/Caption": {
"title": "$:/language/ControlPanel/Palette/Editor/Clone/Caption",
"text": "复制"
},
"$:/language/ControlPanel/Palette/Editor/Clone/Prompt": {
"title": "$:/language/ControlPanel/Palette/Editor/Clone/Prompt",
"text": "建议您修改前先复制此默认调色板"
},
"$:/language/ControlPanel/Palette/Editor/Delete/Hint": {
"title": "$:/language/ControlPanel/Palette/Editor/Delete/Hint",
"text": "从当前调色板中删除此项"
},
"$:/language/ControlPanel/Palette/Editor/Names/External/Show": {
"title": "$:/language/ControlPanel/Palette/Editor/Names/External/Show",
"text": "显示不属于当前调色板的颜色名称"
},
"$:/language/ControlPanel/Palette/Editor/Prompt/Modified": {
"title": "$:/language/ControlPanel/Palette/Editor/Prompt/Modified",
"text": "此默认调色板已被修改过"
},
"$:/language/ControlPanel/Palette/Editor/Prompt": {
"title": "$:/language/ControlPanel/Palette/Editor/Prompt",
"text": "编辑"
},
"$:/language/ControlPanel/Palette/Editor/Reset/Caption": {
"title": "$:/language/ControlPanel/Palette/Editor/Reset/Caption",
"text": "重置"
},
"$:/language/ControlPanel/Palette/HideEditor/Caption": {
"title": "$:/language/ControlPanel/Palette/HideEditor/Caption",
"text": "隐藏编辑器"
},
"$:/language/ControlPanel/Palette/Prompt": {
"title": "$:/language/ControlPanel/Palette/Prompt",
"text": "当前的调色板:"
},
"$:/language/ControlPanel/Palette/ShowEditor/Caption": {
"title": "$:/language/ControlPanel/Palette/ShowEditor/Caption",
"text": "显示编辑器"
},
"$:/language/ControlPanel/Plugins/Add/Hint": {
"title": "$:/language/ControlPanel/Plugins/Add/Hint",
"text": "从官方插件库安装插件"
},
"$:/language/ControlPanel/Plugins/Add/Caption": {
"title": "$:/language/ControlPanel/Plugins/Add/Caption",
"text": "获取更多插件"
},
"$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint": {
"title": "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint",
"text": "此插件已经安装版本 <$text text=<<installedVersion>>/>"
},
"$:/language/ControlPanel/Plugins/AlsoRequires": {
"title": "$:/language/ControlPanel/Plugins/AlsoRequires",
"text": "还需要:"
},
"$:/language/ControlPanel/Plugins/Caption": {
"title": "$:/language/ControlPanel/Plugins/Caption",
"text": "插件"
},
"$:/language/ControlPanel/Plugins/Disable/Caption": {
"title": "$:/language/ControlPanel/Plugins/Disable/Caption",
"text": "禁用"
},
"$:/language/ControlPanel/Plugins/Disable/Hint": {
"title": "$:/language/ControlPanel/Plugins/Disable/Hint",
"text": "重新加载页面时禁用此插件"
},
"$:/language/ControlPanel/Plugins/Disabled/Status": {
"title": "$:/language/ControlPanel/Plugins/Disabled/Status",
"text": "(已禁用)"
},
"$:/language/ControlPanel/Plugins/Downgrade/Caption": {
"title": "$:/language/ControlPanel/Plugins/Downgrade/Caption",
"text": "降级"
},
"$:/language/ControlPanel/Plugins/Empty/Hint": {
"title": "$:/language/ControlPanel/Plugins/Empty/Hint",
"text": "无"
},
"$:/language/ControlPanel/Plugins/Enable/Caption": {
"title": "$:/language/ControlPanel/Plugins/Enable/Caption",
"text": "启用"
},
"$:/language/ControlPanel/Plugins/Enable/Hint": {
"title": "$:/language/ControlPanel/Plugins/Enable/Hint",
"text": "重新加载页面时启用此插件"
},
"$:/language/ControlPanel/Plugins/Install/Caption": {
"title": "$:/language/ControlPanel/Plugins/Install/Caption",
"text": "安装"
},
"$:/language/ControlPanel/Plugins/Installed/Hint": {
"title": "$:/language/ControlPanel/Plugins/Installed/Hint",
"text": "当前已安装的插件:"
},
"$:/language/ControlPanel/Plugins/Languages/Caption": {
"title": "$:/language/ControlPanel/Plugins/Languages/Caption",
"text": "语言"
},
"$:/language/ControlPanel/Plugins/Languages/Hint": {
"title": "$:/language/ControlPanel/Plugins/Languages/Hint",
"text": "语言包插件"
},
"$:/language/ControlPanel/Plugins/NoInfoFound/Hint": {
"title": "$:/language/ControlPanel/Plugins/NoInfoFound/Hint",
"text": "无 ''\"<$text text=<<currentTab>>/>\"''"
},
"$:/language/ControlPanel/Plugins/NoInformation/Hint": {
"title": "$:/language/ControlPanel/Plugins/NoInformation/Hint",
"text": "未提供信息"
},
"$:/language/ControlPanel/Plugins/NotInstalled/Hint": {
"title": "$:/language/ControlPanel/Plugins/NotInstalled/Hint",
"text": "尚未安装此插件"
},
"$:/language/ControlPanel/Plugins/OpenPluginLibrary": {
"title": "$:/language/ControlPanel/Plugins/OpenPluginLibrary",
"text": "开启插件程式库"
},
"$:/language/ControlPanel/Plugins/ClosePluginLibrary": {
"title": "$:/language/ControlPanel/Plugins/ClosePluginLibrary",
"text": "关闭插件程式库"
},
"$:/language/ControlPanel/Plugins/PluginWillRequireReload": {
"title": "$:/language/ControlPanel/Plugins/PluginWillRequireReload",
"text": "(需要重新加载)"
},
"$:/language/ControlPanel/Plugins/Plugins/Caption": {
"title": "$:/language/ControlPanel/Plugins/Plugins/Caption",
"text": "插件"
},
"$:/language/ControlPanel/Plugins/Plugins/Hint": {
"title": "$:/language/ControlPanel/Plugins/Plugins/Hint",
"text": "插件"
},
"$:/language/ControlPanel/Plugins/Reinstall/Caption": {
"title": "$:/language/ControlPanel/Plugins/Reinstall/Caption",
"text": "重新安装"
},
"$:/language/ControlPanel/Plugins/Themes/Caption": {
"title": "$:/language/ControlPanel/Plugins/Themes/Caption",
"text": "布景主题"
},
"$:/language/ControlPanel/Plugins/Themes/Hint": {
"title": "$:/language/ControlPanel/Plugins/Themes/Hint",
"text": "布景主题插件"
},
"$:/language/ControlPanel/Plugins/Update/Caption": {
"title": "$:/language/ControlPanel/Plugins/Update/Caption",
"text": "更新"
},
"$:/language/ControlPanel/Plugins/Updates/Caption": {
"title": "$:/language/ControlPanel/Plugins/Updates/Caption",
"text": "更新"
},
"$:/language/ControlPanel/Plugins/Updates/Hint": {
"title": "$:/language/ControlPanel/Plugins/Updates/Hint",
"text": "已安装插件的可用更新"
},
"$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption": {
"title": "$:/language/ControlPanel/Plugins/Updates/UpdateAll/Caption",
"text": "更新 <<update-count>> 个插件"
},
"$:/language/ControlPanel/Plugins/SubPluginPrompt": {
"title": "$:/language/ControlPanel/Plugins/SubPluginPrompt",
"text": "提供 <<count>> 个可用的附加插件"
},
"$:/language/ControlPanel/Parsing/Caption": {
"title": "$:/language/ControlPanel/Parsing/Caption",
"text": "解析"
},
"$:/language/ControlPanel/Parsing/Hint": {
"title": "$:/language/ControlPanel/Parsing/Hint",
"text": "在此您可以全域禁用或启用维基解析规则。要使更改生效,请保存并重新加载您的维基。禁用某些解析规则,会妨碍 <$text text=\"TiddlyWiki\"/> 正常运作。可使用[[安全模式|https://tiddlywiki.com/#SafeMode]]恢复正常操作。"
},
"$:/language/ControlPanel/Parsing/Block/Caption": {
"title": "$:/language/ControlPanel/Parsing/Block/Caption",
"text": "区块解析规则"
},
"$:/language/ControlPanel/Parsing/Inline/Caption": {
"title": "$:/language/ControlPanel/Parsing/Inline/Caption",
"text": "内联解析规则"
},
"$:/language/ControlPanel/Parsing/Pragma/Caption": {
"title": "$:/language/ControlPanel/Parsing/Pragma/Caption",
"text": "编译指示解析规则"
},
"$:/language/ControlPanel/Saving/Caption": {
"title": "$:/language/ControlPanel/Saving/Caption",
"text": "保存"
},
"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description",
"text": "允许下载保存模块的自动保存"
},
"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint",
"text": "启用下载保存模块的自动保存"
},
"$:/language/ControlPanel/Saving/DownloadSaver/Caption": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/Caption",
"text": "下载保存模块"
},
"$:/language/ControlPanel/Saving/DownloadSaver/Hint": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/Hint",
"text": "这些设置适用于兼容 HTML5 的下载保存模块"
},
"$:/language/ControlPanel/Saving/General/Caption": {
"title": "$:/language/ControlPanel/Saving/General/Caption",
"text": "通用"
},
"$:/language/ControlPanel/Saving/General/Hint": {
"title": "$:/language/ControlPanel/Saving/General/Hint",
"text": "这些设置适用于所有已载入的保存模块"
},
"$:/language/ControlPanel/Saving/Hint": {
"title": "$:/language/ControlPanel/Saving/Hint",
"text": "用于通过保存模块将整个 TiddlyWiki 保存为单个文件的设置"
},
"$:/language/ControlPanel/Saving/GitService/Branch": {
"title": "$:/language/ControlPanel/Saving/GitService/Branch",
"text": "用于保存的目标分支"
},
"$:/language/ControlPanel/Saving/GitService/CommitMessage": {
"title": "$:/language/ControlPanel/Saving/GitService/CommitMessage",
"text": "由 TiddlyWiki 保存"
},
"$:/language/ControlPanel/Saving/GitService/Description": {
"title": "$:/language/ControlPanel/Saving/GitService/Description",
"text": "这些设置仅用于保存至 <<service-name>>"
},
"$:/language/ControlPanel/Saving/GitService/Filename": {
"title": "$:/language/ControlPanel/Saving/GitService/Filename",
"text": "目标文件的文件名称 (例如,`index.html`)"
},
"$:/language/ControlPanel/Saving/GitService/Path": {
"title": "$:/language/ControlPanel/Saving/GitService/Path",
"text": "目标文件的路径 (例如,`/wiki/`)"
},
"$:/language/ControlPanel/Saving/GitService/Repo": {
"title": "$:/language/ControlPanel/Saving/GitService/Repo",
"text": "目标存储库 (例如,`Jermolene/TiddlyWiki5`)"
},
"$:/language/ControlPanel/Saving/GitService/ServerURL": {
"title": "$:/language/ControlPanel/Saving/GitService/ServerURL",
"text": "服务器 API 网址"
},
"$:/language/ControlPanel/Saving/GitService/UserName": {
"title": "$:/language/ControlPanel/Saving/GitService/UserName",
"text": "用户名称"
},
"$:/language/ControlPanel/Saving/GitService/GitHub/Caption": {
"title": "$:/language/ControlPanel/Saving/GitService/GitHub/Caption",
"text": "~GitHub 保存模块"
},
"$:/language/ControlPanel/Saving/GitService/GitHub/Password": {
"title": "$:/language/ControlPanel/Saving/GitService/GitHub/Password",
"text": "密码、OAUTH 令牌,或个人存取令牌 (详见 [[GitHub 帮助页面|https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line]])"
},
"$:/language/ControlPanel/Saving/GitService/GitLab/Caption": {
"title": "$:/language/ControlPanel/Saving/GitService/GitLab/Caption",
"text": "~GitLab 保存模块"
},
"$:/language/ControlPanel/Saving/GitService/GitLab/Password": {
"title": "$:/language/ControlPanel/Saving/GitService/GitLab/Password",
"text": "个人存取令牌的 API (详见 [[GitLab 帮助页面|https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html]])"
},
"$:/language/ControlPanel/Saving/GitService/Gitea/Caption": {
"title": "$:/language/ControlPanel/Saving/GitService/Gitea/Caption",
"text": "Gitea 保存模块"
},
"$:/language/ControlPanel/Saving/GitService/Gitea/Password": {
"title": "$:/language/ControlPanel/Saving/GitService/Gitea/Password",
"text": "个人存取令牌的 API (通过 Gitea 的 Web 界面:`设定 | 应用程序 | 产生新的令牌`)"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading",
"text": "高级设置"
},
"$:/language/ControlPanel/Saving/TiddlySpot/BackupDir": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir",
"text": "备份文件夹"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Backups": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Backups",
"text": "备份"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Caption": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Caption",
"text": "~TiddlySpot 保存模块"
},
"$:/language/ControlPanel/Saving/TiddlySpot/ControlPanel": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ControlPanel",
"text": "~TiddlySpot 控制台"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Description": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Description",
"text": "这些设置只适用于保存到 http://tiddlyspot.com 或兼容的远程服务器时。"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Filename": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Filename",
"text": "上传文件名"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Heading": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Heading",
"text": "~TiddlySpot"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Hint": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Hint",
"text": "//默认之服务器网址 `http://<wikiname>.tiddlyspot.com/store.cgi`,可改为定制之服务器网址,例如 `http://example.com/store.php`。//"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Password": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Password",
"text": "密码"
},
"$:/language/ControlPanel/Saving/TiddlySpot/ReadOnly": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ReadOnly",
"text": "~TiddlySpot 服务目前仅以唯读形式提供。相关最新详细信息,请参阅 http://tiddlyspot.com/ 。~TiddlySpot 保存模块仍可用于保存到兼容的服务器。"
},
"$:/language/ControlPanel/Saving/TiddlySpot/ServerURL": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL",
"text": "服务器网址"
},
"$:/language/ControlPanel/Saving/TiddlySpot/UploadDir": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir",
"text": "上传文件夹"
},
"$:/language/ControlPanel/Saving/TiddlySpot/UserName": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/UserName",
"text": "用户"
},
"$:/language/ControlPanel/Settings/AutoSave/Caption": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Caption",
"text": "自动保存"
},
"$:/language/ControlPanel/Settings/AutoSave/Disabled/Description": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description",
"text": "不要自动保存变更"
},
"$:/language/ControlPanel/Settings/AutoSave/Enabled/Description": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description",
"text": "自动保存变更"
},
"$:/language/ControlPanel/Settings/AutoSave/Hint": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Hint",
"text": "当使用支持的保存模块时,在编辑期间尝试自动保存变更"
},
"$:/language/ControlPanel/Settings/CamelCase/Caption": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Caption",
"text": "驼峰式维基链接"
},
"$:/language/ControlPanel/Settings/CamelCase/Hint": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Hint",
"text": "您可以全域禁用驼峰式短语自动链接。须保存后重新加载,方才生效。"
},
"$:/language/ControlPanel/Settings/CamelCase/Description": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Description",
"text": "启用自动驼峰式链接"
},
"$:/language/ControlPanel/Settings/Caption": {
"title": "$:/language/ControlPanel/Settings/Caption",
"text": "设置"
},
"$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption": {
"title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption",
"text": "默认侧边栏页签"
},
"$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint": {
"title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint",
"text": "指定默认显示的侧边栏页签"
},
"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption": {
"title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption",
"text": "更多侧边栏的默认页签"
},
"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint": {
"title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint",
"text": "指定默认显示的更多侧栏页签"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Caption": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Caption",
"text": "编辑器工具栏"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Hint": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Hint",
"text": "启用或禁用编辑器工具栏︰"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Description": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Description",
"text": "显示编辑器工具栏"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Caption": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Caption",
"text": "条目信息面板模式"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Hint": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Hint",
"text": "控制条目信息面板何时关闭︰"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description",
"text": "条目信息面板自动关闭"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description",
"text": "条目信息面板保持打开状态,直到明确关闭"
},
"$:/language/ControlPanel/Settings/Hint": {
"title": "$:/language/ControlPanel/Settings/Hint",
"text": "这些高级设置让您定制 TiddlyWiki 的行为。"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/Caption": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption",
"text": "条目开启行为"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint",
"text": "从故事河//中//导航"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint",
"text": "从故事河//外//导航"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove",
"text": "开启于当前条目之上"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow",
"text": "开启于当前条目之下"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop",
"text": "开启于故事河的顶端"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom",
"text": "开启于故事河的底部"
},
"$:/language/ControlPanel/Settings/MissingLinks/Caption": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Caption",
"text": "维基链接"
},
"$:/language/ControlPanel/Settings/MissingLinks/Hint": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Hint",
"text": "选择是否要链接到尚未存在的条目"
},
"$:/language/ControlPanel/Settings/MissingLinks/Description": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Description",
"text": "启用链接到佚失条目"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption",
"text": "网址栏导览"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint",
"text": "在浏览器网址栏导览到条目时的行为:"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description",
"text": "不更新网址栏"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description",
"text": "包含目标条目"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description",
"text": "包括目标条目和当前已开启的条目序列"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Caption",
"text": "历史记录导览"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Hint",
"text": "当导览到条目时,更新浏览器历史记录:"
},
"$:/language/ControlPanel/Settings/NavigationHistory/No/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/No/Description",
"text": "不更新历史记录"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description",
"text": "更新历史记录"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption",
"text": "引用链接/固定链接 模式"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint",
"text": "选择 引用链接/固定链接 的处理方式:"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description",
"text": "将 引用链接/固定链接 网址复制到剪贴板"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description",
"text": "以 引用链接/固定链接 更新网址栏"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption",
"text": "性能检测"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint",
"text": "在浏览器的开发人员控制台,显示性能统计数据。需要重新加载才能生效。"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description",
"text": "启用性能检测"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption",
"text": "工具栏按钮样式"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint",
"text": "选择工具栏按钮的样式:"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless",
"text": "无边框"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed",
"text": "方框"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded",
"text": "圆形"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Caption": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Caption",
"text": "工具栏按钮"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Hint": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Hint",
"text": "默认的工具栏按钮外观:"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description",
"text": "包含图标"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description",
"text": "包含文本"
},
"$:/language/ControlPanel/Settings/TitleLinks/Caption": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Caption",
"text": "条目标题"
},
"$:/language/ControlPanel/Settings/TitleLinks/Hint": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Hint",
"text": "可选地显示条目标题为链接"
},
"$:/language/ControlPanel/Settings/TitleLinks/No/Description": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/No/Description",
"text": "不显示条目标题为链接"
},
"$:/language/ControlPanel/Settings/TitleLinks/Yes/Description": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description",
"text": "显示条目标题为链接"
},
"$:/language/ControlPanel/StoryView/Caption": {
"title": "$:/language/ControlPanel/StoryView/Caption",
"text": "查看模式"
},
"$:/language/ControlPanel/StoryView/Prompt": {
"title": "$:/language/ControlPanel/StoryView/Prompt",
"text": "当前的查看模式:"
},
"$:/language/ControlPanel/Stylesheets/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Caption",
"text": "样式表"
},
"$:/language/ControlPanel/Stylesheets/Expand/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Expand/Caption",
"text": "全部展开"
},
"$:/language/ControlPanel/Stylesheets/Hint": {
"title": "$:/language/ControlPanel/Stylesheets/Hint",
"text": "这是当前标签为 <<tag \"$:/tags/Stylesheet\">> 的样式表条目呈现的 CSS"
},
"$:/language/ControlPanel/Stylesheets/Restore/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Restore/Caption",
"text": "复原"
},
"$:/language/ControlPanel/Theme/Caption": {
"title": "$:/language/ControlPanel/Theme/Caption",
"text": "布景主题"
},
"$:/language/ControlPanel/Theme/Prompt": {
"title": "$:/language/ControlPanel/Theme/Prompt",
"text": "当前的布景主题:"
},
"$:/language/ControlPanel/TiddlerFields/Caption": {
"title": "$:/language/ControlPanel/TiddlerFields/Caption",
"text": "条目栏位"
},
"$:/language/ControlPanel/TiddlerFields/Hint": {
"title": "$:/language/ControlPanel/TiddlerFields/Hint",
"text": "这是本维基使用中的所有条目栏位(含系统条目的栏位,但默认条目的栏位除外)。"
},
"$:/language/ControlPanel/Toolbars/Caption": {
"title": "$:/language/ControlPanel/Toolbars/Caption",
"text": "工具栏"
},
"$:/language/ControlPanel/Toolbars/EditToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/EditToolbar/Caption",
"text": "编辑工具栏"
},
"$:/language/ControlPanel/Toolbars/EditToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/EditToolbar/Hint",
"text": "选择将显示哪些按钮于条目的编辑模式工具栏。拖放可改变顺序。"
},
"$:/language/ControlPanel/Toolbars/Hint": {
"title": "$:/language/ControlPanel/Toolbars/Hint",
"text": "选择将显示哪些工具栏按钮"
},
"$:/language/ControlPanel/Toolbars/PageControls/Caption": {
"title": "$:/language/ControlPanel/Toolbars/PageControls/Caption",
"text": "页面工具栏"
},
"$:/language/ControlPanel/Toolbars/PageControls/Hint": {
"title": "$:/language/ControlPanel/Toolbars/PageControls/Hint",
"text": "选择将显示哪些按钮于主页面的工具栏。拖放可改变顺序。"
},
"$:/language/ControlPanel/Toolbars/EditorToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption",
"text": "编辑器工具栏"
},
"$:/language/ControlPanel/Toolbars/EditorToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint",
"text": "选择将显示哪些按钮于编辑器工具栏。请注意,某些按钮只会出现在编辑某一类型的条目时。拖放可改变顺序。"
},
"$:/language/ControlPanel/Toolbars/ViewToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption",
"text": "查看工具栏"
},
"$:/language/ControlPanel/Toolbars/ViewToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint",
"text": "选择将显示哪些按钮于条目的查看模式工具栏。拖放可改变顺序。"
},
"$:/language/ControlPanel/Tools/Download/Full/Caption": {
"title": "$:/language/ControlPanel/Tools/Download/Full/Caption",
"text": "下载完整副本"
},
"$:/core/zh-Hans/readme": {
"title": "$:/core/zh-Hans/readme",
"text": "此插件包含 TiddlyWiki 的核心组件,包括:\n\n* JavaScript 代码模块\n* 图标\n* 创建 TiddlyWiki 的用户介面所需的模板\n* 核心所使用的可当地语系化字串的英国英语 (''en-GB'') 翻译\n"
},
"$:/language/Date/Long/Day/0": {
"title": "$:/language/Date/Long/Day/0",
"text": "周日"
},
"$:/language/Date/Long/Day/1": {
"title": "$:/language/Date/Long/Day/1",
"text": "周一"
},
"$:/language/Date/Long/Day/2": {
"title": "$:/language/Date/Long/Day/2",
"text": "周二"
},
"$:/language/Date/Long/Day/3": {
"title": "$:/language/Date/Long/Day/3",
"text": "周三"
},
"$:/language/Date/Long/Day/4": {
"title": "$:/language/Date/Long/Day/4",
"text": "周四"
},
"$:/language/Date/Long/Day/5": {
"title": "$:/language/Date/Long/Day/5",
"text": "周五"
},
"$:/language/Date/Long/Day/6": {
"title": "$:/language/Date/Long/Day/6",
"text": "周六"
},
"$:/language/Date/Long/Month/1": {
"title": "$:/language/Date/Long/Month/1",
"text": "一月"
},
"$:/language/Date/Long/Month/2": {
"title": "$:/language/Date/Long/Month/2",
"text": "二月"
},
"$:/language/Date/Long/Month/3": {
"title": "$:/language/Date/Long/Month/3",
"text": "三月"
},
"$:/language/Date/Long/Month/4": {
"title": "$:/language/Date/Long/Month/4",
"text": "四月"
},
"$:/language/Date/Long/Month/5": {
"title": "$:/language/Date/Long/Month/5",
"text": "五月"
},
"$:/language/Date/Long/Month/6": {
"title": "$:/language/Date/Long/Month/6",
"text": "六月"
},
"$:/language/Date/Long/Month/7": {
"title": "$:/language/Date/Long/Month/7",
"text": "七月"
},
"$:/language/Date/Long/Month/8": {
"title": "$:/language/Date/Long/Month/8",
"text": "八月"
},
"$:/language/Date/Long/Month/9": {
"title": "$:/language/Date/Long/Month/9",
"text": "九月"
},
"$:/language/Date/Long/Month/10": {
"title": "$:/language/Date/Long/Month/10",
"text": "十月"
},
"$:/language/Date/Long/Month/11": {
"title": "$:/language/Date/Long/Month/11",
"text": "十一月"
},
"$:/language/Date/Long/Month/12": {
"title": "$:/language/Date/Long/Month/12",
"text": "十二月"
},
"$:/language/Date/Period/am": {
"title": "$:/language/Date/Period/am",
"text": "上午"
},
"$:/language/Date/Period/pm": {
"title": "$:/language/Date/Period/pm",
"text": "下午"
},
"$:/language/Date/Short/Day/0": {
"title": "$:/language/Date/Short/Day/0",
"text": "日"
},
"$:/language/Date/Short/Day/1": {
"title": "$:/language/Date/Short/Day/1",
"text": "一"
},
"$:/language/Date/Short/Day/2": {
"title": "$:/language/Date/Short/Day/2",
"text": "二"
},
"$:/language/Date/Short/Day/3": {
"title": "$:/language/Date/Short/Day/3",
"text": "三"
},
"$:/language/Date/Short/Day/4": {
"title": "$:/language/Date/Short/Day/4",
"text": "四"
},
"$:/language/Date/Short/Day/5": {
"title": "$:/language/Date/Short/Day/5",
"text": "五"
},
"$:/language/Date/Short/Day/6": {
"title": "$:/language/Date/Short/Day/6",
"text": "六"
},
"$:/language/Date/Short/Month/1": {
"title": "$:/language/Date/Short/Month/1",
"text": "01月"
},
"$:/language/Date/Short/Month/2": {
"title": "$:/language/Date/Short/Month/2",
"text": "02月"
},
"$:/language/Date/Short/Month/3": {
"title": "$:/language/Date/Short/Month/3",
"text": "03月"
},
"$:/language/Date/Short/Month/4": {
"title": "$:/language/Date/Short/Month/4",
"text": "04月"
},
"$:/language/Date/Short/Month/5": {
"title": "$:/language/Date/Short/Month/5",
"text": "05月"
},
"$:/language/Date/Short/Month/6": {
"title": "$:/language/Date/Short/Month/6",
"text": "06月"
},
"$:/language/Date/Short/Month/7": {
"title": "$:/language/Date/Short/Month/7",
"text": "07月"
},
"$:/language/Date/Short/Month/8": {
"title": "$:/language/Date/Short/Month/8",
"text": "08月"
},
"$:/language/Date/Short/Month/9": {
"title": "$:/language/Date/Short/Month/9",
"text": "09月"
},
"$:/language/Date/Short/Month/10": {
"title": "$:/language/Date/Short/Month/10",
"text": "10月"
},
"$:/language/Date/Short/Month/11": {
"title": "$:/language/Date/Short/Month/11",
"text": "11月"
},
"$:/language/Date/Short/Month/12": {
"title": "$:/language/Date/Short/Month/12",
"text": "12月"
},
"$:/language/RelativeDate/Future/Days": {
"title": "$:/language/RelativeDate/Future/Days",
"text": "<<period>> 天后"
},
"$:/language/RelativeDate/Future/Hours": {
"title": "$:/language/RelativeDate/Future/Hours",
"text": "<<period>> 小时后"
},
"$:/language/RelativeDate/Future/Minutes": {
"title": "$:/language/RelativeDate/Future/Minutes",
"text": "<<period>> 分钟后"
},
"$:/language/RelativeDate/Future/Months": {
"title": "$:/language/RelativeDate/Future/Months",
"text": "<<period>> 个月后"
},
"$:/language/RelativeDate/Future/Second": {
"title": "$:/language/RelativeDate/Future/Second",
"text": "1 秒后"
},
"$:/language/RelativeDate/Future/Seconds": {
"title": "$:/language/RelativeDate/Future/Seconds",
"text": "<<period>> 秒后"
},
"$:/language/RelativeDate/Future/Years": {
"title": "$:/language/RelativeDate/Future/Years",
"text": "<<period>> 年后"
},
"$:/language/RelativeDate/Past/Days": {
"title": "$:/language/RelativeDate/Past/Days",
"text": "<<period>> 天前"
},
"$:/language/RelativeDate/Past/Hours": {
"title": "$:/language/RelativeDate/Past/Hours",
"text": "<<period>> 小时前"
},
"$:/language/RelativeDate/Past/Minutes": {
"title": "$:/language/RelativeDate/Past/Minutes",
"text": "<<period>> 分钟前"
},
"$:/language/RelativeDate/Past/Months": {
"title": "$:/language/RelativeDate/Past/Months",
"text": "<<period>> 个月前"
},
"$:/language/RelativeDate/Past/Second": {
"title": "$:/language/RelativeDate/Past/Second",
"text": "1 秒前"
},
"$:/language/RelativeDate/Past/Seconds": {
"title": "$:/language/RelativeDate/Past/Seconds",
"text": "<<period>> 秒前"
},
"$:/language/RelativeDate/Past/Years": {
"title": "$:/language/RelativeDate/Past/Years",
"text": "<<period>> 年前"
},
"$:/language/Docs/ModuleTypes/allfilteroperator": {
"title": "$:/language/Docs/ModuleTypes/allfilteroperator",
"text": "''all'' 筛选器算子的子算子。"
},
"$:/language/Docs/ModuleTypes/animation": {
"title": "$:/language/Docs/ModuleTypes/animation",
"text": "动画模块包含可用于 RevealWidget 的动画。"
},
"$:/language/Docs/ModuleTypes/authenticator": {
"title": "$:/language/Docs/ModuleTypes/authenticator",
"text": "定义内置 HTTP 服务器对请求的身份验证方式。"
},
"$:/language/Docs/ModuleTypes/bitmapeditoroperation": {
"title": "$:/language/Docs/ModuleTypes/bitmapeditoroperation",
"text": "一个位图编辑器工具栏操作。"
},
"$:/language/Docs/ModuleTypes/command": {
"title": "$:/language/Docs/ModuleTypes/command",
"text": "可于 Node.js 执行的指令。"
},
"$:/language/Docs/ModuleTypes/config": {
"title": "$:/language/Docs/ModuleTypes/config",
"text": "加入 `$tw.config` 的数据。"
},
"$:/language/Docs/ModuleTypes/filteroperator": {
"title": "$:/language/Docs/ModuleTypes/filteroperator",
"text": "个别筛选器算子方法。"
},
"$:/language/Docs/ModuleTypes/global": {
"title": "$:/language/Docs/ModuleTypes/global",
"text": "加入 `$tw` 的全域数据。"
},
"$:/language/Docs/ModuleTypes/info": {
"title": "$:/language/Docs/ModuleTypes/info",
"text": "透过 [[$:/temp/info-plugin]] 伪插件,发布系统信息。"
},
"$:/language/Docs/ModuleTypes/isfilteroperator": {
"title": "$:/language/Docs/ModuleTypes/isfilteroperator",
"text": "''is'' 筛选器算子的运算符。"
},
"$:/language/Docs/ModuleTypes/library": {
"title": "$:/language/Docs/ModuleTypes/library",
"text": "一般用途的 JavaScript 模块的通用模块类型。"
},
"$:/language/Docs/ModuleTypes/macro": {
"title": "$:/language/Docs/ModuleTypes/macro",
"text": "JavaScript ''宏''定义。"
},
"$:/language/Docs/ModuleTypes/parser": {
"title": "$:/language/Docs/ModuleTypes/parser",
"text": "不同内容类型的解析器。"
},
"$:/language/Docs/ModuleTypes/route": {
"title": "$:/language/Docs/ModuleTypes/route",
"text": "定义内置 HTTP 服务器如何处理各个网址格式。"
},
"$:/language/Docs/ModuleTypes/saver": {
"title": "$:/language/Docs/ModuleTypes/saver",
"text": "于浏览器保存文件的不同的保存处理方法。"
},
"$:/language/Docs/ModuleTypes/startup": {
"title": "$:/language/Docs/ModuleTypes/startup",
"text": "启动时期的功能函数。"
},
"$:/language/Docs/ModuleTypes/storyview": {
"title": "$:/language/Docs/ModuleTypes/storyview",
"text": "查看模式用以自订 list 小部件的动画与行为。"
},
"$:/language/Docs/ModuleTypes/texteditoroperation": {
"title": "$:/language/Docs/ModuleTypes/texteditoroperation",
"text": "一个文本编辑器工具栏操作。"
},
"$:/language/Docs/ModuleTypes/tiddlerdeserializer": {
"title": "$:/language/Docs/ModuleTypes/tiddlerdeserializer",
"text": "转换不同内容类型至条目。"
},
"$:/language/Docs/ModuleTypes/tiddlerfield": {
"title": "$:/language/Docs/ModuleTypes/tiddlerfield",
"text": "定义个别条目栏位的行为。"
},
"$:/language/Docs/ModuleTypes/tiddlermethod": {
"title": "$:/language/Docs/ModuleTypes/tiddlermethod",
"text": "添加方法至 `$tw.Tiddler` 原型。"
},
"$:/language/Docs/ModuleTypes/upgrader": {
"title": "$:/language/Docs/ModuleTypes/upgrader",
"text": "于升级/导入过程中,套用升级处理至条目。"
},
"$:/language/Docs/ModuleTypes/utils": {
"title": "$:/language/Docs/ModuleTypes/utils",
"text": "添加方法至 `$tw.utils`。"
},
"$:/language/Docs/ModuleTypes/utils-node": {
"title": "$:/language/Docs/ModuleTypes/utils-node",
"text": "将特定于 Node.js 的方法添加到 '$tw.utils'。"
},
"$:/language/Docs/ModuleTypes/widget": {
"title": "$:/language/Docs/ModuleTypes/widget",
"text": "封装 DOM 渲染和刷新的小部件。"
},
"$:/language/Docs/ModuleTypes/wikimethod": {
"title": "$:/language/Docs/ModuleTypes/wikimethod",
"text": "添加方法至 `$tw.Wiki`。"
},
"$:/language/Docs/ModuleTypes/wikirule": {
"title": "$:/language/Docs/ModuleTypes/wikirule",
"text": "WikiText 解析器的个别的语法规则。"
},
"$:/language/Docs/PaletteColours/alert-background": {
"title": "$:/language/Docs/PaletteColours/alert-background",
"text": "警示背景"
},
"$:/language/Docs/PaletteColours/alert-border": {
"title": "$:/language/Docs/PaletteColours/alert-border",
"text": "警示边框"
},
"$:/language/Docs/PaletteColours/alert-highlight": {
"title": "$:/language/Docs/PaletteColours/alert-highlight",
"text": "警示高亮度"
},
"$:/language/Docs/PaletteColours/alert-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/alert-muted-foreground",
"text": "警示的低调前景"
},
"$:/language/Docs/PaletteColours/background": {
"title": "$:/language/Docs/PaletteColours/background",
"text": "一般背景"
},
"$:/language/Docs/PaletteColours/blockquote-bar": {
"title": "$:/language/Docs/PaletteColours/blockquote-bar",
"text": "引言条"
},
"$:/language/Docs/PaletteColours/button-background": {
"title": "$:/language/Docs/PaletteColours/button-background",
"text": "默认按钮背景"
},
"$:/language/Docs/PaletteColours/button-border": {
"title": "$:/language/Docs/PaletteColours/button-border",
"text": "默认按钮边框"
},
"$:/language/Docs/PaletteColours/button-foreground": {
"title": "$:/language/Docs/PaletteColours/button-foreground",
"text": "默认按钮前景"
},
"$:/language/Docs/PaletteColours/code-background": {
"title": "$:/language/Docs/PaletteColours/code-background",
"text": "代码背景"
},
"$:/language/Docs/PaletteColours/code-border": {
"title": "$:/language/Docs/PaletteColours/code-border",
"text": "代码边框"
},
"$:/language/Docs/PaletteColours/code-foreground": {
"title": "$:/language/Docs/PaletteColours/code-foreground",
"text": "代码前景"
},
"$:/language/Docs/PaletteColours/dirty-indicator": {
"title": "$:/language/Docs/PaletteColours/dirty-indicator",
"text": "未保存变更指示器"
},
"$:/language/Docs/PaletteColours/download-background": {
"title": "$:/language/Docs/PaletteColours/download-background",
"text": "下载按钮背景"
},
"$:/language/Docs/PaletteColours/download-foreground": {
"title": "$:/language/Docs/PaletteColours/download-foreground",
"text": "下载按钮前景"
},
"$:/language/Docs/PaletteColours/dragger-background": {
"title": "$:/language/Docs/PaletteColours/dragger-background",
"text": "拖动区背景"
},
"$:/language/Docs/PaletteColours/dragger-foreground": {
"title": "$:/language/Docs/PaletteColours/dragger-foreground",
"text": "拖动区前景"
},
"$:/language/Docs/PaletteColours/dropdown-background": {
"title": "$:/language/Docs/PaletteColours/dropdown-background",
"text": "下拉背景"
},
"$:/language/Docs/PaletteColours/dropdown-border": {
"title": "$:/language/Docs/PaletteColours/dropdown-border",
"text": "下拉边框"
},
"$:/language/Docs/PaletteColours/dropdown-tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/dropdown-tab-background-selected",
"text": "选定的下拉页签背景"
},
"$:/language/Docs/PaletteColours/dropdown-tab-background": {
"title": "$:/language/Docs/PaletteColours/dropdown-tab-background",
"text": "下拉页签背景"
},
"$:/language/Docs/PaletteColours/dropzone-background": {
"title": "$:/language/Docs/PaletteColours/dropzone-background",
"text": "拖放背景"
},
"$:/language/Docs/PaletteColours/external-link-background-hover": {
"title": "$:/language/Docs/PaletteColours/external-link-background-hover",
"text": "悬停外部链结背景"
},
"$:/language/Docs/PaletteColours/external-link-background-visited": {
"title": "$:/language/Docs/PaletteColours/external-link-background-visited",
"text": "已造访过的外部链结背景"
},
"$:/language/Docs/PaletteColours/external-link-background": {
"title": "$:/language/Docs/PaletteColours/external-link-background",
"text": "外部链结背景"
},
"$:/language/Docs/PaletteColours/external-link-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground-hover",
"text": "悬停外部链结前景"
},
"$:/language/Docs/PaletteColours/external-link-foreground-visited": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground-visited",
"text": "已造访过的外部链结前景"
},
"$:/language/Docs/PaletteColours/external-link-foreground": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground",
"text": "外部链结前景"
},
"$:/language/Docs/PaletteColours/foreground": {
"title": "$:/language/Docs/PaletteColours/foreground",
"text": "一般前景"
},
"$:/language/Docs/PaletteColours/menubar-background": {
"title": "$:/language/Docs/PaletteColours/menubar-background",
"text": "菜单列背景"
},
"$:/language/Docs/PaletteColours/menubar-foreground": {
"title": "$:/language/Docs/PaletteColours/menubar-foreground",
"text": "菜单列前景"
},
"$:/language/Docs/PaletteColours/message-background": {
"title": "$:/language/Docs/PaletteColours/message-background",
"text": "信息框背景"
},
"$:/language/Docs/PaletteColours/message-border": {
"title": "$:/language/Docs/PaletteColours/message-border",
"text": "信息边框"
},
"$:/language/Docs/PaletteColours/message-foreground": {
"title": "$:/language/Docs/PaletteColours/message-foreground",
"text": "信息框前景"
},
"$:/language/Docs/PaletteColours/modal-backdrop": {
"title": "$:/language/Docs/PaletteColours/modal-backdrop",
"text": "模块背景幕"
},
"$:/language/Docs/PaletteColours/modal-background": {
"title": "$:/language/Docs/PaletteColours/modal-background",
"text": "模块背景"
},
"$:/language/Docs/PaletteColours/modal-border": {
"title": "$:/language/Docs/PaletteColours/modal-border",
"text": "模块边框"
},
"$:/language/Docs/PaletteColours/modal-footer-background": {
"title": "$:/language/Docs/PaletteColours/modal-footer-background",
"text": "模块页脚背景"
},
"$:/language/Docs/PaletteColours/modal-footer-border": {
"title": "$:/language/Docs/PaletteColours/modal-footer-border",
"text": "模块页脚边框"
},
"$:/language/Docs/PaletteColours/modal-header-border": {
"title": "$:/language/Docs/PaletteColours/modal-header-border",
"text": "模块标题边框"
},
"$:/language/Docs/PaletteColours/muted-foreground": {
"title": "$:/language/Docs/PaletteColours/muted-foreground",
"text": "一般低调前景"
},
"$:/language/Docs/PaletteColours/notification-background": {
"title": "$:/language/Docs/PaletteColours/notification-background",
"text": "通知背景"
},
"$:/language/Docs/PaletteColours/notification-border": {
"title": "$:/language/Docs/PaletteColours/notification-border",
"text": "通知边框"
},
"$:/language/Docs/PaletteColours/page-background": {
"title": "$:/language/Docs/PaletteColours/page-background",
"text": "页面背景"
},
"$:/language/Docs/PaletteColours/pre-background": {
"title": "$:/language/Docs/PaletteColours/pre-background",
"text": "pre 背景"
},
"$:/language/Docs/PaletteColours/pre-border": {
"title": "$:/language/Docs/PaletteColours/pre-border",
"text": "pre 边框"
},
"$:/language/Docs/PaletteColours/primary": {
"title": "$:/language/Docs/PaletteColours/primary",
"text": "主颜色"
},
"$:/language/Docs/PaletteColours/select-tag-background": {
"title": "$:/language/Docs/PaletteColours/select-tag-background",
"text": "`<select>` 元素背景"
},
"$:/language/Docs/PaletteColours/select-tag-foreground": {
"title": "$:/language/Docs/PaletteColours/select-tag-foreground",
"text": "`<select>` 元素文本"
},
"$:/language/Docs/PaletteColours/sidebar-button-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-button-foreground",
"text": "侧边栏按钮前景"
},
"$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover",
"text": "悬停侧边栏控制项前景"
},
"$:/language/Docs/PaletteColours/sidebar-controls-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground",
"text": "侧边栏控制项前景"
},
"$:/language/Docs/PaletteColours/sidebar-foreground-shadow": {
"title": "$:/language/Docs/PaletteColours/sidebar-foreground-shadow",
"text": "侧边栏前景阴影"
},
"$:/language/Docs/PaletteColours/sidebar-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-foreground",
"text": "侧边栏前景"
},
"$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover",
"text": "悬停侧边栏低调前景"
},
"$:/language/Docs/PaletteColours/sidebar-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground",
"text": "侧边栏低调前景"
},
"$:/language/Docs/PaletteColours/sidebar-tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-background-selected",
"text": "侧边栏选定页签背景"
},
"$:/language/Docs/PaletteColours/sidebar-tab-background": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-background",
"text": "侧边栏页签背景"
},
"$:/language/Docs/PaletteColours/sidebar-tab-border-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-border-selected",
"text": "侧边栏选定页签边框"
},
"$:/language/Docs/PaletteColours/sidebar-tab-border": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-border",
"text": "侧边栏页签边框"
},
"$:/language/Docs/PaletteColours/sidebar-tab-divider": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-divider",
"text": "侧边栏页签分隔线"
},
"$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected",
"text": "侧边栏选定页签前景"
},
"$:/language/Docs/PaletteColours/sidebar-tab-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground",
"text": "侧边栏页签前景"
},
"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover",
"text": "侧边栏悬停条目链结前景"
},
"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground",
"text": "侧边栏条目链结前景"
},
"$:/language/Docs/PaletteColours/site-title-foreground": {
"title": "$:/language/Docs/PaletteColours/site-title-foreground",
"text": "网站标题前景"
},
"$:/language/Docs/PaletteColours/static-alert-foreground": {
"title": "$:/language/Docs/PaletteColours/static-alert-foreground",
"text": "静态警示前景"
},
"$:/language/Docs/PaletteColours/tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/tab-background-selected",
"text": "选定的页签背景"
},
"$:/language/Docs/PaletteColours/tab-background": {
"title": "$:/language/Docs/PaletteColours/tab-background",
"text": "页签背景"
},
"$:/language/Docs/PaletteColours/tab-border-selected": {
"title": "$:/language/Docs/PaletteColours/tab-border-selected",
"text": "选定的页签边框"
},
"$:/language/Docs/PaletteColours/tab-border": {
"title": "$:/language/Docs/PaletteColours/tab-border",
"text": "页签边框"
},
"$:/language/Docs/PaletteColours/tab-divider": {
"title": "$:/language/Docs/PaletteColours/tab-divider",
"text": "页签分隔线"
},
"$:/language/Docs/PaletteColours/tab-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/tab-foreground-selected",
"text": "选定的页签前景"
},
"$:/language/Docs/PaletteColours/tab-foreground": {
"title": "$:/language/Docs/PaletteColours/tab-foreground",
"text": "页签前景"
},
"$:/language/Docs/PaletteColours/table-border": {
"title": "$:/language/Docs/PaletteColours/table-border",
"text": "表格边框"
},
"$:/language/Docs/PaletteColours/table-footer-background": {
"title": "$:/language/Docs/PaletteColours/table-footer-background",
"text": "表格页脚背景"
},
"$:/language/Docs/PaletteColours/table-header-background": {
"title": "$:/language/Docs/PaletteColours/table-header-background",
"text": "表格标题背景"
},
"$:/language/Docs/PaletteColours/tag-background": {
"title": "$:/language/Docs/PaletteColours/tag-background",
"text": "标签背景"
},
"$:/language/Docs/PaletteColours/tag-foreground": {
"title": "$:/language/Docs/PaletteColours/tag-foreground",
"text": "标签前景"
},
"$:/language/Docs/PaletteColours/tiddler-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-background",
"text": "条目背景"
},
"$:/language/Docs/PaletteColours/tiddler-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-border",
"text": "条目边框"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover",
"text": "悬停的条目控制项前景"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected",
"text": "选定的条目控制项前景"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground",
"text": "条目控制项前景"
},
"$:/language/Docs/PaletteColours/tiddler-editor-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-background",
"text": "条目编辑器背景"
},
"$:/language/Docs/PaletteColours/tiddler-editor-border-image": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-border-image",
"text": "条目编辑器边框图片"
},
"$:/language/Docs/PaletteColours/tiddler-editor-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-border",
"text": "条目编辑器边框"
},
"$:/language/Docs/PaletteColours/tiddler-editor-fields-even": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-even",
"text": "条目编辑器中偶数栏位背景"
},
"$:/language/Docs/PaletteColours/tiddler-editor-fields-odd": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd",
"text": "条目编辑器中奇数栏位背景"
},
"$:/language/Docs/PaletteColours/tiddler-info-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-background",
"text": "条目信息面板背景"
},
"$:/language/Docs/PaletteColours/tiddler-info-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-border",
"text": "条目信息面板边框"
},
"$:/language/Docs/PaletteColours/tiddler-info-tab-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-tab-background",
"text": "条目信息面板页签背景"
},
"$:/language/Docs/PaletteColours/tiddler-link-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-link-background",
"text": "条目链结背景"
},
"$:/language/Docs/PaletteColours/tiddler-link-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-link-foreground",
"text": "条目链结前景"
},
"$:/language/Docs/PaletteColours/tiddler-subtitle-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground",
"text": "条目副标题前景"
},
"$:/language/Docs/PaletteColours/tiddler-title-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-title-foreground",
"text": "条目标题前景"
},
"$:/language/Docs/PaletteColours/toolbar-new-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-new-button",
"text": "工具栏 '添加条目' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-options-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-options-button",
"text": "工具栏 '选项' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-save-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-save-button",
"text": "工具栏 '保存' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-info-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-info-button",
"text": "工具栏 '资讯' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-edit-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-edit-button",
"text": "工具栏 '编辑' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-close-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-close-button",
"text": "工具栏 '关闭' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-delete-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-delete-button",
"text": "工具栏 '删除' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-cancel-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-cancel-button",
"text": "工具栏 '取消' 按钮前景"
},
"$:/language/Docs/PaletteColours/toolbar-done-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-done-button",
"text": "工具栏 '完成 按钮前景"
},
"$:/language/Docs/PaletteColours/untagged-background": {
"title": "$:/language/Docs/PaletteColours/untagged-background",
"text": "未设标签的背景"
},
"$:/language/Docs/PaletteColours/very-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/very-muted-foreground",
"text": "非常低调前景"
},
"$:/language/EditTemplate/Body/External/Hint": {
"title": "$:/language/EditTemplate/Body/External/Hint",
"text": "此条目显示保存于主要的 TiddlyWiki 文件之外的内容。你可以编辑其标签和字段,但不能直接编辑内容本身"
},
"$:/language/EditTemplate/Body/Placeholder": {
"title": "$:/language/EditTemplate/Body/Placeholder",
"text": "输入此条目的内容"
},
"$:/language/EditTemplate/Body/Preview/Type/Output": {
"title": "$:/language/EditTemplate/Body/Preview/Type/Output",
"text": "输出"
},
"$:/language/EditTemplate/Field/Remove/Caption": {
"title": "$:/language/EditTemplate/Field/Remove/Caption",
"text": "删除字段"
},
"$:/language/EditTemplate/Field/Remove/Hint": {
"title": "$:/language/EditTemplate/Field/Remove/Hint",
"text": "删除字段"
},
"$:/language/EditTemplate/Field/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Field/Dropdown/Caption",
"text": "字段列表"
},
"$:/language/EditTemplate/Field/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Field/Dropdown/Hint",
"text": "显示字段列表"
},
"$:/language/EditTemplate/Fields/Add/Button": {
"title": "$:/language/EditTemplate/Fields/Add/Button",
"text": "添加"
},
"$:/language/EditTemplate/Fields/Add/Button/Hint": {
"title": "$:/language/EditTemplate/Fields/Add/Button/Hint",
"text": "添加字段至条目"
},
"$:/language/EditTemplate/Fields/Add/Dropdown/System": {
"title": "$:/language/EditTemplate/Fields/Add/Dropdown/System",
"text": "系统字段"
},
"$:/language/EditTemplate/Fields/Add/Dropdown/User": {
"title": "$:/language/EditTemplate/Fields/Add/Dropdown/User",
"text": "使用者字段"
},
"$:/language/EditTemplate/Fields/Add/Name/Placeholder": {
"title": "$:/language/EditTemplate/Fields/Add/Name/Placeholder",
"text": "字段名称"
},
"$:/language/EditTemplate/Fields/Add/Prompt": {
"title": "$:/language/EditTemplate/Fields/Add/Prompt",
"text": "添加字段:"
},
"$:/language/EditTemplate/Fields/Add/Value/Placeholder": {
"title": "$:/language/EditTemplate/Fields/Add/Value/Placeholder",
"text": "字段内容"
},
"$:/language/EditTemplate/Shadow/Warning": {
"title": "$:/language/EditTemplate/Shadow/Warning",
"text": "这是一个默认条目。您做的任何更改将会覆盖来自 <<pluginLink>> 插件的默认版本。"
},
"$:/language/EditTemplate/Shadow/OverriddenWarning": {
"title": "$:/language/EditTemplate/Shadow/OverriddenWarning",
"text": "这是一个修改过的默认条目。删除此条目可以还原为 <<pluginLink>> 插件中的默认版本。"
},
"$:/language/EditTemplate/Tags/Add/Button": {
"title": "$:/language/EditTemplate/Tags/Add/Button",
"text": "添加"
},
"$:/language/EditTemplate/Tags/Add/Button/Hint": {
"title": "$:/language/EditTemplate/Tags/Add/Button/Hint",
"text": "添加标签"
},
"$:/language/EditTemplate/Tags/Add/Placeholder": {
"title": "$:/language/EditTemplate/Tags/Add/Placeholder",
"text": "标签名称"
},
"$:/language/EditTemplate/Tags/ClearInput/Caption": {
"title": "$:/language/EditTemplate/Tags/ClearInput/Caption",
"text": "清除输入"
},
"$:/language/EditTemplate/Tags/ClearInput/Hint": {
"title": "$:/language/EditTemplate/Tags/ClearInput/Hint",
"text": "清除标签输入"
},
"$:/language/EditTemplate/Tags/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Tags/Dropdown/Caption",
"text": "标签清单"
},
"$:/language/EditTemplate/Tags/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Tags/Dropdown/Hint",
"text": "显示标签清单"
},
"$:/language/EditTemplate/Title/BadCharacterWarning": {
"title": "$:/language/EditTemplate/Title/BadCharacterWarning",
"text": "请注意,避免在条目名称中使用这些字符:<<bad-chars>>"
},
"$:/language/EditTemplate/Title/Exists/Prompt": {
"title": "$:/language/EditTemplate/Title/Exists/Prompt",
"text": "目标条目已经存在"
},
"$:/language/EditTemplate/Title/Relink/Prompt": {
"title": "$:/language/EditTemplate/Title/Relink/Prompt",
"text": "将在其他条目的 //tags// 和 //list// 字段中的 ''<$text text=<<fromTitle>>/>'' 改为 ''<$text text=<<toTitle>>/>''"
},
"$:/language/EditTemplate/Title/References/Prompt": {
"title": "$:/language/EditTemplate/Title/References/Prompt",
"text": "下列对此条目的引用,不会自动更新:"
},
"$:/language/EditTemplate/Type/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Type/Dropdown/Caption",
"text": "内容类型清单"
},
"$:/language/EditTemplate/Type/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Type/Dropdown/Hint",
"text": "显示内容类型清单"
},
"$:/language/EditTemplate/Type/Delete/Caption": {
"title": "$:/language/EditTemplate/Type/Delete/Caption",
"text": "删除内容类型"
},
"$:/language/EditTemplate/Type/Delete/Hint": {
"title": "$:/language/EditTemplate/Type/Delete/Hint",
"text": "删除内容类型"
},
"$:/language/EditTemplate/Type/Placeholder": {
"title": "$:/language/EditTemplate/Type/Placeholder",
"text": "内容类型"
},
"$:/language/EditTemplate/Type/Prompt": {
"title": "$:/language/EditTemplate/Type/Prompt",
"text": "类型:"
},
"$:/language/Exporters/StaticRiver": {
"title": "$:/language/Exporters/StaticRiver",
"text": "静态 HTML"
},
"$:/language/Exporters/JsonFile": {
"title": "$:/language/Exporters/JsonFile",
"text": "JSON 文件"
},
"$:/language/Exporters/CsvFile": {
"title": "$:/language/Exporters/CsvFile",
"text": "CSV 文件"
},
"$:/language/Exporters/TidFile": {
"title": "$:/language/Exporters/TidFile",
"text": "\".tid\" 文件"
},
"$:/language/Docs/Fields/_canonical_uri": {
"title": "$:/language/Docs/Fields/_canonical_uri",
"text": "外部图像条目的完整的 URI"
},
"$:/language/Docs/Fields/bag": {
"title": "$:/language/Docs/Fields/bag",
"text": "条目的来源集的名称"
},
"$:/language/Docs/Fields/caption": {
"title": "$:/language/Docs/Fields/caption",
"text": "显示于页签或按钮上的标题文字"
},
"$:/language/Docs/Fields/color": {
"title": "$:/language/Docs/Fields/color",
"text": "条目的 CSS 颜色值"
},
"$:/language/Docs/Fields/component": {
"title": "$:/language/Docs/Fields/component",
"text": "负责[[警示条目|AlertMechanism]]的组件名称"
},
"$:/language/Docs/Fields/created": {
"title": "$:/language/Docs/Fields/created",
"text": "条目的创建日期"
},
"$:/language/Docs/Fields/creator": {
"title": "$:/language/Docs/Fields/creator",
"text": "条目的创建者"
},
"$:/language/Docs/Fields/current-tiddler": {
"title": "$:/language/Docs/Fields/current-tiddler",
"text": "用于缓存[[浏览历史列表|HistoryMechanism]]的最上层条目"
},
"$:/language/Docs/Fields/dependents": {
"title": "$:/language/Docs/Fields/dependents",
"text": "插件的相依插件列表"
},
"$:/language/Docs/Fields/description": {
"title": "$:/language/Docs/Fields/description",
"text": "插件的说明、描述"
},
"$:/language/Docs/Fields/draft.of": {
"title": "$:/language/Docs/Fields/draft.of",
"text": "草稿条目,包含条目的标题、标签、栏位 ..."
},
"$:/language/Docs/Fields/draft.title": {
"title": "$:/language/Docs/Fields/draft.title",
"text": "草稿条目的标题"
},
"$:/language/Docs/Fields/footer": {
"title": "$:/language/Docs/Fields/footer",
"text": "wizard 的注脚"
},
"$:/language/Docs/Fields/icon": {
"title": "$:/language/Docs/Fields/icon",
"text": "条目的标题含有与条目关联的图标"
},
"$:/language/Docs/Fields/library": {
"title": "$:/language/Docs/Fields/library",
"text": "若设为 \"yes\",表示条目应该被保存为一个 JavaScript 程序库"
},
"$:/language/Docs/Fields/list": {
"title": "$:/language/Docs/Fields/list",
"text": "条目的列表,指定一些条目的标题清单"
},
"$:/language/Docs/Fields/list-before": {
"title": "$:/language/Docs/Fields/list-before",
"text": "前条目名称将被添加到条目排序清单中的设置条目名称之前,或若此栏位存在但是空的,则被添加于清单的前端"
},
"$:/language/Docs/Fields/list-after": {
"title": "$:/language/Docs/Fields/list-after",
"text": "当前条目名称将被添加到条目排序清单的设置条目名称之后,或若此栏位存在但是空的,则被添加于清单的尾端"
},
"$:/language/Docs/Fields/modified": {
"title": "$:/language/Docs/Fields/modified",
"text": "条目的最近修改日期与时间"
},
"$:/language/Docs/Fields/modifier": {
"title": "$:/language/Docs/Fields/modifier",
"text": "条目的最近修改者"
},
"$:/language/Docs/Fields/name": {
"title": "$:/language/Docs/Fields/name",
"text": "具可读性的插件条目的名称"
},
"$:/language/Docs/Fields/plugin-priority": {
"title": "$:/language/Docs/Fields/plugin-priority",
"text": "插件条目的优先级数值"
},
"$:/language/Docs/Fields/plugin-type": {
"title": "$:/language/Docs/Fields/plugin-type",
"text": "插件条目的类型"
},
"$:/language/Docs/Fields/released": {
"title": "$:/language/Docs/Fields/released",
"text": "TiddlyWiki 的发布日期"
},
"$:/language/Docs/Fields/revision": {
"title": "$:/language/Docs/Fields/revision",
"text": "条目存放于服务器中的修订版本"
},
"$:/language/Docs/Fields/source": {
"title": "$:/language/Docs/Fields/source",
"text": "条目的网址"
},
"$:/language/Docs/Fields/subtitle": {
"title": "$:/language/Docs/Fields/subtitle",
"text": "一个 wizard 的副标题"
},
"$:/language/Docs/Fields/tags": {
"title": "$:/language/Docs/Fields/tags",
"text": "条目的标签清单"
},
"$:/language/Docs/Fields/text": {
"title": "$:/language/Docs/Fields/text",
"text": "条目的内文"
},
"$:/language/Docs/Fields/throttle.refresh": {
"title": "$:/language/Docs/Fields/throttle.refresh",
"text": "如果存在,则限制此条目的刷新"
},
"$:/language/Docs/Fields/title": {
"title": "$:/language/Docs/Fields/title",
"text": "条目的唯一名称"
},
"$:/language/Docs/Fields/toc-link": {
"title": "$:/language/Docs/Fields/toc-link",
"text": "若设为: \"no\",则抑制目录树中的条目链接。"
},
"$:/language/Docs/Fields/type": {
"title": "$:/language/Docs/Fields/type",
"text": "条目的内容类型"
},
"$:/language/Docs/Fields/version": {
"title": "$:/language/Docs/Fields/version",
"text": "插件的版本信息"
},
"$:/language/Docs/Fields/_is_skinny": {
"title": "$:/language/Docs/Fields/_is_skinny",
"text": "如果存在,则表示必须从服务器加载条目的文本字段"
},
"$:/language/Filters/AllTiddlers": {
"title": "$:/language/Filters/AllTiddlers",
"text": "所有条目,不含系统条目"
},
"$:/language/Filters/RecentSystemTiddlers": {
"title": "$:/language/Filters/RecentSystemTiddlers",
"text": "最近修改的条目,包含系统条目"
},
"$:/language/Filters/RecentTiddlers": {
"title": "$:/language/Filters/RecentTiddlers",
"text": "最近修改的条目"
},
"$:/language/Filters/AllTags": {
"title": "$:/language/Filters/AllTags",
"text": "所有标签,不含系统标签"
},
"$:/language/Filters/Missing": {
"title": "$:/language/Filters/Missing",
"text": "缺失条目"
},
"$:/language/Filters/Drafts": {
"title": "$:/language/Filters/Drafts",
"text": "草稿条目"
},
"$:/language/Filters/Orphans": {
"title": "$:/language/Filters/Orphans",
"text": "孤立条目"
},
"$:/language/Filters/SystemTiddlers": {
"title": "$:/language/Filters/SystemTiddlers",
"text": "系统条目"
},
"$:/language/Filters/ShadowTiddlers": {
"title": "$:/language/Filters/ShadowTiddlers",
"text": "默认条目"
},
"$:/language/Filters/OverriddenShadowTiddlers": {
"title": "$:/language/Filters/OverriddenShadowTiddlers",
"text": "被覆写的默认条目"
},
"$:/language/Filters/SessionTiddlers": {
"title": "$:/language/Filters/SessionTiddlers",
"text": "自维基加载后修改的条目"
},
"$:/language/Filters/SystemTags": {
"title": "$:/language/Filters/SystemTags",
"text": "系统标签"
},
"$:/language/Filters/StoryList": {
"title": "$:/language/Filters/StoryList",
"text": "故事河中的条目,不含 ~$:/AdvancedSearch"
},
"$:/language/Filters/TypedTiddlers": {
"title": "$:/language/Filters/TypedTiddlers",
"text": "非维基文字条目"
},
"GettingStarted": {
"title": "GettingStarted",
"text": "\\define lingo-base() $:/language/ControlPanel/Basics/\n欢迎使用 ~TiddlyWiki 及参与 ~TiddlyWiki 社群\n\n开始将重要资讯存放于 ~TiddlyWiki 之前,确认您可以可靠地保存变更是很重要的。详细资讯请参阅 https://tiddlywiki.com/#GettingStarted\n\n!! 设置此 ~TiddlyWiki\n\n<div class=\"tc-control-panel\">\n\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n</div>\n\n请参阅[[控制台|$:/ControlPanel]]查看更多选项。"
},
"$:/language/Help/build": {
"title": "$:/language/Help/build",
"description": "自动执行已配置的命令",
"text": "生成指定的生成目标为当前 wiki。若未指定任何生成目标,则生成所有可用的目标。\n\n```\n--build <target> [<target> ...]\n```\n\n生成目标在 wiki 文件夹的 `tiddlywiki.info` 文件中定义。\n"
},
"$:/language/Help/clearpassword": {
"title": "$:/language/Help/clearpassword",
"description": "清除用于后续加密的密码",
"text": "清除用于后续加密的密码\n\n```\n--clearpassword\n```\n"
},
"$:/language/Help/default": {
"title": "$:/language/Help/default",
"text": "\\define commandTitle()\n$:/language/Help/$(command)$\n\\end\n```\n用法: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]\n```\n\n可用的命令:\n\n<ul>\n<$list filter=\"[commands[]sort[title]]\" variable=\"command\">\n<li><$link to=<<commandTitle>>><$macrocall $name=\"command\" $type=\"text/plain\" $output=\"text/plain\"/></$link>: <$transclude tiddler=<<commandTitle>> field=\"description\"/></li>\n</$list>\n</ul>\n\n取得关于某个命令的详细帮助:\n\n```\ntiddlywiki --help <command>\n```\n"
},
"$:/language/Help/deletetiddlers": {
"title": "$:/language/Help/deletetiddlers",
"description": "删除一组条目",
"text": "<<.from-version \"5.1.20\">> 删除由筛选器标识的一组条目。\n\n```\n--deletetiddlers <filter>\n```\n"
},
"$:/language/Help/editions": {
"title": "$:/language/Help/editions",
"description": "列出可用的 TiddlyWiki 版本",
"text": "列出可用版本的名称和描述。您可以用 `--init` 命令创建一个指定版本的新维基。\n\n```\n--editions\n```\n"
},
"$:/language/Help/fetch": {
"title": "$:/language/Help/fetch",
"description": "通过网址从维基撷取条目",
"text": "通过 HTTP/HTTPS 撷取一个或多个文件,并导入匹配筛选器的条目,可选的转换传入的名称。\n\n```\n--fetch file <url> <import-filter> <transform-filter>\n--fetch files <url-filter> <import-filter> <transform-filter>\n--fetch raw-file <url> <transform-filter>\n--fetch raw-files <url-filter> <transform-filter>\n```\n\n \"file\" 和 \"files\" 选项撷取指定的文件,并尝试导入其中的条目(与将文件拖动到浏览器视窗中的处理相同)。 \"raw-file\" 和 \"raw-files\" 变选项撷取指定的文件,并将原始文件资料存储于条目,而不套用导入逻辑。\n\n使用 \"file\" and \"raw-file\" 选项为仅撷取单个文件,且第一个参数为要读取文件的网址。\n\n使用 \"files\" 和 \"raw-files\" 选项为撷取多个文件,且第一个参数是一个产生要读取文件的网址清单的筛选器。例如,给定标签为 \"remote-server\" 的一组具有字段 \"url\" 的条目,筛选器 `[tag[remote-server]get[url]]` 将取回所有可用的网址。\n\n对于 \"file\" 和 \"files\" 选项,the `<import-filter>` 参数指定一个筛选器,用于确定要导入哪些条目。如果未提供,则默认为 `[all[tiddlers]]`。\n\n对于所有选项,`<transform-filter>` 参数指定一个可选的筛选器,用于转换导入条目的名称。例如,`[addprefix[$:/myimports/]]` 会将前缀 `$:/myimports/` 加至每个名称。\n\n于 `--fetch` 之前使用 `--verbose` 命令,将在导入期间输出进度信息。\n\n请注意,TiddlyWiki 不会撷取一个已经加载插件的旧版本。\n\n以下示例从 https://tiddlywiki.com 取回所有非系统条目,并将其保存到一个 JSON 文件:\n\n```\ntiddlywiki --verbose --fetch file \"https://tiddlywiki.com/\" \"[!is[system]]\" \"\" --rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[!is[system]]\"\n```\n\n以下范例从 https://tiddlywiki.com 取回 \"favicon\" 文件,并将其保存在名为 \"output.ico\" 的文件中。请注意,在 \"--fetch\" 命令中引用的中间条目 \"Icon Tiddler\",因为它被用作转换筛选器来替换预设的名称,而 \"--savetiddler\" 命令没有引号,因为它是直接用作标题。\n\n```\ntiddlywiki --verbose --fetch raw-file \"https://tiddlywiki.com/favicon.ico\" \"[[Icon Tiddler]]\" --savetiddler \"Icon Tiddler\" output.ico\n```\n"
},
"$:/language/Help/help": {
"title": "$:/language/Help/help",
"description": "显示 TiddlyWiki 命令的说明",
"text": "显示命令的帮助文本:\n\n```\n--help [<command>]\n```\n\n若省略命令名称,则显示可用命令的清单。\n"
},
"$:/language/Help/import": {
"title": "$:/language/Help/import",
"description": "从文件导入条目",
"text": "从 TiddlyWiki 文件 (`.html`)、`.tiddler`、`.tid`、`.json` 或其他本机文件导入条目。必须明确指定解串器,而不像 load 命令,从文件扩展名推断解串器。\n\n```\n--import <filepath> <deserializer> [<title>] [<encoding>]\n```\n\n核心的解串器包括:\n\n* application/javascript\n* application/json\n* application/x-tiddler\n* application/x-tiddler-html-div\n* application/x-tiddlers\n* text/html\n* text/plain\n\n导入的条目名称,默认为文件名。\n\n编码默认为 \"utf8\",但用于导入二进制文件可以是 \"base64\"。\n\n请注意,TiddlyWiki 不会导入旧版本的已加载插件。\n"
},
"$:/language/Help/init": {
"title": "$:/language/Help/init",
"description": "初始化一个新的 wiki 文件夹",
"text": "初始化一个空的 [[WikiFolder|WikiFolders]] 的指定版本的副本。\n\n```\n--init <edition> [<edition> ...]\n```\n\n例如:\n\n```\ntiddlywiki ./MyWikiFolder --init empty\n```\n\n注意:\n\n* 若有需要,将创建 wiki 文件夹目录\n* 其中 \"edition\" 默认为 ''empty''\n* 若 wiki 文件夹不是空的,则初始化命令将失败\n* 初始化命令会删除 'tiddlywiki.info' 文件内所有 'includeWikis' 的定义。\n* 当指定多个版本时,这些版本于初始化后,将覆写早期版本共用的所有文件 (故此最终的 `tiddlywiki.info` 文件将是从最近的版本复制而得)\n* `--editions` 传回所有可用版本的清单。\n"
},
"$:/language/Help/listen": {
"title": "$:/language/Help/listen",
"description": "为 TiddlyWiki 提供一个 HTTP 服务器接口",
"text": "通过 HTTP 提供一个维基服务。\n\nlisten 命令使用[[命名的命令参数|NamedCommandParameters]]:\n\n```\n--listen [<name>=<value>]...\n```\n\n所有参数都是可选的, 具有安全的默认值, 可以按任意顺序指定。认可的参数有:\n\n* ''host'' - 可选的主机名称, (默认为 \"127.0.0.1\" 或名为 \"localhost\")\n* ''path-prefix'' - 可选的路径前缀\n* ''port'' - 侦听的埠号;非数值会被解译为一个系统环境变数,从其中提取埠号 (默认为 \"8080\")\n* ''credentials'' - 凭证 CSV 文件的路径名(相对于维基文件夹)\n* ''anon-username'' - 匿名用户的编辑署名\n* ''username'' - 可选的基本验证用户名称\n* ''password'' - 可选的基本验证密码\n* ''authenticated-user-header'' - 可选的标头名称,用于受信任身份验证\n* ''readers'' - 允许读取此维基的主体,以逗号分隔的清单\n* ''writers'' - 允许写入此维基的主体,以逗号分隔的清单\n* ''csrf-disable'' - 设置为 \"yes\" 以禁用 CSRF 检查 (默认为 \"no\")\n* ''root-tiddler'' - 服务的基本条目 (默认为 \"$:/core/save/all\")\n* ''root-render-type'' - 呈现的基本条目的内容类型 (默认为 \"text/plain\")\n* ''root-serve-type'' - 服务的基本条目的内容类型 (默认为 \"text/html\")\n* ''tls-cert'' - TLS 证书文件的路径名(相对于维基文件夹)\n* ''tls-key'' - TLS 密钥文件的路径名(相对于维基文件夹)\n* ''debug-level'' - 可选的调试级别;设置为 \"debug\" 来查看请求的详细信息;(默认为 \"none\")\n* ''gzip'' - 设为 \"yes\" 以启用某些 http 端点的 gzip 压缩 (默认为 \"no\")\n\n有关向整个本地网络开启实例的信息,以及可能的安全问题,请参阅 TiddlyWiki.com 的 WebServer 条目。\n"
},
"$:/language/Help/load": {
"title": "$:/language/Help/load",
"description": "从文件中加载条目",
"text": "从 TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` 或其他本机文件加载条目。应用的处理程序取决于导入文件的扩展名。如果您需要明确指定解串器和编码,请改用 `import` 命令。\n\n```\n--load <filepath> [noerror]\n--load <dirpath> [noerror]\n```\n\n默认情况下, 如果未找到条目,load 命令会引发错误。通过提供可选的 \"noerror\" 参数可以抑制该错误。\n\n从已加密的 TiddlyWiki 文件中加载条目,须使用 PasswordCommand 指定密码,例如:\n\n```\ntiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html\n```\n\n请注意 TiddlyWiki 将不加载旧版本的已挂载的插件。\n"
},
"$:/language/Help/makelibrary": {
"title": "$:/language/Help/makelibrary",
"description": "构建升级处理所需的程式库插件",
"text": "为升级处理构建 `$:/UpgradeLibrary` 条目。\n\n升级程式库被格式化为一个插件类型为 `library` 的一般插件条目。它包含 TiddlyWiki5 存储库中所有可用的插件、布景主题和语言包的副本。\n\n此命令仅供内部使用;它只是与使用者构建一个自订的升级程序相关。\n\n```\n--makelibrary <title>\n```\n\n标题参数默认为 `$:/UpgradeLibrary`。\n"
},
"$:/language/Help/notfound": {
"title": "$:/language/Help/notfound",
"text": "无此帮助项目"
},
"$:/language/Help/output": {
"title": "$:/language/Help/output",
"description": "设置后续命令的基准输出文件夹",
"text": "设置后续命令的基准输出文件夹,默认为该版本文件夹的 `output` 子文件夹。\n\n```\n--output <pathname>\n```\n\n若指定的路径是相对路径,则它是被解析相对于当前的工作文件夹。例如:`--output .` 將輸出文件夹設置為當前工作文件夹。"
},
"$:/language/Help/password": {
"title": "$:/language/Help/password",
"description": "设置用以加密的密码",
"text": "设置用以加密的密码\n\n```\n--password <password>\n```\n\n''请注意'':这不是用于提供 TiddlyWiki 具有密码保护功能。相反地,请看 [[ServerCommand]] 的密码选项说明。\n"
},
"$:/language/Help/render": {
"title": "$:/language/Help/render",
"description": "呈现个别条目到文件",
"text": "呈现由筛选器标识的个别条目,并将结果保存到指定的文件。\n\n可选择性地指定范本条目名称。在此情况下,不是直接呈现每个条目,而是使用设为正在呈现的条目名称的 \"currentTiddler\" 变量,来呈现范本条目。\n\n也可以选择性地指定附加变量的名称和值。\n\n```\n--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [<name>] [<value>]\n```\n\n* ''tiddler-filter'': 标识要呈现的条目的筛选器\n* ''filename-filter'': 可选的筛选器,转换条目名称至路径名。如果省略,默认为 `[is[tiddler]addsuffix[.html]]`,其使用未改变的条目名称为文件名\n* ''template'': 可选的范本,用于呈现每个条目\n* ''render-type'': 可选的呈现类型:`text/html` (默认值) 会传回完整的 HTML 文本,而 `text/plain` 只会传回文本内容 (即其忽略 HTML 标记与其他不可印出的数据)\n* ''name'': 可选的变量名称\n* ''value'': 可选的变量值\n\n默认情况下,文件名被解析为相对于发行版文件夹的 `output` 子文件夹。`--output` 命令可用于将输出指到一个不同的文件夹。\n\n附注:\n\n* 输出目录不清除任何现有的文件\n* 文件名的路径中,任何不存在的文件夹,将自动创建。\n* 当正呈现的条目名称中带有空格,请注意同时使用命令行接口所要求的引号,与 TiddlyWiki 的双重方括号;`--render \"[[Motovun Jack.jpg]]\"`\n* 所选的项目被设置为当前正在呈现的条目名称,以此评估文件名筛选器,允条目名称用作基础计算的文件名。例如,`[encodeuricomponent[]addprefix[static/]]` 为每个条目名称套用 URI 编码,然后增加首码 `static/`\n* `--render` 命令是已弃用的 `--rendertiddler` 和 `--rendertiddlers` 的一个更灵活的替代命令。\n\n例子:\n\n* `--render \"[!is[system]]\" \"[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]\"` -- 呈现所有非系统条目为 \"tiddlers\" 子文件夹中的文件,文件名为 URL 编码的条目名称和扩展名 HTML\n"
},
"$:/language/Help/rendertiddler": {
"title": "$:/language/Help/rendertiddler",
"description": "呈现个别条目为指定的内容类型",
"text": "(请注意:`--rendertiddler` 命令已被弃用,而支持新的、更灵活的 `--render` 命令)\n\n呈现个别条目为指定的[[内容类型|ContentType]],默认为 `text/html` 且保存为指定的文件名。\n\n还可以指定一个模板,在这种情况下,\"currentTiddler\" 变量设为正在呈现的条目 (第一个参数值) 与模板条目合并呈现。\n\n也能可选地指定附加变量的名称与其值。\n\n```\n--rendertiddler <title> <filename> [<type>] [<template>]\n```\n\n默认情况下,文件名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件夹。\n\n自动创建在文件名称的路径中任何缺少的文件夹。\n\n例如,以下命令通过使用核心模板 `$:/core/templates/exporters/JsonFile`,将所有匹配筛选器 `[tag[done]]` 的条目保存到名为 `output.json` 的 JSON 文件。\n\n```\n--rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[tag[done]]\"\n```"
},
"$:/language/Help/rendertiddlers": {
"title": "$:/language/Help/rendertiddlers",
"description": "呈现符合筛选条件的条目为指定的内容类型",
"text": "(请注意:`--rendertiddlers` 命令已被弃用,而支持新的、更灵活的 `--render` 命令)\n\n呈现符合筛选条的条目为指定的[[内容类型|ContentType]] (默认为 `text/html`) 与扩展名 (默认为 `.html`).\n\n```\n--rendertiddlers '<filter>' <template> <pathname> [<type>] [<extension>] [\"noclean\"]\n```\n\n例如:\n\n```\n--rendertiddlers '[!is[system]]' $:/core/templates/static.tiddler.html ./static text/plain\n```\n\n默认情况下,路径名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件。\n\n在目标文件夹中的任何文件都会被删除,除非指定 ''noclean'' 旗标。若缺少目标文件夹,则以递归方式创建。"
},
"$:/language/Help/save": {
"title": "$:/language/Help/save",
"description": "将个别原始条目保存到文件",
"text": "将筛选器标识的个别条目,以原始文本或二进位格式,保存到指定的文件。\n\n```\n--save <tiddler-filter> <filename-filter>\n```\n\n* ''tiddler-filter'': 标识要保存的条目的筛选器\n* ''filename-filter'': 可选的筛选器,转换条目名称至路径名。如果省略,默认为 `[is[tiddler]]`,其使用未改变的条目名称为文件名\n\n附注:\n\n* 输出文件夹不清除任何现有的文件\n* 文件名的路径中,任何不存在的文件夹,将自动创建。\n* 当正保存的条目的名称中带有空格,请注意同时使用命令行接口所要求的引号,与 TiddlyWiki 的双重方括号;`--save \"[[Motovun Jack.jpg]]\"`\n* 所选的项目被设置为当前正在保存的条目名称,以此评估文件名筛选器,允条目名称用作基础计算的文件名。例如,`[encodeuricomponent[]addprefix[static/]]` 为每个条目名称套用 URI 编码,然后增加首码 `static/`\n* `--save` 命令是已被弃用的 `--savetiddler` 和 `--savetiddlers` 的一个更灵活的替代命令。\n\n例子:\n\n* `--save \"[!is[system]is[image]]\" \"[encodeuricomponent[]addprefix[tiddlers/]]\"` -- 保存所有非系统的图像条目为 \"tiddlers\" 子文件夹中的文件,文件名为 URL 编码的条目名称"
},
"$:/language/Help/savetiddler": {
"title": "$:/language/Help/savetiddler",
"description": "将条目的原始内容保存到一个文件",
"text": "(请注意:`--savetiddler` 命令已被弃用,而支持新的、更灵活的 `--save` 命令)\n\n保存个别条目的原始文本或二进制格式到指定的文件名。\n\n```\n--savetiddler <title> <filename>\n```\n\n默认情况下,文件名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件。\n\n自动创建在文件名称的路径中任何缺少的文件夹。\n"
},
"$:/language/Help/savetiddlers": {
"title": "$:/language/Help/savetiddlers",
"description": "将一群条目的原始内容保存到一个文件夹",
"text": "(请注意:`--savetiddlers` 命令已被弃用,而支持新的、更灵活的 `--save` 命令)\n\n保存一群条目的原始文字或二进制格式到指定的文件夹。\n\n```\n--savetiddlers <filter> <pathname> [noclean]\n```\n\n默认情况下,路径名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件夹。\n\n保存指定的文件之前,会先清除输出目录的现有文件。可藉由指定 ''noclean'' 旗标,禁用该删除动作。\n\n自动创建在路径中任何缺少的文件夹。\n"
},
"$:/language/Help/savewikifolder": {
"title": "$:/language/Help/savewikifolder",
"description": "将维基保存到一个新的维基文件夹",
"text": "<<.from-version \"5.1.20\">> 将当前维基保存为一个维基文件夹,包含条目、插件和配置:\n\n```\n--savewikifolder <wikifolderpath> [<filter>]\n```\n\n* 目标维基文件夹必须为空或不存在\n* 筛选器指定应包括哪些条目。其为可选,默认为 `[all[tiddlers]]`\n* 官方插件库中的插件,将替换为 `tiddlywiki.info` 文件中引用到的插件\n* 自订插件将解压缩到自己的文件夹中\n\n常见的用法是将一个 TiddlyWiki HTML 文件转换成维基文件夹:\n\n```\ntiddlywiki --load ./mywiki.html --savewikifolder ./mywikifolder\n```\n"
},
"$:/language/Help/server": {
"title": "$:/language/Help/server",
"description": "提供一个 HTTP 服务器介面到 TiddlyWiki (已弃用,支持新的 listen 命令)",
"text": "在服务器中内置 TiddlyWiki5 是非常简单。虽与 TiddlyWeb 兼容,但不支持许多健全互联网面向的使用方式所需的功能。\n\n提供呈现一个指定条目,也可将个别条目编码成 JSON,且支持基本的 HTTP 操作 `GET`、`PUT` 及 `DELETE`.\n\n```\n--server <port> <root-tiddler> <root-render-type> <root-serve-type> <username> <password> <host> <path-prefix> <debug-level>\n```\n\n参数说明:\n\n* ''port'' - 要侦听的埠号;非数值会被解译为一个系统环境变数,从其中提取埠号 (默认为 \"8080\")\n* ''root-tiddler'' - 服务的基本条目 (默认为 \"$:/core/save/all\")\n* ''root-render-type'' - 呈现的基本条目的内容类型 (默认为 \"text/plain\")\n* ''root-serve-type'' - 服务的基本条目的内容类型 (默认为 \"text/html\")\n* ''username'' - 默认的编辑者署名\n* ''password'' - 可选的基本验证密码\n* ''host'' - 可选的主机名称, (默认为 \"127.0.0.1\" 或名为 \"localhost\")\n* ''path-prefix'' - 可选的路径前缀\n* ''debug-level'' - 可选的调试级别;设置为 \"debug\" 来查看请求的详细信息;(默认为 \"none\")\n\n若指定密码参数,浏览器将提示使用者输入用户名与密码。注意,密码系以明码方式传递,应只在受信任的网络或 HTTPS 上使用。\n\n例如:\n\n```\n--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n\n若您需要设置主机名称或路径前缀,而不要求输入密码,则可以指定空字符串的使用者名和密码。\n\n```\n--server 8080 $:/core/save/all text/plain text/html \"\" \"\" 192.168.0.245\n```\n\n使用这样的位址,会将您的系统暴露给本地网络。有关向整个本地网络开启实例的信息,以及可能的安全问题,请参阅 TiddlyWiki.com 的 WebServer 条目。\n\n同时执行多个 TiddlyWiki 服务,须分别指定不同的埠号。使用环境变数,有助于将埠号传递给 Node.js 进程。本示例引用一个名为 \"MY_PORT_NUMBER\" 的环境变数:\n\n```\n--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd\n```"
},
"$:/language/Help/setfield": {
"title": "$:/language/Help/setfield",
"description": "准备用于外部条目",
"text": "//请注意此命令是试验性的,且可能会更改或在最终定稿前被替换//\n\n设置一群条目的指定栏位到 wikifying 范本条目的结果,其中的 `currentTiddler` 变数设置为各该条目。\n\n```\n--setfield <filter> <fieldname> <templatetitle> <rendertype>\n```\n\n参数说明:\n\n* ''filter'' - 受影响的辨识条目的筛选条件\n* ''fieldname'' - 要修改的栏位(默认为 \"text\")\n* ''templatetitle'' - 该条目 wikify 到指定栏位。若为空白或丢失,则删除指定的栏位\n* ''rendertype'' - 要呈现的文本类型(默认为 \"text/plain\"; \"text/html\" 可以用于包含 HTML 标记))\n"
},
"$:/language/Help/unpackplugin": {
"title": "$:/language/Help/unpackplugin",
"description": "从插件解开附属的条目",
"text": "提取插件的附属条目,将其建立为一般条目:\n\n```\n--unpackplugin <title>\n```\n"
},
"$:/language/Help/verbose": {
"title": "$:/language/Help/verbose",
"description": "触发详细的输出模式",
"text": "触发显示详细的命令执行过程,可用于调试\n\n```\n--verbose\n```\n"
},
"$:/language/Help/version": {
"title": "$:/language/Help/version",
"description": "显示 TiddlyWiki 的版本编号",
"text": "显示 TiddlyWiki 的版本编号。\n\n```\n--version\n```\n"
},
"$:/language/Import/Imported/Hint": {
"title": "$:/language/Import/Imported/Hint",
"text": "下列条目已被导入:"
},
"$:/language/Import/Listing/Cancel/Caption": {
"title": "$:/language/Import/Listing/Cancel/Caption",
"text": "取消"
},
"$:/language/Import/Listing/Hint": {
"title": "$:/language/Import/Listing/Hint",
"text": "这些条目已备妥导入:"
},
"$:/language/Import/Listing/Import/Caption": {
"title": "$:/language/Import/Listing/Import/Caption",
"text": "导入"
},
"$:/language/Import/Listing/Select/Caption": {
"title": "$:/language/Import/Listing/Select/Caption",
"text": "选择"
},
"$:/language/Import/Listing/Status/Caption": {
"title": "$:/language/Import/Listing/Status/Caption",
"text": "状态"
},
"$:/language/Import/Listing/Title/Caption": {
"title": "$:/language/Import/Listing/Title/Caption",
"text": "条目"
},
"$:/language/Import/Listing/Preview": {
"title": "$:/language/Import/Listing/Preview",
"text": "预览:"
},
"$:/language/Import/Listing/Preview/Text": {
"title": "$:/language/Import/Listing/Preview/Text",
"text": "文本"
},
"$:/language/Import/Listing/Preview/TextRaw": {
"title": "$:/language/Import/Listing/Preview/TextRaw",
"text": "文本 (原始)"
},
"$:/language/Import/Listing/Preview/Fields": {
"title": "$:/language/Import/Listing/Preview/Fields",
"text": "字段"
},
"$:/language/Import/Listing/Preview/Diff": {
"title": "$:/language/Import/Listing/Preview/Diff",
"text": "差异"
},
"$:/language/Import/Listing/Preview/DiffFields": {
"title": "$:/language/Import/Listing/Preview/DiffFields",
"text": "差异 (字段)"
},
"$:/language/Import/Listing/Rename/Prompt": {
"title": "$:/language/Import/Listing/Rename/Prompt",
"text": "重新命名为:"
},
"$:/language/Import/Listing/Rename/Tooltip": {
"title": "$:/language/Import/Listing/Rename/Tooltip",
"text": "导入前重新命名条目"
},
"$:/language/Import/Listing/Rename/ConfirmRename": {
"title": "$:/language/Import/Listing/Rename/ConfirmRename",
"text": "重新命名条目"
},
"$:/language/Import/Listing/Rename/CancelRename": {
"title": "$:/language/Import/Listing/Rename/CancelRename",
"text": "取消"
},
"$:/language/Import/Listing/Rename/OverwriteWarning": {
"title": "$:/language/Import/Listing/Rename/OverwriteWarning",
"text": "具有此标题的条目已存在。"
},
"$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible": {
"title": "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible",
"text": "封锁的不兼容或过时插件。"
},
"$:/language/Import/Upgrader/Plugins/Suppressed/Version": {
"title": "$:/language/Import/Upgrader/Plugins/Suppressed/Version",
"text": "封锁的插件 (由于传入的 <<incoming>> 不比现有版本 <<existing>> 新)。"
},
"$:/language/Import/Upgrader/Plugins/Upgraded": {
"title": "$:/language/Import/Upgrader/Plugins/Upgraded",
"text": "升级插件,从 <<incoming>> 到 <<upgraded>>。"
},
"$:/language/Import/Upgrader/State/Suppressed": {
"title": "$:/language/Import/Upgrader/State/Suppressed",
"text": "封锁的暂存状态条目。"
},
"$:/language/Import/Upgrader/System/Suppressed": {
"title": "$:/language/Import/Upgrader/System/Suppressed",
"text": "封锁的系统条目。"
},
"$:/language/Import/Upgrader/System/Warning": {
"title": "$:/language/Import/Upgrader/System/Warning",
"text": "核心模块条目。"
},
"$:/language/Import/Upgrader/System/Alert": {
"title": "$:/language/Import/Upgrader/System/Alert",
"text": "您即将导入一个条目会覆盖一个核心模块条目。不建议这样做,因为可能会使系统不稳定。"
},
"$:/language/Import/Upgrader/ThemeTweaks/Created": {
"title": "$:/language/Import/Upgrader/ThemeTweaks/Created",
"text": "从 <$text text=<<from>>/> 迁移布景主题。"
},
"$:/language/AboveStory/ClassicPlugin/Warning": {
"title": "$:/language/AboveStory/ClassicPlugin/Warning",
"text": "您貌似要加载为 ~TiddlyWiki 经典版设计的插件。请注意,[[这些插件无法运行于 TiddlyWiki 5.x.x 版|https://tiddlywiki.com/#TiddlyWikiClassic]]。检测到 ~TiddlyWiki 经典版插件:"
},
"$:/language/BinaryWarning/Prompt": {
"title": "$:/language/BinaryWarning/Prompt",
"text": "此条目包含二进制数据"
},
"$:/language/ClassicWarning/Hint": {
"title": "$:/language/ClassicWarning/Hint",
"text": "此条目以经典版 TiddlyWiki 标记格式撰写,不完全兼容新版 TiddlyWiki 的格式,详细信息请参阅:https://tiddlywiki.com/static/Upgrading。"
},
"$:/language/ClassicWarning/Upgrade/Caption": {
"title": "$:/language/ClassicWarning/Upgrade/Caption",
"text": "升级"
},
"$:/language/CloseAll/Button": {
"title": "$:/language/CloseAll/Button",
"text": "全部关闭"
},
"$:/language/ColourPicker/Recent": {
"title": "$:/language/ColourPicker/Recent",
"text": "最近︰"
},
"$:/language/ConfirmCancelTiddler": {
"title": "$:/language/ConfirmCancelTiddler",
"text": "您确定要放弃对条目 \"<$text text=<<title>>/>\" 的更改?"
},
"$:/language/ConfirmDeleteTiddler": {
"title": "$:/language/ConfirmDeleteTiddler",
"text": "您确定要删除条目 \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmOverwriteTiddler": {
"title": "$:/language/ConfirmOverwriteTiddler",
"text": "您确定要复写条目 \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmEditShadowTiddler": {
"title": "$:/language/ConfirmEditShadowTiddler",
"text": "您即将要编辑默认条目,任何更改将会复盖默认的系统,使未来的升级不寻常。您确定要编辑 \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmAction": {
"title": "$:/language/ConfirmAction",
"text": "是否要继续?"
},
"$:/language/Count": {
"title": "$:/language/Count",
"text": "计数"
},
"$:/language/DefaultNewTiddlerTitle": {
"title": "$:/language/DefaultNewTiddlerTitle",
"text": "新条目"
},
"$:/language/Diffs/CountMessage": {
"title": "$:/language/Diffs/CountMessage",
"text": "<<diff-count>> 个差异"
},
"$:/language/DropMessage": {
"title": "$:/language/DropMessage",
"text": "拖放到此处 (或按 ESC 键取消)"
},
"$:/language/Encryption/Cancel": {
"title": "$:/language/Encryption/Cancel",
"text": "取消"
},
"$:/language/Encryption/ConfirmClearPassword": {
"title": "$:/language/Encryption/ConfirmClearPassword",
"text": "您要清除密码吗?当保存此维基时,这将删除已套用的加密"
},
"$:/language/Encryption/Username": {
"title": "$:/language/Encryption/Username",
"text": "用户名称"
},
"$:/language/Encryption/Password": {
"title": "$:/language/Encryption/Password",
"text": "密码"
},
"$:/language/Encryption/PromptSetPassword": {
"title": "$:/language/Encryption/PromptSetPassword",
"text": "为此 TiddlyWiki 设置一个新密码"
},
"$:/language/Encryption/RepeatPassword": {
"title": "$:/language/Encryption/RepeatPassword",
"text": "重复输入密码"
},
"$:/language/Encryption/PasswordNoMatch": {
"title": "$:/language/Encryption/PasswordNoMatch",
"text": "密码不匹配"
},
"$:/language/Encryption/SetPassword": {
"title": "$:/language/Encryption/SetPassword",
"text": "设定密码"
},
"$:/language/Error/Caption": {
"title": "$:/language/Error/Caption",
"text": "错误"
},
"$:/language/Error/EditConflict": {
"title": "$:/language/Error/EditConflict",
"text": "服务器上的文件已更改"
},
"$:/language/Error/Filter": {
"title": "$:/language/Error/Filter",
"text": "筛选器错误"
},
"$:/language/Error/FilterRunPrefix": {
"title": "$:/language/Error/FilterRunPrefix",
"text": "筛选器错误:筛选器 run 的未知首码"
},
"$:/language/Error/FilterSyntax": {
"title": "$:/language/Error/FilterSyntax",
"text": "筛选器运算式中的语法错误"
},
"$:/language/Error/FormatFilterOperator": {
"title": "$:/language/Error/FormatFilterOperator",
"text": "筛选器错误:`format` 筛选器运算符的未知尾码"
},
"$:/language/Error/IsFilterOperator": {
"title": "$:/language/Error/IsFilterOperator",
"text": "筛选器错误︰'is' 筛选器运算符的未知操作数"
},
"$:/language/Error/LoadingPluginLibrary": {
"title": "$:/language/Error/LoadingPluginLibrary",
"text": "加载插件程式库时,发生错误"
},
"$:/language/Error/NetworkErrorAlert": {
"title": "$:/language/Error/NetworkErrorAlert",
"text": "`<h2>''网络错误''</h2>与服务器的连缐似乎已中断。这可能表示您的网络连缐有问题。请尝试恢复网路连缐才能继续。<br><br>''恢复连缐时,所有未保存的更改,将自动同步''。`"
},
"$:/language/Error/RecursiveTransclusion": {
"title": "$:/language/Error/RecursiveTransclusion",
"text": "于 transclude 小部件中的递回嵌入错误"
},
"$:/language/Error/RetrievingSkinny": {
"title": "$:/language/Error/RetrievingSkinny",
"text": "简要条目清单撷取错误"
},
"$:/language/Error/SavingToTWEdit": {
"title": "$:/language/Error/SavingToTWEdit",
"text": "保存到 TWEdit 时,发生错误"
},
"$:/language/Error/WhileSaving": {
"title": "$:/language/Error/WhileSaving",
"text": "保存时,发生错误"
},
"$:/language/Error/XMLHttpRequest": {
"title": "$:/language/Error/XMLHttpRequest",
"text": "XMLHttpRequest 错误代码"
},
"$:/language/InternalJavaScriptError/Title": {
"title": "$:/language/InternalJavaScriptError/Title",
"text": "内部的 JavaScript 错误"
},
"$:/language/InternalJavaScriptError/Hint": {
"title": "$:/language/InternalJavaScriptError/Hint",
"text": "喔,真是令人尴尬。建议刷新您的浏览器,重新启动 TiddlyWiki"
},
"$:/language/InvalidFieldName": {
"title": "$:/language/InvalidFieldName",
"text": "字段名称 \"<$text text=<<fieldName>>/>\" 包含无效字符,字段名称只能包含小写字母、数字、底线 (`_`)、 连字号 (`-`) 和小数点 (`.`)"
},
"$:/language/LayoutSwitcher/Description": {
"title": "$:/language/LayoutSwitcher/Description",
"text": "打开布局切换器"
},
"$:/language/LazyLoadingWarning": {
"title": "$:/language/LazyLoadingWarning",
"text": "<p>正在从 ''<$text text={{!!_canonical_uri}}/>'' 加载外部内容 ...</p><p>如果此信息未消失,可能是条目内容类型与外部内容的类型不匹配,或是您可能正在使用的浏览器,不支援单文件式维基的外部内容。请参阅 https://tiddlywiki.com/#ExternalText</p>"
},
"$:/language/LoginToTiddlySpace": {
"title": "$:/language/LoginToTiddlySpace",
"text": "登录 TiddlySpace"
},
"$:/language/Manager/Controls/FilterByTag/None": {
"title": "$:/language/Manager/Controls/FilterByTag/None",
"text": "(无)"
},
"$:/language/Manager/Controls/FilterByTag/Prompt": {
"title": "$:/language/Manager/Controls/FilterByTag/Prompt",
"text": "依标签筛选︰"
},
"$:/language/Manager/Controls/Order/Prompt": {
"title": "$:/language/Manager/Controls/Order/Prompt",
"text": "反向顺序"
},
"$:/language/Manager/Controls/Search/Placeholder": {
"title": "$:/language/Manager/Controls/Search/Placeholder",
"text": "搜寻"
},
"$:/language/Manager/Controls/Search/Prompt": {
"title": "$:/language/Manager/Controls/Search/Prompt",
"text": "搜寻︰"
},
"$:/language/Manager/Controls/Show/Option/Tags": {
"title": "$:/language/Manager/Controls/Show/Option/Tags",
"text": "标签"
},
"$:/language/Manager/Controls/Show/Option/Tiddlers": {
"title": "$:/language/Manager/Controls/Show/Option/Tiddlers",
"text": "条目"
},
"$:/language/Manager/Controls/Show/Prompt": {
"title": "$:/language/Manager/Controls/Show/Prompt",
"text": "显示︰"
},
"$:/language/Manager/Controls/Sort/Prompt": {
"title": "$:/language/Manager/Controls/Sort/Prompt",
"text": "排序︰"
},
"$:/language/Manager/Item/Colour": {
"title": "$:/language/Manager/Item/Colour",
"text": "颜色"
},
"$:/language/Manager/Item/Fields": {
"title": "$:/language/Manager/Item/Fields",
"text": "字段"
},
"$:/language/Manager/Item/Icon/None": {
"title": "$:/language/Manager/Item/Icon/None",
"text": "(无)"
},
"$:/language/Manager/Item/Icon": {
"title": "$:/language/Manager/Item/Icon",
"text": "图标"
},
"$:/language/Manager/Item/RawText": {
"title": "$:/language/Manager/Item/RawText",
"text": "原始文字"
},
"$:/language/Manager/Item/Tags": {
"title": "$:/language/Manager/Item/Tags",
"text": "标签"
},
"$:/language/Manager/Item/Tools": {
"title": "$:/language/Manager/Item/Tools",
"text": "工具"
},
"$:/language/Manager/Item/WikifiedText": {
"title": "$:/language/Manager/Item/WikifiedText",
"text": "Wikified 文字"
},
"$:/language/MissingTiddler/Hint": {
"title": "$:/language/MissingTiddler/Hint",
"text": "佚失条目 \"<$text text=<<currentTiddler>>/>\" - 点击 {{||$:/core/ui/Buttons/edit}} 可创建此条目"
},
"$:/language/No": {
"title": "$:/language/No",
"text": "否"
},
"$:/language/OfficialPluginLibrary": {
"title": "$:/language/OfficialPluginLibrary",
"text": "~TiddlyWiki 官方插件程式库"
},
"$:/language/OfficialPluginLibrary/Hint": {
"title": "$:/language/OfficialPluginLibrary/Hint",
"text": "此为在 tiddlywiki.com 的 ~TiddlyWiki 官方插件程式库。由核心团队维护的插件、主题和语言包。"
},
"$:/language/PageTemplate/Description": {
"title": "$:/language/PageTemplate/Description",
"text": "默认的 ~Tiddlywiki 布局"
},
"$:/language/PageTemplate/Name": {
"title": "$:/language/PageTemplate/Name",
"text": "默认的 ~PageTemplate"
},
"$:/language/PluginReloadWarning": {
"title": "$:/language/PluginReloadWarning",
"text": "请保存 {{$:/core/ui/Buttons/save-wiki}} 并刷新页面 {{$:/core/ui/Buttons/refresh}} ,使 ~JavaScript 插件的更改生效"
},
"$:/language/RecentChanges/DateFormat": {
"title": "$:/language/RecentChanges/DateFormat",
"text": "YYYY年0MM月0DD日"
},
"$:/language/Shortcuts/Input/Accept/Hint": {
"title": "$:/language/Shortcuts/Input/Accept/Hint",
"text": "接受选取的项目"
},
"$:/language/Shortcuts/Input/AcceptVariant/Hint": {
"title": "$:/language/Shortcuts/Input/AcceptVariant/Hint",
"text": "接受选取项目 (变种)"
},
"$:/language/Shortcuts/Input/AdvancedSearch/Hint": {
"title": "$:/language/Shortcuts/Input/AdvancedSearch/Hint",
"text": "从侧边栏搜寻字段内打开[[进阶搜寻|$:/AdvancedSearch]]面板"
},
"$:/language/Shortcuts/Input/Cancel/Hint": {
"title": "$:/language/Shortcuts/Input/Cancel/Hint",
"text": "清除输入字段"
},
"$:/language/Shortcuts/Input/Down/Hint": {
"title": "$:/language/Shortcuts/Input/Down/Hint",
"text": "选择下一个项目"
},
"$:/language/Shortcuts/Input/Tab-Left/Hint": {
"title": "$:/language/Shortcuts/Input/Tab-Left/Hint",
"text": "选择上一个页签"
},
"$:/language/Shortcuts/Input/Tab-Right/Hint": {
"title": "$:/language/Shortcuts/Input/Tab-Right/Hint",
"text": "选择下一个页签"
},
"$:/language/Shortcuts/Input/Up/Hint": {
"title": "$:/language/Shortcuts/Input/Up/Hint",
"text": "选择前一个项目"
},
"$:/language/Shortcuts/SidebarLayout/Hint": {
"title": "$:/language/Shortcuts/SidebarLayout/Hint",
"text": "更改侧边栏布局"
},
"$:/language/Switcher/Subtitle/theme": {
"title": "$:/language/Switcher/Subtitle/theme",
"text": "切换布景主题"
},
"$:/language/Switcher/Subtitle/layout": {
"title": "$:/language/Switcher/Subtitle/layout",
"text": "切换布局"
},
"$:/language/Switcher/Subtitle/language": {
"title": "$:/language/Switcher/Subtitle/language",
"text": "切换语言"
},
"$:/language/Switcher/Subtitle/palette": {
"title": "$:/language/Switcher/Subtitle/palette",
"text": "切换调色板"
},
"$:/language/SystemTiddler/Tooltip": {
"title": "$:/language/SystemTiddler/Tooltip",
"text": "此为系统条目"
},
"$:/language/SystemTiddlers/Include/Prompt": {
"title": "$:/language/SystemTiddlers/Include/Prompt",
"text": "包括系统条目"
},
"$:/language/TagManager/Colour/Heading": {
"title": "$:/language/TagManager/Colour/Heading",
"text": "颜色"
},
"$:/language/TagManager/Count/Heading": {
"title": "$:/language/TagManager/Count/Heading",
"text": "计数"
},
"$:/language/TagManager/Icon/Heading": {
"title": "$:/language/TagManager/Icon/Heading",
"text": "图标"
},
"$:/language/TagManager/Icons/None": {
"title": "$:/language/TagManager/Icons/None",
"text": "无"
},
"$:/language/TagManager/Info/Heading": {
"title": "$:/language/TagManager/Info/Heading",
"text": "信息"
},
"$:/language/TagManager/Tag/Heading": {
"title": "$:/language/TagManager/Tag/Heading",
"text": "标签"
},
"$:/language/Tiddler/DateFormat": {
"title": "$:/language/Tiddler/DateFormat",
"text": "YYYY年0MM月0DD日 0hh:0mm"
},
"$:/language/UnsavedChangesWarning": {
"title": "$:/language/UnsavedChangesWarning",
"text": "在此 TiddlyWiki 您有尚未保存的变更"
},
"$:/language/Yes": {
"title": "$:/language/Yes",
"text": "是"
},
"$:/language/Modals/Download": {
"title": "$:/language/Modals/Download",
"type": "text/vnd.tiddlywiki",
"subtitle": "Download changes",
"footer": "<$button message=\"tm-close-tiddler\">关闭</$button>",
"help": "https://tiddlywiki.com/",
"text": "您的浏览器只支援手动保存。\n\n要保存更动的维基,右键点击下方的下载链结,选择\"下载文件\"或\"保存文件\",然后选择文件夹或文件名。\n\n//您可以藉由按一下 Ctrl 键(Windows)或 options/ alt 键(Mac OS X)中的链接,稍微加速操作。您不会被提示文件夹或文件名,您的浏览器可能无法辨认它的文件名 -- 在做其他任何事之前,您可能需要重新命名扩展名为 `.html` 的文件。//\n\n在智能型手机上,不允许下载文件,但您可以标记链结,然后从一台可以正常保存维基的台式机的维基同步你的书签。"
},
"$:/language/Modals/SaveInstructions": {
"title": "$:/language/Modals/SaveInstructions",
"type": "text/vnd.tiddlywiki",
"subtitle": "Save your work",
"footer": "<$button message=\"tm-close-tiddler\">关闭</$button>",
"help": "https://tiddlywiki.com/static/SavingChanges.html",
"text": "您对此 wiki 的变更需被保存为 ~TiddlyWiki HTML 文件。\n\n!!! 桌面版浏览器\n\n# 从''文件''菜单点选 ''另存为''\n# 选定文件名及保存位置\n#* 某些浏览器依然需要明确指定文件格式为 ''Webpage, HTML only'' 或类似的。\n# 关闭此页签\n\n!!! 智能手机版浏览器\n\n# 为此页建立书签\n#* 若您已设置 iCloud 或 Google 同步,该书签将自动与之前开启及保存于您电脑的书签同步。\n# 关闭此页签\n\n//若您再次于 Mobile Safari 开启该书签,将会再看到此信息。若要继续使用该文件,只需点击下列 ''关闭'' 按钮//\n"
},
"$:/config/NewJournal/Title": {
"title": "$:/config/NewJournal/Title",
"text": "YYYY年0MM月0DD日"
},
"$:/config/NewJournal/Text": {
"title": "$:/config/NewJournal/Text",
"text": ""
},
"$:/config/NewJournal/Tags": {
"title": "$:/config/NewJournal/Tags",
"text": "日志\n"
},
"$:/language/Notifications/Save/Done": {
"title": "$:/language/Notifications/Save/Done",
"text": "已保存 wiki"
},
"$:/language/Notifications/Save/Starting": {
"title": "$:/language/Notifications/Save/Starting",
"text": "开始保存 wiki"
},
"$:/language/Notifications/CopiedToClipboard/Succeeded": {
"title": "$:/language/Notifications/CopiedToClipboard/Succeeded",
"text": "已复制到剪贴板!"
},
"$:/language/Notifications/CopiedToClipboard/Failed": {
"title": "$:/language/Notifications/CopiedToClipboard/Failed",
"text": "无法复制到剪贴板!"
},
"$:/language/Search/DefaultResults/Caption": {
"title": "$:/language/Search/DefaultResults/Caption",
"text": "列表"
},
"$:/language/Search/Filter/Caption": {
"title": "$:/language/Search/Filter/Caption",
"text": "筛选"
},
"$:/language/Search/Filter/Hint": {
"title": "$:/language/Search/Filter/Hint",
"text": "以[[筛选表达式|https://tiddlywiki.com/static/Filters.html]]查找"
},
"$:/language/Search/Filter/Matches": {
"title": "$:/language/Search/Filter/Matches",
"text": "//<small><<resultCount>> 个条目符合条件</small>//"
},
"$:/language/Search/Matches": {
"title": "$:/language/Search/Matches",
"text": "//<small><<resultCount>> 个条目符合条件</small>//"
},
"$:/language/Search/Matches/All": {
"title": "$:/language/Search/Matches/All",
"text": "所有匹配:"
},
"$:/language/Search/Matches/Title": {
"title": "$:/language/Search/Matches/Title",
"text": "条目名称匹配:"
},
"$:/language/Search/Search": {
"title": "$:/language/Search/Search",
"text": "查找"
},
"$:/language/Search/Search/TooShort": {
"title": "$:/language/Search/Search/TooShort",
"text": "查找文本太短"
},
"$:/language/Search/Shadows/Caption": {
"title": "$:/language/Search/Shadows/Caption",
"text": "默认"
},
"$:/language/Search/Shadows/Hint": {
"title": "$:/language/Search/Shadows/Hint",
"text": "查找默认条目"
},
"$:/language/Search/Shadows/Matches": {
"title": "$:/language/Search/Shadows/Matches",
"text": "//<small><<resultCount>> 个条目符合条件</small>//"
},
"$:/language/Search/Standard/Caption": {
"title": "$:/language/Search/Standard/Caption",
"text": "标准"
},
"$:/language/Search/Standard/Hint": {
"title": "$:/language/Search/Standard/Hint",
"text": "查找一般条目"
},
"$:/language/Search/Standard/Matches": {
"title": "$:/language/Search/Standard/Matches",
"text": "//<small><<resultCount>> 个条目符合条件</small>//"
},
"$:/language/Search/System/Caption": {
"title": "$:/language/Search/System/Caption",
"text": "系统"
},
"$:/language/Search/System/Hint": {
"title": "$:/language/Search/System/Hint",
"text": "查找系统条目"
},
"$:/language/Search/System/Matches": {
"title": "$:/language/Search/System/Matches",
"text": "//<small><<resultCount>> 个条目符合条件</small>//"
},
"$:/language/SideBar/All/Caption": {
"title": "$:/language/SideBar/All/Caption",
"text": "全部"
},
"$:/language/SideBar/Contents/Caption": {
"title": "$:/language/SideBar/Contents/Caption",
"text": "目录"
},
"$:/language/SideBar/Drafts/Caption": {
"title": "$:/language/SideBar/Drafts/Caption",
"text": "草稿"
},
"$:/language/SideBar/Explorer/Caption": {
"title": "$:/language/SideBar/Explorer/Caption",
"text": "探索"
},
"$:/language/SideBar/Missing/Caption": {
"title": "$:/language/SideBar/Missing/Caption",
"text": "缺失"
},
"$:/language/SideBar/More/Caption": {
"title": "$:/language/SideBar/More/Caption",
"text": "更多"
},
"$:/language/SideBar/Open/Caption": {
"title": "$:/language/SideBar/Open/Caption",
"text": "开启"
},
"$:/language/SideBar/Orphans/Caption": {
"title": "$:/language/SideBar/Orphans/Caption",
"text": "孤立"
},
"$:/language/SideBar/Recent/Caption": {
"title": "$:/language/SideBar/Recent/Caption",
"text": "最近"
},
"$:/language/SideBar/Shadows/Caption": {
"title": "$:/language/SideBar/Shadows/Caption",
"text": "默认"
},
"$:/language/SideBar/System/Caption": {
"title": "$:/language/SideBar/System/Caption",
"text": "系统"
},
"$:/language/SideBar/Tags/Caption": {
"title": "$:/language/SideBar/Tags/Caption",
"text": "标签"
},
"$:/language/SideBar/Tags/Untagged/Caption": {
"title": "$:/language/SideBar/Tags/Untagged/Caption",
"text": "未设标签"
},
"$:/language/SideBar/Tools/Caption": {
"title": "$:/language/SideBar/Tools/Caption",
"text": "工具"
},
"$:/language/SideBar/Types/Caption": {
"title": "$:/language/SideBar/Types/Caption",
"text": "类型"
},
"$:/SiteSubtitle": {
"title": "$:/SiteSubtitle",
"text": "一个非线性的网页式笔记"
},
"$:/SiteTitle": {
"title": "$:/SiteTitle",
"text": "我的 ~TiddlyWiki"
},
"$:/language/Snippets/ListByTag": {
"title": "$:/language/Snippets/ListByTag",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "依标签筛选的条目列表",
"text": "<<list-links \"[tag[task]sort[title]]\">>\n"
},
"$:/language/Snippets/MacroDefinition": {
"title": "$:/language/Snippets/MacroDefinition",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "宏的定义",
"text": "\\define macroName(param1:\"默认值\",param2)\n宏的内容\n\\end\n"
},
"$:/language/Snippets/Table4x3": {
"title": "$:/language/Snippets/Table4x3",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "4 x 3 的表格",
"text": "|! | !一 | !二 | !三 | !四 |\n|! 1| | | | |\n|! 2| | | | |\n|! 3 | | | | |\n"
},
"$:/language/Snippets/TableOfContents": {
"title": "$:/language/Snippets/TableOfContents",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "目录",
"text": "<div class=\"tc-table-of-contents\">\n\n<<toc-selective-expandable 'TableOfContents'>>\n\n</div>"
},
"$:/language/ThemeTweaks/ThemeTweaks": {
"title": "$:/language/ThemeTweaks/ThemeTweaks",
"text": "主题调整"
},
"$:/language/ThemeTweaks/ThemeTweaks/Hint": {
"title": "$:/language/ThemeTweaks/ThemeTweaks/Hint",
"text": "您可以调整 ''Vanilla'' 布景主题的某些样貌。"
},
"$:/language/ThemeTweaks/Options": {
"title": "$:/language/ThemeTweaks/Options",
"text": "选项"
},
"$:/language/ThemeTweaks/Options/SidebarLayout": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout",
"text": "侧边栏布局"
},
"$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid",
"text": "固定故事,浮动侧边栏"
},
"$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed",
"text": "浮动故事,固定侧边栏"
},
"$:/language/ThemeTweaks/Options/StickyTitles": {
"title": "$:/language/ThemeTweaks/Options/StickyTitles",
"text": "置顶标题"
},
"$:/language/ThemeTweaks/Options/StickyTitles/Hint": {
"title": "$:/language/ThemeTweaks/Options/StickyTitles/Hint",
"text": "使条目名称\"黏着\"于浏览器窗口的顶端"
},
"$:/language/ThemeTweaks/Options/CodeWrapping": {
"title": "$:/language/ThemeTweaks/Options/CodeWrapping",
"text": "在代码区块中折行"
},
"$:/language/ThemeTweaks/Settings": {
"title": "$:/language/ThemeTweaks/Settings",
"text": "设置"
},
"$:/language/ThemeTweaks/Settings/FontFamily": {
"title": "$:/language/ThemeTweaks/Settings/FontFamily",
"text": "字型"
},
"$:/language/ThemeTweaks/Settings/CodeFontFamily": {
"title": "$:/language/ThemeTweaks/Settings/CodeFontFamily",
"text": "代码字型"
},
"$:/language/ThemeTweaks/Settings/EditorFontFamily": {
"title": "$:/language/ThemeTweaks/Settings/EditorFontFamily",
"text": "编辑器字型"
},
"$:/language/ThemeTweaks/Settings/BackgroundImage": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImage",
"text": "页面背景图像"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment",
"text": "页面背景图像附属"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll",
"text": "随条目卷动"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed",
"text": "固定于窗口"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize",
"text": "页面背景图像大小"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto",
"text": "自动"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover",
"text": "覆盖"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain",
"text": "包含"
},
"$:/language/ThemeTweaks/Metrics": {
"title": "$:/language/ThemeTweaks/Metrics",
"text": "大小"
},
"$:/language/ThemeTweaks/Metrics/FontSize": {
"title": "$:/language/ThemeTweaks/Metrics/FontSize",
"text": "字体大小"
},
"$:/language/ThemeTweaks/Metrics/LineHeight": {
"title": "$:/language/ThemeTweaks/Metrics/LineHeight",
"text": "行高"
},
"$:/language/ThemeTweaks/Metrics/BodyFontSize": {
"title": "$:/language/ThemeTweaks/Metrics/BodyFontSize",
"text": "条目本文的字体大小"
},
"$:/language/ThemeTweaks/Metrics/BodyLineHeight": {
"title": "$:/language/ThemeTweaks/Metrics/BodyLineHeight",
"text": "条目本文的行高"
},
"$:/language/ThemeTweaks/Metrics/StoryLeft": {
"title": "$:/language/ThemeTweaks/Metrics/StoryLeft",
"text": "故事左侧位置"
},
"$:/language/ThemeTweaks/Metrics/StoryLeft/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint",
"text": "故事河(条目区)的左边缘与页面左端的间距"
},
"$:/language/ThemeTweaks/Metrics/StoryTop": {
"title": "$:/language/ThemeTweaks/Metrics/StoryTop",
"text": "故事顶端位置"
},
"$:/language/ThemeTweaks/Metrics/StoryTop/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryTop/Hint",
"text": "故事河(条目区)的上边缘与页面顶端的间距"
},
"$:/language/ThemeTweaks/Metrics/StoryRight": {
"title": "$:/language/ThemeTweaks/Metrics/StoryRight",
"text": "故事右侧位置"
},
"$:/language/ThemeTweaks/Metrics/StoryRight/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryRight/Hint",
"text": "侧边栏的左边缘与页面左端的间距"
},
"$:/language/ThemeTweaks/Metrics/StoryWidth": {
"title": "$:/language/ThemeTweaks/Metrics/StoryWidth",
"text": "故事的宽度"
},
"$:/language/ThemeTweaks/Metrics/StoryWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint",
"text": "故事河的整体宽度"
},
"$:/language/ThemeTweaks/Metrics/TiddlerWidth": {
"title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth",
"text": "条目宽度"
},
"$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint",
"text": "在故事河内"
},
"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint",
"text": "侧边栏中断点"
},
"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint",
"text": "故事河和侧边栏会并排显示的最小页面宽度"
},
"$:/language/ThemeTweaks/Metrics/SidebarWidth": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarWidth",
"text": "侧边栏宽度"
},
"$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint",
"text": "在浮动-固定布局中,侧边栏的宽度"
},
"$:/language/TiddlerInfo/Advanced/Caption": {
"title": "$:/language/TiddlerInfo/Advanced/Caption",
"text": "高级"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint",
"text": "无信息"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Heading": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading",
"text": "插件明细"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint",
"text": "此插件包含以下预设条目:"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading",
"text": "默认条目状态"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint",
"text": "<$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> 不是一个默认条目"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint",
"text": "<$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> 是一个默认条目"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source",
"text": "此条目定义于插件 <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint",
"text": "已被一般条目覆写"
},
"$:/language/TiddlerInfo/Fields/Caption": {
"title": "$:/language/TiddlerInfo/Fields/Caption",
"text": "栏位"
},
"$:/language/TiddlerInfo/List/Caption": {
"title": "$:/language/TiddlerInfo/List/Caption",
"text": "列表"
},
"$:/language/TiddlerInfo/List/Empty": {
"title": "$:/language/TiddlerInfo/List/Empty",
"text": "此条目无指定列表"
},
"$:/language/TiddlerInfo/Listed/Caption": {
"title": "$:/language/TiddlerInfo/Listed/Caption",
"text": "被列于"
},
"$:/language/TiddlerInfo/Listed/Empty": {
"title": "$:/language/TiddlerInfo/Listed/Empty",
"text": "此条目未出现于其他条目的列表中"
},
"$:/language/TiddlerInfo/References/Caption": {
"title": "$:/language/TiddlerInfo/References/Caption",
"text": "反向链接"
},
"$:/language/TiddlerInfo/References/Empty": {
"title": "$:/language/TiddlerInfo/References/Empty",
"text": "无条目链接至此"
},
"$:/language/TiddlerInfo/Tagging/Caption": {
"title": "$:/language/TiddlerInfo/Tagging/Caption",
"text": "子条目"
},
"$:/language/TiddlerInfo/Tagging/Empty": {
"title": "$:/language/TiddlerInfo/Tagging/Empty",
"text": "无任何条目以此条目之标题为标签"
},
"$:/language/TiddlerInfo/Tools/Caption": {
"title": "$:/language/TiddlerInfo/Tools/Caption",
"text": "工具"
},
"$:/language/Docs/Types/application/javascript": {
"title": "$:/language/Docs/Types/application/javascript",
"description": "JavaScript 源码",
"name": "application/javascript",
"group": "开发者"
},
"$:/language/Docs/Types/application/json": {
"title": "$:/language/Docs/Types/application/json",
"description": "JSON 数据",
"name": "application/json",
"group": "开发者"
},
"$:/language/Docs/Types/application/x-tiddler-dictionary": {
"title": "$:/language/Docs/Types/application/x-tiddler-dictionary",
"description": "数据字典",
"name": "application/x-tiddler-dictionary",
"group": "开发者"
},
"$:/language/Docs/Types/image/gif": {
"title": "$:/language/Docs/Types/image/gif",
"description": "GIF 图像",
"name": "image/gif",
"group": "图像"
},
"$:/language/Docs/Types/image/jpeg": {
"title": "$:/language/Docs/Types/image/jpeg",
"description": "JPEG 图像",
"name": "image/jpeg",
"group": "图像"
},
"$:/language/Docs/Types/image/png": {
"title": "$:/language/Docs/Types/image/png",
"description": "PNG 图像",
"name": "image/png",
"group": "图像"
},
"$:/language/Docs/Types/image/svg+xml": {
"title": "$:/language/Docs/Types/image/svg+xml",
"description": "结构式矢量图",
"name": "image/svg+xml",
"group": "图像"
},
"$:/language/Docs/Types/image/x-icon": {
"title": "$:/language/Docs/Types/image/x-icon",
"description": "图标",
"name": "image/x-icon",
"group": "图像"
},
"$:/language/Docs/Types/text/css": {
"title": "$:/language/Docs/Types/text/css",
"description": "静态样式",
"name": "text/css",
"group": "开发者"
},
"$:/language/Docs/Types/text/html": {
"title": "$:/language/Docs/Types/text/html",
"description": "HTML 标记",
"name": "text/html",
"group": "文本"
},
"$:/language/Docs/Types/text/plain": {
"title": "$:/language/Docs/Types/text/plain",
"description": "纯文本",
"name": "text/plain",
"group": "文本"
},
"$:/language/Docs/Types/text/vnd.tiddlywiki": {
"title": "$:/language/Docs/Types/text/vnd.tiddlywiki",
"description": "TiddlyWiki 5",
"name": "text/vnd.tiddlywiki",
"group": "文本"
},
"$:/language/Docs/Types/text/x-tiddlywiki": {
"title": "$:/language/Docs/Types/text/x-tiddlywiki",
"description": "TiddlyWiki 2",
"name": "text/x-tiddlywiki",
"group": "文本"
},
"$:/config/Search/MinLength": {
"title": "$:/config/Search/MinLength",
"text": "1"
},
"$:/languages/zh-Hans/icon": {
"title": "$:/languages/zh-Hans/icon",
"type": "image/svg+xml",
"text": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1500\" height=\"1000\" viewBox=\"-5 -5 30 20\">\n<title>Flag of the People's Republic of China</title>\n<rect fill=\"#de2910\" x=\"-5\" y=\"-5\" width=\"30\" height=\"20\"/>\n<defs>\n<polygon id=\"s\" points=\"0,-513674 301930,415571 -488533,-158734 488533,-158734 -301930,415571\"\nfill=\"#ffde00\" transform=\"scale(0.0000019467600073)\"/>\n</defs>\n<use xlink:href=\"#s\" transform=\"scale(3)\"/>\n<use xlink:href=\"#s\" transform=\"translate(5,-3) rotate(-120.963756)\"/>\n<use xlink:href=\"#s\" transform=\"translate(7,-1) rotate(-98.130102)\"/>\n<use xlink:href=\"#s\" transform=\"translate(7,2) rotate(-74.054604)\"/>\n<use xlink:href=\"#s\" transform=\"translate(5,4) rotate(-51.3401917)\"/>\n</svg>\n"
}
}
}
.bm-table {margin:0 auto;}
.bm-table, .bm-table th, .bm-table td {
border:0; background:white;
}
.bm-input-table {width:100%;}
.bm-input-table > tr > td:nth-child(2) {max-width:300px;}
.bm-input-table select {max-width:calc(100% - 50px - 1.2em);}
.bm-fieldeditor {max-width:calc(100% - 1.2em);}
.bm-relations-table {margin-top:4em;}
.bm-table th.rotate {
white-space: nowrap;
vertical-align:bottom;
}
.bm-table th.rotate > div {
transform: translate(27px, -.5em) rotate(315deg);
width: 1em;
margin-left:-1em;
}
.bm-table th.rotate > div > span {
border-bottom: 1px solid #ccc;
padding: 0px 10px 2px 0;
margin-left:-.6em;
background:white;
}
.bm-table ::-webkit-input-placeholder { color: #a6a6a6; }
.bm-table :-ms-input-placeholder { color: #a6a6a6; }
.bm-table ::-ms-input-placeholder { color: #a6a6a6; }
.bm-table ::-moz-placeholder { color: #a6a6a6; }
.bm-singledata-table-head {border-bottom:2px solid silver}
.bm-btn {width:1em;}
.bm-btn-addtofilter {color:blue; }
.bm-btn-add, .tm-add-tag, .tm-add-field { background:lightgray;}
.bm-btn-remove, .tm-remove-tag, .tm-remove-field {background:lightgreen;}
.peek {display:none;z-index:2;background-color:lightgray;position:absolute;}
.peek-hover:hover .peek {display:block; background:lightgray;}
.bm-tooltip {position:absolute; display:none; z-index:2;background:white; margin:-2.6em -1em; border:1px solid silver; padding:0 5px; color:black;white-space:nowrap;}
.bm-btn-tooltip:hover .bm-tooltip {display:block;}
.bm-fontsmall {font-size:.8em; fill:gray;}
.bm-center {text-align:center; vertical-align:text-bottom;}
.bm-fontsmall svg,
.bm-fontsmall input[type="checkbox"] {vertical-align:text-top}
.bm-alert {border-color:red;}
.bm-drag {background:#ec6; border-radius:1em; padding:0; line-height:1.1em; width:3em; display:inline-block;}
button.green-link {color:#00cc00;}
.matched {background-color:#ffc;}
.tw-context {
border:0px solid #eee;background-color:#eee;
word-break: break-all; word-wrap: break-word;}
{
"tiddlers": {
"$:/plugins/danielo515/ContextPlugin/widgets/context.js": {
"created": "20140418153435777",
"creator": "danielo",
"modified": "20140530231943517",
"modifier": "danielo",
"module-type": "widget",
"title": "$:/plugins/danielo515/ContextPlugin/widgets/context.js",
"type": "application/javascript",
"text": "/*\\\\\ntitle: $:/core/modules/widgets/danielo/context-widget.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-text widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar contextWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\ncontextWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\ncontextWidget.prototype.render = function(parent,nextSibling) {\n // Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n \n if(this.term && this.term.length>3){\n \n this.createRegexp();\n var matches = this.executeRegexp();\n\t if(matches.length > 0){ \n this.domNode = this.document.createElement(this.element);\n this.domNode.className=\"tw-context\";\n this.composeResults( matches ); //this appends to domNode \n \t// Insert element\n \tparent.insertBefore(this.domNode,nextSibling);\n \tthis.renderChildren(this.domNode,null);\n\t \tthis.domNodes.push(this.domNode);\n }\n }\n\t\n};\n\n/*\nCompute the internal state of the widget\n*/\ncontextWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n this.matchedClass = this.getAttribute(\"matchClass\",\"matched\");\n\tthis.tiddler = this.getAttribute( \"tiddler\",this.getVariable(\"currentTiddler\") );\n this.term = this.getAttribute(\"term\",this.getAttribute(\"searchTerm\"));\n\tthis.contextLength = this.getAttribute(\"length\",50);\n this.before = this.getAttribute(\"before\",this.contextLength);\n this.after = this.getAttribute(\"after\",this.contextLength);\n this.maxMatches = this.getAttribute(\"maxMatches\",10);\n this.element = this.getAttribute(\"element\",\"pre\");\n\tthis.makeChildWidgets();\n};\n\n /*Create the regular expression*/\ncontextWidget.prototype.createRegexp = function()\n{\n var regString = \"(\\\\w+[\\\\s\\\\S]{0,#before#})?(#term#)([\\\\s\\\\S]{0,#after#}\\\\w+)?\";\n\n var regString = regString.replace(\"#before#\",this.before).replace(\"#term#\", $tw.utils.escapeRegExp(this.term) ) .replace(\"#after#\",this.after);\n this.regexp = new RegExp(regString,\"ig\");\n //console.log(regString);\n};\n/*\nexecute the regular expresion\n*/\ncontextWidget.prototype.executeRegexp = function()\n{\n var text = this.wiki.getTiddlerText(this.tiddler), match,results = new Array();\n while( (match = this.regexp.exec( text ) ) && (results.length < this.maxMatches) )\n { results.push(match) }\n //console.log(\"matches\",results);\n return results;\n};\n\n/*\ncompose the results\nmatches : array of match objects from regular expression execute\n*/\ncontextWidget.prototype.composeResults = function(matches){\n var result=[], self=this, node = this.domNode,\n dots = textNode(\"...\\n\"),\n span = matchedNode( this.term );\n\n for(var i=0; i < matches.length; i++){\n processMatch( matches[i] );\n }\n \n function processMatch(match){\n if( match.index !== 0) node.appendChild( dots.cloneNode(true) );\n for( var i=1;i<match.length;i++ ) {//match[0] full matched text (all groups together)\n if( match[i] ) {\n if ( match[i].toLowerCase() == self.term.toLowerCase() ) \n node.appendChild( match[i] == self.term ? span.cloneNode(true) : matchedNode( match[i] ) )\n else\n node.appendChild( textNode( match[i]) )\n }\n }\n if( match.index + match[0].length < match.input.length) node.appendChild( dots.cloneNode(true) );\n }\n \n function textNode(text){ return self.document.createTextNode(text) }\n function matchedNode(text) { \n var node = self.document.createElement(\"span\"); node.appendChild( textNode(text) ); node.className = self.matchedClass;\n return node }\n \n};\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\ncontextWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.term || changedAttributes.length || changedAttributes.matchedClass) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n return this.refreshChildren(changedTiddlers);\n};\n\nexports.context = contextWidget;\n\n})();"
},
"$:/plugins/danielo515/ContextPlugin/visualizer": {
"title": "$:/plugins/danielo515/ContextPlugin/visualizer",
"tags": "$:/tags/SearchResults",
"caption": "Context",
"text": "<$list filter=\"[!is[system]search{$:/temp/search}sort[title]limit[250]]\">\r\n {{!!title||$:/core/ui/ListItemTemplate}}\r\n <$context term={{$:/temp/search}} />\r\n</$list>\r\n"
},
"$:/plugins/danielo515/ContextPlugin/Stylesheet/results": {
"created": "20140529162823729",
"tags": "$:/tags/Stylesheet contextPlugin",
"title": "$:/plugins/danielo515/ContextPlugin/Stylesheet/results",
"type": "text/css",
"text": ".matched{background-color:yellow}\n.tw-context {/*border:1px solid;\n /*word-break: break-all; word-wrap: break-word*/}"
},
"$:/plugins/danielo515/ContextPlugin/Caption": {
"created": "20140530174219263",
"tags": "contextPlugin",
"title": "$:/plugins/danielo515/ContextPlugin/Caption",
"type": "text/vnd.tiddlywiki",
"text": "Context search"
},
"Context Search": {
"caption": "{{$:/plugins/danielo515/ContextPlugin/Caption}}",
"created": "20140530173407542",
"tags": "$:/tags/AdvancedSearch",
"title": "Context Search",
"type": "text/vnd.tiddlywiki",
"text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo Standard/Hint>>\n\n<div class=\"tw-search\"><$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/><$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\"> <$link to=\"\" class=\"btn-invisible\">{{$:/core/images/close-button}}</$link></$reveal></div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<div class=\"tw-search-results\">\n\n<<lingo Standard/Matches>>\n\n<$list filter=\"[!is[system]search{$:/temp/advancedsearch}sort[title]limit[250]]\">\n{{!!title||$:/core/ui/ListItemTemplate}}\n<$context term={{$:/temp/advancedsearch}}/>\n</$list>\n\n</div>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
},
"$:/plugins/danielo515/ContextPlugin/readme": {
"title": "$:/plugins/danielo515/ContextPlugin/readme",
"text": "!Usage\n\nAfter installing the plugin you will have a new tab in [[$:/AdvancedSearch]] called [[Context Search]]. If you want this functionality in other places you will have to edit the desired tiddler yourself adding the ''context widget''. For more details about using the widget see the section below.\n\n!!Using the widget\n\nThe very basic usage of the widget is the following:\n\n```\r\n<$context term=\"lorem\"/>\r\n```\r\nWhich will render as:\r\n<$context term=\"lorem\"/>\n\nThe widgets will search inside the current tiddler by default. Because that you see the same content twice here. This example is not very useful. Other more meaningful would be:\n\n```\r\n<$list filter=\"[search{$:/temp/advancedsearch}sort[title]limit[250]]\">\r\n{{!!title||$:/core/ui/ListItemTemplate}}\r\n<$context term={{$:/temp/advancedsearch}}/>\r\n</$list>\r\n```\n\nThat will search for tiddlers containing the text specified in [[$:/temp/advancedsearch]] and will display a link to the matching tiddlers plus a preview of the matching content. Something very similar is used in [[Context Search]]. Below you can find a complete list of parameters and their default values.\n\n|! parameter |! description | !default |\r\n| term | The term you want to search ||\r\n| searchTerm | An alias for the previous one ||\r\n| tiddler | The tiddler's name to look into | current tiddler |\r\n| length | Number of context characters to show | 50 |\r\n| before | Number of characters before the matched term to show | the value of the length parameter |\r\n| after | Number of characters after the matched term to show | the value of the length parameter |\r\n| maxMatches | maximun number of matched elements to show. Incrementing this can cause several performance issues | 10 |\r\n| element | Node element to create. This element will contain the results of the search. If you want to style it its class is `tw-context` | `<pre>` |\r\n| matchClass | The css class to assign to the matched terms in the results. This is used to highlight the results | matched |\n\n!Customizing the output\r\nThere are not many ways to customize the output of this widget. You can specify ''what type of node you want to create'' to wrap the results (div,span...). The default is `<pre>`. This container is created with the class `tw-context` so you can easily apply styles to it. Something similar happens to the ''highlighted'' words. You can specify the name of the class to assign to it and also you can apply styles to that class.\n\nA very basic example of customization could be:\n\n# Create a tiddler, for example [[$/plugins/danielo515/context/css]]\r\n# Paste the following text or any css rule you want: \"\"\"\n\n<pre>\r\n.matched{background-color:yellow}\r\n.tw-context {\r\n border:1px solid blue;\r\n word-break: break-all; word-wrap: break-word;}\r\n</pre>\r\n\"\"\"\r\n# Tag it with `$:/tags/stylesheet`\r\n# Save the tiddler"
}
}
}
.matched{background-color:yellow}
.tw-context {/*border:1px solid;
/*word-break: break-all; word-wrap: break-word*/}
/*\\
title: $:/core/modules/widgets/danielo/context-widget.js
type: application/javascript
module-type: widget
Edit-text widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tc: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var contextWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
contextWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
contextWidget.prototype.render = function(parent,nextSibling) {
// Save the parent dom node
this.parentDomNode = parent;
// Compute our attributes
this.computeAttributes();
// Execute our logic
this.execute();
if(this.term && this.term.length>3){
this.createRegexp();
var matches = this.executeRegexp();
if(matches.length > 0){
this.domNode = this.document.createElement(this.element);
this.domNode.className="tw-context";
this.composeResults( matches ); //this appends to domNode
// Insert element
parent.insertBefore(this.domNode,nextSibling);
this.renderChildren(this.domNode,null);
this.domNodes.push(this.domNode);
}
}
};
/*
Compute the internal state of the widget
*/
contextWidget.prototype.execute = function() {
// Get the parameters from the attributes
this.matchedClass = this.getAttribute("matchClass","matched");
this.tiddler = this.getAttribute( "tiddler",this.getVariable("currentTiddler") );
this.term = this.getAttribute("term",this.getAttribute("searchTerm"));
this.contextLength = this.getAttribute("length",50);
this.before = this.getAttribute("before",this.contextLength);
this.after = this.getAttribute("after",this.contextLength);
this.maxMatches = this.getAttribute("maxMatches",10);
this.element = this.getAttribute("element","pre");
this.makeChildWidgets();
};
/*Create the regular expression*/
contextWidget.prototype.createRegexp = function()
{
var regString = "(\\w+[\\s\\S]{0,#before#})?(#term#)([\\s\\S]{0,#after#}\\w+)?";
var regString = regString.replace("#before#",this.before).replace("#term#", $tw.utils.escapeRegExp(this.term) ) .replace("#after#",this.after);
this.regexp = new RegExp(regString,"ig");
//console.log(regString);
};
/*
execute the regular expresion
*/
contextWidget.prototype.executeRegexp = function()
{
var text = this.wiki.getTiddlerText(this.tiddler), match,results = new Array();
while( (match = this.regexp.exec( text ) ) && (results.length < this.maxMatches) )
{ results.push(match) }
//console.log("matches",results);
return results;
};
/*
compose the results
matches : array of match objects from regular expression execute
*/
contextWidget.prototype.composeResults = function(matches){
var result=[], self=this, node = this.domNode,
dots = textNode("...\n"),
span = matchedNode( this.term );
for(var i=0; i < matches.length; i++){
processMatch( matches[i] );
}
function processMatch(match){
if( match.index !== 0) node.appendChild( dots.cloneNode(true) );
for( var i=1;i<match.length;i++ ) {//match[0] full matched text (all groups together)
if( match[i] ) {
if ( match[i].toLowerCase() == self.term.toLowerCase() )
node.appendChild( match[i] == self.term ? span.cloneNode(true) : matchedNode( match[i] ) )
else
node.appendChild( textNode( match[i]) )
}
}
if( match.index + match[0].length < match.input.length) node.appendChild( dots.cloneNode(true) );
}
function textNode(text){ return self.document.createTextNode(text) }
function matchedNode(text) {
var node = self.document.createElement("span"); node.appendChild( textNode(text) ); node.className = self.matchedClass;
return node }
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
contextWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler || changedAttributes.term || changedAttributes.length || changedAttributes.matchedClass) {
this.refreshSelf();
return true;
}
return this.refreshChildren(changedTiddlers);
};
exports.context = contextWidget;
})();
{
"tiddlers": {
"$:/plugins/flibbles/relink/js/bulkops.js": {
"text": "/*\\\nmodule-type: startup\n\nReplaces the relinkTiddler defined in $:/core/modules/wiki-bulkops.js\n\nThis is a startup instead of a wikimethods module-type because it's the only\nway to ensure this runs after the old relinkTiddler method is applied.\n\n\\*/\n(function(){\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar language = require('$:/plugins/flibbles/relink/js/language.js');\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils.js\");\n\nexports.name = \"redefine-relinkTiddler\";\nexports.synchronous = true;\n// load-modules is when wikimethods are applied in\n// ``$:/core/modules/startup/load-modules.js``\nexports.after = ['load-modules'];\n\nexports.startup = function() {\n\t$tw.Wiki.prototype.relinkTiddler = relinkTiddler;\n};\n\n/** Walks through all relinkable tiddlers and relinks them.\n * This replaces the existing function in core Tiddlywiki.\n */\nfunction relinkTiddler(fromTitle, toTitle, options) {\n\toptions = options || {};\n\tvar failures = [];\n\tvar indexer = utils.getIndexer(this);\n\tvar records = indexer.relinkLookup(fromTitle, toTitle, options);\n\tfor (var title in records) {\n\t\tvar entries = records[title],\n\t\t\tchanges = Object.create(null),\n\t\t\tupdate = false,\n\t\t\tfails = false;\n\t\tfor (var field in entries) {\n\t\t\tvar entry = entries[field];\n\t\t\tfails = fails || entry.impossible;\n\t\t\tif (entry.output) {\n\t\t\t\tchanges[field] = entry.output;\n\t\t\t\tupdate = true;\n\t\t\t}\n\t\t}\n\t\tif (fails) {\n\t\t\tfailures.push(title);\n\t\t}\n\t\t// If any fields changed, update tiddler\n\t\tif (update) {\n\t\t\tconsole.log(\"Renaming '\"+fromTitle+\"' to '\"+toTitle+\"' in '\" + title + \"'\");\n\n\t\t\tvar tiddler = this.getTiddler(title);\n\t\t\tvar newTiddler = new $tw.Tiddler(tiddler,changes,this.getModificationFields())\n\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-relinking-tiddler\",newTiddler,tiddler);\n\t\t\tthis.addTiddler(newTiddler);\n\t\t\t// If the title changed, we need to perform a nested rename\n\t\t\tif (newTiddler.fields.title !== title) {\n\t\t\t\tthis.deleteTiddler(title);\n\t\t\t\tthis.relinkTiddler(title, newTiddler.fields.title,options);\n\t\t\t}\n\t\t}\n\t};\n\tif (failures.length > 0) {\n\t\tvar options = $tw.utils.extend(\n\t\t\t{ variables: {to: toTitle, from: fromTitle},\n\t\t\t wiki: this},\n\t\t\toptions );\n\t\tlanguage.reportFailures(failures, options);\n\t}\n};\n\n})();\n",
"module-type": "startup",
"title": "$:/plugins/flibbles/relink/js/bulkops.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/indexer.js": {
"text": "/*\\\nmodule-type: indexer\n\nIndexes results from tiddler reference reports so we don't have to call them\nso much.\n\n\\*/\n\n\"use strict\";\n\nvar utils = require(\"./utils.js\");\nvar TiddlerContext = utils.getContext('tiddler');\n\nfunction Indexer(wiki) {\n\tthis.wiki = wiki;\n};\n\nIndexer.prototype.init = function() {\n\tthis.rebuild();\n};\n\nIndexer.prototype.rebuild = function() {\n\tthis.index = null;\n\tthis.backIndex = null;\n\tthis.contexts = Object.create(null);\n\tthis.changedTiddlers = undefined;\n\tthis.lastRelinkFrom = undefined;\n};\n\nIndexer.prototype.update = function(updateDescriptor) {\n\tif (!this.index) {\n\t\treturn;\n\t}\n\tvar title;\n\tif (!this.changedTiddlers) {\n\t\tthis.changedTiddlers = Object.create(null);\n\t}\n\tif (updateDescriptor.old.exists) {\n\t\ttitle = updateDescriptor.old.tiddler.fields.title;\n\t\tthis.changedTiddlers[title] = {deleted: true};\n\t\tthis._purge(title);\n\t}\n\tif (updateDescriptor['new'].exists) {\n\t\t// If its the same tiddler as old, this overrides the 'deleted' entry\n\t\ttitle = updateDescriptor['new'].tiddler.fields.title;\n\t\tthis.changedTiddlers[title] = {modified: true};\n\t}\n};\n\nIndexer.prototype.lookup = function(title) {\n\tthis._upkeep();\n\treturn this.index[title];\n};\n\nIndexer.prototype.reverseLookup = function(title) {\n\tthis._upkeep();\n\treturn this.backIndex[title] || Object.create(null);\n};\n\nIndexer.prototype.relinkLookup = function(fromTitle, toTitle, options) {\n\tthis._upkeep();\n\tvar shortlist = undefined;\n\tif (this.lastRelinkFrom === fromTitle) {\n\t\tif (this.lastRelinkTo === toTitle) {\n\t\t\t// We need to reintroduce the relink cache, where temporary info\n\t\t\t// was stored.\n\t\t\toptions.cache = this.lastRelinkCache;\n\t\t\treturn this.lastRelinkResult;\n\t\t}\n\t\tshortlist = Object.keys(this.lastRelinkResult);\n\t}\n\tthis.lastRelinkResult = utils.getRelinkResults(this.wiki, fromTitle, toTitle, this.context, shortlist, options);\n\tthis.lastRelinkTo = toTitle;\n\tthis.lastRelinkFrom = fromTitle;\n\tthis.lastRelinkCache = options.cache;\n\treturn this.lastRelinkResult;\n};\n\nIndexer.prototype._upkeep = function() {\n\tvar title;\n\tif (this.changedTiddlers && (this.context.changed(this.changedTiddlers) || this.context.parent.changed(this.changedTiddlers))) {\n\t\t// If global macro context or whitelist context changed, wipe all\n\t\tthis.rebuild();\n\t}\n\tif (!this.index) {\n\t\tthis.index = Object.create(null);\n\t\tthis.backIndex = Object.create(null);\n\t\tthis.context = utils.getWikiContext(this.wiki);\n\t\tvar titles = this.wiki.getRelinkableTitles();\n\t\tfor (var i = 0; i < titles.length; i++) {\n\t\t\tthis._populate(titles[i]);\n\t\t};\n\t} else if (this.changedTiddlers) {\n\t\t// If there are cached changes, we apply them now.\n\t\tfor (title in this.contexts) {\n\t\t\tvar tiddlerContext = this.contexts[title];\n\t\t\tif (tiddlerContext.changed(this.changedTiddlers)) {\n\t\t\t\tthis._purge(title);\n\t\t\t\tthis._populate(title);\n\t\t\t\tthis._dropResults(title);\n\t\t\t\t// Wipe this change, so we don't risk updating it twice.\n\t\t\t\tthis.changedTiddlers[title] = undefined;\n\t\t\t}\n\t\t}\n\t\tfor (title in this.changedTiddlers) {\n\t\t\tvar change = this.changedTiddlers[title];\n\t\t\tif (change && change.modified) {\n\t\t\t\tthis._purge(title);\n\t\t\t\tthis._populate(title);\n\t\t\t\tthis._dropResults(title);\n\t\t\t}\n\t\t}\n\t\tthis.changedTiddlers = undefined;\n\t}\n};\n\nIndexer.prototype._purge = function(title) {\n\tfor (var entry in this.index[title]) {\n\t\tdelete this.backIndex[entry][title];\n\t}\n\tdelete this.contexts[title];\n\tdelete this.index[title];\n};\n\n// This drops the cached relink results if unsanctioned tiddlers were changed\nIndexer.prototype._dropResults = function(title) {\n\tvar tiddler = this.wiki.getTiddler(title);\n\tif (title !== this.lastRelinkFrom\n\t&& title !== this.lastRelinkTo\n\t&& (!tiddler\n\t\t|| !$tw.utils.hop(tiddler.fields, 'draft.of') // is a draft\n\t\t|| tiddler.fields['draft.of'] !== this.lastRelinkFrom // draft of target\n\t\t|| references(this.index[title], this.lastRelinkFrom))) { // draft references target\n\t\t// This is not the draft of the last relinked title,\n\t\t// so our cached results should be wiped.\n\t\tthis.lastRelinkFrom = undefined;\n\t}\n};\n\nfunction references(list, item) {\n\treturn list !== undefined && list[item];\n};\n\nIndexer.prototype._populate = function(title) {\n\t// Fetch the report for a title, and populate the indexes with result\n\tvar tiddlerContext = new TiddlerContext(this.wiki, this.context, title);\n\tvar references = utils.getTiddlerRelinkReferences(this.wiki, title, tiddlerContext);\n\tthis.index[title] = references;\n\tif (tiddlerContext.hasImports()) {\n\t\tthis.contexts[title] = tiddlerContext;\n\t}\n\tfor (var ref in references) {\n\t\tthis.backIndex[ref] = this.backIndex[ref] || Object.create(null);\n\t\tthis.backIndex[ref][title] = references[ref];\n\t}\n};\n\nexports.RelinkIndexer = Indexer;\n",
"module-type": "indexer",
"title": "$:/plugins/flibbles/relink/js/indexer.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/language.js": {
"text": "/*\\\nmodule-type: library\n\nThis handles all logging and alerts Relink emits.\n\n\\*/\n\nexports.getString = function(title, options) {\n\ttitle = \"$:/plugins/flibbles/relink/language/\" + title;\n\treturn options.wiki.renderTiddler(\"text/plain\", title, options);\n};\n\nvar logger;\n\nexports.reportFailures = function(failureList, options) {\n\tif (!logger) {\n\t\tlogger = new $tw.utils.Logger(\"Relinker\");\n\t}\n\tvar alertString = this.getString(\"Error/ReportFailedRelinks\", options)\n\tvar alreadyReported = Object.create(null);\n\tvar reportList = [];\n\t$tw.utils.each(failureList, function(f) {\n\t\tif (!alreadyReported[f]) {\n\t\t\tif ($tw.browser) {\n\t\t\t\t// This might not make the link if the title is complicated.\n\t\t\t\t// Whatever.\n\t\t\t\treportList.push(\"\\n* [[\" + f + \"]]\");\n\t\t\t} else {\n\t\t\t\treportList.push(\"\\n* \" + f);\n\t\t\t}\n\t\t\talreadyReported[f] = true;\n\t\t}\n\t});\n\tlogger.alert(alertString + \"\\n\" + reportList.join(\"\"));\n};\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/language.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/mangler.js": {
"text": "/*\\\nmodule-type: widget\n\nCreates a mangler widget for field validation. This isn't meant to be used\nby the user. It's only used in Relink configuration.\n\n\\*/\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar language = require('$:/plugins/flibbles/relink/js/language.js');\nvar utils = require('$:/plugins/flibbles/relink/js/utils.js');\n\nvar RelinkManglerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"relink-add-field\", handler: \"handleAddFieldEvent\"},\n\t\t{type: \"relink-add-operator\", handler: \"handleAddOperatorEvent\"},\n\t\t{type: \"relink-add-parameter\", handler: \"handleAddParameterEvent\"},\n\t\t{type: \"relink-add-attribute\", handler: \"handleAddAttributeEvent\"}\n\t]);\n};\n\nexports.relinkmangler = RelinkManglerWidget;\n\nRelinkManglerWidget.prototype = new Widget();\n\n// This wraps alert so it can be monkeypatched during testing.\nRelinkManglerWidget.prototype.alert = function(message) {\n\talert(message);\n};\n\nRelinkManglerWidget.prototype.handleAddFieldEvent = function(event) {\n\tvar param = event.paramObject;\n\tif (typeof param !== \"object\" || !param.field) {\n\t\t// Can't handle it.\n\t\treturn true;\n\t}\n\tvar trimmedName = param.field.toLowerCase().trim();\n\tif (!trimmedName) {\n\t\t// Still can't handle it, but don't warn.\n\t\treturn true;\n\t}\n\tif(!$tw.utils.isValidFieldName(trimmedName)) {\n\t\tthis.alert($tw.language.getString(\n\t\t\t\"InvalidFieldName\",\n\t\t\t{variables:\n\t\t\t\t{fieldName: trimmedName}\n\t\t\t}\n\t\t));\n\t} else {\n\t\tadd(this.wiki, \"fields\", trimmedName);\n\t}\n\treturn true;\n};\n\n/**Not much validation, even though there are definitely illegal\n * operator names. If you input on, Relink won't relink it, but it\n * won't choke on it either. Tiddlywiki will...\n */\nRelinkManglerWidget.prototype.handleAddOperatorEvent = function(event) {\n\tvar param = event.paramObject;\n\tif (param) {\n\t\tadd(this.wiki, \"operators\", param.operator);\n\t}\n\treturn true;\n};\n\nRelinkManglerWidget.prototype.handleAddParameterEvent = function(event) {\n\tvar param = event.paramObject;\n\tif (param && param.macro && param.parameter) {\n\t\tif (/\\s/.test(param.macro.trim())) {\n\t\t\tthis.alert(language.getString(\n\t\t\t\t\"Error/InvalidMacroName\",\n\t\t\t\t{ variables: {macroName: param.macro},\n\t\t\t\t wiki: this.wiki\n\t\t\t\t}\n\t\t\t));\n\t\t} else if (/[ \\/]/.test(param.parameter.trim())) {\n\t\t\tthis.alert(language.getString(\n\t\t\t\t\"Error/InvalidParameterName\",\n\t\t\t\t{ variables: {parameterName: param.parameter},\n\t\t\t\t wiki: this.wiki\n\t\t\t\t}\n\t\t\t));\n\t\t} else {\n\t\t\tadd(this.wiki, \"macros\", param.macro, param.parameter);\n\t\t}\n\t}\n\treturn true;\n};\n\nRelinkManglerWidget.prototype.handleAddAttributeEvent = function(event) {\n\tvar param = event.paramObject;\n\tif (param && param.element && param.attribute) {\n\t\tif (/[ \\/]/.test(param.element.trim())) {\n\t\t\tthis.alert(language.getString(\n\t\t\t\t\"Error/InvalidElementName\",\n\t\t\t\t{ variables: {elementName: param.element},\n\t\t\t\t wiki: this.wiki\n\t\t\t\t}\n\t\t\t));\n\t\t} else if (/[ \\/]/.test(param.attribute.trim())) {\n\t\t\tthis.alert(language.getString(\n\t\t\t\t\"Error/InvalidAttributeName\",\n\t\t\t\t{ variables: {attributeName: param.attribute},\n\t\t\t\t wiki: this.wiki\n\t\t\t\t}\n\t\t\t));\n\t\t} else {\n\t\t\tadd(this.wiki, \"attributes\", param.element, param.attribute);\n\t\t}\n\t}\n\treturn true;\n};\n\nfunction add(wiki, category/*, path parts*/) {\n\tvar path = \"$:/config/flibbles/relink/\" + category;\n\tfor (var x = 2; x < arguments.length; x++) {\n\t\tvar part = arguments[x];\n\t\t// Abort if it's falsy, or only whitespace. Also, trim spaces\n\t\tif (!part || !(part = part.trim())) {\n\t\t\treturn;\n\t\t}\n\t\tpath = path + \"/\" + part;\n\t}\n\tvar def = utils.getDefaultType(wiki);\n\twiki.addTiddler({title: path, text: def});\n};\n",
"module-type": "widget",
"title": "$:/plugins/flibbles/relink/js/mangler.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/settings.js": {
"text": "/*\\\nmodule-type: library\n\nThis handles the fetching and distribution of relink settings.\n\n\\*/\n\nvar utils = require('./utils');\n\n///// Legacy. You used to be able to access the type from utils.\nexports.getType = utils.getType;\n/////\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/settings.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/utils.js": {
"text": "/*\\\nmodule-type: library\n\nUtility methods for relink.\n\n\\*/\n\nvar macroFilter = \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\";\n\n/**This works nearly identically to $tw.modules.getModulesByTypeAsHashmap\n * except that this also takes care of migrating V1 relink modules.\n */\nexports.getModulesByTypeAsHashmap = function(moduleType, nameField) {\n\tvar results = Object.create(null);\n\t$tw.modules.forEachModuleOfType(moduleType, function(title, module) {\n\t\tvar key = module[nameField];\n\t\tif (key !== undefined) {\n\t\t\tresults[key] = module;\n\t\t} else {\n\t\t\tfor (var entry in module) {\n\t\t\t\tresults[entry] = {\n\t\t\t\t\trelink: module[entry],\n\t\t\t\t\treport: function() {}};\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\nexports.getTiddlerRelinkReferences = function(wiki, title, context) {\n\tvar tiddler = wiki.getTiddler(title),\n\t\treferences = Object.create(null),\n\t\toptions = {settings: context, wiki: wiki};\n\tif (tiddler) {\n\t\ttry {\n\t\t\tfor (var relinker in getRelinkOperators()) {\n\t\t\t\tgetRelinkOperators()[relinker].report(tiddler, function(title, blurb) {\n\t\t\t\t\treferences[title] = references[title] || [];\n\t\t\t\t\treferences[title].push(blurb);\n\t\t\t\t}, options);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tif (e.message) {\n\t\t\t\te.message = e.message + \"\\nWhen reporting '\" + title + \"' Relink references\";\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n\treturn references;\n};\n\n/** Returns a pair like this,\n * { title: {field: entry, ... }, ... }\n */\nexports.getRelinkResults = function(wiki, fromTitle, toTitle, context, tiddlerList, options) {\n\toptions = options || {};\n\toptions.wiki = options.wiki || wiki;\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\tvar changeList = Object.create(null);\n\tif(fromTitle && toTitle) {\n\t\tif (tiddlerList === undefined) {\n\t\t\ttiddlerList = wiki.getRelinkableTitles();\n\t\t}\n\t\tfor (var i = 0; i < tiddlerList.length; i++) {\n\t\t\tvar title = tiddlerList[i];\n\t\t\tvar tiddler = wiki.getTiddler(title);\n\t\t\tif(tiddler && !tiddler.fields[\"plugin-type\"]) {\n\t\t\t\ttry {\n\t\t\t\t\tvar entries = Object.create(null),\n\t\t\t\t\t\toperators = getRelinkOperators();\n\t\t\t\t\toptions.settings = new Contexts.tiddler(wiki, context, title);\n\t\t\t\t\tfor (var operation in operators) {\n\t\t\t\t\t\toperators[operation].relink(tiddler, fromTitle, toTitle, entries, options);\n\t\t\t\t\t}\n\t\t\t\t\tfor (var field in entries) {\n\t\t\t\t\t\t// So long as there is one key,\n\t\t\t\t\t\t// add it to the change list.\n\t\t\t\t\t\tchangeList[title] = entries;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// Should we test for instanceof Error instead?: yes\n\t\t\t\t\t// Does that work in the testing environment?: no\n\t\t\t\t\tif (e.message) {\n\t\t\t\t\t\te.message = e.message + \"\\nWhen relinking '\" + title + \"'\";\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn changeList;\n};\n\nvar Contexts = $tw.modules.applyMethods('relinkcontext');\n\nexports.getContext = function(name) {\n\treturn Contexts[name];\n};\n\nexports.getWikiContext = function(wiki) {\n\t// This gives a fresh context every time. It is up to the indexer or\n\t// the cache to preserve those contexts for as long as needed.\n\tvar whitelist = new Contexts.whitelist(wiki);\n\treturn new Contexts.import(wiki, whitelist, macroFilter);\n};\n\n/** Returns the Relink indexer, or a dummy object which pretends to be one.\n */\nexports.getIndexer = function(wiki) {\n\tif (!wiki._relink_indexer) {\n\t\twiki._relink_indexer = (wiki.getIndexer && wiki.getIndexer(\"RelinkIndexer\")) || new (require('$:/plugins/flibbles/relink/js/utils/backupIndexer.js'))(wiki);\n\t}\n\treturn wiki._relink_indexer;\n};\n\n/**Relinking supports a cache that persists throughout a whole relink op.\n * This is because the Tiddlywiki caches may get wiped multiple times\n * throughout the course of a relink.\n */\nexports.getCacheForRun = function(options, cacheName, initializer) {\n\toptions.cache = options.cache || Object.create(null);\n\tif (!$tw.utils.hop(options.cache, cacheName)) {\n\t\toptions.cache[cacheName] = initializer();\n\t}\n\treturn options.cache[cacheName];\n};\n\n/**Returns a specific relinker.\n * This is useful for wikitext rules which need to parse a filter or a list\n */\nexports.getType = function(name) {\n\tvar Handler = getFieldTypes()[name];\n\treturn Handler ? new Handler() : undefined;\n};\n\nexports.getTypes = function() {\n\t// We don't return fieldTypes, because we don't want it modified,\n\t// and we need to filter out legacy names.\n\tvar rtn = Object.create(null);\n\tfor (var type in getFieldTypes()) {\n\t\tvar typeObject = getFieldTypes()[type];\n\t\trtn[typeObject.typeName] = typeObject;\n\t}\n\treturn rtn;\n};\n\nexports.getDefaultType = function(wiki) {\n\tvar tiddler = wiki.getTiddler(\"$:/config/flibbles/relink/settings/default-type\");\n\tvar defaultType = tiddler && tiddler.fields.text;\n\t// make sure the default actually exists, otherwise default\n\treturn fieldTypes[defaultType] ? defaultType : \"title\";\n};\n\nvar fieldTypes;\n\nfunction getFieldTypes() {\n\tif (!fieldTypes) {\n\t\tfieldTypes = Object.create(null);\n\t\t$tw.modules.forEachModuleOfType(\"relinkfieldtype\", function(title, exports) {\n\t\t\tfunction NewType() {};\n\t\t\tNewType.prototype = exports;\n\t\t\tNewType.typeName = exports.name;\n\t\t\tfieldTypes[exports.name] = NewType;\n\t\t\t// For legacy, if the NewType doesn't have a report method, we add one\n\t\t\tif (!exports.report) {\n\t\t\t\texports.report = function() {};\n\t\t\t}\n\t\t\t// Also for legacy, some of the field types can go by other names\n\t\t\tif (exports.aliases) {\n\t\t\t\t$tw.utils.each(exports.aliases, function(alias) {\n\t\t\t\t\tfieldTypes[alias] = NewType;\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\treturn fieldTypes;\n}\n\nvar relinkOperators;\n\nfunction getRelinkOperators() {\n\tif (!relinkOperators) {\n\t\trelinkOperators = exports.getModulesByTypeAsHashmap('relinkoperator', 'name');\n\t}\n\treturn relinkOperators;\n};\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/utils.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/wikimethods.js": {
"text": "/*\\\nmodule-type: wikimethod\n\nIntroduces some utility methods used by Relink.\n\n\\*/\n\nvar utils = require(\"./utils.js\");\n\nexports.getTiddlerRelinkReferences = function(title) {\n\treturn utils.getIndexer(this).lookup(title);\n};\n\nexports.getTiddlerRelinkBackreferences = function(title) {\n\treturn utils.getIndexer(this).reverseLookup(title);\n};\n\nexports.getRelinkableTitles = function() {\n\tvar toUpdate = \"$:/config/flibbles/relink/to-update\";\n\tvar wiki = this;\n\treturn this.getCacheForTiddler(toUpdate, \"relink-toUpdate\", function() {\n\t\tvar tiddler = wiki.getTiddler(toUpdate);\n\t\tif (tiddler) {\n\t\t\treturn wiki.compileFilter(tiddler.fields.text);\n\t\t} else {\n\t\t\treturn wiki.allTitles;\n\t\t}\n\t})();\n};\n",
"module-type": "wikimethod",
"title": "$:/plugins/flibbles/relink/js/wikimethods.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/filteroperators/all_relinkable.js": {
"text": "/*\\\nmodule-type: allfilteroperator\n\nFilter function for [all[relinkable]].\nReturns all tiddlers subject to relinking.\n\n\\*/\n\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.relinkable = function(source,prefix,options) {\n\treturn options.wiki.getRelinkableTitles();\n};\n\n})();\n",
"module-type": "allfilteroperator",
"title": "$:/plugins/flibbles/relink/js/filteroperators/all_relinkable.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/filteroperators/references.js": {
"text": "/*\\\nmodule-type: relinkfilteroperator\n\nGiven a title as an operand, returns all non-shadow tiddlers that have any\nsort of updatable reference to it.\n\n`relink:backreferences[]]`\n`relink:references[]]`\n\nReturns all tiddlers that reference `fromTiddler` somewhere inside them.\n\nInput is ignored. Maybe it shouldn't do this.\n\\*/\n\nvar LinkedList = $tw.utils.LinkedList;\n\nif (!LinkedList) {\n\t/* If the linked list isn't available, make a quick crappy version. */\n\tLinkedList = function() {this.array=[];};\n\n\tLinkedList.prototype.pushTop = function(array) {\n\t\t$tw.utils.pushTop(this.array, array);\n\t};\n\n\tLinkedList.prototype.toArray = function() {\n\t\treturn this.array;\n\t};\n};\n\nexports.backreferences = function(source,operator,options) {\n\tvar results = new LinkedList();\n\tsource(function(tiddler,title) {\n\t\tresults.pushTop(Object.keys(options.wiki.getTiddlerRelinkBackreferences(title,options)));\n\t});\n\treturn results.toArray();\n};\n\nexports.references = function(source,operator,options) {\n\tvar results = new LinkedList();\n\tsource(function(tiddler,title) {\n\t\tvar refs = options.wiki.getTiddlerRelinkReferences(title,options);\n\t\tif (refs) {\n\t\t\tresults.pushTop(Object.keys(refs));\n\t\t}\n\t});\n\treturn results.toArray();\n};\n",
"module-type": "relinkfilteroperator",
"title": "$:/plugins/flibbles/relink/js/filteroperators/references.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/filteroperators/relink.js": {
"text": "/*\\\nmodule-type: filteroperator\n\nThis filter acts as a namespace for several small, simple filters, such as\n\n`[relink:impossible[]]`\n\n\\*/\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar language = require('$:/plugins/flibbles/relink/js/language.js');\n\nvar relinkFilterOperators;\n\nfunction getRelinkFilterOperators() {\n\tif(!relinkFilterOperators) {\n\t\trelinkFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"relinkfilteroperator\",\n\t\t relinkFilterOperators);\n\t}\n\treturn relinkFilterOperators;\n}\n\nexports.relink = function(source,operator,options) {\n\tvar suffixPair = parseSuffix(operator.suffix);\n\tvar relinkFilterOperator = getRelinkFilterOperators()[suffixPair[0]];\n\tif (relinkFilterOperator) {\n\t\tvar newOperator = $tw.utils.extend({}, operator);\n\t\tnewOperator.suffix = suffixPair[1];\n\t\treturn relinkFilterOperator(source, newOperator, options);\n\t} else {\n\t\treturn [language.getString(\"Error/RelinkFilterOperator\", options)];\n\t}\n};\n\nfunction parseSuffix(suffix) {\n\tvar index = suffix? suffix.indexOf(\":\"): -1;\n\tif (index >= 0) {\n\t\treturn [suffix.substr(0, index), suffix.substr(index+1)];\n\t} else {\n\t\treturn [suffix];\n\t}\n}\n",
"module-type": "filteroperator",
"title": "$:/plugins/flibbles/relink/js/filteroperators/relink.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/filteroperators/report.js": {
"text": "/*\\\nmodule-type: relinkfilteroperator\n\nGiven a title as an operand, returns a string for each occurrence of that title\nwithin each input title.\n\n[[title]] +[relink:report[fromTiddler]]`\n\nReturns string representation of fromTiddler occurrences in title.\n\\*/\n\nexports.report = function(source,operator,options) {\n\tvar fromTitle = operator.operand,\n\t\tresults = [];\n\tif (fromTitle) {\n\t\tvar blurbs = options.wiki.getTiddlerRelinkBackreferences(fromTitle);\n\t\tsource(function(tiddler, title) {\n\t\t\tif (blurbs[title]) {\n\t\t\t\tresults = results.concat(blurbs[title]);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n",
"module-type": "relinkfilteroperator",
"title": "$:/plugins/flibbles/relink/js/filteroperators/report.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/filteroperators/signatures.js": {
"text": "/*\\\nmodule-type: relinkfilteroperator\n\nThis filter returns all input tiddlers which are a source of\nrelink configuration.\n\n`[all[tiddlers+system]relink:source[macros]]`\n\n\\*/\n\nvar utils = require('$:/plugins/flibbles/relink/js/utils.js');\n\nexports.signatures = function(source,operator,options) {\n\tvar plugin = operator.operand || null;\n\tvar set = getSet(options);\n\tif (plugin === \"$:/core\") {\n\t\t// Core doesn't actually have any settings. We mean Relink\n\t\tplugin = \"$:/plugins/flibbles/relink\";\n\t}\n\tvar signatures = [];\n\tfor (var signature in set) {\n\t\tvar source = set[signature].source;\n\t\tif (options.wiki.getShadowSource(source) === plugin) {\n\t\t\tsignatures.push(signature);\n\t\t}\n\t}\n\treturn signatures;\n};\n\nexports.type = function(source,operator,options) {\n\tvar results = [];\n\tvar set = getSet(options);\n\tsource(function(tiddler, signature) {\n\t\tif (set[signature]) {\n\t\t\tresults.push(set[signature].name);\n\t\t}\n\t});\n\treturn results;\n};\n\nexports.types = function(source,operator,options) {\n\tvar def = utils.getDefaultType(options.wiki);\n\tvar types = Object.keys(utils.getTypes());\n\ttypes.sort();\n\t// move default to front\n\ttypes.sort(function(x,y) { return x === def ? -1 : y === def ? 1 : 0; });\n\treturn types;\n};\n\nexports.source = function(source,operator,options) {\n\tvar results = [];\n\tvar category = operator.suffix;\n\tvar set = getSet(options);\n\tsource(function(tiddler, signature) {\n\t\tif (set[signature]) {\n\t\t\tresults.push(set[signature].source);\n\t\t}\n\t});\n\treturn results;\n};\n\nfunction getSet(options) {\n\treturn options.wiki.getGlobalCache(\"relink-signatures\", function() {\n\t\tvar config = utils.getWikiContext(options.wiki);\n\t\tvar set = Object.create(null);\n\t\tvar categories = {\n\t\t\tattributes: config.getAttributes(),\n\t\t\tfields: config.getFields(),\n\t\t\tmacros: config.getMacros(),\n\t\t\toperators: config.getOperators()};\n\t\t$tw.utils.each(categories, function(list, category) {\n\t\t\t$tw.utils.each(list, function(item, key) {\n\t\t\t\tset[category + \"/\" + key] = item;\n\t\t\t});\n\t\t});\n\t\treturn set;\n\t});\n};\n",
"module-type": "relinkfilteroperator",
"title": "$:/plugins/flibbles/relink/js/filteroperators/signatures.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/filteroperators/splitafter.js": {
"text": "/*\\\ntitle: $:/core/modules/filters/splitbefore.js\ntype: application/javascript\nmodule-type: relinkfilteroperator\n\nFilter operator that splits each result on the last occurance of the specified separator and returns the last bit.\n\nWhat does this have to do with relink? Nothing. I need this so I can render\nthe configuration menu. I //could// use [splitregexp[]], but then I'd be\nlimited to Tiddlywiki v5.1.20 or later.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.splitafter = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar index = title.lastIndexOf(operator.operand);\n\t\tif(index < 0) {\n\t\t\t$tw.utils.pushTop(results,title);\n\t\t} else {\n\t\t\t$tw.utils.pushTop(results,title.substr(index+1));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n\n",
"title": "$:/plugins/flibbles/relink/js/filteroperators/splitafter.js",
"type": "application/javascript",
"module-type": "relinkfilteroperator"
},
"$:/plugins/flibbles/relink/js/filteroperators/wouldchange.js": {
"text": "/*\\\nmodule-type: relinkfilteroperator\n\nwouldchange: Generator.\n\nGiven each input title, it returns all the tiddlers that would be changed if the currentTiddler were to be renamed to the operand.\n\nimpossible: filters all source titles for ones that encounter errors on failure.\n\nTHESE ARE INTERNAL FILTER OPERATOR AND ARE NOT INTENDED TO BE USED BY USERS.\n\n\\*/\n\nvar language = require(\"$:/plugins/flibbles/relink/js/language.js\");\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils.js\");\n\nexports.wouldchange = function(source,operator,options) {\n\tvar from = options.widget && options.widget.getVariable(\"currentTiddler\"),\n\t\tto = operator.operand,\n\t\tindexer = utils.getIndexer(options.wiki),\n\t\trecords = indexer.relinkLookup(from, to, options);\n\treturn Object.keys(records);\n};\n\nexports.impossible = function(source,operator,options) {\n\tvar from = options.widget && options.widget.getVariable(\"currentTiddler\"),\n\t\tto = operator.operand,\n\t\tresults = [],\n\t\tindexer = utils.getIndexer(options.wiki),\n\t\trecords = indexer.relinkLookup(from, to, options);\n\tsource(function(tiddler, title) {\n\t\tvar fields = records[title];\n\t\tif (fields) {\n\t\t\tfor (var field in fields) {\n\t\t\t\tif (fields[field].impossible) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n",
"module-type": "relinkfilteroperator",
"title": "$:/plugins/flibbles/relink/js/filteroperators/wouldchange.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/fieldtypes/filter.js": {
"text": "/*\\\nThis specifies logic for updating filters to reflect title changes.\n\\*/\n\nvar refHandler = require(\"$:/plugins/flibbles/relink/js/fieldtypes/reference\");\nvar Rebuilder = require(\"$:/plugins/flibbles/relink/js/utils/rebuilder\");\n\nexports.name = \"filter\";\n\nexports.report = function(filter, callback, options) {\n\t// I cheat here for now. Relink handles reporting too in cases where\n\t// fromTitle is undefined. toTitle is the callback in those cases.\n\texports.relink(filter, undefined, callback, options);\n};\n\n/**Returns undefined if no change was made.\n */\nexports.relink = function(filter, fromTitle, toTitle, options) {\n\tvar relinker = new Rebuilder(filter),\n\t\tp = 0, // Current position in the filter string\n\t\tmatch, noPrecedingWordBarrier,\n\t\twordBarrierRequired=false;\n\tvar whitespaceRegExp = /\\s+/mg,\n\t\toperandRegExp = /((?:\\+|\\-|~|=|\\:\\w+)?)(?:(\\[)|(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s\\[\\]]+))/mg,\n\t\tblurbs = [];\n\twhile(p < filter.length) {\n\t\t// Skip any whitespace\n\t\twhitespaceRegExp.lastIndex = p;\n\t\tmatch = whitespaceRegExp.exec(filter);\n\t\tnoPrecedingWordBarrier = false;\n\t\tif(match && match.index === p) {\n\t\t\tp = p + match[0].length;\n\t\t} else if (p != 0) {\n\t\t\tif (wordBarrierRequired) {\n\t\t\t\trelinker.add(' ', p, p);\n\t\t\t\twordBarrierRequired = false;\n\t\t\t} else {\n\t\t\t\tnoPrecedingWordBarrier = true;\n\t\t\t}\n\t\t}\n\t\t// Match the start of the operation\n\t\tif(p < filter.length) {\n\t\t\tvar val;\n\t\t\toperandRegExp.lastIndex = p;\n\t\t\tmatch = operandRegExp.exec(filter);\n\t\t\tif(!match || match.index !== p) {\n\t\t\t\t// It's a bad filter\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif(match[1]) { // prefix\n\t\t\t\tp += match[1].length;\n\t\t\t}\n\t\t\tif(match[2]) { // Opening square bracket\n\t\t\t\t// We check if this is a standalone title,\n\t\t\t\t// like `[[MyTitle]]`. We treat those like\n\t\t\t\t// `\"MyTitle\"` or `MyTitle`. Not like a run.\n\t\t\t\tvar standaloneTitle = /\\[\\[([^\\]]+)\\]\\]/g;\n\t\t\t\tstandaloneTitle.lastIndex = p;\n\t\t\t\tvar alone = standaloneTitle.exec(filter);\n\t\t\t\tif (!alone || alone.index != p) {\n\t\t\t\t\tif (fromTitle === undefined) {\n\t\t\t\t\t\t// toTitle is a callback method in this case.\n\t\t\t\t\t\tp =reportFilterOperation(filter, function(title, blurb){\n\t\t\t\t\t\t\tif (match[1]) {\n\t\t\t\t\t\t\t\tblurbs.push([title, match[1] + (blurb || '')]);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tblurbs.push([title, blurb]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},p,options.settings,options);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp =relinkFilterOperation(relinker,fromTitle,toTitle,filter,p,options.settings,options);\n\t\t\t\t\t}\n\t\t\t\t\t// It's a legit run\n\t\t\t\t\tif (p === undefined) {\n\t\t\t\t\t\t// The filter is malformed\n\t\t\t\t\t\t// We do nothing.\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbracketTitle = alone[1];\n\t\t\t\toperandRegExp.lastIndex = standaloneTitle.lastIndex;\n\t\t\t\tval = alone[1];\n\t\t\t} else {\n\t\t\t\t// standalone Double quoted string, single\n\t\t\t\t// quoted string, or noquote ahead.\n\t\t\t\tval = match[3] || match[4] || match[5];\n\t\t\t}\n\t\t\t// From here on, we're dealing with a standalone title\n\t\t\t// expression. like `\"MyTitle\"` or `[[MyTitle]]`\n\t\t\t// We're much more flexible about relinking these.\n\t\t\tvar preference = undefined;\n\t\t\tif (match[3]) {\n\t\t\t\tpreference = '\"';\n\t\t\t} else if (match[4]) {\n\t\t\t\tpreference = \"'\";\n\t\t\t} else if (match[5]) {\n\t\t\t\tpreference = '';\n\t\t\t}\n\t\t\tif (fromTitle === undefined) {\n\t\t\t\t// Report it\n\t\t\t\tblurbs.push([val, match[1]]);\n\t\t\t} else if (val === fromTitle) {\n\t\t\t\t// Relink it\n\t\t\t\tvar entry = {name: \"title\"};\n\t\t\t\tvar newVal = wrapTitle(toTitle, preference);\n\t\t\t\tif (newVal === undefined || (options.inBraces && newVal.indexOf('}}}') >= 0)) {\n\t\t\t\t\tif (!options.placeholder) {\n\t\t\t\t\t\trelinker.impossible = true;\n\t\t\t\t\t\tp = operandRegExp.lastIndex;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewVal = \"[<\"+options.placeholder.getPlaceholderFor(toTitle)+\">]\";\n\t\t\t\t}\n\t\t\t\tif (newVal[0] != '[') {\n\t\t\t\t\t// not bracket enclosed\n\t\t\t\t\t// this requires whitespace\n\t\t\t\t\t// arnound it\n\t\t\t\t\tif (noPrecedingWordBarrier && !match[1]) {\n\t\t\t\t\t\trelinker.add(' ', p, p);\n\t\t\t\t\t}\n\t\t\t\t\twordBarrierRequired = true;\n\t\t\t\t}\n\t\t\t\tentry.output = toTitle;\n\t\t\t\tentry.operator = {operator: \"title\"};\n\t\t\t\tentry.quotation = preference;\n\t\t\t\tif (entry.impossible) {\n\t\t\t\t\trelinker.impossible = true;\n\t\t\t\t}\n\t\t\t\trelinker.add(newVal,p,operandRegExp.lastIndex);\n\t\t\t}\n\t\t\tp = operandRegExp.lastIndex;\n\t\t}\n\t}\n\tif (fromTitle === undefined) {\n\t\t// We delay the blurb calls until now in case it's a malformed\n\t\t// filter string. We don't want to report some, only to find out\n\t\t// it's bad.\n\t\tfor (var i = 0; i < blurbs.length; i++) {\n\t\t\ttoTitle(blurbs[i][0], blurbs[i][1]);\n\t\t}\n\t}\n\tif (relinker.changed() || relinker.impossible) {\n\t\treturn {output: relinker.results(), impossible: relinker.impossible };\n\t}\n\treturn undefined;\n};\n\n/* Same as this.relink, except this has the added constraint that the return\n * value must be able to be wrapped in curly braces. (i.e. '{{{...}}}')\n */\nexports.relinkInBraces = function(filter, fromTitle, toTitle, options) {\n\tvar braceOptions = $tw.utils.extend({inBraces: true}, options);\n\tvar entry = this.relink(filter, fromTitle, toTitle, braceOptions);\n\tif (entry && entry.output && !canBeInBraces(entry.output)) {\n\t\t// It was possible, but it won't fit in braces, so we must give up\n\t\tdelete entry.output;\n\t\tentry.impossible = true;\n\t}\n\treturn entry;\n};\n\nfunction wrapTitle(value, preference) {\n\tvar choices = {\n\t\t\"\": function(v) {return /^[^\\s\\[\\]]*[^\\s\\[\\]\\}]$/.test(v); },\n\t\t\"[\": canBePrettyOperand,\n\t\t\"'\": function(v) {return v.indexOf(\"'\") < 0; },\n\t\t'\"': function(v) {return v.indexOf('\"') < 0; }\n\t};\n\tvar wrappers = {\n\t\t\"\": function(v) {return v; },\n\t\t\"[\": function(v) {return \"[[\"+v+\"]]\"; },\n\t\t\"'\": function(v) {return \"'\"+v+\"'\"; },\n\t\t'\"': function(v) {return '\"'+v+'\"'; }\n\t};\n\tif (choices[preference]) {\n\t\tif (choices[preference](value)) {\n\t\t\treturn wrappers[preference](value);\n\t\t}\n\t}\n\tfor (var quote in choices) {\n\t\tif (choices[quote](value)) {\n\t\t\treturn wrappers[quote](value);\n\t\t}\n\t}\n\t// No quotes will work on this\n\treturn undefined;\n}\n\nfunction relinkFilterOperation(relinker, fromTitle, toTitle, filterString, p, context, options) {\n\tvar nextBracketPos, operator;\n\t// Skip the starting square bracket\n\tif(filterString.charAt(p++) !== \"[\") {\n\t\t// Missing [ in filter expression\n\t\treturn undefined;\n\t}\n\t// Process each operator in turn\n\toperator = parseOperator(filterString, p);\n\tdo {\n\t\tvar entry = undefined, type;\n\t\tif (operator === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tp = operator.opStart;\n\t\tswitch (operator.bracket) {\n\t\t\tcase \"{\": // Curly brackets\n\t\t\t\ttype = \"indirect\";\n\t\t\t\tnextBracketPos = filterString.indexOf(\"}\",p);\n\t\t\t\tvar operand = filterString.substring(p,nextBracketPos);\n\t\t\t\t// We've got a live reference. relink or report\n\t\t\t\tentry = refHandler.relinkInBraces(operand, fromTitle, toTitle, options);\n\t\t\t\tif (entry && entry.output) {\n\t\t\t\t\t// We don't check the context.\n\t\t\t\t\t// All indirect operands convert.\n\t\t\t\t\trelinker.add(entry.output,p,nextBracketPos);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"[\": // Square brackets\n\t\t\t\ttype = \"string\";\n\t\t\t\tnextBracketPos = filterString.indexOf(\"]\",p);\n\t\t\t\tvar operand = filterString.substring(p,nextBracketPos);\n\t\t\t\t// Check if this is a relevant operator\n\t\t\t\tvar handler = fieldType(context, operator);\n\t\t\t\tif (!handler) {\n\t\t\t\t\t// This operator isn't managed. Bye.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tentry = handler.relink(operand, fromTitle, toTitle, options);\n\t\t\t\tif (!entry || !entry.output) {\n\t\t\t\t\t// The fromTitle wasn't in the operand.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tvar wrapped;\n\t\t\t\tif (!canBePrettyOperand(entry.output) || (options.inBraces && entry.output.indexOf('}}}') >= 0)) {\n\t\t\t\t\tif (!options.placeholder) {\n\t\t\t\t\t\tdelete entry.output;\n\t\t\t\t\t\tentry.impossible = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tvar ph = options.placeholder.getPlaceholderFor(entry.output, handler.name);\n\t\t\t\t\twrapped = \"<\"+ph+\">\";\n\t\t\t\t} else {\n\t\t\t\t\twrapped = \"[\"+entry.output+\"]\";\n\t\t\t\t}\n\t\t\t\trelinker.add(wrapped, p-1, nextBracketPos+1);\n\t\t\t\tbreak;\n\t\t\tcase \"<\": // Angle brackets\n\t\t\t\tnextBracketPos = filterString.indexOf(\">\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"/\": // regexp brackets\n\t\t\t\tvar rex = /^((?:[^\\\\\\/]*|\\\\.)*)\\/(?:\\(([mygi]+)\\))?/g,\n\t\t\t\t\trexMatch = rex.exec(filterString.substring(p));\n\t\t\t\tif(rexMatch) {\n\t\t\t\t\tnextBracketPos = p + rex.lastIndex - 1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Unterminated regular expression\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tif (entry) {\n\t\t\tif (entry.impossible) {\n\t\t\t\trelinker.impossible = true;\n\t\t\t}\n\t\t}\n\n\t\tif(nextBracketPos === -1) {\n\t\t\t// Missing closing bracket in filter expression\n\t\t\treturn undefined;\n\t\t}\n\t\tp = nextBracketPos + 1;\n\t\t// Check for multiple operands\n\t\tswitch (filterString.charAt(p)) {\n\t\tcase ',':\n\t\t\tp++;\n\t\t\tif(/^[\\[\\{<\\/]/.test(filterString.substring(p))) {\n\t\t\t\toperator.bracket = filterString.charAt(p);\n\t\t\t\toperator.opStart = p + 1;\n\t\t\t\toperator.index++;\n\t\t\t} else {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\toperator = parseOperator(filterString, p);\n\t\t\tcontinue;\n\t\tcase ']':\n\t\t}\n\t\tbreak;\n\t} while(true);\n\t// Skip the ending square bracket\n\tif(filterString.charAt(p++) !== \"]\") {\n\t\t// Missing ] in filter expression\n\t\treturn undefined;\n\t}\n\t// Return the parsing position\n\treturn p;\n}\n\nfunction reportFilterOperation(filterString, callback, p, context, options) {\n\tvar nextBracketPos, operator;\n\t// Skip the starting square bracket\n\tif(filterString.charAt(p++) !== \"[\") {\n\t\t// Missing [ in filter expression\n\t\treturn undefined;\n\t}\n\toperator = parseOperator(filterString, p);\n\t// Process each operator in turn\n\tdo {\n\t\tif (operator === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tp = operator.opStart;\n\t\tswitch (operator.bracket) {\n\t\t\tcase \"{\": // Curly brackets\n\t\t\t\tnextBracketPos = filterString.indexOf(\"}\",p);\n\t\t\t\tvar operand = filterString.substring(p,nextBracketPos);\n\t\t\t\t// Just report it\n\t\t\t\trefHandler.report(operand, function(title, blurb) {\n\t\t\t\t\tcallback(title, operatorBlurb(operator, '{' + (blurb || '') + '}'));\n\t\t\t\t}, options);\n\t\t\t\tbreak;\n\t\t\tcase \"[\": // Square brackets\n\t\t\t\tnextBracketPos = filterString.indexOf(\"]\",p);\n\t\t\t\tvar operand = filterString.substring(p,nextBracketPos);\n\t\t\t\t// Check if this is a relevant operator\n\t\t\t\tvar handler = fieldType(context, operator);\n\t\t\t\tif (!handler) {\n\t\t\t\t\t// This operator isn't managed. Bye.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// We just have to report it. Nothing more.\n\t\t\t\thandler.report(operand, function(title, blurb) {\n\t\t\t\t\tcallback(title, operatorBlurb(operator, '[' + (blurb || '') + ']'));\n\t\t\t\t}, options);\n\t\t\t\tbreak;\n\n\t\t\tcase \"<\": // Angle brackets\n\t\t\t\tnextBracketPos = filterString.indexOf(\">\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"/\": // regexp brackets\n\t\t\t\tvar rex = /^((?:[^\\\\\\/]*|\\\\.)*)\\/(?:\\(([mygi]+)\\))?/g,\n\t\t\t\t\trexMatch = rex.exec(filterString.substring(p));\n\t\t\t\tif(rexMatch) {\n\t\t\t\t\tnextBracketPos = p + rex.lastIndex - 1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Unterminated regular expression\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif(nextBracketPos === -1) {\n\t\t\t// Missing closing bracket in filter expression\n\t\t\treturn undefined;\n\t\t}\n\t\tp = nextBracketPos + 1;\n\t\t// Check for multiple operands\n\t\tswitch (filterString.charAt(p)) {\n\t\tcase ',':\n\t\t\tp++;\n\t\t\tif(/^[\\[\\{<\\/]/.test(filterString.substring(p))) {\n\t\t\t\toperator.bracket = filterString.charAt(p);\n\t\t\t\toperator.opStart = p + 1;\n\t\t\t\toperator.index++;\n\t\t\t} else {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\toperator = parseOperator(filterString, p);\n\t\t\tcontinue;\n\t\tcase ']':\n\t\t}\n\t\tbreak;\n\t} while(true);\n\t// Skip the ending square bracket\n\tif(filterString.charAt(p++) !== \"]\") {\n\t\t// Missing ] in filter expression\n\t\treturn undefined;\n\t}\n\t// Return the parsing position\n\treturn p;\n}\n\nfunction parseOperator(filterString, p) {\n\tvar nextBracketPos, operator = {index: 1};\n\t// Check for an operator prefix\n\tif(filterString.charAt(p) === \"!\") {\n\t\toperator.prefix = \"!\";\n\t\tp++;\n\t}\n\t// Get the operator name\n\tnextBracketPos = filterString.substring(p).search(/[\\[\\{<\\/]/);\n\tif(nextBracketPos === -1) {\n\t\t// Missing [ in filter expression\n\t\treturn undefined;\n\t}\n\tnextBracketPos += p;\n\toperator.bracket = filterString.charAt(nextBracketPos);\n\toperator.operator = filterString.substring(p,nextBracketPos);\n\n\t// Any suffix?\n\tvar colon = operator.operator.indexOf(':');\n\tif(colon > -1) {\n\t\toperator.suffix = operator.operator.substring(colon + 1);\n\t\toperator.operator = operator.operator.substring(0,colon) || \"field\";\n\t}\n\t// Empty operator means: title\n\telse if(operator.operator === \"\") {\n\t\toperator.operator = \"title\";\n\t\toperator.default = true;\n\t}\n\toperator.opStart = nextBracketPos + 1;\n\treturn operator;\n};\n\nfunction operatorBlurb(operator, enquotedOperand) {\n\tvar suffix = operator.suffix ? (':' + operator.suffix) : '';\n\t// commas to indicate which number operand\n\tsuffix += (new Array(operator.index)).join(',');\n\tvar op = operator.default ? '' : operator.operator;\n\treturn '[' + (operator.prefix || '') + op + suffix + enquotedOperand + ']';\n};\n\n// Returns the relinker needed for a given operator, or returns undefined.\nfunction fieldType(context, operator) {\n\treturn (operator.suffix &&\n\t context.getOperator(operator.operator + ':' + operator.suffix, operator.index)) ||\n\t context.getOperator(operator.operator, operator.index);\n};\n\nfunction canBePrettyOperand(value) {\n\treturn value.indexOf(']') < 0;\n};\n\nfunction canBeInBraces(value) {\n\treturn value.indexOf(\"}}}\") < 0 && value.substr(value.length-2) !== '}}';\n};\n",
"module-type": "relinkfieldtype",
"title": "$:/plugins/flibbles/relink/js/fieldtypes/filter.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/fieldtypes/list.js": {
"text": "/*\\\nThis manages replacing titles that occur within stringLists, like,\n\nTiddlerA [[Tiddler with spaces]] [[Another Title]]\n\\*/\n\nexports.name = \"list\";\n\nexports.report = function(value, callback, options) {\n\tvar list = $tw.utils.parseStringArray(value);\n\tfor (var i = 0; i < list.length; i++) {\n\t\tcallback(list[i]);\n\t}\n};\n\n/**Returns undefined if no change was made.\n * Parameter: value can literally be a list. This can happen for builtin\n * types 'list' and 'tag'. In those cases, we also return list.\n */\nexports.relink = function(value, fromTitle, toTitle, options) {\n\tvar isModified = false,\n\t\tactualList = false,\n\t\tlist;\n\tif (typeof value !== \"string\") {\n\t\t// Not a string. Must be a list.\n\t\t// clone it, since we may make changes to this possibly\n\t\t// frozen list.\n\t\tlist = (value || []).slice(0);\n\t\tactualList = true;\n\t} else {\n\t\tlist = $tw.utils.parseStringArray(value || \"\");\n\t}\n\t$tw.utils.each(list,function (title,index) {\n\t\tif(title === fromTitle) {\n\t\t\tlist[index] = toTitle;\n\t\t\tisModified = true;\n\t\t}\n\t});\n\tif (isModified) {\n\t\tvar entry = {name: \"list\"};\n\t\t// It doesn't parse correctly alone, it won't\n\t\t// parse correctly in any list.\n\t\tif (!canBeListItem(toTitle)) {\n\t\t\tentry.impossible = true;\n\t\t} else if (actualList) {\n\t\t\tentry.output = list;\n\t\t} else {\n\t\t\tentry.output = $tw.utils.stringifyList(list);\n\t\t}\n\t\treturn entry;\n\t}\n\treturn undefined;\n};\n\nfunction canBeListItem(value) {\n\tvar regexp = /\\]\\][^\\S\\xA0]/m;\n\treturn !regexp.test(value);\n};\n",
"module-type": "relinkfieldtype",
"title": "$:/plugins/flibbles/relink/js/fieldtypes/list.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/fieldtypes/reference.js": {
"text": "/*\\\nThis manages replacing titles that occur inside text references,\n\ntiddlerTitle\ntiddlerTitle!!field\n!!field\ntiddlerTitle##propertyIndex\n\\*/\n\nexports.name = \"reference\";\n\nexports.report = function(value, callback, options) {\n\tif (value) {\n\t\tvar reference = $tw.utils.parseTextReference(value),\n\t\t\ttitle = reference.title,\n\t\t\tblurb;\n\t\tif (title) {\n\t\t\tif (reference.field) {\n\t\t\t\tblurb = '!!' + reference.field;\n\t\t\t} else if (reference.index) {\n\t\t\t\tblurb = '##' + reference.index;\n\t\t\t}\n\t\t\tcallback(title, blurb);\n\t\t}\n\t}\n};\n\nexports.relink = function(value, fromTitle, toTitle, options) {\n\tvar entry;\n\tif (value) {\n\t\tvar reference = $tw.utils.parseTextReference(value);\n\t\tif (reference.title === fromTitle) {\n\t\t\tif (!exports.canBePretty(toTitle)) {\n\t\t\t\tentry = {impossible: true};\n\t\t\t} else {\n\t\t\t\treference.title = toTitle;\n\t\t\t\tentry = {output: exports.toString(reference)};\n\t\t\t}\n\t\t}\n\t}\n\treturn entry;\n};\n\n/* Same as this.relink, except this has the added constraint that the return\n * value must be able to be wrapped in curly braces.\n */\nexports.relinkInBraces = function(value, fromTitle, toTitle, options) {\n\tvar log = this.relink(value, fromTitle, toTitle, options);\n\tif (log && log.output && toTitle.indexOf(\"}\") >= 0) {\n\t\tdelete log.output;\n\t\tlog.impossible = true;\n\t}\n\treturn log;\n};\n\nexports.toString = function(textReference) {\n\tvar title = textReference.title || '';\n\tif (textReference.field) {\n\t\treturn title + \"!!\" + textReference.field;\n\t} else if (textReference.index) {\n\t\treturn title + \"##\" + textReference.index;\n\t}\n\treturn title;\n};\n\nexports.canBePretty = function(title) {\n\treturn !title || (title.indexOf(\"!!\") < 0 && title.indexOf(\"##\") < 0);\n};\n",
"module-type": "relinkfieldtype",
"title": "$:/plugins/flibbles/relink/js/fieldtypes/reference.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/fieldtypes/title.js": {
"text": "/*\\\nThis specifies logic for replacing a single-tiddler field. This is the\nsimplest kind of field type. One title swaps out for the other.\n\\*/\n\n// NOTE TO MODDERS: If you're making your own field types, the name must be\n// alpha characters only.\nexports.name = 'title';\n\nexports.report = function(value, callback, options) {\n\tcallback(value);\n};\n\n/**Returns undefined if no change was made.\n */\nexports.relink = function(value, fromTitle, toTitle, options) {\n\tif (value === fromTitle) {\n\t\treturn {output: toTitle};\n\t}\n\treturn undefined;\n};\n\n// This is legacy support for when 'title' was known as 'field'\nexports.aliases = ['field', 'yes'];\n",
"module-type": "relinkfieldtype",
"title": "$:/plugins/flibbles/relink/js/fieldtypes/title.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/fieldtypes/wikitext.js": {
"text": "/*\\\nThis specifies logic for updating filters to reflect title changes.\n\\*/\n\nexports.name = \"wikitext\";\n\nvar type = 'text/vnd.tiddlywiki';\n\nvar WikiParser = require(\"$:/core/modules/parsers/wikiparser/wikiparser.js\")[type];\nvar Rebuilder = require(\"$:/plugins/flibbles/relink/js/utils/rebuilder.js\");\nvar utils = require('$:/plugins/flibbles/relink/js/utils');\nvar WikitextContext = utils.getContext('wikitext');\n\nfunction collectRules() {\n\tvar rules = Object.create(null);\n\t$tw.modules.forEachModuleOfType(\"relinkwikitextrule\", function(title, exports) {\n\t\tvar names = exports.name;\n\t\tif (typeof names === \"string\") {\n\t\t\tnames = [names];\n\t\t}\n\t\tif (names !== undefined) {\n\t\t\tfor (var i = 0; i < names.length; i++) {\n\t\t\t\trules[names[i]] = exports;\n\t\t\t}\n\t\t}\n\t});\n\treturn rules;\n}\n\nfunction WikiWalker(type, text, options) {\n\tthis.options = options;\n\tif (!this.relinkMethodsInjected) {\n\t\tvar rules = collectRules();\n\t\t$tw.utils.each([this.pragmaRuleClasses, this.blockRuleClasses, this.inlineRuleClasses], function(classList) {\n\t\t\tfor (var name in classList) {\n\t\t\t\tif (rules[name]) {\n\t\t\t\t\tdelete rules[name].name;\n\t\t\t\t\t$tw.utils.extend(classList[name].prototype, rules[name]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tWikiWalker.prototype.relinkMethodsInjected = true;\n\t}\n\tthis.context = new WikitextContext(options.settings);\n\tWikiParser.call(this, type, text, options);\n};\n\nWikiWalker.prototype = Object.create(WikiParser.prototype);\n\nWikiWalker.prototype.parsePragmas = function() {\n\tvar entries = this.tree;\n\twhile (true) {\n\t\tthis.skipWhitespace();\n\t\tif (this.pos >= this.sourceLength) {\n\t\t\tbreak;\n\t\t}\n\t\tvar nextMatch = this.findNextMatch(this.pragmaRules, this.pos);\n\t\tif (!nextMatch || nextMatch.matchIndex !== this.pos) {\n\t\t\tbreak;\n\t\t}\n\t\tentries.push.apply(entries, this.handleRule(nextMatch));\n\t}\n\treturn entries;\n};\n\nWikiWalker.prototype.parseInlineRunUnterminated = function(options) {\n\tvar entries = [];\n\tvar nextMatch = this.findNextMatch(this.inlineRules, this.pos);\n\twhile (this.pos < this.sourceLength && nextMatch) {\n\t\tif (nextMatch.matchIndex > this.pos) {\n\t\t\tthis.pos = nextMatch.matchIndex;\n\t\t}\n\t\tentries.push.apply(entries, this.handleRule(nextMatch));\n\t\tnextMatch = this.findNextMatch(this.inlineRules, this.pos);\n\t}\n\tthis.pos = this.sourceLength;\n\treturn entries;\n};\n\nWikiWalker.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {\n\tvar entries = [];\n\toptions = options || {};\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\tvar inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\twhile(this.pos < this.sourceLength && (terminatorMatch || inlineRuleMatch)) {\n\t\tif (terminatorMatch) {\n\t\t\tif (!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {\n\t\t\t\tthis.pos = terminatorMatch.index;\n\t\t\t\tif (options.eatTerminator) {\n\t\t\t\t\tthis.pos += terminatorMatch[0].length;\n\t\t\t\t}\n\t\t\t\treturn entries;\n\t\t\t}\n\t\t}\n\t\tif (inlineRuleMatch) {\n\t\t\tif (inlineRuleMatch.matchIndex > this.pos) {\n\t\t\t\tthis.pos = inlineRuleMatch.matchIndex;\n\t\t\t}\n\t\t\tentries.push.apply(entries, this.handleRule(inlineRuleMatch));\n\t\t\tinlineRuleMatch = this.findNextMatch(this.inlineRules, this.pos);\n\t\t\tterminatorRegExp.lastIndex = this.pos;\n\t\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\t}\n\t}\n\tthis.pos = this.sourceLength;\n\treturn entries;\n\n};\n\nWikiWalker.prototype.parseBlock = function(terminatorRegExp) {\n\tvar terminatorRegExp = /(\\r?\\n\\r?\\n)/mg;\n\tthis.skipWhitespace();\n\tif (this.pos >= this.sourceLength) {\n\t\treturn [];\n\t}\n\tvar nextMatch = this.findNextMatch(this.blockRules, this.pos);\n\tif(nextMatch && nextMatch.matchIndex === this.pos) {\n\t\treturn this.handleRule(nextMatch);\n\t}\n\treturn this.parseInlineRun(terminatorRegExp);\n};\n\nWikiWalker.prototype.amendRules = function(type, names) {\n\tvar only;\n\tWikiParser.prototype.amendRules.call(this, type, names);\n\tif (type === \"only\") {\n\t\tonly = true;\n\t} else if (type === \"except\") {\n\t\tonly = false;\n\t} else {\n\t\treturn;\n\t}\n\tif (only !== (names.indexOf(\"macrodef\") >= 0) && this.options.macrodefCanBeDisabled) {\n\t\tthis.options.placeholder = undefined\n\t}\n\tif (only !== (names.indexOf(\"html\") >= 0)) {\n\t\tthis.context.allowWidgets = disabled;\n\t}\n\tif (only !== (names.indexOf(\"prettylink\") >= 0)) {\n\t\tthis.context.allowPrettylinks = disabled;\n\t}\n};\n\nfunction disabled() { return false; };\n\n/// Reporter\n\nfunction WikiReporter(type, text, callback, options) {\n\tthis.callback = callback;\n\tWikiWalker.call(this, type, text, options);\n};\n\nWikiReporter.prototype = Object.create(WikiWalker.prototype);\n\nWikiReporter.prototype.handleRule = function(ruleInfo) {\n\tif (ruleInfo.rule.report) {\n\t\truleInfo.rule.report(this.source, this.callback, this.options);\n\t} else {\n\t\tif (ruleInfo.rule.matchRegExp !== undefined) {\n\t\t\tthis.pos = ruleInfo.rule.matchRegExp.lastIndex;\n\t\t} else {\n\t\t\t// We can't easily determine the end of this\n\t\t\t// rule match. We'll \"parse\" it so that\n\t\t\t// parser.pos gets updated, but we throw away\n\t\t\t// the results.\n\t\t\truleInfo.rule.parse();\n\t\t}\n\t}\n};\n\nexports.report = function(wikitext, callback, options) {\n\t// Unfortunately it's the side-effect of creating this that reports.\n\tnew WikiReporter(options.type, wikitext, callback, options);\n};\n\n/// Relinker\n\nfunction WikiRelinker(type, text, fromTitle, toTitle, options) {\n\tthis.fromTitle = fromTitle;\n\tthis.toTitle = toTitle;\n\tthis.placeholder = options.placeholder;\n\tif (this.placeholder) {\n\t\tthis.placeholder.parser = this;\n\t}\n\tWikiWalker.call(this, type, text, options);\n};\n\nWikiRelinker.prototype = Object.create(WikiWalker.prototype);\n\nWikiRelinker.prototype.handleRule = function(ruleInfo) {\n\tif (ruleInfo.rule.relink) {\n\t\tvar start = ruleInfo.matchIndex;\n\t\tvar newEntry = ruleInfo.rule.relink(this.source, this.fromTitle, this.toTitle, this.options);\n\t\tif (newEntry !== undefined) {\n\t\t\tif (newEntry.output) {\n\t\t\t\tnewEntry.start = start;\n\t\t\t\tnewEntry.end = this.pos;\n\t\t\t}\n\t\t\treturn [newEntry];\n\t\t}\n\t} else {\n\t\tif (ruleInfo.rule.matchRegExp !== undefined) {\n\t\t\tthis.pos = ruleInfo.rule.matchRegExp.lastIndex;\n\t\t} else {\n\t\t\t// We can't easily determine the end of this\n\t\t\t// rule match. We'll \"parse\" it so that\n\t\t\t// parser.pos gets updated, but we throw away\n\t\t\t// the results.\n\t\t\truleInfo.rule.parse();\n\t\t}\n\t}\n\treturn [];\n};\n\nexports.relink = function(wikitext, fromTitle, toTitle, options) {\n\tvar parser = new WikiRelinker(options.type, wikitext, fromTitle, toTitle, options),\n\t\twikiEntry = undefined;\n\t// Now that we have an array of entries, let's produce the wikiText entry\n\t// containing them all.\n\tif (parser.tree.length > 0) {\n\t\tvar builder = new Rebuilder(wikitext);\n\t\twikiEntry = {};\n\t\tfor (var i = 0; i < parser.tree.length; i++) {\n\t\t\tvar entry = parser.tree[i];\n\t\t\tif (entry.impossible) {\n\t\t\t\twikiEntry.impossible = true;\n\t\t\t}\n\t\t\tif (entry.output) {\n\t\t\t\tbuilder.add(entry.output, entry.start, entry.end);\n\t\t\t}\n\t\t}\n\t\twikiEntry.output = builder.results();\n\t}\n\treturn wikiEntry;\n};\n",
"module-type": "relinkfieldtype",
"title": "$:/plugins/flibbles/relink/js/fieldtypes/wikitext.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/fields.js": {
"text": "/*\\\n\nHandles all fields specified in the plugin configuration. Currently, this\nonly supports single-value fields.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = 'fields';\n\nexports.report = function(tiddler, callback, options) {\n\tvar fields = options.settings.getFields();\n\t$tw.utils.each(fields, function(handler, field) {\n\t\tvar input = tiddler.fields[field];\n\t\tif (input) {\n\t\t\thandler.report(input, function(title, blurb) {\n\t\t\t\tif (blurb) {\n\t\t\t\t\tcallback(title, field + ': ' + blurb);\n\t\t\t\t} else {\n\t\t\t\t\tcallback(title, field);\n\t\t\t\t}\n\t\t\t}, options);\n\t\t}\n\t});\n};\n\nexports.relink = function(tiddler, fromTitle, toTitle, changes, options) {\n\tvar fields = options.settings.getFields();\n\t$tw.utils.each(fields, function(handler, field) {\n\t\tvar input = tiddler.fields[field];\n\t\tif (input) {\n\t\t\tvar entry = handler.relink(input, fromTitle, toTitle, options);\n\t\t\tif (entry !== undefined) {\n\t\t\t\tchanges[field] = entry;\n\t\t\t}\n\t\t}\n\t});\n};\n",
"module-type": "relinkoperator",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/fields.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text.js": {
"text": "/*\\\n\nDepending on the tiddler type, this will apply textOperators which may\nrelink titles within the body.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar defaultOperator = \"text/vnd.tiddlywiki\";\nvar utils = require('$:/plugins/flibbles/relink/js/utils.js');\n\nexports.name = 'text';\n\nvar textOperators = utils.getModulesByTypeAsHashmap('relinktextoperator', 'type');\n\n// $:/DefaultTiddlers is a tiddler which has type \"text/vnd.tiddlywiki\",\n// but it lies. It doesn't contain wikitext. It contains a filter, so\n// we pretend it has a filter type.\n// If you want to be able to add more exceptions for your plugin, let me know.\nvar exceptions = {\n\t\"$:/DefaultTiddlers\": \"text/x-tiddler-filter\"\n};\n\nexports.report = function(tiddler, callback, options) {\n\tvar fields = tiddler.fields;\n\tif (fields.text) {\n\t\tvar type = exceptions[fields.title] || fields.type || defaultOperator;\n\t\tif (textOperators[type]) {\n\t\t\tvar entry = textOperators[type].report(tiddler, callback, options);\n\t\t}\n\t}\n};\n\nexports.relink = function(tiddler, fromTitle, toTitle, changes, options) {\n\tvar fields = tiddler.fields;\n\tif (fields.text) {\n\t\tvar type = exceptions[fields.title] || fields.type || defaultOperator;\n\t\tif (textOperators[type]) {\n\t\t\tvar entry = textOperators[type].relink(tiddler, fromTitle, toTitle, options);\n\t\t\tif (entry) {\n\t\t\t\tchanges.text = entry;\n\t\t\t}\n\t\t}\n\t}\n};\n",
"module-type": "relinkoperator",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/filtertext.js": {
"text": "/*\\\n\nThis relinks tiddlers which contain filters in their body, as oppose to\nwikitext.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar filterHandler = require(\"$:/plugins/flibbles/relink/js/utils\").getType('filter');\n\nexports.type = 'text/x-tiddler-filter';\n\nexports.report = function(tiddler, callback, options) {\n\treturn filterHandler.report(tiddler.fields.text, callback, options);\n};\n\nexports.relink = function(tiddler, fromTitle, toTitle, options) {\n\treturn filterHandler.relink(tiddler.fields.text, fromTitle, toTitle, options)\n};\n",
"module-type": "relinktextoperator",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/filtertext.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext.js": {
"text": "/*\\\n\nChecks for fromTitle in a tiddler's text. If found, sees if it's relevant,\nand tries to swap it out if it is.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Placeholder = require(\"$:/plugins/flibbles/relink/js/utils/placeholder.js\");\nvar wikitextHandler = require('$:/plugins/flibbles/relink/js/utils.js').getType('wikitext');\n\nexports.type = 'text/vnd.tiddlywiki';\n\nexports.report = function(tiddler, callback, options) {\n\twikitextHandler.report(tiddler.fields.text, callback, options);\n};\n\nexports.relink = function(tiddler, fromTitle, toTitle, options) {\n\tvar placeholder = new Placeholder();\n\tvar currentOptions = Object.create(options);\n\tcurrentOptions.placeholder = placeholder;\n\tvar entry = wikitextHandler.relink(tiddler.fields.text, fromTitle, toTitle, currentOptions);\n\tif (entry && entry.output) {\n\t\t// If there's output, we've also got to prepend any macros\n\t\t// that the placeholder defined.\n\t\tvar preamble = placeholder.getPreamble();\n\t\tentry.output = preamble + entry.output;\n\t}\n\treturn entry;\n};\n",
"module-type": "relinktextoperator",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/code.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles code blocks. Or rather //doesn't// handle them, since we should\nignore their contents.\n\n\"`` [[Renamed Title]] ``\" will remain unchanged.\n\n\\*/\n\nexports.name = [\"codeinline\", \"codeblock\"];\n\nexports.relink = function(text) {\n\tvar reEnd;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// I'm lazy. This relink method works for both codeblock and codeinline\n\tif (this.match[0].length > 2) {\n\t\t// Must be a codeblock\n\t\treEnd = /\\r?\\n```$/mg;\n\t} else {\n\t\t// Must be a codeinline\n\t\treEnd = new RegExp(this.match[1], \"mg\");\n\t}\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(text);\n\tif (match) {\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\treturn undefined;\n};\n\n// Same thing. Just skip the pos ahead.\nexports.report = exports.relink;\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/code.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/comment.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles comment blocks. Or rather //doesn't// handle them, since we should\nignore their contents.\n\n\"<!-- [[Renamed Title]] -->\" will remain unchanged.\n\n\\*/\n\nexports.name = [\"commentinline\", \"commentblock\"];\n\nexports.relink = function(text) {\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\treturn undefined;\n};\n\nexports.report = exports.relink;\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/comment.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/filteredtransclude.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles replacement of filtered transclusions in wiki text like,\n\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n\nThis renames both the list and the template field.\n\n\\*/\n\nexports.name = ['filteredtranscludeinline', 'filteredtranscludeblock'];\n\nvar filterHandler = require(\"$:/plugins/flibbles/relink/js/utils\").getType('filter');\nvar utils = require(\"./utils.js\");\n\nexports.report = function(text, callback, options) {\n\tvar m = this.match,\n\t\tfilter = m[1],\n\t\ttemplate = $tw.utils.trim(m[3]),\n\t\tappend = template ? '||' + template + '}}}' : '}}}';\n\tfilterHandler.report(filter, function(title, blurb) {\n\t\tcallback(title, '{{{' + blurb + append);\n\t}, options);\n\tif (template) {\n\t\tcallback(template, '{{{' + $tw.utils.trim(filter).replace(/\\r?\\n/mg, ' ') + '||}}}');\n\t}\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar m = this.match,\n\t\tfilter = m[1],\n\t\ttooltip = m[2],\n\t\ttemplate = m[3],\n\t\tstyle = m[4],\n\t\tclasses = m[5],\n\t\tparser = this.parser,\n\t\tentry = {};\n\tparser.pos = this.matchRegExp.lastIndex;\n\tvar modified = false;\n\n\tvar filterEntry = filterHandler.relink(filter, fromTitle, toTitle, options);\n\tif (filterEntry !== undefined) {\n\t\tif (filterEntry.output) {\n\t\t\tfilter = filterEntry.output;\n\t\t\tmodified = true;\n\t\t}\n\t\tif (filterEntry.impossible) {\n\t\t\tentry.impossible = true;\n\t\t}\n\t}\n\n\tif ($tw.utils.trim(template) === fromTitle) {\n\t\t// preserves user-inputted whitespace\n\t\ttemplate = template.replace(fromTitle, toTitle);\n\t\tmodified = true;\n\t}\n\tif (!modified) {\n\t\tif (!entry.impossible) {\n\t\t\treturn undefined;\n\t\t}\n\t} else {\n\t\tvar output = this.makeFilteredtransclude(this.parser, filter, tooltip, template, style, classes);\n\t\tif (output === undefined) {\n\t\t\tentry.impossible = true;\n\t\t} else {\n\t\t\t// By copying over the ending newline of the original\n\t\t\t// text if present, thisrelink method thus works for\n\t\t\t// both the inline and block rule\n\t\t\tentry.output = output + utils.getEndingNewline(m[0]);\n\t\t}\n\t}\n\treturn entry;\n};\n\nexports.makeFilteredtransclude = function(parser, filter, tooltip, template, style, classes) {\n\tif (canBePretty(filter) && canBePrettyTemplate(template)) {\n\t\treturn prettyList(filter, tooltip, template, style, classes);\n\t}\n\tif (classes !== undefined) {\n\t\tclasses = classes.split('.').join(' ');\n\t}\n\treturn utils.makeWidget(parser, '$list', {\n\t\tfilter: filter,\n\t\ttooltip: tooltip,\n\t\ttemplate: template,\n\t\tstyle: style || undefined,\n\t\titemClass: classes});\n};\n\nfunction prettyList(filter, tooltip, template, style, classes) {\n\tif (tooltip === undefined) {\n\t\ttooltip = '';\n\t} else {\n\t\ttooltip = \"|\" + tooltip;\n\t}\n\tif (template === undefined) {\n\t\ttemplate = '';\n\t} else {\n\t\ttemplate = \"||\" + template;\n\t}\n\tif (classes === undefined) {\n\t\tclasses = '';\n\t} else {\n\t\tclasses = \".\" + classes;\n\t}\n\tstyle = style || '';\n\treturn \"{{{\"+filter+tooltip+template+\"}}\"+style+\"}\"+classes;\n};\n\nfunction canBePretty(filter) {\n\treturn filter.indexOf('|') < 0 && filter.indexOf('}}') < 0;\n};\n\nfunction canBePrettyTemplate(template) {\n\treturn !template || (\n\t\ttemplate.indexOf('|') < 0\n\t\t&& template.indexOf('{') < 0\n\t\t&& template.indexOf('}') < 0);\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/filteredtransclude.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/html.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles replacement in attributes of widgets and html elements\nThis is configurable to select exactly which attributes of which elements\nshould be changed.\n\n<$link to=\"TiddlerTitle\" />\n\n\\*/\n\nvar utils = require(\"./utils.js\");\nvar Rebuilder = require(\"$:/plugins/flibbles/relink/js/utils/rebuilder\");\nvar relinkUtils = require('$:/plugins/flibbles/relink/js/utils.js');\nvar refHandler = relinkUtils.getType('reference');\nvar filterHandler = relinkUtils.getType('filter');\nvar ImportContext = relinkUtils.getContext('import');\nvar macrocall = require(\"./macrocall.js\");\n\nexports.name = \"html\";\n\nexports.report = function(text, callback, options) {\n\tvar managedElement = this.parser.context.getAttribute(this.nextTag.tag);\n\tvar importFilterAttr;\n\tvar element = this.nextTag.tag;\n\tfor (var attributeName in this.nextTag.attributes) {\n\t\tvar attr = this.nextTag.attributes[attributeName];\n\t\tvar nextEql = text.indexOf('=', attr.start);\n\t\t// This is the rare case of changing tiddler\n\t\t// \"true\" to something else when \"true\" is\n\t\t// implicit, like <$link to /> We ignore those.\n\t\tif (nextEql < 0 || nextEql > attr.end) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (this.nextTag.tag === \"$importvariables\" && attributeName === \"filter\") {\n\t\t\timportFilterAttr = attr;\n\t\t}\n\t\tvar oldLength, quotedValue = undefined, entry;\n\t\tif (attr.type === \"string\") {\n\t\t\tvar handler = getAttributeHandler(this.parser.context, this.nextTag, attributeName, options);\n\t\t\tif (!handler) {\n\t\t\t\t// We don't manage this attribute. Bye.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\thandler.report(attr.value, function(title, blurb) {\n\t\t\t\tif (blurb) {\n\t\t\t\t\tcallback(title, '<' + element + ' ' + attributeName + '=\"' + blurb + '\" />');\n\t\t\t\t} else {\n\t\t\t\t\tcallback(title, '<' + element + ' ' + attributeName + ' />');\n\t\t\t\t}\n\t\t\t}, options);\n\t\t} else if (attr.type === \"indirect\") {\n\t\t\tentry = refHandler.report(attr.textReference, function(title, blurb) {\n\t\t\t\tcallback(title, '<' + element + ' ' + attributeName + '={{' + (blurb || '') + '}} />');\n\t\t\t}, options);\n\t\t} else if (attr.type === \"filtered\") {\n\t\t\tentry = filterHandler.report(attr.filter, function(title, blurb) {\n\t\t\t\tcallback(title, '<' + element + ' ' + attributeName + '={{{' + blurb + '}}} />');\n\t\t\t}, options);\n\t\t} else if (attr.type === \"macro\") {\n\t\t\tvar macro = attr.value;\n\t\t\tentry = macrocall.reportAttribute(this.parser, macro, function(title, blurb) {\n\t\t\t\tcallback(title, '<' + element + ' ' + attributeName + '=' + blurb + ' />');\n\t\t\t}, options);\n\t\t}\n\t\tif (quotedValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (this.nextTag.tag === \"$importvariables\" && attributeName === \"filter\") {\n\t\t\t// If this is an import variable filter, we gotta\n\t\t\t// remember this new value when we import lower down.\n\t\t\timportFilterAttr = quotedValue;\n\t\t}\n\t}\n\tif (importFilterAttr) {\n\t\tprocessImportFilter(this.parser, importFilterAttr, options);\n\t}\n\tthis.parse();\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar managedElement = this.parser.context.getAttribute(this.nextTag.tag),\n\t\tbuilder = new Rebuilder(text, this.nextTag.start);\n\tvar importFilterAttr;\n\tvar widgetEntry = {};\n\twidgetEntry.attributes = Object.create(null);\n\twidgetEntry.element = this.nextTag.tag;\n\tfor (var attributeName in this.nextTag.attributes) {\n\t\tvar attr = this.nextTag.attributes[attributeName];\n\t\tvar nextEql = text.indexOf('=', attr.start);\n\t\t// This is the rare case of changing tiddler\n\t\t// \"true\" to something else when \"true\" is\n\t\t// implicit, like <$link to /> We ignore those.\n\t\tif (nextEql < 0 || nextEql > attr.end) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (this.nextTag.tag === \"$importvariables\" && attributeName === \"filter\") {\n\t\t\timportFilterAttr = attr;\n\t\t}\n\t\tvar oldLength, quotedValue = undefined, entry;\n\t\tvar nestedOptions = Object.create(options);\n\t\tnestedOptions.settings = this.parser.context;\n\t\tswitch (attr.type) {\n\t\tcase 'string':\n\t\t\tvar handler = getAttributeHandler(this.parser.context, this.nextTag, attributeName, options);\n\t\t\tif (!handler) {\n\t\t\t\t// We don't manage this attribute. Bye.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tentry = handler.relink(attr.value, fromTitle, toTitle, nestedOptions);\n\t\t\tif (entry === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (entry.output) {\n\t\t\t\tvar quote = utils.determineQuote(text, attr);\n\t\t\t\toldLength = attr.value.length + (quote.length * 2);\n\t\t\t\tquotedValue = utils.wrapAttributeValue(entry.output,quote);\n\t\t\t\tif (quotedValue === undefined) {\n\t\t\t\t\t// The value was unquotable. We need to make\n\t\t\t\t\t// a macro in order to replace it.\n\t\t\t\t\tif (!options.placeholder) {\n\t\t\t\t\t\t// but we can't...\n\t\t\t\t\t\tentry.impossible = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar value = options.placeholder.getPlaceholderFor(entry.output,handler.name)\n\t\t\t\t\t\tquotedValue = \"<<\"+value+\">>\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'indirect':\n\t\t\tentry = refHandler.relinkInBraces(attr.textReference, fromTitle, toTitle, options);\n\t\t\tif (entry === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (entry.output) {\n\t\t\t\t// +4 for '{{' and '}}'\n\t\t\t\toldLength = attr.textReference.length + 4;\n\t\t\t\tquotedValue = \"{{\"+entry.output+\"}}\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'filtered':\n\t\t\tentry = filterHandler.relinkInBraces(attr.filter, fromTitle, toTitle, options);\n\t\t\tif (entry === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (entry.output) {\n\t\t\t\t// +6 for '{{{' and '}}}'\n\t\t\t\toldLength = attr.filter.length + 6;\n\t\t\t\tquotedValue = \"{{{\"+ entry.output +\"}}}\";\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'macro':\n\t\t\tvar macro = attr.value;\n\t\t\tentry = macrocall.relinkAttribute(this.parser, macro, text, fromTitle, toTitle, options);\n\t\t\tif (entry === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (entry.output) {\n\t\t\t\t// already includes '<<' and '>>'\n\t\t\t\toldLength = macro.end-macro.start;\n\t\t\t\tquotedValue = entry.output;\n\t\t\t}\n\t\t}\n\t\tif (entry.impossible) {\n\t\t\twidgetEntry.impossible = true;\n\t\t}\n\t\tif (quotedValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (this.nextTag.tag === \"$importvariables\" && attributeName === \"filter\") {\n\t\t\t// If this is an import variable filter, we gotta\n\t\t\t// remember this new value when we import lower down.\n\t\t\timportFilterAttr = quotedValue;\n\t\t}\n\t\t// We count backwards from the end to preserve whitespace\n\t\tvar valueStart = attr.end - oldLength;\n\t\tbuilder.add(quotedValue, valueStart, attr.end);\n\t}\n\tif (importFilterAttr) {\n\t\tprocessImportFilter(this.parser, importFilterAttr, options);\n\t}\n\tvar tag = this.parse()[0];\n\tif (tag.children) {\n\t\tfor (var i = 0; i < tag.children.length; i++) {\n\t\t\tvar child = tag.children[i];\n\t\t\tif (child.output) {\n\t\t\t\tbuilder.add(child.output, child.start, child.end);\n\t\t\t}\n\t\t\tif (child.impossible) {\n\t\t\t\twidgetEntry.impossible = true;\n\t\t\t}\n\t\t}\n\t}\n\tif (builder.changed() || widgetEntry.impossible) {\n\t\twidgetEntry.output = builder.results(this.parser.pos);\n\t\treturn widgetEntry;\n\t}\n\treturn undefined;\n};\n\n/** Returns the field handler for the given attribute of the given widget.\n * If this returns undefined, it means we don't handle it. So skip.\n */\nfunction getAttributeHandler(context, widget, attributeName, options) {\n\tif (widget.tag === \"$macrocall\") {\n\t\tvar nameAttr = widget.attributes[\"$name\"];\n\t\tif (nameAttr) {\n\t\t\tvar macro = context.getMacro(nameAttr.value);\n\t\t\tif (macro) {\n\t\t\t\treturn macro[attributeName];\n\t\t\t}\n\t\t}\n\t} else {\n\t\tvar element = context.getAttribute(widget.tag);\n\t\tif (element) {\n\t\t\treturn element[attributeName];\n\t\t}\n\t}\n\treturn undefined;\n};\n\nfunction computeAttribute(context, attribute, options) {\n\tvar value;\n\tif(attribute.type === \"filtered\") {\n\t\tvar parentWidget = context.widget;\n\t\tvalue = options.wiki.filterTiddlers(attribute.filter,parentWidget)[0] || \"\";\n\t} else if(attribute.type === \"indirect\") {\n\t\tvar parentWidget = context.widget;\n\t\tvalue = options.wiki.getTextReference(attribute.textReference,\"\",parentWidget.variables.currentTiddler.value);\n\t} else if(attribute.type === \"macro\") {\n\t\tvar parentWidget = context.widget;\n\t\tvalue = parentWidget.getVariable(attribute.value.name,{params: attribute.value.params});\n\t} else { // String attribute\n\t\tvalue = attribute.value;\n\t}\n\treturn value;\n};\n\n// This processes a <$importvariables> filter attribute and adds any new\n// variables to our parser.\nfunction processImportFilter(parser, importAttribute, options) {\n\tif (typeof importAttribute === \"string\") {\n\t\t// It was changed. Reparse it. It'll be a quoted\n\t\t// attribute value. Add a dummy attribute name.\n\t\timportAttribute = $tw.utils.parseAttribute(\"p=\"+importAttribute, 0)\n\t}\n\tvar context = parser.context;\n\tvar importFilter = computeAttribute(context, importAttribute, options);\n\tparser.context = new ImportContext(options.wiki, context, importFilter);\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/html.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/image.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles replacement in wiki text inline rules, like,\n\n[img[tiddler.jpg]]\n\n[img width=23 height=24 [Description|tiddler.jpg]]\n\n\\*/\n\nvar Rebuilder = require(\"$:/plugins/flibbles/relink/js/utils/rebuilder\");\nvar refHandler = require(\"$:/plugins/flibbles/relink/js/fieldtypes/reference\");\nvar filterHandler = require(\"$:/plugins/flibbles/relink/js/utils\").getType('filter');\nvar macrocall = require(\"./macrocall.js\");\nvar utils = require(\"./utils.js\");\n\nexports.name = \"image\";\n\nexports.report = function(text, callback, options) {\n\tvar ptr = this.nextImage.start + 4; //[img\n\tvar inSource = false;\n\tfor (var attributeName in this.nextImage.attributes) {\n\t\tvar attr = this.nextImage.attributes[attributeName];\n\t\tif (attributeName === \"source\" || attributeName === \"tooltip\") {\n\t\t\tif (inSource) {\n\t\t\t\tptr = text.indexOf('|', ptr);\n\t\t\t} else {\n\t\t\t\tptr = text.indexOf('[', ptr);\n\t\t\t\tinSource = true;\n\t\t\t}\n\t\t\tptr += 1;\n\t\t}\n\t\tif (attributeName === \"source\") {\n\t\t\tvar tooltip = this.nextImage.attributes.tooltip;\n\t\t\tvar blurb = '[img[' + (tooltip ? tooltip.value : '') + ']]';\n\t\t\tcallback(attr.value, blurb);\n\t\t\tptr = text.indexOf(attr.value, ptr);\n\t\t\tptr = text.indexOf(']]', ptr) + 2;\n\t\t} else if (attributeName !== \"tooltip\") {\n\t\t\tptr = reportAttribute(this.parser, attr, callback, options);\n\t\t}\n\t}\n\tthis.parser.pos = ptr;\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar ptr = this.nextImage.start,\n\t\tbuilder = new Rebuilder(text, ptr),\n\t\tmakeWidget = false,\n\t\tskipSource = false,\n\t\timageEntry;\n\tif (this.nextImage.attributes.source.value === fromTitle && !canBePretty(toTitle, this.nextImage.attributes.tooltip)) {\n\t\tif (this.parser.context.allowWidgets() && (utils.wrapAttributeValue(toTitle) || options.placeholder)) {\n\t\t\tmakeWidget = true;\n\t\t\tbuilder.add(\"<$image\", ptr, ptr+4);\n\t\t} else {\n\t\t\t// We won't be able to make a placeholder to replace\n\t\t\t// the source attribute. We check now so we don't\n\t\t\t// prematurely convert into a widget.\n\t\t\t// Keep going in case other attributes need replacing.\n\t\t\tskipSource = true;\n\t\t}\n\t}\n\tptr += 4; //[img\n\tvar inSource = false;\n\tfor (var attributeName in this.nextImage.attributes) {\n\t\tvar attr = this.nextImage.attributes[attributeName];\n\t\tif (attributeName === \"source\" || attributeName === \"tooltip\") {\n\t\t\tif (inSource) {\n\t\t\t\tptr = text.indexOf('|', ptr);\n\t\t\t} else {\n\t\t\t\tptr = text.indexOf('[', ptr);\n\t\t\t\tinSource = true;\n\t\t\t}\n\t\t\tif (makeWidget) {\n\t\t\t\tif (\" \\t\\n\".indexOf(text[ptr-1]) >= 0) {\n\t\t\t\t\tbuilder.add('', ptr, ptr+1);\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.add(' ', ptr, ptr+1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tptr += 1;\n\t\t}\n\t\tif (attributeName === \"source\") {\n\t\t\tptr = text.indexOf(attr.value, ptr);\n\t\t\tif (attr.value === fromTitle) {\n\t\t\t\tif (makeWidget) {\n\t\t\t\t\tvar quotedValue = utils.wrapAttributeValue(toTitle);\n\t\t\t\t\tif (quotedValue === undefined) {\n\t\t\t\t\t\tvar key = options.placeholder.getPlaceholderFor(toTitle);\n\t\t\t\t\t\tbuilder.add(\"source=<<\"+key+\">>\", ptr, ptr+fromTitle.length);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbuilder.add(\"source=\"+quotedValue, ptr, ptr+fromTitle.length);\n\t\t\t\t\t}\n\t\t\t\t} else if (!skipSource) {\n\t\t\t\t\tbuilder.add(toTitle, ptr, ptr+fromTitle.length);\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.impossible = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tptr = text.indexOf(']]', ptr);\n\t\t\tif (makeWidget) {\n\t\t\t\tbuilder.add(\"/>\", ptr, ptr+2);\n\t\t\t}\n\t\t\tptr += 2;\n\t\t} else if (attributeName === \"tooltip\") {\n\t\t\tif (makeWidget) {\n\t\t\t\tptr = text.indexOf(attr.value, ptr);\n\t\t\t\tvar quotedValue = utils.wrapAttributeValue(attr.value);\n\t\t\t\tbuilder.add(\"tooltip=\"+quotedValue, ptr, ptr+attr.value.length);\n\t\t\t}\n\t\t} else {\n\t\t\tptr = relinkAttribute(this.parser, attr, builder, fromTitle, toTitle, options);\n\t\t}\n\t}\n\tthis.parser.pos = ptr;\n\tif (builder.changed() || builder.impossible) {\n\t\timageEntry = {\n\t\t\toutput: builder.results(ptr),\n\t\t\timpossible: builder.impossible };\n\t}\n\treturn imageEntry;\n};\n\nfunction reportAttribute(parser, attribute, callback, options) {\n\tvar text = parser.source;\n\tvar ptr = text.indexOf(attribute.name, attribute.start);\n\tvar end;\n\tptr += attribute.name.length;\n\tptr = text.indexOf('=', ptr);\n\tif (attribute.type === \"string\") {\n\t\tptr = text.indexOf(attribute.value, ptr)\n\t\tvar quote = utils.determineQuote(text, attribute);\n\t\t// ignore first quote. We already passed it\n\t\tend = ptr + quote.length + attribute.value.length;\n\t} else if (attribute.type === \"indirect\") {\n\t\tptr = text.indexOf('{{', ptr);\n\t\tvar end = ptr + attribute.textReference.length + 4;\n\t\trefHandler.report(attribute.textReference, function(title, blurb) {\n\t\t\tcallback(title, '[img ' + attribute.name + '={{' + (blurb || '') + '}}]');\n\t\t}, options);\n\t} else if (attribute.type === \"filtered\") {\n\t\tptr = text.indexOf('{{{', ptr);\n\t\tvar end = ptr + attribute.filter.length + 6;\n\t\tfilterHandler.report(attribute.filter, function(title, blurb) {\n\t\t\tcallback(title, '[img ' + attribute.name + '={{{' + blurb + '}}}]');\n\t\t}, options);\n\t} else if (attribute.type === \"macro\") {\n\t\tptr = text.indexOf(\"<<\", ptr);\n\t\tvar end = attribute.value.end;\n\t\tvar macro = attribute.value;\n\t\toldValue = attribute.value;\n\t\tmacrocall.reportAttribute(parser, macro, function(title, blurb) {\n\t\t\tcallback(title, '[img ' + attribute.name + '=' + blurb + ']');\n\t\t}, options);\n\t}\n\treturn end;\n};\n\nfunction relinkAttribute(parser, attribute, builder, fromTitle, toTitle, options) {\n\tvar text = builder.text;\n\tvar ptr = text.indexOf(attribute.name, attribute.start);\n\tvar end;\n\tptr += attribute.name.length;\n\tptr = text.indexOf('=', ptr);\n\tif (attribute.type === \"string\") {\n\t\tptr = text.indexOf(attribute.value, ptr)\n\t\tvar quote = utils.determineQuote(text, attribute);\n\t\t// ignore first quote. We already passed it\n\t\tend = ptr + quote.length + attribute.value.length;\n\t} else if (attribute.type === \"indirect\") {\n\t\tptr = text.indexOf('{{', ptr);\n\t\tvar end = ptr + attribute.textReference.length + 4;\n\t\tvar ref = refHandler.relinkInBraces(attribute.textReference, fromTitle, toTitle, options);\n\t\tif (ref) {\n\t\t\tif (ref.impossible) {\n\t\t\t\tbuilder.impossible = true;\n\t\t\t}\n\t\t\tif (ref.output) {\n\t\t\t\tbuilder.add(\"{{\"+ref.output+\"}}\", ptr, end);\n\t\t\t}\n\t\t}\n\t} else if (attribute.type === \"filtered\") {\n\t\tptr = text.indexOf('{{{', ptr);\n\t\tvar end = ptr + attribute.filter.length + 6;\n\t\tvar filter = filterHandler.relinkInBraces(attribute.filter, fromTitle, toTitle, options);\n\t\tif (filter !== undefined) {\n\t\t\tif (filter.impossible) {\n\t\t\t\tbuilder.impossible = true;\n\t\t\t}\n\t\t\tif (filter.output) {\n\t\t\t\tvar quoted = \"{{{\"+filter.output+\"}}}\";\n\t\t\t\tbuilder.add(quoted, ptr, end);\n\t\t\t}\n\t\t}\n\t} else if (attribute.type === \"macro\") {\n\t\tptr = text.indexOf(\"<<\", ptr);\n\t\tvar end = attribute.value.end;\n\t\tvar macro = attribute.value;\n\t\toldValue = attribute.value;\n\t\tvar macroEntry = macrocall.relinkAttribute(parser, macro, text, fromTitle, toTitle, options);\n\t\tif (macroEntry !== undefined) {\n\t\t\tif (macroEntry.impossible) {\n\t\t\t\tbuilder.impossible = true;\n\t\t\t}\n\t\t\tif (macroEntry.output) {\n\t\t\t\tbuilder.add(macroEntry.output, ptr, end);\n\t\t\t}\n\t\t}\n\t}\n\treturn end;\n};\n\nfunction canBePretty(title, tooltip) {\n\treturn title.indexOf(']') < 0 && (tooltip || title.indexOf('|') < 0);\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/image.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/import.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles import pragmas\n\n\\import [tag[MyTiddler]]\n\\*/\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils.js\");\nvar filterRelinker = utils.getType('filter');\nvar ImportContext = utils.getContext('import');\n\nexports.name = \"import\";\n\nexports.report = function(text, callback, options) {\n\t// This moves the pos for us\n\tvar parseTree = this.parse();\n\tvar filter = parseTree[0].attributes.filter.value || '';\n\tfilterRelinker.report(filter, function(title, blurb) {\n\t\tif (blurb) {\n\t\t\tblurb = '\\\\import ' + blurb;\n\t\t} else {\n\t\t\tblurb = '\\\\import';\n\t\t}\n\t\tcallback(title, blurb);\n\t}, options);\n\t// Before we go, we need to actually import the variables\n\t// it's calling for, and any /relink pragma\n\tthis.parser.context = new ImportContext(options.wiki, this.parser.context, filter);\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\t// In this one case, I'll let the parser parse out the filter and move\n\t// the ptr.\n\tvar start = this.matchRegExp.lastIndex,\n\t\tparseTree = this.parse(),\n\t\tfilter = parseTree[0].attributes.filter.value || '',\n\t\tentry = filterRelinker.relink(filter, fromTitle, toTitle, options);\n\tif (entry !== undefined && entry.output) {\n\t\tvar newline = text.substring(start+filter.length, this.parser.pos);\n\t\tfilter = entry.output;\n\t\tentry.output = \"\\\\import \" + filter + newline;\n\t}\n\n\t// Before we go, we need to actually import the variables\n\t// it's calling for, and any /relink pragma\n\tthis.parser.context = new ImportContext(options.wiki, this.parser.context, filter);\n\n\treturn entry;\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/import.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/macrocall.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles macro calls.\n\n<<myMacro '[[MyFilter]]' 'myTitle'>>\n\n\\*/\n\nvar utils = require(\"./utils.js\");\nvar Rebuilder = require(\"$:/plugins/flibbles/relink/js/utils/rebuilder\");\nvar EntryNode = require('$:/plugins/flibbles/relink/js/utils/entry');\n\nexports.name = [\"macrocallinline\", \"macrocallblock\"];\n\n// Error thrown when a macro's definition is needed, but can't be found.\nfunction CannotFindMacroDef() {};\nCannotFindMacroDef.prototype.impossible = true;\nCannotFindMacroDef.prototype.name = \"macroparam\";\n// Failed relinks due to missing definitions aren't reported for now.\n// I may want to do something special later on.\nCannotFindMacroDef.prototype.report = function() { return []; };\n\nexports.report = function(text, callback, options) {\n\tvar macroInfo = getInfoFromRule(this);\n\tthis.parser.pos = macroInfo.end;\n\tthis.reportAttribute(this.parser, macroInfo, callback, options);\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar macroInfo = getInfoFromRule(this);\n\tvar managedMacro = this.parser.context.getMacro(macroInfo.name);\n\tthis.parser.pos = macroInfo.end;\n\tif (!managedMacro) {\n\t\t// We don't manage this macro. Bye.\n\t\treturn undefined;\n\t}\n\tvar mayBeWidget = this.parser.context.allowWidgets();\n\tvar names = getParamNames(this.parser, macroInfo.name, macroInfo.params, options);\n\tif (names === undefined) {\n\t\t// Needed the definition, and couldn't find it. So if a single\n\t\t// parameter needs to placeholder, just fail.\n\t\tmayBeWidget = false;\n\t}\n\tvar entry = relinkMacroInvocation(this.parser, macroInfo, text, fromTitle, toTitle, mayBeWidget, options);\n\tif (entry && entry.output) {\n\t\tentry.output = macroToString(entry.output, text, names, options);\n\t}\n\treturn entry;\n};\n\n/** Relinks macros that occur as attributes, like <$element attr=<<...>> />\n * Processes the same, except it can't downgrade into a widget if the title\n * is complicated.\n */\nexports.relinkAttribute = function(parser, macro, text, fromTitle, toTitle, options) {\n\tvar entry = relinkMacroInvocation(parser, macro, text, fromTitle, toTitle, false, options);\n\tif (entry && entry.output) {\n\t\tentry.output = macroToStringMacro(entry.output, text, options);\n\t}\n\treturn entry;\n};\n\n/** As in, report a macrocall invocation that is an html attribute. */\nexports.reportAttribute = function(parser, macro, callback, options) {\n\tvar managedMacro = parser.context.getMacro(macro.name);\n\tif (!managedMacro) {\n\t\t// We don't manage this macro. Bye.\n\t\treturn undefined;\n\t}\n\tfor (var managedArg in managedMacro) {\n\t\tvar index;\n\t\ttry {\n\t\t\tindex = getParamIndexWithinMacrocall(parser, macro.name, managedArg, macro.params, options);\n\t\t} catch (e) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (index < 0) {\n\t\t\t// The argument was not supplied. Move on to next.\n\t\t\tcontinue;\n\t\t}\n\t\tvar param = macro.params[index];\n\t\tvar handler = managedMacro[managedArg];\n\t\tvar nestedOptions = Object.create(options);\n\t\tnestedOptions.settings = parser.context;\n\t\tvar entry = handler.report(param.value, function(title, blurb) {\n\t\t\tvar rtn = managedArg;\n\t\t\tif (blurb) {\n\t\t\t\trtn += ': \"' + blurb + '\"';\n\t\t\t}\n\t\t\tcallback(title, '<<' + macro.name + ' ' + rtn + '>>');\n\t\t}, nestedOptions);\n\t}\n};\n\n/**Processes the given macro,\n * macro: {name:, params:, start:, end:}\n * each parameters: {name:, end:, value:}\n * Macro invocation returned is the same, but relinked, and may have new keys:\n * parameters: {type: macro, start:, newValue: (quoted replacement value)}\n * Output of the returned entry isn't a string, but a macro object. It needs\n * to be converted.\n */\nfunction relinkMacroInvocation(parser, macro, text, fromTitle, toTitle, mayBeWidget, options) {\n\tvar managedMacro = parser.context.getMacro(macro.name);\n\tvar modified = false;\n\tif (!managedMacro) {\n\t\t// We don't manage this macro. Bye.\n\t\treturn undefined;\n\t}\n\tvar outMacro = $tw.utils.extend({}, macro);\n\tvar macroEntry = {};\n\toutMacro.params = macro.params.slice();\n\tfor (var managedArg in managedMacro) {\n\t\tvar index;\n\t\ttry {\n\t\t\tindex = getParamIndexWithinMacrocall(parser, macro.name, managedArg, macro.params, options);\n\t\t} catch (e) {\n\t\t\tif (e instanceof CannotFindMacroDef) {\n\t\t\t\tmacroEntry.impossible = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (index < 0) {\n\t\t\t// this arg either was not supplied, or we can't find\n\t\t\t// the definition, so we can't tie it to an anonymous\n\t\t\t// argument. Either way, move on to the next.\n\t\t\tcontinue;\n\t\t}\n\t\tvar param = macro.params[index];\n\t\tvar handler = managedMacro[managedArg];\n\t\tvar nestedOptions = Object.create(options);\n\t\tnestedOptions.settings = parser.context;\n\t\tvar entry = handler.relink(param.value, fromTitle, toTitle, nestedOptions);\n\t\tif (entry === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Macro parameters can only be string parameters, not\n\t\t// indirect, or macro, or filtered\n\t\tif (entry.impossible) {\n\t\t\tmacroEntry.impossible = true;\n\t\t}\n\t\tif (!entry.output) {\n\t\t\tcontinue;\n\t\t}\n\t\tvar quote = utils.determineQuote(text, param);\n\t\tvar quoted = utils.wrapParameterValue(entry.output, quote);\n\t\tvar newParam = $tw.utils.extend({}, param);\n\t\tif (quoted === undefined) {\n\t\t\tif (!mayBeWidget || !options.placeholder) {\n\t\t\t\tmacroEntry.impossible = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar ph = options.placeholder.getPlaceholderFor(entry.output,handler.name);\n\t\t\tnewParam.newValue = \"<<\"+ph+\">>\";\n\t\t\tnewParam.type = \"macro\";\n\t\t} else {\n\t\t\tnewParam.start = newParam.end - (newParam.value.length + (quote.length*2));\n\t\t\tnewParam.value = entry.output;\n\t\t\tnewParam.newValue = quoted;\n\t\t}\n\t\toutMacro.params[index] = newParam;\n\t\tmodified = true;\n\t}\n\tif (modified || macroEntry.impossible) {\n\t\tif (modified) {\n\t\t\tmacroEntry.output = outMacro;\n\t\t}\n\t\treturn macroEntry;\n\t}\n\treturn undefined;\n};\n\nfunction getInfoFromRule(rule) {\n\t// Get all the details of the match\n\tvar macroInfo = rule.nextCall;\n\tif (!macroInfo) {\n\t\t// rule.match is used <v5.1.24\n\t\tvar match = rule.match,\n\t\t\toffset = $tw.utils.skipWhiteSpace(match[0], match[1].length+2);\n\t\tmacroInfo = {\n\t\t\tname: match[1],\n\t\t\tstart: rule.matchRegExp.lastIndex - match[0].length,\n\t\t\tend: rule.matchRegExp.lastIndex,\n\t\t};\n\t\tmacroInfo.params = parseParams(match[2], offset+macroInfo.start);\n\t}\n\treturn macroInfo;\n};\n\nfunction mustBeAWidget(macro) {\n\tfor (var i = 0; i < macro.params.length; i++) {\n\t\tif (macro.params[i].type === \"macro\") {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false\n};\n\n/**Given a macro object ({name:, params:, start: end:}), and the text where\n * it was parsed from, returns a new macro that maintains any syntactic\n * structuring.\n */\nfunction macroToString(macro, text, names, options) {\n\tif (mustBeAWidget(macro)) {\n\t\tvar attrs = [];\n\t\tfor (var i = 0; i < macro.params.length; i++) {\n\t\t\tvar p = macro.params[i];\n\t\t\tvar val;\n\t\t\tif (p.newValue) {\n\t\t\t\tval = p.newValue;\n\t\t\t} else {\n\t\t\t\tval = utils.wrapAttributeValue(p.value);\n\t\t\t}\n\t\t\tattrs.push(\" \"+names[i]+\"=\"+val);\n\t\t}\n\t\treturn \"<$macrocall $name=\"+utils.wrapAttributeValue(macro.name)+attrs.join('')+\"/>\";\n\t} else {\n\t\treturn macroToStringMacro(macro, text, options);\n\t}\n};\n\nfunction macroToStringMacro(macro, text, options) {\n\tvar builder = new Rebuilder(text, macro.start);\n\tfor (var i = 0; i < macro.params.length; i++) {\n\t\tvar param = macro.params[i];\n\t\tif (param.newValue) {\n\t\t\tbuilder.add(param.newValue, param.start, param.end);\n\t\t}\n\t}\n\treturn builder.results(macro.end);\n};\n\n/** Returns -1 if param definitely isn't in macrocall.\n */\nfunction getParamIndexWithinMacrocall(parser, macroName, param, params, options) {\n\tvar index, i, anonsExist = false;\n\tfor (i = 0; i < params.length; i++) {\n\t\tvar name = params[i].name;\n\t\tif (name === param) {\n\t\t\treturn i;\n\t\t}\n\t\tif (name === undefined) {\n\t\t\tanonsExist = true;\n\t\t}\n\t}\n\tif (!anonsExist) {\n\t\t// If no anonymous parameters are present, and we didn't find\n\t\t// it among the named ones, it must not be there.\n\t\treturn -1;\n\t}\n\tvar expectedIndex = indexOfParameterDef(parser, macroName, param, options);\n\t// We've got to skip over all the named parameter instances.\n\tif (expectedIndex >= 0) {\n\t\tvar anonI = 0;\n\t\tfor (i = 0; i < params.length; i++) {\n\t\t\tif (params[i].name === undefined) {\n\t\t\t\tif (anonI === expectedIndex) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\tanonI++;\n\t\t\t} else {\n\t\t\t\tvar indexOfOther = indexOfParameterDef(parser, macroName, params[i].name, options);\n\t\t\t\tif (indexOfOther < expectedIndex) {\n\t\t\t\t\tanonI++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn -1;\n};\n\n// Looks up the definition of a macro, and figures out what the expected index\n// is for the given parameter.\nfunction indexOfParameterDef(parser, macroName, paramName, options) {\n\tvar def = parser.context.getMacroDefinition(macroName);\n\tif (def === undefined) {\n\t\tthrow new CannotFindMacroDef();\n\t}\n\tvar params = def.params || [];\n\tfor (var i = 0; i < params.length; i++) {\n\t\tif (params[i].name === paramName) {\n\t\t\treturn i;\n\t\t}\n\t}\n\treturn -1;\n};\n\nfunction getParamNames(parser, macroName, params, options) {\n\tvar used = Object.create(null);\n\tvar rtn = new Array(params.length);\n\tvar anonsExist = false;\n\tvar i;\n\tfor (i = 0; i < params.length; i++) {\n\t\tvar name = params[i].name;\n\t\tif (name) {\n\t\t\trtn[i] = name;\n\t\t\tused[name] = true;\n\t\t} else {\n\t\t\tanonsExist = true;\n\t\t}\n\t}\n\tif (anonsExist) {\n\t\tvar def = parser.context.getMacroDefinition(macroName);\n\t\tif (def === undefined) {\n\t\t\t// If there are anonymous parameters, and we can't\n\t\t\t// find the definition, then we can't hope to create\n\t\t\t// a widget.\n\t\t\treturn undefined;\n\t\t}\n\t\tvar defParams = def.params || [];\n\t\tvar defPtr = 0;\n\t\tfor (i = 0; i < params.length; i++) {\n\t\t\tif (rtn[i] === undefined) {\n\t\t\t\twhile(defPtr < defParams.length && used[defParams[defPtr].name]) {\n\t\t\t\t\tdefPtr++;\n\t\t\t\t}\n\t\t\t\tif (defPtr >= defParams.length) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\trtn[i] = defParams[defPtr].name;\n\t\t\t\tused[defParams[defPtr].name] = true;\n\t\t\t}\n\t\t}\n\t}\n\treturn rtn;\n};\n\nfunction parseParams(paramString, pos) {\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = { };\n\t\t// We need to find the group match that isn't undefined.\n\t\tfor (var i = 2; i <= 6; i++) {\n\t\t\tif (paramMatch[i] !== undefined) {\n\t\t\t\tparamInfo.value = paramMatch[i];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\t//paramInfo.start = pos;\n\t\tparamInfo.end = reParam.lastIndex + pos;\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn params;\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/macrocall.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/macrodef.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles pragma macro definitions. Except we only update placeholder macros\nthat we may have previously install.\n\n\\define relink-?() Tough title\n\n\\*/\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils\");\nvar VariableContext = utils.getContext('variable');\n\nexports.name = \"macrodef\";\n\nexports.report = function(text, callback, options) {\n\tvar setParseTreeNode = this.parse(),\n\t\tm = this.match,\n\t\tname = m[1];\n\tthis.parser.context = new VariableContext(this.parser.context, setParseTreeNode[0]);\n\t// Parse set the pos pointer, but we don't want to skip the macro body.\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar endMatch = getBodyMatch(text, this.parser.pos, m[3]);\n\tif (endMatch) {\n\t\tvar value = endMatch[2],\n\t\t\thandler = utils.getType(getActiveType(name, m[2]) || 'wikitext');\n\t\tif (handler) {\n\t\t\tvar entry = handler.report(value, function(title, blurb) {\n\t\t\t\tvar macroStr = '\\\\define ' + name + '()';\n\t\t\t\tif (blurb) {\n\t\t\t\t\tmacroStr += ' ' + blurb;\n\t\t\t\t}\n\t\t\t\tcallback(title, macroStr);\n\t\t\t}, options);\n\t\t}\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t}\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar setParseTreeNode = this.parse(),\n\t\tentry,\n\t\tm = this.match,\n\t\tname = m[1],\n\t\tparams = m[2],\n\t\tmultiline = m[3];\n\tthis.parser.context = new VariableContext(this.parser.context, setParseTreeNode[0]);\n\t// Parse set the pos pointer, but we don't want to skip the macro body.\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar endMatch = getBodyMatch(text, this.parser.pos, multiline);\n\tif (endMatch) {\n\t\tvar value = endMatch[2],\n\t\t\ttype = getActiveType(name, params),\n\t\t\thandler = utils.getType(type || 'wikitext');\n\t\tif (handler) {\n\t\t\t// If this is an active relink placeholder, then let's remember it\n\t\t\tif (type && options.placeholder) {\n\t\t\t\toptions.placeholder.registerExisting(name, value);\n\t\t\t}\n\t\t\t// Relink the contents\n\t\t\tentry = handler.relink(value, fromTitle, toTitle, options);\n\t\t\tif (entry && entry.output) {\n\t\t\t\tentry.output = m[0] + endMatch[1] + entry.output + endMatch[0];\n\t\t\t}\n\t\t}\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t}\n\treturn entry;\n};\n\n// Return another match for the body, but tooled uniquely\n// m[1] = whitespace before body\n// m[2] = body\n// m.index + m[0].length -> end of match\nfunction getBodyMatch(text, pos, isMultiline) {\n\tvar whitespace,\n\t\tvalueRegExp;\n\tif (isMultiline) {\n\t\tvalueRegExp = /\\r?\\n\\\\end[^\\S\\n\\r]*(?:\\r?\\n|$)/mg;\n\t\twhitespace = '';\n\t} else {\n\t\tvalueRegExp = /(?:\\r?\\n|$)/mg;\n\t\tvar newPos = $tw.utils.skipWhiteSpace(text, pos);\n\t\twhitespace = text.substring(pos, newPos);\n\t\tpos = newPos;\n\t}\n\tvalueRegExp.lastIndex = pos;\n\tvar match = valueRegExp.exec(text);\n\tif (match) {\n\t\tmatch[1] = whitespace;\n\t\tmatch[2] = text.substring(pos, match.index);\n\t}\n\treturn match;\n};\n\nfunction getActiveType(macroName, parameters) {\n\tvar placeholder = /^relink-(?:(\\w+)-)?\\d+$/.exec(macroName);\n\t// normal macro or special placeholder?\n\tif (placeholder && parameters === '') {\n\t\treturn placeholder[1] || 'title';\n\t}\n\treturn undefined;\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/macrodef.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/prettylink.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles replacement in wiki text inline rules, like,\n\n[[Introduction]]\n\n[[link description|TiddlerTitle]]\n\n\\*/\n\nvar utils = require(\"./utils.js\");\n\nexports.name = \"prettylink\";\n\nexports.report = function(text, callback, options) {\n\tvar text = this.match[1],\n\t\tlink = this.match[2] || text;\n\tif (!$tw.utils.isLinkExternal(link)) {\n\t\tcallback(link, '[[' + text + ']]');\n\t}\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar caption, m = this.match;\n\tif (m[2] === fromTitle) {\n\t\t// format is [[caption|MyTiddler]]\n\t\tcaption = m[1];\n\t} else if (m[2] !== undefined || m[1] !== fromTitle) {\n\t\t// format is [[MyTiddler]], and it doesn't match\n\t\treturn undefined;\n\t}\n\tvar entry = { output: utils.makePrettylink(this.parser, toTitle, caption) };\n\tif (entry.output === undefined) {\n\t\tentry.impossible = true;\n\t}\n\treturn entry;\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/prettylink.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/relink.js": {
"text": "/*\\\nmodule-type: wikirule\n\nThis defines the \\relink inline pragma used to locally declare\nrelink rules for macros.\n\nIt takes care of providing its own relink and report rules.\n\n\\*/\n\nvar utils = require('$:/plugins/flibbles/relink/js/utils.js');\nvar language = require('$:/plugins/flibbles/relink/js/language.js');\n\nexports.name = \"relink\";\nexports.types = {pragma: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /^\\\\relink[^\\S\\n]+([^(\\s]+)([^\\r\\n]*)(\\r?\\n)?/mg;\n};\n\n/**This makes the widget that the macro library will later parse to determine\n * new macro relink state.\n *\n * It's a <$set> widget so it can appear BEFORE \\define pragma and not\n * prevent that pragma from being scooped up by importvariables.\n * (importvariables stops scooping as soon as it sees something besides $set) */\nexports.parse = function() {\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar macroName;\n\tvar macroParams = Object.create(null);\n\tvar error = undefined;\n\tvar rtn = [];\n\tvar self = this;\n\tthis.interpretSettings(function(macro, parameter, type) {\n\t\tmacroName = macro;\n\t\tif (type && !utils.getType(type)) {\n\t\t\terror = language.getString(\"Error/UnrecognizedType\",\n\t\t\t\t{variables: {type: type}, wiki: self.parser.wiki});\n\t\t}\n\t\tmacroParams[parameter] = type;\n\t});\n\t// If no macroname. Return nothing, this rule will be ignored by parsers\n\tif (macroName) {\n\t\tvar relink = Object.create(null);\n\t\trelink[macroName] = macroParams;\n\t\trtn.push({\n\t\t\ttype: \"set\",\n\t\t\tattributes: {\n\t\t\t\tname: {type: \"string\", value: \"\"}\n\t\t\t},\n\t\t\tchildren: [],\n\t\t\tisMacroDefinition: true,\n\t\t\trelink: relink});\n\t}\n\tif (error) {\n\t\trtn.push({\n\t\t\ttype: \"element\", tag: \"span\", attributes: {\n\t\t\t\t\"class\": {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: \"tc-error tc-relink-error\"\n\t\t\t\t}\n\t\t\t}, children: [\n\t\t\t\t{type: \"text\", text: error}\n\t\t\t]});\n\t}\n\treturn rtn;\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar parser = this.parser;\n\tvar currentTiddler = parser.context.widget.variables.currentTiddler.value;\n\tparser.pos = this.matchRegExp.lastIndex;\n\tthis.interpretSettings(function(macro, parameter, type) {\n\t\toptions.settings.addSetting(parser.wiki, macro, parameter, type, currentTiddler);\n\t});\n\t// Return nothing, because this rule is ignored by the parser\n\treturn undefined;\n};\n\nexports.interpretSettings = function(block) {\n\tvar paramString = this.match[2];\n\tif (paramString !== \"\") {\n\t\tvar macro = this.match[1];\n\t\tvar reParam = /\\s*([A-Za-z0-9\\-_]+)(?:\\s*:\\s*([^\\s]+))?/mg;\n\t\tvar paramMatch = reParam.exec(paramString);\n\t\twhile (paramMatch) {\n\t\t\tvar parameter = paramMatch[1];\n\t\t\tvar type = paramMatch[2];\n\t\t\tblock(macro, parameter, type);\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\t}\n\t}\n};\n",
"module-type": "wikirule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/relink.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/rules.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nParses and acknowledges any pragma rules a tiddler has.\n\n\\rules except html wikilink\n\n\\*/\n\nexports.name = \"rules\";\n\n/**This is all we have to do. The rules rule doesn't parse. It just amends\n * the rules, which is exactly what I want it to do too.\n * It also takes care of moving the pos pointer forward.\n */\nexports.relink = function() {\n\tthis.parse();\n\treturn undefined;\n};\n\n// Same deal\nexports.report = exports.relink;\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/rules.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/syslink.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles sys links\n\n$:/sys/link\n\nbut not:\n\n~$:/sys/link\n\n\\*/\n\nvar utils = require(\"./utils.js\");\n\nexports.name = \"syslink\";\n\nexports.report = function(text, callback, options) {\n\tvar title = this.match[0];\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tif (title[0] !== \"~\") {\n\t\tcallback(title, '~' + title);\n\t}\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar entry = undefined;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tif (this.match[0] === fromTitle && this.match[0][0] !== \"~\") {\n\t\tentry = {output: this.makeSyslink(toTitle, options)};\n\t\tif (entry.output === undefined) {\n\t\t\tentry.impossible = true;\n\t\t}\n\t}\n\treturn entry;\n};\n\nexports.makeSyslink = function(title, options) {\n\tvar match = title.match(this.matchRegExp);\n\tif (match && match[0] === title && title[0] !== \"~\") {\n\t\treturn title;\n\t} else {\n\t\treturn utils.makePrettylink(this.parser, title);\n\t}\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/syslink.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/transclude.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles replacement of transclusions in wiki text like,\n\n{{RenamedTiddler}}\n{{RenamedTiddler||TemplateTitle}}\n\nThis renames both the tiddler and the template field.\n\n\\*/\n\nvar refHandler = require(\"$:/plugins/flibbles/relink/js/fieldtypes/reference\");\nvar utils = require(\"./utils.js\");\n\nexports.name = ['transcludeinline', 'transcludeblock'];\n\nexports.report = function(text, callback, options) {\n\tvar m = this.match,\n\t\trefString = $tw.utils.trim(m[1]),\n\t\tref = parseTextReference(refString);\n\t\ttemplate = $tw.utils.trim(m[2]);\n\tif (ref.title) {\n\t\tvar suffix = '';\n\t\tif (ref.index) {\n\t\t\tsuffix = '##' + ref.index;\n\t\t} else if (ref.field) {\n\t\t\tsuffix = '!!' + ref.field;\n\t\t}\n\t\tif (template) {\n\t\t\tsuffix = suffix + '||' + template;\n\t\t}\n\t\tcallback(ref.title, '{{' + suffix + '}}')\n\t}\n\tif (template) {\n\t\tcallback(template, '{{' + refString + '||}}');\n\t}\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar m = this.match,\n\t\treference = parseTextReference(m[1]),\n\t\ttemplate = m[2],\n\t\tentry = undefined,\n\t\tmodified = false;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tif ($tw.utils.trim(reference.title) === fromTitle) {\n\t\t// preserve user's whitespace\n\t\treference.title = reference.title.replace(fromTitle, toTitle);\n\t\tmodified = true;\n\t}\n\tif ($tw.utils.trim(template) === fromTitle) {\n\t\ttemplate = template.replace(fromTitle, toTitle);\n\t\tmodified = true;\n\t}\n\tif (modified) {\n\t\tvar output = this.makeTransclude(this.parser, reference, template);\n\t\tif (output) {\n\t\t\t// Adding any newline that might have existed is\n\t\t\t// what allows this relink method to work for both\n\t\t\t// the block and inline filter wikitext rule.\n\t\t\tentry = {output: output + utils.getEndingNewline(m[0])};\n\t\t} else {\n\t\t\tentry = {impossible: true}\n\t\t}\n\t}\n\treturn entry;\n};\n\n// I have my own because the core one is deficient for my needs.\nfunction parseTextReference(textRef) {\n\t// Separate out the title, field name and/or JSON indices\n\tvar reTextRef = /^([\\w\\W]*?)(?:!!(\\S[\\w\\W]*)|##(\\S[\\w\\W]*))?$/g;\n\t\tmatch = reTextRef.exec(textRef),\n\t\tresult = {};\n\tif(match) {\n\t\t// Return the parts\n\t\tresult.title = match[1];\n\t\tresult.field = match[2];\n\t\tresult.index = match[3];\n\t} else {\n\t\t// If we couldn't parse it\n\t\tresult.title = textRef\n\t}\n\treturn result;\n};\n\n/** This converts a reference and a template into a string representation\n * of a transclude.\n */\nexports.makeTransclude = function(parser, reference, template) {\n\tvar rtn;\n\tif (!canBePrettyTemplate(template)) {\n\t\tvar widget = utils.makeWidget(parser, '$transclude', {\n\t\t\ttiddler: $tw.utils.trim(template),\n\t\t\tfield: reference.field,\n\t\t\tindex: reference.index});\n\t\tif (reference.title && widget !== undefined) {\n\t\t\trtn = utils.makeWidget(parser, '$tiddler', {tiddler: $tw.utils.trim(reference.title)}, widget);\n\t\t} else {\n\t\t\trtn = widget;\n\t\t}\n\t} else if (!canBePrettyTitle(reference.title)) {\n\t\t// This block and the next account for the 1%...\n\t\tvar reducedRef = {field: reference.field, index: reference.index};\n\t\trtn = utils.makeWidget(parser, '$tiddler', {tiddler: $tw.utils.trim(reference.title)}, prettyTransclude(reducedRef, template));\n\t} else {\n\t\t// This block takes care of 99% of all cases\n\t\trtn = prettyTransclude(reference, template);\n\t}\n\treturn rtn;\n};\n\nfunction canBePrettyTitle(value) {\n\treturn refHandler.canBePretty(value) && canBePrettyTemplate(value);\n};\n\nfunction canBePrettyTemplate(value) {\n\treturn !value || (value.indexOf('}') < 0 && value.indexOf('{') < 0 && value.indexOf('|') < 0);\n};\n\nfunction prettyTransclude(textReference, template) {\n\tif (typeof textReference !== \"string\") {\n\t\ttextReference = refHandler.toString(textReference);\n\t}\n\tif (!textReference) {\n\t\ttextReference = '';\n\t}\n\tif (template !== undefined) {\n\t\treturn \"{{\"+textReference+\"||\"+template+\"}}\";\n\t} else {\n\t\treturn \"{{\"+textReference+\"}}\";\n\t}\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/transclude.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/utils.js": {
"text": "/*\\\nmodule-type: library\n\nUtility methods for the wikitext relink rules.\n\n\\*/\n\nexports.makeWidget = function(parser, tag, attributes, body) {\n\tif (!parser.context.allowWidgets()) {\n\t\treturn undefined;\n\t}\n\tvar string = '<' + tag;\n\tfor (var attr in attributes) {\n\t\tvar value = attributes[attr];\n\t\tif (value !== undefined) {\n\t\t\tvar quoted = exports.wrapAttributeValue(value);\n\t\t\tif (!quoted) {\n\t\t\t\tif (!parser.options.placeholder) {\n\t\t\t\t\t// It's not possible to make this widget\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tvar category = getPlaceholderCategory(parser.context, tag, attr);\n\t\t\t\tquoted = '<<' + parser.placeholder.getPlaceholderFor(value, category) + '>>';\n\t\t\t}\n\t\t\tstring += ' ' + attr + '=' + quoted;\n\t\t}\n\t}\n\tif (body !== undefined) {\n\t\tstring += '>' + body + '</' + tag + '>';\n\t} else {\n\t\tstring += '/>';\n\t}\n\treturn string;\n};\n\nfunction getPlaceholderCategory(context, tag, attribute) {\n\tvar element = context.getAttribute(tag);\n\tvar rule = element && element[attribute];\n\t// titles go to relink-\\d\n\t// plaintext goes to relink-plaintext-\\d\n\t// because titles are way more common, also legacy\n\tif (rule === undefined) {\n\t\treturn 'plaintext';\n\t} else {\n\t\trule = rule.fields.text;\n\t\tif (rule === 'title') {\n\t\t\trule = undefined;\n\t\t}\n\t\treturn rule;\n\t}\n};\n\nexports.makePrettylink = function(parser, title, caption) {\n\tvar output;\n\tif (parser.context.allowPrettylinks() && canBePrettylink(title, caption)) {\n\t\tif (caption !== undefined) {\n\t\t\toutput = \"[[\" + caption + \"|\" + title + \"]]\";\n\t\t} else {\n\t\t\toutput = \"[[\" + title + \"]]\";\n\t\t}\n\t} else if (caption !== undefined) {\n\t\tvar safeCaption = sanitizeCaption(parser, caption);\n\t\tif (safeCaption !== undefined) {\n\t\t\toutput = exports.makeWidget(parser, '$link', {to: title}, safeCaption);\n\t\t}\n\t} else if (exports.shorthandPrettylinksSupported(parser.wiki)) {\n\t\toutput = exports.makeWidget(parser, '$link', {to: title});\n\t} else if (parser.context.allowWidgets() && parser.placeholder) {\n\t\t// If we don't have a caption, we must resort to\n\t\t// placeholders anyway to prevent link/caption desync\n\t\t// from later relinks.\n\t\t// It doesn't matter whether the tiddler is quotable.\n\t\tvar ph = parser.placeholder.getPlaceholderFor(title);\n\t\toutput = \"<$link to=<<\"+ph+\">>><$text text=<<\"+ph+\">>/></$link>\";\n\t}\n\treturn output;\n};\n\n/**In version 5.1.20, Tiddlywiki made it so <$link to\"something\" /> would\n * use \"something\" as a caption. This is preferable. However, Relink works\n * going back to 5.1.14, so we need to have different handling for both\n * cases.\n */\nvar _supported;\nexports.shorthandPrettylinksSupported = function(wiki) {\n\tif (_supported === undefined) {\n\t\tvar test = wiki.renderText(\"text/plain\", \"text/vnd.tiddlywiki\", \"<$link to=test/>\");\n\t\t_supported = (test === \"test\");\n\t}\n\treturn _supported;\n};\n\n/**Return true if value can be used inside a prettylink.\n */\nfunction canBePrettylink(value, customCaption) {\n\treturn value.indexOf(\"]]\") < 0 && value[value.length-1] !== ']' && (customCaption !== undefined || value.indexOf('|') < 0);\n};\n\nfunction sanitizeCaption(parser, caption) {\n\tvar plaintext = parser.wiki.renderText(\"text/plain\", \"text/vnd.tiddlywiki\", caption);\n\tif (plaintext === caption && caption.indexOf(\"</$link>\") <= 0) {\n\t\treturn caption;\n\t} else {\n\t\treturn exports.makeWidget(parser, '$text', {text: caption});\n\t}\n};\n\n/**Finds an appropriate quote mark for a given value.\n *\n *Tiddlywiki doesn't have escape characters for attribute values. Instead,\n * we just have to find the type of quotes that'll work for the given title.\n * There exist titles that simply can't be quoted.\n * If it can stick with the preference, it will.\n *\n * return: Returns the wrapped value, or undefined if it's impossible to wrap\n */\nexports.wrapAttributeValue = function(value, preference) {\n\tvar whitelist = [\"\", \"'\", '\"', '\"\"\"'];\n\tvar choices = {\n\t\t\"\": function(v) {return !/([\\/\\s<>\"'=])/.test(v) && v.length > 0; },\n\t\t\"'\": function(v) {return v.indexOf(\"'\") < 0; },\n\t\t'\"': function(v) {return v.indexOf('\"') < 0; },\n\t\t'\"\"\"': function(v) {return v.indexOf('\"\"\"') < 0 && v[v.length-1] != '\"';}\n\t};\n\tif (choices[preference] && choices[preference](value)) {\n\t\treturn wrap(value, preference);\n\t}\n\tfor (var i = 0; i < whitelist.length; i++) {\n\t\tvar quote = whitelist[i];\n\t\tif (choices[quote](value)) {\n\t\t\treturn wrap(value, quote);\n\t\t}\n\t}\n\t// No quotes will work on this\n\treturn undefined;\n};\n\n/**Like wrapAttribute value, except for macro parameters, not attributes.\n *\n * These are more permissive. Allows brackets,\n * and slashes and '<' in unquoted values.\n */\nexports.wrapParameterValue = function(value, preference) {\n\tvar whitelist = [\"\", \"'\", '\"', '[[', '\"\"\"'];\n\tvar choices = {\n\t\t\"\": function(v) {return !/([\\s>\"'=])/.test(v); },\n\t\t\"'\": function(v) {return v.indexOf(\"'\") < 0; },\n\t\t'\"': function(v) {return v.indexOf('\"') < 0; },\n\t\t\"[[\": canBePrettyOperand,\n\t\t'\"\"\"': function(v) {return v.indexOf('\"\"\"') < 0 && v[v.length-1] != '\"';}\n\t};\n\tif (choices[preference] && choices[preference](value)) {\n\t\treturn wrap(value, preference);\n\t}\n\tfor (var i = 0; i < whitelist.length; i++) {\n\t\tvar quote = whitelist[i];\n\t\tif (choices[quote](value)) {\n\t\t\treturn wrap(value, quote);\n\t\t}\n\t}\n\t// No quotes will work on this\n\treturn undefined;\n};\n\nfunction wrap(value, wrapper) {\n\tvar wrappers = {\n\t\t\"\": function(v) {return v; },\n\t\t\"'\": function(v) {return \"'\"+v+\"'\"; },\n\t\t'\"': function(v) {return '\"'+v+'\"'; },\n\t\t'\"\"\"': function(v) {return '\"\"\"'+v+'\"\"\"'; },\n\t\t\"[[\": function(v) {return \"[[\"+v+\"]]\"; }\n\t};\n\tvar chosen = wrappers[wrapper];\n\tif (chosen) {\n\t\treturn chosen(value);\n\t} else {\n\t\treturn undefined;\n\t}\n};\n\nfunction canBePrettyOperand(value) {\n\treturn value.indexOf(']') < 0;\n};\n\n/**Given some text, and a param or attribute within that text, this returns\n * what type of quotation that attribute is using.\n *\n * param: An object in the form {end:, ...}\n */\nexports.determineQuote = function(text, param) {\n\tvar pos = param.end-1;\n\tif (text[pos] === \"'\") {\n\t\treturn \"'\";\n\t}\n\tif (text[pos] === '\"') {\n\t\tif (text.substr(pos-2, 3) === '\"\"\"') {\n\t\t\treturn '\"\"\"';\n\t\t} else {\n\t\t\treturn '\"';\n\t\t}\n\t}\n\tif (text.substr(pos-1,2) === ']]' && text.substr((pos-param.value.length)-3, 2) === '[[') {\n\t\treturn \"[[\";\n\t}\n\treturn '';\n};\n\n// Finds the newline at the end of a string and returns it. Empty string if\n// none exists.\nexports.getEndingNewline = function(string) {\n\tvar l = string.length;\n\tif (string[l-1] === '\\n') {\n\t\treturn (string[l-2] === '\\r') ? \"\\r\\n\" : \"\\n\";\n\t}\n\treturn \"\";\n};\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/utils.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/wikilink.js": {
"text": "/*\\\nmodule-type: relinkwikitextrule\n\nHandles CamelCase links\n\nWikiLink\n\nbut not:\n\n~WikiLink\n\n\\*/\n\nvar utils = require(\"./utils.js\");\n\nexports.name = \"wikilink\";\n\nexports.report = function(text, callback, options) {\n\tvar title = this.match[0],\n\t\tunlink = $tw.config.textPrimitives.unWikiLink;\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tif (title[0] !== unlink) {\n\t\tcallback(title, unlink + title);\n\t}\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar entry = undefined,\n\t\ttitle = this.match[0];\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tif (title === fromTitle && title[0] !== $tw.config.textPrimitives.unWikiLink) {\n\t\tentry = { output: this.makeWikilink(toTitle, options) };\n\t\tif (entry.output === undefined) {\n\t\t\tentry.impossible = true;\n\t\t}\n\t}\n\treturn entry;\n};\n\nexports.makeWikilink = function(title, options) {\n\tif (title.match(this.matchRegExp) && title[0] !== $tw.config.textPrimitives.unWikiLink) {\n\t\treturn title;\n\t} else {\n\t\treturn utils.makePrettylink(this.parser, title);\n\t}\n};\n",
"module-type": "relinkwikitextrule",
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/wikitext/wikilink.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/context.js": {
"text": "/*\\\n\nBase class for relink contexts.\n\n\\*/\n\nfunction Context() {\n};\n\nexports.context = Context;\n\n// This class does no special handling of fields, operators, or attributes.\n// we pass it along to the parent.\nContext.prototype.getFields = function() {\n\treturn this.parent.getFields();\n};\n\nContext.prototype.getOperator = function(name, index) {\n\treturn this.parent.getOperator(name, index);\n};\n\nContext.prototype.getOperators = function() {\n\treturn this.parent.getOperators();\n};\n\nContext.prototype.getAttribute = function(elementName) {\n\treturn this.parent.getAttribute(elementName);\n};\n\nContext.prototype.getAttributes = function() {\n\treturn this.parent.getAttributes();\n};\n\nContext.prototype.getMacro = function(macroName) {\n\treturn this.parent.getMacro(macroName);\n};\n\nContext.prototype.getMacros = function() {\n\treturn this.parent.getMacros();\n};\n\nContext.prototype.allowPrettylinks = function() {\n\treturn this.parent.allowPrettylinks();\n};\n\nContext.prototype.allowWidgets = function() {\n\treturn this.parent.allowWidgets();\n};\n\nContext.prototype.hasImports = function(value) {\n\treturn this.parent.hasImports(value);\n};\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/context.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/import.js": {
"text": "/*\\\n\nThis handles the fetching and distribution of relink settings.\n\n\\*/\n\nvar WidgetContext = require('./widget').widget;\n\nfunction ImportContext(wiki, parent, filter) {\n\tthis.parent = parent;\n\tthis.wiki = wiki;\n\tvar importWidget = createImportWidget(filter, this.wiki, this.parent.widget);\n\tthis._compileList(importWidget.tiddlerList);\n\t// This only works if only one filter is imported\n\tthis.widget = this.getBottom(importWidget);\n\t// Trickle this up, so that any containing tiddlercontext knows that this\n\t// tiddler does some importing, and must be checked regularly.\n\tparent.hasImports(true);\n};\n\nexports.import = ImportContext;\n\nImportContext.prototype = new WidgetContext();\n\nImportContext.prototype.changed = function(changes) {\n\treturn this.widget && this.widget.refresh(changes)\n};\n\nfunction createImportWidget(filter, wiki, parent) {\n\tvar widget = wiki.makeWidget( { tree: [{\n\t\ttype: \"importvariables\",\n\t\tattributes: {\n\t\t\t\"filter\": {\n\t\t\t\ttype: \"string\",\n\t\t\t\tvalue: filter\n\t\t\t}\n\t\t}\n\t}] }, { parentWidget: parent} );\n\tif (parent) {\n\t\tparent.children.push(widget);\n\t}\n\twidget.execute();\n\twidget.renderChildren();\n\tvar importWidget = widget.children[0];\n\treturn importWidget;\n};\n\nImportContext.prototype._compileList = function(titleList) {\n\tfor (var i = 0; i < titleList.length; i++) {\n\t\tvar parser = this.wiki.parseTiddler(titleList[i]);\n\t\tif (parser) {\n\t\t\tvar parseTreeNode = parser.tree[0];\n\t\t\twhile (parseTreeNode && parseTreeNode.type === \"set\") {\n\t\t\t\tif (parseTreeNode.relink) {\n\t\t\t\t\tfor (var macroName in parseTreeNode.relink) {\n\t\t\t\t\t\tvar parameters = parseTreeNode.relink[macroName];\n\t\t\t\t\t\tfor (paramName in parameters) {\n\t\t\t\t\t\t\tthis.addSetting(this.wiki, macroName, paramName, parameters[paramName], titleList[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tparseTreeNode = parseTreeNode.children && parseTreeNode.children[0];\n\t\t\t}\n\t\t}\n\t}\n};\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/import.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/tiddler.js": {
"text": "/*\\\n\nContext for a tiddler. Defines nothing but makes an entry point to test if\na tiddler must be refreshed.\n\n\\*/\n\nvar WidgetContext = require('./widget.js').widget;\n\nfunction TiddlerContext(wiki, parentContext, title) {\n\tthis.title = title;\n\tthis.parent = parentContext;\n\tvar globalWidget = parentContext && parentContext.widget;\n\tvar parentWidget = wiki.makeWidget(null, {parentWidget: globalWidget});\n\tparentWidget.setVariable('currentTiddler', title);\n\tthis.widget = wiki.makeWidget(null, {parentWidget: parentWidget});\n};\n\nexports.tiddler = TiddlerContext;\n\nTiddlerContext.prototype = new WidgetContext();\n\nTiddlerContext.prototype.changed = function(changes) {\n\treturn this.widget && this.widget.refresh(changes);\n};\n\n// By default, a tiddler context does not use imports, unless an import\n// statement is later discovered somewhere in the fields.\nTiddlerContext.prototype.hasImports = function(value) {\n\treturn this._hasImports || (this._hasImports = value);\n};\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/tiddler.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/variable.js": {
"text": "/*\\\n\nThis handles the context for variables. Either from $set, $vars, or \\define\n\n\\*/\n\nvar WidgetContext = require('./widget').widget;\n\nfunction VariableContext(parent, setParseTreeNode) {\n\tthis.parent = parent;\n\t// Now create a new widget and attach it.\n\tvar attachPoint = parent.widget;\n\tvar setWidget = attachPoint.makeChildWidget(setParseTreeNode);\n\tattachPoint.children.push(setWidget);\n\tsetWidget.computeAttributes();\n\tsetWidget.execute();\n\t// point our widget to bottom, where any other contexts would attach to\n\tthis.widget = this.getBottom(setWidget);\n};\n\nexports.variable = VariableContext;\n\nVariableContext.prototype = new WidgetContext();\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/variable.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/whitelist.js": {
"text": "/*\\\n\nThis top-level context manages settings inside the whitelist. It never has\na parent.\n\n\\*/\n\nvar utils = require('../utils');\nvar Context = require('./context').context;\n\nvar prefix = \"$:/config/flibbles/relink/\";\n\nfunction WhitelistContext(wiki) {\n\tbuild(this, wiki);\n};\n\nexports.whitelist = WhitelistContext;\n\nWhitelistContext.prototype = new Context();\n\n/**Hot directories are directories for which if anything changes inside them,\n * then Relink must completely rebuild its index.\n * By default, this includes the whitelist settings, but relink-titles also\n * includes its rules disabling directory.\n * This is the FIRST solution I came up with to this problem. If you're\n * looking at this, please make a github issue so I have a chance to understand\n * your needs. This is currently a HACK solution.\n */\nWhitelistContext.hotDirectories = [prefix];\n\nWhitelistContext.prototype.getAttribute = function(elementName) {\n\treturn this.attributes[elementName];\n};\n\nWhitelistContext.prototype.getAttributes = function() {\n\treturn flatten(this.attributes);\n};\n\nWhitelistContext.prototype.getFields = function() {\n\treturn this.fields;\n};\n\nWhitelistContext.prototype.getOperator = function(operatorName, operandIndex) {\n\tvar op = this.operators[operatorName];\n\treturn op && op[operandIndex || 1];\n};\n\nWhitelistContext.prototype.getOperators = function() {\n\tvar signatures = Object.create(null);\n\tfor (var op in this.operators) {\n\t\tvar operandSet = this.operators[op];\n\t\tfor (var index in operandSet) {\n\t\t\tvar entry = operandSet[index];\n\t\t\tsignatures[entry.key] = entry;\n\t\t}\n\t}\n\treturn signatures;\n};\n\nWhitelistContext.prototype.getMacro = function(macroName) {\n\treturn this.macros[macroName];\n};\n\nWhitelistContext.prototype.getMacros = function() {\n\treturn flatten(this.macros);\n};\n\nWhitelistContext.prototype.changed = function(changedTiddlers) {\n\tfor (var i = 0; i < WhitelistContext.hotDirectories.length; i++) {\n\t\tvar dir = WhitelistContext.hotDirectories[i];\n\t\tfor (var title in changedTiddlers) {\n\t\t\tif (title.substr(0, dir.length) === dir) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nWhitelistContext.prototype.hasImports = function(value) {\n\t// We don't care if imports are used. This is the global level.\n\treturn false;\n};\n\n/**Factories define methods that create settings given config tiddlers.\n * for factory method 'example', it will be called once for each:\n * \"$:/config/flibbles/relink/example/...\" tiddler that exists.\n * the argument \"key\" will be set to the contents of \"...\"\n *\n * The reason I build relink settings in this convoluted way is to minimize\n * the number of times tiddlywiki has to run through EVERY tiddler looking\n * for relink config tiddlers.\n *\n * Also, by exporting \"factories\", anyone who extends relink can patch in\n * their own factory methods to create settings that are generated exactly\n * once per rename.\n */\nvar factories = {\n\tattributes: function(attributes, data, key) {\n\t\tvar elem = root(key);\n\t\tvar attr = key.substr(elem.length+1);\n\t\tattributes[elem] = attributes[elem] || Object.create(null);\n\t\tattributes[elem][attr] = data;\n\t},\n\tfields: function(fields, data, name) {\n\t\tfields[name] = data;\n\t},\n\tmacros: function(macros, data, key) {\n\t\t// We take the last index, not the first, because macro\n\t\t// parameters can't have slashes, but macroNames can.\n\t\tvar name = dir(key);\n\t\tvar arg = key.substr(name.length+1);\n\t\tmacros[name] = macros[name] || Object.create(null);\n\t\tmacros[name][arg] = data;\n\t},\n\toperators: function(operators, data, key) {\n\t\t// We take the last index, not the first, because the operator\n\t\t// may have a slash to indicate parameter number\n\t\tvar pair = key.split('/');\n\t\tvar name = pair[0];\n\t\tdata.key = key;\n\t\toperators[name] = operators[name] || Object.create(null);\n\t\toperators[name][pair[1] || 1] = data;\n\t}\n};\n\nfunction build(settings, wiki) {\n\tfor (var name in factories) {\n\t\tsettings[name] = Object.create(null);\n\t}\n\twiki.eachShadowPlusTiddlers(function(tiddler, title) {\n\t\tif (title.substr(0, prefix.length) === prefix) {\n\t\t\tvar remainder = title.substr(prefix.length);\n\t\t\tvar category = root(remainder);\n\t\t\tvar factory = factories[category];\n\t\t\tif (factory) {\n\t\t\t\tvar name = remainder.substr(category.length+1);\n\t\t\t\tvar data = utils.getType(tiddler.fields.text.trim());\n\t\t\t\tif (data) {\n\t\t\t\t\tdata.source = title;\n\t\t\t\t\t// Secret feature. You can access a config tiddler's\n\t\t\t\t\t// fields from inside the fieldtype handler. Cool\n\t\t\t\t\t// tricks can be done with this.\n\t\t\t\t\tdata.fields = tiddler.fields;\n\t\t\t\t\tfactory(settings[category], data, name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n};\n\n/* Returns first bit of a path. path/to/tiddler -> path\n */\nfunction root(string) {\n\tvar index = string.indexOf('/');\n\tif (index >= 0) {\n\t\treturn string.substr(0, index);\n\t}\n};\n\n/* Returns all but the last bit of a path. path/to/tiddler -> path/to\n */\nfunction dir(string) {\n\tvar index = string.lastIndexOf('/');\n\tif (index >= 0) {\n\t\treturn string.substr(0, index);\n\t}\n}\n\n/* Turns {dir: {file1: 'value1', file2: 'value2'}}\n * into {dir/file1: 'value1', dir/file2: 'value2'}\n */\nfunction flatten(set) {\n\tvar signatures = Object.create(null);\n\tfor (var outerName in set) {\n\t\tvar setItem = set[outerName];\n\t\tfor (var innerName in setItem) {\n\t\t\tsignatures[outerName + \"/\" + innerName] = setItem[innerName];\n\t\t}\n\t}\n\treturn signatures;\n};\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/whitelist.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/widget.js": {
"text": "/*\\\n\nThis is a virtual subclass of context for contexts that exist within widgets\nof a specific tiddler.\n\nAll widget contexts must have a widget member.\n\n\\*/\n\nvar Context = require('./context.js').context;\nvar utils = require('$:/plugins/flibbles/relink/js/utils.js');\n\nfunction WidgetContext() {};\n\nexports.widget = WidgetContext;\n\nWidgetContext.prototype = new Context();\n\nWidgetContext.prototype.getMacroDefinition = function(variableName) {\n\t// widget.variables is prototyped, so it looks up into all its parents too\n\treturn this.widget.variables[variableName] || $tw.macros[variableName];\n};\n\nWidgetContext.prototype.addSetting = function(wiki, macroName, parameter, type, sourceTitle) {\n\tthis.macros = this.macros || Object.create(null);\n\tvar macro = this.macros[macroName];\n\ttype = type || utils.getDefaultType(wiki);\n\tif (macro === undefined) {\n\t\tmacro = this.macros[macroName] = Object.create(null);\n\t}\n\tvar handler = utils.getType(type);\n\tif (handler) {\n\t\thandler.source = sourceTitle;\n\t\t// We attach the fields of the defining tiddler for the benefit\n\t\t// of any 3rd party field types that want access to them.\n\t\tvar tiddler = wiki.getTiddler(sourceTitle);\n\t\thandler.fields = tiddler.fields;\n\t\tmacro[parameter] = handler;\n\t}\n};\n\nWidgetContext.prototype.getMacros = function() {\n\tvar signatures = this.parent.getMacros();\n\tif (this.macros) {\n\t\tfor (var macroName in this.macros) {\n\t\t\tvar macro = this.macros[macroName];\n\t\t\tfor (var param in macro) {\n\t\t\t\tsignatures[macroName + \"/\" + param] = macro[param];\n\t\t\t}\n\t\t}\n\t}\n\treturn signatures;\n};\n\n/**This does strange handling because it's possible for a macro to have\n * its individual parameters whitelisted in separate places.\n * Don't know WHY someone would do this, but it can happen.\n */\nWidgetContext.prototype.getMacro = function(macroName) {\n\tvar theseSettings = this.macros && this.macros[macroName];\n\tvar parentSettings;\n\tif (this.parent) {\n\t\tparentSettings = this.parent.getMacro(macroName);\n\t}\n\tif (theseSettings && parentSettings) {\n\t\t// gotta merge them without changing either. This is expensive,\n\t\t// but it'll happen rarely.\n\t\tvar rtnSettings = $tw.utils.extend(Object.create(null), theseSettings, parentSettings);\n\t\treturn rtnSettings;\n\t}\n\treturn theseSettings || parentSettings;\n};\n\n/**Returns the deepest descendant of the given widget.\n */\nWidgetContext.prototype.getBottom = function(widget) {\n\twhile (widget.children.length > 0) {\n\t\twidget = widget.children[0];\n\t}\n\treturn widget;\n};\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/widget.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/contexts/wikitext.js": {
"text": "/*\\\n\nContext for wikitext. It can contain rules about what's allowed in this\ncurrent layer of wikitext.\n\n\\*/\n\nvar WidgetContext = require('./widget.js').widget;\n\nfunction WikitextContext(parentContext) {\n\tthis.parent = parentContext;\n\tthis.widget = parentContext.widget;\n};\n\nexports.wikitext = WikitextContext;\n\nWikitextContext.prototype = new WidgetContext();\n\n// Unless this specific context has rules about it, widgets and prettyLInks are allowed.\nWikitextContext.prototype.allowWidgets = enabled;\nWikitextContext.prototype.allowPrettylinks = enabled;\n\nfunction enabled() { return true; };\n",
"module-type": "relinkcontext",
"title": "$:/plugins/flibbles/relink/js/contexts/wikitext.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/utils/backupIndexer.js": {
"text": "/*\\\nmodule-type: library\n\nThis is a backup indexer Relink uses if the real one is disabled, or we're\n<V5.1.23. It's not nearly as good, but it caches some.\n\n\\*/\n\n\"use strict\";\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils.js\");\nvar TiddlerContext = utils.getContext('tiddler');\n\n// This is the indexer we use if the current wiki doesn't support indexers.\nfunction BackupIndexer(wiki) {\n\tthis.wiki = wiki;\n};\n\nmodule.exports = BackupIndexer;\n\nBackupIndexer.prototype.lookup = function(title) {\n\treturn getCache(this.wiki).lookup[title];\n};\n\nBackupIndexer.prototype.reverseLookup = function(title) {\n\tvar index = getCache(this.wiki);\n\tif (!index.reverse[title]) {\n\t\tvar record = Object.create(null);\n\t\tfor (var other in index.lookup) {\n\t\t\tif (index.lookup[other][title]) {\n\t\t\t\trecord[other] = index.lookup[other][title];\n\t\t\t}\n\t\t}\n\t\tindex.reverse[title] = record;\n\t}\n\treturn index.reverse[title];\n};\n\n/* The backup indexer doesn't bother caching relink reports. It would always\n * be called after a draft tiddler had changed, which would defeat the point.\n */\nBackupIndexer.prototype.relinkLookup = function(fromTitle, toTitle, options) {\n\tvar cache = getCache(this.wiki);\n\tif (cache.lastRelinkFrom === fromTitle && cache.lastRelinkTo === toTitle) {\n\t\toptions.cache = cache.lastRelinkCache;\n\t\treturn cache.lastRelink;\n\t}\n\tcache.lastRelink = utils.getRelinkResults(this.wiki, fromTitle, toTitle, cache.context, undefined, options);\n\tcache.lastRelinkFrom = fromTitle;\n\tcache.lastRelinkTo = toTitle;\n\tcache.lastRelinkCache = options.cache;\n\treturn cache.lastRelink;\n};\n\nfunction getCache(wiki) {\n\treturn wiki.getGlobalCache('relink', function() {\n\t\tvar tiddlerList = wiki.getRelinkableTitles();\n\t\tvar index = Object.create(null);\n\t\tvar wikiContext = utils.getWikiContext(wiki);\n\t\tfor (var i = 0; i < tiddlerList.length; i++) {\n\t\t\tvar title = tiddlerList[i];\n\t\t\tvar tiddler = wiki.getTiddler(title);\n\t\t\tif (tiddler && !tiddler.fields[\"plugin-type\"]) {\n\t\t\t\tvar context = new TiddlerContext(wiki, wikiContext, title);\n\t\t\t\tindex[title] = utils.getTiddlerRelinkReferences(wiki, title, context);\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tlookup: index,\n\t\t\treverse: Object.create(null),\n\t\t\tcontext: wikiContext};\n\t});\n};\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/utils/backupIndexer.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/utils/entry.js": {
"text": "/*\\\n\nEntries are deprecated. Don't use them. These classes are here just so that\nany 3rd party modules built for Relink V1 don't break.\n\nJust return an object like, {output: \"string\", impossible: true|undefined}\n\n\\*/\n\nfunction EntryNode() {\n\tthis.children = [];\n};\n\nmodule.exports = EntryNode;\n\n/** PURE VIRTUAL\n * EntryNode.prototype.report = function() -> [\"string\", ...]\n */\n\nEntryNode.newType = function() {\n\treturn EntryNode;\n};\n\nEntryNode.prototype.add = function(entry) {\n\tthis.children.push(entry);\n};\n\nfunction EntryCollection() {\n\tthis.children = Object.create(null);\n\tthis.types = Object.create(null);\n};\n\nEntryNode.newCollection = function(name) {\n\treturn EntryCollection;\n};\n\n// Again. I reiterate. Don't use this. All this is just legacy support.\nObject.defineProperty(EntryCollection, 'impossible', {\n\tget: function() {\n\t\tvar imp = this._impossible;\n\t\tthis.eachChild(function(child) { imp = imp || child.impossible; });\n\t\treturn imp;\n\t},\n\tset: function(impossible) {\n\t\tthis._impossible = true;\n\t}\n});\n\nEntryCollection.prototype.eachChild = function(method) {\n\tfor (var child in this.children) {\n\t\tmethod(this.children[child]);\n\t}\n};\n\nEntryCollection.prototype.addChild = function(child, name, type) {\n\tthis.children[name] = child;\n\tthis.types[name] = type;\n};\n\nEntryCollection.prototype.hasChildren = function() {\n\treturn Object.keys(this.children).length > 0;\n};\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/utils/entry.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/utils/placeholder.js": {
"text": "/*\\\n\nA method which doles out placeholders when requested, and constructs\nthe necessary supporting pragma when requested.\n\n\\*/\n\nvar utils = require('../utils');\n\nfunction Placeholder() {\n\tthis.placeholders = Object.create(null);\n\tthis.reverseMap = {};\n\tthis.used = Object.create(null);\n};\n\nmodule.exports = Placeholder;\n\nPlaceholder.prototype.getPlaceholderFor = function(value, category) {\n\tthis.reverseMap[category] = this.reverseMap[category] || Object.create(null);\n\tvar placeholder = this.reverseMap[category][value];\n\tif (placeholder) {\n\t\treturn placeholder;\n\t}\n\tvar config = (this.parser && this.parser.context) || utils.getWikiContext(this.parser.wiki);\n\tvar number = 0;\n\tvar prefix = \"relink-\"\n\tif (category && category !== \"title\") {\n\t\t// I don't like \"relink-title-1\". \"relink-1\" should be for\n\t\t// titles. lists, and filters can have descriptors though.\n\t\tprefix += category + \"-\";\n\t}\n\tdo {\n\t\tnumber += 1;\n\t\tplaceholder = prefix + number;\n\t} while (config.getMacroDefinition(placeholder) || this.used[placeholder]);\n\tthis.placeholders[placeholder] = value;\n\tthis.reverseMap[category][value] = placeholder;\n\tthis.used[placeholder] = true;\n\treturn placeholder;\n};\n\n// For registering placeholders that already existed\nPlaceholder.prototype.registerExisting = function(key, value) {\n\tthis.reverseMap[value] = key;\n\tthis.used[key] = true;\n};\n\nPlaceholder.prototype.getPreamble = function() {\n\tvar results = [];\n\tvar keys = Object.keys(this.placeholders);\n\tif (keys.length > 0) {\n\t\tkeys.sort();\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tvar name = keys[i];\n\t\t\tvar val = this.placeholders[name];\n\t\t\tresults.push(\"\\\\define \"+name+\"() \"+val+\"\\n\");\n\t\t}\n\t}\n\treturn results.join('');\n};\n\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/utils/placeholder.js",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/utils/rebuilder.js": {
"text": "/*\\\n\nThis helper class aids in reconstructing an existing string with new parts.\n\n\\*/\n\nfunction Rebuilder(text, start) {\n\tthis.text = text;\n\tthis.index = start || 0;\n\tthis.pieces = [];\n};\n\nmodule.exports = Rebuilder;\n\n/**Pieces must be added consecutively.\n * Start and end are the indices in the old string specifying where to graft\n * in the new piece.\n */\nRebuilder.prototype.add = function(value, start, end) {\n\tthis.pieces.push(this.text.substring(this.index, start), value);\n\tthis.index = end;\n};\n\nRebuilder.prototype.changed = function() {\n\treturn this.pieces.length > 0;\n};\n\nRebuilder.prototype.results = function(end) {\n\tif (this.changed()) {\n\t\tthis.pieces.push(this.text.substring(this.index, end));\n\t\treturn this.pieces.join('');\n\t}\n\treturn undefined;\n};\n",
"module-type": "library",
"title": "$:/plugins/flibbles/relink/js/utils/rebuilder.js",
"type": "application/javascript"
},
"$:/config/flibbles/relink/attributes/$button/set": {
"title": "$:/config/flibbles/relink/attributes/$button/set",
"text": "reference"
},
"$:/config/flibbles/relink/attributes/$button/setTo": {
"title": "$:/config/flibbles/relink/attributes/$button/setTo",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$button/to": {
"title": "$:/config/flibbles/relink/attributes/$button/to",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$checkbox/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$checkbox/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$checkbox/tag": {
"title": "$:/config/flibbles/relink/attributes/$checkbox/tag",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$count/filter": {
"title": "$:/config/flibbles/relink/attributes/$count/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$draggable/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$draggable/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$draggable/filter": {
"title": "$:/config/flibbles/relink/attributes/$draggable/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$edit-bitmap/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$edit-bitmap/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$edit-text/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$edit-text/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$edit/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$edit/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$encrypt/filter": {
"title": "$:/config/flibbles/relink/attributes/$encrypt/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$fieldmangler/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$fieldmangler/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$fields/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$fields/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$image/source": {
"title": "$:/config/flibbles/relink/attributes/$image/source",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$importvariables/filter": {
"title": "$:/config/flibbles/relink/attributes/$importvariables/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$linkcatcher/to": {
"title": "$:/config/flibbles/relink/attributes/$linkcatcher/to",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$linkcatcher/set": {
"title": "$:/config/flibbles/relink/attributes/$linkcatcher/set",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$link/to": {
"title": "$:/config/flibbles/relink/attributes/$link/to",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$list/filter": {
"title": "$:/config/flibbles/relink/attributes/$list/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$list/template": {
"title": "$:/config/flibbles/relink/attributes/$list/template",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$list/editTemplate": {
"title": "$:/config/flibbles/relink/attributes/$list/editTemplate",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$list/emptyMessage": {
"title": "$:/config/flibbles/relink/attributes/$list/emptyMessage",
"text": "wikitext"
},
"$:/config/flibbles/relink/attributes/$list/history": {
"title": "$:/config/flibbles/relink/attributes/$list/history",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$navigator/story": {
"title": "$:/config/flibbles/relink/attributes/$navigator/story",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$navigator/history": {
"title": "$:/config/flibbles/relink/attributes/$navigator/history",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$radio/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$radio/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$range/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$range/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$reveal/stateTitle": {
"title": "$:/config/flibbles/relink/attributes/$reveal/stateTitle",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$select/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$select/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$setvariable/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$setvariable/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$setvariable/subtiddler": {
"title": "$:/config/flibbles/relink/attributes/$setvariable/subtiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$setvariable/filter": {
"title": "$:/config/flibbles/relink/attributes/$setvariable/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$set/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$set/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$set/subtiddler": {
"title": "$:/config/flibbles/relink/attributes/$set/subtiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$set/filter": {
"title": "$:/config/flibbles/relink/attributes/$set/filter",
"text": "filter"
},
"$:/config/flibbles/relink/attributes/$tiddler/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$tiddler/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$transclude/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$transclude/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$transclude/subtiddler": {
"title": "$:/config/flibbles/relink/attributes/$transclude/subtiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$view/tiddler": {
"title": "$:/config/flibbles/relink/attributes/$view/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/attributes/$view/subtiddler": {
"title": "$:/config/flibbles/relink/attributes/$view/subtiddler",
"text": "title"
},
"$:/plugins/flibbles/relink/configuration": {
"title": "$:/plugins/flibbles/relink/configuration",
"text": "<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/flibbles/relink/Configuration]!has[draft.of]]\" \"$:/plugins/flibbles/relink/ui/configuration/Fields\">>\n</div>\n"
},
"$:/config/flibbles/relink/fields/caption": {
"title": "$:/config/flibbles/relink/fields/caption",
"text": "wikitext"
},
"$:/config/flibbles/relink/fields/filter": {
"title": "$:/config/flibbles/relink/fields/filter",
"text": "filter"
},
"$:/config/flibbles/relink/fields/list": {
"title": "$:/config/flibbles/relink/fields/list",
"text": "list"
},
"$:/config/flibbles/relink/fields/list-after": {
"title": "$:/config/flibbles/relink/fields/list-after",
"text": "title"
},
"$:/config/flibbles/relink/fields/list-before": {
"title": "$:/config/flibbles/relink/fields/list-before",
"text": "title"
},
"$:/config/flibbles/relink/fields/tags": {
"title": "$:/config/flibbles/relink/fields/tags",
"text": "list"
},
"$:/plugins/flibbles/relink/language/Buttons/Delete/Hint": {
"title": "$:/plugins/flibbles/relink/language/Buttons/Delete/Hint",
"text": "delete"
},
"$:/plugins/flibbles/relink/language/Buttons/LinkToInline/Hint": {
"title": "$:/plugins/flibbles/relink/language/Buttons/LinkToInline/Hint",
"text": "go to defining tiddler"
},
"$:/plugins/flibbles/relink/language/Buttons/NewAttribute/Hint": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewAttribute/Hint",
"text": "Specify a new widget/element attribute to be updated whenever a tiddler is renamed"
},
"$:/plugins/flibbles/relink/language/Buttons/NewAttribute/Caption": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewAttribute/Caption",
"text": "add"
},
"$:/plugins/flibbles/relink/language/Buttons/NewField/Hint": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewField/Hint",
"text": "Specify a new field to be updated whenever a tiddler is renamed"
},
"$:/plugins/flibbles/relink/language/Buttons/NewField/Caption": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewField/Caption",
"text": "add"
},
"$:/plugins/flibbles/relink/language/Buttons/NewOperator/Hint": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewOperator/Hint",
"text": "Specify a new filter operator to be considered whenever a tiddler is renamed"
},
"$:/plugins/flibbles/relink/language/Buttons/NewOperator/Caption": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewOperator/Caption",
"text": "add"
},
"$:/plugins/flibbles/relink/language/Buttons/NewParameter/Hint": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewParameter/Hint",
"text": "Specify a new macro parameter to be updated whenever a tiddler is renamed"
},
"$:/plugins/flibbles/relink/language/Buttons/NewParameter/Caption": {
"title": "$:/plugins/flibbles/relink/language/Buttons/NewParameter/Caption",
"text": "add"
},
"$:/plugins/flibbles/relink/language/Error/InvalidAttributeName": {
"title": "$:/plugins/flibbles/relink/language/Error/InvalidAttributeName",
"text": "Illegal characters in attribute name \"<$text text=<<attributeName>>/>\". Attributes cannot contain slashes ('/'), closing angle or square brackets ('>' or ']'), quotes or apostrophes ('\"' or \"'\"), equals ('='), or whitespace"
},
"$:/plugins/flibbles/relink/language/Error/InvalidElementName": {
"title": "$:/plugins/flibbles/relink/language/Error/InvalidElementName",
"text": "Illegal characters in element/widget name \"<$text text=<<elementName>>/>\". Element tags can only contain letters and the characters hyphen (`-`) and dollar sign (`$`)"
},
"$:/plugins/flibbles/relink/language/Error/InvalidMacroName": {
"title": "$:/plugins/flibbles/relink/language/Error/InvalidMacroName",
"text": "Illegal characters in macro name \"<$text text=<<macroName>>/>\". Macros cannot contain whitespace"
},
"$:/plugins/flibbles/relink/language/Error/InvalidParameterName": {
"title": "$:/plugins/flibbles/relink/language/Error/InvalidParameterName",
"text": "Illegal characters in parameter name \"<$text text=<<parameterName>>/>\". Parameters can only contain letters, digits, and the characters underscore (`_`) and hyphen (`-`)"
},
"$:/plugins/flibbles/relink/language/Error/RelinkFilterOperator": {
"title": "$:/plugins/flibbles/relink/language/Error/RelinkFilterOperator",
"text": "Filter Error: Unknown suffix for the 'relink' filter operator"
},
"$:/plugins/flibbles/relink/language/Error/ReportFailedRelinks": {
"title": "$:/plugins/flibbles/relink/language/Error/ReportFailedRelinks",
"text": "Relink could not update '<<from>>' to '<<to>>' inside the following tiddlers:"
},
"$:/plugins/flibbles/relink/language/Error/UnrecognizedType": {
"title": "$:/plugins/flibbles/relink/language/Error/UnrecognizedType",
"text": "Relink parse error: Unrecognized field type '<<type>>'"
},
"$:/plugins/flibbles/relink/language/Help/Attributes": {
"title": "$:/plugins/flibbles/relink/language/Help/Attributes",
"text": "See the <a href={{{[{$:/plugins/flibbles/relink!!demo}addsuffix[#Attributes]]}}}>Attributes documentation page</a> for details."
},
"$:/plugins/flibbles/relink/language/Help/Fields": {
"title": "$:/plugins/flibbles/relink/language/Help/Fields",
"text": "See the <a href={{{[{$:/plugins/flibbles/relink!!demo}addsuffix[#Fields]]}}}>Fields documentation page</a> for details."
},
"$:/plugins/flibbles/relink/language/Help/Macros": {
"title": "$:/plugins/flibbles/relink/language/Help/Macros",
"text": "See the <a href={{{[{$:/plugins/flibbles/relink!!demo}addsuffix[#Macros]]}}}>Macros documentation page</a> for details."
},
"$:/plugins/flibbles/relink/language/Help/Operators": {
"title": "$:/plugins/flibbles/relink/language/Help/Operators",
"text": "See the <a href={{{[{$:/plugins/flibbles/relink!!demo}addsuffix[#Operators]]}}}>Operators documentation page</a> for details."
},
"$:/plugins/flibbles/relink/language/TiddlerInfo/References/Empty": {
"title": "$:/plugins/flibbles/relink/language/TiddlerInfo/References/Empty",
"text": "No tiddlers contain any fields, links, macros, transclusions, or widgets referencing this one"
},
"$:/plugins/flibbles/relink/language/TiddlerInfo/References/Description": {
"title": "$:/plugins/flibbles/relink/language/TiddlerInfo/References/Description",
"text": "The following tiddlers contain fields, links, macros, transclusions, or widgets referencing this one:"
},
"$:/plugins/flibbles/relink/language/TiddlerInfo/References/Caption": {
"title": "$:/plugins/flibbles/relink/language/TiddlerInfo/References/Caption",
"text": "//Relink// References"
},
"$:/plugins/flibbles/relink/language/ui/Attributes/Caption": {
"title": "$:/plugins/flibbles/relink/language/ui/Attributes/Caption",
"text": "Attributes"
},
"$:/plugins/flibbles/relink/language/ui/Fields/Caption": {
"title": "$:/plugins/flibbles/relink/language/ui/Fields/Caption",
"text": "Fields"
},
"$:/plugins/flibbles/relink/language/ui/Macros/Caption": {
"title": "$:/plugins/flibbles/relink/language/ui/Macros/Caption",
"text": "Macros"
},
"$:/plugins/flibbles/relink/language/ui/Operators/Caption": {
"title": "$:/plugins/flibbles/relink/language/ui/Operators/Caption",
"text": "Operators"
},
"$:/plugins/flibbles/relink/license": {
"title": "$:/plugins/flibbles/relink/license",
"type": "text/vnd.tiddlywiki",
"text": "<a href={{$:/plugins/flibbles/relink!!demo}}>Relink Plugin</a> Copyright (c) 2019-<<now YYYY>> Cameron Fischer\n\n[[BSD 3-Clause License|https://raw.githubusercontent.com/flibbles/tw5-relink/master/LICENSE]]\n"
},
"$:/config/flibbles/relink/macros/csvtiddlers/filter": {
"title": "$:/config/flibbles/relink/macros/csvtiddlers/filter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/datauri/title": {
"title": "$:/config/flibbles/relink/macros/datauri/title",
"text": "title"
},
"$:/config/flibbles/relink/macros/jsontiddler/title": {
"title": "$:/config/flibbles/relink/macros/jsontiddler/title",
"text": "title"
},
"$:/config/flibbles/relink/macros/jsontiddlers/filter": {
"title": "$:/config/flibbles/relink/macros/jsontiddlers/filter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/list-links/filter": {
"title": "$:/config/flibbles/relink/macros/list-links/filter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/list-links-draggable/tiddler": {
"title": "$:/config/flibbles/relink/macros/list-links-draggable/tiddler",
"text": "title"
},
"$:/config/flibbles/relink/macros/list-links-draggable/itemTemplate": {
"title": "$:/config/flibbles/relink/macros/list-links-draggable/itemTemplate",
"text": "title"
},
"$:/config/flibbles/relink/macros/list-tagged-draggable/tag": {
"title": "$:/config/flibbles/relink/macros/list-tagged-draggable/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/list-tagged-draggable/itemTemplate": {
"title": "$:/config/flibbles/relink/macros/list-tagged-draggable/itemTemplate",
"text": "title"
},
"$:/config/flibbles/relink/macros/tabs/buttonTemplate": {
"title": "$:/config/flibbles/relink/macros/tabs/buttonTemplate",
"text": "title"
},
"$:/config/flibbles/relink/macros/tabs/default": {
"title": "$:/config/flibbles/relink/macros/tabs/default",
"text": "title"
},
"$:/config/flibbles/relink/macros/tabs/tabsList": {
"title": "$:/config/flibbles/relink/macros/tabs/tabsList",
"text": "filter"
},
"$:/config/flibbles/relink/macros/tabs/template": {
"title": "$:/config/flibbles/relink/macros/tabs/template",
"text": "title"
},
"$:/config/flibbles/relink/macros/tag/tag": {
"title": "$:/config/flibbles/relink/macros/tag/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/tag-pill/tag": {
"title": "$:/config/flibbles/relink/macros/tag-pill/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/timeline/subfilter": {
"title": "$:/config/flibbles/relink/macros/timeline/subfilter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/toc/tag": {
"title": "$:/config/flibbles/relink/macros/toc/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc/itemClassFilter": {
"title": "$:/config/flibbles/relink/macros/toc/itemClassFilter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/toc-expandable/tag": {
"title": "$:/config/flibbles/relink/macros/toc-expandable/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-expandable/itemClassFilter": {
"title": "$:/config/flibbles/relink/macros/toc-expandable/itemClassFilter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/toc-expandable/exclude": {
"title": "$:/config/flibbles/relink/macros/toc-expandable/exclude",
"text": "list"
},
"$:/config/flibbles/relink/macros/toc-selective-expandable/tag": {
"title": "$:/config/flibbles/relink/macros/toc-selective-expandable/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-selective-expandable/itemClassFilter": {
"title": "$:/config/flibbles/relink/macros/toc-selective-expandable/itemClassFilter",
"text": "filter"
},
"$:/config/flibbles/relink/macros/toc-selective-expandable/exclude": {
"title": "$:/config/flibbles/relink/macros/toc-selective-expandable/exclude",
"text": "list"
},
"$:/config/flibbles/relink/macros/toc-tabbed-external-nav/tag": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-external-nav/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-tabbed-external-nav/selectedTiddler": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-external-nav/selectedTiddler",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-tabbed-external-nav/unselectedText": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-external-nav/unselectedText",
"text": "wikitext"
},
"$:/config/flibbles/relink/macros/toc-tabbed-external-nav/missingText": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-external-nav/missingText",
"text": "wikitext"
},
"$:/config/flibbles/relink/macros/toc-tabbed-external-nav/template": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-external-nav/template",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/tag": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/tag",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/selectedTiddler": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/selectedTiddler",
"text": "title"
},
"$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/unselectedText": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/unselectedText",
"text": "wikitext"
},
"$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/missingText": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/missingText",
"text": "wikitext"
},
"$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/template": {
"title": "$:/config/flibbles/relink/macros/toc-tabbed-internal-nav/template",
"text": "title"
},
"$:/config/flibbles/relink/operators/list": {
"title": "$:/config/flibbles/relink/operators/list",
"text": "reference"
},
"$:/config/flibbles/relink/operators/tag": {
"title": "$:/config/flibbles/relink/operators/tag",
"text": "title"
},
"$:/config/flibbles/relink/operators/title": {
"title": "$:/config/flibbles/relink/operators/title",
"text": "title"
},
"$:/config/flibbles/relink/operators/field:title": {
"title": "$:/config/flibbles/relink/operators/field:title",
"text": "title"
},
"$:/language/EditTemplate/Title/Impossibles/Prompt": {
"title": "$:/language/EditTemplate/Title/Impossibles/Prompt",
"text": "''Warning:'' Not all references in the following tiddlers can be updated by //Relink// due to the complexity of the new title:"
},
"$:/language/EditTemplate/Title/References/Prompt": {
"title": "$:/language/EditTemplate/Title/References/Prompt",
"text": "The following tiddlers will be updated if relinking:"
},
"$:/language/EditTemplate/Title/Relink/Prompt": {
"title": "$:/language/EditTemplate/Title/Relink/Prompt",
"text": "Use //Relink// to update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' across all other tiddlers"
},
"$:/core/ui/EditTemplate/title": {
"title": "$:/core/ui/EditTemplate/title",
"tags": "$:/tags/EditTemplate",
"text": "<$edit-text field=\"draft.title\" class=\"tc-titlebar tc-edit-texteditor\" focus=\"true\" tabindex={{$:/config/EditTabIndex}}/>\n\n<$reveal state=\"!!draft.title\" type=\"nomatch\" text={{!!draft.of}} tag=\"div\">\n\n<$vars pattern=\"\"\"[\\|\\[\\]{}]\"\"\" bad-chars=\"\"\"`| [ ] { }`\"\"\">\n\n<$list filter=\"[all[current]regexp:draft.title<pattern>]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/BadCharacterWarning}}\n\n</div>\n\n</$list>\n\n</$vars>\n\n<$list filter=\"[{!!draft.title}!is[missing]]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/Exists/Prompt}}\n\n</div>\n\n</$list>\n\n<$list filter=\"[{!!draft.of}!is[missing]]\" variable=\"listItem\">\n\n<$vars fromTitle={{!!draft.of}} toTitle={{!!draft.title}}>\n\n<$checkbox tiddler=\"$:/config/RelinkOnRename\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> {{$:/language/EditTemplate/Title/Relink/Prompt}}</$checkbox>\n\n<$tiddler tiddler=<<fromTitle>> >\n\n<$list filter=\"[relink:wouldchange<toTitle>limit[1]]\" variable=\"listItem\">\n\n<$vars stateTiddler=<<qualify \"$:/state/edit/references\">> >\n\n<$set\n\tname=\"prompt\"\n\tfilter=\"[relink:wouldchange<toTitle>relink:impossible<toTitle>]\"\n\tvalue=\"EditTemplate/Title/Impossibles/Prompt\"\n\temptyValue=\"EditTemplate/Title/References/Prompt\" >\n<$reveal type=\"nomatch\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"show\" class=\"tc-btn-invisible\">{{$:/core/images/right-arrow}}\n<$macrocall $name=lingo title=<<prompt>> />\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"hide\" class=\"tc-btn-invisible\">{{$:/core/images/down-arrow}}\n<$macrocall $name=lingo title=<<prompt>> />\n</$button>\n</$reveal>\n</$set>\n\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$list variable=\"listItem\" filter=\"[relink:wouldchange<toTitle>!title[$:/StoryList]sort[title]]\" template=\"$:/plugins/flibbles/relink/ui/ListItemTemplate\">\n</$list>\n</$reveal>\n\n</$vars>\n\n</$list>\n\n</$tiddler>\n\n</$vars>\n\n</$list>\n\n</$reveal>\n"
},
"$:/config/flibbles/relink/PluginLibrary": {
"title": "$:/config/flibbles/relink/PluginLibrary",
"caption": "//Relink// Library",
"url": "https://flibbles.github.io/tw5-relink/library/index.html",
"tags": "$:/tags/PluginLibrary",
"text": "The //Relink// library contains //Relink// as well as its supplemental plugins. It is maintained by Flibbles. See the [[github page|https://github.com/flibbles/tw5-relink]] for more information.\n"
},
"$:/plugins/flibbles/relink/readme": {
"title": "$:/plugins/flibbles/relink/readme",
"type": "text/vnd.tiddlywiki",
"text": "When renaming a tiddler, Relink can update the fields, filters, and widgets\nof all other tiddlers. However, it works through whitelisting.\n\nIt's already configured to update tiddler titles for all core widgets, filters,\nand fields, but the whitelists can be customized for each of this in the\nconfiguration panel.\n\nSee <a href={{$:/plugins/flibbles/relink!!source}}>the tw5-relink website</a> for more details and examples.\n"
},
"$:/config/flibbles/relink/settings/default-type": {
"title": "$:/config/flibbles/relink/settings/default-type",
"text": "title"
},
"$:/plugins/flibbles/relink/ui/ListItemTemplate": {
"title": "$:/plugins/flibbles/relink/ui/ListItemTemplate",
"text": "<$set\n\tname=\"classes\"\n\tfilter=\"[<listItem>relink:impossible<toTitle>]\"\n\tvalue=\"tc-menu-list-item tc-relink-impossible\"\n\temptyValue=\"tc-menu-list-item\">\n<div class=<<classes>>>\n<$link to=<<listItem>>><$text text=<<listItem>> /></$link>\n</div>\n</$set>\n"
},
"$:/plugins/flibbles/relink/ui/TiddlerInfo/References": {
"title": "$:/plugins/flibbles/relink/ui/TiddlerInfo/References",
"caption": "{{$:/plugins/flibbles/relink/language/TiddlerInfo/References/Caption}}",
"tags": "$:/tags/TiddlerInfo",
"text": "\\define lingo-base() $:/plugins/flibbles/relink/language/TiddlerInfo/\n\\define filter() [all[current]relink:backreferences[]!title[$:/StoryList]!prefix[$:/temp/]sort[title]]\n<$list filter=\"[subfilter<filter>first[]]\">\n\n<<lingo References/Description>>\n</$list>\n\n<table class=\"tc-relink-references-table\">\n<tbody>\n<$list filter=<<filter>> emptyMessage=<<lingo References/Empty>> variable=\"listItem\" template=\"$:/plugins/flibbles/relink/ui/TiddlerInfo/ReferencesTemplate\" />\n</tbody>\n</table>\n"
},
"$:/plugins/flibbles/relink/ui/TiddlerInfo/ReferencesTemplate": {
"title": "$:/plugins/flibbles/relink/ui/TiddlerInfo/ReferencesTemplate",
"text": "<tr class=\"tc-relink-references\">\n<td class=\"tc-relink-references-title\">\n<$link to=<<listItem>>/>\n</td>\n<td class=\"tc-relink-references-report\">\n<$list filter=\"[<listItem>relink:report<currentTiddler>]\">\n\n<$text text=<<currentTiddler>> />\n</$list>\n\n</td>\n</tr>\n"
},
"$:/plugins/flibbles/relink/ui/components/button-delete": {
"title": "$:/plugins/flibbles/relink/ui/components/button-delete",
"text": "\\define lingo-base() $:/plugins/flibbles/relink/language/Buttons/\n\\define prefix() $:/config/flibbles/relink/\n\n<$list filter=\"[all[current]prefix<prefix>]\" >\n<$button class=\"tc-btn-invisible\" tooltip={{$:/plugins/flibbles/relink/language/Buttons/Delete/Hint}}><$list filter=\"[all[current]is[tiddler]]\">\n<$action-deletetiddler $tiddler=<<currentTiddler>> />\n</$list><$list filter=\"[all[current]is[shadow]]\">\n<$action-setfield $tiddler=<<tiddlerName>> text=\"\" />\n</$list>\n{{$:/core/images/delete-button}}\n</$button>\n</$list><$list filter=\"[all[current]!prefix<prefix>]\">\n<$link><$button class=\"tc-btn-invisible\" tooltip={{$:/plugins/flibbles/relink/language/Buttons/LinkToInline/Hint}}>{{$:/core/images/link}}</$button></$link>\n</$list>\n"
},
"$:/plugins/flibbles/relink/ui/components/select-fieldtype": {
"title": "$:/plugins/flibbles/relink/ui/components/select-fieldtype",
"text": "\\define prefix() $:/config/flibbles/relink/\n\n<$vars type={{{ [<signature>relink:type[]] }}} >\n<$list filter=\"[all[current]prefix<prefix>]\" >\n<$select tiddler=<<currentTiddler>> >\n<$list variable=\"option\" filter=\"[relink:types[]]\">\n<option><$text text=<<option>> /></option>\n</$list>\n</$select>\n</$list><$list filter=\"[all[current]!prefix<prefix>]\">\n<$text text=<<type>> />\n</$list>\n</$vars>\n"
},
"$:/plugins/flibbles/relink/ui/components/tables": {
"title": "$:/plugins/flibbles/relink/ui/components/tables",
"text": "\\define .make-table(title, plugin, default-table-state:yes)\n\n<$list variable=\"render\" filter=\"[relink:signatures<__plugin__>prefix<__category__>first[]]\">\n<$set name=\"table-state\" value=<<qualify \"\"\"$:/state/flibbles/relink/tables/$title$\"\"\">>>\n<tr><th class=\"tc-relink-header-plugin\" colspan=<<column-count>> >\n<$reveal type=\"nomatch\" state=<<table-state>> text=\"yes\" default=\"\"\"$default-table-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<table-state>> setTo=\"yes\">\n{{$:/core/images/right-arrow}} ''$title$''\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<table-state>> text=\"yes\" default=\"\"\"$default-table-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<table-state>> setTo=\"no\">\n{{$:/core/images/down-arrow}} ''$title$''\n</$button>\n</$reveal>\n</th></tr>\n<$list\n\tvariable=\"signature\"\n\tfilter=\"[relink:signatures<__plugin__>prefix<__category__>sort[]]\">\n<$vars key={{{ [<signature>removeprefix<__category__>removeprefix[/]] }}} >\n<$tiddler tiddler={{{[<signature>relink:source[]]}}} >\n<$reveal tag=\"tr\" type=\"match\" state=<<table-state>> text=\"yes\" default=\"\"\"$default-table-state$\"\"\">\n<$macrocall $name=<<__list-row-macro__>> signature=<<signature>> />\n<td class=\"tc-relink-column-type\">{{||$:/plugins/flibbles/relink/ui/components/select-fieldtype}}</td>\n<td class=\"tc-relink-column-delete\">{{||$:/plugins/flibbles/relink/ui/components/button-delete}}</td>\n</$reveal>\n</$tiddler>\n</$vars>\n</$list>\n</$set>\n</$list>\n\\end\n\n\\define tables(category, list-row-macro, header-list)\n<$vars\n\tcolumn-count={{{[enlist<__header-list__>] [[DeleteColumn]] +[count[]]}}}>\n\n<table class=\"tc-relink-whitelist\"><tbody>\n<tr>\n<$list variable=\"header\" filter=\"[enlist<__header-list__>butlast[]]\"><th><<header>></th></$list>\n<!-- We have the last column extend into the delete/link column, which is unlabeled. -->\n<th colspan=2><$text text={{{ [enlist<__header-list__>last[]] }}} /></th>\n</tr>\n\n<<.make-table Custom \"\" yes>>\n\n<$list\n\tfilter=\"[plugin-type[plugin]![$:/core]![$:/plugins/flibbles/relink]]\">\n<$set name=\"subtitle\" value={{!!description}} emptyValue={{!!title}} >\n<$macrocall $name=\".make-table\" title=<<subtitle>> plugin=<<currentTiddler>> />\n</$set>\n</$list>\n\n<<.make-table Core \"$:/plugins/flibbles/relink\">>\n\n</tbody></table>\n</$vars>\n\\end\n"
},
"$:/plugins/flibbles/relink/ui/configuration/Attributes": {
"title": "$:/plugins/flibbles/relink/ui/configuration/Attributes",
"caption": "{{$:/plugins/flibbles/relink/language/ui/Attributes/Caption}}",
"tags": "$:/tags/flibbles/relink/Configuration",
"text": "\\import $:/plugins/flibbles/relink/ui/components/tables\n\\define prefix-attr() $:/config/flibbles/relink/attributes/\n\\define lingo-base() $:/plugins/flibbles/relink/language/Buttons/\n\\define element-name-tiddler() $:/state/flibbles/relink/element-name\n\\define attribute-name-tiddler() $:/state/flibbles/relink/attribute-name\n\n\\define row()\n<$set name=\"element\"\n filter=\"[<key>splitbefore[/]removesuffix[/]]\">\n<$set name=\"attribute\"\n filter=\"[<key>removeprefix<element>removeprefix[/]]\">\n<td><$text text=<<element>> /></td>\n<td><$text text=<<attribute>> /></td>\n</$set></$set>\n\\end\n\\define body()\n\n{{$:/plugins/flibbles/relink/language/Help/Attributes}}\n\n<em class=\"tc-edit\">Add a new attribute:</em>\n<$edit-text\n\ttiddler=<<element-name-tiddler>>\n\ttag=\"input\"\n\tdefault=\"\"\n\tplaceholder=\"widget/element\" />\n<$edit-text\n\ttiddler=<<attribute-name-tiddler>>\n\ttag=\"input\"\n\tdefault=\"\"\n\tplaceholder=\"attribute\" />\n<$reveal type=\"nomatch\" text=\"\" state=<<element-name-tiddler>> >\n<$reveal type=\"nomatch\" text=\"\" state=<<attribute-name-tiddler>> >\n<$relinkmangler>\n<$button\n\ttooltip={{$(lingo-base)$NewAttribute/Hint}}\n\taria-label={{$(lingo-base)$NewAttribute/Caption}}>\n<$action-sendmessage\n\t$message=\"relink-add-attribute\"\n\telement={{$(element-name-tiddler)$}}\n\tattribute={{$(attribute-name-tiddler)$}} />\n<$action-deletetiddler $tiddler=<<attribute-name-tiddler>> />\n<$action-deletetiddler $tiddler=<<element-name-tiddler>> />\n<$text text={{$(lingo-base)$NewAttribute/Caption}}/>\n</$button>\n</$relinkmangler>\n</$reveal>\n<$reveal type=\"match\" text=\"\" state=<<attribute-name-tiddler>> >\n<$button>\n<$text text={{$(lingo-base)$NewAttribute/Caption}}/>\n</$button>\n</$reveal>\n</$reveal>\n<$reveal type=\"match\" text=\"\" state=<<element-name-tiddler>> >\n<$button>\n<$text text={{$(lingo-base)$NewAttribute/Caption}}/>\n</$button>\n</$reveal>\n\n<$macrocall\n\t$name=tables\n\tcategory=\"attributes\"\n\theader-list=\"[[Widget/HTML Element]] Attribute Type\"\n\tlist-row-macro=\"row\" />\n\\end\n\n<<body>>\n"
},
"$:/plugins/flibbles/relink/ui/configuration/Fields": {
"title": "$:/plugins/flibbles/relink/ui/configuration/Fields",
"caption": "{{$:/plugins/flibbles/relink/language/ui/Fields/Caption}}",
"tags": "$:/tags/flibbles/relink/Configuration",
"text": "\\import $:/plugins/flibbles/relink/ui/components/tables\n\\define lingo-base() $:/plugins/flibbles/relink/language/Buttons/\n\\define field-name-tiddler() $:/state/flibbles/relink/field-name\n\n\\define row()\n<td><$text text=<<key>> /></td>\n\\end\n\\define body()\n\n{{$:/plugins/flibbles/relink/language/Help/Fields}}\n\n<em class=\"tc-edit\">Add a new field:</em>\n<$edit-text\n\ttiddler=<<field-name-tiddler>>\n\ttag=\"input\"\n\tdefault=\"\"\n\tplaceholder=\"field name\" />\n<$reveal type=\"nomatch\" text=\"\" state=<<field-name-tiddler>> >\n<$relinkmangler>\n<$button\n\ttooltip={{$(lingo-base)$NewField/Hint}}\n\taria-label={{$(lingo-base)$NewField/Caption}}>\n<$action-sendmessage\n\t$message=\"relink-add-field\"\n\tfield={{$(field-name-tiddler)$}} />\n<$action-deletetiddler $tiddler=<<field-name-tiddler>> />\n<$text text={{$(lingo-base)$NewField/Caption}}/>\n</$button>\n</$relinkmangler>\n</$reveal>\n<$reveal type=\"match\" text=\"\" state=<<field-name-tiddler>> >\n<$button>\n<$text text={{$(lingo-base)$NewField/Caption}}/>\n</$button>\n</$reveal>\n\n\n<$macrocall\n\t$name=tables\n\tcategory=\"fields\"\n\theader-list=\"[[Field Name]] [[Field Type]]\"\n\tlist-row-macro=\"row\" />\n\\end\n\n<<body>>\n"
},
"$:/plugins/flibbles/relink/ui/configuration/Macros": {
"title": "$:/plugins/flibbles/relink/ui/configuration/Macros",
"caption": "{{$:/plugins/flibbles/relink/language/ui/Macros/Caption}}",
"tags": "$:/tags/flibbles/relink/Configuration",
"text": "\\import $:/plugins/flibbles/relink/ui/components/tables\n\\define prefix-macro() $:/config/flibbles/relink/macros/\n\\define lingo-base() $:/plugins/flibbles/relink/language/Buttons/\n\\define macro-name-tiddler() $:/state/flibbles/relink/macro-name\n\\define parameter-name-tiddler() $:/state/flibbles/relink/parameter-name\n\n\\define row()\n<$set name=\"parameter\"\n filter=\"[<key>relink:splitafter[/]]\">\n<$set name=\"macro\"\n filter=\"[<key>removesuffix<parameter>removesuffix[/]]\">\n<td><$text text=<<macro>> /></td>\n<td><$text text=<<parameter>> /></td>\n</$set></$set>\n\\end\n\\define body()\n\n{{$:/plugins/flibbles/relink/language/Help/Macros}}\n\n<em class=\"tc-edit\">Add a new macro parameter:</em>\n<$edit-text\n\ttiddler=<<macro-name-tiddler>>\n\ttag=\"input\"\n\tdefault=\"\"\n\tplaceholder=\"macro\" />\n<$edit-text\n\ttiddler=<<parameter-name-tiddler>>\n\ttag=\"input\"\n\tdefault=\"\"\n\tplaceholder=\"parameter\" />\n<$reveal type=\"nomatch\" text=\"\" state=<<macro-name-tiddler>> >\n<$reveal type=\"nomatch\" text=\"\" state=<<parameter-name-tiddler>> >\n<$relinkmangler>\n<$button\n\ttooltip={{$(lingo-base)$NewParameter/Hint}}\n\taria-label={{$(lingo-base)$NewParameter/Caption}}>\n<$action-sendmessage\n\t$message=\"relink-add-parameter\"\n\tmacro={{$(macro-name-tiddler)$}}\n\tparameter={{$(parameter-name-tiddler)$}} />\n<$action-deletetiddler $tiddler=<<parameter-name-tiddler>> />\n<$action-deletetiddler $tiddler=<<macro-name-tiddler>> />\n<$text text={{$(lingo-base)$NewParameter/Caption}}/>\n</$button>\n</$relinkmangler>\n</$reveal>\n<$reveal type=\"match\" text=\"\" state=<<parameter-name-tiddler>> >\n<$button>\n<$text text={{$(lingo-base)$NewParameter/Caption}}/>\n</$button>\n</$reveal>\n</$reveal>\n<$reveal type=\"match\" text=\"\" state=<<macro-name-tiddler>> >\n<$button>\n<$text text={{$(lingo-base)$NewParameter/Caption}}/>\n</$button>\n</$reveal>\n\n\n<$macrocall\n\t$name=tables\n\tcategory=\"macros\"\n\theader-list=\"Macro Parameter Type\"\n\tlist-row-macro=\"row\" />\n\\end\n\n<<body>>\n"
},
"$:/plugins/flibbles/relink/ui/configuration/Operators": {
"title": "$:/plugins/flibbles/relink/ui/configuration/Operators",
"caption": "{{$:/plugins/flibbles/relink/language/ui/Operators/Caption}}",
"tags": "$:/tags/flibbles/relink/Configuration",
"text": "\\import $:/plugins/flibbles/relink/ui/components/tables\n\\define lingo-base() $:/plugins/flibbles/relink/language/Buttons/\n\\define operator-name-tiddler() $:/state/flibbles/relink/operator-name\n\n\\define row()\n<td><$text text=<<key>> /></td>\n\\end\n\\define body()\n\n{{$:/plugins/flibbles/relink/language/Help/Operators}}\n\n<em class=\"tc-edit\">Add a new filter operator:</em>\n<$edit-text\n\ttiddler=<<operator-name-tiddler>>\n\ttag=\"input\"\n\tdefault=\"\"\n\tplaceholder=\"operator name\" />\n<$reveal type=\"nomatch\" text=\"\" state=<<operator-name-tiddler>>>\n<$relinkmangler>\n<$button\n\ttooltip={{$(lingo-base)$NewOperator/Hint}}\n\taria-label={{$(lingo-base)$NewOperator/Caption}}>\n<$action-sendmessage\n\t$message=\"relink-add-operator\"\n\toperator={{$(operator-name-tiddler)$}} />\n<$action-deletetiddler $tiddler=<<operator-name-tiddler>> />\n<$text text={{$(lingo-base)$NewOperator/Caption}}/>\n</$button>\n</$relinkmangler>\n</$reveal>\n<$reveal type=\"match\" text=\"\" state=<<operator-name-tiddler>>>\n<$button>\n<$text text={{$(lingo-base)$NewOperator/Caption}}/>\n</$button>\n</$reveal>\n\n<$macrocall\n\t$name=tables\n\tcategory=\"operators\"\n\theader-list=\"[[Filter Operator]] [[Operand Type]]\"\n\tlist-row-macro=\"row\" />\n\\end\n\n<<body>>\n"
},
"$:/plugins/flibbles/relink/ui/stylesheet.css": {
"title": "$:/plugins/flibbles/relink/ui/stylesheet.css",
"text": ".tc-relink-references {\n}\n\n.tc-relink-references-table {\n\twidth: 100%;\n\tborder: none;\n}\n\n.tc-relink-references-table td {\n\tborder-left: none;\n}\n\n.tc-relink-references-table tr:first-child td {\n\tborder-top: none;\n}\n\n.tc-relink-references-title {\n\ttext-align: left;\n\tvertical-align: top;\n}\n\n.tc-relink-references-occurrence {\n\tfont-style: italic;\n\ttext-align: left;\n\tfont-weight: 200;\n\tpadding-left: 25px;\n\tvertical-align: top;\n}\n\n.tc-relink-header-plugin {\n\ttext-align: left;\n}\n\n.tc-relink-header-plugin button {\n\twidth: 100%\n}\n\n.tc-relink-column-type {\n\twidth: 8em;\n}\n\n.tc-relink-column-type select {\n\twidth: 100%;\n}\n\n.tc-relink-column-delete {\n\tborder-left: none;\n\ttext-align: left;\n}\n\n.tc-relink-column-delete button {\n\tpadding-left: 1em;\n}\n\n.tc-relink-impossible a.tc-tiddlylink {\n\tcolor: red;\n}\n",
"tags": "$:/tags/Stylesheet",
"type": "text/css"
}
}
}
{
"tiddlers": {
"$:/plugins/flibbles/relink/js/fieldtypes/markdown.js": {
"title": "$:/plugins/flibbles/relink/js/fieldtypes/markdown.js",
"text": "/*\\\nmodule-type: relinkfieldtype\ntitle: $:/plugins/flibbles/relink/js/fieldtypes/markdown.js\ntype: application/javascript\n\nThis relinks tiddlers which contain markdown. It tries to be agnostic to\nwhichever markdown plugin you're using.\n\n\\*/\n\nvar Rebuilder = require(\"$:/plugins/flibbles/relink/js/utils/rebuilder.js\");\nvar wikitextHandler = require(\"$:/plugins/flibbles/relink/js/utils.js\").getType('wikitext');\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils/markdown.js\");\nvar WikiParser = require(\"$:/core/modules/parsers/wikiparser/wikiparser.js\")['text/vnd.tiddlywiki'];\n\nfunction MarkdownWalker(text, options) {\n\tthis.wiki = options.wiki;\n\tthis.options = Object.create(options);\n\tthis.options.macrodefCanBeDisabled = true;\n\tif(!this.mdInlineRuleClasses) {\n\t\tMarkdownWalker.prototype.mdInlineRuleClasses = $tw.modules.createClassesFromModules(\"relinkmarkdownrule\",\"inline\",$tw.MarkdownRuleBase);\n\t}\n\tif(!this.mdBlockRuleClasses) {\n\t\tMarkdownWalker.prototype.mdBlockRuleClasses = $tw.modules.createClassesFromModules(\"relinkmarkdownrule\",\"block\",$tw.MarkdownRuleBase);\n\t}\n\tthis.source = text || \"\";\n\tthis.sourceLength = this.source.length;\n\t// Set current parse position\n\tthis.pos = 0;\n\t// Instantiate the parser block and inline rules\n\tthis.blockRules = this.instantiateRules(this.mdBlockRuleClasses,\"block\",0);\n\tthis.inlineRules = this.instantiateRules(this.mdInlineRuleClasses,\"inline\",0);\n\t// instantiateRules first with indent==undefined so we can match regardless\n\t// of tabdepth. Now we need to be strict about it.\n\tthis.indent = 0;\n\tthis.parseBlocks();\n};\n\nMarkdownWalker.prototype = Object.create(WikiParser.prototype);\n\nmodule.exports\n\nMarkdownWalker.prototype.parseBlock = function(terminatorRegExpString) {\n\tvar terminatorRegExp = /([^\\S\\n]*\\r?\\n)/mg;\n\tthis.skipEmptyLines();\n\tif(this.pos >= this.sourceLength) {\n\t\treturn [];\n\t}\n\t// Look for a block rule that applies at the current position\n\tvar nextMatch = this.findNextMatch(this.blockRules, this.pos);\n\tif(nextMatch && nextMatch.matchIndex === this.pos) {\n\t\treturn this.handleRule(nextMatch);\n\t}\n\treturn this.parseInlineRun(terminatorRegExp);\n};\n\nMarkdownWalker.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {\n\toptions = options || {};\n\tvar tree = [];\n\t// Find the next occurrence of the terminator\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\t// Find the next occurrence of a inlinerule\n\tvar inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && (terminatorMatch || inlineRuleMatch)) {\n\t\t// Return if we've found the terminator, and it precedes any inline rule match\n\t\tif(terminatorMatch) {\n\t\t\tif(!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {\n\t\t\t\tthis.handleWikitext(this.pos, terminatorMatch.index);\n\t\t\t\t//if(options.eatTerminator) {\n\t\t\t\t\tthis.pos += terminatorMatch[0].length;\n\t\t\t\t//}\n\t\t\t\treturn tree;\n\t\t\t}\n\t\t}\n\t\t// Process any inline rule, along with the text preceding it\n\t\tif(inlineRuleMatch) {\n\t\t\t// Preceding text\n\t\t\tthis.handleWikitext(this.pos, inlineRuleMatch.matchIndex);\n\t\t\tthis.handleRule(inlineRuleMatch);\n\t\t\t// Look for the next inline rule\n\t\t\tinlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t\t\t// Look for the next terminator match\n\t\t\tterminatorRegExp.lastIndex = this.pos;\n\t\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\t}\n\t}\n\t// Process the remaining text\n\tthis.handleWikitext(this.pos, this.sourceLength);\n\treturn tree;\n};\n\nMarkdownWalker.prototype.skipEmptyLines = function() {\n\tvar emptyRegExp = /(?:[^\\S\\n]*\\n)+/mg;\n\temptyRegExp.lastIndex = this.pos;\n\tvar emptyMatch = emptyRegExp.exec(this.source);\n\tif(emptyMatch && emptyMatch.index === this.pos) {\n\t\tthis.pos = emptyRegExp.lastIndex;\n\t}\n};\n\nfunction MarkdownReporter(text, callback, options) {\n\tthis.callback = callback;\n\tMarkdownWalker.call(this, text, options);\n};\n\nMarkdownReporter.prototype = Object.create(MarkdownWalker.prototype);\n\nMarkdownReporter.prototype.handleRule = function(ruleInfo) {\n\tif (ruleInfo.rule.report) {\n\t\truleInfo.rule.report(this.source, this.callback, this.options);\n\t} else {\n\t\tif (ruleInfo.rule.matchRegExp !== undefined) {\n\t\t\tthis.pos = ruleInfo.rule.matchRegExp.lastIndex;\n\t\t} else {\n\t\t\t// We can't easily determine the end of this\n\t\t\t// rule match. We'll \"parse\" it so that\n\t\t\t// parser.pos gets updated, but we throw away\n\t\t\t// the results.\n\t\t\truleInfo.rule.parse();\n\t\t}\n\t}\n};\n\nMarkdownReporter.prototype.handleWikitext = function(startPos, end) {\n\tif (startPos < end) {\n\t\tvar config = utils.getSettings(this.wiki);\n\t\tif (config.wikitext) {\n\t\t\tvar substr = this.source.substring(this.pos, end);\n\n\t\t\tvar pragma = config.wikitextPragma;\n\t\t\tvar wikiEntry = wikitextHandler.report(pragma + substr, this.callback, this.options);\n\t\t}\n\t}\n\tthis.pos = end;\n};\n\nexports.report = function(markdowntext, callback, options) {\n\tnew MarkdownReporter(markdowntext, callback, options);\n};\n\nfunction MarkdownRelinker(text, fromTitle, toTitle, options) {\n\tthis.fromTitle = fromTitle;\n\tthis.toTitle = toTitle;\n\tthis.builder = new Rebuilder(text);\n\tMarkdownWalker.call(this, text, options);\n};\n\nMarkdownRelinker.prototype = Object.create(MarkdownWalker.prototype);\n\nMarkdownRelinker.prototype.handleRule = function(ruleInfo) {\n\tvar newEntry = ruleInfo.rule.relink(this.source, this.fromTitle, this.toTitle, this.options);\n\tif (newEntry !== undefined) {\n\t\tif (newEntry.impossible) {\n\t\t\tthis.impossible = true;\n\t\t}\n\t\tif (newEntry.output) {\n\t\t\tthis.builder.add(newEntry.output, ruleInfo.matchIndex, this.pos);\n\t\t}\n\t}\n};\n\nMarkdownRelinker.prototype.handleWikitext = function(startPos, end) {\n\tif (startPos < end) {\n\t\tvar config = utils.getSettings(this.wiki);\n\t\tif (config.wikitext) {\n\t\t\tvar substr = this.source.substring(this.pos, end);\n\n\t\t\tvar pragma = config.wikitextPragma;\n\t\t\tvar wikiEntry = wikitextHandler.relink(pragma + substr, this.fromTitle, this.toTitle, this.options);\n\t\t\tif (wikiEntry != undefined) {\n\t\t\t\tif (wikiEntry.impossible) {\n\t\t\t\t\tthis.impossible = true;\n\t\t\t\t}\n\t\t\t\tif (wikiEntry.output) {\n\t\t\t\t\tthis.builder.add(wikiEntry.output.slice(pragma.length), startPos, end);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tthis.pos = end;\n};\n\nexports.name = \"markdown\";\n\nexports.relink = function(markdowntext, fromTitle, toTitle, options) {\n\tvar relinker = new MarkdownRelinker(markdowntext, fromTitle, toTitle, options),\n\t\tentry;\n\tif (relinker.builder.changed() || relinker.impossible) {\n\t\tentry = {\n\t\t\toutput: relinker.builder.results(),\n\t\t\timpossible: relinker.impossible };\n\t}\n\treturn entry;\n};\n",
"module-type": "relinkfieldtype",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/codeblock.js": {
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/codeblock.js",
"text": "/*\\\nmodule-type: relinkmarkdownrule\ntitle: $:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/codeblock.js\ntype: application/javascript\n\n```javascript\ncode\n```\n\n\\*/\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils/markdown\");\n\nexports.name = \"codeblock\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /(```+)[^\\n`]*(?:\\n|$)/mg;\n\tthis.maxIndent = 3;\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar endRegExp = new RegExp(\"^ {0,3}\" + this.match[1] + \"+[^\\\\S\\\\n]*\\\\n\", \"mg\");\n\tendRegExp.lastIndex = this.matchRegExp.lastIndex;\n\tvar endMatch = endRegExp.exec(this.parser.source);\n\tif (endMatch) {\n\t\tthis.parser.pos = endRegExp.lastIndex;\n\t} else {\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\treturn undefined;\n};\n\nexports.report = exports.relink;\n",
"module-type": "relinkmarkdownrule",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/codeinline.js": {
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/codeinline.js",
"text": "/*\\\nmodule-type: relinkmarkdownrule\ntitle: $:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/codeinline.js\ntype: application/javascript\n\nHandles markdown `code` and ``code``.\n\n\\*/\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils/markdown\");\n\nexports.name = \"codeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\tvar match, matchRegExp = /`+/mg;\n\tmatchRegExp.lastIndex = startPos;\n\twhile (match = matchRegExp.exec(this.parser.source)) {\n\t\tvar next = this.parser.source.indexOf(match[0], matchRegExp.lastIndex);\n\t\t// make sure we find the corresponding ticks\n\t\tif (next >= 0) {\n\t\t\t// Make sure it's the right length\n\t\t\tvar end = next + match[0].length;\n\t\t\tif (match[0].length < 3 || !isLineStart(this.parser.source, next)) {\n\t\t\t\tif (this.parser.source.charAt(end) !== '`') {\n\t\t\t\t\t// make sure there aren't paragraph breaks between the points\n\t\t\t\t\tvar nextGraph = utils.indexOfParagraph(this.parser.source, matchRegExp.lastIndex);\n\t\t\t\t\tif (nextGraph < 0 || nextGraph > next) {\n\t\t\t\t\t\tthis.end = end;\n\t\t\t\t\t\treturn match.index;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n};\n\nfunction isLineStart(text, pos) {\n\t// if 3 or less spaces precede it, it's a line start.\n\tvar p = text.lastIndexOf('\\n', pos);\n\tif (pos - p > 3) {\n\t\treturn false;\n\t}\n\twhile (++p < pos) {\n\t\tif (text.charAt(p) !== ' ') {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n};\n\nexports.relink = function() {\n\tthis.parser.pos = this.end;\n\treturn undefined;\n};\n\nexports.report = exports.relink;\n",
"module-type": "relinkmarkdownrule",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/footnote.js": {
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/footnote.js",
"text": "/*\\\nmodule-type: relinkmarkdownrule\ntitle: $:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/footnote.js\ntype: application/javascript\n\nHandles markdown footnotes\n\n[1]: #link\n\n\\*/\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils/markdown\");\n\nexports.name = \"markdownfootnote\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /\\[((?:[^\\\\\\]]|\\\\.)*)\\]:(\\s*)(#?)(\\S+)([^\\S\\n]*(?:\\n|$))/mg;\n\tthis.maxIndent = 3;\n};\n\nexports.report = function(text, callback, options) {\n\tvar m = this.match,\n\t\tlink = decodeURIComponent(m[4]),\n\t\tentry;\n\tthis.parser.pos = m.index + m[0].length;\n\tif (m[1].charAt(0) !== \"^\"\n\t && (m[3] === \"#\" || options.wiki.isImageTiddler(link))) {\n\t\tcallback(link, '[' + utils.abridge(m[1]) + ']:');\n\t}\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar m = this.match,\n\t\tlink = m[4],\n\t\tentry;\n\tthis.parser.pos = m.index + m[0].length;\n\tif (m[1].charAt(0) !== \"^\"\n\t && (m[3] === \"#\" || options.wiki.isImageTiddler(toTitle))\n\t && decodeURIComponent(link) === fromTitle) {\n\t\tentry = { output: this.indentString + \"[\" + m[1] + \"]:\" + m[2] + m[3] + utils.encodeLink(toTitle) + m[5] };\n\t}\n\treturn entry;\n};\n",
"module-type": "relinkmarkdownrule",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/link.js": {
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/link.js",
"text": "/*\\\nmodule-type: relinkmarkdownrule\ntitle: $:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/link.js\ntype: application/javascript\n\nHandles markdown links\n\n[caption](#link)\n\n\\*/\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils/markdown\");\nvar markdown = require(\"$:/plugins/flibbles/relink/js/utils\").getType('markdown');\n\nexports.name = \"markdownlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.endMatch = this.matchLink(this.parser.source, startPos);\n\treturn this.endMatch ? this.endMatch.index : undefined;\n};\n\n/**A zero side-effect method which returns a regexp which pretended to match\n * the whole link, caption and all. I do this instead of just using a\n * regexp to begin with, because markdown links require context-free grammar\n * matching.\n * Currently, it doesn't properly set match[0]. No need as of yet.\n * 1. \"!\"\n * 2. caption\n * 3. \"\\s*#?\"\n * 4. \"link\"\n * 5. \"\\s*'tooltip'\"\n */\nexports.matchLink = function(text, pos) {\n\tpos = pos-1;\n\tvar match = undefined;\n\tdo {\n\t\tpos = text.indexOf('[', pos+1);\n\t\tif (pos < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tvar caption = this.getEnclosed(text, pos, '[', ']');\n\t\tif (caption === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tvar linkStart = pos + caption.length+2;\n\t\tif (text.charAt(linkStart) !== '(') {\n\t\t\tcontinue;\n\t\t}\n\t\t// match[1] and match[2] are the \"!\" and \"caption\", filled in later.\n\t\tvar regExp = /\\(()()(\\s*#?)((?:[^\\s\\(\\)]|\\([^\\s\\(\\)]*\\))+)((?:\\s+(?:'(?:[^'\\\\]|\\\\.)*'|\"(?:[^\"\\\\]|\\\\.)*\"|\\([^)]*\\)))?\\s*)\\)/g;\n\t\tregExp.lastIndex = linkStart;\n\t\tmatch = regExp.exec(text);\n\t\tif (match && match.index === linkStart && utils.indexOfParagraph(match[0]) < 0) {\n\t\t\tmatch[2] = caption;\n\t\t\tif (text.charAt(pos-1) === \"!\") {\n\t\t\t\tmatch.index = pos-1;\n\t\t\t\tmatch[1] = \"!\";\n\t\t\t} else {\n\t\t\t\tmatch.index = pos;\n\t\t\t}\n\t\t} else {\n\t\t\tmatch = undefined;\n\t\t}\n\t} while (!match);\n\treturn match;\n};\n\nexports.report = function(text, callback, options) {\n\tvar em = this.endMatch,\n\t\tcaption = em[2],\n\t\tprefix = em[1],\n\t\tisImage = (prefix === '!'),\n\t\tlink = em[4],\n\t\thash = '#';\n\tif (prefix) {\n\t\thash = '';\n\t}\n\tthis.parser.pos = em.index + em[1].length + caption.length + em[0].length + 2;\n\tif (!isImage) {\n\t\tmarkdown.report(caption, function(title, blurb) {\n\t\t\tcallback(title, prefix + '[' + (blurb || '') + '](' + hash + link + ')');\n\t\t}, options);\n\t}\n\tif (isImage !== (em[3].lastIndexOf('#') >= 0)) {\n\t\tvar safeCaption = utils.abridge(caption);\n\t\ttry {\n\t\t\tcallback(decodeURIComponent(link), em[1] + '[' + safeCaption + '](' + hash + ')');\n\t\t} catch (e) {\n\t\t\t// It must be a malformed link. Not our problem.\n\t\t\t// Just move on.\n\t\t}\n\t}\n};\n\nexports.relink = function(text, fromTitle, toTitle, options) {\n\tvar entry = {},\n\t\tem = this.endMatch,\n\t\tmodified = false,\n\t\tcaption = em[2],\n\t\tisImage = (em[1] === '!'),\n\t\tlink = em[4];\n\tthis.parser.pos = em.index + em[1].length + caption.length + em[0].length + 2;\n\tif (!isImage) {\n\t\tvar newCaption = markdown.relink(caption, fromTitle, toTitle, options);\n\t\tif (newCaption) {\n\t\t\tif (newCaption.output) {\n\t\t\t\tif (this.canBeCaption(newCaption.output)) {\n\t\t\t\t\tcaption = newCaption.output;\n\t\t\t\t\tmodified = true;\n\t\t\t\t} else {\n\t\t\t\t\tentry.impossible = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (newCaption.impossible) {\n\t\t\t\tentry.impossible = true;\n\t\t\t}\n\t\t}\n\t}\n\t// I don't know why internal images links don't use the '#', but links\n\t// do, but that's just how it is.\n\tif (isImage !== (em[3].lastIndexOf('#') >=0)) {\n\t\ttry {\n\t\t\tif (decodeURIComponent(link) === fromTitle) {\n\t\t\t\tlink = utils.encodeLink(toTitle);\n\t\t\t\tmodified = true;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t// It must be a malformed link. Not our problem.\n\t\t\t// Keep going in case the caption needs relinking.\n\t\t}\n\t}\n\tif (modified) {\n\t\t// This way preserves whitespace\n\t\tentry.output = em[1]+\"[\"+caption+\"](\"+em[3]+link+em[5]+\")\";\n\t}\n\tif (modified || entry.impossible) {\n\t\treturn entry;\n\t}\n\treturn undefined;\n};\n\nexports.canBeCaption = function(caption) {\n\treturn this.indexOfClose(caption+']', -1, '[', ']') === caption.length;\n};\n\nexports.getEnclosed = function(text, pos, openChar, closeChar) {\n\tvar capEnd = this.indexOfClose(text, pos, openChar, closeChar);\n\tif (capEnd < 0) {\n\t\treturn undefined;\n\t}\n\tvar enclosed = text.substring(pos+1, capEnd);\n\tif (enclosed.match(/\\n\\s*\\n/)) {\n\t\t// Paragraph breaks are not allowed\n\t\treturn undefined;\n\t}\n\treturn enclosed;\n};\n\nexports.indexOfClose = function(text, pos, openChar, closeChar) {\n\tvar close = pos-1,\n\t\topen = pos; // First char is open\n\tdo {\n\t\tclose = text.indexOf(closeChar, close+1);\n\t\tif (close < 0) {\n\t\t\treturn -1;\n\t\t}\n\t\topen = text.indexOf(openChar, open+1);\n\t} while (open >= 0 && open <= close);\n\treturn close;\n};\n",
"module-type": "relinkmarkdownrule",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/markdownrulebase.js": {
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/markdownrulebase.js",
"text": "/*\\\ntitle: $:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext/markdownrulebase.js\ntype: application/javascript\nmodule-type: global\n\nBase class for markdown parser rules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar utils = require(\"$:/plugins/flibbles/relink/js/utils/markdown\");\n\nvar MarkdownRuleBase = function() {};\n\nMarkdownRuleBase.prototype.init = function(parser) {\n\tthis.parser = parser;\n};\n\nMarkdownRuleBase.prototype.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\twhile (this.match = this.matchRegExp.exec(this.parser.source)) {\n\t\tif (utils.indexOfParagraph(this.match[0]) >= 0) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (this.maxIndent !== undefined) {\n\t\t\tvar indent = utils.indentation(this.parser.source,this.match.index);\n\t\t\tif (indent < 0\n\t\t\t || (this.parser.indent !== undefined\n\t\t\t && (indent > this.parser.indent + this.maxIndent))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar nl = this.parser.source.lastIndexOf('\\n', this.match.index-1)+1;\n\t\t\tthis.indentString = this.parser.source.substring(nl, this.match.index);\n\t\t\treturn nl < startPos ? startPos : nl;\n\t\t}\n\t\treturn this.match.index;\n\t}\n\treturn undefined;\n};\n\n\nexports.MarkdownRuleBase = MarkdownRuleBase;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext.js": {
"title": "$:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext.js",
"text": "/*\\\nmodule-type: relinktextoperator\ntitle: $:/plugins/flibbles/relink/js/relinkoperations/text/markdowntext.js\ntype: application/javascript\n\nThis relinks tiddlers which contain markdown. It tries to be agnostic to\nwhichever markdown plugin you're using.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Placeholder = require(\"$:/plugins/flibbles/relink/js/utils/placeholder.js\");\nvar markdownHandler = require('$:/plugins/flibbles/relink/js/utils.js').getType('markdown');\n\nexports.type = \"text/x-markdown\";\n\nexports.report = function(tiddler, callback, options) {\n\tmarkdownHandler.report(tiddler.fields.text, callback, options);\n};\n\nexports.relink = function(tiddler, fromTitle, toTitle, options) {\n\tvar placeholder = new Placeholder();\n\tvar extraOptions = $tw.utils.extend(\n\t\t{\n\t\t\tplaceholder: placeholder\n\t\t}, options);\n\tvar entry = markdownHandler.relink(tiddler.fields.text, fromTitle, toTitle, extraOptions);\n\tif (entry && entry.output) {\n\t\t// If there's output, we've also got to prepend any macros\n\t\t// that the placeholder defined.\n\t\tvar preamble = placeholder.getPreamble();\n\t\tentry.output = preamble + entry.output\n\t}\n\treturn entry;\n};\n",
"module-type": "relinktextoperator",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink/js/utils/markdown.js": {
"title": "$:/plugins/flibbles/relink/js/utils/markdown.js",
"text": "/*\\\nmodule-type: library\ntitle: $:/plugins/flibbles/relink/js/utils/markdown.js\ntype: application/javascript\n\nMethods used in markdown parsing.\n\n\\*/\n\n// tiddlywiki/markdown can't handle having these characters escaped, so we\n// need to unescape them.\nvar problemChars = {\n\t\"23\": \"#\",\n\t\"24\": \"$\",\n\t\"26\": \"&\",\n\t\"2B\": \"+\",\n\t\"2C\": \",\",\n\t\"2F\": \"/\",\n\t\"3A\": \":\",\n\t\"3B\": \";\",\n\t\"3D\": \"=\",\n\t\"3F\": \"?\",\n\t\"40\": \"@\",\n};\n\nexports.encodeLink = function(title) {\n\tvar encoded = encodeURIComponent(title),\n\t\tbalance = 0;\n\tencoded = encoded.replace(/[\\(\\)]/g, function(p) {\n\t\tif (p === '(') {\n\t\t\tif (balance >=1) {\n\t\t\t\treturn '%28';\n\t\t\t} else {\n\t\t\t\tbalance++;\n\t\t\t}\n\t\t} else {\n\t\t\tif (balance <= 0) {\n\t\t\t\treturn '%29';\n\t\t\t}\n\t\t\tbalance--;\n\t\t}\n\t\treturn p;\n\t});\n\twhile (balance--) {\n\t\tvar i = encoded.lastIndexOf('(');\n\t\tencoded = encoded.substr(0, i) + '%28' + encoded.substr(i+1);\n\t}\n\t// tiddlywiki/markdown can't handle these characters escaped\n\treturn encoded.replace(/%([0-9A-F]{2})/g, function(str, code) {\n\t\treturn problemChars[code] || str;\n\t});\n};\n\n// Returns index of next paragraph, or -1\nexports.indexOfParagraph = function(text, startPos) {\n\tvar regExp = /\\n\\s*\\n/mg;\n\tregExp.lastIndex = startPos || 0;\n\tvar match = regExp.exec(text);\n\treturn match ? regExp.lastIndex : -1;\n};\n\n/** Returns how much indentation there is between pos and the previous\n * newline (or other char).\n * tabs are counted as 4 chars.\n */\nexports.indentation = function(text, pos, startChar) {\n\tvar p = text.lastIndexOf(startChar || '\\n', pos-1);\n\tvar count = 0;\n\twhile (++p < pos) {\n\t\tvar c = text.charAt(p);\n\t\tif (c === ' ') {\n\t\t\tcount++;\n\t\t} else if (c === '\\t') {\n\t\t\tcount = count + 4 - (count%4);\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn count;\n};\n\n\nexports.getSettings = function(wiki) {\n\t// Stored here so it's only calculated once, but also so it's different\n\t// per tiddler for testing\n\tif (wiki._markdownSettings === undefined) {\n\t\tvar settings = Object.create(null);\n\t\tvar text = wiki.getTiddlerText(\"$:/config/markdown/renderWikiText\");\n\t\tsettings.wikitext = (text === undefined || text.toLowerCase() === \"true\");\n\t\ttext = wiki.getTiddlerText(\"$:/config/markdown/renderWikiTextPragma\");\n\t\tif (text) {\n\t\t\ttext = text.trim() + '\\n';\n\t\t} else {\n\t\t\ttext = '';\n\t\t}\n\t\tsettings.wikitextPragma = text;\n\t\twiki._markdownSettings = settings;\n\t}\n\treturn wiki._markdownSettings;\n};\n\n// This is the maximum length a reported caption may be\nexports.captionLength = 15;\n\n/** Abridges a string to one that is more log-friendly.\n */\nexports.abridge = function(string) {\n\tvar safe = string.replace(/\\s+/mg, ' ');\n\tif (safe.length > this.captionLength) {\n\t\tsafe = safe.substr(0, this.captionLength) + \"...\";\n\t}\n\treturn safe;\n};\n\n/**I don't actually use this, but I've kept the code around anyway.\n * The only time this plugin is installed and markdown isn't enabled would\n * be if the user forgot to install a markdown plugin, or they disabled it.\n * I GUESS Relink should still be Relinking markdown in that case.\n */\nexports.markdownEnabled = function() {\n\tif (_enabled === undefined) {\n\t\tvar test = $tw.wiki.renderText(\"text/html\", \"text/x-markdown\", \"[test](#test)\");\n\t\t_enabled = (test.indexOf(\"<a\") >= 0);\n\t}\n\treturn _enabled;\n};\nvar _enabled;\n",
"module-type": "library",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink-markdown/readme": {
"title": "$:/plugins/flibbles/relink-markdown/readme",
"text": "Markdown support for Relink.\n\n...or Relink support for Markdown.\n\nThis supplimental plugin allows ''text/x-markdown'' files to be relinked. This means markdown linking syntax like `[Caption](#MyTiddler)` is supported. If your markdown supports wikitext markup as well, this will handle that too.\n\nThis plugin is designed for `tiddlywiki/markdown`, but it will also work for `anstosa/tw5-markdown` and others.\n"
}
}
}
{
"tiddlers": {
"$:/plugins/flibbles/relink-titles/configuration": {
"title": "$:/plugins/flibbles/relink-titles/configuration",
"caption": "{{$:/plugins/flibbles/relink-titles/language/Caption}}",
"tags": "$:/tags/flibbles/relink/Configuration",
"text": "\\define lingo-base() $:/plugins/flibbles/relink-titles/language/\n\\define prefix() $:/config/flibbles/relink-titles/relink/\n\n<<lingo Help>>\n\n<table>\n<tbody>\n<$list filter=\"[[relinktitlesrule]modules[]]\">\n<tr>\n<td>\n<$checkbox\n\ttiddler={{{ [all[current]addprefix<prefix>] }}}\n\tfield=\"text\"\n\tchecked=\"enabled\"\n\tunchecked=\"disabled\"\n\tdefault=\"enabled\"\n> ''{{!!caption}}''</$checkbox></td><td>\n\n<$transclude field='description' />\n\n</td></tr></$list>\n</tbody></table>\n"
},
"$:/plugins/flibbles/relink-titles/language/Caption": {
"title": "$:/plugins/flibbles/relink-titles/language/Caption",
"text": "Titles"
},
"$:/plugins/flibbles/relink-titles/language/Directory/Caption": {
"title": "$:/plugins/flibbles/relink-titles/language/Directory/Caption",
"text": "Rename subdirectories"
},
"$:/plugins/flibbles/relink-titles/language/Directory/Description": {
"title": "$:/plugins/flibbles/relink-titles/language/Directory/Description",
"text": "For wikis set up hierarchically using `/`, like a filesystem. This option will update all tiddlers nested inside the target tiddler. i.e. `fromTiddler/path/file` becomes `toTiddler/path/file`."
},
"$:/plugins/flibbles/relink-titles/language/Help": {
"title": "$:/plugins/flibbles/relink-titles/language/Help",
"text": "See the <a href={{{ [{$:/plugins/flibbles/relink-titles!!demo}addsuffix[#Plugins/Titles]] }}}>//Relink-titles// documentation page</a> for details."
},
"$:/plugins/flibbles/relink-titles/readme": {
"title": "$:/plugins/flibbles/relink-titles/readme",
"text": "Highly customizable relinking of tiddler titles //related// to the renamed tiddler.\n\n* Rename a hierarchy of subtiddlers when renaming a root tiddler.\n* Make custom filter rules to rename other tiddlers the way you want when Relinking.\n* Integrates with other plugins for plugin-specific rules.\n\nSee <a href={{$:/plugins/flibbles/relink-titles!!source}}>the tw5-relink website</a> for more details and examples.\n\n{{$:/core/images/warning}} ''Warning:'' You must use //Relink// v1.10.2 or greater with this, or this plugin may delete some tiddler bodies while trying to relink titles.\n"
},
"$:/plugins/flibbles/relink-titles/relinkoperations/title.js": {
"title": "$:/plugins/flibbles/relink-titles/relinkoperations/title.js",
"text": "/*\\\nmodule-type: relinkoperator\ntitle: $:/plugins/flibbles/relink-titles/relinkoperations/title.js\ntype: application/javascript\n\nRenames tiddlers which have titles derived from fromTitle. Then it makes\nsure that those tiddlers are properly relinked too.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar configPrefix = \"$:/config/flibbles/relink-titles/relink/\";\nvar utils = require('$:/plugins/flibbles/relink/js/utils.js');\nutils.getContext('whitelist').hotDirectories.push(configPrefix);\n\nvar titleRules = Object.create(null);\n$tw.modules.forEachModuleOfType('relinktitlesrule', function(title, module) {\n\ttitleRules[title] = module;\n});\n\nexports.name = 'title';\n\nexports.report = function(tiddler, callback, options) {\n\tvar cache = getCache(options),\n\t\trules = cache.rules;\n\tfor (var i = 0; i < rules.length; i++) {\n\t\trules[i].report(tiddler.fields.title, function(title, blurb) {\n\t\t\tcallback(title, blurb ? ('title: ' + blurb) : 'title');\n\t\t}, options);\n\t}\n};\n\nexports.relink = function(tiddler, fromTitle, toTitle, changes, options) {\n\tvar cache = getCache(options),\n\t\ttitle = tiddler.fields.title;\n\tif (!cache.touched[title]) {\n\t\tvar rules = cache.rules;\n\t\tfor (var i = 0; i < rules.length; i++) {\n\t\t\tvar rule = rules[i];\n\t\t\tvar entry = rule.relink(title, fromTitle, toTitle, options);\n\t\t\tif (entry) {\n\t\t\t\tvar result = entry.output;\n\t\t\t\tif (result && (result !== title)) {\n\t\t\t\t\tif (options.wiki.getTiddler(result) || cache.touched[result]) {\n\t\t\t\t\t\t// There's already a tiddler there. We won't clobber it.\n\t\t\t\t\t\tentry.impossible = true;\n\t\t\t\t\t\tentry.output = undefined;\n\t\t\t\t\t}\n\t\t\t\t\tcache.touched[result] = true;\n\t\t\t\t}\n\t\t\t\t// Record that we've touched this one, so we only touch it once.\n\t\t\t\t// Both its prior and latter. Neither should be touched again.\n\t\t\t\tcache.touched[title] = true;\n\t\t\t\tchanges.title = entry;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n};\n\nfunction getCache(options) {\n\treturn utils.getCacheForRun(options, 'titles', function() {\n\t\treturn {\n\t\t\trules: getRules(options.wiki),\n\t\t\ttouched: Object.create(null)\n\t\t};\n\t});\n};\n\nfunction getRules(wiki) {\n\tvar activeRules = [];\n\tfor (var rule in titleRules) {\n\t\tvar configTiddler = wiki.getTiddler(configPrefix + rule);\n\t\tif (!configTiddler || configTiddler.fields.text !== \"disabled\") {\n\t\t\tactiveRules.push(titleRules[rule]);\n\t\t}\n\t}\n\treturn activeRules;\n};\n",
"module-type": "relinkoperator",
"type": "application/javascript"
},
"$:/plugins/flibbles/relink-titles/rules/directory": {
"title": "$:/plugins/flibbles/relink-titles/rules/directory",
"text": "/*\\\ncaption: {{$:/plugins/flibbles/relink-titles/language/Directory/Caption}}\ndescription: {{$:/plugins/flibbles/relink-titles/language/Directory/Description}}\nmodule-type: relinktitlesrule\ntitle: $:/plugins/flibbles/relink-titles/rules/directory\ntype: application/javascript\n\nHandles subdirectory renaming.\n\n\\*/\n\n/*jslint node: false, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = 'directory';\n\n/**The report returns all parent directories of a given title which exist.\n */\nexports.report = function(title, callback, options) {\n\tvar index = -1;\n\twhile ((index = title.indexOf('/', index+1)) >= 0) {\n\t\tvar dir = title.substr(0, index);\n\t\tcallback(dir, '.' + title.substr(index));\n\t}\n};\n\n/**The relink returns the new title (if any) derived from title for a given\n * rename of fromTitle to toTitle.\n */\nexports.relink = function(title, fromTitle, toTitle, options) {\n\tvar length = fromTitle.length;\n\tif (title.charAt(length) === '/' && title.substr(0, length) === fromTitle) {\n\t\treturn {output: toTitle + title.substr(length)};\n\t}\n\treturn undefined;\n};\n",
"caption": "{{$:/plugins/flibbles/relink-titles/language/Directory/Caption}}",
"description": "{{$:/plugins/flibbles/relink-titles/language/Directory/Description}}",
"module-type": "relinktitlesrule",
"type": "application/javascript"
}
}
}
{
"tiddlers": {
"$:/plugins/snowgoon88/edit-comptext/config": {
"title": "$:/plugins/snowgoon88/edit-comptext/config",
"type": "application/json",
"text": "{\n \"configuration\": {\n \"caseSensitive\" : false,\n \"maxMatch\" : 8,\n \"minPatLength\" : 2,\n \"triggerKeyCombination\" : \"^ \"\n },\n \"template\": [{\n \"pattern\": \"[[\",\n \"filter\": \"[all[tiddlers]!is[system]]\",\n \"start\": \"[[\",\n \"end\": \"]]\"\n }\n ]\n}\n"
},
"$:/plugins/snowgoon88/edit-comptext/edit-comptext.js": {
"title": "$:/plugins/snowgoon88/edit-comptext/edit-comptext.js",
"text": "/*\\\ntitle: $:/plugins/snowgoon88/edit-comptext/edit-comptext.js\ntype: application/javascript\nmodule-type: widget\n\nTaken from original Edit-text widget\nVersion 5.1.13 of TW5\nAdd link-to-tiddler completion in framed.js and simple.js\n\nTODO : CHECK usefull, and particularly save_changes after every input ??\nTODO : where should popupNode be created in the DOM ?\nTODO : check that options are valid (numeric ?)\nvar isNumeric = function(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n};\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar editTextWidgetFactory = require(\"$:/core/modules/editor/factory.js\").editTextWidgetFactory,\n\tFramedCompEngine = require(\"$:/plugins/snowgoon88/edit-comptext/framed.js\").FramedCompEngine,\n\tSimpleCompEngine = require(\"$:/plugins/snowgoon88/edit-comptext/simple.js\").SimpleCompEngine;\n\nexports[\"edit-comptext\"] = editTextWidgetFactory(FramedCompEngine,SimpleCompEngine);\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/plugins/snowgoon88/edit-comptext/examples": {
"title": "$:/plugins/snowgoon88/edit-comptext/examples",
"text": "The configuration file [[$:/plugins/snowgoon88/edit-comptext/config]] allow you to use the completion plugin for various usages. Here are some examples...\n\n!! Link Completion\nThe basic and default usage. Completion is triggered by `[[`, the search is among all non-system tiddlers. When selected, the `title` of the tiddler is inserted in the text, surrounded by `[[` and `]]`. This gives the following Completion Template.\n\n\n```\n{\n \"pattern\": \"[[\",\n \"title\": \"[all[tiddlers]!is[system]]\",\n \"start\": \"[[\",\n \"end\": \"]]\"\n}\t \n```\n\n\n!! Special macro completion\nI have a 'pnjin' macro that is invoked by `<<pnjin \"TiddlerPNJName\">>` where 'TiddlerPNJName is a tiddler that hold data about a PNJ. I use tiddlywiki to organise my Role Playing Games campaigns. So, I want `<p` to trigger the completion. The search is among all non-system tiddlers tagged `PNJ` and, once selected, the title of the tiddler must be inserted surrouned by `<<pnjin \\\"` and `\\\">>`. So...\n\n```\n{\n\t\"pattern\": \"<p\",\n \t\"title\": \"[tag[PNJ]!is[system]]\",\n \t\"start\": \"<<pnjin \\\"\",\n \t\"end\": \"\\\">>\"\n}\n```\n\n!! Insert some templates or stamp or snippets into text.\nI frequently use some text pattern and I want to insert them easily. So, I could create several tiddlers, tagged '$:stamp' and in their body are the piece of texte I want to insert. The titles of these tiddlers always start with `$:/config/stamp/` (i.e. $:/config/stamp/macro, $:/config/stamp/list1, $:/config/stamp/list2). I want to trigger the completion by using `<<`, then I only want to chose among the last part of the titles of tiddlers tagged `$:stamp` so I use a mask (`$:/config/stamp/`) to only display the last part of the tiddlers title. When selectected, the `body` of the tiddler is inserted, with no surrounding strings. As a results, the Completion Template is (notice the `body` field):\n\n```\n{\n \"pattern\": \"<<\",\n \"body\": \"[tag[$:stamp]]\",\n \"mask\" : \"$:/config/stamp/\",\n \"start\": \"\",\n \"end\": \"\"\n}\n```\n\n!! And you ?\nIf you have funny usages of completion, let me know. If you'd like to do something that is not yet possible, let me know...\n\nmail : snowgoon88(AT)gmail(DOT)com"
},
"$:/plugins/snowgoon88/edit-comptext/framed.js": {
"text": "/*\\\ntitle: $:/plugins/snowgoon88/edit-comptext/framed.js\ntype: application/javascript\nmodule-type: library\n\nTaken from $:/core/modules/editor/engines/framed.js\nText editor engine based on a simple input or textarea within an iframe. This is done so that the selection is preserved even when clicking away from the textarea\n\n\\*/\n(function(){\n\n/*jslint node: true,browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\n// Configuration tiddler\nvar COMPLETION_OPTIONS = \"$:/plugins/snowgoon88/edit-comptext/config\";\nvar Completion = require(\"$:/plugins/snowgoon88/edit-comptext/completion.js\").Completion;\n\t\nfunction FramedCompEngine(options) {\n //DEBUG console.log( \"==FramedCompEngine::creation\" );\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\n\t// Completion\n\t// Load Completion configuration as JSON\n this._configOptions = $tw.wiki.getTiddlerData( COMPLETION_OPTIONS, {} );\n\t\n\t// Create our hidden dummy text area for reading styles\n\tthis.dummyTextArea = this.widget.document.createElement(\"textarea\");\n\tif(this.widget.editClass) {\n\t\tthis.dummyTextArea.className = this.widget.editClass;\n\t}\n\tthis.dummyTextArea.setAttribute(\"hidden\",\"true\");\n\tthis.parentNode.insertBefore(this.dummyTextArea,this.nextSibling);\n\tthis.widget.domNodes.push(this.dummyTextArea);\n\t// Create dummy popup for reading its styles\n\t//this._dummyCompletion = new Completion( this.widget, this.dummyTextArea, this._configOptions);\n\t//REMOVEthis._dummyCompletion.setAttribute(\"hidden\",\"true\");\n\t\n\t// Create the iframe\n\tthis.iframeNode = this.widget.document.createElement(\"iframe\");\n\tthis.parentNode.insertBefore(this.iframeNode,this.nextSibling);\n\tthis.iframeDoc = this.iframeNode.contentWindow.document;\n\t// (Firefox requires us to put some empty content in the iframe)\n\tthis.iframeDoc.open();\n\tthis.iframeDoc.write(\"\");\n\tthis.iframeDoc.close();\n\t// Style the iframe\n\tthis.iframeNode.className = this.dummyTextArea.className;\n\tthis.iframeNode.style.border = \"none\";\n\tthis.iframeNode.style.padding = \"0\";\n\tthis.iframeNode.style.resize = \"none\";\n\tthis.iframeDoc.body.style.margin = \"0\";\n\tthis.iframeDoc.body.style.padding = \"0\";\n\tthis.widget.domNodes.push(this.iframeNode);\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.iframeDoc.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.iframeDoc.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\t// Copy the styles from the dummy textarea\n\tthis.copyStyles();\n\t// Add event listeners\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"input\",handlerObject: this,handlerMethod: \"handleInputEvent\"},\n\t\t{name: \"keydown\",handlerObject: this.widget,handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.iframeDoc.body.appendChild(this.domNode);\n\n\t// add Completion popup\n this._completion = new Completion( this.widget, this.domNode, this._configOptions, this.dummyTextArea, this.iframeNode.offsetTop, this.iframeNode.offsetLeft );\n\t// print iframe offset\n\t//DEBUG console.log( \" __iframe.offsetLeft: \"+this.iframeNode.offsetLeft );\n //DEBUG console.log( \" __iframe.offsetTop: \"+this.iframeNode.offsetTop );\n \n\t// Copy all styles from dummyCompletion\n\t//$tw.utils.copyStyles(this._dummyCompletion._popNode, this._completion._popNode);\n\t// Override the ones that should not be set the same as the dummy textarea\n\t//this._completion._popNode.style.display = \"block\";\n\t//this._completion._popNode.style.width = \"100%\";\n\t//this._completion._popNode.style.margin = \"0\";\n\t// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour\n\t//this._completion._popNode.style[\"-webkit-text-fill-color\"] = \"currentcolor\";\n \n}\n\n/*\nCopy styles from the dummy text area to the textarea in the iframe\n*/\nFramedCompEngine.prototype.copyStyles = function() {\n\t// Copy all styles\n\t$tw.utils.copyStyles(this.dummyTextArea,this.domNode);\n\t// Override the ones that should not be set the same as the dummy textarea\n\tthis.domNode.style.display = \"block\";\n\tthis.domNode.style.width = \"100%\";\n\tthis.domNode.style.margin = \"0\";\n\t// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour\n\tthis.domNode.style[\"-webkit-text-fill-color\"] = \"currentcolor\";\n};\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nFramedCompEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode) {\n\t\t\tthis.domNode.value = text;\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nFramedCompEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nFramedCompEngine.prototype.fixHeight = function() {\n\t// Make sure styles are updated\n\tthis.copyStyles();\n\t// Adjust height\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tvar newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t\tthis.iframeNode.style.height = (newHeight + 14) + \"px\"; // +14 for the border on the textarea\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t\tthis.iframeNode.style.height = (fixedHeight + 14) + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nFramedCompEngine.prototype.focus = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nFramedCompEngine.prototype.handleInputEvent = function(event) {\n //DEBUG console.log( \"__framed.js::handleInputEvent\");\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nFramedCompEngine.prototype.createTextOperation = function() {\n\tvar operation = {\n\t\ttext: this.domNode.value,\n\t\tselStart: this.domNode.selectionStart,\n\t\tselEnd: this.domNode.selectionEnd,\n\t\tcutStart: null,\n\t\tcutEnd: null,\n\t\treplacement: null,\n\t\tnewSelStart: null,\n\t\tnewSelEnd: null\n\t};\n\toperation.selection = operation.text.substring(operation.selStart,operation.selEnd);\n\treturn operation;\n};\n\n/*\nExecute a text operation\n*/\nFramedCompEngine.prototype.executeTextOperation = function(operation) {\n\t// Perform the required changes to the text area and the underlying tiddler\n\tvar newText = operation.text;\n\tif(operation.replacement !== null) {\n\t\tnewText = operation.text.substring(0,operation.cutStart) + operation.replacement + operation.text.substring(operation.cutEnd);\n\t\t// Attempt to use a execCommand to modify the value of the control\n\t\tif(this.iframeDoc.queryCommandSupported(\"insertText\") && this.iframeDoc.queryCommandSupported(\"delete\") && !$tw.browser.isFirefox) {\n\t\t\tthis.domNode.focus();\n\t\t\tthis.domNode.setSelectionRange(operation.cutStart,operation.cutEnd);\n\t\t\tif(operation.replacement === \"\") {\n\t\t\t\tthis.iframeDoc.execCommand(\"delete\",false,\"\");\n\t\t\t} else {\n\t\t\t\tthis.iframeDoc.execCommand(\"insertText\",false,operation.replacement);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.domNode.value = newText;\n\t\t}\n\t\tthis.domNode.focus();\n\t\tthis.domNode.setSelectionRange(operation.newSelStart,operation.newSelEnd);\n\t}\n\tthis.domNode.focus();\n\treturn newText;\n};\n\nexports.FramedCompEngine = FramedCompEngine;\n\n})();\n",
"type": "application/javascript",
"title": "$:/plugins/snowgoon88/edit-comptext/framed.js",
"module-type": "library"
},
"$:/plugins/snowgoon88/edit-comptext/simple.js": {
"text": "/*\\\ntitle: $:/plugins/snowgoon88/edit-comptext/simple.js\ntype: application/javascript\nmodule-type: library\n\nTaken from $:/core/modules/editor/engines/simple.js\nText editor engine based on a simple input or textarea tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\n// Configuration tiddler\nvar COMPLETION_OPTIONS = \"$:/plugins/snowgoon88/edit-comptext/config\";\nvar Completion = require(\"$:/plugins/snowgoon88/edit-comptext/completion.js\").Completion;\n\nfunction SimpleCompEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\n // Completion\n\t// Load Completion configuration as JSON\n this._configOptions = $tw.wiki.getTiddlerData( COMPLETION_OPTIONS, {} );\n\t\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.widget.document.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.widget.document.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editClass) {\n\t\tthis.domNode.className = this.widget.editClass;\n\t}\n\t// Add an input event handler\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"focus\", handlerObject: this, handlerMethod: \"handleFocusEvent\"},\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleInputEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.parentNode.insertBefore(this.domNode,this.nextSibling);\n\tthis.widget.domNodes.push(this.domNode);\n\n\t// add Completion popup\n this._completion = new Completion( this.widget, this.domNode, this._configOptions );\n}\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nSimpleCompEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode) {\n\t\t\tthis.domNode.value = text;\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nSimpleCompEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nSimpleCompEngine.prototype.fixHeight = function() {\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\t$tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nSimpleCompEngine.prototype.focus = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nSimpleCompEngine.prototype.handleInputEvent = function(event) {\n\tconsole.log( \"__simple.js::handleInputEvent\");\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"focus\" event\n*/\nSimpleCompEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editFocusPopup) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNode,\n\t\t\ttitle: this.widget.editFocusPopup,\n\t\t\twiki: this.widget.wiki,\n\t\t\tforce: true\n\t\t});\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nSimpleCompEngine.prototype.createTextOperation = function() {\n\treturn null;\n};\n\n/*\nExecute a text operation\n*/\nSimpleCompEngine.prototype.executeTextOperation = function(operation) {\n};\n\nexports.SimpleCompEngine = SimpleCompEngine;\n\n})();\n",
"type": "application/javascript",
"title": "$:/plugins/snowgoon88/edit-comptext/simple.js",
"module-type": "library"
},
"$:/plugins/snowgoon88/edit-comptext/cursor-position.js": {
"text": "/*\\\nModule that compute the pixel position of the cursor of a text\nements.\n\nTaken from https://github.com/component/textarea-caret-position\n\n(as https://github.com/kir/js_cursor_position is not updated any more)\n\\*/\n// Fonction anonyme executée immediatement\n( function(){\n \n// The properties that we copy into a mirrored div.\n// Note that some browsers, such as Firefox,\n// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,\n// so we have to do every single property specifically.\nvar properties = [\n 'direction', // RTL support\n 'boxSizing',\n 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does\n 'height',\n 'overflowX',\n 'overflowY', // copy the scrollbar for IE\n\n 'borderTopWidth',\n 'borderRightWidth',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderStyle',\n\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/font\n 'fontStyle',\n 'fontVariant',\n 'fontWeight',\n 'fontStretch',\n 'fontSize',\n 'fontSizeAdjust',\n 'lineHeight',\n 'fontFamily',\n\n 'textAlign',\n 'textTransform',\n 'textIndent',\n 'textDecoration', // might not make a difference, but better be safe\n\n 'letterSpacing',\n 'wordSpacing',\n\n 'tabSize',\n 'MozTabSize'\n\n];\nvar isFirefox = false;\nif($tw.browser) {\n isFirefox = window.mozInnerScreenX != null;\n}\n\nfunction getCaretCoordinates(element, position, options) {\n\n var debug = options && options.debug || false;\n if (debug) {\n var el = document.querySelector('#input-textarea-caret-position-mirror-div');\n if ( el ) { el.parentNode.removeChild(el); }\n }\n\n // mirrored div\n var div = document.createElement('div');\n div.id = 'input-textarea-caret-position-mirror-div';\n document.body.appendChild(div);\n\n var style = div.style;\n var computed;\n if($tw.browser) {\n computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9\n } \n else {\n computed = element.currentStyle;\n }\n \n\n // default textarea styles\n style.whiteSpace = 'pre-wrap';\n if (element.nodeName !== 'INPUT')\n style.wordWrap = 'break-word'; // only for textarea-s\n\n // position off-screen\n style.position = 'absolute'; // required to return coordinates properly\n if (!debug)\n style.visibility = 'hidden'; // not 'display: none' because we want rendering\n\n // transfer the element's properties to the div\n properties.forEach(function (prop) {\n style[prop] = computed[prop];\n });\n\n if (isFirefox) {\n // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275\n if (element.scrollHeight > parseInt(computed.height))\n style.overflowY = 'scroll';\n } else {\n style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'\n }\n\n div.textContent = element.value.substring(0, position);\n // the second special handling for input type=\"text\" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037\n if (element.nodeName === 'INPUT')\n div.textContent = div.textContent.replace(/\\s/g, \"\\u00a0\");\n\n var span = document.createElement('span');\n // Wrapping must be replicated *exactly*, including when a long word gets\n // onto the next line, with whitespace at the end of the line before (#7).\n // The *only* reliable way to do that is to copy the *entire* rest of the\n // textarea's content into the <span> created at the caret position.\n // for inputs, just '.' would be enough, but why bother?\n span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all\n div.appendChild(span);\n\n var coordinates = {\n top: span.offsetTop + parseInt(computed['borderTopWidth']),\n left: span.offsetLeft + parseInt(computed['borderLeftWidth'])\n };\n\n if (debug) {\n span.style.backgroundColor = '#aaa';\n } else {\n document.body.removeChild(div);\n }\n\n return coordinates;\n}\n\n// Exporte as a module of node.js otherwise set as global\nif (typeof module != \"undefined\" && typeof module.exports != \"undefined\") {\n module.exports = getCaretCoordinates;\n} else {\n window.getCaretCoordinates = getCaretCoordinates;\n}\n\n})();\n",
"type": "application/javascript",
"title": "$:/plugins/snowgoon88/edit-comptext/cursor-position.js",
"module-type": "library"
},
"$:/plugins/snowgoon88/edit-comptext/completion.js": {
"text": "/*\\\ntitle: $:/plugins/snowgoon88/edit-comptext/completion.js\ntype: application/javascript\nmodule-type: library\n\nTry to make self-contained completion module.\n\nTo use this 'module', you need a `widget` with a kind of `editarea` node.\nI do not know the exacte prerequisites of this editarea node for the module to\nwork, but mostly one should be able to attach the following `eventHandler` to\nit:\n - input\n - keydown\n - keypress\n - keyup\nThe `widget` is needed because I use:\n - widget.document\n - widget.wiki.filterTiddlers(...)\n\nFrom the Widget, once you have a proper editarea, you just have to call\n - var completion = new Completion( theWidget, theEditAreaNode, configObject);\nwhere `configObject` is expected to have the following fields. if a field is missing, a default value will be given.\nOne can have many `elements' in the template array.\n\n{\n \"configuration\": {\n \"caseSensitive\" : false,\n \"maxMatch\" : 8,\n \"minPatLength\" : 2,\n \"triggerKeyCombination\" : \"^ \"\n },\n \"template\": [{\n \"pattern\": \"[[\",\n \"filter\": \"[all[tiddlers]!is[system]]\",\n \"start\": \"[[\",\n \"end\": \"]]\"\n }\n ]\n}\n\nTODO : CHECK if needed\n\\*/\n\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// To compute pixel coordinates of cursor\nvar getCaretCoordinates = require(\"$:/plugins/snowgoon88/edit-comptext/cursor-position.js\");\n\n/** Default Completion Attributes */\nvar DEFATT = { maxMatch: 5, minPatLength: 2, caseSensitive: false, triggerKeyCombination: \"^ \" };\n\n/** \n * Struct for generic Completion Templates.\n * <ul>\n * <li>pat : pattern searched for.</li>\n * <li>filter : filter operation used to find the list of completion options</li>\n * <li>mask: replaced by \"\" when presenting completion options</li>\n * </ul>\n */\nvar Template = function( pat, filter, mask, field, start, end ) {\n this.pat = pat;\n this.filter = filter;\n this.mask = \"^\"+regExpEscape(mask);\n this.field = field;\n this.start = start;\n this.end = end;\n this.pos = 0;\n};\n/**\n * Struct for storing completion options, as we need to memorise \n * the titles of the tiddlers when masked and when body must be displayed.\n */\nvar OptCompletion = function( title, str ) {\n this.title = title;\n this.str = str;\n};\n\nvar keyMatchGenerator = function(combination) {\n\tlet singleMatchGenerator = function(character) {\n\t\tif (character === '^') {\n\t\t\treturn event => event.ctrlKey;\n\t\t}\n\t\telse if (character === '+') {\n\t\t\treturn event => event.shiftKey;\n\t\t}\n\t\telse if (character === '!') {\n\t\t\treturn event => event.altKey;\n\t\t}\n\t\telse {\n\t\t\treturn event => (event.keyCode || event.which) === character.charCodeAt(0);\n\t\t}\n\t};\n\n\tlet matchers = [];\n\tfor (let i = 0; i < combination.length; i++) {\n\t\tmatchers.push(singleMatchGenerator(combination[i]));\n\t}\n\n\treturn event => {\n\t\tfor (let i = 0; i < matchers.length; i++) {\n\t\t\tif (!matchers[i](event)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t};\n};\n\n/**\n * Widget is needed in creating popupNode.\n * - widget.document\n * - widget.wiki.filterTiddlers(...)\n * - sibling : where to create the popup in the DOM.\n */\n\tvar Completion = function( editWidget, areaNode, param, sibling, offTop, offLeft ) {\n\tconsole.log( \"==Completion::creation\" );\n\n // About underlying Widget\n this._widget = editWidget;\n\tthis._areaNode = areaNode;\n\tthis._sibling = (typeof sibling !== 'undefined') ? sibling : this._areaNode;\n\tthis._offTop = (typeof offTop !== 'undefined') ? offTop : 0;\n\tthis._offLeft = (typeof offLeft !== 'undefined') ? offLeft : 0;\t\n\t\t\n // Completions attributes\n /** State */\n this._state = \"VOID\";\n this._template = undefined;\n /** Best matches */\n this._bestMatches = []; // An array of OptCompletion\n this._idxChoice = -1;\n /** Param */\n // maximum nb of match displayed\n this._maxMatch = param.configuration.maxMatch || DEFATT.maxMatch; \n this._minPatLength = param.configuration.minPatLength || DEFATT.minPatLength;\n this._caseSensitive= param.configuration.caseSensitive || DEFATT.caseSensitive;\n this._triggerKeyMatcher = keyMatchGenerator(param.configuration.triggerKeyCombination || DEFATT.triggerKeyCombination);\n /** Input information */\n this._lastChar = \"\";\n this._hasInput = false;\n /** List of Completion Templates */\n this._listTemp = [];\n \n // Read templates from Param\n if( param.template ) {\n \tvar idT;\n \tfor( idT=0; idT<param.template.length; idT++ ) {\n \t var temp = param.template[idT];\n\t // field 'body' ou 'title' (default)\n\t if( temp.body ) {\t\t\n \t\tthis._listTemp.push( \n \t\t new Template( temp.pattern, temp.body,\n\t\t\t\t temp.mask ? temp.mask : \"\",\n\t\t\t\t \"body\",\n \t\t\t\t temp.start, temp.end )\n \t\t);\n\t }\n\t else {\n \t\tthis._listTemp.push( \n \t\t new Template( temp.pattern, \n\t\t\t\t temp.title ? temp.title : temp.filter,\n\t\t\t\t temp.mask ? temp.mask : \"\",\n\t\t\t\t \"title\",\n \t\t\t\t temp.start, temp.end )\n \t\t);\n\t }\n\t //DEBUG temp = this._listTemp[this._listTemp.length-1];\n\t //DEBUG console.log( \"__CONF : \"+temp.pattern+\":\"+temp.filter+\":\"+temp.mask+\":\"+temp.field+\":\"+temp.start+\":\"+temp.end );\n \t}\n }\n // or defaut template\n else {\n \tthis._listTemp = [\n \t new Template( \"[[\", \"[all[tiddlers]!is[system]]\", \n\t\t\t \"\", \"title\",\n\t\t\t \"[[\", \"]]\" )\n \t];\n }\n // Create Popup\n\t//this._popNode = createPopup(this._widget, this._areaNode );\n\tthis._popNode = createPopup(this._widget, this._sibling );\t\n \n // Listen to the Keyboard\n $tw.utils.addEventListeners( this._areaNode,[\n\t{name: \"input\", handlerObject: this, handlerMethod: \"handleInput\"},\n\t{name: \"keydown\", handlerObject: this, handlerMethod: \"handleKeydown\"},\n\t{name: \"keypress\", handlerObject: this, handlerMethod: \"handleKeypress\"},\n \t{name: \"keyup\", handlerObject: this, handlerMethod: \"handleKeyup\"}\n ]);\n \n /** \n * Find the bestMatches among listChoice with given pattern\n * @param listChoice : array of String\n * @change : this._bestMatches => array of OptCompletion\n */\n this._findBestMatches = function( listChoice, pattern, nbMax) {\n\t// regexp search pattern, case sensitive\n\tvar flagSearch = this._caseSensitive ? \"\" : \"i\" ;\n\tvar regpat = RegExp( regExpEscape(pattern), flagSearch );\n\tvar regpat_start = RegExp( \"^\"+regExpEscape(pattern), flagSearch );\n\tvar regMask = RegExp( this._template.mask ? this._template.mask : \"\",\"\");\n\tvar nbMatch = 0;\n\t// nbMax set to _maxMatch if no value given\n\tnbMax = nbMax !== undefined ? nbMax : this._maxMatch;\n\n\t//DEBUG console.log( \"__FIND masked=\"+regMask+\" regPat=\"+regpat);\n\n\tthis._bestMatches= [];\n\tvar otherMatches = [];\n\t// We test every possible choice\n\tfor( var i=0; i< listChoice.length; i++ ) {\n\t // apply mask over potential choice\n\t var maskedChoice = listChoice[i].replace( regMask, \"\");\n\t // Test first if pattern is found at START of the maskedChoice\n\t // THEN added to BestMatches\n \t if( regpat_start.test( maskedChoice )) {\n\t\tif (nbMatch >= nbMax) {\n\t\t this._bestMatches.push( new OptCompletion(\"\",\"...\") );\n\t\t return;\n\t\t} else {\n\t\t this._bestMatches.push( new OptCompletion(listChoice[i],maskedChoice) );\n\t\t nbMatch += 1;\n\t\t}\n\t }\n\t // then if pattern is found WITHIN the maskedChoice\n\t // added AFTER the choices that starts with pattern\n\t else if( regpat.test( maskedChoice ) ) {\n\t\tif (nbMatch >= nbMax) {\n\t\t // add all otherMatches to _bestMatches\n\t\t this._bestMatches.push( new OptCompletion(\"\",\"<hr>\") ) ; //separator\n\t\t this._bestMatches = this._bestMatches.concat( otherMatches );\n\t\t this._bestMatches.push( new OptCompletion(\"\",\"...\") );\n\t\t return;\n\t\t} else {\n\t\t otherMatches.push( new OptCompletion(listChoice[i],maskedChoice) );\n\t\t nbMatch += 1;\n\t\t}\n\t }\n\t}\n\t// Here, must add the otherMatches\n\tthis._bestMatches.push( new OptCompletion(\"\",\"<hr>\") ) ; //separator\n\tthis._bestMatches = this._bestMatches.concat( otherMatches );\n };\n /**\n * Change Selected Status of Items\n */\n this._next = function (node) {\n\tvar count = node.children.length;\n\t//DEBUG console.log( \"__NEXT: co=\"+count+\" nbMatch=\"+this._bestMatches.length);\n\tif( this._bestMatches.length > 0 ) \n\t this._goto( node, this._idxChoice < count - 1 ? this._idxChoice + 1 : -1);\n\t//DEBUG this._logStatus( \"NexT\" );\n };\n this._previous = function (node) {\n\tvar count = node.children.length;\n\tvar selected = this._idxChoice > -1;\n\t//DEBUG console.log( \"__PREV: co=\"+count+\" nbMatch=\"+this._bestMatches.length);\n\tif( this._bestMatches.length > 0 ) \n\t this._goto( node, selected ? this._idxChoice - 1 : count - 1);\n\t//DEBUG this._logStatus( \"PreV\" );\n };\n // Should not be used, highlights specific item without any checks!\n this._goto = function (node, idx) {\n\tvar lis = node.children;\n\tvar selected = this._idxChoice > -1;\n\tif (selected) {\n\t lis[this._idxChoice].setAttribute(\"patt-selected\", \"false\");\n\t}\n\n\tthis._idxChoice = idx;\n \n\tif (idx > -1 && lis.length > 0) {\n\t lis[idx].setAttribute(\"patt-selected\", \"true\");\n\t}\n };\n /**\n * Abort pattern and undisplay.\n */\n this._abortPattern = function (displayNode) {\n\tthis._state = \"VOID\";\n\tthis._bestChoices = [];\n\tthis._idxChoice = -1;\n\tthis._undisplay( displayNode );\n\tthis._template = undefined;\n };\n /**\n * Display popupNode at the cursor position in areaNode.\n */\n this._display = function( areaNode, popupNode ) {\n\tif ( popupNode.style.display == 'none' ) {\n\t // Must get coordinate\n\t // Cursor coordinates within area + area coordinates + scroll\n var coord = getCaretCoordinates(areaNode, areaNode.selectionEnd);\n var styleSize = getComputedStyle(areaNode).getPropertyValue('font-size');\n var fontSize = parseFloat(styleSize); \n\t\t\n\t popupNode.style.left = (this._offLeft+areaNode.offsetLeft-areaNode.scrollLeft+coord.left) + 'px';\n\t popupNode.style.top = (this._offTop+areaNode.offsetTop-areaNode.scrollTop+coord.top+fontSize*2) + 'px';\n\t popupNode.style.display = 'block';\n\t}\n };\n /**\n * Undisplay someNode\n */\n this._undisplay = function( displayNode ) {\n\tif ( displayNode.style.display != 'none' ) {\n\t displayNode.style.display = 'none';\n\t}\n };\n\n /**\n * Used for debug\n */\n this._logStatus = function(msg) {\n\tconsole.log( \"__STATUS: \"+this._state+\":-\"+msg+\"- idx=\"+this._idxChoice );\n };\n\n};\n// **************************************************************************\n// ******************************************************************eventCbk\n// **************************************************************************\n/**\n * Disable the *effects* of ENTER / UP / DOWN / ESC when needed.\n * Set _hasInput to false.\n */\nCompletion.prototype.handleKeydown = function(event) {\n // key \n var key = event.keyCode;\n this._hasInput = false;\n \n //DEBUG console.log( \"__KEYDOWN (\"+key+\") hasI=\"+this._hasInput);\n \n // ENTER while selecting\n if( (this._state === \"PATTERN\" || this._state === \"SELECT\") && key === 13 ) {\n \tevent.preventDefault();\n \tevent.stopPropagation();\n }\n // ESC while selecting\n if( (this._state === \"PATTERN\" || this._state === \"SELECT\") && key === 27 ) {\n \tevent.preventDefault();\n \tevent.stopPropagation();\n }\n // UP/DOWN while a pattern is extracted\n if( (key===38 || key===40) && \n\t(this._state === \"PATTERN\" || this._state === \"SELECT\") ) {\n\tevent.preventDefault();\n }\n};\n/**\n * Means that something has been added/deleted => set _hasInput\n */\nCompletion.prototype.handleInput = function(event) {\n this._hasInput = true;\n //DEBUG console.log( \"__INPUT hasI=\"+this._hasInput );\n};\n\t\n/**\n * Set _lastChar, detects CTRL+SPACE.\n */\nCompletion.prototype.handleKeypress = function(event) {\n var curPos = this._areaNode.selectionStart; // cursor position\n var val = this._areaNode.value; // text in the area\n // key \n var key = event.keyCode || event.which;\n\t\n this._lastChar = String.fromCharCode(key);\n //DEBUG console.log( \"__KEYPRESS (\"+key+\") hasI=\"+this._hasInput+\" char=\"+this._lastChar );\n //DEBUG this._logStatus( \"KEYPRESS\" );\n \n // Detect Ctrl+Space\n if( this._triggerKeyMatcher(event) && this._state === \"VOID\" ) {\n\t//Find a proper Template\n\t// first from which we can extract a pattern\n\tif( this._template === undefined ) {\n\t //DEBUG console.log(\"__SPACE : find a Template\" );\n\t var idT, res;\n\t for( idT=0; idT < this._listTemp.length; idT++ ) {\n\t\tres = extractPattern( val, curPos, this._listTemp[idT] );\n\t\t//DEBUG console.log(\" t=\"+this._listTemp[idT].pat+\" res=\"+res);\n\t\t// res is not undefined => good template candidate\n\t\tif( res ) {\n\t\t this._template = this._listTemp[idT];\n\t\t this._state = \"PATTERN\";\n\t\t break;\n\t\t}\n\t }\n\t}\n\telse {\n\t //DEBUG console.log(\"__SPACE : already a template\" );\n\t this._state = \"PATTERN\";\n\t}\n }\n};\n/**\n * ESC -> abort; \n * Detect [ -> VOID switch to _state=PATTERN\n * PATTERN || SELECT : ENTER -> insertText\n * UP/DOWN -> previous/next\n * pattern.length > _minPatternLength -> display \n */\nCompletion.prototype.handleKeyup = function(event) {\n var curPos = this._areaNode.selectionStart; // cursor position\n var val = this._areaNode.value; // text in the area\n // key a\n var key = event.keyCode;\n \n //DEBUG console.log( \"__KEYUP (\"+key+\") hasI=\"+this._hasInput );\n \n // ESC\n if( key === 27 ) {\n\tthis._abortPattern( this._popNode );\n\t//DEBUG this._logStatus( \"\" );\n }\n // Check for every template\n if( this._hasInput && this._state === \"VOID\" ) {\n\t// check every template's pattern\n\tvar idT, template;\n\tfor( idT=0; idT < this._listTemp.length; idT++ ) {\n\t template = this._listTemp[idT];\n\t if( this._lastChar === template.pat[template.pos] ) {\n\t\ttemplate.pos += 1;\n\t\t//DEBUG console.log( \"__CHECK : pat=\"+template.pat+\" pos=\"+template.pos );\n\t\t// Pattern totaly matched ?\n\t\tif( template.pos === template.pat.length ) {\n\t\t //DEBUG console.log( \"__CHECK => found \"+template.pat );\n\t\t this._state = \"PATTERN\";\n\t\t this._template = template;\n\t\t \n\t\t break; // get out of loop\n\t\t}\n\t }\n\t else {\n\t\ttemplate.pos = 0;\n\t\t//DEBUG console.log( \"__CHECK : pat=\"+template.pat+\" pos=\"+template.pos );\n\t }\n\t}\n }\n // a pattern\n else if( this._state === \"PATTERN\" || this._state === \"SELECT\" ) {\n\t// Pattern below cursor : undefined if no pattern\n\tvar pattern = extractPattern( val, curPos, this._template );\n\tif( key === 13 ) { // ENTER\n\t //DEBUG console.log( \"KEY : Enter\" );\n \t // Choice made in the displayNode ?\n \t var selected = this._idxChoice > -1 && this._idxChoice !== this._maxMatch;\n \t //DEBUG console.log( \" > sel=\"+selected+\" len=\"+this._bestChoices.length );\n \t if( selected ) {\n \t\t//DEBUG console.log( \" > selected\" );\n\t\tvar temp = this._bestMatches[this._idxChoice];\n\t\tvar str = temp.str;\n\t\tif( this._template.field === \"body\" ) {\n\t\t str = $tw.wiki.getTiddlerText( temp.title );\n\t\t}\n \t\tinsertInto( this._areaNode,\n\t\t\t str,\n\t\t\t pattern.start, curPos, this._template );\n\t\t// save this new content\n\t\tthis._widget.saveChanges( this._areaNode.value );\n\t }\n\t // otherwise take the first choice (if exists)\n\t else if( this._bestMatches.length > 0 ) {\n \t\t//DEBUG console.log( \" > take first one\" );\n\t\tvar temp = this._bestMatches[0];\n\t\tvar str = temp.str;\n\t\tif( this._template.field === \"body\" ) {\n\t\t str = $tw.wiki.getTiddlerText( temp.title );\n\t\t}\n \t\tinsertInto( this._areaNode,\n\t\t\t str,\n\t\t\t pattern.start, curPos, this._template );\n\t\t// save this new content\n\t\tthis._widget.saveChanges( this._areaNode.value );\n\t }\n\t this._abortPattern( this._popNode );\n\t\t//DEBUG this._logStatus( \"\" );\n \t }\n\t else if( key === 38 && this._hasInput === false) { // up\n\t\tthis._state = \"SELECT\";\n \t\tevent.preventDefault();\n \t\tthis._previous( this._popNode );\n\t\t//DEBUG this._logStatus( pattern.text );\n \t\t//event.stopPropagation();\n \t }\n \t else if( key === 40 && this._hasInput === false) { // down\n\t\tthis._state = \"SELECT\";\n \t\tevent.preventDefault();\n \t\tthis._next( this._popNode );\n\t\t//DEBUG this._logStatus( pattern.text );\n \t\t//event.stopPropagation();\n \t }\n \t else if( pattern ) { // pattern changed by keypressed\n\t\tthis._idxChoice = -1;\n \t\t// log\n\t\t//DEBUG this._logStatus( pattern.text );\n \t\t// Popup with choices if pattern at least minPatLength letters long\n\t\tif( pattern.text.length > (this._minPatLength-1) ) {\n\t\t // compute listOptions from templateFilter\n\t\t var allOptions;\n\t\t if( this._template )\n\t\t\tallOptions = this._widget.wiki.filterTiddlers( this._template.filter );\n\t\t else\n\t\t\tallOptions = this._widget.wiki.filterTiddlers(\"[all[tiddlers]]\");\n\t\t this._findBestMatches( allOptions, pattern.text );\n \t\t this._popNode.innerHTML = \"\";\n \t\t //console.log( \"BC \"+ this._pattern + \" => \" + choice );\n \t\t if (this._bestMatches.length > 0) {\n\t\t\tfor( var i=0; i<this._bestMatches.length; i++) {\n \t\t\t this._popNode.appendChild( \n\t\t\t\titemHTML(this._bestMatches[i].str,\n\t\t\t\t\t pattern.text));\n \t\t\t}\n\t\t\tthis._display( this._areaNode, this._popNode );\t\t\t\n \t\t }\n\t\t else { // no matches\n\t\t\tthis._state = \"PATTERN\";\n\t\t\tthis._undisplay( this._popNode );\n\t\t }\n\t\t}\n \t }\n\t else { // no pattern detected\n\t\tthis._abortPattern( this._popNode );\n\t }\n\t}\n\t// to ensure that one MUST add an input (through onInput())\n\tthis._hasInput = false;\n};\n// **************************************************************************\n// ******************************************************** private functions\n// **************************************************************************\n/**\n * Create popup element.\n */\nvar createPopup = function( widget, node ) {\n // Insert a special \"div\" element for poping up\n // Its 'display' property in 'style' control its visibility\n var popupNode = widget.document.createElement(\"div\");\n popupNode.setAttribute( \"style\", \"display:none; position: absolute;\");\n popupNode.className = \"tc-block-dropdown ect-block-dropdown\";\n // Insert the element into the DOM\n node.parentNode.insertBefore(popupNode,node.nextSibling);\n //CHECK the domNodes is a attribute of Widget [widget.js]\n //CHECK this.domNodes.push(popupNode);\n \n return popupNode;\n};\n/**\n * Extract Pattern from text at a given position.\n *\n * Between previous template.pat (or '[[') and pos\n * \n * If no pattern -> undefined\n */\nvar extractPattern = function( text, pos, template ) {\n // Detect previous and next ]]=>STOP or [[=>START\n var sPat = template.pat ? template.pat : '[[';\n var pos_prevOpen = text.lastIndexOf( sPat, pos );\n var ePat = template.end ? template.end : ']]';\n var pos_prevClosed = text.lastIndexOf( ePat, pos );\n var pos_nextClosed = text.indexOf( ePat, pos );\n //DEBUG console.log(\"__CALC st=\"+sPat+\" -> en=\"+ePat );\n //DEBUG console.log(\"__CALC po=\"+pos_prevOpen+\" pc=\"+pos_prevClosed+\" nc=\"+pos_nextClosed+\" pos=\"+pos);\n pos_nextClosed = (pos_nextClosed >= 0) ? pos_nextClosed : pos;\n \n if( (pos_prevOpen >= 0) && // must be opened\n\t((pos_prevOpen > pos_prevClosed ) || // not closed yet\n\t (pos_prevClosed === pos))) { // closed at cursor\n\t//DEBUG console.log(\" pat=\"+text.slice( pos_prevOpen+sPat.length, pos) );\n\treturn { text: text.slice( pos_prevOpen+sPat.length, pos ),\n\t\t start: pos_prevOpen,\n\t\t end: pos_nextClosed\n\t };\n }\n};\n/**\n * Controls how list items are generated.\n * Function that takes two parameters :\n * - text : suggestion text\n * - input : the user’s input\n * Returns : list item. \n * Generates list items with the user’s input highlighted via <mark>.\n */\nvar itemHTML = function (text, input ) {\n // text si input === ''\n // otherwise, build RegExp that is global (g) and case insensitive (i)\n // to replace with <mark>$&</mark> where \"$&\" is the matched pattern\n var html = input === '' ? text : text.replace(RegExp(regExpEscape(input.trim()), \"gi\"), \"<mark>$&</mark>\");\n return create(\"li\", {\n\tinnerHTML: html,\n\t\"patt-selected\": \"false\"\n });\n};\n/**\n * Insert text into a textarea node, \n * enclosing in 'template.start..template.end'\n *\n * - posBefore : where the 'template.pat+pattern' starts\n * - posAfter : where the cursor currently is\n */\nvar insertInto = function(node, text, posBefore, posAfter, template ) {\n //DEBUG console.log( \"__INSERT : \"+template.pattern+\":\"+template.filter+\":\"+template.mask+\":\"+template.field+\":\"+template.start+\":\"+template.end );\n var val = node.value;\n var sStart = template.start !== undefined ? template.start : '[[';\n var sEnd = template.end !== undefined ? template.end : ']]';\n var newVal = val.slice(0, posBefore) + sStart + text + sEnd + val.slice(posAfter);\n //console.log(\"__INSERT s=\"+sStart+\" e=\"+sEnd);\n //console.log (\"__INSERT pb=\"+posBefore+\" pa=\"+posAfter+\" txt=\"+text);\n //console.log( \"NEW VAL = \"+newVal );\n // WARN : Directly modifie domNode.value.\n // Not sure it does not short-circuit other update methods of the domNode....\n // i.e. could use widget.updateEditor(newVal) from edit-comptext widget.\n // but how to be sure that cursor is well positionned ?\n node.value = newVal;\n node.setSelectionRange(posBefore+text.length+sStart.length+sEnd.length, posBefore+text.length+sStart.length+sEnd.length );\n};\n/**\n * Add an '\\' in front of -\\^$*+?.()|[]{}\n */\nvar regExpEscape = function (s) {\n return s.replace(/[-\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n};\n/**\n * Add an element in the DOM.\n */\nvar create = function(tag, o) {\n var element = document.createElement(tag);\n \n for (var i in o) {\n\tvar val = o[i];\n\t\n\tif (i === \"inside\") {\n\t $(val).appendChild(element);\n\t}\n\telse if (i === \"around\") {\n\t var ref = $(val);\n\t ref.parentNode.insertBefore(element, ref);\n\t element.appendChild(ref);\n\t}\n\telse if (i in element) {\n\t element[i] = val;\n\t}\n\telse {\n\t element.setAttribute(i, val);\n\t}\n }\n \n return element;\n};\n\n\nexports.Completion = Completion;\n\n})();\n\n \n",
"type": "application/javascript",
"title": "$:/plugins/snowgoon88/edit-comptext/completion.js",
"module-type": "library"
},
"$:/plugins/snowgoon88/edit-comptext/edit-comptext.css": {
"text": "\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n/* The \\rules pragma at the top of the tiddler restricts the WikiText \n * to just allow macros and transclusion. This avoids mistakenly \n * triggering unwanted WikiText processing.\n * \n * MUST not save as text/css for macro to be processed\n*/\n\n.ect-block-dropdown li {\n display: block;\n padding: 4px 14px 4px 14px;\n text-decoration: none;\n color: <<colour tiddler-link-foreground>>; /*#5778d8;*/ \n background: transparent;\n}\n.ect-block-dropdown li[patt-selected=\"true\"] {\n color: <<colour tiddler-link-background>>; /*#ffffff; */\n background-color: <<colour tiddler-link-foreground>>; /*#5778d8; */\n}\n.ect-block-dropdown li[patt-selected=\"true\"] mark {\n background: hsl(86, 100%, 21%);\n color: inherit;\n}\n\n",
"type": "text/vnd.tiddlywiki",
"title": "$:/plugins/snowgoon88/edit-comptext/edit-comptext.css",
"tags": "[[$:/tags/Stylesheet]]"
},
"$:/plugins/snowgoon88/edit-comptext/readme": {
"title": "$:/plugins/snowgoon88/edit-comptext/readme",
"text": "!! What ?\nThis plugin adds ''completion'' when editing the body of a tiddler.\n\n* Enter completion-mode by typing `[[` or `CTRL+SPACE`\n* A list of tiddlers with a title that matches the pattern between `[[` and cursor appears\n* `UP/DOWN` keys can select a tiddler, `ENTER` to validate\n* If there is only one match, `ENTER` selects it.\n* `NEW` : you can specify you own trigger pattern and the list of possible completions. See [[$:/plugins/snowgoon88/edit-comptext/usage]] for more details.\n\n\n!! To try it or get the latest news\nSee [[http://snowgoon88.github.io/TW5-extendedit]]\n\n!! Install \n\nTo add the plugin to your own TiddlyWiki5, just drag this link to the browser window:\n\n[[$:/plugins/snowgoon88/edit-comptext]]\n\nSometime, a small configuration step is then needed\n\nin `$:/ControlPanel -> Advanced -> Editor Type -> text/vnd.tiddlywiki` you must chose `comptext` instead of `text`.\n\nReload and « voilà »...\n\nThis plugin is quite mature now :o)\n\n!! Old version\n\n* A version compatible with 5.0.8 to 5.1.11 : [[http://snowgoon88.github.io/TW5-extendedit/index_5.1.11.html]]\n\n!! Source code\nOn github [[https://github.com/snowgoon88/TW5-extendedit]]\n\nGet in touch : snowgoon88(AT)gmail(DOT)com\n"
},
"$:/plugins/snowgoon88/edit-comptext/usage": {
"title": "$:/plugins/snowgoon88/edit-comptext/usage",
"text": "''Important'' : be sure that in `$:/ControlPanel -> Advanced -> Editor Type -> text/vnd.tiddlywiki` you have chosen `comptext` instead of `text`.\n\nConfiguration of the edit-comptext plugin can be done through the tiddler [[$:/plugins/snowgoon88/edit-comptext/config]]. Use a JSON tiddler (do not forget to set the type to `application/json`. See some examples at [[$:/plugins/snowgoon88/edit-comptext/examples]]\n\nIn the `configuration` object you can set :\n\n* `caseSensitive`: `true`/`false` (is search case sensitive ?)\n* `maxMatch` : an `integer` (max number of match displayed)\n* `minPatLength` : an `integer` (minimal length of a pattern to trigger completion search)\n* `triggerKeyCombination ` : a `string` representing the key combination that triggers the autocompletion popup. To use modifier keys in your combination, use following conversions : `ctrl` -> `^`, `alt` -> `!`, `shift` -> `+`. Note: ` ` (literally a whitespace) represents the `space` key.\n\nIn the `template` array you can specify the various completion templates that will be used. Every template can have the following members.\n\n* `pattern` : `string` (pattern that triggers a completion, default \"[[\" )\n* `title` or `body`: `string` (the filter operators that gives the list of valid completions, default \"[all[tiddlers]!is[system]]\"). If you specify `body`, then the body of the tiddler will be inserted on selection.\n* `start` : `string` (when completion is chosen, start is put before the completion, default \"[[\")\n* `end` : `string` (when completion is chosen, end is put after the completion, default \"]]\")\n\n!! Current body of Config Tiddler\n\n{{$:/plugins/snowgoon88/edit-comptext/config}}\n\n"
}
}
}
{
"configuration": {
"caseSensitive" : false,
"maxMatch" : 8,
"minPatLength" : 2,
"triggerKeyCombination" : "^ "
},
"template": [{
"pattern": "[[",
"filter": "[all[tiddlers]!is[system]]",
"start": "[[",
"end": "]]"
}
]
}
{
"tiddlers": {
"$:/plugins/sq/editor-autolist/editor-operation-autolist": {
"text": "/*\\\ntitle: $:/plugins/sq/editor-autolist/editor-operation-autolist.js\ntype: application/javascript\nmodule-type: texteditoroperation\nText editor operation to automate syntax for lists\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"autolist\"] = function(event,operation) {\n\t\n\tvar lineStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\tvar lineEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selStart);\n\tvar line = operation.text.substring(lineStart,lineEnd);\t\n\t\n\tvar listPrefixRegex = /^((\\*|#)+).*/;\n\tvar match = line.match(listPrefixRegex);\n\t\n\tvar mode = event.paramObject? event.paramObject.mode : undefined;\n\t\n\t//ensure we only handle lines starting with * or #\n\tif(match != null && match[1]) {\n\t\t// check if we are handling indent level\n\t\tif(mode === \"indent\" || mode === \"unindent\") {\n\t\t\tvar indentRegExp = /^((\\*|#)+)(.*)$/;\n\t\t\tvar indentMatch = line.match(indentRegExp);\n\t\t\tif(indentMatch != null) {\n\t\t\t\t//check if the line has content\n\t\t\t\tvar content = (indentMatch[3].trim().length != 0) ? indentMatch[3].trim() : \"\";\n\t\t\t\toperation.cutStart = lineStart;\n\t\t\t\toperation.cutEnd = lineEnd;\n\t\t\t\tif(mode === \"indent\") {\t\t\t\t\n\t\t\t\t\t//indent a line\n\t\t\t\t\toperation.replacement = indentMatch[1] + indentMatch[2] + \" \" + content;\n\t\t\t\t\toperation.newSelStart = operation.selStart + 1;\n\t\t\t\t\toperation.newSelEnd = operation.selEnd + 1;\n\t\t\t\t} else if(mode === \"unindent\") {\n\t\t\t\t\t//unindent a line\n\t\t\t\t\toperation.replacement = indentMatch[1].substring(0,indentMatch[1].length - 1) + \" \" + content;\n\t\t\t\t\toperation.newSelStart = operation.selStart - 1;\n\t\t\t\t\toperation.newSelEnd = operation.selEnd - 1;\t\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//handle enter key, meaning new line\n\t\t\tvar trimmed = match[0].replace(/\\s\\s*$/, '');\n\t\t\tvar prefixRegEx = /^((\\*|#)+)$/;\n\t\t\tvar trimmedMatch = trimmed.match(prefixRegEx);\n\t\t\tif(trimmedMatch != null) {\n\t\t\t\t// the line only contains * or # characters and optional whitespace\n\t\t\t\t//terminate the list\n\t\t\t\toperation.replacement = \"\\n\";\n\t\t\t\toperation.cutStart = lineStart;\n\t\t\t\toperation.cutEnd = operation.selStart;\n\t\t\t\toperation.newSelStart = lineStart + 1;\n\t\t\t\toperation.newSelEnd = lineStart + 1;\n\t\t\t} else {\n\t\t\t\t// continue indent level on next line\n\t\t\t\tvar prefix = match[1];\n\t\t\t\toperation.replacement = \"\\n\" + prefix + \" \";\n\t\t\t\toperation.cutStart = operation.selStart;\n\t\t\t\toperation.cutEnd = operation.selStart;\n\t\t\t\t\n\t\t\t\t//check if there is trailing whitespace on the line we are on\n\t\t\t\tvar lineEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selStart);\n\t\t\t\tvar trailingText = operation.text.substring(operation.selStart,lineEnd);\n\t\t\t\tif(trailingText.trim().length == 0) {\n\t\t\t\t\toperation.cutEnd = lineEnd;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\toperation.newSelStart = operation.selStart + prefix.length + 2;\n\t\t\t\toperation.newSelEnd = operation.selEnd + prefix.length + 2;\n\t\t\t}\n\t\t}\n\t} else if(mode != \"indent\" && mode != \"unindent\") {\n\t\t// we need to manually add a linebreak for lines not starting with list markup\n\t\toperation.replacement = \"\\n\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.newSelStart = operation.selStart + 1;\n\t\toperation.newSelEnd = operation.selEnd + 1;\n\t}\n};\n\n})();",
"type": "application/javascript",
"title": "$:/plugins/sq/editor-autolist/editor-operation-autolist",
"tags": "",
"module-type": "texteditoroperation",
"modified": "20200804125155562",
"created": "20200803160356743"
},
"$:/plugins/sq/editor-autolist/EditorToolbar-autolist": {
"created": "20200803165453913",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"autolist\"\n/>\n",
"title": "$:/plugins/sq/editor-autolist/EditorToolbar-autolist",
"tags": "$:/tags/EditorToolbar",
"shortcuts": "((autolist-newline))",
"modified": "20200804124434675",
"icon": "$:/core/images/list-bullet",
"description": "",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"caption": "",
"button-classes": "sq-text-editor-btn-hidden"
},
"$:/plugins/sq/editor-autolist/styles": {
"text": ".sq-text-editor-btn-hidden {\n\tdisplay: none;\n}",
"title": "$:/plugins/sq/editor-autolist/styles",
"tags": "$:/tags/Stylesheet",
"modified": "20200803172530073",
"created": "20200803171440138"
},
"$:/plugins/sq/editor-autolist/EditorToolbar-autolist-indent": {
"created": "20200803213912954",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"autolist\"\n\tmode=\"indent\"\n/>\n",
"title": "$:/plugins/sq/editor-autolist/EditorToolbar-autolist-indent",
"tags": "$:/tags/EditorToolbar",
"shortcuts": "((autolist-indent))",
"modified": "20200804124659294",
"icon": "$:/core/images/list-bullet",
"description": "",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"caption": "",
"button-classes": "sq-text-editor-btn-hidden"
},
"$:/plugins/sq/editor-autolist/EditorToolbar-autolist-unindent": {
"created": "20200804122848593",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"autolist\"\n\tmode=\"unindent\"\n/>\n",
"title": "$:/plugins/sq/editor-autolist/EditorToolbar-autolist-unindent",
"tags": "$:/tags/EditorToolbar",
"shortcuts": "((autolist-unindent))",
"modified": "20200804124808496",
"icon": "$:/core/images/list-bullet",
"description": "",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"caption": "",
"button-classes": "sq-text-editor-btn-hidden"
},
"$:/config/shortcuts/autolist-newline": {
"created": "20200804124551033",
"title": "$:/config/shortcuts/autolist-newline",
"text": "Enter",
"modified": "20200804124551033"
},
"$:/config/shortcuts/autolist-indent": {
"created": "20200804124746636",
"title": "$:/config/shortcuts/autolist-indent",
"text": "Tab",
"modified": "20200804124746636"
},
"$:/config/shortcuts/autolist-unindent": {
"created": "20200804124833452",
"title": "$:/config/shortcuts/autolist-unindent",
"text": "shift-Tab",
"modified": "20200804124833452"
},
"$:/config/ShortcutInfo/autolist-newline": {
"created": "20200804124436341",
"text": "Add a newline and list markup if in a list",
"tags": "",
"title": "$:/config/ShortcutInfo/autolist-newline",
"modified": "20200804124533962"
},
"$:/config/ShortcutInfo/autolist-indent": {
"created": "20200804124703604",
"text": "Indent a line in a list",
"tags": "",
"title": "$:/config/ShortcutInfo/autolist-indent",
"modified": "20200804124720020"
},
"$:/config/ShortcutInfo/autolist-unindent": {
"created": "20200804124811668",
"text": "Unindent a line in a list",
"tags": "",
"title": "$:/config/ShortcutInfo/autolist-unindent",
"modified": "20200804124823040"
}
}
}
{
"tiddlers": {
"$:/_sq/Stories/config/openLinkDivert": {
"text": "bottom",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/openLinkDivert",
"modified": "20200422063802598",
"created": "20170629173808777"
},
"$:/_sq/Stories/config/showRiverDropZones": {
"text": "disable",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/showRiverDropZones",
"modified": "20200523213957947",
"created": "20200417170940547"
},
"$:/_sq/Stories/config/sidebaroverlaybreakpoint": {
"text": "1500px",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/sidebaroverlaybreakpoint",
"modified": "20200416182732404",
"created": "20170616192704225"
},
"$:/_sq/Stories/config/snippets/viewswitcher": {
"text": "\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<$linkcatcher to=\"$:/_sq/Stories/config/Story2-storyview\">\n<div class=\"tc-chooser\">\n<$list filter=\"[storyviews[]]\" variable=\"storyview\">\n<$set name=\"cls\" filter=\"[<storyview>prefix{$:/_sq/Stories/config/Story2-storyview}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link to=<<storyview>>>\n<$transclude tiddler=<<icon>>/>\n<$text text=<<storyview>>/>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/snippets/viewswitcher",
"tags": "",
"modified": "20200416183434009",
"created": "20200416183108721"
},
"$:/_sq/Stories/config/Story2-storyview": {
"text": "classic",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/Story2-storyview",
"tags": "",
"modified": "20200417205214764",
"created": "20200415213157946"
},
"$:/_sq/Stories/config/twostorybreakpoint": {
"text": "1100px",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/twostorybreakpoint",
"modified": "20200416182753284",
"created": "20170616192701335"
},
"$:/_sq/Stories/CorePatch/ButtonDispatchMessage": {
"text": "var ButtonWidget = require(\"$:/core/modules/widgets/button.js\").button;\n\nButtonWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\"), event: event, navigateFromNode: this});\n};\n\n/*\nInvoke the action widgets that are descendents of the current widget.\n*/\nButtonWidget.prototype.invokeActions = function(triggeringWidget,event) {\nevent.navigateFromNode = this;\n\tvar handled = false;\n\t// For each child widget\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar child = this.children[t];\n\t\t// Invoke the child if it is an action widget\n\t\tif(child.invokeAction) {\n\t\t\tchild.refreshSelf();\n\t\t\tif(child.invokeAction(triggeringWidget,event)) {\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t}\n\t\t// Propagate through through the child if it permits it\n\t\tif(child.allowActionPropagation() && child.invokeActions(triggeringWidget,event)) {\n\t\t\thandled = true;\n\t\t}\n\t}\n\treturn handled;\n};",
"bag": "default",
"revision": "0",
"type": "application/javascript",
"title": "$:/_sq/Stories/CorePatch/ButtonDispatchMessage",
"tags": "",
"module-type": "startup",
"modified": "20200430193633599",
"created": "20170616103202530"
},
"$:/_sq/Stories/divertTiddlerEditMacro": {
"text": "\\define divertTiddlerEditButton()\n<$set name=\"original\" value={{!!draft.title}}>\n<$set name=\"otherStoryList\" filter=\"[enlist{$:/_sq/Stories/StoriesList!!list}] -[<tv-story-list>]\" select=\"0\">\n<$set name=\"otherHistoryList\" filter=\"[enlist{$:/_sq/Stories/HistoriesList!!list}] -[<tv-history-list>]\" select=\"0\">\n\t<$button class=<<tv-config-toolbar-class>> tooltip=\"Divert this tiddler to the other story for viewing\">\n\t\t<$navigator story=<<otherStoryList>> history=<<otherHistoryList>> >\n\t\t\t<$action-navigate $to=<<original>> />\n\t\t</$navigator>\n\t\t<span class=\"sq-button-divert-right sq-button-divert\">{{$:/_sq/Stories/icons/divert-right.svg}}</span><span class=\"sq-button-divert-left sq-button-divert\">{{$:/_sq/Stories/icons/divert-left.svg}}</span>\n\t</$button>\n</$set>\n</$set>\n</$set>\n\\end\n\n<<divertTiddlerEditButton>>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/divertTiddlerEditMacro",
"tags": "$:/tags/EditToolbar",
"modified": "20200523202347182",
"list-before": "$:/core/ui/Buttons/delete",
"description": "divert right/left",
"created": "20170616074148780",
"caption": "{{$:/_sq/Stories/icons/divert-right.svg}}"
},
"$:/_sq/Stories/divertTiddlerMacro": {
"created": "20170609055347900",
"text": "\\define divertTiddlerButton()\n<$set name=\"otherStoryList\" filter=\"[enlist{$:/_sq/Stories/StoriesList!!list}] -[<tv-story-list>]\" select=\"0\">\n<$set name=\"otherHistoryList\" filter=\"[enlist{$:/_sq/Stories/HistoriesList!!list}] -[<tv-history-list>]\" select=\"0\">\n\t<$button class=<<tv-config-toolbar-class>> tooltip=\"Divert this tiddler to the other story\">\n\t\t<$navigator story=<<tv-story-list>> history=<<tv-history-list>> >\n\t\t\t<$action-sendmessage $message=\"tm-close-tiddler\" $param=<<currentTiddler>> />\n\t\t</$navigator>\n\t\t<$navigator story=<<otherStoryList>> history=<<otherHistoryList>> >\n\t\t\t<$action-navigate $to=<<currentTiddler>> />\n\t\t</$navigator>\t\n\t\t<span class=\"sq-button-divert-right sq-button-divert\">{{$:/_sq/Stories/icons/divert-right.svg}}</span><span class=\"sq-button-divert-left sq-button-divert\">{{$:/_sq/Stories/icons/divert-left.svg}}</span>\n\t</$button>\n</$set>\n</$set>\n\\end\n\n<<divertTiddlerButton>>\n",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/divertTiddlerMacro",
"tags": "$:/tags/ViewToolbar",
"modified": "20200806034422564",
"list-before": "",
"description": "Divert left/right",
"caption": "{{$:/_sq/Stories/icons/divert-right.svg}} divert left/right"
},
"$:/_sq/Stories/EditTiddlerHook": {
"text": "$tw.hooks.addHook(\"th-editing-tiddler\", function(event) {\n\tvar targetTitle = event.tiddlerTitle;\n\tvar stories = $tw.wiki.getTiddlerList('$:/_sq/Stories/StoriesList');\n\tvar draftTitle = $tw.wiki.findDraft(targetTitle);\n\tvar shiftKey = (event && event.event) ? event.event.shiftKey : null;\n\n\t//if !draftTitle, its not open anywhere\n\t//cant be open without existing, but can exist without being opened\n\n\tif(!draftTitle && !shiftKey) {\n\t\treturn true;\n\t}\n\n\tvar node = event.navigateFromNode;\n\tvar thisStory = node.getVariable(\"tv-story-title\");\n\tvar otherStory = (stories[0] == thisStory)? stories[1] : stories[0];\n\tvar otherStoryList = $tw.wiki.getTiddlerList(otherStory);\n\n\tif(otherStoryList.indexOf(draftTitle) > -1) {\n\t\talert(\"This tiddler is already open for editing in the other story\");\n\t\treturn false;\n\t}\n\n\tvar generateDraftTitle = function(title) {\n\t\tvar c = 0,\n\t\tdraftTitle;\n\t\tdo {\n\t\t\tdraftTitle = \"Draft \" + (c ? (c + 1) + \" \" : \"\") + \"of '\" + title + \"'\";\n\t\t\tc++;\n\t\t} while($tw.wiki.tiddlerExists(draftTitle));\n\t\treturn draftTitle;\n\t};\n\t\n\tif(shiftKey) {\n //open in other story\n\t\tif(!draftTitle) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(targetTitle);\n\t\t\tdraftTitle = generateDraftTitle(targetTitle);\n\t\t\tvar draftTiddler = new $tw.Tiddler(\n\t\t\t\ttiddler,\n\t\t\t\t{\n\t\t\t\t\ttitle: draftTitle,\n\t\t\t\t\t\"draft.title\": targetTitle,\n\t\t\t\t\t\"draft.of\": targetTitle\n\t\t\t\t},\n\t\t\t\t$tw.wiki.getModificationFields()\n\t\t\t);\n\t\t\t$tw.wiki.addTiddler(draftTiddler);\n\t\t}\n\t\tvar otherStoryTiddler = $tw.wiki.getTiddler(otherStory);\n\t\totherStoryList.splice(0 ,0, draftTitle);\n\t\t$tw.wiki.addTiddler(new $tw.Tiddler(\n\t\t\t{title: otherStory},\n\t\t\totherStoryTiddler,\n\t\t\t{list:otherStoryList}\n\t\t));\n\t\treturn false;\n\t}\n\n\treturn true;\n});\n",
"bag": "default",
"revision": "0",
"type": "application/javascript",
"title": "$:/_sq/Stories/EditTiddlerHook",
"tags": "",
"module-type": "startup",
"modified": "20200729135111179",
"created": "20170616091547338"
},
"$:/_sq/Stories/HistoriesList": {
"text": "",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/HistoriesList",
"tags": "",
"modified": "20200414145004336",
"list": "$:/_sq/Stories/Story2HistoryList $:/HistoryList",
"created": "20170610091606312"
},
"$:/_sq/Stories/icons/bars-empty.svg": {
"text": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 100 100\" version=\"1.1\" x=\"0px\" y=\"0px\" class=\"tc-image-bars-empty tc-image-button\" width=\"40pt\" height=\"40pt\"><title>Single fold</title><desc>Created with Sketch.</desc><g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\"><g stroke=\"#000000\"><rect stroke-width=\"2\" x=\"17\" y=\"17\" width=\"66\" height=\"66\" rx=\"2\"/><path d=\"M50.5,18.5 L50.5,80.789646\" stroke-linecap=\"round\" stroke-dasharray=\"2,3,2,3\"/></g></g></svg>",
"bag": "default",
"revision": "0",
"type": "image/svg+xml",
"title": "$:/_sq/Stories/icons/bars-empty.svg",
"tags": "",
"modified": "20200414145004334",
"created": "20170617203017607"
},
"$:/_sq/Stories/icons/bars.svg": {
"text": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\" class=\"tc-image-bars tc-image-button\" width=\"20\" height=\"20\" ><path d=\"M41.667,0h-37.5C0,0,0,0,0,4.167v91.667C0,100,0,100,4.167,100h37.5c4.167,0,4.167,0,4.167-4.167V4.167 C45.833,0,45.833,0,41.667,0z M95.833,0h-37.5c-4.167,0-4.167,0-4.167,4.167v91.667c0,4.167,0,4.167,4.167,4.167h37.5 C100,100,100,100,100,95.833V4.167C100,0,100,0,95.833,0z\"/></svg>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/icons/bars.svg",
"modified": "20200414145004333",
"created": "20170608202154511"
},
"$:/_sq/Stories/icons/divert-left.svg": {
"text": "<svg class=\"tc-image-button\" x=\"0px\" y=\"0px\" width=\"30pt\" height=\"30pt\" viewBox=\"0 0 100 125\" ><path d=\"M7.197,44.697l27.5-27.5c2.929-2.929,7.678-2.929,10.607,0c2.929,2.929,2.929,7.678,0,10.607L30.607,42.5H70 h0c5.118,0,10.237,1.953,14.142,5.858c7.81,7.81,7.81,20.474,0,28.284c-2.929,2.929-7.678,2.929-10.607,0 c-2.929-2.929-2.929-7.678,0-10.607c1.953-1.953,1.953-5.118,0-7.071C72.559,57.988,71.28,57.5,70,57.5h0v0H30.607l14.697,14.697 c2.929,2.929,2.929,7.678,0,10.607c-2.929,2.929-7.678,2.929-10.607,0L16.036,64.142l-8.839-8.839 C4.268,52.374,4.268,47.626,7.197,44.697z\"/></svg>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/icons/divert-left.svg",
"modified": "20200414145004330",
"created": "20170609061834078"
},
"$:/_sq/Stories/icons/divert-right.svg": {
"text": "<svg class=\"tc-image-button\" x=\"0px\" y=\"0px\" width=\"30pt\" height=\"30pt\" viewBox=\"0 0 100 125\" ><path d=\"M92.803,44.697l-27.5-27.5c-2.929-2.929-7.678-2.929-10.607,0c-2.929,2.929-2.929,7.678,0,10.607 L69.393,42.5H30h0c-5.118,0-10.237,1.953-14.142,5.858c-7.81,7.81-7.81,20.474,0,28.284c2.929,2.929,7.678,2.929,10.607,0 c2.929-2.929,2.929-7.678,0-10.607c-1.953-1.953-1.953-5.118,0-7.071C27.441,57.988,28.72,57.5,30,57.5h0v0h39.393L54.697,72.197 c-2.929,2.929-2.929,7.678,0,10.607s7.678,2.929,10.607,0l18.661-18.661l8.839-8.839C95.732,52.374,95.732,47.626,92.803,44.697z\"/></svg>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/icons/divert-right.svg",
"modified": "20200414145004328",
"created": "20170609061824401"
},
"$:/_sq/Stories/LinkKeybindings": {
"text": "$tw.hooks.addHook('th-navigating', function(event) {\n\t//override core behaviour when shift key was used\n\tif( ((event.event && event.event.shiftKey) || (event.shiftKey && event)) && event.navigateTo) {\n\t\tvar stories = $tw.wiki.getTiddlerList('$:/_sq/Stories/StoriesList');\n\t\tvar node = event.navigateFromNode;\n\t\tvar thisStory = node.getVariable(\"tv-story-list\");\n\t\tvar otherStory = (stories[0] == thisStory)? stories[1] : stories[0];\t\n\t\tvar storyList = $tw.wiki.getTiddlerList(otherStory);\n\t\tvar slot = storyList.indexOf(event.navigateTo);\n\t\t\n\t\tif(slot < 0){\n\t\t\tif($tw.wiki.getTiddlerText(\"$:/config/Navigation/openLinkFromOutsideRiver\") === \"bottom\") {\n\t\t\t\n\t\t\t\tstoryList.splice(storyList.length, 0, event.navigateTo);\n\t\t\t} else {\n\t\t\t\tstoryList.splice(0, 0, event.navigateTo);\n\t\t\t}\n\t\t\tvar storyTiddler =\t$tw.wiki.getTiddler(otherStory);\n\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(\n\t\t\t\t{title: otherStory},\n\t\t\t\tstoryTiddler,\n\t\t\t\t{list:storyList}\n\t\t\t));\n\t\t}\n\t\tvar histories = $tw.wiki.getTiddlerList('$:/_sq/Stories/HistoriesList');\n\t\tvar thisHistory = node.getVariable(\"tv-history-list\");\n\t\tvar otherHistory = (histories[0] == thisHistory) ? histories[1] : histories[0];\t\t\n\t\t$tw.wiki.addToHistory(event.navigateTo,event.navigateFromClientRect, otherHistory); \n\t\tif($tw.wiki.getTiddlerText(\"$:/config/_sq/Stories/story2\") === \"no\") {\n\t\t\t$tw.wiki.setText(\"$:/config/_sq/Stories/story2\",undefined,undefined,\"yes\",undefined);\n\t\t}\n\t\tevent.navigateTo = false;\n\t}\n\treturn event;\n});",
"bag": "default",
"revision": "0",
"type": "application/javascript",
"title": "$:/_sq/Stories/LinkKeybindings",
"tags": "",
"module-type": "startup",
"modified": "20200422065240983",
"created": "20170610071940508"
},
"$:/_sq/Stories/startup-actions": {
"text": "<$action-deletetiddler $tiddler=\"$:/_sq/Stories/Story2HistoryList\"/>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/startup-actions",
"tags": "$:/tags/StartupAction/Browser",
"modified": "20200417172054199",
"created": "20200417171756341"
},
"$:/_sq/Stories/Stories.css": {
"text": "\\define if-fluid-fixed(text,disableText)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" type=\"match\" text=\"fluid-fixed\">\n$text$\n</$reveal>\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" type=\"nomatch\" text=\"fluid-fixed\">\n$disableText$\n</$reveal>\n\\end\n\n\\define if-two-stories(twoStoryCommon, twoStorySidebar twoStoryNoSidebar, oneStoryText)\n<$reveal default=\"yes\" type=\"match\" text={{{[{$:/_sq/Stories/Story2StoryList!!list}length[]match[0]then[no]] ~[{$:/config/_sq/Stories/story2}]}}}>\n$twoStoryCommon$\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\">\n$twoStorySidebar$\n</$reveal>\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">\n$twoStoryNoSidebar$\n</$reveal>\n</$reveal>\n<$reveal default=\"yes\" type=\"nomatch\" text={{{[{$:/_sq/Stories/Story2StoryList!!list}length[]match[0]then[no]] ~[{$:/config/_sq/Stories/story2}]}}}>\n$oneStoryText$\n</$reveal>\n\\end\n\n\n<pre>\n\n.tc-page-container.tc-page-view-zoomin .tc-storyview-zoomin-tiddler {\n\twidth: 100%;\n\tposition: relative;\n}\n\n.tc-btn-storytwotoggle {\n\tpadding:0px;\n}\n\n.tc-btn-storytwotoggle img {\n\twidth: 30px;\n\theight: 30px;\n}\n\n.tc-sidebar-lists .tc-btn-storytwotoggle-bars {\n\tfont-size: 1.5em;\n}\n\n.tc-sidebar-lists .tc-btn-storytwotoggle-bars svg {\n\tfill: #aaa;\n}\n\n.tc-story-river .sq-button-divert-left{\n\tdisplay: none;\n}\n\n.sq-story-rivertwo-scrollable::-webkit-scrollbar{width:10px}\n\n.sq-story-rivertwo-scrollable::-webkit-scrollbar-thumb{background:#a5a5a5;border-radius:10px}\n\n.sq-story-rivertwo-scrollable::-webkit-scrollbar-thumb:hover{background:#6f6f6f}\n\n.sq-story-rivertwo-scrollable::-webkit-scrollbar-thumb:active{background:#333}\n\n\t.tc-sidebar-tab-open.sq-sidebar-open .tc-btn-invisible.tc-btn-mini {\n\t\tpadding: 0 0.2em;\n\t}\n\n\t.tc-sidebar-tab-open.sq-sidebar-open .tc-sidebar-tab-open-item {\n\t\tpadding: 0.1em;\n\t}\n\t\n\thtml body.tc-body .tc-sidebar-tab-open.sq-sidebar-open a.tc-tiddlylink {\n\t\tfont-weight: 400;\n\t}\n\n.tc-sidebar-tab-open.sq-sidebar-open a.tc-tiddlylink {\n\tcolor:<<color very-muted-foreground>>;\n}\n\n.tc-sidebar-tab-open.sq-sidebar-open a.tc-tiddlylink:hover {\n\tcolor: <<color sidebar-tiddler-link-foreground-hover>>;\n}\n\n<<if-two-stories twoStoryCommon:\"\"\"\n@media (min-width: {{$:/_sq/Stories/config/twostorybreakpoint}}) {\n.sq-story-rivertwo-scrollable {\n\tposition: fixed;\n\ttop: calc(1em + {{$:/themes/tiddlywiki/vanilla/metrics/storytop}});\n\tbottom: 0;\n}\n\n.tc-story-river.sq-story-rivertwo .tc-tiddler-frame {\n\tmargin-right: 1em !important;\n\tmargin-left: 0;\n\tfont-size: {{$:/config/sq/Stories/story2/fontsize-title}}px;\n}\n\n.tc-story-river.sq-story-rivertwo .tc-tiddler-frame .tc-tiddler-body {\n\tfont-size: {{$:/config/sq/Stories/story2/fontsize-body}}px;\n}\n\n.tc-story-river {\n\tfloat: left;\n\tmargin-right: 0;\n\tpadding-right: 0em;\n\tpadding-top: 0em;\n}\n\nbody .tc-story-river {\n\tpadding: 0 1.5em 1em 0em !important;\n\tmin-height: 500px; /** so story 2 doesnt collapse to left when no tiddler in story 1***/ \n}\n\nbody .tc-story-river.tc-storytwo-river { padding-right:0em !important; }\n\nbody section.story-backdrop p:nth-child(1) {\n\tmargin:0;\n\tpadding:0;\n}\n\n.tc-story-river .sq-button-divert-right{\n\tdisplay:inline-block;\n}\n\n.tc-story-river .sq-button-divert-left{\n\tdisplay: none;\n}\n\n.tc-story-river.sq-story-rivertwo .sq-button-divert-left{\n\tdisplay:inline-block;\n}\n\n.tc-story-river.sq-story-rivertwo .sq-button-divert-right{\n\tdisplay: none;\n}\n\n.sq-storydropzone {\n\tpadding: 0.5em;\n\tborder:1px solid #bbb;\n\tcolor: #ccc;\n\ttext-align: center;\n\tposition: relative;\n\twidth: calc(100% - 45px);\n\t-moz-box-shadow: inset 0 0 10px #ccc;\n\t-webkit-box-shadow: inset 0 0 10px #ccc;\n\tbox-shadow: inset 0 0 10px #ccc;\n\tmargin-bottom: 1em;\n}\n\n.sq-storydropzone-newtiddlerbutton {\n\twidth: 40px;\n\tfloat: right;\n\tpadding: 0.2em 0.5em 0.5em 0.5em;\n\tmargin-top: 0em;\n\tmargin-right: 0.2em;\n}\n\n.tc-tiddler-frame {\n\tpadding-right:28px;\n}\n\n}\n\"\"\" twoStorySidebar:\"\"\"\n\n@media (min-width: {{$:/_sq/Stories/config/twostorybreakpoint}}) {\n.tc-story-river {\n\twidth: calc((100% - {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}} - {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}} + 14px)*{{$:/config/sq/Stories/storyRiverRatio}}/100);\n}\n\n.sq-storydropzone {\n\tpadding: 0.5em;\n\tborder:1px solid #bbb;\n\tcolor: #ccc;\n\ttext-align: center;\n}\n\n.sq-story-rivertwo-scrollable, .sq-story-rivertwo {\n\twidth: calc((100% - {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}} - {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}} + 14px)*(100 - {{$:/config/sq/Stories/storyRiverRatio}})/100);\n}\n}\n\n.tc-sidebar-scrollable {\n\twidth: calc({{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}} - 14px);\n\tpadding-left: 28px;\n}\n\n@media (min-width: {{$:/_sq/Stories/config/twostorybreakpoint}}) and (max-width: {{$:/_sq/Stories/config/sidebaroverlaybreakpoint}}) {\n\t\n\t.tc-story-river {\n\t\twidth: calc((100% - 1em)*{{$:/config/sq/Stories/storyRiverRatio}}/100);\n\t}\n\n\t.sq-story-rivertwo {\n\t\twidth: calc((100% - 1em)*(100 - {{$:/config/sq/Stories/storyRiverRatio}})/100);\n\t}\n\t\n\n\t.sq-story-rivertwo-scrollable {\n\t\twidth: calc((100% - 0.5em)*(100 - {{$:/config/sq/Stories/storyRiverRatio}})/100);\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tz-index:999;\n\t\tbackground:#eee;\n\t\tborder-left: 1px solid #ddd;\n\t}\n\n}\n\n\"\"\" twoStoryNoSidebar:\"\"\"\n\n.tc-story-river.sq-story-rivertwo {\n\tpadding-right: 0.5em;\n}\n\n@media (min-width: {{$:/_sq/Stories/config/twostorybreakpoint}}) {\n.tc-story-river {\n\twidth: calc((100% - 1em)*{{$:/config/sq/Stories/storyRiverRatio}}/100);\n}\n\n.sq-story-rivertwo {\n\twidth: calc((100% - 1em)*(100 - {{$:/config/sq/Stories/storyRiverRatio}})/100);\n}\n}\n\n.sq-story-rivertwo-scrollable {\n\twidth: calc((100% - 0.5em)*(100 - {{$:/config/sq/Stories/storyRiverRatio}})/100);\n}\n\n\n\n\n}\n\n@media (min-width: {{$:/_sq/Stories/config/twostorybreakpoint}}) and (max-width: {{$:/_sq/Stories/config/sidebaroverlaybreakpoint}}) {\n\t.tc-sidebar-scrollable {\n\t\tdisplay:none;\n\t}\n}\n\n\"\"\" oneStoryText: \"\"\"\n.sq-twostoriesonly {\n\tdisplay: none;\n}\n\n.tc-story-river {\n\tpadding-top: 15px;\n}\n\n\"\"\"\n>>\n\n@media (max-width: {{$:/_sq/Stories/config/twostorybreakpoint}}) {\n\t.sq-twostoriesonly {\n\t\tdisplay: none;\n\t}\n\n\t.tc-btn-storytwotoggle {\n\t\tdisplay: none;\n\t}\n\n\t.sq-stories-disabled {\n\t\tdisplay: none;\n\t}\n\n<<if-two-stories twoStoryCommon:\"\"\"\n\n\t.tc-storytwo-river {\n\t\tdisplay: none;\n\t}\n\n\t.tc-story-river {\n\t\twidth: auto;\n\t\tpadding-top: 15px;\n\t}\n\n\t.tc-story-river .sq-button-divert {\n\t\tdisplay: none;\n\t}\n\n\n\t.sq-story-rivertwo-scrollable {\n\t\tdisplay:none;\n\t}\n\n\n\"\"\" twoStorySidebar:\"\"\"\n\t.tc-story-river {\n\t\tmargin-right: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tborder-left: 0;\n\t\tz-index: inherit;\n\t\tbackground: transparent;\n\t}\n\"\"\" twoStoryNoSidebar: \"\"\"\n\t.tc-story-river {\n\t\tpadding-right: 2em;\n\t}\n\"\"\"\n\n>>\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n.tc-story-river {\nmargin-right: 0;\n}\n}\n\n\n</pre>\n",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/Stories.css",
"tags": "$:/tags/Stylesheet",
"modified": "20200731105030883",
"created": "20170608102837192"
},
"$:/_sq/Stories/StoriesList": {
"text": "",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/StoriesList",
"tags": "",
"modified": "20200414145004320",
"list": "$:/_sq/Stories/Story2StoryList $:/StoryList",
"created": "20170610072420739"
},
"$:/_sq/Stories/Story2StoryList": {
"title": "$:/_sq/Stories/Story2StoryList",
"text": "",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"modified": "20200731105210982",
"list": "$:/plugins/sq/Stories/changelog $:/config/sq/Stories/story2/fontsize-title $:/config/sq/Stories/storyRiverRatio [[Pack stories to plugin]]",
"created": "20170615140314952"
},
"$:/_sq/Stories/Templates/RiverDropZone": {
"text": "\\define drop-actions()\n<$action-listops $tiddler=<<otherStoryList>> $subfilter=\"+[remove<actionTiddler>]\"/> \n<$action-navigate $to=<<actionTiddler>>/>\n\\end\n<$reveal state=\"$:/_sq/Stories/config/showRiverDropZones\" text=\"enable\" type=\"match\" default=\"disable\">\n<div class=\"sq-storydropzone-container sq-twostoriesonly\">\n\t<div class=\"sq-storydropzone-newtiddlerbutton tc-page-controls\">\n\t\t<$transclude tiddler=\"$:/core/ui/Buttons/new-tiddler\"/>\n\t</div>\n\t<div style=\"position: relative; \" class=\"sq-storydropzone sq-twostoriesonly\">\n\t\t<$set name=\"otherStoryList\" filter=\"[enlist{$:/_sq/Stories/StoriesList!!list}] -[<tv-story-list>]\" select=\"0\">\n\t\t<$droppable actions=<<drop-actions>>>\n\t\t\t<div class=\"tc-droppable-placeholder\">\n\t\t\t \n\t\t\t</div>\n\t\t\t<div>\n\t\t\t\tDrop link here to open\n\t\t\t</div>\n\t\t</$droppable>\n\t\t</$set>\n\t</div>\n</div>\n</$reveal>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/Templates/RiverDropZone",
"tags": "$:/tags/AboveStory",
"modified": "20200523213430940",
"list-before": "$:/core/ui/PageTemplate/story",
"created": "20170609191118712"
},
"$:/_sq/Stories/Templates/Story2Template": {
"text": "\\whitespace trim\n<$reveal state=\"$:/config/_sq/Stories/story2\" type=\"match\" text=\"yes\" default=\"no\" retain=\"yes\" animate=\"no\" tag=\"section\" class=\"tc-story-river tc-storytwo-river sq-story-rivertwo\">\n\n<$navigator story=\"$:/_sq/Stories/Story2StoryList\" history=\"$:/_sq/Stories/Story2HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n<$scrollable class=\"sq-story-rivertwo-scrollable\" fallthrough=\"no\">\n<section class=\"story-backdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AboveStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n<$list filter=\"[list[$:/_sq/Stories/Story2StoryList]]\" history=\"$:/_sq/Stories/Story2HistoryList\" template={{{[[$:/config/sq/Stories/story2/ViewTemplate]get[text]!is[blank]] ~[[$:/config/ui/ViewTemplate]get[text]]}}} editTemplate={{{[[$:/config/sq/Stories/story2/EditTemplate]get[text]!is[blank]] ~[[$:/config/ui/EditTemplate]get[text]]}}} storyview={{$:/_sq/Stories/config/Story2-storyview}}>\n\n<div>\n<$transclude/>\n</div>\n\n</$list>\n\n<section class=\"story-frontdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/BelowStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n</$scrollable>\n</$navigator>\n\n</$reveal>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/Templates/Story2Template",
"tags": "$:/tags/PageTemplate",
"modified": "20200730045003939",
"list-after": "$:/core/ui/PageTemplate/story",
"created": "20170608171610013"
},
"$:/_sq/Stories/Templates/StoryToggleMenu": {
"text": "<div class=\"sq-twostoriesonly\">\n<$reveal state=\"$:/config/_sq/Stories/story2\" type=\"nomatch\" text=\"no\" default=\"no\">\n<$button set=\"$:/config/_sq/Stories/story2\" setTo=\"no\" tooltip=\"Hide right column\" aria-label=\"\" class=\"tc-btn-invisible tc-btn-storytwotoggle\">{{$:/_sq/Stories/icons/bars-empty.svg}} </$button> Hide right column\n</$reveal>\n</div>\n<$reveal state=\"$:/config/_sq/Stories/story2\" type=\"match\" text=\"no\" default=\"no\">\n<$button set=\"$:/config/_sq/Stories/story2\" setTo=\"yes\" tooltip=\"Show right column\" aria-label=\"\" class=\"tc-btn-invisible tc-btn-storytwotoggle tc-btn-storytwotoggle-bars\">{{$:/_sq/Stories/icons/bars.svg}}</$button> <span class=\"sq-stories-disabled\">Show right column</span>\n</$reveal>\n",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/Templates/StoryToggleMenu",
"modified": "20200425133224298",
"created": "20170608172531552"
},
"$:/_sq/Stories/Templates/StoryTogglePageControl": {
"text": "<span class=\"sq-twostoriesonly\">\n\t<$reveal state=\"$:/config/_sq/Stories/story2\" type=\"nomatch\" text=\"no\" default=\"no\">\n\t\t<$button set=\"$:/config/_sq/Stories/story2\" setTo=\"no\" tooltip=\"Hide right column\" aria-label=\"\" class=\"tc-btn-invisible tc-btn-storytwotoggle\">{{$:/_sq/Stories/icons/bars-empty.svg}} </$button>\n\t</$reveal>\n</span>\n<$reveal state=\"$:/config/_sq/Stories/story2\" type=\"match\" text=\"no\" default=\"no\">\n\t<$button set=\"$:/config/_sq/Stories/story2\" setTo=\"yes\" tooltip=\"Show right column\" aria-label=\"\" class=\"tc-btn-invisible tc-btn-storytwotoggle\">{{$:/_sq/Stories/icons/bars.svg}}</$button>\n</$reveal>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/Templates/StoryTogglePageControl",
"tags": "$:/tags/PageControls",
"modified": "20200425133303133",
"description": "Show right column for second story",
"created": "20170617182141154",
"caption": "{{$:/_sq/Stories/icons/bars.svg}} Show right column"
},
"$:/_sq/Stories/Story2HistoryList": {
"created": "20200425131030296",
"text": "[\n {\n \"title\": \"$:/config/Tiddlers/TitleLinks\",\n \"fromPageRect\": {\n \"top\": 249.296875,\n \"left\": 1230,\n \"width\": 183.515625,\n \"right\": 1413.515625,\n \"bottom\": 269.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerMacro\",\n \"fromPageRect\": {\n \"top\": 623.296875,\n \"left\": 1230,\n \"width\": 220.390625,\n \"right\": 1450.390625,\n \"bottom\": 643.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerMacro\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerMacro\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerEditMacro\",\n \"fromPageRect\": {\n \"top\": 319.296875,\n \"left\": 1230,\n \"width\": 245.53125,\n \"right\": 1475.53125,\n \"bottom\": 339.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerEditMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerEditMacro\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryToggleMenu\",\n \"fromPageRect\": {\n \"top\": 537.296875,\n \"left\": 1230,\n \"width\": 283.546875,\n \"right\": 1513.546875,\n \"bottom\": 557.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\",\n \"fromPageRect\": {\n \"top\": 297.296875,\n \"left\": 1230,\n \"width\": 326.734375,\n \"right\": 1556.734375,\n \"bottom\": 317.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryToggleMenu'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryToggleMenu\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryToggleMenu'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryToggleMenu\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerEditMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerEditMacro\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryToggleMenu'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryToggleMenu\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryToggleMenu'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryToggleMenu\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/Templates/StoryTogglePageControl'\"\n },\n {\n \"title\": \"$:/_sq/Stories/Templates/StoryTogglePageControl\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerEditMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerEditMacro\"\n },\n {\n \"title\": \"$:/core/ui/SideBar/Open\",\n \"fromPageRect\": {\n \"top\": 337.296875,\n \"left\": 1230,\n \"width\": 161.8125,\n \"right\": 1391.8125,\n \"bottom\": 357.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/core/ui/SideBar/Open'\"\n },\n {\n \"title\": \"$:/core/ui/SideBar/Open\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerEditMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerEditMacro\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/divertTiddlerEditMacro'\"\n },\n {\n \"title\": \"$:/_sq/Stories/divertTiddlerEditMacro\"\n },\n {\n \"title\": \"TiddlyBlink\"\n },\n {\n \"title\": \"Stories-overview\",\n \"fromPageRect\": {\n \"top\": 1035.921875,\n \"left\": 1190,\n \"width\": 101.6875,\n \"right\": 1291.6875,\n \"bottom\": 1054.921875,\n \"height\": 19\n }\n },\n {\n \"title\": \"$:/.giffmex/Customize.TiddlyBlink\",\n \"fromPageRect\": {\n \"top\": 735.625,\n \"left\": 107.5,\n \"width\": 145.171875,\n \"right\": 252.671875,\n \"bottom\": 755.625,\n \"height\": 20\n }\n },\n {\n \"title\": \"$:/.giffmex/meta/hack.tiddlyblink\",\n \"fromPageRect\": {\n \"top\": 757.625,\n \"left\": 107.5,\n \"width\": 129.59375,\n \"right\": 237.09375,\n \"bottom\": 777.625,\n \"height\": 20\n }\n },\n {\n \"title\": \"TiddlyBlink\",\n \"fromPageRect\": {\n \"top\": 161.296875,\n \"left\": 221.953125,\n \"width\": 71.859375,\n \"right\": 293.8125,\n \"bottom\": 181.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"TiddlyBlink\",\n \"fromPageRect\": {\n \"top\": 161.296875,\n \"left\": 221.953125,\n \"width\": 71.859375,\n \"right\": 293.8125,\n \"bottom\": 181.296875,\n \"height\": 20\n }\n },\n {\n \"title\": \"Stories-overview\",\n \"fromPageRect\": {}\n },\n {\n \"title\": \"Draft of 'Stories-overview'\"\n },\n {\n \"title\": \"Stories-overview\"\n },\n {\n \"title\": \"Draft of 'Stories-overview'\"\n },\n {\n \"title\": \"Stories-overview\"\n },\n {\n \"title\": \"Draft of 'Stories'\"\n },\n {\n \"title\": \"Plugin maker\",\n \"fromPageRect\": {\n \"top\": 481.34375,\n \"left\": 2259,\n \"width\": 80.890625,\n \"right\": 2339.890625,\n \"bottom\": 500.34375,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of 'Plugin maker'\"\n },\n {\n \"title\": \"Plugin maker\"\n },\n {\n \"title\": \"Stories\",\n \"fromPageRect\": {\n \"top\": 296.84375,\n \"left\": 2259,\n \"width\": 41.453125,\n \"right\": 2300.453125,\n \"bottom\": 315.84375,\n \"height\": 19\n }\n },\n {\n \"title\": \"Plugin maker\",\n \"fromPageRect\": {\n \"top\": 501.34375,\n \"left\": 2259,\n \"width\": 80.890625,\n \"right\": 2339.890625,\n \"bottom\": 520.34375,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of 'Plugin maker'\"\n },\n {\n \"title\": \"Plugin maker\"\n },\n {\n \"title\": \"Draft of 'Stories'\"\n },\n {\n \"title\": \"Stories\"\n },\n {\n \"title\": \"$:/_sq/Stories/config/Settings\",\n \"fromPageRect\": {\n \"top\": 360.171875,\n \"left\": 1245,\n \"width\": 182.21875,\n \"right\": 1427.21875,\n \"bottom\": 379.171875,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/config/Settings'\"\n },\n {\n \"title\": \"$:/_sq/Stories/config/Settings\"\n },\n {\n \"title\": \"$:/_sq/Stories/config/Settings\",\n \"fromPageRect\": {\n \"top\": 360.171875,\n \"left\": 1245,\n \"width\": 182.21875,\n \"right\": 1427.21875,\n \"bottom\": 379.171875,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/config/Settings'\"\n },\n {\n \"title\": \"$:/_sq/Stories/config/Settings\"\n },\n {\n \"title\": \"Draft of 'Stories'\"\n },\n {\n \"title\": \"Stories\"\n },\n {\n \"title\": \"Draft of 'Stories'\"\n },\n {\n \"title\": \"Stories\"\n },\n {\n \"title\": \"Draft of 'Stories'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories\",\n \"fromPageRect\": {\n \"top\": 463.734375,\n \"left\": 2321.1875,\n \"width\": 476.734375,\n \"right\": 2797.921875,\n \"bottom\": 482.734375,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"Stories-overview\"\n },\n {\n \"title\": \"Draft of 'Stories changelog'\"\n },\n {\n \"title\": \"Stories changelog\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories\",\n \"fromPageRect\": {\n \"top\": 573.203125,\n \"left\": 2255.625,\n \"width\": 127.640625,\n \"right\": 2383.265625,\n \"bottom\": 592.203125,\n \"height\": 19\n }\n },\n {\n \"title\": \"$:/_sq/Stories/widgets/action-addtohistory\",\n \"fromPageRect\": {\n \"top\": 1023.453125,\n \"left\": 1194.5,\n \"width\": 263.703125,\n \"right\": 1458.203125,\n \"bottom\": 1042.453125,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"$:/_sq/Stories/widgets/action-addtohistory\",\n \"fromPageRect\": {\n \"top\": 653.453125,\n \"left\": 1194.5,\n \"width\": 263.703125,\n \"right\": 1458.203125,\n \"bottom\": 672.453125,\n \"height\": 19\n }\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories'\"\n },\n {\n \"title\": \"Draft of 'Stories changelog'\"\n },\n {\n \"title\": \"Stories_changelog\"\n },\n {\n \"title\": \"Draft of 'Stories_changelog'\"\n },\n {\n \"title\": \"$:/_sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/_sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"$:/config/_sq/Stories/story2/EditTemplate\",\n \"fromPageRect\": {\n \"top\": 242.78125,\n \"left\": 1226.5,\n \"width\": 273.875,\n \"right\": 1500.375,\n \"bottom\": 262.78125,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"Draft of 'Pack stories to plugin'\"\n },\n {\n \"title\": \"Pack stories to plugin\"\n },\n {\n \"title\": \"$:/config/sq/Stories/story2/EditTemplate\",\n \"fromPageRect\": {\n \"top\": 242.78125,\n \"left\": 1226.5,\n \"width\": 267.65625,\n \"right\": 1494.15625,\n \"bottom\": 262.78125,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"$:/config/sq/Stories/storyRiverRatio\",\n \"fromPageRect\": {\n \"top\": 330.78125,\n \"left\": 1302.75,\n \"width\": 235.375,\n \"right\": 1538.125,\n \"bottom\": 350.78125,\n \"height\": 20\n }\n },\n {\n \"title\": \"$:/config/sq/Stories/story2-fontsize\",\n \"fromPageRect\": {\n \"top\": 220.78125,\n \"left\": 1522.875,\n \"width\": 234.171875,\n \"right\": 1757.046875,\n \"bottom\": 240.78125,\n \"height\": 20\n }\n },\n {\n \"title\": \"Draft of '$:/config/sq/Stories/story2-fontsize'\"\n },\n {\n \"title\": \"$:/config/sq/Stories/story2/fontsize-title\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n },\n {\n \"title\": \"Draft of '$:/plugins/sq/Stories/changelog'\"\n },\n {\n \"title\": \"$:/plugins/sq/Stories/changelog\"\n }\n]",
"type": "application/json",
"current-tiddler": "$:/plugins/sq/Stories/changelog",
"modified": "20200806034532118",
"title": "$:/_sq/Stories/Story2HistoryList",
"revision": "0",
"bag": "default"
},
"$:/core/ui/SideBar/Open": {
"text": "\\whitespace trim\n\\define lingo-base() $:/language/CloseAll/\n\n\\define drop-actions()\n<$action-listops $tiddler=<<tv-story-list>> $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n<$action-listops $tiddler=<<_otherStory>> $subfilter=\"-[<actionTiddler>]\"/>\n\\end\n\n\\define placeholder()\n<div class=\"tc-droppable-placeholder\"/>\n\\end\n\n\\define droppable-item(button)\n\\whitespace trim\n<$droppable actions=<<drop-actions>>>\n<<placeholder>>\n<div>\n$button$\n</div>\n</$droppable>\n\\end\n\n\\define open-tiddler-list()\n<div class=\"tc-sidebar-tab-open sq-sidebar-open\">\n<$list filter=\"[list<tv-story-list>]\" history=<<tv-history-list>> storyview=\"pop\">\n<div class=\"tc-sidebar-tab-open-item\">\n<$macrocall $name=\"droppable-item\" button=\"\"\"<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=\"tc-btn-invisible tc-btn-mini\">{{$:/core/images/close-button}}</$button> <$link to={{!!title}}><$view field=\"title\"/></$link>\"\"\"/>\n</div>\n</$list>\n<$tiddler tiddler=\"\">\n<div>\n<$macrocall $name=\"droppable-item\" button=\"\"\"<$button message=\"tm-close-all-tiddlers\" class=\"tc-btn-invisible tc-btn-mini\"><<lingo Button>></$button>\"\"\"/>\n</div>\n</$tiddler>\n</div>\n\\end\n\n\n''Left Column''\n<$set name=\"_otherStory\" filter=\"[enlist{$:/_sq/Stories/StoriesList!!list}] -[<tv-story-list>]\" select=\"0\">\n<<open-tiddler-list>>\n</$set>\n<div class=\"sq-twostoriesonly\">\n\n---\n\n''Right Column''\n<$set name=\"_otherStory\" value=<<tv-story-list>> >\n<$set name=\"tv-story-list\" filter=\"[enlist{$:/_sq/Stories/StoriesList!!list}] -[<tv-story-list>]\" select=\"0\">\n<$set name=\"tv-history-list\" filter=\"[enlist{$:/_sq/Stories/HistoriesList!!list}] -[<tv-history-list>]\" select=\"0\">\n<$navigator story=<<tv-story-list>> history=<<tv-history-list>> >\n<<open-tiddler-list>>\n</$navigator>\n</$set>\n</$set>\n</$set>\n\n</div>\n\n---\n\n<$transclude tiddler=\"$:/_sq/Stories/Templates/StoryToggleMenu\"/>",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/core/ui/SideBar/Open",
"tags": "$:/tags/SideBar",
"modified": "20200425133519499",
"created": "20170609174945253",
"caption": "{{$:/language/SideBar/Open/Caption}}"
},
"$:/config/_sq/Stories/story2": {
"text": "yes",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/config/_sq/Stories/story2",
"modified": "20200731104006221",
"created": "20170615081040584"
},
"$:/themes/tiddlywiki/vanilla/options/sidebarlayout": {
"text": "fluid-fixed",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/themes/tiddlywiki/vanilla/options/sidebarlayout",
"tags": "tb",
"modified": "20200416185419828",
"created": "20200127172539001"
},
"$:/plugins/sq/Stories/settings": {
"text": "\\define switchStoryView(storyview,default)\n<$select tiddler='$storyview$' default='$default$'>\n<option value=\"zoomin\"><$text text='one tiddler only'/></option>\n<option value=\"classic\"><$text text='multiple tiddlers'/></option>\n</$select>\n\\end\n\n|[[Minimum width to show the second story|$:/_sq/Stories/config/twostorybreakpoint]] |<$edit-text tiddler=\"$:/_sq/Stories/config/twostorybreakpoint\" default=\"\" tag=\"input\"/> |\n|[[Minimum width to show non-overlapping sidebar|$:/_sq/Stories/config/sidebaroverlaybreakpoint]] |<$edit-text tiddler=\"$:/_sq/Stories/config/sidebaroverlaybreakpoint\" default=\"\" tag=\"input\"/> |\n|[[Open tiddlers at top or bottom of story when using divert button|$:/_sq/Stories/config/openLinkDivert]] | <$select tiddler=\"$:/_sq/Stories/config/openLinkDivert\" default=\"top\"><option value=\"top\">top</option><option value=\"bottom\">bottom</option></$select>|\n|<$link to=\"$:/_sq/Stories/config/showRiverDropZones\">Show dropzones above each story</$link>|<$checkbox tiddler=\"$:/_sq/Stories/config/showRiverDropZones\" field=\"text\" checked=\"enable\" unchecked=\"disable\" default=\"disable\"></$checkbox>|\n|[[Story view for second story|$:/_sq/Stories/config/Story2-storyview]]:|{{$:/_sq/Stories/config/snippets/viewswitcher}}|\n\n\n\n''Choose how to view tiddlers in each column''\n\nLeft column: <<switchStoryView $:/view zoomin>>\n\nRight column: <<switchStoryView $:/_sq/Stories/config/Story2-storyview classic>>\n\n''Left column to right column width ratio:''\n\n{{$:/config/sq/Stories/storyRiverRatio}} : <$text text={{{[[100]subtract{$:/config/sq/Stories/storyRiverRatio}]}}}/>\n\n<$range tiddler=\"$:/config/sq/Stories/storyRiverRatio\" min=\"20\" max=\"80\" default=\"50\" increment=\"5\"/> \n<!--\n''Right column font-size''\n\nTiddler: {{$:/config/sq/Stories/story2/fontsize-title}}px\n\n<$range tiddler=\"$:/config/sq/Stories/story2/fontsize-title\" min=\"6\" max=\"40\" default=\"14\" increment=\"1\"/> \n\nBody: {{$:/config/sq/Stories/story2/fontsize-body}}px\n\n<$range tiddler=\"$:/config/sq/Stories/story2/fontsize-body\" min=\"6\" max=\"40\" default=\"15\" increment=\"1\"/> \n\n-->",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/plugins/sq/Stories/settings",
"tags": "$:/tags/ControlPanel/Appearance",
"modified": "20200731105236925",
"created": "20170616185336118",
"caption": "Two Story Layout"
},
"$:/plugins/sq/Stories/changelog": {
"created": "20200430210052275",
"text": "Version 1.03\n\n* Fixed bug in view toolbar position caused by extra blank line in $:/_sq/Stories/divertTiddlerMacro\n\nVersion 1.0.2\n\n* Fixed bug where storyRiverRatio was not respected at some resolutions\n\nVersion 1.0.1\n\n* Added support for config tiddlers to customize view and edit templates for second story. These tiddlers override the core config tiddlers if they exist.\n** $:/config/sq/Stories/story2/EditTemplate\n** $:/config/sq/Stories/story2/ViewTemplate\n* Relative width of each story river can now be customized in settings tab for plugin\n** introduced $:/config/sq/Stories/storyRiverRatio and updated Stories.css accordingly\n\nVersion 1.0.0\n\n* 29/07: updated $:/_sq/Stories/EditTiddlerHook to try and fix https://github.com/felixhayashi/TW5-TiddlyMap/issues/357\n* 23/05 : tweaked Stories.css based on personal theme to allow easier adjustment of story width\n* 23/05 : deprecated action-addtohistory widget\n* 23/05 : updated divertTiddlerEditMacro to use navigator widgets\n* 23/05 : updated divertTiddlerMacro to use navigator widgets\n* 30/04 : updated divertTiddlerEditMacro to also update history and avoid issues with zoomin storyview",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/plugins/sq/Stories/changelog",
"tags": "",
"modified": "20200806034532118"
},
"$:/_sq/Stories/config/storyRiverRatio": {
"text": "50",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/_sq/Stories/config/storyRiverRatio",
"tags": "",
"modified": "20200730045328744",
"created": "20200730040856198"
},
"$:/config/sq/Stories/story2/fontsize-body": {
"text": "15",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/config/sq/Stories/story2/fontsize-body",
"tags": "",
"modified": "20200731104543869",
"created": "20200731102336058"
},
"$:/config/sq/Stories/story2/fontsize-title": {
"text": "14",
"bag": "default",
"revision": "0",
"type": "text/vnd.tiddlywiki",
"title": "$:/config/sq/Stories/story2/fontsize-title",
"tags": "",
"modified": "20200731105040270",
"created": "20200730045554550"
},
"$:/config/sq/Stories/storyRiverRatio": {
"text": "50",
"bag": "default",
"revision": "14",
"type": "text/vnd.tiddlywiki",
"title": "$:/config/sq/Stories/storyRiverRatio",
"tags": "",
"modified": "20200802091529278",
"created": "20200730040856198"
}
}
}
{
"tiddlers": {
"$:/plugins/tiddlywiki/evernote/docs": {
"title": "$:/plugins/tiddlywiki/evernote/docs",
"text": "! Introduction\n\n"
},
"$:/plugins/tiddlywiki/evernote/modules/enex-deserializer.js": {
"title": "$:/plugins/tiddlywiki/evernote/modules/enex-deserializer.js",
"text": "/*\\\ntitle: $:/plugins/tiddlywiki/evernote/modules/enex-deserializer.js\ntype: application/javascript\nmodule-type: tiddlerdeserializer\n\nENEX file deserializer\n\nFor details see: https://blog.evernote.com/tech/2013/08/08/evernote-export-format-enex/\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// DOMParser = require(\"$:/plugins/tiddlywiki/xmldom/dom-parser\").DOMParser;\n\n/*\nParse an ENEX file into tiddlers\n*/\nexports[\"application/enex+xml\"] = function(text,fields) {\n\t// Collect output tiddlers in an array\n\tvar results = [];\n\t// Parse the XML document\n\tvar parser = new DOMParser(),\n\t\tdoc = parser.parseFromString(text,\"application/xml\");\n\t// Output a report tiddler with information about the import\n\tvar enex = doc.querySelector(\"en-export\");\n\tresults.push({\n\t\ttitle: \"Evernote Import Report\",\n\t\ttext: \"Evernote file imported on \" + enex.getAttribute(\"export-date\") + \" from \" + enex.getAttribute(\"application\") + \" (\" + enex.getAttribute(\"version\") + \")\"\n\t})\n\t// Get all the \"note\" nodes\n\tvar noteNodes = doc.querySelectorAll(\"note\");\n\t$tw.utils.each(noteNodes,function(noteNode) {\n\t\tvar result = {\n\t\t\ttitle: getTextContent(noteNode,\"title\"),\n\t\t\ttype: \"text/html\",\n\t\t\ttags: [],\n\t\t\ttext: getTextContent(noteNode,\"content\"),\n\t\t\tmodified: convertDate(getTextContent(noteNode,\"created\")),\n\t\t\tcreated: convertDate(getTextContent(noteNode,\"created\"))\n\n\t\t};\n\t\t$tw.utils.each(noteNode.querySelectorAll(\"tag\"),function(tagNode) {\n\t\t\tresult.tags.push(tagNode.textContent);\n\t\t});\n\t\t// If there's an update date, set modifiy date accordingly\n\t\tvar update = getTextContent(noteNode,\"updated\");\n\t\tif(update) {\n\t\t\tresult.modified = convertDate(update);\n\t\t}\n\t\t$tw.utils.each(noteNode.querySelectorAll(\"note-attributes>*\"),function(attrNode) {\n\t\t\tresult[attrNode.tagName] = attrNode.textContent;\n\t\t});\n\t\tresults.push(result);\n\t\t$tw.utils.each(noteNode.querySelectorAll(\"resource\"),function(resourceNode) {\n\t\t\tresults.push({\n\t\t\t\ttitle: getTextContent(resourceNode,\"resource-attributes>file-name\"),\n\t\t\t\ttype: getTextContent(resourceNode,\"mime\"),\n\t\t\t\twidth: getTextContent(resourceNode,\"width\"),\n\t\t\t\theight: getTextContent(resourceNode,\"height\"),\n\t\t\t\ttext: getTextContent(resourceNode,\"data\")\n\t\t\t});\n\t\t});\n\t});\n\t// Return the output tiddlers\n\treturn results;\n};\n\nfunction getTextContent(node,selector) {\n\treturn (node.querySelector(selector) || {}).textContent;\n}\n\nfunction convertDate(isoDate) {\n\treturn (isoDate || \"\").replace(\"T\",\"\").replace(\"Z\",\"\") + \"000\"\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "tiddlerdeserializer"
},
"$:/plugins/tiddlywiki/evernote/readme": {
"title": "$:/plugins/tiddlywiki/evernote/readme",
"text": "This plugin contains tool to assist migration of content from Evernote ENEX files.\n\n!! Instructions\n\n# Download or save your ENEX file from Evernote\n# Rename the file to have an `.enex` extension\n# Drag the file into the TiddlyWiki browser window\n## Alternatively, click the \"Import\" button in the \"Tools\" sidebar tab\n# Review and accept the converted tiddlers\n"
}
}
}
{
"tiddlers": {
"$:/config/HighlightPlugin/TypeMappings/application/javascript": {
"title": "$:/config/HighlightPlugin/TypeMappings/application/javascript",
"text": "javascript"
},
"$:/config/HighlightPlugin/TypeMappings/application/json": {
"title": "$:/config/HighlightPlugin/TypeMappings/application/json",
"text": "json"
},
"$:/config/HighlightPlugin/TypeMappings/text/css": {
"title": "$:/config/HighlightPlugin/TypeMappings/text/css",
"text": "css"
},
"$:/config/HighlightPlugin/TypeMappings/text/html": {
"title": "$:/config/HighlightPlugin/TypeMappings/text/html",
"text": "html"
},
"$:/config/HighlightPlugin/TypeMappings/image/svg+xml": {
"title": "$:/config/HighlightPlugin/TypeMappings/image/svg+xml",
"text": "xml"
},
"$:/config/HighlightPlugin/TypeMappings/text/x-markdown": {
"title": "$:/config/HighlightPlugin/TypeMappings/text/x-markdown",
"text": "markdown"
},
"$:/plugins/tiddlywiki/highlight/highlight.js": {
"text": "var hljs = require(\"$:/plugins/tiddlywiki/highlight/highlight.js\");\n/*! highlight.js v9.18.1 | BSD3 License | git.io/hljslicense */\n!function(e){var n=\"object\"==typeof window&&window||\"object\"==typeof self&&self;\"undefined\"==typeof exports||exports.nodeType?n&&(n.hljs=e({}),\"function\"==typeof define&&define.amd&&define([],function(){return n.hljs})):e(exports)}(function(a){var f=[],i=Object.keys,_={},c={},C=!0,n=/^(no-?highlight|plain|text)$/i,l=/\\blang(?:uage)?-([\\w-]+)\\b/i,t=/((^(<[^>]+>|\\t|)+|(?:\\n)))/gm,r={case_insensitive:\"cI\",lexemes:\"l\",contains:\"c\",keywords:\"k\",subLanguage:\"sL\",className:\"cN\",begin:\"b\",beginKeywords:\"bK\",end:\"e\",endsWithParent:\"eW\",illegal:\"i\",excludeBegin:\"eB\",excludeEnd:\"eE\",returnBegin:\"rB\",returnEnd:\"rE\",variants:\"v\",IDENT_RE:\"IR\",UNDERSCORE_IDENT_RE:\"UIR\",NUMBER_RE:\"NR\",C_NUMBER_RE:\"CNR\",BINARY_NUMBER_RE:\"BNR\",RE_STARTERS_RE:\"RSR\",BACKSLASH_ESCAPE:\"BE\",APOS_STRING_MODE:\"ASM\",QUOTE_STRING_MODE:\"QSM\",PHRASAL_WORDS_MODE:\"PWM\",C_LINE_COMMENT_MODE:\"CLCM\",C_BLOCK_COMMENT_MODE:\"CBCM\",HASH_COMMENT_MODE:\"HCM\",NUMBER_MODE:\"NM\",C_NUMBER_MODE:\"CNM\",BINARY_NUMBER_MODE:\"BNM\",CSS_NUMBER_MODE:\"CSSNM\",REGEXP_MODE:\"RM\",TITLE_MODE:\"TM\",UNDERSCORE_TITLE_MODE:\"UTM\",COMMENT:\"C\",beginRe:\"bR\",endRe:\"eR\",illegalRe:\"iR\",lexemesRe:\"lR\",terminators:\"t\",terminator_end:\"tE\"},m=\"</span>\",O=\"Could not find the language '{}', did you forget to load/include a language module?\",B={classPrefix:\"hljs-\",tabReplace:null,useBR:!1,languages:void 0},o=\"of and for in not or if then\".split(\" \");function x(e){return e.replace(/&/g,\"&\").replace(/</g,\"<\").replace(/>/g,\">\")}function g(e){return e.nodeName.toLowerCase()}function u(e){return n.test(e)}function s(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function E(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:\"start\",offset:t,node:r}),t=e(r,t),g(r).match(/br|hr|img|input/)||a.push({event:\"stop\",offset:t,node:r}));return t}(e,0),a}function d(e,n,t){var r=0,a=\"\",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:\"start\"===n[0].event?e:n:e.length?e:n}function c(e){a+=\"<\"+g(e)+f.map.call(e.attributes,function(e){return\" \"+e.nodeName+'=\"'+x(e.value).replace(/\"/g,\""\")+'\"'}).join(\"\")+\">\"}function l(e){a+=\"</\"+g(e)+\">\"}function u(e){(\"start\"===e.event?c:l)(e.node)}for(;e.length||n.length;){var s=o();if(a+=x(t.substring(r,s[0].offset)),r=s[0].offset,s===e){for(i.reverse().forEach(l);u(s.splice(0,1)[0]),(s=o())===e&&s.length&&s[0].offset===r;);i.reverse().forEach(c)}else\"start\"===s[0].event?i.push(s[0].node):i.pop(),u(s.splice(0,1)[0])}return a+x(t.substr(r))}function R(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return s(n,{v:null},e)})),n.cached_variants?n.cached_variants:function e(n){return!!n&&(n.eW||e(n.starts))}(n)?[s(n,{starts:n.starts?s(n.starts):null})]:Object.isFrozen(n)?[s(n)]:[n]}function p(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(p)}}function v(n,r){var a={};return\"string\"==typeof n?t(\"keyword\",n):i(n).forEach(function(e){t(e,n[e])}),a;function t(t,e){r&&(e=e.toLowerCase()),e.split(\" \").forEach(function(e){var n=e.split(\"|\");a[n[0]]=[t,function(e,n){return n?Number(n):function(e){return-1!=o.indexOf(e.toLowerCase())}(e)?0:1}(n[0],n[1])]})}}function S(r){function s(e){return e&&e.source||e}function f(e,n){return new RegExp(s(e),\"m\"+(r.cI?\"i\":\"\")+(n?\"g\":\"\"))}function a(a){var i,e,o={},c=[],l={},t=1;function n(e,n){o[t]=e,c.push([e,n]),t+=function(e){return new RegExp(e.toString()+\"|\").exec(\"\").length-1}(n)+1}for(var r=0;r<a.c.length;r++){n(e=a.c[r],e.bK?\"\\\\.?(?:\"+e.b+\")\\\\.?\":e.b)}a.tE&&n(\"end\",a.tE),a.i&&n(\"illegal\",a.i);var u=c.map(function(e){return e[1]});return i=f(function(e,n){for(var t=/\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./,r=0,a=\"\",i=0;i<e.length;i++){var o=r+=1,c=s(e[i]);for(0<i&&(a+=n),a+=\"(\";0<c.length;){var l=t.exec(c);if(null==l){a+=c;break}a+=c.substring(0,l.index),c=c.substring(l.index+l[0].length),\"\\\\\"==l[0][0]&&l[1]?a+=\"\\\\\"+String(Number(l[1])+o):(a+=l[0],\"(\"==l[0]&&r++)}a+=\")\"}return a}(u,\"|\"),!0),l.lastIndex=0,l.exec=function(e){var n;if(0===c.length)return null;i.lastIndex=l.lastIndex;var t=i.exec(e);if(!t)return null;for(var r=0;r<t.length;r++)if(null!=t[r]&&null!=o[\"\"+r]){n=o[\"\"+r];break}return\"string\"==typeof n?(t.type=n,t.extra=[a.i,a.tE]):(t.type=\"begin\",t.rule=n),t},l}if(r.c&&-1!=r.c.indexOf(\"self\")){if(!C)throw new Error(\"ERR: contains `self` is not supported at the top-level of a language. See documentation.\");r.c=r.c.filter(function(e){return\"self\"!=e})}!function n(t,e){t.compiled||(t.compiled=!0,t.k=t.k||t.bK,t.k&&(t.k=v(t.k,r.cI)),t.lR=f(t.l||/\\w+/,!0),e&&(t.bK&&(t.b=\"\\\\b(\"+t.bK.split(\" \").join(\"|\")+\")\\\\b\"),t.b||(t.b=/\\B|\\b/),t.bR=f(t.b),t.endSameAsBegin&&(t.e=t.b),t.e||t.eW||(t.e=/\\B|\\b/),t.e&&(t.eR=f(t.e)),t.tE=s(t.e)||\"\",t.eW&&e.tE&&(t.tE+=(t.e?\"|\":\"\")+e.tE)),t.i&&(t.iR=f(t.i)),null==t.relevance&&(t.relevance=1),t.c||(t.c=[]),t.c=Array.prototype.concat.apply([],t.c.map(function(e){return R(\"self\"===e?t:e)})),t.c.forEach(function(e){n(e,t)}),t.starts&&n(t.starts,e),t.t=a(t))}(r)}function T(n,e,a,t){var i=e;function o(e,n){if(function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}if(e.eW)return o(e.parent,n)}function c(e,n,t,r){if(!t&&\"\"===n)return\"\";if(!e)return n;var a='<span class=\"'+(r?\"\":B.classPrefix);return(a+=e+'\">')+n+(t?\"\":m)}function l(){p+=null!=d.sL?function(){var e=\"string\"==typeof d.sL;if(e&&!_[d.sL])return x(v);var n=e?T(d.sL,v,!0,R[d.sL]):w(v,d.sL.length?d.sL:void 0);return 0<d.relevance&&(M+=n.relevance),e&&(R[d.sL]=n.top),c(n.language,n.value,!1,!0)}():function(){var e,n,t,r,a,i,o;if(!d.k)return x(v);for(r=\"\",n=0,d.lR.lastIndex=0,t=d.lR.exec(v);t;)r+=x(v.substring(n,t.index)),a=d,i=t,void 0,o=g.cI?i[0].toLowerCase():i[0],(e=a.k.hasOwnProperty(o)&&a.k[o])?(M+=e[1],r+=c(e[0],x(t[0]))):r+=x(t[0]),n=d.lR.lastIndex,t=d.lR.exec(v);return r+x(v.substr(n))}(),v=\"\"}function u(e){p+=e.cN?c(e.cN,\"\",!0):\"\",d=Object.create(e,{parent:{value:d}})}function s(e){var n=e[0],t=e.rule;return t&&t.endSameAsBegin&&(t.eR=function(e){return new RegExp(e.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\"),\"m\")}(n)),t.skip?v+=n:(t.eB&&(v+=n),l(),t.rB||t.eB||(v=n)),u(t),t.rB?0:n.length}var f={};function r(e,n){var t=n&&n[0];if(v+=e,null==t)return l(),0;if(\"begin\"==f.type&&\"end\"==n.type&&f.index==n.index&&\"\"===t)return v+=i.slice(n.index,n.index+1),1;if(\"begin\"===(f=n).type)return s(n);if(\"illegal\"===n.type&&!a)throw new Error('Illegal lexeme \"'+t+'\" for mode \"'+(d.cN||\"<unnamed>\")+'\"');if(\"end\"===n.type){var r=function(e){var n=e[0],t=i.substr(e.index),r=o(d,t);if(r){var a=d;for(a.skip?v+=n:(a.rE||a.eE||(v+=n),l(),a.eE&&(v=n));d.cN&&(p+=m),d.skip||d.sL||(M+=d.relevance),(d=d.parent)!==r.parent;);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),u(r.starts)),a.rE?0:n.length}}(n);if(null!=r)return r}return v+=t,t.length}var g=D(n);if(!g)throw console.error(O.replace(\"{}\",n)),new Error('Unknown language: \"'+n+'\"');S(g);var E,d=t||g,R={},p=\"\";for(E=d;E!==g;E=E.parent)E.cN&&(p=c(E.cN,\"\",!0)+p);var v=\"\",M=0;try{for(var b,h,N=0;d.t.lastIndex=N,b=d.t.exec(i);)h=r(i.substring(N,b.index),b),N=b.index+h;for(r(i.substr(N)),E=d;E.parent;E=E.parent)E.cN&&(p+=m);return{relevance:M,value:p,i:!1,language:n,top:d}}catch(e){if(e.message&&-1!==e.message.indexOf(\"Illegal\"))return{i:!0,relevance:0,value:x(i)};if(C)return{relevance:0,value:x(i),language:n,top:d,errorRaised:e};throw e}}function w(t,e){e=e||B.languages||i(_);var r={relevance:0,value:x(t)},a=r;return e.filter(D).filter(L).forEach(function(e){var n=T(e,t,!1);n.language=e,n.relevance>a.relevance&&(a=n),n.relevance>r.relevance&&(a=r,r=n)}),a.language&&(r.second_best=a),r}function M(e){return B.tabReplace||B.useBR?e.replace(t,function(e,n){return B.useBR&&\"\\n\"===e?\"<br>\":B.tabReplace?n.replace(/\\t/g,B.tabReplace):\"\"}):e}function b(e){var n,t,r,a,i,o=function(e){var n,t,r,a,i=e.className+\" \";if(i+=e.parentNode?e.parentNode.className:\"\",t=l.exec(i)){var o=D(t[1]);return o||(console.warn(O.replace(\"{}\",t[1])),console.warn(\"Falling back to no-highlight mode for this block.\",e)),o?t[1]:\"no-highlight\"}for(n=0,r=(i=i.split(/\\s+/)).length;n<r;n++)if(u(a=i[n])||D(a))return a}(e);u(o)||(B.useBR?(n=document.createElement(\"div\")).innerHTML=e.innerHTML.replace(/\\n/g,\"\").replace(/<br[ \\/]*>/g,\"\\n\"):n=e,i=n.textContent,r=o?T(o,i,!0):w(i),(t=E(n)).length&&((a=document.createElement(\"div\")).innerHTML=r.value,r.value=d(t,E(a),i)),r.value=M(r.value),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?c[n]:t,a=[e.trim()];return e.match(/\\bhljs\\b/)||a.push(\"hljs\"),-1===e.indexOf(r)&&a.push(r),a.join(\" \").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.relevance},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.relevance}))}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll(\"pre code\");f.forEach.call(e,b)}}var N={disableAutodetect:!0};function D(e){return e=(e||\"\").toLowerCase(),_[e]||_[c[e]]}function L(e){var n=D(e);return n&&!n.disableAutodetect}return a.highlight=T,a.highlightAuto=w,a.fixMarkup=M,a.highlightBlock=b,a.configure=function(e){B=s(B,e)},a.initHighlighting=h,a.initHighlightingOnLoad=function(){window.addEventListener(\"DOMContentLoaded\",h,!1),window.addEventListener(\"load\",h,!1)},a.registerLanguage=function(n,e){var t;try{t=e(a)}catch(e){if(console.error(\"Language definition for '{}' could not be registered.\".replace(\"{}\",n)),!C)throw e;console.error(e),t=N}p(_[n]=t),t.rawDefinition=e.bind(null,a),t.aliases&&t.aliases.forEach(function(e){c[e]=n})},a.listLanguages=function(){return i(_)},a.getLanguage=D,a.requireLanguage=function(e){var n=D(e);if(n)return n;throw new Error(\"The '{}' language is required, but not loaded.\".replace(\"{}\",e))},a.autoDetection=L,a.inherit=s,a.debugMode=function(){C=!1},a.IR=a.IDENT_RE=\"[a-zA-Z]\\\\w*\",a.UIR=a.UNDERSCORE_IDENT_RE=\"[a-zA-Z_]\\\\w*\",a.NR=a.NUMBER_RE=\"\\\\b\\\\d+(\\\\.\\\\d+)?\",a.CNR=a.C_NUMBER_RE=\"(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",a.BNR=a.BINARY_NUMBER_RE=\"\\\\b(0b[01]+)\",a.RSR=a.RE_STARTERS_RE=\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",a.BE=a.BACKSLASH_ESCAPE={b:\"\\\\\\\\[\\\\s\\\\S]\",relevance:0},a.ASM=a.APOS_STRING_MODE={cN:\"string\",b:\"'\",e:\"'\",i:\"\\\\n\",c:[a.BE]},a.QSM=a.QUOTE_STRING_MODE={cN:\"string\",b:'\"',e:'\"',i:\"\\\\n\",c:[a.BE]},a.PWM=a.PHRASAL_WORDS_MODE={b:/\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/},a.C=a.COMMENT=function(e,n,t){var r=a.inherit({cN:\"comment\",b:e,e:n,c:[]},t||{});return r.c.push(a.PWM),r.c.push({cN:\"doctag\",b:\"(?:TODO|FIXME|NOTE|BUG|XXX):\",relevance:0}),r},a.CLCM=a.C_LINE_COMMENT_MODE=a.C(\"//\",\"$\"),a.CBCM=a.C_BLOCK_COMMENT_MODE=a.C(\"/\\\\*\",\"\\\\*/\"),a.HCM=a.HASH_COMMENT_MODE=a.C(\"#\",\"$\"),a.NM=a.NUMBER_MODE={cN:\"number\",b:a.NR,relevance:0},a.CNM=a.C_NUMBER_MODE={cN:\"number\",b:a.CNR,relevance:0},a.BNM=a.BINARY_NUMBER_MODE={cN:\"number\",b:a.BNR,relevance:0},a.CSSNM=a.CSS_NUMBER_MODE={cN:\"number\",b:a.NR+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",relevance:0},a.RM=a.REGEXP_MODE={cN:\"regexp\",b:/\\//,e:/\\/[gimuy]*/,i:/\\n/,c:[a.BE,{b:/\\[/,e:/\\]/,relevance:0,c:[a.BE]}]},a.TM=a.TITLE_MODE={cN:\"title\",b:a.IR,relevance:0},a.UTM=a.UNDERSCORE_TITLE_MODE={cN:\"title\",b:a.UIR,relevance:0},a.METHOD_GUARD={b:\"\\\\.\\\\s*\"+a.UIR,relevance:0},[a.BE,a.ASM,a.QSM,a.PWM,a.C,a.CLCM,a.CBCM,a.HCM,a.NM,a.CNM,a.BNM,a.CSSNM,a.RM,a.TM,a.UTM,a.METHOD_GUARD].forEach(function(e){!function n(t){Object.freeze(t);var r=\"function\"==typeof t;Object.getOwnPropertyNames(t).forEach(function(e){!t.hasOwnProperty(e)||null===t[e]||\"object\"!=typeof t[e]&&\"function\"!=typeof t[e]||r&&(\"caller\"===e||\"callee\"===e||\"arguments\"===e)||Object.isFrozen(t[e])||n(t[e])});return t}(e)}),a});hljs.registerLanguage(\"swift\",function(e){var i={keyword:\"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet\",literal:\"true false nil\",built_in:\"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip\"},t=e.C(\"/\\\\*\",\"\\\\*/\",{c:[\"self\"]}),n={cN:\"subst\",b:/\\\\\\(/,e:\"\\\\)\",k:i,c:[]},r={cN:\"string\",c:[e.BE,n],v:[{b:/\"\"\"/,e:/\"\"\"/},{b:/\"/,e:/\"/}]},a={cN:\"number\",b:\"\\\\b([\\\\d_]+(\\\\.[\\\\deE_]+)?|0x[a-fA-F0-9_]+(\\\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\\\b\",relevance:0};return n.c=[a],{k:i,c:[r,e.CLCM,t,{cN:\"type\",b:\"\\\\b[A-Z][\\\\wÀ-ʸ']*[!?]\"},{cN:\"type\",b:\"\\\\b[A-Z][\\\\wÀ-ʸ']*\",relevance:0},a,{cN:\"function\",bK:\"func\",e:\"{\",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{b:/</,e:/>/},{cN:\"params\",b:/\\(/,e:/\\)/,endsParent:!0,k:i,c:[\"self\",a,r,e.CBCM,{b:\":\"}],i:/[\"']/}],i:/\\[|%/},{cN:\"class\",bK:\"struct protocol class extension enum\",k:i,e:\"\\\\{\",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][\\u00C0-\\u02B80-9A-Za-z$_]*/})]},{cN:\"meta\",b:\"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain|@dynamicMemberLookup|@propertyWrapper)\"},{bK:\"import\",e:/$/,c:[e.CLCM,t]}]}});hljs.registerLanguage(\"less\",function(e){function r(e){return{cN:\"string\",b:\"~?\"+e+\".*?\"+e}}function t(e,r,t){return{cN:e,b:r,relevance:t}}var a=\"[\\\\w-]+\",c=\"(\"+a+\"|@{\"+a+\"})\",s=[],n=[],b={b:\"\\\\(\",e:\"\\\\)\",c:n,relevance:0};n.push(e.CLCM,e.CBCM,r(\"'\"),r('\"'),e.CSSNM,{b:\"(url|data-uri)\\\\(\",starts:{cN:\"string\",e:\"[\\\\)\\\\n]\",eE:!0}},t(\"number\",\"#[0-9A-Fa-f]+\\\\b\"),b,t(\"variable\",\"@@?\"+a,10),t(\"variable\",\"@{\"+a+\"}\"),t(\"built_in\",\"~?`[^`]*?`\"),{cN:\"attribute\",b:a+\"\\\\s*:\",e:\":\",rB:!0,eE:!0},{cN:\"meta\",b:\"!important\"});var i=n.concat({b:\"{\",e:\"}\",c:s}),l={bK:\"when\",eW:!0,c:[{bK:\"and not\"}].concat(n)},o={b:c+\"\\\\s*:\",rB:!0,e:\"[;}]\",relevance:0,c:[{cN:\"attribute\",b:c,e:\":\",eE:!0,starts:{eW:!0,i:\"[<=$]\",relevance:0,c:n}}]},u={cN:\"keyword\",b:\"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\\\b\",starts:{e:\"[;{}]\",rE:!0,c:n,relevance:0}},v={cN:\"variable\",v:[{b:\"@\"+a+\"\\\\s*:\",relevance:15},{b:\"@\"+a}],starts:{e:\"[;}]\",rE:!0,c:i}},C={v:[{b:\"[\\\\.#:&\\\\[>]\",e:\"[;{}]\"},{b:c,e:\"{\"}],rB:!0,rE:!0,i:\"[<='$\\\"]\",relevance:0,c:[e.CLCM,e.CBCM,l,t(\"keyword\",\"all\\\\b\"),t(\"variable\",\"@{\"+a+\"}\"),t(\"selector-tag\",c+\"%?\",0),t(\"selector-id\",\"#\"+c),t(\"selector-class\",\"\\\\.\"+c,0),t(\"selector-tag\",\"&\",0),{cN:\"selector-attr\",b:\"\\\\[\",e:\"\\\\]\"},{cN:\"selector-pseudo\",b:/:(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"'.]+/},{b:\"\\\\(\",e:\"\\\\)\",c:i},{b:\"!important\"}]};return s.push(e.CLCM,e.CBCM,u,v,o,C),{cI:!0,i:\"[=>'/<($\\\"]\",c:s}});hljs.registerLanguage(\"armasm\",function(s){return{cI:!0,aliases:[\"arm\"],l:\"\\\\.?\"+s.IR,k:{meta:\".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND \",built_in:\"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @\"},c:[{cN:\"keyword\",b:\"\\\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?\",e:\"\\\\s\"},s.C(\"[;@]\",\"$\",{relevance:0}),s.CBCM,s.QSM,{cN:\"string\",b:\"'\",e:\"[^\\\\\\\\]'\",relevance:0},{cN:\"title\",b:\"\\\\|\",e:\"\\\\|\",i:\"\\\\n\",relevance:0},{cN:\"number\",v:[{b:\"[#$=]?0x[0-9a-f]+\"},{b:\"[#$=]?0b[01]+\"},{b:\"[#$=]\\\\d+\"},{b:\"\\\\b\\\\d+\"}],relevance:0},{cN:\"symbol\",v:[{b:\"^[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+\"},{b:\"^\\\\s*[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+:\"},{b:\"[=#]\\\\w+\"}],relevance:0}]}});hljs.registerLanguage(\"ruby\",function(e){var c=\"[a-zA-Z_]\\\\w*[!?=]?|[-+~]\\\\@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?\",b={keyword:\"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor\",literal:\"true false nil\"},r={cN:\"doctag\",b:\"@[A-Za-z]+\"},a={b:\"#<\",e:\">\"},n=[e.C(\"#\",\"$\",{c:[r]}),e.C(\"^\\\\=begin\",\"^\\\\=end\",{c:[r],relevance:10}),e.C(\"^__END__\",\"\\\\n$\")],s={cN:\"subst\",b:\"#\\\\{\",e:\"}\",k:b},t={cN:\"string\",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/\"/,e:/\"/},{b:/`/,e:/`/},{b:\"%[qQwWx]?\\\\(\",e:\"\\\\)\"},{b:\"%[qQwWx]?\\\\[\",e:\"\\\\]\"},{b:\"%[qQwWx]?{\",e:\"}\"},{b:\"%[qQwWx]?<\",e:\">\"},{b:\"%[qQwWx]?/\",e:\"/\"},{b:\"%[qQwWx]?%\",e:\"%\"},{b:\"%[qQwWx]?-\",e:\"-\"},{b:\"%[qQwWx]?\\\\|\",e:\"\\\\|\"},{b:/\\B\\?(\\\\\\d{1,3}|\\\\x[A-Fa-f0-9]{1,2}|\\\\u[A-Fa-f0-9]{4}|\\\\?\\S)\\b/},{b:/<<[-~]?'?(\\w+)(?:.|\\n)*?\\n\\s*\\1\\b/,rB:!0,c:[{b:/<<[-~]?'?/},{b:/\\w+/,endSameAsBegin:!0,c:[e.BE,s]}]}]},i={cN:\"params\",b:\"\\\\(\",e:\"\\\\)\",endsParent:!0,k:b},l=[t,a,{cN:\"class\",bK:\"class module\",e:\"$|;\",i:/=/,c:[e.inherit(e.TM,{b:\"[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|\\\\!)?\"}),{b:\"<\\\\s*\",c:[{b:\"(\"+e.IR+\"::)?\"+e.IR}]}].concat(n)},{cN:\"function\",bK:\"def\",e:\"$|;\",c:[e.inherit(e.TM,{b:c}),i].concat(n)},{b:e.IR+\"::\"},{cN:\"symbol\",b:e.UIR+\"(\\\\!|\\\\?)?:\",relevance:0},{cN:\"symbol\",b:\":(?!\\\\s)\",c:[t,{b:c}],relevance:0},{cN:\"number\",b:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},{b:\"(\\\\$\\\\W)|((\\\\$|\\\\@\\\\@?)(\\\\w+))\"},{cN:\"params\",b:/\\|/,e:/\\|/,k:b},{b:\"(\"+e.RSR+\"|unless)\\\\s*\",k:\"unless\",c:[a,{cN:\"regexp\",c:[e.BE,s],i:/\\n/,v:[{b:\"/\",e:\"/[a-z]*\"},{b:\"%r{\",e:\"}[a-z]*\"},{b:\"%r\\\\(\",e:\"\\\\)[a-z]*\"},{b:\"%r!\",e:\"![a-z]*\"},{b:\"%r\\\\[\",e:\"\\\\][a-z]*\"}]}].concat(n),relevance:0}].concat(n);s.c=l;var d=[{b:/^\\s*=>/,starts:{e:\"$\",c:i.c=l}},{cN:\"meta\",b:\"^([>?]>|[\\\\w#]+\\\\(\\\\w+\\\\):\\\\d+:\\\\d+>|(\\\\w+-)?\\\\d+\\\\.\\\\d+\\\\.\\\\d(p\\\\d+)?[^>]+>)\",starts:{e:\"$\",c:l}}];return{aliases:[\"rb\",\"gemspec\",\"podspec\",\"thor\",\"irb\"],k:b,i:/\\/\\*/,c:n.concat(d).concat(l)}});hljs.registerLanguage(\"lua\",function(e){var t=\"\\\\[=*\\\\[\",a=\"\\\\]=*\\\\]\",n={b:t,e:a,c:[\"self\"]},l=[e.C(\"--(?!\"+t+\")\",\"$\"),e.C(\"--\"+t,a,{c:[n],relevance:10})];return{l:e.UIR,k:{literal:\"true false nil\",keyword:\"and break do else elseif end for goto if in local not or repeat return then until while\",built_in:\"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove\"},c:l.concat([{cN:\"function\",bK:\"function\",e:\"\\\\)\",c:[e.inherit(e.TM,{b:\"([_a-zA-Z]\\\\w*\\\\.)*([_a-zA-Z]\\\\w*:)?[_a-zA-Z]\\\\w*\"}),{cN:\"params\",b:\"\\\\(\",eW:!0,c:l}].concat(l)},e.CNM,e.ASM,e.QSM,{cN:\"string\",b:t,e:a,c:[n],relevance:5}])}});hljs.registerLanguage(\"matlab\",function(e){var a=\"('|\\\\.')+\",s={relevance:0,c:[{b:a}]};return{k:{keyword:\"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while\",built_in:\"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson max min nanmax nanmin mean nanmean type table readtable writetable sortrows sort figure plot plot3 scatter scatter3 cellfun legend intersect ismember procrustes hold num2cell \"},i:'(//|\"|#|/\\\\*|\\\\s+/\\\\w+)',c:[{cN:\"function\",bK:\"function\",e:\"$\",c:[e.UTM,{cN:\"params\",v:[{b:\"\\\\(\",e:\"\\\\)\"},{b:\"\\\\[\",e:\"\\\\]\"}]}]},{cN:\"built_in\",b:/true|false/,relevance:0,starts:s},{b:\"[a-zA-Z][a-zA-Z_0-9]*\"+a,relevance:0},{cN:\"number\",b:e.CNR,relevance:0,starts:s},{cN:\"string\",b:\"'\",e:\"'\",c:[e.BE,{b:\"''\"}]},{b:/\\]|}|\\)/,relevance:0,starts:s},{cN:\"string\",b:'\"',e:'\"',c:[e.BE,{b:'\"\"'}],starts:s},e.C(\"^\\\\s*\\\\%\\\\{\\\\s*$\",\"^\\\\s*\\\\%\\\\}\\\\s*$\"),e.C(\"\\\\%\",\"$\")]}});hljs.registerLanguage(\"apache\",function(e){var r={cN:\"number\",b:\"[\\\\$%]\\\\d+\"};return{aliases:[\"apacheconf\"],cI:!0,c:[e.HCM,{cN:\"section\",b:\"</?\",e:\">\"},{cN:\"attribute\",b:/\\w+/,relevance:0,k:{nomarkup:\"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername\"},starts:{e:/$/,relevance:0,k:{literal:\"on off all\"},c:[{cN:\"meta\",b:\"\\\\s\\\\[\",e:\"\\\\]$\"},{cN:\"variable\",b:\"[\\\\$%]\\\\{\",e:\"\\\\}\",c:[\"self\",r]},r,e.QSM]}}],i:/\\S/}});hljs.registerLanguage(\"yaml\",function(e){var b=\"true false yes no null\",a={cN:\"string\",relevance:0,v:[{b:/'/,e:/'/},{b:/\"/,e:/\"/},{b:/\\S+/}],c:[e.BE,{cN:\"template-variable\",v:[{b:\"{{\",e:\"}}\"},{b:\"%{\",e:\"}\"}]}]};return{cI:!0,aliases:[\"yml\",\"YAML\",\"yaml\"],c:[{cN:\"attr\",v:[{b:\"\\\\w[\\\\w :\\\\/.-]*:(?=[ \\t]|$)\"},{b:'\"\\\\w[\\\\w :\\\\/.-]*\":(?=[ \\t]|$)'},{b:\"'\\\\w[\\\\w :\\\\/.-]*':(?=[ \\t]|$)\"}]},{cN:\"meta\",b:\"^---s*$\",relevance:10},{cN:\"string\",b:\"[\\\\|>]([0-9]?[+-])?[ ]*\\\\n( *)[\\\\S ]+\\\\n(\\\\2[\\\\S ]+\\\\n?)*\"},{b:\"<%[%=-]?\",e:\"[%-]?%>\",sL:\"ruby\",eB:!0,eE:!0,relevance:0},{cN:\"type\",b:\"!\"+e.UIR},{cN:\"type\",b:\"!!\"+e.UIR},{cN:\"meta\",b:\"&\"+e.UIR+\"$\"},{cN:\"meta\",b:\"\\\\*\"+e.UIR+\"$\"},{cN:\"bullet\",b:\"\\\\-(?=[ ]|$)\",relevance:0},e.HCM,{bK:b,k:{literal:b}},{cN:\"number\",b:e.CNR+\"\\\\b\"},a]}});hljs.registerLanguage(\"plaintext\",function(e){return{disableAutodetect:!0}});hljs.registerLanguage(\"erlang-repl\",function(e){return{k:{built_in:\"spawn spawn_link self\",keyword:\"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor\"},c:[{cN:\"meta\",b:\"^[0-9]+> \",relevance:10},e.C(\"%\",\"$\"),{cN:\"number\",b:\"\\\\b(\\\\d+#[a-fA-F0-9]+|\\\\d+(\\\\.\\\\d+)?([eE][-+]?\\\\d+)?)\",relevance:0},e.ASM,e.QSM,{b:\"\\\\?(::)?([A-Z]\\\\w*(::)?)+\"},{b:\"->\"},{b:\"ok\"},{b:\"!\"},{b:\"(\\\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\\\b[a-z'][a-zA-Z0-9_']*)\",relevance:0},{b:\"[A-Z][a-zA-Z0-9_']*\",relevance:0}]}});hljs.registerLanguage(\"cmake\",function(e){return{aliases:[\"cmake.in\"],cI:!0,k:{keyword:\"break cmake_host_system_information cmake_minimum_required cmake_parse_arguments cmake_policy configure_file continue elseif else endforeach endfunction endif endmacro endwhile execute_process file find_file find_library find_package find_path find_program foreach function get_cmake_property get_directory_property get_filename_component get_property if include include_guard list macro mark_as_advanced math message option return separate_arguments set_directory_properties set_property set site_name string unset variable_watch while add_compile_definitions add_compile_options add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_link_options add_subdirectory add_test aux_source_directory build_command create_test_sourcelist define_property enable_language enable_testing export fltk_wrap_ui get_source_file_property get_target_property get_test_property include_directories include_external_msproject include_regular_expression install link_directories link_libraries load_cache project qt_wrap_cpp qt_wrap_ui remove_definitions set_source_files_properties set_target_properties set_tests_properties source_group target_compile_definitions target_compile_features target_compile_options target_include_directories target_link_directories target_link_libraries target_link_options target_sources try_compile try_run ctest_build ctest_configure ctest_coverage ctest_empty_binary_directory ctest_memcheck ctest_read_custom_files ctest_run_script ctest_sleep ctest_start ctest_submit ctest_test ctest_update ctest_upload build_name exec_program export_library_dependencies install_files install_programs install_targets load_command make_directory output_required_files remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or not command policy target test exists is_newer_than is_directory is_symlink is_absolute matches less greater equal less_equal greater_equal strless strgreater strequal strless_equal strgreater_equal version_less version_greater version_equal version_less_equal version_greater_equal in_list defined\"},c:[{cN:\"variable\",b:\"\\\\${\",e:\"}\"},e.HCM,e.QSM,e.NM]}});hljs.registerLanguage(\"kotlin\",function(e){var t={keyword:\"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default\",built_in:\"Byte Short Char Int Long Boolean Float Double Void Unit Nothing\",literal:\"true false null\"},a={cN:\"symbol\",b:e.UIR+\"@\"},n={cN:\"subst\",b:\"\\\\${\",e:\"}\",c:[e.CNM]},c={cN:\"variable\",b:\"\\\\$\"+e.UIR},r={cN:\"string\",v:[{b:'\"\"\"',e:'\"\"\"(?=[^\"])',c:[c,n]},{b:\"'\",e:\"'\",i:/\\n/,c:[e.BE]},{b:'\"',e:'\"',i:/\\n/,c:[e.BE,c,n]}]};n.c.push(r);var i={cN:\"meta\",b:\"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\\\s*:(?:\\\\s*\"+e.UIR+\")?\"},l={cN:\"meta\",b:\"@\"+e.UIR,c:[{b:/\\(/,e:/\\)/,c:[e.inherit(r,{cN:\"meta-string\"})]}]},s={cN:\"number\",b:\"\\\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+)(\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))?|\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))([eE][-+]?\\\\d+)?)[lLfF]?\",relevance:0},b=e.C(\"/\\\\*\",\"\\\\*/\",{c:[e.CBCM]}),o={v:[{cN:\"type\",b:e.UIR},{b:/\\(/,e:/\\)/,c:[]}]},d=o;return d.v[1].c=[o],o.v[1].c=[d],{aliases:[\"kt\"],k:t,c:[e.C(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,c:[{cN:\"doctag\",b:\"@[A-Za-z]+\"}]}),e.CLCM,b,{cN:\"keyword\",b:/\\b(break|continue|return|this)\\b/,starts:{c:[{cN:\"symbol\",b:/@\\w+/}]}},a,i,l,{cN:\"function\",bK:\"fun\",e:\"[(]|$\",rB:!0,eE:!0,k:t,i:/fun\\s+(<.*>)?[^\\s\\(]+(\\s+[^\\s\\(]+)\\s*=/,relevance:5,c:[{b:e.UIR+\"\\\\s*\\\\(\",rB:!0,relevance:0,c:[e.UTM]},{cN:\"type\",b:/</,e:/>/,k:\"reified\",relevance:0},{cN:\"params\",b:/\\(/,e:/\\)/,endsParent:!0,k:t,relevance:0,c:[{b:/:/,e:/[=,\\/]/,eW:!0,c:[o,e.CLCM,b],relevance:0},e.CLCM,b,i,l,r,e.CNM]},b]},{cN:\"class\",bK:\"class interface trait\",e:/[:\\{(]|$/,eE:!0,i:\"extends implements\",c:[{bK:\"public protected internal private constructor\"},e.UTM,{cN:\"type\",b:/</,e:/>/,eB:!0,eE:!0,relevance:0},{cN:\"type\",b:/[,:]\\s*/,e:/[<\\(,]|$/,eB:!0,rE:!0},i,l]},r,{cN:\"meta\",b:\"^#!/usr/bin/env\",e:\"$\",i:\"\\n\"},s]}});hljs.registerLanguage(\"javascript\",function(e){var r=\"<>\",a=\"</>\",t={b:/<[A-Za-z0-9\\\\._:-]+/,e:/\\/[A-Za-z0-9\\\\._:-]+>|\\/>/},c=\"[A-Za-z$_][0-9A-Za-z$_]*\",n={keyword:\"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as\",literal:\"true false null undefined NaN Infinity\",built_in:\"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise\"},s={cN:\"number\",v:[{b:\"\\\\b(0[bB][01]+)n?\"},{b:\"\\\\b(0[oO][0-7]+)n?\"},{b:e.CNR+\"n?\"}],relevance:0},o={cN:\"subst\",b:\"\\\\$\\\\{\",e:\"\\\\}\",k:n,c:[]},i={b:\"html`\",e:\"\",starts:{e:\"`\",rE:!1,c:[e.BE,o],sL:\"xml\"}},b={b:\"css`\",e:\"\",starts:{e:\"`\",rE:!1,c:[e.BE,o],sL:\"css\"}},l={cN:\"string\",b:\"`\",e:\"`\",c:[e.BE,o]};o.c=[e.ASM,e.QSM,i,b,l,s,e.RM];var u=o.c.concat([e.CBCM,e.CLCM]);return{aliases:[\"js\",\"jsx\",\"mjs\",\"cjs\"],k:n,c:[{cN:\"meta\",relevance:10,b:/^\\s*['\"]use (strict|asm)['\"]/},{cN:\"meta\",b:/^#!/,e:/$/},e.ASM,e.QSM,i,b,l,e.CLCM,e.C(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,c:[{cN:\"doctag\",b:\"@[A-Za-z]+\",c:[{cN:\"type\",b:\"\\\\{\",e:\"\\\\}\",relevance:0},{cN:\"variable\",b:c+\"(?=\\\\s*(-)|$)\",endsParent:!0,relevance:0},{b:/(?=[^\\n])\\s/,relevance:0}]}]}),e.CBCM,s,{b:/[{,\\n]\\s*/,relevance:0,c:[{b:c+\"\\\\s*:\",rB:!0,relevance:0,c:[{cN:\"attr\",b:c,relevance:0}]}]},{b:\"(\"+e.RSR+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",k:\"return throw case\",c:[e.CLCM,e.CBCM,e.RM,{cN:\"function\",b:\"(\\\\(.*?\\\\)|\"+c+\")\\\\s*=>\",rB:!0,e:\"\\\\s*=>\",c:[{cN:\"params\",v:[{b:c},{b:/\\(\\s*\\)/},{b:/\\(/,e:/\\)/,eB:!0,eE:!0,k:n,c:u}]}]},{cN:\"\",b:/\\s/,e:/\\s*/,skip:!0},{v:[{b:r,e:a},{b:t.b,e:t.e}],sL:\"xml\",c:[{b:t.b,e:t.e,skip:!0,c:[\"self\"]}]}],relevance:0},{cN:\"function\",bK:\"function\",e:/\\{/,eE:!0,c:[e.inherit(e.TM,{b:c}),{cN:\"params\",b:/\\(/,e:/\\)/,eB:!0,eE:!0,c:u}],i:/\\[|%/},{b:/\\$[(.]/},e.METHOD_GUARD,{cN:\"class\",bK:\"class\",e:/[{;=]/,eE:!0,i:/[:\"\\[\\]]/,c:[{bK:\"extends\"},e.UTM]},{bK:\"constructor get set\",e:/\\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage(\"scss\",function(e){var t=\"@[a-z-]+\",r={cN:\"variable\",b:\"(\\\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\\\b\"},i={cN:\"number\",b:\"#[0-9A-Fa-f]+\"};e.CSSNM,e.QSM,e.ASM,e.CBCM;return{cI:!0,i:\"[=/|']\",c:[e.CLCM,e.CBCM,{cN:\"selector-id\",b:\"\\\\#[A-Za-z0-9_-]+\",relevance:0},{cN:\"selector-class\",b:\"\\\\.[A-Za-z0-9_-]+\",relevance:0},{cN:\"selector-attr\",b:\"\\\\[\",e:\"\\\\]\",i:\"$\"},{cN:\"selector-tag\",b:\"\\\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\\\b\",relevance:0},{cN:\"selector-pseudo\",b:\":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)\"},{cN:\"selector-pseudo\",b:\"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)\"},r,{cN:\"attribute\",b:\"\\\\b(src|z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\\\b\",i:\"[^\\\\s]\"},{b:\"\\\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\\\b\"},{b:\":\",e:\";\",c:[r,i,e.CSSNM,e.QSM,e.ASM,{cN:\"meta\",b:\"!important\"}]},{b:\"@(page|font-face)\",l:t,k:\"@page @font-face\"},{b:\"@\",e:\"[{;]\",rB:!0,k:\"and or not only\",c:[{b:t,cN:\"keyword\"},r,e.QSM,e.ASM,i,e.CSSNM]}]}});hljs.registerLanguage(\"perl\",function(e){var t=\"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when\",r={cN:\"subst\",b:\"[$@]\\\\{\",e:\"\\\\}\",k:t},s={b:\"->{\",e:\"}\"},n={v:[{b:/\\$\\d/},{b:/[\\$%@](\\^\\w\\b|#\\w+(::\\w+)*|{\\w+}|\\w+(::\\w*)*)/},{b:/[\\$%@][^\\s\\w{]/,relevance:0}]},c=[e.BE,r,n],a=[n,e.HCM,e.C(\"^\\\\=\\\\w\",\"\\\\=cut\",{eW:!0}),s,{cN:\"string\",c:c,v:[{b:\"q[qwxr]?\\\\s*\\\\(\",e:\"\\\\)\",relevance:5},{b:\"q[qwxr]?\\\\s*\\\\[\",e:\"\\\\]\",relevance:5},{b:\"q[qwxr]?\\\\s*\\\\{\",e:\"\\\\}\",relevance:5},{b:\"q[qwxr]?\\\\s*\\\\|\",e:\"\\\\|\",relevance:5},{b:\"q[qwxr]?\\\\s*\\\\<\",e:\"\\\\>\",relevance:5},{b:\"qw\\\\s+q\",e:\"q\",relevance:5},{b:\"'\",e:\"'\",c:[e.BE]},{b:'\"',e:'\"'},{b:\"`\",e:\"`\",c:[e.BE]},{b:\"{\\\\w+}\",c:[],relevance:0},{b:\"-?\\\\w+\\\\s*\\\\=\\\\>\",c:[],relevance:0}]},{cN:\"number\",b:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",relevance:0},{b:\"(\\\\/\\\\/|\"+e.RSR+\"|\\\\b(split|return|print|reverse|grep)\\\\b)\\\\s*\",k:\"split return print reverse grep\",relevance:0,c:[e.HCM,{cN:\"regexp\",b:\"(s|tr|y)/(\\\\\\\\.|[^/])*/(\\\\\\\\.|[^/])*/[a-z]*\",relevance:10},{cN:\"regexp\",b:\"(m|qr)?/\",e:\"/[a-z]*\",c:[e.BE],relevance:0}]},{cN:\"function\",bK:\"sub\",e:\"(\\\\s*\\\\(.*?\\\\))?[;{]\",eE:!0,relevance:5,c:[e.TM]},{b:\"-\\\\w\\\\b\",relevance:0},{b:\"^__DATA__$\",e:\"^__END__$\",sL:\"mojolicious\",c:[{b:\"^@@.*\",e:\"$\",cN:\"comment\"}]}];return r.c=a,{aliases:[\"pl\",\"pm\"],l:/[\\w\\.]+/,k:t,c:s.c=a}});hljs.registerLanguage(\"go\",function(e){var n={keyword:\"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune\",literal:\"true false iota nil\",built_in:\"append cap close complex copy imag len make new panic print println real recover delete\"};return{aliases:[\"golang\"],k:n,i:\"</\",c:[e.CLCM,e.CBCM,{cN:\"string\",v:[e.QSM,e.ASM,{b:\"`\",e:\"`\"}]},{cN:\"number\",v:[{b:e.CNR+\"[i]\",relevance:1},e.CNM]},{b:/:=/},{cN:\"function\",bK:\"func\",e:\"\\\\s*(\\\\{|$)\",eE:!0,c:[e.TM,{cN:\"params\",b:/\\(/,e:/\\)/,k:n,i:/[\"']/}]}]}});hljs.registerLanguage(\"x86asm\",function(s){return{cI:!0,l:\"[.%]?\"+s.IR,k:{keyword:\"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63\",built_in:\"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr\",meta:\"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__\"},c:[s.C(\";\",\"$\",{relevance:0}),{cN:\"number\",v:[{b:\"\\\\b(?:([0-9][0-9_]*)?\\\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\\\b\",relevance:0},{b:\"\\\\$[0-9][0-9A-Fa-f]*\",relevance:0},{b:\"\\\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\\\b\"},{b:\"\\\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\\\b\"}]},s.QSM,{cN:\"string\",v:[{b:\"'\",e:\"[^\\\\\\\\]'\"},{b:\"`\",e:\"[^\\\\\\\\]`\"}],relevance:0},{cN:\"symbol\",v:[{b:\"^\\\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\\\s+label)\"},{b:\"^\\\\s*%%[A-Za-z0-9_$#@~.?]*:\"}],relevance:0},{cN:\"subst\",b:\"%[0-9]+\",relevance:0},{cN:\"subst\",b:\"%!S+\",relevance:0},{cN:\"meta\",b:/^\\s*\\.[\\w_-]+/}]}});hljs.registerLanguage(\"cpp\",function(e){function t(e){return\"(?:\"+e+\")?\"}var r=\"decltype\\\\(auto\\\\)\",a=\"[a-zA-Z_]\\\\w*::\",i=\"(\"+r+\"|\"+t(a)+\"[a-zA-Z_]\\\\w*\"+t(\"<.*?>\")+\")\",c={cN:\"keyword\",b:\"\\\\b[a-z\\\\d_]*_t\\\\b\"},s={cN:\"string\",v:[{b:'(u8?|U|L)?\"',e:'\"',i:\"\\\\n\",c:[e.BE]},{b:\"(u8?|U|L)?'(\\\\\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\\\S)|.)\",e:\"'\",i:\".\"},{b:/(?:u8?|U|L)?R\"([^()\\\\ ]{0,16})\\((?:.|\\n)*?\\)\\1\"/}]},n={cN:\"number\",v:[{b:\"\\\\b(0b[01']+)\"},{b:\"(-?)\\\\b([\\\\d']+(\\\\.[\\\\d']*)?|\\\\.[\\\\d']+)(u|U|l|L|ul|UL|f|F|b|B)\"},{b:\"(-?)(\\\\b0[xX][a-fA-F0-9']+|(\\\\b[\\\\d']+(\\\\.[\\\\d']*)?|\\\\.[\\\\d']+)([eE][-+]?[\\\\d']+)?)\"}],relevance:0},o={cN:\"meta\",b:/#\\s*[a-z]+\\b/,e:/$/,k:{\"meta-keyword\":\"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include\"},c:[{b:/\\\\\\n/,relevance:0},e.inherit(s,{cN:\"meta-string\"}),{cN:\"meta-string\",b:/<.*?>/,e:/$/,i:\"\\\\n\"},e.CLCM,e.CBCM]},l={cN:\"title\",b:t(a)+e.IR,relevance:0},u=t(a)+e.IR+\"\\\\s*\\\\(\",p={keyword:\"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_tshort reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq\",built_in:\"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary\",literal:\"true false nullptr NULL\"},m=[c,e.CLCM,e.CBCM,n,s],d={v:[{b:/=/,e:/;/},{b:/\\(/,e:/\\)/},{bK:\"new throw return else\",e:/;/}],k:p,c:m.concat([{b:/\\(/,e:/\\)/,k:p,c:m.concat([\"self\"]),relevance:0}]),relevance:0},b={cN:\"function\",b:\"(\"+i+\"[\\\\*&\\\\s]+)+\"+u,rB:!0,e:/[{;=]/,eE:!0,k:p,i:/[^\\w\\s\\*&:<>]/,c:[{b:r,k:p,relevance:0},{b:u,rB:!0,c:[l],relevance:0},{cN:\"params\",b:/\\(/,e:/\\)/,k:p,relevance:0,c:[e.CLCM,e.CBCM,s,n,c,{b:/\\(/,e:/\\)/,k:p,relevance:0,c:[\"self\",e.CLCM,e.CBCM,s,n,c]}]},c,e.CLCM,e.CBCM,o]};return{aliases:[\"c\",\"cc\",\"h\",\"c++\",\"h++\",\"hpp\",\"hh\",\"hxx\",\"cxx\"],k:p,i:\"</\",c:[].concat(d,b,m,[o,{b:\"\\\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\\\s*<\",e:\">\",k:p,c:[\"self\",c]},{b:e.IR+\"::\",k:p},{cN:\"class\",bK:\"class struct\",e:/[{;:]/,c:[{b:/</,e:/>/,c:[\"self\"]},e.TM]}]),exports:{preprocessor:o,strings:s,k:p}}});hljs.registerLanguage(\"arduino\",function(e){var t=\"boolean byte word String\",r=\"setup loopKeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put\",i=\"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW\",o=e.requireLanguage(\"cpp\").rawDefinition(),a=o.k;return a.keyword+=\" \"+t,a.literal+=\" \"+i,a.built_in+=\" \"+r,o});hljs.registerLanguage(\"nginx\",function(e){var r={cN:\"variable\",v:[{b:/\\$\\d+/},{b:/\\$\\{/,e:/}/},{b:\"[\\\\$\\\\@]\"+e.UIR}]},b={eW:!0,l:\"[a-z/_]+\",k:{literal:\"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll\"},relevance:0,i:\"=>\",c:[e.HCM,{cN:\"string\",c:[e.BE,r],v:[{b:/\"/,e:/\"/},{b:/'/,e:/'/}]},{b:\"([a-z]+):/\",e:\"\\\\s\",eW:!0,eE:!0,c:[r]},{cN:\"regexp\",c:[e.BE,r],v:[{b:\"\\\\s\\\\^\",e:\"\\\\s|{|;\",rE:!0},{b:\"~\\\\*?\\\\s+\",e:\"\\\\s|{|;\",rE:!0},{b:\"\\\\*(\\\\.[a-z\\\\-]+)+\"},{b:\"([a-z\\\\-]+\\\\.)+\\\\*\"}]},{cN:\"number\",b:\"\\\\b\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}(:\\\\d{1,5})?\\\\b\"},{cN:\"number\",b:\"\\\\b\\\\d+[kKmMgGdshdwy]*\\\\b\",relevance:0},r]};return{aliases:[\"nginxconf\"],c:[e.HCM,{b:e.UIR+\"\\\\s+{\",rB:!0,e:\"{\",c:[{cN:\"section\",b:e.UIR}],relevance:0},{b:e.UIR+\"\\\\s\",e:\";|{\",rB:!0,c:[{cN:\"attribute\",b:e.UIR,starts:b}],relevance:0}],i:\"[^\\\\s\\\\}]\"}});hljs.registerLanguage(\"xml\",function(e){var c={cN:\"symbol\",b:\"&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;\"},s={b:\"\\\\s\",c:[{cN:\"meta-keyword\",b:\"#?[a-z_][a-z1-9_-]+\",i:\"\\\\n\"}]},a=e.inherit(s,{b:\"\\\\(\",e:\"\\\\)\"}),t=e.inherit(e.ASM,{cN:\"meta-string\"}),l=e.inherit(e.QSM,{cN:\"meta-string\"}),r={eW:!0,i:/</,relevance:0,c:[{cN:\"attr\",b:\"[A-Za-z0-9\\\\._:-]+\",relevance:0},{b:/=\\s*/,relevance:0,c:[{cN:\"string\",endsParent:!0,v:[{b:/\"/,e:/\"/,c:[c]},{b:/'/,e:/'/,c:[c]},{b:/[^\\s\"'=<>`]+/}]}]}]};return{aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xjb\",\"xsd\",\"xsl\",\"plist\",\"wsf\",\"svg\"],cI:!0,c:[{cN:\"meta\",b:\"<![a-z]\",e:\">\",relevance:10,c:[s,l,t,a,{b:\"\\\\[\",e:\"\\\\]\",c:[{cN:\"meta\",b:\"<![a-z]\",e:\">\",c:[s,a,l,t]}]}]},e.C(\"\\x3c!--\",\"--\\x3e\",{relevance:10}),{b:\"<\\\\!\\\\[CDATA\\\\[\",e:\"\\\\]\\\\]>\",relevance:10},c,{cN:\"meta\",b:/<\\?xml/,e:/\\?>/,relevance:10},{b:/<\\?(php)?/,e:/\\?>/,sL:\"php\",c:[{b:\"/\\\\*\",e:\"\\\\*/\",skip:!0},{b:'b\"',e:'\"',skip:!0},{b:\"b'\",e:\"'\",skip:!0},e.inherit(e.ASM,{i:null,cN:null,c:null,skip:!0}),e.inherit(e.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:\"tag\",b:\"<style(?=\\\\s|>)\",e:\">\",k:{name:\"style\"},c:[r],starts:{e:\"</style>\",rE:!0,sL:[\"css\",\"xml\"]}},{cN:\"tag\",b:\"<script(?=\\\\s|>)\",e:\">\",k:{name:\"script\"},c:[r],starts:{e:\"<\\/script>\",rE:!0,sL:[\"actionscript\",\"javascript\",\"handlebars\",\"xml\"]}},{cN:\"tag\",b:\"</?\",e:\"/?>\",c:[{cN:\"name\",b:/[^\\/><\\s]+/,relevance:0},r]}]}});hljs.registerLanguage(\"markdown\",function(e){return{aliases:[\"md\",\"mkdown\",\"mkd\"],c:[{cN:\"section\",v:[{b:\"^#{1,6}\",e:\"$\"},{b:\"^.+?\\\\n[=-]{2,}$\"}]},{b:\"<\",e:\">\",sL:\"xml\",relevance:0},{cN:\"bullet\",b:\"^\\\\s*([*+-]|(\\\\d+\\\\.))\\\\s+\"},{cN:\"strong\",b:\"[*_]{2}.+?[*_]{2}\"},{cN:\"emphasis\",v:[{b:\"\\\\*.+?\\\\*\"},{b:\"_.+?_\",relevance:0}]},{cN:\"quote\",b:\"^>\\\\s+\",e:\"$\"},{cN:\"code\",v:[{b:\"^```\\\\w*\\\\s*$\",e:\"^```[ ]*$\"},{b:\"`.+?`\"},{b:\"^( {4}|\\\\t)\",e:\"$\",relevance:0}]},{b:\"^[-\\\\*]{3,}\",e:\"$\"},{b:\"\\\\[.+?\\\\][\\\\(\\\\[].*?[\\\\)\\\\]]\",rB:!0,c:[{cN:\"string\",b:\"\\\\[\",e:\"\\\\]\",eB:!0,rE:!0,relevance:0},{cN:\"link\",b:\"\\\\]\\\\(\",e:\"\\\\)\",eB:!0,eE:!0},{cN:\"symbol\",b:\"\\\\]\\\\[\",e:\"\\\\]\",eB:!0,eE:!0}],relevance:10},{b:/^\\[[^\\n]+\\]:/,rB:!0,c:[{cN:\"symbol\",b:/\\[/,e:/\\]/,eB:!0,eE:!0},{cN:\"link\",b:/:\\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage(\"properties\",function(e){var r=\"[ \\\\t\\\\f]*\",t=\"(\"+r+\"[:=]\"+r+\"|[ \\\\t\\\\f]+)\",n=\"([^\\\\\\\\\\\\W:= \\\\t\\\\f\\\\n]|\\\\\\\\.)+\",a=\"([^\\\\\\\\:= \\\\t\\\\f\\\\n]|\\\\\\\\.)+\",c={e:t,relevance:0,starts:{cN:\"string\",e:/$/,relevance:0,c:[{b:\"\\\\\\\\\\\\n\"}]}};return{cI:!0,i:/\\S/,c:[e.C(\"^\\\\s*[!#]\",\"$\"),{b:n+t,rB:!0,c:[{cN:\"attr\",b:n,endsParent:!0,relevance:0}],starts:c},{b:a+t,rB:!0,relevance:0,c:[{cN:\"meta\",b:a,endsParent:!0,relevance:0}],starts:c},{cN:\"attr\",relevance:0,b:a+r+\"$\"}]}});hljs.registerLanguage(\"bash\",function(e){var t={cN:\"variable\",v:[{b:/\\$[\\w\\d#@][\\w\\d_]*/},{b:/\\$\\{(.*?)}/}]},a={cN:\"string\",b:/\"/,e:/\"/,c:[e.BE,t,{cN:\"variable\",b:/\\$\\(/,e:/\\)/,c:[e.BE]}]};return{aliases:[\"sh\",\"zsh\"],l:/\\b-?[a-z\\._]+\\b/,k:{keyword:\"if then else elif fi for while in do done case esac function\",literal:\"true false\",built_in:\"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp\",_:\"-ne -eq -lt -gt -f -d -e -s -l -a\"},c:[{cN:\"meta\",b:/^#![^\\n]+sh\\s*$/,relevance:10},{cN:\"function\",b:/\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,rB:!0,c:[e.inherit(e.TM,{b:/\\w[\\w\\d_]*/})],relevance:0},e.HCM,a,{cN:\"\",b:/\\\\\"/},{cN:\"string\",b:/'/,e:/'/},t]}});hljs.registerLanguage(\"dockerfile\",function(e){return{aliases:[\"docker\"],cI:!0,k:\"from maintainer expose env arg user onbuild stopsignal\",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:\"run cmd entrypoint volume add copy workdir label healthcheck shell\",starts:{e:/[^\\\\]$/,sL:\"bash\"}}],i:\"</\"}});hljs.registerLanguage(\"python\",function(e){var r={keyword:\"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10\",built_in:\"Ellipsis NotImplemented\",literal:\"False None True\"},b={cN:\"meta\",b:/^(>>>|\\.\\.\\.) /},c={cN:\"subst\",b:/\\{/,e:/\\}/,k:r,i:/#/},a={b:/\\{\\{/,relevance:0},l={cN:\"string\",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[e.BE,b],relevance:10},{b:/(u|b)?r?\"\"\"/,e:/\"\"\"/,c:[e.BE,b],relevance:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[e.BE,b,a,c]},{b:/(fr|rf|f)\"\"\"/,e:/\"\"\"/,c:[e.BE,b,a,c]},{b:/(u|r|ur)'/,e:/'/,relevance:10},{b:/(u|r|ur)\"/,e:/\"/,relevance:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)\"/,e:/\"/},{b:/(fr|rf|f)'/,e:/'/,c:[e.BE,a,c]},{b:/(fr|rf|f)\"/,e:/\"/,c:[e.BE,a,c]},e.ASM,e.QSM]},n={cN:\"number\",relevance:0,v:[{b:e.BNR+\"[lLjJ]?\"},{b:\"\\\\b(0o[0-7]+)[lLjJ]?\"},{b:e.CNR+\"[lLjJ]?\"}]},i={cN:\"params\",b:/\\(/,e:/\\)/,c:[\"self\",b,n,l,e.HCM]};return c.c=[l,n,b],{aliases:[\"py\",\"gyp\",\"ipython\"],k:r,i:/(<\\/|->|\\?)|=>/,c:[b,n,{bK:\"if\",relevance:0},l,e.HCM,{v:[{cN:\"function\",bK:\"def\"},{cN:\"class\",bK:\"class\"}],e:/:/,i:/[${=;\\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:\"None\"}]},{cN:\"meta\",b:/^[\\t ]*@/,e:/$/},{b:/\\b(print|exec)\\(/}]}});hljs.registerLanguage(\"ini\",function(e){var b={cN:\"number\",relevance:0,v:[{b:/([\\+\\-]+)?[\\d]+_[\\d_]+/},{b:e.NR}]},a=e.C();a.v=[{b:/;/,e:/$/},{b:/#/,e:/$/}];var c={cN:\"variable\",v:[{b:/\\$[\\w\\d\"][\\w\\d_]*/},{b:/\\$\\{(.*?)}/}]},r={cN:\"literal\",b:/\\bon|off|true|false|yes|no\\b/},n={cN:\"string\",c:[e.BE],v:[{b:\"'''\",e:\"'''\",relevance:10},{b:'\"\"\"',e:'\"\"\"',relevance:10},{b:'\"',e:'\"'},{b:\"'\",e:\"'\"}]};return{aliases:[\"toml\"],cI:!0,i:/\\S/,c:[a,{cN:\"section\",b:/\\[+/,e:/\\]+/},{b:/^[a-z0-9\\[\\]_\\.-]+(?=\\s*=\\s*)/,cN:\"attr\",starts:{e:/$/,c:[a,{b:/\\[/,e:/\\]/,c:[a,r,c,n,b,\"self\"],relevance:0},r,c,n,b]}}]}});hljs.registerLanguage(\"diff\",function(e){return{aliases:[\"patch\"],c:[{cN:\"meta\",relevance:10,v:[{b:/^@@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +@@$/},{b:/^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$/},{b:/^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$/}]},{cN:\"comment\",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\\-{3}/,e:/$/},{b:/^\\*{3} /,e:/$/},{b:/^\\+{3}/,e:/$/},{b:/^\\*{15}$/}]},{cN:\"addition\",b:\"^\\\\+\",e:\"$\"},{cN:\"deletion\",b:\"^\\\\-\",e:\"$\"},{cN:\"addition\",b:\"^\\\\!\",e:\"$\"}]}});hljs.registerLanguage(\"http\",function(e){var t=\"HTTP/[0-9\\\\.]+\";return{aliases:[\"https\"],i:\"\\\\S\",c:[{b:\"^\"+t,e:\"$\",c:[{cN:\"number\",b:\"\\\\b\\\\d{3}\\\\b\"}]},{b:\"^[A-Z]+ (.*?) \"+t+\"$\",rB:!0,e:\"$\",c:[{cN:\"string\",b:\" \",e:\" \",eB:!0,eE:!0},{b:t},{cN:\"keyword\",b:\"[A-Z]+\"}]},{cN:\"attribute\",b:\"^\\\\w\",e:\": \",eE:!0,i:\"\\\\n|\\\\s|=\",starts:{e:\"$\",relevance:0}},{b:\"\\\\n\\\\n\",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage(\"sql\",function(e){var t=e.C(\"--\",\"$\");return{cI:!0,i:/[<>{}*]/,c:[{bK:\"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with\",e:/;/,eW:!0,l:/[\\w\\.]+/,k:{keyword:\"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek\",literal:\"true false null unknown\",built_in:\"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void\"},c:[{cN:\"string\",b:\"'\",e:\"'\",c:[{b:\"''\"}]},{cN:\"string\",b:'\"',e:'\"',c:[{b:'\"\"'}]},{cN:\"string\",b:\"`\",e:\"`\"},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}});hljs.registerLanguage(\"vala\",function(e){return{k:{keyword:\"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var\",built_in:\"DBus GLib CCode Gee Object Gtk Posix\",literal:\"false true null\"},c:[{cN:\"class\",bK:\"class interface namespace\",e:\"{\",eE:!0,i:\"[^,:\\\\n\\\\s\\\\.]\",c:[e.UTM]},e.CLCM,e.CBCM,{cN:\"string\",b:'\"\"\"',e:'\"\"\"',relevance:5},e.ASM,e.QSM,e.CNM,{cN:\"meta\",b:\"^#\",e:\"$\",relevance:2}]}});hljs.registerLanguage(\"asciidoc\",function(e){return{aliases:[\"adoc\"],c:[e.C(\"^/{4,}\\\\n\",\"\\\\n/{4,}$\",{relevance:10}),e.C(\"^//\",\"$\",{relevance:0}),{cN:\"title\",b:\"^\\\\.\\\\w.*$\"},{b:\"^[=\\\\*]{4,}\\\\n\",e:\"\\\\n^[=\\\\*]{4,}$\",relevance:10},{cN:\"section\",relevance:10,v:[{b:\"^(={1,5}) .+?( \\\\1)?$\"},{b:\"^[^\\\\[\\\\]\\\\n]+?\\\\n[=\\\\-~\\\\^\\\\+]{2,}$\"}]},{cN:\"meta\",b:\"^:.+?:\",e:\"\\\\s\",eE:!0,relevance:10},{cN:\"meta\",b:\"^\\\\[.+?\\\\]$\",relevance:0},{cN:\"quote\",b:\"^_{4,}\\\\n\",e:\"\\\\n_{4,}$\",relevance:10},{cN:\"code\",b:\"^[\\\\-\\\\.]{4,}\\\\n\",e:\"\\\\n[\\\\-\\\\.]{4,}$\",relevance:10},{b:\"^\\\\+{4,}\\\\n\",e:\"\\\\n\\\\+{4,}$\",c:[{b:\"<\",e:\">\",sL:\"xml\",relevance:0}],relevance:10},{cN:\"bullet\",b:\"^(\\\\*+|\\\\-+|\\\\.+|[^\\\\n]+?::)\\\\s+\"},{cN:\"symbol\",b:\"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\\\s+\",relevance:10},{cN:\"strong\",b:\"\\\\B\\\\*(?![\\\\*\\\\s])\",e:\"(\\\\n{2}|\\\\*)\",c:[{b:\"\\\\\\\\*\\\\w\",relevance:0}]},{cN:\"emphasis\",b:\"\\\\B'(?!['\\\\s])\",e:\"(\\\\n{2}|')\",c:[{b:\"\\\\\\\\'\\\\w\",relevance:0}],relevance:0},{cN:\"emphasis\",b:\"_(?![_\\\\s])\",e:\"(\\\\n{2}|_)\",relevance:0},{cN:\"string\",v:[{b:\"``.+?''\"},{b:\"`.+?'\"}]},{cN:\"code\",b:\"(`.+?`|\\\\+.+?\\\\+)\",relevance:0},{cN:\"code\",b:\"^[ \\\\t]\",e:\"$\",relevance:0},{b:\"^'{3,}[ \\\\t]*$\",relevance:10},{b:\"(link:)?(http|https|ftp|file|irc|image:?):\\\\S+\\\\[.*?\\\\]\",rB:!0,c:[{b:\"(link|image:?):\",relevance:0},{cN:\"link\",b:\"\\\\w\",e:\"[^\\\\[]+\",relevance:0},{cN:\"string\",b:\"\\\\[\",e:\"\\\\]\",eB:!0,eE:!0,relevance:0}],relevance:10}]}});hljs.registerLanguage(\"json\",function(e){var i={literal:\"true false null\"},n=[e.CLCM,e.CBCM],c=[e.QSM,e.CNM],r={e:\",\",eW:!0,eE:!0,c:c,k:i},t={b:\"{\",e:\"}\",c:[{cN:\"attr\",b:/\"/,e:/\"/,c:[e.BE],i:\"\\\\n\"},e.inherit(r,{b:/:/})].concat(n),i:\"\\\\S\"},a={b:\"\\\\[\",e:\"\\\\]\",c:[e.inherit(r)],i:\"\\\\S\"};return c.push(t,a),n.forEach(function(e){c.push(e)}),{c:c,k:i,i:\"\\\\S\"}});hljs.registerLanguage(\"rust\",function(e){var t=\"([ui](8|16|32|64|128|size)|f(32|64))?\",r=\"drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!\";return{aliases:[\"rs\"],k:{keyword:\"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield\",literal:\"true false Some None Ok Err\",built_in:r},l:e.IR+\"!?\",i:\"</\",c:[e.CLCM,e.C(\"/\\\\*\",\"\\\\*/\",{c:[\"self\"]}),e.inherit(e.QSM,{b:/b?\"/,i:null}),{cN:\"string\",v:[{b:/r(#*)\"(.|\\n)*?\"\\1(?!#)/},{b:/b?'\\\\?(x\\w{2}|u\\w{4}|U\\w{8}|.)'/}]},{cN:\"symbol\",b:/'[a-zA-Z_][a-zA-Z0-9_]*/},{cN:\"number\",v:[{b:\"\\\\b0b([01_]+)\"+t},{b:\"\\\\b0o([0-7_]+)\"+t},{b:\"\\\\b0x([A-Fa-f0-9_]+)\"+t},{b:\"\\\\b(\\\\d[\\\\d_]*(\\\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)\"+t}],relevance:0},{cN:\"function\",bK:\"fn\",e:\"(\\\\(|<)\",eE:!0,c:[e.UTM]},{cN:\"meta\",b:\"#\\\\!?\\\\[\",e:\"\\\\]\",c:[{cN:\"meta-string\",b:/\"/,e:/\"/}]},{cN:\"class\",bK:\"type\",e:\";\",c:[e.inherit(e.UTM,{endsParent:!0})],i:\"\\\\S\"},{cN:\"class\",bK:\"trait enum struct union\",e:\"{\",c:[e.inherit(e.UTM,{endsParent:!0})],i:\"[\\\\w\\\\d]\"},{b:e.IR+\"::\",k:{built_in:r}},{b:\"->\"}]}});hljs.registerLanguage(\"awk\",function(e){return{k:{keyword:\"BEGIN END if else while do for in break continue delete next nextfile function func exit|10\"},c:[{cN:\"variable\",v:[{b:/\\$[\\w\\d#@][\\w\\d_]*/},{b:/\\$\\{(.*?)}/}]},{cN:\"string\",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,relevance:10},{b:/(u|b)?r?\"\"\"/,e:/\"\"\"/,relevance:10},{b:/(u|r|ur)'/,e:/'/,relevance:10},{b:/(u|r|ur)\"/,e:/\"/,relevance:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)\"/,e:/\"/},e.ASM,e.QSM]},e.RM,e.HCM,e.NM]}});hljs.registerLanguage(\"java\",function(e){var a=\"false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do\",t={cN:\"number\",b:\"\\\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+)(\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))?|\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))([eE][-+]?\\\\d+)?)[lLfF]?\",relevance:0};return{aliases:[\"jsp\"],k:a,i:/<\\/|#/,c:[e.C(\"/\\\\*\\\\*\",\"\\\\*/\",{relevance:0,c:[{b:/\\w+@/,relevance:0},{cN:\"doctag\",b:\"@[A-Za-z]+\"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:\"class\",bK:\"class interface\",e:/[{;=]/,eE:!0,k:\"class interface\",i:/[:\"\\[\\]]/,c:[{bK:\"extends implements\"},e.UTM]},{bK:\"new throw return else\",relevance:0},{cN:\"function\",b:\"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\\\s*,\\\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\\\s+)+\"+e.UIR+\"\\\\s*\\\\(\",rB:!0,e:/[{;=]/,eE:!0,k:a,c:[{b:e.UIR+\"\\\\s*\\\\(\",rB:!0,relevance:0,c:[e.UTM]},{cN:\"params\",b:/\\(/,e:/\\)/,k:a,relevance:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},t,{cN:\"meta\",b:\"@[A-Za-z]+\"}]}});hljs.registerLanguage(\"cs\",function(e){var a={keyword:\"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let nameof on orderby partial remove select set value var when where yield\",literal:\"null false true\"},i={cN:\"number\",v:[{b:\"\\\\b(0b[01']+)\"},{b:\"(-?)\\\\b([\\\\d']+(\\\\.[\\\\d']*)?|\\\\.[\\\\d']+)(u|U|l|L|ul|UL|f|F|b|B)\"},{b:\"(-?)(\\\\b0[xX][a-fA-F0-9']+|(\\\\b[\\\\d']+(\\\\.[\\\\d']*)?|\\\\.[\\\\d']+)([eE][-+]?[\\\\d']+)?)\"}],relevance:0},c={cN:\"string\",b:'@\"',e:'\"',c:[{b:'\"\"'}]},r=e.inherit(c,{i:/\\n/}),n={cN:\"subst\",b:\"{\",e:\"}\",k:a},t=e.inherit(n,{i:/\\n/}),s={cN:\"string\",b:/\\$\"/,e:'\"',i:/\\n/,c:[{b:\"{{\"},{b:\"}}\"},e.BE,t]},l={cN:\"string\",b:/\\$@\"/,e:'\"',c:[{b:\"{{\"},{b:\"}}\"},{b:'\"\"'},n]},b=e.inherit(l,{i:/\\n/,c:[{b:\"{{\"},{b:\"}}\"},{b:'\"\"'},t]});n.c=[l,s,c,e.ASM,e.QSM,i,e.CBCM],t.c=[b,s,r,e.ASM,e.QSM,i,e.inherit(e.CBCM,{i:/\\n/})];var o={v:[l,s,c,e.ASM,e.QSM]},d=e.IR+\"(<\"+e.IR+\"(\\\\s*,\\\\s*\"+e.IR+\")*>)?(\\\\[\\\\])?\";return{aliases:[\"csharp\",\"c#\"],k:a,i:/::/,c:[e.C(\"///\",\"$\",{rB:!0,c:[{cN:\"doctag\",v:[{b:\"///\",relevance:0},{b:\"\\x3c!--|--\\x3e\"},{b:\"</?\",e:\">\"}]}]}),e.CLCM,e.CBCM,{cN:\"meta\",b:\"#\",e:\"$\",k:{\"meta-keyword\":\"if else elif endif define undef warning error line region endregion pragma checksum\"}},o,i,{bK:\"class interface\",e:/[{;=]/,i:/[^\\s:,]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:\"namespace\",e:/[{;=]/,i:/[^\\s:]/,c:[e.inherit(e.TM,{b:\"[a-zA-Z](\\\\.?\\\\w)*\"}),e.CLCM,e.CBCM]},{cN:\"meta\",b:\"^\\\\s*\\\\[\",eB:!0,e:\"\\\\]\",eE:!0,c:[{cN:\"meta-string\",b:/\"/,e:/\"/}]},{bK:\"new return throw await else\",relevance:0},{cN:\"function\",b:\"(\"+d+\"\\\\s+)+\"+e.IR+\"\\\\s*\\\\(\",rB:!0,e:/\\s*[{;=]/,eE:!0,k:a,c:[{b:e.IR+\"\\\\s*\\\\(\",rB:!0,c:[e.TM],relevance:0},{cN:\"params\",b:/\\(/,e:/\\)/,eB:!0,eE:!0,k:a,relevance:0,c:[o,i,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage(\"mathematica\",function(e){return{aliases:[\"mma\",\"wl\"],l:\"(\\\\$|\\\\b)\"+e.IR+\"\\\\b\",k:\"AASTriangle AbelianGroup Abort AbortKernels AbortProtect AbortScheduledTask Above Abs AbsArg AbsArgPlot Absolute AbsoluteCorrelation AbsoluteCorrelationFunction AbsoluteCurrentValue AbsoluteDashing AbsoluteFileName AbsoluteOptions AbsolutePointSize AbsoluteThickness AbsoluteTime AbsoluteTiming AcceptanceThreshold AccountingForm Accumulate Accuracy AccuracyGoal ActionDelay ActionMenu ActionMenuBox ActionMenuBoxOptions Activate Active ActiveClassification ActiveClassificationObject ActiveItem ActivePrediction ActivePredictionObject ActiveStyle AcyclicGraphQ AddOnHelpPath AddSides AddTo AddToSearchIndex AddUsers AdjacencyGraph AdjacencyList AdjacencyMatrix AdjustmentBox AdjustmentBoxOptions AdjustTimeSeriesForecast AdministrativeDivisionData AffineHalfSpace AffineSpace AffineStateSpaceModel AffineTransform After AggregatedEntityClass AggregationLayer AircraftData AirportData AirPressureData AirTemperatureData AiryAi AiryAiPrime AiryAiZero AiryBi AiryBiPrime AiryBiZero AlgebraicIntegerQ AlgebraicNumber AlgebraicNumberDenominator AlgebraicNumberNorm AlgebraicNumberPolynomial AlgebraicNumberTrace AlgebraicRules AlgebraicRulesData Algebraics AlgebraicUnitQ Alignment AlignmentMarker AlignmentPoint All AllowAdultContent AllowedCloudExtraParameters AllowedCloudParameterExtensions AllowedDimensions AllowedFrequencyRange AllowedHeads AllowGroupClose AllowIncomplete AllowInlineCells AllowKernelInitialization AllowLooseGrammar AllowReverseGroupClose AllowScriptLevelChange AllTrue Alphabet AlphabeticOrder AlphabeticSort AlphaChannel AlternateImage AlternatingFactorial AlternatingGroup AlternativeHypothesis Alternatives AltitudeMethod AmbientLight AmbiguityFunction AmbiguityList Analytic AnatomyData AnatomyForm AnatomyPlot3D AnatomySkinStyle AnatomyStyling AnchoredSearch And AndersonDarlingTest AngerJ AngleBisector AngleBracket AnglePath AnglePath3D AngleVector AngularGauge Animate AnimationCycleOffset AnimationCycleRepetitions AnimationDirection AnimationDisplayTime AnimationRate AnimationRepetitions AnimationRunning AnimationRunTime AnimationTimeIndex Animator AnimatorBox AnimatorBoxOptions AnimatorElements Annotate Annotation AnnotationDelete AnnotationNames AnnotationRules AnnotationValue Annuity AnnuityDue Annulus AnomalyDetection AnomalyDetectorFunction Anonymous Antialiasing AntihermitianMatrixQ Antisymmetric AntisymmetricMatrixQ Antonyms AnyOrder AnySubset AnyTrue Apart ApartSquareFree APIFunction Appearance AppearanceElements AppearanceRules AppellF1 Append AppendCheck AppendLayer AppendTo ApplicationIdentificationKey Apply ApplySides ArcCos ArcCosh ArcCot ArcCoth ArcCsc ArcCsch ArcCurvature ARCHProcess ArcLength ArcSec ArcSech ArcSin ArcSinDistribution ArcSinh ArcTan ArcTanh Area Arg ArgMax ArgMin ArgumentCountQ ARIMAProcess ArithmeticGeometricMean ARMAProcess Around AroundReplace ARProcess Array ArrayComponents ArrayDepth ArrayFilter ArrayFlatten ArrayMesh ArrayPad ArrayPlot ArrayQ ArrayResample ArrayReshape ArrayRules Arrays Arrow Arrow3DBox ArrowBox Arrowheads ASATriangle Ask AskAppend AskConfirm AskDisplay AskedQ AskedValue AskFunction AskState AskTemplateDisplay AspectRatio AspectRatioFixed Assert AssociateTo Association AssociationFormat AssociationMap AssociationQ AssociationThread AssumeDeterministic Assuming Assumptions AstronomicalData AsymptoticDSolveValue AsymptoticEqual AsymptoticEquivalent AsymptoticGreater AsymptoticGreaterEqual AsymptoticIntegrate AsymptoticLess AsymptoticLessEqual AsymptoticOutputTracker AsymptoticRSolveValue AsymptoticSolve AsymptoticSum Asynchronous AsynchronousTaskObject AsynchronousTasks Atom AtomCoordinates AtomCount AtomDiagramCoordinates AtomList AtomQ AttentionLayer Attributes Audio AudioAmplify AudioAnnotate AudioAnnotationLookup AudioBlockMap AudioCapture AudioChannelAssignment AudioChannelCombine AudioChannelMix AudioChannels AudioChannelSeparate AudioData AudioDelay AudioDelete AudioDevice AudioDistance AudioFade AudioFrequencyShift AudioGenerator AudioIdentify AudioInputDevice AudioInsert AudioIntervals AudioJoin AudioLabel AudioLength AudioLocalMeasurements AudioLooping AudioLoudness AudioMeasurements AudioNormalize AudioOutputDevice AudioOverlay AudioPad AudioPan AudioPartition AudioPause AudioPitchShift AudioPlay AudioPlot AudioQ AudioRecord AudioReplace AudioResample AudioReverb AudioSampleRate AudioSpectralMap AudioSpectralTransformation AudioSplit AudioStop AudioStream AudioStreams AudioTimeStretch AudioTrim AudioType AugmentedPolyhedron AugmentedSymmetricPolynomial Authenticate Authentication AuthenticationDialog AutoAction Autocomplete AutocompletionFunction AutoCopy AutocorrelationTest AutoDelete AutoEvaluateEvents AutoGeneratedPackage AutoIndent AutoIndentSpacings AutoItalicWords AutoloadPath AutoMatch Automatic AutomaticImageSize AutoMultiplicationSymbol AutoNumberFormatting AutoOpenNotebooks AutoOpenPalettes AutoQuoteCharacters AutoRefreshed AutoRemove AutorunSequencing AutoScaling AutoScroll AutoSpacing AutoStyleOptions AutoStyleWords AutoSubmitting Axes AxesEdge AxesLabel AxesOrigin AxesStyle AxiomaticTheory AxisBabyMonsterGroupB Back Background BackgroundAppearance BackgroundTasksSettings Backslash Backsubstitution Backward Ball Band BandpassFilter BandstopFilter BarabasiAlbertGraphDistribution BarChart BarChart3D BarcodeImage BarcodeRecognize BaringhausHenzeTest BarLegend BarlowProschanImportance BarnesG BarOrigin BarSpacing BartlettHannWindow BartlettWindow BaseDecode BaseEncode BaseForm Baseline BaselinePosition BaseStyle BasicRecurrentLayer BatchNormalizationLayer BatchSize BatesDistribution BattleLemarieWavelet BayesianMaximization BayesianMaximizationObject BayesianMinimization BayesianMinimizationObject Because BeckmannDistribution Beep Before Begin BeginDialogPacket BeginFrontEndInteractionPacket BeginPackage BellB BellY Below BenfordDistribution BeniniDistribution BenktanderGibratDistribution BenktanderWeibullDistribution BernoulliB BernoulliDistribution BernoulliGraphDistribution BernoulliProcess BernsteinBasis BesselFilterModel BesselI BesselJ BesselJZero BesselK BesselY BesselYZero Beta BetaBinomialDistribution BetaDistribution BetaNegativeBinomialDistribution BetaPrimeDistribution BetaRegularized Between BetweennessCentrality BeveledPolyhedron BezierCurve BezierCurve3DBox BezierCurve3DBoxOptions BezierCurveBox BezierCurveBoxOptions BezierFunction BilateralFilter Binarize BinaryDeserialize BinaryDistance BinaryFormat BinaryImageQ BinaryRead BinaryReadList BinarySerialize BinaryWrite BinCounts BinLists Binomial BinomialDistribution BinomialProcess BinormalDistribution BiorthogonalSplineWavelet BipartiteGraphQ BiquadraticFilterModel BirnbaumImportance BirnbaumSaundersDistribution BitAnd BitClear BitGet BitLength BitNot BitOr BitSet BitShiftLeft BitShiftRight BitXor BiweightLocation BiweightMidvariance Black BlackmanHarrisWindow BlackmanNuttallWindow BlackmanWindow Blank BlankForm BlankNullSequence BlankSequence Blend Block BlockchainAddressData BlockchainBase BlockchainBlockData BlockchainContractValue BlockchainData BlockchainGet BlockchainKeyEncode BlockchainPut BlockchainTokenData BlockchainTransaction BlockchainTransactionData BlockchainTransactionSign BlockchainTransactionSubmit BlockMap BlockRandom BlomqvistBeta BlomqvistBetaTest Blue Blur BodePlot BohmanWindow Bold Bond BondCount BondList BondQ Bookmarks Boole BooleanConsecutiveFunction BooleanConvert BooleanCountingFunction BooleanFunction BooleanGraph BooleanMaxterms BooleanMinimize BooleanMinterms BooleanQ BooleanRegion Booleans BooleanStrings BooleanTable BooleanVariables BorderDimensions BorelTannerDistribution Bottom BottomHatTransform BoundaryDiscretizeGraphics BoundaryDiscretizeRegion BoundaryMesh BoundaryMeshRegion BoundaryMeshRegionQ BoundaryStyle BoundedRegionQ BoundingRegion Bounds Box BoxBaselineShift BoxData BoxDimensions Boxed Boxes BoxForm BoxFormFormatTypes BoxFrame BoxID BoxMargins BoxMatrix BoxObject BoxRatios BoxRotation BoxRotationPoint BoxStyle BoxWhiskerChart Bra BracketingBar BraKet BrayCurtisDistance BreadthFirstScan Break BridgeData BrightnessEqualize BroadcastStationData Brown BrownForsytheTest BrownianBridgeProcess BrowserCategory BSplineBasis BSplineCurve BSplineCurve3DBox BSplineCurve3DBoxOptions BSplineCurveBox BSplineCurveBoxOptions BSplineFunction BSplineSurface BSplineSurface3DBox BSplineSurface3DBoxOptions BubbleChart BubbleChart3D BubbleScale BubbleSizes BuildingData BulletGauge BusinessDayQ ButterflyGraph ButterworthFilterModel Button ButtonBar ButtonBox ButtonBoxOptions ButtonCell ButtonContents ButtonData ButtonEvaluator ButtonExpandable ButtonFrame ButtonFunction ButtonMargins ButtonMinHeight ButtonNote ButtonNotebook ButtonSource ButtonStyle ButtonStyleMenuListing Byte ByteArray ByteArrayFormat ByteArrayQ ByteArrayToString ByteCount ByteOrderingC CachedValue CacheGraphics CachePersistence CalendarConvert CalendarData CalendarType Callout CalloutMarker CalloutStyle CallPacket CanberraDistance Cancel CancelButton CandlestickChart CanonicalGraph CanonicalizePolygon CanonicalizePolyhedron CanonicalName CanonicalWarpingCorrespondence CanonicalWarpingDistance CantorMesh CantorStaircase Cap CapForm CapitalDifferentialD Capitalize CapsuleShape CaptureRunning CardinalBSplineBasis CarlemanLinearize CarmichaelLambda CaseOrdering Cases CaseSensitive Cashflow Casoratian Catalan CatalanNumber Catch Catenate CatenateLayer CauchyDistribution CauchyWindow CayleyGraph CDF CDFDeploy CDFInformation CDFWavelet Ceiling CelestialSystem Cell CellAutoOverwrite CellBaseline CellBoundingBox CellBracketOptions CellChangeTimes CellContents CellContext CellDingbat CellDynamicExpression CellEditDuplicate CellElementsBoundingBox CellElementSpacings CellEpilog CellEvaluationDuplicate CellEvaluationFunction CellEvaluationLanguage CellEventActions CellFrame CellFrameColor CellFrameLabelMargins CellFrameLabels CellFrameMargins CellGroup CellGroupData CellGrouping CellGroupingRules CellHorizontalScrolling CellID CellLabel CellLabelAutoDelete CellLabelMargins CellLabelPositioning CellLabelStyle CellLabelTemplate CellMargins CellObject CellOpen CellPrint CellProlog Cells CellSize CellStyle CellTags CellularAutomaton CensoredDistribution Censoring Center CenterArray CenterDot CentralFeature CentralMoment CentralMomentGeneratingFunction Cepstrogram CepstrogramArray CepstrumArray CForm ChampernowneNumber ChangeOptions ChannelBase ChannelBrokerAction ChannelDatabin ChannelHistoryLength ChannelListen ChannelListener ChannelListeners ChannelListenerWait ChannelObject ChannelPreSendFunction ChannelReceiverFunction ChannelSend ChannelSubscribers ChanVeseBinarize Character CharacterCounts CharacterEncoding CharacterEncodingsPath CharacteristicFunction CharacteristicPolynomial CharacterName CharacterRange Characters ChartBaseStyle ChartElementData ChartElementDataFunction ChartElementFunction ChartElements ChartLabels ChartLayout ChartLegends ChartStyle Chebyshev1FilterModel Chebyshev2FilterModel ChebyshevDistance ChebyshevT ChebyshevU Check CheckAbort CheckAll Checkbox CheckboxBar CheckboxBox CheckboxBoxOptions ChemicalData ChessboardDistance ChiDistribution ChineseRemainder ChiSquareDistribution ChoiceButtons ChoiceDialog CholeskyDecomposition Chop ChromaticityPlot ChromaticityPlot3D ChromaticPolynomial Circle CircleBox CircleDot CircleMinus CirclePlus CirclePoints CircleThrough CircleTimes CirculantGraph CircularOrthogonalMatrixDistribution CircularQuaternionMatrixDistribution CircularRealMatrixDistribution CircularSymplecticMatrixDistribution CircularUnitaryMatrixDistribution Circumsphere CityData ClassifierFunction ClassifierInformation ClassifierMeasurements ClassifierMeasurementsObject Classify ClassPriors Clear ClearAll ClearAttributes ClearCookies ClearPermissions ClearSystemCache ClebschGordan ClickPane Clip ClipboardNotebook ClipFill ClippingStyle ClipPlanes ClipPlanesStyle ClipRange Clock ClockGauge ClockwiseContourIntegral Close Closed CloseKernels ClosenessCentrality Closing ClosingAutoSave ClosingEvent CloudAccountData CloudBase CloudConnect CloudDeploy CloudDirectory CloudDisconnect CloudEvaluate CloudExport CloudExpression CloudExpressions CloudFunction CloudGet CloudImport CloudLoggingData CloudObject CloudObjectInformation CloudObjectInformationData CloudObjectNameFormat CloudObjects CloudObjectURLType CloudPublish CloudPut CloudRenderingMethod CloudSave CloudShare CloudSubmit CloudSymbol CloudUnshare ClusterClassify ClusterDissimilarityFunction ClusteringComponents ClusteringTree CMYKColor Coarse CodeAssistOptions Coefficient CoefficientArrays CoefficientDomain CoefficientList CoefficientRules CoifletWavelet Collect Colon ColonForm ColorBalance ColorCombine ColorConvert ColorCoverage ColorData ColorDataFunction ColorDetect ColorDistance ColorFunction ColorFunctionScaling Colorize ColorNegate ColorOutput ColorProfileData ColorQ ColorQuantize ColorReplace ColorRules ColorSelectorSettings ColorSeparate ColorSetter ColorSetterBox ColorSetterBoxOptions ColorSlider ColorsNear ColorSpace ColorToneMapping Column ColumnAlignments ColumnBackgrounds ColumnForm ColumnLines ColumnsEqual ColumnSpacings ColumnWidths CombinedEntityClass CombinerFunction CometData CommonDefaultFormatTypes Commonest CommonestFilter CommonName CommonUnits CommunityBoundaryStyle CommunityGraphPlot CommunityLabels CommunityRegionStyle CompanyData CompatibleUnitQ CompilationOptions CompilationTarget Compile Compiled CompiledCodeFunction CompiledFunction CompilerOptions Complement CompleteGraph CompleteGraphQ CompleteKaryTree CompletionsListPacket Complex Complexes ComplexExpand ComplexInfinity ComplexityFunction ComplexListPlot ComplexPlot ComplexPlot3D ComponentMeasurements ComponentwiseContextMenu Compose ComposeList ComposeSeries CompositeQ Composition CompoundElement CompoundExpression CompoundPoissonDistribution CompoundPoissonProcess CompoundRenewalProcess Compress CompressedData ComputeUncertainty Condition ConditionalExpression Conditioned Cone ConeBox ConfidenceLevel ConfidenceRange ConfidenceTransform ConfigurationPath ConformAudio ConformImages Congruent ConicHullRegion ConicHullRegion3DBox ConicHullRegionBox ConicOptimization Conjugate ConjugateTranspose Conjunction Connect ConnectedComponents ConnectedGraphComponents ConnectedGraphQ ConnectedMeshComponents ConnectedMoleculeComponents ConnectedMoleculeQ ConnectionSettings ConnectLibraryCallbackFunction ConnectSystemModelComponents ConnesWindow ConoverTest ConsoleMessage ConsoleMessagePacket ConsolePrint Constant ConstantArray ConstantArrayLayer ConstantImage ConstantPlusLayer ConstantRegionQ Constants ConstantTimesLayer ConstellationData ConstrainedMax ConstrainedMin Construct Containing ContainsAll ContainsAny ContainsExactly ContainsNone ContainsOnly ContentFieldOptions ContentLocationFunction ContentObject ContentPadding ContentsBoundingBox ContentSelectable ContentSize Context ContextMenu Contexts ContextToFileName Continuation Continue ContinuedFraction ContinuedFractionK ContinuousAction ContinuousMarkovProcess ContinuousTask ContinuousTimeModelQ ContinuousWaveletData ContinuousWaveletTransform ContourDetect ContourGraphics ContourIntegral ContourLabels ContourLines ContourPlot ContourPlot3D Contours ContourShading ContourSmoothing ContourStyle ContraharmonicMean ContrastiveLossLayer Control ControlActive ControlAlignment ControlGroupContentsBox ControllabilityGramian ControllabilityMatrix ControllableDecomposition ControllableModelQ ControllerDuration ControllerInformation ControllerInformationData ControllerLinking ControllerManipulate ControllerMethod ControllerPath ControllerState ControlPlacement ControlsRendering ControlType Convergents ConversionOptions ConversionRules ConvertToBitmapPacket ConvertToPostScript ConvertToPostScriptPacket ConvexHullMesh ConvexPolygonQ ConvexPolyhedronQ ConvolutionLayer Convolve ConwayGroupCo1 ConwayGroupCo2 ConwayGroupCo3 CookieFunction Cookies CoordinateBoundingBox CoordinateBoundingBoxArray CoordinateBounds CoordinateBoundsArray CoordinateChartData CoordinatesToolOptions CoordinateTransform CoordinateTransformData CoprimeQ Coproduct CopulaDistribution Copyable CopyDatabin CopyDirectory CopyFile CopyTag CopyToClipboard CornerFilter CornerNeighbors Correlation CorrelationDistance CorrelationFunction CorrelationTest Cos Cosh CoshIntegral CosineDistance CosineWindow CosIntegral Cot Coth Count CountDistinct CountDistinctBy CounterAssignments CounterBox CounterBoxOptions CounterClockwiseContourIntegral CounterEvaluator CounterFunction CounterIncrements CounterStyle CounterStyleMenuListing CountRoots CountryData Counts CountsBy Covariance CovarianceEstimatorFunction CovarianceFunction CoxianDistribution CoxIngersollRossProcess CoxModel CoxModelFit CramerVonMisesTest CreateArchive CreateCellID CreateChannel CreateCloudExpression CreateDatabin CreateDataSystemModel CreateDialog CreateDirectory CreateDocument CreateFile CreateIntermediateDirectories CreateManagedLibraryExpression CreateNotebook CreatePalette CreatePalettePacket CreatePermissionsGroup CreateScheduledTask CreateSearchIndex CreateSystemModel CreateTemporary CreateUUID CreateWindow CriterionFunction CriticalityFailureImportance CriticalitySuccessImportance CriticalSection Cross CrossEntropyLossLayer CrossingCount CrossingDetect CrossingPolygon CrossMatrix Csc Csch CTCLossLayer Cube CubeRoot Cubics Cuboid CuboidBox Cumulant CumulantGeneratingFunction Cup CupCap Curl CurlyDoubleQuote CurlyQuote CurrencyConvert CurrentDate CurrentImage CurrentlySpeakingPacket CurrentNotebookImage CurrentScreenImage CurrentValue Curry CurvatureFlowFilter CurveClosed Cyan CycleGraph CycleIndexPolynomial Cycles CyclicGroup Cyclotomic Cylinder CylinderBox CylindricalDecompositionD DagumDistribution DamData DamerauLevenshteinDistance DampingFactor Darker Dashed Dashing DatabaseConnect DatabaseDisconnect DatabaseReference Databin DatabinAdd DatabinRemove Databins DatabinUpload DataCompression DataDistribution DataRange DataReversed Dataset Date DateBounds Dated DateDelimiters DateDifference DatedUnit DateFormat DateFunction DateHistogram DateList DateListLogPlot DateListPlot DateListStepPlot DateObject DateObjectQ DateOverlapsQ DatePattern DatePlus DateRange DateReduction DateString DateTicksFormat DateValue DateWithinQ DaubechiesWavelet DavisDistribution DawsonF DayCount DayCountConvention DayHemisphere DaylightQ DayMatchQ DayName DayNightTerminator DayPlus DayRange DayRound DeBruijnGraph DeBruijnSequence Debug DebugTag Decapitalize Decimal DecimalForm DeclareKnownSymbols DeclarePackage Decompose DeconvolutionLayer Decrement Decrypt DecryptFile DedekindEta DeepSpaceProbeData Default DefaultAxesStyle DefaultBaseStyle DefaultBoxStyle DefaultButton DefaultColor DefaultControlPlacement DefaultDuplicateCellStyle DefaultDuration DefaultElement DefaultFaceGridsStyle DefaultFieldHintStyle DefaultFont DefaultFontProperties DefaultFormatType DefaultFormatTypeForStyle DefaultFrameStyle DefaultFrameTicksStyle DefaultGridLinesStyle DefaultInlineFormatType DefaultInputFormatType DefaultLabelStyle DefaultMenuStyle DefaultNaturalLanguage DefaultNewCellStyle DefaultNewInlineCellStyle DefaultNotebook DefaultOptions DefaultOutputFormatType DefaultPrintPrecision DefaultStyle DefaultStyleDefinitions DefaultTextFormatType DefaultTextInlineFormatType DefaultTicksStyle DefaultTooltipStyle DefaultValue DefaultValues Defer DefineExternal DefineInputStreamMethod DefineOutputStreamMethod DefineResourceFunction Definition Degree DegreeCentrality DegreeGraphDistribution DegreeLexicographic DegreeReverseLexicographic DEigensystem DEigenvalues Deinitialization Del DelaunayMesh Delayed Deletable Delete DeleteAnomalies DeleteBorderComponents DeleteCases DeleteChannel DeleteCloudExpression DeleteContents DeleteDirectory DeleteDuplicates DeleteDuplicatesBy DeleteFile DeleteMissing DeleteObject DeletePermissionsKey DeleteSearchIndex DeleteSmallComponents DeleteStopwords DeleteWithContents DeletionWarning DelimitedArray DelimitedSequence Delimiter DelimiterFlashTime DelimiterMatching Delimiters DeliveryFunction Dendrogram Denominator DensityGraphics DensityHistogram DensityPlot DensityPlot3D DependentVariables Deploy Deployed Depth DepthFirstScan Derivative DerivativeFilter DerivedKey DescriptorStateSpace DesignMatrix DestroyAfterEvaluation Det DeviceClose DeviceConfigure DeviceExecute DeviceExecuteAsynchronous DeviceObject DeviceOpen DeviceOpenQ DeviceRead DeviceReadBuffer DeviceReadLatest DeviceReadList DeviceReadTimeSeries Devices DeviceStreams DeviceWrite DeviceWriteBuffer DGaussianWavelet DiacriticalPositioning Diagonal DiagonalizableMatrixQ DiagonalMatrix DiagonalMatrixQ Dialog DialogIndent DialogInput DialogLevel DialogNotebook DialogProlog DialogReturn DialogSymbols Diamond DiamondMatrix DiceDissimilarity DictionaryLookup DictionaryWordQ DifferenceDelta DifferenceOrder DifferenceQuotient DifferenceRoot DifferenceRootReduce Differences DifferentialD DifferentialRoot DifferentialRootReduce DifferentiatorFilter DigitalSignature DigitBlock DigitBlockMinimum DigitCharacter DigitCount DigitQ DihedralAngle DihedralGroup Dilation DimensionalCombinations DimensionalMeshComponents DimensionReduce DimensionReducerFunction DimensionReduction Dimensions DiracComb DiracDelta DirectedEdge DirectedEdges DirectedGraph DirectedGraphQ DirectedInfinity Direction Directive Directory DirectoryName DirectoryQ DirectoryStack DirichletBeta DirichletCharacter DirichletCondition DirichletConvolve DirichletDistribution DirichletEta DirichletL DirichletLambda DirichletTransform DirichletWindow DisableConsolePrintPacket DisableFormatting DiscreteChirpZTransform DiscreteConvolve DiscreteDelta DiscreteHadamardTransform DiscreteIndicator DiscreteLimit DiscreteLQEstimatorGains DiscreteLQRegulatorGains DiscreteLyapunovSolve DiscreteMarkovProcess DiscreteMaxLimit DiscreteMinLimit DiscretePlot DiscretePlot3D DiscreteRatio DiscreteRiccatiSolve DiscreteShift DiscreteTimeModelQ DiscreteUniformDistribution DiscreteVariables DiscreteWaveletData DiscreteWaveletPacketTransform DiscreteWaveletTransform DiscretizeGraphics DiscretizeRegion Discriminant DisjointQ Disjunction Disk DiskBox DiskMatrix DiskSegment Dispatch DispatchQ DispersionEstimatorFunction Display DisplayAllSteps DisplayEndPacket DisplayFlushImagePacket DisplayForm DisplayFunction DisplayPacket DisplayRules DisplaySetSizePacket DisplayString DisplayTemporary DisplayWith DisplayWithRef DisplayWithVariable DistanceFunction DistanceMatrix DistanceTransform Distribute Distributed DistributedContexts DistributeDefinitions DistributionChart DistributionDomain DistributionFitTest DistributionParameterAssumptions DistributionParameterQ Dithering Div Divergence Divide DivideBy Dividers DivideSides Divisible Divisors DivisorSigma DivisorSum DMSList DMSString Do DockedCells DocumentGenerator DocumentGeneratorInformation DocumentGeneratorInformationData DocumentGenerators DocumentNotebook DocumentWeightingRules Dodecahedron DomainRegistrationInformation DominantColors DOSTextFormat Dot DotDashed DotEqual DotLayer DotPlusLayer Dotted DoubleBracketingBar DoubleContourIntegral DoubleDownArrow DoubleLeftArrow DoubleLeftRightArrow DoubleLeftTee DoubleLongLeftArrow DoubleLongLeftRightArrow DoubleLongRightArrow DoubleRightArrow DoubleRightTee DoubleUpArrow DoubleUpDownArrow DoubleVerticalBar DoublyInfinite Down DownArrow DownArrowBar DownArrowUpArrow DownLeftRightVector DownLeftTeeVector DownLeftVector DownLeftVectorBar DownRightTeeVector DownRightVector DownRightVectorBar Downsample DownTee DownTeeArrow DownValues DragAndDrop DrawEdges DrawFrontFaces DrawHighlighted Drop DropoutLayer DSolve DSolveValue Dt DualLinearProgramming DualPolyhedron DualSystemsModel DumpGet DumpSave DuplicateFreeQ Duration Dynamic DynamicBox DynamicBoxOptions DynamicEvaluationTimeout DynamicGeoGraphics DynamicImage DynamicLocation DynamicModule DynamicModuleBox DynamicModuleBoxOptions DynamicModuleParent DynamicModuleValues DynamicName DynamicNamespace DynamicReference DynamicSetting DynamicUpdating DynamicWrapper DynamicWrapperBox DynamicWrapperBoxOptionsE EarthImpactData EarthquakeData EccentricityCentrality Echo EchoFunction EclipseType EdgeAdd EdgeBetweennessCentrality EdgeCapacity EdgeCapForm EdgeColor EdgeConnectivity EdgeContract EdgeCost EdgeCount EdgeCoverQ EdgeCycleMatrix EdgeDashing EdgeDelete EdgeDetect EdgeForm EdgeIndex EdgeJoinForm EdgeLabeling EdgeLabels EdgeLabelStyle EdgeList EdgeOpacity EdgeQ EdgeRenderingFunction EdgeRules EdgeShapeFunction EdgeStyle EdgeThickness EdgeWeight EdgeWeightedGraphQ Editable EditButtonSettings EditCellTagsSettings EditDistance EffectiveInterest Eigensystem Eigenvalues EigenvectorCentrality Eigenvectors Element ElementData ElementwiseLayer ElidedForms Eliminate EliminationOrder Ellipsoid EllipticE EllipticExp EllipticExpPrime EllipticF EllipticFilterModel EllipticK EllipticLog EllipticNomeQ EllipticPi EllipticReducedHalfPeriods EllipticTheta EllipticThetaPrime EmbedCode EmbeddedHTML EmbeddedService EmbeddingLayer EmbeddingObject EmitSound EmphasizeSyntaxErrors EmpiricalDistribution Empty EmptyGraphQ EmptyRegion EnableConsolePrintPacket Enabled Encode Encrypt EncryptedObject EncryptFile End EndAdd EndDialogPacket EndFrontEndInteractionPacket EndOfBuffer EndOfFile EndOfLine EndOfString EndPackage EngineEnvironment EngineeringForm Enter EnterExpressionPacket EnterTextPacket Entity EntityClass EntityClassList EntityCopies EntityFunction EntityGroup EntityInstance EntityList EntityPrefetch EntityProperties EntityProperty EntityPropertyClass EntityRegister EntityStore EntityStores EntityTypeName EntityUnregister EntityValue Entropy EntropyFilter Environment Epilog EpilogFunction Equal EqualColumns EqualRows EqualTilde EqualTo EquatedTo Equilibrium EquirippleFilterKernel Equivalent Erf Erfc Erfi ErlangB ErlangC ErlangDistribution Erosion ErrorBox ErrorBoxOptions ErrorNorm ErrorPacket ErrorsDialogSettings EscapeRadius EstimatedBackground EstimatedDistribution EstimatedProcess EstimatorGains EstimatorRegulator EuclideanDistance EulerAngles EulerCharacteristic EulerE EulerGamma EulerianGraphQ EulerMatrix EulerPhi Evaluatable Evaluate Evaluated EvaluatePacket EvaluateScheduledTask EvaluationBox EvaluationCell EvaluationCompletionAction EvaluationData EvaluationElements EvaluationEnvironment EvaluationMode EvaluationMonitor EvaluationNotebook EvaluationObject EvaluationOrder Evaluator EvaluatorNames EvenQ EventData EventEvaluator EventHandler EventHandlerTag EventLabels EventSeries ExactBlackmanWindow ExactNumberQ ExactRootIsolation ExampleData Except ExcludedForms ExcludedLines ExcludedPhysicalQuantities ExcludePods Exclusions ExclusionsStyle Exists Exit ExitDialog ExoplanetData Exp Expand ExpandAll ExpandDenominator ExpandFileName ExpandNumerator Expectation ExpectationE ExpectedValue ExpGammaDistribution ExpIntegralE ExpIntegralEi ExpirationDate Exponent ExponentFunction ExponentialDistribution ExponentialFamily ExponentialGeneratingFunction ExponentialMovingAverage ExponentialPowerDistribution ExponentPosition ExponentStep Export ExportAutoReplacements ExportByteArray ExportForm ExportPacket ExportString Expression ExpressionCell ExpressionPacket ExpressionUUID ExpToTrig ExtendedEntityClass ExtendedGCD Extension ExtentElementFunction ExtentMarkers ExtentSize ExternalBundle ExternalCall ExternalDataCharacterEncoding ExternalEvaluate ExternalFunction ExternalFunctionName ExternalObject ExternalOptions ExternalSessionObject ExternalSessions ExternalTypeSignature ExternalValue Extract ExtractArchive ExtractLayer ExtremeValueDistributionFaceForm FaceGrids FaceGridsStyle FacialFeatures Factor FactorComplete Factorial Factorial2 FactorialMoment FactorialMomentGeneratingFunction FactorialPower FactorInteger FactorList FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList Fail Failure FailureAction FailureDistribution FailureQ False FareySequence FARIMAProcess FeatureDistance FeatureExtract FeatureExtraction FeatureExtractor FeatureExtractorFunction FeatureNames FeatureNearest FeatureSpacePlot FeatureSpacePlot3D FeatureTypes FEDisableConsolePrintPacket FeedbackLinearize FeedbackSector FeedbackSectorStyle FeedbackType FEEnableConsolePrintPacket FetalGrowthData Fibonacci Fibonorial FieldCompletionFunction FieldHint FieldHintStyle FieldMasked FieldSize File FileBaseName FileByteCount FileConvert FileDate FileExistsQ FileExtension FileFormat FileHandler FileHash FileInformation FileName FileNameDepth FileNameDialogSettings FileNameDrop FileNameForms FileNameJoin FileNames FileNameSetter FileNameSplit FileNameTake FilePrint FileSize FileSystemMap FileSystemScan FileTemplate FileTemplateApply FileType FilledCurve FilledCurveBox FilledCurveBoxOptions Filling FillingStyle FillingTransform FilteredEntityClass FilterRules FinancialBond FinancialData FinancialDerivative FinancialIndicator Find FindAnomalies FindArgMax FindArgMin FindChannels FindClique FindClusters FindCookies FindCurvePath FindCycle FindDevices FindDistribution FindDistributionParameters FindDivisions FindEdgeCover FindEdgeCut FindEdgeIndependentPaths FindEquationalProof FindEulerianCycle FindExternalEvaluators FindFaces FindFile FindFit FindFormula FindFundamentalCycles FindGeneratingFunction FindGeoLocation FindGeometricConjectures FindGeometricTransform FindGraphCommunities FindGraphIsomorphism FindGraphPartition FindHamiltonianCycle FindHamiltonianPath FindHiddenMarkovStates FindIndependentEdgeSet FindIndependentVertexSet FindInstance FindIntegerNullVector FindKClan FindKClique FindKClub FindKPlex FindLibrary FindLinearRecurrence FindList FindMatchingColor FindMaximum FindMaximumFlow FindMaxValue FindMeshDefects FindMinimum FindMinimumCostFlow FindMinimumCut FindMinValue FindMoleculeSubstructure FindPath FindPeaks FindPermutation FindPostmanTour FindProcessParameters FindRepeat FindRoot FindSequenceFunction FindSettings FindShortestPath FindShortestTour FindSpanningTree FindSystemModelEquilibrium FindTextualAnswer FindThreshold FindTransientRepeat FindVertexCover FindVertexCut FindVertexIndependentPaths Fine FinishDynamic FiniteAbelianGroupCount FiniteGroupCount FiniteGroupData First FirstCase FirstPassageTimeDistribution FirstPosition FischerGroupFi22 FischerGroupFi23 FischerGroupFi24Prime FisherHypergeometricDistribution FisherRatioTest FisherZDistribution Fit FitAll FitRegularization FittedModel FixedOrder FixedPoint FixedPointList FlashSelection Flat Flatten FlattenAt FlattenLayer FlatTopWindow FlipView Floor FlowPolynomial FlushPrintOutputPacket Fold FoldList FoldPair FoldPairList FollowRedirects Font FontColor FontFamily FontForm FontName FontOpacity FontPostScriptName FontProperties FontReencoding FontSize FontSlant FontSubstitutions FontTracking FontVariations FontWeight For ForAll Format FormatRules FormatType FormatTypeAutoConvert FormatValues FormBox FormBoxOptions FormControl FormFunction FormLayoutFunction FormObject FormPage FormTheme FormulaData FormulaLookup FortranForm Forward ForwardBackward Fourier FourierCoefficient FourierCosCoefficient FourierCosSeries FourierCosTransform FourierDCT FourierDCTFilter FourierDCTMatrix FourierDST FourierDSTMatrix FourierMatrix FourierParameters FourierSequenceTransform FourierSeries FourierSinCoefficient FourierSinSeries FourierSinTransform FourierTransform FourierTrigSeries FractionalBrownianMotionProcess FractionalGaussianNoiseProcess FractionalPart FractionBox FractionBoxOptions FractionLine Frame FrameBox FrameBoxOptions Framed FrameInset FrameLabel Frameless FrameMargins FrameRate FrameStyle FrameTicks FrameTicksStyle FRatioDistribution FrechetDistribution FreeQ FrenetSerretSystem FrequencySamplingFilterKernel FresnelC FresnelF FresnelG FresnelS Friday FrobeniusNumber FrobeniusSolve FromAbsoluteTime FromCharacterCode FromCoefficientRules FromContinuedFraction FromDate FromDigits FromDMS FromEntity FromJulianDate FromLetterNumber FromPolarCoordinates FromRomanNumeral FromSphericalCoordinates FromUnixTime Front FrontEndDynamicExpression FrontEndEventActions FrontEndExecute FrontEndObject FrontEndResource FrontEndResourceString FrontEndStackSize FrontEndToken FrontEndTokenExecute FrontEndValueCache FrontEndVersion FrontFaceColor FrontFaceOpacity Full FullAxes FullDefinition FullForm FullGraphics FullInformationOutputRegulator FullOptions FullRegion FullSimplify Function FunctionCompile FunctionCompileExport FunctionCompileExportByteArray FunctionCompileExportLibrary FunctionCompileExportString FunctionDomain FunctionExpand FunctionInterpolation FunctionPeriod FunctionRange FunctionSpace FussellVeselyImportanceGaborFilter GaborMatrix GaborWavelet GainMargins GainPhaseMargins GalaxyData GalleryView Gamma GammaDistribution GammaRegularized GapPenalty GARCHProcess GatedRecurrentLayer Gather GatherBy GaugeFaceElementFunction GaugeFaceStyle GaugeFrameElementFunction GaugeFrameSize GaugeFrameStyle GaugeLabels GaugeMarkers GaugeStyle GaussianFilter GaussianIntegers GaussianMatrix GaussianOrthogonalMatrixDistribution GaussianSymplecticMatrixDistribution GaussianUnitaryMatrixDistribution GaussianWindow GCD GegenbauerC General GeneralizedLinearModelFit GenerateAsymmetricKeyPair GenerateConditions GeneratedCell GeneratedDocumentBinding GenerateDerivedKey GenerateDigitalSignature GenerateDocument GeneratedParameters GeneratedQuantityMagnitudes GenerateHTTPResponse GenerateSecuredAuthenticationKey GenerateSymmetricKey GeneratingFunction GeneratorDescription GeneratorHistoryLength GeneratorOutputType Generic GenericCylindricalDecomposition GenomeData GenomeLookup GeoAntipode GeoArea GeoArraySize GeoBackground GeoBoundingBox GeoBounds GeoBoundsRegion GeoBubbleChart GeoCenter GeoCircle GeodesicClosing GeodesicDilation GeodesicErosion GeodesicOpening GeoDestination GeodesyData GeoDirection GeoDisk GeoDisplacement GeoDistance GeoDistanceList GeoElevationData GeoEntities GeoGraphics GeogravityModelData GeoGridDirectionDifference GeoGridLines GeoGridLinesStyle GeoGridPosition GeoGridRange GeoGridRangePadding GeoGridUnitArea GeoGridUnitDistance GeoGridVector GeoGroup GeoHemisphere GeoHemisphereBoundary GeoHistogram GeoIdentify GeoImage GeoLabels GeoLength GeoListPlot GeoLocation GeologicalPeriodData GeomagneticModelData GeoMarker GeometricAssertion GeometricBrownianMotionProcess GeometricDistribution GeometricMean GeometricMeanFilter GeometricScene GeometricTransformation GeometricTransformation3DBox GeometricTransformation3DBoxOptions GeometricTransformationBox GeometricTransformationBoxOptions GeoModel GeoNearest GeoPath GeoPosition GeoPositionENU GeoPositionXYZ GeoProjection GeoProjectionData GeoRange GeoRangePadding GeoRegionValuePlot GeoResolution GeoScaleBar GeoServer GeoSmoothHistogram GeoStreamPlot GeoStyling GeoStylingImageFunction GeoVariant GeoVector GeoVectorENU GeoVectorPlot GeoVectorXYZ GeoVisibleRegion GeoVisibleRegionBoundary GeoWithinQ GeoZoomLevel GestureHandler GestureHandlerTag Get GetBoundingBoxSizePacket GetContext GetEnvironment GetFileName GetFrontEndOptionsDataPacket GetLinebreakInformationPacket GetMenusPacket GetPageBreakInformationPacket Glaisher GlobalClusteringCoefficient GlobalPreferences GlobalSession Glow GoldenAngle GoldenRatio GompertzMakehamDistribution GoodmanKruskalGamma GoodmanKruskalGammaTest Goto Grad Gradient GradientFilter GradientOrientationFilter GrammarApply GrammarRules GrammarToken Graph Graph3D GraphAssortativity GraphAutomorphismGroup GraphCenter GraphComplement GraphData GraphDensity GraphDiameter GraphDifference GraphDisjointUnion GraphDistance GraphDistanceMatrix GraphElementData GraphEmbedding GraphHighlight GraphHighlightStyle GraphHub Graphics Graphics3D Graphics3DBox Graphics3DBoxOptions GraphicsArray GraphicsBaseline GraphicsBox GraphicsBoxOptions GraphicsColor GraphicsColumn GraphicsComplex GraphicsComplex3DBox GraphicsComplex3DBoxOptions GraphicsComplexBox GraphicsComplexBoxOptions GraphicsContents GraphicsData GraphicsGrid GraphicsGridBox GraphicsGroup GraphicsGroup3DBox GraphicsGroup3DBoxOptions GraphicsGroupBox GraphicsGroupBoxOptions GraphicsGrouping GraphicsHighlightColor GraphicsRow GraphicsSpacing GraphicsStyle GraphIntersection GraphLayout GraphLinkEfficiency GraphPeriphery GraphPlot GraphPlot3D GraphPower GraphPropertyDistribution GraphQ GraphRadius GraphReciprocity GraphRoot GraphStyle GraphUnion Gray GrayLevel Greater GreaterEqual GreaterEqualLess GreaterEqualThan GreaterFullEqual GreaterGreater GreaterLess GreaterSlantEqual GreaterThan GreaterTilde Green GreenFunction Grid GridBaseline GridBox GridBoxAlignment GridBoxBackground GridBoxDividers GridBoxFrame GridBoxItemSize GridBoxItemStyle GridBoxOptions GridBoxSpacings GridCreationSettings GridDefaultElement GridElementStyleOptions GridFrame GridFrameMargins GridGraph GridLines GridLinesStyle GroebnerBasis GroupActionBase GroupBy GroupCentralizer GroupElementFromWord GroupElementPosition GroupElementQ GroupElements GroupElementToWord GroupGenerators Groupings GroupMultiplicationTable GroupOrbits GroupOrder GroupPageBreakWithin GroupSetwiseStabilizer GroupStabilizer GroupStabilizerChain GroupTogetherGrouping GroupTogetherNestedGrouping GrowCutComponents Gudermannian GuidedFilter GumbelDistributionHaarWavelet HadamardMatrix HalfLine HalfNormalDistribution HalfPlane HalfSpace HamiltonianGraphQ HammingDistance HammingWindow HandlerFunctions HandlerFunctionsKeys HankelH1 HankelH2 HankelMatrix HankelTransform HannPoissonWindow HannWindow HaradaNortonGroupHN HararyGraph HarmonicMean HarmonicMeanFilter HarmonicNumber Hash Haversine HazardFunction Head HeadCompose HeaderLines Heads HeavisideLambda HeavisidePi HeavisideTheta HeldGroupHe HeldPart HelpBrowserLookup HelpBrowserNotebook HelpBrowserSettings Here HermiteDecomposition HermiteH HermitianMatrixQ HessenbergDecomposition Hessian HexadecimalCharacter Hexahedron HexahedronBox HexahedronBoxOptions HiddenMarkovProcess HiddenSurface Highlighted HighlightGraph HighlightImage HighlightMesh HighpassFilter HigmanSimsGroupHS HilbertCurve HilbertFilter HilbertMatrix Histogram Histogram3D HistogramDistribution HistogramList HistogramTransform HistogramTransformInterpolation HistoricalPeriodData HitMissTransform HITSCentrality HjorthDistribution HodgeDual HoeffdingD HoeffdingDTest Hold HoldAll HoldAllComplete HoldComplete HoldFirst HoldForm HoldPattern HoldRest HolidayCalendar HomeDirectory HomePage Horizontal HorizontalForm HorizontalGauge HorizontalScrollPosition HornerForm HostLookup HotellingTSquareDistribution HoytDistribution HTMLSave HTTPErrorResponse HTTPRedirect HTTPRequest HTTPRequestData HTTPResponse Hue HumanGrowthData HumpDownHump HumpEqual HurwitzLerchPhi HurwitzZeta HyperbolicDistribution HypercubeGraph HyperexponentialDistribution Hyperfactorial Hypergeometric0F1 Hypergeometric0F1Regularized Hypergeometric1F1 Hypergeometric1F1Regularized Hypergeometric2F1 Hypergeometric2F1Regularized HypergeometricDistribution HypergeometricPFQ HypergeometricPFQRegularized HypergeometricU Hyperlink HyperlinkCreationSettings Hyperplane Hyphenation HyphenationOptions HypoexponentialDistribution HypothesisTestDataI IconData Iconize IconizedObject IconRules Icosahedron Identity IdentityMatrix If IgnoreCase IgnoreDiacritics IgnorePunctuation IgnoreSpellCheck IgnoringInactive Im Image Image3D Image3DProjection Image3DSlices ImageAccumulate ImageAdd ImageAdjust ImageAlign ImageApply ImageApplyIndexed ImageAspectRatio ImageAssemble ImageAugmentationLayer ImageBoundingBoxes ImageCache ImageCacheValid ImageCapture ImageCaptureFunction ImageCases ImageChannels ImageClip ImageCollage ImageColorSpace ImageCompose ImageContainsQ ImageContents ImageConvolve ImageCooccurrence ImageCorners ImageCorrelate ImageCorrespondingPoints ImageCrop ImageData ImageDeconvolve ImageDemosaic ImageDifference ImageDimensions ImageDisplacements ImageDistance ImageEffect ImageExposureCombine ImageFeatureTrack ImageFileApply ImageFileFilter ImageFileScan ImageFilter ImageFocusCombine ImageForestingComponents ImageFormattingWidth ImageForwardTransformation ImageGraphics ImageHistogram ImageIdentify ImageInstanceQ ImageKeypoints ImageLevels ImageLines ImageMargins ImageMarker ImageMarkers ImageMeasurements ImageMesh ImageMultiply ImageOffset ImagePad ImagePadding ImagePartition ImagePeriodogram ImagePerspectiveTransformation ImagePosition ImagePreviewFunction ImagePyramid ImagePyramidApply ImageQ ImageRangeCache ImageRecolor ImageReflect ImageRegion ImageResize ImageResolution ImageRestyle ImageRotate ImageRotated ImageSaliencyFilter ImageScaled ImageScan ImageSize ImageSizeAction ImageSizeCache ImageSizeMultipliers ImageSizeRaw ImageSubtract ImageTake ImageTransformation ImageTrim ImageType ImageValue ImageValuePositions ImagingDevice ImplicitRegion Implies Import ImportAutoReplacements ImportByteArray ImportOptions ImportString ImprovementImportance In Inactivate Inactive IncidenceGraph IncidenceList IncidenceMatrix IncludeAromaticBonds IncludeConstantBasis IncludeDefinitions IncludeDirectories IncludeFileExtension IncludeGeneratorTasks IncludeHydrogens IncludeInflections IncludeMetaInformation IncludePods IncludeQuantities IncludeRelatedTables IncludeSingularTerm IncludeWindowTimes Increment IndefiniteMatrixQ Indent IndentingNewlineSpacings IndentMaxFraction IndependenceTest IndependentEdgeSetQ IndependentPhysicalQuantity IndependentUnit IndependentUnitDimension IndependentVertexSetQ Indeterminate IndeterminateThreshold IndexCreationOptions Indexed IndexGraph IndexTag Inequality InexactNumberQ InexactNumbers InfiniteLine InfinitePlane Infinity Infix InflationAdjust InflationMethod Information InformationData InformationDataGrid Inherited InheritScope InhomogeneousPoissonProcess InitialEvaluationHistory Initialization InitializationCell InitializationCellEvaluation InitializationCellWarning InitializationObjects InitializationValue Initialize InitialSeeding InlineCounterAssignments InlineCounterIncrements InlineRules Inner InnerPolygon InnerPolyhedron Inpaint Input InputAliases InputAssumptions InputAutoReplacements InputField InputFieldBox InputFieldBoxOptions InputForm InputGrouping InputNamePacket InputNotebook InputPacket InputSettings InputStream InputString InputStringPacket InputToBoxFormPacket Insert InsertionFunction InsertionPointObject InsertLinebreaks InsertResults Inset Inset3DBox Inset3DBoxOptions InsetBox InsetBoxOptions Insphere Install InstallService InstanceNormalizationLayer InString Integer IntegerDigits IntegerExponent IntegerLength IntegerName IntegerPart IntegerPartitions IntegerQ IntegerReverse Integers IntegerString Integral Integrate Interactive InteractiveTradingChart Interlaced Interleaving InternallyBalancedDecomposition InterpolatingFunction InterpolatingPolynomial Interpolation InterpolationOrder InterpolationPoints InterpolationPrecision Interpretation InterpretationBox InterpretationBoxOptions InterpretationFunction Interpreter InterpretTemplate InterquartileRange Interrupt InterruptSettings IntersectingQ Intersection Interval IntervalIntersection IntervalMarkers IntervalMarkersStyle IntervalMemberQ IntervalSlider IntervalUnion Into Inverse InverseBetaRegularized InverseCDF InverseChiSquareDistribution InverseContinuousWaveletTransform InverseDistanceTransform InverseEllipticNomeQ InverseErf InverseErfc InverseFourier InverseFourierCosTransform InverseFourierSequenceTransform InverseFourierSinTransform InverseFourierTransform InverseFunction InverseFunctions InverseGammaDistribution InverseGammaRegularized InverseGaussianDistribution InverseGudermannian InverseHankelTransform InverseHaversine InverseImagePyramid InverseJacobiCD InverseJacobiCN InverseJacobiCS InverseJacobiDC InverseJacobiDN InverseJacobiDS InverseJacobiNC InverseJacobiND InverseJacobiNS InverseJacobiSC InverseJacobiSD InverseJacobiSN InverseLaplaceTransform InverseMellinTransform InversePermutation InverseRadon InverseRadonTransform InverseSeries InverseShortTimeFourier InverseSpectrogram InverseSurvivalFunction InverseTransformedRegion InverseWaveletTransform InverseWeierstrassP InverseWishartMatrixDistribution InverseZTransform Invisible InvisibleApplication InvisibleTimes IPAddress IrreduciblePolynomialQ IslandData IsolatingInterval IsomorphicGraphQ IsotopeData Italic Item ItemAspectRatio ItemBox ItemBoxOptions ItemSize ItemStyle ItoProcessJaccardDissimilarity JacobiAmplitude Jacobian JacobiCD JacobiCN JacobiCS JacobiDC JacobiDN JacobiDS JacobiNC JacobiND JacobiNS JacobiP JacobiSC JacobiSD JacobiSN JacobiSymbol JacobiZeta JankoGroupJ1 JankoGroupJ2 JankoGroupJ3 JankoGroupJ4 JarqueBeraALMTest JohnsonDistribution Join JoinAcross Joined JoinedCurve JoinedCurveBox JoinedCurveBoxOptions JoinForm JordanDecomposition JordanModelDecomposition JulianDate JuliaSetBoettcher JuliaSetIterationCount JuliaSetPlot JuliaSetPointsK KagiChart KaiserBesselWindow KaiserWindow KalmanEstimator KalmanFilter KarhunenLoeveDecomposition KaryTree KatzCentrality KCoreComponents KDistribution KEdgeConnectedComponents KEdgeConnectedGraphQ KelvinBei KelvinBer KelvinKei KelvinKer KendallTau KendallTauTest KernelExecute KernelFunction KernelMixtureDistribution Kernels Ket Key KeyCollisionFunction KeyComplement KeyDrop KeyDropFrom KeyExistsQ KeyFreeQ KeyIntersection KeyMap KeyMemberQ KeypointStrength Keys KeySelect KeySort KeySortBy KeyTake KeyUnion KeyValueMap KeyValuePattern Khinchin KillProcess KirchhoffGraph KirchhoffMatrix KleinInvariantJ KnapsackSolve KnightTourGraph KnotData KnownUnitQ KochCurve KolmogorovSmirnovTest KroneckerDelta KroneckerModelDecomposition KroneckerProduct KroneckerSymbol KuiperTest KumaraswamyDistribution Kurtosis KuwaharaFilter KVertexConnectedComponents KVertexConnectedGraphQLABColor Label Labeled LabeledSlider LabelingFunction LabelingSize LabelStyle LabelVisibility LaguerreL LakeData LambdaComponents LambertW LaminaData LanczosWindow LandauDistribution Language LanguageCategory LanguageData LanguageIdentify LanguageOptions LaplaceDistribution LaplaceTransform Laplacian LaplacianFilter LaplacianGaussianFilter Large Larger Last Latitude LatitudeLongitude LatticeData LatticeReduce Launch LaunchKernels LayeredGraphPlot LayerSizeFunction LayoutInformation LCHColor LCM LeaderSize LeafCount LeapYearQ LearnDistribution LearnedDistribution LearningRate LearningRateMultipliers LeastSquares LeastSquaresFilterKernel Left LeftArrow LeftArrowBar LeftArrowRightArrow LeftDownTeeVector LeftDownVector LeftDownVectorBar LeftRightArrow LeftRightVector LeftTee LeftTeeArrow LeftTeeVector LeftTriangle LeftTriangleBar LeftTriangleEqual LeftUpDownVector LeftUpTeeVector LeftUpVector LeftUpVectorBar LeftVector LeftVectorBar LegendAppearance Legended LegendFunction LegendLabel LegendLayout LegendMargins LegendMarkers LegendMarkerSize LegendreP LegendreQ LegendreType Length LengthWhile LerchPhi Less LessEqual LessEqualGreater LessEqualThan LessFullEqual LessGreater LessLess LessSlantEqual LessThan LessTilde LetterCharacter LetterCounts LetterNumber LetterQ Level LeveneTest LeviCivitaTensor LevyDistribution Lexicographic LibraryDataType LibraryFunction LibraryFunctionError LibraryFunctionInformation LibraryFunctionLoad LibraryFunctionUnload LibraryLoad LibraryUnload LicenseID LiftingFilterData LiftingWaveletTransform LightBlue LightBrown LightCyan Lighter LightGray LightGreen Lighting LightingAngle LightMagenta LightOrange LightPink LightPurple LightRed LightSources LightYellow Likelihood Limit LimitsPositioning LimitsPositioningTokens LindleyDistribution Line Line3DBox Line3DBoxOptions LinearFilter LinearFractionalOptimization LinearFractionalTransform LinearGradientImage LinearizingTransformationData LinearLayer LinearModelFit LinearOffsetFunction LinearOptimization LinearProgramming LinearRecurrence LinearSolve LinearSolveFunction LineBox LineBoxOptions LineBreak LinebreakAdjustments LineBreakChart LinebreakSemicolonWeighting LineBreakWithin LineColor LineGraph LineIndent LineIndentMaxFraction LineIntegralConvolutionPlot LineIntegralConvolutionScale LineLegend LineOpacity LineSpacing LineWrapParts LinkActivate LinkClose LinkConnect LinkConnectedQ LinkCreate LinkError LinkFlush LinkFunction LinkHost LinkInterrupt LinkLaunch LinkMode LinkObject LinkOpen LinkOptions LinkPatterns LinkProtocol LinkRankCentrality LinkRead LinkReadHeld LinkReadyQ Links LinkService LinkWrite LinkWriteHeld LiouvilleLambda List Listable ListAnimate ListContourPlot ListContourPlot3D ListConvolve ListCorrelate ListCurvePathPlot ListDeconvolve ListDensityPlot ListDensityPlot3D Listen ListFormat ListFourierSequenceTransform ListInterpolation ListLineIntegralConvolutionPlot ListLinePlot ListLogLinearPlot ListLogLogPlot ListLogPlot ListPicker ListPickerBox ListPickerBoxBackground ListPickerBoxOptions ListPlay ListPlot ListPlot3D ListPointPlot3D ListPolarPlot ListQ ListSliceContourPlot3D ListSliceDensityPlot3D ListSliceVectorPlot3D ListStepPlot ListStreamDensityPlot ListStreamPlot ListSurfacePlot3D ListVectorDensityPlot ListVectorPlot ListVectorPlot3D ListZTransform Literal LiteralSearch LocalAdaptiveBinarize LocalCache LocalClusteringCoefficient LocalizeDefinitions LocalizeVariables LocalObject LocalObjects LocalResponseNormalizationLayer LocalSubmit LocalSymbol LocalTime LocalTimeZone LocationEquivalenceTest LocationTest Locator LocatorAutoCreate LocatorBox LocatorBoxOptions LocatorCentering LocatorPane LocatorPaneBox LocatorPaneBoxOptions LocatorRegion Locked Log Log10 Log2 LogBarnesG LogGamma LogGammaDistribution LogicalExpand LogIntegral LogisticDistribution LogisticSigmoid LogitModelFit LogLikelihood LogLinearPlot LogLogisticDistribution LogLogPlot LogMultinormalDistribution LogNormalDistribution LogPlot LogRankTest LogSeriesDistribution LongEqual Longest LongestCommonSequence LongestCommonSequencePositions LongestCommonSubsequence LongestCommonSubsequencePositions LongestMatch LongestOrderedSequence LongForm Longitude LongLeftArrow LongLeftRightArrow LongRightArrow LongShortTermMemoryLayer Lookup Loopback LoopFreeGraphQ LossFunction LowerCaseQ LowerLeftArrow LowerRightArrow LowerTriangularize LowerTriangularMatrixQ LowpassFilter LQEstimatorGains LQGRegulator LQOutputRegulatorGains LQRegulatorGains LUBackSubstitution LucasL LuccioSamiComponents LUDecomposition LunarEclipse LUVColor LyapunovSolve LyonsGroupLyMachineID MachineName MachineNumberQ MachinePrecision MacintoshSystemPageSetup Magenta Magnification Magnify MailAddressValidation MailExecute MailFolder MailItem MailReceiverFunction MailResponseFunction MailSearch MailServerConnect MailServerConnection MailSettings MainSolve MaintainDynamicCaches Majority MakeBoxes MakeExpression MakeRules ManagedLibraryExpressionID ManagedLibraryExpressionQ MandelbrotSetBoettcher MandelbrotSetDistance MandelbrotSetIterationCount MandelbrotSetMemberQ MandelbrotSetPlot MangoldtLambda ManhattanDistance Manipulate Manipulator MannedSpaceMissionData MannWhitneyTest MantissaExponent Manual Map MapAll MapAt MapIndexed MAProcess MapThread MarchenkoPasturDistribution MarcumQ MardiaCombinedTest MardiaKurtosisTest MardiaSkewnessTest MarginalDistribution MarkovProcessProperties Masking MatchingDissimilarity MatchLocalNameQ MatchLocalNames MatchQ Material MathematicalFunctionData MathematicaNotation MathieuC MathieuCharacteristicA MathieuCharacteristicB MathieuCharacteristicExponent MathieuCPrime MathieuGroupM11 MathieuGroupM12 MathieuGroupM22 MathieuGroupM23 MathieuGroupM24 MathieuS MathieuSPrime MathMLForm MathMLText Matrices MatrixExp MatrixForm MatrixFunction MatrixLog MatrixNormalDistribution MatrixPlot MatrixPower MatrixPropertyDistribution MatrixQ MatrixRank MatrixTDistribution Max MaxBend MaxCellMeasure MaxColorDistance MaxDetect MaxDuration MaxExtraBandwidths MaxExtraConditions MaxFeatureDisplacement MaxFeatures MaxFilter MaximalBy Maximize MaxItems MaxIterations MaxLimit MaxMemoryUsed MaxMixtureKernels MaxOverlapFraction MaxPlotPoints MaxPoints MaxRecursion MaxStableDistribution MaxStepFraction MaxSteps MaxStepSize MaxTrainingRounds MaxValue MaxwellDistribution MaxWordGap McLaughlinGroupMcL Mean MeanAbsoluteLossLayer MeanAround MeanClusteringCoefficient MeanDegreeConnectivity MeanDeviation MeanFilter MeanGraphDistance MeanNeighborDegree MeanShift MeanShiftFilter MeanSquaredLossLayer Median MedianDeviation MedianFilter MedicalTestData Medium MeijerG MeijerGReduce MeixnerDistribution MellinConvolve MellinTransform MemberQ MemoryAvailable MemoryConstrained MemoryConstraint MemoryInUse MengerMesh Menu MenuAppearance MenuCommandKey MenuEvaluator MenuItem MenuList MenuPacket MenuSortingValue MenuStyle MenuView Merge MergeDifferences MergingFunction MersennePrimeExponent MersennePrimeExponentQ Mesh MeshCellCentroid MeshCellCount MeshCellHighlight MeshCellIndex MeshCellLabel MeshCellMarker MeshCellMeasure MeshCellQuality MeshCells MeshCellShapeFunction MeshCellStyle MeshCoordinates MeshFunctions MeshPrimitives MeshQualityGoal MeshRange MeshRefinementFunction MeshRegion MeshRegionQ MeshShading MeshStyle Message MessageDialog MessageList MessageName MessageObject MessageOptions MessagePacket Messages MessagesNotebook MetaCharacters MetaInformation MeteorShowerData Method MethodOptions MexicanHatWavelet MeyerWavelet Midpoint Min MinColorDistance MinDetect MineralData MinFilter MinimalBy MinimalPolynomial MinimalStateSpaceModel Minimize MinimumTimeIncrement MinIntervalSize MinkowskiQuestionMark MinLimit MinMax MinorPlanetData Minors MinRecursion MinSize MinStableDistribution Minus MinusPlus MinValue Missing MissingBehavior MissingDataMethod MissingDataRules MissingQ MissingString MissingStyle MissingValuePattern MittagLefflerE MixedFractionParts MixedGraphQ MixedMagnitude MixedRadix MixedRadixQuantity MixedUnit MixtureDistribution Mod Modal Mode Modular ModularInverse ModularLambda Module Modulus MoebiusMu Molecule MoleculeContainsQ MoleculeEquivalentQ MoleculeGraph MoleculeModify MoleculePattern MoleculePlot MoleculePlot3D MoleculeProperty MoleculeQ MoleculeValue Moment Momentary MomentConvert MomentEvaluate MomentGeneratingFunction MomentOfInertia Monday Monitor MonomialList MonomialOrder MonsterGroupM MoonPhase MoonPosition MorletWavelet MorphologicalBinarize MorphologicalBranchPoints MorphologicalComponents MorphologicalEulerNumber MorphologicalGraph MorphologicalPerimeter MorphologicalTransform MortalityData Most MountainData MouseAnnotation MouseAppearance MouseAppearanceTag MouseButtons Mouseover MousePointerNote MousePosition MovieData MovingAverage MovingMap MovingMedian MoyalDistribution Multicolumn MultiedgeStyle MultigraphQ MultilaunchWarning MultiLetterItalics MultiLetterStyle MultilineFunction Multinomial MultinomialDistribution MultinormalDistribution MultiplicativeOrder Multiplicity MultiplySides Multiselection MultivariateHypergeometricDistribution MultivariatePoissonDistribution MultivariateTDistributionN NakagamiDistribution NameQ Names NamespaceBox NamespaceBoxOptions Nand NArgMax NArgMin NBernoulliB NBodySimulation NBodySimulationData NCache NDEigensystem NDEigenvalues NDSolve NDSolveValue Nearest NearestFunction NearestNeighborGraph NearestTo NebulaData NeedCurrentFrontEndPackagePacket NeedCurrentFrontEndSymbolsPacket NeedlemanWunschSimilarity Needs Negative NegativeBinomialDistribution NegativeDefiniteMatrixQ NegativeIntegers NegativeMultinomialDistribution NegativeRationals NegativeReals NegativeSemidefiniteMatrixQ NeighborhoodData NeighborhoodGraph Nest NestedGreaterGreater NestedLessLess NestedScriptRules NestGraph NestList NestWhile NestWhileList NetAppend NetBidirectionalOperator NetChain NetDecoder NetDelete NetDrop NetEncoder NetEvaluationMode NetExtract NetFlatten NetFoldOperator NetGraph NetInformation NetInitialize NetInsert NetInsertSharedArrays NetJoin NetMapOperator NetMapThreadOperator NetMeasurements NetModel NetNestOperator NetPairEmbeddingOperator NetPort NetPortGradient NetPrepend NetRename NetReplace NetReplacePart NetSharedArray NetStateObject NetTake NetTrain NetTrainResultsObject NetworkPacketCapture NetworkPacketRecording NetworkPacketRecordingDuring NetworkPacketTrace NeumannValue NevilleThetaC NevilleThetaD NevilleThetaN NevilleThetaS NewPrimitiveStyle NExpectation Next NextCell NextDate NextPrime NextScheduledTaskTime NHoldAll NHoldFirst NHoldRest NicholsGridLines NicholsPlot NightHemisphere NIntegrate NMaximize NMaxValue NMinimize NMinValue NominalVariables NonAssociative NoncentralBetaDistribution NoncentralChiSquareDistribution NoncentralFRatioDistribution NoncentralStudentTDistribution NonCommutativeMultiply NonConstants NondimensionalizationTransform None NoneTrue NonlinearModelFit NonlinearStateSpaceModel NonlocalMeansFilter NonNegative NonNegativeIntegers NonNegativeRationals NonNegativeReals NonPositive NonPositiveIntegers NonPositiveRationals NonPositiveReals Nor NorlundB Norm Normal NormalDistribution NormalGrouping NormalizationLayer Normalize Normalized NormalizedSquaredEuclideanDistance NormalMatrixQ NormalsFunction NormFunction Not NotCongruent NotCupCap NotDoubleVerticalBar Notebook NotebookApply NotebookAutoSave NotebookClose NotebookConvertSettings NotebookCreate NotebookCreateReturnObject NotebookDefault NotebookDelete NotebookDirectory NotebookDynamicExpression NotebookEvaluate NotebookEventActions NotebookFileName NotebookFind NotebookFindReturnObject NotebookGet NotebookGetLayoutInformationPacket NotebookGetMisspellingsPacket NotebookImport NotebookInformation NotebookInterfaceObject NotebookLocate NotebookObject NotebookOpen NotebookOpenReturnObject NotebookPath NotebookPrint NotebookPut NotebookPutReturnObject NotebookRead NotebookResetGeneratedCells Notebooks NotebookSave NotebookSaveAs NotebookSelection NotebookSetupLayoutInformationPacket NotebooksMenu NotebookTemplate NotebookWrite NotElement NotEqualTilde NotExists NotGreater NotGreaterEqual NotGreaterFullEqual NotGreaterGreater NotGreaterLess NotGreaterSlantEqual NotGreaterTilde Nothing NotHumpDownHump NotHumpEqual NotificationFunction NotLeftTriangle NotLeftTriangleBar NotLeftTriangleEqual NotLess NotLessEqual NotLessFullEqual NotLessGreater NotLessLess NotLessSlantEqual NotLessTilde NotNestedGreaterGreater NotNestedLessLess NotPrecedes NotPrecedesEqual NotPrecedesSlantEqual NotPrecedesTilde NotReverseElement NotRightTriangle NotRightTriangleBar NotRightTriangleEqual NotSquareSubset NotSquareSubsetEqual NotSquareSuperset NotSquareSupersetEqual NotSubset NotSubsetEqual NotSucceeds NotSucceedsEqual NotSucceedsSlantEqual NotSucceedsTilde NotSuperset NotSupersetEqual NotTilde NotTildeEqual NotTildeFullEqual NotTildeTilde NotVerticalBar Now NoWhitespace NProbability NProduct NProductFactors NRoots NSolve NSum NSumTerms NuclearExplosionData NuclearReactorData Null NullRecords NullSpace NullWords Number NumberCompose NumberDecompose NumberExpand NumberFieldClassNumber NumberFieldDiscriminant NumberFieldFundamentalUnits NumberFieldIntegralBasis NumberFieldNormRepresentatives NumberFieldRegulator NumberFieldRootsOfUnity NumberFieldSignature NumberForm NumberFormat NumberLinePlot NumberMarks NumberMultiplier NumberPadding NumberPoint NumberQ NumberSeparator NumberSigns NumberString Numerator NumeratorDenominator NumericalOrder NumericalSort NumericArray NumericArrayQ NumericArrayType NumericFunction NumericQ NuttallWindow NValues NyquistGridLines NyquistPlotO ObservabilityGramian ObservabilityMatrix ObservableDecomposition ObservableModelQ OceanData Octahedron OddQ Off Offset OLEData On ONanGroupON Once OneIdentity Opacity OpacityFunction OpacityFunctionScaling Open OpenAppend Opener OpenerBox OpenerBoxOptions OpenerView OpenFunctionInspectorPacket Opening OpenRead OpenSpecialOptions OpenTemporary OpenWrite Operate OperatingSystem OptimumFlowData Optional OptionalElement OptionInspectorSettings OptionQ Options OptionsPacket OptionsPattern OptionValue OptionValueBox OptionValueBoxOptions Or Orange Order OrderDistribution OrderedQ Ordering OrderingBy OrderingLayer Orderless OrderlessPatternSequence OrnsteinUhlenbeckProcess Orthogonalize OrthogonalMatrixQ Out Outer OuterPolygon OuterPolyhedron OutputAutoOverwrite OutputControllabilityMatrix OutputControllableModelQ OutputForm OutputFormData OutputGrouping OutputMathEditExpression OutputNamePacket OutputResponse OutputSizeLimit OutputStream Over OverBar OverDot Overflow OverHat Overlaps Overlay OverlayBox OverlayBoxOptions Overscript OverscriptBox OverscriptBoxOptions OverTilde OverVector OverwriteTarget OwenT OwnValuesPackage PackingMethod PaddedForm Padding PaddingLayer PaddingSize PadeApproximant PadLeft PadRight PageBreakAbove PageBreakBelow PageBreakWithin PageFooterLines PageFooters PageHeaderLines PageHeaders PageHeight PageRankCentrality PageTheme PageWidth Pagination PairedBarChart PairedHistogram PairedSmoothHistogram PairedTTest PairedZTest PaletteNotebook PalettePath PalindromeQ Pane PaneBox PaneBoxOptions Panel PanelBox PanelBoxOptions Paneled PaneSelector PaneSelectorBox PaneSelectorBoxOptions PaperWidth ParabolicCylinderD ParagraphIndent ParagraphSpacing ParallelArray ParallelCombine ParallelDo Parallelepiped ParallelEvaluate Parallelization Parallelize ParallelMap ParallelNeeds Parallelogram ParallelProduct ParallelSubmit ParallelSum ParallelTable ParallelTry Parameter ParameterEstimator ParameterMixtureDistribution ParameterVariables ParametricFunction ParametricNDSolve ParametricNDSolveValue ParametricPlot ParametricPlot3D ParametricRegion ParentBox ParentCell ParentConnect ParentDirectory ParentForm Parenthesize ParentList ParentNotebook ParetoDistribution ParetoPickandsDistribution ParkData Part PartBehavior PartialCorrelationFunction PartialD ParticleAcceleratorData ParticleData Partition PartitionGranularity PartitionsP PartitionsQ PartLayer PartOfSpeech PartProtection ParzenWindow PascalDistribution PassEventsDown PassEventsUp Paste PasteAutoQuoteCharacters PasteBoxFormInlineCells PasteButton Path PathGraph PathGraphQ Pattern PatternSequence PatternTest PauliMatrix PaulWavelet Pause PausedTime PDF PeakDetect PeanoCurve PearsonChiSquareTest PearsonCorrelationTest PearsonDistribution PercentForm PerfectNumber PerfectNumberQ PerformanceGoal Perimeter PeriodicBoundaryCondition PeriodicInterpolation Periodogram PeriodogramArray Permanent Permissions PermissionsGroup PermissionsGroupMemberQ PermissionsGroups PermissionsKey PermissionsKeys PermutationCycles PermutationCyclesQ PermutationGroup PermutationLength PermutationList PermutationListQ PermutationMax PermutationMin PermutationOrder PermutationPower PermutationProduct PermutationReplace Permutations PermutationSupport Permute PeronaMalikFilter Perpendicular PerpendicularBisector PersistenceLocation PersistenceTime PersistentObject PersistentObjects PersistentValue PersonData PERTDistribution PetersenGraph PhaseMargins PhaseRange PhysicalSystemData Pi Pick PIDData PIDDerivativeFilter PIDFeedforward PIDTune Piecewise PiecewiseExpand PieChart PieChart3D PillaiTrace PillaiTraceTest PingTime Pink PitchRecognize Pivoting PixelConstrained PixelValue PixelValuePositions Placed Placeholder PlaceholderReplace Plain PlanarAngle PlanarGraph PlanarGraphQ PlanckRadiationLaw PlaneCurveData PlanetaryMoonData PlanetData PlantData Play PlayRange Plot Plot3D Plot3Matrix PlotDivision PlotJoined PlotLabel PlotLabels PlotLayout PlotLegends PlotMarkers PlotPoints PlotRange PlotRangeClipping PlotRangeClipPlanesStyle PlotRangePadding PlotRegion PlotStyle PlotTheme Pluralize Plus PlusMinus Pochhammer PodStates PodWidth Point Point3DBox Point3DBoxOptions PointBox PointBoxOptions PointFigureChart PointLegend PointSize PoissonConsulDistribution PoissonDistribution PoissonProcess PoissonWindow PolarAxes PolarAxesOrigin PolarGridLines PolarPlot PolarTicks PoleZeroMarkers PolyaAeppliDistribution PolyGamma Polygon Polygon3DBox Polygon3DBoxOptions PolygonalNumber PolygonAngle PolygonBox PolygonBoxOptions PolygonCoordinates PolygonDecomposition PolygonHoleScale PolygonIntersections PolygonScale Polyhedron PolyhedronAngle PolyhedronCoordinates PolyhedronData PolyhedronDecomposition PolyhedronGenus PolyLog PolynomialExtendedGCD PolynomialForm PolynomialGCD PolynomialLCM PolynomialMod PolynomialQ PolynomialQuotient PolynomialQuotientRemainder PolynomialReduce PolynomialRemainder Polynomials PoolingLayer PopupMenu PopupMenuBox PopupMenuBoxOptions PopupView PopupWindow Position PositionIndex Positive PositiveDefiniteMatrixQ PositiveIntegers PositiveRationals PositiveReals PositiveSemidefiniteMatrixQ PossibleZeroQ Postfix PostScript Power PowerDistribution PowerExpand PowerMod PowerModList PowerRange PowerSpectralDensity PowersRepresentations PowerSymmetricPolynomial Precedence PrecedenceForm Precedes PrecedesEqual PrecedesSlantEqual PrecedesTilde Precision PrecisionGoal PreDecrement Predict PredictionRoot PredictorFunction PredictorInformation PredictorMeasurements PredictorMeasurementsObject PreemptProtect PreferencesPath Prefix PreIncrement Prepend PrependLayer PrependTo PreprocessingRules PreserveColor PreserveImageOptions Previous PreviousCell PreviousDate PriceGraphDistribution PrimaryPlaceholder Prime PrimeNu PrimeOmega PrimePi PrimePowerQ PrimeQ Primes PrimeZetaP PrimitivePolynomialQ PrimitiveRoot PrimitiveRootList PrincipalComponents PrincipalValue Print PrintableASCIIQ PrintAction PrintForm PrintingCopies PrintingOptions PrintingPageRange PrintingStartingPageNumber PrintingStyleEnvironment Printout3D Printout3DPreviewer PrintPrecision PrintTemporary Prism PrismBox PrismBoxOptions PrivateCellOptions PrivateEvaluationOptions PrivateFontOptions PrivateFrontEndOptions PrivateKey PrivateNotebookOptions PrivatePaths Probability ProbabilityDistribution ProbabilityPlot ProbabilityPr ProbabilityScalePlot ProbitModelFit ProcessConnection ProcessDirectory ProcessEnvironment Processes ProcessEstimator ProcessInformation ProcessObject ProcessParameterAssumptions ProcessParameterQ ProcessStateDomain ProcessStatus ProcessTimeDomain Product ProductDistribution ProductLog ProgressIndicator ProgressIndicatorBox ProgressIndicatorBoxOptions Projection Prolog PromptForm ProofObject Properties Property PropertyList PropertyValue Proportion Proportional Protect Protected ProteinData Pruning PseudoInverse PsychrometricPropertyData PublicKey PublisherID PulsarData PunctuationCharacter Purple Put PutAppend Pyramid PyramidBox PyramidBoxOptionsQBinomial QFactorial QGamma QHypergeometricPFQ QnDispersion QPochhammer QPolyGamma QRDecomposition QuadraticIrrationalQ QuadraticOptimization Quantile QuantilePlot Quantity QuantityArray QuantityDistribution QuantityForm QuantityMagnitude QuantityQ QuantityUnit QuantityVariable QuantityVariableCanonicalUnit QuantityVariableDimensions QuantityVariableIdentifier QuantityVariablePhysicalQuantity Quartics QuartileDeviation Quartiles QuartileSkewness Query QueueingNetworkProcess QueueingProcess QueueProperties Quiet Quit Quotient QuotientRemainderRadialGradientImage RadialityCentrality RadicalBox RadicalBoxOptions RadioButton RadioButtonBar RadioButtonBox RadioButtonBoxOptions Radon RadonTransform RamanujanTau RamanujanTauL RamanujanTauTheta RamanujanTauZ Ramp Random RandomChoice RandomColor RandomComplex RandomEntity RandomFunction RandomGeoPosition RandomGraph RandomImage RandomInstance RandomInteger RandomPermutation RandomPoint RandomPolygon RandomPolyhedron RandomPrime RandomReal RandomSample RandomSeed RandomSeeding RandomVariate RandomWalkProcess RandomWord Range RangeFilter RangeSpecification RankedMax RankedMin RarerProbability Raster Raster3D Raster3DBox Raster3DBoxOptions RasterArray RasterBox RasterBoxOptions Rasterize RasterSize Rational RationalFunctions Rationalize Rationals Ratios RawArray RawBoxes RawData RawMedium RayleighDistribution Re Read ReadByteArray ReadLine ReadList ReadProtected ReadString Real RealAbs RealBlockDiagonalForm RealDigits RealExponent Reals RealSign Reap RecognitionPrior RecognitionThreshold Record RecordLists RecordSeparators Rectangle RectangleBox RectangleBoxOptions RectangleChart RectangleChart3D RectangularRepeatingElement RecurrenceFilter RecurrenceTable RecurringDigitsForm Red Reduce RefBox ReferenceLineStyle ReferenceMarkers ReferenceMarkerStyle Refine ReflectionMatrix ReflectionTransform Refresh RefreshRate Region RegionBinarize RegionBoundary RegionBounds RegionCentroid RegionDifference RegionDimension RegionDisjoint RegionDistance RegionDistanceFunction RegionEmbeddingDimension RegionEqual RegionFunction RegionImage RegionIntersection RegionMeasure RegionMember RegionMemberFunction RegionMoment RegionNearest RegionNearestFunction RegionPlot RegionPlot3D RegionProduct RegionQ RegionResize RegionSize RegionSymmetricDifference RegionUnion RegionWithin RegisterExternalEvaluator RegularExpression Regularization RegularlySampledQ RegularPolygon ReIm ReImLabels ReImPlot ReImStyle Reinstall RelationalDatabase RelationGraph Release ReleaseHold ReliabilityDistribution ReliefImage ReliefPlot RemoteAuthorizationCaching RemoteConnect RemoteConnectionObject RemoteFile RemoteRun RemoteRunProcess Remove RemoveAlphaChannel RemoveAsynchronousTask RemoveAudioStream RemoveBackground RemoveChannelListener RemoveChannelSubscribers Removed RemoveDiacritics RemoveInputStreamMethod RemoveOutputStreamMethod RemoveProperty RemoveScheduledTask RemoveUsers RenameDirectory RenameFile RenderAll RenderingOptions RenewalProcess RenkoChart RepairMesh Repeated RepeatedNull RepeatedString RepeatedTiming RepeatingElement Replace ReplaceAll ReplaceHeldPart ReplaceImageValue ReplaceList ReplacePart ReplacePixelValue ReplaceRepeated ReplicateLayer RequiredPhysicalQuantities Resampling ResamplingAlgorithmData ResamplingMethod Rescale RescalingTransform ResetDirectory ResetMenusPacket ResetScheduledTask ReshapeLayer Residue ResizeLayer Resolve ResourceAcquire ResourceData ResourceFunction ResourceObject ResourceRegister ResourceRemove ResourceSearch ResourceSubmissionObject ResourceSubmit ResourceSystemBase ResourceUpdate ResponseForm Rest RestartInterval Restricted Resultant ResumePacket Return ReturnEntersInput ReturnExpressionPacket ReturnInputFormPacket ReturnPacket ReturnReceiptFunction ReturnTextPacket Reverse ReverseBiorthogonalSplineWavelet ReverseElement ReverseEquilibrium ReverseGraph ReverseSort ReverseSortBy ReverseUpEquilibrium RevolutionAxis RevolutionPlot3D RGBColor RiccatiSolve RiceDistribution RidgeFilter RiemannR RiemannSiegelTheta RiemannSiegelZ RiemannXi Riffle Right RightArrow RightArrowBar RightArrowLeftArrow RightComposition RightCosetRepresentative RightDownTeeVector RightDownVector RightDownVectorBar RightTee RightTeeArrow RightTeeVector RightTriangle RightTriangleBar RightTriangleEqual RightUpDownVector RightUpTeeVector RightUpVector RightUpVectorBar RightVector RightVectorBar RiskAchievementImportance RiskReductionImportance RogersTanimotoDissimilarity RollPitchYawAngles RollPitchYawMatrix RomanNumeral Root RootApproximant RootIntervals RootLocusPlot RootMeanSquare RootOfUnityQ RootReduce Roots RootSum Rotate RotateLabel RotateLeft RotateRight RotationAction RotationBox RotationBoxOptions RotationMatrix RotationTransform Round RoundImplies RoundingRadius Row RowAlignments RowBackgrounds RowBox RowHeights RowLines RowMinHeight RowReduce RowsEqual RowSpacings RSolve RSolveValue RudinShapiro RudvalisGroupRu Rule RuleCondition RuleDelayed RuleForm RulePlot RulerUnits Run RunProcess RunScheduledTask RunThrough RuntimeAttributes RuntimeOptions RussellRaoDissimilaritySameQ SameTest SampledEntityClass SampleDepth SampledSoundFunction SampledSoundList SampleRate SamplingPeriod SARIMAProcess SARMAProcess SASTriangle SatelliteData SatisfiabilityCount SatisfiabilityInstances SatisfiableQ Saturday Save Saveable SaveAutoDelete SaveConnection SaveDefinitions SavitzkyGolayMatrix SawtoothWave Scale Scaled ScaleDivisions ScaledMousePosition ScaleOrigin ScalePadding ScaleRanges ScaleRangeStyle ScalingFunctions ScalingMatrix ScalingTransform Scan ScheduledTask ScheduledTaskActiveQ ScheduledTaskInformation ScheduledTaskInformationData ScheduledTaskObject ScheduledTasks SchurDecomposition ScientificForm ScientificNotationThreshold ScorerGi ScorerGiPrime ScorerHi ScorerHiPrime ScreenRectangle ScreenStyleEnvironment ScriptBaselineShifts ScriptForm ScriptLevel ScriptMinSize ScriptRules ScriptSizeMultipliers Scrollbars ScrollingOptions ScrollPosition SearchAdjustment SearchIndexObject SearchIndices SearchQueryString SearchResultObject Sec Sech SechDistribution SecondOrderConeOptimization SectionGrouping SectorChart SectorChart3D SectorOrigin SectorSpacing SecuredAuthenticationKey SecuredAuthenticationKeys SeedRandom Select Selectable SelectComponents SelectedCells SelectedNotebook SelectFirst Selection SelectionAnimate SelectionCell SelectionCellCreateCell SelectionCellDefaultStyle SelectionCellParentStyle SelectionCreateCell SelectionDebuggerTag SelectionDuplicateCell SelectionEvaluate SelectionEvaluateCreateCell SelectionMove SelectionPlaceholder SelectionSetStyle SelectWithContents SelfLoops SelfLoopStyle SemanticImport SemanticImportString SemanticInterpretation SemialgebraicComponentInstances SemidefiniteOptimization SendMail SendMessage Sequence SequenceAlignment SequenceAttentionLayer SequenceCases SequenceCount SequenceFold SequenceFoldList SequenceForm SequenceHold SequenceLastLayer SequenceMostLayer SequencePosition SequencePredict SequencePredictorFunction SequenceReplace SequenceRestLayer SequenceReverseLayer SequenceSplit Series SeriesCoefficient SeriesData ServiceConnect ServiceDisconnect ServiceExecute ServiceObject ServiceRequest ServiceResponse ServiceSubmit SessionSubmit SessionTime Set SetAccuracy SetAlphaChannel SetAttributes Setbacks SetBoxFormNamesPacket SetCloudDirectory SetCookies SetDelayed SetDirectory SetEnvironment SetEvaluationNotebook SetFileDate SetFileLoadingContext SetNotebookStatusLine SetOptions SetOptionsPacket SetPermissions SetPrecision SetProperty SetSecuredAuthenticationKey SetSelectedNotebook SetSharedFunction SetSharedVariable SetSpeechParametersPacket SetStreamPosition SetSystemModel SetSystemOptions Setter SetterBar SetterBox SetterBoxOptions Setting SetUsers SetValue Shading Shallow ShannonWavelet ShapiroWilkTest Share SharingList Sharpen ShearingMatrix ShearingTransform ShellRegion ShenCastanMatrix ShiftedGompertzDistribution ShiftRegisterSequence Short ShortDownArrow Shortest ShortestMatch ShortestPathFunction ShortLeftArrow ShortRightArrow ShortTimeFourier ShortTimeFourierData ShortUpArrow Show ShowAutoConvert ShowAutoSpellCheck ShowAutoStyles ShowCellBracket ShowCellLabel ShowCellTags ShowClosedCellArea ShowCodeAssist ShowContents ShowControls ShowCursorTracker ShowGroupOpenCloseIcon ShowGroupOpener ShowInvisibleCharacters ShowPageBreaks ShowPredictiveInterface ShowSelection ShowShortBoxForm ShowSpecialCharacters ShowStringCharacters ShowSyntaxStyles ShrinkingDelay ShrinkWrapBoundingBox SiderealTime SiegelTheta SiegelTukeyTest SierpinskiCurve SierpinskiMesh Sign Signature SignedRankTest SignedRegionDistance SignificanceLevel SignPadding SignTest SimilarityRules SimpleGraph SimpleGraphQ SimplePolygonQ SimplePolyhedronQ Simplex Simplify Sin Sinc SinghMaddalaDistribution SingleEvaluation SingleLetterItalics SingleLetterStyle SingularValueDecomposition SingularValueList SingularValuePlot SingularValues Sinh SinhIntegral SinIntegral SixJSymbol Skeleton SkeletonTransform SkellamDistribution Skewness SkewNormalDistribution SkinStyle Skip SliceContourPlot3D SliceDensityPlot3D SliceDistribution SliceVectorPlot3D Slider Slider2D Slider2DBox Slider2DBoxOptions SliderBox SliderBoxOptions SlideView Slot SlotSequence Small SmallCircle Smaller SmithDecomposition SmithDelayCompensator SmithWatermanSimilarity SmoothDensityHistogram SmoothHistogram SmoothHistogram3D SmoothKernelDistribution SnDispersion Snippet SnubPolyhedron SocialMediaData Socket SocketConnect SocketListen SocketListener SocketObject SocketOpen SocketReadMessage SocketReadyQ Sockets SocketWaitAll SocketWaitNext SoftmaxLayer SokalSneathDissimilarity SolarEclipse SolarSystemFeatureData SolidAngle SolidData SolidRegionQ Solve SolveAlways SolveDelayed Sort SortBy SortedBy SortedEntityClass Sound SoundAndGraphics SoundNote SoundVolume SourceLink Sow Space SpaceCurveData SpaceForm Spacer Spacings Span SpanAdjustments SpanCharacterRounding SpanFromAbove SpanFromBoth SpanFromLeft SpanLineThickness SpanMaxSize SpanMinSize SpanningCharacters SpanSymmetric SparseArray SpatialGraphDistribution SpatialMedian SpatialTransformationLayer Speak SpeakTextPacket SpearmanRankTest SpearmanRho SpeciesData SpecificityGoal SpectralLineData Spectrogram SpectrogramArray Specularity SpeechRecognize SpeechSynthesize SpellingCorrection SpellingCorrectionList SpellingDictionaries SpellingDictionariesPath SpellingOptions SpellingSuggestionsPacket Sphere SphereBox SpherePoints SphericalBesselJ SphericalBesselY SphericalHankelH1 SphericalHankelH2 SphericalHarmonicY SphericalPlot3D SphericalRegion SphericalShell SpheroidalEigenvalue SpheroidalJoiningFactor SpheroidalPS SpheroidalPSPrime SpheroidalQS SpheroidalQSPrime SpheroidalRadialFactor SpheroidalS1 SpheroidalS1Prime SpheroidalS2 SpheroidalS2Prime Splice SplicedDistribution SplineClosed SplineDegree SplineKnots SplineWeights Split SplitBy SpokenString Sqrt SqrtBox SqrtBoxOptions Square SquaredEuclideanDistance SquareFreeQ SquareIntersection SquareMatrixQ SquareRepeatingElement SquaresR SquareSubset SquareSubsetEqual SquareSuperset SquareSupersetEqual SquareUnion SquareWave SSSTriangle StabilityMargins StabilityMarginsStyle StableDistribution Stack StackBegin StackComplete StackedDateListPlot StackedListPlot StackInhibit StadiumShape StandardAtmosphereData StandardDeviation StandardDeviationFilter StandardForm Standardize Standardized StandardOceanData StandbyDistribution Star StarClusterData StarData StarGraph StartAsynchronousTask StartExternalSession StartingStepSize StartOfLine StartOfString StartProcess StartScheduledTask StartupSound StartWebSession StateDimensions StateFeedbackGains StateOutputEstimator StateResponse StateSpaceModel StateSpaceRealization StateSpaceTransform StateTransformationLinearize StationaryDistribution StationaryWaveletPacketTransform StationaryWaveletTransform StatusArea StatusCentrality StepMonitor StereochemistryElements StieltjesGamma StirlingS1 StirlingS2 StopAsynchronousTask StoppingPowerData StopScheduledTask StrataVariables StratonovichProcess StreamColorFunction StreamColorFunctionScaling StreamDensityPlot StreamMarkers StreamPlot StreamPoints StreamPosition Streams StreamScale StreamStyle String StringBreak StringByteCount StringCases StringContainsQ StringCount StringDelete StringDrop StringEndsQ StringExpression StringExtract StringForm StringFormat StringFreeQ StringInsert StringJoin StringLength StringMatchQ StringPadLeft StringPadRight StringPart StringPartition StringPosition StringQ StringRepeat StringReplace StringReplaceList StringReplacePart StringReverse StringRiffle StringRotateLeft StringRotateRight StringSkeleton StringSplit StringStartsQ StringTake StringTemplate StringToByteArray StringToStream StringTrim StripBoxes StripOnInput StripWrapperBoxes StrokeForm StructuralImportance StructuredArray StructuredSelection StruveH StruveL Stub StudentTDistribution Style StyleBox StyleBoxAutoDelete StyleData StyleDefinitions StyleForm StyleHints StyleKeyMapping StyleMenuListing StyleNameDialogSettings StyleNames StylePrint StyleSheetPath Subdivide Subfactorial Subgraph SubMinus SubPlus SubresultantPolynomialRemainders SubresultantPolynomials Subresultants Subscript SubscriptBox SubscriptBoxOptions Subscripted Subsequences Subset SubsetEqual SubsetMap SubsetQ Subsets SubStar SubstitutionSystem Subsuperscript SubsuperscriptBox SubsuperscriptBoxOptions Subtract SubtractFrom SubtractSides SubValues Succeeds SucceedsEqual SucceedsSlantEqual SucceedsTilde Success SuchThat Sum SumConvergence SummationLayer Sunday SunPosition Sunrise Sunset SuperDagger SuperMinus SupernovaData SuperPlus Superscript SuperscriptBox SuperscriptBoxOptions Superset SupersetEqual SuperStar Surd SurdForm SurfaceArea SurfaceColor SurfaceData SurfaceGraphics SurvivalDistribution SurvivalFunction SurvivalModel SurvivalModelFit SuspendPacket SuzukiDistribution SuzukiGroupSuz SwatchLegend Switch Symbol SymbolName SymletWavelet Symmetric SymmetricGroup SymmetricKey SymmetricMatrixQ SymmetricPolynomial SymmetricReduction Symmetrize SymmetrizedArray SymmetrizedArrayRules SymmetrizedDependentComponents SymmetrizedIndependentComponents SymmetrizedReplacePart SynchronousInitialization SynchronousUpdating Synonyms Syntax SyntaxForm SyntaxInformation SyntaxLength SyntaxPacket SyntaxQ SynthesizeMissingValues SystemDialogInput SystemException SystemGet SystemHelpPath SystemInformation SystemInformationData SystemInstall SystemModel SystemModeler SystemModelExamples SystemModelLinearize SystemModelParametricSimulate SystemModelPlot SystemModelProgressReporting SystemModelReliability SystemModels SystemModelSimulate SystemModelSimulateSensitivity SystemModelSimulationData SystemOpen SystemOptions SystemProcessData SystemProcesses SystemsConnectionsModel SystemsModelDelay SystemsModelDelayApproximate SystemsModelDelete SystemsModelDimensions SystemsModelExtract SystemsModelFeedbackConnect SystemsModelLabels SystemsModelLinearity SystemsModelMerge SystemsModelOrder SystemsModelParallelConnect SystemsModelSeriesConnect SystemsModelStateFeedbackConnect SystemsModelVectorRelativeOrders SystemStub SystemTestTab TabFilling Table TableAlignments TableDepth TableDirections TableForm TableHeadings TableSpacing TableView TableViewBox TableViewBoxBackground TableViewBoxOptions TabSpacings TabView TabViewBox TabViewBoxOptions TagBox TagBoxNote TagBoxOptions TaggingRules TagSet TagSetDelayed TagStyle TagUnset Take TakeDrop TakeLargest TakeLargestBy TakeList TakeSmallest TakeSmallestBy TakeWhile Tally Tan Tanh TargetDevice TargetFunctions TargetSystem TargetUnits TaskAbort TaskExecute TaskObject TaskRemove TaskResume Tasks TaskSuspend TaskWait TautologyQ TelegraphProcess TemplateApply TemplateArgBox TemplateBox TemplateBoxOptions TemplateEvaluate TemplateExpression TemplateIf TemplateObject TemplateSequence TemplateSlot TemplateSlotSequence TemplateUnevaluated TemplateVerbatim TemplateWith TemporalData TemporalRegularity Temporary TemporaryVariable TensorContract TensorDimensions TensorExpand TensorProduct TensorQ TensorRank TensorReduce TensorSymmetry TensorTranspose TensorWedge TestID TestReport TestReportObject TestResultObject Tetrahedron TetrahedronBox TetrahedronBoxOptions TeXForm TeXSave Text Text3DBox Text3DBoxOptions TextAlignment TextBand TextBoundingBox TextBox TextCases TextCell TextClipboardType TextContents TextData TextElement TextForm TextGrid TextJustification TextLine TextPacket TextParagraph TextPosition TextRecognize TextSearch TextSearchReport TextSentences TextString TextStructure TextStyle TextTranslation Texture TextureCoordinateFunction TextureCoordinateScaling TextWords Therefore ThermodynamicData ThermometerGauge Thick Thickness Thin Thinning ThisLink ThompsonGroupTh Thread ThreadingLayer ThreeJSymbol Threshold Through Throw ThueMorse Thumbnail Thursday Ticks TicksStyle TideData Tilde TildeEqual TildeFullEqual TildeTilde TimeConstrained TimeConstraint TimeDirection TimeFormat TimeGoal TimelinePlot TimeObject TimeObjectQ Times TimesBy TimeSeries TimeSeriesAggregate TimeSeriesForecast TimeSeriesInsert TimeSeriesInvertibility TimeSeriesMap TimeSeriesMapThread TimeSeriesModel TimeSeriesModelFit TimeSeriesResample TimeSeriesRescale TimeSeriesShift TimeSeriesThread TimeSeriesWindow TimeUsed TimeValue TimeWarpingCorrespondence TimeWarpingDistance TimeZone TimeZoneConvert TimeZoneOffset Timing Tiny TitleGrouping TitsGroupT ToBoxes ToCharacterCode ToColor ToContinuousTimeModel ToDate Today ToDiscreteTimeModel ToEntity ToeplitzMatrix ToExpression ToFileName Together Toggle ToggleFalse Toggler TogglerBar TogglerBox TogglerBoxOptions ToHeldExpression ToInvertibleTimeSeries TokenWords Tolerance ToLowerCase Tomorrow ToNumberField TooBig Tooltip TooltipBox TooltipBoxOptions TooltipDelay TooltipStyle Top TopHatTransform ToPolarCoordinates TopologicalSort ToRadicals ToRules ToSphericalCoordinates ToString Total TotalHeight TotalLayer TotalVariationFilter TotalWidth TouchPosition TouchscreenAutoZoom TouchscreenControlPlacement ToUpperCase Tr Trace TraceAbove TraceAction TraceBackward TraceDepth TraceDialog TraceForward TraceInternal TraceLevel TraceOff TraceOn TraceOriginal TracePrint TraceScan TrackedSymbols TrackingFunction TracyWidomDistribution TradingChart TraditionalForm TraditionalFunctionNotation TraditionalNotation TraditionalOrder TrainingProgressCheckpointing TrainingProgressFunction TrainingProgressMeasurements TrainingProgressReporting TrainingStoppingCriterion TransferFunctionCancel TransferFunctionExpand TransferFunctionFactor TransferFunctionModel TransferFunctionPoles TransferFunctionTransform TransferFunctionZeros TransformationClass TransformationFunction TransformationFunctions TransformationMatrix TransformedDistribution TransformedField TransformedProcess TransformedRegion TransitionDirection TransitionDuration TransitionEffect TransitiveClosureGraph TransitiveReductionGraph Translate TranslationOptions TranslationTransform Transliterate Transparent TransparentColor Transpose TransposeLayer TrapSelection TravelDirections TravelDirectionsData TravelDistance TravelDistanceList TravelMethod TravelTime TreeForm TreeGraph TreeGraphQ TreePlot TrendStyle Triangle TriangleCenter TriangleConstruct TriangleMeasurement TriangleWave TriangularDistribution TriangulateMesh Trig TrigExpand TrigFactor TrigFactorList Trigger TrigReduce TrigToExp TrimmedMean TrimmedVariance TropicalStormData True TrueQ TruncatedDistribution TruncatedPolyhedron TsallisQExponentialDistribution TsallisQGaussianDistribution TTest Tube TubeBezierCurveBox TubeBezierCurveBoxOptions TubeBox TubeBoxOptions TubeBSplineCurveBox TubeBSplineCurveBoxOptions Tuesday TukeyLambdaDistribution TukeyWindow TunnelData Tuples TuranGraph TuringMachine TuttePolynomial TwoWayRule Typed TypeSpecifierUnateQ Uncompress UnconstrainedParameters Undefined UnderBar Underflow Underlined Underoverscript UnderoverscriptBox UnderoverscriptBoxOptions Underscript UnderscriptBox UnderscriptBoxOptions UnderseaFeatureData UndirectedEdge UndirectedGraph UndirectedGraphQ UndoOptions UndoTrackedVariables Unequal UnequalTo Unevaluated UniformDistribution UniformGraphDistribution UniformPolyhedron UniformSumDistribution Uninstall Union UnionPlus Unique UnitaryMatrixQ UnitBox UnitConvert UnitDimensions Unitize UnitRootTest UnitSimplify UnitStep UnitSystem UnitTriangle UnitVector UnitVectorLayer UnityDimensions UniverseModelData UniversityData UnixTime Unprotect UnregisterExternalEvaluator UnsameQ UnsavedVariables Unset UnsetShared UntrackedVariables Up UpArrow UpArrowBar UpArrowDownArrow Update UpdateDynamicObjects UpdateDynamicObjectsSynchronous UpdateInterval UpdateSearchIndex UpDownArrow UpEquilibrium UpperCaseQ UpperLeftArrow UpperRightArrow UpperTriangularize UpperTriangularMatrixQ Upsample UpSet UpSetDelayed UpTee UpTeeArrow UpTo UpValues URL URLBuild URLDecode URLDispatcher URLDownload URLDownloadSubmit URLEncode URLExecute URLExpand URLFetch URLFetchAsynchronous URLParse URLQueryDecode URLQueryEncode URLRead URLResponseTime URLSave URLSaveAsynchronous URLShorten URLSubmit UseGraphicsRange UserDefinedWavelet Using UsingFrontEnd UtilityFunctionV2Get ValenceErrorHandling ValidationLength ValidationSet Value ValueBox ValueBoxOptions ValueDimensions ValueForm ValuePreprocessingFunction ValueQ Values ValuesData Variables Variance VarianceEquivalenceTest VarianceEstimatorFunction VarianceGammaDistribution VarianceTest VectorAngle VectorAround VectorColorFunction VectorColorFunctionScaling VectorDensityPlot VectorGlyphData VectorGreater VectorGreaterEqual VectorLess VectorLessEqual VectorMarkers VectorPlot VectorPlot3D VectorPoints VectorQ Vectors VectorScale VectorStyle Vee Verbatim Verbose VerboseConvertToPostScriptPacket VerificationTest VerifyConvergence VerifyDerivedKey VerifyDigitalSignature VerifyInterpretation VerifySecurityCertificates VerifySolutions VerifyTestAssumptions Version VersionNumber VertexAdd VertexCapacity VertexColors VertexComponent VertexConnectivity VertexContract VertexCoordinateRules VertexCoordinates VertexCorrelationSimilarity VertexCosineSimilarity VertexCount VertexCoverQ VertexDataCoordinates VertexDegree VertexDelete VertexDiceSimilarity VertexEccentricity VertexInComponent VertexInDegree VertexIndex VertexJaccardSimilarity VertexLabeling VertexLabels VertexLabelStyle VertexList VertexNormals VertexOutComponent VertexOutDegree VertexQ VertexRenderingFunction VertexReplace VertexShape VertexShapeFunction VertexSize VertexStyle VertexTextureCoordinates VertexWeight VertexWeightedGraphQ Vertical VerticalBar VerticalForm VerticalGauge VerticalSeparator VerticalSlider VerticalTilde ViewAngle ViewCenter ViewMatrix ViewPoint ViewPointSelectorSettings ViewPort ViewProjection ViewRange ViewVector ViewVertical VirtualGroupData Visible VisibleCell VoiceStyleData VoigtDistribution VolcanoData Volume VonMisesDistribution VoronoiMeshWaitAll WaitAsynchronousTask WaitNext WaitUntil WakebyDistribution WalleniusHypergeometricDistribution WaringYuleDistribution WarpingCorrespondence WarpingDistance WatershedComponents WatsonUSquareTest WattsStrogatzGraphDistribution WaveletBestBasis WaveletFilterCoefficients WaveletImagePlot WaveletListPlot WaveletMapIndexed WaveletMatrixPlot WaveletPhi WaveletPsi WaveletScale WaveletScalogram WaveletThreshold WeaklyConnectedComponents WeaklyConnectedGraphComponents WeaklyConnectedGraphQ WeakStationarity WeatherData WeatherForecastData WebAudioSearch WebElementObject WeberE WebExecute WebImage WebImageSearch WebSearch WebSessionObject WebSessions WebWindowObject Wedge Wednesday WeibullDistribution WeierstrassE1 WeierstrassE2 WeierstrassE3 WeierstrassEta1 WeierstrassEta2 WeierstrassEta3 WeierstrassHalfPeriods WeierstrassHalfPeriodW1 WeierstrassHalfPeriodW2 WeierstrassHalfPeriodW3 WeierstrassInvariantG2 WeierstrassInvariantG3 WeierstrassInvariants WeierstrassP WeierstrassPPrime WeierstrassSigma WeierstrassZeta WeightedAdjacencyGraph WeightedAdjacencyMatrix WeightedData WeightedGraphQ Weights WelchWindow WheelGraph WhenEvent Which While White WhiteNoiseProcess WhitePoint Whitespace WhitespaceCharacter WhittakerM WhittakerW WienerFilter WienerProcess WignerD WignerSemicircleDistribution WikipediaData WikipediaSearch WilksW WilksWTest WindDirectionData WindingCount WindingPolygon WindowClickSelect WindowElements WindowFloating WindowFrame WindowFrameElements WindowMargins WindowMovable WindowOpacity WindowPersistentStyles WindowSelected WindowSize WindowStatusArea WindowTitle WindowToolbars WindowWidth WindSpeedData WindVectorData WinsorizedMean WinsorizedVariance WishartMatrixDistribution With WolframAlpha WolframAlphaDate WolframAlphaQuantity WolframAlphaResult WolframLanguageData Word WordBoundary WordCharacter WordCloud WordCount WordCounts WordData WordDefinition WordFrequency WordFrequencyData WordList WordOrientation WordSearch WordSelectionFunction WordSeparators WordSpacings WordStem WordTranslation WorkingPrecision WrapAround Write WriteLine WriteString WronskianXMLElement XMLObject XMLTemplate Xnor Xor XYZColorYellow Yesterday YuleDissimilarityZernikeR ZeroSymmetric ZeroTest ZeroWidthTimes Zeta ZetaZero ZIPCodeData ZipfDistribution ZoomCenter ZoomFactor ZTest ZTransform$Aborted $ActivationGroupID $ActivationKey $ActivationUserRegistered $AddOnsDirectory $AllowExternalChannelFunctions $AssertFunction $Assumptions $AsynchronousTask $AudioInputDevices $AudioOutputDevices $BaseDirectory $BatchInput $BatchOutput $BlockchainBase $BoxForms $ByteOrdering $CacheBaseDirectory $Canceled $ChannelBase $CharacterEncoding $CharacterEncodings $CloudBase $CloudConnected $CloudCreditsAvailable $CloudEvaluation $CloudExpressionBase $CloudObjectNameFormat $CloudObjectURLType $CloudRootDirectory $CloudSymbolBase $CloudUserID $CloudUserUUID $CloudVersion $CloudVersionNumber $CloudWolframEngineVersionNumber $CommandLine $CompilationTarget $ConditionHold $ConfiguredKernels $Context $ContextPath $ControlActiveSetting $Cookies $CookieStore $CreationDate $CurrentLink $CurrentTask $CurrentWebSession $DateStringFormat $DefaultAudioInputDevice $DefaultAudioOutputDevice $DefaultFont $DefaultFrontEnd $DefaultImagingDevice $DefaultLocalBase $DefaultMailbox $DefaultNetworkInterface $DefaultPath $Display $DisplayFunction $DistributedContexts $DynamicEvaluation $Echo $EmbedCodeEnvironments $EmbeddableServices $EntityStores $Epilog $EvaluationCloudBase $EvaluationCloudObject $EvaluationEnvironment $ExportFormats $Failed $FinancialDataSource $FontFamilies $FormatType $FrontEnd $FrontEndSession $GeoEntityTypes $GeoLocation $GeoLocationCity $GeoLocationCountry $GeoLocationPrecision $GeoLocationSource $HistoryLength $HomeDirectory $HTMLExportRules $HTTPCookies $HTTPRequest $IgnoreEOF $ImageFormattingWidth $ImagingDevice $ImagingDevices $ImportFormats $IncomingMailSettings $InitialDirectory $Initialization $InitializationContexts $Input $InputFileName $InputStreamMethods $Inspector $InstallationDate $InstallationDirectory $InterfaceEnvironment $InterpreterTypes $IterationLimit $KernelCount $KernelID $Language $LaunchDirectory $LibraryPath $LicenseExpirationDate $LicenseID $LicenseProcesses $LicenseServer $LicenseSubprocesses $LicenseType $Line $Linked $LinkSupported $LoadedFiles $LocalBase $LocalSymbolBase $MachineAddresses $MachineDomain $MachineDomains $MachineEpsilon $MachineID $MachineName $MachinePrecision $MachineType $MaxExtraPrecision $MaxLicenseProcesses $MaxLicenseSubprocesses $MaxMachineNumber $MaxNumber $MaxPiecewiseCases $MaxPrecision $MaxRootDegree $MessageGroups $MessageList $MessagePrePrint $Messages $MinMachineNumber $MinNumber $MinorReleaseNumber $MinPrecision $MobilePhone $ModuleNumber $NetworkConnected $NetworkInterfaces $NetworkLicense $NewMessage $NewSymbol $Notebooks $NoValue $NumberMarks $Off $OperatingSystem $Output $OutputForms $OutputSizeLimit $OutputStreamMethods $Packages $ParentLink $ParentProcessID $PasswordFile $PatchLevelID $Path $PathnameSeparator $PerformanceGoal $Permissions $PermissionsGroupBase $PersistenceBase $PersistencePath $PipeSupported $PlotTheme $Post $Pre $PreferencesDirectory $PreInitialization $PrePrint $PreRead $PrintForms $PrintLiteral $Printout3DPreviewer $ProcessID $ProcessorCount $ProcessorType $ProductInformation $ProgramName $PublisherID $RandomState $RecursionLimit $RegisteredDeviceClasses $RegisteredUserName $ReleaseNumber $RequesterAddress $RequesterWolframID $RequesterWolframUUID $ResourceSystemBase $RootDirectory $ScheduledTask $ScriptCommandLine $ScriptInputString $SecuredAuthenticationKeyTokens $ServiceCreditsAvailable $Services $SessionID $SetParentLink $SharedFunctions $SharedVariables $SoundDisplay $SoundDisplayFunction $SourceLink $SSHAuthentication $SummaryBoxDataSizeLimit $SuppressInputFormHeads $SynchronousEvaluation $SyntaxHandler $System $SystemCharacterEncoding $SystemID $SystemMemory $SystemShell $SystemTimeZone $SystemWordLength $TemplatePath $TemporaryDirectory $TemporaryPrefix $TestFileName $TextStyle $TimedOut $TimeUnit $TimeZone $TimeZoneEntity $TopDirectory $TraceOff $TraceOn $TracePattern $TracePostAction $TracePreAction $UnitSystem $Urgent $UserAddOnsDirectory $UserAgentLanguages $UserAgentMachine $UserAgentName $UserAgentOperatingSystem $UserAgentString $UserAgentVersion $UserBaseDirectory $UserDocumentsDirectory $Username $UserName $UserURLBase $Version $VersionNumber $VoiceStyles $WolframID $WolframUUID\",c:[e.C(\"\\\\(\\\\*\",\"\\\\*\\\\)\",{c:[\"self\"]}),e.QSM,e.CNM]}});hljs.registerLanguage(\"vim\",function(e){return{l:/[!#@\\w]+/,k:{keyword:\"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank\",built_in:\"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp\"},i:/;/,c:[e.NM,{cN:\"string\",b:\"'\",e:\"'\",i:\"\\\\n\"},{cN:\"string\",b:/\"(\\\\\"|\\n\\\\|[^\"\\n])*\"/},e.C('\"',\"$\"),{cN:\"variable\",b:/[bwtglsav]:[\\w\\d_]*/},{cN:\"function\",bK:\"function function!\",e:\"$\",relevance:0,c:[e.TM,{cN:\"params\",b:\"\\\\(\",e:\"\\\\)\"}]},{cN:\"symbol\",b:/<[\\w-]+>/}]}});hljs.registerLanguage(\"makefile\",function(e){var i={cN:\"variable\",v:[{b:\"\\\\$\\\\(\"+e.UIR+\"\\\\)\",c:[e.BE]},{b:/\\$[@%<?\\^\\+\\*]/}]},r={cN:\"string\",b:/\"/,e:/\"/,c:[e.BE,i]},a={cN:\"variable\",b:/\\$\\([\\w-]+\\s/,e:/\\)/,k:{built_in:\"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value\"},c:[i]},n={b:\"^\"+e.UIR+\"\\\\s*(?=[:+?]?=)\"},t={cN:\"section\",b:/^[^\\s]+:/,e:/$/,c:[i]};return{aliases:[\"mk\",\"mak\"],k:\"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath\",l:/[\\w-]+/,c:[e.HCM,i,r,a,n,{cN:\"meta\",b:/^\\.PHONY:/,e:/$/,k:{\"meta-keyword\":\".PHONY\"},l:/[\\.\\w]+/},t]}});hljs.registerLanguage(\"objectivec\",function(e){var t=/[a-zA-Z@][a-zA-Z0-9_]*/,i=\"@interface @class @protocol @implementation\";return{aliases:[\"mm\",\"objc\",\"obj-c\"],k:{keyword:\"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN\",literal:\"false true FALSE TRUE nil YES NO NULL\",built_in:\"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once\"},l:t,i:\"</\",c:[{cN:\"built_in\",b:\"\\\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\\\w+\"},e.CLCM,e.CBCM,e.CNM,e.QSM,e.ASM,{cN:\"string\",v:[{b:'@\"',e:'\"',i:\"\\\\n\",c:[e.BE]}]},{cN:\"meta\",b:/#\\s*[a-z]+\\b/,e:/$/,k:{\"meta-keyword\":\"if else elif endif define undef warning error line pragma ifdef ifndef include\"},c:[{b:/\\\\\\n/,relevance:0},e.inherit(e.QSM,{cN:\"meta-string\"}),{cN:\"meta-string\",b:/<.*?>/,e:/$/,i:\"\\\\n\"},e.CLCM,e.CBCM]},{cN:\"class\",b:\"(\"+i.split(\" \").join(\"|\")+\")\\\\b\",e:\"({|$)\",eE:!0,k:i,l:t,c:[e.UTM]},{b:\"\\\\.\"+e.UIR,relevance:0}]}});hljs.registerLanguage(\"shell\",function(s){return{aliases:[\"console\"],c:[{cN:\"meta\",b:\"^\\\\s{0,3}[/\\\\w\\\\d\\\\[\\\\]()@-]*[>%$#]\",starts:{e:\"$\",sL:\"bash\"}}]}});hljs.registerLanguage(\"erlang\",function(e){var r=\"[a-z'][a-zA-Z0-9_']*\",c=\"(\"+r+\":\"+r+\"|\"+r+\")\",n={keyword:\"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor\",literal:\"false true\"},a=e.C(\"%\",\"$\"),b={cN:\"number\",b:\"\\\\b(\\\\d+#[a-fA-F0-9]+|\\\\d+(\\\\.\\\\d+)?([eE][-+]?\\\\d+)?)\",relevance:0},i={b:\"fun\\\\s+\"+r+\"/\\\\d+\"},l={b:c+\"\\\\(\",e:\"\\\\)\",rB:!0,relevance:0,c:[{b:c,relevance:0},{b:\"\\\\(\",e:\"\\\\)\",eW:!0,rE:!0,relevance:0}]},d={b:\"{\",e:\"}\",relevance:0},o={b:\"\\\\b_([A-Z][A-Za-z0-9_]*)?\",relevance:0},t={b:\"[A-Z][a-zA-Z0-9_]*\",relevance:0},v={b:\"#\"+e.UIR,relevance:0,rB:!0,c:[{b:\"#\"+e.UIR,relevance:0},{b:\"{\",e:\"}\",relevance:0}]},f={bK:\"fun receive if try case\",e:\"end\",k:n};f.c=[a,i,e.inherit(e.ASM,{cN:\"\"}),f,l,e.QSM,b,d,o,t,v];var s=[a,i,f,l,e.QSM,b,d,o,t,v];l.c[1].c=s,d.c=s;var u={cN:\"params\",b:\"\\\\(\",e:\"\\\\)\",c:v.c[1].c=s};return{aliases:[\"erl\"],k:n,i:\"(</|\\\\*=|\\\\+=|-=|/\\\\*|\\\\*/|\\\\(\\\\*|\\\\*\\\\))\",c:[{cN:\"function\",b:\"^\"+r+\"\\\\s*\\\\(\",e:\"->\",rB:!0,i:\"\\\\(|#|//|/\\\\*|\\\\\\\\|:|;\",c:[u,e.inherit(e.TM,{b:r})],starts:{e:\";|\\\\.\",k:n,c:s}},a,{b:\"^-\",e:\"\\\\.\",relevance:0,eE:!0,rB:!0,l:\"-\"+e.IR,k:\"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec\",c:[u]},b,e.QSM,v,o,t,d,{b:/\\.$/}]}});hljs.registerLanguage(\"powershell\",function(e){var t={keyword:\"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter\"},n={b:\"`[\\\\s\\\\S]\",relevance:0},c={cN:\"variable\",v:[{b:/\\$\\B/},{cN:\"keyword\",b:/\\$this/},{b:/\\$[\\w\\d][\\w\\d_:]*/}]},i={cN:\"string\",v:[{b:/\"/,e:/\"/},{b:/@\"/,e:/^\"@/}],c:[n,c,{cN:\"variable\",b:/\\$[A-z]/,e:/[^A-z]/}]},a={cN:\"string\",v:[{b:/'/,e:/'/},{b:/@'/,e:/^'@/}]},r=e.inherit(e.C(null,null),{v:[{b:/#/,e:/$/},{b:/<#/,e:/#>/}],c:[{cN:\"doctag\",v:[{b:/\\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{b:/\\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\\s+\\S+/}]}]}),o={cN:\"built_in\",v:[{b:\"(\".concat(\"Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|New|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Complete|Confirm|Deny|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where\",\")+(-)[\\\\w\\\\d]+\")}]},l={cN:\"class\",bK:\"class enum\",e:/\\s*[{]/,eE:!0,relevance:0,c:[e.TM]},s={cN:\"function\",b:/function\\s+/,e:/\\s*\\{|$/,eE:!0,rB:!0,relevance:0,c:[{b:\"function\",relevance:0,cN:\"keyword\"},{cN:\"title\",b:/\\w[\\w\\d]*((-)[\\w\\d]+)*/,relevance:0},{b:/\\(/,e:/\\)/,cN:\"params\",relevance:0,c:[c]}]},p={b:/using\\s/,e:/$/,rB:!0,c:[i,a,{cN:\"keyword\",b:/(using|assembly|command|module|namespace|type)/}]},b={v:[{cN:\"operator\",b:\"(\".concat(\"-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor\",\")\\\\b\")},{cN:\"literal\",b:/(-)[\\w\\d]+/,relevance:0}]},d={cN:\"function\",b:/\\[.*\\]\\s*[\\w]+[ ]??\\(/,e:/$/,rB:!0,relevance:0,c:[{cN:\"keyword\",b:\"(\".concat(t.keyword.toString().replace(/\\s/g,\"|\"),\")\\\\b\"),endsParent:!0,relevance:0},e.inherit(e.TM,{endsParent:!0})]},u=[d,r,n,e.NM,i,a,o,c,{cN:\"literal\",b:/\\$(null|true|false)\\b/},{cN:\"selector-tag\",b:/\\@\\B/,relevance:0}],m={b:/\\[/,e:/\\]/,eB:!0,eE:!0,relevance:0,c:[].concat(\"self\",u,{b:\"(\"+[\"string\",\"char\",\"byte\",\"int\",\"long\",\"bool\",\"decimal\",\"single\",\"double\",\"DateTime\",\"xml\",\"array\",\"hashtable\",\"void\"].join(\"|\")+\")\",cN:\"built_in\",relevance:0},{cN:\"type\",b:/[\\.\\w\\d]+/,relevance:0})};return d.c.unshift(m),{aliases:[\"ps\",\"ps1\"],l:/-?[A-z\\.\\-]+/,cI:!0,k:t,c:u.concat(l,s,p,b,m)}});hljs.registerLanguage(\"typescript\",function(e){var r=\"[A-Za-z$_][0-9A-Za-z$_]*\",t={keyword:\"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await\",literal:\"true false null undefined NaN Infinity\",built_in:\"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise\"},n={cN:\"meta\",b:\"@\"+r},a={b:\"\\\\(\",e:/\\)/,k:t,c:[\"self\",e.QSM,e.ASM,e.NM]},c={cN:\"params\",b:/\\(/,e:/\\)/,eB:!0,eE:!0,k:t,c:[e.CLCM,e.CBCM,n,a]},s={cN:\"number\",v:[{b:\"\\\\b(0[bB][01]+)n?\"},{b:\"\\\\b(0[oO][0-7]+)n?\"},{b:e.CNR+\"n?\"}],relevance:0},o={cN:\"subst\",b:\"\\\\$\\\\{\",e:\"\\\\}\",k:t,c:[]},i={b:\"html`\",e:\"\",starts:{e:\"`\",rE:!1,c:[e.BE,o],sL:\"xml\"}},l={b:\"css`\",e:\"\",starts:{e:\"`\",rE:!1,c:[e.BE,o],sL:\"css\"}},b={cN:\"string\",b:\"`\",e:\"`\",c:[e.BE,o]};return o.c=[e.ASM,e.QSM,i,l,b,s,e.RM],{aliases:[\"ts\"],k:t,c:[{cN:\"meta\",b:/^\\s*['\"]use strict['\"]/},e.ASM,e.QSM,i,l,b,e.CLCM,e.CBCM,s,{b:\"(\"+e.RSR+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",k:\"return throw case\",c:[e.CLCM,e.CBCM,e.RM,{cN:\"function\",b:\"(\\\\(.*?\\\\)|\"+e.IR+\")\\\\s*=>\",rB:!0,e:\"\\\\s*=>\",c:[{cN:\"params\",v:[{b:e.IR},{b:/\\(\\s*\\)/},{b:/\\(/,e:/\\)/,eB:!0,eE:!0,k:t,c:[\"self\",e.CLCM,e.CBCM]}]}]}],relevance:0},{cN:\"function\",bK:\"function\",e:/[\\{;]/,eE:!0,k:t,c:[\"self\",e.inherit(e.TM,{b:r}),c],i:/%/,relevance:0},{bK:\"constructor\",e:/[\\{;]/,eE:!0,c:[\"self\",c]},{b:/module\\./,k:{built_in:\"module\"},relevance:0},{bK:\"module\",e:/\\{/,eE:!0},{bK:\"interface\",e:/\\{/,eE:!0,k:\"interface extends\"},{b:/\\$[(.]/},{b:\"\\\\.\"+e.IR,relevance:0},n,a]}});hljs.registerLanguage(\"fortran\",function(e){return{cI:!0,aliases:[\"f90\",\"f95\"],k:{literal:\".False. .True.\",keyword:\"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then block endblock public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data\",built_in:\"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image\"},i:/\\/\\*/,c:[e.inherit(e.ASM,{cN:\"string\",relevance:0}),e.inherit(e.QSM,{cN:\"string\",relevance:0}),{cN:\"function\",bK:\"subroutine function program\",i:\"[${=\\\\n]\",c:[e.UTM,{cN:\"params\",b:\"\\\\(\",e:\"\\\\)\"}]},e.C(\"!\",\"$\",{relevance:0}),{cN:\"number\",b:\"(?=\\\\b|\\\\+|\\\\-|\\\\.)(?=\\\\.\\\\d|\\\\d)(?:\\\\d+)?(?:\\\\.?\\\\d*)(?:[de][+-]?\\\\d+)?\\\\b\\\\.?\",relevance:0}]}});hljs.registerLanguage(\"php\",function(e){var c={b:\"\\\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*\"},i={cN:\"meta\",b:/<\\?(php)?|\\?>/},t={cN:\"string\",c:[e.BE,i],v:[{b:'b\"',e:'\"'},{b:\"b'\",e:\"'\"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},a={v:[e.BNM,e.CNM]};return{aliases:[\"php\",\"php3\",\"php4\",\"php5\",\"php6\",\"php7\"],cI:!0,k:\"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally\",c:[e.HCM,e.C(\"//\",\"$\",{c:[i]}),e.C(\"/\\\\*\",\"\\\\*/\",{c:[{cN:\"doctag\",b:\"@[A-Za-z]+\"}]}),e.C(\"__halt_compiler.+?;\",!1,{eW:!0,k:\"__halt_compiler\",l:e.UIR}),{cN:\"string\",b:/<<<['\"]?\\w+['\"]?$/,e:/^\\w+;?$/,c:[e.BE,{cN:\"subst\",v:[{b:/\\$\\w+/},{b:/\\{\\$/,e:/\\}/}]}]},i,{cN:\"keyword\",b:/\\$this\\b/},c,{b:/(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/},{cN:\"function\",bK:\"function\",e:/[;{]/,eE:!0,i:\"\\\\$|\\\\[|%\",c:[e.UTM,{cN:\"params\",b:\"\\\\(\",e:\"\\\\)\",c:[\"self\",c,e.CBCM,t,a]}]},{cN:\"class\",bK:\"class interface\",e:\"{\",eE:!0,i:/[:\\(\\$\"]/,c:[{bK:\"extends implements\"},e.UTM]},{bK:\"namespace\",e:\";\",i:/[\\.']/,c:[e.UTM]},{bK:\"use\",e:\";\",c:[e.UTM]},{b:\"=>\"},t,a]}});hljs.registerLanguage(\"haskell\",function(e){var i={v:[e.C(\"--\",\"$\"),e.C(\"{-\",\"-}\",{c:[\"self\"]})]},a={cN:\"meta\",b:\"{-#\",e:\"#-}\"},l={cN:\"meta\",b:\"^#\",e:\"$\"},c={cN:\"type\",b:\"\\\\b[A-Z][\\\\w']*\",relevance:0},n={b:\"\\\\(\",e:\"\\\\)\",i:'\"',c:[a,l,{cN:\"type\",b:\"\\\\b[A-Z][\\\\w]*(\\\\((\\\\.\\\\.|,|\\\\w+)\\\\))?\"},e.inherit(e.TM,{b:\"[_a-z][\\\\w']*\"}),i]};return{aliases:[\"hs\"],k:\"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec\",c:[{bK:\"module\",e:\"where\",k:\"module where\",c:[n,i],i:\"\\\\W\\\\.|;\"},{b:\"\\\\bimport\\\\b\",e:\"$\",k:\"import qualified as hiding\",c:[n,i],i:\"\\\\W\\\\.|;\"},{cN:\"class\",b:\"^(\\\\s*)?(class|instance)\\\\b\",e:\"where\",k:\"class family instance where\",c:[c,n,i]},{cN:\"class\",b:\"\\\\b(data|(new)?type)\\\\b\",e:\"$\",k:\"data family type newtype deriving\",c:[a,c,n,{b:\"{\",e:\"}\",c:n.c},i]},{bK:\"default\",e:\"$\",c:[c,n,i]},{bK:\"infix infixl infixr\",e:\"$\",c:[e.CNM,i]},{b:\"\\\\bforeign\\\\b\",e:\"$\",k:\"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe\",c:[c,e.QSM,i]},{cN:\"meta\",b:\"#!\\\\/usr\\\\/bin\\\\/env runhaskell\",e:\"$\"},a,l,e.QSM,e.CNM,c,e.inherit(e.TM,{b:\"^[_a-z][\\\\w']*\"}),i,{b:\"->|<-\"}]}});hljs.registerLanguage(\"coffeescript\",function(e){var c={keyword:\"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not\",literal:\"true false null undefined yes no on off\",built_in:\"npm require console print module global window document\"},n=\"[A-Za-z$_][0-9A-Za-z$_]*\",r={cN:\"subst\",b:/#\\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:\"(\\\\s*/)?\",relevance:0}}),{cN:\"string\",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/\"\"\"/,e:/\"\"\"/,c:[e.BE,r]},{b:/\"/,e:/\"/,c:[e.BE,r]}]},{cN:\"regexp\",v:[{b:\"///\",e:\"///\",c:[r,e.HCM]},{b:\"//[gim]{0,3}(?=\\\\W)\",relevance:0},{b:/\\/(?![ *]).*?(?![\\\\]).\\/[gim]{0,3}(?=\\W)/}]},{b:\"@\"+n},{sL:\"javascript\",eB:!0,eE:!0,v:[{b:\"```\",e:\"```\"},{b:\"`\",e:\"`\"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t=\"(\\\\(.*\\\\))?\\\\s*\\\\B[-=]>\",a={cN:\"params\",b:\"\\\\([^\\\\(]\",rB:!0,c:[{b:/\\(/,e:/\\)/,k:c,c:[\"self\"].concat(i)}]};return{aliases:[\"coffee\",\"cson\",\"iced\"],k:c,i:/\\/\\*/,c:i.concat([e.C(\"###\",\"###\"),e.HCM,{cN:\"function\",b:\"^\\\\s*\"+n+\"\\\\s*=\\\\s*\"+t,e:\"[-=]>\",rB:!0,c:[s,a]},{b:/[:\\(,=]\\s*/,relevance:0,c:[{cN:\"function\",b:t,e:\"[-=]>\",rB:!0,c:[a]}]},{cN:\"class\",bK:\"class\",e:\"$\",i:/[:=\"\\[\\]]/,c:[{bK:\"extends\",eW:!0,i:/[:=\"\\[\\]]/,c:[s]},s]},{b:n+\":\",e:\":\",rB:!0,rE:!0,relevance:0}])}});hljs.registerLanguage(\"r\",function(e){var r=\"([a-zA-Z]|\\\\.[a-zA-Z.])[a-zA-Z0-9._]*\";return{c:[e.HCM,{b:r,l:r,k:{keyword:\"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...\",literal:\"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10\"},relevance:0},{cN:\"number\",b:\"0[xX][0-9a-fA-F]+[Li]?\\\\b\",relevance:0},{cN:\"number\",b:\"\\\\d+(?:[eE][+\\\\-]?\\\\d*)?L\\\\b\",relevance:0},{cN:\"number\",b:\"\\\\d+\\\\.(?!\\\\d)(?:i\\\\b)?\",relevance:0},{cN:\"number\",b:\"\\\\d+(?:\\\\.\\\\d*)?(?:[eE][+\\\\-]?\\\\d*)?i?\\\\b\",relevance:0},{cN:\"number\",b:\"\\\\.\\\\d+(?:[eE][+\\\\-]?\\\\d*)?i?\\\\b\",relevance:0},{b:\"`\",e:\"`\",relevance:0},{cN:\"string\",c:[e.BE],v:[{b:'\"',e:'\"'},{b:\"'\",e:\"'\"}]}]}});hljs.registerLanguage(\"autohotkey\",function(e){var a={b:\"`[\\\\s\\\\S]\"};return{cI:!0,aliases:[\"ahk\"],k:{keyword:\"Break Continue Critical Exit ExitApp Gosub Goto New OnExit Pause return SetBatchLines SetTimer Suspend Thread Throw Until ahk_id ahk_class ahk_pid ahk_exe ahk_group\",literal:\"true false NOT AND OR\",built_in:\"ComSpec Clipboard ClipboardAll ErrorLevel\"},c:[a,e.inherit(e.QSM,{c:[a]}),e.C(\";\",\"$\",{relevance:0}),e.CBCM,{cN:\"number\",b:e.NR,relevance:0},{cN:\"variable\",b:\"%[a-zA-Z0-9#_$@]+%\"},{cN:\"built_in\",b:\"^\\\\s*\\\\w+\\\\s*(,|%)\"},{cN:\"title\",v:[{b:'^[^\\\\n\";]+::(?!=)'},{b:'^[^\\\\n\";]+:(?!=)',relevance:0}]},{cN:\"meta\",b:\"^\\\\s*#\\\\w+\",e:\"$\",relevance:0},{cN:\"built_in\",b:\"A_[a-zA-Z0-9]+\"},{b:\",\\\\s*,\"}]}});hljs.registerLanguage(\"elixir\",function(e){var b=\"[a-zA-Z_][a-zA-Z0-9_.]*(\\\\!|\\\\?)?\",c=\"and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote require import with|0\",n={cN:\"subst\",b:\"#\\\\{\",e:\"}\",l:b,k:c},r=\"[/|([{<\\\"']\",a={cN:\"string\",b:\"~[a-z](?=\"+r+\")\",c:[{endsParent:!0,c:[{c:[e.BE,n],v:[{b:/\"/,e:/\"/},{b:/'/,e:/'/},{b:/\\//,e:/\\//},{b:/\\|/,e:/\\|/},{b:/\\(/,e:/\\)/},{b:/\\[/,e:/\\]/},{b:/\\{/,e:/\\}/},{b:/</,e:/>/}]}]}]},i={cN:\"string\",b:\"~[A-Z](?=\"+r+\")\",c:[{b:/\"/,e:/\"/},{b:/'/,e:/'/},{b:/\\//,e:/\\//},{b:/\\|/,e:/\\|/},{b:/\\(/,e:/\\)/},{b:/\\[/,e:/\\]/},{b:/\\{/,e:/\\}/},{b:/\\</,e:/\\>/}]},l={cN:\"string\",c:[e.BE,n],v:[{b:/\"\"\"/,e:/\"\"\"/},{b:/'''/,e:/'''/},{b:/~S\"\"\"/,e:/\"\"\"/,c:[]},{b:/~S\"/,e:/\"/,c:[]},{b:/~S'''/,e:/'''/,c:[]},{b:/~S'/,e:/'/,c:[]},{b:/'/,e:/'/},{b:/\"/,e:/\"/}]},s={cN:\"function\",bK:\"def defp defmacro\",e:/\\B\\b/,c:[e.inherit(e.TM,{b:b,endsParent:!0})]},t=e.inherit(s,{cN:\"class\",bK:\"defimpl defmodule defprotocol defrecord\",e:/\\bdo\\b|$|;/}),d=[l,i,a,e.HCM,t,s,{b:\"::\"},{cN:\"symbol\",b:\":(?![\\\\s:])\",c:[l,{b:\"[a-zA-Z_]\\\\w*[!?=]?|[-+~]\\\\@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?\"}],relevance:0},{cN:\"symbol\",b:b+\":(?!:)\",relevance:0},{cN:\"number\",b:\"(\\\\b0o[0-7_]+)|(\\\\b0b[01_]+)|(\\\\b0x[0-9a-fA-F_]+)|(-?\\\\b[1-9][0-9_]*(.[0-9_]+([eE][-+]?[0-9]+)?)?)\",relevance:0},{cN:\"variable\",b:\"(\\\\$\\\\W)|((\\\\$|\\\\@\\\\@?)(\\\\w+))\"},{b:\"->\"},{b:\"(\"+e.RSR+\")\\\\s*\",c:[e.HCM,{cN:\"regexp\",i:\"\\\\n\",c:[e.BE,n],v:[{b:\"/\",e:\"/[a-z]*\"},{b:\"%r\\\\[\",e:\"\\\\][a-z]*\"}]}],relevance:0}];return{l:b,k:c,c:n.c=d}});hljs.registerLanguage(\"gradle\",function(e){return{cI:!0,k:{keyword:\"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine\"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage(\"css\",function(e){var c={b:/(?:[A-Z\\_\\.\\-]+|--[a-zA-Z0-9_-]+)\\s*:/,rB:!0,e:\";\",eW:!0,c:[{cN:\"attribute\",b:/\\S/,e:\":\",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\\w-]+\\(/,rB:!0,c:[{cN:\"built_in\",b:/[\\w-]+/},{b:/\\(/,e:/\\)/,c:[e.ASM,e.QSM,e.CSSNM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:\"number\",b:\"#[0-9A-Fa-f]+\"},{cN:\"meta\",b:\"!important\"}]}}]};return{cI:!0,i:/[=\\/|'\\$]/,c:[e.CBCM,{cN:\"selector-id\",b:/#[A-Za-z0-9_-]+/},{cN:\"selector-class\",b:/\\.[A-Za-z0-9_-]+/},{cN:\"selector-attr\",b:/\\[/,e:/\\]/,i:\"$\",c:[e.ASM,e.QSM]},{cN:\"selector-pseudo\",b:/:(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"'.]+/},{b:\"@(page|font-face)\",l:\"@[a-z-]+\",k:\"@page @font-face\"},{b:\"@\",e:\"[{;]\",i:/:/,rB:!0,c:[{cN:\"keyword\",b:/@\\-?\\w[\\w]*(\\-\\w+)*/},{b:/\\s/,eW:!0,eE:!0,relevance:0,k:\"and or not only\",c:[{b:/[a-z-]+:/,cN:\"attribute\"},e.ASM,e.QSM,e.CSSNM]}]},{cN:\"selector-tag\",b:\"[a-zA-Z-][a-zA-Z0-9_-]*\",relevance:0},{b:\"{\",e:\"}\",i:/\\S/,c:[e.CBCM,c]}]}});\n\nexports.hljs = hljs;\n",
"type": "application/javascript",
"title": "$:/plugins/tiddlywiki/highlight/highlight.js",
"module-type": "library"
},
"$:/plugins/tiddlywiki/highlight/highlight.css": {
"text": "/*\n\nOriginal highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>\n\n*/\n\n.hljs {\n display: block;\n overflow-x: auto;\n padding: 0.5em;\n background: #F0F0F0;\n}\n\n\n/* Base color: saturation 0; */\n\n.hljs,\n.hljs-subst {\n color: #444;\n}\n\n.hljs-comment {\n color: #888888;\n}\n\n.hljs-keyword,\n.hljs-attribute,\n.hljs-selector-tag,\n.hljs-meta-keyword,\n.hljs-doctag,\n.hljs-name {\n font-weight: bold;\n}\n\n\n/* User color: hue: 0 */\n\n.hljs-type,\n.hljs-string,\n.hljs-number,\n.hljs-selector-id,\n.hljs-selector-class,\n.hljs-quote,\n.hljs-template-tag,\n.hljs-deletion {\n color: #880000;\n}\n\n.hljs-title,\n.hljs-section {\n color: #880000;\n font-weight: bold;\n}\n\n.hljs-regexp,\n.hljs-symbol,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-link,\n.hljs-selector-attr,\n.hljs-selector-pseudo {\n color: #BC6060;\n}\n\n\n/* Language color: hue: 90; */\n\n.hljs-literal {\n color: #78A960;\n}\n\n.hljs-built_in,\n.hljs-bullet,\n.hljs-code,\n.hljs-addition {\n color: #397300;\n}\n\n\n/* Meta color: hue: 200 */\n\n.hljs-meta {\n color: #1f7199;\n}\n\n.hljs-meta-string {\n color: #4d99bf;\n}\n\n\n/* Misc effects */\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n",
"type": "text/css",
"title": "$:/plugins/tiddlywiki/highlight/highlight.css",
"tags": "[[$:/tags/Stylesheet]]"
},
"$:/plugins/tiddlywiki/highlight/highlightblock.js": {
"title": "$:/plugins/tiddlywiki/highlight/highlightblock.js",
"text": "/*\\\ntitle: $:/plugins/tiddlywiki/highlight/highlightblock.js\ntype: application/javascript\nmodule-type: widget\n\nWraps up the fenced code blocks parser for highlight and use in TiddlyWiki5\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar TYPE_MAPPINGS_BASE = \"$:/config/HighlightPlugin/TypeMappings/\";\n\nvar CodeBlockWidget = require(\"$:/core/modules/widgets/codeblock.js\").codeblock;\n\nvar hljs = require(\"$:/plugins/tiddlywiki/highlight/highlight.js\");\n\nhljs.configure({tabReplace: \" \"});\t\n\nCodeBlockWidget.prototype.postRender = function() {\n\tvar domNode = this.domNodes[0],\n\t\tlanguage = this.language,\n\t\ttiddler = this.wiki.getTiddler(TYPE_MAPPINGS_BASE + language);\n\tif(tiddler) {\n\t\tlanguage = tiddler.fields.text || \"\";\n\t}\n\tif(language && hljs.getLanguage(language)) {\n\t\tdomNode.className = language.toLowerCase() + \" hljs\";\n\t\tif($tw.browser && !domNode.isTiddlyWikiFakeDom) {\n\t\t\thljs.highlightBlock(domNode);\t\t\t\n\t\t} else {\n\t\t\tvar text = domNode.textContent;\n\t\t\tdomNode.children[0].innerHTML = hljs.fixMarkup(hljs.highlight(language,text).value);\n\t\t\t// If we're using the fakedom then specially save the original raw text\n\t\t\tif(domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tdomNode.children[0].textInnerHTML = text;\n\t\t\t}\n\t\t}\n\t}\t\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/plugins/tiddlywiki/highlight/howto": {
"title": "$:/plugins/tiddlywiki/highlight/howto",
"text": "! Supporting Additional Languages\n \nThe [[highlight.js|https://github.com/highlightjs/highlight.js]] project supports many languages. Only a subset of these languages are supported by the plugin. It is possible for users to change the set of languages supported by the plugin by following these steps:\n \n# Go to the highlight.js project [[download page|https://highlightjs.org/download/]], select the language definitions to include, and press the Download button to download a zip archive containing customised support files for a highlight.js syntax highlighting server.\n# Locate the `highlight.pack.js` file in the highlight plugin -- on a stock Debian 8 system running Tiddlywiki5 under node-js it is located at `/usr/local/lib/node_modules/tiddlywiki/plugins/tiddlywiki/highlight/files/highlight.pack.js`.\n# Replace the plugin `highlight.pack.js` file located in step 2 with the one from the downloaded archive obtained in step 1.\n# Restart the Tiddlywiki server.\n"
},
"$:/plugins/tiddlywiki/highlight/license": {
"title": "$:/plugins/tiddlywiki/highlight/license",
"type": "text/plain",
"text": "Copyright (c) 2006, Ivan Sagalaev\nAll rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n * Neither the name of highlight.js nor the names of its contributors\n may be used to endorse or promote products derived from this software\n without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
},
"$:/plugins/tiddlywiki/highlight/readme": {
"title": "$:/plugins/tiddlywiki/highlight/readme",
"text": "This plugin provides syntax highlighting of code blocks using v9.18.1 of [[highlight.js|https://github.com/isagalaev/highlight.js]] from Ivan Sagalaev.\n\n! Usage\n\nWhen the plugin is installed it automatically applies highlighting to all codeblocks defined with triple backticks or with the CodeBlockWidget.\n\nThe language can optionally be specified after the opening triple braces:\n\n<$codeblock code=\"\"\"```css\n * { margin: 0; padding: 0; } /* micro reset */\n\nhtml { font-size: 62.5%; }\nbody { font-size: 14px; font-size: 1.4rem; } /* =14px */\nh1 { font-size: 24px; font-size: 2.4rem; } /* =24px */\n```\"\"\"/>\n\nIf no language is specified highlight.js will attempt to automatically detect the language.\n\n! Built-in Language Brushes\n\nThe plugin includes support for the following languages (referred to as \"brushes\" by highlight.js):\n\n* apache\n* arduino\n* arm assembly\n* asciidoc\n* autohotkey\n* awk\n* bash\n* cmake\n* coffeescript\n* cpp\n* cs\n* css\n* diff\n* dockerfile\n* erlang\n* elixir\n* fortran\n* go\n* gradle\n* haskell\n* html\n* http\n* ini\n* intel x86 assembly\n* java\n* javascript\n* json\n* kotlin\n* less\n* lua\n* makefile\n* markdown\n* mathematica\n* matlab\n* nginx\n* objectivec\n* perl\n* php\n* plaintext\n* powershell\n* properties\n* python\n* R\n* ruby\n* rust\n* scss\n* shell session\n* sql\n* swift\n* toml\n* typescript\n* vala\n* vim script\n* xml\n* yaml\n\nYou can also specify the language as a MIME content type (eg `text/html` or `text/css`). The mapping is accomplished via mapping tiddlers whose titles start with `$:/config/HighlightPlugin/TypeMappings/`.\n"
},
"$:/plugins/tiddlywiki/highlight/styles": {
"title": "$:/plugins/tiddlywiki/highlight/styles",
"tags": "[[$:/tags/Stylesheet]]",
"text": ".hljs {\n display: block;\n overflow-x: auto;\n padding: 0.5em;\n background: <<colour tiddler-editor-background>>;\n color: <<colour foreground>>;\n -webkit-text-size-adjust:none\n}\n\n.hljs-comment,\n.hljs-quote {\n color: #93a1a1;\n}\n\n/* Solarized Green */\n.hljs-keyword,\n.hljs-selector-tag,\n.hljs-addition {\n color: #859900;\n}\n\n/* Solarized Cyan */\n.hljs-number,\n.hljs-string,\n.hljs-meta .hljs-meta-string,\n.hljs-literal,\n.hljs-doctag,\n.hljs-regexp {\n color: #2aa198;\n}\n\n/* Solarized Blue */\n.hljs-title,\n.hljs-section,\n.hljs-name,\n.hljs-selector-id,\n.hljs-selector-class {\n color: #268bd2;\n}\n\n/* Solarized Yellow */\n.hljs-attribute,\n.hljs-attr,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-class .hljs-title,\n.hljs-type {\n color: #b58900;\n}\n\n/* Solarized Orange */\n.hljs-symbol,\n.hljs-bullet,\n.hljs-subst,\n.hljs-meta,\n.hljs-meta .hljs-keyword,\n.hljs-selector-attr,\n.hljs-selector-pseudo,\n.hljs-link {\n color: #cb4b16;\n}\n\n/* Solarized Red */\n.hljs-built_in,\n.hljs-deletion {\n color: #dc322f;\n}\n\n.hljs-formula {\n background: #eee8d5;\n}\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n"
},
"$:/plugins/tiddlywiki/highlight/usage": {
"title": "$:/plugins/tiddlywiki/highlight/usage",
"text": "! Usage\n\nFenced code blocks can have a language specifier added to trigger highlighting in a specific language. Otherwise heuristics are used to detect the language.\n\n```\n ```js\n var a = b + c; // Highlighted as JavaScript\n ```\n```\n! Adding Themes\n\nYou can add themes from highlight.js by copying the CSS to a new tiddler and tagging it with [[$:/tags/Stylesheet]]. The available themes can be found on GitHub:\n\nhttps://github.com/isagalaev/highlight.js/tree/master/src/styles\n"
}
}
}
{
"tiddlers": {
"$:/plugins/tiddlywiki/markdown/EditorToolbar/bold": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/bold",
"list-after": "$:/core/ui/EditorToolbar/bold",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/bold",
"caption": "{{$:/language/Buttons/Bold/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Bold/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((bold))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"**\"\n\tsuffix=\"**\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-1": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-1",
"list-after": "$:/core/ui/EditorToolbar/heading-1",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-1",
"caption": "{{$:/language/Buttons/Heading1/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Heading1/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((heading-1))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"1\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-2": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-2",
"list-after": "$:/core/ui/EditorToolbar/heading-2",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-2",
"caption": "{{$:/language/Buttons/Heading2/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Heading2/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((heading-2))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"2\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-3": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-3",
"list-after": "$:/core/ui/EditorToolbar/heading-3",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-3",
"caption": "{{$:/language/Buttons/Heading3/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Heading3/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((heading-3))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"3\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-4": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-4",
"list-after": "$:/core/ui/EditorToolbar/heading-4",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-4",
"caption": "{{$:/language/Buttons/Heading4/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Heading4/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((heading-4))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"4\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-5": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-5",
"list-after": "$:/core/ui/EditorToolbar/heading-5",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-5",
"caption": "{{$:/language/Buttons/Heading5/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Heading5/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((heading-5))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"5\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-6": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-6",
"list-after": "$:/core/ui/EditorToolbar/heading-6",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-6",
"caption": "{{$:/language/Buttons/Heading6/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Heading6/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((heading-6))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"6\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/italic": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/italic",
"list-after": "$:/core/ui/EditorToolbar/italic",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/italic",
"caption": "{{$:/language/Buttons/Italic/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Italic/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((italic))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"*\"\n\tsuffix=\"*\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/list-bullet": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/list-bullet",
"list-after": "$:/core/ui/EditorToolbar/list-bullet",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/list-bullet",
"caption": "{{$:/language/Buttons/ListBullet/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/ListBullet/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((list-bullet))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"*\"\n\tcount=\"1\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/list-number": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/list-number",
"list-after": "$:/core/ui/EditorToolbar/list-number",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/list-number",
"caption": "{{$:/language/Buttons/ListNumber/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/ListNumber/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((list-number))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"1.\"\n\tcount=\"1\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/mono-line": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/mono-line",
"list-after": "$:/core/ui/EditorToolbar/mono-line",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/mono-line",
"caption": "{{$:/language/Buttons/MonoLine/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/MonoLine/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((mono-line))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"`\"\n\tsuffix=\"`\"\n/>\n"
},
"$:/plugins/tiddlywiki/markdown/EditorToolbar/quote": {
"title": "$:/plugins/tiddlywiki/markdown/EditorToolbar/quote",
"list-after": "$:/core/ui/EditorToolbar/quote",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/quote",
"caption": "{{$:/language/Buttons/Quote/Caption}} (Markdown)",
"description": "{{$:/language/Buttons/Quote/Hint}}",
"condition": "[<targetTiddler>type[text/x-markdown]]",
"shortcuts": "((quote))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\">\"\n\tcount=\"1\"\n/>\n"
},
"$:/config/markdown/breaks": {
"title": "$:/config/markdown/breaks",
"text": "false"
},
"$:/config/markdown/linkNewWindow": {
"title": "$:/config/markdown/linkNewWindow",
"text": "true"
},
"$:/config/markdown/linkify": {
"title": "$:/config/markdown/linkify",
"text": "false"
},
"$:/config/markdown/quotes": {
"title": "$:/config/markdown/quotes",
"text": "“”‘’"
},
"$:/config/markdown/renderWikiText": {
"title": "$:/config/markdown/renderWikiText",
"text": "true"
},
"$:/config/markdown/renderWikiTextPragma": {
"title": "$:/config/markdown/renderWikiTextPragma",
"text": "\\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock"
},
"$:/config/markdown/typographer": {
"title": "$:/config/markdown/typographer",
"text": "false"
},
"$:/language/Docs/Types/text/x-markdown": {
"title": "$:/language/Docs/Types/text/x-markdown",
"description": "Markdown",
"name": "text/x-markdown",
"group": "Text"
},
"$:/plugins/tiddlywiki/markdown/remarkable.js": {
"text": "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?t(exports):\"function\"==typeof define&&define.amd?define([\"exports\"],t):t((e=e||self).remarkable={})}(this,function(e){\"use strict\";var t={Aacute:\"Á\",aacute:\"á\",Abreve:\"Ă\",abreve:\"ă\",ac:\"∾\",acd:\"∿\",acE:\"∾̳\",Acirc:\"Â\",acirc:\"â\",acute:\"´\",Acy:\"А\",acy:\"а\",AElig:\"Æ\",aelig:\"æ\",af:\"\",Afr:\"𝔄\",afr:\"𝔞\",Agrave:\"À\",agrave:\"à\",alefsym:\"ℵ\",aleph:\"ℵ\",Alpha:\"Α\",alpha:\"α\",Amacr:\"Ā\",amacr:\"ā\",amalg:\"⨿\",AMP:\"&\",amp:\"&\",And:\"⩓\",and:\"∧\",andand:\"⩕\",andd:\"⩜\",andslope:\"⩘\",andv:\"⩚\",ang:\"∠\",ange:\"⦤\",angle:\"∠\",angmsd:\"∡\",angmsdaa:\"⦨\",angmsdab:\"⦩\",angmsdac:\"⦪\",angmsdad:\"⦫\",angmsdae:\"⦬\",angmsdaf:\"⦭\",angmsdag:\"⦮\",angmsdah:\"⦯\",angrt:\"∟\",angrtvb:\"⊾\",angrtvbd:\"⦝\",angsph:\"∢\",angst:\"Å\",angzarr:\"⍼\",Aogon:\"Ą\",aogon:\"ą\",Aopf:\"𝔸\",aopf:\"𝕒\",ap:\"≈\",apacir:\"⩯\",apE:\"⩰\",ape:\"≊\",apid:\"≋\",apos:\"'\",ApplyFunction:\"\",approx:\"≈\",approxeq:\"≊\",Aring:\"Å\",aring:\"å\",Ascr:\"𝒜\",ascr:\"𝒶\",Assign:\"≔\",ast:\"*\",asymp:\"≈\",asympeq:\"≍\",Atilde:\"Ã\",atilde:\"ã\",Auml:\"Ä\",auml:\"ä\",awconint:\"∳\",awint:\"⨑\",backcong:\"≌\",backepsilon:\"϶\",backprime:\"‵\",backsim:\"∽\",backsimeq:\"⋍\",Backslash:\"∖\",Barv:\"⫧\",barvee:\"⊽\",Barwed:\"⌆\",barwed:\"⌅\",barwedge:\"⌅\",bbrk:\"⎵\",bbrktbrk:\"⎶\",bcong:\"≌\",Bcy:\"Б\",bcy:\"б\",bdquo:\"„\",becaus:\"∵\",Because:\"∵\",because:\"∵\",bemptyv:\"⦰\",bepsi:\"϶\",bernou:\"ℬ\",Bernoullis:\"ℬ\",Beta:\"Β\",beta:\"β\",beth:\"ℶ\",between:\"≬\",Bfr:\"𝔅\",bfr:\"𝔟\",bigcap:\"⋂\",bigcirc:\"◯\",bigcup:\"⋃\",bigodot:\"⨀\",bigoplus:\"⨁\",bigotimes:\"⨂\",bigsqcup:\"⨆\",bigstar:\"★\",bigtriangledown:\"▽\",bigtriangleup:\"△\",biguplus:\"⨄\",bigvee:\"⋁\",bigwedge:\"⋀\",bkarow:\"⤍\",blacklozenge:\"⧫\",blacksquare:\"▪\",blacktriangle:\"▴\",blacktriangledown:\"▾\",blacktriangleleft:\"◂\",blacktriangleright:\"▸\",blank:\"␣\",blk12:\"▒\",blk14:\"░\",blk34:\"▓\",block:\"█\",bne:\"=⃥\",bnequiv:\"≡⃥\",bNot:\"⫭\",bnot:\"⌐\",Bopf:\"𝔹\",bopf:\"𝕓\",bot:\"⊥\",bottom:\"⊥\",bowtie:\"⋈\",boxbox:\"⧉\",boxDL:\"╗\",boxDl:\"╖\",boxdL:\"╕\",boxdl:\"┐\",boxDR:\"╔\",boxDr:\"╓\",boxdR:\"╒\",boxdr:\"┌\",boxH:\"═\",boxh:\"─\",boxHD:\"╦\",boxHd:\"╤\",boxhD:\"╥\",boxhd:\"┬\",boxHU:\"╩\",boxHu:\"╧\",boxhU:\"╨\",boxhu:\"┴\",boxminus:\"⊟\",boxplus:\"⊞\",boxtimes:\"⊠\",boxUL:\"╝\",boxUl:\"╜\",boxuL:\"╛\",boxul:\"┘\",boxUR:\"╚\",boxUr:\"╙\",boxuR:\"╘\",boxur:\"└\",boxV:\"║\",boxv:\"│\",boxVH:\"╬\",boxVh:\"╫\",boxvH:\"╪\",boxvh:\"┼\",boxVL:\"╣\",boxVl:\"╢\",boxvL:\"╡\",boxvl:\"┤\",boxVR:\"╠\",boxVr:\"╟\",boxvR:\"╞\",boxvr:\"├\",bprime:\"‵\",Breve:\"˘\",breve:\"˘\",brvbar:\"¦\",Bscr:\"ℬ\",bscr:\"𝒷\",bsemi:\"⁏\",bsim:\"∽\",bsime:\"⋍\",bsol:\"\\\\\",bsolb:\"⧅\",bsolhsub:\"⟈\",bull:\"•\",bullet:\"•\",bump:\"≎\",bumpE:\"⪮\",bumpe:\"≏\",Bumpeq:\"≎\",bumpeq:\"≏\",Cacute:\"Ć\",cacute:\"ć\",Cap:\"⋒\",cap:\"∩\",capand:\"⩄\",capbrcup:\"⩉\",capcap:\"⩋\",capcup:\"⩇\",capdot:\"⩀\",CapitalDifferentialD:\"ⅅ\",caps:\"∩︀\",caret:\"⁁\",caron:\"ˇ\",Cayleys:\"ℭ\",ccaps:\"⩍\",Ccaron:\"Č\",ccaron:\"č\",Ccedil:\"Ç\",ccedil:\"ç\",Ccirc:\"Ĉ\",ccirc:\"ĉ\",Cconint:\"∰\",ccups:\"⩌\",ccupssm:\"⩐\",Cdot:\"Ċ\",cdot:\"ċ\",cedil:\"¸\",Cedilla:\"¸\",cemptyv:\"⦲\",cent:\"¢\",CenterDot:\"·\",centerdot:\"·\",Cfr:\"ℭ\",cfr:\"𝔠\",CHcy:\"Ч\",chcy:\"ч\",check:\"✓\",checkmark:\"✓\",Chi:\"Χ\",chi:\"χ\",cir:\"○\",circ:\"ˆ\",circeq:\"≗\",circlearrowleft:\"↺\",circlearrowright:\"↻\",circledast:\"⊛\",circledcirc:\"⊚\",circleddash:\"⊝\",CircleDot:\"⊙\",circledR:\"®\",circledS:\"Ⓢ\",CircleMinus:\"⊖\",CirclePlus:\"⊕\",CircleTimes:\"⊗\",cirE:\"⧃\",cire:\"≗\",cirfnint:\"⨐\",cirmid:\"⫯\",cirscir:\"⧂\",ClockwiseContourIntegral:\"∲\",CloseCurlyDoubleQuote:\"”\",CloseCurlyQuote:\"’\",clubs:\"♣\",clubsuit:\"♣\",Colon:\"∷\",colon:\":\",Colone:\"⩴\",colone:\"≔\",coloneq:\"≔\",comma:\",\",commat:\"@\",comp:\"∁\",compfn:\"∘\",complement:\"∁\",complexes:\"ℂ\",cong:\"≅\",congdot:\"⩭\",Congruent:\"≡\",Conint:\"∯\",conint:\"∮\",ContourIntegral:\"∮\",Copf:\"ℂ\",copf:\"𝕔\",coprod:\"∐\",Coproduct:\"∐\",COPY:\"©\",copy:\"©\",copysr:\"℗\",CounterClockwiseContourIntegral:\"∳\",crarr:\"↵\",Cross:\"⨯\",cross:\"✗\",Cscr:\"𝒞\",cscr:\"𝒸\",csub:\"⫏\",csube:\"⫑\",csup:\"⫐\",csupe:\"⫒\",ctdot:\"⋯\",cudarrl:\"⤸\",cudarrr:\"⤵\",cuepr:\"⋞\",cuesc:\"⋟\",cularr:\"↶\",cularrp:\"⤽\",Cup:\"⋓\",cup:\"∪\",cupbrcap:\"⩈\",CupCap:\"≍\",cupcap:\"⩆\",cupcup:\"⩊\",cupdot:\"⊍\",cupor:\"⩅\",cups:\"∪︀\",curarr:\"↷\",curarrm:\"⤼\",curlyeqprec:\"⋞\",curlyeqsucc:\"⋟\",curlyvee:\"⋎\",curlywedge:\"⋏\",curren:\"¤\",curvearrowleft:\"↶\",curvearrowright:\"↷\",cuvee:\"⋎\",cuwed:\"⋏\",cwconint:\"∲\",cwint:\"∱\",cylcty:\"⌭\",Dagger:\"‡\",dagger:\"†\",daleth:\"ℸ\",Darr:\"↡\",dArr:\"⇓\",darr:\"↓\",dash:\"‐\",Dashv:\"⫤\",dashv:\"⊣\",dbkarow:\"⤏\",dblac:\"˝\",Dcaron:\"Ď\",dcaron:\"ď\",Dcy:\"Д\",dcy:\"д\",DD:\"ⅅ\",dd:\"ⅆ\",ddagger:\"‡\",ddarr:\"⇊\",DDotrahd:\"⤑\",ddotseq:\"⩷\",deg:\"°\",Del:\"∇\",Delta:\"Δ\",delta:\"δ\",demptyv:\"⦱\",dfisht:\"⥿\",Dfr:\"𝔇\",dfr:\"𝔡\",dHar:\"⥥\",dharl:\"⇃\",dharr:\"⇂\",DiacriticalAcute:\"´\",DiacriticalDot:\"˙\",DiacriticalDoubleAcute:\"˝\",DiacriticalGrave:\"`\",DiacriticalTilde:\"˜\",diam:\"⋄\",Diamond:\"⋄\",diamond:\"⋄\",diamondsuit:\"♦\",diams:\"♦\",die:\"¨\",DifferentialD:\"ⅆ\",digamma:\"ϝ\",disin:\"⋲\",div:\"÷\",divide:\"÷\",divideontimes:\"⋇\",divonx:\"⋇\",DJcy:\"Ђ\",djcy:\"ђ\",dlcorn:\"⌞\",dlcrop:\"⌍\",dollar:\"$\",Dopf:\"𝔻\",dopf:\"𝕕\",Dot:\"¨\",dot:\"˙\",DotDot:\"⃜\",doteq:\"≐\",doteqdot:\"≑\",DotEqual:\"≐\",dotminus:\"∸\",dotplus:\"∔\",dotsquare:\"⊡\",doublebarwedge:\"⌆\",DoubleContourIntegral:\"∯\",DoubleDot:\"¨\",DoubleDownArrow:\"⇓\",DoubleLeftArrow:\"⇐\",DoubleLeftRightArrow:\"⇔\",DoubleLeftTee:\"⫤\",DoubleLongLeftArrow:\"⟸\",DoubleLongLeftRightArrow:\"⟺\",DoubleLongRightArrow:\"⟹\",DoubleRightArrow:\"⇒\",DoubleRightTee:\"⊨\",DoubleUpArrow:\"⇑\",DoubleUpDownArrow:\"⇕\",DoubleVerticalBar:\"∥\",DownArrow:\"↓\",Downarrow:\"⇓\",downarrow:\"↓\",DownArrowBar:\"⤓\",DownArrowUpArrow:\"⇵\",DownBreve:\"̑\",downdownarrows:\"⇊\",downharpoonleft:\"⇃\",downharpoonright:\"⇂\",DownLeftRightVector:\"⥐\",DownLeftTeeVector:\"⥞\",DownLeftVector:\"↽\",DownLeftVectorBar:\"⥖\",DownRightTeeVector:\"⥟\",DownRightVector:\"⇁\",DownRightVectorBar:\"⥗\",DownTee:\"⊤\",DownTeeArrow:\"↧\",drbkarow:\"⤐\",drcorn:\"⌟\",drcrop:\"⌌\",Dscr:\"𝒟\",dscr:\"𝒹\",DScy:\"Ѕ\",dscy:\"ѕ\",dsol:\"⧶\",Dstrok:\"Đ\",dstrok:\"đ\",dtdot:\"⋱\",dtri:\"▿\",dtrif:\"▾\",duarr:\"⇵\",duhar:\"⥯\",dwangle:\"⦦\",DZcy:\"Џ\",dzcy:\"џ\",dzigrarr:\"⟿\",Eacute:\"É\",eacute:\"é\",easter:\"⩮\",Ecaron:\"Ě\",ecaron:\"ě\",ecir:\"≖\",Ecirc:\"Ê\",ecirc:\"ê\",ecolon:\"≕\",Ecy:\"Э\",ecy:\"э\",eDDot:\"⩷\",Edot:\"Ė\",eDot:\"≑\",edot:\"ė\",ee:\"ⅇ\",efDot:\"≒\",Efr:\"𝔈\",efr:\"𝔢\",eg:\"⪚\",Egrave:\"È\",egrave:\"è\",egs:\"⪖\",egsdot:\"⪘\",el:\"⪙\",Element:\"∈\",elinters:\"⏧\",ell:\"ℓ\",els:\"⪕\",elsdot:\"⪗\",Emacr:\"Ē\",emacr:\"ē\",empty:\"∅\",emptyset:\"∅\",EmptySmallSquare:\"◻\",emptyv:\"∅\",EmptyVerySmallSquare:\"▫\",emsp:\" \",emsp13:\" \",emsp14:\" \",ENG:\"Ŋ\",eng:\"ŋ\",ensp:\" \",Eogon:\"Ę\",eogon:\"ę\",Eopf:\"𝔼\",eopf:\"𝕖\",epar:\"⋕\",eparsl:\"⧣\",eplus:\"⩱\",epsi:\"ε\",Epsilon:\"Ε\",epsilon:\"ε\",epsiv:\"ϵ\",eqcirc:\"≖\",eqcolon:\"≕\",eqsim:\"≂\",eqslantgtr:\"⪖\",eqslantless:\"⪕\",Equal:\"⩵\",equals:\"=\",EqualTilde:\"≂\",equest:\"≟\",Equilibrium:\"⇌\",equiv:\"≡\",equivDD:\"⩸\",eqvparsl:\"⧥\",erarr:\"⥱\",erDot:\"≓\",Escr:\"ℰ\",escr:\"ℯ\",esdot:\"≐\",Esim:\"⩳\",esim:\"≂\",Eta:\"Η\",eta:\"η\",ETH:\"Ð\",eth:\"ð\",Euml:\"Ë\",euml:\"ë\",euro:\"€\",excl:\"!\",exist:\"∃\",Exists:\"∃\",expectation:\"ℰ\",ExponentialE:\"ⅇ\",exponentiale:\"ⅇ\",fallingdotseq:\"≒\",Fcy:\"Ф\",fcy:\"ф\",female:\"♀\",ffilig:\"ffi\",fflig:\"ff\",ffllig:\"ffl\",Ffr:\"𝔉\",ffr:\"𝔣\",filig:\"fi\",FilledSmallSquare:\"◼\",FilledVerySmallSquare:\"▪\",fjlig:\"fj\",flat:\"♭\",fllig:\"fl\",fltns:\"▱\",fnof:\"ƒ\",Fopf:\"𝔽\",fopf:\"𝕗\",ForAll:\"∀\",forall:\"∀\",fork:\"⋔\",forkv:\"⫙\",Fouriertrf:\"ℱ\",fpartint:\"⨍\",frac12:\"½\",frac13:\"⅓\",frac14:\"¼\",frac15:\"⅕\",frac16:\"⅙\",frac18:\"⅛\",frac23:\"⅔\",frac25:\"⅖\",frac34:\"¾\",frac35:\"⅗\",frac38:\"⅜\",frac45:\"⅘\",frac56:\"⅚\",frac58:\"⅝\",frac78:\"⅞\",frasl:\"⁄\",frown:\"⌢\",Fscr:\"ℱ\",fscr:\"𝒻\",gacute:\"ǵ\",Gamma:\"Γ\",gamma:\"γ\",Gammad:\"Ϝ\",gammad:\"ϝ\",gap:\"⪆\",Gbreve:\"Ğ\",gbreve:\"ğ\",Gcedil:\"Ģ\",Gcirc:\"Ĝ\",gcirc:\"ĝ\",Gcy:\"Г\",gcy:\"г\",Gdot:\"Ġ\",gdot:\"ġ\",gE:\"≧\",ge:\"≥\",gEl:\"⪌\",gel:\"⋛\",geq:\"≥\",geqq:\"≧\",geqslant:\"⩾\",ges:\"⩾\",gescc:\"⪩\",gesdot:\"⪀\",gesdoto:\"⪂\",gesdotol:\"⪄\",gesl:\"⋛︀\",gesles:\"⪔\",Gfr:\"𝔊\",gfr:\"𝔤\",Gg:\"⋙\",gg:\"≫\",ggg:\"⋙\",gimel:\"ℷ\",GJcy:\"Ѓ\",gjcy:\"ѓ\",gl:\"≷\",gla:\"⪥\",glE:\"⪒\",glj:\"⪤\",gnap:\"⪊\",gnapprox:\"⪊\",gnE:\"≩\",gne:\"⪈\",gneq:\"⪈\",gneqq:\"≩\",gnsim:\"⋧\",Gopf:\"𝔾\",gopf:\"𝕘\",grave:\"`\",GreaterEqual:\"≥\",GreaterEqualLess:\"⋛\",GreaterFullEqual:\"≧\",GreaterGreater:\"⪢\",GreaterLess:\"≷\",GreaterSlantEqual:\"⩾\",GreaterTilde:\"≳\",Gscr:\"𝒢\",gscr:\"ℊ\",gsim:\"≳\",gsime:\"⪎\",gsiml:\"⪐\",GT:\">\",Gt:\"≫\",gt:\">\",gtcc:\"⪧\",gtcir:\"⩺\",gtdot:\"⋗\",gtlPar:\"⦕\",gtquest:\"⩼\",gtrapprox:\"⪆\",gtrarr:\"⥸\",gtrdot:\"⋗\",gtreqless:\"⋛\",gtreqqless:\"⪌\",gtrless:\"≷\",gtrsim:\"≳\",gvertneqq:\"≩︀\",gvnE:\"≩︀\",Hacek:\"ˇ\",hairsp:\" \",half:\"½\",hamilt:\"ℋ\",HARDcy:\"Ъ\",hardcy:\"ъ\",hArr:\"⇔\",harr:\"↔\",harrcir:\"⥈\",harrw:\"↭\",Hat:\"^\",hbar:\"ℏ\",Hcirc:\"Ĥ\",hcirc:\"ĥ\",hearts:\"♥\",heartsuit:\"♥\",hellip:\"…\",hercon:\"⊹\",Hfr:\"ℌ\",hfr:\"𝔥\",HilbertSpace:\"ℋ\",hksearow:\"⤥\",hkswarow:\"⤦\",hoarr:\"⇿\",homtht:\"∻\",hookleftarrow:\"↩\",hookrightarrow:\"↪\",Hopf:\"ℍ\",hopf:\"𝕙\",horbar:\"―\",HorizontalLine:\"─\",Hscr:\"ℋ\",hscr:\"𝒽\",hslash:\"ℏ\",Hstrok:\"Ħ\",hstrok:\"ħ\",HumpDownHump:\"≎\",HumpEqual:\"≏\",hybull:\"⁃\",hyphen:\"‐\",Iacute:\"Í\",iacute:\"í\",ic:\"\",Icirc:\"Î\",icirc:\"î\",Icy:\"И\",icy:\"и\",Idot:\"İ\",IEcy:\"Е\",iecy:\"е\",iexcl:\"¡\",iff:\"⇔\",Ifr:\"ℑ\",ifr:\"𝔦\",Igrave:\"Ì\",igrave:\"ì\",ii:\"ⅈ\",iiiint:\"⨌\",iiint:\"∭\",iinfin:\"⧜\",iiota:\"℩\",IJlig:\"IJ\",ijlig:\"ij\",Im:\"ℑ\",Imacr:\"Ī\",imacr:\"ī\",image:\"ℑ\",ImaginaryI:\"ⅈ\",imagline:\"ℐ\",imagpart:\"ℑ\",imath:\"ı\",imof:\"⊷\",imped:\"Ƶ\",Implies:\"⇒\",in:\"∈\",incare:\"℅\",infin:\"∞\",infintie:\"⧝\",inodot:\"ı\",Int:\"∬\",int:\"∫\",intcal:\"⊺\",integers:\"ℤ\",Integral:\"∫\",intercal:\"⊺\",Intersection:\"⋂\",intlarhk:\"⨗\",intprod:\"⨼\",InvisibleComma:\"\",InvisibleTimes:\"\",IOcy:\"Ё\",iocy:\"ё\",Iogon:\"Į\",iogon:\"į\",Iopf:\"𝕀\",iopf:\"𝕚\",Iota:\"Ι\",iota:\"ι\",iprod:\"⨼\",iquest:\"¿\",Iscr:\"ℐ\",iscr:\"𝒾\",isin:\"∈\",isindot:\"⋵\",isinE:\"⋹\",isins:\"⋴\",isinsv:\"⋳\",isinv:\"∈\",it:\"\",Itilde:\"Ĩ\",itilde:\"ĩ\",Iukcy:\"І\",iukcy:\"і\",Iuml:\"Ï\",iuml:\"ï\",Jcirc:\"Ĵ\",jcirc:\"ĵ\",Jcy:\"Й\",jcy:\"й\",Jfr:\"𝔍\",jfr:\"𝔧\",jmath:\"ȷ\",Jopf:\"𝕁\",jopf:\"𝕛\",Jscr:\"𝒥\",jscr:\"𝒿\",Jsercy:\"Ј\",jsercy:\"ј\",Jukcy:\"Є\",jukcy:\"є\",Kappa:\"Κ\",kappa:\"κ\",kappav:\"ϰ\",Kcedil:\"Ķ\",kcedil:\"ķ\",Kcy:\"К\",kcy:\"к\",Kfr:\"𝔎\",kfr:\"𝔨\",kgreen:\"ĸ\",KHcy:\"Х\",khcy:\"х\",KJcy:\"Ќ\",kjcy:\"ќ\",Kopf:\"𝕂\",kopf:\"𝕜\",Kscr:\"𝒦\",kscr:\"𝓀\",lAarr:\"⇚\",Lacute:\"Ĺ\",lacute:\"ĺ\",laemptyv:\"⦴\",lagran:\"ℒ\",Lambda:\"Λ\",lambda:\"λ\",Lang:\"⟪\",lang:\"⟨\",langd:\"⦑\",langle:\"⟨\",lap:\"⪅\",Laplacetrf:\"ℒ\",laquo:\"«\",Larr:\"↞\",lArr:\"⇐\",larr:\"←\",larrb:\"⇤\",larrbfs:\"⤟\",larrfs:\"⤝\",larrhk:\"↩\",larrlp:\"↫\",larrpl:\"⤹\",larrsim:\"⥳\",larrtl:\"↢\",lat:\"⪫\",lAtail:\"⤛\",latail:\"⤙\",late:\"⪭\",lates:\"⪭︀\",lBarr:\"⤎\",lbarr:\"⤌\",lbbrk:\"❲\",lbrace:\"{\",lbrack:\"[\",lbrke:\"⦋\",lbrksld:\"⦏\",lbrkslu:\"⦍\",Lcaron:\"Ľ\",lcaron:\"ľ\",Lcedil:\"Ļ\",lcedil:\"ļ\",lceil:\"⌈\",lcub:\"{\",Lcy:\"Л\",lcy:\"л\",ldca:\"⤶\",ldquo:\"“\",ldquor:\"„\",ldrdhar:\"⥧\",ldrushar:\"⥋\",ldsh:\"↲\",lE:\"≦\",le:\"≤\",LeftAngleBracket:\"⟨\",LeftArrow:\"←\",Leftarrow:\"⇐\",leftarrow:\"←\",LeftArrowBar:\"⇤\",LeftArrowRightArrow:\"⇆\",leftarrowtail:\"↢\",LeftCeiling:\"⌈\",LeftDoubleBracket:\"⟦\",LeftDownTeeVector:\"⥡\",LeftDownVector:\"⇃\",LeftDownVectorBar:\"⥙\",LeftFloor:\"⌊\",leftharpoondown:\"↽\",leftharpoonup:\"↼\",leftleftarrows:\"⇇\",LeftRightArrow:\"↔\",Leftrightarrow:\"⇔\",leftrightarrow:\"↔\",leftrightarrows:\"⇆\",leftrightharpoons:\"⇋\",leftrightsquigarrow:\"↭\",LeftRightVector:\"⥎\",LeftTee:\"⊣\",LeftTeeArrow:\"↤\",LeftTeeVector:\"⥚\",leftthreetimes:\"⋋\",LeftTriangle:\"⊲\",LeftTriangleBar:\"⧏\",LeftTriangleEqual:\"⊴\",LeftUpDownVector:\"⥑\",LeftUpTeeVector:\"⥠\",LeftUpVector:\"↿\",LeftUpVectorBar:\"⥘\",LeftVector:\"↼\",LeftVectorBar:\"⥒\",lEg:\"⪋\",leg:\"⋚\",leq:\"≤\",leqq:\"≦\",leqslant:\"⩽\",les:\"⩽\",lescc:\"⪨\",lesdot:\"⩿\",lesdoto:\"⪁\",lesdotor:\"⪃\",lesg:\"⋚︀\",lesges:\"⪓\",lessapprox:\"⪅\",lessdot:\"⋖\",lesseqgtr:\"⋚\",lesseqqgtr:\"⪋\",LessEqualGreater:\"⋚\",LessFullEqual:\"≦\",LessGreater:\"≶\",lessgtr:\"≶\",LessLess:\"⪡\",lesssim:\"≲\",LessSlantEqual:\"⩽\",LessTilde:\"≲\",lfisht:\"⥼\",lfloor:\"⌊\",Lfr:\"𝔏\",lfr:\"𝔩\",lg:\"≶\",lgE:\"⪑\",lHar:\"⥢\",lhard:\"↽\",lharu:\"↼\",lharul:\"⥪\",lhblk:\"▄\",LJcy:\"Љ\",ljcy:\"љ\",Ll:\"⋘\",ll:\"≪\",llarr:\"⇇\",llcorner:\"⌞\",Lleftarrow:\"⇚\",llhard:\"⥫\",lltri:\"◺\",Lmidot:\"Ŀ\",lmidot:\"ŀ\",lmoust:\"⎰\",lmoustache:\"⎰\",lnap:\"⪉\",lnapprox:\"⪉\",lnE:\"≨\",lne:\"⪇\",lneq:\"⪇\",lneqq:\"≨\",lnsim:\"⋦\",loang:\"⟬\",loarr:\"⇽\",lobrk:\"⟦\",LongLeftArrow:\"⟵\",Longleftarrow:\"⟸\",longleftarrow:\"⟵\",LongLeftRightArrow:\"⟷\",Longleftrightarrow:\"⟺\",longleftrightarrow:\"⟷\",longmapsto:\"⟼\",LongRightArrow:\"⟶\",Longrightarrow:\"⟹\",longrightarrow:\"⟶\",looparrowleft:\"↫\",looparrowright:\"↬\",lopar:\"⦅\",Lopf:\"𝕃\",lopf:\"𝕝\",loplus:\"⨭\",lotimes:\"⨴\",lowast:\"∗\",lowbar:\"_\",LowerLeftArrow:\"↙\",LowerRightArrow:\"↘\",loz:\"◊\",lozenge:\"◊\",lozf:\"⧫\",lpar:\"(\",lparlt:\"⦓\",lrarr:\"⇆\",lrcorner:\"⌟\",lrhar:\"⇋\",lrhard:\"⥭\",lrm:\"\",lrtri:\"⊿\",lsaquo:\"‹\",Lscr:\"ℒ\",lscr:\"𝓁\",Lsh:\"↰\",lsh:\"↰\",lsim:\"≲\",lsime:\"⪍\",lsimg:\"⪏\",lsqb:\"[\",lsquo:\"‘\",lsquor:\"‚\",Lstrok:\"Ł\",lstrok:\"ł\",LT:\"<\",Lt:\"≪\",lt:\"<\",ltcc:\"⪦\",ltcir:\"⩹\",ltdot:\"⋖\",lthree:\"⋋\",ltimes:\"⋉\",ltlarr:\"⥶\",ltquest:\"⩻\",ltri:\"◃\",ltrie:\"⊴\",ltrif:\"◂\",ltrPar:\"⦖\",lurdshar:\"⥊\",luruhar:\"⥦\",lvertneqq:\"≨︀\",lvnE:\"≨︀\",macr:\"¯\",male:\"♂\",malt:\"✠\",maltese:\"✠\",Map:\"⤅\",map:\"↦\",mapsto:\"↦\",mapstodown:\"↧\",mapstoleft:\"↤\",mapstoup:\"↥\",marker:\"▮\",mcomma:\"⨩\",Mcy:\"М\",mcy:\"м\",mdash:\"—\",mDDot:\"∺\",measuredangle:\"∡\",MediumSpace:\" \",Mellintrf:\"ℳ\",Mfr:\"𝔐\",mfr:\"𝔪\",mho:\"℧\",micro:\"µ\",mid:\"∣\",midast:\"*\",midcir:\"⫰\",middot:\"·\",minus:\"−\",minusb:\"⊟\",minusd:\"∸\",minusdu:\"⨪\",MinusPlus:\"∓\",mlcp:\"⫛\",mldr:\"…\",mnplus:\"∓\",models:\"⊧\",Mopf:\"𝕄\",mopf:\"𝕞\",mp:\"∓\",Mscr:\"ℳ\",mscr:\"𝓂\",mstpos:\"∾\",Mu:\"Μ\",mu:\"μ\",multimap:\"⊸\",mumap:\"⊸\",nabla:\"∇\",Nacute:\"Ń\",nacute:\"ń\",nang:\"∠⃒\",nap:\"≉\",napE:\"⩰̸\",napid:\"≋̸\",napos:\"ʼn\",napprox:\"≉\",natur:\"♮\",natural:\"♮\",naturals:\"ℕ\",nbsp:\" \",nbump:\"≎̸\",nbumpe:\"≏̸\",ncap:\"⩃\",Ncaron:\"Ň\",ncaron:\"ň\",Ncedil:\"Ņ\",ncedil:\"ņ\",ncong:\"≇\",ncongdot:\"⩭̸\",ncup:\"⩂\",Ncy:\"Н\",ncy:\"н\",ndash:\"–\",ne:\"≠\",nearhk:\"⤤\",neArr:\"⇗\",nearr:\"↗\",nearrow:\"↗\",nedot:\"≐̸\",NegativeMediumSpace:\"\",NegativeThickSpace:\"\",NegativeThinSpace:\"\",NegativeVeryThinSpace:\"\",nequiv:\"≢\",nesear:\"⤨\",nesim:\"≂̸\",NestedGreaterGreater:\"≫\",NestedLessLess:\"≪\",NewLine:\"\\n\",nexist:\"∄\",nexists:\"∄\",Nfr:\"𝔑\",nfr:\"𝔫\",ngE:\"≧̸\",nge:\"≱\",ngeq:\"≱\",ngeqq:\"≧̸\",ngeqslant:\"⩾̸\",nges:\"⩾̸\",nGg:\"⋙̸\",ngsim:\"≵\",nGt:\"≫⃒\",ngt:\"≯\",ngtr:\"≯\",nGtv:\"≫̸\",nhArr:\"⇎\",nharr:\"↮\",nhpar:\"⫲\",ni:\"∋\",nis:\"⋼\",nisd:\"⋺\",niv:\"∋\",NJcy:\"Њ\",njcy:\"њ\",nlArr:\"⇍\",nlarr:\"↚\",nldr:\"‥\",nlE:\"≦̸\",nle:\"≰\",nLeftarrow:\"⇍\",nleftarrow:\"↚\",nLeftrightarrow:\"⇎\",nleftrightarrow:\"↮\",nleq:\"≰\",nleqq:\"≦̸\",nleqslant:\"⩽̸\",nles:\"⩽̸\",nless:\"≮\",nLl:\"⋘̸\",nlsim:\"≴\",nLt:\"≪⃒\",nlt:\"≮\",nltri:\"⋪\",nltrie:\"⋬\",nLtv:\"≪̸\",nmid:\"∤\",NoBreak:\"\",NonBreakingSpace:\" \",Nopf:\"ℕ\",nopf:\"𝕟\",Not:\"⫬\",not:\"¬\",NotCongruent:\"≢\",NotCupCap:\"≭\",NotDoubleVerticalBar:\"∦\",NotElement:\"∉\",NotEqual:\"≠\",NotEqualTilde:\"≂̸\",NotExists:\"∄\",NotGreater:\"≯\",NotGreaterEqual:\"≱\",NotGreaterFullEqual:\"≧̸\",NotGreaterGreater:\"≫̸\",NotGreaterLess:\"≹\",NotGreaterSlantEqual:\"⩾̸\",NotGreaterTilde:\"≵\",NotHumpDownHump:\"≎̸\",NotHumpEqual:\"≏̸\",notin:\"∉\",notindot:\"⋵̸\",notinE:\"⋹̸\",notinva:\"∉\",notinvb:\"⋷\",notinvc:\"⋶\",NotLeftTriangle:\"⋪\",NotLeftTriangleBar:\"⧏̸\",NotLeftTriangleEqual:\"⋬\",NotLess:\"≮\",NotLessEqual:\"≰\",NotLessGreater:\"≸\",NotLessLess:\"≪̸\",NotLessSlantEqual:\"⩽̸\",NotLessTilde:\"≴\",NotNestedGreaterGreater:\"⪢̸\",NotNestedLessLess:\"⪡̸\",notni:\"∌\",notniva:\"∌\",notnivb:\"⋾\",notnivc:\"⋽\",NotPrecedes:\"⊀\",NotPrecedesEqual:\"⪯̸\",NotPrecedesSlantEqual:\"⋠\",NotReverseElement:\"∌\",NotRightTriangle:\"⋫\",NotRightTriangleBar:\"⧐̸\",NotRightTriangleEqual:\"⋭\",NotSquareSubset:\"⊏̸\",NotSquareSubsetEqual:\"⋢\",NotSquareSuperset:\"⊐̸\",NotSquareSupersetEqual:\"⋣\",NotSubset:\"⊂⃒\",NotSubsetEqual:\"⊈\",NotSucceeds:\"⊁\",NotSucceedsEqual:\"⪰̸\",NotSucceedsSlantEqual:\"⋡\",NotSucceedsTilde:\"≿̸\",NotSuperset:\"⊃⃒\",NotSupersetEqual:\"⊉\",NotTilde:\"≁\",NotTildeEqual:\"≄\",NotTildeFullEqual:\"≇\",NotTildeTilde:\"≉\",NotVerticalBar:\"∤\",npar:\"∦\",nparallel:\"∦\",nparsl:\"⫽⃥\",npart:\"∂̸\",npolint:\"⨔\",npr:\"⊀\",nprcue:\"⋠\",npre:\"⪯̸\",nprec:\"⊀\",npreceq:\"⪯̸\",nrArr:\"⇏\",nrarr:\"↛\",nrarrc:\"⤳̸\",nrarrw:\"↝̸\",nRightarrow:\"⇏\",nrightarrow:\"↛\",nrtri:\"⋫\",nrtrie:\"⋭\",nsc:\"⊁\",nsccue:\"⋡\",nsce:\"⪰̸\",Nscr:\"𝒩\",nscr:\"𝓃\",nshortmid:\"∤\",nshortparallel:\"∦\",nsim:\"≁\",nsime:\"≄\",nsimeq:\"≄\",nsmid:\"∤\",nspar:\"∦\",nsqsube:\"⋢\",nsqsupe:\"⋣\",nsub:\"⊄\",nsubE:\"⫅̸\",nsube:\"⊈\",nsubset:\"⊂⃒\",nsubseteq:\"⊈\",nsubseteqq:\"⫅̸\",nsucc:\"⊁\",nsucceq:\"⪰̸\",nsup:\"⊅\",nsupE:\"⫆̸\",nsupe:\"⊉\",nsupset:\"⊃⃒\",nsupseteq:\"⊉\",nsupseteqq:\"⫆̸\",ntgl:\"≹\",Ntilde:\"Ñ\",ntilde:\"ñ\",ntlg:\"≸\",ntriangleleft:\"⋪\",ntrianglelefteq:\"⋬\",ntriangleright:\"⋫\",ntrianglerighteq:\"⋭\",Nu:\"Ν\",nu:\"ν\",num:\"#\",numero:\"№\",numsp:\" \",nvap:\"≍⃒\",nVDash:\"⊯\",nVdash:\"⊮\",nvDash:\"⊭\",nvdash:\"⊬\",nvge:\"≥⃒\",nvgt:\">⃒\",nvHarr:\"⤄\",nvinfin:\"⧞\",nvlArr:\"⤂\",nvle:\"≤⃒\",nvlt:\"<⃒\",nvltrie:\"⊴⃒\",nvrArr:\"⤃\",nvrtrie:\"⊵⃒\",nvsim:\"∼⃒\",nwarhk:\"⤣\",nwArr:\"⇖\",nwarr:\"↖\",nwarrow:\"↖\",nwnear:\"⤧\",Oacute:\"Ó\",oacute:\"ó\",oast:\"⊛\",ocir:\"⊚\",Ocirc:\"Ô\",ocirc:\"ô\",Ocy:\"О\",ocy:\"о\",odash:\"⊝\",Odblac:\"Ő\",odblac:\"ő\",odiv:\"⨸\",odot:\"⊙\",odsold:\"⦼\",OElig:\"Œ\",oelig:\"œ\",ofcir:\"⦿\",Ofr:\"𝔒\",ofr:\"𝔬\",ogon:\"˛\",Ograve:\"Ò\",ograve:\"ò\",ogt:\"⧁\",ohbar:\"⦵\",ohm:\"Ω\",oint:\"∮\",olarr:\"↺\",olcir:\"⦾\",olcross:\"⦻\",oline:\"‾\",olt:\"⧀\",Omacr:\"Ō\",omacr:\"ō\",Omega:\"Ω\",omega:\"ω\",Omicron:\"Ο\",omicron:\"ο\",omid:\"⦶\",ominus:\"⊖\",Oopf:\"𝕆\",oopf:\"𝕠\",opar:\"⦷\",OpenCurlyDoubleQuote:\"“\",OpenCurlyQuote:\"‘\",operp:\"⦹\",oplus:\"⊕\",Or:\"⩔\",or:\"∨\",orarr:\"↻\",ord:\"⩝\",order:\"ℴ\",orderof:\"ℴ\",ordf:\"ª\",ordm:\"º\",origof:\"⊶\",oror:\"⩖\",orslope:\"⩗\",orv:\"⩛\",oS:\"Ⓢ\",Oscr:\"𝒪\",oscr:\"ℴ\",Oslash:\"Ø\",oslash:\"ø\",osol:\"⊘\",Otilde:\"Õ\",otilde:\"õ\",Otimes:\"⨷\",otimes:\"⊗\",otimesas:\"⨶\",Ouml:\"Ö\",ouml:\"ö\",ovbar:\"⌽\",OverBar:\"‾\",OverBrace:\"⏞\",OverBracket:\"⎴\",OverParenthesis:\"⏜\",par:\"∥\",para:\"¶\",parallel:\"∥\",parsim:\"⫳\",parsl:\"⫽\",part:\"∂\",PartialD:\"∂\",Pcy:\"П\",pcy:\"п\",percnt:\"%\",period:\".\",permil:\"‰\",perp:\"⊥\",pertenk:\"‱\",Pfr:\"𝔓\",pfr:\"𝔭\",Phi:\"Φ\",phi:\"φ\",phiv:\"ϕ\",phmmat:\"ℳ\",phone:\"☎\",Pi:\"Π\",pi:\"π\",pitchfork:\"⋔\",piv:\"ϖ\",planck:\"ℏ\",planckh:\"ℎ\",plankv:\"ℏ\",plus:\"+\",plusacir:\"⨣\",plusb:\"⊞\",pluscir:\"⨢\",plusdo:\"∔\",plusdu:\"⨥\",pluse:\"⩲\",PlusMinus:\"±\",plusmn:\"±\",plussim:\"⨦\",plustwo:\"⨧\",pm:\"±\",Poincareplane:\"ℌ\",pointint:\"⨕\",Popf:\"ℙ\",popf:\"𝕡\",pound:\"£\",Pr:\"⪻\",pr:\"≺\",prap:\"⪷\",prcue:\"≼\",prE:\"⪳\",pre:\"⪯\",prec:\"≺\",precapprox:\"⪷\",preccurlyeq:\"≼\",Precedes:\"≺\",PrecedesEqual:\"⪯\",PrecedesSlantEqual:\"≼\",PrecedesTilde:\"≾\",preceq:\"⪯\",precnapprox:\"⪹\",precneqq:\"⪵\",precnsim:\"⋨\",precsim:\"≾\",Prime:\"″\",prime:\"′\",primes:\"ℙ\",prnap:\"⪹\",prnE:\"⪵\",prnsim:\"⋨\",prod:\"∏\",Product:\"∏\",profalar:\"⌮\",profline:\"⌒\",profsurf:\"⌓\",prop:\"∝\",Proportion:\"∷\",Proportional:\"∝\",propto:\"∝\",prsim:\"≾\",prurel:\"⊰\",Pscr:\"𝒫\",pscr:\"𝓅\",Psi:\"Ψ\",psi:\"ψ\",puncsp:\" \",Qfr:\"𝔔\",qfr:\"𝔮\",qint:\"⨌\",Qopf:\"ℚ\",qopf:\"𝕢\",qprime:\"⁗\",Qscr:\"𝒬\",qscr:\"𝓆\",quaternions:\"ℍ\",quatint:\"⨖\",quest:\"?\",questeq:\"≟\",QUOT:'\"',quot:'\"',rAarr:\"⇛\",race:\"∽̱\",Racute:\"Ŕ\",racute:\"ŕ\",radic:\"√\",raemptyv:\"⦳\",Rang:\"⟫\",rang:\"⟩\",rangd:\"⦒\",range:\"⦥\",rangle:\"⟩\",raquo:\"»\",Rarr:\"↠\",rArr:\"⇒\",rarr:\"→\",rarrap:\"⥵\",rarrb:\"⇥\",rarrbfs:\"⤠\",rarrc:\"⤳\",rarrfs:\"⤞\",rarrhk:\"↪\",rarrlp:\"↬\",rarrpl:\"⥅\",rarrsim:\"⥴\",Rarrtl:\"⤖\",rarrtl:\"↣\",rarrw:\"↝\",rAtail:\"⤜\",ratail:\"⤚\",ratio:\"∶\",rationals:\"ℚ\",RBarr:\"⤐\",rBarr:\"⤏\",rbarr:\"⤍\",rbbrk:\"❳\",rbrace:\"}\",rbrack:\"]\",rbrke:\"⦌\",rbrksld:\"⦎\",rbrkslu:\"⦐\",Rcaron:\"Ř\",rcaron:\"ř\",Rcedil:\"Ŗ\",rcedil:\"ŗ\",rceil:\"⌉\",rcub:\"}\",Rcy:\"Р\",rcy:\"р\",rdca:\"⤷\",rdldhar:\"⥩\",rdquo:\"”\",rdquor:\"”\",rdsh:\"↳\",Re:\"ℜ\",real:\"ℜ\",realine:\"ℛ\",realpart:\"ℜ\",reals:\"ℝ\",rect:\"▭\",REG:\"®\",reg:\"®\",ReverseElement:\"∋\",ReverseEquilibrium:\"⇋\",ReverseUpEquilibrium:\"⥯\",rfisht:\"⥽\",rfloor:\"⌋\",Rfr:\"ℜ\",rfr:\"𝔯\",rHar:\"⥤\",rhard:\"⇁\",rharu:\"⇀\",rharul:\"⥬\",Rho:\"Ρ\",rho:\"ρ\",rhov:\"ϱ\",RightAngleBracket:\"⟩\",RightArrow:\"→\",Rightarrow:\"⇒\",rightarrow:\"→\",RightArrowBar:\"⇥\",RightArrowLeftArrow:\"⇄\",rightarrowtail:\"↣\",RightCeiling:\"⌉\",RightDoubleBracket:\"⟧\",RightDownTeeVector:\"⥝\",RightDownVector:\"⇂\",RightDownVectorBar:\"⥕\",RightFloor:\"⌋\",rightharpoondown:\"⇁\",rightharpoonup:\"⇀\",rightleftarrows:\"⇄\",rightleftharpoons:\"⇌\",rightrightarrows:\"⇉\",rightsquigarrow:\"↝\",RightTee:\"⊢\",RightTeeArrow:\"↦\",RightTeeVector:\"⥛\",rightthreetimes:\"⋌\",RightTriangle:\"⊳\",RightTriangleBar:\"⧐\",RightTriangleEqual:\"⊵\",RightUpDownVector:\"⥏\",RightUpTeeVector:\"⥜\",RightUpVector:\"↾\",RightUpVectorBar:\"⥔\",RightVector:\"⇀\",RightVectorBar:\"⥓\",ring:\"˚\",risingdotseq:\"≓\",rlarr:\"⇄\",rlhar:\"⇌\",rlm:\"\",rmoust:\"⎱\",rmoustache:\"⎱\",rnmid:\"⫮\",roang:\"⟭\",roarr:\"⇾\",robrk:\"⟧\",ropar:\"⦆\",Ropf:\"ℝ\",ropf:\"𝕣\",roplus:\"⨮\",rotimes:\"⨵\",RoundImplies:\"⥰\",rpar:\")\",rpargt:\"⦔\",rppolint:\"⨒\",rrarr:\"⇉\",Rrightarrow:\"⇛\",rsaquo:\"›\",Rscr:\"ℛ\",rscr:\"𝓇\",Rsh:\"↱\",rsh:\"↱\",rsqb:\"]\",rsquo:\"’\",rsquor:\"’\",rthree:\"⋌\",rtimes:\"⋊\",rtri:\"▹\",rtrie:\"⊵\",rtrif:\"▸\",rtriltri:\"⧎\",RuleDelayed:\"⧴\",ruluhar:\"⥨\",rx:\"℞\",Sacute:\"Ś\",sacute:\"ś\",sbquo:\"‚\",Sc:\"⪼\",sc:\"≻\",scap:\"⪸\",Scaron:\"Š\",scaron:\"š\",sccue:\"≽\",scE:\"⪴\",sce:\"⪰\",Scedil:\"Ş\",scedil:\"ş\",Scirc:\"Ŝ\",scirc:\"ŝ\",scnap:\"⪺\",scnE:\"⪶\",scnsim:\"⋩\",scpolint:\"⨓\",scsim:\"≿\",Scy:\"С\",scy:\"с\",sdot:\"⋅\",sdotb:\"⊡\",sdote:\"⩦\",searhk:\"⤥\",seArr:\"⇘\",searr:\"↘\",searrow:\"↘\",sect:\"§\",semi:\";\",seswar:\"⤩\",setminus:\"∖\",setmn:\"∖\",sext:\"✶\",Sfr:\"𝔖\",sfr:\"𝔰\",sfrown:\"⌢\",sharp:\"♯\",SHCHcy:\"Щ\",shchcy:\"щ\",SHcy:\"Ш\",shcy:\"ш\",ShortDownArrow:\"↓\",ShortLeftArrow:\"←\",shortmid:\"∣\",shortparallel:\"∥\",ShortRightArrow:\"→\",ShortUpArrow:\"↑\",shy:\"\",Sigma:\"Σ\",sigma:\"σ\",sigmaf:\"ς\",sigmav:\"ς\",sim:\"∼\",simdot:\"⩪\",sime:\"≃\",simeq:\"≃\",simg:\"⪞\",simgE:\"⪠\",siml:\"⪝\",simlE:\"⪟\",simne:\"≆\",simplus:\"⨤\",simrarr:\"⥲\",slarr:\"←\",SmallCircle:\"∘\",smallsetminus:\"∖\",smashp:\"⨳\",smeparsl:\"⧤\",smid:\"∣\",smile:\"⌣\",smt:\"⪪\",smte:\"⪬\",smtes:\"⪬︀\",SOFTcy:\"Ь\",softcy:\"ь\",sol:\"/\",solb:\"⧄\",solbar:\"⌿\",Sopf:\"𝕊\",sopf:\"𝕤\",spades:\"♠\",spadesuit:\"♠\",spar:\"∥\",sqcap:\"⊓\",sqcaps:\"⊓︀\",sqcup:\"⊔\",sqcups:\"⊔︀\",Sqrt:\"√\",sqsub:\"⊏\",sqsube:\"⊑\",sqsubset:\"⊏\",sqsubseteq:\"⊑\",sqsup:\"⊐\",sqsupe:\"⊒\",sqsupset:\"⊐\",sqsupseteq:\"⊒\",squ:\"□\",Square:\"□\",square:\"□\",SquareIntersection:\"⊓\",SquareSubset:\"⊏\",SquareSubsetEqual:\"⊑\",SquareSuperset:\"⊐\",SquareSupersetEqual:\"⊒\",SquareUnion:\"⊔\",squarf:\"▪\",squf:\"▪\",srarr:\"→\",Sscr:\"𝒮\",sscr:\"𝓈\",ssetmn:\"∖\",ssmile:\"⌣\",sstarf:\"⋆\",Star:\"⋆\",star:\"☆\",starf:\"★\",straightepsilon:\"ϵ\",straightphi:\"ϕ\",strns:\"¯\",Sub:\"⋐\",sub:\"⊂\",subdot:\"⪽\",subE:\"⫅\",sube:\"⊆\",subedot:\"⫃\",submult:\"⫁\",subnE:\"⫋\",subne:\"⊊\",subplus:\"⪿\",subrarr:\"⥹\",Subset:\"⋐\",subset:\"⊂\",subseteq:\"⊆\",subseteqq:\"⫅\",SubsetEqual:\"⊆\",subsetneq:\"⊊\",subsetneqq:\"⫋\",subsim:\"⫇\",subsub:\"⫕\",subsup:\"⫓\",succ:\"≻\",succapprox:\"⪸\",succcurlyeq:\"≽\",Succeeds:\"≻\",SucceedsEqual:\"⪰\",SucceedsSlantEqual:\"≽\",SucceedsTilde:\"≿\",succeq:\"⪰\",succnapprox:\"⪺\",succneqq:\"⪶\",succnsim:\"⋩\",succsim:\"≿\",SuchThat:\"∋\",Sum:\"∑\",sum:\"∑\",sung:\"♪\",Sup:\"⋑\",sup:\"⊃\",sup1:\"¹\",sup2:\"²\",sup3:\"³\",supdot:\"⪾\",supdsub:\"⫘\",supE:\"⫆\",supe:\"⊇\",supedot:\"⫄\",Superset:\"⊃\",SupersetEqual:\"⊇\",suphsol:\"⟉\",suphsub:\"⫗\",suplarr:\"⥻\",supmult:\"⫂\",supnE:\"⫌\",supne:\"⊋\",supplus:\"⫀\",Supset:\"⋑\",supset:\"⊃\",supseteq:\"⊇\",supseteqq:\"⫆\",supsetneq:\"⊋\",supsetneqq:\"⫌\",supsim:\"⫈\",supsub:\"⫔\",supsup:\"⫖\",swarhk:\"⤦\",swArr:\"⇙\",swarr:\"↙\",swarrow:\"↙\",swnwar:\"⤪\",szlig:\"ß\",Tab:\"\\t\",target:\"⌖\",Tau:\"Τ\",tau:\"τ\",tbrk:\"⎴\",Tcaron:\"Ť\",tcaron:\"ť\",Tcedil:\"Ţ\",tcedil:\"ţ\",Tcy:\"Т\",tcy:\"т\",tdot:\"⃛\",telrec:\"⌕\",Tfr:\"𝔗\",tfr:\"𝔱\",there4:\"∴\",Therefore:\"∴\",therefore:\"∴\",Theta:\"Θ\",theta:\"θ\",thetasym:\"ϑ\",thetav:\"ϑ\",thickapprox:\"≈\",thicksim:\"∼\",ThickSpace:\" \",thinsp:\" \",ThinSpace:\" \",thkap:\"≈\",thksim:\"∼\",THORN:\"Þ\",thorn:\"þ\",Tilde:\"∼\",tilde:\"˜\",TildeEqual:\"≃\",TildeFullEqual:\"≅\",TildeTilde:\"≈\",times:\"×\",timesb:\"⊠\",timesbar:\"⨱\",timesd:\"⨰\",tint:\"∭\",toea:\"⤨\",top:\"⊤\",topbot:\"⌶\",topcir:\"⫱\",Topf:\"𝕋\",topf:\"𝕥\",topfork:\"⫚\",tosa:\"⤩\",tprime:\"‴\",TRADE:\"™\",trade:\"™\",triangle:\"▵\",triangledown:\"▿\",triangleleft:\"◃\",trianglelefteq:\"⊴\",triangleq:\"≜\",triangleright:\"▹\",trianglerighteq:\"⊵\",tridot:\"◬\",trie:\"≜\",triminus:\"⨺\",TripleDot:\"⃛\",triplus:\"⨹\",trisb:\"⧍\",tritime:\"⨻\",trpezium:\"⏢\",Tscr:\"𝒯\",tscr:\"𝓉\",TScy:\"Ц\",tscy:\"ц\",TSHcy:\"Ћ\",tshcy:\"ћ\",Tstrok:\"Ŧ\",tstrok:\"ŧ\",twixt:\"≬\",twoheadleftarrow:\"↞\",twoheadrightarrow:\"↠\",Uacute:\"Ú\",uacute:\"ú\",Uarr:\"↟\",uArr:\"⇑\",uarr:\"↑\",Uarrocir:\"⥉\",Ubrcy:\"Ў\",ubrcy:\"ў\",Ubreve:\"Ŭ\",ubreve:\"ŭ\",Ucirc:\"Û\",ucirc:\"û\",Ucy:\"У\",ucy:\"у\",udarr:\"⇅\",Udblac:\"Ű\",udblac:\"ű\",udhar:\"⥮\",ufisht:\"⥾\",Ufr:\"𝔘\",ufr:\"𝔲\",Ugrave:\"Ù\",ugrave:\"ù\",uHar:\"⥣\",uharl:\"↿\",uharr:\"↾\",uhblk:\"▀\",ulcorn:\"⌜\",ulcorner:\"⌜\",ulcrop:\"⌏\",ultri:\"◸\",Umacr:\"Ū\",umacr:\"ū\",uml:\"¨\",UnderBar:\"_\",UnderBrace:\"⏟\",UnderBracket:\"⎵\",UnderParenthesis:\"⏝\",Union:\"⋃\",UnionPlus:\"⊎\",Uogon:\"Ų\",uogon:\"ų\",Uopf:\"𝕌\",uopf:\"𝕦\",UpArrow:\"↑\",Uparrow:\"⇑\",uparrow:\"↑\",UpArrowBar:\"⤒\",UpArrowDownArrow:\"⇅\",UpDownArrow:\"↕\",Updownarrow:\"⇕\",updownarrow:\"↕\",UpEquilibrium:\"⥮\",upharpoonleft:\"↿\",upharpoonright:\"↾\",uplus:\"⊎\",UpperLeftArrow:\"↖\",UpperRightArrow:\"↗\",Upsi:\"ϒ\",upsi:\"υ\",upsih:\"ϒ\",Upsilon:\"Υ\",upsilon:\"υ\",UpTee:\"⊥\",UpTeeArrow:\"↥\",upuparrows:\"⇈\",urcorn:\"⌝\",urcorner:\"⌝\",urcrop:\"⌎\",Uring:\"Ů\",uring:\"ů\",urtri:\"◹\",Uscr:\"𝒰\",uscr:\"𝓊\",utdot:\"⋰\",Utilde:\"Ũ\",utilde:\"ũ\",utri:\"▵\",utrif:\"▴\",uuarr:\"⇈\",Uuml:\"Ü\",uuml:\"ü\",uwangle:\"⦧\",vangrt:\"⦜\",varepsilon:\"ϵ\",varkappa:\"ϰ\",varnothing:\"∅\",varphi:\"ϕ\",varpi:\"ϖ\",varpropto:\"∝\",vArr:\"⇕\",varr:\"↕\",varrho:\"ϱ\",varsigma:\"ς\",varsubsetneq:\"⊊︀\",varsubsetneqq:\"⫋︀\",varsupsetneq:\"⊋︀\",varsupsetneqq:\"⫌︀\",vartheta:\"ϑ\",vartriangleleft:\"⊲\",vartriangleright:\"⊳\",Vbar:\"⫫\",vBar:\"⫨\",vBarv:\"⫩\",Vcy:\"В\",vcy:\"в\",VDash:\"⊫\",Vdash:\"⊩\",vDash:\"⊨\",vdash:\"⊢\",Vdashl:\"⫦\",Vee:\"⋁\",vee:\"∨\",veebar:\"⊻\",veeeq:\"≚\",vellip:\"⋮\",Verbar:\"‖\",verbar:\"|\",Vert:\"‖\",vert:\"|\",VerticalBar:\"∣\",VerticalLine:\"|\",VerticalSeparator:\"❘\",VerticalTilde:\"≀\",VeryThinSpace:\" \",Vfr:\"𝔙\",vfr:\"𝔳\",vltri:\"⊲\",vnsub:\"⊂⃒\",vnsup:\"⊃⃒\",Vopf:\"𝕍\",vopf:\"𝕧\",vprop:\"∝\",vrtri:\"⊳\",Vscr:\"𝒱\",vscr:\"𝓋\",vsubnE:\"⫋︀\",vsubne:\"⊊︀\",vsupnE:\"⫌︀\",vsupne:\"⊋︀\",Vvdash:\"⊪\",vzigzag:\"⦚\",Wcirc:\"Ŵ\",wcirc:\"ŵ\",wedbar:\"⩟\",Wedge:\"⋀\",wedge:\"∧\",wedgeq:\"≙\",weierp:\"℘\",Wfr:\"𝔚\",wfr:\"𝔴\",Wopf:\"𝕎\",wopf:\"𝕨\",wp:\"℘\",wr:\"≀\",wreath:\"≀\",Wscr:\"𝒲\",wscr:\"𝓌\",xcap:\"⋂\",xcirc:\"◯\",xcup:\"⋃\",xdtri:\"▽\",Xfr:\"𝔛\",xfr:\"𝔵\",xhArr:\"⟺\",xharr:\"⟷\",Xi:\"Ξ\",xi:\"ξ\",xlArr:\"⟸\",xlarr:\"⟵\",xmap:\"⟼\",xnis:\"⋻\",xodot:\"⨀\",Xopf:\"𝕏\",xopf:\"𝕩\",xoplus:\"⨁\",xotime:\"⨂\",xrArr:\"⟹\",xrarr:\"⟶\",Xscr:\"𝒳\",xscr:\"𝓍\",xsqcup:\"⨆\",xuplus:\"⨄\",xutri:\"△\",xvee:\"⋁\",xwedge:\"⋀\",Yacute:\"Ý\",yacute:\"ý\",YAcy:\"Я\",yacy:\"я\",Ycirc:\"Ŷ\",ycirc:\"ŷ\",Ycy:\"Ы\",ycy:\"ы\",yen:\"¥\",Yfr:\"𝔜\",yfr:\"𝔶\",YIcy:\"Ї\",yicy:\"ї\",Yopf:\"𝕐\",yopf:\"𝕪\",Yscr:\"𝒴\",yscr:\"𝓎\",YUcy:\"Ю\",yucy:\"ю\",Yuml:\"Ÿ\",yuml:\"ÿ\",Zacute:\"Ź\",zacute:\"ź\",Zcaron:\"Ž\",zcaron:\"ž\",Zcy:\"З\",zcy:\"з\",Zdot:\"Ż\",zdot:\"ż\",zeetrf:\"ℨ\",ZeroWidthSpace:\"\",Zeta:\"Ζ\",zeta:\"ζ\",Zfr:\"ℨ\",zfr:\"𝔷\",ZHcy:\"Ж\",zhcy:\"ж\",zigrarr:\"⇝\",Zopf:\"ℤ\",zopf:\"𝕫\",Zscr:\"𝒵\",zscr:\"𝓏\",zwj:\"\",zwnj:\"\"},r=Object.prototype.hasOwnProperty;function n(e){return o=e,(n=t)&&r.call(n,o)?t[e]:e;var n,o}var o=Object.prototype.hasOwnProperty;function s(e,t){return!!e&&o.call(e,t)}function i(e){return[].slice.call(arguments,1).forEach(function(t){if(t){if(\"object\"!=typeof t)throw new TypeError(t+\"must be object\");Object.keys(t).forEach(function(r){e[r]=t[r]})}}),e}var a=/\\\\([\\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;function u(e){return e.indexOf(\"\\\\\")<0?e:e.replace(a,\"$1\")}function l(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function c(e){if(e>65535){var t=55296+((e-=65536)>>10),r=56320+(1023&e);return String.fromCharCode(t,r)}return String.fromCharCode(e)}var p=/&([a-z#][a-z0-9]{1,31});/gi,h=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;function f(e,t){var r=0,o=n(t);return t!==o?o:35===t.charCodeAt(0)&&h.test(t)&&l(r=\"x\"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10))?c(r):e}function g(e){return e.indexOf(\"&\")<0?e:e.replace(p,f)}var d=/[&<>\"]/,m=/[&<>\"]/g,b={\"&\":\"&\",\"<\":\"<\",\">\":\">\",'\"':\""\"};function v(e){return b[e]}function k(e){return d.test(e)?e.replace(m,v):e}var A=Object.freeze({isString:function(e){return\"[object String]\"===function(e){return Object.prototype.toString.call(e)}(e)},has:s,assign:i,unescapeMd:u,isValidEntityCode:l,fromCodePoint:c,replaceEntities:g,escapeHtml:k}),y={};y.blockquote_open=function(){return\"<blockquote>\\n\"},y.blockquote_close=function(e,t){return\"</blockquote>\"+x(e,t)},y.code=function(e,t){return e[t].block?\"<pre><code>\"+k(e[t].content)+\"</code></pre>\"+x(e,t):\"<code>\"+k(e[t].content)+\"</code>\"},y.fence=function(e,t,r,n,o){var i,a,l=e[t],c=\"\",p=r.langPrefix;if(l.params){if(a=(i=l.params.split(/\\s+/g)).join(\" \"),s(o.rules.fence_custom,i[0]))return o.rules.fence_custom[i[0]](e,t,r,n,o);c=' class=\"'+p+k(g(u(a)))+'\"'}return\"<pre><code\"+c+\">\"+(r.highlight&&r.highlight.apply(r.highlight,[l.content].concat(i))||k(l.content))+\"</code></pre>\"+x(e,t)},y.fence_custom={},y.heading_open=function(e,t){return\"<h\"+e[t].hLevel+\">\"},y.heading_close=function(e,t){return\"</h\"+e[t].hLevel+\">\\n\"},y.hr=function(e,t,r){return(r.xhtmlOut?\"<hr />\":\"<hr>\")+x(e,t)},y.bullet_list_open=function(){return\"<ul>\\n\"},y.bullet_list_close=function(e,t){return\"</ul>\"+x(e,t)},y.list_item_open=function(){return\"<li>\"},y.list_item_close=function(){return\"</li>\\n\"},y.ordered_list_open=function(e,t){var r=e[t];return\"<ol\"+(r.order>1?' start=\"'+r.order+'\"':\"\")+\">\\n\"},y.ordered_list_close=function(e,t){return\"</ol>\"+x(e,t)},y.paragraph_open=function(e,t){return e[t].tight?\"\":\"<p>\"},y.paragraph_close=function(e,t){var r=!(e[t].tight&&t&&\"inline\"===e[t-1].type&&!e[t-1].content);return(e[t].tight?\"\":\"</p>\")+(r?x(e,t):\"\")},y.link_open=function(e,t,r){var n=e[t].title?' title=\"'+k(g(e[t].title))+'\"':\"\",o=r.linkTarget?' target=\"'+r.linkTarget+'\"':\"\";return'<a href=\"'+k(e[t].href)+'\"'+n+o+\">\"},y.link_close=function(){return\"</a>\"},y.image=function(e,t,r){var n=' src=\"'+k(e[t].src)+'\"',o=e[t].title?' title=\"'+k(g(e[t].title))+'\"':\"\";return\"<img\"+n+(' alt=\"'+(e[t].alt?k(g(u(e[t].alt))):\"\")+'\"')+o+(r.xhtmlOut?\" /\":\"\")+\">\"},y.table_open=function(){return\"<table>\\n\"},y.table_close=function(){return\"</table>\\n\"},y.thead_open=function(){return\"<thead>\\n\"},y.thead_close=function(){return\"</thead>\\n\"},y.tbody_open=function(){return\"<tbody>\\n\"},y.tbody_close=function(){return\"</tbody>\\n\"},y.tr_open=function(){return\"<tr>\"},y.tr_close=function(){return\"</tr>\\n\"},y.th_open=function(e,t){var r=e[t];return\"<th\"+(r.align?' style=\"text-align:'+r.align+'\"':\"\")+\">\"},y.th_close=function(){return\"</th>\"},y.td_open=function(e,t){var r=e[t];return\"<td\"+(r.align?' style=\"text-align:'+r.align+'\"':\"\")+\">\"},y.td_close=function(){return\"</td>\"},y.strong_open=function(){return\"<strong>\"},y.strong_close=function(){return\"</strong>\"},y.em_open=function(){return\"<em>\"},y.em_close=function(){return\"</em>\"},y.del_open=function(){return\"<del>\"},y.del_close=function(){return\"</del>\"},y.ins_open=function(){return\"<ins>\"},y.ins_close=function(){return\"</ins>\"},y.mark_open=function(){return\"<mark>\"},y.mark_close=function(){return\"</mark>\"},y.sub=function(e,t){return\"<sub>\"+k(e[t].content)+\"</sub>\"},y.sup=function(e,t){return\"<sup>\"+k(e[t].content)+\"</sup>\"},y.hardbreak=function(e,t,r){return r.xhtmlOut?\"<br />\\n\":\"<br>\\n\"},y.softbreak=function(e,t,r){return r.breaks?r.xhtmlOut?\"<br />\\n\":\"<br>\\n\":\"\\n\"},y.text=function(e,t){return k(e[t].content)},y.htmlblock=function(e,t){return e[t].content},y.htmltag=function(e,t){return e[t].content},y.abbr_open=function(e,t){return'<abbr title=\"'+k(g(e[t].title))+'\">'},y.abbr_close=function(){return\"</abbr>\"},y.footnote_ref=function(e,t){var r=Number(e[t].id+1).toString(),n=\"fnref\"+r;return e[t].subId>0&&(n+=\":\"+e[t].subId),'<sup class=\"footnote-ref\"><a href=\"#fn'+r+'\" id=\"'+n+'\">['+r+\"]</a></sup>\"},y.footnote_block_open=function(e,t,r){return(r.xhtmlOut?'<hr class=\"footnotes-sep\" />\\n':'<hr class=\"footnotes-sep\">\\n')+'<section class=\"footnotes\">\\n<ol class=\"footnotes-list\">\\n'},y.footnote_block_close=function(){return\"</ol>\\n</section>\\n\"},y.footnote_open=function(e,t){return'<li id=\"fn'+Number(e[t].id+1).toString()+'\" class=\"footnote-item\">'},y.footnote_close=function(){return\"</li>\\n\"},y.footnote_anchor=function(e,t){var r=\"fnref\"+Number(e[t].id+1).toString();return e[t].subId>0&&(r+=\":\"+e[t].subId),' <a href=\"#'+r+'\" class=\"footnote-backref\">↩</a>'},y.dl_open=function(){return\"<dl>\\n\"},y.dt_open=function(){return\"<dt>\"},y.dd_open=function(){return\"<dd>\"},y.dl_close=function(){return\"</dl>\\n\"},y.dt_close=function(){return\"</dt>\\n\"},y.dd_close=function(){return\"</dd>\\n\"};var x=y.getBreak=function(e,t){return(t=function e(t,r){return++r>=t.length-2?r:\"paragraph_open\"===t[r].type&&t[r].tight&&\"inline\"===t[r+1].type&&0===t[r+1].content.length&&\"paragraph_close\"===t[r+2].type&&t[r+2].tight?e(t,r+2):r}(e,t))<e.length&&\"list_item_close\"===e[t].type?\"\":\"\\n\"};function w(){this.rules=i({},y),this.getBreak=y.getBreak}function C(){this.__rules__=[],this.__cache__=null}function E(e,t,r,n,o){this.src=e,this.env=n,this.options=r,this.parser=t,this.tokens=o,this.pos=0,this.posMax=this.src.length,this.level=0,this.pending=\"\",this.pendingLevel=0,this.cache=[],this.isInLabel=!1,this.linkLevel=0,this.linkContent=\"\",this.labelUnmatchedScopes=0}function D(e,t){var r,n,o,s=-1,i=e.posMax,a=e.pos,u=e.isInLabel;if(e.isInLabel)return-1;if(e.labelUnmatchedScopes)return e.labelUnmatchedScopes--,-1;for(e.pos=t+1,e.isInLabel=!0,r=1;e.pos<i;){if(91===(o=e.src.charCodeAt(e.pos)))r++;else if(93===o&&0===--r){n=!0;break}e.parser.skipToken(e)}return n?(s=e.pos,e.labelUnmatchedScopes=0):e.labelUnmatchedScopes=r-1,e.pos=a,e.isInLabel=u,s}function _(e,t,r,n){var o,s,i,a,u,l;if(42!==e.charCodeAt(0))return-1;if(91!==e.charCodeAt(1))return-1;if(-1===e.indexOf(\"]:\"))return-1;if((s=D(o=new E(e,t,r,n,[]),1))<0||58!==e.charCodeAt(s+1))return-1;for(a=o.posMax,i=s+2;i<a&&10!==o.src.charCodeAt(i);i++);return u=e.slice(2,s),0===(l=e.slice(s+2,i).trim()).length?-1:(n.abbreviations||(n.abbreviations={}),void 0===n.abbreviations[\":\"+u]&&(n.abbreviations[\":\"+u]=l),i)}function B(e){var t=g(e);try{t=decodeURI(t)}catch(e){}return encodeURI(t)}function q(e,t){var r,n,o,s=t,i=e.posMax;if(60===e.src.charCodeAt(t)){for(t++;t<i;){if(10===(r=e.src.charCodeAt(t)))return!1;if(62===r)return o=B(u(e.src.slice(s+1,t))),!!e.parser.validateLink(o)&&(e.pos=t+1,e.linkContent=o,!0);92===r&&t+1<i?t+=2:t++}return!1}for(n=0;t<i&&32!==(r=e.src.charCodeAt(t))&&!(r<32||127===r);)if(92===r&&t+1<i)t+=2;else{if(40===r&&++n>1)break;if(41===r&&--n<0)break;t++}return s!==t&&(o=u(e.src.slice(s,t)),!!e.parser.validateLink(o)&&(e.linkContent=o,e.pos=t,!0))}function F(e,t){var r,n=t,o=e.posMax,s=e.src.charCodeAt(t);if(34!==s&&39!==s&&40!==s)return!1;for(t++,40===s&&(s=41);t<o;){if((r=e.src.charCodeAt(t))===s)return e.pos=t+1,e.linkContent=u(e.src.slice(n+1,t)),!0;92===r&&t+1<o?t+=2:t++}return!1}function M(e){return e.trim().replace(/\\s+/g,\" \").toUpperCase()}function S(e,t,r,n){var o,s,i,a,u,l,c,p,h;if(91!==e.charCodeAt(0))return-1;if(-1===e.indexOf(\"]:\"))return-1;if((s=D(o=new E(e,t,r,n,[]),0))<0||58!==e.charCodeAt(s+1))return-1;for(a=o.posMax,i=s+2;i<a&&(32===(u=o.src.charCodeAt(i))||10===u);i++);if(!q(o,i))return-1;for(c=o.linkContent,l=i=o.pos,i+=1;i<a&&(32===(u=o.src.charCodeAt(i))||10===u);i++);for(i<a&&l!==i&&F(o,i)?(p=o.linkContent,i=o.pos):(p=\"\",i=l);i<a&&32===o.src.charCodeAt(i);)i++;return i<a&&10!==o.src.charCodeAt(i)?-1:(h=M(e.slice(1,s)),void 0===n.references[h]&&(n.references[h]={title:p,href:c}),i)}w.prototype.renderInline=function(e,t,r){for(var n=this.rules,o=e.length,s=0,i=\"\";o--;)i+=n[e[s].type](e,s++,t,r,this);return i},w.prototype.render=function(e,t,r){for(var n=this.rules,o=e.length,s=-1,i=\"\";++s<o;)\"inline\"===e[s].type?i+=this.renderInline(e[s].children,t,r):i+=n[e[s].type](e,s,t,r,this);return i},C.prototype.__find__=function(e){for(var t=this.__rules__.length,r=-1;t--;)if(this.__rules__[++r].name===e)return r;return-1},C.prototype.__compile__=function(){var e=this,t=[\"\"];e.__rules__.forEach(function(e){e.enabled&&e.alt.forEach(function(e){t.indexOf(e)<0&&t.push(e)})}),e.__cache__={},t.forEach(function(t){e.__cache__[t]=[],e.__rules__.forEach(function(r){r.enabled&&(t&&r.alt.indexOf(t)<0||e.__cache__[t].push(r.fn))})})},C.prototype.at=function(e,t,r){var n=this.__find__(e),o=r||{};if(-1===n)throw new Error(\"Parser rule not found: \"+e);this.__rules__[n].fn=t,this.__rules__[n].alt=o.alt||[],this.__cache__=null},C.prototype.before=function(e,t,r,n){var o=this.__find__(e),s=n||{};if(-1===o)throw new Error(\"Parser rule not found: \"+e);this.__rules__.splice(o,0,{name:t,enabled:!0,fn:r,alt:s.alt||[]}),this.__cache__=null},C.prototype.after=function(e,t,r,n){var o=this.__find__(e),s=n||{};if(-1===o)throw new Error(\"Parser rule not found: \"+e);this.__rules__.splice(o+1,0,{name:t,enabled:!0,fn:r,alt:s.alt||[]}),this.__cache__=null},C.prototype.push=function(e,t,r){var n=r||{};this.__rules__.push({name:e,enabled:!0,fn:t,alt:n.alt||[]}),this.__cache__=null},C.prototype.enable=function(e,t){e=Array.isArray(e)?e:[e],t&&this.__rules__.forEach(function(e){e.enabled=!1}),e.forEach(function(e){var t=this.__find__(e);if(t<0)throw new Error(\"Rules manager: invalid rule name \"+e);this.__rules__[t].enabled=!0},this),this.__cache__=null},C.prototype.disable=function(e){(e=Array.isArray(e)?e:[e]).forEach(function(e){var t=this.__find__(e);if(t<0)throw new Error(\"Rules manager: invalid rule name \"+e);this.__rules__[t].enabled=!1},this),this.__cache__=null},C.prototype.getRules=function(e){return null===this.__cache__&&this.__compile__(),this.__cache__[e]||[]},E.prototype.pushPending=function(){this.tokens.push({type:\"text\",content:this.pending,level:this.pendingLevel}),this.pending=\"\"},E.prototype.push=function(e){this.pending&&this.pushPending(),this.tokens.push(e),this.pendingLevel=this.level},E.prototype.cacheSet=function(e,t){for(var r=this.cache.length;r<=e;r++)this.cache.push(0);this.cache[e]=t},E.prototype.cacheGet=function(e){return e<this.cache.length?this.cache[e]:0};var T=\" \\n()[]'\\\".,!?-\";function L(e){return e.replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g,\"\\\\$1\")}var R=/\\+-|\\.\\.|\\?\\?\\?\\?|!!!!|,,|--/,N=/\\((c|tm|r|p)\\)/gi,z={c:\"©\",r:\"®\",p:\"§\",tm:\"™\"};var P=/['\"]/,j=/['\"]/g,I=/[-\\s()\\[\\]]/,O=\"’\";function U(e,t){return!(t<0||t>=e.length)&&!I.test(e[t])}function H(e,t,r){return e.substr(0,t)+r+e.substr(t+1)}var V=[[\"block\",function(e){e.inlineMode?e.tokens.push({type:\"inline\",content:e.src.replace(/\\n/g,\" \").trim(),level:0,lines:[0,1],children:[]}):e.block.parse(e.src,e.options,e.env,e.tokens)}],[\"abbr\",function(e){var t,r,n,o,s=e.tokens;if(!e.inlineMode)for(t=1,r=s.length-1;t<r;t++)if(\"paragraph_open\"===s[t-1].type&&\"inline\"===s[t].type&&\"paragraph_close\"===s[t+1].type){for(n=s[t].content;n.length&&!((o=_(n,e.inline,e.options,e.env))<0);)n=n.slice(o).trim();s[t].content=n,n.length||(s[t-1].tight=!0,s[t+1].tight=!0)}}],[\"references\",function(e){var t,r,n,o,s=e.tokens;if(e.env.references=e.env.references||{},!e.inlineMode)for(t=1,r=s.length-1;t<r;t++)if(\"inline\"===s[t].type&&\"paragraph_open\"===s[t-1].type&&\"paragraph_close\"===s[t+1].type){for(n=s[t].content;n.length&&!((o=S(n,e.inline,e.options,e.env))<0);)n=n.slice(o).trim();s[t].content=n,n.length||(s[t-1].tight=!0,s[t+1].tight=!0)}}],[\"inline\",function(e){var t,r,n,o=e.tokens;for(r=0,n=o.length;r<n;r++)\"inline\"===(t=o[r]).type&&e.inline.parse(t.content,e.options,e.env,t.children)}],[\"footnote_tail\",function(e){var t,r,n,o,s,i,a,u,l,c=0,p=!1,h={};if(e.env.footnotes&&(e.tokens=e.tokens.filter(function(e){return\"footnote_reference_open\"===e.type?(p=!0,u=[],l=e.label,!1):\"footnote_reference_close\"===e.type?(p=!1,h[\":\"+l]=u,!1):(p&&u.push(e),!p)}),e.env.footnotes.list)){for(i=e.env.footnotes.list,e.tokens.push({type:\"footnote_block_open\",level:c++}),t=0,r=i.length;t<r;t++){for(e.tokens.push({type:\"footnote_open\",id:t,level:c++}),i[t].tokens?((a=[]).push({type:\"paragraph_open\",tight:!1,level:c++}),a.push({type:\"inline\",content:\"\",level:c,children:i[t].tokens}),a.push({type:\"paragraph_close\",tight:!1,level:--c})):i[t].label&&(a=h[\":\"+i[t].label]),e.tokens=e.tokens.concat(a),s=\"paragraph_close\"===e.tokens[e.tokens.length-1].type?e.tokens.pop():null,o=i[t].count>0?i[t].count:1,n=0;n<o;n++)e.tokens.push({type:\"footnote_anchor\",id:t,subId:n,level:c});s&&e.tokens.push(s),e.tokens.push({type:\"footnote_close\",level:--c})}e.tokens.push({type:\"footnote_block_close\",level:--c})}}],[\"abbr2\",function(e){var t,r,n,o,s,i,a,u,l,c,p,h,f=e.tokens;if(e.env.abbreviations)for(e.env.abbrRegExp||(h=\"(^|[\"+T.split(\"\").map(L).join(\"\")+\"])(\"+Object.keys(e.env.abbreviations).map(function(e){return e.substr(1)}).sort(function(e,t){return t.length-e.length}).map(L).join(\"|\")+\")($|[\"+T.split(\"\").map(L).join(\"\")+\"])\",e.env.abbrRegExp=new RegExp(h,\"g\")),c=e.env.abbrRegExp,r=0,n=f.length;r<n;r++)if(\"inline\"===f[r].type)for(t=(o=f[r].children).length-1;t>=0;t--)if(\"text\"===(s=o[t]).type){for(u=0,i=s.content,c.lastIndex=0,l=s.level,a=[];p=c.exec(i);)c.lastIndex>u&&a.push({type:\"text\",content:i.slice(u,p.index+p[1].length),level:l}),a.push({type:\"abbr_open\",title:e.env.abbreviations[\":\"+p[2]],level:l++}),a.push({type:\"text\",content:p[2],level:l}),a.push({type:\"abbr_close\",level:--l}),u=c.lastIndex-p[3].length;a.length&&(u<i.length&&a.push({type:\"text\",content:i.slice(u),level:l}),f[r].children=o=[].concat(o.slice(0,t),a,o.slice(t+1)))}}],[\"replacements\",function(e){var t,r,n,o,s,i;if(e.options.typographer)for(s=e.tokens.length-1;s>=0;s--)if(\"inline\"===e.tokens[s].type)for(t=(o=e.tokens[s].children).length-1;t>=0;t--)\"text\"===(r=o[t]).type&&(n=r.content,n=(i=n).indexOf(\"(\")<0?i:i.replace(N,function(e,t){return z[t.toLowerCase()]}),R.test(n)&&(n=n.replace(/\\+-/g,\"±\").replace(/\\.{2,}/g,\"…\").replace(/([?!])…/g,\"$1..\").replace(/([?!]){4,}/g,\"$1$1$1\").replace(/,{2,}/g,\",\").replace(/(^|[^-])---([^-]|$)/gm,\"$1—$2\").replace(/(^|\\s)--(\\s|$)/gm,\"$1–$2\").replace(/(^|[^-\\s])--([^-\\s]|$)/gm,\"$1–$2\")),r.content=n)}],[\"smartquotes\",function(e){var t,r,n,o,s,i,a,u,l,c,p,h,f,g,d,m,b;if(e.options.typographer)for(b=[],d=e.tokens.length-1;d>=0;d--)if(\"inline\"===e.tokens[d].type)for(m=e.tokens[d].children,b.length=0,t=0;t<m.length;t++)if(\"text\"===(r=m[t]).type&&!P.test(r.text)){for(a=m[t].level,f=b.length-1;f>=0&&!(b[f].level<=a);f--);b.length=f+1,s=0,i=(n=r.content).length;e:for(;s<i&&(j.lastIndex=s,o=j.exec(n));)if(u=!U(n,o.index-1),s=o.index+1,g=\"'\"===o[0],(l=!U(n,s))||u){if(p=!l,h=!u)for(f=b.length-1;f>=0&&(c=b[f],!(b[f].level<a));f--)if(c.single===g&&b[f].level===a){c=b[f],g?(m[c.token].content=H(m[c.token].content,c.pos,e.options.quotes[2]),r.content=H(r.content,o.index,e.options.quotes[3])):(m[c.token].content=H(m[c.token].content,c.pos,e.options.quotes[0]),r.content=H(r.content,o.index,e.options.quotes[1])),b.length=f;continue e}p?b.push({token:t,pos:o.index,single:g,level:a}):h&&g&&(r.content=H(r.content,o.index,O))}else g&&(r.content=H(r.content,o.index,O))}}]];function G(){this.options={},this.ruler=new C;for(var e=0;e<V.length;e++)this.ruler.push(V[e][0],V[e][1])}function $(e,t,r,n,o){var s,i,a,u,l,c,p;for(this.src=e,this.parser=t,this.options=r,this.env=n,this.tokens=o,this.bMarks=[],this.eMarks=[],this.tShift=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.parentType=\"root\",this.ddIndent=-1,this.level=0,this.result=\"\",c=0,p=!1,a=u=c=0,l=(i=this.src).length;u<l;u++){if(s=i.charCodeAt(u),!p){if(32===s){c++;continue}p=!0}10!==s&&u!==l-1||(10!==s&&u++,this.bMarks.push(a),this.eMarks.push(u),this.tShift.push(c),p=!1,c=0,a=u+1)}this.bMarks.push(i.length),this.eMarks.push(i.length),this.tShift.push(0),this.lineMax=this.bMarks.length-1}function Z(e,t){var r,n,o;return(n=e.bMarks[t]+e.tShift[t])>=(o=e.eMarks[t])?-1:42!==(r=e.src.charCodeAt(n++))&&45!==r&&43!==r?-1:n<o&&32!==e.src.charCodeAt(n)?-1:n}function W(e,t){var r,n=e.bMarks[t]+e.tShift[t],o=e.eMarks[t];if(n+1>=o)return-1;if((r=e.src.charCodeAt(n++))<48||r>57)return-1;for(;;){if(n>=o)return-1;if(!((r=e.src.charCodeAt(n++))>=48&&r<=57)){if(41===r||46===r)break;return-1}}return n<o&&32!==e.src.charCodeAt(n)?-1:n}G.prototype.process=function(e){var t,r,n;for(t=0,r=(n=this.ruler.getRules(\"\")).length;t<r;t++)n[t](e)},$.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},$.prototype.skipEmptyLines=function(e){for(var t=this.lineMax;e<t&&!(this.bMarks[e]+this.tShift[e]<this.eMarks[e]);e++);return e},$.prototype.skipSpaces=function(e){for(var t=this.src.length;e<t&&32===this.src.charCodeAt(e);e++);return e},$.prototype.skipChars=function(e,t){for(var r=this.src.length;e<r&&this.src.charCodeAt(e)===t;e++);return e},$.prototype.skipCharsBack=function(e,t,r){if(e<=r)return e;for(;e>r;)if(t!==this.src.charCodeAt(--e))return e+1;return e},$.prototype.getLines=function(e,t,r,n){var o,s,i,a,u,l=e;if(e>=t)return\"\";if(l+1===t)return s=this.bMarks[l]+Math.min(this.tShift[l],r),i=n?this.eMarks[l]+1:this.eMarks[l],this.src.slice(s,i);for(a=new Array(t-e),o=0;l<t;l++,o++)(u=this.tShift[l])>r&&(u=r),u<0&&(u=0),s=this.bMarks[l]+u,i=l+1<t||n?this.eMarks[l]+1:this.eMarks[l],a[o]=this.src.slice(s,i);return a.join(\"\")};var J={};[\"article\",\"aside\",\"button\",\"blockquote\",\"body\",\"canvas\",\"caption\",\"col\",\"colgroup\",\"dd\",\"div\",\"dl\",\"dt\",\"embed\",\"fieldset\",\"figcaption\",\"figure\",\"footer\",\"form\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"header\",\"hgroup\",\"hr\",\"iframe\",\"li\",\"map\",\"object\",\"ol\",\"output\",\"p\",\"pre\",\"progress\",\"script\",\"section\",\"style\",\"table\",\"tbody\",\"td\",\"textarea\",\"tfoot\",\"th\",\"tr\",\"thead\",\"ul\",\"video\"].forEach(function(e){J[e]=!0});var Y=/^<([a-zA-Z]{1,15})[\\s\\/>]/,K=/^<\\/([a-zA-Z]{1,15})[\\s>]/;function Q(e,t){var r=e.bMarks[t]+e.blkIndent,n=e.eMarks[t];return e.src.substr(r,n-r)}function X(e,t){var r,n,o=e.bMarks[t]+e.tShift[t],s=e.eMarks[t];return o>=s?-1:126!==(n=e.src.charCodeAt(o++))&&58!==n?-1:o===(r=e.skipSpaces(o))?-1:r>=s?-1:r}var ee=[[\"code\",function(e,t,r){var n,o;if(e.tShift[t]-e.blkIndent<4)return!1;for(o=n=t+1;n<r;)if(e.isEmpty(n))n++;else{if(!(e.tShift[n]-e.blkIndent>=4))break;o=++n}return e.line=n,e.tokens.push({type:\"code\",content:e.getLines(t,o,4+e.blkIndent,!0),block:!0,lines:[t,e.line],level:e.level}),!0}],[\"fences\",function(e,t,r,n){var o,s,i,a,u,l=!1,c=e.bMarks[t]+e.tShift[t],p=e.eMarks[t];if(c+3>p)return!1;if(126!==(o=e.src.charCodeAt(c))&&96!==o)return!1;if(u=c,(s=(c=e.skipChars(c,o))-u)<3)return!1;if((i=e.src.slice(c,p).trim()).indexOf(\"`\")>=0)return!1;if(n)return!0;for(a=t;!(++a>=r||(c=u=e.bMarks[a]+e.tShift[a])<(p=e.eMarks[a])&&e.tShift[a]<e.blkIndent);)if(e.src.charCodeAt(c)===o&&!(e.tShift[a]-e.blkIndent>=4||(c=e.skipChars(c,o))-u<s||(c=e.skipSpaces(c))<p)){l=!0;break}return s=e.tShift[t],e.line=a+(l?1:0),e.tokens.push({type:\"fence\",params:i,content:e.getLines(t+1,a,s,!0),lines:[t,e.line],level:e.level}),!0},[\"paragraph\",\"blockquote\",\"list\"]],[\"blockquote\",function(e,t,r,n){var o,s,i,a,u,l,c,p,h,f,g,d=e.bMarks[t]+e.tShift[t],m=e.eMarks[t];if(d>m)return!1;if(62!==e.src.charCodeAt(d++))return!1;if(e.level>=e.options.maxNesting)return!1;if(n)return!0;for(32===e.src.charCodeAt(d)&&d++,u=e.blkIndent,e.blkIndent=0,a=[e.bMarks[t]],e.bMarks[t]=d,s=(d=d<m?e.skipSpaces(d):d)>=m,i=[e.tShift[t]],e.tShift[t]=d-e.bMarks[t],p=e.parser.ruler.getRules(\"blockquote\"),o=t+1;o<r&&!((d=e.bMarks[o]+e.tShift[o])>=(m=e.eMarks[o]));o++)if(62!==e.src.charCodeAt(d++)){if(s)break;for(g=!1,h=0,f=p.length;h<f;h++)if(p[h](e,o,r,!0)){g=!0;break}if(g)break;a.push(e.bMarks[o]),i.push(e.tShift[o]),e.tShift[o]=-1337}else 32===e.src.charCodeAt(d)&&d++,a.push(e.bMarks[o]),e.bMarks[o]=d,s=(d=d<m?e.skipSpaces(d):d)>=m,i.push(e.tShift[o]),e.tShift[o]=d-e.bMarks[o];for(l=e.parentType,e.parentType=\"blockquote\",e.tokens.push({type:\"blockquote_open\",lines:c=[t,0],level:e.level++}),e.parser.tokenize(e,t,o),e.tokens.push({type:\"blockquote_close\",level:--e.level}),e.parentType=l,c[1]=e.line,h=0;h<i.length;h++)e.bMarks[h+t]=a[h],e.tShift[h+t]=i[h];return e.blkIndent=u,!0},[\"paragraph\",\"blockquote\",\"list\"]],[\"hr\",function(e,t,r,n){var o,s,i,a=e.bMarks[t],u=e.eMarks[t];if((a+=e.tShift[t])>u)return!1;if(42!==(o=e.src.charCodeAt(a++))&&45!==o&&95!==o)return!1;for(s=1;a<u;){if((i=e.src.charCodeAt(a++))!==o&&32!==i)return!1;i===o&&s++}return!(s<3||!n&&(e.line=t+1,e.tokens.push({type:\"hr\",lines:[t,e.line],level:e.level}),0))},[\"paragraph\",\"blockquote\",\"list\"]],[\"list\",function(e,t,r,n){var o,s,i,a,u,l,c,p,h,f,g,d,m,b,v,k,A,y,x,w,C,E=!0;if((p=W(e,t))>=0)d=!0;else{if(!((p=Z(e,t))>=0))return!1;d=!1}if(e.level>=e.options.maxNesting)return!1;if(g=e.src.charCodeAt(p-1),n)return!0;for(b=e.tokens.length,d?(c=e.bMarks[t]+e.tShift[t],f=Number(e.src.substr(c,p-c-1)),e.tokens.push({type:\"ordered_list_open\",order:f,lines:k=[t,0],level:e.level++})):e.tokens.push({type:\"bullet_list_open\",lines:k=[t,0],level:e.level++}),o=t,v=!1,y=e.parser.ruler.getRules(\"list\");!(!(o<r)||((h=(m=e.skipSpaces(p))>=e.eMarks[o]?1:m-p)>4&&(h=1),h<1&&(h=1),s=p-e.bMarks[o]+h,e.tokens.push({type:\"list_item_open\",lines:A=[t,0],level:e.level++}),a=e.blkIndent,u=e.tight,i=e.tShift[t],l=e.parentType,e.tShift[t]=m-e.bMarks[t],e.blkIndent=s,e.tight=!0,e.parentType=\"list\",e.parser.tokenize(e,t,r,!0),e.tight&&!v||(E=!1),v=e.line-t>1&&e.isEmpty(e.line-1),e.blkIndent=a,e.tShift[t]=i,e.tight=u,e.parentType=l,e.tokens.push({type:\"list_item_close\",level:--e.level}),o=t=e.line,A[1]=o,m=e.bMarks[t],o>=r)||e.isEmpty(o)||e.tShift[o]<e.blkIndent);){for(C=!1,x=0,w=y.length;x<w;x++)if(y[x](e,o,r,!0)){C=!0;break}if(C)break;if(d){if((p=W(e,o))<0)break}else if((p=Z(e,o))<0)break;if(g!==e.src.charCodeAt(p-1))break}return e.tokens.push({type:d?\"ordered_list_close\":\"bullet_list_close\",level:--e.level}),k[1]=o,e.line=o,E&&function(e,t){var r,n,o=e.level+2;for(r=t+2,n=e.tokens.length-2;r<n;r++)e.tokens[r].level===o&&\"paragraph_open\"===e.tokens[r].type&&(e.tokens[r+2].tight=!0,e.tokens[r].tight=!0,r+=2)}(e,b),!0},[\"paragraph\",\"blockquote\"]],[\"footnote\",function(e,t,r,n){var o,s,i,a,u,l=e.bMarks[t]+e.tShift[t],c=e.eMarks[t];if(l+4>c)return!1;if(91!==e.src.charCodeAt(l))return!1;if(94!==e.src.charCodeAt(l+1))return!1;if(e.level>=e.options.maxNesting)return!1;for(a=l+2;a<c;a++){if(32===e.src.charCodeAt(a))return!1;if(93===e.src.charCodeAt(a))break}return!(a===l+2||a+1>=c||58!==e.src.charCodeAt(++a)||!n&&(a++,e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.refs||(e.env.footnotes.refs={}),u=e.src.slice(l+2,a-2),e.env.footnotes.refs[\":\"+u]=-1,e.tokens.push({type:\"footnote_reference_open\",label:u,level:e.level++}),o=e.bMarks[t],s=e.tShift[t],i=e.parentType,e.tShift[t]=e.skipSpaces(a)-a,e.bMarks[t]=a,e.blkIndent+=4,e.parentType=\"footnote\",e.tShift[t]<e.blkIndent&&(e.tShift[t]+=e.blkIndent,e.bMarks[t]-=e.blkIndent),e.parser.tokenize(e,t,r,!0),e.parentType=i,e.blkIndent-=4,e.tShift[t]=s,e.bMarks[t]=o,e.tokens.push({type:\"footnote_reference_close\",level:--e.level}),0))},[\"paragraph\"]],[\"heading\",function(e,t,r,n){var o,s,i,a=e.bMarks[t]+e.tShift[t],u=e.eMarks[t];if(a>=u)return!1;if(35!==(o=e.src.charCodeAt(a))||a>=u)return!1;for(s=1,o=e.src.charCodeAt(++a);35===o&&a<u&&s<=6;)s++,o=e.src.charCodeAt(++a);return!(s>6||a<u&&32!==o||!n&&(u=e.skipCharsBack(u,32,a),(i=e.skipCharsBack(u,35,a))>a&&32===e.src.charCodeAt(i-1)&&(u=i),e.line=t+1,e.tokens.push({type:\"heading_open\",hLevel:s,lines:[t,e.line],level:e.level}),a<u&&e.tokens.push({type:\"inline\",content:e.src.slice(a,u).trim(),level:e.level+1,lines:[t,e.line],children:[]}),e.tokens.push({type:\"heading_close\",hLevel:s,level:e.level}),0))},[\"paragraph\",\"blockquote\"]],[\"lheading\",function(e,t,r){var n,o,s,i=t+1;return!(i>=r||e.tShift[i]<e.blkIndent||e.tShift[i]-e.blkIndent>3||(o=e.bMarks[i]+e.tShift[i])>=(s=e.eMarks[i])||45!==(n=e.src.charCodeAt(o))&&61!==n||(o=e.skipChars(o,n),(o=e.skipSpaces(o))<s||(o=e.bMarks[t]+e.tShift[t],e.line=i+1,e.tokens.push({type:\"heading_open\",hLevel:61===n?1:2,lines:[t,e.line],level:e.level}),e.tokens.push({type:\"inline\",content:e.src.slice(o,e.eMarks[t]).trim(),level:e.level+1,lines:[t,e.line-1],children:[]}),e.tokens.push({type:\"heading_close\",hLevel:61===n?1:2,level:e.level}),0)))}],[\"htmlblock\",function(e,t,r,n){var o,s,i,a=e.bMarks[t],u=e.eMarks[t],l=e.tShift[t];if(a+=l,!e.options.html)return!1;if(l>3||a+2>=u)return!1;if(60!==e.src.charCodeAt(a))return!1;if(33===(o=e.src.charCodeAt(a+1))||63===o){if(n)return!0}else{if(47!==o&&!function(e){var t=32|e;return t>=97&&t<=122}(o))return!1;if(47===o){if(!(s=e.src.slice(a,u).match(K)))return!1}else if(!(s=e.src.slice(a,u).match(Y)))return!1;if(!0!==J[s[1].toLowerCase()])return!1;if(n)return!0}for(i=t+1;i<e.lineMax&&!e.isEmpty(i);)i++;return e.line=i,e.tokens.push({type:\"htmlblock\",level:e.level,lines:[t,e.line],content:e.getLines(t,i,0,!0)}),!0},[\"paragraph\",\"blockquote\"]],[\"table\",function(e,t,r,n){var o,s,i,a,u,l,c,p,h,f,g;if(t+2>r)return!1;if(u=t+1,e.tShift[u]<e.blkIndent)return!1;if((i=e.bMarks[u]+e.tShift[u])>=e.eMarks[u])return!1;if(124!==(o=e.src.charCodeAt(i))&&45!==o&&58!==o)return!1;if(s=Q(e,t+1),!/^[-:| ]+$/.test(s))return!1;if((l=s.split(\"|\"))<=2)return!1;for(p=[],a=0;a<l.length;a++){if(!(h=l[a].trim())){if(0===a||a===l.length-1)continue;return!1}if(!/^:?-+:?$/.test(h))return!1;58===h.charCodeAt(h.length-1)?p.push(58===h.charCodeAt(0)?\"center\":\"right\"):58===h.charCodeAt(0)?p.push(\"left\"):p.push(\"\")}if(-1===(s=Q(e,t).trim()).indexOf(\"|\"))return!1;if(l=s.replace(/^\\||\\|$/g,\"\").split(\"|\"),p.length!==l.length)return!1;if(n)return!0;for(e.tokens.push({type:\"table_open\",lines:f=[t,0],level:e.level++}),e.tokens.push({type:\"thead_open\",lines:[t,t+1],level:e.level++}),e.tokens.push({type:\"tr_open\",lines:[t,t+1],level:e.level++}),a=0;a<l.length;a++)e.tokens.push({type:\"th_open\",align:p[a],lines:[t,t+1],level:e.level++}),e.tokens.push({type:\"inline\",content:l[a].trim(),lines:[t,t+1],level:e.level,children:[]}),e.tokens.push({type:\"th_close\",level:--e.level});for(e.tokens.push({type:\"tr_close\",level:--e.level}),e.tokens.push({type:\"thead_close\",level:--e.level}),e.tokens.push({type:\"tbody_open\",lines:g=[t+2,0],level:e.level++}),u=t+2;u<r&&!(e.tShift[u]<e.blkIndent)&&-1!==(s=Q(e,u).trim()).indexOf(\"|\");u++){for(l=s.replace(/^\\||\\|$/g,\"\").split(\"|\"),e.tokens.push({type:\"tr_open\",level:e.level++}),a=0;a<l.length;a++)e.tokens.push({type:\"td_open\",align:p[a],level:e.level++}),c=l[a].substring(124===l[a].charCodeAt(0)?1:0,124===l[a].charCodeAt(l[a].length-1)?l[a].length-1:l[a].length).trim(),e.tokens.push({type:\"inline\",content:c,level:e.level,children:[]}),e.tokens.push({type:\"td_close\",level:--e.level});e.tokens.push({type:\"tr_close\",level:--e.level})}return e.tokens.push({type:\"tbody_close\",level:--e.level}),e.tokens.push({type:\"table_close\",level:--e.level}),f[1]=g[1]=u,e.line=u,!0},[\"paragraph\"]],[\"deflist\",function(e,t,r,n){var o,s,i,a,u,l,c,p,h,f,g,d,m,b;if(n)return!(e.ddIndent<0)&&X(e,t)>=0;if(c=t+1,e.isEmpty(c)&&++c>r)return!1;if(e.tShift[c]<e.blkIndent)return!1;if((o=X(e,c))<0)return!1;if(e.level>=e.options.maxNesting)return!1;l=e.tokens.length,e.tokens.push({type:\"dl_open\",lines:u=[t,0],level:e.level++}),i=t,s=c;e:for(;;){for(b=!0,m=!1,e.tokens.push({type:\"dt_open\",lines:[i,i],level:e.level++}),e.tokens.push({type:\"inline\",content:e.getLines(i,i+1,e.blkIndent,!1).trim(),level:e.level+1,lines:[i,i],children:[]}),e.tokens.push({type:\"dt_close\",level:--e.level});;){if(e.tokens.push({type:\"dd_open\",lines:a=[c,0],level:e.level++}),d=e.tight,h=e.ddIndent,p=e.blkIndent,g=e.tShift[s],f=e.parentType,e.blkIndent=e.ddIndent=e.tShift[s]+2,e.tShift[s]=o-e.bMarks[s],e.tight=!0,e.parentType=\"deflist\",e.parser.tokenize(e,s,r,!0),e.tight&&!m||(b=!1),m=e.line-s>1&&e.isEmpty(e.line-1),e.tShift[s]=g,e.tight=d,e.parentType=f,e.blkIndent=p,e.ddIndent=h,e.tokens.push({type:\"dd_close\",level:--e.level}),a[1]=c=e.line,c>=r)break e;if(e.tShift[c]<e.blkIndent)break e;if((o=X(e,c))<0)break;s=c}if(c>=r)break;if(i=c,e.isEmpty(i))break;if(e.tShift[i]<e.blkIndent)break;if((s=i+1)>=r)break;if(e.isEmpty(s)&&s++,s>=r)break;if(e.tShift[s]<e.blkIndent)break;if((o=X(e,s))<0)break}return e.tokens.push({type:\"dl_close\",level:--e.level}),u[1]=c,e.line=c,b&&function(e,t){var r,n,o=e.level+2;for(r=t+2,n=e.tokens.length-2;r<n;r++)e.tokens[r].level===o&&\"paragraph_open\"===e.tokens[r].type&&(e.tokens[r+2].tight=!0,e.tokens[r].tight=!0,r+=2)}(e,l),!0},[\"paragraph\"]],[\"paragraph\",function(e,t){var r,n,o,s,i,a,u=t+1;if(u<(r=e.lineMax)&&!e.isEmpty(u))for(a=e.parser.ruler.getRules(\"paragraph\");u<r&&!e.isEmpty(u);u++)if(!(e.tShift[u]-e.blkIndent>3)){for(o=!1,s=0,i=a.length;s<i;s++)if(a[s](e,u,r,!0)){o=!0;break}if(o)break}return n=e.getLines(t,u,e.blkIndent,!1).trim(),e.line=u,n.length&&(e.tokens.push({type:\"paragraph_open\",tight:!1,lines:[t,e.line],level:e.level}),e.tokens.push({type:\"inline\",content:n,level:e.level+1,lines:[t,e.line],children:[]}),e.tokens.push({type:\"paragraph_close\",tight:!1,level:e.level})),!0}]];function te(){this.ruler=new C;for(var e=0;e<ee.length;e++)this.ruler.push(ee[e][0],ee[e][1],{alt:(ee[e][2]||[]).slice()})}te.prototype.tokenize=function(e,t,r){for(var n,o=this.ruler.getRules(\"\"),s=o.length,i=t,a=!1;i<r&&(e.line=i=e.skipEmptyLines(i),!(i>=r))&&!(e.tShift[i]<e.blkIndent);){for(n=0;n<s&&!o[n](e,i,r,!1);n++);if(e.tight=!a,e.isEmpty(e.line-1)&&(a=!0),(i=e.line)<r&&e.isEmpty(i)){if(a=!0,++i<r&&\"list\"===e.parentType&&e.isEmpty(i))break;e.line=i}}};var re=/[\\n\\t]/g,ne=/\\r[\\n\\u0085]|[\\u2424\\u2028\\u0085]/g,oe=/\\u00a0/g;function se(e){switch(e){case 10:case 92:case 96:case 42:case 95:case 94:case 91:case 93:case 33:case 38:case 60:case 62:case 123:case 125:case 36:case 37:case 64:case 126:case 43:case 61:case 58:return!0;default:return!1}}te.prototype.parse=function(e,t,r,n){var o,s=0,i=0;if(!e)return[];(e=(e=e.replace(oe,\" \")).replace(ne,\"\\n\")).indexOf(\"\\t\")>=0&&(e=e.replace(re,function(t,r){var n;return 10===e.charCodeAt(r)?(s=r+1,i=0,t):(n=\" \".slice((r-s-i)%4),i=r-s+1,n)})),o=new $(e,this,t,r,n),this.tokenize(o,o.line,o.lineMax)};for(var ie=[],ae=0;ae<256;ae++)ie.push(0);function ue(e){return e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122}function le(e,t){var r,n,o,s=t,i=!0,a=!0,u=e.posMax,l=e.src.charCodeAt(t);for(r=t>0?e.src.charCodeAt(t-1):-1;s<u&&e.src.charCodeAt(s)===l;)s++;return s>=u&&(i=!1),(o=s-t)>=4?i=a=!1:(32!==(n=s<u?e.src.charCodeAt(s):-1)&&10!==n||(i=!1),32!==r&&10!==r||(a=!1),95===l&&(ue(r)&&(i=!1),ue(n)&&(a=!1))),{can_open:i,can_close:a,delims:o}}\"\\\\!\\\"#$%&'()*+,./:;<=>?@[]^_`{|}~-\".split(\"\").forEach(function(e){ie[e.charCodeAt(0)]=1});var ce=/\\\\([ \\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;var pe=/\\\\([ \\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;var he=[\"coap\",\"doi\",\"javascript\",\"aaa\",\"aaas\",\"about\",\"acap\",\"cap\",\"cid\",\"crid\",\"data\",\"dav\",\"dict\",\"dns\",\"file\",\"ftp\",\"geo\",\"go\",\"gopher\",\"h323\",\"http\",\"https\",\"iax\",\"icap\",\"im\",\"imap\",\"info\",\"ipp\",\"iris\",\"iris.beep\",\"iris.xpc\",\"iris.xpcs\",\"iris.lwz\",\"ldap\",\"mailto\",\"mid\",\"msrp\",\"msrps\",\"mtqp\",\"mupdate\",\"news\",\"nfs\",\"ni\",\"nih\",\"nntp\",\"opaquelocktoken\",\"pop\",\"pres\",\"rtsp\",\"service\",\"session\",\"shttp\",\"sieve\",\"sip\",\"sips\",\"sms\",\"snmp\",\"soap.beep\",\"soap.beeps\",\"tag\",\"tel\",\"telnet\",\"tftp\",\"thismessage\",\"tn3270\",\"tip\",\"tv\",\"urn\",\"vemmi\",\"ws\",\"wss\",\"xcon\",\"xcon-userid\",\"xmlrpc.beep\",\"xmlrpc.beeps\",\"xmpp\",\"z39.50r\",\"z39.50s\",\"adiumxtra\",\"afp\",\"afs\",\"aim\",\"apt\",\"attachment\",\"aw\",\"beshare\",\"bitcoin\",\"bolo\",\"callto\",\"chrome\",\"chrome-extension\",\"com-eventbrite-attendee\",\"content\",\"cvs\",\"dlna-playsingle\",\"dlna-playcontainer\",\"dtn\",\"dvb\",\"ed2k\",\"facetime\",\"feed\",\"finger\",\"fish\",\"gg\",\"git\",\"gizmoproject\",\"gtalk\",\"hcp\",\"icon\",\"ipn\",\"irc\",\"irc6\",\"ircs\",\"itms\",\"jar\",\"jms\",\"keyparc\",\"lastfm\",\"ldaps\",\"magnet\",\"maps\",\"market\",\"message\",\"mms\",\"ms-help\",\"msnim\",\"mumble\",\"mvn\",\"notes\",\"oid\",\"palm\",\"paparazzi\",\"platform\",\"proxy\",\"psyc\",\"query\",\"res\",\"resource\",\"rmi\",\"rsync\",\"rtmp\",\"secondlife\",\"sftp\",\"sgn\",\"skype\",\"smb\",\"soldat\",\"spotify\",\"ssh\",\"steam\",\"svn\",\"teamspeak\",\"things\",\"udp\",\"unreal\",\"ut2004\",\"ventrilo\",\"view-source\",\"webcal\",\"wtai\",\"wyciwyg\",\"xfire\",\"xri\",\"ymsgr\"],fe=/^<([a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/,ge=/^<([a-zA-Z.\\-]{1,25}):([^<>\\x00-\\x20]*)>/;function de(e,t){return e=e.source,t=t||\"\",function r(n,o){return n?(o=o.source||o,e=e.replace(n,o),r):new RegExp(e,t)}}var me=de(/(?:unquoted|single_quoted|double_quoted)/)(\"unquoted\",/[^\"'=<>`\\x00-\\x20]+/)(\"single_quoted\",/'[^']*'/)(\"double_quoted\",/\"[^\"]*\"/)(),be=de(/(?:\\s+attr_name(?:\\s*=\\s*attr_value)?)/)(\"attr_name\",/[a-zA-Z_:][a-zA-Z0-9:._-]*/)(\"attr_value\",me)(),ve=de(/<[A-Za-z][A-Za-z0-9]*attribute*\\s*\\/?>/)(\"attribute\",be)(),ke=de(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)(\"open_tag\",ve)(\"close_tag\",/<\\/[A-Za-z][A-Za-z0-9]*\\s*>/)(\"comment\",/<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->/)(\"processing\",/<[?].*?[?]>/)(\"declaration\",/<![A-Z]+\\s+[^>]*>/)(\"cdata\",/<!\\[CDATA\\[[\\s\\S]*?\\]\\]>/)();var Ae=/^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,ye=/^&([a-z][a-z0-9]{1,31});/i;var xe=[[\"text\",function(e,t){for(var r=e.pos;r<e.posMax&&!se(e.src.charCodeAt(r));)r++;return r!==e.pos&&(t||(e.pending+=e.src.slice(e.pos,r)),e.pos=r,!0)}],[\"newline\",function(e,t){var r,n,o=e.pos;if(10!==e.src.charCodeAt(o))return!1;if(r=e.pending.length-1,n=e.posMax,!t)if(r>=0&&32===e.pending.charCodeAt(r))if(r>=1&&32===e.pending.charCodeAt(r-1)){for(var s=r-2;s>=0;s--)if(32!==e.pending.charCodeAt(s)){e.pending=e.pending.substring(0,s+1);break}e.push({type:\"hardbreak\",level:e.level})}else e.pending=e.pending.slice(0,-1),e.push({type:\"softbreak\",level:e.level});else e.push({type:\"softbreak\",level:e.level});for(o++;o<n&&32===e.src.charCodeAt(o);)o++;return e.pos=o,!0}],[\"escape\",function(e,t){var r,n=e.pos,o=e.posMax;if(92!==e.src.charCodeAt(n))return!1;if(++n<o){if((r=e.src.charCodeAt(n))<256&&0!==ie[r])return t||(e.pending+=e.src[n]),e.pos+=2,!0;if(10===r){for(t||e.push({type:\"hardbreak\",level:e.level}),n++;n<o&&32===e.src.charCodeAt(n);)n++;return e.pos=n,!0}}return t||(e.pending+=\"\\\\\"),e.pos++,!0}],[\"backticks\",function(e,t){var r,n,o,s,i,a=e.pos;if(96!==e.src.charCodeAt(a))return!1;for(r=a,a++,n=e.posMax;a<n&&96===e.src.charCodeAt(a);)a++;for(o=e.src.slice(r,a),s=i=a;-1!==(s=e.src.indexOf(\"`\",i));){for(i=s+1;i<n&&96===e.src.charCodeAt(i);)i++;if(i-s===o.length)return t||e.push({type:\"code\",content:e.src.slice(a,s).replace(/[ \\n]+/g,\" \").trim(),block:!1,level:e.level}),e.pos=i,!0}return t||(e.pending+=o),e.pos+=o.length,!0}],[\"del\",function(e,t){var r,n,o,s,i,a=e.posMax,u=e.pos;if(126!==e.src.charCodeAt(u))return!1;if(t)return!1;if(u+4>=a)return!1;if(126!==e.src.charCodeAt(u+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(s=u>0?e.src.charCodeAt(u-1):-1,i=e.src.charCodeAt(u+2),126===s)return!1;if(126===i)return!1;if(32===i||10===i)return!1;for(n=u+2;n<a&&126===e.src.charCodeAt(n);)n++;if(n>u+3)return e.pos+=n-u,t||(e.pending+=e.src.slice(u,n)),!0;for(e.pos=u+2,o=1;e.pos+1<a;){if(126===e.src.charCodeAt(e.pos)&&126===e.src.charCodeAt(e.pos+1)&&(s=e.src.charCodeAt(e.pos-1),126!==(i=e.pos+2<a?e.src.charCodeAt(e.pos+2):-1)&&126!==s&&(32!==s&&10!==s?o--:32!==i&&10!==i&&o++,o<=0))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=u+2,t||(e.push({type:\"del_open\",level:e.level++}),e.parser.tokenize(e),e.push({type:\"del_close\",level:--e.level})),e.pos=e.posMax+2,e.posMax=a,!0):(e.pos=u,!1)}],[\"ins\",function(e,t){var r,n,o,s,i,a=e.posMax,u=e.pos;if(43!==e.src.charCodeAt(u))return!1;if(t)return!1;if(u+4>=a)return!1;if(43!==e.src.charCodeAt(u+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(s=u>0?e.src.charCodeAt(u-1):-1,i=e.src.charCodeAt(u+2),43===s)return!1;if(43===i)return!1;if(32===i||10===i)return!1;for(n=u+2;n<a&&43===e.src.charCodeAt(n);)n++;if(n!==u+2)return e.pos+=n-u,t||(e.pending+=e.src.slice(u,n)),!0;for(e.pos=u+2,o=1;e.pos+1<a;){if(43===e.src.charCodeAt(e.pos)&&43===e.src.charCodeAt(e.pos+1)&&(s=e.src.charCodeAt(e.pos-1),43!==(i=e.pos+2<a?e.src.charCodeAt(e.pos+2):-1)&&43!==s&&(32!==s&&10!==s?o--:32!==i&&10!==i&&o++,o<=0))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=u+2,t||(e.push({type:\"ins_open\",level:e.level++}),e.parser.tokenize(e),e.push({type:\"ins_close\",level:--e.level})),e.pos=e.posMax+2,e.posMax=a,!0):(e.pos=u,!1)}],[\"mark\",function(e,t){var r,n,o,s,i,a=e.posMax,u=e.pos;if(61!==e.src.charCodeAt(u))return!1;if(t)return!1;if(u+4>=a)return!1;if(61!==e.src.charCodeAt(u+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(s=u>0?e.src.charCodeAt(u-1):-1,i=e.src.charCodeAt(u+2),61===s)return!1;if(61===i)return!1;if(32===i||10===i)return!1;for(n=u+2;n<a&&61===e.src.charCodeAt(n);)n++;if(n!==u+2)return e.pos+=n-u,t||(e.pending+=e.src.slice(u,n)),!0;for(e.pos=u+2,o=1;e.pos+1<a;){if(61===e.src.charCodeAt(e.pos)&&61===e.src.charCodeAt(e.pos+1)&&(s=e.src.charCodeAt(e.pos-1),61!==(i=e.pos+2<a?e.src.charCodeAt(e.pos+2):-1)&&61!==s&&(32!==s&&10!==s?o--:32!==i&&10!==i&&o++,o<=0))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=u+2,t||(e.push({type:\"mark_open\",level:e.level++}),e.parser.tokenize(e),e.push({type:\"mark_close\",level:--e.level})),e.pos=e.posMax+2,e.posMax=a,!0):(e.pos=u,!1)}],[\"emphasis\",function(e,t){var r,n,o,s,i,a,u,l=e.posMax,c=e.pos,p=e.src.charCodeAt(c);if(95!==p&&42!==p)return!1;if(t)return!1;if(r=(u=le(e,c)).delims,!u.can_open)return e.pos+=r,t||(e.pending+=e.src.slice(c,e.pos)),!0;if(e.level>=e.options.maxNesting)return!1;for(e.pos=c+r,a=[r];e.pos<l;)if(e.src.charCodeAt(e.pos)!==p)e.parser.skipToken(e);else{if(n=(u=le(e,e.pos)).delims,u.can_close){for(s=a.pop(),i=n;s!==i;){if(i<s){a.push(s-i);break}if(i-=s,0===a.length)break;e.pos+=s,s=a.pop()}if(0===a.length){r=s,o=!0;break}e.pos+=n;continue}u.can_open&&a.push(n),e.pos+=n}return o?(e.posMax=e.pos,e.pos=c+r,t||(2!==r&&3!==r||e.push({type:\"strong_open\",level:e.level++}),1!==r&&3!==r||e.push({type:\"em_open\",level:e.level++}),e.parser.tokenize(e),1!==r&&3!==r||e.push({type:\"em_close\",level:--e.level}),2!==r&&3!==r||e.push({type:\"strong_close\",level:--e.level})),e.pos=e.posMax+r,e.posMax=l,!0):(e.pos=c,!1)}],[\"sub\",function(e,t){var r,n,o=e.posMax,s=e.pos;if(126!==e.src.charCodeAt(s))return!1;if(t)return!1;if(s+2>=o)return!1;if(e.level>=e.options.maxNesting)return!1;for(e.pos=s+1;e.pos<o;){if(126===e.src.charCodeAt(e.pos)){r=!0;break}e.parser.skipToken(e)}return r&&s+1!==e.pos?(n=e.src.slice(s+1,e.pos)).match(/(^|[^\\\\])(\\\\\\\\)*\\s/)?(e.pos=s,!1):(e.posMax=e.pos,e.pos=s+1,t||e.push({type:\"sub\",level:e.level,content:n.replace(ce,\"$1\")}),e.pos=e.posMax+1,e.posMax=o,!0):(e.pos=s,!1)}],[\"sup\",function(e,t){var r,n,o=e.posMax,s=e.pos;if(94!==e.src.charCodeAt(s))return!1;if(t)return!1;if(s+2>=o)return!1;if(e.level>=e.options.maxNesting)return!1;for(e.pos=s+1;e.pos<o;){if(94===e.src.charCodeAt(e.pos)){r=!0;break}e.parser.skipToken(e)}return r&&s+1!==e.pos?(n=e.src.slice(s+1,e.pos)).match(/(^|[^\\\\])(\\\\\\\\)*\\s/)?(e.pos=s,!1):(e.posMax=e.pos,e.pos=s+1,t||e.push({type:\"sup\",level:e.level,content:n.replace(pe,\"$1\")}),e.pos=e.posMax+1,e.posMax=o,!0):(e.pos=s,!1)}],[\"links\",function(e,t){var r,n,o,s,i,a,u,l,c=!1,p=e.pos,h=e.posMax,f=e.pos,g=e.src.charCodeAt(f);if(33===g&&(c=!0,g=e.src.charCodeAt(++f)),91!==g)return!1;if(e.level>=e.options.maxNesting)return!1;if(r=f+1,(n=D(e,f))<0)return!1;if((a=n+1)<h&&40===e.src.charCodeAt(a)){for(a++;a<h&&(32===(l=e.src.charCodeAt(a))||10===l);a++);if(a>=h)return!1;for(f=a,q(e,a)?(s=e.linkContent,a=e.pos):s=\"\",f=a;a<h&&(32===(l=e.src.charCodeAt(a))||10===l);a++);if(a<h&&f!==a&&F(e,a))for(i=e.linkContent,a=e.pos;a<h&&(32===(l=e.src.charCodeAt(a))||10===l);a++);else i=\"\";if(a>=h||41!==e.src.charCodeAt(a))return e.pos=p,!1;a++}else{if(e.linkLevel>0)return!1;for(;a<h&&(32===(l=e.src.charCodeAt(a))||10===l);a++);if(a<h&&91===e.src.charCodeAt(a)&&(f=a+1,(a=D(e,a))>=0?o=e.src.slice(f,a++):a=f-1),o||(void 0===o&&(a=n+1),o=e.src.slice(r,n)),!(u=e.env.references[M(o)]))return e.pos=p,!1;s=u.href,i=u.title}return t||(e.pos=r,e.posMax=n,c?e.push({type:\"image\",src:s,title:i,alt:e.src.substr(r,n-r),level:e.level}):(e.push({type:\"link_open\",href:s,title:i,level:e.level++}),e.linkLevel++,e.parser.tokenize(e),e.linkLevel--,e.push({type:\"link_close\",level:--e.level}))),e.pos=a,e.posMax=h,!0}],[\"footnote_inline\",function(e,t){var r,n,o,s,i=e.posMax,a=e.pos;return!(a+2>=i||94!==e.src.charCodeAt(a)||91!==e.src.charCodeAt(a+1)||e.level>=e.options.maxNesting||(r=a+2,(n=D(e,a+1))<0||(t||(e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.list||(e.env.footnotes.list=[]),o=e.env.footnotes.list.length,e.pos=r,e.posMax=n,e.push({type:\"footnote_ref\",id:o,level:e.level}),e.linkLevel++,s=e.tokens.length,e.parser.tokenize(e),e.env.footnotes.list[o]={tokens:e.tokens.splice(s)},e.linkLevel--),e.pos=n+1,e.posMax=i,0)))}],[\"footnote_ref\",function(e,t){var r,n,o,s,i=e.posMax,a=e.pos;if(a+3>i)return!1;if(!e.env.footnotes||!e.env.footnotes.refs)return!1;if(91!==e.src.charCodeAt(a))return!1;if(94!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;for(n=a+2;n<i;n++){if(32===e.src.charCodeAt(n))return!1;if(10===e.src.charCodeAt(n))return!1;if(93===e.src.charCodeAt(n))break}return!(n===a+2||n>=i||(n++,r=e.src.slice(a+2,n-1),void 0===e.env.footnotes.refs[\":\"+r]||(t||(e.env.footnotes.list||(e.env.footnotes.list=[]),e.env.footnotes.refs[\":\"+r]<0?(o=e.env.footnotes.list.length,e.env.footnotes.list[o]={label:r,count:0},e.env.footnotes.refs[\":\"+r]=o):o=e.env.footnotes.refs[\":\"+r],s=e.env.footnotes.list[o].count,e.env.footnotes.list[o].count++,e.push({type:\"footnote_ref\",id:o,subId:s,level:e.level})),e.pos=n,e.posMax=i,0)))}],[\"autolink\",function(e,t){var r,n,o,s,i,a=e.pos;return!(60!==e.src.charCodeAt(a)||(r=e.src.slice(a)).indexOf(\">\")<0||((n=r.match(ge))?he.indexOf(n[1].toLowerCase())<0||(i=B(s=n[0].slice(1,-1)),!e.parser.validateLink(s)||(t||(e.push({type:\"link_open\",href:i,level:e.level}),e.push({type:\"text\",content:s,level:e.level+1}),e.push({type:\"link_close\",level:e.level})),e.pos+=n[0].length,0)):!(o=r.match(fe))||(i=B(\"mailto:\"+(s=o[0].slice(1,-1))),!e.parser.validateLink(i)||(t||(e.push({type:\"link_open\",href:i,level:e.level}),e.push({type:\"text\",content:s,level:e.level+1}),e.push({type:\"link_close\",level:e.level})),e.pos+=o[0].length,0))))}],[\"htmltag\",function(e,t){var r,n,o,s=e.pos;return!(!e.options.html||(o=e.posMax,60!==e.src.charCodeAt(s)||s+2>=o||33!==(r=e.src.charCodeAt(s+1))&&63!==r&&47!==r&&!function(e){var t=32|e;return t>=97&&t<=122}(r)||!(n=e.src.slice(s).match(ke))||(t||e.push({type:\"htmltag\",content:e.src.slice(s,s+n[0].length),level:e.level}),e.pos+=n[0].length,0)))}],[\"entity\",function(e,t){var r,o,s=e.pos,i=e.posMax;if(38!==e.src.charCodeAt(s))return!1;if(s+1<i)if(35===e.src.charCodeAt(s+1)){if(o=e.src.slice(s).match(Ae))return t||(r=\"x\"===o[1][0].toLowerCase()?parseInt(o[1].slice(1),16):parseInt(o[1],10),e.pending+=l(r)?c(r):c(65533)),e.pos+=o[0].length,!0}else if(o=e.src.slice(s).match(ye)){var a=n(o[1]);if(o[1]!==a)return t||(e.pending+=a),e.pos+=o[0].length,!0}return t||(e.pending+=\"&\"),e.pos++,!0}]];function we(){this.ruler=new C;for(var e=0;e<xe.length;e++)this.ruler.push(xe[e][0],xe[e][1]);this.validateLink=Ce}function Ce(e){var t=e.trim().toLowerCase();return-1===(t=g(t)).indexOf(\":\")||-1===[\"vbscript\",\"javascript\",\"file\",\"data\"].indexOf(t.split(\":\")[0])}we.prototype.skipToken=function(e){var t,r,n=this.ruler.getRules(\"\"),o=n.length,s=e.pos;if((r=e.cacheGet(s))>0)e.pos=r;else{for(t=0;t<o;t++)if(n[t](e,!0))return void e.cacheSet(s,e.pos);e.pos++,e.cacheSet(s,e.pos)}},we.prototype.tokenize=function(e){for(var t,r,n=this.ruler.getRules(\"\"),o=n.length,s=e.posMax;e.pos<s;){for(r=0;r<o&&!(t=n[r](e,!1));r++);if(t){if(e.pos>=s)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},we.prototype.parse=function(e,t,r,n){var o=new E(e,this,t,r,n);this.tokenize(o)};var Ee={default:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:\"language-\",linkTarget:\"\",typographer:!1,quotes:\"“”‘’\",highlight:null,maxNesting:20},components:{core:{rules:[\"block\",\"inline\",\"references\",\"replacements\",\"smartquotes\",\"references\",\"abbr2\",\"footnote_tail\"]},block:{rules:[\"blockquote\",\"code\",\"fences\",\"footnote\",\"heading\",\"hr\",\"htmlblock\",\"lheading\",\"list\",\"paragraph\",\"table\"]},inline:{rules:[\"autolink\",\"backticks\",\"del\",\"emphasis\",\"entity\",\"escape\",\"footnote_ref\",\"htmltag\",\"links\",\"newline\",\"text\"]}}},full:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:\"language-\",linkTarget:\"\",typographer:!1,quotes:\"“”‘’\",highlight:null,maxNesting:20},components:{core:{},block:{},inline:{}}},commonmark:{options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:\"language-\",linkTarget:\"\",typographer:!1,quotes:\"“”‘’\",highlight:null,maxNesting:20},components:{core:{rules:[\"block\",\"inline\",\"references\",\"abbr2\"]},block:{rules:[\"blockquote\",\"code\",\"fences\",\"heading\",\"hr\",\"htmlblock\",\"lheading\",\"list\",\"paragraph\"]},inline:{rules:[\"autolink\",\"backticks\",\"emphasis\",\"entity\",\"escape\",\"htmltag\",\"links\",\"newline\",\"text\"]}}}};function De(e,t,r){this.src=t,this.env=r,this.options=e.options,this.tokens=[],this.inlineMode=!1,this.inline=e.inline,this.block=e.block,this.renderer=e.renderer,this.typographer=e.typographer}function _e(e,t){\"string\"!=typeof e&&(t=e,e=\"default\"),t&&null!=t.linkify&&console.warn(\"linkify option is removed. Use linkify plugin instead:\\n\\nimport Remarkable from 'remarkable';\\nimport linkify from 'remarkable/linkify';\\nnew Remarkable().use(linkify)\\n\"),this.inline=new we,this.block=new te,this.core=new G,this.renderer=new w,this.ruler=new C,this.options={},this.configure(Ee[e]),this.set(t||{})}function Be(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,n=e.length;r<n;r++)if(e[r]===t)return r;return-1}function qe(e,t){for(var r=e.length-1;r>=0;r--)!0===t(e[r])&&e.splice(r,1)}function Fe(e){throw new Error(\"Unhandled case for value: '\"+e+\"'\")}_e.prototype.set=function(e){i(this.options,e)},_e.prototype.configure=function(e){var t=this;if(!e)throw new Error(\"Wrong `remarkable` preset, check name/content\");e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach(function(r){e.components[r].rules&&t[r].ruler.enable(e.components[r].rules,!0)})},_e.prototype.use=function(e,t){return e(this,t),this},_e.prototype.parse=function(e,t){var r=new De(this,e,t);return this.core.process(r),r.tokens},_e.prototype.render=function(e,t){return t=t||{},this.renderer.render(this.parse(e,t),this.options,t)},_e.prototype.parseInline=function(e,t){var r=new De(this,e,t);return r.inlineMode=!0,this.core.process(r),r.tokens},_e.prototype.renderInline=function(e,t){return t=t||{},this.renderer.render(this.parseInline(e,t),this.options,t)};var Me=function(){function e(e){void 0===e&&(e={}),this.tagName=\"\",this.attrs={},this.innerHTML=\"\",this.whitespaceRegex=/\\s+/,this.tagName=e.tagName||\"\",this.attrs=e.attrs||{},this.innerHTML=e.innerHtml||e.innerHTML||\"\"}return e.prototype.setTagName=function(e){return this.tagName=e,this},e.prototype.getTagName=function(){return this.tagName||\"\"},e.prototype.setAttr=function(e,t){return this.getAttrs()[e]=t,this},e.prototype.getAttr=function(e){return this.getAttrs()[e]},e.prototype.setAttrs=function(e){return Object.assign(this.getAttrs(),e),this},e.prototype.getAttrs=function(){return this.attrs||(this.attrs={})},e.prototype.setClass=function(e){return this.setAttr(\"class\",e)},e.prototype.addClass=function(e){for(var t,r=this.getClass(),n=this.whitespaceRegex,o=r?r.split(n):[],s=e.split(n);t=s.shift();)-1===Be(o,t)&&o.push(t);return this.getAttrs().class=o.join(\" \"),this},e.prototype.removeClass=function(e){for(var t,r=this.getClass(),n=this.whitespaceRegex,o=r?r.split(n):[],s=e.split(n);o.length&&(t=s.shift());){var i=Be(o,t);-1!==i&&o.splice(i,1)}return this.getAttrs().class=o.join(\" \"),this},e.prototype.getClass=function(){return this.getAttrs().class||\"\"},e.prototype.hasClass=function(e){return-1!==(\" \"+this.getClass()+\" \").indexOf(\" \"+e+\" \")},e.prototype.setInnerHTML=function(e){return this.innerHTML=e,this},e.prototype.setInnerHtml=function(e){return this.setInnerHTML(e)},e.prototype.getInnerHTML=function(){return this.innerHTML||\"\"},e.prototype.getInnerHtml=function(){return this.getInnerHTML()},e.prototype.toAnchorString=function(){var e=this.getTagName(),t=this.buildAttrsStr();return[\"<\",e,t=t?\" \"+t:\"\",\">\",this.getInnerHtml(),\"</\",e,\">\"].join(\"\")},e.prototype.buildAttrsStr=function(){if(!this.attrs)return\"\";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'=\"'+e[r]+'\"');return t.join(\" \")},e}();var Se=function(){function e(e){void 0===e&&(e={}),this.newWindow=!1,this.truncate={},this.className=\"\",this.newWindow=e.newWindow||!1,this.truncate=e.truncate||{},this.className=e.className||\"\"}return e.prototype.build=function(e){return new Me({tagName:\"a\",attrs:this.createAttrs(e),innerHtml:this.processAnchorText(e.getAnchorText())})},e.prototype.createAttrs=function(e){var t={href:e.getAnchorHref()},r=this.createCssClass(e);return r&&(t.class=r),this.newWindow&&(t.target=\"_blank\",t.rel=\"noopener noreferrer\"),this.truncate&&this.truncate.length&&this.truncate.length<e.getAnchorText().length&&(t.title=e.getAnchorHref()),t},e.prototype.createCssClass=function(e){var t=this.className;if(t){for(var r=[t],n=e.getCssClassSuffixes(),o=0,s=n.length;o<s;o++)r.push(t+\"-\"+n[o]);return r.join(\" \")}return\"\"},e.prototype.processAnchorText=function(e){return e=this.doTruncate(e)},e.prototype.doTruncate=function(e){var t=this.truncate;if(!t||!t.length)return e;var r=t.length,n=t.location;return\"smart\"===n?function(e,t,r){var n,o;null==r?(r=\"…\",o=3,n=8):(o=r.length,n=r.length);var s=function(e){var t=\"\";return e.scheme&&e.host&&(t+=e.scheme+\"://\"),e.host&&(t+=e.host),e.path&&(t+=\"/\"+e.path),e.query&&(t+=\"?\"+e.query),e.fragment&&(t+=\"#\"+e.fragment),t},i=function(e,t){var n=t/2,o=Math.ceil(n),s=-1*Math.floor(n),i=\"\";return s<0&&(i=e.substr(s)),e.substr(0,o)+r+i};if(e.length<=t)return e;var a=t-o,u=function(e){var t={},r=e,n=r.match(/^([a-z]+):\\/\\//i);return n&&(t.scheme=n[1],r=r.substr(n[0].length)),(n=r.match(/^(.*?)(?=(\\?|#|\\/|$))/i))&&(t.host=n[1],r=r.substr(n[0].length)),(n=r.match(/^\\/(.*?)(?=(\\?|#|$))/i))&&(t.path=n[1],r=r.substr(n[0].length)),(n=r.match(/^\\?(.*?)(?=(#|$))/i))&&(t.query=n[1],r=r.substr(n[0].length)),(n=r.match(/^#(.*?)$/i))&&(t.fragment=n[1]),t}(e);if(u.query){var l=u.query.match(/^(.*?)(?=(\\?|\\#))(.*?)$/i);l&&(u.query=u.query.substr(0,l[1].length),e=s(u))}if(e.length<=t)return e;if(u.host&&(u.host=u.host.replace(/^www\\./,\"\"),e=s(u)),e.length<=t)return e;var c=\"\";if(u.host&&(c+=u.host),c.length>=a)return u.host.length==t?(u.host.substr(0,t-o)+r).substr(0,a+n):i(c,a).substr(0,a+n);var p=\"\";if(u.path&&(p+=\"/\"+u.path),u.query&&(p+=\"?\"+u.query),p){if((c+p).length>=a)return(c+p).length==t?(c+p).substr(0,t):(c+i(p,a-c.length)).substr(0,a+n);c+=p}if(u.fragment){var h=\"#\"+u.fragment;if((c+h).length>=a)return(c+h).length==t?(c+h).substr(0,t):(c+i(h,a-c.length)).substr(0,a+n);c+=h}if(u.scheme&&u.host){var f=u.scheme+\"://\";if((c+f).length<a)return(f+c).substr(0,t)}if(c.length<=t)return c;var g=\"\";return a>0&&(g=c.substr(-1*Math.floor(a/2))),(c.substr(0,Math.ceil(a/2))+r+g).substr(0,a+n)}(e,r):\"middle\"===n?function(e,t,r){if(e.length<=t)return e;var n,o;null==r?(r=\"…\",n=8,o=3):(n=r.length,o=r.length);var s=t-o,i=\"\";return s>0&&(i=e.substr(-1*Math.floor(s/2))),(e.substr(0,Math.ceil(s/2))+r+i).substr(0,s+n)}(e,r):function(e,t,r){return function(e,t,r){var n;return e.length>t&&(null==r?(r=\"…\",n=3):n=r.length,e=e.substring(0,t-n)+r),e}(e,t,r)}(e,r)},e}(),Te=function(){function e(e){this.__jsduckDummyDocProp=null,this.matchedText=\"\",this.offset=0,this.tagBuilder=e.tagBuilder,this.matchedText=e.matchedText,this.offset=e.offset}return e.prototype.getMatchedText=function(){return this.matchedText},e.prototype.setOffset=function(e){this.offset=e},e.prototype.getOffset=function(){return this.offset},e.prototype.getCssClassSuffixes=function(){return[this.getType()]},e.prototype.buildTag=function(){return this.tagBuilder.build(this)},e}(),Le=function(e,t){return(Le=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};function Re(e,t){function r(){this.constructor=e}Le(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}var Ne=function(){return(Ne=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)},ze=function(e){function t(t){var r=e.call(this,t)||this;return r.email=\"\",r.email=t.email,r}return Re(t,e),t.prototype.getType=function(){return\"email\"},t.prototype.getEmail=function(){return this.email},t.prototype.getAnchorHref=function(){return\"mailto:\"+this.email},t.prototype.getAnchorText=function(){return this.email},t}(Te),Pe=function(e){function t(t){var r=e.call(this,t)||this;return r.serviceName=\"\",r.hashtag=\"\",r.serviceName=t.serviceName,r.hashtag=t.hashtag,r}return Re(t,e),t.prototype.getType=function(){return\"hashtag\"},t.prototype.getServiceName=function(){return this.serviceName},t.prototype.getHashtag=function(){return this.hashtag},t.prototype.getAnchorHref=function(){var e=this.serviceName,t=this.hashtag;switch(e){case\"twitter\":return\"https://twitter.com/hashtag/\"+t;case\"facebook\":return\"https://www.facebook.com/hashtag/\"+t;case\"instagram\":return\"https://instagram.com/explore/tags/\"+t;default:throw new Error(\"Unknown service name to point hashtag to: \"+e)}},t.prototype.getAnchorText=function(){return\"#\"+this.hashtag},t}(Te),je=function(e){function t(t){var r=e.call(this,t)||this;return r.serviceName=\"twitter\",r.mention=\"\",r.mention=t.mention,r.serviceName=t.serviceName,r}return Re(t,e),t.prototype.getType=function(){return\"mention\"},t.prototype.getMention=function(){return this.mention},t.prototype.getServiceName=function(){return this.serviceName},t.prototype.getAnchorHref=function(){switch(this.serviceName){case\"twitter\":return\"https://twitter.com/\"+this.mention;case\"instagram\":return\"https://instagram.com/\"+this.mention;case\"soundcloud\":return\"https://soundcloud.com/\"+this.mention;default:throw new Error(\"Unknown service name to point mention to: \"+this.serviceName)}},t.prototype.getAnchorText=function(){return\"@\"+this.mention},t.prototype.getCssClassSuffixes=function(){var t=e.prototype.getCssClassSuffixes.call(this),r=this.getServiceName();return r&&t.push(r),t},t}(Te),Ie=function(e){function t(t){var r=e.call(this,t)||this;return r.number=\"\",r.plusSign=!1,r.number=t.number,r.plusSign=t.plusSign,r}return Re(t,e),t.prototype.getType=function(){return\"phone\"},t.prototype.getPhoneNumber=function(){return this.number},t.prototype.getNumber=function(){return this.getPhoneNumber()},t.prototype.getAnchorHref=function(){return\"tel:\"+(this.plusSign?\"+\":\"\")+this.number},t.prototype.getAnchorText=function(){return this.matchedText},t}(Te),Oe=function(e){function t(t){var r=e.call(this,t)||this;return r.url=\"\",r.urlMatchType=\"scheme\",r.protocolUrlMatch=!1,r.protocolRelativeMatch=!1,r.stripPrefix={scheme:!0,www:!0},r.stripTrailingSlash=!0,r.decodePercentEncoding=!0,r.schemePrefixRegex=/^(https?:\\/\\/)?/i,r.wwwPrefixRegex=/^(https?:\\/\\/)?(www\\.)?/i,r.protocolRelativeRegex=/^\\/\\//,r.protocolPrepended=!1,r.urlMatchType=t.urlMatchType,r.url=t.url,r.protocolUrlMatch=t.protocolUrlMatch,r.protocolRelativeMatch=t.protocolRelativeMatch,r.stripPrefix=t.stripPrefix,r.stripTrailingSlash=t.stripTrailingSlash,r.decodePercentEncoding=t.decodePercentEncoding,r}return Re(t,e),t.prototype.getType=function(){return\"url\"},t.prototype.getUrlMatchType=function(){return this.urlMatchType},t.prototype.getUrl=function(){var e=this.url;return this.protocolRelativeMatch||this.protocolUrlMatch||this.protocolPrepended||(e=this.url=\"http://\"+e,this.protocolPrepended=!0),e},t.prototype.getAnchorHref=function(){return this.getUrl().replace(/&/g,\"&\")},t.prototype.getAnchorText=function(){var e=this.getMatchedText();return this.protocolRelativeMatch&&(e=this.stripProtocolRelativePrefix(e)),this.stripPrefix.scheme&&(e=this.stripSchemePrefix(e)),this.stripPrefix.www&&(e=this.stripWwwPrefix(e)),this.stripTrailingSlash&&(e=this.removeTrailingSlash(e)),this.decodePercentEncoding&&(e=this.removePercentEncoding(e)),e},t.prototype.stripSchemePrefix=function(e){return e.replace(this.schemePrefixRegex,\"\")},t.prototype.stripWwwPrefix=function(e){return e.replace(this.wwwPrefixRegex,\"$1\")},t.prototype.stripProtocolRelativePrefix=function(e){return e.replace(this.protocolRelativeRegex,\"\")},t.prototype.removeTrailingSlash=function(e){return\"/\"===e.charAt(e.length-1)&&(e=e.slice(0,-1)),e},t.prototype.removePercentEncoding=function(e){var t=e.replace(/%22/gi,\""\").replace(/%26/gi,\"&\").replace(/%27/gi,\"'\").replace(/%3C/gi,\"<\").replace(/%3E/gi,\">\");try{return decodeURIComponent(t)}catch(e){return t}},t}(Te),Ue=function(e){this.__jsduckDummyDocProp=null,this.tagBuilder=e.tagBuilder},He=/[A-Za-z]/,Ve=/[0-9]/,Ge=/\\s/,$e=/['\"]/,Ze=/[\\x00-\\x1F\\x7F]/,We=/A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B4\\u08B6-\\u08BD\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FD5\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC/.source,Je=We+/\\u00a9\\u00ae\\u2000-\\u3300\\ud83c\\ud000-\\udfff\\ud83d\\ud000-\\udfff\\ud83e\\ud000-\\udfff/.source+/\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08D4-\\u08E1\\u08E3-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D01-\\u0D03\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u1885\\u1886\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DF5\\u1DFB-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C5\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F/.source,Ye=/0-9\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19/.source,Ke=Je+Ye,Qe=Je+Ye,Xe=\"(?:[\"+Ye+\"]{1,3}\\\\.){3}[\"+Ye+\"]{1,3}\",et=\"[\"+Qe+\"](?:[\"+Qe+\"\\\\-]{0,61}[\"+Qe+\"])?\",tt=function(e){return\"(?=(\"+et+\"))\\\\\"+e},rt=function(e){return\"(?:\"+tt(e)+\"(?:\\\\.\"+tt(e+1)+\"){0,126}|\"+Xe+\")\"},nt=new RegExp(\"[\"+Qe+\"]\"),ot=/(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|northwesternmutual|travelersinsurance|vermögensberatung|xn--3oq18vl8pn36a|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|vermögensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbaakc7dvf|xn--mgbc0a9azcg|xn--nqv7fs00ema|afamilycompany|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq61u9w7b|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|spreadbetting|travelchannel|wolterskluwer|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|rightathome|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pbt977c|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nationwide|newholland|nextdirect|onyourside|properties|protection|prudential|realestate|republican|restaurant|schaeffler|swiftcover|tatamotors|technology|telefonica|university|vistaprint|vlaanderen|volkswagen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|fujixerox|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|honeywell|institute|insurance|kuokgroup|ladbrokes|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|scjohnson|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--tckwe|xn--vhquv|yodobashi|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|budapest|builders|business|capetown|catering|catholic|chrysler|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|esurance|etisalat|everbank|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|movistar|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|symantec|training|uconnect|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|السعودية|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|cartier|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|iselect|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lancome|lanxess|lasalle|latrobe|leclerc|liaison|limited|lincoln|markets|metlife|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|shriram|singles|staples|starhub|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|yamaxun|youtube|zuerich|католик|اتصالات|الجزائر|العليان|پاکستان|كاثوليك|موبايلي|இந்தியா|abarth|abbott|abbvie|active|africa|agency|airbus|airtel|alipay|alsace|alstom|anquan|aramco|author|bayern|beauty|berlin|bharti|blanco|bostik|boston|broker|camera|career|caseih|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|mobily|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|piaget|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|warman|webcam|xihuan|yachts|yandex|zappos|москва|онлайн|ابوظبي|ارامكو|الاردن|المغرب|امارات|فلسطين|مليسيا|भारतम्|இலங்கை|ファッション|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|dodge|drive|dubai|earth|edeka|email|epost|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glade|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|intel|irish|iveco|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|lixil|loans|locus|lotte|lotto|lupin|macys|mango|media|miami|money|mopar|movie|nadex|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|zippo|ایران|بازار|بھارت|سودان|سورية|همراه|भारोत|संगठन|বাংলা|భారత్|ഭാരതം|嘉里大酒店|aarp|able|adac|aero|aigo|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|doha|duck|duns|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|raid|read|reit|rent|rest|rich|rmit|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scor|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|дети|сайт|بارت|بيتك|ڀارت|تونس|شبكة|عراق|عمان|موقع|भारत|ভারত|ভাৰত|ਭਾਰਤ|ભારત|ଭାରତ|ಭಾರತ|ලංකා|グーグル|クラウド|ポイント|大众汽车|组织机构|電訊盈科|香格里拉|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bnl|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceb|ceo|cfa|cfd|com|crs|csc|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jcp|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|off|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|qvc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|srl|srt|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|бел|ком|қаз|мкд|мон|орг|рус|срб|укр|հայ|קום|عرب|قطر|كوم|مصر|कॉम|नेट|คอม|ไทย|ストア|セール|みんな|中文网|天主教|我爱你|新加坡|淡马锡|诺基亚|飞利浦|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|бг|ею|рф|გე|닷넷|닷컴|삼성|한국|コム|世界|中信|中国|中國|企业|佛山|信息|健康|八卦|公司|公益|台湾|台灣|商城|商店|商标|嘉里|在线|大拿|娱乐|家電|工行|广东|微博|慈善|手机|手表|招聘|政务|政府|新闻|时尚|書籍|机构|游戏|澳門|点看|珠宝|移动|网址|网店|网站|网络|联通|谷歌|购物|通販|集团|食品|餐厅|香港)/,st=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.localPartCharRegex=new RegExp(\"[\"+Qe+\"!#$%&'*+/=?^_`{|}~-]\"),t.strictTldRegex=new RegExp(\"^\"+ot.source+\"$\"),t}return Re(t,e),t.prototype.parseMatches=function(e){for(var t=this.tagBuilder,r=this.localPartCharRegex,n=this.strictTldRegex,o=[],s=e.length,i=new it,a={m:\"a\",a:\"i\",i:\"l\",l:\"t\",t:\"o\",o:\":\"},u=0,l=0,c=i;u<s;){var p=e.charAt(u);switch(l){case 0:h(p);break;case 1:f(e.charAt(u-1),p);break;case 2:g(p);break;case 3:d(p);break;case 4:m(p);break;case 5:b(p);break;case 6:v(p);break;case 7:k(p);break;default:Fe(l)}u++}return x(),o;function h(e){\"m\"===e?A(1):r.test(e)&&A()}function f(e,t){\":\"===e?r.test(t)?(l=2,c=new it(Ne({},c,{hasMailtoPrefix:!0}))):y():a[e]===t||(r.test(t)?l=2:\".\"===t?l=3:\"@\"===t?l=4:y())}function g(e){\".\"===e?l=3:\"@\"===e?l=4:r.test(e)||y()}function d(e){\".\"===e?y():\"@\"===e?y():r.test(e)?l=2:y()}function m(e){nt.test(e)?l=5:y()}function b(e){\".\"===e?l=7:\"-\"===e?l=6:nt.test(e)||x()}function v(e){\"-\"===e||\".\"===e?x():nt.test(e)?l=5:x()}function k(e){\".\"===e||\"-\"===e?x():nt.test(e)?(l=5,c=new it(Ne({},c,{hasDomainDot:!0}))):x()}function A(e){void 0===e&&(e=2),l=e,c=new it({idx:u})}function y(){l=0,c=i}function x(){if(c.hasDomainDot){var r=e.slice(c.idx,u);/[-.]$/.test(r)&&(r=r.slice(0,-1));var s=c.hasMailtoPrefix?r.slice(\"mailto:\".length):r;(function(e){var t=(e.split(\".\").pop()||\"\").toLowerCase();return n.test(t)})(s)&&o.push(new ze({tagBuilder:t,matchedText:r,offset:c.idx,email:s}))}y()}},t}(Ue),it=function(e){void 0===e&&(e={}),this.idx=void 0!==e.idx?e.idx:-1,this.hasMailtoPrefix=!!e.hasMailtoPrefix,this.hasDomainDot=!!e.hasDomainDot},at=function(){function e(){}return e.isValid=function(e,t){return!(t&&!this.isValidUriScheme(t)||this.urlMatchDoesNotHaveProtocolOrDot(e,t)||this.urlMatchDoesNotHaveAtLeastOneWordChar(e,t)&&!this.isValidIpAddress(e)||this.containsMultipleDots(e))},e.isValidIpAddress=function(e){var t=new RegExp(this.hasFullProtocolRegex.source+this.ipRegex.source);return null!==e.match(t)},e.containsMultipleDots=function(e){var t=e;return this.hasFullProtocolRegex.test(e)&&(t=e.split(\"://\")[1]),t.split(\"/\")[0].indexOf(\"..\")>-1},e.isValidUriScheme=function(e){var t=e.match(this.uriSchemeRegex),r=t&&t[0].toLowerCase();return\"javascript:\"!==r&&\"vbscript:\"!==r},e.urlMatchDoesNotHaveProtocolOrDot=function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf(\".\"))},e.urlMatchDoesNotHaveAtLeastOneWordChar=function(e,t){return!(!e||!t)&&!this.hasWordCharAfterProtocolRegex.test(e)},e.hasFullProtocolRegex=/^[A-Za-z][-.+A-Za-z0-9]*:\\/\\//,e.uriSchemeRegex=/^[A-Za-z][-.+A-Za-z0-9]*:/,e.hasWordCharAfterProtocolRegex=new RegExp(\":[^\\\\s]*?[\"+We+\"]\"),e.ipRegex=/[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?(:[0-9]*)?\\/?$/,e}(),ut=function(e){function t(t){var r,n=e.call(this,t)||this;return n.stripPrefix={scheme:!0,www:!0},n.stripTrailingSlash=!0,n.decodePercentEncoding=!0,n.matcherRegex=(r=new RegExp(\"[/?#](?:[\"+Qe+\"\\\\-+&@#/%=~_()|'$*\\\\[\\\\]?!:,.;✓]*[\"+Qe+\"\\\\-+&@#/%=~_()|'$*\\\\[\\\\]✓])?\"),new RegExp([\"(?:\",\"(\",/(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\\/\\/)(?!\\d+\\/?)(?:\\/\\/)?)/.source,rt(2),\")\",\"|\",\"(\",\"(//)?\",/(?:www\\.)/.source,rt(6),\")\",\"|\",\"(\",\"(//)?\",rt(10)+\"\\\\.\",ot.source,\"(?![-\"+Ke+\"])\",\")\",\")\",\"(?::[0-9]+)?\",\"(?:\"+r.source+\")?\"].join(\"\"),\"gi\")),n.wordCharRegExp=new RegExp(\"[\"+Qe+\"]\"),n.stripPrefix=t.stripPrefix,n.stripTrailingSlash=t.stripTrailingSlash,n.decodePercentEncoding=t.decodePercentEncoding,n}return Re(t,e),t.prototype.parseMatches=function(e){for(var t,r=this.matcherRegex,n=this.stripPrefix,o=this.stripTrailingSlash,s=this.decodePercentEncoding,i=this.tagBuilder,a=[],u=function(){var r=t[0],u=t[1],c=t[4],p=t[5],h=t[9],f=t.index,g=p||h,d=e.charAt(f-1);if(!at.isValid(r,u))return\"continue\";if(f>0&&\"@\"===d)return\"continue\";if(f>0&&g&&l.wordCharRegExp.test(d))return\"continue\";if(/\\?$/.test(r)&&(r=r.substr(0,r.length-1)),l.matchHasUnbalancedClosingParen(r))r=r.substr(0,r.length-1);else{var m=l.matchHasInvalidCharAfterTld(r,u);m>-1&&(r=r.substr(0,m))}var b=[\"http://\",\"https://\"].find(function(e){return!!u&&-1!==u.indexOf(e)});if(b){var v=r.indexOf(b);r=r.substr(v),u=u.substr(v),f+=v}var k=u?\"scheme\":c?\"www\":\"tld\",A=!!u;a.push(new Oe({tagBuilder:i,matchedText:r,offset:f,urlMatchType:k,url:r,protocolUrlMatch:A,protocolRelativeMatch:!!g,stripPrefix:n,stripTrailingSlash:o,decodePercentEncoding:s}))},l=this;null!==(t=r.exec(e));)u();return a},t.prototype.matchHasUnbalancedClosingParen=function(e){var t,r=e.charAt(e.length-1);if(\")\"===r)t=\"(\";else{if(\"]\"!==r)return!1;t=\"[\"}for(var n=0,o=0,s=e.length-1;o<s;o++){var i=e.charAt(o);i===t?n++:i===r&&(n=Math.max(n-1,0))}return 0===n},t.prototype.matchHasInvalidCharAfterTld=function(e,t){if(!e)return-1;var r=0;t&&(r=e.indexOf(\":\"),e=e.slice(r));var n=new RegExp(\"^((.?//)?[-.\"+Qe+\"]*[-\"+Qe+\"]\\\\.[-\"+Qe+\"]+)\").exec(e);return null===n?-1:(r+=n[1].length,e=e.slice(n[1].length),/^[^-.A-Za-z0-9:\\/?#]/.test(e)?r:-1)},t}(Ue),lt=function(e){function t(t){var r=e.call(this,t)||this;return r.serviceName=\"twitter\",r.matcherRegex=new RegExp(\"#[_\"+Qe+\"]{1,139}(?![_\"+Qe+\"])\",\"g\"),r.nonWordCharRegex=new RegExp(\"[^\"+Qe+\"]\"),r.serviceName=t.serviceName,r}return Re(t,e),t.prototype.parseMatches=function(e){for(var t,r=this.matcherRegex,n=this.nonWordCharRegex,o=this.serviceName,s=this.tagBuilder,i=[];null!==(t=r.exec(e));){var a=t.index,u=e.charAt(a-1);if(0===a||n.test(u)){var l=t[0],c=t[0].slice(1);i.push(new Pe({tagBuilder:s,matchedText:l,offset:a,serviceName:o,hashtag:c}))}}return i},t}(Ue),ct=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.matcherRegex=/(?:(?:(?:(\\+)?\\d{1,3}[-\\040.]?)?\\(?\\d{3}\\)?[-\\040.]?\\d{3}[-\\040.]?\\d{4})|(?:(\\+)(?:9[976]\\d|8[987530]\\d|6[987]\\d|5[90]\\d|42\\d|3[875]\\d|2[98654321]\\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\\040.]?(?:\\d[-\\040.]?){6,12}\\d+))([,;]+[0-9]+#?)*/g,t}return Re(t,e),t.prototype.parseMatches=function(e){for(var t,r=this.matcherRegex,n=this.tagBuilder,o=[];null!==(t=r.exec(e));){var s=t[0],i=s.replace(/[^0-9,;#]/g,\"\"),a=!(!t[1]&&!t[2]),u=0==t.index?\"\":e.substr(t.index-1,1),l=e.substr(t.index+s.length,1),c=!u.match(/\\d/)&&!l.match(/\\d/);this.testMatch(t[3])&&this.testMatch(s)&&c&&o.push(new Ie({tagBuilder:n,matchedText:s,offset:t.index,number:i,plusSign:a}))}return o},t.prototype.testMatch=function(e){return/\\D/.test(e)},t}(Ue),pt=function(e){function t(t){var r=e.call(this,t)||this;return r.serviceName=\"twitter\",r.matcherRegexes={twitter:new RegExp(\"@[_\"+Qe+\"]{1,50}(?![_\"+Qe+\"])\",\"g\"),instagram:new RegExp(\"@[_.\"+Qe+\"]{1,30}(?![_\"+Qe+\"])\",\"g\"),soundcloud:new RegExp(\"@[-_.\"+Qe+\"]{1,50}(?![-_\"+Qe+\"])\",\"g\")},r.nonWordCharRegex=new RegExp(\"[^\"+Qe+\"]\"),r.serviceName=t.serviceName,r}return Re(t,e),t.prototype.parseMatches=function(e){var t,r=this.serviceName,n=this.matcherRegexes[this.serviceName],o=this.nonWordCharRegex,s=this.tagBuilder,i=[];if(!n)return i;for(;null!==(t=n.exec(e));){var a=t.index,u=e.charAt(a-1);if(0===a||o.test(u)){var l=t[0].replace(/\\.+$/g,\"\"),c=l.slice(1);i.push(new je({tagBuilder:s,matchedText:l,offset:a,serviceName:r,mention:c}))}}return i},t}(Ue);function ht(e,t){for(var r=t.onOpenTag,n=t.onCloseTag,o=t.onText,s=t.onComment,i=t.onDoctype,a=new ft,u=0,l=e.length,c=0,p=0,h=a;u<l;){var f=e.charAt(u);switch(c){case 0:g(f);break;case 1:d(f);break;case 2:b(f);break;case 3:m(f);break;case 4:v(f);break;case 5:k(f);break;case 6:A(f);break;case 7:y(f);break;case 8:x(f);break;case 9:w(f);break;case 10:C(f);break;case 11:E(f);break;case 12:D(f);break;case 13:_();break;case 14:B(f);break;case 15:q(f);break;case 16:F(f);break;case 17:M(f);break;case 18:S(f);break;case 19:T(f);break;case 20:L(f);break;default:Fe(c)}u++}function g(e){\"<\"===e&&N()}function d(e){\"!\"===e?c=13:\"/\"===e?(c=2,h=new ft(Ne({},h,{isClosing:!0}))):\"<\"===e?N():He.test(e)?(c=3,h=new ft(Ne({},h,{isOpening:!0}))):(c=0,h=a)}function m(e){Ge.test(e)?(h=new ft(Ne({},h,{name:P()})),c=4):\"<\"===e?N():\"/\"===e?(h=new ft(Ne({},h,{name:P()})),c=12):\">\"===e?(h=new ft(Ne({},h,{name:P()})),z()):He.test(e)||Ve.test(e)||\":\"===e||R()}function b(e){\">\"===e?R():He.test(e)?c=3:R()}function v(e){Ge.test(e)||(\"/\"===e?c=12:\">\"===e?z():\"<\"===e?N():\"=\"===e||$e.test(e)||Ze.test(e)?R():c=5)}function k(e){Ge.test(e)?c=6:\"/\"===e?c=12:\"=\"===e?c=7:\">\"===e?z():\"<\"===e?N():$e.test(e)&&R()}function A(e){Ge.test(e)||(\"/\"===e?c=12:\"=\"===e?c=7:\">\"===e?z():\"<\"===e?N():$e.test(e)?R():c=5)}function y(e){Ge.test(e)||('\"'===e?c=8:\"'\"===e?c=9:/[>=`]/.test(e)?R():\"<\"===e?N():c=10)}function x(e){'\"'===e&&(c=11)}function w(e){\"'\"===e&&(c=11)}function C(e){Ge.test(e)?c=4:\">\"===e?z():\"<\"===e&&N()}function E(e){Ge.test(e)?c=4:\"/\"===e?c=12:\">\"===e?z():\"<\"===e?N():(c=4,u--)}function D(e){\">\"===e?(h=new ft(Ne({},h,{isClosing:!0})),z()):c=4}function _(t){\"--\"===e.substr(u,2)?(u+=2,h=new ft(Ne({},h,{type:\"comment\"})),c=14):\"DOCTYPE\"===e.substr(u,7).toUpperCase()?(u+=7,h=new ft(Ne({},h,{type:\"doctype\"})),c=20):R()}function B(e){\"-\"===e?c=15:\">\"===e?R():c=16}function q(e){\"-\"===e?c=18:\">\"===e?R():c=16}function F(e){\"-\"===e&&(c=17)}function M(e){c=\"-\"===e?18:16}function S(e){\">\"===e?z():\"!\"===e?c=19:\"-\"===e||(c=16)}function T(e){\"-\"===e?c=17:\">\"===e?z():c=16}function L(e){\">\"===e?z():\"<\"===e&&N()}function R(){c=0,h=a}function N(){c=1,h=new ft({idx:u})}function z(){var t=e.slice(p,h.idx);t&&o(t,p),\"comment\"===h.type?s(h.idx):\"doctype\"===h.type?i(h.idx):(h.isOpening&&r(h.name,h.idx),h.isClosing&&n(h.name,h.idx)),R(),p=u+1}function P(){var t=h.idx+(h.isClosing?2:1);return e.slice(t,u).toLowerCase()}p<u&&function(){var t=e.slice(p,u);o(t,p),p=u+1}()}var ft=function(e){void 0===e&&(e={}),this.idx=void 0!==e.idx?e.idx:-1,this.type=e.type||\"tag\",this.name=e.name||\"\",this.isOpening=!!e.isOpening,this.isClosing=!!e.isClosing},gt=function(){function e(t){void 0===t&&(t={}),this.version=e.version,this.urls={},this.email=!0,this.phone=!0,this.hashtag=!1,this.mention=!1,this.newWindow=!0,this.stripPrefix={scheme:!0,www:!0},this.stripTrailingSlash=!0,this.decodePercentEncoding=!0,this.truncate={length:0,location:\"end\"},this.className=\"\",this.replaceFn=null,this.context=void 0,this.matchers=null,this.tagBuilder=null,this.urls=this.normalizeUrlsCfg(t.urls),this.email=\"boolean\"==typeof t.email?t.email:this.email,this.phone=\"boolean\"==typeof t.phone?t.phone:this.phone,this.hashtag=t.hashtag||this.hashtag,this.mention=t.mention||this.mention,this.newWindow=\"boolean\"==typeof t.newWindow?t.newWindow:this.newWindow,this.stripPrefix=this.normalizeStripPrefixCfg(t.stripPrefix),this.stripTrailingSlash=\"boolean\"==typeof t.stripTrailingSlash?t.stripTrailingSlash:this.stripTrailingSlash,this.decodePercentEncoding=\"boolean\"==typeof t.decodePercentEncoding?t.decodePercentEncoding:this.decodePercentEncoding;var r=this.mention;if(!1!==r&&\"twitter\"!==r&&\"instagram\"!==r&&\"soundcloud\"!==r)throw new Error(\"invalid `mention` cfg - see docs\");var n=this.hashtag;if(!1!==n&&\"twitter\"!==n&&\"facebook\"!==n&&\"instagram\"!==n)throw new Error(\"invalid `hashtag` cfg - see docs\");this.truncate=this.normalizeTruncateCfg(t.truncate),this.className=t.className||this.className,this.replaceFn=t.replaceFn||this.replaceFn,this.context=t.context||this}return e.link=function(t,r){return new e(r).link(t)},e.parse=function(t,r){return new e(r).parse(t)},e.prototype.normalizeUrlsCfg=function(e){return null==e&&(e=!0),\"boolean\"==typeof e?{schemeMatches:e,wwwMatches:e,tldMatches:e}:{schemeMatches:\"boolean\"!=typeof e.schemeMatches||e.schemeMatches,wwwMatches:\"boolean\"!=typeof e.wwwMatches||e.wwwMatches,tldMatches:\"boolean\"!=typeof e.tldMatches||e.tldMatches}},e.prototype.normalizeStripPrefixCfg=function(e){return null==e&&(e=!0),\"boolean\"==typeof e?{scheme:e,www:e}:{scheme:\"boolean\"!=typeof e.scheme||e.scheme,www:\"boolean\"!=typeof e.www||e.www}},e.prototype.normalizeTruncateCfg=function(e){return\"number\"==typeof e?{length:e,location:\"end\"}:function(e,t){for(var r in t)t.hasOwnProperty(r)&&void 0===e[r]&&(e[r]=t[r]);return e}(e||{},{length:Number.POSITIVE_INFINITY,location:\"end\"})},e.prototype.parse=function(e){var t=this,r=[\"a\",\"style\",\"script\"],n=0,o=[];return ht(e,{onOpenTag:function(e){r.indexOf(e)>=0&&n++},onText:function(e,r){if(0===n){var s=function(e,t){if(!t.global)throw new Error(\"`splitRegex` must have the 'g' flag set\");for(var r,n=[],o=0;r=t.exec(e);)n.push(e.substring(o,r.index)),n.push(r[0]),o=r.index+r[0].length;return n.push(e.substring(o)),n}(e,/( | |<|<|>|>|"|"|')/gi),i=r;s.forEach(function(e,r){if(r%2==0){var n=t.parseText(e,i);o.push.apply(o,n)}i+=e.length})}},onCloseTag:function(e){r.indexOf(e)>=0&&(n=Math.max(n-1,0))},onComment:function(e){},onDoctype:function(e){}}),o=this.compactMatches(o),o=this.removeUnwantedMatches(o)},e.prototype.compactMatches=function(e){e.sort(function(e,t){return e.getOffset()-t.getOffset()});for(var t=0;t<e.length-1;t++){var r=e[t],n=r.getOffset(),o=r.getMatchedText().length,s=n+o;if(t+1<e.length){if(e[t+1].getOffset()===n){var i=e[t+1].getMatchedText().length>o?t:t+1;e.splice(i,1);continue}e[t+1].getOffset()<s&&e.splice(t+1,1)}}return e},e.prototype.removeUnwantedMatches=function(e){return this.hashtag||qe(e,function(e){return\"hashtag\"===e.getType()}),this.email||qe(e,function(e){return\"email\"===e.getType()}),this.phone||qe(e,function(e){return\"phone\"===e.getType()}),this.mention||qe(e,function(e){return\"mention\"===e.getType()}),this.urls.schemeMatches||qe(e,function(e){return\"url\"===e.getType()&&\"scheme\"===e.getUrlMatchType()}),this.urls.wwwMatches||qe(e,function(e){return\"url\"===e.getType()&&\"www\"===e.getUrlMatchType()}),this.urls.tldMatches||qe(e,function(e){return\"url\"===e.getType()&&\"tld\"===e.getUrlMatchType()}),e},e.prototype.parseText=function(e,t){void 0===t&&(t=0),t=t||0;for(var r=this.getMatchers(),n=[],o=0,s=r.length;o<s;o++){for(var i=r[o].parseMatches(e),a=0,u=i.length;a<u;a++)i[a].setOffset(t+i[a].getOffset());n.push.apply(n,i)}return n},e.prototype.link=function(e){if(!e)return\"\";for(var t=this.parse(e),r=[],n=0,o=0,s=t.length;o<s;o++){var i=t[o];r.push(e.substring(n,i.getOffset())),r.push(this.createMatchReturnVal(i)),n=i.getOffset()+i.getMatchedText().length}return r.push(e.substring(n)),r.join(\"\")},e.prototype.createMatchReturnVal=function(e){var t;return this.replaceFn&&(t=this.replaceFn.call(this.context,e)),\"string\"==typeof t?t:!1===t?e.getMatchedText():t instanceof Me?t.toAnchorString():e.buildTag().toAnchorString()},e.prototype.getMatchers=function(){if(this.matchers)return this.matchers;var e=this.getTagBuilder(),t=[new lt({tagBuilder:e,serviceName:this.hashtag}),new st({tagBuilder:e}),new ct({tagBuilder:e}),new pt({tagBuilder:e,serviceName:this.mention}),new ut({tagBuilder:e,stripPrefix:this.stripPrefix,stripTrailingSlash:this.stripTrailingSlash,decodePercentEncoding:this.decodePercentEncoding})];return this.matchers=t},e.prototype.getTagBuilder=function(){var e=this.tagBuilder;return e||(e=this.tagBuilder=new Se({newWindow:this.newWindow,truncate:this.truncate,className:this.className})),e},e.version=\"3.11.0\",e.AnchorTagBuilder=Se,e.HtmlTag=Me,e.matcher={Email:st,Hashtag:lt,Matcher:Ue,Mention:pt,Phone:ct,Url:ut},e.match={Email:ze,Hashtag:Pe,Match:Te,Mention:je,Phone:Ie,Url:Oe},e}(),dt=/www|@|\\:\\/\\//;function mt(e){return/^<\\/a\\s*>/i.test(e)}function bt(){var e=[],t=new gt({stripPrefix:!1,url:!0,email:!0,replaceFn:function(t){switch(t.getType()){case\"url\":e.push({text:t.matchedText,url:t.getUrl()});break;case\"email\":e.push({text:t.matchedText,url:\"mailto:\"+t.getEmail().replace(/^mailto:/i,\"\")})}return!1}});return{links:e,autolinker:t}}function vt(e){var t,r,n,o,s,i,a,u,l,c,p,h,f,g,d=e.tokens,m=null;for(r=0,n=d.length;r<n;r++)if(\"inline\"===d[r].type)for(p=0,t=(o=d[r].children).length-1;t>=0;t--)if(\"link_close\"!==(s=o[t]).type){if(\"htmltag\"===s.type&&(g=s.content,/^<a[>\\s]/i.test(g)&&p>0&&p--,mt(s.content)&&p++),!(p>0)&&\"text\"===s.type&&dt.test(s.content)){if(m||(h=(m=bt()).links,f=m.autolinker),i=s.content,h.length=0,f.link(i),!h.length)continue;for(a=[],c=s.level,u=0;u<h.length;u++)e.inline.validateLink(h[u].url)&&((l=i.indexOf(h[u].text))&&a.push({type:\"text\",content:i.slice(0,l),level:c}),a.push({type:\"link_open\",href:h[u].url,title:\"\",level:c++}),a.push({type:\"text\",content:h[u].text,level:c}),a.push({type:\"link_close\",level:--c}),i=i.slice(l+h[u].text.length));i.length&&a.push({type:\"text\",content:i,level:c}),d[r].children=o=[].concat(o.slice(0,t),a,o.slice(t+1))}}else for(t--;o[t].level!==s.level&&\"link_open\"!==o[t].type;)t--}e.Remarkable=_e,e.linkify=function(e){e.core.ruler.push(\"linkify\",vt)},e.utils=A,Object.defineProperty(e,\"__esModule\",{value:!0})});\n",
"type": "application/javascript",
"title": "$:/plugins/tiddlywiki/markdown/remarkable.js",
"module-type": "library"
},
"$:/plugins/tiddlywiki/markdown/images/new-markdown-button": {
"title": "$:/plugins/tiddlywiki/markdown/images/new-markdown-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-new-markdown-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <rect x=\"80\" y=\"96\" width=\"48\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"96\" y=\"80\" width=\"16\" height=\"48\" rx=\"8\"></rect>\n <path d=\"M3.23876972,39.5396716 C3.23876972,35.9653274 6.13586353,33.0691646 9.7141757,33.0691646 L98.1283744,33.0691646 C101.706101,33.0691646 104.60378,35.9646626 104.60378,39.5396716 L104.60378,84.8296213 C104.60378,88.4039654 101.706687,91.3001282 98.1283744,91.3001282 L9.7141757,91.3001282 C6.13644944,91.3001282 3.23876972,88.4046302 3.23876972,84.8296213 L3.23876972,39.5396716 L3.23876972,39.5396716 Z M-2.15298617,39.5396716 L-2.15298617,84.8296213 C-2.15298617,91.3833243 3.15957363,96.6918841 9.7141757,96.6918841 L98.1283744,96.6918841 C104.684083,96.6918841 109.995536,91.382138 109.995536,84.8296213 L109.995536,39.5396716 C109.995536,32.9859686 104.682977,27.6774087 98.1283744,27.6774087 L9.7141757,27.6774087 C3.15846686,27.6774087 -2.15298617,32.9871549 -2.15298617,39.5396716 Z M14.0222815,80.5166164 L14.0222815,43.8526764 L24.8057933,43.8526764 L35.589305,57.3320661 L46.3728168,43.8526764 L57.1563286,43.8526764 L57.1563286,80.5166164 L46.3728168,80.5166164 L46.3728168,59.4887685 L35.589305,72.9681582 L24.8057933,59.4887685 L24.8057933,80.5166164 L14.0222815,80.5166164 Z M81.4192301,80.5166164 L65.2439624,62.723822 L76.0274742,62.723822 L76.0274742,43.8526764 L86.810986,43.8526764 L86.810986,62.723822 L97.5944978,62.723822 L81.4192301,80.5166164 Z\"transform=\"translate(53.921275, 62.184646) rotate(-60.000000) translate(-53.921275, -62.184646) \"></path>\n </g>\n</svg>"
},
"$:/plugins/tiddlywiki/markdown/new-markdown-button": {
"title": "$:/plugins/tiddlywiki/markdown/new-markdown-button",
"tags": "$:/tags/PageControls",
"caption": "{{$:/plugins/tiddlywiki/markdown/images/new-markdown-button}} {{$:/language/Buttons/NewMarkdown/Caption}}",
"description": "{{$:/language/Buttons/NewMarkdown/Hint}}",
"list-after": "$:/core/ui/Buttons/new-tiddler",
"text": "\\whitespace trim\n<$button tooltip={{$:/language/Buttons/NewMarkdown/Hint}} aria-label={{$:/language/Buttons/NewMarkdown/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-new-tiddler\" type=\"text/x-markdown\"/>\n<$list filter=\"[<tv-config-toolbar-icons>match[yes]]\">\n{{$:/plugins/tiddlywiki/markdown/images/new-markdown-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>match[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewMarkdown/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/plugins/tiddlywiki/markdown/readme": {
"title": "$:/plugins/tiddlywiki/markdown/readme",
"text": "This is a TiddlyWiki plugin for parsing Markdown text, using the [[Remarkable|https://github.com/jonschlinkert/remarkable]] library.\n\nIt is completely self-contained, and doesn't need an Internet connection in order to work. It works both in the browser and under Node.js.\n\n[[Source code|https://github.com/Jermolene/TiddlyWiki5/blob/master/plugins/tiddlywiki/markdown]]\n"
},
"$:/plugins/tiddlywiki/markdown/usage": {
"title": "$:/plugins/tiddlywiki/markdown/usage",
"text": "! Plugin Configuration\n\n|!Config |!Default |!Description |\n| <code>[[breaks|$:/config/markdown/breaks]]</code>| ``false``|Remarkable library config: Convert '\\n' in paragraphs into ``<br>`` |\n| <code>[[linkify|$:/config/markdown/linkify]]</code>| ``false``|Remarkable library config: Autoconvert URL-like text to links |\n| <code>[[linkNewWindow|$:/config/markdown/linkNewWindow]]</code>| ``true``|For external links, should clicking on them open a new window/tab automatically? |\n| <code>[[quotes|$:/config/markdown/quotes]]</code>| ``“”‘’``|Remarkable library config: Double + single quotes replacement pairs, when ``typographer`` enabled |\n| <code>[[renderWikiText|$:/config/markdown/renderWikiText]]</code>| ``true``|After Markdown is parsed, should any text elements be handed off to the ~WikiText parser for further processing? |\n| <code>[[renderWikiTextPragma|$:/config/markdown/renderWikiTextPragma]]</code>| ``\\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock``|When handing off to the ~WikiText parser, what pragma rules should it follow? |\n| <code>[[typographer|$:/config/markdown/typographer]]</code>| ``false``|Remarkable library config: Enable some language-neutral replacement + quotes beautification |\n\n! Creating ~WikiLinks\n\nCreate wiki links with the usual Markdown link syntax targeting `#` and the target tiddler title:\n\n```\n[link text](#TiddlerTitle)\n```\n\nIf the target tiddler has a space in its name, that name must be URL-escaped to be detected as a URL:\n\n```\n[link text](#Test%20Tiddler)\n```\n\n! Images\n\nMarkdown image syntax can be used to reference images by tiddler title or an external URI. For example:\n\n```\n\n\n\n```\n"
},
"$:/plugins/tiddlywiki/markdown/wrapper.js": {
"title": "$:/plugins/tiddlywiki/markdown/wrapper.js",
"text": "/*\\\ntitle: $:/plugins/tiddlywiki/markdown/wrapper.js\ntype: application/javascript\nmodule-type: parser\n\nWraps up the remarkable parser for use as a Parser in TiddlyWiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar r = require(\"$:/plugins/tiddlywiki/markdown/remarkable.js\");\n\nvar Remarkable = r.Remarkable,\n\tlinkify = r.linkify,\n\tutils = r.utils;\n\n///// Set up configuration options /////\nfunction parseAsBoolean(tiddlerName) {\n\treturn $tw.wiki.getTiddlerText(tiddlerName).toLowerCase() === \"true\";\n}\nvar pluginOpts = {\n\tlinkNewWindow: parseAsBoolean(\"$:/config/markdown/linkNewWindow\"),\n\trenderWikiText: parseAsBoolean(\"$:/config/markdown/renderWikiText\"),\n\trenderWikiTextPragma: $tw.wiki.getTiddlerText(\"$:/config/markdown/renderWikiTextPragma\").trim()\n};\nvar remarkableOpts = {\n\tbreaks: parseAsBoolean(\"$:/config/markdown/breaks\"),\n\tquotes: $tw.wiki.getTiddlerText(\"$:/config/markdown/quotes\"),\n\ttypographer: parseAsBoolean(\"$:/config/markdown/typographer\")\n};\nvar accumulatingTypes = {\n\t\"text\": true,\n\t\"softbreak\": true\n};\n\nvar md = new Remarkable(remarkableOpts);\n\nif (parseAsBoolean(\"$:/config/markdown/linkify\")) {\n\tmd = md.use(linkify);\n}\n\nfunction findTagWithType(nodes, startPoint, type, level) {\n\tfor (var i = startPoint; i < nodes.length; i++) {\n\t\tif (nodes[i].type === type && nodes[i].level === level) {\n\t\t\treturn i;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Remarkable creates nodes that look like:\n * [\n * { type: 'paragraph_open'},\n * { type: 'inline', content: 'Hello World', children:[{type: 'text', content: 'Hello World'}]},\n * { type: 'paragraph_close'}\n * ]\n *\n * But TiddlyWiki wants the Parser (https://tiddlywiki.com/dev/static/Parser.html) to emit nodes like:\n *\n * [\n * { type: 'element', tag: 'p', children: [{type: 'text', text: 'Hello World'}]}\n * ]\n */\nfunction convertNodes(remarkableTree, isStartOfInline) {\n\tlet out = [];\n\tvar accumulatedText = '';\n\tfunction withChildren(currentIndex, currentLevel, closingType, nodes, callback) {\n\t\tvar j = findTagWithType(nodes, currentIndex + 1, closingType, currentLevel);\n\t\tif (j === false) {\n\t\t\tconsole.error(\"Failed to find a \" + closingType + \" node after position \" + currentIndex);\n\t\t\tconsole.log(nodes);\n\t\t\treturn currentIndex + 1;\n\t\t}\n\t\tlet children = convertNodes(nodes.slice(currentIndex + 1, j));\n\t\tcallback(children);\n\t\treturn j;\n\t}\n\tfunction wrappedElement(elementTag, currentIndex, currentLevel, closingType, nodes) {\n\t\treturn withChildren(currentIndex, currentLevel, closingType, nodes, function(children) {\n\t\t\tout.push({\n\t\t\t\ttype: \"element\",\n\t\t\t\ttag: elementTag,\n\t\t\t\tchildren: children\n\t\t\t});\n\t\t});\n\t}\n\n\tfor (var i = 0; i < remarkableTree.length; i++) {\n\t\tvar currentNode = remarkableTree[i];\n\t\tswitch (currentNode.type) {\n\t\tcase \"paragraph_open\":\n\t\t\ti = wrappedElement(\"p\", i, currentNode.level, \"paragraph_close\", remarkableTree);\n\t\t\tbreak;\n\n\t\tcase \"heading_open\":\n\t\t\ti = wrappedElement(\"h\" + currentNode.hLevel, i, currentNode.level, \"heading_close\", remarkableTree);\n\t\t\tbreak;\n\n\t\tcase \"bullet_list_open\":\n\t\t\ti = wrappedElement(\"ul\", i, currentNode.level, \"bullet_list_close\", remarkableTree);\n\t\t\tbreak;\n\n\t\tcase \"ordered_list_open\":\n\t\t\ti = wrappedElement('ol', i, currentNode.level,'ordered_list_close', remarkableTree);\n\t\t\tbreak;\n\n\t\tcase \"list_item_open\":\n\t\t\ti = wrappedElement(\"li\", i, currentNode.level, \"list_item_close\", remarkableTree);\n\t\t\tbreak;\n\n\t\tcase \"link_open\":\n\t\t\ti = withChildren(i, currentNode.level, \"link_close\", remarkableTree, function(children) {\n\t\t\t\tif (currentNode.href[0] !== \"#\") {\n\t\t\t\t\t// External link\n\t\t\t\t\tvar attributes = {\n\t\t\t\t\t\tclass: { type: \"string\", value: \"tc-tiddlylink-external\" },\n\t\t\t\t\t\thref: { type: \"string\", value: currentNode.href },\n\t\t\t\t\t\trel: { type: \"string\", value: \"noopener noreferrer\" }\n\t\t\t\t\t};\n\t\t\t\t\tif (pluginOpts.linkNewWindow) {\n\t\t\t\t\t\tattributes.target = { type: \"string\", value: \"_blank\" };\n\t\t\t\t\t}\n\t\t\t\t\tout.push({\n\t\t\t\t\t\ttype: \"element\",\n\t\t\t\t\t\ttag: \"a\",\n\t\t\t\t\t\tattributes: attributes,\n\t\t\t\t\t\tchildren: children\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Internal link\n\t\t\t\t\tout.push({\n\t\t\t\t\t\ttype: \"link\",\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\tto: { type: \"string\", value: decodeURI(currentNode.href.substr(1)) }\n\t\t\t\t\t\t},\n\t\t\t\t\t\tchildren: children\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"code\":\n\t\t\tout.push({\n\t\t\t\ttype: \"element\",\n\t\t\t\ttag: currentNode.block ? \"pre\" : \"code\",\n\t\t\t\tchildren: [{ type: \"text\", text: currentNode.content }]\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"fence\":\n\t\t\tout.push({\n\t\t\t\ttype: \"codeblock\",\n\t\t\t\tattributes: {\n\t\t\t\t\tlanguage: { type: \"string\", value: currentNode.params },\n\t\t\t\t\tcode: { type: \"string\", value: currentNode.content }\n\t\t\t\t}\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"image\":\n\t\t\tout.push({\n\t\t\t\ttype: \"image\",\n\t\t\t\tattributes: {\n\t\t\t\t\ttooltip: { type: \"string\", value: currentNode.alt },\n\t\t\t\t\tsource: { type: \"string\", value: decodeURIComponent(currentNode.src) }\n\t\t\t\t}\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"softbreak\":\n\t\t\tif (remarkableOpts.breaks) {\n\t\t\t\tout.push({\n\t\t\t\t\ttype: \"element\",\n\t\t\t\t\ttag: \"br\",\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\taccumulatedText = accumulatedText + '\\n';\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase \"hardbreak\":\n\t\t\tout.push({\n\t\t\t\ttype: \"element\",\n\t\t\t\ttag: \"br\",\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"th_open\":\n\t\tcase \"td_open\":\n\t\t\tvar elementTag = currentNode.type.slice(0, 2);\n\t\t\ti = withChildren(i, currentNode.level, elementTag + \"_close\", remarkableTree, function(children) {\n\t\t\t\tvar attributes = {};\n\t\t\t\tif (currentNode.align) {\n\t\t\t\t\tattributes.style = { type: \"string\", value: \"text-align:\" + currentNode.align };\n\t\t\t\t}\n\t\t\t\tout.push({\n\t\t\t\t\ttype: \"element\",\n\t\t\t\t\ttag: elementTag,\n\t\t\t\t\tattributes: attributes,\n\t\t\t\t\tchildren: children\n\t\t\t\t});\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"hr\":\n\t\t\tout.push({\n\t\t\t\ttype: 'element',\n\t\t\t\ttag: 'hr',\n\t\t\t});\n\t\t\tbreak;\n\n\t\tcase \"inline\":\n\t\t\tout = out.concat(convertNodes(currentNode.children, true));\n\t\t\tbreak;\n\n\t\tcase \"text\":\n\t\t\t// We need to merge this text block with the upcoming text block and parse it all together.\n\t\t\taccumulatedText = accumulatedText + currentNode.content;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (currentNode.type.substr(currentNode.type.length - 5) === \"_open\") {\n\t\t\t\tvar tagName = currentNode.type.substr(0, currentNode.type.length - 5);\n\t\t\t\ti = wrappedElement(tagName, i, currentNode.level, tagName + \"_close\", remarkableTree);\n\t\t\t} else {\n\t\t\t\tconsole.error(\"Unknown node type: \" + currentNode.type, currentNode);\n\t\t\t\tout.push({\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: currentNode.content\n\t\t\t\t});\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\t// We test to see if we process the block now, or if there's\n\t\t// more to accumulate first.\n\t\tif (accumulatedText\n\t\t\t&& (\n\t\t\t\tremarkableOpts.breaks ||\n\t\t\t\t(i+1) >= remarkableTree.length ||\n\t\t\t\t!accumulatingTypes[remarkableTree[i+1].type]\n\t\t\t)\n\t\t) {\n\t\t\t// The Markdown compiler thinks this is just text.\n\t\t\t// Hand off to the WikiText parser to see if there's more to render\n\t\t\t// But only if it's configured to, and we have more than whitespace\n\t\t\tif (!pluginOpts.renderWikiText || accumulatedText.match(/^\\s*$/)) {\n\t\t\t\tout.push({\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: accumulatedText\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// If we're inside a block element (div, p, td, h1), and this is the first child in the tree,\n\t\t\t\t// handle as a block-level parse. Otherwise not.\n\t\t\t\tvar parseAsInline = !(isStartOfInline && i === 0);\n\t\t\t\tvar textToParse = accumulatedText;\n\t\t\t\tif (pluginOpts.renderWikiTextPragma !== \"\") {\n\t\t\t\t\ttextToParse = pluginOpts.renderWikiTextPragma + \"\\n\" + textToParse;\n\t\t\t\t}\n\t\t\t\tvar wikiParser = $tw.wiki.parseText(\"text/vnd.tiddlywiki\", textToParse, {\n\t\t\t\t\tparseAsInline: parseAsInline\n\t\t\t\t});\n\t\t\t\tvar rs = wikiParser.tree;\n\n\t\t\t\t// If we parsed as a block, but the root element the WikiText parser gave is a paragraph,\n\t\t\t\t// we should discard the paragraph, since the way Remarkable nests its nodes, this \"inline\"\n\t\t\t\t// node is always inside something else that's a block-level element\n\t\t\t\tif (!parseAsInline\n\t\t\t\t\t&& rs.length === 1\n\t\t\t\t\t&& rs[0].type === \"element\"\n\t\t\t\t\t&& rs[0].tag === \"p\"\n\t\t\t\t) {\n\t\t\t\t\trs = rs[0].children;\n\t\t\t\t}\n\n\t\t\t\t// If the original text element started with a space, add it back in\n\t\t\t\tif (rs.length > 0\n\t\t\t\t\t&& rs[0].type === \"text\"\n\t\t\t\t\t&& (accumulatedText[0] === \" \" || accumulatedText[0] === \"\\n\")\n\t\t\t\t) {\n\t\t\t\t\trs[0].text = \" \" + rs[0].text;\n\t\t\t\t}\n\t\t\t\tout = out.concat(rs);\n\t\t\t}\n\t\t\taccumulatedText = '';\n\t\t}\n\t}\n\treturn out;\n}\n\nvar MarkdownParser = function(type, text, options) {\n\tvar tree = md.parse(text, {});\n\t//console.debug(tree);\n\ttree = convertNodes(tree);\n\t//console.debug(tree);\n\n\tthis.tree = tree;\n};\n\nexports[\"text/x-markdown\"] = MarkdownParser;\n\n})();\n",
"type": "application/javascript",
"module-type": "parser"
}
}
}
{
"tiddlers": {
"$:/core/macros/tabs": {
"title": "$:/core/macros/tabs",
"tags": "$:/tags/Macro",
"text": "\\define tabs(tabsList,default,state:\"$:/state/tab\",class,template,buttonTemplate,retain,actions,explicitState)\n<$set name=\"qualifiedState\" value=<<qualify \"$state$\">>>\n<$set name=\"tabsState\" filter=\"[<__explicitState__>minlength[1]] ~[<qualifiedState>]\">\n<div class=\"tc-tab-set $class$\">\n<div class=\"tc-tab-buttons $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\" storyview=\"pop\"><$set name=\"save-currentTiddler\" value=<<currentTiddler>>><$tiddler tiddler=<<currentTab>>><$button set=<<tabsState>> setTo=<<currentTab>> default=\"$default$\" selectedClass=\"tc-tab-selected\" tooltip={{!!tooltip}}>\n<$tiddler tiddler=<<save-currentTiddler>>>\n<$set name=\"tv-wikilinks\" value=\"no\">\n<$transclude tiddler=\"$buttonTemplate$\" mode=\"inline\">\n<$transclude tiddler=<<currentTab>> field=\"caption\">\n<$macrocall $name=\"currentTab\" $type=\"text/plain\" $output=\"text/plain\"/>\n</$transclude>\n</$transclude>\n</$set></$tiddler>$actions$</$button><span class=\"wltc-link-to-tab\"><$link overrideClass=\"\" to=<<currentTiddler>> >{{$:/core/images/link}}</$link></span></$tiddler></$set></$list>\n</div>\n<div class=\"tc-tab-divider $class$\"/>\n<div class=\"tc-tab-content $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\">\n\n<$reveal type=\"match\" state=<<tabsState>> text=<<currentTab>> default=\"$default$\" retain=\"\"\"$retain$\"\"\">\n\n<$transclude tiddler=\"$template$\" mode=\"block\">\n\n<$transclude tiddler=<<currentTab>> mode=\"block\"/>\n\n</$transclude>\n\n</$reveal>\n\n</$list>\n</div>\n</div>\n</$set>\n</$set>\n\\end\n"
},
"$:/core/ui/ControlPanel/Settings/link-to-tabs": {
"title": "$:/core/ui/ControlPanel/Settings/link-to-tabs",
"caption": "Link-to-Tabs plugin",
"created": "20190712133607244",
"modified": "20190714104631250",
"tags": "$:/tags/ControlPanel/Settings",
"type": "text/vnd.tiddlywiki",
"text": "<$checkbox tiddler=\"$:/plugins/wikilabs/link-to-tabs/config\" field=\"show-all-links\" checked=\"inline-block\" unchecked=\"none\" default=\"none\"> Show internal tab link for ''all tabs''</$checkbox>\n\n<$checkbox tiddler=\"$:/plugins/wikilabs/link-to-tabs/config\" field=\"show-single-link\" checked=\"inline-block\" unchecked=\"none\" default=\"inline-block\"> Show internal tab link for ''selected tabs''</$checkbox>\n\n<$checkbox tiddler=\"$:/plugins/wikilabs/link-to-tabs/config\" field=\"initial-opacity\" checked=\"0\" unchecked=\"0.7\" default=\"0.7\"> Tab links are initially hidden and need mouse hover to become visible.</$checkbox> The transition time in seconds is: <$edit-text tiddler=\"$:/plugins/wikilabs/link-to-tabs/config\" field=\"transition\" default=\"0.3\"/>\n\n<$button message=\"tm-delete-tiddler\" param=\"$:/plugins/wikilabs/link-to-tabs/config\">\nReset to Default!\n</$button>"
},
"$:/plugins/wikilabs/link-to-tabs/config": {
"title": "$:/plugins/wikilabs/link-to-tabs/config",
"created": "20190712133008077",
"initial-opacity": "0.7",
"modified": "20190714104541701",
"show-all-links": "none",
"show-single-link": "inline-block",
"transition": "0.3",
"type": "text/vnd.tiddlywiki",
"text": "This tiddler is used to configure the \"Link-to-tabs\" plugin behaviour. \n\nThere are 4 fields, which are used by [[$:/plugins/wikilabs/link-to-tabs/styles]] enable and disable the internal links. \n\n* show-all-links: {{!!show-all-links}}\n* show-single-link: {{!!show-single-link}}\n* initial-opacity: {{!!initial-opacity}}\n* transition time in seconds: {{!!transition}}\n"
},
"$:/plugins/wikilabs/link-to-tabs/history": {
"title": "$:/plugins/wikilabs/link-to-tabs/history",
"text": "V 2.0.1 - 2020-12-25\n\n* update license\n\nV 2.0.0 - 2020.12.05\n\n* Update $:/core/macros/tabs to V5.1.23\n\nV 1.1.1 - 2020.01.19\n\n* Update license link/text\n\nV 1.1.0 - 2019.07.14\n\n* Add new option: Initially hide link\n** Transition time from hidden to visible is adjustable\n* Added: \"Reset to Default\" button\n\nV 1.0.1 - 2019.02.18\n\n* link-to-tabs works in drop-down elements now.\n\nV 1.0.0 - 2019.02.14\n\n* Use core tabs-macro from TW 5.1.19\n\nV <1.0.0\n\n* Use core tabs-macro from TW 5.1.15\n"
},
"$:/plugins/wikilabs/link-to-tabs/license": {
"title": "$:/plugins/wikilabs/link-to-tabs/license",
"text": "[[Link-to-Tabs-Macro|https://wikilabs.github.io/#link-to-tabs]] (c) Mario Pietsch - 2016-2021\n\nhttps://opensource.org/licenses/BSD-3-Clause\n"
},
"$:/plugins/wikilabs/link-to-tabs/styles": {
"title": "$:/plugins/wikilabs/link-to-tabs/styles",
"created": "20190712133348541",
"modified": "20190714104306483",
"tags": "$:/tags/Stylesheet",
"type": "text/vnd.tiddlywiki",
"text": "<pre>\n\n.wltc-link-to-tab {\n display: {{$:/plugins/wikilabs/link-to-tabs/config!!show-all-links}};\n position: relative;\n top: -1em;\n left: -1.3em;\n font-size: 0.7em;\n opacity: {{$:/plugins/wikilabs/link-to-tabs/config!!initial-opacity}};\n margin-right: -1em;\n}\n\n.wltc-link-to-tab svg{\n width: 1.4em;\n height: 1.4em;\n}\n\n.wltc-link-to-tab:hover {\n opacity: 1;\n transition:opacity {{$:/plugins/wikilabs/link-to-tabs/config!!transition}}s;\n transition-timing-function: cubic-bezier(1,-0.06,.39,.89);\n}\n\n.tc-tab-selected + .wltc-link-to-tab {\n display: {{$:/plugins/wikilabs/link-to-tabs/config!!show-single-link}};\n}\n\n.tc-vertical > .wltc-link-to-tab {\n top: -1.9em;\n left: 0;\n height: 0;\n float: right;\n}\n\n.tc-search-results .wltc-link-to-tab a {\n display: contents;\n padding: 0;\n}\n\n</pre>"
},
"$:/plugins/wikilabs/link-to-tabs/readme": {
"title": "$:/plugins/wikilabs/link-to-tabs/readme",
"text": "This plugin adds a little link icon to every tab.\n\n''Important:'' This plugin changes the core tabs macro.\n\n! Lint-to-Tabs Settings\n\n{{$:/core/ui/ControlPanel/Settings/link-to-tabs}}"
}
}
}
A Roam-like experience in a free, downloadable file
$:/config/OfficialPluginLibrary
$:/core/ui/DefaultSearchResultList
$:/core/ui/ControlPanel/Plugins/Add/Plugins
$:/core/ui/ControlPanel/Plugins/Add/Themes
$:/core/ui/ControlPanel/Saving
$:/core/ui/ControlPanel/Saving/GitHub
$:/core/ui/DefaultSearchResultList
$:/core/ui/SideBar/Recent
$:/themes/tiddlywiki/snowwhite
{
"tiddlers": {
"$:/themes/tiddlywiki/snowwhite/base": {
"title": "$:/themes/tiddlywiki/snowwhite/base",
"tags": "[[$:/tags/Stylesheet]]",
"text": "\\define sidebarbreakpoint-minus-one()\n<$text text={{{ [{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}removesuffix[px]subtract[1]addsuffix[px]] ~[{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}] }}}/>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\n\n.tc-sidebar-header {\n\ttext-shadow: 0 1px 0 <<colour sidebar-foreground-shadow>>;\n}\n\n.tc-tiddler-info {\n\t<<box-shadow \"inset 1px 2px 3px rgba(0,0,0,0.1)\">>\n}\n\n@media screen {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow \"1px 1px 5px rgba(0, 0, 0, 0.3)\">>\n\t}\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow none>>\n\t}\n}\n\n.tc-page-controls button svg, .tc-tiddler-controls button svg, .tc-topbar button svg {\n\t<<transition \"fill 150ms ease-in-out\">>\n}\n\n.tc-tiddler-controls button.tc-selected,\n.tc-page-controls button.tc-selected {\n\t<<filter \"drop-shadow(0px -1px 2px rgba(0,0,0,0.25))\">>\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-edit-tags {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-tiddler-frame .tc-edit-tags input.tc-edit-texteditor {\n\t<<box-shadow \"none\">>\n\tborder: none;\n\toutline: none;\n}\n\ntextarea.tc-edit-texteditor {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\ncanvas.tc-edit-bitmapeditor {\n\t<<box-shadow \"2px 2px 5px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-drop-down {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-block-dropdown {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-modal {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n}\n\n.tc-modal-footer {\n\tborder-radius: 0 0 6px 6px;\n\t<<box-shadow \"inset 0 1px 0 #fff\">>;\n}\n\n\n.tc-alert {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.6)\">>\n}\n\n.tc-notification {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n\ttext-shadow: 0 1px 0 rgba(255,255,255, 0.8);\n}\n\n.tc-sidebar-lists .tc-tab-set .tc-tab-divider {\n\tborder-top: none;\n\theight: 1px;\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.0) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.01) 0%, rgba(0,0,0,0.1) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.05) 0%, rgba(255,255,255,0.05) 100%\">>\n}\n\n.tc-message-box img {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n\n.tc-plugin-info {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n"
}
}
}
{
"tiddlers": {
"$:/themes/tiddlywiki/vanilla/themetweaks": {
"title": "$:/themes/tiddlywiki/vanilla/themetweaks",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ThemeTweaks/ThemeTweaks}}",
"text": "\\define lingo-base() $:/language/ThemeTweaks/\n\n\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n\\define backgroundimage-dropdown()\n<div class=\"tc-drop-down-wrapper\">\n<$button popup=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">> class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">> type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n<div class=\"tc-drop-down\">\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"\n\t$value=<<imageTitle>>\n/>\n\n\"\"\"/>\n</div>\n</$reveal>\n</div>\n\\end\n\n\\define backgroundimageattachment-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\" default=\"scroll\">\n<option value=\"scroll\"><<lingo Settings/BackgroundImageAttachment/Scroll>></option>\n<option value=\"fixed\"><<lingo Settings/BackgroundImageAttachment/Fixed>></option>\n</$select>\n\\end\n\n\\define backgroundimagesize-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\" default=\"scroll\">\n<option value=\"auto\"><<lingo Settings/BackgroundImageSize/Auto>></option>\n<option value=\"cover\"><<lingo Settings/BackgroundImageSize/Cover>></option>\n<option value=\"contain\"><<lingo Settings/BackgroundImageSize/Contain>></option>\n</$select>\n\\end\n\n<<lingo ThemeTweaks/Hint>>\n\n! <<lingo Options>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><<lingo Options/SidebarLayout>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><option value=\"fixed-fluid\"><<lingo Options/SidebarLayout/Fixed-Fluid>></option><option value=\"fluid-fixed\"><<lingo Options/SidebarLayout/Fluid-Fixed>></option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><<lingo Options/StickyTitles>></$link><br>//<<lingo Options/StickyTitles/Hint>>// |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><option value=\"no\">{{$:/language/No}}</option><option value=\"yes\">{{$:/language/Yes}}</option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><<lingo Options/CodeWrapping>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><option value=\"pre\">{{$:/language/No}}</option><option value=\"pre-wrap\">{{$:/language/Yes}}</option></$select> |\n\n! <<lingo Settings>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"><<lingo Settings/FontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\"><<lingo Settings/CodeFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\"><<lingo Settings/EditorFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"><<lingo Settings/BackgroundImage>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" default=\"\" tag=\"input\"/> |<<backgroundimage-dropdown>> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\"><<lingo Settings/BackgroundImageAttachment>></$link> |<<backgroundimageattachment-dropdown>> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\"><<lingo Settings/BackgroundImageSize>></$link> |<<backgroundimagesize-dropdown>> | |\n\n! <<lingo Metrics>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\"><<lingo Metrics/FontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\"><<lingo Metrics/LineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\"><<lingo Metrics/BodyFontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\"><<lingo Metrics/BodyLineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\"><<lingo Metrics/StoryLeft>></$link><br>//<<lingo Metrics/StoryLeft/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\"><<lingo Metrics/StoryTop>></$link><br>//<<lingo Metrics/StoryTop/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\"><<lingo Metrics/StoryRight>></$link><br>//<<lingo Metrics/StoryRight/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\"><<lingo Metrics/StoryWidth>></$link><br>//<<lingo Metrics/StoryWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"><<lingo Metrics/TiddlerWidth>></$link><br>//<<lingo Metrics/TiddlerWidth/Hint>>//<br> |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\"><<lingo Metrics/SidebarBreakpoint>></$link><br>//<<lingo Metrics/SidebarBreakpoint/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\"><<lingo Metrics/SidebarWidth>></$link><br>//<<lingo Metrics/SidebarWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\" default=\"\" tag=\"input\"/> |\n"
},
"$:/themes/tiddlywiki/vanilla/base": {
"title": "$:/themes/tiddlywiki/vanilla/base",
"tags": "[[$:/tags/Stylesheet]]",
"text": "\\define custom-background-datauri()\n<$set name=\"background\" value={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}>\n<$list filter=\"[<background>is[image]]\">\n`background: url(`\n<$list filter=\"[<background>!has[_canonical_uri]]\">\n`\"`<$macrocall $name=\"datauri\" title={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}/>`\"`\n</$list>\n<$list filter=\"[<background>has[_canonical_uri]]\">\n`\"`<$view tiddler={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}} field=\"_canonical_uri\"/>`\"`\n</$list>\n`) center center;`\n`background-attachment: `{{$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment}}`;\n-webkit-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-moz-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-o-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\nbackground-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;`\n</$list>\n</$set>\n\\end\n\n\\define sidebarbreakpoint()\n<$text text={{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}/>\n\\end\n\n\\define sidebarbreakpoint-minus-one()\n<$text text={{{ [{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}removesuffix[px]subtract[1]addsuffix[px]] ~[{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}] }}}/>\n\\end\n\n\\define if-fluid-fixed(text,hiddenSidebarText)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" type=\"match\" text=\"fluid-fixed\">\n$text$\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">\n$hiddenSidebarText$\n</$reveal>\n</$reveal>\n\\end\n\n\\define if-editor-height-fixed(then,else)\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n$then$\n</$reveal>\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n$else$\n</$reveal>\n\\end\n\n\\define set-type-selector-min-width()\n<$set name=\"typeLength\" value={{{ [all[shadows+tiddlers]prefix[$:/language/Docs/Types/]get[name]length[]maxall[]] }}}>\n\n\t.tc-type-selector-dropdown-wrapper {\n\t\tmin-width: calc(<<typeLength>>ch + 4em);\n\t}\n\n\t.tc-type-selector-dropdown-wrapper input.tc-edit-typeeditor {\n\t\tmin-width: <<typeLength>>ch;\n\t}\n\n</$set>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n/*\n** Start with the normalize CSS reset, and then belay some of its effects\n*/\n\n{{$:/themes/tiddlywiki/vanilla/reset}}\n\n*, input[type=\"search\"] {\n\tbox-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\t-webkit-box-sizing: border-box;\n}\n\ninput[type=\"search\"] {\n outline-offset: initial;\n}\n\nhtml button {\n\tline-height: 1.2;\n\tcolor: <<colour button-foreground>>;\n\tfill: <<colour button-foreground>>;\n\tbackground: <<colour button-background>>;\n\tborder-color: <<colour button-border>>;\n}\n\n/*\n** Basic element styles\n*/\n\nhtml, body {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/fontfamily}};\n\ttext-rendering: optimizeLegibility; /* Enables kerning and ligatures etc. */\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\nhtml:-webkit-full-screen {\n\tbackground-color: <<colour page-background>>;\n}\n\nbody.tc-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/fontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/lineheight}};\n\tword-wrap: break-word;\n\t<<custom-background-datauri>>\n\tcolor: <<colour foreground>>;\n\tbackground-color: <<colour page-background>>;\n\tfill: <<colour foreground>>;\n}\n\n<<if-background-attachment \"\"\"\n\nbody.tc-body {\n background-color: transparent;\n}\n\n\"\"\">>\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n\tfont-size: 2em;\n}\n\nh1, h2, h3, h4, h5, h6 {\n\tline-height: 1.2;\n\tfont-weight: 300;\n}\n\npre {\n\tdisplay: block;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n\tword-break: normal;\n\tword-wrap: break-word;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tbackground-color: <<colour pre-background>>;\n\tborder: 1px solid <<colour pre-border>>;\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\ncode {\n\tcolor: <<colour code-foreground>>;\n\tbackground-color: <<colour code-background>>;\n\tborder: 1px solid <<colour code-border>>;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\nblockquote {\n\tborder-left: 5px solid <<colour blockquote-bar>>;\n\tmargin-left: 25px;\n\tpadding-left: 10px;\n\tquotes: \"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n}\n\nblockquote > div {\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n}\n\nblockquote.tc-big-quote {\n\tfont-family: Georgia, serif;\n\tposition: relative;\n\tbackground: <<colour pre-background>>;\n\tborder-left: none;\n\tmargin-left: 50px;\n\tmargin-right: 50px;\n\tpadding: 10px;\n border-radius: 8px;\n}\n\nblockquote.tc-big-quote cite:before {\n\tcontent: \"\\2014 \\2009\";\n}\n\nblockquote.tc-big-quote:before {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: open-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n left: -50px;\n top: 42px;\n}\n\nblockquote.tc-big-quote:after {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: close-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n right: -80px;\n bottom: -20px;\n}\n\ndl dt {\n\tfont-weight: bold;\n\tmargin-top: 6px;\n}\n\nbutton, textarea, input, select {\n\toutline-color: <<colour primary>>;\n}\n\ntextarea,\ninput[type=text],\ninput[type=search],\ninput[type=\"\"],\ninput:not([type]) {\n\tcolor: <<colour foreground>>;\n\tbackground: <<colour background>>;\n}\n\ninput[type=\"checkbox\"] {\n vertical-align: middle;\n}\n\ninput[type=\"search\"]::-webkit-search-decoration,\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-results-button,\ninput[type=\"search\"]::-webkit-search-results-decoration {\n\t-webkit-appearance:none;\n}\n\n.tc-muted {\n\tcolor: <<colour muted-foreground>>;\n}\n\nsvg.tc-image-button {\n\tpadding: 0px 1px 1px 0px;\n}\n\n.tc-icon-wrapper > svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\nkbd {\n\tdisplay: inline-block;\n\tpadding: 3px 5px;\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tcolor: <<colour foreground>>;\n\tvertical-align: middle;\n\tbackground-color: <<colour background>>;\n\tborder: solid 1px <<colour muted-foreground>>;\n\tborder-bottom-color: <<colour muted-foreground>>;\n\tborder-radius: 3px;\n\tbox-shadow: inset 0 -1px 0 <<colour muted-foreground>>;\n}\n\n::selection {\n\tbackground-color: Highlight;\n\tcolor: HighlightText;\n\tbackground-color: <<colour selection-background>>;\n\tcolor: <<colour selection-foreground>>;\n}\n\n/*\nMarkdown likes putting code elements inside pre elements\n*/\npre > code {\n\tpadding: 0;\n\tborder: none;\n\tbackground-color: inherit;\n\tcolor: inherit;\n}\n\ntable {\n\tborder: 1px solid <<colour table-border>>;\n\twidth: auto;\n\tmax-width: 100%;\n\tcaption-side: bottom;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n\t/* next 2 elements needed, since normalize 8.0.1 */\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n}\n\ntable th, table td {\n\tpadding: 0 7px 0 7px;\n\tborder-top: 1px solid <<colour table-border>>;\n\tborder-left: 1px solid <<colour table-border>>;\n}\n\ntable thead tr td, table th {\n\tbackground-color: <<colour table-header-background>>;\n\tfont-weight: bold;\n}\n\ntable tfoot tr td {\n\tbackground-color: <<colour table-footer-background>>;\n}\n\n.tc-csv-table {\n\twhite-space: nowrap;\n}\n\n.tc-tiddler-frame img,\n.tc-tiddler-frame svg,\n.tc-tiddler-frame canvas,\n.tc-tiddler-frame embed,\n.tc-tiddler-frame iframe {\n\tmax-width: 100%;\n}\n\n.tc-tiddler-body > embed,\n.tc-tiddler-body > iframe {\n\twidth: 100%;\n\theight: 600px;\n}\n\n/*\n** Links\n*/\n\nbutton.tc-tiddlylink,\na.tc-tiddlylink {\n\ttext-decoration: none;\n\tfont-weight: 500;\n\tcolor: <<colour tiddler-link-foreground>>;\n\t-webkit-user-select: inherit; /* Otherwise the draggable attribute makes links impossible to select */\n}\n\n.tc-sidebar-lists a.tc-tiddlylink {\n\tcolor: <<colour sidebar-tiddler-link-foreground>>;\n}\n\n.tc-sidebar-lists a.tc-tiddlylink:hover {\n\tcolor: <<colour sidebar-tiddler-link-foreground-hover>>;\n}\n\nbutton.tc-tiddlylink:hover,\na.tc-tiddlylink:hover {\n\ttext-decoration: underline;\n}\n\na.tc-tiddlylink-resolves {\n}\n\na.tc-tiddlylink-shadow {\n\tfont-weight: bold;\n}\n\na.tc-tiddlylink-shadow.tc-tiddlylink-resolves {\n\tfont-weight: normal;\n}\n\na.tc-tiddlylink-missing {\n\tfont-style: italic;\n}\n\na.tc-tiddlylink-external {\n\ttext-decoration: underline;\n\tcolor: <<colour external-link-foreground>>;\n\tbackground-color: <<colour external-link-background>>;\n}\n\na.tc-tiddlylink-external:visited {\n\tcolor: <<colour external-link-foreground-visited>>;\n\tbackground-color: <<colour external-link-background-visited>>;\n}\n\na.tc-tiddlylink-external:hover {\n\tcolor: <<colour external-link-foreground-hover>>;\n\tbackground-color: <<colour external-link-background-hover>>;\n}\n\n.tc-drop-down a.tc-tiddlylink:hover {\n\tcolor: <<colour tiddler-link-background>>;\n}\n\n/*\n** Drag and drop styles\n*/\n\n.tc-tiddler-dragger {\n\tposition: relative;\n\tz-index: -10000;\n}\n\n.tc-tiddler-dragger-inner {\n\tposition: absolute;\n\ttop: -1000px;\n\tleft: -1000px;\n\tdisplay: inline-block;\n\tpadding: 8px 20px;\n\tfont-size: 16.9px;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: <<colour dragger-foreground>>;\n\ttext-shadow: 0 1px 0 rgba(0, 0, 0, 1);\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour dragger-background>>;\n\tborder-radius: 20px;\n}\n\n.tc-tiddler-dragger-cover {\n\tposition: absolute;\n\tbackground-color: <<colour page-background>>;\n}\n\n.tc-dropzone {\n\tposition: relative;\n}\n\n.tc-dropzone.tc-dragover:before {\n\tz-index: 10000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour dropzone-background>>;\n\ttext-align: center;\n\tcontent: \"<<lingo DropMessage>>\";\n}\n\n.tc-droppable > .tc-droppable-placeholder {\n\tdisplay: none;\n}\n\n.tc-droppable.tc-dragover > .tc-droppable-placeholder {\n\tdisplay: block;\n\tborder: 2px dashed <<colour dropzone-background>>;\n}\n\n.tc-draggable {\n\tcursor: move;\n}\n\n.tc-sidebar-tab-open .tc-droppable-placeholder, .tc-tagged-draggable-list .tc-droppable-placeholder,\n.tc-links-draggable-list .tc-droppable-placeholder {\n\tline-height: 2em;\n\theight: 2em;\n}\n\n.tc-sidebar-tab-open-item {\n\tposition: relative;\n}\n\n.tc-sidebar-tab-open .tc-btn-invisible.tc-btn-mini svg {\n\tfont-size: 0.7em;\n\tfill: <<colour muted-foreground>>;\n}\n\n/*\n** Plugin reload warning\n*/\n\n.tc-plugin-reload-warning {\n\tz-index: 1000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour alert-background>>;\n\ttext-align: center;\n}\n\n/*\n** Buttons\n*/\n\nbutton svg, button img, label svg, label img {\n\tvertical-align: middle;\n}\n\n.tc-btn-invisible {\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\tcursor: pointer;\n\tcolor: <<colour foreground>>;\n\tfill: <<colour foreground>>;\n}\n\n.tc-btn-boxed {\n\tfont-size: 0.6em;\n\tpadding: 0.2em;\n\tmargin: 1px;\n\tbackground: none;\n\tborder: 1px solid <<colour tiddler-controls-foreground>>;\n\tborder-radius: 0.25em;\n}\n\nhtml body.tc-body .tc-btn-boxed svg {\n\tfont-size: 1.6666em;\n}\n\n.tc-btn-boxed:hover {\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n}\n\nhtml body.tc-body .tc-btn-boxed:hover svg {\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded {\n\tfont-size: 0.5em;\n\tline-height: 2;\n\tpadding: 0em 0.3em 0.2em 0.4em;\n\tmargin: 1px;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n\tborder-radius: 2em;\n}\n\nhtml body.tc-body .tc-btn-rounded svg {\n\tfont-size: 1.6666em;\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded:hover {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tcolor: <<colour muted-foreground>>;\n}\n\nhtml body.tc-body .tc-btn-rounded:hover svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-icon svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-text {\n\tpadding: 0;\n\tmargin: 0;\n}\n\n/* used for documentation \"fake\" buttons */\n.tc-btn-standard {\n\tline-height: 1.8;\n\tcolor: #667;\n\tbackground-color: #e0e0e0;\n\tborder: 1px solid #888;\n\tpadding: 2px 1px 2px 1px;\n\tmargin: 1px 4px 1px 4px;\n}\n\n.tc-btn-big-green {\n\tdisplay: inline-block;\n\tpadding: 8px;\n\tmargin: 4px 8px 4px 8px;\n\tbackground: <<colour download-background>>;\n\tcolor: <<colour download-foreground>>;\n\tfill: <<colour download-foreground>>;\n\tborder: none;\n\tborder-radius: 2px;\n\tfont-size: 1.2em;\n\tline-height: 1.4em;\n\ttext-decoration: none;\n}\n\n.tc-btn-big-green svg,\n.tc-btn-big-green img {\n\theight: 2em;\n\twidth: 2em;\n\tvertical-align: middle;\n\tfill: <<colour download-foreground>>;\n}\n\n.tc-primary-btn {\n \tbackground: <<colour primary>>;\n}\n\n.tc-sidebar-lists input {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-sidebar-lists button {\n\tcolor: <<colour sidebar-button-foreground>>;\n\tfill: <<colour sidebar-button-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini {\n\tcolor: <<colour sidebar-muted-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini:hover {\n\tcolor: <<colour sidebar-muted-foreground-hover>>;\n}\n\n.tc-sidebar-lists button small {\n\tcolor: <<colour foreground>>;\n}\n\nbutton svg.tc-image-button, button .tc-image-button img {\n\theight: 1em;\n\twidth: 1em;\n}\n\n.tc-unfold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 100%;\n\twidth: calc(100% + 2px);\n\tmargin-left: -43px;\n\ttext-align: center;\n\tborder-top: 2px solid <<colour tiddler-info-background>>;\n\tmargin-top: 4px;\n}\n\n.tc-unfold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n\tborder-top: 2px solid <<colour tiddler-info-border>>;\n}\n\n.tc-unfold-banner svg, .tc-fold-banner svg {\n\theight: 0.75em;\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-unfold-banner:hover svg, .tc-fold-banner:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n.tc-fold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 23px;\n\ttext-align: center;\n\tmargin-left: -35px;\n\ttop: 6px;\n\tbottom: 6px;\n}\n\n.tc-fold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-unfold-banner {\n\t\tposition: static;\n\t\twidth: calc(100% + 59px);\n\t}\n\n\t.tc-fold-banner {\n\t\twidth: 16px;\n\t\tmargin-left: -16px;\n\t\tfont-size: 0.75em;\n\t}\n\n}\n\n/*\n** Tags and missing tiddlers\n*/\n\n.tc-tag-list-item {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin-right: 7px;\n}\n\n.tc-tags-wrapper {\n\tmargin: 4px 0 14px 0;\n}\n\n.tc-missing-tiddler-label {\n\tfont-style: italic;\n\tfont-weight: normal;\n\tdisplay: inline-block;\n\tfont-size: 11.844px;\n\tline-height: 14px;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n}\n\n.tc-block-tags-dropdown > .tc-btn-invisible:hover {\n\tbackground-color: <<colour primary>>;\n}\n\nbutton.tc-tag-label, span.tc-tag-label {\n\tdisplay: inline-block;\n\tpadding: 0.16em 0.7em;\n\tfont-size: 0.9em;\n\tfont-weight: 400;\n\tline-height: 1.2em;\n\tcolor: <<colour tag-foreground>>;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour tag-background>>;\n\tborder-radius: 1em;\n}\n\n.tc-sidebar-scrollable .tc-tag-label {\n\ttext-shadow: none;\n}\n\n.tc-untagged-separator {\n\twidth: 10em;\n\tleft: 0;\n\tmargin-left: 0;\n\tborder: 0;\n\theight: 1px;\n\tbackground: <<colour tab-divider>>;\n}\n\nbutton.tc-untagged-label {\n\tbackground-color: <<colour untagged-background>>;\n}\n\n.tc-tag-label svg, .tc-tag-label img {\n\theight: 1em;\n\twidth: 1em;\n\tmargin-right: 3px; \n\tmargin-bottom: 1px;\n\tvertical-align: bottom;\n}\n\n.tc-edit-tags button.tc-remove-tag-button svg {\n\tfont-size: 0.7em;\n\tvertical-align: middle;\n}\n\n.tc-tag-manager-table .tc-tag-label {\n\twhite-space: normal;\n}\n\n.tc-tag-manager-tag {\n\twidth: 100%;\n}\n\nbutton.tc-btn-invisible.tc-remove-tag-button {\n\toutline: none;\n}\n\n.tc-tag-button-selected,\n.tc-list-item-selected a.tc-tiddlylink, a.tc-list-item-selected {\n\tbackground-color: <<colour primary>>;\n\tcolor: <<colour tiddler-background>>;\n}\n\n/*\n** Page layout\n*/\n\n.tc-topbar {\n\tposition: fixed;\n\tz-index: 1200;\n}\n\n.tc-topbar-left {\n\tleft: 29px;\n\ttop: 5px;\n}\n\n.tc-topbar-right {\n\ttop: 5px;\n\tright: 29px;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-topbar-right {\n\t\tright: 10px;\n\t}\n\n}\n\n.tc-topbar button {\n\tpadding: 8px;\n}\n\n.tc-topbar svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-topbar button:hover svg {\n\tfill: <<colour foreground>>;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-show-sidebar-btn svg.tc-image-chevron-left, .tc-hide-sidebar-btn svg.tc-image-chevron-right {\n\t\ttransform: rotate(-90deg);\n\t}\n\n}\n\n.tc-sidebar-header {\n\tcolor: <<colour sidebar-foreground>>;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-sidebar-header .tc-title a.tc-tiddlylink-resolves {\n\tfont-weight: 300;\n}\n\n.tc-sidebar-header .tc-sidebar-lists p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-sidebar-header .tc-missing-tiddler-label {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-advanced-search input {\n\twidth: 60%;\n}\n\n.tc-search a svg {\n\twidth: 1.2em;\n\theight: 1.2em;\n\tvertical-align: middle;\n}\n\n.tc-page-controls {\n\tmargin-top: 14px;\n\tfont-size: 1.5em;\n}\n\n.tc-page-controls .tc-drop-down {\n font-size: 1rem;\n}\n\n.tc-page-controls button {\n\tmargin-right: 0.5em;\n}\n\n.tc-page-controls a.tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-page-controls img {\n\twidth: 1em;\n}\n\n.tc-page-controls svg {\n\tfill: <<colour sidebar-controls-foreground>>;\n}\n\n.tc-page-controls button:hover svg, .tc-page-controls a:hover svg {\n\tfill: <<colour sidebar-controls-foreground-hover>>;\n}\n\n.tc-sidebar-lists .tc-menu-list-item {\n\twhite-space: nowrap;\n}\n\n.tc-menu-list-count {\n\tfont-weight: bold;\n}\n\n.tc-menu-list-subitem {\n\tpadding-left: 7px;\n}\n\n.tc-story-river {\n\tposition: relative;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-sidebar-header {\n\t\tpadding: 14px;\n\t\tmin-height: 32px;\n\t\tmargin-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\ttransition: min-height {{$:/config/AnimationDuration}}ms ease-in-out, padding-top {{$:/config/AnimationDuration}}ms ease-in-out, padding-bottom {{$:/config/AnimationDuration}}ms ease-in-out;\n\t}\n\t\n\t<<if-no-sidebar \"\"\"\n\n\t\t.tc-sidebar-header {\n\t\t\tmin-height: 0;\n\t\t\tpadding-top: 0;\n\t\t\tpadding-bottom: 0;\n\t\t}\n\n\t\"\"\">>\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tpadding: 0;\n\t}\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-message-box {\n\t\tmargin: 21px -21px 21px -21px;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tposition: fixed;\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t\tbottom: 0;\n\t\tright: 0;\n\t\toverflow-y: auto;\n\t\toverflow-x: auto;\n\t\t-webkit-overflow-scrolling: touch;\n\t\tmargin: 0 0 0 -42px;\n\t\tpadding: 71px 0 28px 42px;\n\t}\n\n\thtml[dir=\"rtl\"] .tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tright: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t}\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/storywidth}};\n\t\tpadding: 42px 42px 42px 42px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-story-river {\n\t\twidth: calc(100% - {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}});\n\t}\n\n\">>\n\n\t.tc-story-river.tc-static-story-river {\n\t\tmargin-right: 0;\n\t\tpadding-right: 42px;\n\t}\n\n}\n\n@media print {\n\n\tbody.tc-body {\n\t\tbackground-color: transparent;\n\t}\n\n\t.tc-sidebar-header, .tc-topbar {\n\t\tdisplay: none;\n\t}\n\n\t.tc-story-river {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t}\n\n\t.tc-story-river .tc-tiddler-frame {\n\t\tmargin: 0;\n\t\tborder: none;\n\t\tpadding: 0;\n\t}\n}\n\n/*\n** Tiddler styles\n*/\n\n.tc-tiddler-frame {\n\tposition: relative;\n\tmargin-bottom: 28px;\n\tbackground-color: <<colour tiddler-background>>;\n\tborder: 1px solid <<colour tiddler-border>>;\n}\n\n{{$:/themes/tiddlywiki/vanilla/sticky}}\n\n.tc-tiddler-info {\n\tpadding: 14px 42px 14px 42px;\n\tbackground-color: <<colour tiddler-info-background>>;\n\tborder-top: 1px solid <<colour tiddler-info-border>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-border>>;\n}\n\n.tc-tiddler-info p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-tiddler-info .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour tiddler-info-tab-background>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-tab-background>>;\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\n\t.tc-tiddler-info {\n\t\tpadding: 14px 14px 14px 14px;\n\t}\n\n}\n\n.tc-view-field-table {\n\twidth: 100%;\n}\n\n.tc-view-field-name {\n\twidth: 1%; /* Makes this column be as narrow as possible */\n\ttext-align: right;\n\tfont-style: italic;\n\tfont-weight: 200;\n}\n\n.tc-view-field-value {\n}\n\n@media (max-width: <<sidebarbreakpoint-minus-one>>) {\n\t.tc-tiddler-frame {\n\t\tpadding: 14px 14px 14px 14px;\n\t\tmargin-bottom: .5em;\n\t}\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -14px 0 -14px;\n\t}\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\t.tc-tiddler-frame {\n\t\tpadding: 28px 42px 42px 42px;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};\n\t\tborder-radius: 2px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\">>\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -42px 0 -42px;\n\t}\n}\n\n.tc-site-title,\n.tc-titlebar {\n\tfont-weight: 300;\n\tfont-size: 2.35em;\n\tline-height: 1.35em;\n\tcolor: <<colour tiddler-title-foreground>>;\n\tmargin: 0;\n}\n\n.tc-site-title {\n\tcolor: <<colour site-title-foreground>>;\n}\n\n.tc-tiddler-title-icon {\n\tvertical-align: middle;\n\tmargin-right: .1em;\n}\n\n.tc-system-title-prefix {\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-titlebar h2 {\n\tfont-size: 1em;\n\tdisplay: inline;\n}\n\n.tc-titlebar img {\n\theight: 1em;\n}\n\n.tc-subtitle {\n\tfont-size: 0.9em;\n\tcolor: <<colour tiddler-subtitle-foreground>>;\n\tfont-weight: 300;\n}\n\n.tc-subtitle .tc-tiddlylink {\n\tmargin-right: .3em;\n}\n\n.tc-tiddler-missing .tc-title {\n font-style: italic;\n font-weight: normal;\n}\n\n.tc-tiddler-frame .tc-tiddler-controls {\n\tfloat: right;\n}\n\n.tc-tiddler-controls .tc-drop-down {\n\tfont-size: 0.6em;\n}\n\n.tc-tiddler-controls .tc-drop-down .tc-drop-down {\n\tfont-size: 1em;\n}\n\n.tc-tiddler-controls > span > button,\n.tc-tiddler-controls > span > span > button,\n.tc-tiddler-controls > span > span > span > button {\n\tvertical-align: baseline;\n\tmargin-left:5px;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img,\n.tc-search button svg, .tc-search a svg {\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img {\n\theight: 0.75em;\n}\n\n.tc-search button svg, .tc-search a svg {\n height: 1.2em;\n width: 1.2em;\n margin: 0 0.25em;\n}\n\n.tc-tiddler-controls button.tc-selected svg,\n.tc-page-controls button.tc-selected svg {\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n}\n\n.tc-tiddler-controls button.tc-btn-invisible:hover svg,\n.tc-search button:hover svg, .tc-search a:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n@media print {\n\t.tc-tiddler-controls {\n\t\tdisplay: none;\n\t}\n}\n\n.tc-tiddler-help { /* Help prompts within tiddler template */\n\tcolor: <<colour muted-foreground>>;\n\tmargin-top: 14px;\n}\n\n.tc-tiddler-help a.tc-tiddlylink {\n\tcolor: <<colour very-muted-foreground>>;\n}\n\n.tc-tiddler-frame .tc-edit-texteditor {\n\twidth: 100%;\n\tmargin: 4px 0 4px 0;\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor,\n.tc-tiddler-frame iframe.tc-edit-texteditor {\n\tpadding: 3px 3px 3px 3px;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tline-height: 1.3em;\n\t-webkit-appearance: none;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor {\n\tbackground-color: <<colour tiddler-editor-background>>;\n}\n\n.tc-tiddler-frame iframe.tc-edit-texteditor {\n\tbackground-color: <<colour tiddler-background>>;\n}\n\n.tc-tiddler-frame .tc-binary-warning {\n\twidth: 100%;\n\theight: 5em;\n\ttext-align: center;\n\tpadding: 3em 3em 6em 3em;\n\tbackground: <<colour alert-background>>;\n\tborder: 1px solid <<colour alert-border>>;\n}\n\ncanvas.tc-edit-bitmapeditor {\n\tborder: 6px solid <<colour tiddler-editor-border-image>>;\n\tcursor: crosshair;\n\t-moz-user-select: none;\n\t-webkit-user-select: none;\n\t-ms-user-select: none;\n\tmargin-top: 6px;\n\tmargin-bottom: 6px;\n}\n\n.tc-edit-bitmapeditor-width {\n\tdisplay: block;\n}\n\n.tc-edit-bitmapeditor-height {\n\tdisplay: block;\n}\n\n.tc-tiddler-body {\n\tclear: both;\n}\n\n.tc-tiddler-frame .tc-tiddler-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}};\n}\n\n.tc-titlebar, .tc-tiddler-edit-title {\n\toverflow: hidden; /* https://github.com/Jermolene/TiddlyWiki5/issues/282 */\n}\n\nhtml body.tc-body.tc-single-tiddler-window {\n\tmargin: 1em;\n\tbackground: <<colour tiddler-background>>;\n}\n\n.tc-single-tiddler-window img,\n.tc-single-tiddler-window svg,\n.tc-single-tiddler-window canvas,\n.tc-single-tiddler-window embed,\n.tc-single-tiddler-window iframe {\n\tmax-width: 100%;\n}\n\n/*\n** Editor\n*/\n\n.tc-editor-toolbar {\n\tmargin-top: 8px;\n}\n\n.tc-editor-toolbar button {\n\tvertical-align: middle;\n\tbackground-color: <<colour tiddler-controls-foreground>>;\n\tcolor: <<colour tiddler-controls-foreground-selected>>;\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n\tborder-radius: 4px;\n\tpadding: 3px;\n\tmargin: 2px 0 2px 4px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-adjunct {\n\tmargin-left: 1px;\n\twidth: 1em;\n\tborder-radius: 8px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-start-group {\n\tmargin-left: 11px;\n}\n\n.tc-editor-toolbar button.tc-selected {\n\tbackground-color: <<colour primary>>;\n}\n\n.tc-editor-toolbar button svg {\n\twidth: 1.6em;\n\theight: 1.2em;\n}\n\n.tc-editor-toolbar button:hover {\n\tbackground-color: <<colour tiddler-controls-foreground-selected>>;\n\tfill: <<colour background>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more {\n\twhite-space: normal;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more button {\n\tdisplay: inline-block;\n\tpadding: 3px;\n\twidth: auto;\n}\n\n.tc-editor-toolbar .tc-search-results {\n\tpadding: 0;\n}\n\n/*\n** Adjustments for fluid-fixed mode\n*/\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n<<if-fluid-fixed text:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 0;\n\t\tposition: relative;\n\t\twidth: auto;\n\t\tleft: 0;\n\t\tmargin-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\tmargin-right: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tbottom: 0;\n\t\tright: 0;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\tbody.tc-body .tc-storyview-zoomin-tiddler {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 42px);\n\t}\n\n\"\"\" hiddenSidebarText:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 3em;\n\t\tmargin-right: 0;\n\t}\n\n\tbody.tc-body .tc-storyview-zoomin-tiddler {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 84px);\n\t}\n\n\"\"\">>\n\n}\n\n/*\n** Toolbar buttons\n*/\n\n.tc-page-controls svg.tc-image-new-button {\n fill: <<colour toolbar-new-button>>;\n}\n\n.tc-page-controls svg.tc-image-options-button {\n fill: <<colour toolbar-options-button>>;\n}\n\n.tc-page-controls svg.tc-image-save-button {\n fill: <<colour toolbar-save-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-info-button {\n fill: <<colour toolbar-info-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-edit-button {\n fill: <<colour toolbar-edit-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-close-button {\n fill: <<colour toolbar-close-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-delete-button {\n fill: <<colour toolbar-delete-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-cancel-button {\n fill: <<colour toolbar-cancel-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-done-button {\n fill: <<colour toolbar-done-button>>;\n}\n\n/*\n** Tiddler edit mode\n*/\n\n.tc-tiddler-edit-frame em.tc-edit {\n\tcolor: <<colour muted-foreground>>;\n\tfont-style: normal;\n}\n\n.tc-edit-type-dropdown a.tc-tiddlylink-missing {\n\tfont-style: normal;\n}\n\n.tc-type-selector .tc-edit-typeeditor {\n\twidth: auto;\n}\n\n.tc-type-selector-dropdown-wrapper {\n\tdisplay: inline-block;\n}\n\n<<set-type-selector-min-width>>\n\n.tc-edit-tags {\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tpadding: 4px 8px 4px 8px;\n}\n\n.tc-edit-add-tag {\n\tdisplay: inline-block;\n}\n\n.tc-edit-add-tag .tc-add-tag-name input {\n\twidth: 50%;\n}\n\n.tc-edit-add-tag .tc-keyboard {\n\tdisplay:inline;\n}\n\n.tc-edit-tags .tc-tag-label {\n\tdisplay: inline-block;\n}\n\n.tc-edit-tags-list {\n\tmargin: 14px 0 14px 0;\n}\n\n.tc-remove-tag-button {\n\tpadding-left: 4px;\n}\n\n.tc-tiddler-preview {\n\toverflow: auto;\n}\n\n.tc-tiddler-preview-preview {\n\tfloat: right;\n\twidth: 49%;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tmargin: 4px 0 3px 3px;\n\tpadding: 3px 3px 3px 3px;\n}\n\n<<if-editor-height-fixed then:\"\"\"\n\n.tc-tiddler-preview-preview {\n\toverflow-y: scroll;\n\theight: {{$:/config/TextEditor/EditorHeight/Height}};\n}\n\n\"\"\">>\n\n.tc-tiddler-frame .tc-tiddler-preview .tc-edit-texteditor {\n\twidth: 49%;\n}\n\n.tc-tiddler-frame .tc-tiddler-preview canvas.tc-edit-bitmapeditor {\n\tmax-width: 49%;\n}\n\n.tc-edit-fields {\n\twidth: 100%;\n}\n\n.tc-edit-fields.tc-edit-fields-small {\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n}\n\n.tc-edit-fields table, .tc-edit-fields tr, .tc-edit-fields td {\n\tborder: none;\n\tpadding: 4px;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(odd) {\n\tbackground-color: <<colour tiddler-editor-fields-odd>>;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(even) {\n\tbackground-color: <<colour tiddler-editor-fields-even>>;\n}\n\n.tc-edit-field-name {\n\ttext-align: right;\n}\n\n.tc-edit-field-value input {\n\twidth: 100%;\n}\n\n.tc-edit-field-remove {\n}\n\n.tc-edit-field-remove svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n\tvertical-align: middle;\n}\n\n.tc-edit-field-add-name-wrapper input.tc-edit-texteditor {\n\twidth: auto;\n}\n\n.tc-edit-field-add-name-wrapper {\n\tdisplay: inline-block;\n}\n\n.tc-edit-field-add-value {\n\tdisplay: inline-block;\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-edit-field-add-value {\n\t\twidth: 35%;\n\t}\n\n}\n\n.tc-edit-field-add-button {\n\tdisplay: inline-block;\n\twidth: 10%;\n}\n\n/*\n** Storyview Classes\n*/\n\n.tc-viewswitcher .tc-image-button {\n\tmargin-right: .3em;\n}\n\n.tc-storyview-zoomin-tiddler {\n\tposition: absolute;\n\tdisplay: block;\n\twidth: 100%;\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-storyview-zoomin-tiddler {\n\t\twidth: calc(100% - 84px);\n\t}\n\n}\n\n/*\n** Dropdowns\n*/\n\n.tc-btn-dropdown {\n\ttext-align: left;\n}\n\n.tc-btn-dropdown svg, .tc-btn-dropdown img {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-drop-down-wrapper {\n\tposition: relative;\n}\n\n.tc-drop-down {\n\tmin-width: 380px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\ttext-shadow: none;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-drop-down {\n\tmargin-left: 14px;\n}\n\n.tc-drop-down button svg, .tc-drop-down a svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-drop-down button.tc-btn-invisible:hover svg {\n\tfill: <<colour background>>;\n}\n\n.tc-drop-down .tc-drop-down-info {\n\tpadding-left: 14px;\n}\n\n.tc-drop-down p {\n\tpadding: 0 14px 0 14px;\n}\n\n.tc-drop-down svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-drop-down img {\n\twidth: 1em;\n}\n\n.tc-drop-down a, .tc-drop-down button {\n\tdisplay: block;\n\tpadding: 0 14px 0 14px;\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: <<colour foreground>>;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-tab-set .tc-tab-buttons button {\n\tdisplay: inline-block;\n width: auto;\n margin-bottom: 0px;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.tc-drop-down .tc-prompt {\n\tpadding: 0 14px;\n}\n\n.tc-drop-down .tc-chooser {\n\tborder: none;\n}\n\n.tc-drop-down .tc-chooser .tc-swatches-horiz {\n\tfont-size: 0.4em;\n\tpadding-left: 1.2em;\n}\n\n.tc-drop-down .tc-file-input-wrapper {\n\twidth: 100%;\n}\n\n.tc-drop-down .tc-file-input-wrapper button {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-drop-down a:hover, .tc-drop-down button:hover, .tc-drop-down .tc-file-input-wrapper:hover button {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-tab-buttons button {\n\tbackground-color: <<colour dropdown-tab-background>>;\n}\n\n.tc-drop-down .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour dropdown-tab-background-selected>>;\n\tborder-bottom: 1px solid <<colour dropdown-tab-background-selected>>;\n}\n\n.tc-drop-down-bullet {\n\tdisplay: inline-block;\n\twidth: 0.5em;\n}\n\n.tc-drop-down .tc-tab-contents a {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-block-dropdown-wrapper {\n\tposition: relative;\n}\n\n.tc-block-dropdown {\n\tposition: absolute;\n\tmin-width: 220px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\tz-index: 1000;\n\ttext-shadow: none;\n}\n\n.tc-block-dropdown.tc-search-drop-down {\n\tmargin-left: -12px;\n}\n\n.tc-block-dropdown a {\n\tdisplay: block;\n\tpadding: 4px 14px 4px 14px;\n}\n\n.tc-block-dropdown.tc-search-drop-down a {\n\tdisplay: block;\n\tpadding: 0px 10px 0px 10px;\n}\n\n.tc-drop-down .tc-dropdown-item-plain,\n.tc-block-dropdown .tc-dropdown-item-plain {\n\tpadding: 4px 14px 4px 7px;\n}\n\n.tc-drop-down .tc-dropdown-item,\n.tc-block-dropdown .tc-dropdown-item {\n\tpadding: 4px 14px 4px 7px;\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-block-dropdown a.tc-tiddlylink:hover {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-search-results {\n\tpadding: 0 7px 0 7px;\n}\n\n.tc-image-chooser, .tc-colour-chooser {\n\twhite-space: normal;\n}\n\n.tc-image-chooser a,\n.tc-colour-chooser a {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\ttext-align: center;\n\tposition: relative;\n}\n\n.tc-image-chooser a {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 2px;\n\tmargin: 2px;\n\twidth: 4em;\n\theight: 4em;\n}\n\n.tc-colour-chooser a {\n\tpadding: 3px;\n\twidth: 2em;\n\theight: 2em;\n\tvertical-align: middle;\n}\n\n.tc-image-chooser a:hover,\n.tc-colour-chooser a:hover {\n\tbackground: <<colour primary>>;\n\tpadding: 0px;\n\tborder: 3px solid <<colour primary>>;\n}\n\n.tc-image-chooser a svg,\n.tc-image-chooser a img {\n\tdisplay: inline-block;\n\twidth: auto;\n\theight: auto;\n\tmax-width: 3.5em;\n\tmax-height: 3.5em;\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n}\n\n/*\n** Modals\n*/\n\n.tc-modal-wrapper {\n\tposition: fixed;\n\toverflow: auto;\n\toverflow-y: scroll;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 900;\n}\n\n.tc-modal-backdrop {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 1000;\n\tbackground-color: <<colour modal-backdrop>>;\n}\n\n.tc-modal {\n\tz-index: 1100;\n\tbackground-color: <<colour modal-background>>;\n\tborder: 1px solid <<colour modal-border>>;\n}\n\n@media (max-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 1em;\n\t\tleft: 1em;\n\t\tright: 1em;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n@media (min-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 2em;\n\t\tleft: 25%;\n\t\twidth: 50%;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n.tc-modal-header {\n\tpadding: 9px 15px;\n\tborder-bottom: 1px solid <<colour modal-header-border>>;\n}\n\n.tc-modal-header h3 {\n\tmargin: 0;\n\tline-height: 30px;\n}\n\n.tc-modal-header img, .tc-modal-header svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-modal-body {\n\tpadding: 15px;\n}\n\n.tc-modal-footer {\n\tpadding: 14px 15px 15px;\n\tmargin-bottom: 0;\n\ttext-align: right;\n\tbackground-color: <<colour modal-footer-background>>;\n\tborder-top: 1px solid <<colour modal-footer-border>>;\n}\n\n\n/*\n** Centered modals\n*/\n.tc-modal-centered .tc-modal {\n\twidth: auto;\n\ttop: 50%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%) !important;\n}\n\n/*\n** Notifications\n*/\n\n.tc-notification {\n\tposition: fixed;\n\ttop: 14px;\n\tright: 42px;\n\tz-index: 1300;\n\tmax-width: 280px;\n\tpadding: 0 14px 0 14px;\n\tbackground-color: <<colour notification-background>>;\n\tborder: 1px solid <<colour notification-border>>;\n}\n\n/*\n** Tabs\n*/\n\n.tc-tab-set.tc-vertical {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tab-buttons {\n\tfont-size: 0.85em;\n\tpadding-top: 1em;\n\tmargin-bottom: -2px;\n}\n\n.tc-tab-buttons.tc-vertical {\n\tz-index: 100;\n\tdisplay: block;\n\tpadding-top: 14px;\n\tvertical-align: top;\n\ttext-align: right;\n\tmargin-bottom: inherit;\n\tmargin-right: -1px;\n\tmax-width: 33%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n}\n\n.tc-tab-buttons button.tc-tab-selected {\n\tcolor: <<colour tab-foreground-selected>>;\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-left: 1px solid <<colour tab-border-selected>>;\n\tborder-top: 1px solid <<colour tab-border-selected>>;\n\tborder-right: 1px solid <<colour tab-border-selected>>;\n}\n\n.tc-tab-buttons button {\n\tcolor: <<colour tab-foreground>>;\n\tpadding: 3px 5px 3px 5px;\n\tmargin-right: 0.3em;\n\tfont-weight: 300;\n\tborder: none;\n\tbackground: inherit;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-right: 1px solid <<colour tab-border>>;\n\tborder-top-left-radius: 2px;\n\tborder-top-right-radius: 2px;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button {\n\tdisplay: block;\n\twidth: 100%;\n\tmargin-top: 3px;\n\tmargin-right: 0;\n\ttext-align: right;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tborder-right: none;\n\tborder-top-left-radius: 2px;\n\tborder-bottom-left-radius: 2px;\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button.tc-tab-selected {\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-right: 1px solid <<colour tab-background-selected>>;\n}\n\n.tc-tab-divider {\n\tborder-top: 1px solid <<colour tab-divider>>;\n}\n\n.tc-tab-divider.tc-vertical {\n\tdisplay: none;\n}\n\n.tc-tab-content {\n\tmargin-top: 14px;\n}\n\n.tc-tab-content.tc-vertical {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-top: 0;\n\tpadding-left: 14px;\n\tborder-left: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 70%;\n\tflex: 1 0 70%;\n\toverflow: auto;\n}\n\n.tc-sidebar-lists .tc-tab-buttons {\n\tmargin-bottom: -1px;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tcolor: <<colour sidebar-tab-foreground-selected>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border-selected>>;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button {\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tcolor: <<colour sidebar-tab-foreground>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border>>;\n}\n\n.tc-sidebar-lists .tc-tab-divider {\n\tborder-top: 1px solid <<colour sidebar-tab-divider>>;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\tdisplay: block;\n\twidth: 100%;\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tborder-top: none;\n\tborder-left: none;\n\tborder-bottom: none;\n\tborder-right: 1px solid #ccc;\n\tmargin-bottom: inherit;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tborder: none;\n}\n\n/*\n** Manager\n*/\n\n.tc-manager-wrapper {\n\t\n}\n\n.tc-manager-controls {\n\t\n}\n\n.tc-manager-control {\n\tmargin: 0.5em 0;\n}\n\n.tc-manager-list {\n\twidth: 100%;\n\tborder-top: 1px solid <<colour muted-foreground>>;\n\tborder-left: 1px solid <<colour muted-foreground>>;\n\tborder-right: 1px solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item {\n\n}\n\n.tc-manager-list-item-heading {\n display: block;\n width: 100%;\n text-align: left;\t\n\tborder-bottom: 1px solid <<colour muted-foreground>>;\n\tpadding: 3px;\n}\n\n.tc-manager-list-item-heading-selected {\n\tfont-weight: bold;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n\tbackground-color: <<colour foreground>>;\n}\n\n.tc-manager-list-item-heading:hover {\n\tbackground: <<colour primary>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-manager-list-item-content {\n\tdisplay: flex;\n}\n\n.tc-manager-list-item-content-sidebar {\n flex: 1 0;\n background: <<colour tiddler-editor-background>>;\n border-right: 0.5em solid <<colour muted-foreground>>;\n border-bottom: 0.5em solid <<colour muted-foreground>>;\n white-space: nowrap;\n}\n\n.tc-manager-list-item-content-item-heading {\n\tdisplay: block;\n\twidth: 100%;\n\ttext-align: left;\n background: <<colour muted-foreground>>;\n\ttext-transform: uppercase;\n\tfont-size: 0.6em;\n\tfont-weight: bold;\n padding: 0.5em 0 0.5em 0;\n}\n\n.tc-manager-list-item-content-item-body {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-manager-list-item-content-item-body > pre {\n\tmargin: 0.5em 0 0.5em 0;\n\tborder: none;\n\tbackground: inherit;\n}\n\n.tc-manager-list-item-content-tiddler {\n flex: 3 1;\n border-left: 0.5em solid <<colour muted-foreground>>;\n border-right: 0.5em solid <<colour muted-foreground>>;\n border-bottom: 0.5em solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item-content-item-body > table {\n\tborder: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.tc-manager-list-item-content-item-body > table td {\n\tborder: none;\n}\n\n.tc-manager-icon-editor > button {\n\twidth: 100%;\n}\n\n.tc-manager-icon-editor > button > svg,\n.tc-manager-icon-editor > button > button {\n\twidth: 100%;\n\theight: auto;\n}\n\n/*\n** Import table\n*/\n\n.tc-import-table {\n\twidth: 100%;\n}\n\n.tc-import-table svg.tc-image-edit-button {\n\tmax-width: unset;\n}\n\n.tc-import-table th:first-of-type {\n\twidth: 10%;\n}\n\n.tc-import-table th:last-of-type {\n\twidth: 30%;\n}\n\n.tc-import-table .tc-row-disabled {\n\tbackground: <<colour very-muted-foreground>>10;\n\topacity: 0.8;\n}\n\n.tc-import-table .tc-row-warning {\n\tbackground: <<colour diff-delete-background>>50;\n}\n\n/*\n** Alerts\n*/\n\n.tc-alerts {\n\tposition: fixed;\n\ttop: 28px;\n\tleft: 0;\n\tright: 0;\n\tmax-width: 50%;\n\tz-index: 20000;\n}\n\n.tc-alert {\n\tposition: relative;\n\tmargin: 14px;\n\tpadding: 7px;\n\tborder: 1px solid <<colour alert-border>>;\n\tbackground-color: <<colour alert-background>>;\n}\n\n.tc-alert-toolbar {\n\tposition: absolute;\n\ttop: 7px;\n\tright: 7px;\n line-height: 0;\n}\n\n.tc-alert-toolbar svg {\n\tfill: <<colour alert-muted-foreground>>;\n}\n\n.tc-alert-subtitle {\n\tcolor: <<colour alert-muted-foreground>>;\n\tfont-weight: bold;\n font-size: 0.8em;\n margin-bottom: 0.5em;\n}\n\n.tc-alert-body > p {\n\tmargin: 0;\n}\n\n.tc-alert-highlight {\n\tcolor: <<colour alert-highlight>>;\n}\n\n@media (min-width: <<sidebarbreakpoint>>) {\n\n\t.tc-static-alert {\n\t\tposition: relative;\n\t}\n\n\t.tc-static-alert-inner {\n\t\tposition: absolute;\n\t\tz-index: 100;\n\t}\n\n}\n\n.tc-static-alert-inner {\n\tpadding: 0 2px 2px 42px;\n\tcolor: <<colour static-alert-foreground>>;\n}\n\n/*\n** Floating drafts list\n*/\n\n.tc-drafts-list {\n\tz-index: 2000;\n\tposition: fixed;\n\tfont-size: 0.8em;\n\tleft: 0;\n\tbottom: 0;\n}\n\n.tc-drafts-list a {\n\tmargin: 0 0.5em;\n\tpadding: 4px 4px;\n\tborder-top-left-radius: 4px;\n\tborder-top-right-radius: 4px;\n\tborder: 1px solid <<colour background>>;\n\tborder-bottom-none;\n\tbackground: <<colour dirty-indicator>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a:hover {\n\ttext-decoration: none;\n\tbackground: <<colour foreground>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a svg {\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: text-bottom;\n}\n\n/*\n** Control panel\n*/\n\n.tc-control-panel td {\n\tpadding: 4px;\n}\n\n.tc-control-panel table, .tc-control-panel table input, .tc-control-panel table textarea {\n\twidth: 100%;\n}\n\n.tc-plugin-info {\n\tdisplay: flex;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tfill: <<colour muted-foreground>>;\n\tbackground-color: <<colour background>>;\n\tmargin: 0.5em 0 0.5em 0;\n\tpadding: 4px;\n align-items: center;\n}\n\n.tc-plugin-info-sub-plugins .tc-plugin-info {\n margin: 0.5em;\n\tbackground: <<colour background>>;\n}\n\n.tc-plugin-info-sub-plugin-indicator {\n\tmargin: -16px 1em 0 2em;\n}\n\n.tc-plugin-info-sub-plugin-indicator button {\n\tcolor: <<colour background>>;\n\tbackground: <<colour foreground>>;\n\tborder-radius: 8px;\n padding: 2px 7px;\n font-size: 0.75em;\n}\n\n.tc-plugin-info-sub-plugins .tc-plugin-info-dropdown {\n\tmargin-left: 1em;\n\tmargin-right: 1em;\n}\n\n.tc-plugin-info-disabled {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n\tbackground: repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n}\n\n.tc-plugin-info-disabled:hover {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n\tbackground: repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n}\n\na.tc-tiddlylink.tc-plugin-info:hover {\n\ttext-decoration: none;\n\tbackground-color: <<colour primary>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour foreground>>;\n}\n\na.tc-tiddlylink.tc-plugin-info:hover > .tc-plugin-info-chunk > svg {\n\tfill: <<colour background>>;\n}\n\n.tc-plugin-info-chunk {\n margin: 2px;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-toggle {\n\tflex-grow: 0;\n\tflex-shrink: 0;\n\tline-height: 1;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-icon {\n\tflex-grow: 0;\n\tflex-shrink: 0;\n\tline-height: 1;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description {\n\tflex-grow: 1;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-buttons {\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tflex-grow: 0;\n\tflex-shrink: 0;\n text-align: right;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description h1 {\n\tfont-size: 1em;\n\tline-height: 1.2;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description h2 {\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-description div {\n\tfont-size: 0.7em;\n\tline-height: 1.2;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-toggle img, .tc-plugin-info-chunk.tc-plugin-info-toggle svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-plugin-info-chunk.tc-plugin-info-icon img, .tc-plugin-info-chunk.tc-plugin-info-icon svg {\n\twidth: 2em;\n\theight: 2em;\n}\n\n.tc-plugin-info-dropdown {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tmargin-top: -8px;\n}\n\n.tc-plugin-info-dropdown-message {\n\tbackground: <<colour message-background>>;\n\tpadding: 0.5em 1em 0.5em 1em;\n\tfont-weight: bold;\n\tfont-size: 0.8em;\n}\n\n.tc-plugin-info-dropdown-body {\n\tpadding: 1em 1em 0 1em;\n\tbackground: <<colour background>>;\n}\n\n.tc-plugin-info-sub-plugins {\n\tpadding: 0.5em;\n margin: 0 1em 1em 1em;\n\tbackground: <<colour notification-background>>;\n}\n\n.tc-install-plugin {\n\tfont-weight: bold;\n\tbackground: green;\n\tcolor: white;\n\tfill: white;\n\tborder-radius: 4px;\n\tpadding: 3px;\n}\n\n.tc-install-plugin.tc-reinstall-downgrade {\n\tbackground: red;\n}\n\n.tc-install-plugin.tc-reinstall {\n\tbackground: blue;\n}\n\n.tc-install-plugin.tc-reinstall-upgrade {\n\tbackground: orange;\n}\n\n.tc-check-list {\n\tline-height: 2em;\n}\n\n.tc-check-list .tc-image-button {\n\theight: 1.5em;\n}\n\n/*\n** Message boxes\n*/\n\n.tc-message-box {\n\tborder: 1px solid <<colour message-border>>;\n\tbackground: <<colour message-background>>;\n\tpadding: 0px 21px 0px 21px;\n\tfont-size: 12px;\n\tline-height: 18px;\n\tcolor: <<colour message-foreground>>;\n}\n\n.tc-message-box svg {\n\twidth: 1em;\n\theight: 1em;\n vertical-align: text-bottom;\n}\n\n/*\n** Pictures\n*/\n\n.tc-bordered-image {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 5px;\n\tmargin: 5px;\n}\n\n/*\n** Floats\n*/\n\n.tc-float-right {\n\tfloat: right;\n}\n\n/*\n** Chooser\n*/\n\n.tc-chooser {\n\tborder-right: 1px solid <<colour table-header-background>>;\n\tborder-left: 1px solid <<colour table-header-background>>;\n}\n\n\n.tc-chooser-item {\n\tborder-bottom: 1px solid <<colour table-header-background>>;\n\tborder-top: 1px solid <<colour table-header-background>>;\n\tpadding: 2px 4px 2px 14px;\n}\n\n.tc-drop-down .tc-chooser-item {\n\tpadding: 2px;\n}\n\n.tc-chosen,\n.tc-chooser-item:hover {\n\tbackground-color: <<colour table-header-background>>;\n\tborder-color: <<colour table-footer-background>>;\n}\n\n.tc-chosen .tc-tiddlylink {\n\tcursor:default;\n}\n\n.tc-chooser-item .tc-tiddlylink {\n\tdisplay: block;\n\ttext-decoration: none;\n\tbackground-color: transparent;\n}\n\n.tc-chooser-item:hover .tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-chosen .tc-tiddlylink,\n.tc-drop-down .tc-chooser-item .tc-tiddlylink:hover {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-chosen > .tc-tiddlylink:before {\n\tmargin-left: -10px;\n\tposition: relative;\n\tcontent: \"» \";\n}\n\n.tc-chooser-item svg,\n.tc-chooser-item img{\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: middle;\n}\n\n.tc-language-chooser .tc-image-button img {\n\twidth: 2em;\n\tvertical-align: -0.15em;\n}\n\n/*\n** Palette swatches\n*/\n\n.tc-swatches-horiz {\n}\n\n.tc-swatches-horiz .tc-swatch {\n\tdisplay: inline-block;\n}\n\n.tc-swatch {\n\twidth: 2em;\n\theight: 2em;\n\tmargin: 0.4em;\n\tborder: 1px solid #888;\n}\n\ninput.tc-palette-manager-colour-input {\n\twidth: 100%;\n\tpadding: 0;\n}\n\n/*\n** Table of contents\n*/\n\n.tc-sidebar-lists .tc-table-of-contents {\n\twhite-space: nowrap;\n}\n\n.tc-table-of-contents button {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents svg {\n\twidth: 0.7em;\n\theight: 0.7em;\n\tvertical-align: middle;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents ol {\n\tlist-style-type: none;\n\tpadding-left: 0;\n}\n\n.tc-table-of-contents ol ol {\n\tpadding-left: 1em;\n}\n\n.tc-table-of-contents li {\n\tfont-size: 1.0em;\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li a {\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li li {\n\tfont-size: 0.95em;\n\tfont-weight: normal;\n\tline-height: 1.4;\n}\n\n.tc-table-of-contents li li a {\n\tfont-weight: normal;\n}\n\n.tc-table-of-contents li li li {\n\tfont-size: 0.95em;\n\tfont-weight: 200;\n\tline-height: 1.5;\n}\n\n.tc-table-of-contents li li li li {\n\tfont-size: 0.95em;\n\tfont-weight: 200;\n}\n\n.tc-tabbed-table-of-contents {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents {\n\tz-index: 100;\n\tdisplay: inline-block;\n\tpadding-left: 1em;\n\tmax-width: 50%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n\tbackground: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a,\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tdisplay: block;\n\tpadding: 0.12em 1em 0.12em 0.25em;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a {\n\tborder-top: 1px solid <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-background>>;\n\tborder-bottom: 1px solid <<colour tab-background>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a:hover {\n\ttext-decoration: none;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour background>>;\n\tmargin-right: -1px;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a:hover {\n\ttext-decoration: none;\n}\n\n.tc-tabbed-table-of-contents .tc-tabbed-table-of-contents-content {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-left: 1.5em;\n\tpadding-right: 1.5em;\n\tborder: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 50%;\n\tflex: 1 0 50%;\n}\n\n/*\n** Dirty indicator\n*/\n\nbody.tc-dirty span.tc-dirty-indicator, body.tc-dirty span.tc-dirty-indicator svg {\n\tfill: <<colour dirty-indicator>>;\n\tcolor: <<colour dirty-indicator>>;\n}\n\n/*\n** File inputs\n*/\n\n.tc-file-input-wrapper {\n\tposition: relative;\n\toverflow: hidden;\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n\n.tc-file-input-wrapper input[type=file] {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tfont-size: 999px;\n\tmax-width: 100%;\n\tmax-height: 100%;\n\tfilter: alpha(opacity=0);\n\topacity: 0;\n\toutline: none;\n\tbackground: white;\n\tcursor: pointer;\n\tdisplay: inline-block;\n}\n\n::-webkit-file-upload-button {\n\tcursor:pointer;\n}\n\n/*\n** Thumbnail macros\n*/\n\n.tc-thumbnail-wrapper {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin: 6px;\n\tvertical-align: top;\n}\n\n.tc-thumbnail-right-wrapper {\n\tfloat:right;\n\tmargin: 0.5em 0 0.5em 0.5em;\n}\n\n.tc-thumbnail-image {\n\ttext-align: center;\n\toverflow: hidden;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-image svg,\n.tc-thumbnail-image img {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n\tmin-width: 100%;\n\tmin-height: 100%;\n\tmax-width: 100%;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image img {\n\tfilter: alpha(opacity=0.8);\n\topacity: 0.8;\n}\n\n.tc-thumbnail-background {\n\tposition: absolute;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-icon svg,\n.tc-thumbnail-icon img {\n\twidth: 3em;\n\theight: 3em;\n\t<<filter \"drop-shadow(2px 2px 4px rgba(0,0,0,0.3))\">>\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon img {\n\tfill: #fff;\n\t<<filter \"drop-shadow(3px 3px 4px rgba(0,0,0,0.6))\">>\n}\n\n.tc-thumbnail-icon {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tdisplay: -webkit-flex;\n\t-webkit-align-items: center;\n\t-webkit-justify-content: center;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.tc-thumbnail-caption {\n\tposition: absolute;\n\tbackground-color: #777;\n\tcolor: #fff;\n\ttext-align: center;\n\tbottom: 0;\n\twidth: 100%;\n\tfilter: alpha(opacity=0.9);\n\topacity: 0.9;\n\tline-height: 1.4;\n\tborder-bottom-left-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-caption {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n}\n\n/*\n** Diffs\n*/\n\n.tc-diff-equal {\n\tbackground-color: <<colour diff-equal-background>>;\n\tcolor: <<colour diff-equal-foreground>>;\n}\n\n.tc-diff-insert {\n\tbackground-color: <<colour diff-insert-background>>;\n\tcolor: <<colour diff-insert-foreground>>;\n}\n\n.tc-diff-delete {\n\tbackground-color: <<colour diff-delete-background>>;\n\tcolor: <<colour diff-delete-foreground>>;\n}\n\n.tc-diff-invisible {\n\tbackground-color: <<colour diff-invisible-background>>;\n\tcolor: <<colour diff-invisible-foreground>>;\n}\n\n.tc-diff-tiddlers th {\n\ttext-align: right;\n\tbackground: <<colour background>>;\n\tfont-weight: normal;\n\tfont-style: italic;\n}\n\n.tc-diff-tiddlers pre {\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n}\n\n/*\n** Errors\n*/\n\n.tc-error {\n\tbackground: #f00;\n\tcolor: #fff;\n}\n\n/*\n** Tree macro\n*/\n\n.tc-tree div {\n \tpadding-left: 14px;\n}\n\n.tc-tree ol {\n \tlist-style-type: none;\n \tpadding-left: 0;\n \tmargin-top: 0;\n}\n\n.tc-tree ol ol {\n \tpadding-left: 1em; \n}\n\n.tc-tree button { \n \tcolor: #acacac;\n}\n\n.tc-tree svg {\n \tfill: #acacac;\n}\n\n.tc-tree span svg {\n \twidth: 1em;\n \theight: 1em;\n \tvertical-align: baseline;\n}\n\n.tc-tree li span {\n \tcolor: lightgray;\n}\n\nselect {\n color: <<colour select-tag-foreground>>;\n background: <<colour select-tag-background>>;\n}\n\n/*\n** Utility classes for SVG icons\n*/\n\n.tc-fill-background {\n\tfill: <<colour background>>;\n}\n\n/*\n** Flexbox utility classes\n*/\n\n.tc-flex {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-flex-column {\n\tflex-direction: column;\n}\n\n.tc-flex-row {\n\tflex-direction: row;\n}\n\n.tc-flex-grow-1 {\n\tflex-grow: 1;\n}\n\n.tc-flex-grow-2 {\n\tflex-grow: 2;\n}\n\n/*\n** Other utility classes\n*/\n\n.tc-small-gap {\n\tmargin-left: .5em;\n\tmargin-right: .5em;\n}\n\n.tc-small-gap-left {\n\tmargin-left: .5em;\n}\n\n.tc-small-gap-right {\n\tmargin-right: .5em;\n}\n\n.tc-big-gap {\n\tmargin-left: 1em;\n\tmargin-right: 1em;\n}\n\n.tc-big-gap-left {\n\tmargin-left: 1em;\n}\n\n.tc-big-gap-right {\n\tmargin-right: 1em;\n}\n\n.tc-word-break {\n\tword-break: break-all;\n}\n"
},
"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize",
"text": "15px"
},
"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/bodylineheight",
"text": "22px"
},
"$:/themes/tiddlywiki/vanilla/metrics/fontsize": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/fontsize",
"text": "14px"
},
"$:/themes/tiddlywiki/vanilla/metrics/lineheight": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/lineheight",
"text": "20px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storyleft": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storyleft",
"text": "0px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storytop": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storytop",
"text": "0px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storyright": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storyright",
"text": "770px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storywidth": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storywidth",
"text": "770px"
},
"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth",
"text": "686px"
},
"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint",
"text": "960px"
},
"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth",
"text": "350px"
},
"$:/themes/tiddlywiki/vanilla/options/stickytitles": {
"title": "$:/themes/tiddlywiki/vanilla/options/stickytitles",
"text": "no"
},
"$:/themes/tiddlywiki/vanilla/options/sidebarlayout": {
"title": "$:/themes/tiddlywiki/vanilla/options/sidebarlayout",
"text": "fixed-fluid"
},
"$:/themes/tiddlywiki/vanilla/options/codewrapping": {
"title": "$:/themes/tiddlywiki/vanilla/options/codewrapping",
"text": "pre-wrap"
},
"$:/themes/tiddlywiki/vanilla/reset": {
"title": "$:/themes/tiddlywiki/vanilla/reset",
"type": "text/plain",
"text": "/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */\n\n/*\nDocument\n========\n*/\n\n/**\nUse a better box model (opinionated).\n*/\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/**\nUse a more readable tab size (opinionated).\n*/\n\n:root {\n -moz-tab-size: 4;\n tab-size: 4;\n}\n\n/**\n1. Correct the line height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n*/\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/*\nSections\n========\n*/\n\n/**\nRemove the margin in all browsers.\n*/\n\nbody {\n margin: 0;\n}\n\n/**\nImprove consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n*/\n\nbody {\n font-family:\n system-ui,\n -apple-system, /* Firefox supports this but not yet `system-ui` */\n 'Segoe UI',\n Roboto,\n Helvetica,\n Arial,\n sans-serif,\n 'Apple Color Emoji',\n 'Segoe UI Emoji';\n}\n\n/*\nGrouping content\n================\n*/\n\n/**\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n}\n\n/*\nText-level semantics\n====================\n*/\n\n/**\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr[title] {\n text-decoration: underline dotted;\n}\n\n/**\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n2. Correct the odd 'em' font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family:\n ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n Menlo,\n monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/**\nPrevent 'sub' and 'sup' elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\nTabular data\n============\n*/\n\n/**\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n}\n\n/*\nForms\n=====\n*/\n\n/**\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\nRemove the inheritance of text transform in Edge and Firefox.\n1. Remove the inheritance of text transform in Firefox.\n*/\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\nCorrect the inability to style clickable types in iOS and Safari.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button;\n}\n\n/**\nRemove the inner border and padding in Firefox.\n*/\n\n::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\nRestore the focus styles unset by the previous rule.\n*/\n\n:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\nRemove the additional ':invalid' styles in Firefox.\nSee: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/**\nRemove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.\n*/\n\nlegend {\n padding: 0;\n}\n\n/**\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to 'inherit' in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nInteractive\n===========\n*/\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n"
},
"$:/themes/tiddlywiki/vanilla/settings/fontfamily": {
"title": "$:/themes/tiddlywiki/vanilla/settings/fontfamily",
"text": "system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\""
},
"$:/themes/tiddlywiki/vanilla/settings/codefontfamily": {
"title": "$:/themes/tiddlywiki/vanilla/settings/codefontfamily",
"text": "\"SFMono-Regular\",Consolas,\"Liberation Mono\",Menlo,Courier,monospace"
},
"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment": {
"title": "$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment",
"text": "fixed"
},
"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize": {
"title": "$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize",
"text": "auto"
},
"$:/themes/tiddlywiki/vanilla/sticky": {
"title": "$:/themes/tiddlywiki/vanilla/sticky",
"text": "<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\" type=\"match\" text=\"yes\">\n``\n.tc-tiddler-title {\n\tposition: -webkit-sticky;\n\tposition: -moz-sticky;\n\tposition: -o-sticky;\n\tposition: -ms-sticky;\n\tposition: sticky;\n\ttop: 0px;\n\tbackground: ``<<colour tiddler-background>>``;\n\tz-index: 500;\n}\n\n``\n<$list filter=\"[range[100]]\">\n`.tc-story-river .tc-tiddler-frame:nth-child(100n+`<$text text=<<currentTiddler>>/>`) {\nz-index: `<$text text={{{ [[200]subtract<currentTiddler>] }}}/>`;\n}\n`\n</$list>\n</$reveal>\n"
}
}
}
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [mubu.com](https://mubu.com/doc/explore/12609)
如果想要表达对象的状态或现象就用不及物动词,如果想要表达行为及其背后的原因就用及物动词。将这样的表达方式作为分组的一个原则,是实现子弹笔记条理化的捷径。 想要描述动作就使用及物动词,明确主语和宾语,体现出层次感。而在描述目标、理想、问题、特征等某件事情未来、现在或过去的状态时,用不及物动词。 不要以名词结尾,一旦在子弹笔记中以名词结尾,就会导致信息接收者难以理解你想表达的真实含义。如果在本应该用动词结尾的地方使用了名词,就会妨碍信息接收者对子弹笔记的理解
就像电流顺着电路流动一样,时间在串联型连接的句子与句子之间 “流动”;而在并联型连接的句子里,就没有时间的 “流动”。 如果句子之间存在时间变化,就以串联型的形式来排列。反之,就以并联型的形式来排列。 把内容以串联型或者并联型的形式整理排列后,就能够让信息接收者快速意识到子弹笔记中的时间流动,从而更容易理解和掌握该子弹笔记想要表达的内容。 具体来说,当子弹笔记里的句子以串联型的形式排列时,其中一定会有某种时间的流动。与最开始的句子相比,它之后的句子或是在描述之后(未来)的事,或是在描述之前(过去)的事,其中一定有时间的流动。 反之,如果子弹笔记的内容以并联型的形式排列,就代表其中没有时间的流动。最典型的就是未来想要实现的梦想的清单、现在应该要做的事情的清单和过去失败原因的清单。
governing,即 “统一”。比如想要表达的内容有三个重点的时候,会先在文章的开头表明“重点有三个”,再继续展开讲述具体的内容。“重点有三个” 这个表明意图的句子就是 governing。
信息接收者如果不能被开头的引导文吸引,接下来的内容就无法很好地传达给他。换句话说,对方会不会有兴趣看这份子弹笔记就取决于引导文的好坏。 我们应该在引导文里写什么,向对方传达什么呢?答案是“对方期望看到的内容”。这个答案并不唯一,它会根据对方以及对方所处的环境的不同而改变。 “结论第一”并不是万能的。但是我们应该注意,要根据对方的需求来决定是不是要采用 “结论第一” 的表达方式。
MECE 是 Mutually Exclusive and Collectively Exhaustive 的省略,意思是 “不遗漏、不重复”。 “不遗漏、不重复” 地表达之后,子弹笔记失去了 “能够勾起人兴趣的诱饵”。 简单说来就是会产生子弹笔记没能做到剧情化,不能吸引对方注意力的问题。 所以用子弹笔记进行表达的时候,不应该执着于 MECE。有的时候,通过拆分 MECE 的方式来表达可能会收到更好的效果。 MECE 可大致分为两种。 第一种是不会根据时间、地点、任何人的想法改变的 MECE,也称作绝对 MECE。另一种是会根据对方的关注点等情况进行调整的 MECE,也称作相对 MECE。 从结论上来说,适用于子弹笔记的是后者,也就是相对 MECE。我们应该明白,如果使用了绝对 MECE,就无法拆分 MECE 了。
我们要找到一般名词,然后用我们与对方都能够理解的专有名词将其替换掉。 般名词比较抽象,因此对方很难认为接收到的内容与自己有关。 而用专有名词,特别是对方十分熟悉的专有名词来表达,对方在看到与自己有关的专有名词时,会立刻对这个内容留下一个具体的印象。因为在对方的脑海里,用这个专有名词来表达的内容,往往和他此前的经验有关。 使用专有名词,能够让子弹笔记的内容更好地吸引信息接收者。
隐藏性重复内容是指文章里没有重复的语句,但是表达的某些内容是重复的,没有特地写出来的必要,也没有太大的意义。 子弹笔记的信息含量是有限的,隐藏性重复内容不仅浪费了表达的机会,还会影响表达的效果。 看似有用的无用词:“改善……”“重新审视……”“推进……”“将…… 做到最优”“保持…… 的平衡”“贯彻……”“强化……”“执行……”
所谓使用否定来斩断退路就是“通过否定 XX 来更加明确地表达”。这种方式可以帮助我们更清晰地表达自己的立场。 柔软的否定:比起 A 来 B 更好,用 B 比 A 更好来表明立场,但未必否定了 A。 柔软的否定:从 A 变成 B,“从 A 变成 B”的句式能够让子弹笔记明确表达出 “成为 B” 这层含义。 不想使用绝对否定的人,可以通过比较句式来表达否定。这种方式既缓和了语气,也能够清晰地表明我们的观点,使子弹笔记实现信息化。
把形容词和副词换成数字,尤其是在叙述 “大小” 等表示程度的内容时,使用数字后,内容会表达得更清晰。 使用数字能够使子弹笔记更清晰,是使子弹笔记实现信息化的诀窍之一。 将想要表达的内容用数字来进行思考,可以帮助我们重新审祝自己拥有的闪光点。 目标来说,数字是不可或缺的。无论什么目标,如果没有表明状态和期限的数字,那么这个目标就不具有向心力。 目标必须要有两个数字,一个表示状态,另一个表示期限。如果难以明确地用数字表达,用表示程度的词语,或者能够判断是否已经实现的表达方式也可以。
围绕 day notes 展开的工作流
之前写的一篇文章里介绍过我的 [[Trilium]] 工作流,主要围绕它内建的 day notes 也就是日记展开。日记相当于 inbox,每天的新笔记都放在日记下面。Trilium 网页剪辑插件默认的剪辑根目录就是当天的日记页面;如果有和项目相关或篇幅较长的想法,我也会在日记下新建笔记记录。
重点来了:如何整理?这就得仰赖 Trilium 的特色功能——clone,它能把笔记链接到文档树的另一个位置。我把它理解为「发送」。每次写完一条新笔记,我就立刻右键把它 clone 到对应的主题页面下。这样,一条笔记就同时拥有了主题和日期两个上下文。
输出内容
按照[[卢曼卡片法]]的原理,先在各种媒介或者其他软件上面记录一些零散的笔记,然后改写成长期笔记,放到 Roam Research 中,利用可以触达 block 的双向链接,把笔记节点织成一张大网,不断调整链接,根据新的输入和思考迭代内容。
为了方便输出,我用 Keyboard Maestro 做了几个脚本,可以帮我一键把 [[Roam Research]] 中的内容输出成为 Textbundle、docx 或者 reveal.js 幻灯格式。这样一来,笔记整理和写作就都可以在 [[Roam Research]] 之内无障碍完成。
![[卡片笔记]]
* 首先建立条目的空白笔记
* 再新建时间戳笔记
* 在时间戳笔记记录相关概念
* 使用 ``[[]]``` 来链接
[[Roam Research]],看起来是一款笔记工具,但其实是一款思考工具。但是它远不止于成为个人的第二大脑那么简单,它有点儿类似知识界的 GitHub,有着追求集体智能的远大愿景。
> Roam对人类知识的愿景是一种集体的、开源的智能,不断地重新排列、迭代和进化以追求真理。我们每个人都将成为这个集体智能中的一个节点,建立联系并创建网络,分享每个人所能提供的最好的东西,在改善他人的同时也在改善自己,推进人类的前进。 —— Roam Research 白皮书
卡片盒笔记法和其他知识管理方法的共同问题就是,笔记量越大,回顾的成本越高,越到后期回顾越花费时间,很多人有心里负担也就放弃或是干脆觉得这些方法都是糊弄人的。
知识管理就像打怪升级,想要超凡的经验,苦练不能少。我们也可以通过定期删掉过时、重复的笔记,剔除一些无效的节点来减少阅读成本。
卡片盒笔记法还鼓励定期提炼多张同类的笔记为一个笔记,从而减少后期回顾成本。即把知识网络中的节点合并起来。这些小技巧因人而异,实践中可以多多总结发现。
Projects, Areas, Resources, Archives, attachment
平时的临时笔记和文献笔记,都在Resources里面。
然后如果有计划(感兴趣)新起一个项目时,但暂时没有deadline的,在Areas里面新建一个Page,慢慢从Resources里面添加相关信息。
当决定立项时,移动到Projects里,然后给个deadline。
项目完成后就放在Archives里。
[[PARA模式]]
[[笔记系统]]目标
- 简单,高效,灵活: 工具要简单,流程要简单,专注于笔记,而不是繁杂的流程
- 通用,跨平台: 随时随地,都可以记录
- 结果导向: 笔记要可跟踪,有进度,做到心里有数
- 模块化: 最大限度的降低因流程更新带来的变动
- 弹性省时: 时间是最重要的, 该系统对于时间要求最低,不能为了维护该系统而花费大量时间,也不能因为没有时间维护,而导致系统崩溃
P : Projects 项目
- 作用:结果导向,清晰的进度,详细的步骤,有截止时间
- 来源:细分自Areas
- 特点: 有目标和deadline
- 比如:写一篇关于para的博客;确定产品规格;参加会议
- 笔记模板:
[img[https://pic4.zhimg.com/80/v2-b739f774f9507c292b69655ee49ec11f_720w.jpg]]
注意:tag部分,要添加 所属的区域和区域内的项目名;还有正在进行的子项目,记得加上TODO
[[PARA模式]]
A : Areas 领域
- 作用:标准化某一个领域或者角色
- 来源:整合自Resource
- 特点:
- 没有时间限制,持续性
- 个人的角色或者近期的兴趣
- 比如:健康;财务;编程;英语;朋友;写作;运动;
- 每个笔记有个 tag 即可
[[PARA模式]]
R : Resources 资源
- 作用:资源库,素材库
- 来源:每日笔记, 每个笔记默认都是在这里面的(需要加标签)
- 特点:感想,灵感,突然感兴趣但不准备长期的东西,拿不准的东西,不确定的
- 比如:咖啡;音乐;营销;设计;宠物;音乐;营销;
- 每个笔记有个 tag 即可
[[PARA模式]]
A : Archives 档案
- 作用:归档
- 来源:所有
- 特点:除了归档,也可以放一些不会变的东西,比如个人信息,密码,地址, 电器使用说明书,激活码等
- 比如:简历;完成的项目回顾;去年年终总结;提案;不再使用的项目资料
[[PARA模式]]
比如:
我们在查找、记录、整理一条笔记的时候,
首先,我们会想该笔记属于什么类型,日常?技能?公司?财务?健康?运动等
然后找到对应的文件夹,如果文件夹下面还有其他细分类别,就会重复该动作
有时候还会使用标签,但也和查找相关类别的文件夹是差不多的动作
有时候还会用到关键词,当然大部分是在关键词非常明确,或者实在找不到笔记的时候。
这个就是典型的[[线性笔记]]的大概流程
具体来说
不要像我之前那样,
创建PARA四个页面,做为类文件夹,
然后在该页面内,添加新的相关页面(比如:项目,编程,英语等)
再然后,在相关页面内,填写新的具体内容或者知识点或者项目
如果要添加新的笔记,则是先写在每日笔记上
然后,整理的时候,把它拖到相关页面比如:项目,编程,英语等)
最后,如果是新项目,则在PARA上添加新页面
以上就是典型的[[线性笔记]]的流程
接下来说说我理解中,正确的或者说[[非线性笔记]]应该是这样的
每日笔记依旧是每天笔记的主要入口
通过标签来初步分类PARA笔记,这样就不用特地把笔记移动到PARA的相关页面,更灵活
我的主要标签:Projects, Areas, Resources, Archives, Inbox
其他标签:
日期标签:如果是一个日程的话,就可以添加一个日期标签,等到了那天,每日笔记下面就会出现相关链接
A\B\C\D:如果需要,可以添加任务的优先级
查找项目的时候,直接搜索PARA标签或者关键字
有新笔记的时候,直接创建新页面,然后打上相关标签,相关的关键字同样,也要\[[]\]起来
当网络建立起来后,通过笔记来漫游,就会出现很多以前没有注意到的灵感
乍一看,感觉只是把文件夹变成了标签 ,事实上确实如此
这样就可以剔除“移动笔记到相关页面”这个动作,更专注于笔记,笔记在哪里并不重要,重要的是它的内容,它的关键词,是否可以成为别的笔记的基础
小小的一个动作的简化,确是一种完全不同理念的系统,有时候进步就是这么简单的一步,却很难迈出。
写作练习
针对新闻的写作
找出新闻的主旨
新闻要表达的内容
要抨击的对象
立场
代表的阶级
完善新闻的故事背景
人物的构成
时空的建构
事情的发展及原委
针对故事做衍生
卡片笔记法是
先收集
再整理
找出其中的脉络
归纳和发散
将para模式用于创意写作
资源池是收集故事
领域池是再创作的片段
项目池是作品
故事素材的每日练习
解剖素材
里面的人物
人物的背景
人物的动机和渴望
人物的行为
人物得到的结果
背景/时空的设计
时间线
空间的安排
首相自然是不会选择一个利民的长效政策
因为对他的支持力量,来源于对疫情的恐慌
我国政府的政党,支持的力量多源自恐慌
无论是族群或宗教政党皆属存亡危机下的恐慌
我国无一政党是追求人民福祉为第一目标的
[[疫情]]
[[政治]]
如果你足够了解极权主义,你会不会更认同极权呢?那你更了解自由,为何会转向自由呢?
因为你的心底认为,自由是更可贵,更美好,是正常心智的人共同追求的。
有这种想法,其实就不客观了。
杜威编码系统分类法
是用十进位的方式,将领域分类及细分
应用于标签
将自己的心得记录下来(即便只是片语),存放为暂存池
链接其参考/或激发灵感的文章,将之存放在资源池
项目池为已经整理,欲输出的结果
反向链接/标签化的功用是在于强迫自己对该素材进行初步的整理,方便之后的联想。
主动学习可以提升学习的效率
所以在[[para模式]]里建立项目来收集资料
"""
故事讲好是小说的基础
微型小说的定位在哪里?
有文学张力,有艺术感染力
错位产生冲击力
"""
[[小说创作]]
[[2021 / 01 / 18 / 13:10:40 /]]
如果我有一座新冰箱
如果我有一座新冰箱
我会把
时钟、照片、掌纹
和你分手的前一天
都放进去
"""
像没办法转台的电视机,单曲循环低播放着自觉委屈老要掀桌的过气演员、患服装选择困难症而一直要打别人屁股的帐篷爱好者、除不尽的数字的数学老师。
一只只的噪音,首尾相衔的钻透墙壁,啃遍家具,爬满他的身躯。
"""
"""
Core V1
DIMENSION (H X W X D)
276 x 260 x 316 mm
(10.9 x 10.2 x 12.4 inch)
Cougar QBX
Dimensions 291 mm × 178 mm × 384 mm
11.46 in × 7.01 in × 15.12 in
"""
我快死了,就先找个墓地
两个人争一个墓地
人权,每个人都要体面的死去
集大成者,从来就不是指,在其领域里,读更多的第一文本。
阅读,也包含阅读受其影响而衍生的产品。
remedit
user :kawee0183216068
ps:ZBN99RES248854
在小说里使用你、我、他之类的考量
# 第三人称的方式,表示视角可以转移;第一人称,则不行
# 第一人称的,叙述者可以和主角重合(待争议)
图文相关
我将小说初稿交给编辑
编辑要求附上图片
现代的读者,和老一代的读者已经大大的不同
现在的创作方式
古老的打字机
隔壁的散文区
已经施行
如游记
如证据
甚至于说,你描写毒药,也需要附上口吐白沫的临死模样
-----
我将打字机带到报社
将稿纸绞进打字机
再将编辑的头按在键盘处,
滚动一幅图文相关的图片
文 學 創 作 課 程 一 散 文 組
[img[https://raw.githubusercontent.com/l7943416/pic/main/clip_image001-1610174120768.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/clip_image001-1610174120769.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/clip_image001-1610174162531.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/clip_image001-1610174174553.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/clip_image001-1610174199616.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/clip_image001-1610174252858.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109143752882.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109143703384.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109143831752.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109144058079.png]]
杂文
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109144251008.png]]
杂文
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109144347294.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109144415415.png]]
杂文
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109144615263.png]]
散文
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109144915799.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109145139553.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109145258176.png]]
蒋勋的文字美感是很高的
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109145523074.png]]
余光中,散文相当好看。
[img[余光中-鬼雨]]
视角
第一人称:比较直接
第二人称:审视自己
第三人称:解离性的
--------------
** 王修捷
:PROPERTIES:
:CUSTOM_ID: 王修捷
:END:
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109153209876.png]]
空间叙事:经营空间,身历其境。
意象
阎
言叔夏
潘雨桐
散文小说化,遇到一件事情,戏剧化,需要亲历其中的可以这样写。
灵感来源:质量
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109154707604.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109154730763.png]]
陈黎[[戰爭交響曲-陳黎]]
[[弃物祭文-翁弦尉]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109155400443.png]]
互文
碎片化的写法
作家的文学养分不仅仅来自于"作家"/文学
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109160542339.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109160731304.png]]
[[垂釣睡眠-鍾怡雯]]
[[山外书-郑愁予]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109161458056.png]]
[[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109163321206.png]]
[[无理之数-言叔夏]]
[[秋夜-鲁迅]]
[[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109164133273.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109164342743.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109164726926.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109164911413.png]]
[img[https://raw.githubusercontent.com/l7943416/pic/main/image-20210109164845471.png]]
阿拉比【註】
`【註】一八九四年五月十四到十九日在都柏林曾經舉辦過一場名為「大東方節慶」(Grand Oriental)的市集活動,阿拉比(Araby)是東京阿拉伯的諧音,小說中代表浪漫詩意,充滿神秘的東方想像。`
李奇蒙北街是條死巷,除了基督教兄弟會學校放學的那一刻,一向都非常安靜。一幢無人居住的兩層樓房子矗立在死巷盡頭,與方形廣場上的其他房子隔離開來。街上的其他房子認為自己生活體面,便以一張張冷漠的面孔,互相注視著對方。
這幢房子先前的房客是一位神父,後來他死在房子後方的起居室裡。這房子因為長期門窗緊閉,所以空氣中瀰漫著一股霉味。廚房後面的房間裡,丟棄的紙張,散落一地。在紙堆裡,我找到幾本平裝書,書頁早因泛潮而捲曲:它們是瓦特.史考特的《修道院長》、《虔誠的領聖餐者》和《維德克回憶錄》【註】。我喜歡最後一本,因為它的書頁都變黃了。在荒蕪的後院中央有一棵蘋果樹和一些雜亂的樹叢。我在樹叢裡找到一把先前房客留下來生了鏽的打氣唧筒。他是一位慈悲的神父;根據他的遺囑,他把身後所有的錢都捐給了幾家慈善機構,也把一些家具留給了他的姊妹們。
`【註】《修道院長》是史考特爵士在一八二〇年出版的浪漫傳奇小說。《虔誠的領聖餐者》是聖芳濟教會僧侶貝克在一八一三年所寫的一本傳道書。《維德克回憶錄》是一八二八年出版的一本有關偵探與犯罪的小說。`
冬天來了,晝短夜長,在我們享用晚餐之前,暮色早已降臨。當我們在街頭碰面時,房子早已變得黯淡模糊了,但我們頭上的天空仍是瞬息萬變的紫色一片。街頭的路燈,向著天際,高舉著微弱的燈火。寒風刺骨,但我們仍盡情玩樂,直到渾身發熱為止。我們的叫聲迴響在謐靜的街頭。在遊戲的追逐中,有時候我們會穿過房子後面那條黑暗泥濘的小巷,我們在那兒躲避鄰村野孩子的攻擊;有時候跑到院子後門,那兒潮濕陰暗,垃圾堆還散發著惡臭;有時候則跑到陰暗發臭的馬廄裡,那兒馬伕在刷洗馬匹,馬具上的銅釦發出了悅耳的鈴聲。當我們回到街頭時,早已萬家燈火,整條街也亮了起來。這時如果看見我舅舅轉過街角回家來,我們就躲在街角暗處直到他完全走進屋子裡為止;如果看見曼庚的姊姊走上門口的階梯,來叫她的弟弟回去喝茶吃點心,我們也會躲在暗處偷看她朝街頭上下探看時的眼神。我們等著看她是否會停留在原地或是走回屋裡去。如果留下來,我們只好跟隨曼庚的腳步,心不甘情不願地從暗處走出來。她在那兒等著我們,從半開的門口流瀉出來的燈光,映襯著她的體態。她的弟弟總是先逗她一會兒,才答應聽她的話。我站在欄杆附近注視著她。她的羅衫隨著移動的身體迎風揚起,那清柔的秀髮也跟著左右搖擺了起來。
每天早晨我都會趴在前廳的地板上,朝著她家的大門窺看。我把百葉窗拉低到離窗台一吋的地方,免得被對方發現。一旦看到她出現在台階上,我的心就怦然一跳,趕緊跑到大廳,拿起書包,緊隨在後。我讓她棕色的背影保持在我的視線範圍之內。當我們快到分岔路口的時候,我就加快腳步,三步併作兩步,趕上去從她的身旁超越她。每天早晨,這些儀式不停上演。我除了幾句寒暄的話外,從來不敢和她攀談。但是她的名字卻不斷召喚著我,挑起我盲動的熱情。
她的一顰一笑,如影隨形伴著我,甚至於還出現在與浪漫氣氛格格不入的地方。每個星期六的傍晚,我得隨舅媽去市場幫忙提些採買的東西。我們走在明亮的街道,受到醉漢和討價還價婦女的推擠,耳際充斥著工人們的叫罵詛咒聲,豬肉攤的小夥計連珠炮般的叫賣聲,還有街頭藝人,帶著濃濃鼻音,吟唱羅莎的愛國歌曲〈大家一起來吧!〉,或一曲有關國土家園多災多難的民謠【註】。這些不同的聲音交織成一首生命的悸動:我想像自己護衛著一只聖杯,奮勇通過敵人重重的包圍。她的名字不時在念禱告詞或讚美詩時,莫名其妙地從我的口中吐了出來。我經常淚水盈眶(我也不清楚為什麼會如此),有時候心頭熱血,似乎溢滿胸膛。我無法想像未來。我不知道要不要告訴她,如果要,那我要怎樣向她傾訴表白我那神魂顛倒的思慕之情。我的身體就像一把豎琴,她的言語和姿態如手指,撥動著我的心弦。
```
【註】羅莎有關的民謠很多。此處的羅莎自然少不了喬伊斯的弦外之,羅莎也指Jeremiah donovan Rossa,他是一位新芬黨員,因抗英被捕入獄後,流亡美國,客死異鄉,最後他的遺體被迎回愛爾蘭安葬。
```
有一天晚上,我去神父過世的那間客廳。那是一個下著小雨的暗夜,屋子裡寂靜無聲。透過一扇破窗,我聽見雨滴打在地上的聲音,那細細不斷的雨絲在濕漉漉的地上嬉樂彈跳。在我的下方遠處有一盞燈火,或是一扇窗戶內閃爍的燭火。我的心情激動,黑暗之中,什麼也看不清。黑暗之中,我的五官感覺按捺不住,只覺得自己的靈魂快要出竅了,於是使力緊握雙手直到身體不自覺顫抖了起來,同時嘴裡則不斷喃喃地唸著:啊!我的愛!啊!我的愛!
她終於開口對我說話。但她說的前幾句話,卻叫我心慌意亂,不知道如何回答。她問我要不要去逛阿拉比。我不記得是回答去或不去。她說,市集裡一定有很多好玩的事,真希望也能去看看。
──那妳為什麼不能去?我問道。
她一面玩著手腕上的銀色手鐲,一面回答我。她說,她不能去,因為那個星期她的教會有一個靜修活動。她的兩個弟弟正在搶奪帽子,只有我單獨一個人站在欄杆邊。她的雙手握著欄杆上的尖釘部分,低頭對著我看。對面家的燈光照到她粉頸的雪白曲線,和她的秀髮。隨著燈光流洩,也照亮她放在欄杆上的纖手。她安詳地站在那兒,燈光落在她衣裳的另一邊,也照到她襯裙的白邊,我剛好看見。
──真好,你能去,她說。
──如果我去,我說,我就帶一件東西回來給妳。
從那天的黃昏起,無數個混亂的念頭就開始盤據在我諸多醒醒睡睡的思緒之間。我真希望這些橫梗在其間的無聊時光能早點過去。我無心做學校的功課。夜晚在臥室裡,白天在學校裡,她的影子總是出現在我和我試圖專心去閱讀的書頁之間。「阿拉比」這個字的音節,在靜默中不斷地呼喚著我,使我的靈魂沉溺於東方的神秘魔力之中。星期六的晚上,我要求要去逛市集。我舅媽很吃驚,懷疑我是不是參加了反天主教會的地下活動【註】。我在教室裡很少回答問題,我看到老師的臉色從溫和可親逐漸變得嚴肅起來;他希望我不要漫不經心。我沒法子把散亂的思緒重整起來。我對生活中正經的事,逐漸失去耐性。這些橫在我和我的欲望之間的事,看起來只是孩子們的遊戲,只是一些幼稚無聊的兒戲罷了!
`【註】共濟會(Freemason)為英國新教徒的組織,其成立宗旨在於抵制羅馬天主教。它的成員多為男性,經常以秘密的方式集會。`
星期六早晨,我提醒舅舅說我當天晚上想要去逛市集。他正在衣帽架上窸窸索索地尋找帽刷子,只簡短地回答說:
──我知道了,孩子。
因為他在走廊上,所以我沒有辦法穿過前廳到窗邊去趴下來窺看。我的心情惡劣極了,只有離家踱步到學校去。路上的空氣冷冽無比,我的心情也隨之不安了起來。
我回家吃晚飯的時候,舅舅還沒回到家。時間還早。我坐下來盯著時鐘看了好一會兒,一直到覺得時鐘的滴答聲令人坐立不安,才離開房間。我爬樓梯,到二樓的房間去。這些高高在上空洞、冰冷、幽暗的房間,反給了我一種自由解放的感覺。我一面哼著歌曲,一面從一個房間走到另一個房間。從前面的窗戶向下看,我看見我那些夥伴們在街上遊戲。他們的叫聲傳到這裡時已經變得微弱而模糊不清了。我把前額貼在冰涼的窗戶玻璃上,俯瞰著她家那幢陰暗的房子。我大概在那兒站了一小時,但什麼都沒看清楚,除了想像中的那個棕色身影,那燈光投射下的粉頸曲線、那擺在欄杆上的纖手、那底裙的蕾絲邊。
我下樓來,看見莫瑟太太坐在爐火邊。她經營一家當鋪店,是個長舌嘮叨的老寡婦。她收集舊郵票,替教會做慈善公益。我必須忍受她在餐桌上的喋喋不休。這頓飯吃了超過一小時,但是舅舅還是沒回來。莫瑟太太起身告別,說八點多了,她不能再等了,因為她不喜歡太晚了還在街頭走動,夜晚的空氣對她的身子不好。她走後,我開始在屋子裡踱來踱去,一雙拳頭握得緊緊的。舅媽說:
──你今天晚上恐怕去不成市集了!
晚上九點的時候,我聽見舅舅的鑰匙轉動廳門的聲音。我聽見他在自言自語,也聽見他掛大衣時,衣帽架搖晃的聲音。我當然知道這些聲響所代表的意義。在他飯吃一半時,我向他要錢去市集。他完全忘了這回事。
──現在大家都已經上床睡過一覺了吧!他說。
我沒有笑。舅媽很認真地告訴他:
──給他錢,讓他去吧。你已經耽誤他夠久了!
舅舅回答說他很抱歉忘了這件事。他說他相信一句古老的諺語:「只有工作沒有娛樂,會讓人變傻變笨。」他問我要去哪裡,我回答他兩次以後,他問我知不知道〈阿拉伯人告別良駒〉這首詩【註】?我離開房子的時候,他正要開始對舅媽朗誦這首詩的開頭幾行。
`【註一】〈阿拉伯人告別良騎〉這首詩是諾頓夫人(1808─1877)所寫的一首浪漫詩。阿拉伯人把自己的馬賣了卻又反悔,最後再把馬買回來。這首詩的前幾行是:`
※※※
我美麗的馬兒啊!溫順地站在我身旁
你背如弓,頸子閃亮,眸子烏黑如灼
我擔憂,沒了你,今後恐無法在沙漠上飛馳!
不能再騎你了──你已賣出了,我的阿拉伯神駒;
我煩惱,馬蹄聲不再急切,輕煙不再揚起──
如今,你飛馳而去,把我遠遠拋在後頭。
※※※
當我踏上白金漢大街朝著火車站去的時候,我手裡緊緊地握著一枚金幣。街燈明亮,街頭擠滿了採購的人潮,我念著不忘此行的目的。我上了一輛空盪盪的火車,在一節三等車廂坐了下來。經過一段難以忍受的延遲之後,火車終於緩緩開出。它慢慢爬行經過荒蕪的屋舍,越過蜿蜒的河流。經過衛斯蘭蘿車站時,一大群人推擠在車廂門前,但是站務員告訴他們這是開往市集的專車,他們不能上車。我孤零零的一個人坐在空無一人的車廂裡。幾分鐘後,車子停靠在一個臨時搭建的木造月台邊。我走過月台到馬路上,看到時鐘上有亮光的指針指著九點五十分。我眼前一幢龐大的建築物,高懸著那個具有魔力的名字。
我找不到任何六便士的入口,但又擔心市集要關門了,所以就拿一先令給一位滿臉疲憊的看門老頭,很焦急地通過一個旋轉柵門,接著發現自己置身在一個大廳之中,它的半高處環繞著一圈各式各樣的攤位。此刻大多數的攤位都收攤了,而大廳的絕大部分也已經罩在黑暗之中。就像教堂禮拜儀式剛結束的那一刻,我感受到一股靜默之聲,瀰漫其間。我帶著怯懦的心情,走到市集的中央,看到有些人還逗留在尚未打烊的攤子邊。在一家有彩色燈泡閃著「音樂咖啡廳」的店前,有兩個人正在數著托盤上的錢。我靜靜聆聽著硬幣落在托盤的聲音。
我費了一些勁才想起我此行的目的,於是我走到一個攤子前,挑著看一些瓷器花瓶和一些燒有花朵圖案的茶具。在攤子的入口處,一位小姐和兩位年輕人正在談天說笑。我聽到他們的英國腔,和一些模模糊糊的對話:
──喔!我沒說過這件事!
──喔!但是你有!
──喔!我沒有!
──她沒有說嗎?
──有,我有聽到。
──喔!你…… 胡說!
那位小姐看到我,就走過來問我要買什麼。她說話的口氣聽起來並不像要鼓勵我買東西,似乎只是在虛應故事。我看到攤位入口的兩旁,擺著兩只看起來像東方衛士的大花瓶,便細聲客氣地說:
──沒有,謝謝你。
這位小姐把其中一只花瓶移動一下,再回去和那兩位年輕人聊天。他們又聊起同樣的話題。偶爾,那位小姐會轉頭過來看我一眼。
我在她的攤位前逗留一會兒,裝出我對瓷器花瓶很感興趣的樣子,雖然我知道我的逗留已經沒意義了。我慢慢轉身離去,走到市集的中央。我把玩著口袋裡的兩個一便士的錢幣,讓它們落在六便士錢幣的上面。我聽到一個聲音從長廊的另一端傳來,說要熄燈了!大廳的上半部現在已經完全暗了下來。
凝視著這一片漆黑,我看見自己像一隻被虛榮心驅使與嘲弄的可憐蟲;眼裡不禁燃起憤怒與羞愧的熊熊烈火。
from [他枯燥无味的人生](:/e4bb63e857504431952def322cc2692d)
阿莱夫_博尔赫斯文集_博尔赫斯 小说在线阅读
======================
<https://www.kanunu8.com/book3/7491/164095.html>
阿莱夫_博尔赫斯文集_[[博尔赫斯]]
> 啊,上帝,即便我困在坚果壳里,我仍以为自己是无限空间的国王。
> 啊,上帝,即便我困在坚果壳里,我仍以为自己是无限空间的国王。《哈姆雷特》第二幕第二场他们会教导我们说,永恒是目前的静止,也就是哲学学派所说的时间凝固;但他们或任何别人对此并不理解,正如不理解无限广阔的地方是空间的凝固一样。
>
> 《利维坦》第四章第四十六节
贝亚特丽丝 · 维特波临终前苦楚万分,感伤和恐惧都不能使痛苦缓解片刻,终于在 2 月份一个炎热的早晨去世,那天我发现宪法广场高耸的广告铁架换了一个不知什么牌子的香烟广告;那件事让我伤心,因为我明白不停顿的广大的世界已经同她远离,广告牌的变化是一系列无穷无尽的变化中的第一个。世界会变,但是我始终如一,我带着悲哀的自负想道;我知道我对她不合情理的爱慕有时使她难以容忍;如今她死了,我可以专心致志地怀念她,不抱希望,但也没有屈辱感。我想,4 月 30 日是她的生日;那天去加拉伊街他们家探望她的父亲和她的表哥卡洛斯 · 阿亨蒂诺 · 达内里是合乎礼节的,无可非议,或许也无可回避。我将再次等在幽暗的、满是摆设的小会客室里,再次端详她许多背景各异的相片。贝亚特丽丝 · 维特波彩色的侧面照;1921 年狂欢节时贝亚特丽丝戴着面具的照片;贝亚特丽丝第一次领圣餐;贝亚特丽丝和罗伯托 · 亚历山德里结婚那天的留影;贝亚特丽丝离婚后不久在马术俱乐部午餐会上;贝亚特丽丝同德利亚 · 圣马科 · 波塞尔和卡洛斯 · 阿亨蒂诺在基尔梅斯;贝亚特丽丝和维列加斯 · 阿埃多送给她的哈巴狗在一起;贝亚特丽丝的正面照和斜侧面照,手托着下巴在微笑…… 我不必像往常那样带几本送她的书作为去拜访的借口,我终于学了乖先把那些毛边书书页裁开,免得几个月后发现它们原封未动而发窘。
贝亚特丽丝 · 维特波是 1929 年去世的;此后每年到了 4 月 30 日我总是去她家看看。我一般在七点一刻到,坐二十多分钟;每年晚去一会儿,多坐一些时间;1933 年那次一场瓢泼大雨帮了我忙:他们不得不留我吃晚饭。我当然不错过那个良好的开端;1934 年那次到她家时已过八点钟,我带了圣菲的杏仁甜饼;很自然地留下吃饭。这样,在忧伤和略带哀艳的周年纪念日里,我逐渐赢得了卡洛斯 · 阿亨蒂诺 · 达内里的信任。
贝亚特丽丝颀长老弱,略微有点朝前倾;她的步态(如果允许使用矛盾修饰法的话)有一种优美的笨拙,一种陶醉的意味;卡洛斯 · 阿亨蒂诺脸色红润,身体壮实,头发灰白,眉清目秀。他在南郊一家不出名的图书馆里担任一个不重要的职务;他相当专横,但不起作用;从不久前始,晚上和节日他都待在家里不外出。虽然隔了两代,他的意大利口音和说话时的大量手势依然存在。他的心理活动活跃、激动、多变,但无足轻重,充满了无用的类推和多余的顾虑。他的手(像贝亚特丽丝一样)细长漂亮。有几个月,他迷上了保尔 · 福特,他佩服的不是福特的歌谣,而是他无可挑剔的名声。"福特是法国诗人中的王子," 他自负地说。"你再怎么攻击他也是白费气力;你的浸透毒汁的箭休想射中他。"
1941 年 4 月 30 日,我在杏仁甜饼之外,加了一瓶国产的白兰地酒。卡洛斯 · 阿亨蒂诺尝了酒,觉得味道不错,几杯下肚后,他开始为现代人进行辩护。
"我想到书房里的现代人," 他带着莫名其妙的兴奋说,"仿佛在一座城堡的塔楼里,配备有电话、电报、唱机、无线电报机、电影机、幻灯机、词典、时刻表、便览、简报……"
他评论说,具有这种便利条件的人根本不需要出门旅行;我们的 20 世纪改变了穆罕默德和山的寓言;如今大山移樽就教,向现代的穆罕默德靠拢了。
我觉得那些想法是如此愚蠢,表达的方式又如此自命不凡,马上把它们同文学联系起来;我问他为什么不留诸笔墨。他果然不出所料回答说已经这么做了:多年来他一直在写一部长诗,从不宣扬,从不大吹大擂,只靠勤奋和孤寂两根拐杖,那些想法和另一些同样新奇的概念都包含在长诗的引子篇、给论篇,或者干脆叫前言篇里。他首先打开想像的闸门;然后遣词造句,合辙押韵。那部诗题名为 "大干世界";主要是描绘地球,当然也不缺渲染烘托的题外话和帅气的呼语助词。
我请他念一节给我听听,即使短一点也不妨。他拉出写字桌的抽屉,取去一个大卷宗夹,里面是印有胡安 · 克里索斯托莫 · 拉菲努尔图书馆名称的便笺,自鸣得意地朗诵起来:
我像希借人一样看到了人们的城市,
工作、五光十色的时日、饥饿;
我不纠正事实,也不篡改名字,
但我记叙的航行是在房间里的卧游。
"显而易见是很有趣的诗节," 他自己评定说。"第一句虽然不被舆论界占多数的紫色派学者赞赏,却得到教授、学院派和研究古希腊文化的学者的喝彩;第二句笔锋一转,从荷马谈到赫西奥德(仿佛一座新房子的门脸,这完全是对教学诗歌之父的含蓄的恭维),并且对那种可以溯源到《圣经》的综述堆砌的手法有所创新;第三句——巴罗克风格、颓废主义、对形式的净化和狂热的崇拜?——包含两个对称的半句;第四句不言自明,有双语成分,凡是豁达恢弘、有幽默感的人在这句诗上都对我佩服得五体投地。我不必谈韵脚和功力了,不是卖弄,四句诗里包含了上下三千年浓缩文学的三个精辟的隐喻:第一个指《奥德赛》,第二个指《工作与时日》,第三个指那个萨瓦人妙笔给我们留下的不朽的小诗……" 我再一次领会到现代艺术要求笑的调剂,要求有些玩笑。哥尔多尼的话确实不假!
他还念了许多节诗,自赞自叹,作了大量评论。我听过之后毫无印象;甚至不觉得它们比前面一节更糟。从达内里的诗里可以看到勤奋、忍耐和偶然性,就是看不到他自己所说的才华。我明白,那位诗人的气力不是花在诗上,而是千方百计找出理由来让人赞赏他的诗;很自然,这番努力提高了他作品在他心目中的地位,但是改变不了别人的看法。达内里的朗诵有点狂放;但除了极个别的情况之外,笨拙的韵律妨碍了他把那种狂放传递给他的诗句。
我生平只有一次机会细读了《波利奥比昂卜万五千行十二音节的诗,迈克尔 · 德雷顿在那首地形史诗里记载了英国的动植物、水文、山岳、军事和寺院的历史;我敢说这部有分量、但也有局限性的作品使人厌倦的程度要低于卡洛斯 · 阿亨蒂诺同样性质的鸿篇巨制。他雄心勃勃地想用诗歌表现整个地球;1941 年,他已经解决了昆士兰州几公顷土地、鄂毕河一公里多的河道、维拉克鲁斯北面的一个贮气罐、康塞普西翁区的主要商行、玛丽亚娜 · 坎巴塞雷斯 · 德 · 阿韦亚尔在贝尔格拉诺九月十一日街上的别墅,以及离布赖顿著名水族馆不远的一家土耳其浴室。他又念了他诗中有关澳大利亚地区的吃力的段落;那些又长又不像样的亚历山大体的诗句缺少引子里比较使人激动的东西。我不妨抄录一节:
听着。在那根通常的木桩右面
(不用说,当然是从北、西北方向过来)
有一具无聊的骨架——颜色么,天白——
给了羊栏以尸骨家的面貌。
"两个奇崛的用法,简直妙不可言," 他狂喜地嚷道。"我已经听到你在暗暗叫绝了!我承认,我承认。首先是那个形容词通常,它一针见血地点破了田园农事固有的,不可避免的沉闷,以前的田园诗和我们的赫赫有名的《堂塞贡多 · 松布拉》从不敢这样淋漓尽致地指出过。其次,那个平铺直叙、然而力透纸背的无聊的骨架在矫揉造作的诗人的眼里会被看成异端邪说,但是欣赏道劲豪放的批评家却爱之苦命。此外,整个一节诗品位很高。第三行后半句和读者生动活泼地攀谈起来;它料到读者迫切的好奇心理,借读者之口提个问题,随即又作了回答。至于那个创新天白,你如何评价?那个形象生动的新词使人联想到天空,而天空是澳大利亚风景的至关重要的因素。如果没有那个联想,全诗的笔调难免过于暗淡,读者内心深处将被无法缓解的悲哀所袭,不得不掩卷长叹。"
将近午夜时我才告辞。
过了两个星期天,达内里打电话找我,据我记忆所及,那是他生平第一次。他邀我四点钟见面,"一起在附近的酒吧沙龙喝牛奶,那是有开拓思想的苏尼诺和松格里——也就是我的房东,你记得吗——在街角新开的咖啡馆;你该见见这个场所。" 我兴致不高,无可奈何地同意了。我们好不容易才找到一张空桌;那个 "酒吧沙龙" 现代化得没治,糟糕的程度比我想像的稍低一些;旁边几张桌子的顾客兴奋地谈论着苏尼诺和松格里毫不吝啬的巨额投资。卡洛斯 · 阿亨蒂诺装出为灯光设计的精致感到惊奇(其实他肯定早见过了),一本正经地对我说:
"不管你愿不愿意,你得承认这个地方可以和弗洛雷斯街最高级的咖啡馆相比。"
然后他把他的诗又念了四五页给我听。他根据那个炫耀辞藻的等而下之的原则作了修改:原先写成湛蓝的地方,现在改为蓝晶晶、蓝莹莹、甚至蓝盈盈。他本来认为乳白这个词不坏;在描写洗羊毛池的时候,他换了奶白、乳汁白、乳浆白…… 他痛骂批评家;接着,他比较厚道地把批评家说成是 "那种自己没有铸币的金银,也没有蒸汽压机、滚轧机和硫酸,但能指点别人藏镪的地点"。随后,他抨击了前言癖,"天才中的天才在《堂吉诃德》的优雅的前言里已经嘲笑了这种毛病。" 然而他承认在新著的扉页最好有一篇显眼的前言,由一位有声望、有地位的名士签署的认可。他说他打算发表长诗的前几章。我明白了那次奇特的电话邀请的动机;那人想请我替他的卖弄学识的杂烩写个前言。我的担心是没有根据的:卡洛斯 · 阿亨蒂诺带着怨恨的钦佩说,阿尔瓦罗 · 梅利安 · 拉菲努尔是个有学问的人,如果我出面求他欣然为长诗写序,他博大精深的声望也就名副其实了。为了防止最不可原谅的失误,我得为两个未完成的优点做说客:十全十美的形式和严格的科学内容,"因为在那个优美比喻和形象的花园里最小的细节都严格符合真实"。他又说贝亚特丽丝生前和阿尔瓦罗一直相处甚得。
我满口答应。为了做得更逼真,我声明我不在星期一,而在星期四作家俱乐部会后通常举行的小型晚餐会上和阿尔瓦罗谈这件事。(晚餐会是没有的,会确实在星期四开,卡洛斯 · 阿亨蒂诺 · 达内里从报纸上可以核实,相信我的话有点真实性。)他半是猜测,半是机灵地说,在提到序言之前,我会介绍作品奇特的构思。我们分了手;在拐到贝尔纳多 · 德 · 伊里戈延街之前我毫无偏见地看到面前的两种可能性:一、找阿尔瓦罗谈谈,告诉他贝亚特丽丝的那位表哥(我用那种委婉的解释才能提起贝亚特丽丝)写了一部长诗,似乎能无限制地延伸唠叨和混乱的可能性;二、不和阿尔瓦罗谈。我清醒地预见到生性懒惰的我会选择第二种可能性。
从星期五一早开始,电话就使我忐忑不安。我气恼的是那个装置以前曾传来再也听不到的贝亚特丽丝的声音,现在随时都可能成为那个失望的卡洛斯 · 阿亨蒂诺 · 达内里无用的、甚至愤怒的抱怨的传话筒。幸好他没有来电话,但那人先则强人所难,要我办一件棘手的事,后又把我忘得一千二净,使我满腹不快。
电话不再是可怕的东西,然而 10 月底的一天,卡洛斯 · 阿亨蒂诺打电话来找我。他非常着急,开头我辨不出是他的声音。他又恨又气地说那两个贪得无厌的家伙,苏尼诺和松格里,借口扩大他们的无法无天的咖啡馆准备拆除他的住房。
"我祖祖辈辈的家,我的家,加拉伊街根深蒂固的老家!" 他气急败坏,也许忘了斟酌音韵。
我不难分担他的苦恼。过了四十年之久,任何变动都是时间流逝的令人难以忍受的象征;此外,对我来说,那幢房子永远是贝亚特丽丝的影射。我想说明这个十分微妙的特点;对方根本听不进。他说如果苏尼诺和松格里坚持他们荒唐的计划,他的律师松尼博士将根据事实向他们起诉,要求赔偿损害,付十万比索。
松尼的名字使我肃然起敬;他在卡塞罗斯一塔夸里街的事务所信誉卓著。我问他是不是已经承办了这件案子。达内里说当天下午找他谈。他迟疑了一下,然后像透露一件十分隐秘的事那样,用平淡客观的声调说,为了完成那部长诗,那幢房子是必不可少的。因为地下室的角落里有个阿莱夫。他解释说,阿莱夫是空间的一个包罗万象的点。
"就在餐厅下面的地下室里," 他解释说,由于苦恼而压低了声音。"是我的,我的,我小时候还没有上学之前发现的。地下室的楼梯很陡,我的叔叔不让我下去,但是听别人说地下室别有天地。我后来才知道指的是一个大箱子,但当时我以为真是一个天地。我偷偷地去看,在禁止的楼梯上一脚踩空,滚了下去。我再睁开眼睛时,看到了阿莱夫。"
"阿莱夫?" 我说。
"不错,从各种角度看到的、全世界各个地方所在的一点。我没有向任何人透露我的发现,但我回去了。小孩不懂得他已得到长大时雕琢诗篇的天赋!苏尼诺和松格里休想把我轰走,不行,一千个不行。松尼博士手持法典将证明我的阿莱夫是不可转让的。"
我试图作一些推理。
"地下室不是很暗吗?"
"真理不会进入拒绝理解的心灵。既然世界各地都包罗在阿莱夫里面,那么所有的灯盏和所有的光源当然也在其中了。"
"我马上去看。"
我唯恐他拒绝,立即挂断电话。一件小事就足以证实以前没有想到的一系列疑点;我奇怪为什么在此以前不知道卡洛斯 · 阿亨蒂诺神经有毛病。维特波一家人,还有…… 贝亚特丽丝(我自己常这么说)是个异常敏锐的女人,从小如此,但她有疏忽、走神、马虎和真正残忍的地方,也许需要从病理学的观点才能找出原因。卡洛斯 · 阿亨蒂诺神经不正常使我幸灾乐祸,我们内心里一向互相厌恶。
到了加拉伊街,女仆请我稍候。那个大孩如往常一样,在地下室冲印相片。无用的钢琴上那个空花瓶旁边,贝亚特丽丝的色彩刺眼的大照片在微笑(与其说是时代错乱,不如说是不受时间限制)。谁也见不到我们;我一时感情迸发,走近照片对她说:
"贝亚特丽丝,贝亚特丽丝 · 埃莱娜,贝亚特特丽丝 · 埃莱娜 · 维特波,亲爱的贝亚特丽丝,永远失去了的贝亚特丽丝,是我呀,是博尔赫斯。"
过了不久,卡洛斯来了。他说话的口气很冷漠;我理解他一心只想着失去阿莱夫的事。
"你先喝一小杯白兰地," 他吩咐说,"然后钻进地下室。你知道,你必须仰躺着。在黑暗里,一动不动,让眼睛先适应一下。你躺在砖地上,眼睛盯着楼梯的第十九级。我走了,放下地板门,你一个人待着。也许有个别耗子会吓你一跳,再简单不过了。几分钟后,你就会看到阿莱夫。炼丹术士和神秘哲学家们的微观世界,我们熟悉的谚语的体现:麻雀虽小,五脏俱全!"
在餐厅里,他又说:
"即使你看不到,你的无能显然也驳不倒的话…… 下去吧;你很快就能和贝亚特丽丝所有的形象交谈了。"
他的废话叫我腻烦,快步下去。地下室不比楼梯宽多少,很像一口井。我用目光搜寻卡洛斯 · 阿亨蒂诺说的大箱子,但是找不见。一个角落里堆放着几箱瓶子和一些帆布袋。卡洛斯拿了一个帆布袋,把它对折好,放在一个特定的地方。
"枕头差点劲," 他解释说,"不过只要再高一公分,你就什么都看不到,丢人现眼了。你就在地上摆平,数一十九级楼梯。"
我按照他荒唐的要求做了;他终于走开。他小心翼翼地盖好地板门;尽管我后来发现一道罅隙,地下室一片漆黑。我蓦地领会到自己的危险:我喝了一杯毒酒,然后听一个疯子摆布,给埋在地下。卡洛斯的大话里流露出唯恐我看不到神奇现象的恐惧;卡洛斯为了维护他的谵妄,由于不知道自己是疯子,非把我杀掉不可。我觉得浑身不自在,但我归因于躺的姿势,而不是麻醉剂的作用。我合上眼睛,过一会又睁开。我看到了阿莱夫。
现在我来到我故事的难以用语言表达的中心;我作为作家的绝望心情从这里开始。任何语言都是符号的字母表,运用语言时要以交谈者共有的过去经历为前提;我的羞惭的记忆力简直无法包括那个无限的阿莱夫,我又如何向别人传达呢?神秘主义者遇到相似的困难时便大量运用象征:想表明神道时,波斯人说的是众鸟之鸟;阿拉努斯 · 德 · 英苏利斯说的是一个圆球,球心在所有的地方,圆周则任何地方都不在;以西结说的是一个有四张脸的天使,同时面对东西南北。(我想起这些难以理解的相似不是没有道理的,因为它们同阿莱夫有关。)也许神道不会禁止我发现一个相当的景象,但是这篇故事会遭到文学和虚构的污染。此外,中心问题是无法解决的:综述一个无限的总体,即使综述其中一部分,是办不到的。在那了不起的时刻,我看到几百万愉快的或者骇人的场面;最使我吃惊的是,所有场面在同一个地点,没有重叠,也不透明,我眼睛看到的事是同时发生的:我记叙下来的却有先后顺序,因为语言有先后顺序。总之,我记住了一部分。
我看见阶梯下方靠右一点的地方有一个闪色的小圆球,亮得使人不敢逼视。起初我认为它在旋转;随后我明白,球里包含的使人眼花缭乱的场面造成旋转的幻觉。
阿莱夫的直径大约为两三公分,但宇宙空间都包罗其中,体积没有按比例缩小。每一件事物(比如说镜子玻璃)都是无穷的事物,因为我从宇宙的任何角度都清楚地看到。我看到浩瀚的海洋、黎明和黄昏,看到美洲的人群、一座黑金字塔中心一张银光闪闪的蜘蛛网,看到一个残破的迷宫(那是伦敦),看到无数眼睛像照镜子似的近看着我,看到世界上所有的镜子,但没有一面能反映出我,我在索莱尔街一幢房子的后院看到三十年前在弗赖本顿街一幢房子的前厅看到的一模一样的细砖地,我看到一串串的葡萄、白雪、烟叶、金属矿脉、蒸汽,看到隆起的赤道沙漠和每一颗沙粒,我在因弗内斯看到一个永远忘不了的女人,看到一头秀发、颀长的身体、乳癌,看到行人道上以前有株树的地方现在是一圈干士,我看到阿德罗格的一个庄园,看到菲莱蒙荷兰公司印行的普林尼《自然史》初版的英译本,同时看到每一页的每一个字母(我小时候常常纳闷,一本书合上后字母怎么不会混淆,过一宿后为什么不消失),我看到克雷塔罗的夕阳仿佛反映出孟加拉一朵玫瑰花的颜色,我看到我的空无一人的卧室,我看到阿尔克马尔一个房间里两面镜子之间的一个地球仪,互相反映,直至无穷,我看到鬃毛飞扬的马匹黎明时在里海海滩上奔驰,我看到一只手的纤巧的骨胳,看到一场战役的幸存者在寄明信片,我在米尔扎普尔的商店橱窗里看到一副西班牙纸牌,我看到温室的地上羊齿类植物的斜影,看到老虎、活塞、美洲野牛、浪潮和军队,看到世界上所有的蚂蚁,看到一个古波斯的星盘,看到书桌抽屉里的贝亚特丽丝写给卡洛斯 · 阿亨蒂诺的猥亵的、难以置信但又干真万确的信(信上的字迹使我颤抖),我看到查卡里塔一座受到膜拜的纪念碑,我看到曾是美好的贝亚特丽丝的怵目的遗骸,看到我自己暗红的血的循环,我看到爱的关联和死的变化,我看到阿莱夫,从各个角度在阿莱夫之中看到世界,在世界中再一次看到阿莱夫,在阿莱夫中看到世界,我看到我的脸和脏腑,看到你的脸,我觉得眩晕,我哭了,因为我亲眼看到了那个名字屡屡被人们盗用、但无人正视的秘密的、假设的东西:难以理解的宇宙。
我感到无限崇敬、无限悲哀。
"你这样呆头呆脑地看下去要走火入魔了," 一个厌烦的声音取笑说。"我让你大开眼界,你绞尽脑汁一百年都报答不清。多么了不起的观察站,博尔赫斯老兄!"
卡洛斯 · 阿亨蒂诺的鞋子出现在最高的梯级上。我在昏暗中摸索着站起来,含含糊糊地说:
"了不起,确实了不起。"
我冷漠的口气使我自己也感到惊奇。卡洛斯 · 阿亨蒂诺急切地追问:
"你是不是都看清了,带色的?"
那时我想出报复的办法。我和蔼地、摆出十分同情但又不安地谢了卡洛斯 · 阿亨蒂诺 · 达内里盛情让我看了他的地下室,然后请他利用房屋拆除的机会离开有害的大城市,因为它饶不了任何人,对,任何人!我委婉而坚决地闭口不谈阿莱夫;我和他拥抱告别,再次重申乡村和宁静是两位好大夫。
在街上,在宪法大街的梯级上,在地下铁道,我觉得每一张脸都是熟悉的。我担心没有一张脸会使我感到惊奇,担心回来的印象永远不会消退。幸运的是,经过几个不眠之夜后,遗忘再一次在我身上起了作用。
1943 年 3 月 1 日后记:加拉伊街的房子拆除六个月之后,普罗库斯托出版社没有被那部长诗的篇幅吓倒,推出一个《阿根廷片段》选集。无需重复发生的事情;卡洛斯 · 阿亨蒂诺 · 达内里获得了国家文学奖二等奖。一等奖授予艾塔博士;三等奖获得者是马里奥 · 布范蒂博士;难以置信的是,我的作品,《赌棍的纸牌》,一票都没有捞到。不理解和嫉妒再一次占了上风!我好久没能和达内里见面,报上说他另一卷诗选很快就要出版。他那枝走运的笔(如今已不受阿莱夫的妨碍)已经致力于把阿塞韦多 · 迪亚斯博士的概述改写成诗歌。
我想补充说明两点:一是关于阿莱夫的性质;二是关于它的名称。大家知道,阿莱夫是希伯来语字母表的第一个字母。用它来做我啰唆的故事的标题并不是信手拈来的。在犹太神秘哲学中,这个字母指无限的、纯真的神明;据说它的形状是一个指天指地的人,说明下面的世界是一面镜子,是上面世界的地图;在集合论理论中,它是超穷数字的象征,在超穷数字中,总和并不大于它的组成部分。我想知道的是,卡洛斯 · 阿亨蒂诺自己想出这个名称呢,还是在他家的阿莱夫向他揭示的无数文章中看到的,然后拿它来指诸点汇合的另一点呢?看来难以置信,我却认为另外有(或者有过)另一个阿莱夫,我认为加拉伊街的阿莱夫是假的。
我谈谈我的理由。1867 年,伯顿船长在巴西担任英国领事;1942 年 7 月,佩德罗 · 恩里克斯 · 乌雷尼亚在巴西桑托斯的一家图书馆里发现了伯顿的一份手稿,谈到那面指点马其顿亚历山大大帝去征服东方的镜子。那面镜于反映了整个宇宙。伯顿还提到其他相似的器具——凯 · 约斯鲁的七倍杯,塔里克 · 本泽亚德在一座塔中找到的镜子(《一千零一夜》,第二百七十二夜),卢西亚诺 · 德 · 萨莫萨塔可以从中看到月亮的镜子(《真实故事》,第一卷第二十六章),彼特罗纽斯的《萨蒂里康》第一卷说的朱庇特的有镜子功能的长矛,巫师默林的包罗万象的镜子,"圆形中空,像一个玻璃世界"(《仙后》,第三卷第二章第十九节)——又说了这么一段奇怪的话:"前面所说的(除了根本不存在的缺点之外),无非是一些光学器具。去开罗阿姆尔清真寺礼拜的信徒们清楚地知道,宇宙在中央大院周围许多石柱之一的内部…… 当然,谁都看不到,但是把耳朵贴在柱子上的人过不久就宣称听到了宇宙繁忙的声响……" 清真寺建于 7 世纪;石柱是从早在伊斯兰教创始之前的其他寺院迁来的,正如阿本贾尔敦写的:"在游牧民族建立的共和国里,任何土木工程都需要外来工匠的协助。"
难道石头内部存在阿莱夫?当我看到所有的事物时是不是也看到了它?我们的记忆是容易消退的;在岁月悲惨的侵蚀下,我自己也在歪曲和遗忘贝亚特丽丝的面貌。
献给埃斯特拉 · 坎托
以上译自《阿莱夫》
[[阿丽阿德娜的石头 - 阿尔贝·加缪 |https://www.kanunu8.com/files/little/2012/09-06-8137.html]]
阿丽阿德娜的石头
来源: 作者:阿尔贝·加缪 发布时间:2012-09-06
阿尔贝·加缪作品全集
-----
峨朗的居民像是福楼拜的那位朋友,他临终时望了这不变的世界一眼,说道:“关上窗子吧!它太美了。”他们关上了窗户,封闭了自己,隔离了风景。但是福楼拜的朋友勒布洼德万(Le Poittevin)死了,岁月依旧。同样的,在峨朗的黄褐色的围墙外,大地和海岸仍然继续着它们漠然的对话。世上的这种表演对人永远有两种媚力。它让人绝望,却又刺激他。世界永远只表达一件事物:它首先吸引人,然后让人厌倦,最后它凭顽固的一声赢得了胜利。它永远是对的。
自然在峨朗的每一扇门,已经响起了它的声音。在卡纳斯特尔方面,有覆盖着芬芳灌木丛的荒原。太阳和风诉说着的只是孤独。峨朗上面是圣十字山,是高原以及千万道入山的峪谷。一度通行车马的道路攀向高悬海面的斜坡。正月天里,有些路上满是花朵。雏菊和金凤花把它们变化成黄白缀饰的锦绣大道。圣十字山是众所周知的,如果我要谈它,我应该忘记那些在飨宴的日子,为了回忆往昔朝圣而攀登崎岖的神圣行列。静静地,他们踏着红石,高踞在一平如镜的海湾上,在一个完美的晨光里,献身给赤裸。
峨朗也有它的沙漠:它的海滩。城门附近的那些沙滩冬春两季被人遗弃了。他们是长满水仙花的高地,百花缤纷中也有光秃秃的小茅屋。底下是隐隐吼号的大海。然而,太阳、微风、水仙的白艳和天空的碧蓝,一切都使人想起夏天——躺在海滩上的金黄色青年,沙上的镇日盘桓,以及黄昏倏然而至的柔情。在那些海滩上每天都有一次鲜花般姑娘的丰收。显而易见的,她们只能开放一季。第二年,新开的热情花朵取代了她们。去年,那些女孩的胴体,还硬梆梆的像花苞一样。上午十一点钟,所有的新鲜胴体穿着花花绿绿的东西,走下了高地,在沙滩上散开,有若五彩的波浪。
再走远一点(怪的是很接近那二十万人劳作的地点)我们会发现一处更原始的风景:一长条荒僻的沙丘,那儿只有一间虫蛀了的小木屋是唯一有人迹的地方。许多年来,一个阿拉伯牧人沿着沙丘的顶端赶着那群黑色的灰斑的山羊。每一个夏日清晨似乎最先降到峨朗乡间的沙滩上。每一道暮霭似乎都是夕阳西下时,染黑一切色彩的最后光线所宣布的最后且肃穆的愤怒。海是蔚蓝的,道路是血凝色的,海滩是黄的,万物皆随绿色的太阳消失了。一小时后,沙丘又沐浴在月光下了,然后便是星雨下无边的夜。偶尔,暴风雨来袭,闪电照亮了沙丘和天空,给沙地和人们的眸子增添了金色的闪光。
这一切是无法分享的,人们必须亲身经历它。广阔的孤独和崇高,赋予这地方一种令人难忘的面貌。在破晓前的温暖片刻中,遭遇过第一道苦涩、黑色的浪潮后,一个新的生命抵抗着夜晚那广袤、沉浊的水。这些欢乐所留给我的回忆,并未使我惋惜,因此我认为它们是善的。经过这许多年月后,它们仍然存在于这颗善变之心的深处。现在我知道,假如我再回到那荒僻的沙丘上去,同样的天空会向我倾泻它的微风和星斗。这些地方是天真的土地。
然而,天真是需要沙和石头的,人类已经遗忘了如何在沙石中居住。至少表面上是这样的,因为人们在这座为厌倦所笼罩着不平凡的城市寻求庇护。虽然如此,这种冷静的对抗形成了峨朗的价值。厌倦的首都被天真与美包围着,它被军队包围着;每块石头都是一个战士。在这城里的某些时刻,投降到敌人那边的诱惑是多么大啊!那是多么大的诱惑啊——与石头同化,把自己融入那燃烧着的、无感觉的、唾弃历史及其纷扰的宇宙!当然,那是徒劳的。然而,任何人都具有一种既非毁灭又非创造的深刻本能。那只是一种不酷似任何事物的东西。在峨朗温暖墙垣的阴影里,在它灰麻麻的柏油路上,人们有时会听到这种邀请的声音。有一度,在它投靠的心灵从不会失望。这是优里底斯(Eurydice)的黑暗和爱惜斯(Isis)的睡眠。在这儿的思想能够集中的沙漠,是黄昏时抚慰一颗烦乱之心的凉手。在这橄榄山上,守夜是徒劳的;心灵召唤着,赞许着十二门徒。他们真的错了吗?他们到底得到了启示。
想想在沙漠中的沙奇亚木尼(Sakyamuni)吧。几年来他竖立着,纹丝不动的蹲在那儿,两眼凝视着苍天。诸神都羡慕他的智慧和如石般的命运,燕子在他伸展的双手上筑巢。但是,有一天他们应着对方的召唤,飞走了。这位四大皆空的苦修者开始哭泣。就这样,花朵在岩石上绽开。是的,必要的时候让我们接受石头吧。我们希冀透过人的面孔得到秘密和狂喜,也可以从石头那儿知道。不错,这不能长存。但究竟有什么能长存呢?人脸的秘密消逝了,我们又被掷回欲望的链条。如果石头如人们所做的不比人心多,至少和它一样。
“哦,一切都空吧!”数千年来,这伟大的呼唤煽动成百万的人反对欲望和痛苦。它那将熄的回声跨过了世纪与海洋,到达那遥远的、世上最古老的海上。他们仍然沉闷地回响在峨朗的山崖上。这国度里的每个人都不自觉地遵循着这项忠告。当然,它几乎是徒然的。空无之不能被求得,何异与绝对之不能被求得。但是,既然我们当作恩惠似地,接受了玫瑰或人类苦难所带来的永恒讯息,让我们也不要拒绝这世界所提出的,让人安眠的罕有邀请吧!因为二者所含的真理是一样的。
也许,这就是这位梦游和这座狂乱的城市的阿丽阿德娜(Ariadne)的线索吧!这儿,人们学会了(当然只是暂时)某种厌倦的德性。为了逃避一死,人们必须对米诺陀说“是的”。这是一种古老但有效的睿智。海上,红色山崖的底部是寂静的,我们能够在两块庞然的山岬间寻得一种微妙的平衡,山岬的左右两边,倾泻降入清澈的水底。沿着远方的水域,沐浴在明亮光辉中有一艘海岸防卫船在巡行。在它的喷气中,我们似乎可以清晰地听到一种非人性的、灼人力量的模糊呼唤:那便是米诺陀的道别。
现在是正午,白昼在天秤上平衡着。旅人的祭典完成了,他享受着解放后的报偿:小小的石头,干燥光滑得像是一朵水仙花,那是他在山崖上拾得的。对一个历经沧桑的人而言,这世界并不比这石头重。阿特拉斯(Atlas)的工作并不困难,选择一个人的时刻足够了。于是人们了解到,这些海岸会浸溺在一小时、一个月或一年的自由重。他们忙乱地欢迎着僧人、公仆,或征服者,虽然可能没有望着他们。有些日子,我当希望在峨朗的街道上遇见笛卡儿或色沙雷·波吉亚(Cesare Borgia),我没有遇到,但也许旁人的运气会好些吧。伟大的事迹、伟大的工作、刚健的冥思用来召唤沙或修道院的孤独。在那儿有武装的精神守夜。除了在一座以非智性的美建筑了许多年的大城的空虚外,它们还能在何处得到更大的礼赞?
这儿是块小石头,光滑得像朵水仙花。这是万物开始之时。花朵、眼泪(如果你坚持的话)、分离和斗争都是属于明天的。在这日中时分,天空在广袤、宏亮的太虚中,喷射出它光明的泉源,海岸上所有的岬角好像要启航的船队。这些沉重的岩石和光明之舟,摇动着他们的龙骨,仿佛要航向日光群岛。哦,峨朗乡间的清晨啊!燕子从高原上投入巨大的山坳,那儿大气激荡着。整个海岸准备出发了;它身上发散出一股冒险的凛冽。明天,也许,我们将一道离去。
艾丽斯·芒罗(又译爱丽丝·门罗,Alice Munro,1931.07.10~),加拿大女作家,被誉为“加拿大的契诃夫”。1968年发表第一部短篇小说集《快乐影子之舞》(Dance of the Happy Shades),并获得加拿大总督文学奖,后来共创作了14部作品并多次获奖,同时作品被翻译成13种文字传遍全球,受到读者与媒体的高度评价。2013年10月10日,艾丽斯·芒罗获得2013年诺贝尔文学奖,瑞典学院给出的颁奖词是:“当代短篇文学小说大师”。由此艾丽斯·芒罗也成为了诺贝尔文学奖历史上的第13位女性。
# 爱的进程 [[艾丽丝·门罗]]
-----
我上班时接到电话,是父亲打来的。那是我离了婚,干起房地产行当后没多久的事。我两个儿子都在上学。九月挺热的一天。
父亲礼貌周全,哪怕对家人也是如此。他不厌其烦,先对我问候一番。乡下人讲究礼节。就算为了通知你家房子着火了,电话里也必定先是一通寒暄。
“我很好啊。”我说,“你呢?”
“不咋样吧,我觉着。”父亲答道,还是他那老一套口气—带点歉意又有点矜持。“我想,你母亲去了。”
我知道“去了”意味着“死了”。这个我懂。然而有那么一两秒钟,我看到的是母亲戴着她的黑色草帽,沿小巷走远的样子。“去了”这个词好像满载的不是别的,而是一股子深深的欣慰甚至欢乐—门一关,你家回到正常状态,你可以无拘无束地享用空间时的兴奋感觉。我父亲的语气里也流露出这种情绪—在歉意的后面,有一种类似屏住呼吸的奇怪音调。然而,我母亲从来都不是个负担啊—她一天也没病过—而且,对于她的去世,我父亲远非感到宽慰,而是难以接受。他说,他从来过不惯一个人的日子。他心甘情愿地搬进内特菲尔德县立老人之家。
他告诉我中午进门时发现我母亲躺在厨房沙发上。她摘了些西红柿,摆在窗台上捂熟,然后一定是觉得不舒服,躺了下来。讲着讲着,他声音颤抖起来—正如你能预料到的,变得结结巴巴—是因为不知所措吧。我在脑海中看到那张沙发,它铺着旧被子,就在电话下方。
“所以我想,最好还是给你打个电话吧。”父亲说。然后等着我吩咐他该干什么。
每天中午、晚上,还有早上,一睁眼,母亲都要跪下祈祷。对她来说,每一天的开始都蕴含着上帝的旨意。每晚她都要总结所做、所说、所想的,看看能否得到上帝的认可。有人可能会觉得这种生活挺无趣的吧,但他们没看到关键。首先,这样一种生活永不会令人厌倦。没有哪件事对你而言不是意味深长的。即便困难重重,生病、穷困、丑陋,你依然能珍惜你的灵魂,就像用盘子端着一枚珍宝走过人生。午饭后上楼祈祷时,我母亲总是精力充沛、兴致勃勃,庄严地微笑着。
她是十四岁那年,在一次营地聚会时被拯救的。就在那个夏天,她自己的妈妈—我外婆—去世了。有好几年,我母亲都会和其他许多被拯救的人一起聚会,其中有些人被拯救了一次又一次,是些热情洋溢的老罪人了。她会讲述聚会上都发生了些什么:唱歌、喊叫、手舞足蹈。她讲过有个老人站起来嚷道:“下来吧,主啊,下到我们中间吧!穿过屋顶下来吧,屋瓦的钱我来赔!”
结婚后,她做回一个简单的圣公会信徒,一个认真的信徒。那会儿她二十五岁,我父亲三十八岁。一对身材高挑、相貌出众的人儿,出色的舞者,打牌高手,擅长社交;不过也是一对认真的人儿—要我一准会这么形容他们。现如今没什么人这样认真地生活啦。我父亲不像我母亲那样笃信宗教。他是圣公会信徒,奥兰治党员,那也是一个保守党派,因为他从小就受那样的教育。几个儿子当中,他留在农场上和父母同住,照料他们一直到去世。他遇到我母亲,等着她,和她结婚。然后他有了一个可以为之奋斗的家庭,为此倍感幸运。(我有两个兄弟,以及一个婴儿时就夭折的妹妹。)我总感觉,在我母亲之前,我父亲从没睡过别的女人,而且娶她之前也没和她睡过。他不得不等啊等的,因为我母亲一直不肯结婚,直到她把她妈去世后,她爸花在她身上的每一分钱都还了回去。一笔一笔账她都记着—食宿啊,书本啊,衣服啊—以便日后偿还。身为教师,她结婚时不像别的教师那样有积蓄,也没嫁妆、床上用品或餐具。父亲时常开玩笑地做出一脸忧郁神情,感叹他本指望娶个银行里有存款的女人。“不过,要弄到银行存款,就得接受那存款的脸蛋儿,”他说,“有时候那样划不来啊。”
我们家有大大的、屋顶高高的房间,装着墨绿色百叶窗。百叶帘拉下、挡住太阳的时候,我常喜欢晃着脑袋,捕捉从孔穴和缝隙里透进的光线。我喜欢看的另一样东西是烟囱的污渍,不管旧的还是新的,我可以把它们想象成各种动物、人脸,甚至远方的城市。我给两个儿子讲这个,他们的爸爸丹·凯西说:“瞧,你们妈妈家里穷透了,他们连电视都买不起,只好在天花板上弄出这些污渍—你们的妈妈只有天花板上的污渍可看!”他素来喜欢取笑我以贫穷为荣的想法。
父亲很老的时候,我发觉他并不怎么介意人们尝试新做法—比如说吧,我的离婚—他更介意的是他们编出各种新理由来作解释。
谢天谢地,他无须知道嬉皮士公社那类事。
“主可从来没想这样。”他常这么感叹。在绣线菊灌木丛后头,和老人之家的其他老人们围坐在漫长昏暗的走廊里,他会感叹,主可从来没想要人们骑着摩托车或雪地摩托车在乡下乱闯。还有主可从来没想要护士们的制服变成长裤。护士们对此毫不介意。她们管他叫“帅哥”,还告诉我他是一个真正的老甜心,一个真正虔诚的老绅士。她们对他那头浓密乌发惊叹不已,他一直到死都是一头密发。她们给他洗头发,梳得漂漂亮亮的,趁还湿着,用她们的手指给它绕出波浪。
有时,尽管她们百般照料,他还是有点闷闷不乐。他想回家。他担心母牛啊,篱笆啊,还操心谁来起床生火的问题。偶尔也会有个把刻薄的瞬间—不过非常少见。一次我进门时,他带着敌意,轻蔑地瞥我一眼,说:“这会儿你膝盖上的皮还没全磨掉啊,真叫我意外。”
我笑了。我问:“为啥?擦地板吗?”
“做祈祷嘛!”他唾弃般道。
他搞不清自己是在和谁说话。
我不记得母亲的头发除了白色以外还有过什么别的颜色。母亲二十出头时头发就白了,而且一缕年轻时的头发都不曾保留—它曾经是棕色的。我常常缠着她告诉我那是一种什么样的棕色。
“深色的。”
“是像布伦特,还是像多莉?”它们是我们家的两匹工作马,组成一支马队。
“我说不清。那又不是马毛。”
“是像巧克力吗?”
“有点吧。”
“它变白了,你不难过吗?”
“没有,我很高兴。”
“为什么?”
“我很高兴我头发的颜色不再跟我爸爸一样了。”
恨始终是一种罪过,母亲告诉过我。记住这个。你灵魂里的一滴仇恨,会扩散开来毁掉所有色彩,就像白牛奶里的一滴黑墨水。我被这个震住了,挺想做个试验来着,但我知道不能浪费牛奶。
我记得所有这些事情。关于我从未见过的人的各种事情,都知道或者听说了。我取名尤菲米亚,这曾是我母亲的母亲的名字。一个可怕的名字,现如今没人叫这个了。在家里他们叫我菲米,不过,我工作后,自己改名叫费玛[1]。我丈夫,丹·凯西,就管我叫费玛。多年后,我离了婚,某次在夏姆洛克饭店的酒吧,我正要出门,一个男人问我:“费玛,我一直想问你来着,你到底为什么有名呢?”
“不知道啊,”我告诉他,“我也不清楚,莫非是因为我会浪费时间跟你这样的傻瓜讨论?”
之后我想过彻底换个名字,诸如琼之类的,可除非我从这里搬走,否则如何能做到呢?
1947年夏,我十二岁,帮着母亲给楼下一间闲置的卧室贴墙纸。母亲的妹妹贝瑞尔要来看我们。两姐妹已多年未见面。她们的母亲去世后,她们的父亲很快就再婚了。他带着新老婆和小女儿贝瑞尔搬到明尼阿波利斯,然后是西雅图。母亲不愿跟他们走。她留在他们之前一直住着的拉姆塞镇上,在一对没孩子的邻居夫妇家寄宿。她和贝瑞尔长大后只见过一两面。贝瑞尔住在加利福尼亚。
墙纸是白底矢车菊花纹的。它是一卷纸的最后一截儿了,母亲以打折价买了来。这意味着我们得煞费苦心地对图案,门背后只能用碎片和纸条拼拼凑凑。那时还没有自粘墙纸这种玩意儿。我们在前厅支起一张搁板桌,调了糨糊,用板刷刷到墙纸背面,挑掉疙瘩。我们忙活着,窗子推上去,留着纱窗透气,关着纱门,敞开前门。透过纱网和不平整的旧玻璃看出去,田野炎热无比,百花盛开—牧场上开着乳草和野胡萝卜花,芥菜疯长,几片田当时种着荞麦,一片奶油色。母亲唱着歌。一首据说是她妈妈常在她和贝瑞尔还是小女孩时唱的歌。
我从前有个情郎,现在落了单。
他走啦,留下我一个人泪汪汪。
他走啦,把我抛下,可我不悲伤。
我呀要再找个情郎,比他还要强!
我兴高采烈,因为贝瑞尔要来了,一个客人,从加利福尼亚远道而来。此外,也因为我六月底进镇参加了高中入学考试,希望很快收到高分录取的消息。乡间学校所有读完八年级的人都要到镇上考试。我喜欢这个—沙沙响的大张考卷,庄严的寂静,石头造的巨大的高中校舍,刻在桌上、涂了清漆变成深色的古老缩写字母。屋外首度绽放的夏天,绿色黄色的光线,带有城镇气派的栗子树,还有金银花。这一切都是同一个镇子,我如今住了大半辈子的镇子。我对这些惊奇不已,对我自己也一样—这个能够轻而易举地绘制地图、解答难题、知道许多答案的人。我觉得自己是那么聪明。不过我还不够聪明,不足以理解最简单的事实。我甚至不明白,参加考试对我毫无意义。我不可能上高中。怎么上呢?那时还没校车,你得住到镇上。我父母供不起这个。就像那时候的很多农夫一样,他们只有一点点现金。奶酪厂付的钱就是唯一的固定收入。而且他们也不觉得我的生活该往那个方向发展,去读高中。他们觉得我该待在家里,帮母亲做事,或许还可以出门打工,到邻近的人家照料生病或生孩子的女人。一直干到比如说我结婚为止。那就是我收到成绩之后,他们要对我宣布的。
你或许会以为我母亲未必这么想,她本人可是当过老师的。可她说,上帝不在乎。上帝对于任何人做什么工作受什么教育都不感兴趣,她告诉我。他才不在乎那个呢,只有他在乎的事情才值得我们关注。
这是我头一回意识到,上帝有可能成为一个真正的敌对者,而不仅仅是某种小麻烦或者大摆设。
母亲小时候的名字叫玛丽埃塔。当然了,那一直就是她的名字,可在贝瑞尔来之前,我从没听人这样叫过她。我父亲一直用的是“母亲”。我有个孩子气的想法—我知道它是孩子气的—觉得我母亲比别的母亲们更适合“母亲”这个叫法。“母亲”,而不是“妈妈”。不在她身边时,我总想不起来母亲的脸是啥样,这让我害怕。坐在学校里,离家只隔了一个山坡,我会试图想象母亲的脸。有时我觉得要是做不到,就有可能意味着母亲死了。不过我总能感觉到她,会因为一些最不可思议的东西想到她—一架立式钢琴,或者一条高高的白面包。挺荒唐吧,可这是真的。
在我心里,玛丽埃塔是独立的,没被吸纳进母亲成年的身体里。玛丽埃塔还在她那个拉姆塞镇,在渥太华河边乱跑着哩。那个镇子,路上全是马匹和水坑,街头黑压压的,挤满周末从矮树林涌出的人群,伐木工们。大街上开了十一家旅馆,供伐木工入住、酗酒。
玛丽埃塔住的房子坐落在河岸往上延伸出的一条陡峭街道的中间。那是一幢双宅建筑,前方有两扇飘窗,两个前廊由一道木栅隔开。另一半住着萨克里夫一家,玛丽埃塔在她妈妈去世、爸爸离开镇子后,就寄宿在他家。电报员萨克里夫先生是英国人。他老婆是德国人。她总是冲咖啡而不是沏茶。她会做奶酪卷。面团从桌边挂下,宛如一张精致的桌布。有时,玛丽埃塔觉得它看起来像一张皮肤。
正是萨克里夫太太说服了玛丽埃塔的妈妈不要上吊。
那是个星期六,玛丽埃塔待在家里没上学。她醒得很迟,家中一片寂静。她向来害怕这个—一幢寂静无声的房子。她放学后一开门就会大声嚷嚷:“妈妈!妈妈!”妈妈经常不回答。但她都在。玛丽埃塔听到炉子格栅的咔咔声,铁熨斗稳稳当当的啪啪声,心头一阵宽慰。
那天早上,她什么也没听到。她走下楼,切片面包,涂上花生酱和糖浆,折起来吃。她打开地窖门招呼几声。她走进前厅,透过蕨草朝窗外看。她看到妹妹贝瑞尔和几个邻居孩子从人行道边一小片长草的斜坡上滚下来,翻起身爬到坡顶,再滚下来。
“妈妈?”玛丽埃塔嚷道。她穿过房子,走向后院。时值暮春,天气多云而暖和。发芽的蔬菜园里,泥土濡湿,树上的叶子好像突然长满了,滴答着夜里积下的雨水。
“妈妈?”玛丽埃塔在树下,在晾衣绳下喊。
院子尽头是一个小谷仓,存放柴火、工具和旧家具。透过敞开的门,可以看到一把椅子—一把直背椅。椅子上,玛丽埃塔看到妈妈的脚,妈妈的黑色系带鞋。然后是印花棉布做的夏季工作长裙、围裙、卷起的袖口。妈妈白得发亮的白胳膊、脖子,还有脸。
妈妈站在椅子上没回答。她没看玛丽埃塔,自顾自微笑着,脚底板叩击着椅子,好像在说:“我在这儿哩。你想怎么着吧。”除了站在一把椅子上,用这种奇怪、紧张的表情笑着之外,她还有哪里不大对劲儿。站在一把椅背的横档都不见了的椅子上,这椅子被她拖到谷仓中间,摇摇晃晃地立在不平整的地面上。她的脖子上有一道阴影。
是一根绳子,从头顶横梁挂下来的一根绳子尽头绕出的一个环。
“妈妈?”玛丽埃塔用突然虚弱的声音请求道,“妈妈,请你下来吧。”她的声音变得虚弱,因为她担心任何嚷嚷或者哭喊都会惊动妈妈,让她蹬开椅子,把全身重量挂上绳子。不过,就算玛丽埃塔想喊,也喊不出来。她全身只有力气发出这可怜的细线一样的声音—就像在梦里,一只野兽或者一台机器正往你身上碾来的时候。
“叫你爸爸来。”
妈妈命令道。玛丽埃塔赶紧照办。她拖着灌满恐惧的双腿跑起来。穿着睡衣,在星期六早上,她跑了起来。她跑过贝瑞尔和别的孩子,他们还在斜坡上打滚。她沿着那会儿还是木板栈道的人行道跑着,跑上没铺路面、布满昨夜积起的水坑的马路。马路穿过铁轨,在山脚下与镇上的大街交叉。大街和河流之间有一些仓库和小工厂。玛丽埃塔的爸爸的马车制造厂就在其中,运货马车、轻便马车和雪橇都有生产。事实上,玛丽埃塔的爸爸发明了一种在矮树林中运木材的新型雪橇,申请到了专利。他的事业在拉姆塞刚刚起步。(后来他在美国发了财。一个喜爱旅馆酒吧、理发店、马车赛和女人的男人,但也不畏惧工作—公允地讲。)
玛丽埃塔在工厂没找到他。办公室空无一人。她跑到工人正在干活的院子,在新鲜锯末中跌跌撞撞。工人们哄笑起来,冲她摇脑袋。不。不在这。这会儿不在。不晓得。你干吗不到市中心找找?等等。等一下。你不先找点衣服穿上?
他们并没恶意。他们没觉察到出事了。但是玛丽埃塔向来无法忍受哄笑的人群。有一些地方她连路过都憎恨,更不用说进去了,原因就在于此。哄笑的男人们。因为这个,她厌恶理发店,厌恶它们的味道。(她后来和我父亲去舞会时,特意请他不要往头发上涂发胶,因为那味道会让她想起这些。)某家旅馆外头站在大街上的一群男人,这对玛丽埃塔而言简直就是一团毒药。你竭力不去听他们在说什么,可你能肯定那一准是些恶毒之语。哪怕他们什么也没说,他们也会哄笑,那同样恶毒—恶毒从他们身上散发出来—毒药。玛丽埃塔在得到拯救后,才做到了从他们面前昂首走过。上帝是她的武装,她径直从他们当中穿过,没有任何东西能磕绊她,没有任何东西能灼伤她。她像但以理[2]一样安全无虞。
现在她转身又跑起来,沿来路跑回去,攀上山坡,一路往家跑。她觉得她离开母亲是个错误。妈妈为什么吩咐她走开?为什么想要她爸爸来?很可能她是打算用自己悬挂在绳子尽头,尚且温热的尸体迎接他。玛丽埃塔本该留下—她本该留下,劝说妈妈收手。她本该跑到萨克里夫太太,或者任何邻居那里求助,而不是这样浪费时间。只是她想不到谁可以帮她,谁居然会信她的话。她以为所有人家,除他们家之外,都活得太太平平,她以为威胁和痛苦这类东西根本不存在于别人的房子里,所以对别人无法解释。
一列火车正开进镇里。玛丽埃塔不得不停下等着。乘客们从车窗里看她。她当着那些陌生人的面,忍不住放声痛哭。火车开过,她继续朝山上跑去—这场面真值得一看。她头也没梳,光脚沾满泥泞,只穿着睡衣,发疯一样,脸上泪淋淋的。她跑进自家后院,看到谷仓便哭嚎起来。“妈妈!”她哭嚎着,“妈妈!”
里面没人。椅子摆在原处。绳子在椅背上晃荡。玛丽埃塔断定妈妈已经走出那一步。她妈死啦—绳子被切断,她被放下来,运走啦。
不过,一双温暖肥胖的手按上她肩头,萨克里夫太太说:“玛丽埃塔。安静点。玛丽埃塔,好孩子。别哭了。进来吧。她很好,玛丽埃塔。进来你就看到了。”
萨克里夫太太的外国口音说着“玛丽—埃—达”,给这个名字平添一种浓郁、不同寻常的韵味。她满怀慈爱。后来,玛丽埃塔住到萨克里夫家,被当成这家的女儿一样对待,而这是一个完全和她想象中的别人家一样平静舒适的人家。不过,她在这里始终没找到做女儿的感觉。
在萨克里夫太太家的厨房里,贝瑞尔坐在地板上啃着一块葡萄干饼干,和黑白两色的小猫迪基玩耍。玛丽埃塔的妈妈坐在桌边,面前搁着一杯咖啡。
“她真傻。”萨克里夫太太说。她指的是玛丽埃塔的妈妈还是玛丽埃塔呢?她掌握的英语单词不多,没法说清。
玛丽埃塔的妈妈笑了。玛丽埃塔眼前一黑。在这么个温暖潮湿的早上,哭嚎着一口气跑上山,弄得她昏过去了。她知道的下一件事就是她正从萨克里夫太太手中的汤匙里喝着黑黑的、甜甜的咖啡。贝瑞尔抓着迪基的前爪,当作一件逗她开心的礼物递过来。玛丽埃塔的妈妈依旧坐在桌边。
她的心碎了—每次我母亲都是这么总结的。这就是结局。这几个字收拢了整个故事,一锤定音。我从没问,是谁弄碎了它呢?我从没问,男人们毒药般的话都说的啥呢?“恶毒”这个词到底是什么意思呢?
玛丽埃塔的妈妈没上吊,反倒笑了。很久以前,她坐在萨克里夫家的厨房桌边笑了。她的心碎了。
对于母亲的闲聊和故事,我一直有一种感觉,它们后头有什么东西膨胀着,就像一个你没法看透、找不到尽头的云团。有一团乌云,或者一剂毒药,侵入了母亲的生活。当我让母亲难过的时候,我也成了它的一部分。于是我会用头撞着母亲的肚子和胸部,撞着她高高的、坚实的身体,祈求宽恕。母亲总会叫我去问上帝。可我不得不与之理顺关系的并非上帝,而是母亲。看起来,她仿佛明了我身上有一些东西,比寻常的谎言、诡计和劣行更糟糕,糟糕得多。那真是一种令人恶心的耻辱啊。我撞击着母亲的身体,想要她忘掉。
我的弟弟们却毫无这种烦恼。我从没觉得他们有。我觉得他们就像些开心的野人,无拘无束地乱逛,根本不用明白什么。当我自己有了两个儿子,而没有女儿的时候,我感觉仿佛有什么事情终于可以从此打住—那些故事,那些悲伤,那些你无法抵御亦无法解决的古老谜团。
贝瑞尔姨妈说,不要管她叫姨妈。“我不习惯当谁的姨妈,亲爱的。我甚至连谁的妈妈都还不是呢。我就是我。叫我贝瑞尔好了。”
贝瑞尔是速记员出身,现在创建了自己的打字速记公司,雇了很多女孩。她和一个男性朋友一起来,叫弗洛伦斯先生。她信上写,会搭朋友的车来。但没提这个朋友是打算住下,还是打算马上就开走;甚至没提是个男人还是女人。
弗洛伦斯先生要住下来。他是一个瘦高的男人,一张晒黑的长脸,眼睛颜色非常浅,还有个抽抽嘴角的习惯,没准是在表示微笑吧。
到头来,他成了在我和母亲贴了墙纸的房间里睡觉的人;因为他是陌生人,而且是个男人。贝瑞尔只好跟我睡。一开始我们觉得弗洛伦斯先生相当粗鲁,因为他不习惯我们的说话方式,我们也不习惯他的。头天早上,父亲对弗洛伦斯先生问候道:“呃,希望你在那张旧床上好歹能睡个囫囵觉吧?”(其实闲置房间里的床铺着羽毛褥垫,再舒服不过。)而弗洛伦斯先生应该回答说,他从没睡得比这更舒服了。
弗洛伦斯先生抽抽嘴角,说:“比这更糟的我也睡过。”
他最喜欢待的地方是他的车里。一辆宝蓝色的克莱斯勒,战后生产的第一批。座椅、地板、车顶和车门上的软垫全都是珠灰色的。弗洛伦斯先生牢牢记着这些颜色的名称,一旦你只说“蓝色”或“灰色”,他就会纠正你。
“我觉得这就是老鼠皮的颜色嘛,”贝瑞尔大大咧咧地评价道,“我告诉他这就是鼠皮色!”
汽车停在房子边的槐树丛下。弗洛伦斯先生坐在车里,摇上车窗,在奢华的新车味道中抽烟。
“恐怕我们没怎么让你的朋友快活哪。”母亲说。
“我才不会操心他呢。”贝瑞尔说。她说到弗洛伦斯先生,总好像关于他有个只有她明白的笑话似的。之后很久,我都怀疑他莫非在仪表板下的抽屉里藏了那么一瓶,时不时呷一口振作精神。他一直戴着帽子。
贝瑞尔本人则享受了双份的快乐。她不像通常的女客人那样坐在家里,跟母亲聊天,而是要求参观农场上的所有东西。她说,我得带着她四处走走,解释各种事情给她听,还要提防不要让她跌进什么肥料堆里。
我不知道有什么好展示的。我带贝瑞尔去冰屋,一块块冰像梳妆台抽屉那么大,更大的冰块埋在锯末里保存着。每隔几天,父亲就会砍下一块冰,搬进厨房,在一个锡皮盒里融化,用来冰镇牛奶和奶油。
贝瑞尔说她从不知道冰有这么大块的。她似乎热衷于发现各种事物是多么奇特、可怕,或者滑稽。
“你们到底是打哪儿弄来那么大的冰块的呢?”
我搞不清这句是不是玩笑。
“从湖上。”我说。
“从湖上!你们这儿有整个夏天都结冰的湖吗?”
我告诉她父亲如何每年冬天从湖上取冰,拖回家埋在木屑里,木屑可以防止冰融化。
贝瑞尔说:“不可思议!”
“嗯,化还是会化一点的。”我说。我对贝瑞尔失望透了。
“太不可思议了。”
我去赶牛,贝瑞尔一个人继续溜达。一个穿白色休闲裤的稻草人(父亲后来就是这么叫她的),戴一顶白色太阳帽,用夺目的红色缎带系在下巴上。她的手指甲和脚指甲—她穿的是凉鞋—都涂成和缎带一样的颜色。她戴着当时人们都戴的小小的深色太阳镜。(我认识的那些人不算—他们可没有太阳镜。)她有一张大红嘴,发出响亮的笑声,头发是一种不自然的颜色,异常耀眼,像樱桃木。她是那么热闹、闪耀,打扮得那样炫目,以至于很难判断她到底好不好看,开不开心,或者任何事情。
我们沿牛群走的小道走着,没再怎么交谈,因为贝瑞尔与牛群保持距离,忙着小心下脚的地方。等我把它们全拴进牛栏,她又凑了过来。她点了支烟。没人在谷仓里抽烟。父亲和别的农夫在这里总是嚼烟草来替代。我不知道怎样才能让贝瑞尔嚼烟草。
“你会给它们挤奶吗,还是由你爸来弄?”贝瑞尔问,“那很难吗?”
我抓住母牛的奶头,挤下一点奶。谷仓猫群里的一只跑过来跃跃欲试。我把细细一股牛奶射进它嘴里。我和猫都扬扬得意。
“那样会痛吗?”贝瑞尔问,“想想看,要是换了是你的话。”
我可从没把母牛的奶头和我自己身体的哪个部位联系起来过,这猥亵的意味让我大吃一惊。事实上,从此我再也无法像这样不假思索地随手抓住一个温暖、粗糙的奶牛奶头了。
贝瑞尔睡觉时穿一件缀有本白色花边的桃色尼龙睡衣。她还有一件配套的袍子。她说“本白色”,就像弗洛伦斯先生说到他的宝蓝色和珠灰色一样郑重其事。
我设法在脱衣服或换睡袍时都不暴露出身体的任何部分。这是很难弄的。我没脱内衣裤,希望贝瑞尔也这么做。与一个成年人睡一张床,对我而言真是折磨。不过,我倒是趁机研究了贝瑞尔称之为美容套装的玩意儿们。装了一团团棉花球的手绘玻璃罐、滑石粉、乳液、冰蓝色的紧肤水、小罐红色和紫红色的唇膏—看起来油亮亮的。蓝色和黑色铅笔。指甲锉板,一块浮石,散发着浓烈香蕉味儿的指甲油,装在一个贝壳形状赛璐珞盒里的敷面粉—它有个听起来像甜点的名字—“甜杏花”。
我在夏天用的煤油炉上热了一点水。贝瑞尔擦干净脸,突然像是变了个人,我几乎以为脸盆里会有片片剥落下来的化妆壳儿,就像我们浸湿、剥下的旧墙纸一样呢。贝瑞尔的皮肤现在变得苍白,遍布细细的裂纹,挺像初夏时分水坑底部渐渐干涸的发亮的淤泥。
“瞧我的皮肤变成啥样了,”她说,“节食。我过去有一百六十九磅重呢,减肥减得太快,脸整个陷下去了。不过,现在我弄到了这种膏。是用秘方做的,你在市场上都买不到呢。闻闻。你看,它闻起来一点也不香,一股子正经八百的味道。”
她用棉花球往脸上拍膏,拍来拍去的,拍到一点也不剩。
“闻起来像猪油。”我说。
“全能的上帝啊,我出了那么大价钱,可不是为了往脸上涂猪油啊。别告诉你妈我拿上帝说事了哦。”
她往水杯里倒点干净的水,打湿梳子,把头发梳湿,用手指绕起一缕缕头发,用两个交叉的发夹把绕好的发卷别到脑袋上。再过两三年,我自己也做起这种事来了。
“永远记得把头发打湿,不然卷起来一点用也没有,”贝瑞尔说,“而且永远记得要向下卷,哪怕你想要它耸起来。明白了吗?”
我卷着自己的头发时—卷了好多年—时不时想起这话,寻思着人们给过的所有建议中,我遵守得最严格的就数这一条了。
我们熄灯上床。贝瑞尔说:“真不知道天会这么黑。真不知道还有这么漆黑的晚上啊。”她喃喃低语着。我很迟钝地意识到,她是在将乡间夜晚与城市的夜晚作比较。我好奇着内特菲尔德县的黑夜是否果真比加利福尼亚的黑夜更黑。
“亲爱的?”贝瑞尔低声说,“外面有动物吗?”
“有母牛啊。”我说。
“不错,但是野生动物呢?有没有熊?”
“有。”我说。父亲有一次在灌木丛中发现过熊脚印和熊粪,还发现一棵野苹果树上的苹果全都被扯掉了。那是好多年以前,他年轻时的事了。
贝瑞尔呻吟着,咯咯地笑。“想想看,要是弗洛伦斯先生晚上不得不出门,结果撞上一头熊!”
第二天是星期天。贝瑞尔和弗洛伦斯先生开着克莱斯勒车送我和弟弟们去主日学校。那是早上十点。他们在十一点回来,带我父母去教堂。
“快跳上来。”贝瑞尔吩咐我,“你们也一样,”她对男孩们说,“我们开车兜风去咯。”
贝瑞尔穿了件缎子样的象牙色红点连衣裙,屁股那里有一道镶红边的荷叶皱褶,脚上是红色高跟鞋。弗洛伦斯先生穿了一身浅蓝色夏季西装。
“你们去教堂吗?”我问。根据我的经验,人们为了这事才盛装打扮。
贝瑞尔笑了。“亲爱的,弗洛伦斯先生信的可不是那种宗教哦。”
我习惯从主日学校直接走到教堂,再坐上一个半小时。夏天,敞开的窗户飘进墓园的雪松气味,还会传来路上偶尔一辆汽车嗖地驶过、几近亵渎的声响。今天,我们把这段时间用来在我从未见过的乡村驱车穿行。我从没到过这里,尽管它离家不到二十英里。我们的卡车只会开到奶酪厂、教堂,或者在星期六晚上去镇上,开到垃圾场就算是最接近兜风的了。我见到过贝尔斯湖靠我们的这头,因为父亲冬天在那里取冰。夏天你可没法走近那里,湖岸满满当当地长着芦苇呢。我以为湖的另一头差不离也是这么回事。可今天开车过去,我看到村庄、码头和小船,深色的水面倒映着树木。所有这一切,我以前都一无所知。这里,同样也是贝尔斯湖呢。我很高兴终于看到它了,但不知怎的,对于这种惊喜并不怎么感到开心。
最后,一幢白色的框架建筑出现了。它有走廊,摆着盆栽植物,房前还有一些亮闪闪的白杨树。野树林酒吧。今天,这幢房子涂上灰泥,重装了都铎风格的横梁,取名叫作“幽居”。白杨树被砍掉,给停车场让路。
回头去教堂接我父母的途中,弗洛伦斯先生拐到我们隔壁的农场上,它的主人是麦克阿斯特一家。麦克阿斯特夫妇是天主教徒。我们两家是邻居,但不怎么往来。
“来吧,男孩们,下来。”贝瑞尔招呼我的弟弟们。“你不要动,”她吩咐我,“你待在原处。”她推搡着小男孩们走上门廊,麦克阿斯特家的几个人站在那里。他们穿着破破烂烂的家常衣服,因为他们的教堂仪式,或者弥撒,或者不知道叫什么的玩意儿,早早就结束了。麦克阿斯特夫人走出门,目瞪口呆地听着贝瑞尔快活的说话声。
贝瑞尔独自回到车边。“好了,”她说,“他们和邻居的孩子们玩去啦。”
和麦克阿斯特一家人玩?可他们是天主教徒,而且他们家所有孩子,除了那个婴儿,都是女孩儿啊。
“他们还穿着好衣服呢。”我说。
“那又怎样?他们就不能穿着好衣服过点好时光吗?我不就是这样!”
我父母同样被弄了个猝不及防。贝瑞尔走下车,告诉父亲他可以坐前排,那里搁腿的空间宽敞些。她挤到后排,与母亲和我坐一道。弗洛伦斯先生再度掉头,开上贝尔斯湖边小路,贝瑞尔宣布我们要一起去野树林酒吧吃晚饭。
“你们全都穿戴整齐了,干吗不利用这个机会呢?”她说,“我们把男孩子们丢在你们邻居家了。我想他们还太小,不懂享受这个。邻居很乐意接待他们呢。”她特别强调是他们请客,她和弗洛伦斯先生。
“嗯。可是—”父亲说,他口袋里可能五块钱都没有,“嗯。可是,我不晓得他们让不让农夫进门。”
他沿着这条思路开了很多玩笑。在旅馆餐厅里,到处都是白色—白桌布,白色描花椅子—还有结满水珠的玻璃水罐,转个不停的高高的吊扇。他拿起一块尿布一般大的餐巾,出声地对我低语道:“你能告诉我这玩意儿该怎么用吗?我可以把它包在脑袋上挡风吗?”
当然了,他以前在旅馆餐厅吃过饭。他知道桌上的餐巾和馅饼叉子该怎么用。我母亲也知道—她甚至算不得乡下女人。尽管如此,这仍然是件大事。说实话不是什么开心的事—有违贝瑞尔的本意—不过仍是一件重大的、令人不安的事。当众吃饭,在离家只有几英里的地方,在一个装满陌生人的大房间里吃饭;由一个陌生人—一个模样傲慢,多半是个打暑期短工的女大学生端来食物。
“我想要大公鸡。”父亲说,“它在罐子里待了多久啊?”按照他的理解,跟服务他的人开点玩笑,是一种礼貌。
“您说什么?”女孩问。
“烤鸡,”贝瑞尔说,“大家都同意这个吧?”
弗洛伦斯先生样子挺阴郁。或许在花他的钱的时候,他不乐意听什么玩笑吧。也有可能他指望杯子里能有点比冰水更强劲的玩意儿。
女招待放下一碟芹菜和橄榄,母亲说:“稍等,我做一下感恩祈祷。”她低下头,轻声但是一清二楚地祷告道:“主啊,请赐福我们所用的食物,请赐福为您服务的我们,为了基督。阿门。”她容光焕发,坐直身子,把碟子推向我说:“小心橄榄,里面有核。”
贝瑞尔冲房间里四下点头讪笑。
女招待回来了,带来一篮面包卷。
“派克屋面包卷[3]!”贝瑞尔俯身嗅着香味,“趁它们还热,能把奶油融化,赶紧吃!”
弗洛伦斯先生抽抽嘴角,瞥了一眼奶油碟。“就是这个吗—奶油?我还以为是秀兰·邓波儿的发卷子呢。”
他的脸和先前差不多阴郁,不过这是一句玩笑啊,而他说出了它,就好像授予了我们刚刚才当众请求得到的东西—赐福。
“每次他说些有趣的话呀,”贝瑞尔说—她经常用“他”来称呼弗洛伦斯先生,哪怕他就在场—“你们瞧见他是怎样不动声色的吧?这让我想起妈来了。我说的是咱们的妈,玛丽埃塔和我的。爹地呢,他说笑话的时候,你一英里之外就能看出来了—他脸上啥都藏不住—可妈完全是另一回事了。她能从头到尾一脸酸溜溜的模样儿。不过她一直到尸床上都还能说笑话呢。事实上,她真是那样的。玛丽埃塔,你记得她死前那年春天,躺在前厅那张床上的情形吧?”
“我记得她躺在那房间的床上,”母亲说,“是的。”
“嗯。爹地进门来,她躺在那里,穿着干净睡袍,被子掀开,因为隔壁那个德国女人刚帮她擦了个澡,还在忙着整理床铺哩。所以,爹地想显得开心些,就说:‘春天肯定就要来咯,我今天看到了一只乌鸦。’那时想必是三月吧。妈妈快嘴快舌地答道:‘哼,那你最好把我盖起来,免得它从那扇窗户看进来,打起什么坏主意!’那个德国女人—爹地说她差点把盆子都掉地上了。因为说得还真像那么回事,妈妈瘦得只剩皮包骨头了嘛。她快要死了。可她还能说笑话呢。”
弗洛伦斯先生说:“到了哭也没用的时候,倒不如这样。”
“不过她也会玩笑开过了头,我说的是我妈。有一次,有那么一回,她想吓爹地一跳。他好像对一个常跑来工厂的女孩有了兴趣。哎,他是一个高大英俊的帅哥嘛。妈说了:‘好吧,我自个儿死了算了,你尽管跟她厮混下去,等我回来找你闹鬼,看你咋办吧。’他告诉她别傻了,就进城去了。妈跑到谷仓,爬上一把椅子,把一根绳子绕在脖子上。不是吗?玛丽埃塔?玛丽埃塔跑去找她,发现她就那副模样儿!”
母亲低下头,双手按着膝盖,几乎像是打算再做一次祷告。
“爹地告诉了我这个,不过我自己其实也记得。我记得玛丽埃塔穿着睡衣跑下山,我猜想那个德国女人看到她跑开,就出门来找妈,不知怎的后来我们全都跑到谷仓—我也去了,还有和我一起玩的小孩子们—妈就站在椅子上,打算好好吓唬爹地一次。她打发玛丽埃塔去找他了。德国女人哭嚎起来:‘哎呀,夫人哪,快下来啊,夫人哪,想想你的哈子们。’—哈子是德语里孩子的意思吧—‘想想你的哈子们’,诸如此类。到头来,是站在那里的我—我只是个小娃娃,不过是我注意到那绳子的。我的眼睛顺着那绳子朝上又朝上看去,看到它挂在横梁上,就搭在那里—根本没打结!玛丽埃塔没注意,那个德国女人也没注意。可我就大声说了:‘妈,绳子都没系在横梁上,你打算怎么上吊哩?’”
弗洛伦斯先生说:“这话问得好。”
“我破坏了她的游戏。德国女人冲了咖啡,我们坐下来吃了些点心。然后,玛丽埃塔,你根本没找到爹地,对吗?隔了一个街区,都能听到玛丽埃塔在哭嚎,一路哭上山。”
“她害怕是自然的嘛。”父亲说。
“那是当然。妈做过头了。”
“她是来真的,”母亲说,“她其实是想那样的,不像你以为的。”
“她是想惹怒爹地来着。他们的整个生活就是这么回事。他总是说,她是个不容易相处的女人,不过很有性格。我相信,和格莱迪斯在一起的时候,他很怀念她这一点。”
“我可不知道,”母亲用她提及她爸爸时永远异常平静的口气说,“不管他说了什么或者没说什么。”
“他们都死了,”父亲说,“我们不该去评判了。”
“我知道,”贝瑞尔说,“我知道玛丽埃塔总是另有看法。”
母亲看了看弗洛伦斯先生,相当轻松、富有感染力地笑了。“我相信我们这些家务事把你都搞糊涂了吧。”
我拜访过贝瑞尔一次,那时她已是个老太太,得了风湿病,关节扭曲,佝偻着身子。贝瑞尔说:“玛丽埃塔遗传了爹地的好相貌。她从不打扮。记得我们去旅馆那次,她穿的那件旧的深蓝色绉绸裙子吗?当然了,我知道那可能就是她最好的衣服了,但她非得只有这件衣服吗?你知道,我有点怕她。我没法跟她单独待在一间房间里。不过她的相貌真是出众。”我试图想起我什么时候注意过母亲的相貌,涌上脑海的就是那家旅馆,母亲浅橄榄色的皮肤被一头盘起的茂密白发衬着,明朗、端庄的脸对着弗洛伦斯先生微笑—仿佛他才是要被宽恕的人。
当时我对贝瑞尔的故事没什么想法。首先,我又饿又馋,注意力都放在烤鸡、肉汁、用冰激凌勺扣在盘子上的土豆泥,以及富有光泽的罐头蔬菜丁上,我当时觉得后者比园子里现摘的高级多了。甜点我吃的是奶油糖布丁圣代,我在它和巧克力口味之间作选择时可谓痛苦万分。其他人吃的是普通香草冰激凌。
贝瑞尔的故事干吗不可以是另一个版本呢?尽管与母亲讲的是同一件事。贝瑞尔在所有方面都怪怪的—她的一切都挺别扭,都是从一个新的视角看过来的。有那么一阵子,为主的还是母亲的版本。它吸收了贝瑞尔的故事,覆盖了它。不过贝瑞尔的故事没有消失。它被封存多年,却始终存在。就像关于那家旅馆和餐厅的印象一样。尽管我想我不会再有机会去那地方,可我知道它的存在。事实上,如果没有贝瑞尔或者弗洛伦斯先生买单,我是不可能再去的。但我知道它就在那儿。
事实上,我下一次到野树林酒吧,是结婚之后的事了。雄狮俱乐部在那里举办了一个宴会和一场舞会。我嫁的男人,丹·凯西,是俱乐部成员。那时候,你在那里可以买到酒喝。丹·凯西可不会去任何买不到酒的地方。然后它被改造成“幽居”,现如今,除了周日之外,那里每晚都有脱衣舞表演。周四晚上还有个男脱衣舞表演者。我和房地产公司的同事们会去那里庆祝生日或别的大事。
农场在1965年以五千元的价格卖掉了。一个从多伦多来的人买下它,也许是为了建个休闲农场,或者纯粹是投资。两年后,他把它租给一个公社。它维持了十来年,其间各种各样的人来来去去。他们养山羊,卖羊奶给镇上开的健康食品店。他们在谷仓面对马路的墙上画了一道彩虹。他们在窗户上挂扎染床单,任院子里的长草和野花繁茂。我父母后来终于给房子接了电线,可这些人并不用电。他们选择油灯和烧木柴的炉子,脏衣服都送到镇上洗。人们说,这些人不懂摆弄油灯或柴火,迟早会把整个地方烧掉。但是他们没有。事实上,他们干得不赖。修理了房子和谷仓,辟出一个大园子。甚至给土豆田撒药粉,防止枯死病—尽管我听说这个做法在他们中引起一些争执,导致一些比较刻板的成员退出。实际上,这地方变得比周围留在原先的农户手中的农场要好得多。麦克阿斯特家的儿子在他家农场上做起旧车零件生意。我的弟弟们早已远走高飞。
我知道这没什么道理,不过我有种感觉,宁愿看到农场完全荒废—宁愿看到它落入流氓和乞丐手中—也不愿看到谷仓上那道彩虹,还有墙上绘制的几排类似埃及文的文字。那像是个嘲讽。我甚至不喜欢看到那些人进城的样子—男人头发梳成辫子,大衣上有破洞,我相信那是故意割出来的。女人留长发,不化妆,一脸恭顺超然的表情。你们知道什么是生活吗,我很想质问他们。你们凭什么觉得可以过来嘲弄我父母,嘲弄他们的生活和贫穷?不过,一想到彩虹和那些字母,我就明白他们其实无意嘲弄或模仿我父母的生活。他们用自己的生活,把我父母的取而代之,几乎都不知道后者的存在。他们在这个地方建立起自己的信仰和习惯。我真希望它们失败。
结果果然差不离。公社解体了。山羊消失了。女人们有些搬到镇上,剪短头发,化了妆,当起女招待或收银员,抚养她们的孩子。那个多伦多男人给这个地方挂上出售牌,一年后它卖了个比当初他付的十倍还要高的价钱。一对渥太华来的年轻夫妇买下了它。他们把外墙刷成浅灰色,用牡蛎色缀边,开了几扇天窗,装了一扇漂亮的前门,门两侧各安一盏马车灯。他们对内部也进行了彻底改造。人家告诉我,我再也不会认出它了。
在这一切之前,在房子清空、准备出售的那一年,我确实进去过一次。它由我的公司经手,归另一个经纪人管,不过我有一把钥匙。我是在一个周日下午去的。有个男人陪着我,不是客户,而是一个朋友—博比·马科斯,我那会儿经常和他厮混。
“这是个嬉皮士的地盘嘛。”我停车的时候,博比·马科斯说,“我以前到过这里。”
他是个律师,一个天主教徒,与妻子分居。他想要安顿下来,在这里的镇上开业。不过此地已有一个天主教律师,生意清淡。每周总有两回,博比·马科斯晚饭前就喝得酩酊大醉。
“不止如此。”我说,“这里是我出生的地方。我在这里长大。”我们穿过野草,我打开门。
他说,以前听我的口气,他还以为那是在远得多的地方呢。
“那会儿它确实显得挺偏远。”
所有房间都空荡荡的,地板扫干净了。木制家具新近涂了油漆—我吃惊地发现,窗玻璃一尘不染。有些是新玻璃,有些仍是坑坑洼洼的旧玻璃。一些墙面上的墙纸被撕掉,刷了颜色。厨房的一堵墙涂成深蓝色,上面画了一只巨大的鸽子。前厅的一面墙上画了巨大的向日葵,还有一只几乎同样巨大的蝴蝶。
博比·马科斯吹了声口哨,“还是个艺术家呢。”
“你要这么说也行啊。”我说着,转身走进厨房。烧柴的炉子还在。“我妈有一次烧掉了三千块,”我指着,“她在那个炉子里烧掉了三千块。”
他又吹声口哨,不过含义与刚才大大不同。“你什么意思?她丢进了一张支票吗?”
“不,不是。都是现金。她是故意这么做的。她进城到银行,让人把它全部兑成现金,装了一鞋盒。她把它带回家,丢进炉子。她一次只丢几张钞票,免得火烧太大。爸爸站在那里看着她烧。”
“你在说什么啊?”博比·马科斯说,“我以为你们穷困潦倒呢。”
“不错,我们是穷得要命。”
“那她怎么会有三千块?那差不多相当于今天的三万块了。真的。比今天的三万块还要多啊。”
“那是遗产,”我说,“从她爸爸那里得到的。她爸爸住在西雅图,给她留下三千块。她把它都烧了,因为她恨他。她不想要他的钱。她恨他。”
“那得多恨啊。”博比·马科斯说。
“这不是关键。她对他的恨,还有他是不是足够坏,让她有理由这样恨他,很有可能他没那么坏,都不是关键。”
“钱嘛,”他说,“钱总是关键。”
“不。我爸爸任由她这么做了,这才是关键。对我而言是这样的。爸爸站着,看着她这么做,一句反对的话也没有。要是任何人试图阻止她,他会保护她。我想那就是爱吧。”
“有人会认为那是发疯。”
我记得那就是贝瑞尔的看法,一字不差。
我走进前厅,盯着那蝴蝶看,看它粉色和橙色的翅膀。我又走进前面的卧室,看到墙上画了两个人。一个男人和一个女人手拉手的正面像。他们赤裸着,比真人还要大。
“这让我想起约翰·列侬和小野洋子的那张照片,”我对跟在后头进来的博比·马科斯说,“那张唱片的封面,记得吗?”我不想让他觉得他在厨房里说的话弄得我不高兴了。
博比·马科斯说:“头发颜色不一样。”
不错。这两个人都有浓厚的大色块涂出的黄头发,就像漫画里的画法一样。马尾般的黄头发卷曲着挂下他们的肩头,小猪尾巴一般的黄色发卷装点着他们并不显得隐私的部位。他们皮肤的颜色是一种平淡的卡其粉色,眼睛是一种直勾勾的蓝色,就像厨房墙上的蓝色。
我注意到他们在画这幅画之前,没怎么撕干净墙纸。角落里还残留了一点墙纸,呼应着另外几面墙—一种现代派的粉色、灰色和紫红色泡泡交错的图案。想必是那个多伦多男人贴上去的。贴新墙纸的时候,底下的旧墙纸没撕掉。我能看到它的一角,白底上的矢车菊。
“我猜这是他们玩那些性游戏的地方吧。”博比·马科斯用一种熟悉的语调说。那种凝重、悲哀、不自在却又毅然决然的语调,那种体面中年男子的并不特别友善的欲望。
我不作评论。我撕掉几片泡泡墙纸,想看下面的矢车菊。突然我撕到一片松动的地方,一撕一大片纸。不过矢车菊墙纸也被带了下来,掀起一小股灰泥粉末。
“为什么?”我说,“来说说看,为什么一提到这样的地方,没哪个男人不是两秒钟不到就要扯到性的话题?只要一提到‘嬉皮士’或者‘公社’,你们所有这些人能想到的就只有性交!就好像这后面什么都没有,只有狂欢、滥交,没完没了的性交!我烦透了—这蠢透了,真让我恶心!”
在车里,从旅馆回家的路上,我们像原先一样坐—男人坐前排,女人在后排。我坐中间,两侧是贝瑞尔和母亲。她们发热的身体隔着衣服贴着我。她们的味道压过了我们正穿过的雪松树丛,以及一个个小水塘的味道,在那些小水塘边,贝瑞尔对睡莲花啧啧惊叹过。贝瑞尔散发出的是罐子和瓶子里那些东西的味道。我母亲散发出的是面粉、硬肥皂和她那好衣服上温热的绉绸味道,以及用来擦掉污渍的煤油的味道。
“一顿可爱的晚饭,”母亲说,“谢谢你,贝瑞尔。谢谢你,弗洛伦斯先生。”
“我不知道谁还能去干挤奶的活儿了。”父亲说,“我们都已经这么气派地吃过饭啦。”
“说到钱嘛,”贝瑞尔说—尽管其实没人提这个话题—“介意我问一句吗?你们是怎么处理你们的钱的?我把我那份都用来投资房地产了。加利福尼亚的房地产—你不会亏的。我在想,你们该弄个电炉了,这样你们就不用在大夏天费神点火,或者摆弄那个煤油玩意儿了,不管是哪个吧。”
车里所有其他人都笑了,甚至包括弗洛伦斯先生。
“那是个好主意,贝瑞尔。”父亲说,“我们可以用它来搁东西,直到我们通上电为止。”
“哦,天哪,”贝瑞尔说,“我怎么这么蠢?”
“而且我们实际上也没钱。”母亲快活地说,好像在继续这个笑话似的。
贝瑞尔尖锐地说:“你写信说你收到了。你收到了和我一样多的钱。”
父亲在座位上侧过身子:“你们在说什么钱啊?”他问,“这是什么钱?”
“从爹地的遗嘱中得的,”贝瑞尔说,“你去年得的嘛。唉,或许我不该多嘴。就算你不得不用它还什么账,那也算是派上了用场,不是吗?没关系的。都是自家人。不是吗?”
“我们不需要用它来还什么账,”母亲说,“我烧掉它了。”
然后她说了大约一年前的某天她如何坐卡车进镇,让人把钱装在一个她特地带去的鞋盒里。她把它带回家,丢进炉子里,烧了。
父亲转回身,脸对着前方的路。
我能感觉到母亲讲述的时候,贝瑞尔在我身边扭动着。她抽搐着,微微呻吟着,好像强忍着什么难以忍受的痛苦。故事讲到最后,她发出一声震惊、痛苦、愤怒的呻吟。
“你竟然烧钱!”她说,“你在炉子里烧钱!”
母亲的声音依然欢快:“你这口气,好像我烧掉的是自己的一个孩子似的。”
“你烧掉了他们的机会啊。你烧掉了这钱可以给他们带来的一切。”
“我的孩子们最不需要的就是钱了。我们谁也不需要他的钱。”
“那是犯罪啊。”贝瑞尔嘶哑地说。她把声音转向前排,“你干吗不管管她?”
“他不在场,”母亲说,“当时没人。”
我父亲说:“那是她的钱,贝瑞尔。”
“都一样,”贝瑞尔说,“那是犯罪。”
“犯罪是你报警了才算的。”弗洛伦斯先生说。就像那天他说的其他话一样,这引起了一点点惊奇,还有一种特别的感激之情。
不过感激之情并非发自所有人。
“别假装这不是你听过的最疯狂的事,”贝瑞尔冲前排吼道,“别假装你没这样想!因为确实如此,而且你确实是这么想的。你和我想得一模一样!”
父亲不曾站在厨房里,看着母亲把钞票放进火焰。不会有这种事。他甚至不知道它—事情一清二楚,如果我没记错的话,他是直到那个星期天下午,在弗洛伦斯先生的克莱斯勒汽车里,在母亲讲给他们所有人听的时候,才知道这事的。那么,我为什么能如此真切地看到那一幕,就像我对博比·马科斯(以及对别人—他并不是第一个)形容的那样呢?我看到父亲站在屋子中央的桌子边—有装刀叉的抽屉、铺着刷洗干净的油布的桌子—桌上搁着那盒钱。母亲正小心地把钞票丢进火里。她一只手用熏黑的钳子拉着炉门盖子。父亲站在旁边,似乎不仅允许她这么做,还在保护她。一幕庄严的景象,但并不疯狂。正在做着对他们而言自然而然、别无选择的事情的两个人。至少,是他们中的一个在做着自然而然、别无选择的事,而他们中的另一个相信,重要的在于让第一个人自由自在地继续。他们知道别人未必认同这些,但他们不在乎。
要我相信这都是我想象出来的,该有多难啊。看起来它完全就是真的。这就是我对他们的信仰吧。我从没停止过这种信仰。不过我不再讲这个故事了。自打博比·马科斯之后,我再没对哪个人讲过。我想再也没有了吧。我不再讲,不是因为它严格说起来不是真的。我不再讲这个故事,是因为意识到不能指望别人像我一样理解它。不能指望他们对这事表示出任何一点赞许。我甚至都不能说自己也赞同它呢。要是我属于会赞同它、会这么做的人,又何至于干出后来那些事呢—十五岁离家出走,到饭店打工,去夜校学打字和速记,进入房地产公司,最后成为一名有执照的经纪人。我也就不会离婚了。父亲就不会在县立老人之家去世了。我的头发,也本该遵循多年前就开始的自然变化,一直是白色的,而不是弄成一种叫作“日出铜”的颜色。这一切,就算我能,我也一件都不会改变,真不会。
博比·马科斯是个体面人—心肠好,有时还有点想象力。我像那样冲他发火之后,他说:“你不用对我们这么苛刻嘛。”很快又说,“这是你小时候的房间吗?”他觉得那就是提到性游戏的话题让我生气的原因。
我想,不妨就让他这么以为好了。我回答说是的,不错,这是我小时候的房间。最好还是当场就和解吧。纵然分手是迟早的事,善意与和解的时刻仍旧值得拥有嘛。不知道这些时刻在一些人(比如说我本人)的处境中,是否更会被珍惜,被刻意追求,甚于在那种旧式婚姻中呢—在那里,爱与恨每每都是悄悄滋生,如此混沌一团、冥顽不灵,好像真能熬到地老天荒似的。
[1] 原文为“Fame”,作为名词有“名声”之意。—本书注释若无特别说明,均为译注。
[2] 《旧约》中的一位先知。
[3] 1870年由波士顿的派克屋酒店首创的一种面包卷,在面包卷里加入额外的黄油烤制而成,味道香浓。
爱情故事-余华
========================
爱情故事-[[余华]]
------
一九七七年的秋天和两个少年有关。在那个天空明亮的日子里,他们乘坐一辆嘎吱作响的公共汽车,去四十里以外的某个地方。车票是男孩买的,女孩一直躲在车站外的一根水泥电线杆后。在她的四周飘扬着落叶和尘土,水泥电线杆发出的嗡嗡声覆盖着周围错综复杂的声响,女孩此刻的心情像一页课文一样单调,她偷偷望着车站敞开的小门,她的目光平静如水。
然后男孩从车站走了出来,他的脸色苍白而又憔悴。他知道女孩躲在何处,但他没有看她。他往那座桥的方向走了过去,他在走过去时十分紧张地左顾右盼。不久之后他走到了桥上,他心神不安地站住了脚,然后才朝那边的女孩望了一眼。他看到女孩此刻正看着自己,他便狠狠地盯了她一眼,可她依旧看着他。他非常生气地转过脸去。在此后的一段时间里,他一直站在桥上,他一直没有看她。但他总觉得她始终都在看着自己,这个想法使他惊慌失措。后来他确定四周没有熟人,才朝她走去。
他走过去时的胆战心惊,她丝毫不觉。她看到这个白皙的少年在阳光里走来时十分动人。她内心微微有些激动,因此她脸上露出了笑容。然而他走到她身旁后却对她的笑容表示了愤怒,他低声说:
“这种时候你还能笑?”
她的美丽微笑还未成长便被他摧残了。她有些紧张地望着他,因为他的神色有些凶狠。这种凶狠此刻还在继续下去,他说:
“我说过多少次,你不要看我,你要装着不认识我。你为什么看我?真讨厌。”
她没有丝毫反抗的表示,只是将目光从他脸上无声地移开。她看着地上一片枯黄的树叶,听着他从牙缝里出来的声音。他告诉她:
“上车以后你先找到座位坐下,如果没有熟人,我就坐到你身旁。如果有熟人,我就站在车门旁。记住,我们互相不要说话。”
他将车票递了过去,她拿住后他就走开了。他没有走向候车室,而是走向那座桥。
这个女孩在十多年之后接近三十岁的时候,就坐在我的对面。我们一起坐在一间黄昏的屋子里,那是我们的寓所。我们的窗帘垂挂在两端,落日的余晖在窗台上飘拂。她坐在窗前的一把椅子里,正在织一条天蓝色的围巾。此刻围巾的长度已经超过了她的身高,可她还在往下织。坐在她对面的我,曾在一九七七年的秋天与她一起去那个四十里以外的地方。我们在五岁的时候就相互认识,这种认识经过长途跋涉以后,导致了婚姻的出现。我们的第一次性生活是在我们十六岁行将结束时完成的。她第一次怀孕也是在那时候。她此刻坐在窗前的姿势已经重复了五年,因此我看着她的目光怎么还会有激情?多年来,她总是在我眼前晃来晃去,这种晃来晃去使我沮丧无比。我的最大错误就是在结婚的前一夜,没有及时意识到她一生都将在我眼前晃来晃去。所以我的生活才变得越来越陈旧。现在她在织着围巾的时候,我手里正拿着作家洪峰的一封信。洪峰的美妙经历感动了我,我觉得自己没有理由将这种旧报纸似的生活继续下去。
因此我像她重复的坐姿一样重复着现在的话,我不断向她指明的,是青梅竹马的可怕。我一次又一次地问她:
“难道你不觉得我太熟悉了吗?”
但她始终以一种迷茫的神色望着我。
我继续说:“我们从五岁的时候就认识了,二十多年后我们居然还在一起。我们谁还能指望对方来改变自己呢?”
她总是在这个时候表现出一些慌乱。
“你对我来说,早已如一张贴在墙上的白纸一样一览无余。而我对于你,不也同样如此?”
我看到她眼泪流下来时显得有些愚蠢。
我仍然往下说:“我们唯一可做的事只剩下回忆过去。可是过多的回忆,使我们的过去像每日的早餐那样,总在预料之中。”
我们的第一次性生活是我们十六岁行将结束时完成的。在那个没有月光的夜晚,我们在学校操场中央的草地上,我们颤抖不已地拥抱在一起,是因为我们胆战心惊。不远的那条小路上,有拿着手电走过的人,他们的说话声在夜空里像匕首一样锋利,好几次都差点使我仓皇而逃。只是因为我被她紧紧抱住,才使我现在回忆当初的情景时,没有明显地看到自己的狼狈。
我一想到那个夜晚就会感受到草地上露珠的潮湿,当我的手侵入她的衣服时,她热烈的体温使我不停地打寒战。我的手在她的腹部往下进入,我开始感受到如草地一样的潮湿了。起先我什么都不想干,我觉得抚摸一下就足够了。可是后来我非常想看一眼,我很想知道那地方是怎么回事。但是在那个没有月光的夜晚,我凑过去闻到的只是一股平淡的气味。在那个黑乎乎潮湿的地方所散发的气味,是我以前从未闻到过的气味。然而这种气味并未像我以前想象的那么激动人心。尽管如此,在不久之后我还是干了那桩事。欲望的一往无前差点毁了我,在此后很多的日子里,我设计了多种自杀与逃亡的方案。在她越来越像孕妇的时候,我接近崩溃的绝望使我对当初只有几分钟天旋地转般的快乐痛恨无比。在一九七七年秋天的那一日,我与她一起前往四十里以外的那个地方,我希望那家坐落在马路旁的医院能够证实一切都是一场虚惊。
她面临困难所表现出来的紧张,并未像我那样来势凶猛。当我提出应该去医院检查一下时,她马上想起那个四十里以外的地方。她当时表现的冷静与理智使我暗暗有些吃惊。她提出的这个地方向我暗示了一种起码的安全,这样将会没人知道我们所进行的这次神秘的检查。可是她随后颇有激情地提起五年前她曾去过那个地方,她对那个地方街道的描述,以及泊在海边退役的海轮的抒情,使我十分生气。我告诉她我们准备前往并不是为了游玩,而是一次要命的检查。这次检查关系到我们是否还能活下去。我告诉她这次检查的结果若证实她确已怀孕,那么我们将被学校开除,将被各自的父母驱出家门。有关我们的传闻将像街上的灰尘一样经久不息。我们最后只能:
“自杀。”
她只有在这个时候才显得惊慌失措。几年以后她告诉我,我当时的脸色十分恐怖。我当时对我们的结局的设计,显然使她大吃一惊。可是她即使在惊慌失措的时候也从不真正绝望。她认为起码是她的父母不会把她驱出家庭,但她承认她的父母会惩罚她。她安慰我:
“惩罚比自杀好。”
那天我是最后一个上车的,我从后面看着她上车,她不停地向我回身张望。我让她不要看我,反复提醒在她那里始终是一页白纸。我上车的时候汽车已经发动起来。我没有立刻走向我的座位,而是站在门旁,我的目光在车内所有的脸上转来转去,我看到起码有二十张曾经见过的脸。因此我无法走向自己的座位,我只能站在这辆已经行驶的汽车里。我看着那条破烂不堪的公路怎样捉弄着我们的汽车。我感到自己像是被装在瓶子里,然后被人不停地摇晃。后来我听到她在叫我的声音,她的声音使我蓦然产生无比的恐惧。我因为她的不懂事而极为愤怒,我没有答理。我希望她因此终止那种叫声,可是她那种令人讨厌的叫声却不停地重复着。我只能转过头去,我知道自己此刻的脸色像路旁的杂草一样青得可怕。
然而她脸上却洋溢着天真烂漫的笑容,她佯装吃惊的样子表示了她与我是意外相遇。然后她邀请我坐在她身旁的空座位上。我只能走过去。我在她身旁坐下以后感到她的身体有意紧挨着我。她说了很多话,可我一句都没有听进去,我为了掩饰只能不停地点头。这一切使我心烦意乱。那时候她偷偷捏住了我的手指,我立刻甩开她的手。在这种时候她居然还会这样,真要把我气疯过去。此刻她才重视我的愤怒,她不再说话,自然也不会伸过手来。她似乎十分委屈地转过脸去,望着车外萧瑟的景色。然而她的安静并未保持多久,在汽车一次剧烈的震颤后,她突然哧哧笑了起来。接着凑近我偷偷说:
“腹内的小孩震出来了。”
她的玩笑只能加剧我的气愤,因此我凑近她咬牙切齿地低声说:
“闭上你的嘴。”
后来我看到了几艘泊在海边的轮船,有两艘已被拆得惨不忍睹,只有一艘暂且完整无损。有几只灰色的鸟在海边水草上盘旋。
汽车在驶入车站大约几分钟以后,两个少年从车站出口处走了出来。那时候一辆卡车从他们身旁驶过,扬起的灰尘将他们的身体涂改了一下。
男孩此刻铁青着脸,他一声不吭地往前走。女孩似乎有些害怕地跟在他身后,她不时偷偷看他侧面的脸色。男孩在走到一条胡同口时,没有走向医院的方向,而是走入了胡同。女孩也走了进去。男孩一直走到胡同的中央才站住脚,女孩也站住了脚。他们共同看着一个中年的女人走来,又看着她走出胡同。然后男孩低声吼了起来:
“你为什么叫我?”
女孩委屈地看着他,然后才说:
“我怕你站着太累。”
男孩继续吼道:
“我说过多少次了,你别看我。可你总看我,而且还叫我的名字,用手捏我。”
这时有两个男人从胡同口走来,男孩不再说话,女孩也没有辩解。那两个男人从他们身边走过时,兴趣十足地看了他们一眼。两个男人走过去以后,男孩就往胡同口走去了,女孩迟疑了一下也跟了上去。
他们默不作声地走在通往医院的大街上。男孩此刻不再怒气冲冲,在医院越来越接近的时候,他显得越来越忧心忡忡。他转过脸去看着身旁的女孩,女孩的双眼正望着前方。从她有些迷茫的眼神里,他感到医院就在前面。
然后他们来到了医院的门诊部,挂号处空空荡荡。男孩此刻突然胆怯起来,他不由走出门厅,站在外面。他这时突然害怕地感到自己会被人抓住,他没有丝毫勇气进入眼下的冒险。当女孩也走出门厅时,他找到了掩盖自己胆怯的理由,他要让女孩独自去冒险,而自己则随时准备逃之夭夭。他告诉她:他继续陪着她实在太危险,别人一眼就会看出这两个少年干了什么坏事。他让她:
“你一个人去吧。”
她没有表示异议,点了点头后就走了进去。他看着她走到挂号处的窗前,她从口袋里掏出钱来时没有显出一丝紧张。他听到她告诉里面的人她叫什么名字,她二十岁。名字是假的,年龄也是假的。这些他事先并未设计好。然后他听到她说:
“妇科。”
这两个字使他不寒而栗,他感到她的声音有些疲倦。接着她离开窗口转身看了他一眼,随后走上楼梯。她手里拿着的病历在上楼时摇摇晃晃。
男孩一直看着她的身影在楼梯上消失,然后才将目光移开。他感到心情越来越沉重,呼吸也困难起来。他望着大街上的目光在此刻杂乱无章。他在那里站了好长一段时间,那个楼梯总有人下来,可是她一直没有下来。他不由害怕起来,他感到自己所干的事已在这个楼上被揭发。这个想法变得越来越真实,因此他也越发紧张。他决定逃离这个地方,于是便往大街对面走去,他在横穿大街时显得失魂落魄。他来到街对面后,没有停留,而是立刻钻入一家商店。
那是一家杂货店,一个丑陋不堪的年轻女子站在柜台内一副无所事事的模样。另一边有两个男人在拉玻璃,他便走到近旁看着他们。同时不时地往街对面的医院望上一眼。那是一块青色的玻璃,两个男人都在抽烟,因此玻璃上有几堆小小的烟灰。两个男人那种没有心事的无聊模样,使他更为沉重。他看着钻石在玻璃上划过时出现一道白痕,那声音仿佛破裂似的来回响着。
不久后女孩出现在街对面,她站在一棵梧桐树旁有些不知所措地在寻找男孩。男孩透过商店布满灰尘的窗玻璃看到了她。他看到女孩身后并未站着可疑的人,于是立刻走出商店。他在穿越街道时,她便看到了他。待他走到近旁,她向他苦笑一下,低声说:
“有了。”
男孩像一棵树一样半晌没有动弹,仅有的一丝希望在此刻彻底破灭了。他望着眼前愁眉不展的女孩说:
“怎么办呢?”
女孩轻声说:“我不知道。”
男孩继续说:“怎么办呢?”
女孩安慰他:“别去想这些了,我们去那些商店看看吧。”
男孩摇摇头,说:“我不想去。”
女孩不再说话,她看着大街上来往的车辆,几个行人过来时发出嘻嘻笑声。他们过去以后,女孩再次说:
“去商店看看吧。”
男孩还是说:“我不想去。”
他们一直站在那里,很久以后男孩才有气无力地说:“我们回去吧。”
女孩点点头。
然后他们往回走去。走不多远,在一家商店前,女孩站住了脚,她拉住男孩的衣袖,说道:
“我们进去看看吧。”
男孩迟疑了一会儿就和她一起走入商店。他们在一条白色的学生裙前站了很久,女孩一直看着这条裙子,她告诉男孩:
“我很喜欢这条裙子。”
女孩的嗓音在十六岁时已经固定下来。在此后的十多年里,她的声音几乎每日都要在我的耳边盘旋。这种过于熟悉的声音,已将我的激情清扫。因此在此刻的黄昏里,我看着坐在对面的妻子,只会感到越来越疲倦。她还在织着那条天蓝色的围巾。她的脸依然还是过去的脸。只是此刻的脸已失去昔日的弹性。她脸上的皱纹是在我的目光下成长起来的,我熟悉它们犹如熟悉自己的手掌。现在她开始注意我的话了。
“在你还没有说话的时候,我就知道你要说什么;在每天中午十一点半和傍晚五点的时候,我知道你要回家了。我可以在一百个女人的脚步声里,听出你的声音。而我对你来说,不也同样如此?”
她停止了织毛衣的动作,她开始认真地望着我。
我继续说:“因此我们互相都不可能使对方感到惊喜。我们最多只能给对方一点高兴,而这种高兴在大街上到处都有。”
这时她开口说话了,她说:
“我明白你的意思了。”
“是吗?”我不知道该如何对付她这句话,所以我只能这么说。
她又说:“我明白你的意思了。”
我看到她的眼泪流了出来。
她说:“你是想把我一脚踢开。”
我没有否认,而是说:“这话多难听。”
她又重复道:“你想把我一脚踢开。”她的眼泪在继续流。
“这话太难听了。”我说。然后我建议道:
“让我们共同来回忆一下往事吧。”
“是最后一次吗?”她问。
我回避她的问话,继续说:“我们的回忆从什么时候开始呢?”
“是最后一次吧?”她仍然这样问。
“从一九七七年的秋天开始吧。”我说,“我们坐上那辆嘎吱作响的汽车,去四十里以外的那个地方,去检查你是否已经怀孕,那个时候我可真是失魂落魄。”
“你没有失魂落魄。”她说。
“你不用安慰我,我确实失魂落魄了。”
“不,你没有失魂落魄。”她再次这样说,“我从认识你到现在,你只有一次失魂落魄。”
我问:“什么时候?”
“现在。”她回答。
-----
一九八九年三月二十三日
爱斯基摩人-艾丽丝·门罗
========================
# 爱斯基摩人-[[艾丽丝·门罗]]
-----
玛丽·乔知道斯齐特医生会发什么议论。
“还真是个小联合国哟。”
玛丽·乔知道如何对付他,她会指出,头等舱就是这样的。
他会说,他可没提议斥巨资来换取敞开喝香槟的特权。
“再说,你知道头等舱里现在都是什么人吗?日本佬。把这个国家又买下不少之后往家赶的日本商人。”
玛丽·乔会说,她现在可不觉得日本人是什么外国人啦。她会若有所思地说这话,就好像她正对此暗自惊叹,几乎是在自言自语似的。
“我是说,他们看起来已经不像外国的种族啦。”
“哼,你在他们眼中是外国人,最好别忘记这一点。”
如此一吐为快之后,斯齐特医生就不会再闷闷不乐了。他会在她身边安顿下来,乐滋滋的,因为坐在前排,有地方给他放腿。作为一个高大、壮实、面色红润、满头银发的男人,他会显得鹤立鸡群—一个有点笨拙却高贵不凡的巨人—在这些肤色比他深、比他矮小、骨骼更细致、穿着华丽或者奇特的服装的人当中。他会坐定下来,仿佛有权坐在这,有权在这个世界上占据一席之地—仿佛这种权利只有他这个年纪和种族、这种衣着和思维的男人才能享有。
不过他没在她身边伸直双腿,心满意足地嘟囔。她孤身奔赴塔希提之旅。这次度假是他给的圣诞礼物。她坐靠走道的座位,靠窗位置空着。
“他的脑袋就恐龙那么点大,就是这么回事。”斯齐特医生的女儿丽亚宣称,她正跟玛丽·乔聊她最心爱的话题—她爸爸。她有一长串心爱的话题,心爱的严肃话题—核扩散、酸雨、失业率,以及种族偏见和女性地位—不过通往它们的道路无一例外都是从她爸爸开始。照丽亚的说法,她爸爸差不离就是这一切的肇因。是他促成了原子弹、污染、贫穷和种族歧视。玛丽·乔不得不承认有时他发的议论确实会让人得此结论。
“那些只是他的看法罢了。”玛丽·乔说。她都能想象出那种恐龙了,脊梁上有一些扁扁的骨头突出—一种华丽的盔甲,几乎像饰物。“男人嘛,总要有点看法才成。”
这话多蠢啊,尤其是对丽亚而言。丽亚二十五岁,失业,是个肥胖、活泼、美丽的女孩,骑辆摩托车。玛丽·乔说完这话,胖姑娘丽亚保持淡定的微笑,盯着她看了一分钟之久,这才轻柔地说:“为什么呢,玛丽·乔?为什么男人非得有看法才成?以便男人毁掉世界的时候,女人只需要坐在那里咂咂嘴吗?”
她摘掉摩托车头盔,把被雨水打湿的头盔搁在玛丽·乔的办公桌上,抖开一头乱糟糟的深色长发。
“没什么男人在毁灭我的世界。”玛丽·乔拿起头盔搁到地板上,轻快地答道。在这场谈话中,她并不像听起来那样势均力敌。丽亚这家伙,跑进她爸爸的办公室,这番高谈阔论,到底想干什么呢?她想必不曾指望玛丽·乔赞同她。不。她想要、希望玛丽·乔捍卫她爸爸,这样她就可以得意地表示不屑(哦,当然了,玛丽·乔,你觉得他就是上帝!),同时也能安心。玛丽·乔似乎该承担起这女孩妈妈的分内事—让她理解爸爸,原谅他,钦佩他。不过,斯齐特医生的妻子可不大会原谅或者钦佩任何人,更不用说是对她丈夫了。她酗酒,自视为一个智者。有时她会打电话到办公室,问可否跟“伟大的医治者”通个话。一个身材高大、声音洪亮的邋遢女人,一头白发乱糟糟的,成天与演员们(她是当地剧院的董事)和所谓的诗人(她过去这几年一直在读博士的那所大学里的英语教授们)厮混。
“一个像你爸爸那样的男人,每天都在拯救生命,”玛丽·乔告诉丽亚—她经常强调这一点—“怎么能说他在毁灭世界呢?”玛丽·乔之所以捍卫斯齐特医生,并不只因为他是个男人,是个父亲,根本不是。并非因为这些,她才觉得他妻子应该给孩子灌输一些对他的尊敬之情。而是因为他是这个地区最出色的心脏病专家,因为他每天都奉献给等在候诊室里面如死灰的病人了,心脏病患者,生存在恐惧和痛苦中的人们。他的生命都用来奉献了。
丽亚尽管戴了头盔,头发还是湿了,她把雨水直甩到玛丽·乔的办公桌上。
“丽亚,小心点,拜托。”
“你的世界是什么呢,玛丽·乔?”
“没时间跟你解释。”
“你尽忙着帮我爹地咯。”
玛丽·乔为斯齐特医生工作了十二年,在楼上的公寓住了十年。丽亚小一点的时候—还是个喧闹、肥胖、烦人却可爱的十来岁丫头的时候—喜欢到公寓找玛丽·乔玩,玛丽·乔只好煞费苦心地确保斯齐特医生频频短暂逗留的痕迹都已消抹干净。如今丽亚对此想必早已心知肚明,只是不曾直接质问过什么。她经常像是试探性地围着这个话题绕圈子。玛丽·乔尽量装作面无表情,却时不时觉得好累。
“不过,你能去趟塔希提,真不赖。”丽亚说,仍旧危险地微笑着,头发和眼睛都闪闪发亮。“你一直就想去那里,对吗?”
“当然了,”玛丽·乔说,“谁不是呢?”
“并不是说他不欠你这一趟哦。我觉着吧,是他对你的奉献作点回报的时候了。”
玛丽·乔不做声,继续填病历。过了一会儿,丽亚平静下来,讨论起了从她爸爸那里弄点钱来修摩托车的可能性—她来诊所就是为了这个。
为什么丽亚,在那些老一套的嘲弄、说教和宣传之外,总能问中个把烦人的问题呢?“你一直就想去那里,对吗?”塔希提,事实上,玛丽·乔想都没想过要去那里。塔希提对她而言意味着棕榈树、红花、碧波翻滚,以及她毫无兴趣的热带的繁茂和慵懒。这份礼物有种缺乏想象力却挺感人的味道,就像情人节的巧克力。
冬天到塔希提度假!我打赌你激动得要跳起来了!
是啊,我当然是!
她告诉病人们、朋友们,还有妹妹们—她疑心他们都觉得她没有真正的生活—她是多么激动。而且昨夜她辗转无眠—如果那也算数的话。今天早上六点不到—似乎是很久之前了—她就站在公寓窗前,从里到外一身新衣,等着出租车送她去机场。一段短暂、颠簸的飞行去多伦多,一段从多伦多到温哥华的长途飞行,然后就上路啦,朝太平洋飞去。在火奴鲁鲁暂停,再然后就到塔希提啦。没回头路可走。
要是希腊就好了。或者斯堪的纳维亚。好吧,或许斯堪的纳维亚不适合这个季节。或者爱尔兰吧。去年夏天,斯齐特医生和妻子去了爱尔兰。他妻子正在“研究”一些爱尔兰诗人。玛丽·乔根本不认为他们会开心。跟这样一个邋遢、乖戾、麻烦不断的女人一起,谁会开心呢?她相信他们喝得不少。他去钓鲑鱼。他们住在一幢城堡里。他们的度假—以及他独自的休假,通常都是去钓鱼—总是很奢侈,而且在玛丽·乔看来,无非都是例行公事,无聊透顶。他的宅邸也一样,还有他的社交和家庭生活—全都一个样,她想,全都是例行公事,无趣而昂贵。
玛丽·乔开始为斯齐特医生工作时,获得护理学位已有三年,不过她手头从没余钱,要还读书贷款,也要帮几个妹妹还。她来自休伦县的一个小镇。她爸在镇上的维修队干活。她妈因为所谓的“心脏病”去世了—后来玛丽·乔才得知,这只是一种心脏方面的小毛病,斯齐特医生可以诊断出来,并推荐手术加以治疗。
玛丽·乔一有足够的钱,就开始整牙。它们让她羞愧。她从不涂唇膏,笑起来总是小心翼翼。她拔掉犬齿,补了门牙。但她仍不满意,于是戴上了牙箍。她计划牙箍一取下,就把头发染成浅色—现在是平淡无奇的褐色—买点新衣服,甚至搬走,换个工作。等牙箍真摘掉之后,她的生活果然不同于以前,不过并非因为这些策略。
随着时间流逝,更多变化出现了。她从一个模样严肃、全神贯注、声音温柔、胸部肥大的水桶腰女孩,变成一个苗条、衣着入时的女人,一头夹杂金色的头发—如今她超过了年轻时比她漂亮得多的同龄女人们—说话讨人喜欢且不乏权威。这些变化对斯齐特医生起了多少作用,这一点不好说。他过去经常戏言她不要变得太迷人,不然会有人盯上她,把她从他身边夺走。这类话流露出一丝令她沮丧的意味,让她好不自在。后来他不再这么说了,为此她很高兴。不过最近他又开始了,在提到她的塔希提之旅的时候。她想,现在她知道如何对付他了。她调戏他道,谁说得准呢?真要那样也不奇怪嘛。
他喜欢上她的时候她还戴着牙箍。他第一次和她做爱时,牙箍还在。她把头扭到一边,担心一嘴金属块块不会讨人喜欢。他闭着眼睛,她想,或许是因为牙箍吧。后来她知道他那种时候总会闭上眼睛。那种时候他不希望记起自己,没准也不愿意记起她。他的快乐是一种猛烈而孤独的快乐。
隔着走道,玛丽·乔对面是两个空座位,之后是一个年轻的家庭,妈妈和爸爸带着一个宝宝和一个大约两岁的小女孩。意大利人,或者希腊人,或者西班牙人吧,玛丽·乔想,通过他们跟空姐的交谈,她很快判断出是希腊人,不过现在住在澳大利亚的珀斯。他们的座位位于电影屏幕下面,是飞机上唯一有足够空间供他们摆放行李和照料孩子的地方。保温包、塑料食碟、和宝宝一般大的枕头、可以当椅子的折叠床、奶瓶、果汁瓶,还有一个巨大的熊猫玩具,用来哄小女孩的。做父母的忙着照料孩子们—给他们换上颜色粉嫩的睡衣,喂他们吃,逗他们玩,唱歌给他们听。是的,他们告诉啧啧惊叹的空姐,年龄相差不大,只隔了十四个月。婴儿是个男孩。他有点出牙期的小问题。小女孩时不时会吃醋呢。两人都非常喜欢香蕉。她能整根吃,他吃香蕉泥。亲爱的,把他的围嘴拿来,在蓝色包里。毛巾也拿出来吧,他有点流口水。不,毛巾不在那,在塑料袋里。快点。对了。快点。好咯。
玛丽·乔吃惊地发现,她对这个无害的家庭充满厌恶。你们为啥把食物硬塞进他嘴里?她恨不能这么问(他们在一个蓝色碗里调燕麦粥)。他这个年纪吃固体食物完全是浪费,只会让你上下两头都忙着擦洗。多么小题大做,多么累赘繁琐、哗众取宠和沾沾自喜啊,就因为他们设法生出了孩子。此外,他们还耽误空姐给别的乘客端饮料的时间。
他们后面坐着另外一个年轻的家庭,印度人。做妈妈的穿一件金线绣的红纱丽,做爸爸的一身紧绷绷的奶油色西装。苗条、沉默、遍体金色的妈妈;营养过剩、模样懒散的父亲,正听着耳机里的摇滚频道。你可以根据他拍打绷在圆滚滚大腿上的奶油色布料的手指判断出是摇滚频道。父母之间坐着两个小女孩,都穿红衣服,戴金手镯、金耳环,脚蹬漆皮鞋,还有一个小弟弟,或许跟前排的希腊小女孩一个年纪,一身西服,完全就是爸爸那身的微缩版—马甲、暗门襟、口袋,一应俱全。空姐给他们送来蜡笔和画画本,但是浑身金光闪烁的小女孩们只是掩住脸咯咯笑。她给他们送上一杯杯干姜水。小弟弟对干姜水摇摇头。他爬到妈妈的膝盖上,她从纱丽中拉出一个若隐若现的饱满乳房。他安顿下来,懒洋洋地躺着吮吸,瞪着大眼睛,看起来不可一世、心满意足。
这也没让玛丽·乔好受一点。她不大习惯现下的这种厌恶感。她知道这实乃无中生有。她在诊所从不会这样。不管遇到什么困难,也不管有多累,她都能轻而易举地对付各种古怪或粗鲁的举止、令人不快的习惯、不好闻的味道和令人无语的问题。她肯定有什么地方不对劲儿了。晚上失眠来着。她的喉咙有点堵,脑袋沉甸甸的。可能要发烧了。不过这更像是她的身体在抗议用这种不断拉开的距离,太快地把它从习惯的归属地和休憩地挪走。今天早上,她还可以从窗口看到维多利亚公园一角、街灯下的积雪和光秃秃的树木。公寓和诊所都位于一幢好看的旧砖房里,它属于斯齐特医生。周围的整排房子模样都差不离,用途也都类似。玛丽·乔看着泥泞的街道、肮脏的二月积雪、周围房子的灰墙,还有公园后头高高的办公大楼区,那里夜灯通明。她什么都不想要,只想留下。她想取消出租车,换掉新买的麂皮套装,穿回护士服,下楼把咖啡壶放在火上,给植物浇浇水,准备好面对漫长的又一天,它充满各种难题和例行公事、恐惧和宽慰,以及对于被缠着谈论糟糕天气的担忧—这时不时会发生。她爱这诊所,这候诊室,这昏暗冰冻的下午亮起的灯光。她爱这些挑战和日复一日。一天到头,斯齐特医生有时会上楼到她那里。她做晚饭,他会待上半个晚上。他妻子出门去开会、上课,或者参加诗歌朗诵会了。她出门喝酒,或者已经回家,直接上床了。
空姐终于走过来,玛丽·乔点了一份伏特加马天尼。她向来选择伏特加,希望说它不容易闻出酒味儿的传闻是真的。出于很显然的原因,斯齐特医生不喜欢女人身上飘出酒味。
又有两个人沿过道走来,显然是想换座位,他们挡住了饮料车。另一个空姐手忙脚乱地跟在他们后头。她和那个女人拎着几个购物袋、一只旅行包和一把伞。那个男人两手空空走在前面。他们一屁股坐在玛丽·乔对面的位置上,在希腊一家的旁边。他们试图把行头塞进座位底下,没成功。
空姐说,顶上的柜子里地方足够。
不。男人发出几句低低的抗议,女人则嘟囔着道歉。空姐终于明白,他们决定盯着自己的所有行李。饮料车推走了,他们发现有一个地方可以放行李—在玛丽·乔前面,空姐起飞和着陆时坐的小弹跳椅后头。
空姐说,希望不会太妨碍那位女士哦。她语调轻快,表明这两个乘客已经惹过一些麻烦。玛丽·乔表示不会,对她没什么影响。那两个人便安顿下来,男人坐靠过道的位置。他又嘟囔一声,颇为专横,但不意味着心情不佳。空姐端来两杯威士忌。他朝玛丽·乔的方向轻轻举举杯。一个傲慢的姿态,可能是表示谢谢吧。显然不是道歉。
他身形肥胖,可能比斯齐特医生老一些,但更精神。一个轻率、乖戾的男人,一头相当长的灰发,身穿昂贵的新衣。棕色袜子上套着凉鞋,上面是锈色长裤,明黄色衬衫,一件体面的金色麂皮上衣,有很多小小的垂片、褶子和口袋。他的皮肤是棕色的,眼睛细长。不是日本人或中国人—他是干什么的?玛丽·乔觉得似曾相识。不是一个病人,不是在诊所里。在哪里呢?
女人从他肩膀后面窥出来,抿嘴微笑,讨人喜欢地皱着宽宽的脸庞。她眼睛细细的,比他更明显,皮肤也更苍白。黑发中分,用橡皮筋扎成小孩一样的马尾辫。她的衣服廉价但挺齐整,或许还很新—棕色休闲裤,印花上衣—不过跟他站在一起很不匹配。拎着购物袋沿过道走来时,她像是个中年人—水桶腰,肩膀浑圆。不过,这会儿她在男人壮实的肩膀后面冲玛丽·乔微笑着,看起来相当年轻。这个微笑本身也有点古怪。她张开嘴对男人说话,古怪的原因揭晓了。少了前排牙齿,整整一排都不见了。正因为此,她的微笑显得偷偷摸摸的,又挺天真—一种看起来狡黠又持久的欢乐表情,就像老太太或小宝宝的微笑一样。
现在,玛丽·乔想起在哪里可能看到过这个男人了。几星期前,她看了一个电视节目,关于阿富汗一个深深的山谷里的一个部落,靠近西藏边缘。节目是几年前俄国人入侵之前拍摄的。部落民住兽皮屋,成群的绵羊、山羊和骏马就是他们的财产。有个男人似乎积累了最多的这种财富,借助个人魅力和经济实力当上了部落统领,而不是通过继承权。他被称作“可汗”,在兽皮屋里铺上美丽的地毯,装了一台收音机,养了好几个老婆或小妾。
这个男人让她想起这人—可汗。或许正是他本人,不可能吗?难道真没可能吗?他没准离开了他的国家,在俄国人入侵之前就走了,带着毯子、女人,没准还有大量金子,尽管不大可能把山羊、绵羊和马群都带上。你要是搭乘各大航班周游世界,不是迟早会撞上什么电视上见过的人吗?大有可能就是一个异国首领,就像撞上演员、政治家或者心灵治愈大师一样。在现如今这个不安宁的时代,那也大有可能是某个被当作与世隔绝之国的异域风情甚至遗迹而拍摄下来,现在却跟大家一样出来到处溜达的家伙。
女人想必是他的老婆之一咯。最年轻,或许也是最受宠的一个,才被带着进行这番旅行。他带她去了加拿大或美国,儿子们在那里上学。他带她去看了牙医,帮她装假牙。或许假牙就放在手提包里,她还没适应,时戴时不戴。
玛丽·乔被自己这番编造逗乐了,或许伏特加也起了点作用。她在脑海里草拟起一封描述这两人和电视节目的信。当然是写给斯齐特医生的,她看那节目的时候,他就挨着她坐在沙发上—不过睡着了。她会提到女人的牙齿,以及它们是被特意拔掉以迎合某种古怪的女性审美观的可能。
“要是他邀请我加入他的后宫,我发誓决不接受任何这类古怪做法!”
电影屏幕放下来了。玛丽·乔乖乖打开顶灯。她考虑着再点一杯喝的,但旋即改了主意。在这个高度,酒精会比平时更强劲。她试着看电影,不过从她的位置看过去,人物都被拉长了,看起来既阴郁又古怪。开头两分钟就有一场谋杀—某个一头迷人金发的女郎在空无一人的走廊被跟踪,然后根据画外音,显然遭到枪杀。玛丽·乔几乎立刻兴味索然,过了一会儿便摘下耳机。这时,她注意到过道对面好像在吵架。
女人,或者女孩,好像想站起来。男人把她按下。他冲她嘟囔了一阵。她回答的语调从抱怨过渡到保证再过渡到抱怨。他好像不搭理她了,仰头看起屏幕。女孩从座位上挤出来,踉踉跄跄爬过他。他突然激动地嚷嚷起来,拽住她的腿。玛丽·乔吃惊地发现,女孩跟他说的是英语。
“我没有,”她固执地说,“我没有。没醉。”语调激动而绝望,喝醉的人坚持自己没醉时通常都是这副腔调。
男人厌恶地哼了一声,放开了她。
“你不能控制我,”她说,声音中、眼睛里都有了眼泪,“你又不是我爸。”她没沿过道走向洗手间—如果这是她的目的地—而是站在他够得到的地方,悲哀地低头看他。他佯作又要抓住她,动作迅速凶狠,好像这次,或者下次,他真的不惜伤害她了。她踉踉跄跄躲到一边。他把注意力重新转回屏幕。
女孩仍旧没沿过道走开。她冲玛丽·乔俯下身。
“原谅我。”她说,眼泪汪汪地微笑着。困惑、受辱的脸皱着,抿着嘴做出大大的、或是道歉或是推心置腹的微笑。“请原谅。”
“没关系。”玛丽·乔说,以为女孩是为了吵架而道歉,旋即意识到“请原谅”意思是“可以借过吗”。女孩想跨过玛丽·乔的腿,这腿正脚踝交叠,舒服地伸直着。她想坐到靠窗位置。
玛丽·乔让开路。女孩坐下,用食指做了一个直直的横掠动作抹干眼睛,不慌不忙、总结性地吸了一下鼻子。又要怎样呢?
“别告诉任何人,”女孩说,“别告诉任何人。”
她把宽宽的手搁在玛丽·乔的膝盖上,又收回去。
“不会。”玛丽·乔说。不过能告诉谁呢?又干吗要告诉别人这样一场不伦不类的吵架呢?
“不要告诉任何人。我是爱斯基摩人。”
自然,女孩一站上走道,一张嘴,玛丽·乔就意识到什么可汗和他最宠爱的老婆之类全是瞎扯。她点了点头,不过“爱斯基摩人”这个词比它表明的事实更让她不自在。人们不再用这个词了吧,对吗?“因纽特人”,这才是现在的叫法。
“他是米提斯人[1]。我是爱斯基摩人。”
真不赖啊。米提斯人和爱斯基摩人。加拿大老乡。够离谱的,玛丽·乔想。她在脑海里寻思着,得重写一封信啦。
“别告诉任何人。”
女孩的样子,好像在吐露什么秘密—一个羞耻的秘密,一个可怕的错误。她很害怕,同时竭力保持尊严。她又说了一遍:“不要告诉任何人。”并把手指在玛丽·乔嘴上按了几秒钟。玛丽·乔可以感觉到她皮肤的炙热,还有在这手指里和女孩整个身体里贯通着的颤抖劲儿。她就像一只身陷完全无法言喻的恐惧中的动物。
“不,不,我不会的。”玛丽·乔再度保证。她想,最好还是假装完全明白这个要求的含义。
“你要去塔希提吗?”她友好地问。她知道,这种时候问个寻常问题,可以帮惊恐的人分分神。
女孩又绽放出一个微笑,好像理解了这个问题的目的,它的善意,尽管对她而言这点根本微不足道。“他要去塔希提,”女孩说,“我,也一样。”
玛丽·乔看看过道对面。男人的脑袋正懒洋洋地靠着,或许已经打起瞌睡。即便掉开脸,她仍能感到女孩的炙热和颤抖。
“你多大了?”玛丽·乔问。也不知道为什么问这个。
女孩摇摇头,好像她的年龄确实是件荒谬、悲惨的事。“我是爱斯基摩人。”
有什么相干吗?她说着这事,好像它是一个玛丽·乔终究会读懂的密码似的。
“不错。可是你多大了?”玛丽·乔更坚定地问,“有二十岁吗?过了二十没有?十八岁?”
继续摇头和困窘,继续微笑。“不要告诉任何人。”
“多大了?”
“我是爱斯基摩人。我十六岁啦。”
玛丽·乔又看看过道对面,确定男人没在听。他好像睡着了。
“十六岁?”
女孩重重地晃晃脑袋,几乎笑了。颤抖依旧。
“你是吗?不是?是吗?是吧。”
再次地,沉甸甸的手指像羽毛一样在玛丽·乔嘴上掠过。
“你想跟他去夏威夷吗?是吗?”
“他要去夏威夷。我,也一样。”
“听着,”玛丽·乔温柔而小心地提议,“我要站起来,走到飞机后头。我要去洗手间。洗手间。我在那里等你。过一会儿,你就站起来,朝后走。你到飞机后头,洗手间那里,我们在那里聊聊。那里说话方便。行吗?明白我的意思吗?好。”
她不急不忙地站起身,拿起滑到椅子上的外套,理理好。男人在垫子上扭过脑袋,冲她投来茫然、阴郁的一瞥,眼神像一只半睡半醒的狗。他的眼珠在眼皮下转了转,脑袋又扭了回去。
“好吗?”玛丽·乔做着口型问女孩。
女孩用手指按住自己的嘴,按在微笑的双唇上。
玛丽·乔朝飞机后头走去。早些时候,她脱掉靴子,换上了拖鞋。现在,她舒服地吧嗒吧嗒走着,不过还是挺怀念靴子带来的成就感和坚定感。
她不得不站在排队上洗手间的人中,因为别处没地方可站。队列延伸到窗边那块小小的地方,她本打算站在那里等的。她不断四下打量,等着女孩跟在后面走来。还没来。有几个高个子也来排队,她不得不设法绕过他们朝后看,想确保女孩可以看到她。她只能跟着队列前进,轮到她的时候,她没有选择,只有进去。不过反正也差不多该用洗手间了。
她尽快出来了。女孩还是不见。没在排队。没在厨房附近晃荡,也没坐在后部的哪个座位上。队列现在比原先短,玛丽·乔可以站在窗边了。她站在那里等着,直发抖,懊悔没带上外套。
在洗手间里,她没顾上补口红。现在,她对着黑色的窗子映出的脸涂了起来。假设她决定跟什么人说女孩的事—他们会怎么想她?她现在可以跟什么人讲讲的—那个年长些、看起来相当严肃、画着铜色眼妆的空姐,她似乎是领头的,或者那个空中先生,他看起来心不在焉,不过似乎更平易近人。她可以告诉他们女孩的话,女孩的颤抖,可以说说她的怀疑。不过这些有什么用呢?女孩没说任何可以直接引起怀疑的话。她是个爱斯基摩人,十六岁,要跟一个比她大得多、不是她爸爸的男人去夏威夷。十六岁到法定年龄了吗?带一个女孩去夏威夷犯法吗?毕竟,她有可能不止十六岁。看起来当然不止。她或许醉了,在扯谎。或许是他老婆,虽说没戴戒指。他也当然有可能是她的什么亲戚。玛丽·乔现在不管说什么,估计都会被视为一个多管闲事的女人,刚灌过一杯,没准还不止一杯呢。没准会被认为是为了不可告人的目的,试图控制那女孩。
如果要采取什么措施,女孩得自己说点什么。
不提出要求,就得不到帮助。
得说出你要什么。
得开口。
玛丽·乔慢慢走回座位,一路上注意着女孩有没有行动,有没有坐在别处。她寻找着那个梳着马尾辫的硕大驯服的脑袋。
哪里都不见。
不过快回到座位时,她看到女孩已经挪动了。她坐回原来的位置,在男人旁边。他们又要了两杯威士忌。
或许他趁她起身之后,把女孩拽了回去,强迫她坐在身边。玛丽·乔该让女孩先走的。不过当时能说服她,让她明白吗?女孩真的明白她有意相助吗?
玛丽·乔站在过道上穿外套。她低头看着那两人,但他们都没看她。她坐下,打开阅读灯又关上。电影已经没人看了。希腊宝宝正在哭闹,做爸爸的抱着他在过道上来回走动。印度小女孩们彼此依偎着,她们的小弟弟在妈妈窄窄的大腿上睡着了。
斯齐特医生会让玛丽·乔很快就明白过来。有些关心—他让她承认过这点—实属无事生非、自作主张。人们出于自作主张的好心,每每会惹出麻烦,而不是做好事。这次她就差点如此。
不错。不过他自己总是关心着人们的体内,关心着他们的胸腔内部。要是这女孩心脏有毛病,哪怕她比现在大上二十岁,四十岁,哪怕她的生活根本就是一团糟,等同废物,脑子因为酗酒而荒废近半—就算如此,他也会全力治疗。他会毫无保留,为了这样的拯救或者说拯救的努力而竭尽全力。要是事关真正的心脏,要是事关人们胸膛里血淋淋、怦怦跳、承受重负的心脏。
斯齐特医生的声音里有种隐隐的悲哀。不仅是他的声音,他的呼吸也是悲哀的。在电话里,还没听到他的声音,你就能感到一种无药可救、平静得体的悲伤从他的呼吸中传来。要是告诉他这个,他会不高兴。不是说他特别希望你觉得他开心,而是他会认为有人断言他很悲伤,这既无意义又过于唐突。
这种悲伤似乎是恭顺所致。玛丽·乔只能意识到它的存在,却永远无法理解它。她觉得男人身上有一种恭顺是女人无法理解的。(丽亚对此会作何评论?)问题并不在于他所知道的—那个玛丽·乔能对付—而在于他所逆来顺受的。他令她困惑,压力重重。她以一种困惑、谨慎、永恒不变的爱情爱着这个男人。
她想到他的时候,脑海中的他总穿着棕色三件套。那是一套老式西装,让他看起来酷似他童年时代—道道地地的贫困乡村的童年时代—的医生。他有一些好看的休闲服,她看到过他穿它们,可她觉得他穿那些并不自在。他对变有钱不怎么适应,她想,尽管他觉得必须如此,而且对于任何有可能阻碍他的政府都仇恨无比。恭顺、逆来顺受和悲哀。
要是她对他这样讲,他不会相信的。没人会信。
尽管穿着外套,她还是直发抖。她好像有点传染了女孩顽固、古怪的不安。或许真的病了,发烧啦。她扭着身体,试图恢复平静。她闭上眼,忍不住又要睁开。没法不看看过道对面。
这会儿发生的事,她要是够明智、够得体,就该扭头避开才对。不过她没有,而是眼睁睁看了下去。
威士忌酒杯空了。女孩朝前探身,吻着男人的脸。他的脑袋靠在垫子上,没动弹。她眼睛闭着,或者半闭着,朝他贴过去。她的脸宽阔、苍白而冷漠,好一张银盆大脸。她吻他的嘴唇,他的脸颊,他的眼皮,他的额头。他任由着她,纵容着她。她吻他,舔他,舔他的鼻子,他脸颊、脖子和下巴上淡淡的胡茬。舔遍他的脸,吸口气,又开始吻。
吻得不急不忙,心平气和。并非机械性的吻。没有任何被胁迫的迹象。女孩很投入:身陷一种奉献的痴狂。真正的奉献。这里面没有什么像原谅或者安慰那样冒昧的意味。这是一个仪式,占据了她的全部注意力和自我,她的自我迷失在其中。它可以没完没了地继续下去。
即便女孩眼睛睁开,带着一种并非茫然迷惑,而是直率尖锐的表情径直朝过道对面看过来—即便这时,玛丽·乔仍旧没法不盯着她看。她作了巨大的努力,花了难以估量的很长一段时间,才终于把双眼挪开。
要是有人问她,看这一切时有何感受,玛丽·乔会回答,她觉得恶心。这并非敷衍。恶心不仅仅是出于发烧的最初症状,或者别的什么令她头晕发抖的原因,而是一种让她厌恶不已的恶心,就好像她能感觉到那温热、肥厚的舌头在自己脸上缓慢舔过。旋即,等她挪开视线,另一种感受涌出,那就是欲望—突如其来、摧枯拉朽的欲望,仿佛松动的泥土从高山奔涌而下。
同时,她听到斯齐特医生的声音,它一清二楚地说道:“你知道,那女孩的牙齿没准是被撞掉的,在哪次吵架的时候。”
这是斯齐特医生熟悉的、有条有理的声音,它要求你应当认清某些事实,某些条件。不过她还从中听出了一些新鲜的意思—一种会心的、自然的满足感。他不仅仅是悲哀的,不仅仅逆来顺受着,而且还因为某些事情如其所是而心满意足着。这种满足感深藏在他的声音里,呼应着她体内松动的感觉。她感到一种生理上的羞耻和厌恶,一种仿佛从胃部扩散出来的热度。这个会过去,这波浪潮会退却,可这种厌恶的感觉不会消失。从你心里散发出的厌恶、恶心、不快,可以比痛苦更糟。它会比痛苦更令人难以忍受。想到这个,并给她的感觉定了一些名目之后,她终于稍稍平静。想必是飞行的陌生感,还有酒精,还有女孩带来的困惑,或许还有某种病毒,让她不自在。斯齐特医生的声音与真正的幻觉相差无几,不过毕竟不是幻觉。她知道是自己炮制出了它。她炮制出了它,以便可以扭头躲开它,因为她是那样恨他。要是这感觉变成真的,要是这样一种幻觉征服了她,那她的处境可就太悲惨了,想想都可怕。
她竭力让自己平静,做着深呼吸,假装自己快睡着了。她开始给自己讲故事,故事中各种事情都变得更加顺利。假设女孩刚才跟她去了飞机后部,假设她们有机会交谈,那会怎样?故事不知怎的发展到了火奴鲁鲁的候机室。玛丽·乔看到自己坐在软垫椅子上,房间里装饰着矮小的盆栽棕榈树。男人和女孩从她面前走过。女孩拎着购物袋走在前面。男人把旅行包甩在肩膀上,抓着雨伞。他用卷起来的雨伞一头捣捣女孩。并非想伤害她,甚至都不是为了吓唬她。只是一个玩笑。女孩小跑着,咯咯笑,带着一种深深的道歉、发窘、无助、好脾气的神情看看四周。然后玛丽·乔迎上她的目光,男人对此毫无觉察。玛丽·乔站起身,穿过候机室,走进女洗手间这个明亮的、铺着瓷砖的避难所。
这回女孩果真跟在她身后。
玛丽·乔打开冷水,以一种鼓励的姿态,用水泼泼自己的脸。
她敦促女孩也这么做。
她平静地、不容置疑地跟她说话。
“对啦。给你的脸降点温,让头脑清醒点。你必须清醒地思考,必须非常清醒地思考。对啦。是什么?想要的是什么?你害怕的是什么?别怕。他进不来这里。我们有时间。你可以告诉我想要什么,我可以帮你。我可以跟当局联系。”
不过,故事到这里戛然而止。玛丽·乔陷入了僵局,她的梦—因为她正在做梦—笨拙地将这个转译为水槽底部搪瓷脱落的地方露出的一块歪歪扭扭、出乎意料的铁锈。
这个女洗手间保养得够糟的。
“热带地区都像这样吗?”玛丽·乔问站在旁边水槽前的女人,女人用手掩住她的水槽,好像不想让玛丽·乔看或者用它。(并不是说玛丽·乔想这么做。)她是个高大、白发、穿红纱丽的女人,貌似在女洗手间里颇有权威。玛丽·乔四处寻找爱斯基摩女孩,吃惊地发现她躺在地上。她缩小了,长得跟橡皮人似的,一张洋娃娃一样粗糙的脸。不过真正惊人的在于她的脑袋从身体上脱落了,尽管仍由一根内部的松紧带连着。
“你可以选择你自己的。”白发女人说,玛丽·乔觉得指的是你自己的惩罚方式。她知道自己不必担心—她不用负责,又不是她打了女孩或者把她推到地上。那女人准是疯了。
“抱歉,”她说,“我得回飞机了。”
不过这是后来的事,她们已不在女洗手间里了。她们回到了斯齐特医生的诊所。玛丽·乔隐隐察觉到事情有点混乱,令她无所适从,时间中出现了一段莫名其妙的缺失。她仍旧惦记着要回到飞机上,可上哪儿去找候机室,又如何去火奴鲁鲁呢?
一个高大的、完全裹着绷带的人形被抬过,玛丽·乔急于搞清那是谁,发生了什么,为什么他们会送一个烧伤患者来这里。
穿红纱丽的女人也在。她非常友好地问玛丽·乔:“判决[2]是在花园里吗?”
这或许意味着玛丽·乔仍旧要因为什么事受指控,花园里正进行判决呢。另一方面,“判决”也可能指的是斯齐特医生。女人想说的或许是“伯爵”,只是发音不准。要真是那样,那她准是在嘲讽他。管他叫“伯爵”是个玩笑,“在花园里”也意味深长,玛丽·乔要琢磨出它的含义,得绞尽脑汁才行。
不过女人张开手,给玛丽·乔看几朵小小的蓝色花—像雪花,却是蓝色的—她解释说这些就是“攀蕨”,“攀蕨”指的是花。
这是个诡计,玛丽·乔明白,但她没法集中注意力,因为她正在醒来。在一架飞越太平洋的巨大客机中,电影屏幕收起,灯光几乎全部熄灭,就连那个宝宝也入睡了。她没法穿过梦境中的层层屏障,回到清晰的部分。女洗手间里,她们正用冷水泼脸,她—玛丽·乔—正告诉女孩可以如何自救。她没法回去。周围人都盖着毯子沉睡,脑袋枕着橙色小枕头。不知何时,她自己也给枕了一个小枕头,盖着一床毯子。过道对面的男人和女孩都睡着了,张着嘴,他俩流畅、纯洁的鼾声二重唱终于让玛丽·乔浮上现实。
她的假期的开始。
[1] 加拿大原住民的一族。
[2] 原文为court,与count(伯爵)音形均相似。
安纳克莱托 · 蒙罗纳斯——[[胡安.鲁尔福]]
作者:[墨西哥] 胡安 · 鲁尔福 / 屠孟超译
-----
```
这些老婆子,真像是魔鬼生的,我看到她们顺着次序一个个地走来了。她们一身黑衣,像烈日照耀下的母驴那样满头大汗。从远处看去,我看见她们像一群牲口那样掀起滚滚尘埃,她们浑身都是黑的,满脸都是灰尘。她们沿着到阿穆拉去的那条道路走来,冒着酷暑,口中不停地祈祷着。脸上的汗珠大滴大滴地落在她们那巨大的黑色披肩上。
见到她们来了,我便躲藏起来,我知道她们在干些什么,也清楚她们要找什么人。因此,我一手提着裤子,急匆匆地奔到鸡舍里躲了起来,躲在最里面的地方。
但是,她们也走进鸡舍,找到了我,嘴里还念着:“圣洁的圣母玛利亚!”
当时我脱下裤子一动也不动地蹲在一块石头上,好让她们见到我这个模样,不敢走近我。但她们只是说了句 “圣洁的玛利亚!” 却更靠近我了。
这些不知羞耻的老太婆!她们本来应该觉得难为情的!她们却划着十字,最后竟相互紧挨着站在我的周围,把我给围了起来。她们汗流如注,头发紧紧地贴着脸部,仿佛被雨淋过一般。
“我们是来看你的,卢卡斯 · 卢卡特罗,我们是专程从阿穆拉来看你的。到了这儿附近,有人告诉我们,你在家里,但我们没有想到你会待得这么靠里,也没有想到会待在这么个地方,干这样的玩意儿。我们原来以为你是进来喂鸡的,因此,我们也进来了。我们是来看你的。”
这几个老东西!不但老,还像驴背那样丑!
“请告诉我,你们有何贵干?” 我一面对她们说话,一面系上了裤带,她们蒙上了眼睛不看我。
“我们是受人之托。我们去过圣地亚哥和圣伊纳斯,但当地的人告诉我们,你已不在那儿居住,已经搬迁到这个庄上来了,于是,我们便找到了这里。我们是阿穆拉人。”
我早知道她们是从那儿来的,也知道她们的身分,我甚至可以一一说出她们的名字,但我却装作什么也不明白的样子。
“是这样的,卢卡斯 · 卢卡特罗,感谢上帝,我们终子找到你了。”
我请她们来到过道上,拿出几把椅子让她们坐下。我问她们是不是饿了,想不想喝点水,那怕是一小罐,以润润喉。
她们坐下来,拿披肩擦着汗。
“不必啦,谢谢。” 她们说,“我们可不是来给你添麻烦的。我们有件事情请你帮忙。你是认识我的,卢卡斯 · 卢卡特罗,可不是么?” 其中的一个女人问我。
“是有点儿面熟,” 我回答说,“我好像在什么地方见到过你。也许你就是被奥蒙博诺 · 拉莫斯拐去的那个潘恰 · 弗雷戈索吧?”
“不错,我就是,不过,我可没有被任何人拐骗过,这完全是恶意中伤。当时我们俩在寻找仙人掌时迷了路。我是主教会会员,要是发生那样的情况,我压根儿也不允许……”
“不允许什么,潘恰?”
“唉,卢卡斯,你就爱往坏处想,至今你还没有改掉诬蔑人的坏习惯。不过,既然你认出了我,我就借此机会告诉你我们此行的目的。”
“你们连一罐水也不想喝吗?” 我又问她们。
“你别麻烦了。不过,既然你多次请我们喝水,那就恭敬不如从命了。”
我给她们拿来一罐番石榴汁,她们一下子全喝完了。我又拿来一罐,她们又喝完了,于是,我给她们提来一桶河水,放在那里备用。因为据她们说,等一会儿开始消化食物时,她们会觉得很渴的。
她们一共十人,坐成一排,身上的黑衣服溅满了泥土。她们是潘西亚诺、埃米利亚诺、克雷森西亚诺,还有酒店老板托利维奥和理发师安纳斯塔西奥的女儿。
妈的,全都是老太婆,没有一个能勉强过得去的,都是年过半百的人,像落花一样枯干憔悴。真找不出一个好的来。
“你们来这儿干什么?”
“我们是来看你的。”
“现在你们已见到我了。我很好,用不到为我担忧。”
“你是从很远的地方到这儿来的,来到这个偏僻的地方,没有住址,也没有人认识你。我们费了不少劲,四处打听才找到你的。”
“我并没有躲起来,我在这儿过得很自在,没有人来打搅我。如果可以让我知道的话,你们此行有什么任务?” 我问她们。
“是为的这样一件事…… 不过,你别麻烦给我们弄吃的了,我们在托尔卡西塔家吃过了,她家给我们每个人都吃饱了肚子。因此,请你好好思考思考,就坐在我们面前让我们看看你,听我们说说话。”
我总是难以宁静,我又想上鸡舍去。我听到母鸡在咯咯地叫着,想去捡鸡蛋,免得让兔子给吃掉。
“我捡鸡蛋去。” 我对她们说。
“我们真的吃过了,别为我们费心了。”
“那儿有两只没有圈起来的兔子,它们会把鸡蛋给吃掉的。我一会儿就回来。”
于是,我便上鸡舍那儿去了。
我打算不回来了。我想从朝山那边开的那扇门出去,就将这群老弱病残的女人丢下不理了。
我望了一眼墙脚边的一堆石头,颇像一座坟。于是,我开始把石头一块一块地搬开,东一块西一块地扔得到处都是石头。. 这是一些河里的石头,圆圆的,可以扔得很远。这些死老太婆,害得我干起这样的活儿来。我不知道她们怎么会想起上这儿来的。
我放下活儿又回来了,把鸡蛋送给她们。
“你把兔子全给砸死了?我们看到你在朝它们扔石头。我们将鸡蛋放在这儿,等一会儿吃。你本来用不着费这个心的。”
“鸡蛋搁在你们胸口,会孵出小鸡来的。还是放在外面好。”
“呀,看你这个卢卡斯 · 卢卡特罗,总爱满口雌黄,我们身上也不会这么热呀!”
“关于这点我可一无所知,不过,外面天气确实很热。”
我当时是想撵她们走。我一面岔开她们的话题,一面想着如何将她们赶走,让她们再也不想回来。但是,我一点办法也想不出来。
我明白,从一月份起,也就是在安纳克莱托 · 蒙罗纳斯失踪后不久,她们就在到处找我了。那时节就有人对我说,阿穆拉主教会的那些老太婆在找我。她们是唯一的对安纳克莱托 · 蒙罗纳斯感兴趣的女人。现在,她们果真来到了这里。
我可以与她们进行闲聊,稳住她们,一直到拉开夜幕,这样,她们便只好走了。她们是不会冒险在我家里过夜的。
我所以这样认为,是因为我们在闲聊时谈起过这一点。潘西亚诺的女儿说,她们想快点把事情办好,以便早点回阿穆拉去。这时,我对她们说,她们可不必急着回去,天晚了就睡在我这里,反正有的是席子,让她们睡地铺总是可以的。她们却说,这可不行,要是让他人知晓,她们在我家里过夜,而我也在家里,那会怎么说呢。这可万万使不得。
为此,现在的问题是得想办法延长聊天的时间,一直到天黑,这样便能打消充斥她们头脑中的那个念头。我问她们中间的一人:
“你男人怎么样了?”
“我没有男人,卢卡斯。难道你已忘了我曾经是你的未婚妻吗?我等了又等,等了又等,一直在等待着,后来才知道你已经结婚了。到了那时已经没有男人会娶我了。”
“我当时的情况怎样呢?当时的问题是事情太多,弄得我手忙脚乱。不过,现在还是时候嘛。”
“可是你已经结婚了,卢卡斯,而且是同圣婴的女儿。你干吗还要来和我纠缠呢?我几乎已经将你给遗忘了。”
“我却没有忘掉。你说你那会儿叫什么名字来着?”
“涅埃贝斯…… 眼下我还是叫这个名字。我的全名是涅埃贝斯 · 加西亚。你别让我流泪了,卢卡斯 · 卢卡特罗,一想起你那些甜言蜜语,我就生气。”
“涅埃贝斯呀,涅埃贝斯,我怎么能不记得你呢?你是永远不会使人忘记的…… 我记得当时你是那么温柔,至今我仍感到你在我的怀里,那么柔情脉脉,那么柔软。你出来与我会面时穿的衣服散发着樟脑味。那时你经常与我同居,你挨得我这样紧,以致我都觉得你快进入我的骨髓了。这些我都记得。”
“卢卡斯,你不要再说这些了。昨天我已忏悔过了,而现在你却又在使我产生坏念头,使我犯罪。”
“我记得我吻过你的大腿根,你总是说那儿不能吻,因为你感到痒痒。今天你的大腿根部还有酒窝吗?”
“卢卡斯 · 卢卜特罗,最好你别说下去了,上帝不会原谅你对我干的事情,你会得到报应的。”
“我做了什么坏事了?难道我对你不好?”
“当时我不得不摒弃这样的日子。你别让我在人们面前说这样的事。但是,你得知道,我不得不这样做。我就像丢弃一块咸肉一样摒弃这一切。你父亲只不过是个牧人,我干吗要迷恋这样的日子呢?”
“事情原来是这样?我以前不知道。你们想不想再喝点番石榴汁?我一会儿就去取来,请稍候片刻。”
我再次去鸡舍边砍番石榴树,尽可能在那么多待一会儿,好让那个女人消消气。
我回来时她己离开那里。
“她走了?”
“对,她走了。你刚才弄得她哭了。”
“其实我只是想同她聊聊天,消磨一会儿时间。你们注意到这儿好久没下雨了吗?在阿穆拉大概早下过雨了,是不是?”
“下了,前天下了一阵雷阵雨。”
“毫无疑问,那是个好地方。雨下得适时,日子就过得舒坦。我可以起誓,这里连云朵也见不到。罗甘西亚诺还在当镇长吗?”
“还在当。”
“这个罗甘西亚诺可是个好人。”
“不,他可坏呢。”
“也许你们说得对。埃德米洛的情况怎么样?他的药店还关着吗?”
“他已经去世了。他死得好,虽说这样说是不对的。他也是个坏人。他是那伙诬蔑圣婴安纳克莱托的人中间的一个,他说圣婴是个流氓、巫师和骗子。他到处这样说,但人们都不听他的。上帝惩罚了他,他得狂犬症死了。”
“但愿上帝将他打入地狱。”
“但愿法官里利奥 · 洛佩斯也落得个同样的下场。他站在埃德米洛一边,将圣婴送进了监狱。”
现在是她们在说话了。我让她们随便说,只要不牵涉到我就行。但是,她们突然又问我道:
“你想跟我们一起去吗?”
“去哪里?”
“阿穆拉。我们正为此而来,我们是来带你上那儿去的。”
一时间我又想到鸡舍去,想从对面开着的那扇门出去,溜之大吉。这些倒霉的老太婆!
“叫我去阿穆拉干什么鬼名堂?”
“我们希望你陪我们进行祈祷。我们圣婴安纳克莱托主教会的全体女会员进行了一次九日祷,求上帝谥封安纳克莱托为圣徒。你是他的证人,我们需要你去作他的证人。神父先生嘱托我们,让我们替他找一个与安纳克莱托很亲近的人,此人应该早就认识他了,在他创奇迹扬名四海之前就熟悉他了。这个人非你莫属了,因为你在他身边生活过,而且比谁都能更清楚地说明他作的种种慈善事业。为此,我们需要你,请你在这次活动中协助我们。”
这些混帐老太婆,早该说出这些话来了。
“我不能去,” 我对她们说,“没有人给我看家。”
“我们留下两个姑娘给你看家,这件事我们早就准备好了。另外,这儿还有你妻子嘛。”
“我已没有妻子了。”
“你妻子也过世了?圣婴安纳克莱托的女儿也死了?”
“她离开我走了,我将她赶走了。”
“这么做可不对啊,卢卡斯 · 卢卡特罗。这可怜的女人,她一定很痛苦。她可是个很好的姑娘,又年轻,又漂亮,你将她赶到哪儿去了,卢卡斯?你就是将她送进里面都是从良的烟花女的那一类修道院也可以嘛。”
“我没有将她送到任何地方去。我将她赶出去了。我可以肯定,她是不会和那些从良的妓女在一起的。她最喜欢胡闹腾,喜欢胡来,眼下她一定在那些地方,说不定正在脱裤子呢。”
“你的话我们不信,卢卡斯,一点也不信。眼下她也许就在这里,关在这家里的哪间房子里作祈祷呢。你就是爱说谎,甚至还会造谣。你该记得吧,卢卡斯,埃尔梅林多的那几个可怜的女儿,由于你制造流言蜚语,她们一上街便有人对她们唱《小白鸽之歌》,取笑她们,害得她们只好躲到埃尔格罗约去了。你的话一句也不可信,卢卜斯 · 卢卡特罗。”
“这么说,我去阿穆拉也就是多余的了。”
“你先要进行忏悔,这样一切问题便都解决了。从什么时候起你不再忏悔了?”
“哦,大约有 15 年了吧。就是从基督派打算枪毙我的那个时候开始的。他们把枪顶着我的背部,让我跪在神父面前,就在那里我连没有做过的事情也说了。这就是说,我进行了超前忏悔。”
“要不是这中间存在着你是圣婴的女婿的问题,我们是决不会来找你的,也不会来求你任何事情的。卢卡斯 · 卢卡特罗,你这个人向来很鬼。”
“由于某种原因,我曾经当过安纳克莱托 · 蒙罗纳斯的助手。他才是个真正的魔鬼呢。”
“你不要亵渎神明。”
“那是由于你们不了解他的真面目。”
“我们认为他是个圣徒。”
“但是,你们却不知道他还当过行乞僧(译者注:指那些身背圣像沿街乞讨的教士)”。
“卢卡斯,你在说什么呀?”
“这件事你们不知道。但他以前确实在集市上,在教堂门口卖过圣德像的。我当时替他背着一只包,我们俩一前一后地走着,从一个村庄走到另一个村庄。他走在前面,我替他背着那只包,里面装满了对圣潘达菜翁、圣安布罗西奥和圣帕斯库亚尔进行九日祭的祈祷词,其重量至少有三阿罗瓦(译者注:阿罗瓦约合 25 磅)。
“有一天,我们遇到了几个朝圣者。安纳克莱托跪在蚂蚁窝上,他教我怎样咬着舌头,便不会被蚂蚁咬的方法。这时,过来了几个朝圣者。他们见到他这个样子,出于好奇,停下来观看。他们问。‘你怎么能跪在蚂蚁窝上,蚂蚁不咬你呢?’
“于是,他便伸开双臂,合成十字,说他才从罗马回来,从那儿带来一个福音,还带来一块钉过耶稣的圣十字架上的木片。
“朝圣者们将他抱起来,用担架将他抬到了阿穆拉。到了那里,人们便跪倒在他的面前,求他赏赐奇迹。”
“这还仅是个开端。我见到他这样欺骗着成群结队去看望他的朝圣者,惊讶得瞠目结舌。”
“你真是一派胡言,你把圣徒亵渎得够厉害的了。在认识他之前,你是干什么的?不只是个猪倌么。他使你富有,给了你现在拥有的东西。就为这些,你也应该替他说几句好话。你这个没良心的!”
“就这方面而言,我是该感谢他,是他让我吃饱了肚子。但是,这并不能不说他就是个地地道道的魔鬼。不管他到了什么地方,他仍然是个真正的魔鬼。”
“可他现在在天上,在天使中间,尽管你不愿意,他还是在那里。”
“我一直以为他在监狱里。”
“这是许久以前的事了。他从狱中逃出来后,便销声匿迹。现在他的肉体和灵魂都在天上,从那儿为我们祝福。姑娘们,让我们跪下来,念‘主啊,我们是罪人’,好让圣婴为我们说情。”
老婆子们跪了下来,每念一句天主经,便对绣着安纳克莱托 · 蒙罗纳斯像的披肩吻一次。
时间已是下午 3 时了。
我利用这一空隙走进厨房,吃了几块包着菜豆的油炸玉米饼。我出来的时候,只剩下 5 个女人了。
“别的女人干什么去了?” 我问她们。
潘恰摸了摸上唇上面长的四根髭须,对我说:
“她们走了,她们不想跟你交往了。”
“这样更好,驴少饲料就多嘛。你们还要番石榴汁吗?”
她们中间有一个人一直没有开口说话,她名叫菲洛梅娜,外号叫 “死人”。这时她朝我其中的一只花盆弯下身子,一只手指伸进嘴里,将她刚才咽下的番石榴汁连同嚼碎吞下的炸肉皮和其他食物都一古脑儿吐了出来。
“你这个亵渎神灵的人,我连你的番石榴水也不要。你的东西我都不要。”
她将我馈赠给她的鸡蛋放在椅子上,说:
“你的鸡蛋我也不要。我这就走。”
现在只剩下 4 个女人了。
“我也想吐,” 潘恰对我说,“但我忍住了。无论怎样,我们要将你带到阿穆拉去。你是唯一的能证明圣婴是神圣的人。他会使你的心肠软下来。我们已将他的圣像安置在教堂里了,由于你的问题而将他赶出教堂是不公平的。”
“你们去找别的人吧,我不想在这次葬礼中为他守灵。”
“你几乎是他的儿子,你继承了他神圣的果实,他眼睁睁地指望着你替他传种接代,他把女儿嫁给了你。”
“不错。但是,他嫁给我的是已经传上了种的女儿。”
“上帝保佑,你胡说些什么,卢卡斯 · 卢卡特罗!”
“情况确是这样,他把女儿许配我的时候,她少说也有四个月的身孕了。”
“可是,她全身散发着仙气。”
“她全身臭气冲天。她一个劲儿地让所有站在她面前的人看她的肚子,目的只是让他们看到她的肚子是肉做的。她将她日益变大的肚子指给人们看,这肚子由于里面怀着孩子而肿胀得呈青紫色了。人们都笑起来,觉得实在好笑。她是个不要脸的骚货。这就是安纳克莱托 · 蒙罗纳斯的女儿的情况。”
“你是个不信神的人,你不配谈论这方面的事情。我们要送你一件披肩,让你用来驱赶魔鬼。”
“…… 她正是跟随着其中的一个魔鬼走了。听说这魔鬼爱她。他只对她说:‘我愿冒险作你孩子的父亲。’于是,她便随他走了。”
“那是圣婴传的种。是个女孩。你白白地得到了她,你成了神灵赐与的这份财富的得主。”
“一笔糊涂账!”
“你说什么?”
“在安纳克莱托 · 蒙罗纳斯女儿的肚子里,怀着他的孙子。”
“你这是为了往她身上泼污水才制造出这一套来的。你向来爱制造谎言。”
“是这样的吗?你们其他几位对我有什么看法?他总是请求每天晚上有一个女孩子陪他度过不眠之夜。这样一来,世界上这个地区的姑娘都失去了童贞。”
“他这样做是为了使她们保持纯洁无瑕,使她们不被罪孽玷污。他想处身于童贞之中,使自己的灵魂免遭污染。”
“由于他没有叫到你们,你们才相信这种说法。”
“他是叫过我的,” 一个名叫梅尔基亚德斯的女人说。“我曾陪他度过不眠之夜。”
“发生什么事了?”
“什么事也没有发生。只是在我感到寒冷的时候,他那双创造奇迹的手搂住了我,给我御寒。对他的身体给我的温暖我表示了谢意。仅此而已。”
“那是因为你老了,他喜欢年轻女人。他压得她们骨头咯吱咯吱地响,就像剥花生壳一样。”
“你是个该诅咒的无神论者,卢卡斯 · 卢卡特罗,是最坏的无神论者之一。”
现在讲话的是个绰号叫 “孤女” 的女人,总是哭丧着脸。她是这些老婆子中年纪最大的一个。她眼中含泪,双手颤抖不停。
“我是个孤儿,是他减轻了我孤苦伶仃的痛苦,在他身上我又见到了我的父亲和母亲。那天晚上他整夜在抚摸我,以减轻我的痛苦。”
她的眼泪滚滚而下。
“你用不着哭嘛。” 我对她说。
“我哭的原因是我的父母已经去世,抛下我一个人孤孤单单的,像我这般年龄失去双亲是很难找到依托的。在圣婴安纳克莱托那亲切的怀抱中度过的夜晚是我唯一幸福的夜晚。而这时你却在诽谤他。”
“他是个圣徒。”
“是个仁慈的人。”
“我们希望你继续他的事业。你已经继承了他的一切。”
“我继承了他一大堆最恶劣的习惯,还得到了一个疯婆子。虽说还没有你们这么老,她却是非常的疯。她走了是好的,是我亲自给她开的门。”
“你这个异教徒,说的全是异端邪说。”
这时,只剩下两个老婆子了,其他的都一个一个地走了。她们一面后退,一面对我划着十字,还保证说下次回来要佩戴着镇邪符来。
“你不能对我否认圣婴安纳克莱托是创了奇迹的,” 安纳斯塔西奥的女儿说,“这一点你是否定不了的。”
生孩子可不是什么奇迹,可这是他最拿手的。
“他给我丈夫治好了花柳病。”
“我不知道你有丈夫。你不是理发师安纳斯塔西奥的女儿吗?据我所知,塔乔(译者注:这是安纳斯塔西典的小名)的女儿是个单身。”
“我是单身,但我有丈夫。你知道,姑娘是一回事,单身又是一回事。我不是姑娘,却是单身。”
“你这样的年纪还干这个,米卡埃拉。”
“我只能这样做。做姑娘,我又靠什么来谋生呢?我是个女人,女人生来就要拿出上帝赐与她的东西。”
“你说的和安纳克莱托 · 蒙罗纳斯说的完全一样。”
“是的,是他规劝我这样干的,这样,可以治好肝炎。我就和某个男人一块儿过日子。年届五十,还是个处女,也是个罪孽。”
“这是安纳克莱托 · 蒙罗纳斯对你说的啰。”
“是的,是他对我说的。但是,我们这次来另有目的,就是让你跟我们去,证明他是个圣徒。”
“为什么我不是圣人呢?”
“你没有创造什么奇迹嘛。他可治好了我丈夫的病,我很清楚这一点。难道你也替人治好过花柳病吗?”
“没有,我连这病是怎么一回事也不清楚。”
“这病有点像毒疮。他当时全身青紫,浑身上下都是烂疮,难以入眠。他说,他见到的东西都呈红色,好像探身于地狱的门口。后来,他又感到全身火辣辣的,疼得他在地上打滚。于是,我们就找圣婴安纳克莱托看病去了,他治好了我丈夫的病。他用一根燃着的香蒲烧灸他,还用唾沫涂在他的疮面上。然后,他说:去掉你的毒疮。我丈夫的病就全好了。请你告诉我,这是不是奇迹。”
“你丈夫得的一定是麻疹。我小时人们也用唾液治好了我的麻疹。”
“我还是刚才说过的那句话,你是个该死的无神论者。”
“使我感到慰藉的是安纳克莱托 · 蒙罗纳斯比我还坏。”
“他把你当儿子看待,而你竟敢…… 我不想再听你说下去了。我走了,潘恰,你还待在这里么?”
“我再待一会儿,我想一个人作一次最后的努力。”
“听着,弗朗西斯卡,现在她们都走了,你想留下来跟我睡觉,是不是?”
“就是上帝命我这样干我也不干。人们会怎样想呢?我留下来的目的是想说服你。”
“那我俩就互相说服吧。跟我睡觉到头来你会失去什么呢?你已老了,谁也不会想到你了,也不会来帮你什么忙了。”
“但是,人言可畏啊,人们会对我们往坏处想的。”
“人们爱怎么样想就让他们怎么样想吧,他们又能怎么样呢?不管怎么样,你潘恰还是叫潘恰。”
“好吧,我就留下来跟你睡,但只能睡到明天天亮,而且,你得向我保证,我们将一起去阿穆拉。这样,我便可以对她们说,我整个夜晚都在请求他来阿穆拉。我如果不留下来,又怎能请求他来呢。”
“好的,不过,你得先将上唇上的那几根髭须给剪掉。我去拿剪刀。”
“卢卡斯 · 卢卡特罗,你干吗要这样戏弄我。你这辈子一直在注意我的短处。请你不要触动我这几根胡须,这样,她们便不会产生疑心了。”
“好吧,就照你的意思办。”
天黑下来后,她帮我修理了一下鸡舍的顶棚,还将我乱扔在鸡舍里的那些石块放到原来的角落里。
她丝毫也没有猜想到安纳克莱托 · 蒙罗纳斯就埋在那里,也不知道他逃出监狱的当天便死了。那天他逃出来后,便来到这里,要求归还他的产业。
他一来便说:
“你把东西全都卖了吧,把钱交给我,因为我要上北方去。到那儿我再给你写信,我俩将再次在一起做生意。”
“你为什么不把你女儿带走?” 我问他。“这是我拥有的东西中唯一多余的东西,而且你还说是你的。你竟然对我也耍起花招来了。”
“等我派人告诉你们我的地址后,你们再去吧。帐我们到那里后再结吧。”
“还是现在一次算清好。这样,我们之间就清楚了。”
“眼下我没有心思干这方面的事情,” 他对我说。“你把我的东西全给我吧。你存有多少钱?”
“钱是有点儿,但我现在不交给你。跟你那不要脸的女儿在一起,日子过得像该隐(译者注:据说是亚当与夏娃的长子,因妒忌杀死弟弟,受上帝的诅咒)一样。我养着你这样的女儿,你应该认为我已报答你了。”
他火气上来了,双脚蹬着地,但又急着要走……
“安纳克莱托 · 蒙罗纳斯,安息吧!” 我在安葬他的时候这样对他说。每次从河边搬来石头压在他坟上的时候,我总是这样说:“纵然用尽你的全部计谋,你也无法离开这里。”
现在,潘恰帮助我在坟头上再次添加石头,她并不怀疑在这堆石头的下面埋着阿纳克莱托,也不怀疑我这样做正是怕他从坟墓里出来,再来同我吵架。他这个人一向诡计多端,他一定相信他有办法让自己死而复生,离开那里的。
“再往上面丢几块石头,潘恰。就将它们放在这个角落里,我不喜欢看到我的鸡舍到处都是石头。”
后来,时间已到清晨,她对我说:
“你是个笨蛋,卢卡斯 · 卢卡特罗。你丝毫也没有激情。你知道谁对女人情炽似火?”
“谁?”
“圣婴安纳克莱托,他才真正精于此道。”
```
安妥我灵魂的这本书-贾平凹
========================
安妥我灵魂的这本书-[[贾平凹]]
-------
一晃荡,我在城里已经住罢了二十年,但还未写出过一部关于城的小说。越是有一种内疚,越是不敢贸然下笔,甚至连商州的小说也懒得作了。依我在四十岁的觉悟,如果文章是千古的事——文章并不是谁要怎么写就可以怎么写的——它是一段故事,属天地早有了的,只是有没有宿命可得到。姑且不以国外的事作例子,中国的《西厢记》、《红楼梦》,读它的时候,哪里会觉它是作家的杜撰呢?恍惚如所经历,如在梦境。好的文章,囫囵囵是一脉山,山不需要雕琢,也不需要机巧地在这儿让长一株白桦,那儿又该栽一棵兰草的。这种觉悟使我陷于了尴尬,我看不起了我以前的作品,也失却了对世上很多作品的敬畏,虽然清清楚楚这样的文章究竟还是人用笔写出来的,但为什么天下有了这样的文章而我却不能呢?!检讨起来,往日企羡的什么词章灿烂,情趣盎然,风格独特,其实正是阻碍着天才的发展。鬼魅狰狞,上帝无言。奇才是冬雪夏雷,大才是四季转换。我已是四十岁的人,到了一日不刮脸就面目全非的年纪,不能说头脑不成熟,笔下不流畅,即使一块石头,石头也要生出一层苦衣的,而舍去了一般人能享受的升官发财、吃喝嫖赌,那么搔秃了头发,淘虚了身子,仍没美文出来,是我真个没有宿命吗?
我为我深感悲哀。这悲哀又无人与我论说。所以,出门在外,总有人知道了我是某某后要说许多恭维话,我脸烧如炭;当去书店,一发现那儿有我的书,就赶忙走开。我愈是这样,别人还以为我在谦逊。我谦逊什么呢?我实实在在地觉得我是浪了个虚名,而这虚名又使我苦楚难言。
有这种思想,作为现实生活中的一个人来说,我知道是不祥的兆头。事实也真如此。这些年里,灾难接踵而来,先是我患乙肝不愈,度过了变相牢狱的一年多医院生活,注射的针眼集中起来,又可以说经受了万箭穿身;吃过大包小包的中药草,这些草足能喂大一头牛的。再是母亲染病动手术;再是父亲得癌症又亡故;再是一场官司没完没了地纠缠我;再是为了他人而卷入单位的是是非非中受尽屈辱,直至又陷入到另一种更可怕的困境里,流言蜚语铺天盖地而来……。我没有儿子,父亲死后,我曾说过我前无古人后无来者了。现在,该走的未走,不该走的都走了,几十年奋斗的营造的一切稀里哗啦都打碎了,只剩下了肉体上精神上都有着毒病的我和我的三个字的姓名,而名字又常常被别人叫着写着用着骂着。
这个时候开始写这本书了。
要在这本书里写这个城了,这个城里却已没有了供我写这本书的一张桌子。
在一九九二年最热的天气里,托朋友安黎的关系,我逃离到了耀县。耀县是药王孙思邈的故乡,我兴奋的是在药王山上的药王洞里看到一个"坐虎针龙"的彩塑,彩塑的原意是讲药王当年曾经骑着虎为一条病龙治好了病的。我便认为我的病要好了,因为我是属龙相。后来我同另一位搞戏剧的老景被安排到一座水库管理站住,这是很吉祥的一个地方。不要说我是水命,水又历来与文学有关,且那条沟叫锦阳川就很灿烂辉煌;水库地名又是叫桃曲坡,曲有文的含义,我写的又多是女人之事,这桃便更好了。在那里,远离村庄,少鸡没狗,绿树成荫,繁花遍地,十数名管理人员待我又敬而远之,实在是难得的清静处。整整一个月里,没有广播可听,没有报纸可看,没有麻将,没有扑克。每日早晨起来去树林里掏一股黄亮亮的小便了,透着树干看远处的库面上晨雾蒸腾,直到波光粼粼了一片银的铜的,然后回来洗漱,去伙房里提开水,敲着碗筷去吃饭。夏天的苍蝇极多。饭一盛在碗里,苍蝇也站在了碗沿上,后来听说这是一种饭苍蝇,从此也不在乎了。吃过第一顿饭,我们就各在各的房间里写作,规定了谁也不能打扰谁的,于是一直到下午四点,除了大小便,再不出门。我写起来喜欢关门关窗,窗帘也要拉得严严实实,如果是一个地下的洞穴那就更好。烟是一根接一根地抽,每当老景在外边喊吃饭了,推开门直感烟雾笼罩了你了!再吃过了第二顿饭,这一天里是该轻松轻松了,就趿个拖鞋去库区里游泳。六点钟的太阳还毒着,远近并没有人,虽然勇敢着脱光了衣服,却只会狗刨式,只能在浅水里手脚乱打,打得腥臭的淤泥上来。岸上的蒿草丛里嘎嘎地有嘲笑声,原来早有人在那里窥视。他们说,水库十多年来,每年要淹死三个人的,今年只死过一个,还有两个指标的。我们就毛骨悚然,忙爬出水来穿了裤头就走。再不敢去耍水,饭后的时光就拿了长长的竹竿去打崖畔儿上的酸枣。当第一颗酸枣红起来,我们就把它打下来了,红红的酸枣是我们惟一能吃到的水果。后来很奢侈,竟能贮存很多,专等待山梁背后的一个女孩子来了吃。这女孩子是安黎的同学,人漂亮,性格也开朗,她受安黎之托常来看望我们,送笔呀纸呀药片呀,有时会带来几片烙饼。夜里,这里的夜特别黑,真正的伸手不见五指,我们就互相念着写过的章节,念着念着,我们常害肚子饥,但并没有什么可吃的。我们曾经设计过去偷附近村庄农民的南瓜和土豆,终是害怕了那里的狗,未能实施。管理站前的丁字路口边是有一棵核桃树的,树之顶尖上有一颗青皮核桃,我去告诉了老景,老景说他早已发现。黄昏的时候我们去那里抛着石头掷打,但总是目标不中,歇歇气,搜集了好大一堆石块瓦片,掷完了还是打不下来,倒累得脖子疼胳膊疼,只好一边回头看着一边走开。这个晚上,已经是十一点了,老景馋得不行,说知了的幼虫是可以油炸了吃的,并厚了脸借来了电炉子、小锅、油、盐,似乎手到擒来,一顿美味就要到口了。他领着我去树林子;用手电在这棵树上照照,又到那棵树上照照,树干上是有着蝉的壳,却没有发现一只幼虫。这样为着觅食而去,觅食的过程却获得了另一番快感。往后的每个晚上这成了我们的一项工作。不知为什么,幼虫还是一只未能捉到,提到的倒是许多萤火虫,这里的萤火虫到处在飞,星星点点又非常的亮,我们从林子中的小路上走过,常恍惚是身在了银河的。
老景长得白净,我戏谑他是唐僧,果然有一夜一只蝎子就钻进他的被窝咬了他,这使我们都提心吊胆起来,睡觉前翻来覆去地检查屋之四壁,抖动被褥。蝎子是再也没有出现的,而草蚊飞蛾每晚在我们的窗外聚会,黑乎乎地一疙瘩一疙瘩的,用灭害灵去喷,尸体一扫一簸箕的。我们便认为这是不吉利的事。我开始打磨我在香山捡到的一块石头,这石头很奇特,上边天然形成一个"大"字,间架结构又颇似柳体。我把"大"字石头雕刻了一个人头模样系在脖子上,当作我的护身符。这护身符一直系着,直到我写完了这部书。老景却在树林子里捡到了一条七寸蛇的干尸,那干尸弯曲得特别好,他挂在白墙上,样子极像一个凝视的美妙的少女。我每天去他房间看一次蛇美人,想入非非。但他要送我,我不敢要。
在耀县锦阳川桃曲坡水库——我永远不会忘记这个地名的——呆过了整整一个月,人明显是瘦多了,却完成了三十万字的草稿。那间房子的门口,初来时是开绽了一朵灼灼的大理花的,现在它已经枯萎。我摘下一片花瓣夹在书稿里下山。一到耀县,我坐在一家咸汤面馆门口,长出了一口气,说:"让我好好吃顿面条吧!"吃了两海碗,口里还想要,肚子已经不行了,坐在那里立不起来。
回到西安,我是奉命参加这个城市的古文化艺术节书市活动的。书市上设有我的专门书柜,疯狂的读者抱着一摞一摞的书让我签名,秩序大乱,人潮翻涌,我被围在那里几乎要被挤得粉碎。几个小时后幸得十名警察用警棍组成一个圆圈,护送了我钻进大门外的一辆车中急速遁去。那样子回想起来极其可笑。事后我的一个朋友告诉说,他骑车从书市大门口经过时,正瞧着我被警察拥着下来,吓了一跳,还以为我犯了什么罪。我那时确实有犯罪的心理,虽然我不能对着读者说我太对不起你们了,但我的脸上没有一丝笑容。离开了被人拥簇的热闹之地,一个人回来,却寡寡地窝在沙发上吸烟落泪。人人都有一本难念的经,我的经比别人更难念。对谁去说?谁又能理解?这本书并没有写完,但我再没有了耀县的清静,我便第一次出去约人打麻将,第一次夜不归宿,那一夜我输了个精光。但写起这本书来我可以忘记打麻将,而打起麻将了又可以忘记这本书的写作。我这么神不守舍地握着日子,白天害怕天黑。天黑了又害怕天亮。我感觉有鬼在暗中逼我,我要彻底毁掉我自己了,但我不知道我该怎么办。这时候,我收到一位朋友的信,他在信中骂我迷醉于声名之中,为什么不加紧把这本书写完?!我并没有迷醉于声名之中,正是我知道成名不等于成功,才痛苦得不被人理解,不理解又要以自己的想法去做,才一步步陷入了众要叛亲要离的境地!但我是多么感激这位朋友的责骂,他的骂使我下狠心摆脱一切干扰,再一次逃离这个城市去完成和改抄这本书的全稿了。我虽然还不敢保险这本书到底会写成什么模样,但我起码得完成它!
于是我带着未完稿又开始了时间更长更久的流亡写作。
我先是投奔了户县李连成的家。李氏夫妇是我的乡党,待人热情,又能做一手我喜爱吃的家乡饭菜。一九八六年我改抄长篇小说《浮躁》就在他家。去后,我被安排在计生委楼上的一间空屋里。计生委的领导极其关照,拿出了他们崭新的被褥,又买了电炉子专供我取暖,我对他们的接纳十分感激,说我实在没法回报他们,如果我是一个妇女,我宁愿让他们在我肚子上开一刀,完成一个计划生育的指标。一天两顿饭,除了按时去连成家吃饭,我就呆在房子里改写这本书,整层楼上再没有住人,老鼠在过道里爬过,我也能听得它的声音。窗外临着街道,因不是繁华地段,又是寒冷的冬天,并没有喧嚣。只是太阳出来的中午,有一个黑脸的老头总在窗外楼下的固定的树下卖鼠药,老头从不吆喝,却有节奏地一直敲一种竹板。那梆梆的声音先是心烦,由心烦而去欣赏,倒觉得这竹板响如寺院禅房的木鱼声,竟使我愈发心神安静了。先头的日子里,电炉子常要烧断,一天要修理六至八次;我不会修,就得喊连成来。那一日连成去乡下出了公差,电炉子又坏了,外边又刮风下雪,窗子的一块玻璃又撞碎在楼下,我冻得握不住笔,起身拿报纸去夹在窗纱扇里挡风;刚夹好,风又把它张开;再去夹,再张开,只好拉闭了门往连成家去。袖手缩脖下得楼来,回头看三楼那个还飘动着破报纸的窗户,心里突然体会到了杜甫的《茅屋为秋风所破歌》的境界。
住过了二十余天,大荔县的一位朋友来看我,硬要我到他家去住,说他新置了一院新宅,有好几间空余的房子。于是连成亲自开车送我去了渭北的一个叫邓庄的村庄,我又在那里住过了二十天。这位朋友姓马,也是一位作家,我所住的是他家二楼上的一间小房。白日里,他在楼下看书写文章,或者逗弄他一岁的孩子;我在楼上关门写作,我们谁也不理谁。只有到了晚上,两人在一处走六盘象棋。我们的棋艺都很臭,但我们下得认真,从来没有悔过子儿。渭北的天气比户县还要冷,他家的楼房又在村头,后墙之外就是一眼望不到边的大平原,房子里虽然有煤火炉,我依然得借穿了他的一件羊皮背心,又买了一条棉裤,穿得臃臃肿肿。我个子原本不高,几乎成了一个圆球,每次下那陡陡的楼梯就想到如果一脚不慎滚下去,一定会骨碌碌直滚到院门口去的。邓庄距县城五里多路,老马每日骑车进城去采买肉呀菜呀粉条呀什么的。他不在,他的媳妇抱了孩子也在村中串门去了。我的小房里烟气太大,打开门敞着,我就站立在楼栏杆处看着这个村子。正是天近黄昏,田野里浓雾又开始弥漫,村巷里有许多狗咬,邻家的鸡就扑扑棱棱往树上爬,这些鸡夜里要栖在树上,但竟要栖在四五丈高的杨树梢上,使我感到十分惊奇。
二十天里,我烧掉了他家好大一堆煤块,每顿的饭里都有豆腐,以致卖豆腐的小贩每日数次在大门外吆喝。他家的孩子刚刚走步,正是一刻也不安静地动手动脚,这孩子就与我熟了,常常偷偷从水泥楼梯台爬上来,冲着我不会说话地微笑。老马的媳妇笑着说:"这孩子喜欢你,怕将来也要学文学的。"我说,孩子长大干什么都可以,千万别让弄文学。这话或许不应该对老马的媳妇说,因为老马就是弄文学的,但我那时说这样的话是一片真诚。渭北农村的供电并不正常,动不动就停电了,没有电的晚上是可怕的,我静静地长坐在藤椅上不起,大睁着夜一样黑的眼睛。这个夜晚自然是失眠了,天亮时方睡着。已经是十一点了,迷迷糊糊睁开眼,第一个感觉里竟不知自己是在哪儿。听得楼下的老马媳妇对老马说:"怎不听见他叔的咳嗽声,你去敲敲门,不敢中了煤气了!"我赶忙穿衣起来,走下楼去,说我是不会死的,上帝也不会让我无知无觉地自在死去的,却问:"我咳嗽得厉害吗?"老马的媳妇说:"是厉害,难道你不觉得?!"我对我的咳嗽确实没有经意,也是从那次以后留心起来,才知道我不停地咳嗽着。这恐怕是我抽烟太多的缘故。我曾经想,如果把这本书从构思到最后完稿的多半年时间里所抽的烟支接连起来,绝对地有一条长长的铁路那么长。
当我所带的稿纸用完了最后的一张,我又返回到了户县,住在了先前住过的房间里。这时已经月满,年也将尽,"五豆"、"腊八"、廿三,县城里的人多起来,忙忙碌碌筹办年货。我也抓紧着我的工作,每日无论如何不能少于七千字的速度。李氏夫妇瞧我脸面发胀,食欲不振,想方设法地变换饭菜的花样,但我还是病了,而且严重的失眠。我知道一走近书桌,书里的庄之蝶、唐宛儿、柳月在纠缠我;一离开书桌躺在床上,又是现实生活中纷乱的人事在困扰我。为了摆脱现实生活中人事的困扰,我只有面对了庄之蝶和庄之蝶的女人,我也就常常处于一种现实与幻想混在一起无法分清的境界里。这本书的写作,实在是上帝给我大大的安慰和太大的惩罚,明明是一朵光亮美艳的火焰,给了我这只黑暗中的飞蛾兴奋和追求,但诱我近去了却把我烧毁。
腊月廿九的晚上,我终于写完了全书的最后一个字。
对我来说,多事的一九九二年终于让我写完了,我不知道新的一年我将会如何地生活,我也不知道这部苦难之作命运又是怎样。从大年的三十到正月的十五,我每日回坐在书桌前目注着那四十万字的书稿,我不愿动手翻开一页。这一部比我以前的作品更优秀呢,还是情况更糟?是完成了一桩宿命呢,还是上苍的一场戏弄?一切都是茫然,茫然如我不知我生前为何物所变、死后又变何物。我便在未作全书最后的一次润色工作前写下这篇短文,目的是让我记住这本书带给我的无法向人说清的苦难,记住在生命的苦难中又惟一能安定我破碎了的灵魂的这本书。
1993年1月下旬
! As an image for your device:
* Raspberry Pi 3 Model B and B+ 32-bit (32-bit is required for GPIO support)
* Raspberry Pi 3 Model B and B+ 64-bit
* Raspberry Pi 4 Model B (1 GB, 2 GB and 4 GB model) 32-bit (32-bit is required for GPIO support)
* Raspberry Pi 4 Model B (1 GB, 2 GB, 4 GB and 8 GB model) 64-bit (64-bit is required for 8 GB model)
* Tinkerboard
* [[Odroid-C2]], [[Odroid-C4]], [[Odroid-N2]], [[Odroid-XU4]]
* Guide: Flashing Odroid-N2 using OTG-USB
* Intel NUC
奥兰治大街溜冰场的月亮-艾丽丝·门罗
========================
# 奥兰治大街溜冰场的月亮-[[艾丽丝·门罗]]
-----
山姆走进卡丽的杂货点心铺,大吃一惊。他本以为会撞上一堆乱七八糟的杂货、廉价针头线脑、一股子陈腐味儿,没准还有褪色的毛条彩带,无人问津的旧圣诞节装饰品什么的。结果正相反,他看到的是一个几乎被电子游戏全面占据的地方。红蓝色蜡笔手写的告示牌上警告不许在此饮酒、打架、闲逛、说粗话。店里满是尖声怪叫的电声噪音,光线闪烁,挤满现如今那些令人生畏、发型古怪、涂脂抹粉的孩子们。不过,柜台后坐着的正是卡丽本人,她也画着浓妆,戴顶粉金色假发。她在读一本平装书。
为了试试她,山姆表示想买香烟。她放下书,他瞥了眼书名:《我的爱情里强风肆虐》,维罗妮卡·格雷著。她给他找了钱,拽拽肩头的毛衣,又拿起书,自始至终都没看他一眼。她的毛衣上满是粉色和白色羊毛线编成的小球,晃悠悠的,挺像爆米花。最后一刻她才开了口。
“你老来反而抽起烟了,山姆?”
“还以为你没认出我呢。”
“烧成灰我也能认出来。”卡丽得意地说,“打你一进门,我就认出来了。”
山姆今年六十九岁,是个鳏夫。他去宾夕法尼亚州看出嫁的女儿,路上抽几天空,在公路边的三只小猪汽车旅馆小住。尽管过去常跟太太说起加拉格尔,但他从不肯带她来。相反,他们去了夏威夷,去了欧洲,连日本都去了。
现在他可以去加拉格尔散散步了。他通常是唯一一个步行者。交通很繁忙,也不像过去那样选择多样。制造业已经让步给服务业。山姆觉得环境有点脏乱。不过或许是因为他如今住在维多利亚的缘故—在橡树湾,一个昂贵而美丽的街区,住的都是像他一样的退休的有钱人。
从前,科纳汉寄宿屋是挨着镇子边缘的最后一幢房子—最后一幢建筑物。它仍在原地,坐落在人行道边。不过镇子各处的边缘已经延伸开去。一个加油站,一家有巨大停车场的加拿大轮胎商店,一些低矮的新房子。科纳汉的房子刷上一种淡淡的冰蓝色,却依旧一派凋零模样。房前的走廊—从前,寄宿者每人都有一张自己的专座—不见了,现在山姆眼前是一个玻璃走廊,被一片片绝缘材料、一张竖起来的床垫、几副帘子和几扇厚重的旧防风窗填得满满当当。从前这房子是浅褐色的,镶棕色边儿。所有东西都干净得吓人。尘土是个难题,道路挨得那么近,那时又没铺路面。老有马匹路过,以及步行者,还有汽车和农用卡车。“你只能跟在后头打扫。”科纳汉小姐声调阴沉地说着那些尘土。事实上,跟在后头打扫的是卡丽。卡丽·科纳汉,山姆和埃德加·格拉吉亚初次邂逅她时,她十九岁,不过大有可能被看成十二岁。一个魔鬼一样工作的人。有人管她叫包身工,科纳汉小姐的包身工,或者也会管叫她女奴—女奴科纳汉。他们错在以为她是被迫的。
有时,扛着奶油和鸡蛋的女人从乡下过来,会在前门台阶上歇歇脚。或者某个女孩子会坐在那里,脱掉胶鞋,换上镇上穿的鞋子—把胶鞋藏在沟里,回家时再换上。这时科纳汉小姐就会在餐厅窗户后头的黑暗中吼道:“这可不是公园长凳!”科纳汉小姐是个高大、阔肩、丑陋的女人,身材前平后扁,头发用指甲花染红,脸在厚粉之下若隐若现,还有一张涂了厚厚唇膏的嘴,嘴角闷闷不乐地下垂着。关于她的淫荡故事四下流传,远比关于她惊人的贪婪和吝啬的轶事更扑朔迷离。比如有人透露,身为弃婴的卡丽其实是科纳汉小姐的亲生女儿。不过,寄宿者们不得不乖乖遵守规定。不许喝酒、禁止抽烟、禁说粗话、不得无礼—格拉吉亚家的男孩们刚来的第一天,她就对他们三令五申。后来她又提醒道,不得在卧室吃喝。那是在感恩节之后,他们从家里带来一大盒油乎乎的饼子。“会招老鼠。”她说。
科纳汉小姐不断指出,她以前从来不招男孩子。听那口气像是给了他们什么恩惠似的。她还有另外四个寄宿客人。一个是寡妇克鲁兹夫人,年纪老迈,不过仍能自理生活。一个是职业女性维尔纳小姐,手套厂的簿记员。一个是单身汉亚当·德拉亨,在银行工作,兼在主日学校教课。还有一个是爱丽丝·皮尔,时髦、傲慢的年轻女郎,跟个警察订了婚,本人是电话接线员。这四个人占据着楼上的卧室。科纳汉小姐睡餐厅沙发,卡丽睡厨房的沙发。山姆和埃德加分到阁楼。里面摆了两张窄窄的铁床,由一个五斗橱和一条编织地毯隔开。
四下打量一番后,山姆推搡着埃德加下楼,问有没有地方给他们挂衣服。“我想你们这样的男孩子不会有多少衣服。”科纳汉小姐说,“我以前从来不招男孩子。你们干吗不能像德拉亨先生那样?他每晚把裤子压在床垫下面,那会让裤缝笔挺的。”
埃德加以为没戏了,但是很快卡丽带着一根扫帚柄和一捆铁丝上来了。她站在柜子上,竭力弄出一根有一环环铁丝绕在上面的晾衣杆儿。
“我们可以自己做那个。”山姆说。他们好奇但并不怎么愉快地研究着她松松垮垮的灰内衣。她没接腔。她甚至带来几个衣架。不知怎的,他们一看便知全是她自己的主意。
“谢谢你,卡丽。”埃德加说。他是一个瘦高个儿男孩,长了一头金色卷毛,对着她发出那种怯生生、温和的微笑。那微笑刚才在楼下一无所获。
卡丽像在杂货店要人家给她上好的土豆一样,粗声大气道:“你们用这个成不?”
山姆和埃德加是表兄弟—虽然一般人都以为他们是亲兄弟。他俩同年—十七岁—为了上商学院,到加拉格尔寄宿。他俩在距此地大约十英里的地方长大,上了同一所乡下学校,又上了同样的乡村成人补习学校。在商学院待上一年,他们就可以找份银行或办事处的工作,或者去会计行做学徒。他们不会再回农场。
可他们真想做的,也是自打大概十岁起就一直渴望的,是成为杂技演员。他们练习了好多年,在成人补习学校还做过表演。那所学校没有体操馆,不过地下室里有几副双杠、一个平衡木和一些垫子。在家时,他们到谷仓练习,天气好的话就在草地上练。杂技演员如何谋生呢?山姆是第一个想到这个问题的人。他没法想象他和埃德加加入马戏团。首先,他俩不够黑。(他一直觉得马戏团里都是吉卜赛人。)他思忖道,想必有自立门户、到处表演的杂技演员吧,在集市上、在教堂大厅表演绝活。他记得小时候看到过一些这样的人。他们从哪来?怎么挣钱?怎样才能加入他们?这类问题越来越多地困扰着山姆,埃德加却从不操心。
初秋时节,晚饭之后,趁着还有点光线,他们在科纳汉寄宿屋街对面的空地上练习,那里地面很平坦。他们穿着汗衫和羊毛裤,先做侧手翻、双手倒立和头着地倒立、翻筋斗和双重筋斗来热身,随后便扭作一团。他们把身体扭成各种符号—各种象形文字—令人称奇地合为一体,看不出头和肩膀的存在。当然了,有时这些创造物会垮塌,一切突然分崩离析,胳膊和腿松开了,变回两个扭得弯弯的身体—只是两个男孩的身体而已,一个高而瘦,另一个略矮壮。然后他们再次开始,飞速地构造成形。身体摇晃着,力图维持住平衡。他们或许会倒下,或许会撑住。一切取决于他们能否使自己柔软得像纯粹的线条,衔接得天衣无缝,达到魔术般的平衡。成了。不成。成了。再来。
观众就是坐在走廊上的寄宿者们。爱丽丝·皮尔对他们不感兴趣。她要么和未婚夫约会,要么就待在房间里,保养衣服或身体—涂指甲、洗毛衣洗丝袜、擦鞋。亚当·德拉亨也是个大忙人—要去参加戒酒会和基甸会[1]的聚会,还要监督他的主日学校班的社会活动。不过他会坐一会儿,和克鲁兹夫人、维尔纳小姐、科纳汉小姐一道观赏。克鲁兹夫人视力仍旧不错,爱看这表演。她用拐杖捣着走廊地板,嚷嚷道:“抓住他,孩子!抓住!”好像这杂技表演是摔跤比赛似的。
德拉亨先生给山姆和埃德加介绍了他的主日学校班,叫作“三个V”,代表的是贞洁、勇气和胜利[2]。他说,要是他们加入,就可以使用联合教会的体操馆。不过男孩子们在家是克德沃特浸信会教徒,没法答应。
如果说卡丽也在看的话,那准是在窗子后面。她总有活儿要忙。
科纳汉小姐评价道,那么多锻炼,会弄得两个男孩子胃口惊人。
每当山姆想起和埃德加在空地上—如今它被纳入加拿大轮胎商店的停车场—的练习,总感觉自己也坐在走廊上,看着那两个男孩在草地上用力、摔倒、跃起—一个飞身一跃,双手支撑平衡,成功地立在另一个的肩头—然后快活地翻着筋斗跳下来。这些回忆总被一种潮乎乎的棕色阴影所覆盖。或许是科纳汉寄宿屋里墙纸的颜色。那会儿,路边种的都是榆树,秋天树叶都变成一种带棕斑的金色。树叶形似烛火。在他心中,这些树叶是在一个无风的傍晚飘落的,彼时天空清澈,夕阳却为云层所遮挡,乡间薄雾朦胧。小镇为树叶和燃烧树叶的烟雾所笼罩,带着它的教堂尖塔和工厂汽笛、富人宅邸和联排房子、网络系统、流行口号、利益集团,显得神秘莫测、难以捉摸,仿佛一个自成一体的世界。他收到过警告。人家提醒过他镇上的人都自以为是。其实远不止这样。
锻炼确实令格拉吉亚家的男孩们食欲大增,不过即使不是这样,他们的胃口也已经够惊人的了。他们习惯了农家饭菜,从不知道人们靠着这里供应的这点口粮也能过活。他们困惑地看到维尔纳小姐连盘子里那一点点食物也要剩下一半,爱丽丝·皮尔拒绝吃土豆、面包、咸肉、可可,担心会造成肥胖。她也不吃芜菁、卷心菜和豆子,认为会影响消化。她还不吃任何带葡萄干的食物,因为受不了那味儿。他们很想把爱丽丝·皮尔放弃的食物,或者维尔纳小姐剩在盘子里的东西弄来,但是绞尽脑汁也想不出辙儿,尽管那样肯定是合情合理的。
晚上十点半,科纳汉小姐会提供所谓的“晚间餐”。一盘切片面包,一点奶油和果酱,几杯可可或茶。寄宿屋不提供咖啡。科纳汉小姐说那是给美国人喝的,会腐蚀人的食道。奶油事先分成可怜的小块,果酱碟摆在桌子正中间,任何人都不大容易够到。科纳汉小姐指出,甜东西会毁掉面包和奶油的味道。出于长期的习惯,其他客人都遵从她的意见,山姆和埃德加却总把果酱碟蘸得干干净净。很快果酱的量缩减为分开的两小勺。可可是用水兑的,只添了一点脱脂奶来结成一层奶皮,好支撑科纳汉小姐口中它完全是由牛奶冲成的说法。
没人提出质疑。科纳汉小姐扯谎并不是为了愚弄人们,而是为了堵他们的嘴。要是哪个住户提出“昨晚楼上有点冷啊”,科纳汉小姐便会立刻反唇相讥:“真不明白。我点了一堆熊熊烈火,烟管烫到没法摸。”事实是她把火减弱,或者彻底熄灭了。住户都心知肚明,或者会产生强烈的怀疑,但是个别住户的疑虑哪能与科纳汉小姐坚定、华丽的谎言相抗衡呢?克鲁兹夫人一定会赶紧道歉,维尔纳小姐会嘟囔说是自己的冻疮在作怪,德拉亨先生和爱丽丝·皮尔会闷闷不乐,但不会坚持。
山姆和埃德加不得不把所有零花钱都用来买吃的,尽管这钱本也不多。一开始他们在快活烧烤买热狗。后来山姆想到他们可以大胆一点,到食品店买一整盒果酱馅饼或者无花果牛顿饼干。他们得在回家路上把一整盒都吃掉,因为在卧室禁止吃东西。他们喜欢吃热狗,但去快活烧烤总感觉不自在,那里全是闹哄哄的高中生,比他们小,也老练得多。山姆担心有可能遭到羞辱,尽管并没真发展到那一步。从食品店回科纳汉寄宿屋途中,他们不得不路过快活烧烤,然后是迪克森药店,它后头有个冰激凌店。商学院的同学们放学后和傍晚时分都会去那里去买樱桃可乐和香蕉船。从迪克森药店窗前走过时,他俩会停止咀嚼,淡漠地直视前方。他们从不进去。
他们是商学院里唯一的农场男孩,单单衣着就足以让他俩显得格格不入。他们没有天蓝色或浅咖啡色V领毛衣,没有看起来比较成熟的灰色长裤,只有硬邦邦的羊毛马裤、厚实的家织毛衣和当作运动服穿的旧西服上衣。他们按要求穿衬衫、系领带,但他们每人只有一条领带、两件衬衫。科纳汉小姐只允许一个人每周洗一件衬衫,因此山姆和埃德加经常穿着领口和袖口都脏兮兮的,甚至沾着污渍—或许来自果酱馅饼—的衬衣。他们试着擦掉污渍,但没成功。
此外还有一个问题,部分与衣服有关,部分与衣服里面的身体有关。寄宿屋从来就没有足够的热水,爱丽丝·皮尔用的超过了她的份额。倦意沉沉的早上,男孩们会像在家里一样只洗洗手和脸。他们身体上和日常衣服上的味道挥之不去,他们也习以为常—它堪称一份他们的努力和行动的记录。这没准是件幸事。否则的话,女孩们或许就会对埃德加更加关注了—他的相貌颇讨她们喜欢—却会对山姆视若无睹。他长着邋遢的沙土色头发,满脸雀斑,还习惯低着脑袋,好像打算掘宝似的。那样一来,他们之间就要产生隔阂了。或者,换句话说,隔阂就会更早出现了。
冬天来了,空地上的杂技表演终止了。山姆和埃德加很想去溜冰。溜冰场在奥兰治大街,只有两个街区远。有人溜冰的晚上,也就是星期一和星期四晚上,可以听到音乐声。他们来加拉格尔时带着冰鞋。他们好像打记事起就开始溜冰,在沼泽地的湖塘里,或者村里的户外溜冰场。这里溜冰要十五分,付了这钱,就得放弃买吃的。可因为天冷,他们的胃口前所未有地大。
一个星期天晚上,他们趁着溜冰场周围空无一人,走到那里。之后的一个星期一晚上,又去了一次,夜间溜冰已经结束,没人拦着他们。他们进了溜冰场,混进正离开冰面、脱下冰鞋的人群。在灯熄灭之前,好好研究了周围一番。回家路上,以及在自己的房间里,他们轻声讨论着。山姆喜欢琢磨无须付钱就混进去的办法,不过仅限于纸上谈兵。埃德加却坚信可以从计划发展到行动。
“不行的,”山姆说,“我俩都太大啦。”
埃德加没接腔,山姆以为这事就算完了。他真不该想得这么简单。
在山姆的记忆中,奥兰治大街溜冰场是一个昏暗的长条形棚子,摇摇欲坠。板子间的缝隙透出暗淡、晃动的灯光。留声机唱片放着音乐,声音沙哑、刮擦—就像从一道摇摆不定的荆棘墙中硬钻出来似的,《维也纳森林的故事》、《快乐寡妇》、《金银华尔兹》、《睡美人》。板子裂缝中晃出来的灯光来自一个叫作“月亮”的设备。溜冰场顶棚上的月亮是一个装在大锡皮罐里的黄灯泡,罐子是个截掉一头的糖浆罐。月亮打开,别的灯都会关掉。通过一系列电线和绳子,你可以左右拉扯罐子,造成一种光线变幻的效果—光源本身,那强劲的黄色灯泡,则藏而不露。
冰场小弟们负责控制月亮。冰场小弟都是些十一二岁到十五六岁的男孩。他们清理冰面,把雪从雪门扫出去。雪门是一扇紧贴在内墙低处的小门,在墙里侧用钩子钩住。除了拉控制月亮的绳子之外,他们还负责操控顶棚上的百叶窗—打开透进空气,关上挡住落雪。冰场小弟们负责收钱,有时会故意少找钱给那些害怕他们的女孩子,不过他们不会欺骗布林科。他不知怎的哄骗他们信以为真,以为他一个溜冰人都不会漏算。布林科是溜冰场经理,一个面色蜡黄、皮包骨头的男人,样子挺凶。他和朋友们总坐在他位于男厕所和更衣室后面的房间里。屋里有一个烧柴火的炉子,炉顶上坐着一只高高的、烧黑的圆锥形咖啡壶,此外房间里还有几把缺胳膊少腿的直背椅子,一些脏兮兮的旧扶手椅。像溜冰场各处的地面、板凳和壁板一样,这里的木头地面也嵌满新旧不等的冰刀划痕,被烟熏和尘土弄得黑乎乎的。房间里热气腾腾,烟熏火燎。都说他们在里面喝酒来着,尽管有可能只是用脏兮兮的搪瓷缸盛咖啡喝而已。当然了,有则传闻说,某次一些男孩在那些男人们到来前先溜进房间,往咖啡壶里撒了泡尿。另一个版本则是布林科出屋去捞门票钱的时候,他的一个朋友干了这事。
冰场小弟们在溜冰场各处晃悠,有时忙碌,有时悠闲,他们攀上墙梯,沿长凳踱步,甚至在顶棚的几个开口下方那片没有防护栏的平台上跑动。有时扭着身子,从开口处爬到顶棚上,又原路爬下来。当然了,有时也溜冰。他们是不用买票的。
没多久,山姆、埃德加和卡丽也做到了这样。他们趁着溜冰生意如火如荼、冰场上拥挤喧闹的当儿过来。房子一角附近有几棵樱桃树,一个非常瘦小的人可以爬上一棵,跳到顶棚上。然后这个瘦小、勇敢、灵活的人可以沿顶棚爬动,从一个开口爬进去,跳到下方的平台上,冒着跌到下面的冰面上摔断骨头甚至摔死的风险。不过男孩们对于这种冒险向来乐此不疲。从平台上,你可以顺着墙梯爬下,在长凳附近偷偷挪动,溜到用来铲雪出去的雪门那里。然后只须躲在阴影里,等待合适的时机,打开雪门,放进等在外面的两个人:山姆和埃德加,他们总是争分夺秒地换上溜冰鞋,直奔冰面。
别人为什么没试过这种把戏呢?多年后,每次山姆想起来讲这个故事,常有人这样问。而他总是答道,没准他们做过,只是他不知道罢了。冰场小弟们当然可以打开雪门,想放进多少朋友就放进多少,但他们大概不愿这么干,因为他们吝于使用自己的特权。夜晚来溜冰的人中,几乎没有哪个瘦小、敏捷、轻盈、勇敢得足够从顶棚爬进来。孩子们或许会试着这么干,但他们都是在星期六下午溜冰,没有黑夜可以利用。为什么没人发现卡丽呢?好吧,因为她很敏捷,而且她从不大意。她懂得伺机而动。她穿一身东拼西凑的破旧衣服—马裤、风雪衣、鸭舌帽。溜冰场上总有一些穿着别人扔掉不要的破衣服的男孩。小镇并没有那么小,不是每张脸都会被人一下认出。镇上有两所公共学校,这一所学校的男生看到她,准会以为她来自那一所。
山姆的太太有一次问:“你们是怎么说服她的呢?”卡丽—卡丽在这里面有什么好处呢?她根本就没有溜冰鞋。
“卡丽的生命中只有干活儿,”山姆说,“所以任何干活之外的事—对她来说都是刺激。”不过他也纳闷了一阵—他们是如何说服她的呢?想必是用激将法吧。与卡丽交朋友一开始有点像与一只暴躁、狐疑的小狗打交道,后来又像是在跟她看起来像是的那种十二岁女孩交朋友。起初,她根本不肯停下活计看他们一眼。他们赞美她做的刺绣画,上面有青山、圆形的碧水潭和一艘大帆船。她却把它紧紧搂在胸前,好像他们是在嘲笑她似的。“是你自己设计的这些图案吗?”山姆问,本想恭维她,没料想却惹毛了她。
“邮购来的,”她回答说,“从辛辛那提买的。”
他们坚持了下来。为什么?因为她是个小奴隶,永远跟不上趟儿,模样古怪,身材瘦小,有她做陪衬,他们就是主流,他们就是幸运儿。他们想对她苛刻就苛刻,想对她慷慨就慷慨,不过还是慷慨更让他们开心。此外,这也是一种挑战。到头来,是恶作剧和激将法最终解除了她的武装。他们送给她小块包在巧克力糖纸里的木炭。她在他们的床单下塞进干荆棘。她告诉他们她从不拒绝挑战。这就是卡丽的秘密—永远不愿开口承认有什么事是她干不了的。她远没有被那些不得不干的活儿压垮,而是以之为荣。一天晚上,山姆在餐厅桌上做会计作业,她把一本练习簿捅到他眼前。
“这是什么,卡丽?”
“不知道!”
那是她的剪贴本,里面都是跟她有关的新闻报道。报纸邀请人们参加各种比赛。谁能在八小时内纫好最多的纽扣眼?谁能在一天当中装最多罐的覆盆子?谁能用钩针钩出最多的床罩、桌布、桌旗和桌巾?卡丽,卡丽,卡丽,卡丽·科纳汉,是她,还是她。在她自己看来,她哪里是什么奴隶,根本就是一个奇才,倒是对别人混吃等死的活法怜悯不已。
他们只有星期一晚上才能去溜冰,因为这天晚上科纳汉小姐要到军人礼堂玩宾戈游戏[3]。卡丽把那身男孩子服装藏在柴火棚里。它们是从克鲁兹夫人的一个破布包里翻出来的,她把这包破布从老房子里带过来,打算缀被面,但从没真正动手。只有帽子来自别处。它是亚当·德拉亨的,他把它塞在一捆衣物里,让卡丽捐到传道会去,不过科纳汉小姐命令卡丽把这捆东西收进地下室,以备万一能派点用场。
卡丽一旦完成任务,就可以从溜冰场上溜走—可以从大门走出去,没人会管她。但她从没这么干过。她爬到长凳顶端,沿凳子走着,研究板子的弹性,或者在一个墙梯上爬爬,单手单脚吊在上面晃荡,挂在隔墙上方,看溜冰的人。埃德加和山姆总是争分夺秒地溜冰,一直到月亮被关掉,音乐停下,别的灯都亮起来为止。有时他们会比赛,在安静的恋人和一排排摇摇晃晃的女生当中穿梭来去。有时他们也会卖弄卖弄,张开胳膊,在冰面上掠过。(埃德加在溜冰上更有天赋,尽管赛速度时没那么不顾一切—要是那会儿男孩们已经开始玩花样滑冰,他准是个中高手。)他们从不和女孩溜冰,不过与其说是因为害怕邀请女孩,不如说是因为不愿受任何人的束缚。溜冰结束后,卡丽总在门外等他们,然后他们,三个男孩子,一起走回家。卡丽不会刻意吹口哨或丢雪球来表示自己是男孩。她有一种拖着脚的男孩步法,显得若有所思、潇洒独立、来者不拒—随便打架还是冒险。她沉甸甸、乱蓬蓬的黑发塞在鸭舌帽里,正好免得帽子太大戴不住。周围少了那堆乱发之后,脸蛋显得没那么苍白了,也不再皱着眉头—她时不时挂着的不屑、嘲弄、冷酷的表情不见了,变得严肃矜持。他们管她叫卡尔。
他们从后门溜进屋。男孩们上楼,卡丽在冰冻的柴房里换掉衣服。她只有十分钟左右把晚间餐端上桌。
星期一晚上溜完冰,山姆和埃德加在黑暗里躺在床上,话比平时多。埃德加喜欢提到克丽西·杨的名字,他去年在老家的女朋友。埃德加宣称已有过性经验了。他说去年冬天跟克丽西搞过,某次他们摸黑滑雪橇,撞上一个雪堆的时候。山姆觉得那没可能,想想那冰天雪地的,还有他们穿的衣服,再说其他雪橇很快就赶过来了。不过他也不能肯定,而且听得越多,渐渐越觉得躁动,或许还有点妒忌。于是他提起别的女孩,在溜冰场上穿着超短裙和小小的毛皮镶边上衣的女孩们。山姆和埃德加比较着这些女孩飞旋而过或者她们中哪个摔倒在冰面上时他们所看到的。你会对谢莉,或者多丽丝做什么?山姆问埃德加,并且很快地抛出新的问题,带着一种嘲笑和兴奋混合的奇特情绪,问他会对别的女孩或女人做什么,如果正好撞上她们无法自卫的时刻?商学院的老师们—男人婆会计老师刘易森小姐,瘦弱的打字老师帕金森小姐;邮局的胖女人,艾顿汇兑局的贫血金发女人;后院里俯身在洗衣篮上、撅着屁股的家庭主妇们。这些选项的变态趣味比受到普遍仰慕的女孩们的优雅美丽更让他们兴奋。爱丽丝·皮尔几乎是被心不在焉地打发了—他们下楼吃晚饭时顺便把她绑在她的床上蹂躏了一番。维尔纳小姐则被公然按倒在楼梯上,因为她双腿缠在楼梯中心柱上宣泄,被他们逮个正着。他们放过了老克鲁兹夫人—他们毕竟还有底线。那么科纳汉小姐,这个患风湿病、套了一层又一层烂糟糟的衣服、嘴巴涂着怪异口红的女人呢?他们听过闲话,所有人都听过。据说卡丽就是一个《圣经》推销员兼寄宿客留下的种。他们想象《圣经》推销员就在他们现在待的地方做这事,干着老科纳汉小姐。《圣经》推销员一下一下撞她,撕扯她古老的灯笼式内裤,把她饥渴双唇上的唇膏弄花,让她发出最狂乱的欲求和感激涕零的叫唤与呻吟。
“还有卡丽呢。”埃德加说。
那么卡丽呢?一提到她,这个游戏顿时让山姆兴味索然。她居然也算女人,这个事实让他发窘。就好像他突然意识到了自己的恶心与可悲。
埃德加的意思是说,他们不是只能想象对卡丽做什么。
“我们可以让她真来。打赌我们能做到。”
山姆说:“她太小了。”
“不,不小啦。”
对于那次劝服,山姆倒是印象挺深。是靠激将法成功的。正因为这他才觉得溜冰场冒险想必也是以同样手段促成的。冬天几乎过去了,农人的雪橇从压得结结实实的雪地上驶过,路过科纳汉寄宿屋时,会咯吱咯吱地碾上一片片光秃秃的土地。一个星期六早上,卡丽带着打湿的拖把、水桶、抹布爬上阁楼台阶。她把编织地毯从楼梯上踢下,准备拎到门外抖干净。从床上扯下法兰绒床单,它们犹带着一股子慵懒私密的体味。科纳汉寄宿屋没有新鲜空气涌入,窗子外还罩着一层防风窗。这时机,这地点,正好对卡丽展开引诱。
引诱这词并不恰当。卡丽一开始气呼呼的,很不耐烦,不肯停下活计,后来她阴沉着脸,再然后就莫名其妙地顺从了。成功之策想必就是嘲笑她该不是害怕了吧。他们那会儿应当已经知道了她的真实年龄,但他们仍旧像哄小孩一样待她—不觉得该视她为一个女孩儿,爱抚她、恭维她。
即便她肯合作了,事情也根本不像他们想象的那样容易。山姆可以确定关于克丽西的故事实为谎言,尽管埃德加这会儿正借用着这姑娘的名字。
“来吧,”埃德加说,“给你瞧瞧我是怎么对我女朋友的。我就是这样对克丽西干的。”
“我打赌一准是的。”卡丽挖苦道,不过还是任着自个儿被拉倒在窄窄的床垫上。冬天穿的灯笼式内裤的松紧带在她腿上腰上勒出红印。内衣外穿着一件扣扣子的法兰绒马甲,她的棕色编织长袜用长长的、粗笨的吊袜带固定着。除了灯笼式内裤之外,什么都没脱掉。埃德加说吊袜带弄痛他了,打算扯下它们,但是卡丽嚷道:“别碰!”好像非得捍卫它们似的。
山姆对那个早上的回忆中,缺了一件非常重要的东西—血。他毫不怀疑卡丽是个处女,因为他记得埃德加的挣扎,然后是他自己的,那样的刺啊戳啊的,却每每无功而返。卡丽轮流躺在他们两个人身下,既不大情愿又义不容辞,她容忍着他们,一句痛都不抱怨。抱怨是她永远不会干的事。不过她也不打算刻意做什么来帮忙。
“张开你的腿。”埃德加急切地说。
“已经张开了嘛。”
他不记得看到血了,原因或许是确实没血。他们没进得足够深。卡丽那么瘦,髋骨直戳出来,但是山姆依旧觉得她相当广阔、笨重、复杂。她身上被埃德加弄湿的地方冷冰冰、黏糊糊的,别的地方则干巴巴的,还有些意料之外的凸起、平地和死胡同—她摸起来像皮革。事后回忆起来,他仍旧不能确定是否就此摸清了女孩们是怎么回事。那感觉就好像他们用的是一个人偶或者一只顺从的小狗。从她身上爬起的时候,他看到她裸露出来的皮肤上起了鸡皮疙瘩,那团死一样的毛丛周围一圈都是。此外,还看到他们的液体弄湿了她的一条长袜。卡丽用抹布擦着身子—确实如此,好像是块干净抹布—并评论说,这让她想起擤出来的鼻涕。
“你没生气吧?”山姆问,部分是认真的,部分的意思是,你不会说吧?“我们弄疼你没有?”
卡丽说:“要弄疼我,这点蠢事哪够啊?”
之后他们就没再溜冰了。太暖和了。
科纳汉小姐的风湿病加重了。卡丽要干的活儿前所未有地多。埃德加得了扁桃腺炎,待在家里没上学。孤身一人的山姆在商学院里,突然发现自己深深喜欢上了这里。他喜欢打字机的声音—叮叮的铃声,滑筒砰地复位的声音。他喜欢用直杆笔在账本上画线,画出规定的粗线和细线。他尤其喜欢计算百分比,迅速加出一栏栏数字的总和,处理X先生和B先生的问题,他们分别拥有一个木料场和一个五金销售连锁店。
埃德加停了几乎三星期课。回到学校,他所有课程都落后了。打字打得七零八落,比圣诞节时还慢了不少,尺子给他沾上了墨水,而且他看不懂利率表。他没精打采的,一派消沉,看着窗外发呆。他的模样让女教师们不由得心生爱怜—自打生病以来,他瘦了,苍白了,甚至金发颜色也变浅了—有好一阵他都不曾因为慵懒迟钝而遇上什么麻烦。他作了点努力,偶尔试着和山姆一起做家庭作业,中午去打字室练习。但进步不明显,或者说不够见效。他开始一请就是好几天假。
埃德加生病期间收到了一张祝福卡。上面画着一条从床上坐起的穿条纹睡衣的龙。卡片封面上印着“听说你的尾巴被拖住了?很遗憾”,里面印着“希望你很快又能让它摇摆起来!”。卡片底下用铅笔写着克丽西的名字。
但是克丽西这会儿还在斯特拉特福接受护士培训呢。她怎么可能知道埃德加生病了?信封上写着埃德加的名字,是通过邮局寄来的,盖的是本地邮戳。
“是你寄的。”埃德加说,“我知道不是她。”
“不是我。”山姆实话实说。
“是你寄的,”埃德加声音嘶哑、激动而失望地说,“你甚至都懒得用钢笔写。”
“我们在银行里还有多少钱?”埃德加问。这是在五月初。他们的钱足够把寄宿费付到学期末。
埃德加好几天没上学。他去了火车站,打听去多伦多的单程票价。他说,如果山姆不跟他走,他就自己去。他铆足了劲要走。山姆很快发现了原因。
“卡丽有可能怀娃娃了。”
“她还不够大吧。”山姆说,旋即想起其实她已经不小了。不过他还是对埃德加解释道,他确信他们没干得足够深。
“我不是指那一次。”埃德加愠怒道。
那是山姆第一次了解到埃德加不上学时都在干什么。但是山姆再次理解错了。他以为是卡丽告诉埃德加她遇到了麻烦。她没有。她没告诉他任何事,没提出任何要求或发出任何威胁。但是埃德加很害怕。他惊恐万状,都变得病怏怏了。他们在食品店买了一盒蛋糕甜甜圈,坐在圣公会教堂前的石头墙上吃。埃德加举着甜甜圈,啃了一口就停下。
山姆说,他们在大学里只需要再待五个星期。
“我反正不会再回那里了,落后太多啦。”埃德加说。
山姆没说他最近正在想象自己作为商学院的毕业生,在银行工作的模样。他想象自己坐在出纳室里,穿着三件套西服。他会蓄胡须。有的出纳员会变成银行经理呢。他最近刚刚意识到,银行经理并不是天生的,也是从别的位置升上去的。
他问埃德加他们在多伦多能干什么。
“我们可以演杂技,”埃德加说,“可以在人行道上演杂技。”
现在山姆知道要面对的是什么了。埃德加不是在开玩笑。他坐在那里,举着只啃了一口的甜甜圈,畅谈在多伦多的这种谋生方式。在人行道上演杂技。
那他们的爸妈怎么办?这问题仅仅激发出更加疯狂的计划。
“你可以告诉他们我被绑架了。”
“那警察怎么办?”山姆说,“警察会去找所有被绑架的人。他们会找到你的。”
“那就不要告诉他们我被绑架了,”埃德加说,“告诉他们我目睹了一次谋杀,只好从此躲起来。告诉他们我看到一具装在麻袋里的尸体被推下雪松林大桥,我看到了干这事的那些家伙,后来在街上又撞上他们,被认出来了。就跟他们这么说。告诉他们不要去报警,也不要提这事,因为我的生命有危险。”
“你怎么知道麻袋里是尸体呢?”山姆白痴似的问道,“别再扯了。我要想一想。”
然而走回科纳汉寄宿屋的路上,埃德加一直在喋喋不休,编造这种那种故事。比如他被政府招去做间谍了,不得不染黑头发,隐姓埋名。
他们走回寄宿屋,正好爱丽丝·皮尔和她的警察未婚夫从前门走出来。
“绕到后门。”埃德加说。
厨房门大开着。卡丽刚擦洗了炉子的烟囱。她把管子重新装好,擦起炉子。她用打蜡的面包纸擦炉子上黑色的部分,用干净抹布擦炉沿儿。炉子看起来漂亮极了,就像一块嵌在银底座上的黑色大理石,但是卡丽本人从头到脚都黑乎乎的。连眼皮都黑了。她唱着《我亲爱的耐利·格雷》,唱得飞快,以便跟上擦洗的动作。
哦,我亲爱的耐利·格雷,
他们把你带走喽,
我再也见不到我的宝贝。
科纳汉小姐坐在桌边喝热水。她除了关节炎之外,还遭受消化不良之苦。关节发出咯吱咯吱的声音,肚子深处传来咕噜声、呻吟声,甚至还有尖啸声。她面无表情。
“你们这两个男孩啊,”她说,“干什么去了?”
“散步。”埃德加说。
“你们不练杂技了。”
山姆说:“地面太湿了。”
“坐下。”科纳汉小姐说。
山姆能听到埃德加颤抖的呼吸声。他自己胃里也感觉沉甸甸的,好像对那些甜甜圈的所有消化工作—差不多整盒都是他吃的,除了一个—都停止了。卡丽告状了吗?她没抬头看他们。
“我从没跟你们这些男孩讲过卡丽是怎么出生的。”科纳汉小姐说。她滔滔不绝起来。
“那是在斯特拉特福的皇后旅馆。我和我的朋友路易·格林住在那里。路易·格林和我开着一家女帽店。我们正在去多伦多进春季货品的路上。不过那时还是冬天。事实上,正刮着暴风雪。只有我们两个人在那里吃晚饭。后来,我们从餐厅出来,旅馆门突然被撞开了,闯进来三个人。是旅馆负责到火车站接送的司机,还有一个女人和一个男人。男人和司机架着那女人,把她夹在他们当中拖着。她尖声惨叫着,肚子鼓得吓人。他们把她放到沙发上,但她又滑到地上。她还是个女孩儿,十八九岁光景。婴儿从她身体里直接就掉到了地板上。那男人一屁股坐在沙发上,把脑袋埋在膝盖中间。是我跑去喊来了旅馆老板和他老婆。他们跑来了,他们的狗冲在前头叫个不停。路易抓着楼梯栏杆,担心会昏过去。这一切就在一眨眼间。
“司机是个说法语的加拿大人,所以他或许见过婴儿出生。他用牙齿咬断脐带,从口袋里掏出一团脏兮兮的绳子把它扎起来。他抓过一张地毯,塞到她两腿中间。血从她身上涌出,像灭蝇剂一样黑乎乎的—在地板上摊开来。他嚷嚷着让人去弄点雪来,那个做丈夫的,或者天晓得是做什么的吧,只知道把脑袋埋在腿中间。是路易冲了出去,两手捧得满满的回来,司机看到她弄回来的只有不像样的那么一点点,气得冲她破口大骂,把那点雪砸在地上。然后他踢飞了那狗,因为它一个劲往上凑。他踢得那么重,让它飞到房间另一头。旅馆老板娘尖叫起来,说狗被踢死了。我抱起婴儿,用外套裹住它。那就是卡丽。看起来是那样一个病怏怏的小家伙。那狗根本没死。地毯浸透了血,法国人连珠炮似的咒骂着。她死了,不过还在往外流血。
“是路易提出希望我们能收养她。那个做丈夫的说会和我们联系,但是从来没有。我们不得不弄个瓶子,把一点牛奶和玉米糖浆煮开了,用抽屉给她做一张小床。路易渐渐非常喜欢她。但是一年不到,路易就结婚了,搬到里贾纳,再没回来过。再喜欢也就那么回事。”
山姆觉得这十有八九全是胡扯,不过仍旧令他胆战心惊。为什么这会儿告诉他们这个?不管是真事还是扯谎,或者是不是真有谁踢飞了狗或者流血而死吧,都无关紧要。关键在于科纳汉小姐讲这事时一字一句的冰冷口气,她不曾明说却显然不怎么友好的意图,她那份突如其来的残忍。
卡丽没有停下活儿来听这故事的一个字。她压低了唱歌声音,但没停下。厨房溢满春季傍晚的光线,到处是卡丽的粗肥皂和清洁粉味儿。山姆之前也会时不时感觉身陷麻烦,不过总是明白地知道麻烦是什么,惩罚又会是什么,总能想出办法蒙混过关。但现在他觉得撞上的是一种高深莫测的麻烦,其惩罚难以预料。令他们不寒而栗的甚至都不是科纳汉小姐那种病态的决心。到底是什么呢?埃德加有数吗?埃德加也觉得风雨欲来—那将是某种足以令人崩溃的重击。他觉得这想必与卡丽、婴儿,以及他们干的好事有关。山姆感觉情况会比这更严重,但也只好相信埃德加的直觉。
星期六早上,他们穿过后街,走向火车站。他们趁卡丽拖着一辆当作食品篮的婴儿车出门做周末采购时离开了寄宿屋。他们事先从银行取出钱,在门缝里塞了一张纸条,门打开就会掉下:“我们走了。山姆,埃德加。”
“我们走了”字样是前一天山姆在学院里用打字机打的,不过他们的名字是手签的。山姆本想加上一句“食宿费付到星期一”或者“会写信告知父母”,但是科纳汉小姐自然知道他们的食宿费付到星期一,而提到会写信给父母则表明他们并非直接回家。“我们走了”听起来挺傻,可他担心要是不留个说法,人们会以为出事了,会展开搜寻。
他们留下了本打算期末卖掉的沉重、破旧的书本:《会计实务》、《商业算术》,把衣服尽可能塞进两个牛皮纸袋。
早上天气很好,很多人都出了门。孩子们占据了人行道,拍球、跳房子、跳绳。他们不得不对两个鼓鼓囊囊的牛皮纸袋作着解释。
“你们袋子里都装了些啥?”
“死猫。”埃德加说,把手中的袋子朝一个女孩的脑袋晃去。
可是她胆子挺大。“你们要怎么处理它们?”
“卖给中国佬做剁猫杂碎汤。”埃德加用吓人的声音说。
他们脱了身,女孩在后头嚷嚷着:“剁猫杂碎汤!剁猫杂碎汤!吃得病怏怏!”快到火车站时,成群结队的孩子们变少、消失了。周围换上了十二三岁的男孩们—差不离就是曾经在溜冰场一带闲逛的那些—在月台附近溜达、捡烟头,试图点着。他俩装出大人的傲慢神情,免得再被盘问,露出马脚。
“你们这些男孩可真闲啊。”车站管理员说。火车要到十二点半才开,但他们的出逃时间是根据卡丽的购物时间决定的。“你们知道进城后要去哪儿吗?有人来接吗?”
山姆被问了个猝不及防,不过埃德加回答道:“我姐。”
他根本没姐姐。
“她住在那里吗?你们要住她家吗?”
“她和她老公家,”埃德加说,“她结婚啦。”
山姆都能猜到接下来会是什么了。
“他们住在多伦多什么地方?”
但是埃德加毫不露怯。“北部,”他说,“每个城市都有个北部,不是吗?”车站管理员看起来居然好像满意了。
“看好钱。”他提醒他们。
他们坐在条凳上,面对铁轨对面的木栅栏,抓着车票和牛皮纸袋。山姆脑袋里计算着他们还剩多少钱。他十岁时跟爸爸去过一次多伦多。他记得搭街车时遇到的窘事。他们上车时或者是下车时走错了门。人们对他们嚷嚷。爸爸嘟囔道,他们全都是他妈的蠢蛋。山姆断定自己必须准备好接受某种可怕的羞辱,他力图想象接下来可能出现的复杂情况,免得到时弄得措手不及。然后,仿佛天赐的礼物,脑海中突然灵光一现。他也不知道这念头是怎么来的。基督教青年会。他们可以去基督教青年会,在那里过夜。到达时估计已经接近傍晚。可以先买点吃的,向人打听去基督教青年会的路。没准可以走着去。
他跟埃德加描述了这个前景。“然后明天我们得四处走走,熟悉熟悉地形,找到最便宜的吃饭地点。”
他知道埃德加此刻任何提议都会接受。埃德加尽管无中生有地炮制出了一对姐姐和姐夫,但对于多伦多还是毫无概念可言。埃德加这会儿坐在车站条凳上,满脑子想的都是火车开过来,他们上火车之类。汽笛尖啸、出发—逃脱啦。像爆炸一样让他们突然挣脱束缚的逃脱。他从没想过他们要下火车,抱着牛皮纸袋进入一个喧闹、骚动、拥挤、完全令人摸不着头脑的地方。但是山姆有了一个启动计划以后感觉好多了。既然能凭空涌出一个好主意,第二个想必也会接踵而至。
过了一会儿,其他人陆续赶到,都在等同一列火车。两位女士穿戴整齐,准备去斯特拉特福购物。她们戴着刷清漆的草帽,这表明夏天将至。有个穿一身闪亮黑西装的老头抱着一个用麻绳捆好的硬纸盒。在附近闲逛、哪儿也不去的男孩们也作好准备迎接火车—他们都坐在月台尽头,晃荡着双腿。两条狗在月台上像模像样地巡逻,嗅着一个箱子和几个包裹,研究行李车,甚至朝铁轨打量,仿佛它们像人一样知道火车将从哪个方向开来。
一听到镇子西部的十字路口传来汽笛声,山姆和埃德加就站起来,等在月台边。火车到了,仿佛是个好兆头似的,他们恰好站在列车员搬着小台阶爬下车的地方。列车员没完没了地帮着一个抱孩子、拎手提箱、领着两个小孩的女人上车,之后他俩终于上了车。他们抢在戴夏季帽子的两位女士、抱盒子的男人和不知还有什么别的排队的人前面。他俩一次头也没回。他们走到几乎全空的车厢尽头,挑了两个面对面的位置,靠着木栅栏一侧,而不是月台。刚才他们整整四十五分钟多的时间里一直在盯着这道木栅栏看。这么坐着等了两三分钟,车外一片如常的混乱,传来几声貌似充满权威的喊叫,列车员吼道:“开车!”这吼声不知怎的从人的声音过渡到了火车的高鸣。火车动啦。他们开始动啦。他俩一只胳膊依旧搂着牛皮纸袋,另一只手攥着车票。他们动啦。他们看着栅栏上的木条来证实这事。已经把栅栏完全抛在后头啦,正穿过镇子逐渐消隐的郊区—各家的后院、屋后的棚子、房后的走廊、开花的苹果树。铁轨边铺天盖地的丁香花疯长。
正当他们看着窗外,镇子尚未完全消失的时候,一个男孩儿在过道对面的座位上坐下。山姆感觉准是月台上晃荡的男孩中的一个溜上了车,或者不知怎的被允许免费搭一段车,没准是要到铁路交汇处去吧。他没抬头,不过还是感觉到了那男孩的衣服—穿得太破烂、太古怪了,不可能是为了什么正经的旅行。他定睛一看,发现男孩抓着一张票,和他们一样。
冬夜里,走向溜冰场时,他们并不经常互相打量。在街灯下,他们看着自己在雪地上扭动的影子。在溜冰场里,人工月亮变幻不定,有些角落几乎完全陷入黑暗。因此过道对面这个男孩的衣服并没有立刻让他明白过来。除了它们不是人们旅行时通常会穿的之外。胶靴,沾满油渍或油漆的厚重马裤,一条胳膊下撕了个口子,就现在的天气而言已经嫌热的风雨衣,一顶大得离谱的帽子。
卡丽穿着这身衣服,是怎么从车站管理员的眼皮下溜过的?车站管理员对山姆和埃德加狐疑地看了又看,盘问他们打算住哪儿、谁来接,却不闻不问地让这个古里古怪、肮里肮脏、衣衫褴褛的假冒男孩买了一张票(到多伦多—卡丽是猜的,而且猜对了)并且上了月台。这一点,在男孩们认出她之后,更加坚信她施展了某种几乎称得上是魔法的本领。(或许埃德加对此尤其深信不疑。)她是怎么知道的?哪来的钱?怎么会到这里?
没什么不可能的。她买完食品回来,去了阁楼。(为什么?她没说。)她发现了字条,立刻猜出他们没回农场老家,也不会在公路上搭便车。她知道火车什么时候出发。她知道它会去两个地方—斯特拉特福和多伦多。她从钢琴凳里面压在赞美诗本子下的铁盒里偷拿了买票的钱。(科纳汉小姐当然不相信银行。)等她赶到车站买票时,火车已经进站,车站管理员忙不过来,没顾得上盘问她。她交了不少好运—幸运的时间、对每一个步骤的幸运猜测—但仅此而已。不是什么魔法,根本谈不上。
山姆和埃德加没认出那些衣服,她也没做什么特别的举动或姿态引起注意。男孩卡丽坐着,看着窗外,偏着脑袋,避开了他们。山姆再也想不起来是何时意识到那就是卡丽了,也记不得是如何发现这一点的。他也搞不清他是看了看埃德加,还是立马意识到埃德加也在同时得知了此事。这认识就好像渗进空气中,等在那里让他们吸收似的。他们驶过一条长长的洼地,两侧都是清新的绿草堤岸,然后穿过雪松林大桥—镇上的男孩在这座桥上互相挑战着爬下去,在火车从头顶驶过时,把身子紧贴在桥枕下的支柱上。(要是他们挑战卡丽,她也敢做这个吗?)就在开过大桥的时候,他俩都知道卡丽坐在对面了。他俩也都知道对方知道了。
埃德加先开口:“你想挪到我们这儿坐吗?”
卡丽站起身,挪过走道,坐到埃德加旁边。她一脸男孩子的表情—与平时狡猾暴躁的表情截然不同。她变成了一个或多或少好脾气的男孩,通情达理的。
她开口说话的对象是山姆。“你不介意逆着方向坐吗?”
山姆说不介意。
接着,她问他们包里是什么,他俩同时开口。
埃德加说:“死猫。”
山姆说:“午饭。”
他们并没觉得被人抓住了。他们立刻就明白了,卡丽并不是来抓他们回去的。她是来加入他们的。她用那套男孩衣服,提醒他们那些幸运而巧妙的冬夜,那执行得天衣无缝的计划,免费溜冰,速度和快乐,耍滑头的愉悦。那会儿没出任何差错,也没可能出任何差错,成功势在必得,他们的每一步都拿捏得恰到好处。穿着男孩衣服,用偷来的钱混上火车的卡丽,看来与其说施加了威胁,毋宁说是消除了它。就连山姆也不再担心他们在多伦多能做什么,他们的钱能撑多久了。要是他的脑筋能像平时一样转,他就该看出,一旦降落到真实世界,卡丽的存在注定要带来各种麻烦。然而他的脑筋没那样转,没看出任何称得上麻烦的东西。这会儿,他看到的是力量—卡丽不愿被落下时展示出的力量—这力量慷慨地分给了他们三个。此刻似乎满满当当—满是力量,还有各种可能性。不过真开心。真是不折不扣的开心。
那就是山姆的故事惯常采用的结尾—省掉了一些细节和原因。要是有人问,打这之后又怎样了,他或许会回答说:“嗯,比预想的复杂一点,不过我们都大难不死。”具体地说,那意思就是:基督教青年会啃着鸡蛋洋葱三明治的办事员两分钟不到就看出卡丽不对劲儿。疑问、谎言、冷笑、威胁、电话,诱拐未成年人,试图把一个姑娘带进基督教青年会干不道德的勾当。她父母在哪里?有谁知道她在这里吗?谁允许她来的?谁是监护人?冒出了一个警察。两个警察。供认不讳和一个电话,车站管理员想起了一切。他想起了扯谎。科纳汉小姐已经发现丢钱,发誓绝不宽恕。再也不想看到她。一个生在旅馆大厅的弃婴,父母没准都没结婚,收留了养育了,不知好歹,天生的坏种。就当个教训吧。太丢人了,哪怕卡丽不是个未成年人。
再往后,那意思就是:他们全都大难不死,而且发生了许多事。他本人,哪怕在多伦多最初的那些困惑、蒙羞的日子里,也想到了像这样一个地方,一个城市,正午的影子投在深邃狭窄的市中心街道上,各个办事处装潢气派,街车频频开动,喧闹刺耳,这里正是他想待的地方。一个可以工作、挣钱的地方。所以他待了下来,待在基督教青年会,在这里他的危机—他的和埃德加的和卡丽的—迅速被淡忘。第二周便发生了一些别的事情。他找到一份工作。过了几年,他发现这里并非挣钱的真正宝地。西部才是发财的好去处,所以又挪了地儿。
埃德加和卡丽回到农场上,埃德加的爸妈家。不过没待多久。科纳汉小姐发现少了他们,简直没法过日子。
卡丽的商店位于一幢属于她和埃德加的房子里。楼下是杂货店和一家美发店,他们住楼上。(美发店从前是食品店—山姆和埃德加过去正是在那里买果酱馅饼来着。“可是谁要听那个啊?”卡丽说,“谁想听过去的事啊?”)
山姆对于好品位的概念是由他太太对灰色白色蓝色和笔直线条,还有单只花瓶的崇尚培养而成的。卡丽楼上的住所令他眼花缭乱。金色锦缎做成窗帘,挂在没窗的墙上,假装有个大窗户。金色长毛绒地毯,糙面白石膏天花板上群星闪烁。一堵墙整面都是哑金色镜子。山姆看到里面的自己周身遍布黑色和银色纹路。许多盏灯从链子上垂下,装着琥珀色玻璃灯泡。
屋子当中坐着埃德加,几乎一动不动,恰似一个精心擦拭的装饰品。他们三个当中,他的容貌保持得最好,几乎没什么变化,高大、瘦削,精心拾掇,衣着优雅。他的胡子是卡丽刮的。她每天都给他洗头,头发变成雪白色,像圣诞树上天使的头发一样闪闪发亮。他可以自己穿衣,不过她什么都帮他拿好—裤子、袜子、配套的领带和胸袋手帕,还有柔软的深蓝色或酒红色衬衫,它们能衬出他粉色的脸颊和他的头发。
“他晕倒过一次,”卡丽说,“四年前的五月份。他没失去说话能力或别的什么,不过我带他去看了医生,他说不错,他是晕了一下。但他很健康,状态不错。”
卡丽同意山姆带埃德加出去散步。她平时都待在店里。埃德加正在楼上的电视机前等着。他认得山姆,好像很高兴看到他。山姆说:“穿上大衣吧,我们这就出发。”他顺从地点点头。山姆从衣柜里取出一件新的浅灰色大衣和一顶灰帽子,想了想,又拿出一副橡胶鞋套,以便保护埃德加闪闪发亮的皮鞋。
“行吗?”山姆问,不过埃德加做了个手势,意思是“等一等”。他正在看一个俊俏的年轻女人采访一位年长女士。年长女士是做娃娃的。面团制成,大小不一,不过都带着同样的表情。这在山姆看来白痴极了。埃德加好像对它们很感兴趣。或者也许他感兴趣的是那个一头蓬松金发的采访者吧。
山姆站着等节目播完。然后是天气预报,埃德加示意他坐下。那倒是合情合理的—在出门散步前关心一下天气。山姆打算走到奥兰治大街—那里的溜冰场和樱桃树已被一个老年中心取而代之—然后绕到老科纳汉寄宿屋和加拿大轮胎商店看看。天气预报过后,山姆又坐着看了一会儿新闻,有个关于新税率规定的新闻引起他的关注。当然了,不断有广告干扰,不过新闻最后还是播完了。换上了几个花样滑冰运动员。过了差不多一小时,山姆意识到,要让埃德加出门是没指望了。
不管山姆说什么,埃德加总是举起手,好像想说稍等一分钟。他永不厌烦,看所有节目都兴趣盎然。看到花样滑冰选手穿着闪闪发亮的服装,他微笑起来。他似乎真心想走,不过山姆察觉出他其实别无所求。
电动壁炉前的仿壁炉台上,摆着一张卡丽和埃德加的婚纱照。卡丽的面纱还是很久以前的古老式样,连在一顶缀珍珠、在她额头处拉下的帽子上。她坐在扶手椅中,怀里满满地搂着玫瑰,埃德加站在她身后,忠诚、瘦削。
山姆知道这幅照片并非他们结婚当天所拍。那时很多人都会在事后穿着结婚礼服,到摄影棚拍照片。不过这些甚至都不是他们的结婚礼服。山姆记得有个基督教青年会的女人送了一条裙子给卡丽,一件没形没状的闷粉色玩意儿。埃德加则根本没什么新衣服,他们在多伦多由一个谁都不认识的牧师主持着,匆匆忙忙结了婚。而这张照片一准想营造截然不同的印象。或许它是多年之后补照的。卡丽的样子比她真正的婚礼那天老了很多,脸庞变宽了,变厚重了,显得更加充满权威。事实上,她有一点点像科纳汉小姐。
那就是让人永远捉摸不透的关键所在—为什么埃德加在多伦多的第一晚就宣布要和卡丽结婚。没这必要啊—至少山姆看不出有什么必要。卡丽没怀孕,而且事实上,据山姆所知,她从来不曾怀孕。或许她确实太小了,或者没正常发育。埃德加迈出这一步,干了没人逼他干的事,接纳了本想逃离的东西。他是感到良心谴责吗?是感到有什么事令他无处可逃吗?他说要和卡丽结婚。可那并不是他们原先的打算—不是这么计划的,对吧?火车上,山姆看着对面的他俩,他们三个都宽慰地笑着,那可不是因为预见到了这样的结局。他们只不过在笑罢了。他们很开心。他们很自由。
五十年后才想到问,太迟了,山姆想。不过当年他就觉得莫名其妙。埃德加突然让他感觉陌生。卡丽变回了可怜的女性状态。和他们分享过的快乐时刻仍令他记忆犹新,但始终不知该如何理解。这样的时刻是否果真如它们所呈现的,意味着我们可以拥有快乐的生活,但对它的触及只能是偶然的,会意的?它们是否放射出如此强大的光辉,以至于此前此后我们生命中的一切—或者说我们主动促成的一切—都可以忽略不计?
卡丽上楼时,他没提婚纱照的事。“楼下来了个电工,”卡丽说,“所以我得再下去,盯着他点儿。我可不想他坐在那儿抽抽烟就找我要钱。”
他正学着不去触及一些话题。科纳汉小姐、寄宿屋、溜冰场、旧日时光。一个早已开溜的人对留在原地不动的人喋喋不休什么旧日时光,真够讨厌的—简直就是一种微妙的侮辱。卡丽则正学着不去打听他的房产值多少钱,他在夏威夷的公寓值多少钱,他在各种休假和女儿的婚礼上花了多少钱—简言之,正学着永远不去打听他到底有多少钱。
他看得出她还在琢磨另一个问题。他看得出,这问题令她的眼睛—它们展示出她运筹帷幄、稳操胜券的一生—涂成蓝色的眼窝的皱纹加深了。
山姆为何而来?这就是卡丽的问题。
他打算告诉她,他或许会待下去,直到找出答案。他或许会做一个寄宿客人。
“埃德加好像不想出去,”山姆说,“他好像没有要出去的意思。”
“当然,”卡丽说,“当然。他很快乐。”
[1] 信奉基督教的商界和学界人士建立的一个协会,旨在促进基督的福音传递给每一个人,并使之最终接受基督作为其个人的救主。
[2] 英文中这三个词首字母均为V。
[3] 一种由多人参加,手中卡片上的数字全被读中者胜的游戏。
白山包-艾丽丝·门罗
========================
白山包-[[艾丽丝·门罗]]
------
"""
一
“不知道是什么颜色,”戴妮斯回答玛歌达,“我其实不记得房子里的任何颜色啦。”
“你当然不记得,”玛歌达同情地说,“屋里没光亮,自然就没颜色。都没试着透点光进来。那么昏暗,我简直没法相信。”
除了拆掉木屋古老、阴森、不透光的走廊,玛歌达—她是戴妮斯的爸爸劳伦斯现在的老婆—还装了天窗,把几堵墙刷成白色,另一些刷成黄色。她挂上墨西哥和摩洛哥织毯,铺了魁北克地毯。松木梳妆台和桌子取代了油漆拙劣的廉价家具。装了一个有窗子和植物环绕的按摩浴缸,还整出一个很棒的厨房。这些想必花了一大笔钱。毫无疑问,劳伦斯现在有钱了,付得起。他在渥太华附近开了一家小工厂,生产塑料,特别是仿彩绘玻璃的窗玻璃和灯罩。它们花样好看,颜色也不算俗气,玛歌达设法在木屋里不显眼的地方装了几片。
与她的名字听起来不同,玛歌达不是匈牙利人,而是英国人。她曾是舞者,后来当了舞蹈教师。是个矮个儿、腰部粗壮的女人,仍旧非常优雅,颈子光滑苍白,头顶一团可爱轻盈的金银色交织的秀发。她穿件朴素的灰裙,披一条色彩柔和的花朵图案披巾,它有时搭在她卧室的高背椅子上。
“玛歌达真是无比、无比有品位啊。”戴妮斯有一次对弟弟彼得感叹。
“那有什么不对?”彼得说。他是个电脑工程师,住在加利福尼亚,一年或许才回家一次。他不明白戴妮斯为何仍对这些人如此在意。
“没什么啦,”戴妮斯说,“不过你去木屋看看,里面甚至没有一堆围巾杂乱地堆在某个旧柜子上。只有一些精心安排的杂乱。厨房里挂的打蛋器或者碗当中,没有哪件不是你所能买到的最雅致的。”
彼得看着她,没接腔。戴妮斯说:“好吧。”
戴妮斯开车从多伦多过来,每年夏天她都会这样来一两回,拜访爸爸和继母。劳伦斯和玛歌达整个夏天都住这里,他们谈论着干脆卖掉渥太华的房子,全年在此长住。八月下旬一个星期天下午,他们三个坐在铺砖的天井里,它取代了原先走廊的一部分。玛歌达用小陶罐养着各种最近盛开的花朵—戴妮斯唯一认得的是天竺葵。他们喝掺苏打水的酒—真正的酒要等晚宴客人到来后才上。直到这会儿都没出现什么荒唐的争论。开车来的路上,戴妮斯就决定不要让这种争论出现。她在车里放莫扎特的音乐,放松心情,振作精神。她下了决心。目前为止一切正常。
戴妮斯在多伦多开了一家妇女中心,给遭遇家暴的女性提供庇护所,帮她们找医生和律师,向私人和公共机构拉赞助,做演讲,召开会议,处理各种各样,有时甚至不乏危险的人生纠纷。她的收入还不如政府开设的售酒商店的售货员。
劳伦斯说过,这正是有钱人家的女孩子爱干的工作。
他说,妇女中心对真正需要它的人来说是个好东西。不过他有时忍不住好奇。
有时忍不住好奇什么?
坦率地讲,他有时忍不住好奇这些女人中是否有一些—只是一些—在宣称遭殴打、被强暴等等的时候,搞不好也在享受她们赢得的各种关注。
劳伦斯照例抛出诱饵,戴妮斯每每一口接住。(玛歌达这种时候总是置身事外,对她的花儿们微笑。)
用纳税人的钱。帮助那些不晓得自助的家伙。要消灭酸雨,我们就要失业了,你的那些工会就该抱怨了。
“它们不是我的工会。”
“要是你为新民主党投票,它们就是你的工会。新民主党都是些什么人啊?”
戴妮斯没法判断他到底是真信他说的这些,还是仅仅半信半疑,还是专门在跟她作对。她不止一次眼泪汪汪地冲出门,冲进汽车,一路开回多伦多。她的情人,一个来自加勒比群岛的快活的马克思主义者(她不曾带他回家),就会评论道,在资本主义工业社会里,老男人们,尤其是成功的老男人们,几乎个个本质邪恶。他们身上什么也不剩,只有恼怒的自卫和贪婪。戴妮斯也会跟他吵起来。首先,她爸爸不是个老男人,而且骨子里是个好人。
“我讨厌你那些男性观念和彻头彻尾的男性论点。”她说,然后沉思道,“此外,我也讨厌听到自己说‘男性’这个词。”她明智地避免提及这个事实:要是能在争论中最终取胜,她爸爸就会给她一张支票捐给中心。
今天,她的决心生了效。她看到诱饵在闪烁,却设法绕过了它,一条聪明的、看起来纯洁无辜的鱼儿,大多数时候都在跟玛歌达谈天,赞美翻新房子的各种细节。劳伦斯是个英俊男人,一脸讽刺,胡髭完全变成灰色,一头柔软、日渐稀疏的灰棕色头发,身材高大,肩膀和肚子都略微松弛。他数次站起,踱到湖边又踱回来,踱到路边又踱回来,深深地叹气,毫不掩饰自己对于这种女性话题的不耐烦。
最后他终于粗暴地打断玛歌达,对戴妮斯发问。
“你妈怎样?”
“很好,”戴妮斯说,“据我所知不错。”
伊莎贝尔住在遥远的科莫克斯谷,位于不列颠哥伦比亚。
“哦—那山羊农场如何?”
和伊莎贝尔一起生活的男人是个职业渔夫,当过电视台摄像。他们住在一个小农场上,把土地,或者说土地的一部分,租给一个养山羊的。某次,戴妮斯告诉了劳伦斯这事(她很谨慎,没说那男人比伊莎贝尔小好多,也没提他们的关系时不时变得“不稳”),劳伦斯从此认定伊莎贝尔和她的姘头(他的说法)干着经营山羊农场的营生。他的问法让人想到一种无比艰辛的乡下生活:在泥泞中苦苦对付难以驯服的牲畜,贫穷,某种过时得可怕的理想主义。
“也不错。”戴妮斯微笑道。
通常她会争论,会指出他在事实上犯的错误,谴责他歪曲真相,不安好心,恶意讽刺。
“那一带还有足够的反传统思潮支持人们买山羊奶喝?”
“我觉着有吧。”
劳伦斯的嘴唇在胡髭下不耐烦地抽动。她盯住他,保持着心无芥蒂、没心没肺的快乐神情。他嗤笑一声。
“山羊奶!”他说。
“这是一则新的内部玩笑吗?”玛歌达说,“我错过了什么?山羊奶?”
劳伦斯说:“玛歌达,你知道吗,我四十岁生日那回,戴妮斯用飞机带我上天?”
“其实不是我开的啦。”戴妮斯说。
“我四十岁生日,1969年。月球登陆那一年。月球登陆实际上比那迟了两天。她听到过我说希望能从一千英尺高空看看这个地方。我从渥太华到多伦多那回已经飞过了,但没看到什么。”
“我只付了他一个人上去的钱,但到头来我们全都上去了,挤在一架五座飞机里,”戴妮斯说,“价钱不变。”
“我们全上去了,除了伊莎贝尔。”劳伦斯说,“得有人让出位置,于是她让了。”
“我让他—让爹地—蒙着眼睛,开车到了飞机场,”戴妮斯告诉玛歌达,“哦,不是蒙着眼睛开车—”他们全都笑了—“是蒙着眼睛坐车,免得他知道我们要去哪里,得让他完全蒙在鼓里。”
“是妈妈开的车,”劳伦斯说,“我想我蒙着眼睛也能比她开得好点。为什么是她开,而不是伊莎贝尔?”
“我们不得不坐奶奶的车去。标致车没法装下我们所有人,而我得让所有人都去看你,因为这是我操办的大事,是我的礼物。我真是个糟糕的导演。”
“我们全都在丽都湖区上飞了一通,”劳伦斯说,“妈妈很高兴。记得吗,那天早上她刚刚跟那些嬉皮士干了一架。所以对她而言那是件好事。飞行员够慷慨。他让他老婆辛苦做蛋糕,不是吗?”
戴妮斯说:“她是个食品定制师。”
“她做了我的生日蛋糕,”劳伦斯说,“就在那个生日。我后来才知道的。”
“不是伊莎贝尔做的吗?”玛歌达问,“伊莎贝尔没做蛋糕吗?”
“烤箱坏啦。”戴妮斯说。她的声音警惕起来,有点懊恼。
“哦,”玛歌达说,“那干架是怎么回事?”
戴妮斯、彼得和父母每年夏天从渥太华赶到木屋,孩子们的奶奶索菲总是先到一步,她从多伦多开车过去。房子已经打开通风,清扫干净,就好像向来如此。戴妮斯会冲进所有昏暗的、岩洞似的房间,拥抱粗笨的垫子,夸张地表示来这里的开心。不过她确实是发自肺腑。房子散发着旧雪松木味,还有挥之不去的潮气和冬天的耗子味道。每样东西都恒久不变。这里有无聊的扑克牌,教会你加拿大野花的名称;有拼字游戏,其中的y和一个u不见了;有索菲小时候看过的好玩得不行的书,一战时期的卡通书,不配套的碟子,索菲用作烟灰缸的破茶碟,带着要么是金属要么是洗碗水怪味儿的刀叉。
只有索菲用烤箱。她端出硬邦邦的烤土豆、中间夹生的蛋糕和骨头还带血的烤鸡。她从没想过换个烤箱。她是有钱人的女儿,后来变穷了—当了斯堪的纳维亚语的助教,在她的大半个工作生涯中,大学教师都穷困潦倒—养成了古怪的消费习惯。坐火车时总是自带三明治,从不去理发店,但要说送劳伦斯上普通学校,她连想都不愿想。她对木屋非常吝啬,不是因为不喜欢它(其实很喜欢),而是本能让她在漏水处摆上罐子接水,给弯曲的窗框贴上胶带,对地板上的凸起视若无睹(它表明房子有一根柱础坏了)。不管手头多么紧张,她从不考虑卖掉房子周围的地皮—她的兄弟们早就把在她两侧的地皮都卖给了农夫,赚了一大笔。
戴妮斯的爸妈私底下给索菲起了个绰号,这是他俩的秘密:“老挪威人”。貌似他们认识不久后,劳伦斯就对伊莎贝尔形容索菲:“我妈妈不像你们那种普通的妈妈。她能读老挪威语。实际上,她自己就有点像个老挪威人。”
开车去木屋的一路上,他们感觉到索菲已经先到一步,便玩起这个游戏。
“老挪威人的车窗会用黑胶带贴住吗?”
“不会。要是老挪威人的车窗破了,那就永远不会去补。”
“老挪威人最喜欢的广播节目是什么?”
“我们来瞧瞧,我们来瞧瞧。大都会歌剧院?克里斯滕·弗拉格斯塔德[1]唱的瓦格纳?”
“不对。那些太露骨了。太精英了。”
“各国民歌?”
“老挪威人早饭吃什么?”戴妮斯从后座回答:“稀粥!”稀粥是她最讨厌的东西。
“稀粥加鳕鱼。”劳伦斯说,“绝不能跟奶奶提到这个游戏啊,戴妮斯。老挪威人暑假去哪里?”
“老挪威人从来不过暑假,”伊莎贝尔严厉地指出,“老挪威人只过寒假,去北方。”
“斯匹次卑尔根岛[2],”劳伦斯说,“詹姆斯湾低地[3]。”
“坐船巡游,”伊莎贝尔说,“从特罗姆斯[4]到阿尔汉格尔斯克[5]。”
“那里有很多冰吗?”
“嗯,是乘破冰船去的。而且天色昏暗,因为巡游只在十二月和一月进行。”
“难道奶奶不会也认为这很好玩吗?”戴妮斯问。她想象着奶奶从屋里走出来,穿过走廊迎接他们—一个敦实强健、有雀斑的老太太,变白的金发梳成辫子盘在头上,她的旧外套、毛衣和裙子的味道跟这房子差不多。她平静而亲切地欢迎他们,尽管也有点不知所措。她吃惊,是因为看到他们来得这么快,因为他们的孩子长大了,因为劳伦斯突然变得这样兴高采烈,因为伊莎贝尔显得如此苗条年轻吗?她知道他们一路上在车里是如何编排她的吗?
“或许吧。”劳伦斯令人气馁地答道。
“在她读的那些古代诗歌里,”伊莎贝尔说,“你知道那些古老的冰岛诗歌,里面有最可怕的血腥的砍人故事—尤其是女人,其中有一个割断了自己孩子的喉咙,把血掺进酒里给她丈夫喝。我读过那个。可索菲却是这样一个和平主义者、社会主义者,这不是挺怪吗?”
伊莎贝尔早上开车到奥布雷维尔取生日蛋糕。戴妮斯跟她同去,以便在归途中负责抱蛋糕。飞行计划在下午五点。只有伊莎贝尔知道这事,因为上周是她开车送戴妮斯去机场的。这全是戴妮斯的主意。现在她一心担心云层。
“那些条状云是没问题的,”伊莎贝尔说,“只有一堆堆巨大的白色云团才有可能带来暴风雨。”
“积雨云,”戴妮斯说,“我知道。你觉得爹地是个典型的巨蟹座吗?顾家、好吃?恋旧?”
“我猜是的吧。”伊莎贝尔说。
“你第一次遇到他的时候是怎么想的?我是说,是什么吸引你了呢?你知道这个人就是你最后会嫁的那个吗?真不可思议啊。”
劳伦斯和伊莎贝尔邂逅于大学餐厅,伊莎贝尔是收银员。她是大一新生,是个聪明的穷女孩,来自镇上的工厂区,穿件粉色紧身毛衣,劳伦斯一直记得它。
(“伍尔沃斯超市买的,”伊莎贝尔说,“我不大懂。我以为大学联谊会的女生们穿得都挺难看。”)
她对劳伦斯说的第一句话是:“那是个错误。”她指的是他点的餐—牧羊人馅饼。
劳伦斯要么是太窘迫,要么是太固执,不愿更换。“我以前吃过,味道不错。”他说。他拿回找钱后又磨蹭了一会儿,“它让我想起我妈做的饭。”
“你妈想必是个糟糕的厨师。”
“确实。”
他设法打听到她的名字,当晚给她打了电话。“我是牧羊人馅饼,”他颤抖地说道,“愿意跟我看场电影吗?”
“真吃惊你居然还活着。”伊莎贝尔说。这个口无遮拦、穿紧身毛衣的女孩肯定会让索菲大跌眼镜。“愿意。”
这些戴妮斯早已烂熟于心。她想听的是别的信息。“你为什么跟他约会呢?为什么说‘愿意’?”
“他很帅啊,”伊莎贝尔说,“他看起来很有趣。”
“就这些?”
“嗯,他并没有做出一副他是上帝赐给女人的礼物的样子。我跟他说话时他会脸红。”
“他经常脸红,”戴妮斯说,“我也一样。这太可怕啦。”
她想,这两个人,劳伦斯和伊莎贝尔,爸爸和妈妈,想必隐瞒了点什么。他俩之间的秘密。她能感觉到它新鲜地、戏谑地涌出,或者悄悄地、酸涩地隐藏着,但她永远无法搞清那到底是什么,或者是如何起作用的。他们不肯让她搞清。
奥布雷维尔是个石灰岩小镇,沿河而建。让索菲爸爸挣了大钱的铸炉厂仍坐落在河岸边的老地方,部分被改建成一个工艺中心,人们到这里吹玻璃、织围巾、做小鸟笼,现场出售。“沃格申”的字样仍旧高悬在大门上方的石板上,这个德国名字烙在炉子上,第一次世界大战期间导致公司破产。索菲出生的那幢好看的房子现在成了一个护理中心。
定制食品的女人住在镇子新区的街道边—索菲厌恶那些街道,它们最近铺了路面,又宽又黑,修着平滑的马路牙。路边没人行道,也没种树、装树篱或栅栏,只有一些很小的装饰灌木,围着保护网。错层式住宅和牧场风格的房子交替出现。有的车道上铺着闪闪发亮的白色碎石,奥布雷维尔这一带称它们为“白色大理石”。一片草坪上站着三只带斑点的塑料鹿。一个门廊里有一个小小的黑人男孩,举着一盏马车灯。有个宅子的拐角处装了一排粉色灰色交织的大岩石,阻止人们踏地而过。
“塑料岩石,”伊莎贝尔说,“真不知道它们本身有没有重量,还是说要插进地里?”
定制食品的女人把蛋糕端到车边。她身材矮胖,深色皮肤,风姿绰约,大约四十出头,涂着厚厚的绿色眼影,梳着完美的蓬松发型,发色亮闪闪的。
“就等你们呢。”她说,“我得送一些馅饼到兵团去。你想检查一下这个行不行吗?”
“我相信它一定很好。”伊莎贝尔取出钱包说。戴妮斯把蛋糕盒捧到膝盖上。
“真希望我有个这么大的女儿做帮手。”女人说。
伊莎贝尔看了看那两个小男孩—他们大概三四岁—正在草坪上一个充气水池里跳进跳出。“他们是你的孩子吗?”她礼貌地问。
“开玩笑!他们是我女儿的孩子,她把他们丢给我了。我有一个已婚儿子和一个已婚女儿,另外还有一个儿子—我看到他的那次,他戴着摩托车头盔。我很早就成家啦。”
伊莎贝尔沿车道倒车,突然戴妮斯惊讶地嚷嚷起来:“妈妈!是那个飞行员!”
一个男人从边门走出来,正和定制食品的女人说话。
“见鬼,戴妮斯,不要这样吓我!”伊莎贝尔说,“我还以为有个小孩跑到我车轮后头去了。”
“是我们在机场说过话的那个飞行员呀!”
“肯定是她丈夫嘛。好好端着蛋糕。”
“但那不奇怪吗?在爹地的生日?给他做蛋糕的女人和带他坐飞机的男人是一对夫妻。他有可能是啊。他还有个助手。他和助手一起给人上飞行课,带打猎的人飞到瀑布北面,带渔夫飞到不通陆路的湖边。他告诉我的。那不奇怪吗?”
“在奥布雷维尔这样一个小地方,这只算有点怪罢了。戴妮斯,你得留神点那蛋糕。”
戴妮斯泄了气,感觉有点受辱。要是一个成年人吃惊地嚷嚷起来,伊莎贝尔估计就不会那么不耐烦了吧。要是一个大人惊叹于这个奇特的巧合,伊莎贝尔没准会同意说这确实少见。戴妮斯讨厌伊莎贝尔拿她当小孩对待。她奶奶,或者劳伦斯,她觉得都有点固执,不肯变通。这两人向来如此。伊莎贝尔却会在这一刻推心置腹,又友好又讲道理,下一刻就遥不可及、暴躁易怒。有时她对你越好,你越不安心。戴妮斯疑心爸爸对伊莎贝尔也是同样感觉。
今天,伊莎贝尔穿了一件印度棉长裹裙—劳伦斯称之为她的嬉皮士裙子—和一件深蓝色挂脖露背衣。她身材苗条,棕色皮肤—作为一个红发女人,她的肤色晒得很棒—除非你凑近了看,不然她好像只有二十五岁。即使凑近看,她感觉也不会超过二十九岁。劳伦斯是这么说的。他不让她剪短深红色头发,而且监督她晒太阳,一旦她打算挪进阴凉地或者进屋,他就警告地、不安地喊道:“你想上哪儿去?”
“要是由着伊莎贝尔,她会趁我一转身就溜进阴凉地。”劳伦斯对客人们这么说过,戴妮斯听到伊莎贝尔笑着。
“确实。我得谢谢劳伦斯呢。要是由着我自己,我根本没法待多久,一点肤色都晒不出来。我怕中暑啊。”
“要是你有一个迷人的棕色身体,谁管你有没有中暑呢。”劳伦斯带着专断滑稽的表情说道,拍拍伊莎贝尔的比基尼下露出的平坦小腹。
那些有节奏的轻拍,让戴妮斯觉得自己的腹部也紧张起来。为了不失口喊出“住手!”,她唯一的办法就是跳起来,张开胳膊冲到湖边,傻里傻气地喊叫着。
戴妮斯再次看到定制食品的女人,是一年多以后。临近八月底,憋闷、温暖、多云的一天,他们在木屋的夏季逗留已接近尾声。伊莎贝尔去镇上看牙医,那年夏天她定期去看牙医。她在奥布雷维尔接受复杂的牙齿治疗,因为她喜欢这里的牙医胜过渥太华的。索菲自夏天起就没待在木屋里。她在多伦多的威利斯莱医院做检查。
戴妮斯、彼得和爸爸在厨房为午饭做咸肉西红柿三明治。劳伦斯相信他有些东西做得比别人都好吃,其中一样就是咸肉。戴妮斯在切西红柿,彼得负责给吐司涂奶油,但他一心看书。收音机开着,在播午间新闻。劳伦斯喜欢一天听好几次新闻。
戴妮斯去开前门。她一开始没能认出定制食品的女人。她穿了一件比较青春的衣服—一条宽松裙,上面有旋转的红色、蓝色和紫色“迷幻”图案—而且看起来没上回美丽。她的头发耷拉在肩膀上。
“你妈妈在吗?”女人问。
“很抱歉,她这会儿不在。”戴妮斯用一种屈尊俯就、有点刺耳的礼貌语调回答。她以为这女人是来兜售什么东西的。
“她不在,”女人说,“不。她不在。”她的脸肿着,一丝笑意也没有。她的唇膏厚厚的,很滑稽,眼影涂花了。她的声音里充满讽刺,令戴妮斯不得其解。要是为了兜售东西,她可不会用这种语调说话。莫非他们欠她钱?彼得在她的草地上乱跑了,还是欺负她的狗了?
“我爸爸在家,”戴妮斯负疚地说,“你想跟他说吗?”
“你爸爸,是的,我要和他说。”女人回答,把胳膊下面巨大、发亮的红色提包朝上拎了拎。“去叫他来,好吗?”
戴妮斯这才意识到,这是说过“真希望我有个这么大的女儿做帮手”的那个声音。
“定制食品的女人在门口。”她告诉爸爸。
“定制食品的女人?”他用一种不高兴、不相信的声音重复道,好像她是故意捏造出这个女人来打搅他似的。
不过他还是擦干净手,走过大厅。她听到他平静地说:“是的,不错。有什么可以效劳吗?”
他没有很快回来,反倒带女人进了餐厅。他关上餐厅门。为什么要进餐厅?访客都是带进起居室的。搁在餐巾纸上的咸肉要慢慢冷啦。
厨房和餐厅之间的门上有一扇高高的小窗。索菲还是小女孩的时候,厨房里总有个厨师。厨师会透过这扇窗看看用餐的进展,决定何时上菜。
戴妮斯踮起脚尖。
“偷看。”彼得头也不抬地说。他在看一本叫作《魔鬼世界》的科幻小说。
“我只想知道什么时候可以做三明治。”戴妮斯说。
她发现进餐厅是有道理的。她爸爸坐在他通常的位置上,在餐桌一头。女人坐在彼得平时的位置上,靠近大厅门。她把皮包放在桌上,双手按住。不管他们在谈什么,看来都需要一张桌子和一些直背椅子,以及一种直挺挺的严肃坐姿。这有点像一场访谈。给出信息,提出问题,斟酌考虑。
好吧,随便吧,戴妮斯想。他们在讨论一件事。总会讨论完,解决它,这事总会过去。爸爸会解释给家里人听,或者不告诉他们。它总会过去。
她关掉收音机,做了三明治。彼得吃了他那份。她等了一阵,也把自己那份吃掉。他们喝了可乐,爸爸允许他们午饭时喝。戴妮斯吃得太快了。她坐在桌边安静地打嗝,回味咸肉的滋味,突然听到一种可怕的声音,一个陌生人在他们家里哭。
爸爸生日那天,在飞机上,他们看到一些精致的,几乎是透明的云团飘在西边的空中。戴妮斯说:“积雨云。”
“不错,”飞行员说,“不过它们还远着呢。”
“那想必很传奇吧,”劳伦斯说,“在积雨云中飞行。”
“有一次我往外一看,螺旋桨周围有一圈蓝光,”飞行员说,“在螺旋桨和翼尖位置。我看到机头位置也有。我伸手摸了摸玻璃—就是这里,树脂玻璃—手刚凑近,火焰就从我的手指上喷出来了。我都不知道有没有碰到玻璃。什么感觉也没有。小小的蓝色火焰。在大雷雨中遇到过那么一次。那就是人们所谓的圣艾尔摩之火。”
“是大气中的电流造成的。”彼得从后座上喊道。
“说得对。”飞行员大声回应道。
“真神奇。”劳伦斯说。
“把我吓了一大跳。”
戴妮斯在脑海中想象着飞行员的指尖射出冰冷的蓝色火焰,觉得那应该标志着痛苦,尽管他说没任何感觉。她想起碰到一道通电的篱笆那回。餐厅传来的声响让她想起来了。彼得仍在看书,他们没交谈,尽管她知道他也听到了。
玛歌达在厨房做沙拉。她哼着一首歌剧里的调子。《回到我们的山居之家》。戴妮斯在餐厅铺桌子。她听到爸爸在院子里的笑声。客人们已经到了—两对快乐、有钱的夫妻,而不是什么住度假屋的人。一对夫妻来自波士顿,另一对来自蒙特利尔。他们在维斯特菲尔德都有避暑宅子。
戴妮斯听到爸爸说:“厌世。”好像是在引经据典。想必他引用的是他们都看的某份杂志上他们都知道的一个说法吧。
我应当像彼得一样,她想。不应当再来这儿。
但或许没什么,或许这其实是一种快乐,只是她太固执,太幼稚,太富有政治性—太深陷于一段所有其他人都已淡忘的过去—以至于无法接受?
餐厅扩大了,容纳了原先走廊的一部分,扩大的部分全由玻璃构成—墙和斜顶都是。在渐渐变黑的玻璃上,她看到自己—一个高挑、拘谨的女人,梳一条长辫,衣着异常朴素,坐在长长的松木桌边,在一碗碗美丽盛开的旱金莲、一个个装满盐的蓝玻璃小碟子当中。红橙相间的亚麻餐巾,小团黄油似的圆形黄蜡烛,边缘绘有葡萄的厚厚的白色乡村盘子。一重重即将端上的食物和美酒,还有谈话,它打破了家居的气氛:一重重和谐与满足。
玛歌达搅着沙拉,不再哼歌。
“你妈—她快乐吗,在不列颠哥伦比亚?”
都怪她,戴妮斯想。都怪伊莎贝尔。
不公平、不由自主的想法竟会突然来袭,粗鲁地、莫名其妙地回荡在心头。
“是的,”她说,“我想是的吧。”意思是,至少伊莎贝尔没什么可懊悔的吧。
二
地板被索菲踩得直抖。一大早,她光着脚,身上只裹件条纹毛巾浴袍。打她还是个孩子、湖边一直到布莱斯的农场为止的所有土地都属于她爸爸的时候起,她就习惯到湖里裸泳。如今她要是还想这样,就得一大早起床。这个容易。她醒得早。老年人都是如此。
游完泳后,她喜欢坐在岩石上,抽一天的第一支烟。她这会儿在找的就是这个—不是烟,而是打火机。在水槽上方的架子上找,在刀叉抽屉里找—本来没想弄出这么大动静—又在餐厅柜子上找。然后她想起来,昨晚坐在起居室里看电视上的《大卫·科波菲尔》。果然,打火机就躺在印花棉布裹着的椅子脏兮兮的扶手上。
劳伦斯租了一台电视,让大家看月球登陆。她同意这个事件孩子们不该错过—劳伦斯严厉地修正道,他们全都不该错过—但她觉得或许只租二十四小时,让电视在家里摆一夜就够了。劳伦斯指出她的错误。发射在星期三,也就是后天,然后一切顺利的话,星期天才能登陆。她难道以为旅程只要几个小时就够了吗?劳伦斯说,要是等到最后再租,那就根本没希望租到什么像样的电视。所有住度假屋的人都会抢着去租的。所以他们提前十天就租了一台,电视机还没进门,劳伦斯就制订了战略计划,那就是要让索菲学会看电视。他幸运地发现去年冬天的《国家地理》节目正在重播。一个是关于加拉帕戈斯群岛的,索菲对它并不抗拒。还有一个是关于美国国家公园的,她评价说很不错,只是美国人自我吹嘘的味道未免重了点。然后是《大卫·科波菲尔》,一出英国连续剧,星期天晚上一播就是好几个小时。
“这下你知道一直以来都错过些什么了吧?”劳伦斯对索菲说。她这些年一直拒绝买电视—不仅在木屋,在多伦多她的公寓也是如此。
“哎哟,劳伦斯。别得寸进尺。”伊莎贝尔说。她语调亲切,却令人厌烦。索菲没接腔儿,不过比起劳伦斯,她更厌烦伊莎贝尔。这女孩对自己的丈夫是多么无知啊,竟然指望他会默默享受胜利。她对索菲又是多么无知啊,竟然以为劳伦斯的紧逼不舍会惹恼她。其实他向来如此—他们都已习以为常。他会对索菲磨了又磨,不管逼她做了多少,对他来说永远不够。索菲对于电视的投降远不足以让他满意。她还没真正喜欢它,劳伦斯一清二楚。
台阶的事也一样。(索菲正爬下那些木头疙瘩,费力地朝水边挪去。)索菲不想要水泥台阶,宁愿选择嵌进湖岸的圆木台阶,不过最后她还是屈从了,因为劳伦斯抱怨木头会烂,更换它们的苦差事总是落到他头上。现在他每天都会打电话给她,查问他的成就。
“我造的可是能管好多年的。”他豪迈地宣称。他给他们每人都造了一级纪念台阶:盖个手掌印,刻上姓名缩写,还有日期—1969年7月。
索菲从岩石上滑进水里,朝湖中间的阳光地带游去。接着她翻身仰泳。尽管沿岸遍布小屋,但大多数人都很谨慎,没砍掉树丛。她可以躺在水里,看那些松树和杉树、白杨和软枫木、白色和金色桦树组成的高高树岸。没有风,湖上也没什么涟漪,只有索菲拍打出来的几道水纹。然而桦树和白杨树叶兀自翻动,在阳光中闪闪发亮,像硬币一样。
不只是树叶有动静。索菲看到几个人影。他们走下湖岸,从她搁浴袍的岩石后面的树丛中冒出来。她伏低身子,改浮水为踩水,观察着他们。
两个男孩和一个女孩。三人都蓄着长发,差不多都长及腰部,其中一个男孩头发朝后梳,扎成一根马尾辫。马尾辫男孩蓄着胡子,戴着墨镜,光身套件西装外套。另一个男孩只穿着牛仔裤,瘦瘦的棕色胸膛上挂着几条像是羽毛做的链子或项链。女孩身子肥胖,像个吉卜赛人,穿一条长长的红裙,额头上系一条印花帕。她把裙子在前面扎一个松松的结,便于爬下湖岸。
这种模样的孩子—年轻人们—对索菲来说当然不算新鲜。周末时你会看到很多这样的人在湖边晃荡—住小屋的人的孩子们,他们过来玩耍,带来朋友。有时他们会占着小屋,没有父母管束,整个周末开聚会。业主通报上提议禁止长发和“奇装异服”,希望各位业主在自己的物业范围内展开自行监督,并邀请人们写信,对这项禁令表示支持或反对。索菲写的是反对信。她在信里写道,这整片湖一度都是沃格申家的产业,而奥古斯塔·沃格申抛弃了俾斯麦德国相对舒适的条件,就是为了到新世界寻找自由,这里的每一个人都应当有权决定穿什么、说什么、信什么,等等。
不过她相信这三个人不是来自任何一幢小屋。他们肯定是私自闯入者,流浪汉。为什么这么想呢?因为他们有点偷偷摸摸的感觉—以及某种胆大妄为、不屑一顾的味道。不过,她想他们不至于做出什么伤人的举动。无非是些自恋的表现者,谈不上真正的入侵者吧。
他们看到了她的浴袍,正越过水面看着她。
索菲挥挥手,嚷道:“早上好啊!”用的是一种打招呼的开心语调—表示这问候就是全部,到此为止。
他们没挥手,也没回答。女孩坐下了。
打赤膊的男孩抓起索菲的浴袍穿上。他在她的口袋里摸到香烟和打火机,扔给女孩,后者取了一根香烟点上。另一个男孩坐下来,拽下靴子,光着脚拍水。
穿浴袍的男孩跳了一阵摇摆舞。他的头发是黑色的,在肩头波动,闪烁着美丽的光芒。他在模仿某个女人,尽管可以肯定地说,模仿的不是索菲。(她现在觉得,他们有可能一直在偷看她,看到她脱下浴袍,跳进水里。)
“请脱下那个好吗?”索菲喊道,“欢迎抽根香烟,不过请把它们放回口袋!”
男孩又跳了一段摇摆舞,不过这回背对着她。另一个男孩笑了。女孩抽着烟,对这些置若罔闻。
“脱掉我的浴袍,放回我的香烟!”
索菲朝湖岸游来,头部抬在水面上。男孩拽下浴袍,抓起来一撕两半。穿旧的布料一撕就裂。他往水里走几步,把它朝水中扔去。
“你这小混蛋!”索菲嚷道。
他把另一半也扔出来。
梳马尾辫的男孩穿上靴子。
黑发男孩把手伸给女孩。她摇摇头。他猛地探进她裙子的皱褶中,她抗议地叫起来。跟着浴袍碎片之后,他把别的什么东西也丢进水里。
索菲的打火机。
索菲听到女孩说了句什么—听起来像是“你这该死的脏鬼”—然后他们三个头也不回地朝湖岸爬去。黑发男孩优雅地大步走着。另一个男孩快步跟在后面,有点笨拙。女孩穿着扎得高高的裙子,费劲地走着。索菲爬出水面,攀上岩石的时候,他们全都已经消失不见。
女孩的香烟—索菲的香烟—没掐熄,只是随手丢在一小堆泥土上—岩石当中的一小堆泥土和碎石块上。
索菲坐在岩石上,凌乱地、深深地喘气。她没发抖—因为一股凌厉徒劳的怒火而燃烧着。她拼命让自己平静下来。
她回忆着童年时代经常系在这里的一艘划桨船。一艘安全、笨拙的老划桨船,在码头边的水面上摇晃。每天傍晚吃完晚饭,索菲,或者索菲和她弟弟中的一个(两个弟弟都已过世了),不过通常只有索菲一人,划船去布莱斯的农庄取牛奶。她随身带一个带盖罐子,由沃格申家的厨师擦洗打磨得干干净净—你可不能对布莱斯家的任何容器放心。布莱斯家没码头。他们的房子和谷仓都面对大路,背湖而建。索菲不得不把船划进芦苇丛,把绳子丢给跑来迎接她的布莱斯家的孩子们。他们噼噼啪啪跑过泥水,拽着绳子爬上船,索菲不停地嚷嚷着每次都要重复的训话。
“别把船桨拿出去!别让它沉下去!别全都趴在船的一侧!”
她会像他们一样光着脚跳出船去,跑到石头牛奶房。(它还在,据索菲所知被一个住小屋的人拿来当暗室了。)布莱斯先生或者布莱斯夫人把温热多沫的牛奶倒进罐子。
布莱斯家的孩子有几个和索菲一般年纪,另几个比她大,但全都比她矮小。到底有几个?都叫什么来着?索菲记得有一个芮塔,一个谢尔顿或者谢尔文,一个乔治,一个安妮。不管夏天的太阳有多大,他们总是皮肤苍白,身上到处都是虫咬伤、挠伤、结痂、蚊子咬的疙瘩、墨蚊咬的疙瘩、虱子咬的红斑,血淋淋地化着脓。因为他们都是穷孩子。因为穷,所以芮塔—或者是安妮—长了双对眼,还有个男孩肩膀不对称,古怪极了,而且他们说的话和举止一样乱七八糟、毫无章法,尽说些“俺们往城里跑”和“桨子”之类索菲几乎听不明白的话。没人会游泳。他们对待这船,好像它是一件奇怪的家具—某样可以爬过去、钻进去的东西。他们对划桨一无所知。
索菲喜欢单独去拿牛奶,不带任何一个弟弟,这样就可以多待一会儿,和布莱斯家的孩子们聊聊,问点话,教他们点东西—她的弟弟们做梦也不会想到做这些。他们在哪里上学?圣诞节收到什么礼物?会唱什么歌吗?他们熟悉她之后,就会向她透露一些,给她讲公牛挣脱绳子,冲到大门口的事,还有他们看到一团闪电飞过卧室地板,还有谢尔文脖子上的大疙瘩,以及里面涌出了什么。
索菲想邀请他们到木屋玩,梦想给他们洗澡,换上干净衣服,在他们身上的咬伤上涂点药膏,教会他们正确地说话。有时她会做长长的、复杂的白日梦,全都是关于如何给布莱斯一家过圣诞节的。包括对他们的房子进行重新装饰和涂色,以及给他们的院子来个彻底大清扫。神奇的眼镜出现了,可以纠正对眼。还有一些图画书和电动火车,穿塔夫绸裙的洋娃娃,成队成队的玩具士兵和一堆堆杏仁蛋白软糖做的水果和动物。(杏仁蛋白软糖是索菲最喜欢的点心。在与布莱斯家的孩子们的某次交谈中,她得知他们对它一无所知。)
过了一阵,她真的得到妈妈允许,邀请他们中的一位来做客。她邀请的那个—芮塔或者安妮—临阵退缩了,因为害臊,所以另一个替她来。这个安妮还是芮塔穿上索菲的一件游泳衣,它可笑地耷拉在她身上。她可真不好招待。她不愿作任何选择,不肯说想要哪种三明治、饼干或饮料,也不愿选择是去玩秋千还是玩跷跷板,或者是去水边玩还是玩洋娃娃。她不肯选择,这使她显得挺孤傲,好像她遵守着某种索菲不得而知的行为规范。她吃你给她端来的任何东西,任由索菲推着她荡秋千,不管干什么,总是固执地一脸无趣。最后,索菲带她到水边,玩起抓青蛙的工程。索菲打算把一整窝青蛙从码头一侧迁到另一侧,从长满芦苇的小水湾挪到岩石中一个有凹凸洞穴的舒适地儿。青蛙们由水路展开这场旅行。索菲和布莱斯家的女孩把它们抓来,放在一个轮胎上,推着绕过码头—水很浅,布莱斯家的女孩可以蹚水—到它们的新家。这一天结束时,青蛙一家已经全搬过去了。
布莱斯家的女孩,还有几个小一点的孩子,几年后都在他们家的一场大火中丧生。或者也可能死的是另一个,那个不肯来的女孩。她的一个哥哥继承了农场,把它卖给了开发商,后者据说讹了他一笔。不过这个哥哥买了一辆大汽车—好像是凯迪拉克?—过去,索菲夏天常在奥布雷维尔遇到他。他会斜斜地瞥来一眼,表明没兴趣搭话,除非她主动开口。
索菲记得给劳伦斯的爸爸讲过青蛙搬家的故事—他是个德语教师,她第一次吸引他的注意,是因为在班上就某个威斯特伐利亚的发音问题与他展开激烈争论。读研究生时,她已经无可救药地爱上了他。她怀孕了,出于自尊,没提出要他脱离他的生活,离开他妻子,跟她住到木屋,陪她生下劳伦斯。不过她相信他自会这么做。他确实来了,不过只有两次,是作为客人。他们坐在码头上,她给他讲了青蛙和布莱斯家女孩的故事。
“当然咯,第二天它们全都回到了芦苇丛中。”她说。
他笑了,亲切友爱地拍拍她的膝盖。“哎呀,索菲,你瞧。”
今天是劳伦斯四十岁生日。她儿子出生于攻占巴士底狱纪念日。她寄去一张明信片:男囚七月十四日获释,八磅九盎司。他妻子是怎么想的?她不得而知。沃格申一家富有尊严地处理了这事,索菲转到另一所大学继续攻读学位。她从未对结婚与否扯谎。不过劳伦斯在学校里捏造出一个爸爸—他妈的大表哥(因此他们姓氏相同),他在一次独木舟旅行中淹死了。索菲表示可以理解,不过其实对他挺失望的。
下午迟些时候,索菲发现自己坐在一架飞机里。她以前飞过两次—都是搭乘大飞机。她没想过自己会害怕。她坐在后座上,两侧是兴高采烈的孙子孙女。戴妮斯和彼得—劳伦斯和飞行员坐前排—事实上,她搞不清这会儿的感觉是否就是恐惧。
小飞机似乎根本没在移动,尽管马达并没有停止。它发出可怕的轰鸣。他们在空中盘旋,离地大约一千英尺。下方是刺柏灌木丛,铺展在田野里,像一团一团针插。雪松变成小巧的玩具圣诞树。深色水面上有闪闪发亮的波纹。所有东西都像玩具一样精巧完美,这让索菲有一种特别的、难受的感觉。她觉得仿佛是自己,而不是地面上的东西缩小了,而且仍在不断收缩—或者说,他们全都在收缩。这种感觉如此强烈,以至于她现在变得小小的、蟹爪似的手脚感到一阵麻刺—一种极度细微的麻刺感,或者说是一种极度的细微造成的麻刺感。她的胃收缩了,肺变得像空荡荡的植物籽囊一般弱小,心脏只有一只甲虫的心脏那么大。
“很快我们就要飞到湖面正上方啦。”劳伦斯告诉孩子们,“瞧见没,田地全在这一头,树丛都在那一头。看啊,这一头是石灰石上的泥土地,那一头是前寒武纪地盾。一头是岩石,一头是芦苇。这就是所谓的界崖线湖了。”(劳伦斯学过,也热爱过地理,她一度以为他会当个地理学家而不是商人。)
这么说他们在移动,很慢很慢地。他们正飞过湖面。在右边,索菲看到奥布雷维尔铺展着,上有硅矿的白色裂隙。她的感觉,关于犯了个错误,遭遇了某个莫名其妙、难以表述的问题的感觉,并不曾消退。从金灿灿的空气中,她感觉到的并非灾难的来临,而是它的后果—仿佛他们全都被掸飞,消灭,团成小团,压缩成原子,可自己却茫然不觉。
“让我们瞧瞧能不能看到木屋的屋顶。”劳伦斯说,“我外公是个德国人。他在树林里造了房子,有点像一幢狩猎小屋。”他告诉飞行员。
“是吗?”飞行员说。关于沃格申家,他估计至少知道这个吧。
这种感觉—索菲意识到—对她来说并不陌生。她小时候就有过。一种真正的收缩感。你很小的时候经常会感受到这类吓人的强烈感觉,陷入这样的心理状态。就和头朝下吊着、走在天花板上、跨过高高的门槛时的感觉一样。小时候,这可是一种强烈的快乐,为何现在不再是了呢?
因为现在不是她的选择。她确定无疑地感觉到变化即将出现,而这不是她的选择。
劳伦斯把屋顶指给她看,木屋的屋顶。她心满意足地惊叹着。
仍在缩小,卷成令人难受的点儿,不过并没彻底消失,在这一步上她撑住了。她竭尽全力,在这一步上撑住了,而且对孙子孙女们说看这里啊,瞧那里啊,看啊,地面上那些形状,看啊,水里的影子和光线。
三
自个儿坐着就是我老婆的最大乐趣。
伊莎贝尔躲在几棵干瘦的白杨树的树影里,坐在汽车边的草地上想,今天这样一个愉快的家庭聚会之日,真是障碍重重,但她到目前为止都一一化解了。早上她醒来时,劳伦斯想做爱。她知道孩子们已经醒了。他们正在楼下戴妮斯的房间里忙碌,准备今天的第一份惊喜—一张上面有一首诗的海报、一首生日歌,以及一份给爸爸的抽象拼贴画。要是劳伦斯因为他们冲进来而被打断—或者被他们捶门的声音干扰,假如说她爬起来闩上门的话,那他的情绪肯定好不了。戴妮斯会很失望—事实上,会悲痛万分。这一天可就有了个糟糕的开头。不过,推开劳伦斯,跟他解释孩子们的计划,似乎也不妥。那样一来,无异于表明他们的位置先于他,他们的感受更让她在意。因此,最佳策略看来就是催促他赶紧完事,她正是这么做的。即使索菲在楼下走来走去,发出沉重的脚步声,不停地开开关关厨房的抽屉,让他暂时分了点神,她也仍旧不断地催促他。
“老天爷啊,她到底怎么啦?”他对着伊莎贝尔的耳朵喃喃道。而她只是拍打着他,似乎急不可耐,要他再猛点再快点。果然有效。很快就完事了。孩子们跑过大厅,发出模仿号角的一阵乱七八糟的喇叭声的时候,他正握着她的手仰躺着。孩子们推开父母的房门,举着一张巨大的海报跑进来,上面用五彩蜡笔精心写着生日诗。
“致敬!”他们齐声嚷着,一边鞠躬,放低海报。戴妮斯裹着一张床单,抓着一根裹锡箔的棍子,棍子一头粘了颗银色纸星,伊莎贝尔的大多数项链、链子、手镯和耳环都挂在它周围,或者戴在戴妮斯身上。彼得只穿着睡衣。
他们开始背诗。戴妮斯的声音高亢,声情并茂,尽管不乏自嘲。彼得念得拖沓,慢吞吞的,公事公办,还有点不屑为之的意思。
祝贺啊,你的四十岁生日,
它是你幸运一生的一个里程碑!
而我啊,是一个仙后,
亲自前来祝你健康富有,拥有爱情和欢乐!
彼得拖后半拍背诵道:“而她啊,是一个仙后,亲自前来……”背完之后,戴妮斯说:“实际上,我是仙女娘娘,但那样音节太多了。”她和彼得鞠躬如仪。
劳伦斯和伊莎贝尔笑着鼓掌,请求凑近一点看看生日海报。诗歌四周贴了很多从杂志上逐一剪下的形象、场景和话语。插图均与过去一年里,伟大的L.P.沃格申(“劳逸结合”劳伦斯·彼得)的生活经历有关。一次到澳大利亚的商务旅行由一只跳过艾尔岩的袋鼠和一瓶驱虫剂表示。
在令人激动的旅行之余,后是图下注释,伟大的L.P.挤出时间享用他的特殊爱好(一个兔女郎晃着漂亮的尾巴,举着一瓶跟她本人一般高的香槟),与亲爱的家人共度美好时光(一个对眼女孩吐着舌头,一个家庭主妇威胁地挥舞着一根拖把,一个全身泥泞的顽童头手倒立)。他还考虑干份第二职业(画面上是一个水泥搅拌器与一个怪老头的形象重叠)。“生日快乐,伟大的L.P.。”成群的农场动物戴着宴会帽,举着气球说:“我们都是你的忠实粉丝。”
“实在太棒了,”劳伦斯说,“看得出,你们费了不少心。我特别喜欢‘特殊爱好’那部分。”
“还有‘亲爱的家人’,”戴妮斯说,“你难道不也爱他们吗?”
“还有‘亲爱的家人’。”劳伦斯说。
“现在,”戴妮斯说,“仙女娘娘准备实现你三个愿望。”
“其实只要一个就够啦,”彼得提醒道,“你只用希望其他的愿望都能成真。”
“这种许愿是不允许的,”戴妮斯说,“你可以有三个愿望,不过都得是具体的东西。你不能希望你会永远快乐之类,也不能许愿说你希望实现所有愿望。”
劳伦斯说:“真是个专制的仙女娘娘。”然后表示希望今天天气晴朗。
“已经是了。”彼得厌烦地指出。
“好吧,那我希望一直是晴天。”劳伦斯说。然后他希望能够做完六级台阶,早饭能有煎西红柿、香肠和炒蛋。
“真走运,你要的是煎西红柿,”伊莎贝尔说,“烤箱的煎烤顶层还能用。要是让仙女娘娘给索菲变出一个新烤箱,我想难度未免也太大啦。”
他们在厨房热闹地做早饭,想必盖住了索菲在湖边的叫喊声。他们打算在走廊上用餐。戴妮斯在野餐桌上铺了一张桌布。他们鱼贯而出,戴妮斯端咖啡碟,伊莎贝尔捧热食物盘,上面是鸡蛋、香肠和西红柿,彼得端着他自己的早饭,内容是干麦片和蜂蜜。劳伦斯本来应当什么也不用拿,不过他还是抓起装着涂好奶油的吐司的架子,免得它被落下。
他们刚刚走进走廊,索菲就从湖岸顶端冒出,一丝不挂。她穿过修剪过的草坪,径直朝他们走来。
“我遇到了一个小事故。”她说,“生日快乐,劳伦斯!”
这是伊莎贝尔头一回看到一个赤裸的老太婆。有好几点令她始料未及。与索菲的脸、脖子、手臂和手上皱巴巴的皮肤相比,她身体其余部分的皮肤出奇地光滑。乳房很小。(索菲穿着衣服的时候,伊莎贝尔总以为她的乳房和她身体其余部分的比例是协调的。)它们像小小的口袋,小小的吊着的口袋,在她布满雀斑的宽宽的胸上耷拉着。阴毛稀疏,颜色也令人意外。没变成白色,而是保持着发亮的金棕色,像非常年轻的女孩的私处一样只覆盖着薄薄一层。
那一大片白皮肤,松松垮垮的,让伊莎贝尔想起法国牛,那些脏兮兮的白牛群,有时你可以在农夫的田里看到它们。夏洛莱牛。
索菲当然毫无用胳膊挡住胸前,或者用手谦逊地捂住私处的打算。她也没有快步从家人面前走过。她站在阳光中,一只脚踩上走廊的最低一级台阶—把暴露在他们眼皮底下的隐私范围稍微又扩大了一点—平静地解释道:“在湖边,有人抢走了我的浴袍。我的香烟和打火机也没了。打火机掉到湖底去啦。”
“天哪,妈妈!”劳伦斯惊呼。
他匆忙把吐司架一放,弄翻了它。他把碟子推到一边,抽出桌布。
“接着!”他说,把桌布朝她扔去。
索菲没伸手接。桌布掉在她脚下。
“劳伦斯,那是桌布!”
“别管了,”劳伦斯说,“把它披上!”
索菲弯腰捡起桌布,打量一番,好像在研究上面的花样,然后把它随手围在身上,动作不紧不慢,而且裹得松松垮垮。
“谢谢你,劳伦斯。”她说。她摆弄着桌布,正好露出那些最不该露出来的地方。她朝下看看,补充道:“希望这能让你开心点。”她接着讲她的故事。
不,伊莎贝尔想,她不可能真的浑然不觉。这肯定是故意的。这肯定是场游戏。狡猾的故作天真。这个夸张的老卖弄者。卖弄她的无邪、她的高洁、她的单纯。怪异的老骗子。
“戴妮斯,快点再去找块布。”伊莎贝尔吩咐,“难道我们就看着这些食物冷掉吗?”
目的就是—索菲的目的始终就是—让儿子出洋相。要让他在老婆孩子面前出洋相。而他果然上当了。他站在走廊上,在索菲上方,羞愧的热血一直涌到他的脖子,刺灼着他的耳朵。他费劲地压低声音,做出一副男子汉的谴责口气,却按捺不住颤抖。这就是索菲一有机会就能做到,也必定会做的事。
“那些坏小子多放肆啊。”伊莎贝尔应着索菲的讲述说,“我总以为他们都该可爱、快乐、上进什么的才对。”
“要是你记得穿件游泳衣,就什么事都不会有了。”劳伦斯说。
然后是去拿蛋糕的旅行,一路担心它能否顺利到家,时刻要督促戴妮斯把它好好捧着。还有一场单独的旅行,到海威超市买熟透的批量种植的西红柿,劳伦斯觉得它们比你在商店买的西红柿都要好吃。伊莎贝尔不得不计划一份能快速成形的晚餐。必须是某种等他们一起从机场返回、饥肠辘辘的时候,可以飞快烧好或热好的东西。还应当是某种劳伦斯特别喜欢,索菲不会觉得过于古怪,彼得又愿意吃的东西。她决定做红酒鸡,尽管她还不大肯定索菲和彼得能否接受它。毕竟,今天是劳伦斯的好日子嘛。她整个下午都忙着做饭,注意时间,督促他们准时出发去机场,免得戴妮斯陷入焦虑。
虽然有她盯着,他们还是有点晚了。她站在台阶顶上招呼劳伦斯,他应了一声,却迟迟没有出现。伊莎贝尔只好跑下去告诉他时间紧迫,有一个为他的生日安排的意外惊喜,要是他不快点,一切就全完了—此外,那是戴妮斯专门设计的,而她已经坐立不安了。即便如此,劳伦斯好像还是故意不紧不慢,花了比平时更长的时间梳洗、更衣。他不赞成因为戴妮斯会焦虑就弄得手忙脚乱的。
不过他们还是到达了,现在全体,除了伊莎贝尔之外,都坐上了飞机。那可不是原先的计划。原本的计划是:他们一起开车去机场,解开劳伦斯的蒙眼布,给他一个惊喜,大家目送他登机,展开生日之旅,再欢迎他返回。
不过飞行员从用作办公室的小屋走出来时,看到他们都在,便说:“我带你们一家上去怎样?咱们开那架五座飞机好了—这样你们可以飞得舒服些。”他对戴妮斯笑笑,“不会多收你钱。反正是今天最后一单生意了。”
“你真是太好啦。”戴妮斯敏捷地回答。
“就这么办,”飞行员看看他们说,“不过得去掉一个人。”
“我吧。”伊莎贝尔说。
“希望你不是因为害怕,”飞行员眼光锁定她说,“那可没必要。”
他四十多岁—或许五十岁了—一头非常浅的金色或者白色波浪发,从额头朝后直直梳去,或许那是褪成白色的金发。他个头不高,比劳伦斯矮,不过肩膀结实,胸部和腰部肌肉紧实,皮带上方微微鼓突的肚子也紧绷绷的,毫不松垮。一个高高的弧形额头,明亮的蓝眼睛像搞户外的人一样时不时习惯性地眯缝着,一副专业人士的冷静派头,心平气和。他的声音也有同样特点—心平气和、不紧不慢、略带憨态的乡下口音。她知道劳伦斯会怎么评价—他会说这人是条朴实的汉子,却不会注意到他的另一面—骨子里藏而不露的几分戒备,以及对于他们的不以为然甚至是轻蔑。
“你不怕吧,是吗,夫人?”飞行员对索菲说。
“我没坐过小飞机,”索菲说,“不过我想不怕吧,不会。”
“我们全都没飞过小飞机,一定会很棒。”劳伦斯说,“谢谢!”
“我就自个儿在这里坐会儿好了。”伊莎贝尔说,劳伦斯笑了。
“自个儿坐着就是我老婆的最大乐趣。”
就算果真如此—没准还真是的,因为她并不害怕,最多只是隐隐有点怕而已,但她却衷心希望独自留下—就算果真如此,这听起来也不像什么赞美之词吧。她坐在那儿回顾她这一天,感觉就是在不断克服一个又一个难关。炉子上等着的红酒鸡、安全到家的蛋糕、顺利买到的酒和西红柿,这个到目前为止尚未出现什么真正的错误或者破坏或者失望的生日。接下来只剩开车回家,然后吃晚饭了。明天劳伦斯要去渥太华待大半天,晚上才回来。他星期三要和他们一起看月球登陆。
像这样回顾她的生活,想着:好,不错,这关总算过了。过关喽,这对她可没什么好处。盼着把这关,这关,还有这关都过去,她期待什么呢?她想得到什么呢?
是自由吧—甚至都不是自由。是空空如也,或者是免受关注。似乎她总是在强迫自己再投入一点—再注意一点,热情一点,用心一点—比她确定自己能做到的再多一点。她一直在努力,免得被人发现,发现其实她骨子里和老挪威人索菲一样铁石心肠。
有时她觉得自己被带回他家,首先就是作为一种对索菲的微妙挑战。劳伦斯与她一见钟情,但他的爱与这挑战并非毫无关联。她身上相当矛盾的各方面都起了作用:她放荡的模样和糟糕的举止(到底有多放荡、多糟糕,那会儿她浑然不自知);她的高分和她认为它们证明了智慧的天真想法;她作为工薪阶层高中的最出色学生,一个毫无野心的家族里的变种而染上的所有特点。
“她可不是你通常看得中的那种商业广告,对吗,妈妈?”劳伦斯当着伊莎贝尔的面这样问索菲。他上了大学里索菲讨厌的那个学院—工商管理。
索菲不予评论,只是对伊莎贝尔微笑着。笑容里没有恶意,也不曾表露出对劳伦斯的不屑—它看起来很平和—不过它明显在说:“你准备好了吗,你能接受这个吗?”那会儿一心爱慕劳伦斯的英俊相貌、聪明才智和远大前程的伊莎贝尔明白这个意思。它意味着她决定去爱的这个劳伦斯(尽管她样子放荡、举止无当,但她其实是个严肃、毫无经验的女孩,相信终生不渝的爱情,无法想象任何别的爱法),对这个劳伦斯,她将不得不煞费苦心,用鼓励,还有精心的安排,支持他,敦促他。他要依赖她的帮助来成为男人。她不喜欢索菲提醒她注意这一点,她也没让它影响她的决定。这就是爱吧,或者说,这就是生活吧,她对此跃跃欲试。她其实挺孤单,却以为是自己喜欢独处。她是她妈妈第二次婚姻唯一的孩子。她妈妈去世了,异母哥哥和姐姐都比她大很多,早已结婚。家族里的人都知道她自以为与众不同。她现在仍享有这个名声,自从和劳伦斯结婚后,她就几乎不再见娘家亲戚了。
她大量阅读,认真地节食和锻炼。她成了一位出色的厨师。在聚会上,她和逢场作戏的男人们调情。(她注意到要是她不引起一些关注,劳伦斯就会很失望。)有时她想象自己在大多数一时兴起、虚情假意的狂热关系中充任伴侣,被那些男人,或别的人压制着。有时她想起童年,心头涌起一阵几乎称得上怪异、不宜公开的向往。街角小店前松松垮垮的雨篷、中午时分烹饪的浓香、一棵巨大城市遮荫树的树根周围的垃圾和泥土,都会让她若有所思。
飞机着陆后,她起身去迎接他们。她吻了劳伦斯一下,好像他刚从远方回来似的。他看起来很开心。她想,她很少在乎劳伦斯是不是开心。她只是希望他心情好,以便诸事顺利,那不是一回事。
“太棒啦,”劳伦斯说,“你可以一清二楚地看到地形变化。”他解释起界崖线湖。
“真有趣啊。”索菲说。
戴妮斯说:“你可以一直看到水里,可以看到岩石伸进去,甚至可以看到沙子哦。”
“你都可以看到有什么船。”彼得说。
“我是说真的,妈妈。你可以看到岩石伸下去,往下再往下,然后就是沙子啦。”
“能看到鱼吗?”伊莎贝尔问。
飞行员笑了,尽管他肯定常听到这类问题。
“你没来,真是太可惜了。”劳伦斯说。
“哦,她会的,总有一天,”飞行员说,“她明天就可以来嘛。”
他们全都笑了起来。他大胆的目光接上伊莎贝尔的,尽管看起来胆大妄为,却依旧显得极其纯洁、友好、亲切,里面并不乏尊敬之情。他大概是个没什么恶意,也不会起什么蠢念头的男人,所以几乎不大可能是在对她发出邀请。
他对他们一群人说再见,他们又谢了他一回。伊莎贝尔觉得,她知道自己为什么心慌意乱。因为索菲的故事。仿佛是她自己,而非索菲,赤身裸体从水里爬出,走向那些为非作歹的男孩。(她在想象中抹掉了那个女孩。)是这个让她渴望并想象出了一个胆大妄为的邀请,让她为之蠢蠢欲动。
他们走向汽车,她得努力才能不让自己回头。她想象他俩同时回头,彼此对视,就像在一部浪漫电影,某个言情故事,或者一则高中生的幻想中一样。他俩同时回头,彼此对视,交换了一个几乎是真心诚意的承诺,尽管他们或许根本不会再见面。这个承诺像闪电一样击中她,像闪电一样劈开她,可她始终婷婷袅袅地走着,若无其事。
哦,当然啦。所有那一套。
不过,那其实不像闪电,根本不是什么来自外部的触动。我们不过是在自欺欺人罢了。
“要是有谁不介意开车的话,”索菲说,“我累了。”
那晚,伊莎贝尔慷慨地关注劳伦斯,关注她的孩子们,还有索菲,尽管后者根本不需要这个。他们全都感觉到了她的快乐。他们感觉好像有一道看不见的、惯常的障碍被清除了,好像有一道透明的屏障被扯开了。或许他们一直以来只是想象着它的存在?劳伦斯忘了跟戴妮斯作对,或者把她当成一个竞争对手来针锋相对。他甚至都没再跟索菲争斗,没再纠缠电视的话题。
“我们从空中看到硅矿了,”晚饭时他告诉伊莎贝尔,“像一片雪原。”
“白色大理石,”索菲引用当地的叫法,“那些做作的玩意儿,他们把它铺在奥布雷维尔的所有公园小路上,把公园都给毁了。闪闪发亮的。”
伊莎贝尔说:“你知道吗,我们过去有过一座白山包。在我上的学校里—它位于一家饼干厂后头,操场和饼干厂紧挨着。时不时地,他们会把那么多香草糖粉、坚果和硬棉花糖块堆成一堆。他们成桶成桶把它们运来,倒在那里堆着,亮闪闪的。它闪闪发亮,就像一座纯白的雪山。在学校里,总有人远远地一眼看到它,嚷嚷起来:‘白山包!’放学后,我们就会翻过篱笆,或者绕过它跑进去。我们都会跑到那里,在巨大的白色糖堆里刨来刨去。”
“他们会把它刮个一干二净吗?”彼得问。这个想法好像让他兴高采烈,“你会吃它吗?”
“当然啦,”戴妮斯说,“他们只有这个。他们是穷孩子。”
“不,不,不,”伊莎贝尔说,“我们很穷,不过还是有糖吃,时不时会得到个五分硬币去店里买。不是那么回事。是因为那白山包—有那么多糖,而它又是那么白晃晃、闪闪亮的。就像是小孩子做的梦一样—你所见过的最奇妙的美梦成真哦。”
“妈妈会在夜深人静时把它全拿走,”劳伦斯说,“然后给你们橙子取而代之。”
“如果拿杏仁蛋白软糖来想象的话,我就能理解了。”索菲说,“尽管你得承认,那好像不大利于健康。”
“那一定很糟糕,”伊莎贝尔说,“对我们的牙齿,对一切而言。不过我们并没真的因为吃太多而生病,因为我们人那么多,而且我们得那么用力才能挖下去。它只是看起来像是最最美妙的一件事罢了。”
“白山包!”劳伦斯说—换个时候,这样一个故事本该让他发些“穷人单纯的乐趣!”之类的感慨。“白山包。”他说,欢喜和嘲讽参半,流露出一种自然的欣赏之情,似乎正合伊莎贝尔心意。
她不应当吃惊。她熟知劳伦斯的敏感和善良,也洞悉他的霸道和吹嘘。她了解他思想的转折,他心情的变换,他身体里小小的变化和响动。他俩亲密无间。他们彼此那样了解,以至于一切都被别的什么给抵消了。这就是他们的性爱为何显得如此令人羞耻的缘故,它们完完全全地,而且无比狂乱地因为欲望而起,就像兄妹乱伦一样。不过爱可以不受影响—它幸存下来了。瞧啊,她此刻是多么爱他。伊莎贝尔感觉自己前所未有地、无边无际地充满绵绵爱意。
要是他的同事在,要是他和他的同事都在,她可以说:“我想我们昨天落下了点什么。我婆婆觉得她丢下了眼镜盒。不是她的眼镜,只是盒子,没什么重要的。我想最好还是来看看。”
要是他一个人在,不过带着一脸茫然而放松的神情,询问地朝她走来,那或许这么微不足道的理由就不够了。
“我来是想看看飞行课的安排。我丈夫让我来看看。”
要是他一个人在,不过并非一脸茫然—然而还是有必要说点什么,她可以说:“你昨天把大家都带上去,真是太好了,他们开心极了。我只是想过来说声谢谢。”
她真不敢相信,真不敢相信它会发生。尽管她读了那么多书,有过那么多幻想,听过几个朋友吐露秘密,但她还是没法相信人们每天都会发出、收到这类信息,并且付诸实施,制订危险的计划,溜进非法的区域(它们到头来都与家惊人地相似,或惊人地不同)。
接下来的岁月中,她将学会分辨爱情开始和结束时的种种迹象。她不再会因为当下的表象会瞬间撕裂而如此震惊。不过吃惊还是吃惊的,以至于某天,和成年的女儿戴妮斯一道喝酒、聊着这些的时候,她说:“我觉得,最美好的部分总是在开头。就在开头的时候。那是唯一纯净的部分。”“甚至是在开头之前,”她说,“或许就在可能性在你脑海中一闪的那个时刻。那或许就是最美好的部分了。”
“那么第一次的恋情呢?我说的是第一次婚外情?”(戴妮斯按捺下所有责难。)“那是最美好的吗?”
“在我而言,那是最有激情的,也是最肮脏的。”
(指的是这个事实:生意走淡,飞行员向她要钱,她给了。也指的是真相揭穿时的不堪场面,它导致了这次偷情和她的婚姻的结束,不过他的仍旧完好。此外,也指的是那些如此火热、令人癫狂的快乐场景,双方都被弄得精疲力竭,有几次还淌下了热泪。也指的是最开始那一幕,她随时都能在脑海中重播它,记起那种不可思议的慌乱平静参半的感觉。
早上大约九点的机场,那寂静,那阳光,那灰蒙蒙的远处的树。想必是从别处拖来,充当办公室的白色小屋。没有窗帘或窗百叶。倒有一道尖头篱笆,充当大门。他走出来,给她开了门。他穿的还是昨天那身衣服,一样的浅色工装裤和工装衬衫,袖子卷着。她也穿着昨天的衣服。两人都没能听清对方说什么,或者用什么有意义的话作答。
要是他过于自如,或者流露出任何算计的痕迹—或者更糟,显出几丝得意之情—都会让她落荒而逃。但他没犯那种错误,或许是因为没被诱惑到忘乎所以吧。对女人有一手的男人—他一直以来就是的。她慢慢才会发现他之前得手过,在非常相似的情况下—有此天赋的男人其实并不像人们以为的那样举止轻浮,也并非心存恶意。第一次触碰她时,他下手果断,却一脸凝重,好像还带着歉意。一种安抚的、欣赏的触摸,一种慢慢增强的表白,袭上她赤裸的脖子和肩膀,赤裸的手臂和背部,衣不蔽体的胸与臀。他跟她说话—亲密地、真诚地不知所云着—而她因这触摸已经几乎不能自持,前后扭动着。
她感觉被拯救,被抬升,被凝视,而且很安全。)
晚饭后,他们玩了猜字谜游戏。彼得是猎户座。为了说明第二个音节,他假装从一个想象的杯子里喝东西,踉踉跄跄走着,倒在地上。[6]他们都觉得猎户座是个专有名词,不过并没赶他出局。
“毕竟,太空就是彼得的世界嘛。”戴妮斯说。劳伦斯和伊莎贝尔都乐了。这话变成一则家族笑话,时不时有人提起。
索菲从来搞不懂猜字谜游戏的规则—至少从来都跟不上—所以很快就放弃了,改看起书。《挪威古诗集》,每年夏天她都要读它,最近因为电视的诱惑没再读。上床时,她把书留在椅子扶手上。
伊莎贝尔关灯前拾起书,恰好读到这句:
Seinat er at segia;
Svá er nu rádit
(多说无益,木已成舟。)
[1] 1895—1962,挪威女高音,擅长演唱瓦格纳歌剧。
[2] 位于挪威。
[3] 位于加拿大魁北克。
[4] 挪威极地城市。
[5] 位于俄罗斯,北临北冰洋。
[6] 猎户座的英文“Orion”中的第二个音节与“rye”,即“黑麦威士忌”发音相同,故此。
"""
背影-三毛
========================
背影-[[三毛]]
-------
那片墓园曾经是荷西与我常常经过的地方。
过去,每当我们散步在这个新来离岛上的高岗时,总喜欢俯视着那方方的纯白的厚墙,看看墓园中特有的丝杉,还有那一扇古老的镶花大铁门。
不知为什么,总也不厌的怅望着那一片被围起来的寂寂的土地,好似乡愁般的依恋着它,而我们,是根本没有进去过的。
当时并不明白,不久以后,这竟是荷西要归去的地方了。是的,荷西是永远睡了下去。
清晨的墓园,鸟声如洗,有风吹过,带来了树叶的清香。不远的山坡下,看得见荷西最后工作的地方,看得见古老的小镇,自然也看得见那蓝色的海。
总是痴痴的一直坐到黄昏,坐到幽暗的夜慢慢的给四周带来了死亡的阴影。
也总是那个同样的守墓人,拿着一个大铜环,环上吊着一把古老的大钥匙向我走来,低低的劝慰着:“太太,回去吧!天暗了。”
我向他道谢,默默的跟着他穿过一排又一排十字架,最后,看他锁上了那扇分隔生死的铁门,这才往万家灯火的小镇走去。
回到那个租来的公寓,只要母亲听见了上楼的脚步声,门便很快的打开了,面对的,是憔悴不堪等待了我一整天的父亲和母亲。
照例喊一声:“爹爹,姆妈,我回来了!”然后回到自己的卧室里去,躺下来,望着天花板,等着黎明的再来,清晨六时,墓园开了,又可以往荷西奔去。
父母亲马上跟进了卧室,母亲总是捧着一碗汤,察言观色,又近乎哀求的轻声说:“喝一口也好,也不勉强你不再去坟地,只求你喝一口,这么多天来什么也不吃怎么撑得住。”
也不是想顶撞母亲,可是我实在吃不下任何东西,摇摇头不肯再看父母一眼,将自己侧埋在枕头里不动。母亲站了好一会,那碗汤又捧了出去。
客厅里,一片死寂,父亲母亲好似也没有在交谈。
不知是荷西葬下去的第几日了,堆着的大批花环已经枯萎了,我跪在地上,用力将花环里缠着的铁丝拉开,一趟又一趟的将拆散的残梗抱到远远的垃圾桶里去丢掉。
花没有了,阳光下露出来的是一片黄黄干干的尘土,在这片刺目的,被我看了一千遍一万遍的土地下,长眠着我生命中最最心爱的丈夫。
鲜花又被买了来,放在注满了清水的大花瓶里,那片没有名字的黄土,一样固执的沉默着,微风里,红色的、白色的玫瑰在轻轻的摆动,却总也带不来生命的信息。
那日的正午,我从墓园里下来,停好了车,望着来来往往的车辆和行人发呆。
不时有认识与不认识的路人经过我,停下来,照着岛上古老的习俗,握住我的双手,亲吻我的额头,喃喃的说几句致哀的语言然后低头走开。我只是麻木的在道谢,根本没有在听他们,手里捏了一张已经皱得不成样子的白纸,上面写着一些必须去面对的事情——:要去葬仪社结帐,去找法医看解剖结果,去警察局交回荷西的身份证和驾驶执照,去海防司令部填写出事经过,去法院申请死亡证明,去市政府请求墓地式样许可,去社会福利局申报死亡,去打长途电话给马德里总公司要荷西工作合同证明,去打听寄车回大加纳利岛的船期和费用,去做一件又一件刺心而又无奈的琐事。
我默默的盘算着要先开始去做哪一件事,又想起来一些要影印的文件被忘在家里了。
天好似非常的闷热,黑色的丧服更使人汗出如雨,从得知荷西出事时那一刻便升上来的狂渴又一次一次的袭了上来。
这时候,在邮局的门口,我看见了父亲和母亲,那是在荷西葬下去之后第一次在镇上看见他们,好似从来没有将他们带出来一起办过事情。他们就该当是成天在家苦盼我回去的人。
我还是靠在车门边,也没有招呼他们,父亲却很快的指着我,拉着母亲过街了。
那天,母亲穿着一件藏青色的材衫,一条白色的裙子,父亲穿着他在仓促中赶回这个离岛时唯一带来的一套灰色的西装,居然还打了领带。
母亲的手里握着一把黄色的康乃馨。
他们是从镇的那头走路来的,父亲那么不怕热的人都在揩汗。
“你们去哪里?”我淡然的说。
“看荷西。”
“不用了。”我仍然没有什么反应。
“我们要去看荷西。”母亲又说。
“找了好久好久,才在一条小巷子里买到了花,店里的人也不肯收钱,话又讲不通,争了半天,就是不肯收,我们丢下几百块跑出店,也不知够不够。”父亲急急的告诉我这件事,我仍是漠漠然的。
现在回想起来,父母亲不只是从家里走了长长的路出来,在买花的时候又不知道绕了多少冤枉路,而他们那几日其实也是不眠不食的在受着苦难,那样的年纪,怎么吃得消在烈日下走那么长的路。
“开车一起去墓地好了,你们累了。”我说。
“不用了,我们还可以走,你去办事。”母亲马上拒绝了。“路远,又是上坡,还是坐车去的好,再说,还有回程。”
“不要,不要,你去忙,我们认得路。”父亲也说了。“不行,天太热了。”我也坚持着。
“我们要走走,我们想慢慢的走走。”
母亲重复着这一句话,好似我再逼她上车便要哭了出来,这几日的苦,在她的声调里是再也控制不住了。
父亲母亲默默的穿过街道,弯到上山的那条公路去。我站在他们背后,并没有马上离开。
花被母亲紧紧的握在手里,父亲弯着身好似又在掏手帕揩汗,耀眼的阳光下,哀伤,那么明显的压垮了他们的两肩,那么沉重的拖住了他们的步伐,四周不断的有人在我面前经过,可是我的眼睛只看见父母渐渐远去的背影,那份肉体上实实在在的焦渴的感觉又使人昏眩起来。
一直站在那里想了又想,不知为什么自己在这种情境里,不明白为什么荷西突然不见了,更不相信自己的眼睛——我的父母竟在那儿拿着一束花去上一座谁的坟,千山万水的来与我们相聚,而这个梦是在一条通向死亡的路上遽然结束。我眼睛干干的,没有一滴泪水,只是在那儿想痴了过去。对街书报店的老板向我走过来,说:“来,不要站在大太阳下面。”
我跟他说:“带我去你店里喝水,我口渴。”
他扶着我的手肘过街,我又回头去找父亲和母亲,他们还在那儿爬山路,两个悲愁的身影和一束黄花。
当我黄昏又回荷西的身畔去时,看见父母亲的那束康乃馨插在别人的地方了,那是荷西逝后旁边的一座新坟,听说是一位老太太睡了。两片没有名牌的黄土自然是会弄错的,更何况在下葬的那一刻因为我狂叫的缘故,父母几乎也被弄得疯狂,他们是不可能在那种时刻认仔细墓园的路的。
“老婆婆,花给了你是好的,请你好好照顾荷西吧!”
我轻轻的替老婆婆抚平了四周松散了的泥沙,又将那束错放的花又扶了扶正,心里想着,这个识别的墓碑是得快做了。
在老木匠的店里,我画下了简单的十字架的形状,又说明了四周栅栏的高度,再请他做一块厚厚的牌子钉在十字架的中间,他本来也是我们的朋友。
“这块墓志铭如果要刻太多字就得再等一星期了。”他抱歉的说。
“不用,只要刻这几个简单的字:荷西·马利安·葛罗——安息。”
“下面刻上——你的妻子纪念你。”我轻轻的说。“刻好请你自己来拿吧,找工人去做坟,给你用最好的木头刻。这份工作和材料都是送的,孩子,坚强呵!”
老先生粗糙有力的手重重的握着我的两肩,他的眼里有泪光在闪烁。
“要付钱的,可是一样的感谢您。”
我不自觉的向他弯下腰去,我只是哭不出来。
那些日子,夜间总是跟着父母亲在家里度过,不断的有朋友们来探望我,我说着西班牙话,父母便退到卧室里去。窗外的海,白日里平静无波,在夜间一轮明月的照耀下,将这拿走荷西生命的海洋爱抚得更是温柔。
父亲、母亲与我,在分别了十二年之后的第一个中秋节,便是那样的度过了。
讲好那天是早晨十点钟去拿十字架和木栅栏的,出门时没见到母亲。父亲好似没有吃早饭,厨房里清清冷冷的,他背着我站在阳台上,所能见到的,也只是那逃也逃不掉的海洋。
“爹爹,我出去了。”我在他身后低低的说。
“要不要陪你去?今天去做哪些事情?爹爹姆妈语言不通,什么忙也帮不上你。”
听见父亲那么痛惜的话,我几乎想请他跟我一起出门,虽然他的确是不能说西班牙话,可是如果我要他陪,他心里会好过得多。
“哪里,是我对不起你们,发生这样的事情……”话再也说不下去了,我开了门便很快的走了。
不敢告诉父亲说我不请工人自己要去做坟的事,怕他拚了命也要跟着我同去。
要一个人去搬那个对我来说还是太重的十字架和木栅栏,要用手指再一次去挖那片埋着荷西的黄土,喜欢自己去筑他永久的寝园,甘心自己用手,用大石块,去挖,去钉,去围,替荷西做这世上最后的一件事情。
那天的风特别的大,拍散在车道旁边堤防上的浪花飞溅得好似天高。
我缓缓的开着车子,堤防对面的人行道上也沾满了风吹过去的海水,突然,在那一排排被海风蚀剥得几乎成了骨灰色的老木房子前面,我看见了在风里,水雾里,踽踽独行的母亲。
那时人行道上除了母亲之外空无人迹,天气不好,熟路的人不会走这条堤防边的大道。
母亲腋下紧紧的夹着她的皮包,双手重沉沉的各提了两个很大的超级市场的口袋,那些东西是这么的重,使得母亲快蹲下去了般的弯着小腿在慢慢一步又一步的拖着。
她的头发在大风里翻飞着,有时候吹上来盖住了她的眼睛,可是她手上有那么多的东西,几乎没有一点法子拂去她脸上的乱发。
眼前孤伶伶在走着的妇人会是我的母亲吗?会是那个在不久以前还穿着大红衬衫跟着荷西与我像孩子似的采野果子的妈妈?是那个同样的妈妈?为什么她变了,为什么这明明是她又实在不是她了?
这个憔悴而沉默妇人的身体,不必说一句话,便河也似的奔流出来了她自己的灵魂,在她的里面,多么深的悲伤,委屈,顺命和眼泪像一本摊开的故事书,向人诉说了个明明白白。
可是她手里牢牢的提着她的那几个大口袋,怎么样的打击好似也提得动它们,不会放下来。
我赶快停了车向她跑过去:“姆妈,你去哪里了,怎么不叫我。”
“去买菜啊!”母亲没事似的回答着。
“我拿着超级市场的空口袋,走到差不多觉得要到了的地方,就指着口袋上的字问人,自然有人会拉着我的手带我到菜场门口,回来自己就可以了,以前荷西跟你不是开车送过我好多次吗?”母亲仍然和蔼的说着。
想到母亲是在台北住了半生也还弄不清街道的人,现在居然一个人在异乡异地拿着口袋到处打手势问人菜场的路,回公寓又不晓得走小街,任凭堤防上的浪花飞溅着她,我看见她的样子,自责得恨不能自己死去。
荷西去了的这些日子,我完完全全将父母亲忘了,自私的哀伤将我弄得死去活来,竟不知父母还在身边,竟忘了他们也痛,竟没有想到,他们的世界因为没有我语言的媒介已经完全封闭了起来,当然,他们日用品的缺乏更不在我的心思里了。
是不是这一阵父母亲也没有吃过什么?为什么我没有想到过?
只记得荷西的家属赶来参加葬礼过后的那几小时,我被打了镇静剂躺在床上,药性没有用,仍然在喊荷西回来,荷西回来!父亲在当时也快崩溃了,只有母亲,她不进来理我,她将我交给我眼泪汪汪的好朋友格劳丽亚,因为她是医生。我记得那一天,厨房里有油锅的声音,我事后知道母亲发着抖撑着用一个小平底锅在一次一次的炒蛋炒饭,给我的婆婆和荷西的哥哥姐姐们开饭,而那些家属,哭号一阵,吃一阵,然后赶着上街去抢购了一些岛上免税的烟酒和手表、相机,匆匆忙忙的登机而去,包括做母亲的,都没有忘记买了新表才走。
以后呢?以后的日子,再没有听见厨房里有炒菜的声音了。为什么那么安静了呢,好像也没有看见父母吃什么。“姆妈上车来,东西太重了,我送你回去。”我的声音哽住了。
“不要,你去办事情,我可以走。”
“不许走,东西太重。”我上去抢她的重口袋。“你去镇上做什么?”妈妈问我。
我不敢说是去做坟,怕她要跟。
“有事要做,你先上来嘛!”
“有事就快去做,我们语言不通不能帮上一点点忙,看你这么东跑西跑连哭的时间也没有,你以为做大人的心里不难过?你看你,自己嘴唇都裂开了,还在争这几个又不重的袋子。”她这些话一讲,眼睛便湿透了。
母亲也不再说了,怕我追她似的加快了步子,大风里几乎开始跑起来。
我又跑上去抢母亲袋子里沉得不堪的一瓶瓶矿泉水,她叫了起来:“你脊椎骨不好,快放手。”
这时,我的心脏不争气的狂跳起来,又不能通畅的呼吸了,肋骨边针尖似的刺痛又来了,我放了母亲,自己慢慢的走回车上去,趴在驾驶盘上,这才将手赶快压住了痛的地方。等我稍稍喘过气来,母亲已经走远了。
我坐在车里,车子斜斜的就停在街心,后望镜里,还是看得见母亲的背影,她的双手,被那些东西拖得好似要掉到了地上,可是她仍是一步又一步的在那里走下去。
母亲踏着的青石板,是一片又一片碎掉的心,她几乎步伐踉跄了,可是手上的重担却不肯放下来交给我,我知道,只要我活着一天,她便不肯委屈我一秒。
回忆到这儿,我突然热泪如倾,爱到底是什么东西,为什么那么辛酸那么苦痛,只要还能握住它,到死还是不肯放弃,到死也是甘心。
父亲,母亲,这一次,孩子又重重的伤害了你们,不是前不久才说过,再也不伤你们了,这么守诺言的我,却是又一次失信于你们,虽然当时我应该坚强些的,可是我没有做到。
守望的天使啊!你们万里迢迢的飞去了北非,原来冥冥中又去保护了我,你们那双老硬的翅膀什么时候才可以休息?
终于有泪了。那么我还不是行尸走肉,父亲,母亲,你们此时正在安睡,那么让我悄悄的尽情的流一次泪吧。
孩子真情流露的时候,好似总是背着你们,你们向我显明最深的爱的时候,也好似恰巧都是一次又一次的背影。什么时候,我们能够面对面的看一眼,不再隐藏彼此,也不只在文章里偷偷的写出来,什么时候我才肯明明白白的将这份真诚在我们有限的生命里向你们交代得清清楚楚呢。
背影-朱自清
========================
背影-[[朱自清]]
-------
我与父亲不相见已二年余了,我最不能忘记的是他的背影。那年冬天,祖母死了,父亲的差使也交卸了,正是祸不单行的日子,我从北京到徐州,打算跟着父亲奔丧回家。到徐州见着父亲,看见满院狼藉的东西,又想起祖母,不禁簌簌地流下眼泪。父亲说,“事已如此,不必难过,好在天无绝人之路!”
回家变卖典质,父亲还了亏空;又借钱办了丧事。这些日子,家中光景很是惨淡,一半为了丧事,一半为了父亲赋闲。丧事完毕,父亲要到南京谋事,我也要回到北京念书,我们便同行。
到南京时,有朋友约去游逛,勾留了一日;第二日上午便须渡江到浦口,下午上车北去。父亲因为事忙,本已说定不送我,叫旅馆里一个熟识的茶房陪我同去。他再三嘱咐茶房,甚是仔细。但他终于不放心,怕茶房不妥贴;颇踌躇了一会。其实我那年已二十岁,北京已来往过两三次,是没有甚么要紧的了。他踌躇了一会,终于决定还是自己送我去。我两三回劝他不必去;他只说,“不要紧,他们去不好!”
我们过了江,进了车站。我买票,他忙着照看行李。行李太多了,得向脚夫行些小费,才可过去。他便又忙着和他们讲价钱。我那时真是聪明过分,总觉他说话不大漂亮,非自己插嘴不可。但他终于讲定了价钱;就送我上车。他给我拣定了靠车门的一张椅子;我将他给我做的紫毛大衣铺好坐位。他嘱我路上小心,夜里警醒些,不要受凉。又嘱托茶房好好照应我。我心里暗笑他的迂;他们只认得钱,托他们直是白托!而且我这样大年纪的人,难道还不能料理自己么?唉,我现在想想,那时真是太聪明了!
我说道,“爸爸,你走吧。”他往车外看了看,说,“我买几个橘子去。你就在此地,不要走动。”我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。我赶紧拭干了泪,怕他看见,也怕别人看见。我再向外看时,他已抱了朱红的桔子往回走了。过铁道时,他先将橘子散放在地上,自己慢慢爬下,再抱起橘子走。到这边时,我赶紧去搀他。他和我走到车上,将橘子一股脑儿放在我的皮大衣上。于是扑扑衣上的泥土,心里很轻松似的,过一会说,“我走了;到那边来信!”我望着他走出去。他走了几步,回过头看见我,说,“进去吧,里边没人。”等他的背影混入来来往往的人里,再找不着了,我便进来坐下,我的眼泪又来了。
近几年来,父亲和我都是东奔西走,家中光景是一日不如一日。他少年出外谋生,独立支持,做了许多大事。那知老境却如此颓唐!他触目伤怀,自然情不能自已。情郁于中,自然要发之于外;家庭琐屑便往往触他之怒。他待我渐渐不同往日。但最近两年的不见,他终于忘却我的不好,只是惦记着我,惦记着我的儿子。我北来后,他写了一信给我,信中说道,“我身体平安,惟膀子疼痛利害,举箸提笔,诸多不便,大约大去之期不远矣。”我读到此处,在晶莹的泪光中,又看见那肥胖的,青布棉袍,黑布马褂的背影。唉!我不知何时再能与他相见!
1925年10月在北京。
(原载1925年11月22日《文学周报》第200期)
被窃的文件
作者:[[星新一]]
-----
夜阑人静。在F博士研究所的附近潜伏着一个小偷。
至今为止,F博士已相继发明了一系列性能优异的药物,据最近传出的消息说,他即将又要完成一种新型药物的研制。
小偷决定尽快盗出这种药物的技术文件,出卖给别人以牟取暴利。
他屏息凝神地从窗口偷偷朝里窥视,只见屋里只有博士独自一人在埋头于药物的制备。博士那种目不转睛、聚精会神的样子,使小偷根本不用担心会被发现。
过了一会,博士制出为数不多的一点成品,这是一种呈绿色的液体。他舀起少许放在嘴里,一边细细地品尝着,一边啧啧有声地说道:
“啊,滋味不错,气味也挺好闻……”
博士舒展双臂,长长地伸了个懒腰,然后又唠唠叨叨地自言自语起来。
“嘿,总算成功了。这些年来,我虽然研制出一系列新药物,但是还没有一个品种能超过现在这种药物。在我看来,它真可称得上是一个世界性的伟大发明。对,我现在首先要做的是把这种制备方法记录下来。”
博士取出纸笔迅速地写起来,写完以后,把它郑重其事地放进位于墙角的一只大保险柜里,然后离开了研究所。
窗外,早已等得不耐烦的小偷见博士一走,便立刻行动了。他轻轻地把窗子撬开,悄无声息地潜入屋里,然后走到保险柜前,熟悉地旋动号码盘。在他的手里,保险柜被轻而易举地打开了。小偷取出技术文件,把揣入怀里,喜不自胜地逃遁于漆黑的夜幕中。
“这下可好了,准可以赚得一笔大钱!我亲眼见到博士把药放进嘴里,已证明它对人体无害,而且我还亲耳听到博士说它是世界上一项伟大的发明。但是,它究竟具有什么功效呢?……”
只有这一点目前还是个谜。博士吃了以后不知怎样了,现在既没有时间也没有办法调查,总不能直接打电话去询问吧。不过,只要是F博士发明的药物,就必定有奇效,这已为无数事实所证明。
回到隐匿处的小偷,决定按照博士所写的方法自己动手来进行制造。这是因为不这样便无法知道它的效能。也就无法向买主交代。他设法搞到了原料,又买来了烧瓶和烧杯,花了几天的时间,他终于制得了药物。
小偷捧起散发着铃兰草般清香的药物,一饮而尽。药物顺着他喉咙流下去,使他产生一种凉爽甜润的感觉。他静静地坐在椅子里,等待着药物供功效的发作。
突然,小偷站了起来,他以急促的步子走出房间,头也不回地一直走到F博士的研究所。
“博士,我做了对不起您的事。几天前,我从这里的保险柜里偷走了您的技术文件,请把我送给警察吧。”
小偷对着迎上前来的博士这样说道。
“真是你拿走的吗?”
“是的。我按照您所写的方法制造了这种药,并且把它喝下去了。我现在已经认识到自己干了坏事,因此特地前来请求您的宽恕,并把偷去的文件送还给您。”
小偷声泪俱下,心情沉重地向博士认了罪。可是F博士非但没有发怒,反而哈哈大笑起来。
“哪里,哪里。你要知道,这是我的发明在起作用。这种新药具有使人良心发现的功效。不过,由于没有一个坏人肯自愿为了试验而服用这种药,我正在犯愁呢。现在好了,承蒙你的协助,证明了它的功效,辛苦你了。”
(全文完)
-----
(日)星新一著苏德成龚云表译录入:snowboy
鼻子-芥川龙之介
========================
鼻子-[[芥川龙之介]]
-----
说到禅智内供[1]的鼻子,在池尾[2]这个地方几乎无人不知。
他的鼻子长度足有五六寸,从上唇之上一直垂到下巴。形状上下粗细一致,像一根香肠一样耷拉在脸中央。
内供已经五十多岁了,从他初当沙弥那时候起,一直到成为内道场供奉的今天,内心里始终为鼻子苦恼着。在人们面前,他总是假装不在乎这张脸。这样做,一方面是因为他觉得一心向往来世净土的僧人不宜在乎鼻子之类小事,另一方面他不想让人知道他在意鼻子。平日说话时,内供最怕听到“鼻子”这个词。
内供腻烦鼻子的原因有二:首先是因为鼻子长确实很不方便。内供都无法自己吃饭,因为鼻尖很容易杵到碗里的饭上去。因此他只好吩咐一个弟子在吃饭时坐到他对面,用一个长两尺宽一寸的细长木条替自己把鼻子抬起来。可这样吃饭,对抬鼻子的弟子和被抬的内供来说,都很不容易。有一次中童子[3]代替弟子帮内供抬鼻子时,打了一个喷嚏,手颤抖了一下,内供的鼻子就一下扎到粥里去了。这件事当时在京都都传遍了。然而这并不是内供为鼻子而苦闷的主要原因。内供苦闷是因为鼻子使他伤了自尊。
池尾的老百姓为内供着想,他们觉得幸好内供出家了,不然有那样一个鼻子,哪有女人肯嫁给他。有人甚至揣测,内供就是因为有那样的鼻子才出家的吧。然而内供自己却不觉得做了和尚,鼻子的烦恼就因此减少了。他并不会为娶妻这样的事所左右情绪,但他的自尊心确实很容易受到伤害。于是内供决定从积极和消极两方面来恢复损毁的自尊心。
内供一开始是想办法让长鼻子显得短一些。没人的时候,他自己对着镜子从不同角度仔细研究。看着看着,他觉得光改变脸的位置还是不够好,于是他试着用手托着腮帮子,或者扶着下巴。左照右照,怎么也不能让自己满意。有时候越看越觉得鼻子显得更长了。内供叹口气,只好把镜子收回盒中,不情不愿地到经案那里去读《观音经》了。
内供还总留心观察别人的鼻子。池尾寺经常供养僧人并举行讲经活动。寺院里,禅房栉比鳞次,僧徒每天在浴室里烧热水。这里僧侣们进进出出络绎不绝。内供不厌其烦地端详这些人的脸。他想着哪怕找到一个人像自己的鼻子,也能聊以自慰。所以不管是深蓝色的绢衣,还是白色的单衫,都入不了他的眼;至于橙黄色帽子和暗褐色僧袍,正因为平素看惯了,更是似有若无了。内供不看人,只看鼻子;鹰钩鼻能看到,但像他这样的鼻子却一个都没有。找了又找还是找不到,内供内心不免开始气恼起来。他一边跟人说话,一边捏捏那耷拉的鼻子,虽然一把年纪了,还是会脸红,这全是因为内心的懊恼。
最后,内供竟然想在佛经和其他书里找一个跟自己鼻子一样的人,好歹能排遣下内心的愁闷。然而没有经书记载目犍连[4]和舍利弗[5]的鼻子是长的。龙树[6]和马鸣[7]这两尊菩萨的鼻子当然也跟常人没什么两样。内供听人说中国蜀汉时期的刘玄德耳朵特别长,他想,要是鼻子长,那该多让自己感到宽慰啊。
内供一面消极地苦心自我安慰,一面积极地寻找缩短鼻子的办法,在这里就不再赘述了。他几乎什么方法都试了。他喝过老鸦爪熬的汤,也在鼻子上抹过老鼠尿。然,无论怎样,那五六寸长的鼻子照旧还在脸上挂着。
一年秋天,内供的弟子上京办事,从一位医生朋友那里学到了缩短长鼻子的办法。那位医生原是从中国渡海而来的,当时在长乐寺做供奉僧。
内供假装和平常一样对鼻子满不在乎,偏不说试试这个方法;然而又在吃饭时表现出每次都麻烦弟子于心不安的样子。内供心里其实巴望着弟子提出让他试试这个方法。弟子内心也明白内供的心思,虽然有点反感,但更多的是对内供的同情。于是弟子开始费尽口舌地劝内供,而内供也如愿以偿,答应了这热忱的劝告。
医生给的方法其实很简单:用热水烫鼻子,然后让人踩鼻子。
热水很好准备,寺院的浴室照例每天都烧。弟子马上就用提桶从浴室打来了热得伸不进指头的开水。要是径直把鼻子伸进提桶,恐怕蒸气会把脸烫坏。于是,就在木托盘上钻了个洞,盖在提桶上,从洞里把鼻子伸进热水中。这样只有鼻子浸在热水里,脸也不会烫坏。过了一会儿,弟子说:“烫够了吧?”
内供苦笑了一下,因为单听这句话,谁也想不到这是在说鼻子的事。鼻子被热水烫得通红,好像被跳蚤咬了似的痒。
内供一把鼻子从木托盘的洞里抽出来,弟子就马上开始用脚使劲踩鼻子。内供侧身躺着,将鼻子放在地上,看着弟子在面前一下一下用力踩。弟子脸上显出过意不去的表情,盯着内供的秃脑袋瓜儿,说:“疼吗?医生说得用力踩,但是,会疼吧?”
内供想摇头表示不疼,但是鼻子被踩着没法摇头,他盯着弟子皴裂的脚,生气地说:“不疼!”
实际上,鼻子痒痒的,被踩得不但不疼,还挺舒服的。
踩了一会儿,鼻子里冒出来米粒一样的东西,有点像被拔了毛烤的鸟。弟子看到这个,停下来,像是自言自语地说:“医生说得用镊子把这个钳出来呢。”
内供状似不满地鼓起腮帮子,默默忍受弟子的摆弄。虽然知道弟子一片好心,但看着自己的鼻子像物品一样被摆弄,还是有些不愉快的。内供那神情活像是一个由自己所不信任的医生来开刀的病人似的,迟迟疑疑地瞥着徒弟用镊子从鼻子的毛孔里钳出脂肪来。脂肪的形状犹如鸟羽的根,一拔就是四分来长。
钳了一通之后,弟子终于舒了一口气,说:“再烫一回就成啦!”
内供面色不快,却还是按照弟子说的去做。
如此又烫一次之后,鼻子果然短了,跟普通的鹰钩鼻差不多。内供边摸着自己变短的鼻子,边腼腆地照着弟子拿来的镜子。
鼻子——那只曾经耷拉到下巴的鼻子,已经令人难以置信地变短了,如今正瑟缩地停在上唇之上。上面有好多地方还是红红的,大概是踩出来的。内供心想,这样肯定不会有人嘲笑我了。镜子里的内供的脸,对着镜子外面内供的脸,满意地眨了眨眼睛。
可是之后一天的时间里,内供都很担心鼻子会再次变长,以至于不管是诵经时,还是吃饭时,只要一有空他就会不由自主地悄悄摸摸自己的鼻子。每次摸完后鼻子都好端端地在上唇之上,没有下垂的迹象。睡了一宿,清早醒来,内供第一件事就是摸鼻子。鼻子还是短的。内供的心情顿时就好像积了多年抄写《法华经》的功德一样神清气爽。这种舒畅他已经多年不曾拥有过了。
但是过了两三天,内供发现有点不对劲。有个武士来池尾寺办事,看到内供连话都说不利索了,只盯着内供的鼻子看,表情更加奇怪。不仅如此,还有那个把内供鼻子掉到粥里的中童子,有一次在讲堂外与内供错身路过时强忍笑意,大约后来实在憋不住了,终于扑哧笑了出来。内供吩咐僧徒们事情,他们当面正经受教,内供一转身,他们就吃吃笑出来。这样的情况不是一两回了。
内供刚开始自我解释是因为自己的脸变了,人们不习惯。后来随即就发现,这样的解释似乎不够完全。中童子和僧徒们发笑的原因定是如此。然而,同样是笑,跟过去他的鼻子还长的时候相比,笑得可不大一样。如果说,没有见惯的短鼻子比见惯了的长鼻子更可笑,倒也罢了。但是似乎还有别的原因。
“先前没像这样笑过……”
内供诵经的时候,经常停下来,歪着头喃喃自语道。可爱的内供茫然地望着旁边挂着的普贤画像,颇有一种“今如零落者,却忆荣华时”的感慨。内供不够明智,回答不出这个问题。
人的心都有两种相互矛盾的情感。没有人会对不幸者不同情。然而一旦不幸者想方设法摆脱了不幸,人们不知怎的反而会怅然所失。夸大一点说,甚至想让那个人再度陷入以往的不幸。于是,虽说态度是不对的,却在不知不觉之间对那个人怀起敌意来了。——内供尽管不晓得个中奥妙,然而还是心有所感,很是不快,这无非是因为他从池尾的僧俗的态度中觉察到了旁观者的利己主义。
内供的脾气一天天变差。无论对谁,说不了两句就开始叱责人家。连帮内供治鼻子的弟子也在背地里说:“内供会由于犯了暴戾罪而受到惩罚的。”让内供鼻子掉粥里的中童子尤其惹内供生气。有一天,内供听见狗在外面狂叫不止,就漫不经心地踱出屋门一看,中童子正抡起一根二尺来长的木条,在追赶一只瘦骨嶙嶙的长毛狗。光是追着玩倒也罢了,他还边追边嚷着:“别打着鼻子,喂,可别打着鼻子!”内供从中童子手里一把夺过那根木条,气得狠狠给了他一个耳光。原来那就是早先用来抬鼻子的木条。
内供开始为弄短鼻子后悔不迭。
一天傍晚,太阳落山后起风了,塔上的风铃叮当作响声传入屋内。再加上天气变得有点冷,年老的内供怎么也睡不着。在床上辗转反侧间,感觉鼻子有点痒,用手去摸,仿佛有点肿,还有点发热。
内供以在佛前供花那种虔诚的姿势按着鼻子,嘟囔道:“也许是因为硬把它弄短,出了什么毛病吧。”
第二天,内供像往常一样一大早就醒了。睁眼一看,寺院里的银杏和七叶树一夜之间掉光了叶子,庭园明亮得犹如铺满了黄金。大概是由于塔顶上降了霜的缘故,九轮[8]在晨曦中闪闪发光。板窗已经打开了,禅智内供站在走廊里深深地吸了一口气。
就在这时,内供又恢复了某种几乎忘却了的感觉。
他赶紧去摸鼻子。伸手摸到的不是昨天晚上的短鼻子了,而是以前那只长鼻子,从上唇之上一直垂到下巴,足有五六寸长。内供知道自己的鼻子一夜之间又跟过去一样长了。不知怎的,内供的心情又爽朗起来,正如鼻子缩短了的时候那样。
内供在秋风乍起的黎明晃荡着长鼻子,喃喃自语道:“这样一来,准没有人再笑我了。”
大正五年(1916)一月
[1] 内供:内供奉僧的简称,均为高德之僧,服务于内道场,为天皇祈祷、诵经。
[2] 池尾:地名,位于京都府宇治郡。
[3] 中童子:寺中供使唤的十二三岁的少年。法会时持旗杆标志等,陪身份高的僧人外出。依年龄分大中小。
[4] 目犍连:释迦牟尼高徒之一。神通第一。
[5] 舍利弗:释迦牟尼高徒之一。智慧第一。
[6] 龙树:发展了空性的中观学说,是领导大乘佛教复兴的伟大论师。
[7] 马鸣:古印度的佛教大师、诗人、剧作家。
[8] 九轮:寺庙塔顶的装饰物。
病 -阿嗅-文艺春秋
========================
-----
地铁上,报站的声音震耳,爸的双手微颤,似乎很不安。
城市里熙来攘往的人群,川流不息的车辆、如轮转的货物,与他常年生活的地方迥然相异,此时的他,担心着什么。
爸今年 56 岁,患精神病近 40 年,导火线不明。也许是未遂的初恋。也许是繁重的课业。或是寄宿外太婆家的经历。阿玛也不清楚。
爸是长子,也是独子。家里的手足十来个,全是称他哥的妹妹。阿爸 17 岁那年,阿嫲说阿爸突然中邪,精神恍惚,时而呓语。阿嫲和阿爷初初以为那只是很小的事,直到阿爸发狂的那天。两公婆不忍,搁下了猪肉摊的生意,遍访全马名医庸医与神棍,为的是治好爸突如其来的 “卡到阴”。
千方试尽后,他们才肯接受爸患病的事实。那年头,精神病若瘟疫,闻者避之。蜚短流长,很快就全村皆知。成长时,师长多用 “难得……” 来开头,形容我用小聪明换来的成绩单,那语气神情,是赞许,是惋惜,还是其他,已经记不清了。我只记得跟阿爸搭火车到彩虹广场去看医生的日子,是我难得出远门的机会。
**阿爷**
阿爷辞世,是 96 年的事。补习中阿爸骑摩托来载我回家守灵。让我环腰抱着的阿爸,是如此巨大。记忆中,自己站在摩托篮中,而阿爸以低于时速 10 公里的速度滑行,任我尽兴蹦跳。 记得的是随手采摘的 lalang 或插在不见了望后镜的螺丝口中摇摆或任我蹂躏成絮,随风而逝,记不得的是身后正努力保持平衡的面容。
少了酗酒爱应酬的阿爷,日子就是阿爸加婆媳妯娌间的磨擦。日日难念日日念的,不是可扫入地毯关上衣柜,眼不见为净的尘。而阿爸不理是经还是尘,大部分的时间都在睡房中度过。很后来很后来的我才知道,让阿爸越来越迟钝的,是药也是阿嫲。数不清的夜晚,催眠曲是妈被窝里传来的抽泣声。她不明白,当初追求她的人那么多,自己为何会选上阿爸,过上此种生活。
“若不是你们,我早就走了。”
阿嫲出生在 8 年抗战期间。11 岁差点魂断井中,背上还揹着她弟。17 岁嫁给阿爷,侍奉抽烟的太公太婆,还要应付妯娌间的算计、日常的柴米油盐和烟酒开销。11 个孩子几乎一年一个轮着生,凌晨 4 时到芭场割胶,6 时到猪肉摊帮忙,回家到家要煮饭凑小孩,晚上还要等满身酒气的阿爷回家。一晃过半生。回忆起那段往事时,却笑得比谁还大声。
阿嫲山长水远从梅县漂过来找吃,上船时用的还是别人的名字。在船上漂着的那两三个月如何艰苦,她从没提过。更苦的日子原来在前头。那些她记得更清楚。比如嫁给阿爷。阿嫲和阿爷的结合,凭的是媒妁之言。想起就觉得旧时人真认命。人生,地又不熟,从一个小镇迁移到另一个小镇原来就靠他人的几句话,红纸上的几个字。命定终生,靠的是别人的嘴。(阿嫲认不得几个字)而几十年的不离不弃靠的是日久生的情,和责任感。阿爷风流,花钱如水,最后因肾病而卧病不起,三十多年的时光,拉拔了 11 个孩子,4 个内孙,二十多个外孙,而嘴巴不饶人的阿嫲,始终待在阿爷身边。当然,间中的争吵并不少。
“早话昵知嘅啦,仲咁硬颈,人哋出钱昵出命。” 阿爷逐日流泪,肉体却逐日败坏。回首已是百年身。你如何想像悔恨。
妈说,阿爷最疼的,是我。可我什么都不记得。
**发病**
后来大姑也步上阿爸的后尘,患了病。是职场上的不公。防人之心不可无,此后阿嫲常说。大姑比阿爸决绝,数次饮毒想自尽。家里务农,橡胶不好价就种油棕,但小地方的收成,靠的是农药和化肥。那一次,家人大意,洗胃不及,就这样走了。后来我在橱柜里找到大姑留下的《新青年》杂志、《疾病大全》、《中医大辞典》等书和几本邮票簿,才知道大姑也曾想过行医也曾心怀世界,可她最后还是毅然饮毒。流入土地的药也灌得入体内,大家承受的,是一样的剧毒。
“活着或离去,都是种选择,没有更好或更坏,无需论断。” 师说。
当时我 4 岁吧?只记得大姑常陪我们玩老鹰捉小鸡的游戏。空荡荡的客厅里,我们在青色的水泥地不停转圈,在闪躲和追捕中消耗一个又一个下午。大姑的不治让阿嫲很自责。也许是这样,她才会擅自加药,看见阿爸一不对劲就让阿爸多啃几粒药,说阿爸若是能好好哋瞓觉,就天下太平了。我气愤,可我如何忍心怪她?特别是经历了阿爸的追杀后。那天,妈像母鸡一样将我们护在身后。只是那次的老鹰换成了手里拿着猪肉刀的阿爸。只是那次的保命游戏是真的。那年我该是什么都不知道的岁数。隔着门,妈哭着求饶,我们也该是跟着哭。妹哭得最大声。我不知道我有没有流泪。可能更想置身事外。
那幕刻得有多深,我从来不知道。直到有天睡醒后你问我,是不是梦见被僵尸追啦?那场景始现。我默然不语,只摇摇头,给了你一个微笑。你无须对我小心翼翼。
**寄人篱下**
阿嫲说,阿爸与大姑是家里最会读书的,换作今日,可谓名校生。从前的人质朴,还很看重书,可他们不知道,后来的我们,读的全是参考书。彼时,能以成绩考进城里知名的高级中学的,阿爸和大姑是少数几个。城乡之间,路途颠簸,来回耗时,也耗精神。于是,阿嫲让他俩寄宿在豆沙路的外太婆家。寄人篱下有多难,阿爸从没说过什么,直到我到四姑家暂住时才知晓。
阿爸和大姑相继患病的事,让本有芥蒂的外太婆和阿嫲,更是相对两无言。印象中的外太婆家,只有一粒昏黄的灯泡,厕所外建,食物都在木橱里,木橱的四脚放了小碟,碟中有水,用来防蚂蚁。大风吹时,屋顶锌片沙沙作响,落水时地上铺满五颜六色的盆,还有那印有公鸡的痰盂。
那简陋的木屋,外太婆一住便是几十年。记忆里的外太婆,已经很老很老,走路时驼着背,佝偻地养着几只鸡,吃隔夜的菜,喝井里的水。我们去时,就从橱里端菜出来,怕我们饿着。阿嫲对她始终有怨。
外太婆用陷进去的嘴说出的客家话,是千山万水外的乡音,只是我除了 ngai(我),其他的都听不懂。她和我之间,隔着两代人、一种话,这鸿沟我没来得及跨,她已只身前往彼岸。外太婆究竟是什么时候走的,我也记不清了。只记得外太婆的唇深陷缝中,脸就像块缝补过的布,还要是手工粗糙的那种。
(岁月可以在我们身上留下多少痕迹?)
高中毕业后来新工作,寄住四姑家时被告了状。(当时我始终不明白部分 - 成人处理问题的方式,那不当面说清而选择迂回投诉的行径让我不齿)阿嫲指责妈不会教孩子。妈又默默饮泣。爸爸见了,心情大坏,似乎好几天不吃药,结果就被警车送进了疗养院。几位姑姑和阿嫲对我们颇有微词。
那时见到阿爸,我就只会哭。阿嫲和姑姑们就只会骂我长不大,没用,说让阿爸沦落至此的,不是别人,是我和妈。那时只会自责,怪自己不够成熟不够自立。却也无比愤怒。为何将全部的责任推给我和妈?难道四姑没有责任?难道你们没有责任?
“你是如何都敌不过十张嘴的。” 妈说。
**迷宫**
在里面待了半年多才出院。迷宫般的疗养院,要走上半个小时才见得到爸。每个礼拜天,你越过长堤走过充满尿酸味的走廊,经过许多被铁栅隔开的病房去见爸。路途中偶尔对上铁条后瞪大的双眼,偶尔有隔着铁条伸出手要烟的病人。
“Moi, ada rokok tak?” (小妹,有烟吗?)
每次你都有种错觉,以为这是监狱。但你并不是来探监的啊。从默默等待亲人与友人的探访,到伸出手向陌生人或要或抢那稀缺的烟,被遗弃的他们最后也只好遗弃自己所珍视的东西。
每次看护喊阿爸的名字,看着阿爸走出铁门,经过四周钦羡的目光与话语,你都不知道要说些什么才好。他有时衣衫不整。有时根本没穿裤子。阿爸看见你的第一件事也是伸手要烟。那时你开始厌恶这一切。病人。看护。家人。还有你自己。
看护拿的是政府的俸禄,也兼收病人亲属的贡品。要烟要手下留人?凡事有商有量有价码。仿佛精神病人他妈的不是人。有次阿爸出来,嘴角和鼻子有伤,他们都说是阿爸自己弄的。(嘿,谁知道精神病人会做出什么事?)那时你开始明白气愤本身并不能改变现实。
这些,在你跟我诉说你那研究思觉失调友人的片言中,闪过脑际。“她说,好些大总裁和大教授或多或少都有神经病,只是后来受控制了就好了。”(如此轻易?)你说你喜欢 A Beautiful Mind,很佩服 John Nash 的坚毅,也希望自己能当个出色的教授,写的论文能精辟地说明个 Research question 并得到认可。
(不是每个人都那么幸运。)
“为什么突然这么静?” 我回你以微笑。不想多谈时就微笑。
**隐喻**
苏珊.桑塔《疾病的隐喻》尝试说明,疾病只是疾病,与隐喻无涉,亦无关惩处。可你不知道的是,“神经病” 这词已在我脑中印上了记。分手后事情几乎一发不可收拾。你说小孩不明白老人要的东西,然后就这样消失了。我不明白。我闹我发酒疯我到你宿舍楼下等了整个晚上你依然拒绝相见。我在长凳上等了一晚,看着也许是你房间的灯明灭,窗里的人影若即若离。凌晨离去时搭了德士,还能和司机温柔的介绍新校舍的建筑。原来伤心欲绝不过如此。
事后你来信,说我该找专业人士,而你会闪躲到一边,无需挂心。那行字,正中红心。也只有你能如此,常常戳破我成功骗过所有人的开朗面具,揭露我极不愿人知的晦暗一面。
后来给你写信,说我自己也吓坏了。那不堪的言语,恶毒的诅咒,气极下对过往的全盘否定,刀刀见血,且不留情面。可那是把双刃剑。比起受伤,我更介意的是如此伤人的自己。那长长的时间里,避免碰面,避免经过蕴藏共同回忆的地方,还要避过旁人的问长问短,真心和假意的关心。于是我学你,隐身江湖。独自坐上我们常一起搭的 33 号巴士。偶尔会从市中心一路哭回校舍。而这些你都不需要知道。我的心再也与你无关。
“一家人平平安安、健健康康最重要。” 阿嫲说。
平安又何尝容易?人生到处是吴刚。况且这吴刚还是自己派生出来的。
吴刚无意伐桂。师说。月桂有情,虽日日受创,却也随即愈合。你看,月桂树下还有杵着药的玉兔呢。你不知道,吴刚和月桂是同一个人。
“做人最重要嘅系开心。”
开心开心,是否将心锁卸去,不再自困自扰即是开心?我想,你还是待我好的。只是我还没好。
那天以后,无论受伤或伤人,已成事实,虽然我俩都不是有意为之。你不想这样一刀两断想弥补的心意我知道,可我还害怕我自己。那伤人的自己。我也害怕你。竟可以如此冷漠无情的你。
恐惧就横在这里,你我过不去,我们也回不去。人生的旅途漫漫,你和我只能各自修行。面朝大海,春暖花开。那是最后的独白,也是约定。我寄予明天的想望也很多,比如说孝顺与成就。但海子的明天未曾到来,他的尸首已卧铁轨。
“爸,对不起,我是个任性的孩子。” 我说。无业游民选择逃避选择玩,将两年的硕士生涯拖成 3 年。
“你才不是任性的孩子,你是好孩子。” 爸说。
到站了。
爸,我们下车吧。
博尔赫斯的现实- 余华
========================
博尔赫斯的现实- [[余华]]
------
这是一位退休的图书馆馆长、双目失明的老人,一位女士的丈夫,作家和诗人。就这样,晚年的博尔赫斯带着四重身份,离开了布宜诺斯艾利斯之岸,开始其漂洋过海的短暂生涯,他的终点是日内瓦。就像其他感到来日不多的老人一样,博尔赫斯也选择了落叶归根,他如愿以偿地死在了日内瓦。一年以后,他的遗孀接受了一位记者的采访。
玛丽娅·科达玛因为悲伤显得异常激动,记者在括号里这样写道:“整个采访中,她哭了三次。”然而有一次,科达玛笑了,她告诉记者:“我想我将会梦见他,就像我常常梦见我的父亲一样。密码很快就会出现,我们两人之间新的密码,需要等待……这是一个秘密。它刚刚到来……我与我父亲之间就有一个密码。”
作为一位作家,博尔赫斯与现实之间似乎也有一个密码,使迷恋他的读者在他生前,也在他死后都处于科达玛所说的“需要等待”之中,而且“这是一个秘密”。确实是一个秘密,很少有作家像博尔赫斯那样写作,当人们试图从他的作品中眺望现实时,能看到什么呢?
他似乎生活在时间的长河里,他的叙述里转身离去的经常是一些古老的背影,来到的又是虚幻的声音,而现实只是昙花一现的景色。于是就有了这样的疑惑,从1899年8月24日到1986年6月14日之间出现过的那个名叫博尔赫斯的生命,是否真的如此短暂?因为人们阅读中的博尔赫斯似乎有着历史一样的高龄,和源源不断的长寿。
就像他即将落叶归根之时,选择了日内瓦,而不是他的出生地布宜诺斯艾利斯,博尔赫斯将自己的故乡谜语般地隐藏在自己的内心深处,他也谜语一样地选择了自己的现实,让它在转瞬即逝中始终存在着。
这几乎也成为了博尔赫斯叙述时的全部乐趣。在和维尔杜戈·富恩斯特的那次谈话里,博尔赫斯说:“他(指博尔赫斯自己)写的短篇小说中,我比较喜欢的是《南方》《乌尔里卡》和《沙之书》。”
《乌尔里卡》开始于一次雪中散步,结束在旅店的床上。与博尔赫斯其他小说一样,故事单纯的就像是挂在树叶上的一滴水,一个上了年纪的男人和一个似乎还年轻的女人。博尔赫斯在小说的开始令人费解地这样写道:“我的故事一定忠于事实,或者至少忠于我个人记忆所及的事实。”
这位名叫乌尔里卡的女子姓什么?哈维尔·奥塔罗拉,也就是叙述中的“我”并不知道。两个人边走边说,互相欣赏着对方的发言,由于过于欣赏,两个人说的话就像是出自同一张嘴。最后“天老地荒的爱情在幽暗中荡漾,我第一次也是最后一次占有了乌尔里卡肉体的形象”。
为什么在“肉体”的后面还要加上“形象”?从而使刚刚来到的“肉体”的现实立刻变得虚幻了。这使人们有理由怀疑博尔赫斯在小说开始时声称的“忠于事实”是否可信?因为人们读到了一个让事实飞走的结尾。其实博尔赫斯从一开始就不准备拿事实当回事,与其他的优秀作家一样,叙述中的博尔赫斯不会是一个信守诺言的人。他将乌尔里卡的肉体用“形象”这个词虚拟了,并非他不会欣赏和品味女性之美,这方面他恰恰是个行家,他曾经在另一个故事里写一位女子的肉体时,使用了这样的感受:“平易近人的身体。”他这样做就是为了让读者离开现实,这是他一贯的叙述方式,他总是乐意表现出对非现实处理的更多关心。
仍然是在和维尔杜戈·富恩斯特的那次谈话里,我们读到了两个博尔赫斯,作为“我”的这个博尔赫斯谈论着那个“他”的博尔赫斯。有意思的是,在这样一次随便的朋友间的交谈里,博尔赫斯议论自己的时候,始终没有使用“我”这个词,就像是议论别人似的说“他”,或者就是直呼其名。谈话的最后,博尔赫斯告诉维尔杜戈·富恩斯特:“我不知道我们两人之中谁和你谈话。”
这让我们想到了那篇只有一页的著名短文《博尔赫斯和我》,一个属于生活的博尔赫斯如何对那个属于荣誉的博尔赫斯心怀不满,因为那个荣誉的博尔赫斯让生活中的博尔赫斯感到自己不像自己了,就像老虎不像老虎、石头不像石头那样,他抱怨道:“与他的书籍相比,我在许多别的书里,在一把吉他累人的演奏之中,更能认出我自己。”
然而到了最后,博尔赫斯又来那一套了:“我不知道我俩之中是谁写下了这一页。”
这就是怀疑,或者说这就是博尔赫斯的叙述。在他的诗歌里、在他的故事里以及他的随笔,甚至是那些前言里,博尔赫斯让怀疑流行在自己的叙述之中,从而使他的叙述经常出现两个方向,它们互相压制,同时又互相解放。
当他一生的写作完成以后,在其为数不多的作品里,我们看到博尔赫斯有三次将自己放入了叙述之中。第三次是在1977年,已经双目失明的博尔赫斯写下了一段关于1983年8月25日的故事,在这个夜晚的故事里,六十一岁的博尔赫斯见到了八十四岁的博尔赫斯,年老的博尔赫斯说话时,让年轻一些的博尔赫斯感到是自己在录音带上放出的那种声音。与此同时,后者过于衰老的脸,让年轻的博尔赫斯感到不安,他说:“我讨厌你的面孔,它是我的漫画。”
“真怪,”那个声音说,“我们是两个人,又是一个人……”
这个事实使两个博尔赫斯都深感困惑,他们相信这可能是一个梦,然而,“到底是谁梦见了谁?我知道我梦见了你,可是不知道你是否也梦见了我?”……“最重要的是要弄清楚,是一个人做梦还是两个人做梦。”有趣的是,当他们回忆往事时,他们都放弃了“我”这个词,两个博尔赫斯都谨慎地用上了“我们”。
与其他作家不一样,博尔赫斯在叙述故事的时候,似乎有意要使读者迷失方向,于是他成为了迷宫的创造者,并且乐此不疲。即便是在一些最简短的故事里,博尔赫斯都假装要给予我们无限多的乐趣,经常是多到让我们感到一下子拿不下。而事实上他给予我们的并不像他希望的那么多,或者说并不比他那些优秀的同行更多。不同的地方就在于他的叙述,他的叙述总是假装地要确定下来了,可是永远无法确定。我们耐心细致地阅读他的故事,终于读到了期待已久的肯定时,接踵而来的立刻是否定。于是我们又得重新开始,我们身处迷宫之中,而且找不到出口,这似乎正是博尔赫斯乐意看到的。
另一方面,这样的叙述又与他的真实身份──图书馆员吻合了起来,作为图书馆员的他,有理由将自己的现实建立在九十万册的藏书之上,以此暗示他拥有了与其他所有作家完全不同的现实。从而让我们读到“无限、混乱与宇宙,泛神论与人性,时间与永恒,理想主义与非现实的其他形式”。《迷宫的创造者博尔赫斯》的作者安娜·玛丽亚·巴伦奈切亚这样认为:“这位作家的著作只有一个方面──对非现实的表现──得到了处理。”
这似乎是正确的,他的故事总是让我们难以判断:是一段真实的历史还是虚构?是深不可测的学问还是平易近人的描叙?是活生生的事实还是非现实的幻觉?叙述上的似是而非,使这一切都变得真假难辨。
在那篇关于书籍的故事《沙之书》里,我们读到了一个由真实堆积起来的虚幻。一位退休的老人得到了一册无始无终的书:
“页码的排列引起了我的注意,比如说,逢双的一页印的是40,514,接下去却是999。我翻过那一页,背面的页码有八位数,像字典一样,还有插画:一个钢笔绘制的铁锚……我记住地方,合上书。随即又打开。尽管一页一页地翻阅,铁锚图案却再也找不到了。”
“他让我找第一页……我把左手按在封面上,大拇指几乎贴着食指去揭书页。白费劲,封面和手之间总有好几页。仿佛是从书里冒出来的……现在再找找最后一页……我照样失败。”
“我发现每隔两千页有一帧小插画。我用一本有字母索引的记事簿把它们临摹下来,记事簿不久就用完了。插画没有一张重复。”
这些在引号里的段落是《沙之书》中最为突出的部分,因为它将我们的阅读带离了现实,走向令人不安的神秘。就像作品中那位从国立图书馆退休的老人一样,用退休金和花体字的威克利夫版《圣经》换来了这本神秘之书,一本随时在生长和消亡的无限的书,最后的结局却是无法忍受它的神秘。他想到“隐藏一片树叶的最好地点是树林”,于是就将这本神秘之书偷偷放在了图书馆某一层阴暗的搁架上,隐藏在了九十万册藏书之中。
博尔赫斯在书前引用了英国玄学派诗人乔治·赫伯特的诗句:
……你的沙制的绳索……
他是否在暗示“沙之书”其实和赫伯特牧师的“沙制的绳索”一样的不可靠?然而在叙述上,《沙之书》却是用最为直率的方式讲出的,同时也是讲述故事时最为规范的原则。我们读到了街道、房屋、敲门声、两个人的谈话,谈话被限制在买卖的关系中……
显然,博尔赫斯是在用我们熟悉的方式讲述我们所熟悉的事物,即使在上述引号里的段落,我们仍然读到了我们的现实:“页码的排列”、“我记住地方,合上书”、“我把左手按在封面上”、“把它们临摹下来”,这些来自生活的经验和动作让我们没有理由产生警惕,恰恰是这时候,令人不安的神秘和虚幻来到了。
这正是博尔赫斯叙述里最为迷人之处,他在现实与神秘之间来回走动,就像在一座桥上来回踱步一样自然流畅和从容不迫。与他的其他故事相比,比如说《巴别图书馆》这样的故事,《乌尔里卡》和《沙之书》多少还为我们提供了一些现实的场景和可靠的时间,虽然他的叙述最终仍然让我们感到了场景的非现实和时间的不可靠,起码我们没有从一开始就昏迷在他的叙述之中。而另外一些用纯粹抽象方式写出的故事,则从一开始就拒我们于千里之外,如同观看日出一样,我们知道自己看到了,同时也看清楚了,可是我们永远无法接近它。虽然里面迷人的意象和感受已经深深地打动了我们,可我们依然无法接近。值得注意的是这些意象和感受总是和他绵绵不绝的思考互相包括,丝丝入扣之后变得难以分辨。
于是博尔赫斯的现实也变得扑朔迷离,他的神秘和幻觉、他的其他的非现实倒是一目了然。他的读者深陷在他的叙述之中,在他叙述的花招里长时间昏迷不醒,以为读到的这位作家是史无前例的,读到的这类文学也是从未有过的,或者说他们读到的已经不是文学,而是智慧、知识和历史的化身。最后他们只能同意安娜·玛丽亚·巴伦奈切亚的话:读到的是“无限、混乱与宇宙,泛神论与人性,时间与永恒,理想主义与非现实的其他形式”。博尔赫斯自己也为这位女士的话顺水推舟,他说:“我感谢她对一个无意识过程的揭示。”
事实上,真正的博尔赫斯并非如此虚幻。当他离开那些故事的叙述,而创作他的诗歌和散文时,他似乎更像博尔赫斯。他在一篇题为《神曲》的散文里这样写:“但丁试图让我们感到离弦飞箭到达的速度,就对我们说,箭中了目标,离了弦,把因果关系倒了过来,以此表现事情发生的速度是多么快……我还要回顾一下《地狱篇》第五唱的最后一句……‘倒下了,就像死去的躯体倒下。’为什么令人难忘?因为有‘倒下’的声响。”
在这里,博尔赫斯向我们揭示了语言里最为敏感的是什么,就像他在一篇小说里写到某个人从世上消失时,用了这样的比喻:“仿佛水消失在水中。”他让我们知道,比喻并不一定需要另外事物的帮助,水自己就可以比喻自己。他把本体和喻体,还有比喻词之间原本清晰可见的界线抹去了。
在一篇例子充足的短文《比喻》里面,博尔赫斯指出了两种已经存在的比喻:亚里士多德认为比喻生成于两种不同事物的相似性,和斯诺里所收集的并没有相似性的比喻。博尔赫斯说:“亚里士多德把比喻建立在事物而非语言上……斯诺里收集的比喻不是……只是语言的建构。”
历史学家斯诺里·斯图鲁松所收集的冰岛诗歌中的比喻十分有趣,博尔赫斯向我们举例:“比如愤怒的海鸥、血的猎鹰和血色或红色天鹅象征的乌鸦;鲸鱼屋子或岛屿项链意味着大海;牙齿的卧室则是指嘴巴。”
博尔赫斯随后写道:“这些串连在诗句中的比喻一经他精心编织,给人(或曾给人)以莫大的惊喜。但是过后一想,我们又觉得它们没有什么,无非是些缺乏价值的劳作。”
在对亚里士多德表示了温和的不赞成,和对斯诺里的辛勤劳动否定之后,博尔赫斯顺便还嘲笑了象征主义和词藻华丽的意大利诗人马里诺,接下去他一口气举出了十九个比喻的例子,并且认为“有时候,本质的统一性比表面的不同性更难觉察”。
显然,博尔赫斯已经意识到了比喻有时候也存在于同一个事物的内部,这时候出现的比喻往往是最为奇妙的。虽然博尔赫斯没有直接说出来,当他对但丁的“倒下了,就像死去的躯体倒下”赞不绝口的时候,当他在《圣经·旧约》里读到“大卫长眠于父母身旁,葬于大卫城内”时,他已经认识了文学里这一支最为奇妙的家族,并且通过写作,使自己也成为了这一家族中的成员。
于是我们读到了这样的品质,那就是同一个事物就足可以完成一次修辞的需要,和结束一次完整的叙述。博尔赫斯具备了这样的智慧和能力,就像他曾经三次将自己放入到叙述之中,类似的才华在他的作品里总是可以狭路相逢。这才真正是他与同时代很多作家的不同之处,那些作家的写作都是建立在众多事物的关系上,而且还经常是错综复杂的关系,所以他们必须解开上百道方程式,才有希望看到真理在水中的倒影。
博尔赫斯不需要通过几个事物相互建立起来的关系写作,而是在同一事物的内部进行着瓦解和重建的工作。他有着奇妙的本领,他能够在相似性的上面出现对立,同时又可以是一致。他似乎拥有了和真理直接对话的特权,因此他的声音才那样的简洁、纯净和直接。
他的朋友,美国人乔瓦尼在编纂他的诗歌英译本的时候发现:“作为一个诗人,博尔赫斯多年来致力于使他的写作愈来愈明晰、质朴和直率。研究一下他通过一本又一本诗集对早期诗作进行的修订,就能看出一种对巴罗克装饰的清除,一种对使用自然词序和平凡语言的更大关心。”
在这个意义上,博尔赫斯显然已经属于了那个古老的家族。在他们的族谱上,我们可以看到这样的名字:荷马、但丁、蒙田、塞万提斯、拉伯雷、莎士比亚……虽然博尔赫斯的名字远没有他那些遥远的前辈那样耀眼,可他不多的光芒足以照亮一个世纪,也就是他生命逗留过的20世纪。在博尔赫斯这里,我们看到一种古老的传统,或者说是古老的品质,历尽艰难之后成为了永不消失。这就是一个作家的现实。
当他让两个博尔赫斯在漫长旅途的客栈中相遇时,毫无疑问这是一个在幻觉里展开的故事,可是当年轻一些的博尔赫斯听到年老的博尔赫斯说话时,感到是自己在录音带上放出的那种声音。多么奇妙的录音带,录音带的现实性使幻觉变得真实可信,使时间的距离变得合理。在他的另一个故事《永生》里,一个人存活了很多个世纪,可是当这个长生不死的人在沙漠里历经艰辛时,博尔赫斯这样写道:“我一连好几天没有找到水,毒辣的太阳、干渴和对干渴的恐惧使日子长得难以忍受。”在这个充满神秘的故事里,博尔赫斯仍然告诉了我们什么是恐惧,或者说什么才是恐惧的现实。
这就是博尔赫斯的现实。尽管他的故事是那样的神秘和充满了幻觉,时间被无限地拉长了,现实又总是转瞬即逝,然而当他笔下的人物表达感受和发出判断时,立刻让我们有了切肤般的现实感。就像他告诉我们,在“干渴”的后面还有更可怕的“对干渴的恐惧”那样,博尔赫斯洞察现实的能力超凡脱俗,他外表温和的思维里隐藏着尖锐,只要进入一个事物,并且深入进去,对博尔赫斯来说已经足够了。
这正是博尔赫斯叙述中最为坚实的部分,也是一切优秀作品得以存在的支点,无论这些作品是写实的,还是荒诞的或者是神秘的。
然而,迷宫似的叙述使博尔赫斯拥有了另外的形象,他自己认为:“我知道我文学产品中最不易朽的是叙述。”事实上,他如烟般飘起的叙述却是用明晰、质朴和直率的方式完成的,于是最为变幻莫测的叙述恰恰是用最为简洁的方式创造的。因此,美国作家约翰·厄普代克这样认为:博尔赫斯的叙述“回答了当代小说的一种深刻需要──对技巧的事实加以承认的需要”。
与其他作家不同,博尔赫斯通过叙述让读者远离了他的现实,而不是接近。他似乎真的认为自己创造了叙述的迷宫,认为他的读者找不到出口,同时又不知道身在何处。他在《秘密奇迹》的最后这样写:“行刑队用四倍的子弹,将他打倒。”
这是一个奇妙的句子,博尔赫斯告诉了我们“四倍的子弹”,却不说这四倍的基数是多少。类似的叙述充满了他的故事,博尔赫斯似乎在暗示我们,他写到过的现实比任何一个作家都要多。他写了四倍的现实,可他又极其聪明地将这四倍的基数秘而不宣。在这不可知里,他似乎希望我们认为他的现实是无法计算的,认为他的现实不仅内部极其丰富,而且疆域无限辽阔。
他曾经写到过有个王子一心想娶一个世界之外的女子为妻,于是巫师“借助魔法和想象,用栎树花和金雀花,还有合叶子创造了这个女人”。博尔赫斯是否也想使自己成为文学之外的作家?
一九九八年三月三日
布尔加科夫与《大师和玛格丽特》-余华
========================
布尔加科夫与《大师和玛格丽特》-[[余华]]
-----
布尔加科夫
1930年3月28日,贫困潦倒的布尔加科夫给斯大林写去了一封信,希望得到莫斯科艺术剧院一个助理导演的职位。“如果不能任命我为助理导演……”他说,“请求当个在编的普通配角演员。如果当普通配角也不行,我就请求当个管剧务的工人。如果连工人也不能当,那就请求苏联政府以它认为必要的任何方式尽快处置我,只要处置就行……”
作为一位作品被禁的大师,布尔加科夫在骄傲与克服饥饿之间显得困难重重,最终他两者都选择了,他在“请求”的后面没有丝毫的乞讨,当他请求做一个管剧务的工人时,依然骄傲地说:“只要处置就行。”
同年4月18日,斯大林拨通了布尔加科夫家的电话,与布尔加科夫进行了简短的交谈,然后布尔加科夫成为了莫斯科艺术剧院的一名助理导演。他重新开始写作《大师和玛格丽特》,一部在那个时代不可能获得发表的作品,布尔加科夫深知这一点,因此他的写作就更为突出地表达了内心的需要,也就是说他的写作失去了实际的意义,与发表、收入、名誉等等毫无关系,写作成为了纯粹的自我表达,成为了布尔加科夫对自己的纪念。
这位来自基辅的神学教授的儿子,自幼腼腆、斯文、安静,他认为:“作家不论遇到多大困难都应该坚贞不屈……如果使文学去适应把个人生活安排得更为舒适、富有的需要,这样的文学便是一种令人厌恶的勾当了。”
他说到做到,无论是来自政治的斯大林的意见,还是来自艺术的斯坦尼斯拉夫斯基的压力,都不能使他改变自己的主张,于是他生活贫困,朋友疏远,人格遭受侮辱,然而布尔加科夫“微笑着接受厄运的挑战”,就像一首牙买加民歌里的奴隶的歌唱:“你们有权利,我们有道德。”
在这种情况下,布尔加科夫的写作只能是内心独白,于是在愤怒、仇恨和绝望之后,他突然幸福地回到了写作,就像疾病使普鲁斯特回到写作,孤独使卡夫卡回到写作那样,厄运将布尔加科夫与荣誉、富贵分开了,同时又将真正的写作赋予了他,给了他另一种欢乐,也给了他另一种痛苦。
回到了写作的布尔加科夫,没有了出版,没有了读者,没有了评论,与此同时他也没有了虚荣,没有了毫无意义的期待。他获得了宁静,获得了真正意义上的写作。他用不着去和自己的盛名斗争;用不着一方面和报纸、杂志夸夸其谈,另一方面独自一人时又要反省自己的言行。最重要的是,他不需要迫使自己从世俗的荣耀里脱身而出,回到写作,因为他没有机会离开写作了,他将自己的人生掌握在叙述的虚构里,他已经消失在自己的写作之中,而且无影无踪,就像博尔赫斯写到佩德罗·达米安生命消失时的比喻:“仿佛水消失在水中。”
在生命的最后十二年里,布尔加科夫失去一切之后,《大师和玛格丽特》的写作又使他得到了一切;他虚构了撒旦对莫斯科的访问,也虚构了自己;或者说他将自己的生活进行了重新的安排,他扩张了想象,缩小了现实。因此在最后的十二年里,很难说布尔加科夫是贫困的,还是富有的;是软弱的,还是强大的;是走投无路,还是左右逢源。
大师和玛格丽特
在这部作品中,有两个十分重要的人物,就是大师和玛格丽特,他们第一次的出现,是在书的封面上,可是以书名的身份出现了一次以后,他们的第二次出现却被叙述一再推迟,直到284页,大师才悄然而来,紧接着在314页的时候,美丽的玛格丽特也接踵而至了。在这部580页的作品里,大师和玛格丽特真正的出现正是在叙述最为舒展的部分,也就是一部作品中间的部分。这时候,读者已经忘记了书名,忘记了曾经在书的封面上看到过他们的名字。
在此之前,化名沃兰德的撒旦以叙述里最为有力的声音,改变了莫斯科的现实。虽然撒旦的声音极其低沉,低到泥土之下,但是它建立了叙述的基础,然后就像是地震一样,在其之上,我们看到了莫斯科如何紧张了起来,并且惊恐不安。
显然,布尔加科夫的天才得到了魔鬼的帮助,饱尝痛苦和耻辱的内心,使他在有生之年就远离了人世,当他发现自己讨厌的不是几个人,而是所有的人时,他的内心逐渐地成为了传说,在传说中与撒旦相遇,然后和撒旦重叠。因此可以这样说,《大师和玛格丽特》里的撒旦,就是布尔加科夫自己,而大师——这个试图重写本丢·彼拉多的历史的作家,则是布尔加科夫留在现实里的残缺不全的影子。
从钱诚先生的汉语翻译来看,《大师和玛格丽特》的叙述具备了19世纪式的耐心,尤其是开始的几章,牧首湖畔的冗长的交谈,本丢·彼拉多对耶稣的审讯,然后又回到牧首湖畔的谈话,61页过去了,布尔加科夫才让那位诗人疯跑起来,当诗人无家汉开始其丧失理智的疯狂奔跑,布尔加科夫叙述的速度也跑动起来了,一直到283页,也就是大师出现之前,布尔加科夫让笔下的人物像是传递接力似的,把叙述中的不安和恐惧迅速弥漫开去。
我们读到的篇章越来越辉煌,叙述逐渐地成为了集会,莫斯科众多的声音一个接着一个地汇入红场。在魔鬼的游戏的上面,所有的人都在惊慌失措地摇晃,而且都是不由自主。所发生的一切事都丧失了现实的原则,人们目瞪口呆、浑身发抖、莫名其妙和心惊胆战。就这样,当所有的不安、所有的恐惧、所有的虚张声势都聚集起来时,也就是说当叙述开始显示出无边无际的前景时,叙述断了。这时候大师和玛格丽特的爱情开始了,强劲有力的叙述一瞬间就转换成柔情似水,中间没有任何过渡,就是片刻的沉默也没有,仿佛是突然伸过来一双纤细的手,“咔嚓”一声扭断了一根铁管。
这时候283页过去了,这往往是一部作品找到方向的时候,最起码也是方向逐渐清晰起来的时候,因此在这样的时候再让两个崭新的人物出现,叙述的危险也随之产生,因为这时候读者开始了解叙述中的人物了,叙述中的各种关系也正是在这时候得到全部的呈现。叙述在经历了此刻的复杂以后,接下去应该是逐渐单纯地走向结尾。所以,作家往往只有出于无奈,才会在这时候让新的人物出来,作家这样做是因为新的人物能够带来新的情节和新的细节,将它们带入停滞不前的叙述中,从而推动叙述。
在这里,大师和玛格丽特的出现显然不是出于布尔加科夫的无奈,他们虽然带来了新的情节和新的细节,但是他们不是推动,而是改变了叙述的方向。这样一来,就注定了这部作品在叙述上的多层选择,也就是说它不是一部结构严密的作品。事实也正是如此,人们在这部作品中读到的是一段又一段光彩夺目的篇章,而章节之间的必要联结却显得并不重要了,有时候甚至没有联结,直接就是中断。
布尔加科夫在丰富的欲望和叙述的控制之间,做出了明智的选择,他要表达的事物实在是太多了,以至于叙述的完美必然会破坏事实的丰富,他干脆放任自己的叙述,让自己的想象和感受尽情发挥,直到淋漓尽致之时,他才会做出结构上的考虑。这时候大师和玛格丽特的重要性显示出来了,正是他们的爱情,虚幻的和抽象的爱情使《大师和玛格丽特》有了结构,同时也正是这爱情篇章的简短,这样也就一目了然,使结构在叙述中浮现了出来,让叙述在快速奔跑的时候有了回首一望,这回首一望恰到好处地拉住了快要迷途不返的叙述。
《大师和玛格丽特》似乎证明了这样的一种叙述,在一部五百页以上的长篇小说里,结构不应该是清晰可见的,它应该是时隐时现,它应该在叙述者训练有素的内心里,而不应该在急功近利的笔尖。只有这样,长篇小说里跌宕的幅度辽阔的叙述才不会受到伤害。
大师和玛格丽特,这是两个雕像般的人物,他们具有不可思议的完美,布尔加科夫让他们来自现实,又不给予他们现实的性格。与柏辽兹、斯乔帕、瓦列奴哈和里姆斯基他们相比,大师和玛格丽特实在不像是莫斯科的居民。这并不是指他们身上没有莫斯科平庸和虚伪的时尚,重要的是在他们的内心里我们读不到莫斯科的现实,而且他们的完美使他们更像是传说中的人物,让人们觉得他们和书中的撒旦、耶稣还有本丢·彼拉多一样古老,甚至还没有撒旦和耶稣身上的某些现实性,而大师笔下的犹太总督本丢·彼拉多,倒是和今天的政治家十分相近。
布尔加科夫在描叙这两个人物时,显然是放弃了他们应该具有的现实性。因为在《大师和玛格丽特》里,我们已经读到了足够多的现实。在柏辽兹、里姆斯基这些莫斯科的平庸之辈那里,布尔加科夫已经显示出了其洞察现实的天才,可以说是我们要什么,布尔加科夫就给了我们什么。就是在撒旦,在耶稣,在本丢·彼拉多那里,我们也读到了来自人间的沉思默想,来自人间的对死亡的恐惧和来自人间的如何让阴谋得以实现。
在长达十二年的写作里,布尔加科夫有足够多的时间来斟酌大师和玛格丽特,他不会因为疏忽而将他们写得像抒情诗那样与现实十分遥远。当然,他们也和现实格格不入。布尔加科夫之所以这样,就是要得到叙述上的不和谐,让大师和玛格丽特在整个叙述中突出起来,然后,正像前面所说的那样,使结构在叙述中得到浮现。
在《大师和玛格丽特》里,作为一个作家,大师与现实之间唯一的联系,就是他被剥夺了发表作品的自由,这一点和布尔加科夫的现实境况完全一致,这也是布尔加科夫自身的现实与作品之间的唯一联系。这样的联系十分脆弱,正是因为其脆弱,大师这个人物在布尔加科夫的笔下才如此虚幻。
在这里,布尔加科夫对自己的理解是虚幻的,或者说他宁愿虚幻地去理解自己。现实的压制使他完全退回到了自己的内心,接着又使他重新掌握了自己的命运,他将自己的命运推入到想象之中。于是出现了玛格丽特,这个美丽超凡的女子,与大师一样,她也沉浸在自己的想象之中。两个同样的人在莫斯科的某一个街角邂逅时,都是一眼就看出了对方的内心,爱情就这样开始了。
玛格丽特的出现,不仅使大师的内心获得了宁静,也使布尔加科夫得到了无与伦比的安慰。这个虚幻的女子与其说是为了大师而来,还不如说是布尔加科夫为自己创造的。大师只是布尔加科夫在虚构世界里的一个代表:当布尔加科夫思考时,他成为了语言;当布尔加科夫说话时,他成为了声音;当布尔加科夫抚摸时,他成为了手。因此可以这样说,玛格丽特是布尔加科夫在另一条人生道路上的全部的幸福,也是布尔加科夫现实与写作之间的唯一模糊之区。只有这样,布尔加科夫才能完好无损地保护住了自己的信念,就像人们常说的这是爱情的力量,并且将这样的信念继续下去,就是在自己生命结束以后,仍然让它向前延伸,因为他的另一条人生道路没有止境。
所以当大师的完美因为抽象而显得苍白时,玛格丽特的完美则是楚楚动人。对布尔加科夫来说,《大师和玛格丽特》中的大师在很大程度上只是结构的需要,玛格丽特就不仅仅是结构的需要了,她柔软的双肩同时还要挑起布尔加科夫内心沉重的爱情。
于是她不可逃避地变得极其忧郁,她的忧郁正是大师——其实是布尔加科夫——给予的,是大师在镜中映出的另一个人的现实造成的。玛格丽特被撒旦选中,出来担当魔鬼晚会的女主人,这位一夜皇后在布尔加科夫笔下光彩照人。虽然在这辉煌的篇章里,有关玛格丽特最多的描绘是她的视线,让她的视线去勾勒晚会的全部,也就是说在这个篇章里主要出现的都是别人,玛格丽特出现的只是眼睛,然而这正是人们常说的烘云托月,布尔加科夫向我们证明了烘云托月是最能让女人美丽,而且也是女人最为乐意的。
不久之后,玛格丽特开始在天空飞翔了,这又是一段美丽无比的描叙,让玛格丽特的身体在夜空的风中舒展开来,虚幻之后的美已经无法表达,只有几声叹息来滥竽充数。飞翔的最后是看到了一条月光铺成的道路,这条道路来自于遥远的月亮,在月光路上,玛格丽特看到本丢·彼拉多拼命地追赶着耶稣,大声喊叫着告诉耶稣:杀害他的不是本丢·彼拉多。
作家就是这样,穷尽一生的写作,总会有那么一两次出于某些隐秘的原因,将某一个叙述中的人物永远留给自己。这既是对自己的纪念,也是对自己的奖励。布尔加科夫同样如此,玛格丽特看上去是属于《大师和玛格丽特》的,是属于所有阅读者的,其实她只属于布尔加科夫。她是布尔加科夫内心的所有的爱人,是布尔加科夫对美的所有的感受,也是布尔加科夫漫长的人生中的所有力量。在玛格丽特这里,布尔加科夫的内心得到了所有的美和所有的爱,同时也得到了所有的保护。玛格丽特在天空的飞翔曾经中断过一次,就是为了大师,也就是布尔加科夫,她在莫斯科的上空看到了伤害大师的批评家拉铜斯基的住所,于是她毅然中断了美丽的飞翔,降落到了拉铜斯基的家中,将所有的仇恨都发泄了出来。事实上她的仇恨正是布尔加科夫的仇恨,而她的发泄又正是布尔加科夫内心深处对自己的保护。有时候道理就是这样简单。
幽默与现实
可以说,《大师和玛格丽特》的写作,是布尔加科夫在生命最后岁月里最为真实的生活,这位几乎是与世隔绝的作家,就是通过写作,不停的写作使自己与现实之间继续着藕断丝连的联系。
在卡夫卡之后,布尔加科夫成为20世纪又一位现实的敌人,不同的是卡夫卡对现实的仇恨源自于自己的内心,而布尔加科夫则有切肤之痛,并且伤痕累累。因此,当他开始发出一生中最后的声音时,《大师和玛格丽特》就成为了道路,把他带到了现实面前,让他的遗嘱得到了发言的机会。
这时候对布尔加科夫来说,与现实建立起什么样的关系就显得极其重要了,显然他绝不会和现实妥协,可是和现实剑拔弩张又会使他的声音失去力量,他的声音很可能会成为一堆谩骂,一堆哭叫。
他两者都放弃了,他做出的选择是一个优秀作家应有的选择,最后他与现实建立了幽默的关系。他让魔鬼访问莫斯科,作品一开始他就表明了自己的态度,那就是他要讲述的不是一个斤斤计较的故事,他要告诉我们的不是个人的恩怨,而是真正意义上的现实,这样的现实不是人们所认为的实在的现实,而是事实、想象、荒诞的现实,是过去、现在、将来的现实,是应有尽有的现实。同时他也表明了自己的内心在仇恨之后已经获得了宁静。所以,他把撒旦请来了。撒旦在作品中经常沉思默想,这样的品格正是布尔加科夫历尽艰难之后的安详。
因此,布尔加科夫对幽默的选择不是出于修辞的需要,不是叙述中机智的讽刺和人物俏皮的发言。在这里,幽默成为了结构,成为了叙述中控制的恰如其分的态度,也就是说幽默使布尔加科夫找到了与世界打交道的最好方式。
正是这样的方式,使布尔加科夫在其最后的写作里,没有被自己的仇恨淹没,也没有被贫穷拖垮,更没有被现实欺骗。同时,他的想象力,他的洞察力,他写作的激情开始茁壮成长了。就这样,在那最后的十二年里,布尔加科夫解放了《大师和玛格丽特》的叙述,也解放了自己越来越阴暗的内心。
一九九六年八月二十日
布偶猫-周晓枫
========================
布偶猫-[[周晓枫]]
-----
1
倒叙,时间回到一年以前。
无需触碰和抚摸,你就能感觉它的柔软,皮毛仿佛经过轻微静电的蓬松处理。这只名叫布布的猫格外温顺,被陌生人以并不舒服的姿势紧拥,布布尽量适应,不叫,不挣扎。它的主人告诉我,布布刚来时只是刚满月的黏人小毛球,天生就擅长自我克制,乖巧,清洁,从不抓坏家具。当我抱着布布离开它所熟悉的环境,它软绵绵地靠在我肩膀上,像只松懈的暖水袋,温热、随形,让人觉得,它根本没有猫科动物的利爪与尖牙。
这正是布偶猫作为宠物受到欢迎的原因。异常安静和友善,松弛柔软像个布娃娃,因此有了这样的得名,它以对疼痛的惊人忍受力著称,甚至外伤和骨折,布偶猫也无表情和呻吟,让人怀疑它真的像布娃娃一样丧失痛感。布偶猫并非迟钝,它艰难消化着自身的不幸,对灾难抱有持久的接受耐心。耐痛的美德,正是布偶猫的独特之处。
布布长得颇有别趣,属于布偶猫里的重点色品种:身体的大部分纯白,脸、耳朵、四肢和尾巴呈现巧克力色的晕染效果……只有匍匐在地、埋下脸部才能同时晕染到这几个部位,好像是它天生会做跪拜的动作。猫,多数都具有杀手那样矫捷的身段和凌厉的眼锋;布偶猫,友善、服从,不喜欢挑衅和威胁。
布布像戴了手套似的两只前爪搭在我肩上,它有时用可爱的小脑袋蹭蹭我,给予我轻易且由衷的信任。布布不知道自己的命运将发生短期改变。它对小主人身上发生的意外,一无所知。
2
黑白相间的X光片影像,如同骷髅。
左侧上颌骨可见两处骨质不连续阴影,骨折线锐利。透射线能揭示隐藏在皮层之后的损伤,除此之外,小怜受到的伤害明显。清创之后,她像米其林轮胎广告人那样被重重裹缠,掩盖了头枕部2厘米和额颢部3厘米的伤口。左侧耳膜穿孔,左眼面临失明,只剩模糊光感,要等瘀肿消除之后再次进行伤情鉴定。手,由于抵挡凶器挫伤,小怜全身多处青紫,血块在皮下组织沉积淤塞,让年仅十九岁的姑娘如此斑驳。病床上的小怜,就像个弄坏的布娃娃被扔在那里。
面对哭泣的父母和质询的警察,小怜沉默。只有一次,她向护士小声求乞打杜冷丁止痛,剩下的,她对自己的伤情不谈不问,似乎成了局外人。案件如何发生,时间、地点和人物究竟怎样,小怜一概没有说明和解释,只是不放心她的猫,叮嘱有人要去照顾布布。小怜是我同学的侄女,因为我既清闲又有养猫经验,寄养布布的任务辗转交给了我。
出事之前,小怜刚刚喂过听话的布布,又奖励给它一条鱼刺。凶器一样的食物,布布惬意地享受上面细密的荆棘,它有这个天赋,可以不让鱼刺划伤自己的咽喉和食道。饱餐后的布布感恩地依偎着主人的脚踝,而小怜独自吃饭,完成寂寞而潦草的消化……布布所依偎的脚踝,离家后不久,遭到棍棒轮番击打。
3
行凶者的名字不是秘密。
猜也猜得出来,是她的男朋友。并非第一次动手,不能用激情犯罪来解释他的恶行。前两次不过皮外伤,遮掩之后就过去了,这回严重。小怜几乎被打瞎眼睛,也许导致某种偏移终身难以得到校正。男友施暴,有时因妒意,有时因琐事,这次,起端于几乎是无聊的争执、积怨和关于分手的谈判。这场历时一年、激情澎湃的恋爱,衔接以可怕的尾声。
开端可谓美好,深情款款,一对璧人。沉浸在彼此的身体和快感里,他们如影随形,男友在黑暗里不断施放雄性的烟花……然后在她体内积累足够的灰烬。他们曾拥有节日般的往昔。幸福敲门的声音轻微而短促,听起来,像被硬甲虫撞了一下……等人满怀欣喜地迎接,它已碾碎在门框之下,带着它幼稚可笑的小翅膀和一腔难以分辨的糊涂的内脏。那只名叫幸福的小昆虫,那么古老,却是一副童话的清新模样,可惜承受不了一只从上面任意踏过的脚——幸福如此不承重,被破坏后的尸体惨不忍睹。
男友来自婚姻畸形的家庭,目睹父亲的暴力,他继承同样的方式来解决冲突。这个下手凶狠的男性符合施暴者的心理特征:强烈占有欲、不安感、冲动以及低自尊。自知罪孽深重、难逃法责,肇事之后,男友跑了。
警方希望小怜提供线索,以便早日将嫌犯捉拿归案。小怜不配合,不提供任何可能,千疮百孔的受害者低头,迟迟不语。可怜的孩子已被恐惧深深笼罩,她蜷起四肢,形同遭受暴力的姿态,回缩成为母腹中脆弱的胎儿。小怜像只脱尽羽毛的越冬鸟,像个被突然定义的孤儿……既不能接受现实,也难以面对未来。
4
我的同学以前发现过小怜的伤痕,强烈建议自己的侄女尽早分手,可小怜为男友辩护。悲剧中有一种诗意的美学,女性容易沉湎其中。散发珠光、宛如少女的小怜甚至是喜欢流泪的,这几乎变成她秘密的消遣;与其说她迷恋爱情,不如说迷恋其中浓烈的悲伤。小怜最初幻想以悲剧女主角的示弱与忍耐,唤起男人的怜爱,她以为暴力是欠账的方式,男友将在未来加倍偿还自己,其实都是错觉。
由柔弱变为懦弱,这是暴力升级的重要原因。男女之间的关系,是通过不断试错、触底才得以确立界限的,小怜一再退让,体罚和伤害成了男友习惯运用的统治手段。这是爱吗?小怜真傻,被伤到剧烈,还要在掩饰中歌唱,仿佛注定是男友的密纹唱片,可以承受他重复中不断的划痛。想不明白,为何小怜对施暴者的依赖如此强烈,以致她很早就散发出一种爱情殡葬品的气息。
终于在异地抓到潜逃者,从警察那里得知的情况让人瞠目结舌。
趁看护人不备,小怜用仅剩的没有受伤的手指头,吃力地给男友发送短信:他们一直有联系!小怜清楚男友的逃跑路线和栖身之所,只是拒不交待。古怪地,她把那看作一种情感出卖,她始终包庇加害自己的罪犯——出于细心的保护,她甚至注意更改通讯录里的名字,用昵称指代男友。小怜密告男友:“警察正在调查,追踪你的行迹;现在尽量少联系,先别回来,会被判刑。”
几乎致残的小怜,不希望男友受到法律制裁。当行凶者被绳之以法,小怜不快,并且明显不希望自己解脱。好像寡妇守节一样,小怜坚守着不快——似乎,不快才是她的忠贞。
小怜一次次情愿把自己送回险境,让我想起达尔文在《物种起源》里的描述:“许多人都曾经听说过,在活体解剖的时候狗一边忍着痛,一边还舔着手术者的手;只要这个人的心不是石头做的,那么他生命中余下的时光都将带着悔恨。”小怜自己的心理问题,比她的男友更严重。
5
丧失平等,意味着关系的失衡。亲密关系中的暴力并不鲜见,女人通常为主要受害者。从常见的推掇、扇耳光、拳打脚踢,上升到用刑般的灼烫、刺字、皮带抽、棍棒打。在施暴者的观念里,私人领域的肢体冲突并非犯罪,似乎在某种特殊情况下可以偶然逾越界限。
诉诸武力的男人,体现出低智、低能。暴力完成统治,但它同时是失败的证明,证明这个男人无法以魅力或能力等更为简易、经济而有效的手段达至成效,只能用消耗体力的笨重方式,来表达态度。也许对某类男人来说,恰恰由于其他途径的失效,暴力成为被认可的唯一捷径。女人,被操纵中的小玩偶,她的悲戚、恐慌和屈服,对他来说是一种小娱乐──哭红的眼睛,颤抖的肩膀,女人反而具有旦角般的一种妩媚……哀感顽艳的形象让他兴奋,仿佛听到做爱中的叹息。
男性借摧毁,以验证力量。将中西历史向前翻动数页,我们在至今仍被旧习统治的某些区域,或者就在我们切近的身旁,都可以找到普证。然而,部分女性当事者对于暴力的长期忍耐,几乎到了适应角色的程度。
6
有些恋情,一开始就埋下意外却必然的陷阱。受伤的女人啊,她担忧自己还能不能忍住满身的伤痛去拥抱施暴者——像个脱臼的孩子,小心翼翼,用被对方打至弯曲的骨节,去修复这种包含敌意的关系,哪怕,她自己已难承受哪怕温存的抚摸。无数次逃离的机会,她都放弃,选择回到阴影的笼罩之中。用恐惧是不能彻底解释的,因为即使暴君消除,她依然在他的灵位下殉情。毕加索的女人们,就是极端的例证。
朵拉·玛尔曾是颇具才华的摄影家,年轻、聪明,美貌的脸,长得像嘉宝那样带有冷艳的神秘感。当五十四岁的毕加索在咖啡馆遇到迷人的朵拉,惊为天人和艺术创造的缪斯。二十八岁的朵拉从此走入毁灭性的关系,被这位天才狂热的性欲和偶尔的温情所征服,越陷越深难以自拔。
毕加索创作过一幅最为凶暴的妇女形象,这是以朵拉为原型的《裸体梳妆女》。与此同时,是毕加索对朵拉的殴打,许多次打得她躺在地板上不省人事。事实上,从1939年至1940年间,毕加索的画作有超过三分之二的比例在画畸形扭曲的女人,脸和肢体都被暴力袭击过一样,或是被愤怒所席卷。毕加索羞辱朵拉说:“你不美……就是会哭!”于是朵拉放声大哭,毕加索得以继续创作他的《哭泣的女人》,完成一个被撕裂的女性形象。毕加索饶有兴致地旁观情人之间争风吃醋、拳打脚踢,当朵拉被玛丽·泰蕾兹打出满嘴的血,袖手旁观的毕加索更有激情去创作他的巨幅油画,来谴责人类斗争的恐怖。
即使二人恋情结束,朵拉的肉体伤害得以终止,但内心的折磨继续。当毕加索第一次见到朵拉,她正挑战血淋淋的游戏,用刀快速插进张开的指缝里,并果真扎伤了手指;然而,被毕加索抛弃的朵拉,却丧失了复仇与解放自己的勇气。朵拉依然牵挂毕加索:“有时她悄悄来到毕加索工作室外张望。一个节日的晚上,她感到很孤单,她知道毕加索到南方去了,却穿着晚礼服,乘出租车又来到那里,她坐在车上,一直待到东方发白,泪流满面。”
朵拉珍惜毕加索留给她的所有,从画作到餐巾纸上随意的涂鸦,从未出售。她把毕加索相赠的房产,建造成一座关于他的纪念馆。朵拉长期住在疗养院,接受包括电击的理疗。当毕加索的至交艾吕雅,征求毕加索的同意后来追求朵拉,想用爱情唤醒朵拉已然丧失殆尽的智慧和微妙的艺术感觉,遭到朵拉的拒绝,因为她说:“毕加索之后,只有上帝。”她曾奢望汹涌而专注的爱,失宠的不甘与屈辱,使精神崩溃的朵拉在回忆的废墟中度过残生,穷困潦倒,无名且无人知晓地离世。围绕着毕加索的轨道旋转,像浴缸里旋转的水流,体会如置幸福感的晕眩错觉……越迷惑,越快进入脏黑的下水道之中。朵拉被吞噬,片甲不留。
7
当初与朵拉在画室互殴的玛丽·泰蕾兹,也绝非竞争中的获胜者。1927年初,还是未成年少女的玛丽·泰蕾兹在火车站与毕加索相遇,并于数年后为他生下女儿玛雅。因为毕加索有妇之夫的身份,女儿当时得不到法律的认可。毕加索要求泰蕾兹每天给他写信,否则,他说“我就会生病的”;毕加索的回信里满是鲜花、白鸽以及“你是最好的女人”“只爱你一个”之类的甜言蜜语,尽管当时毕加索既有法律上的婚姻,又有公开化的情人。毕加索的艳遇太多了,他那么殷勤地背叛自己的誓言,那么坦荡地陷入崭新的狂热。
可泰蕾兹必须对毕加索的宠幸和吩咐感激涕零,甚至感恩戴德。驯服的玛丽·泰蕾兹,盲目遵从毕加索,全部的生活就是等待着他闲暇时前来看望。在毕加索不出现的日子里,泰蕾兹锁上一间空房,并且告诫女儿:父亲正在里面工作,不要打扰。毕加索死后,泰蕾兹在自己与毕加索相识的五十周年纪念日,上吊自杀。床头,正是一张印有毕加索讣告的旧报。
最后一任妻子杰奎琳,外界评说为“唯一能拴住毕加索的绳子”的女人,在毕加索去世后,她靠服药和酗酒抵抗漫长而剧烈的煎熬。当走过挂着毕加索肖像的长廊,杰奎琳对着暴君的遗像表白:“阁下,请吩咐我。”在毕加索去世十三年之后,在他生日纪念这天,过度抑郁的杰奎琳,对准自己的太阳穴开枪自杀,完成了她迟到且终将的殉情。国王可以进行死后的统治,他的奴隶来了。她的亡灵追随并服侍他,在死神铺开的锦榻……继续无尽黑暗中的缱绻,从此不要天明。
8
她们为什么没有成为及时的避难者?多数受害女性因为没有找到逃生路径,除此之外,有些女性却自愿受到这种危险关系磁极般的吸引。有人语气铿锵地指责家暴受害者,认为她们乏智,咎由自取。一味指责性格缺陷,对她们已构成另外延伸的暴力,我们不妨转移注意力,探讨暴力中的寄生关系。
所谓亲密,首先需要打破间距,这是建立在微妙的侵犯之上才能获得的关系。友谊,所谓深交,是建立在开放基础上的侵犯特权。性,意味着同时进行的肢体亲密与肢体冲突,是由肉体彼此侵犯带来的享乐。婚姻需要分享情爱、家人、财产和秘密,这是法律赋予的正义。夫妻之间讲礼貌,有时出自教养,有时是形式感不那么明确的冷暴力。在私人情感领域,忍受礼貌比忍受粗暴有时更难,粗暴至少说明两者之间特殊的亲近;而礼貌,甚至是以并不婉曲的方式告知:这是仅限于皮毛意义的泛泛之交。
暴力逾越常人之间的秋毫无犯:激进的特权,夸张的表态。失控的情绪和肢体配合在一起,很像强烈到失控的爱欲。更深入的侵犯,更密切的榫接,更痛楚的咬合,血肉嵌进血肉,齿锋咬紧齿锋……锐利的金属牙,连续运转。暴躁者把情感狂飙到极值,施受双方一旦习惯这种强度,似乎就难以满足日常的平淡——宁静,成了无聊乏味的美化说法,成了不愿分享的可疑自私。
女性受到暴力侵犯之后的反应,通常是震惊、绝望、否认、麻木、退缩、屈服等等,她有时难以把愤怒转化为力量。由于自尊,她需要杜撰一套自欺说辞。小怜坚定认为,一切因男友难以处理他的激情,小怜甚至把自己想象为另类的受惠者:他对别人从不这样,只对我,他运用气力去捶打我们之间的关系,从性器到四肢。男友自卑而少安全感:嫉妒,焦虑,害怕被抛弃。当他把小怜置于更自卑、更无安全感的地位上,他才能获得心理平衡。至少,男友怕失去她——小怜感觉自己被需要,她在意和珍惜男友的这份恐惧,由此产生盲目的无畏。小怜顽强体会男友艰难分泌的暖意,其实那里面不完全是爱,也包含占有欲里面的感情敲诈。小怜从施暴者的依赖中辨认所谓的个人价值,听任自己在这段垃圾关系中病菌般,靠霉变的幸福存活。
9
小怜走火入魔,她病态的宽容难以被理解,但就在荒谬之中,依然埋藏着一定合理性。男友暴力宣泄之后,常以悔意、告饶、示好和极尽的柔情来表达依恋——像苦药后的糖,暴力伴随着随后到来的奖励,小怜得到了黑暗过后的节日礼物。男友的苦情戏和苦肉计总是对她特别有效,间接过渡,成为一种控制手段。小怜能否区别:味蕾之上,到底是刀头之蜜还是凶器之腥?
乖孩子的布布,擅长配合的布布,瞳孔宁可在纺锤形和线形之间变化也聋哑般不喊不叫的布布……这只可爱的小母猫,正是来自男友的礼物,作为肢体冲突后的道歉和补偿。布偶猫耐痛,如同示范的榜样。
我们知道,舌骨是长在咽喉部位的小骨头,大型猫科动物的舌骨骨化不完全,所以狮子、老虎、豹子和美洲豹都可以吼叫;小型猫科动物则不能,像布偶猫,它的喉咙,有锁死的锈开关。尽管猫科动物手脚轻捷,擅长杂技和轻功;尽管它以速度见长,可以无声接近,跑起来它的爪子可以锋利像跑鞋上的铁钉;尽管颗粒粗糙的舌头能够刮下肉屑,作为一只宠物,布布更多用它来清理自己的皮毛……如同它既不逃跑,也不攻击,它收起自己的系列绝技和匕首形的犬齿,以超乎寻常的忍耐,乞怜垂青与偏宠。
寄养在我家的阶段,布布听话,加了几分谨慎。它常常毫无声息,在阳台上眯起眼睛晒太阳,皮毛散发丝丝缕缕的光芒。唯一流露捕猎者本性的,是布布对玻璃缸里的鱼感兴趣,专注观察两条鱼单调的游动。
出于责任我喂食换水,可我感觉它们并非生机勃勃,而在无比缓慢地死去。鱼是恒温动物──恒温动物?这个词的意思不如换个说法:永远冰冷。一条鱼白璧无瑕,像得了白化病,通体化学般失真的白,几乎引人生理性的紧张;另一条是玛瑙色,轮毂般生硬的眼球四周也布满斑点,像是剥夺了另一条鱼的所有色彩。饥饿时,两条鱼对任何漂浮物都孜孜以求,尝试吞下对方和自己的排泄物。尤其那条白鱼张开浅肉色、贫血的口腔,总让我隐隐恶心。对两条鱼自身而言,这大概就是相濡以沫的状态。
……他们的吻,深入缠绵,像两条相濡以沫的鱼。迷失在她身体里的穴道,他就像沉船没入她的身体,没入温暖、渊深的洋流之中;她教堂一样的身体里,空旷、幽暗,盛纳着祈祷的烛火,也宽容了那么多罪恶。施暴后的悔意、哀求、痛楚和求饶,他的样子,就像等待原谅的闯祸的孩子,这给她某种美好的错觉,她在宽恕里拥有一种母性的伟大与强大。仿佛是她的命、她的责任,有什么需要终生喂养的,即使痛苦,正像病婴一样在她体内酝酿和分娩。女人的一生被雌激素和孕激素轮流统治。先不说雌激素下的情欲,只谈被侵犯之后的宽恕,形同某种甜美的孕激素……那种暴力,却像入侵子宫的胎儿,享有霸主般的专宠。这是变形的母爱,这是畸形的宽恕错觉,这是在侮辱的强力锻打下产生的歪曲的自我形象重塑……有些女性借以自我欺骗,完成地位和等级的心理翻转。
男女之间,关系微妙,难以进行非黑即白的判断。有时,他对她格外的“坏”以达至控制;有时,她对他格外的“好”以达至控制。就这样,以给予的方式剥夺对方,就像鸟想把天空交给尾鳍,鱼想把海洋交给翅膀,最终死于彼此的慷慨。
10
有些女性可以逃离男性的心理掌控和武力威胁,从而获得新生;但是剩下的一小部分,忍受暴力的时间越长,摆脱的难度就越大,自由之路会变得越来越艰难。她们的反应令人错愕,重复去体验这种身体和内心的疼痛——当施暴者的拳头收拢,女性受害者接力完成对自己的戗害,她们延续自厌与自毁,让自己陷溺于致命的沼泽。如毕加索的朵拉,似乎她自己就该被拳脚教训,就该遭此劫数,命运才有它自洽的逻辑。这样悲剧里的女性,承担苦役和羞辱,变成聋哑的沉默者,甚至变成盲目的崇拜者与歌颂者。
斯德哥尔摩综合征。
1973年8月23日,瑞典斯德哥尔摩发生一起银行抢劫案,两男一女三名银行职员被绑为人质。在开始几天里,绑匪对人质的态度粗暴,不提供食物,不让他们洗澡,拿枪口对着他们,动辄威胁要杀死他们。后来,绑匪态度转变,允许人质在屋里随便走动,说话口气相对温和了。这种待遇上的转变,成了斯德哥尔摩综合征产生的必要条件。十天后解救行动成功,但人质和绑匪之间已经产生了亲密的感情。当局吃惊地发现,人质想方设法地保护绑匪,一位获释人质给当时的瑞典首相打电话,积极为绑匪辩护。此案庭审中,人质甚至拒绝作为控方证人出庭。并且其中的女性人质,后来嫁给了其中一个绑匪。
11
有种名为蓄奴蚁的蚂蚁,有着它们的放牧业:养蚜虫。蓄奴蚁敲打蚜虫的背以使它分泌蜜露;换言之,蚜虫的甜蜜来自于对敲打的忍受。哪里有压迫,哪里就有顺从,以及顺从导致的持续压迫。
男人的拳脚或棍棒之下的女性,不是一个与他平等的人,而只是他指端的宠物、胯下的玩物。暴力是一个人在另一个人身上建立的独裁与苛政。互动中,关系才能得以建立或瓦解……然而,对暴力与权威的恐惧、屈服乃至膜拜,是人类的本性。奴性和贱性,沉淀在即使是圣徒的品德底层,这是人性必然的重力。平等之所以难以实现,不仅归咎于外部的社会制度,也是因为我们内心的量尺。耐受型人格,是存在于每个人身上的阴影,也可以说是一种集体性的麻木。
受虐者的麻木,他如影随形的适应性,也可以被统治者歌颂为吃苦耐劳、忍辱负重。女性最初被打沉浸在痛楚和屈辱中,假设施虐受虐的固定模式一旦形成,偶尔不打,受虐者释然,反而分泌出一种近于幸福的快感。政治权力也是如此运作,暴政下的人民有时坚信自己过着无比幸福的生活,在习惯性的颤抖和噤言之后,是麻木后近似由衷的歌颂。对她们施暴的国王拥有绝对的豁免权,可以不被追究责任,因为施暴者控制了受害者的经济、人身和头脑里的自由……绝对胁迫,有助受害者产生绝对的依恋。正因他对她们使用的暴力以及间或的关怀,他反而成为英雄——围绕他的圣像,奴隶唱起颂歌。
暴君让臣民生活在残羹般的岁月里。在他的辖域之内,谁也无心再去窃取权杖下被击打得已然变形的真理,也忘记了自由存在的意义。不曾预知自己命运的奴隶,如抒情诗歌的结构分行,她们的骨骼也将在未来折成数段。
12
在艺术圣殿卢浮宫里,两尊著名雕塑被视为镇殿之宝:一尊是维纳斯,另一尊胜利女神。两者呈现的女性肢体,恰恰都是:半裸且残缺。
维纳斯古典、优雅、高贵,她端庄圣洁的面庞,富有音乐韵律的旋转体态,体现出感官的诗意和内心的美德。胜利女神,英武、雄健、自信,巨大的翅膀迎风展开,给人以饱满的力量感和强烈的动感。两尊雕塑之所以美得令人震撼,因为它们的残缺如完美凹陷的容器,用来盛纳人类无限的想象。
不过,从男性沙文主义角度,维纳斯和胜利女神正好能够用来满足另外的解读。有些男性坚持认为需要对女性进行必要的修剪,使其更加完美。折断她的胳膊,即使她残疾到无能自理,无妨,至少,她就会变成神秘的维纳斯。如果她强健,她无畏,一次次独自,在被击碎的浪涛前面赢得胜利……哦,既然她已拥有自由到飞的双翼,那么,她应该匹配断头的命运。
对施暴者来说,这是残酷而至美的艺术。对于精神上缺乏独立意识与自由精神的人们,无论说的是家暴下的柔弱女性,还是强权下的蒙昧人民,都难以从这样的严苛法则里逃脱。
13
回顾毕加索一生的女人,多数无法“善终”。弗朗索瓦斯·吉洛特,唯一主动离开毕加索的女性,绝地重生,是个特例。
弗朗索瓦斯·吉洛特是索邦大学哲学系毕业的才女,热爱文艺与绘画,这个二十多岁的姑娘与六十多岁的毕加索相遇。她说之所以爱上毕加索,“因为这是一场我不想躲过的灾难”。经历了“烟花般绚烂”“棒极了”的彼此渴望的生活之后,吉洛特厌倦了“和一座历史纪念碑一起生活”,她带着两个孩子离开了“强悍的怪物”,否则,她感觉自己必被“吞灭”。
毕加索曾说:“在我的心中,谁也不会占据真正重要的地位,对我来说,女人就像飘浮在阳光里的尘粒,只需挥动一下扫帚,它们就得飞出门外。”吉洛特的离开令毕加索暴跳如雷,“没有人会离开像我这样的男人”,他断言吉洛特的生命即将枯萎。
吉洛特竭力避免这个结果。她与人合作出版的传记,前卫且成功,披露的内容令毕加索震怒。他要求查禁此书,最后败诉。吉洛特并未成为毕加索的囚徒,她不是艺术家的附属物,而是艺术家本身。她的作品被博物馆收藏,被授予法国最高的艺术奖项,她最后与二十世纪的另一位天才、小儿麻痹症疫苗的研究先驱、一个美国科学家相伴二十五年,婚姻美满。
吉洛特灵巧地逃离了宠物与弃妇的命运,逃离了猎物与牺牲者的命运……像昏暗中视力更为敏感的猫科动物,她没有迷失方向,她终身追逐属于自己的骄傲。
14
当我把布布交还小怜,已是一年以后。
重新回到自己的家,布布已长成丰腴的美猫。布偶相对其他品种的猫发育缓慢,毛色丰满至少要两岁之后,三年左右它才完全发育成熟。看起来松软无力的布偶猫,如果真正了解自身,它将骄傲于自己是体型最大的猫,并且力量和它的重量一样不可小觑。布布敏捷地跳上数倍于身长的高度,伏在花架上,以平静中略带审慎的眼神,凝望着小怜:一个同样迟育、同样需要对自身价值重估的雌性。
小怜正在整理旧物,手里拿了一个看不出男女性别的破旧娃娃:它有张醉红的心形脸,连酒窝的造型,都是两个对称的白色心形。娃娃肿胀的身体曾经用作枕头,所以它柔软,很容易折叠成不堪的一团塞进塑料袋、垃圾桶或者火堆里。男人的吻热力能够燃烧多久?没关系,火焰能够更快地把一个旧玩偶舔黑。小怜将如何处理玩偶和记忆?总有一天,她会发现自己无需从一个廉价而受损的心形那里获得安慰。
假设我们以跪着的姿势和侏儒跳华尔兹,无论对方是否有张沉醉的脸,无论舞曲是否悠扬,我们对自己的残酷磨损都缺乏意义。从某人怀抱或者某段关系里滑脱,不必遗憾自己是变旧的果实,应该就此享受成熟之妙。
房间里汇聚着四个雌性:小怜、布布、我,还有砧板上的一条鱼。
……雌鱼湿漉漉的,未来的路刺痛,她体验着小人鱼的命运。不仅失去逃到童话里的尾鳍,还被剥落几乎所有的鳞片。即使每个鳞片,都曾是一枚爱的勋章,她也将失去全部的所谓财富。除鳞的鱼,体表可见分割清晰的侧线,像经过某种秘密的切割。我从雌鱼的肚子里掏出肥腴、滑腻的籽。离水之后,这个被驱赶出乐园的女性,圆睁湿亮的眼睛,间杂着血丝,她周身仿佛被丝网捆绑,随时携带着她的牢狱、她的刑具。
宠物布布,弱者小怜,还有刚刚放下刀刃的我,一起享用晚餐。现在,只剩三个。最后那个雌性,抵达终点,被我们的肠胃消化得毫无痕迹。空气中弥散着她体内的一丝微腥,尚未散去,尚未散去。
<div class="tc-table-of-contents">
<<toc-selective-expandable 'TableOfContents'>>
</div>
[[todo]]
[[语法]]
沉默的大多数-王小波
========================
沉默的大多数-[[王小波]]
-----
一
君特·格拉斯在《铁皮鼓》里,写了一个不肯长大的人。小奥斯卡发现周围的世界太过荒诞,就暗下决心要永远做小孩子。在冥冥之中,有一种力量成全了他的决心,所以他就成了个侏儒。这个故事太过神奇,但很有意思。人要永远做小孩子虽办不到,但想要保持沉默是能办到的。在我周围,像我这种性格的人特多——在公众场合什么都不说,到了私下里则妙语连珠,换言之,对信得过的人什么都说,对信不过的人什么都不说。起初我以为这是因为经历了严酷的时期(“文革”),后来才发现,这是中国人的通病。龙应台女士就大发感慨,问中国人为什么不说话。她在国外住了很多年,几乎变成了个心直口快的外国人。她把保持沉默看做怯懦,但这是不对的。沉默是一种生活方式,不但是中国人,外国人中也有选择这种生活方式的。
我就知道这样一个例子:他是前苏联的大作曲家萧斯塔科维奇。有好长一段时间他写自己的音乐,一声也不吭。后来忽然口授了一厚本回忆录,并在每一页上都签了名,然后他就死掉了。据我所知,回忆录的主要内容,就是谈自己在沉默中的感受。阅读那本书时,我得到了很大的乐趣——当然,当时我在沉默中。把这本书借给一个话语圈子里的朋友去看,他却得不到任何的乐趣,还说这本书格调低下,气氛阴暗。那本书里有一段讲到了前苏联三十年代,有好多人忽然就不见了,所以大家都很害怕,人们之间都不说话;邻里之间起了纷争都不敢吵架,所以有了另一种表达感情的方式,就是往别人烧水的壶里吐痰。顺便说一句,前苏联人盖过一些宿舍式的房子,有公用的卫生间、盥洗室和厨房,这就给吐痰提供了方便。我觉得有趣,是因为像萧斯塔科维奇那样的大音乐家,戴着夹鼻眼镜,留着山羊胡子,吐起痰来一定多有不便。可以想见,他必定要一手抓住眼镜,另一手护住胡子,探着头去吐。假如就这样被人逮到揍上一顿,那就更有趣了。其实萧斯塔科维奇长得什么样,我也不知道。我只是想象他是这个样子,然后就哈哈大笑。我的朋友看了这一段就不笑,他以为这样吐痰动作不美,境界不高,思想也不好。这使我不敢与他争辩——再争辩就要涉入某些话语的范畴,而这些话语,就是阴阳两界的分界线。
看过《铁皮鼓》的人都知道,小奥斯卡后来改变了他的决心,也长大了。我现在已决定了要说话,这样我就不是小奥斯卡,而是大奥斯卡。我现在当然能同意往别人的水壶里吐痰是思想不好,境界不高。不过有些事继续发生在我身边,举个住楼的人都知道的例子:假设有人常把一辆自行车放在你门口的楼道上,挡了你的路,你可以开口去说——打电话给居委会;或者直接找到车主,说道:同志,“五讲四美”,请你注意。此后他会用什么样的语言来回答你,我就不敢保证。我估计他最起码要说你“事儿”,假如你是女的,他还会说你“事儿妈”,不管你有多大岁数,够不够做他妈。当然,你也可以选择沉默的方式来表达自己对这种行为的厌恶之情:把他车胎里的气放掉。干这件事时,当然要注意别被车主看见。还有一种更损的方式,不值得推荐,那就是在车胎上按上个图钉。有人按了图钉再拔下来,这样车主找不到窟窿在哪儿,补胎时更困难。假如车子可以搬动,把它挪到难找的地方去,让车主找不着它,也是一种选择。这方面就说这么多,因为我不想教坏。这些事使我想到了福柯先生的话:话语即权力。这话应该倒过来说:权力即话语。就以上面的例子来说,你要给人讲“五讲四美”,最好是戴上个红箍。根据我对事实的了解,红箍还不大够用,最好穿上一身警服。“五讲四美”虽然是些好话,讲的时候最好有实力或者说是身份作为保证。话说到这个地步,可以说说当年和朋友讨论萧斯塔科维奇,他一说到思想、境界等等,我为什么就一声不吭——朋友倒是个很好的朋友,但我怕他挑我的毛病。
一般人从七岁开始走进教室,开始接受话语的熏陶。我觉得自己还要早些,因为从我记事时开始,外面总是装着高音喇叭,没黑没夜地乱嚷嚷。从这些话里我知道了土平炉可以炼钢,这种东西和做饭的灶相仿,装了一台小鼓风机,嗡嗡地响着,好像一窝飞行的屎壳郎。炼出的东西是一团团火红的粘在一起的锅片子,看起来是牛屎的样子。有一位手持钢钎的叔叔说,这就是钢。那一年我只有六岁,以后有好长一段时间,一听到钢铁这个词,我就会想到牛屎。从那些话里我还知道了一亩地可以产三十万斤粮,然后我们就饿得要死。总而言之,从小我对讲出来的话就不大相信,越是声色俱厉,嗓门高亢,我越是不信,这种怀疑态度起源于我饥饿的肚肠。和任何话语相比,饥饿都是更大的真理。除了怀疑话语,我还有一个恶习,就是吃铅笔。上小学时,在课桌后面一坐定就开始吃。那种铅笔一毛三一支,后面有橡皮头。我从后面吃起,先吃掉柔软可口的橡皮,再吃掉柔韧爽口的铁皮,吃到木头笔杆以后,软糟糟的没什么味道,但有一点香料味,诱使我接着吃。终于把整支铅笔吃得只剩了一支铅芯,用橡皮膏缠上接着使。除了铅笔之外,课本、练习本,甚至课桌都可以吃。我说到的这些东西,有些被吃掉了,有些被啃得十分狼藉。这也是一个真理,但没有用话语来表达过:饥饿可以把小孩子变成白蚁。
这个世界上有个很大的误会,那就是以为人的种种想法都是由话语教出来的。假设如此,话语就是思维的样板。我说它是个误会,是因为世界还有阴的一面。除此之外,同样的话语也可能教出些很不同的想法。从我懂事的年龄起,就常听人们说:我们这一代,生于一个神圣的时代,多么幸福;而且肩负着解放天下三分之二受苦人的神圣使命,等等。同年龄的人听了都很振奋,很爱听,但我总有点疑问,这么多美事怎么都叫我赶上了。除此之外,我以为这种说法不够含蓄。而含蓄是我们的家教。在三年困难时期,有一天开饭时,每人碗里有一小片腊肉。我弟弟见了以后,按捺不住心中的狂喜,冲上阳台,朝全世界放声高呼:我们家吃大鱼大肉了!结果是被我爸爸拖回来臭揍了一顿。经过这样的教育,我一直比较深沉。所以听到别人说我们多么幸福,多么神圣,别人在受苦,我们没有受等等,心里老在想着:假如我们真遇上了这么多美事,不把它说出来会不会更好。当然,这不是说,我不想履行自己的神圣职责。对于天下三分之二的受苦人,我是这么想的:与其大呼小叫说要去解放他们,让人家苦等,倒不如一声不吭,忽然有一天把他们解放,给他们一个意外惊喜。总而言之,我总是从实际的方面去考虑,而且考虑得很周到。幼年的经历、家教和天性谨慎,是我变得沉默的起因。
二
在我小时候,话语好像是一池冷水,它使我一身一身起鸡皮疙瘩。但不管怎么说吧,人来到世间,仿佛是来游泳的,迟早要跳进去。我可没有想到自己会保持沉默直到四十岁,假如想到了,未必有继续生活的勇气。不管怎么说吧,我听到的话也不总是那么疯,是一阵疯,一阵不疯。所以在十四岁之前,我并没有终身沉默的决心。
小的时候,我们只有听人说话的份儿。当我的同龄人开始说话时,给我一种极恶劣的印象。有位朋友写了一本书,写的是自己在“文革”中的遭遇,书名为《血统》。可以想见,她出身不好。她要我给她的书写个序。这件事使我想起来自己在那些年的所见所闻。“文革”开始时,我十四岁,正上初中一年级。有一天,忽然发生了惊人的变化,班上的一部分同学忽然变成了红五类,另一部分则成了黑五类。我自己的情况特殊,还说不清是哪一类。当然,这红和黑的说法并不是我们发明出来的,这个变化也不是由我们发起的。在这方面我们毫无责任。只是我们中间的一些人,该负一点欺负同学的责任。
照我看来,红的同学忽然得到了很大的好处,这是值得祝贺的。黑的同学忽然遇上了很大的不幸,也值得同情。不等我对他们一一表示祝贺和同情,一些红的同学就把脑袋刮光,束上了大皮带,站在校门口,问每一个想进来的人:你什么出身?他们对同班同学问得格外仔细,一听到他们报出不好的出身,就从牙缝里迸出三个字:“狗崽子!”当然,我能理解他们突然变成了红五类的狂喜,但为此非要使自己的同学在大庭广众下变成狗崽子,未免也太过分。当年我就这么想,现在我也这么想:话语教给我们很多,但善恶还是可以自明。话语想要教给我们,人与人生来就不平等。在人间,尊卑有序是永恒的真理,但你也可以不听。
我上小学六年级时,暑期布置的读书作业是《南方来信》。那是一本记述越南人民抗美救国斗争的读物,其中充满了处决、拷打和虐杀。看完以后,心里充满了怪怪的想法。那时正在青春期的前沿,差一点要变成个性变态了。总而言之,假如对我的那种教育完全成功,换言之,假如那些园丁、人类灵魂的工程师对我的期望得以实现,我就想象不出现在我怎能不嗜杀成性、怎能不残忍,或者说,在我身上,怎么还会保留了一些人性。好在人不光是在书本上学习,还会在沉默中学习。这是我人性尚存的主因。至于话语,它教给我的是:要横扫一切牛鬼蛇神,把“文化革命”进行到底。当时话语正站在人性的反面上。假如完全相信它,就不会有人性。
三
现在我来说明自己为什么人性尚存。“文化革命”刚开始时,我住在一所大学里。有一天,我从校外回来,遇上一大伙人,正在向校门口行进。走在前面的是一伙大学生,彼此争论不休,而且嗓门很大;当然是在用时髦话语争吵,除了毛主席的教导,还经常提到“十六条”。所谓十六条,是中央颁布的展开“文化革命”的十六条规定,其中有一条叫做“要文斗,不要武斗”,制定出来就是供大家违反之用。在那些争论的人之中,有一个人居于中心地位。但他双唇紧闭,一声不吭,唇边似有血迹。在场的大学生有一半在追问他,要他开口说话,另一半则在维护他,不让他说话。“文化革命”里到处都有两派之争,这是个具体的例子。至于队伍的后半部分,是一帮像我这么大的男孩子,一个个也是双唇紧闭,一声不吭,但唇边没有血迹,阴魂不散地跟在后面。有几个大学生想把他们拦住,但是不成功,你把正面拦住,他们就从侧面绕过去,但保持着一声不吭的态度。这件事相当古怪,因为我们院里的孩子相当地厉害,不但敢吵敢骂,而且动起手来,大学生还未必是个儿,那天真是令人意外的老实。我立刻投身其中,问他们出了什么事,怪的是这些孩子都不理我,继续双唇紧闭,两眼发直,显出一种坚忍的态度,继续向前行进——这情形好像他们发了一种集体性的癔症。
有关癔症,我们知道,有一种一声不吭,只顾扬尘舞蹈;另一种喋喋不休,就不大扬尘舞蹈。不管哪一种,心里想的和表现出来的完全不是一回事。我在北方插队时,村里有几个妇女有癔症,其中有一位,假如你信她的说法,她其实是个死去多年的狐狸,成天和丈夫(假定此说成立,这位丈夫就是个兽奸犯)吵吵闹闹,以狐狸的名义要求吃肉。但肉割来以后,她要求把肉煮熟,并以大蒜佐餐。很显然,这不合乎狐狸的饮食习惯。所以,实际上是她,而不是它要吃肉。至于“文化革命”,有几分像场集体性的癔症,大家闹的和心里想的也不是一回事。当然,这要把世界阴的一面考虑在内。只考虑阳的一面,结论就只能是:当年大家胡打乱闹,确实是为了保卫毛主席,保卫党中央。
但是我说的那些大学里的男孩子其实没有犯癔症。后来,我揪住了一个和我很熟的孩子,问出了这件事的始末:原来,在大学生宿舍的盥洗室里,有两个学生在洗脸时相遇,为各自不同的观点争辩起来。争着争着,就打了起来。其中一位受了伤,已被送到医院。另一位没受伤,理所当然地成了打人凶手,就是走在队伍前列的那一位。这一大伙人在理论上是前往某个机构(叫做校革委还是筹委会,我已经不记得了)讲理,实际上是在校园里做无目标的布朗运动。这个故事还有另一个线索:被打伤的学生血肉模糊,有一只耳朵(是左耳还是右耳已经记不得,但我肯定是两者之一)的一部分不见了,在现场也没有找到。根据一种阿加莎·克里斯蒂式的推理,这块耳朵不会在别的地方,只能在打人的学生嘴里,假如他还没把它吃下去的话;因为此君不但脾气暴躁,急了的时候还会咬人,而且咬了不止一次了。我急于交待这件事的要点,忽略了一些细节,比方说,受伤的学生曾经惨叫了一声,别人就闻声而来,使打人者没有机会把耳朵吐出来藏起来,等等。总之,此君现在只有两个选择,或是在大庭广众之下把耳朵吐出来,证明自己的品行恶劣,或者把它吞下去。我听到这些话,马上就加入了尾随的行列,双唇紧闭,牙关紧咬,并且感觉到自己嘴里仿佛含了一块咸咸的东西。
现在我必须承认,我没有看到那件事的结局:因为天晚了,回家太晚会有麻烦。但我的确关心着这件事的进展,几乎失眠。这件事的结局是别人告诉我的:最后,那个咬人的学生把耳朵吐了出来,并且被人逮住了。不知你会怎么看,反正当时我觉得如释重负:不管怎么说,人性尚存。同类不会相食,也不会把别人的一部分吞下去。当然,这件事可能会说明一些别的东西:比方说,咬掉的耳朵块太大,咬人的学生嗓子眼太细,但这些可能性我都不愿意考虑。我说到这件事,是想说明我自己曾在沉默中学到了一点东西。你可以说,这些东西还不够,但这些东西是好的,虽然学到它的方式不值得推广。
我把一个咬人的大学生称为人性的教师,肯定要把一些人气得发狂。但我有自己的道理:一个脾气暴躁、动辄使用牙齿的人,尚且不肯吞下别人的肉体,这一课看起来更有力量。再说,在“文化革命”的那一阶段里,人也不可能学到更好的东西了。
有一段时间常听到年长的人说我们这一代人不好,是“文革”中的红卫兵,品格低劣。考虑到红卫兵也不是孤儿院里的孩子,他们都是学校教育出来的,对于这种低劣品行,学校和家庭教育应该负一定的责任。除此之外,对我们的品行,大家也过虑了。这是因为,世界不光有阳的一面,还有阴的一面。后来我们这些人就去插队。在插队时,同学们之间表现得相当友爱,最起码这是可圈可点的。我的亲身经历就可证明:有一次农忙时期我生了重病,闹得实在熬不过去了,当时没人来管我,只有一个同样在生病的同学,半搀半拖,送我涉过了南宛河,到了医院。那条河虽然不深,但当时足有五公里宽,因为它已经泛滥得连岸都找不着了。假如别人生了病,我也会这样送他。因为有这些表现,我以为我们并不坏,不必青春无悔,留在农村不回来;也不必听从某种暗示而集体自杀,给现在的年轻人空出位子来。而我们的人品的一切可取之处,都该感谢沉默的教诲。
四
有一件事大多数人都知道:我们可以在沉默和话语两种文化中选择。我个人经历过很多选择的机会,比方说,插队的时候,有些插友就选择了说点什么,到“积代会”上去“讲用”,然后就会有些好处。有些话年轻的朋友不熟悉,我只能简单地解释道:积代会是“活学活用毛主席著作积极分子代表大会”,讲用是指讲自己活学活用毛主席著作的心得体会。参加了积代会,就是积极分子。而积极分子是个好意思。另一种机会是当学生时,假如在会上积极发言,再积极参加社会活动,就可能当学生干部,学生干部又是个好意思。这些机会我都自愿地放弃了。选择了说话的朋友可能不相信我是自愿放弃的,他们会认为,我不会说话或者不够档次,不配说话。因为话语即权力,权力又是个好意思,所以的确有不少人挖空心思要打进话语的圈子,甚至在争夺“话语权”。我说我是自愿放弃的,有人会不信——好在还有不少人会相信。主要的原因是进了那个圈子就要说那种话,甚至要以那种话来思索,我觉得不够有意思。据我所知,那个圈子里常常犯着贫乏症。
二十多年前,我在云南当知青。除了穿着比较干净、皮肤比较白皙之外,当地人怎么看待我们,是个很费猜的问题。我觉得,他们以为我们都是台面上的人,必须用台面上的语言和我们交谈——最起码在我们刚去时,他们是这样想的。这当然是一个误会,但并不讨厌。还有个讨厌的误会是:他们以为我们很有钱,在集市上死命地朝我们要高价,以致我们买点东西,总要比当地人多花一两倍的钱。后来我们就用一种独特的方法买东西:不还价,甩下一叠毛票让你慢慢数,同时把货物抱走。等你数清了毛票,连人带货都找不到了。起初我们给的是公道价,后来有人就越给越少,甚至在毛票里杂有些分票。假如我说自己洁身自好,没干过这种事,你一定不相信,所以我决定不争辩。终于有一天,有个学生在这样买东西时被老乡扯住了——但这个人绝不是我。那位老乡决定要说该同学一顿,期期艾艾地憋了好半天,才说出:哇!不行啦!思想啦!斗私批修啦!后来我们回家去,为该老乡的话语笑得打滚。可想而知,在今天,那老乡就会说:哇!不行啦!“五讲”啦!“四美”啦!“三热爱”啦!同样也会使我们笑得要死。从当时的情形和该老乡的情绪来看,他想说的只是一句很简单的话,那一句话的头一个字发音和洗澡的澡有些相似。我举这个例子,绝不是讨了便宜又要卖乖,只是想说明一下话语的贫乏。用它来说话都相当困难,更不要说用它来思想了。话语圈子里的朋友会说,我举了一个很恶劣的例子——我记住这种事,只是为了丑化生活,但我自己觉得不是的。
我在沉默中过了很多年:插队,当工人,当大学生,后来又在大学里任过教。当教师的人保持沉默似不可能,但我教的是技术性的课程,在讲台上只讲技术性的话,下了课我就走人。照我看,不管干什么都可以保持沉默。当然,我还有一个终生爱好,就是写小说。但是写好了不拿去发表,同样也保持了沉默。至于沉默的理由,很是简单,那就是信不过话语圈。从我短短的人生经历来看,它是一座声名狼藉的疯人院。当时我怀疑的不仅是说过亩产三十万斤粮、炸过精神原子弹的那个话语圈,而是一切话语圈子。假如在今天能证明我当时犯了一个以偏概全的错误,我会感到无限的幸福。
五
我说自己多年以来保持了沉默,你可能会不信。这说明你是个过来人。你不信我从未在会议上“表过态”,也没写过批判稿。这种怀疑是对的:因为我既不能证明自己是哑巴,也不能证明自己不会写字,所以这两件事我都是干过的。但是照我的标准,那不叫说话,而是上着一种话语的捐税。我们听说,在过去的年代里,连一些伟大的人物都“讲过一些违心的话”,这说明征税面非常的宽。因为有征话语捐的事,不管我们讲过什么,都可以不必自责:话是上面让说的嘛。但假如一切话语都是征来的捐税,事情就不很妙。拿这些东西可以干什么?它是话,不是钱,既不能用来修水坝,也不能拿来修电站;只能搁在那里臭掉,供后人耻笑。当然,拿征募来的话语干什么,不是我该考虑的事,也许它还有别的用处我没有想到。我要说的是:征收话语捐的事是古已有之。说话的人往往有种输捐纳税的意识,融化在血液里,落实在口头上。在这方面有个例子,是古典名著《红楼梦》。在那本书里,有两个姑娘在大观园里联句,联着联着,冒出了颂圣的词句。这件事让我都觉得不好意思:两个十几岁的小姑娘,躲在后花园里,半夜三更作几句诗,都忘不了颂圣,这叫什么事?仔细推敲起来,毛病当然出在写书人的身上,是他有这种毛病。这种毛病就是:在使用话语时总想交税的强迫症。
我认为,可以在话语的世界里分出两极。一极是圣贤的话语,这些话是自愿的捐献。另一极是沉默者的话语,这些话是强征来的税金。在这两极之间的话,全都暧昧难明:既是捐献,又是税金。在那些说话的人心里都有一个税吏。中国的读书人有很强的社会责任感,就是交纳税金,做一个好的纳税人——这是难听的说法。好听的说法就是以天下为己任。
我曾经是个沉默的人,这就是说,我不喜欢在各种会议上发言,也不喜欢写稿子。这一点最近已经发生了改变,参加会议时也会发言,有时也写点稿。对这种改变我有种强烈的感受,有如丧失了童贞。这就意味着我违背了多年以来的积习,不再属于沉默的大多数了。我还不致为此感到痛苦,但也有一点轻微的失落感。开口说话并不意味着恢复了交纳税金的责任感,假设我真是这么想,大家就会见到一个最大的废话篓子。我有的是另一种责任感。
几年前,我参加了一些社会学研究,因此接触了一些“弱势群体”,其中最特别的就是同性恋者。做过了这些研究之后,我忽然猛省到:所谓弱势群体,就是有些话没有说出来的人。就是因为这些话没有说出来,所以很多人以为他们不存在或者很遥远。在中国,人们以为同性恋者不存在。在外国,人们知道同性恋者存在,但不知他们是谁。有两位人类学家给同性恋者写了一本书,题目就叫做Word Is Out。然后我又猛省到自己也属于古往今来最大的一个弱势群体,就是沉默的大多数。这些人保持沉默的原因多种多样,有些人没能力,或者没有机会说话;还有人有些隐情不便说话;还有一些人,因为种种原因,对于话语的世界有某种厌恶之情。我就属于这最后一种。作为最后这种人,也有义务谈谈自己的所见所闻。
六
我现在写的东西大体属于文学的范畴。所谓文学,在我看来就是:先把文章写好看了再说,别的就管他妈的。除了文学,我想不到有什么地方可以接受我这些古怪想法。赖在文学上,可以给自己在圈子中找到一个立脚点。有这样一个立脚点,就可以攻击这个圈子,攻击整个阳的世界。
几年前,我在美国读书。有个洋鬼子这样问我们:你们中国那个阴阳学说,怎么一切好的东西都属阳,一点不给阴剩下?当然,她这样发问,是因为她正是一个五体不全之阴人。但是这话也有些道理。话语权属于阳的一方,它当然不会说阴的一方任何好话。就是夫子也未能免俗,他把妇女和小人攻击了一通。这句话几千年来总被人引用,但我就没听到受攻击一方有任何回应。人们只是小心提防着不要做小人,至于怎样不做妇人,这问题一直没有解决。就是到了现代,女变男的变性手术也是一个难题,而且也不宜推广——这世界上假男人太多,真男人就会找不到老婆。简言之,话语圈里总是在说些不会遇到反驳的话。往好听里说,这叫做自说自话;往难听里说,就让人想起了一个形容缺德行为的顺口溜:打聋子骂哑巴扒绝户坟。仔细考较起来,恐怕聋子、哑巴、绝户都属阴的一类,所以遇到种种不幸也是活该——笔者的国学不够精深,不知这样理解对不对。但我知道一个确定无疑的事实:任何人说话都会有毛病,圣贤说话也有毛病,这种毛病还相当严重。假如一般人犯了这种病,就会被说成精神分裂症。在现实生活里,我们就是这样看待自说自话的人。
如今我也挤进了话语圈子。这只能说明一件事:这个圈子已经分崩离析。基于这种不幸的现实,可以听到各种要求振奋的话语:让我们来重建中国的精神结构,等等。作为从另一个圈子里来的人,我对新圈子里的朋友有个建议:让我们来检查一下自己,看看傻不傻,疯不疯?有各种各样的镜子可供检查自己之用:中国的传统是一面镜子,外国文化是另一面镜子。还有一面更大的镜子,就在我们身边,那就是沉默的大多数。这些议论当然是有感而发的。几年前,我刚刚走出沉默,写了一本书,送给长者看。他不喜欢这本书,认为书不能这样来写。照他看来,写书应该能教育人民,提升人的灵魂。这真是金玉良言。但是在这世界上的一切人之中,我最希望予以提升的一个,就是我自己。这话很卑鄙,很自私,也很诚实。
本篇最初发表于1996年第4期《东方》杂志(双月刊)。
# [[陈凯宇]]/两河。之间
## 两河 / 他说他想去三温暖
台北的12月中时暖时冻,跟我和米亚其实没有不同。
这是旅程第五个过剩的冬夜,我将自己从旅馆驱至转冷的大街,抱着风褛,试图将仅存的清醒另寄他处。但途经的餐店、租书店乃至理应全日营业的麦当劳也因每月维修,子夜一到就纷纷休店,我因而找不到一扇可供逗留的门窗。车流随着夜半过尽以后,西门一带像是空阔成一片野原,放牧睡眠的男女不再靠边而行,四散起来,仿佛一个又一个我,怀揣着多少居无定所的焦虑,四处流窜。所以他们围观街头艺人的魔术表演,一些打赤膊踩滑板,有的蹲坐在便利店门口埋头进食或者,借宿一出午夜场的电影。大家各有所向。
游荡了西门一圈探索不果,我折返旅馆外名为昆明的长街,坐进阔路边餐车的光照里,等米亚回来。彼时陪同一起驻扎的,还有街道两旁零星而晃亮的小食摊,干冷的腔道如此漫着整夜微温。
饿的缘故,我终于从书包和风褛旁侧的洞口搜刮出存藏多天的硬币,一点一点给予,前后换来四五串冰糖葫芦。几日来往返旅馆和捷运站,阿姨的冰糖葫芦车刚好都在,一支支固着在铁板上的生果串,草莓葡萄梨子,由糖浆薄薄地裹出一层滑亮色泽,胶着如热恋的依附情状。与米亚结伴并行的来时路上我偶尔为此停步,不喜甜食的米亚在旁总提醒想食就买啦,只是想到散居一身的零钱可换来更多悠游储值和对分的美食,我便会甩手说之后先买,再暗地里偷渡泛滥的口水。未料这些原先共享的远方和美食归为己有,过多的硬币于是囤积成有形的负担,我只能在它们沦为无用的手信和行李重量前尽量用尽,对食物的囫囵填充也诚如迫切的赎身,嚼吞连日来无形的自身所失,软烂地以形补形。
直到街边垃圾桶满泻了,米亚还是没有回来。
好天气的残忍坏天气的仁慈,兴许是此时将至的雨和偏执的乌云,高高的互相牵制,没有不中气地倾落下来。无期的果腹与等待,我才觉得自己无异于周围结伴度夜的少年,同为热闹拥挤的余数,这并不是此前米亚在旁时,显得理所当然的西门与阴天。
眼见旅程结束在即,我点开线上同步修改的行程表,往下划选这最后一日,点选偏深的灰。已然化成同一片灰色的昨日复昨日,景点的先后次序似乎已不重要,和米亚不过重复着一起抵达又离开的盖章积分,用一天的完整兑换完整的另一天,仅此而已。是盖章半途发觉一切积存徒劳无偿,不会换来更多暖意抵御周遭和关系的低温,所以这日晨早醒来,我自行作废了这张同行卡,单独前往计划中的渔人码头,思寻着或许可以浮上关系的水面,换气呼吸。
各行各路的白日尽处,两人原先说好相约在双连站前往大稻埕看海,直到向晚的淡水线捷运上,米亚忽而来电。
今晚我想去三温暖,一阵间唔去码头喇。
好啊。你自己玩得开心啲。
你真系唔要一齐去?
我想去诚品行下。
自是无法诚实如米亚的我,顿了一阵,到底还是选择半实半欺地回应。也把声量压得很低,唯恐那糅杂的卑微与抗拒被听见,尽管米亚不会细听,旁人也多半听不懂。身前的单行线就此无限延长,我并不知道这般行进将终于何处,只想借以不间断的风景到风景、空间到空间的移动,规避关系形式上恶性循环的等。想要却无法略过的事实大概也包括,这是一段因米亚想去三温暖而开始策划的旅程,去或不去的决定,其实取决于爱或不爱,不去是因为还有爱,而去则相反。
关于米亚向往的三温暖是怎样的地方,过去我从米亚的说话中抓握到的,不外乎是好玩(可以识多几个新朋友呀嘛)、刺激(黑麻麻嘅房间)、relax(谷桑拿嘅feel同环境,石头叠石头,热热地湿湿地……),多与情欲相关的关键词。自己所知的概貌,不外乎是一个需要不断加温的地方。与三温暖最近的时候,是蔡明亮的《河流》,跟着歪颈的小康走在幽深狭长的廊道上,路经一间间看不进去的暗房、下身围着浴巾的裸男,一路到暗房亮起以前,彼此宽慰的父与子。曾经想像过,在那暖与暗反差交错的空间,肉身叠住肉身,高温蒸汽填满所有罅隙,焗出一身粘腻与忘我的呼吸,直到取足了温暖,啪地压下灯掣,便宛如一记现实的耳光,回到暖与光的正常交合,和互不相识的各自淋浴吧。这般欠缺暖意的冬日,偏偏我单方面压抑的勃起是力量单薄的,米亚强烈需要的活着的快感,像片中小康始现漏水的家屋最后漫溢成灾,面对欲望超乎预期的膨胀,求神拜佛皆没有用。
人影寥落的长街旁,我想起一笔一划习字的小学,因直白无忌的认知,屡屡将暖的横式开展成日与爱,老师多次纠正不果,在于我始终不明白,为什么日不是与爱。直到一次分发作文,老师怒意难忍,在前面咆哮起来:你们听好来,暖是这、样(在白板写下大大的日)、写、的(大大的爰)。讲了这么多次,还一直爱爱爱。暖这个字很像爱,可是它不是爱——那堂课以后,始于高度自觉,终于过分谨慎,我跟其他犯下相同错字的同学便集体记住,日只能跟爰匹配,每每写到暖都会确认再三,那不是爱。
作为“日光”的“于是”,暖很像有爱,却与爱无尤。理所当然的样子,暖是缺爱的。也可以说,逐日而居的爱,往往都是残缺。
所以我跟米亚其实没有不同,惟米亚看起来更需要温暖,清澈的事实在冷天尤其无助。我甚至不解起来,人类为什么需要温暖、寻求温暖?像是一道异于常人的困惑,而探问了谷歌也无解。显示着明确答案的无非是这些:人类为什么不冬眠?人为什么要做一个行善或利益他人的人?为什么被阳光照射时,人类会感到温暖呢?为什么人类会不幸福呢?全都答非所问,然而仔细想想,似乎又指向这薄冰一般易碎的凌晨。
要安然渡夜,我用旅行前买的迷你即时打印机,想给米亚打印一张合照,但零星穿插在满满风景照里的,只有尚未糜烂的街边小食,和未曾觉察过镜头的米亚的侧面和瘦影。自己全然从缺的图标中,我选择打印一张居中而正好斜身左望的米亚:不太拥挤的九份老街,亮光鹅黄色地裹覆着米亚的侧脸,仿佛经由厚的眼镜片,在凝望的单眼折射出一道灯火通明,而我前所未见的长街。——又忽的想起什么,我从书包取出一叠宫崎骏明信片,挑出无脸男的那张。米亚喜欢无脸男,这是少数我还能指认的,米亚的真实。随后垂低视线,虔诚地写起字来:
呢段日子有啲乜嘢令你沉重,好对唔住,我唔系一个好好嘅旅伴,但你要开心。
灯火蜿蜒如河的老街,人流往返像鱼,整座九份失陷于橙橙黄黄的光霾中,暧昧不明的,仿佛复兴了一段沉落光阴尽处的文明。身在其中,行至半路我拉着米亚脱离鱼群,走入一间手信小店。我忙着挑选明信片,在旁的米亚随手抽起那张无脸男,直呼得意可爱,还兴奋地扯拉我的风褛长袖,你觉得呢你觉得呢?动作之大让我忍不住笑着系呀系呀地应和,也决定把无脸男一并买下来。美好的幻象之尽,两人坐上开往台北的客运,车厢光线随着行车归复贫瘠。
通常话昨天,你比较惯用寻日定琴日架?
琴日系比较接近而家嘅讲法,寻日就偏向旧式。我自己系用惯咗寻日。
我都系呀。
紧急出口旁边,长途的沉默挨着沉默,我记得自己并非第一次如此筑建对话。这些片片刻刻大概足以砌成一座巴别塔,完工无期的,因神打乱了子民的语言,将他们分散各地。无以为继中,我和米亚低下各自的头,走失在无边的蓝光地图里,米亚可能落脚于新的所爱,我则把头斜贴向窗口,逐点逐点摊还积欠的睡眠。暗中我为那段对话附上的注解是,寻日作为旧式的语言,似乎比琴日多了一层寻的意味。寻。像后来米亚夜里向外寻找光与温暖,我则往后不断躬身捡拾着开心的小日子,两个道向不同的奔波,一往一返,在名为寻日的公路上。字词的正字或现代与否,并非是至关重要的了。
毕竟无雪的冬日,不分时段的沉默也在处处结霜。抵达西门的闹市以前,这般更显孤身的时刻,我往往会设想,假使可以不需要一段关系,或者温暖能够自供自足,该有多好?继而发现,由始至今的明日复明日,两人都会不自觉把亲密的路走得很生疏,以至每一个景点乍现的说笑寒暄,都像是浮光,引领我们通往最光明的那边,既危险却也安全。
因此这晚,我终究没有路过米亚所在的三温暖,也没有闲情浸濡于满室书香,终其一夜的,把潮湿未干的自己晾在户外的冷空气里,像手中捏着的小照片,和写在无脸男身后的字。看似无处可去的,更像是自甘绑死于此,我观望着德士一辆辆开过,而米亚还在很远的地方。
长街上人来车往的带来带去,形如两人居无定所的相同本质里,我反复自我虚构又推翻的美好。我重建的方式,是在周遭杂声中插上无线耳筒,拨通远在福冈的L。起码连日夜里频频拨出与发送的无助,都不再是不达的回音。与L所谈说旅行前的憧憬,是一种毋需醉意使然的亲密,只是跟米亚一起走很远很远的路,不必刻意搭肩牵手,单单共享着一对耳筒,以慢歌汇合着两个人耳际,恍如之间悬着一条隐形的Y线,接驳着Shuffle与Repeat,摇摇晃晃。浅白易懂。但也是在这时差的甬道里,我才知悉自己是害怕回房,一来是旅行当前,早睡似乎是一种身在福中不知福,二来是那小房间出于二人名义,成单是缺陷,不合常理。即管同房时也多半是水流经输水管,虚空而微弱的簌簌声,像肉眼看不见也不会看见的种种盼望,导向熄灯以后,无边的阒寂。
无眠的长街,头上的光霾如同蜃楼,摸不到、散不去。凌晨一时许,睡意袭来,与L沉默的间隙阔了,我才忍不住拉开通话,你等我一下啊,随后切换视窗速写一则信息:米亚,你今晚会唔会返嚟呀?
我而家返嚟,你瞓先啦。
通话结束前后,过路人开始一一淡出视线,餐车与摊贩也接连开离长街。暖光一道随着一道离去,长街渐而冷寂下来,但并没有比连日来的我们安静,倒是我跟附近几个各有所待的少年,二度失所的赤裸一般,眼神远远交杂起来,热热的,湿湿的。烫手的机身降回常温时,对街冰糖葫芦阿姨斜斜地走来,递来两串草莓。我掏出仅剩的硬币要付钱,阿姨却摆手摇头,我要回家了喔,她告诉我,满脸笑意,像是对圆满结束的又一天心满意足。吃食中米亚捎来信息说已在旅馆附近,我才站起身,拉上拉链背起书包,匆忙收束起在外夜游的部分,恍若整夜留守在房里,寸步未离。
米亚最终从我抗拒抵达的远方回来,带着斑驳的痕和准备熄灯而起的鼾声回来。我没有过问,倒是发现那甫充满自己不久的甜腻又开始蛀起虚空的洞,从而后知后觉地懂得,换来的甜食不是自己的一部分,而手上所剩无几的硬币才是。基于房间无窗,自然没有根据告诉米亚,这最后一夜彼此能够发生什么的想望,很像外面那场迟迟不落的大雨。我只是旁观米亚自顾拾掇所有杂物,然后除下眼镜,靠在床头敲打睡前信息,疲乏的一动不动。房间灯掣多而分散,临睡前米亚依然摸不到的日光灯掣,其实就在自己床头旁边而已。灯掣不远,然而想到过去夜晚那样没有过问的伸手越界,我仍然会感到害怕。于是拉上被单前又提醒米亚,就喺你隔离咋,从此便也更加记得,无论在米亚旁边或面前,自己一直都是美索,也只会是美索。
## 之间 / 看不见恋人的城市
### **00\. 隆市地带的静音公路**
回航机舱的满室亮光在倾斜中渐暗时,一侧过身我仿佛融进身旁舷窗的暗夜,看着密布的光点被黑夜排挤出去,那样从有到无的低空叙事,是令人安心的。不会有人觉察到我在一场冷的暴力中百般变形的悔疚,或彼时倦怠却清醒异常的,很想回家。
机体降陆时,天光初醒。越过国人稀疏的关卡找回身分,拉着行李入境而无任何违禁,再从皮夹红黄蓝绿地凑成55块,买一张机场快线的车卡,避开可能拥堵的公路。昏昏沉沉的例行过关,我自觉像一只受伤的猫,在外求生中断尾落皮地存活下来,负着一身未及舔舐的狼狈,只想原路折返安全的暗角,补足透支的睡眠。
机场快线停抵南湖镇以前打给贤,你可以来载我吗?贤含含糊糊地说好就挂断了,而恍惚中我知道自己这样的拨打,是出于无法言说的需要。
跳上贤的副驾,我将鸭舌帽压得很低,斜靠着窗。熟悉的路段拥挤却也空余。贤欲醒不醒而我重度晃神,两个极度想睡的人是注定失语的。
不知道将这些自讨苦吃的耻事告诉贤,他会不会笑我死蠢?像是过去走进鲜少光顾的日本服装店,买一件外黑内绿的深色风褛,旅人就算未有表示过什么,风褛往后也再着无期,我却深深记取着穿起它时,被自体制造的温暖所保护的安全感。或者依着网评与星级,买了一台迷你即时打印机,其时少女心的那面,只贪恋它易于携带的轻便。几经摸索才觉知它无墨盒的打印功能,心电感应般的操作,在于空白的背胶相纸已蕴有底色,接上蓝牙,便能隔空印出相应的颜色。类似的自以为是的乐观,还有当初不畏变数地订购这趟最晚回航,岂料要跟旅人好好道别,竟跟此时在贤身旁的欲言又止一样,沉重非常。
想讨要的怜惜始终字字维艰。
住家楼下,碰上车门前跟贤说,谢谢你载我回家。源于虚脱的礼貌,尽是无从叫贤上来家里坐坐或休息的亏欠。这样的晨早,对贤来说大概是怪梦一场,载着一只身无分文的猫,甚至也忘了最后,有没有向它说再见。
### **01\. 精品旅馆的皮与影**
德士将我们运抵西门旅馆了,但身体还在滚烫。回到本就不甚讨喜的小房间,持续厌恶它。
狭小的方形空间,双人床占去大半,其它歪斜靠墙的家具摆设渺小又无助,似乎所有的人与物都囿于形式而挤迫一室,甚至洗手盆也裸露在床的斜对角,没有区隔。其时旅人盥洗时偏执的猛力刷牙、大声漱口,似左手锯切右手挥拳的施暴。我只记得自己盘坐在被铺上屏着气,作状抵御的身姿带有些许怨怒,侧目看着镜里龇牙咧嘴的一脸狰狞。很想叫旅人收声。
没有一扇透光的窗的房间,所有的光线是人造的,温暖也是。床的旁侧是浴间,由三大片磨砂玻璃落地围成的一隅,半透的,里面小小的旅人与其它静物如置物架与马桶,都被光投成大大的影,笼罩我。倚着床头我是唯一的皮影戏观众,观望米褐色的平面,旅人的影子站着坐着排解、按手机、淋浴洗头、擦干吹干。在大小水声中起落进退的这些动作剪影,凝视久了便会发现,不过是日复一日一镜到底、被肢体操纵的自然演出罢。然后旅人披上人皮一般套上汗衫穿起短裤,挂起毛巾,从幕布后推门出来。警醒我,匆匆更换T恤棉裤,不顾一身粘腻钻入被穴,仿佛在一头人皮熊的旁边装死,浓浓酒气不散,熊嗅见了,相信我是因醉而不洗澡,自己继续周旋于交友圈,生态蓬勃的方圆百里。
自身缺口欲填却不满的缘故,皮与影因光合而完整,也在熄灯后分离而焦虑。与旅人自我稀释于相异的酒精浓度里,必然的差异是,红酒终会给旅人报以一场酣梦,我则一身胀热地翻覆难眠。如此睡在一起,理性一边逼迫我入睡,感性却一再的诱使我贴近旅人。试着平躺拉开肢体的交战,也无助的又传信息给L,可以跟你讲电话吗?但L仍然已睡。我于是再允许自己背弃理智,挨近旅人安稳起伏的背而不完全依附,以抚平皱褶的手势,手轻放在隆起的沙丘上,练习把失序的呼吸安顿成阵风一样的轻。几天下来其实都是如此,旅人稍有动身,便收回。汲取暖意的片刻,是想像我们一起坐在那白茫茫的沙丘上,仿造起卡尔维诺式的浪漫:他们相信以前曾经度过一个相同的星辰,而且觉得那时候快乐。
每天重复的日常显得扭曲、每夜必经的场景陷入压抑。那样的时刻,我觉得欲望比身体更具体、更真实地存在。
此前我们趁夜探路到敦化南路的A吧。吧台前旅人很快地决定喝Bostavan Merlot,不熟酒精的我原想点选汽水果汁之类,指尖却还是搁浅在陌生的Long Island。漂流的整夜,旅人把高脚的梅鹿酒一啖一啖饮尽,而低球杯里的冰茶我再努力吸啜,仍剩无能为力的半杯搁在一旁。仅余一半清醒的毫升,我攀爬着脸书主页假装很忙,实则以大量大量的冷静清醒抵消滚烫与头痛,怕非哭即吐的丑态,更怕一肚子的卑微逆流成恶心酸蚀的呕吐物。偶尔窥看旅人刷滑的不同的男子,也随口问过,揾到新对象未呀?旅人不置可否,幻听一般,光线缺缺里只露以浅笑。
无窗的房间,我们不会知道来临的天亮会是几点。随着泛滥的感性与热渐渐消退,胸口的焗闷也会平复下来,一如透支的安全感中,我所看见的房间缺陷,退房后都将不复存在;不会被涵盖成旅馆的入住须知或温馨提醒,照片会继续精致好看,入住的一对对房客保持乐观。中隔于我和旅人的无论是不透的幕布还是不平的棉被,都像那终将填海的人造沙丘,很快逝去,我们又将回到现实的平地。不宜被写成反馈与投诉的图文不符,最好的自行负责,便是好好睡觉了。
### **02\. 电话卡的十字街口**
离境那日上午,天还是灰蒙蒙的一脸欲雨。跟旅人说好会合于大同区的旧厝地带。
赤峰街的十字路旁,双双背着书包,行李仍寄放在各自原先所在的店里。基于一张有待归还之物的再见,我从书包暗格拎出曲奇饼大小的密封袋,里面两张电话卡依附着彼此。大概有稍稍一愣,原来还有物件与我们有关,甚至比我们要更亲密。面对面旅人认领电话卡时,我也取出自己的,归回手机的小抽屉。剩密封袋虚空地捏在两指间,伴着随行多日压现的皱褶,形如一种存放的痕迹。
旅行初日,桃园往台北车站的机场捷运上,邻座的旅人置入漫游卡时,将旧的交给我保管。唔好整唔见呀,旅人提醒。收起密封袋时也暗忖,并存的两张电话卡,只要慎守旅人的,自己便也会在吧,反之亦然。逼仄的空间,一起相依或一起失踪、全有或全无,照理来说,落单并不会发生。——我的电话卡买于入境前,有柜姐帮忙设置网络,通过网购的旅人则要亲自设定,这是极其细微的区别。但许是不同机身语境有异,旅人的流量反复开关仍无反应,网络停摆不前。我打开热点与其共享。
短期旅游配套的好处是额度无限,可以恣意给予,任己任人挥霍,旅人看的高清短片与限时动态、交友软体上的男子,我方的流量即使被大口大口地吃掉,也都无伤大雅。但如此一人一半的共享毕竟长远无益,一两日下来耗电不少,隔天夜晚跟旅人到101散步观景,顺道踏入临近的电讯商咨询,只见职员不看说明书,熟练地跳转几个页面、速写一些字码,旅人从此自成支流,拥有自己的流量和方向。
一路来到车流稀少的十字街口,归还了电话卡,除了拜拜之外说什么都不对的境地,我才猛然醒起暗格里,还有旅人的侧影照和无脸男。旅人接过了,礼貌地多谢,把它们塞入风褛侧边的斜隙。因住跌出嚟呀,我提醒回旅人,怕那些抱歉的字句真的丢失,我找不回来,由陌生的人捡起、读见。是旦啦,旅人看上去一脸释然,基于找回失散多天的电话卡。仅余的联系断开,站在街口我仿佛处在未及压封的缝口,一不觉意,就失足坠入密封缺氧的地带。这般塑胶质而不透风的若有所失里,我可以如何爬回上来?
油漆集体老旧的透天厝,门面洁白的小日子矗在我们旁边。冬日其实也将我们保鲜得这般洁净亮白,没有泌出油污打散脸庞的光影,没有一厢情愿的热带汗臭和体味,一切诚诚恳恳。然而这些完好精致的表象,都经不起欲望的叩问,那只会使我越来越不确定自己的本意,也对旅人的表达逐步失去把握。很大一部分我和旅人不说的心照,是界限分明后背离彼此,钻回各自的街巷继续梦游;旅人回到充满爱的三猫小铺继续吃食逗猫,我则返回一个转角后的Hudson Coffee,室小且静,晴朗透光的蓝白小店。庞然的独处在橱窗般的小店里,摄取咖啡因舒缓孤独的情境公式一如既往。
如此只能虚度的下午,时间差不多了,便逆着单向道行出梦的迷宫,中山捷运站就在对街,电话卡的寓意也是。
### **03\. KTV房的地震速报**
处理好流量的晚上,即兴的旅人嚷着想要唱歌。搜见临近有家新开张的KTV,“专属你的KTV”,一心想吃时间,见KTV相貌与评价不错,我们便轻率地决定去了,价钱也不多关心。旅行的缘故。
直到坐入偌大的海洋主题包厢,蓝色亮光干净地盈满一室,我才逐些看见那些不适之处。像是地方本身过于高级炫丽,不吃不喝的费用无论平分或换汇,都显得浪费不划,昂贵是其次。走进走出的服务生恐怕也会觉得奇怪,两个普通人,不是盛装打扮来狂欢的网红,却占用这么大一个房间。但我和旅人无论如何都踏进来了,离开有失礼貌,只好在L形梳化上各踞一边,麦一人一支,你先我先地填充歌单。
不过两三首歌,一股深沉的低鸣包围着我们。视线在晃动中轻微晕眩,周遭虚浮过一时半刻。异感平复了我才迟晚地意识到,是地震。斜对面的旅人同样一脸镇静。更新脸书,看到同样位于台北的友人张贴出地震速报的截图。国家级警报、Beware of probable shaking。我也在手机提示里第一次收到速报:
>>
\[地震速报\] 16/12 19:25左右东北地区发生中型地震,预估震度4.5级 地区:宜兰,台北,气象局。
地震很快的退去了,高楼稳住,包厢却像是发生断层一般诡谲丛生:点唱容祖儿,〈痛爱〉由另一把关不掉的走音女声伴唱,〈心淡〉前奏开始便歪音斜调,另外好些想选的,不是查无此歌,便是播映像素差劣的山水风景、非原本的MV。高清电视误差百出,再唱亦只是添乱。其后旅人放弃广东歌,点选周杰伦的早期作品。为了不枉两小时的奢侈消费,我不熟周董,但情怀可以假装。两人紧随着旋律与印象哼唱,都落得像〈稻香〉里旅人大段大段跳过饶舌的部分,而〈晴天〉ㄖㄨㄟ/ㄙㄡ/ㄌㄚ/ㄒ一/ㄉㄛ的注音我估计自己并没有对上几个——你会等待还是离开?偶尔对唱,偶尔让一首歌只有伴奏的白白流过,不唱歌的时候,我们可能同样的,都在留恋着地面的温度。到头来发现,彼此都在自以为对方会唱,仲以为你识唱添。这才是最要命的尴尬。
像干净的空气不带丝毫烟酒味,桌上的烟灰缸无有悲伤的焦痕,我们安然爬了出来。
离开前没有〈劲歌金曲〉和〈情歌王〉可以点选,但电视最后〈珊瑚海〉的画面、音乐、歌声、红蓝绿交杂的歌词都分外谐和起来,原汁原味的,重新撑起一所KTV的门面。
危楼般的高处,种种不适的细节在后回想总觉失真。某程度上我们是被骗的,却又能从中一一找到对应,且都堪于设想。最初图的大抵只是一个落脚处,却误入了现实与想像断裂的夹层。地震所提醒的,约莫是早已发生的,一场无形的关系坍塌事故。我们会不会早已反应过来,却自命跑不掉,所以一味呆坐着?那样的时候,所有镇静都源于心息,所有藏匿或逃跑的危机意识,并不会让我们比较安全。——专属你的KTV。专属我们的KTV。
### **04\. 后遗的地下街Y区**
深夜离境前的傍晚,来到台北地下街的Y区入口等待子明。子明接济一般从桃园赶赴而至,而我解离多时的灵肉与腔调仿佛重新相认,初见时第一句说的记得是,哇,终于可以好好讲话了。
子明携着我到街侧的卤肉饭餐店,店名饶有广东话谐音趣味,卤肉饭/切仔面。空间狭长的店,里里外外置满方桌圆凳,光临的食客多如巨人般驼着背吃食。我们相邻坐在长桌前,埋头用着30元的卤肉饭猪血汤,小小的咸咸淡淡,已足够温热溢满咖啡因而食欲荡失的胃。隔板对面的烹饪台不断冒着暖热的炊烟,仿佛也是小两口经营的温馨,男的烹煮女的写单。见着人客疏离,我跟子明进食很慢,不急,很难想像子明说的,小店周末爆满的样子。
作为重点交通枢纽,听闻地下街有二十几个出口之多,一如单字的Y可以孵化出许多关键词,Young、游人、愉快、永远、欲望、Yesterday,还有很多很多。那样的多义无疑是使人混乱的,像种种随着离境在即而生的症状,羞耻、恍惚、焦灼之类,隐而幽微。它们最具象的时候,无非是子明开朗地问起这五天四夜,玩到开心没有?去过哪里来?而我毫无被问的心理建设,支支吾吾一番仍梳理不好回应的脉络,只是艰难吐出不好不糟,再索性以有些乱、不知道该怎么讲作结,扑灭对方期待知情更多的满眼亮光。
彼时羞于向子明启齿的,该也包括,这是一场因旅人想体验三温暖而展开的旅行,我作为后期走入的另一个旅人,一切的策划必然匆忙而粗糙。共同为空白的Google Sheets填塞景点时尽管不乏感动,例如旅人就算一心向往三温暖,也还是就于我的生疏,改以大稻埕为景,但旅行前单方面发生的不忠,都让如斯定数陷入未知,最后仅仅是为了不想浪费或吃亏,因为答应过,而毅然决然一起,不顾安危。许是这段不堪的旅途于当时而言太近,并且未完,所以在子明面前挣扎多番仍口述不果。凌乱的像无数浮于河面的杂质,无止境地捞取或剔除,只会加剧自身疲乏。需要待它们渐次沉入水底,说的线索才能更为清澈。
饭后余裕,子明带着我把名字各异的快乐商店一间间光顾着,有类别众多的电玩、手工精致的动漫模型、琳琅满目的信物精品和拼图。齐集吃喝玩乐、机能健全的阔长的街,年轻人的快乐天堂,在隆市其实分布得相当疏离,往往物稀而贵,或是不景气地硬撑着度日,说不定,知音人的现身认购是需要苦盼的。或许是这样,身上仅存的隔夜硬币,我决定全部投入扭蛋机店,最终带着几只黑白褐的猫猫狗狗回家,当作自己,陪伴自己。相信这些对于一名不懂如何保暖的赤道旅人,已是无限体贴的关怀慰问。
在笔直的地底街一路往前,与子明无恙地说笑,内里我则始终留坐在那家卤肉饭店的长桌前,为自己的混乱和子明的无言感到歉疚。像极了包括旅人在内,那些无以善终的告别:有什么令你觉得沉重的,我感到很抱歉,我并不是好的同伴。子明反复道的没有关系、不用紧,其实只会让那顿温饱的饭汤更近乎于虚拟,很快的我们又需要找地方解渴。但我深切感受过的Y区绝对是快乐的,并且不老。这是后来我慢慢选择相信的。
初洗如婴-周晓枫
========================
初洗如婴-[[周晓枫]]
-----
“我想知道记忆是你所持之物还是你所失之物。”
——伍迪·艾伦《另一个女人》
边角有些塌陷的黑呢帽,链子银亮的怀表,是爷爷随身不离的两样道具。她记得那只康恩贝怀表的不锈钢硬壳,以及表盘上划分精细的刻度。爷爷早年是私塾先生,后来做过列车车长,因为一次酒后误了货物运输引咎辞职……但酒,一直没戒。
她对爷爷的印象,不是全家福上那个稳重老者。她的回忆,是这个尊崇儒教、善良懦弱的好老头儿,被按在床上打——扫床笤帚打在骨头和皮肉上,交替的脆响和闷响。奶奶在那个年代算得上是身材高大的女性,她彪悍地骑跨在自己丈夫身上,使他无法挣脱,抡下来的笤帚躲过挨打者胡乱抵挡的手臂,准确落下。她记得爷爷含混的求饶和呜呜的哭声,眼泪鼻涕,斯文扫地。
爷爷是否记得住侮辱?也许不,否则这样的侮辱不会一再重复。爷爷不长教训,他还是经常醉到不省人事,醒了以后背着家人借钱,用以借酒买醉。在奶奶看来,一个没有记性的人是不值得尊重的。
沉溺于酒精的麻醉之中,也许谈不上什么灵魂之痛或对于伤害的回避,仅仅出于无聊和怠惰。并非不长记性那么简单,加之脑血栓重复发作,曾经知情达理的爷爷逐渐失去了他的记忆。随后几年,他糊涂,迷路,别人找到他的时候,他已衣衫破落地离家数百公里。爷爷不记得自己是谁,他的余生,将置身陌生人之中。直到死,爷爷不认识这个世界上的任何一个人,像初生婴儿,所有的都还回去。
她和奶奶关系不佳,因为她难以消除隐恨,也许内心的冲突源自奶奶对爷爷的家暴。一个失忆者,将失去全部的经纬,包括亲情温柔的捆绑……她无法安慰爷爷,无法缓解他彻骨的孤独。
爷爷去世以后,她被安排和奶奶一个房间,为了陪伴。奶奶入睡后打呼噜,她摇动椅子,希望终止恼人的噪音。奶奶愤恨的骂声在呼噜声里间歇响起。她不回嘴,沉默,然后持续椅子的反抗。咯吱咯吱。咯吱咯吱。奶奶说她必遭天谴。她们的关系从未真正和好。即使多年以后,奶奶亲手给她做过一个红丝绒背心,她依然不适应这种奇怪的暖意,像喝了一杯不凉不烫、温得无感而近于不舒服的水。
她怀念爷爷。帽子,怀表,他的黑条绒外衣,他的庄重和狼狈。她怀疑,失忆者的骨灰更轻,更虚无。
她从小就粗心大意,丢三落四成了习惯。直到成年,她每天花费大量时间,重复寻找那些无聊、单调又必备的日常用品。钥匙。钱包。手机。身份证。入门证。交通卡。每个人都被那么多琐碎的小事物围绕和干扰,甚至是影响和决定。她的手表经常神秘失踪,有的仅仅佩戴几天,还没有习惯表盘上的指针,就需要重新购买了。无数的耳机,无数的眼镜。她时常认错人,对甲称呼乙的名字,把从丙那里借来的东西还给丁。她不具备精细者的精明,这是性格,是命。
事务繁忙,睡眠不足,她轻易找到许多借口来解释自己的健忘。她以前对文字敏感,年少时曾有过目不忘的阶段,能把自己即兴的高考作文背诵得一字不落;现在她字斟句酌地写完一篇散文,过几天就想不起内容——这是轻量级的,几乎算正常反应,她有时竟连题目也想不起来。口语中错乱更多,张冠李戴,指鹿为马。“三心二用。”她说出的成语,即使隐隐感觉不对劲,也不知哪里错了。别人提醒后,她才明白,把“三心二意”和“一心两用”混淆了。她原来被夸奖为笔舌玲珑,现在,写错别字,说错别话。她感觉自己像个涩住的圆珠笔芯,如果不用力划,就不会呈现字迹。
对人对事,“记错了”的尴尬,往往超过“忘记了”的尴尬,所以,有时即使存在模糊的印象,她干脆说自己忘了。慢慢地,她巩固她的遗忘。
最初她并未慌张。爷爷只是个偶然事件,即使父亲如出一辙地重复家族性的健忘和抑郁,或许是他长期责任感缺乏造成的问题,她并不消沉。她虽然糊涂混乱,但对未来指向精确,像修表匠手下飞快拧动的指针。她不信,或说不愿,自己被套上魔咒。
随后发生的两件事,让她惊恐。
一次笔友聚会。不过是四个人的小场子,其中有个久闻其名、从未谋面的朋友。咖啡香缭绕、弥散,聊了整整一个下午,宾主尽欢。随后大家转场去餐厅吃饭。她去卫生间洗了下手,回到雅室,看到又赶来两位认识的作家。正在研究菜谱、商量点餐的几个人都熟悉,但,那个陌生客是谁呢?看似关系熟络,没有人感觉需要为她介绍。她若无其事,貌似对答如流,其实是在脑子里吃力地寻找线索。直到,陌生客的名字被他人称呼,她内心一凉。这个新朋友,她通过一个下午的了解如遇知己,仅仅数分钟离开视线,她不认识他了……竟然,雁过寒潭,了无痕迹。
另外一次的经历,更让她害怕。把车泊到停车场,她在一家北欧风格的家具店闲逛,买了小鸟造型的铁艺烛台。她在展厅里转着转着,毫无征兆,她想不起自己的家是什么风格的。家在哪个方向,是什么样子呢?她手里攥着一块不知什么时候拿上的织物,毛巾还是枕垫?她尝试辨识里面由红蓝两色编织的雪花图案。瞬间,她丧失了时空的衡量。可能过了三五分钟,或者更长时间,她震惊地发现,她不知道自己是谁,叫什么名字,从哪里来、到哪里去。时间一分一秒地过去,顾客穿梭,无人知晓她脚下的基座已被抽空,整个人沦陷到虚无里。她说不出话,不知怎么自救,每一根落下来的秒针都像压死骆驼的稻草,让她有窒息之感。展厅里造型古怪的灯,照耀着那些空旷的沙发和寝具,其中有张黑色的床。她的行为能力降至为零。很久之后,逻辑能力才有所恢复,她打开双肩背包,寻找携带的证据。小偷般的手在黑暗里摸索,尚未触碰到证件包的拉链……突然,她的障碍消失了。家庭关系和社会角色,重新像编织细密的蛛丝,把她捆绑到半空之中。
她专程去医院请教,大夫说这叫“人格解体”,但她心生疑惑。她并未产生扭曲的知觉,没有置身梦魇的失真感,她甚至并不承认渗透已久的焦虑。只是瞬间从皮壳中脱落,成为无所佑护的孤魂——她无法解释,这种短暂的解离性失忆。
想起祖辈和父辈日渐茫然的眼神,她开始怀疑,自己正是下一任的继承者——阿尔茨海默病,将在她身上表现出越来越明显的征兆。
别人以为她八面玲珑,其实她从未克服社交不适,尤其健忘缺陷日益严重的情况下,她辞去了编辑岗位。接触的人越来越减少,与此同时,手机里的通讯录里不认识的名字越来越多——她经常像面对外语一样,破译那些陌生的笔画。这让她产生隐秘而强烈的不安。她害怕的方式,同时也是害羞的方式。她尽量隐居,不提供让别人指责自己傲慢的机会。曾以尖牙利嘴著称,现在由于脑细胞的运转速度降低,她乔装宽厚的微笑。
雪崩终会来临吗?固如山峰的冰川倘若融化,她的记忆是否会变成一片冰冷的汪洋?
她陪同学去看望他的父亲,一个资深的电影导演。
老导演曾经指导演员如何通过表情和肢体,传达丰富的信息;现在无能为力,他有一张“面具脸”。如果患上阿尔茨海默病,平常说话不多、表情平淡的人开始不易被察觉,可假如平日性情活泼,对比就会明显。他们少言寡语,表情木讷,常走动的人能够勉强认识,不常走动的人根本想不起名字。
同学最早发现父亲的病症,是在堂弟的婚礼上。父亲代表长辈发言,他事先准备了讲话提纲,可他发现段落之间有许多怪字,不认识,不知道怎么念;父亲放下手里的稿子,说得不知所云。从此,他怕面对难堪的处境,开始沉默寡言。阿尔茨海默病患者常伴有抑郁,这是相辅相成的。
病程一般需要三到六年,但老导演就像他迅速消瘦的体型一样,数月间发展变化很快。他分不出冷暖,记不住家里厕所的位置,他不知道自己生活在哪一年,也说不出带有转折的复句……然后是一句完整话都说不出来,然后只剩下几个词,然后过渡到几个发音。
洗澡时,老导演用手遮挡着自己,不让别人碰触他的身体。最开始他易怒,有攻击性,他感觉烦躁和恶心,渐渐,他从暴脾气变成唯唯诺诺,眼神里全是弱势的哀求。医生越努力改善脑供血的不足,老导演越嗜睡。同学虽然觉得自己的父亲可怜,可宁愿父亲维持在这种状态里。因为治疗过程数次受挫,他服药后有时呓语,神经错乱,偶尔化学反应引起亢奋,见到陌生人会打。老导演向来以自持自律为傲,一生体面,却在一次试药过程中变成新花痴和老流氓,热衷以猥亵的动作调戏护士。等老导演的智力和体能速降,家人反而松了口气。她的同学被迫承认事实,父亲的病程不可逆,没救,没有奇迹。药物的作用并非治疗,而是抑制症状的恶化,让它减缓发展,让它相对停滞。所谓“治疗”,似乎针对的是尊严而不是身体。
每个人的成长都像树一样储藏自己的年轮。老导演彻底忘了,忘了春盛秋枯,忘了循序渐进的时间……那些本来易于分辨的年轮,变得像地图等高线一样弯曲变形,他忘记了它们隐约的数目。
忘了春盛秋枯,忘了循序渐进的时间……那些本来易于分辨的年轮,变得像地图等高线一样弯曲变形,他忘记了它们隐约的数目。
半年后,同学告诉她,老导演彻底失去了打理自己的能力。为父亲洗澡的时候,父亲衰老的肌肤浸泡在热水里变成奇怪的粉红色,令他想起晚餐时的鲑鱼。鲑鱼一如树木,它的身体也纹刻清晰的肌理,像是漩涡状的年轮。当鲑鱼呈现艳异的粉红色,它将溯流而上,靠近它童年的栖居地,靠近它临终的死亡。
她想,遗忘并非是专属老年的问题,它可能是一生的忠诚伴侣。
媒体报道夏天的不幸,被遗忘在汽车里的孩子死亡,他们体表变色、灼伤、溃烂、脱皮,器官自溶——玻璃上印着挣扎的手印,座椅上留着扯下的头发和失控的排泄物,幼小的尸体承受过最后的煎熬。孩子的父母因此遭受强烈的舆论谴责与剧烈的内心折磨。是啊,多么粗心、多么不负责任的人才能制造这样的疏忽。致命的分心,简直是犯罪。
然而,调查结果,令人难过。这些被视同作恶的失职者,在意外发生之前,同样是温暖、耐心、慈爱甚至是近乎完美的父母。各种阶层、种族、年龄、职业的人都可能发生这样的悲剧,一次偶然的遗忘,足以将他们的余生推入内疚的深渊。
心理学家用模型来解释,灾难何以穿越重重防御机制发生,就像数片摞起的奶酪,不幸在于:奶酪上的孔洞巧合地重叠在一起。数小时遗忘,是因为父母以为孩子正安然地待在幼儿园或其他某个地方,就像我们上班时日常处理电话、文档、报表甚至安排娱乐活动那么安心,不知道自己的家门没有锁好,不知道贼会乘虚而入,不知道一生的财宝已被窃取,永不复还。
对健忘症患者来说,也许危险并未增加。比如她很怕拿公章、票据、证件之类的要物,怕那些需要细心或牢记才能做好的事情。由于不自信,她频繁质疑自己的能力,宁愿绕行,希望借此避开祸患。像猫掩盖自己的尿骚一样,她羞惭,试图掩盖自己昭然若揭的糊涂。她得承认自己害怕,因为不知道什么时候,暮色中的钟声突然敲响,伴随而来的,是绝望无边的黑暗。
我们之所以选择性地记忆,因为无法逾越我们选择性的感知。人类的眼睛只能看到百分之三十的光线,动物可以看到更丰富的。我们根本不知道冰山之下还有更大的冰山,甚至是想象也不能抵达。几乎是在沉睡状态,我们危险地漂移在生活的表层。
她难以开口谈论隐忧,没有谁会信,她看起来的状态与她所描述的,大相径庭。那么,病症究竟是生理事实还是她的精神臆想?趋势会渐渐严重吗?还是说,她的大脑只有某个区域受损,只要绕过盲区和禁区,一切无碍,她可以安享自己有尊严的晚年?
也许问题并非家庭遗传。她十五岁时误服药物,端起满杯开水准备饮用时晕倒,造成颜面烫伤——醒来时发现她自己坐在冰冷的水泥地面上,不知道发生了什么,不知道短短几分钟的失忆从此影响一生。此后,由于各种各样的原因,她经历数次全麻手术,其中一次,术后呼吸暂停。导致她忘记了许多名词:话梅、暖水瓶、拖鞋,她只能描述它们的功用,却想不起名称。名词,鱼鳞一样的名词细密地覆盖了世界……她看到的却是其中的斑驳。她用了整整八个月,勉强康复。对了,她有情绪抑郁的问题,一直没有根治。还有严重的慢性中耳炎问题,发病时她必须侧躺,头颅里就像一枚倒扣的钟被铜舌持续碰撞,带给她内置的难以消除的震荡。大夫说她需要经常体检,以防颅内生长胆脂瘤。抑或,无他,只是流感、发烧之类的小问题给她带来的大麻烦?人的体温通常保持在37度左右,体温过高过低,神智就会错乱。看,我们的脑子必须储藏在恒温的育婴箱里。温差、撞击、感染,都会使它致命地损毁。
脑部解剖面有着难以计数的生僻术语:枕叶、颞肌、皮质与并骶小体的联结纤维组织,她印象深的,是那个优美而神秘的命名:海马体。海马体主要承担短期记忆的功能,若遭到损坏,就会导致健忘症和学习能力的下降。她想象自己受损后的海马体,蜷起害羞的尾环,由此给她带来种种阻碍。
怎么解决呢?科学家一方面承认它的不可逆转,一方面又给出积极的应对策略:比如注意饮食、加强锻炼、学习外语、绘画或者听音乐。听起来,健康、明亮、大有希望……又那么,隔靴搔痒,画饼充饥。
她坚持每天食用坚果,据说可提升记忆。核桃状如脑部模型,她怀疑这种所谓的食补,近于仿生学意义上的原始信念。不过,宁信其有,如果消除了那些核桃般的褶皱,她的头脑,就会像被磨平图案的硬币一样失去价值吧?她更偏爱杏仁,清凉微苦,就像记忆本身的味道。她不习惯整个地吃掉那个坚硬、象形的心形;她喜欢像嗑瓜子一样,轻轻的咬力作用在杏仁的顶端……让它变成两扇对称打开的袖珍门。
她太懒惰,缺乏耐心,难以获得坚持才能取得的成绩。体育锻炼、掌握外语都需要滴水穿石的功夫,绘画更需要基础训练的漫长铺垫,不在她的耐力之内。她倒是尝试,去接受音乐洗礼,希望旋律的流水能洗去记忆鹅卵石上的沙砾,使它们得以干净地呈现。她对音乐一窍不通,所谓欣赏,不过是文盲见到了繁体字。庞大的交响乐团,或低婉、如泣如诉,或在高亢的混响里达至辉煌。那是个富有天赋的女性指挥,削紧的黑色礼服,双臂修长……她有燕子般自由灵动的翅翼,仿佛可以数年盘旋,甚至睡眠也悬浮在半空。指挥家镰刀般的双臂下,有无限的丰收。而她,不再是一粒包浆充盈的籽实,时间正抽干往昔的积累。她接受了,那种平静的无望。某个美国作曲家说过:“即使是最野心勃勃的大师之作,它最核心的任务,依然是将你带回一个脆弱的、仅属于你自己的瞬间。”
她每年花大量时间旅行。异国他乡,永远置身陌生人群,她有时抱有美好而积极的设想:爷爷当年的频繁走失对他自己来说,并非危险,如同旅行,只是好奇之下的冒险,是对个人处境的逃离,是对难堪窘境的解脱——因为,在不熟悉的地方迷路属正常现象,不会被当作病人;异域的语言神秘而复杂,无法沟通、交流,失语者的障碍也是自然的,不会引以为异。一个旅行者,可以任性,可以自由。
在里约热内卢,狂欢的桑巴,到处是炸溅的斑斓色彩,她有若置身于一个放大的望花筒之中。人们脸上的油彩与面具,闪耀的胸乳、蓬勃的大腿和电力充沛的臀部,热烈的情色几乎把人淹没。
在洛杉矶的海岸,巨鲸沉潜,需要从暗色的涡流或浪脊中加以区别。那礁岩般结实宽阔的体魄,就隐现在闪烁的波纹之间,偶尔露出深黑的背脊,或喷出澎湃的水柱。由于鲸鱼伟大的谦逊,她能看到隐约的部分非常有限,但惊心动魄的想象依然令她沉醉。
在加德满都河谷,巴德岗神庙上瑰丽的木雕与漆彩。那里的人民对宗教怀有汹涌的情感,传说他们用收集的露水修建庙宇。那里的人们皮肤黧黑、眼睛渊深,那里的流浪狗皮毛肮脏,却可以在游客稠密之处安眠,在人群错乱的脚步和泥坯色的阳光中松弛地裸露自己的腹部。独木庙,帕坦皇宫,达拉哈拉塔……那些优美的古迹竟然在她参观不久就毁于一场地震,成为坍塌的废墟。
还有,卡萨布兰卡,一个随着阳光而改变面容的城市:阳光下,通透明亮,风情妖娆;阴影里,满是尘垢的沧桑。路途奔波,她枕着陌生的枕头入眠,黑夜巨大,像遥远的童年那样包裹着她。她严重失眠,好像还是置身于集市上那些叫卖地毯、布匹、琥珀、香料、尖脚拖鞋和金属灯具的阿拉伯商人之中。似乎,鼓点延续,有个敲钟的盲人阻止了梦境。
……街上陆续有喇叭的短促声响,贯穿的人声,像在宣告或祈祷。掺杂着欢快的乐曲,高高低低的音阶。车辆驰过,有的在她的左侧,有的在她的右侧,交响嘹亮。车轮摩擦的声音,是破旧而松弛的交通工具碾过颠簸路面。一声喇叭被另一声喇叭追随、修正,这里响一下,那里响一下……她想象街上的萤火虫之夜。然后是狗叫,昏昏沉沉睡去已久的狗兴奋起来:还是这里一声,那里一声。皮毛松散、身姿曼妙的流浪猫,在汽车底盘的庇护下无声地醒来,伸开柔软的懒腰,埋藏在肉趾之间弦月般的爪钩暴露出来。狗吠不停,穿插在人声和车声里。平底锅上的黎明,像煎蛋一样慢慢热起来。然后是轰鸣,年轻而嚣张的摩托车呼啸而来。她利用窗口的微光,看到表盘反射出的指针:四点二十五分。她以为,城市只有六点半以后才会出现的喧嚣,没想到五点不到,就这么热闹。她感觉疲惫,与这个分贝剧烈的世界格格不入。为什么如此热闹?她隐约想起白天的短信,尽管隔着辽阔的欧亚大陆,她依然屡屡收到祖国传来的商场营销短信,用看似温馨的套语,提醒这是感恩节:一个重要的购物理由。她混沌,想当地穆斯林居多,为什么感恩节如此受到重视?是否居留此地的什么后裔,在遥远之地延续着他们的传统。摩洛哥有一些天主教堂,经常聚集虔诚的信徒。她想到教堂,想到悬置高处的钟舌……忽然,周围一切就像个聋哑者那样安静下来。随后的世界又像翻卷的潮汐,重新裹挟着它的声响,涌上她的床边和梦境……不重要,她睡着了。
第二天她才从导游那里得知,热闹并非来自宗教节日,只是世俗的欢乐。这只是摩洛哥人的风俗习惯,他们半夜结婚,在纹路好看的特雅木镜框前不断梳妆的新娘要换满七套衣服,欢宴持续到黎明,人们才会散去。想象中是神圣肃穆,其实是新人即将开始缱绻的淫乐。
作为游客,她难以对他人抱有哪怕是短暂的正确理解,依据记忆所积累的知识可能带来误导。人生,亦如此。当她坐在火车座位的一侧,从窗口窥望,景色飞驰,掠过她的视线和记忆。她能记住那些影像吗?记得一棵果树因丰收而发光,或者一个发疯少年正沉默执斧,无论带给她怎样的触动,意义也难免薄弱。不论禁受着怎样盛大的节日或灾难,对他人来说,只是相当于,一个困倦游客所目睹的、终将遗忘的风景。
人生如旅行,终会忘记一切。她想,包括至美的幻境和剧烈的羞耻。
荒谬的是,她甚至被朋友和亲人,误解为是一个记忆出色的人。她忘记她的财产,被误解为慷慨;她忘记她的仇恨,被误解为宽容。何况,还有白纸黑字的证据:她写下的文字,具有一些能带来现场还原感的细节。
她热爱写作,从未放弃初衷。她最初的职业是编辑,写东西纯属业余。朋友鼓励她说:“业余和专业怎么区分?达至水准的就是专业。”然而,这使得她在后来获得了专业作家的身份之后,依然强烈感受到自己的业余。每每听闻作家逸事,她发现他们可以通过放纵或者贞烈的生活方式来保持写作的极端品质,甚至在同一个人身上保持分裂的两极……在对峙的张力中,他们拥有瀑布般席卷的想象力,既美又暴力,没有什么可以将之阻挡。以她的才智和勇气,只够,勉强支撑到平庸。但她心怀感恩和忠诚,执着于童年至今都模糊不明却依然难以放弃的目标。
辨别事物,有时靠记忆,有时靠想象,而想象是在记忆力的基础上形成的……她明白她的缺陷。她小心翼翼地敲击一个又一个的词,直到它们的蛋壳上出现细小的裂隙。那些精美因她而破裂的纹路,是属于她的创造,属于她的偶然性的奇迹。依靠写作,她才拥有那些时刻,才得以模拟那些瞬间而非凡的记忆。
她记得天上的云,如同无垠的北极冰层,堆云之术如何达至技艺的绝境。她记得夜空满天的霜晶,迁徙的飞鸟日夜兼程。她记得南方小镇,穿睡衣的女子梦游般穿过自己的八月。她记得那些覆满松林的无人山坡,起风时让人嗅到一种冷香。她记得自己在大雨中泡温泉,她无需逃避任何来自天空的击打。尽情的雨在水面砸出小小的凹坑,而打在泡池的水泥台子上,则是另一番状态:底部是平的,四周溅起小小的棘刺,就像饮下尽情的酒,却把起开的啤酒瓶盖子翻过来摆满平台……感觉自己方生方死、一醉方休,她记得。
即使与奶奶关系不睦,她依然记得关于奶奶的生活细节。蒸馒头时,奶奶总在锅里放一片摔破的碗瓷。那片瓷发出轻微的响声,这样可以避免蒸锅耗尽水位而不被察觉。她不知道自己和记忆什么时候会被蒸干,但只要细节的瓷片一直响着,她的头脑里就弥漫云蒸霞蔚的水汽。出于自救,她不断捕捉那些一闪即逝的细节。
很奇怪,她偶尔记住的内容是如此零乱,几乎难以追踪往昔的线索。她最早忘记的是结构。是逻辑。是关系的骨架。比如,她会忘记和谁、在哪里、什么时间,在一起共享晚餐,但是她会记得铁板烧被厨师浇上醇酒,火焰像只狂怒的马升腾而起。她将进入一个丧失逻辑关系的世界里。全是碎片,她认不出它们曾经属于怎样的整体。
对她来说,保持记忆唯一的办法,是逐字逐句地记录。甚至照片为证都是失效的,因为她想不起合影者,背景也像是照相馆幕布上的虚设。她的秘密武器,是笔纸。别人以为她随身携带记录本是刻苦,其实是失忆者的防范和弥补,是一种过度掩饰。效果倒是显著,她看起来比常人更缜密、更疏而不漏……可离开记录的本册,她回忆不起具体的地名,复述不了大致的行程。
一方面,写作确实是有效的支撑,她欣赏过的风景、见识过的人以及由此涌起的悲欢,过不了多久她就会忘掉,可只要她写过与此有关的文字,哪怕是应景之作,都能提供刻在树干上的线索,让猎人不致在密林中走失,让沉沦大地重新浮现汪洋中的岛屿。另一方面,她不知自己到最后拿什么抵挡。因为,字词也开始了背叛。她喜欢阅读,那些书籍被她贪婪地捕食,很快成为狼藉的猎物,再后来就像被微生物消灭一样无踪无迹——有时到了一本书的结尾,她才羞愧地发现,这是自己的旧日读物。
有一次,边读边写,她在书桌上睡着了。仿佛,所有的秒针都停滞。凄迷的紫丁香般的梦境,从细碎的花枝间散发出浓烈却易逝的气息。她梦到一个占卜者,说着玄虚的语词;翻开对方的手心,那人竟没有一线掌纹,比婴儿更恐怖的纯洁展现眼前。醒来她立即感觉到冷,并且像做了整夜的梦那样,头昏沉沉的,像玻璃罐里塞满了石头。刚才所见,真实得不像幻觉,她看见自己的掌心布满纷乱的渔网状纹路。这便是树木的纹刻、鲑鱼体内的曲线吗?岁月潜藏,她不知自己将葬身于哪道掌纹之中。
有人说,健忘是好的。就像个魔法雪橇,什么恩怨的沟坎都被掩盖,速滑速降在陡崖,既有恐惧,也有快感。时间抹平沟壑,抹平她核桃般褶皱里所储存的那些词,那些精微的感知……一切,光滑、寒冷,像冰层,像镜面和锋刃,没有什么往事的棘刺能勾住她,摩擦系数变得越来越低,她从万事万物的表层滑过。
没有仇恨,没有积怨。有一次她去讲课,下面有张依稀仿佛的脸,她有印象,可是观察和搜索过后,一无所获。她只好不断微笑,显示出抱歉之下的殷勤。直到交流结束,那人上来问候,自报家门和出处,她才恍然,这是个攀龙附凤的钻营者,写作水准乏善可陈,擅长动用上层关系压制编辑以谋求发表,做人行事为她不齿。她轻蔑且愠怒,曾当着他本人直言不讳,并在内心誓不与此人交往。谁知事隔不久,她荒谬到主动示好。
有位哲学家认为:“人的行为是由他们的记忆决定的。社会出于对自己的保护,必须使其公民通过希望和恐惧建立起社会秩序和合作的理念。”她羡慕那些受到记忆管教和盘剥的人,她愿意为昨天交纳高额的利息……但命运,要给她一个虽破碎却勉强成型的未来,还有一份因丧失痛感而带来的另类的自由。是啊,“记忆是一种相聚的方式”,如果某天彻底失去记忆,她将失去约束,也失去她用一生时间慢慢累积的亲人和敌人。
遗忘带来打击,也象征安慰。记忆的砂纸打磨,多少铭心刻骨的爱恨都变得粗糙而模糊。从某种意义上说,记忆流失,是上苍给予人类的一份特殊礼物,它作用于摆脱那些易于让人沉陷的苦恼、哀怨、痛楚和仇恨——如果记忆不被磨损,这些不快将如影随形,烙印终生。毕竟,幸福在人生中所占的比例微小,更多时候我们被失意、疾病和灾难主宰。忘记了,能否就此不必偿还往昔的债务,负担瞬间清零?没有储存受挫的经验和教训,忘记了“害怕”,是否谁都勇敢无畏,人人皆英雄,刀山火海如履平地?不过,记忆真的提供了那么确凿的保障吗?不错,它是重要的储藏器,可它同样也是个容易变形的容器。某些时刻,有了记忆,我们反而丧失真相。几个记忆卓越的人回想同一桩事却大相径庭,甚至南辕北辙。每个人都言之凿凿,笃定别人撒谎。记忆天然地带有个人偏见,各自的利益和立场,不动声色地渗透进去,从而导致真相的歪曲和迷失。
小时候,她喜欢挤压塑料包装膜上均匀分布的气泡,指端压力下,破裂的小小气囊噼啪作响。她所存储的记忆将被时间压榨,被磨损或摧毁,她的人生将失去减震般的呵护。不过,无论悲观者还是乐观者,多多少少都有自毁倾向,以期缓解和逐渐适应死亡的冲击。所以人们在过程中不断寻找理由,失落的亲情、受挫的爱情、背叛的友情……受够了这些,就可以释然于最后的劫掠。人人终将陷入遗忘,像服用退烧药之后陷入安详的睡眠,化学分子作用于生物原子,物质、情绪、幻象、梦境以及凝结的种种记忆,都被分解。她想,死神之所以不等于魔鬼,是因为他比魔鬼严肃、公正,也比魔鬼更日常。无论忘情水还是孟婆汤,抹除前生记忆,死神最后把所有人都变成阿尔茨海默病患者。
忘掉表达,忘掉爱恨达至忘情,她能否获得唯婴孩才能体会的澄澈?无善无恶,无概念的困扰;无喜无悲,无利益的纠缠;无生无死,飘浮在冥河,飘浮在丧失坐标系的虚空之中……她是老胎儿,浑身布满新生的皱褶。往事中的羞耻或荣耀,将葬入马里亚纳海沟那样不可打捞的深处。每个清晨醒来,都是全新世界,像爱情中即将遇到的那个人。
2012年9月,大卫·希尔菲克被确诊为阿尔茨海默病患者,这位退休医生兼作家开始记录患病后发生的一切。博客题为“看着灯光熄灭”,他以此形容逐渐丧失心智的过程;然而,他希望为数百万处于黑暗中的人们指引方向。乐观得令人惊讶,因为大卫认为自己由此开始了“有生以来最为快乐和幸福的时光”。
在确诊之前,大卫沿着同样路线,重复同样事情,却丝毫不记得。他曾以为这是“离奇的记忆丧失事件”,仅仅因为上了年纪,并未予以重视。直到两年半以后,他知道自己成为了阿尔茨海默病患者。所有事情都在崩塌。他看不懂自己亲手制作的表格,经常遗失钱包,在一次认知测试中没能画出立方体,有一次他在离家只有30米的地方迷路,靠路牌和询问行人才得以返回。从卧室到厨房贴满蓝色纸条,上面记录着大卫不想忘记的事情。
“我们倾向于对老年痴呆症感到害怕,或是自觉尴尬……我们视其为生命的终点,而非一个阶段,一个给我们机会去成长、学习和去爱人的阶段。”谈吐依然迷人的大卫说,“如果我活在未来,这是痛苦的疾病;但如果我活在当下,却不是。”
大卫失去了“自我”,却开始享受生活。“我可以‘出离自己’了,这是一个巨大的礼物。”他说,“跟佛教的‘无我’是一样的,我们所认为的自己是不断改变的。坚持自己让人受罪,拥抱变化却开启了光明。”大卫·希尔菲克不知道自己还能活多久,但他试着以全新角度来理解放手,接受频繁犯错的自己,并学会对付可怕的无助感。
……读到这样的励志故事总是令人鼓舞。
她曾经幻想自己的晚年,能够拥有写作者寒意凛冽的笔。如果命运答案出乎意外,如果和大卫一样,她能够因为长期的心理准备而从容吗?因受挫而厌弃自己,还是深怀感恩地接受陌生的成长?她可以更豁达吗,忘记怨恨,就像把雨水葬进河流?她喜欢喝棕色的饮料:浓茶、咖啡、热巧克力;她喜欢口感跨界的食材:笋、蘑菇、茄子;她恐惧蛇的形象:一种全身密布关节的动物;她敬畏烟花,仿佛那是神明放大的彩色瞳孔……随着病程变化,她在丧失学习能力的同时,也会忘记如影随形的习惯吗?至少,未来让她好奇,这已算作对今天的贡献。
一生无论怎样壮烈或优雅,终点,不过是一支烟弹下的骨灰。她看到一个肉体被蚀空的昆虫外壳挂在悬动的蛛丝末端,被风吹拂,像打秋千的小亡灵……一切皆空,它说它看见真理耀目的条纹。
她父亲的视力急剧下降,分不出黄昏之后的台阶,分不出河水中鳞色灰暗的鱼。开始误诊为白内障,其实是青光眼,眼压增高导致的种种问题。他所看到的世界越来越狭窄,如同他所记忆的内容越来越遥远。某天,父亲心情大好,竟然跑到楼下参加象棋比赛,他自信掌握所有的规则和计谋——结果当然尴尬,握着圆润的棋子一味沉吟,他不敌招数简单的初学者。好在,他能够迅速忘记不快,记忆的粗筛,漏下他生命里的宝石和砖砾。
未必是阿尔茨海默病,医学检查只是支持智力和记忆衰减的猜测,父亲的颅内区域出现明显腔梗;或者更悲观地说,不仅是阿尔茨海默病的问题,老年带来了综合的麻烦。鲜衣怒马的少年,能够匹配上驰骋的未来;对一个年迈者来说,世界充满频繁的敌意。
为了掩饰沮丧,父亲的脾气变得急躁、易怒;但他失神的时候越来越多。除了日常服药,新鲜事物的刺激也有助大脑运转,当她发现旅游中父亲的活跃思维,她每隔一段时间,就会安排父母出行。即使衰老掠走体能,记忆逐渐闭合,她希望父母能够克服重重障碍,晚年过得平顺安详。
置身异地,母亲和她最担心的,是父亲万一走失。她们不会让他远离视线。防范之下,有一次父亲也险些迷路,他自己毫无慌张,闲庭信步。如同,当年的爷爷。有一次,她发现父亲的额头撞出硕大、青淤的肿包,手背尚在流血,他自己并未留意,也不知道是什么时候造成这些伤痕。
她想起自己的童年。蒙住脸,把额头抵在粗糙纵裂的树干上,开始倒数。在她看不见的背后,小伙伴们陆续藏匿,直至,在她回望的时刻全部消失。寻找的道路,她既兴奋又慌张……她不畏惧,即使暮色正在降临,巨兽正在打开饥饿的肠胃。但愿自己和家人,在降临的暮色中不会失去曾经的勇气。
人间流徙,还有什么可供感慨?情到绝处,不留后路,不留令人唏嘘的归宿。
事实上,她自己也曾在只有一条主街的彼得堡迷路。她不急于寻找归途,随意走进路边一间餐馆。意外的相遇:那是著名之地,诗人普希金在这里喝下生命里最后一杯咖啡,他随后被决斗的子弹击中。室内设计复古,氛围低沉,墙面暗红,有一股暗杀的味道。播放的音乐,是歌剧里高亢的咏叹调。
她暂时想不起酒店的名称,没关系,这使她获得理由,可以不慌不忙品尝餐馆里的鱼子酱。橘黄色,黏着成团状,带有失真的化学色泽和质感。用舌头和上颚压碎,既脆弱又坚韧的鱼卵,爆涌出微甜、微咸、微腥的味道。几乎带来进食中的游戏感,那些颗粒释放一股股细小的暖流。她记得住饱满卵粒在齿间的破裂,却无法得知那条在溪流间闪耀鳞光的鱼。她将被滞留,在精心酝酿的未来被一天天摧毁却由此得到快意的这个瞬间。
她慢慢地喝着一杯含有气泡的饮料。泡沫破碎:明天、梦想、机会、健康……好在,什么也不多,什么也不少。一切,如溯流之鱼,重归亲切又生疏的远方。决斗的枪声尚未响起,命运的刺客还在途中。
创作群像剧有哪些技巧? - 知乎
================
<https://www.zhihu.com/question/32092968/answer/128037191>
咳咳,群像这个事哈,是个坑!我们先不说技巧,我们需要先说说硬件的问题,然后再说技巧。
要写好群像戏需要的是硬实力,仅仅靠小聪明一点用都没有,甚至可能会产生反作用。因为群像一旦有一个地方塌了,就全塌了。
我们首先要确定“群像戏”到底是要干啥用的。一般情况下,“群像戏”是用来写时代和社会的,老生常谈《茶馆》,《小井胡同》是两部标准的群像戏。都是写时代的群像戏,所以写群像首先的任务是对时代和社会的总结和梳理,这是一部分案头工作。
然后我们要理解一下“群像”的概念,“群像”字面意思是:一群人物形象。而结合上一条,群像就是要用一群人物形象表现时代。所以,我们这里需要一群人物形象,而且一群人物形象往往带来的是——多人物场面。这个事超级麻烦,每个人物形象的状态动作,行为逻辑都要展现出来,并且要把人物性格,人物关系,人物的发展,展现出来,且必须要要快,要准,要狠。
然后就是群像戏的事件组织,“群像”是一群人物,这代表着一大堆事,问题是这一大堆事要交织起来,合理合情的有作用的滚动起来,往往群像戏的难点都在于“事件”的选择上。
好的,我们在来聊聊怎么写群像。
一,人物小传
人物小传吼!群像的人物小传必须要做好,每一个人物都必须当主角来做人物小传!每一个人物都必须立得住!都必须考虑内部和外部矛盾,也必须考虑到人物的“个人,半个人,公共空间”的状态,都必须有发展线和心理支撑以及最高目的。
二,人物关系
人物关系必须要详细搭建,所有人物都不能落单,人物关系上力求各方牵制,可以考虑组织性,团体性分化,再在其内部分化的处理方式,但是这一招不能多用,用多了就不好看也不好玩了。
三,公共环境
群像戏一定有一个公共环境,不然群像戏是不能够很好的成立的。而公共环境必须具有开放的,有共性,包含矛盾的特点。而矛盾往往来自于时代或者来自于社会问题。所有的人都必须到这个公共环境里面来。
四,暗场戏要处理好
往往重点的场面都发展在公共环境之中,而在每个人的个人空间和半个人空间要作为暗场处理。而群像戏的问题就是这个,人物众多,且必须又要立的住,所以会具有大量的暗场戏,而实际上的大问题就是人物暗场戏是几乎所有人的噩梦。具体办法真的要靠练,但是可以用“扩大世界”的方式来帮助,这是个笨办法,把公共环境之外的环境更细致的做出来,可以安排好各个人物的各个空间事件。也方便于处理各种人物关系。
五,大场面的处理
因为群像戏往往事件的变化都偏快,人物也大都带着大量的状态和信息上场,所以场面上都偏向于快速发展的大事件。所以当人物上场之后,必须要引起事件的变化,或者推进。多个人物在场上的时候必须有每个人的行为动作和逻辑,这就是为什么人物小传必须要做好的最重要的原因之一。人物在场上不能无所事事,不能闲着必须要有自己的事情。不然场面会乱,《茶馆》的开场辣么多人,看上去乱糟糟的但是每个人都有自己的动作和事,虽然这要感谢焦菊隐先生。
六,学会使用静默场面
既然群像戏里面的大场面很多,也很激烈,所以更要好好使用静默场面,或者单人场面。这种时候往往可以很好的拉伸张力,并且也可以得到很好的抒情作用。但是不能使用过多,不然群像戏不成立。
七,人物的共性和差异
因为是群像戏,所以往往人人是具有一个共性的,这个共性不是性格上的而是命运上的。可能来自于时代和社会,往往这种群像戏是悲剧式的写法,但是不代表不可以作为荒诞喜剧。这一点我们可以看看奈保尔的《米格尔街》的处理,人物的共性是什么样子的,如果还可以的话不妨读读荣格。
这一部分的目的实际上就是为了维护人物的个性差异和整体的命运共性,这样可以让群像戏更好的组织起来。而且实际上这也是好的群像戏的前提。
八,核心事件
群像必须有核心事件!没有核心事件人物之间的关系勾起来更难!核心事件可以作为很好的磁石将所有人结合在一起,往往核心事件是必须关系到所有人的,但是千万不能写成讨论戏。
九,发展与变化
群像戏必须包含丰富的变化,无论是人物还是社会或者核心事件。这种变化必须有,可能是境遇,是观念,甚至是死亡。而这也是承载一个群像很重要很重要的部分,这一部分可以和暗场戏有比较大的关联。
不难看出,这九条好像废话。我开头就说了,群像是个坑!需要硬实力!没有小聪明可以耍!这些都是必须的!把这9条都做到了,自然写出来的群像不会差,同时写别的也不会差,可是如果单双线事件都搞不定就要写群像,不如用那个时间吃点好的比较有意义。
群像写好了很出彩,写不好,很坑,而且很折磨人。
一定是誰下的咒語,拐跑了我從未出走的睡眠。鬧鐘的聲音被靜夜顯微數十
倍,清清脆脆的鞭韃著我的聽覺。凌晨三點十分了,六點半得起床,我開始著急,
精神反而更亢奮,五彩繽紛的意念不停的在腦海走馬燈。我不耐煩的把枕頭又掐
又捏。陪伴我快五年的枕頭,以往都很盡責的把我送抵夢鄉,今晚它似乎不太對
勁,柔軟度不夠?凹陷的弧度異常?它把那個叫睡眠的傢伙藏起來還是趕走了?
我耍起性子狠狠的擠壓它。枕頭依舊柔軟而豐滿,任搓任搥,雍容大度地容
忍我的魯莽和欺凌。此時無數的野遊的睡眠都該已帶著疲憊的身子各就其位,獨
有我的不知落腳何處。它大概迷路了,或者誤入別人的夢土,在那裡生根發芽而
不知歸途。靜夜的狗嘷在巷子裡遠遠近近的此起彼落,那聲音隱藏著焦躁不安,
夾雜幾許興奮,像遇見貓兒篷毛挑釁,我突發奇想,牠們遇見我那蹺家的壞小孩
了吧!
我便這樣迷迷糊糊的半睡半醒,間中偶爾閃現淺薄的夢境,像一湖漣漪被一
陣輕風吹開,慢慢的擴散開來。然而風過水無痕,睡意只讓我淺嚐即止,就像舔
了一下糖果,還沒嚐出滋味就無端消失。然後,天亮了。鬧鐘催命似地鬼嚎。
我從此開始與失眠打起交道,一如以往與睡眠為伍。莫名所以的就突然失去
了它,好像突然丟掉了重要零件的機器。事先沒有任何預兆,它又不是病,不痛
不癢,嚴重了可以吃藥打針;既不是傷口,抹點軟膏耐心等一等,總有新皮長出
完好如初的時候。它不知為何而來,從何處降。壓力、病變、環境太亮太吵、雜
念太多,在醫學資料上,這些例舉為失眠的諸多可能性都被我否定了。然而不知
緣起,就不知如何滅緣。可惜不清楚睡眠愛吃什麼,否則就向釣魚那樣用餌誘它
上鉤,再把它哄回意識的牢籠關起來。失眠讓我錯覺身體的重心改變,頭部加重,
而腳下踩的卻是海綿。感覺也變遲鈍,常常以血肉之軀去頂撞家具玻璃,以及一
切有形之物。不過兩三天的時間,我的身體變成了小麥町─大大小小的瘀傷深情
而脆弱,一碰就呼痛,一如我極度敏感的神經。那些傷痛是出走的睡眠留給我的
紀念,同時提醒我它的重要性。它用這種磨人脾性損人體膚的方式給我「顏色」
好看,多向情人樂此不疲的傷害。然而情人分手有因,而我則莫名的被遺棄了。
每當夜色翻轉進入最黑最濃的核心,燈光逐窗滅去,聲音也愈來愈單純、只
剩嬰啼和狗吠的時候,我總能感受到萎縮的精神在夜色中發酵,情緒也逐漸高
昂,於是感官便更敏銳起來。遠處細微的貓叫,在聽覺裡放大成高分貝的廝殺;
機車的引擎特別容易發動不安的情緒;甚至還遷怒風扇的窗簾,它驚嚇了剛要蒞
臨的膽小睡意。一隻該死的蚊子,發出絲毫沒有美感和品味的鼓翅聲,引爆我積
累的敵意,於是乾脆起床追殺牠。蚊子被我的掌心夾成了肉餅,榨出無辜的鮮血。
我對著那美麗的血色發呆,慣性的又去瞄一瞄鬧鐘。失眠的人對時間總是特別在
意,哎!三點半了!時間行走的聲音讓我反應過度,對分分秒秒無情的流失尤其
小心眼。我想閱讀,然而書本也充滿睡意,每一粒文字都是蠕動的睡蟲,開啟我
哈欠和淚腺的閘門。難怪我掀開被子,腳跟著地的剎那,恍惚聽見一個似曾相識
的聲音在冷笑:「認輸了吧!」原來失眠並不意味著擁有多餘的時間,它要人安
靜而專心的陪伴她,一如陪伴專橫的情人。
我趿上拖鞋,故意拖出趴噠趴噠的響聲,不是打地板的耳光,而是拍打暗夜
的心臟。心有不甘的旋亮桌燈,溫暖的燈光下兩隻貓兒在桌底下的籃子裡相擁酣
眠。多幸福啊!能夠這樣擁抱對方也擁抱睡眠。我不由十分羨慕此刻正安眠的眾
生、腳下的貓兒、以及那個一碰枕頭就能接通夢境的「以前的我」。眼皮掛了十
斤五花肉般快提不起來了,四天以來它們闔眼的時間不超過十二小時,工作量確
實太重了。黃色的桌燈令春夜分以外安靜而溫暖。這樣的夜晚適宜窩在床上,和
眾生同在睡海里載浮載沉。
或許粗心的我弄丟了開啟睡門的鑰匙吧!又或者我突然失去了泅泳於深邃
睡海的能力;還是我的夢囈干犯眾怒,被逐出夢鄉。總而言之,睡眠成了生活的
主題,無時無刻都糾纏著我,因為失去它,日子像塌陷的蛋糕疲弱無力。此刻我
是獵犬,而睡眠是兔子,牠不知去向,我則四處搜尋牠的氣味和蹤跡,於是不免
草木皆兵,聲色俱疑。眾人皆睡我獨醒本就是痛苦,更何況睡意都已悉數凝聚在
前額,它沉重得讓我的脖子無法負荷。當然那睡意極可能是假象,儘管如此,我
仍乖乖的躺回床上。模糊中感到鈍重的意識不斷壓在身上,甜美的春夜吻遍我每
一寸肌膚,然而我不肯定那是不是「睡覺」,因為心理明白身心處在昏迷狀態,
但同時又聽到隱隱的穿巷風聲遊走,不知是心動還是風動,或是二者皆非,只是
被睡眠製造的假象矇騙了。那濃稠的睡意蒸發成絲絲縷縷從身上的孔竅游離,融
入眾多沉睡者煮成的無邊濃湯裡。
就這樣意志模糊的過了六天,每天像拖個重殼的蝸牛在爬行。那天對鏡頭梳
頭時,赫然發現一具近似吸血殭屍的慘白面容,立時恍然大悟,原來別人說我是
熊貓只是善意的謊言。此時剛洗過的頭髮糾結成條,額上垂下的劉海懸一排晶亮
的水珠,面目只有「猙獰」二字可形容。頭髮嫌長了,短些是否較易入眠?太長
太密或許睡意不易滲透,也不易把過多的睡意排放出去,所以這才失眠的吧!
到第七天,我暗忖這命定的數字或會賜我好眠,連上帝都只工作六天,第七
天可憐的腦袋也該休息了,我聽到每一個細胞都在喊睏,便決定用誘餌把兔子引
回來,那是四顆粉紅色、每顆直徑不超過零點五公分的夢幻之丸,散發著甜美的
睡香,只要吃下一粒,即能享有美妙的好夢。
然後我有些猶豫,原是自然本能的睡眠竟然可以廉價購得。小小的一顆化學
藥物變成高明的鎖匠,既然睡眠之鑰可以打造,以後是否連夢境也能夠一併複
製,譬如想要回味初戀酸酸甜甜的滋味,就可以買一瓶青蘋果口味的夢幻之水;
那瓶紅豔如火的液體可以讓夢飛到非洲大草原看日落;淡黃色的是月光下的約
會;藍色的呢!是重回少年那段歲月,嚐嚐早已遺忘的憂鬱少年那種浪漫情懷
吧!
我對那幾顆小小的東西注視良久。連自己的睡眠都要仰仗外力,那我還殘存
多少自主,這樣活著憑的是什麼?然而我極想念那隻柔順可愛的兔子,多想再度
感受夢的花朵開放在黑夜的沃土。睡眠是個舒服的繭,躲進去可以暫時離開黏身
的現實,在夢工場修復被現實利刃劃開的傷口。我疲弱的神經再也無法承受時間
行走在暗夜的聲音。醒在暗夜如死刑犯坐困牢房,尤其月光令人發狂地恐慌。陽
光升起時除了一絲涼淡淡的希望,伴隨而來是身心俱累的悲觀,彷彿刑期更近
了,而我要努力撐起鈍重的腦袋,去和永無止境的日子打仗。
我掀開窗簾,從沒看過那麼刺眼的陽光,狠狠刺痛我充血的眼睛,便刷的一
聲又把簾子拉上。習慣了蒼白的月光和溫潤微涼的夜露,陽光顯得太直接明亮。
黑夜來臨,我站在陽臺眺望燈火滅盡的巷子,彷彿一粒洩氣的氣球,精神卻不正
常的亢奮起來,如服食過興奮劑,甚至可以感覺到充血的眼球發光,像嗜血的獸。
我想起大二時那位仙風道骨的書法老師。上課第一節照例是講理論,第二節
習作。正當同學把濃黑的注意力化作墨汁流淌到紙上,筆尖和宣紙作無聲的討論
時,突然聽到老師低沉的聲音說:「唉!我足足失眠兩個星期了。」我訝然抬頭,
還撇壞了一筆。老師厚重鏡片後的眼神閃現異光,那是一頭極度渴睡的獸。我正
好和他四目相接,立刻深深為那燃燒著強烈睡慾的眼神所懾,那是被睡意醃漬浸
透、形神都淪陷的空洞,或許是吸收太多太多的夜氣,以致充滿陰冷的寒意。然
而他上起課來仍是有條有理,風格流變講的井然有序,而我現在終於明白他不時
用力敲打自己的腦部、揉太陽穴,一副巴不得戳出個洞來的狠勁,其實是一種極
度無奈的沮喪。他是在叩一扇生理本能的門,那道門的鑰匙因為芸芸眾生各持一
把,丟掉了借來別人的也無濟於事,便那麼自責的又敲又戳起來。
然則如今我終於能體會他的無奈了。可怕的是我從自己日趨空洞的眼神,看
到當年那瞬間的一瞥復又出現。畫伏夜出的朋友對夜色這妖魅迷戀不已,而願此
生永為夜的奴僕。他們該試一試永續不眠的夜色,一如被綁在高加索山上,日日
夜夜被鷲鷹啄食內臟的普羅米修斯,承受不斷被撕裂且永無結局的痛苦。然而那
是偷火種的代價和懲罰,若是為不知名的命運所詛咒,這永無止境的折難就成了
不甘的怨懟而非救贖,如此,普羅米修斯的怨魂將會永生永世磐桓。
失眠就是不知緣由的懲罰。那四顆夢幻之丸足以終止它嗎?我聽上癮的人說
它是嗎啡,讓人既愛又恨,明知傷身,卻又拒絕不了,因為無它不成眠。這樣聽
來委實令人心寒,就像自家的鑰匙落入賊子手裡,每晚還要他來給自己開門。於
是我便一直猶豫,害怕自己軟弱的意志一旦肯首,變墜入深淵永劫不復了。
睡眠的慾望化成氣味充斥整個房間,和經過一冬未曬的床墊、棉被濃稠地混
合,在久閉的室內滯留不去,形成房間特有的氣息。我以為是自己因失眠而嗅覺
失靈的緣故。一日朋友來訪,我關上房門後問:「你有沒有聞到睡眠的味道?」
他露出不可思議、似被驚嚇的眼神,我才意識到自己言重了。
就像我沒有想到會失眠一樣,睡眠突然倦鳥知返。事先也沒有任何預示,我
迴避鏡子許久了,一如忘了究竟有多少日子是與夜為伴,以免嚇著自己,也害怕
一直叨念這一點也不稀罕的文明病,終將為人所唾棄。何況失眠不能稱為「病」
吧!如此身旁的人會厭惡我一如睡眠突然離去。而朋友一旦離開就像逝去的時間
永不回頭,他們不是身體的一部分,亦非血濃於水的親密關係,更不會像丟失的
狗兒會認路回家。
那天清晨,自深沉香醇的夢海泅回現實,急忙把那四顆粉紅色的夢幻之丸埋
入曇花的泥土裡。也許,它們會變成香噴噴的釣餌,有朝一日再度誘回迷路的睡
眠;也可能長出嫩芽,抽葉綻放黑色的夜之花,像曇花一樣,以它短暫的美麗溫
暖暗夜的心臟。
導讀
早期的鍾怡雯沉湎在她原鄉的雨林地景,南洋生活圖案,蘊含深厚的人文情
感,歷史文化的關照。後來她毅然離開,選擇一些不起眼的生活素材,增加語言
的敘事性和趣味性,發掘平淡中的理趣,以語言釀製詩的質感,進而創造一個遊
刃事理中的靈魂。有時還專注於日常生活的構成事物:化妝品、首飾、家具、跑
車、還有寵物與纏人的病痛,記下作者以靈魂豢養自身的宇宙,有著女子的細膩
與鍾怡雯獨有的時空觀照。同是散文家的簡媜如此稱許:「豐沛的想像與獨特的
敘述魅力,使尋常事務展露異彩,鍾怡雯無疑地是新生代中即亮眼的散文新星。
她的潛力足以呼風喚雨。」詩人焦桐則以為:「鍾怡雯散文心思細膩,構思奇妙,
通過神秘的想像,當超越現實邏輯,表現詭奇的設境,和一種驚悚之美,敘述來
往於想像與現實之間,變化多端,如狐如兔。」
〈垂釣睡眠〉就像在大海中釣魚一樣,要將出走的「睡眠」垂釣出來,換言
之,這是一種描寫失眠之苦的文章,將睡眠擬人化、異樣化,寫出自己六天失眠
的經驗,從內在心理的培養、意志的模糊,外在燈光的誘惑、夢幻之丸的可能成
效,掙扎、攀爬,多樣的譬喻,猶未能垂釣睡眠,就在這時,睡眠突然倦鳥知返,
正是一種詭奇的設境,彷彿讀者也陪著她,在如夢似幻間,穿越想像的雨林。
──選自《台灣現代文選》(三民,2004)
品味時間
1、作者如何描寫失眠之苦?如果你有過失眠,試想一下你會如何描寫。
[[从小白到入门-自建服务器部署家庭应用之各种教程-长期更新|https://www.chiphell.com/forum.php?mod=viewthread&tid=2198315&mobile=1]]
!!前言
* Linux安装——debian10
* 科学网关——透明代理
* 文件共享——samba
* PT及离线下载——qbitttorrent和aria2
* 密码管理器——bitwarden
* 公网访问——DDNS及端口映射
* 性能测试——测试命令与软件
* 公网web——speedtest测速
* OMV安装与简介——all in one NAS系统
* 远程管理——宝塔面板
* 个人网盘——nextcloud
* 聊天服务器——matrix
* 本帖最后由 T.JOHN 于 2020-6-13 19:09 编辑
由于多数家庭有淘汰的旧电脑或是土豪会购置各种小体积“软路由”,本着变废为宝,一机多用的绿色生活。此贴用来介绍以debian为基础,部署各种开源程序以实现安全,快捷,强大的服务端。包含0.科学网关1.文件共享 2.离线下载 3.远程监控 4.NAS管理 5.个人网盘 6.聊天服务器... 甚至 网站 图床 编译openwrt 等
本文的目的在于不花一分钱购买硬件设备的前提下理解以下内容:
* 公益。保护个人隐私。具体可以参看2014年发起的非营利网站及其创始人的TED演讲
本贴就是将公益实践的一个过程,即去windows和群晖等商业性方案开始,采用全开源方案。开源方案越来越被推广的原因是符合人类未来需求,微软虽然是商业公司在github上开源贡献也最多
* 简化。硬件区对于此类的需求有很多虚拟化(exsi hyperv),ROS,群晖等方案,甚至很多在windows上部署
这些在我看来显然是因为对linux不熟悉而舍近求远,费力劳神搞的方案。以每个人都知道的ss为例,简述原因
# linux一般是软件诞生平台。因为所有的开源软件都可以根据源代码自行编译的,而编译这个过程大多是在linux下完成的,也就是说第一版软件会发布在linux上,其他的win exe及IOS app等都是交叉编译或二次开发的。虽说win也能构建编译环境,但是这不是程序员常规的开发平台
# 对软件直接调用。linux主要以命令行完成操作,图形界面可有可无,但windows是全图形化界面,这是两者重要区别。因此像ss有个配置文件,在linux上用写入后再用命令行运行,是直接调用,整个过程无中间环节。而通过路由器的luci图形界面或者win上软件的图形界面则是间接调用,等于是在内核上套个壳,如果不开源你不知道他会不会有后门
# 在理解安装和编译linux软件后,你开始理解什么叫返璞归真,和那些能在windows也能运行的方案相比。在性能,鲁棒性,可持续性,易用性及隐私保护等方面有多大的优势
* 认知。对于在CHH,koolshare,群晖,恩山上所讨论的很多需求都是需要大神给出固件或者教程,没了固件你就歇菜,提升认知后我们可以跳过这个步骤,一切不求于人
- 即学会使用github,全世界的第一手代码都在这个网站,使用linux就相当于学会使用了github,所有需求你都可以自助了
# 当你学会使用linux和github以后,你不再是用户,你也成为了半个开发者,你可以逐步理解这些软件工作的原理,进行更定制化的优化使用 (比如v2ray解决DNS污染问题)
# 当你对linux使用时间长了以后,你越理解为什么它适合做服务系统,感受到他的简单快捷,越体验到windows为何在服务器领域远不如桌面来的受欢迎
* 节能。在路由器上差个U盘部署一些24小时运行的软件,其实就是为了节能的一种表现,但很多服务路由器不堪胜任
*
linux是可以运行在非常简化的设备上的,比如树莓派之类的开发板,N1这类电视盒等等,他们可以24小时开机,满足大部分人的个人或者需求,每年为你省不少电费。
x86有历史包袱,要兼容之前构架,在追逐高性能的道路上无法和arm比节能的。很多人可能不知道大多数云服务器(aws 阿里云)是512M内存,1CPU 15%的可用起步的,但是还是有很多人购买并使用。linux就能做到在这种低配机器上可靠运行,而debian/centos两大免费服务器系统就是跨平台的,arm设备以后会越来越多,所以这也是为什么微软也要做arm的windows,死活不放弃的原因
# 软件。我们的需求永远是软件,软件优先于硬件,硬件只是软件运行的平台
整个教程的过程中,大家会逐步理解这一点。CHH很多人也许会在乎硬件性能,但随着使用服务器一段时间,大家就会知道树莓派都可能是硬件性能过剩的服务器,因为就你一个人或者家庭成员的少数人访问,基本不存在大量并发需求。
!!Part 1 前言,
Q: 为什么要学“服务器部署”?什么是“服务器部署”
A: 因为要个性化服务,只有自己动手才能丰衣足食。所谓“服务器部署”就是使用Linux CLI(command in line)安装服务端的软件和调试,对应的是windows GUI下鼠标点exe装客户端的软件和设置
Q: 学“服务器部署”会不会比较没性价比?应用面狭窄,学习曲线过抖等?
A: 看你需求,如果你真的有以上方面个性化需求,学个入门绝对不亏。从win95到win10的20年你肯定会觉得变化很大,毕竟控制面板都大变。然而20年过去了,linux的安装命令还是apt/yum install xxx,远程控制还是通过ssh,修改配置还是通过vim,基本没变。过去如此,未来还会是如此。如果你需要的个人服务越多,你的“linux全方位认知”越有用。我会从最简单的部署开始,从实践逐步了解linux
Q: 你怎么能保证这些软件不会过时或者可以长期使用?
A: 因为专用(闭源)方案长期来看比不上通用(开源)方案有生命力,专用方案像windwos Mac这种获得巨大成功的,需要大量资金,而开源就是指一代一代传承和贡献,不断有人维护。群晖就是典型的专用方案,它除了提供集成度较高的硬件和漂亮的硬盘位,还提供了亲和的软件界面,甚至web服务,然而如果公司倒闭就没人维护了。而开源软件即便像clowwindy把源码删了,后来者在fork后依旧会使软件得到更新。
Q: 你为什么不提供windows的客户端软件?这样更方便大家使用。
A: 因为没有,几乎所有Github上服务器的客户端都部署在linux上,这对于开发者和使用者都是开源免费,而linux作为操作系统本身开源。所以这就是为什么服务器市场windows份额极低的原因。然而各位可能不知道win10大量的新feature比如wsl,powershell,hyper-v二代甚至vs code等,都是为了拥有linux等同的功能,提供更好支持,拉拢开发者。
Q: 为什么是debian?不是centos?或者是其他linux发行版本
A: 很多人linux都是从ubuntu入手,而debian和ubuntu没啥太大区别,命令一样,较易学习。debian相比centos占用内存更小,而且国外社区支持了更多,所以有树莓派的raspbian和各种电视盒的armbian(debian for arm)的诞生。这样硬件方面可以照顾N1和树莓派用户,让你的arm设备也能当服务器,软件方面一大优势是独占openmediavault(后文会提到的NAS系统),另一方面仓库的软件源也更新些,这样对新人更友善。centos我一般部署在云服务器上,毕竟他一个版本的维护周期是十年(现在是centos7第五年和centos8元年),软件旧就旧了,服务器稳定第一,比如centos7上的默认python2已经于2020年1月1日停止维护,默认的数据库sqlite软件源停留在3.7(2013年)已经不被某些软件所支持了。
Q: All in one的方案会不会不稳?一个服务崩了其他全崩?
A: 要看你是如何部署,如何维护。由于现在有docker的出现,它作为linux上的虚拟机,现在是一种很流行的方案去隔离各种软件,一行命令把所有软件全装完。一方面方便快捷,一方面崩溃了不影响系统。他的原理和安卓上的app雷同,运行在java虚拟机上。部当然有的人不喜欢docker,喜欢用自己部署的系统环境。其实最重要的还是备份,linux自带dd命令可以全盘复制(ghost)。
Q: 你好像没怎么提到虚拟化技术,很流行的esxi装多个系统不好么?
A: 这个需要根据每个人的需求决定,看你要在虚拟机上运行什么。首先,除了迅雷和QQ,我想不太到win作为server的意义。其次,openwrt作为一个虚拟机上的系统在linux下可以用docker安装并运行,而debian安装v2ray配合iptables规则也可以当网关。最后像freenas这种管理zfs的系统在debian上安装OVM后一样可以建立zfs存储池。因此大部分情况下是无需虚拟方案的。这除了降低机器性能和复杂化以外没什么好处。
在IDC领域最流行的虚拟化技术是KVM,主要是开源和免费,其用途是母鸡生小鸡,出售资源用。在个人家庭,你拥有服务器的所有资源,因此没有这种目的。其他IDC还用的虚拟化技术有Xen(AWS),OVZ(早期非独立虚拟化)和hyper-v(Azure),esxi是vmware给某些企业特殊用途的方案,十分小众。
它是一种认知偏差现象,指的是能力欠缺的人在自己欠缺能力的基础上得出自己认为正确但其实是错误的结论,他们无法正确认识到自身的不足,也无法辨别错误行为。这些能力欠缺者们沉浸在自我营造的虚幻的优势之中,常常高估自己的能力水平,却无法客观评价他人的能力。(KrugerandDunning,1999)
逮香蕉鱼的最佳日子_九故事_塞林格
========================
** 逮香蕉鱼的最佳日子**
[[逮香蕉鱼的最佳日子|https://www.kanunu8.com/book/3825/39359.html]]_九故事_[[塞林格]]
-----
威格利大叔在康涅狄格州
就在跟爱斯基摩人开战之前
笑面人
下到小船里
为埃斯米而作
嘴唇美丽而我的双眸澄碧
德 • 杜米埃. 史密斯的蓝色时期
特迪
逮香蕉鱼的最佳日子
旅馆单住了九十七位纽约来的广告业务员,他们简直把长途电话线全给霸占了,住 507 号房间的那位姑娘为要通长途只好从中午一直等到快两点半。不过她倒也没闲着。她看了小开本妇女杂志上登的一篇文章,标题是《性是乐趣——也可能是受罪》。她洗了她的梳子和头发刷子,把她那身米色套服裙子上的一处行债刮掉,又把她在萨克斯买的那件衬衫上的纽扣挪了挪位置。而且,还用镊子把她一颗痣上新冒出来的两根毛拔掉。在接线生终于拨响她房间的电话时,她止坐在窗前座位上染指甲,左手上的已经快染完了。
她是那种姑娘,绝不会听到电话响便把手里任何东西胡乱一扔的。瞧她那副架势,仿佛是自打进人青春期起,电话就一直在响似的。
电话零零地响着,她继续用小刷子涂抹小手指指甲,刻意描绘着那个月牙形的边缘。接着,她把盖子放回到指甲油瓶上,站起身,把她的左手——那只湿的——在空中前后甩动。她用那只干手把烟灰缸从窗台拿到床头柜上,电话就是放在这里的。她在两张铺叠整齐的单人床中的一张上坐下,捏起话筒,此时,铃声已经口自了五六遍了。
“喂,” 她说,左手五指揸开着,伸出去,离她那身白丝绸晨衣尽可能远些,这晨衣是此刻她身上惟一穿着的东西,另外就只有一双拖鞋了… 那几只戒指她都留在洗澡间里了。
“您要的纽约长途电话接通了,格拉斯太太。” 接线生说。
“谢谢你。” 姑娘说,一边在床头柜上给烟灰缸腾出个地方。
电话里传来一个妇人的声音,“穆里尔吗? 是你吗?”
姑娘把听筒从耳边稍稍斜开一些。“是的,妈妈。你好吗?” 她说。
“你可让我担心死了。你干吗不来电话? 你没事吧?”
“我昨儿晚上、前天晚上都一遍遍给你拨电话来着。这儿的电话可--”
“你没事吧,穆里尔?”
姑娘把话筒从耳边再多支开去一些。“我挺好的。就是觉得热。这么多年来,佛罗里达还没有这么热过——”
“你怎么不给我打电话呢? 我真为你担心——”
“蚂妈,亲爱的,别冲着我叫。你的声音我听得真真儿的,” 那姑娘说。“昨儿晚上我给你打了两回。一回就在刚剐——”
“这不,我就跟你爸爸说过没准你昨儿晚上打过电话。可是,没用,他非说——你没事吧,穆里尔? 要跟我说实话呀。”
“我挺好的。别再问这个了,求求你了。”
“你们什么时候抵达的?”
“我也说不上来。星期三上午吧,挺早的。”
“谁开的车?”
“他呀,” 姑娘说。“你别激动嘛。他开得非常棒。我都没想到。”
“真的是他开的? 穆里尔,你要向我保”
“妈妈,” 姑娘打断了话头,“我不是跟你说了嘛,他开得非常棒。一整天时速都没超过五十,我是实话实说。”
“他没冲着树什么的玩什么花招吧?”
“我说了他开得非常棒,妈妈。行了,求求你了。我跟他说了要紧挨白线,该说的都说了,他明白我的意思,也照着做了。他甚至都没打算刘着树看上一眼——这是明摆着的。哦,对了,老爸把丰子拾掇好了吗?”
“还没呢。人家要四百块钱,光就——”
“妈妈,西摩跟爸爸说过这钱由他来出。没有理由让——”
“好吧,以后再说。他行为怎么样——在汽车里和别的地方?”
“挺好的呀,” 那姑娘说。
“他还是没完没了地叫你那难听的——”
“不了。他现在又趁了新的了。”
“是什么?”
“哦,这又有什么两样呢,妈妈?”
“穆里尔,我必须知道。你爸爸——”
“好吧,好吧。他管我叫‘1948 年度精神流浪小姐’,” 姑娘说,发出了格格的笑声。
“这没什么好笑的,穆里尔。这根本就一点也不好笑。简直是让人作呕。实际上,是让人感到悲哀。我一想到怎么一’
“妈妈.” 姑娘打断了话头,“听我说。你记得他从德国给我寄来的那本书吗? 你知道吧——那本德国诗集。我把它怎么的啦? 我想得脑袋生疼——”
“书你没丢。”
“你敢肯定?” 姑娘说。
“当然啦。也就是说,我没有丢。就在弗雷迪房间里呢。你把它丢在我这儿了.我没地方放--怎么啦,他又要啦?”
“不。他只是问起这事,在我们开车来的路上。他想知道我读了没有。”
“那可是德文的!”
“是啊,亲爱的。这没什么区别,” 姑娘说,交叉起了双腿。“他说那些诗正是本世纪独一无二的伟大诗人写的。他说我该去买一本译本什么的。要不就学会这种语言,如果我愿意的话。”
“可怕。可怕。简直是可悲,的确是的。你爸爸昨儿晚上说——”
“等会儿,妈妈,” 姑娘说。她走到窗台前取来香烟,点上一根,又回到床边坐下。“妈妈?” 她说,吐出了一口烟。
“穆里尔,好,现在你听我说。”
“我听着呢。”
“你爸爸跟西威茨基大夫谈过了。”
“是吗?” 姑娘说。
“他跟他谈了所有的情况。至步,他说他这样做了… 你是了解你爸爸的。那些树的事。窗户的事儿。他对奶奶说的关于她故世的打算那些可怕的事情。他怎样对待百慕大带来的所有的漂亮图片的事情——一切的一切。”
“怎么样?” 姑娘说。
“哼。头一条,医生说部队把他从医院里放出来简直是在祀罪—我说的全是实话。他非常明确地告诉你父亲很有可能——非常大的可能,他说——西摩会完完垒全失去对自己的控制。我说的全是实话。”
“这儿旅馆里就有一位精神病专家,” 姑娘说。
“谁? 他叫什么名字?”
“我不清楚,像是叫里塞尔什么的。听说他非常卅色。”
“从没听说过他嘛.”
“嗯,反正大家都认为他很了不起。”
“穆里尔,别那么幼稚,好不好。我们太替你担心了。你爸爸昨儿晚上直想打电报让你回来,老实说——”
“我这会儿不想回家,妈妈。你别紧张嘛。”
“穆里尔。我一点儿没瞎说。西威茨基大夫说西摩很可能会完全失去控——”
“我刚到这儿,妈妈。这是多年来我头一次休假,我可不想把什么都胡乱往箱包里一塞就回家,” 姑娘说。“再说我现在也走不了哇。我皮肤晒坏了,简直没法动。”
“你晒得很厉害吗? 我在你包里放了那瓶布朗兹防晒油,你没有抹吗? 我就放在——”
“我抹了。可还是挨晒了。”
“太糟糕了。你哪个部位晒坏了?”
“全身上下,好妈妈,哪儿哪儿都是。”
“那真糟糕。”
“我死不了的。”
“告诉我,你跟这位精神病专家淡过啦?”
“唉,也算是谈了吧,” 那姑娘说。
“他说什么来着? 你跟医生说的时候西摩在哪儿?”
“在大洋厅里,弹钢琴呢。我们来到这儿接连两晚他都弹钢琴了。”
“噼,那医生说什么了?”
“哦,也没几句话。是他先跟我搭话的.昨晚玩宾戈… 时我坐在他旁边,他问我在那个房间里弹钢琴的是不是我的先生。我说是的.话就是这么说起来的,接着他问我丽摩是不是确病或是有什么别的事儿。我就告诉他——”
“他怎么会问起这个来的?”
“我哪里知道,妈妈。我琢磨是因为他脸色不好这样的事吧,” 姑娘说。“反正,宾戈散局后他和他太太问我愿不愿跟他们一起喝上一杯。我就去了。他太太真让人受不了。你还记得咱们那回在邦维特橱窗里见到的那件难看的晚礼服吗? 就是那件,你说穿的人得有一个非常小,非常小——”
“那件绿的?”
“她正穿着呢。就只看见两爿屁股了。她不断地问我西摩是不是跟在麦迪逊大街开一家店——是女帽店——的苏珊妮 • 格拉斯有亲戚关系。”
“那他到底说了什么,那医生?”
“哦。唉,其实也没说几句话。我的意思是我们在酒吧里呆着,喝了点酒。那里吵得要命。”
“是的,可是你可曾——可曾告诉医生他想把奶奶的椅子怎么样吗?”
“没有,妈妈。我可没谈得那么细,” 那姑娘说。“我可能有机会跟他再谈一次。他一整天都泡在酒吧里。”
“他有没有说他认为西摩有可能变得——你明白吧——反常什么的? 也许会对你做出什么来!”
“倒没这样蜕 -” 那姑娘说。“他得掌握更多的情况呀,妈妈。他们得从你小时候的情况知道起——一切有关的情况。我方才跟你说了,我们简直没法谈话,那里吵得什么似的。”
“对了。你那件蓝色的外衣怎么样了?”
“没问题。我把里面的村垫取了些出来。”
“今年的时装有什么新情况?”
“太可怕了。不过倒是真漂亮。满眼都是闪光装饰片——真是应有尽有,” 姑娘说。
“你们的房间怎么样?”
“还行。也就是还行吧。战前我们住过的那间这次没弄到,” 姑娘说,“今年来的人档次太低了。你真该瞧瞧在餐厅里坐在我们身边的是些什么人。在我们旁边那一桌的,简直像是一路挤在一辆太卡车里来的。”
“唉,现在哪儿哪儿都是这样。你的软底低跟便鞋怎么样?”
“太长了。我早就对你说那鞋太长了。”
“穆里尔,我就再一次问你一句——你真的没事儿吗?”
“是的,妈妈,” 姑娘说。“都跟你说了快一百遍了。”
“那么你真不想回家?”
“不想,妈妈。”
“际爸爸昨天晚上说,要是你愿意一个人独自到某个地方去把事情好好掂量掂量,他非常愿意支付费用。你满可以作一次惬意的海上航行的。我们俩都认为——”
“不,谢谢了,” 姑娘说,把叉着的腿放平了。“妈妈,这长途电话很贵—~”
“我一想副你在整个战争中怎样一直等着那小子--我的意思是当你想到所有那些中了魔法似的年轻妻子,她们——”
“妈妈,” 姑娘说,“咱们还是挂上电话吧。西摩说不定什么时候都会进来的。”
“他在哪儿?”
“在海滩上。”
“在海滩上? 就他自己一个人? 他在悔滩上表现得好吧,”
“妈妈,” 姑娘说.“你这么说他就好像他是个乱叫乱嚷的疯子似的——”
“这样的话我可一个字也没说呀,穆里尔。”
“哼,你话里就有这个意思。我是说他光是躺在沙滩上。他连浴袍都不肯脱。”
“他不肯脱浴袍? 为什么不肯,”
“我不知道。我猜他觉得自己太苍白了吧。”
“我的天,他正需要晒太阳呢。你就不能让他听你的?”
“你是知道西摩的脾气的,” 姑娘说,又一次把腿交叉起来。“他说他不想让一堆傻瓜盯看他身上的图徽。”
“他身上没刺任何花纹呀! 他在部队里史过身啦?”
“没有,妈妈。没有,亲爱的,” 姑娘说着又站起了身子。“听我说,没准明天我再给你去电话。”
“穆里尔。等一下,你先听我说。”
“好吧,妈妈,” 姑娘说,把身体重心全移到右腿上。
“只要他行动,哪怕说话上有一点点古怪的迹象,马上给我打电话——你明白我的意思吧。你听见了吗?”
“妈妈,我又不怕西摩。”
“穆里尔,我要你答应我。”
“好吧,我一定做到就是了。再见了,妈妈,” 那姑娘说,“跟爸说我爱他。” 她挂上了电话。
“又看见更多玻璃了,” 西比尔 • 卡彭特说,她跟她母亲也住在这座旅馆里。“你见到更多玻璃了吗?”
“坏小妞,不许再那样说。妈妈简直要给你逼疯了。别乱动,求求你了。”
卡彭特太太正往西比尔双肩上抹防晒袖,往下涂匀在她背上那两片细嫩的、翅膀般的肩胛骨上。西比尔摇摇晃晃地坐在一只充了气的海滩大皮球上,面对着大海。她穿着一套嫩黄色两件式的游泳衣,其中一件即使再过十年八年也未必对她有用。
“那其实只是一条普普通通的丝巾——你靠近了就能看清了,” 坐在卡彭特太太旁边一张躺椅罩的那个女人说。“我真想知道她是怎么系的。那真招人喜欢。”
“听起来也招人喜欢,” 卡彭特太太应了一句,“西比尔,别动,淘气包。”
“你见到更多玻璃了吗?” 西比尔说。
卡彭特太太叹了口气,“算了,” 她说。她把防晒油瓶子的盖子拧上。“好了,你走开去玩吧,小淘气。妈眯要回旅馆去和哈贝尔太太喝杯鸟提尼酒。我一会儿给你带橄榄来。”
西比尔得到解脱,马上就奔过一段平坦的海滩,开始朝渔人亭的方向走去。她仅仅停下了一次,为的是把脚往一个被海水袍透、坍塌的沙堡狠狠地踩下去,很快,她就走出了旅馆为游客划定的海滨浴场。
她走了大约四分之一英里,突然斜着朝海滩的一个松软部分冲上去。最后.在一个仰面躺着的年轻人的跟前猛地收住脚步。
“你打算下水吗,见到更多玻璃?” 她说。
年轻人吃了一惊,他的右手伸上去捏住毛巾浴袍的翻领。他翻过身趴着睡,任凭一条卷起来盖住眼睛的毛巾掉落下来,接着他眯起眼睛仰望着西比尔。
“嘿。你好,西比尔。”
“你想下水吗?”
“我在等你呢,” 年轻人说。“有什么新鲜事?”
“什么?” 两比尔说。
“有什么新鲜事? 今天有什么节目?”
“我爸爸明天要坐一架奈里飞机来,” 西比尔说,一面踢着沙子。
“别往我脸上踢呀,宝贝儿,” 年轻人说,把手按在西比尔脚踝上。“我说,他也该来了,你爸爸。我每时每刻都在等他来。每时每刻呢。”
“那位女士在哪儿?” 西比尔说。
“那位女士?” 年轻人掸出些他稀疏头发里的沙子。“那可难说了,西比尔。那么多地方谁知道她在哪里,没准在美发厅。把她的头发染成貂皮颜色。要不就在她房间里,给穷苦孩子缝布娃娃。” 年轻人此刻采取了平卧的姿势,他捏起两只拳头,把一只撂在另一只上,又把下巴搁在上面的那只拳头上。“问我点儿别的什么,西比尔,” 他说。“你穿的游泳衣挺不错的。要说我喜欢什么,那就是一件蓝游泳衣了。”
西比尔盯着他看,接着又低下头看看自己鼓嘟嘟的肚皮。“这件可是黄的,” 她说。“这件是黄的。”
“是吗? 你走过来一点。”
西比尔往前跨了一步。
“你完全正确。瞧我有多傻。”
“那你准备下水吗?” 西比尔说。
“我正在严肃考虑这个问题呢。我正翻过来覆过去地想呢,西比尔,你一定会很想知道的。”
西比尔捅了捅年轻人有时用来作枕头的那只橡皮气床。“这得打气了,” 她说。
“你说得不错。它需要的气比我认为的还要多了。” 他移开两只拳头,让下巴落在沙子上。“西比尔,” 他说,“你看上去气色不错,见到你真好。给我说说你自己的事儿。” 他伸出胳膊把西比尔两只脚腕都捏在手里。“我是山羊座的,” 他说。“你是什么座的?”
“沙伦 • 利普舒兹说,你让她跟你一块儿坐在钢琴凳上,” 西比尔说。
“沙伦 • 利普舒兹这么说了吗?”
西比尔使劲儿点了点头。
他松开她的脚腕,收回双手,把一边儿的脸靠在他的右前臂上,“哦,” 他说,“你也知道那样的事儿怎么来的,西比尔。我坐在那里弹琴。没见到你的人影。而沙伦 • 利普舒兹正好走过来挨着我坐下。我总不能把她推下去吧,是不是?”
“能的。”
“哦,不,不行的。这样的事我做不出来,” 年轻人说。“不过我可以告诉你我当时是怎么做的。”
“怎么做的?”
“我假设她就是你。”
西比尔立刻弯下腰去,开始在沙滩上挖掘起来。“咱们下水吧,” 她说。
“好吧,” 年轻人说。“我寻思我也能抽空去泡一会儿的。”
“下一回,得把她推开,” 阿比尔说。
“把谁推开?”
“沙伦 • 利普舒兹呀。”
“哦,沙伦 • 利普舒兹,” 那年轻人说。“这名字怎么起的。里面混合着回忆与欲望。” 他猛地站起身子,朝大海看去。“西比尔,” 他说,“我告诉你咱们干什幺好。看看咱们能不能逮到一条香蕉鱼①。”
“一条什么?”
“一条香蕉鱼呀,” 他说,同时解开了他浴衣的腰带,脱掉浴衣。他的肩膀又白又窄,他那条游泳裤是宝蓝色的。他折好他的浴袍,先是竖着对折,然后横里折成三叠。他把盖眼睛的毛巾展开,铺在沙滩上,然后把叠好的浴袍放在上面。他弯下身子,捡起气床,把它夹在右胳肢窝底下。接着又伸出左手去拉住西比尔的手。
这两个人开始朝海里走去。
“我猜你长这么大准见过不少香蕉鱼吧,” 年轻人说。
西比尔摇了摇头。
“你没见到过? 你是住在什么地方的,那么说?”
“我不知道。”
“你肯定知道。你必然知道。沙伦 • 利普舒兹知道她住在什么地方,而她只有三岁半。”
西比尔站住脚,猛地挣开被他拉住的手。她拾起一只普普通通的海滩上的皿壳,仔仔细细地察看着。她把吼壳扔掉,“是康涅狄格州的惠利森林,” 她说,又开始彳乇前走巾肚皮挺出在蛀前面。
“康涅狄格州的惠利森林,” 年轻人说。“这么说,你的家正好是在离康涅狱格州惠利森林不远的某个地方?”
西比尔看着他。“那正是我住的地方,” 她不耐烦地说。“我就住在康涅狄格州惠利森林。” 她跑了几步,把他甩在后面,用左手吊住左脚,单腿跳了两三步。
“你不知道这一来事情就变得非常清楚了,” 年轻人说。
西比尔放开了她的脚。“你看过《小黑人萨姆博》吗?” 她说。
“你问我这个太有意思了,” 他说。“巧得很,我昨天晚上刚看完。” 他怄下身去再谈捏住西比尔的手。“你觉得这书怎么样?” 他问小姑娘。
“那些老虎全绕着那棵树跑吗?”
“我认为它们从来没停下过。我从来没有见到过那么多老虎。”
“拢共只有六只呀,” 西比尔说。
“只有六只!” 年轻人说。“你还说是只有?”
“你喜欢蜡吗?” 西比尔闾道。
“我喜欢什么?” 年轻人问。
“蜡。”
“非常喜欢。你不喜欢吗?”
西比尔点点头。“你喜欢橄榄吗?” 她问。
“橄榄——喜欢的。橄榄和蜡。我不管什么时候走到哪里都要带上它们的。”
“你喜欢沙伦 • 利普舒兹吗?”
“是的。是的,我喜欢的,” 年轻人说。“我特别喜欢她的是她从不欺侮旅馆大厅里的小小狗。就拿那位加拿大太太的那只小型大头狗来说吧。你也许不会相信,但是有些小姑娘就喜欢用气球杆去戳弄它。沙伦不这么干。她从来不那么歹毒,那么不存好心,这就是我那么喜欢她的原因。”
西比尔不吱声了。
“我喜欢嚼蜡烛。” 最后她说。
“又有谁不喜欢呢?” 年轻人说,把脚泡湿了。“唷! 好冷呀。” 他把橡皮气床平扔到水里。“不,先等等,西比尔。咱们再走出去一点点。”
他们蹬着永往海里走,直到水没到了西比尔的腰。接着年轻人把她抱起,让她面朝下平躺在气床上。
“你从来也不戴游泳帽什么的吗?” 他问。
“别撒手,” 西比尔命令道。“你抓住我呀,喂。”
“卡彭特小姐。行了。我是懂行的,” 那年轻人说。“你就只管睁大眼睛看有没有香蕉鱼好了。今天可是逮香蕉鱼的最佳日子呀。”
“我没见到有鱼嘛,” 西比尔说。
“那是很自然的。它们的习性非常特别。” 他继续推着气床。水还没有没到他胸口。“它们过着一种非常悲惨的生活,” 他说,“你知道它们干什么吗,西比尔?”
小姑娘摇了摇头。
“嗯,它们游到一个洞里去,那儿有许多香蕉。它们游进去时还是样子很普通的鱼。可是它们一进了洞,就馋得跟猪一样了。嘿,我就知道有那么一些香蕉鱼,它们游进一个香蕉洞,居然吃了是是有七十八根香蕉。” 他推着气床和上面的乘客又往海平面前进了英尺。“自然,它们吃得太胖了,就再也没法从洞里出来了。连挤都挤不出洞口了。”
“别离岸太远了,” 西比尔说。“后来它们怎么样了?”
“后来谁怎么样了?”
“那些香焦龟呀。”
“哦,你是说吃了那么多香蕉出不,香蕉洞的那些鱼后来怎么了吗?”
“是啊,” 西比尔说。
“唉,我真不忍心告诉你,西比尔。它们死了。”
“为什么呢?” 西比尔问。
“哦,它们得了香蕉热。那是一种可怕的病。”
“有个浪头冲过来了,” 西比尔紧张地说。
“咱们不理它。咱们瞧不起它,’那年轻人说。“两个自以为了不起的人①。” 他双手捏住西比尔的两只脚腕,往下压也往前推。气床头一跷盖过了浪头。海水让西比尔的金发湿了个透,不过她的尖叫声里充满了欢乐。
气床重新平稳后,她用手把盖住双眼的一绺扁平的湿发撩开,报告说:“我刚才见到了一条。”
“见到什么啦,我的宝贝儿?”
“一条香蕉鱼呀。”
“我的天哪,真的吗!” 那年轻人说。“嘴里有香蕉吗?”
“有啊,” 西比尔说。“六根呢。”
年轻人突然抓起西比尔垂在气床外缘的一只湿漉漉的脚,亲了亲弓起的脚心。
“嗨!” 脚的主人转过身子来说。
“嗨什么嗨! 咱们该回去了。你玩够了吗。"
“还设呢!”
“对不起了,” 他说,把气床朝岸边推去一直到西比尔从上面爬下来。剩下的路他把气床抱在手里。
“再见,” 西比尔说,毫无遗憾地朝旅馆的方向跑去,
年轻人穿七浴袍,把翻领捏捏紧,把他的毛巾使劲塞进了口袋。他捡起湿滑沉重的气床,夹在胳膊底下。他独自踩着沉重的步子,穿过柔软、灼热的沙滩朝旅馆走去。
在旅馆专门让洗海水澡的人走的地下大厅里,一个鼻子上涂了含锌软膏的女人和年轻人一起进了电梯。
“我看到你是在瞧我的脚,” 电梯开动后他对那女的说。
“对不起,你说什么?” 那女的说。
“我说我看到你在瞧我的脚。”
“对不起。方才我是在看地板。” 那女的说,把脸转向电梯门。
“要是你想看我的脚,就直说好了,” 年轻人说。“别他蚂的这么鬼鬼祟祟的。”
“请让我出去,” 那女的急忙对开电梯的姑娘说。
电梯门开了,那女的头也不回地走了出去.
“我两只脚挺正常,褴他妈一丁点儿值得别人盯着看的,” 年轻人说。“五楼,劳驾。” 他从浴袍口袋里掏出钥匙。
他在五楼走出电梯,穿过走廊,进了 507 号。房间里一股新小牛皮箱子和洗甲水去除剂的气味。
他朝在一张单人床上睡着的姑娘瞥了一眼。然后他走到一件行李前,打开它,从一叠短裤、内衣底下抽出一把 765 口径的奥特基恩自动手枪。他退出弹夹,检查了一下,又重新塞回去。他扳上击铁。接着他走过去在空着的那张单人床上坐下,看看那个姑娘,把枪对准,开了一枪,子弹穿过了他右侧的太阳穴。
带上她的眼睛--刘慈欣
"""
工作了两个多月, 我实在累了,便请求主任给我两天假,出去短暂旅游一下散散心。主任答应了,条件是我再带一双眼睛去,我也答应了,于是他带我去拿眼睛。眼睛放在控制中心走廊尽头的一个小房间里,现在还剩下十几双。
主任递给我一双眼睛, 指指前面的大屏幕,把眼睛的主人介绍给我,是一个好象刚毕业的小姑娘, 呆呆地看着我。在肥大的太空服中,她更显得娇小,一副可怜兮兮的样子,显然刚刚体会到太空不是她在大学图书馆中想象的浪漫天堂,某些方面可能比地狱还稍差些。
"麻烦您了,真不好意思。她连连向我鞠躬,这是我听到过的最轻柔的声音,我想象着这声音从外太空飘来,象一阵微风吹过轨道上那些庞大粗陋的钢结构,使它们立刻变得象橡皮泥一样软。
"一点都不,我很高兴有个伴儿的。你想去那儿?"我豪爽地说。
"什么?您自己还没决定去哪儿?"她看上去很高兴。但我立刻感到两个异样的地方, 其一,地面与外太空通讯都有延时,即使在月球,延时也有两秒钟,小行星带延时更长,但她的回答几乎感觉不到延时,这就是说,她现在在近地轨道,那里回地面不用中转,费用和时间都不需多少,没必要托别人带眼睛去渡假。其二是她身上的太空服,做为航天个人装备工程师, 我觉得这种太空服很奇怪:在服装上看不到防辐射系统,放在她旁边的头盔的面罩上也没有强光防护系统;我还注意到,这套服装的隔热和冷却系统异常发达。
"她在哪个空间站?"我扭头问主任。
"先别问这个吧。"主任的脸色很阴沉.
"别问好吗?"屏幕上的她也说,还是那副让人心软的小可怜样儿。
"你不会是被关禁闭吧? "我开玩笑说,因为她所在的舱室十分窄小,显然是一个航行体的驾驶舱, 各种复杂的导航系统此起彼伏地闪烁着,但没有窗子,也没有观察屏幕,只有一支在她头顶打转的失重的铅笔说明她是在太空中。听了我的话,她和主任似乎都愣了一下, 我赶紧说:"好,我不问自己不该知道的事了,你还是决定我们去哪儿吧。
这个决定对她很艰难, 她的双手在太空服的手套里握在胸前,双眼半闭着,似乎是在决定生存还是死亡, 或者认为地球在我们这次短暂的旅行后就要爆炸了。我不由笑出声来。
"哦, 这对我来说不容易,您要是看过海伦.凯勒的<<三天所见>>的话,就能明白这多难了!"
"我们没有三天, 只有两天。在时间上,这个时代的人都是穷光蛋。但比那个二十世纪盲人的幸运的是,我和你的眼晴在三小时内可到达地球的仍何一个地方。"
"那就去我们起航前去过的地方吧!" 她告诉了我那个地方,于是我带着她的眼睛去了。
草原
这是高山与平原,草原与森林的交接处,距我工作的航天中心有两千多公里,乘电离层飞机用了15分钟就到了这儿。面前的塔克拉玛干,经过几代人的努力,已由沙漠变成了草原, 又经过几代强有力的人口控制,这儿再次变成了人迹罕至的地方。现在大草原从我面前一直延伸到天边,背后的天山覆盖着暗绿色的森林,几座山顶还有银色的雪冠。我掏出她的眼晴戴上。
所谓眼睛就是一付传感眼镜,当你戴上它时,你所看到的一切图象由超高频信息波发射出去,可以被远方的另一个戴同样传感眼镜的人接收到,于是他就能看到你所看到的一切,就象你带着他的眼睛一样。
现在,长年在月球和小行星带工作的人已有上百万,他们回地球渡假的费用是惊人的,于是吝啬的宇航局就设计了这玩艺儿,于是每个生活在外太空的宇航员在地球上都有了另一双眼睛, 由这里真正能去渡假的幸运儿带上这双眼睛,让身处外太空的那个思乡者分享他的快乐。这个小玩艺开始被当做笑柄, 但后来由于用它"渡假"的人能得到可观的补助, 竟流行开来。最尖端的技术被采用,这人造眼睛越做越精致, 现在,它竟能通过采集戴着它的人的脑电波,把他(她)的触觉和味觉一同发射出去。多带一双眼睛去渡假成了宇航系统地面工作人员从事的一项公益活动, 由于渡假中的隐私等原因,并不是每个人都乐意再带双眼睛,但我这次无所谓。
我对眼前的景色大发感叹,但从她的眼睛中,我听到了一阵轻轻的抽泣声。
"上次离开后, 我常梦到这里,现在回到梦里来了!"她细细的声音从她的眼睛中传出来,"我现在就象从很深很深的水底冲出来呼吸到空气,我太怕封闭了。
我从中真的听到她在做深呼吸。
我说:"可你现在并不封闭,同你周围的太空比起来,这草原太小了。"
她沉默了,似乎连呼吸都停止了。
"啊,当然,太空中的人还是封闭的,二十世纪的一个叫耶格尔的飞行员曾有一句话,是描述飞船中的宇航员的,说他们象......"
"罐头中的肉。"
我们都笑了起来。她突然惊叫:"呀,花儿,有花啊!上次我来时没有的!"是的,广阔的草原上到处点缀着星星点点的小花。"能近些看看那朵花吗?",我蹲下来看,"呀,真美耶!能闻闻她吗?不,别拔下她!",我只好半趴到地上闻,一缕淡淡的清香,"啊,我也闻到了,真象一首隐隐传来的小夜曲呢!"
我笑着摇摇头,这是一个闪电变幻疯狂追逐的时代,女孩子们都浮躁到了极点,
象这样的见花落泪的林妹妹真是太少了。
"我们给这朵小花起个名字好吗?嗯......叫她梦梦吧。我们再看看那一朵好吗? 他该叫什么呢? 嗯,叫小雨吧;再到那一朵那儿去,啊,谢谢,看她的淡蓝色,她的名字应该是月光......"
我们就这样一朵朵地看花, 闻花,然后再给它起名字。她陶醉于其中,没完没了地进行下去, 忘记了一切。我对这套小女孩的游戏实在厌烦了,到我坚持停止时,我们已给上百朵花起了名字。
一抬头, 我发现已走出了好远,便回去拿丢在后面的背包,当我拾起草地上的背包时, 又听到了她的惊叫:"天啊,你把小雪踩住了!"我扶起那朵白色的野花,觉得很可笑,就用两只手各捂住一朵小花,问她:"她们都叫什么?什么样儿?"
"左边那朵叫水晶, 也是白色的,它的茎上有分开的三片叶儿;右边那朵叫火苗, 粉红色,茎上有四片叶子,上面两片是单的,下面两片连在一起。"
她说的都对,我有些感动了。
"你看,我和她们都互相认识了,以后漫长的日子里,我会好多次一遍遍地想她们每一个的样儿,象背一本美丽的童话书。你那儿的世界真好!"
"我这儿的世界?要是你再这么孩子气地多愁善感下去,这也是你的世界了,那些挑剔的太空心理医生会让你永远呆在地球上。"
我在草原上无目标地漫步, 很快来到一条隐没在草丛中的小溪旁。我迈过去继续向前走,她叫住了我,说:"我真想把手伸到小河里。"我蹲下来把手伸进溪水,一股清凉流遍全身,她的眼睛用超高频信息波把这感觉传给远在太空中的她,我又听到了她的感叹。
"你那儿很热吧?"我想起了她那窄小的控制舱和隔热系统异常发达的太空服。
"热,热得象......地狱。呀,天啊,这是什么?草原的风?!"这时我刚把手从水中拿出来, 微风吹在湿手上凉丝丝的,"不,别动,这是真是天国的风呀!"我把双手举在草原的微风中, 直到手被吹干。然后应她的要求,我又把手在溪水中打湿,再举到风中把天国的感觉传给她。我们就这样又消磨了很长时间。
再次上路后,沉默地走了一段,她又轻轻地说:"你那儿的世界真好。"
我说:"我不知道,灰色的生活把我这方面的感觉都磨钝了。"
"怎么会呢?!这世界能给人多少感觉啊!谁要能说清这些感觉,就如同说清大雷雨有多少雨点一样。看天边那大团的白云,银白银白的,我这时觉得它们好象是固态的,象发光玉石构成的高山。下面的草原,这时倒象是气态的,好象所有的绿草都飞离了大地,成了一片绿色的云海。看!当那片云遮住太阳又飘开时,草原上光和影的变幻是多么气势磅薄啊!看看这些,您真的感受不到什么吗?"
......
我带着她的眼睛在草原上转了一天,她渴望地看草原上的每一朵野花,每一棵小草,看草丛中跃动的每一缕阳光,渴望地听草原上的每一种声音。一条突然出现的小溪,小溪中的一条小鱼,都会令她激动不已;一阵不期而至的微风,风中一缕绿草的清香都会让她落泪......我感到,她对这个世界的情感已丰富到病态的程度。
日落前,我走到了草原中一间孤伶伶的白色小屋,那是为旅游者准备的一间小旅店,似乎好久没人光顾了,只有一个迟钝的老式机器人照看着旅店里的一切。我又累又饿,可晚饭只吃到一半,她又提议我们立刻去看日落。
"看着晚霞渐渐消失,夜幕慢慢降临森林,就象在听一首宇宙间最美的交响曲。"
她陶醉地说。我暗暗叫苦,但还是拖着沉重的双腿去了。
草原的落日确实很美,但她对这种美倾泻的情感使这一切有了一种异样的色彩。
"你很珍视这些平凡的东西。"回去的路上我对她说,这时夜色已很重,星星已在夜空中出现。
"你为什么不呢,这才象在生活。"她说.
"我,还有其他的大部分人,不可能做到这样。在这个时代,得到太容易了。物质的东西自不必说, 蓝天绿水的优美环境、乡村和孤岛的宁静等等都可以毫不费力地得到;甚至以前人们认为最难寻觅的爱情,在虚拟现实网上至少也可以暂时体会到。所以人们不再珍视什么了,面对着一大堆伸手可得的水果,他们把拿起的每一个咬一口就扔掉。
"但也有人面前没有这些水果。"她低声说。
我感觉自己剌痛了她,但不知为什么。回去的路上,我们都没再说话。
这天夜里的梦境中,我看到了她,穿着太空服在那间小控制舱中,眼里含泪,向我伸出手来喊: "快带我出去,我怕封闭!"我惊醒了,发现她真在喊我,我是戴着她的眼睛仰躺着睡的。
"请带我出去好吗?我们去看月亮,月亮该升起来了!"
我脑袋发沉,迷迷糊糊很不情愿地起了床。到外面后发现月亮真的刚升起来,草原上的夜雾使它有些发红。月光下的草原也在沉睡, 有无数点萤火虫的幽光在朦朦胧胧的草海上浮动,仿佛是草原的梦在显形。
我伸了个懒腰, 对着夜空说:"喂,你是不是从轨道上看到月光照到这里?告诉我你的飞船的大概方位,说不定我还能看到呢,我肯定它是在近地轨道上。"
她没有回答我的话, 而是自己轻轻哼起了一首曲子,一小段旋律过后,她说:"这是德彪西的<<月光>>。"又接着哼下去,陶醉于其中,完全忘记了我的存在。<<月光>>的旋律同月光一起从太空降落到草原上。我想象着太空中的那个娇弱的女孩, 她的上方是银色的月球,下面是蓝色的地球,小小的她从中间飞过,把音乐溶入月光......
直到一个小时后我回去躺到床上,她还在哼着音乐,是不是德彪西的我就不知道了,那轻柔的乐声一直在我的梦中飘荡着。
不知过了多久,音乐变成了呼唤,她又叫醒了我,还要出去。
"你不是看过月亮了吗?!"我生气地说。
"可现在不一样了, 记得吗,刚才西边有云的,现在那些云可能飘过来了,现在月亮正在云中时隐时现呢,想想草原上的光和影,多美啊,那是另一种音乐了,求你带我的眼睛出去吧!"
我十分恼火, 但还是出去了。云真的飘过来了,月亮在云中穿行,草原上大块的光斑在缓缓浮动,如同大地深处浮现的远古的记忆。
"你象是来自十八世纪的多愁善感的诗人, 完全不适合这个时代,更不适合当宇 航员。"我对着夜空说, 然后摘下她的眼睛,挂到旁边一棵红柳的枝上,"你自己看月亮吧,我真的得睡觉去了,明天还要赶回航天中心,继续我那毫无诗意的生活呢。"
她的眼睛中传出了她细细的声音,我听不清说什么,径自回去了。
我醒来时天已大亮,阴云已布满了天空,草原笼罩在蒙蒙的小雨中。她的眼睛仍挂在红柳枝上,镜片上蒙上了一层水雾。我小心地擦干镜片,戴上它。原以为她看了一夜月亮,现在还在睡觉,却从眼睛中听到了她低低的抽泣声,我的心一下子软下来。
"真对不起,我昨天晚上实在太累了。"
"不,不是因为你,呜呜,天从三点半就阴了,五点多又下起雨.....。
"你一夜都没睡?!"
"......呜呜,下起雨,我,我看不到日出了,我好想看草原的日出,呜呜,好想看的,呜.....。
我的心象是被什么东西溶化了,脑海中出现她眼泪汪汪,小鼻子一抽一抽的样儿,眼睛竟有些湿润。不得不承认, 在过去的一天一夜里,她教会了我某种东西,一种说不清的东西, 象月夜中草原上的光影一样朦胧,由于它,以后我眼中的世界与以前会有些不同的。
"草原上总还会有日出的, 以后我一定会再带你的眼睛来,或者,带你本人来看, 好吗?"
她不哭了,突然,她低声说:
"听.....。"
我没听见什么,但紧张起来。
"这是今天的第一声鸟叫,雨中也有鸟呢!"她激动地说,那口气如同听到世纪钟声一样庄严。
落日六号
又回到了灰色的生活和忙碌的工作中,以上的经历很快就淡忘了。很长时间后,当我想起洗那些那次旅行时穿的衣服时,在裤脚上发现了两三棵草籽。同时,在我的意识深处,也有一棵小小的种子留了下来。在我孤独寂寞的精神沙漠中,那棵种子已长出了令人难以察觉的绿芽。虽然是无意识地,当一天的劳累结束后,我已能感觉到晚风吹到脸上时那淡淡的诗意,鸟儿的鸣叫已能引起我的注意,我甚至黄昏时站在天桥上,看着夜幕降临城市......世界在我的眼中仍是灰色的,但星星点点的嫩绿在其中出现,并在增多。当这种变化发展到让我觉察出来时,我又想起了她。也是无意识地, 在闲暇时甚至睡梦中,她身处的环境常在我的脑海中出现,那封闭窄小的控制舱, 奇怪的隔热太空服......后来这些东西在我的意识中都隐去了,只有一样东西凸现出来,这就是那在她头顶上打转的失重的铅笔,不知为什么,一闭上眼睛,这只铅笔总在我的眼前飘浮。终于有一天,上班时我走进航天中心高大的门厅,一幅见过无数次的巨大壁画把我吸引住了,壁画上是从太空中拍摄的蔚蓝色的地球。那只飘浮的铅笔又在我的眼前出现了,同壁画叠印在一起,我又听到了她的声音:
"我怕封闭....."一道闪电在我的脑海里出现。
除了太空,还有一个地方会失重!!
我发疯似地跑上楼,猛砸主任办公室的门,他不在,我心有灵犀地知道他在哪儿,就飞跑到存放眼睛的那个小房间, 他果然在里面,看着大屏幕。她在大屏幕上,还在那个封闭的控制舱中,穿着那件"太空服",画面凝固着,是以前录下来的。"是为了她来的吧。"主任说,眼睛还看着屏幕。
"她到底在哪儿?!"我大声问。
"你可能已经猜到了,她是'落日六号'的领航员。"
一切都明白了,我无力地跌坐在地毯上。
"落日工程"原计划发射十艘飞船,它们是"落日一号"到"落日十号",但计划由于"落日六号"的失事而中断了。 "落日工程"是一次标准的探险航行,它的航行程序同航天中心的其它航行几乎一样。
唯一不同的是,"落日"飞船不是飞向太空,而是潜入地球深处。
第一次太空飞行一个半世纪后,人类开始了向相反方向的探险,"落日"系列地航飞船就是这种探险的首次尝试。
四年前,我在电视中看到过"落日一号"发射时的情景。那时正是深夜,吐鲁番盆地的中央出现了一个如太阳般耀眼的火球, 火球的光芒使新疆夜空中的云层变成了绚丽的朝霞。当火球暗下来时,"落日一号"已潜入地层。大地被烧红了一大片,这片圆形的发着红光的区域中央, 是一个岩浆的湖泊,白热化的岩浆沸腾着,激起一根根雪亮的浪柱......那一夜,远至乌鲁木奇,都能感到飞船穿过地层时传到大地上的微微振动。
"落日工程"的前五艘飞船都成功地完成了地层航行,安全返回地面。其中"落日五号"创造了迄今为止人类在地层中航行深度的记录: 海平面下3100公里。"落日六号"不打算突破这个记录。因为据地球物理学家的结论,在地层3400-3500公里深处,存在着地幔和地核的交界面, 学术上把它叫做"古腾堡不连续面",一旦通过这个交界面, 便进入地球的液态铁镍核心,那里物质密度骤然增大,"落日六号"的设计强度是不允许在如此大的密度中航行的。
"落日六号"的航行开始很顺利, 飞船只用了两个小时便穿过了地表和地幔的交界面----莫霍不连续面,并在大陆板块漂移的滑动面上停留了五个小时,然后开始了在地幔中三千多公里的漫长航行。宇宙航行是寂寞的, 但宇航员们能看到无限的太空和壮丽的星群;而地航飞船上的地航员们,只能凭感觉触摸飞船周围不断向上移去的高密度物质。从飞船上的全息后视电视中能看到这样的情景: 炽热的岩浆剌目地闪亮着,翻滚着,随着飞船的下潜,在船尾飞快地合拢起来,瞬间充满了飞船通过的空间。有一名地航员回忆: 他们一闭上眼睛,就看到了飞快合拢并压下来的岩浆,这个幻象使航行者意识到压在他们上方那巨量的并不断增厚的物质, 一种地面上的人难以理解的压抑感折磨着地航飞船中的每一个人,他们都受到这种封闭恐惧症的袭击.
"落日六号"出色地完成着航行中的各项研究工作。飞船的速度大约是每小时15公里,飞船需要航行20小时才能到达预定深度。但在飞船航行15小时40分钟时,警报出现了。 从地层雷达的探测中得知, 航行区的物质密度由每立方厘米6.3克猛增到9.5克, 物质成份由硅酸盐类突然变为以铁镍为主的金属,物质状态也由固态变为液态。尽管"落日六号"当时只到达了2500公里的深度,目前所有的迹象却冷酷地表明,他们闯入了地核! 后来得知,这是地幔中一条通向地核的裂隙,地核中的高压液态铁镍充满了这条裂隙,使得在"落日六号"的航线上,古腾堡不连续面向上延伸了近1000公里!飞船立刻紧急转向,企图冲出这条裂隙,不幸就在这时发生了:由中子材料制造的船体顶住了突然增加到每平方厘米1600吨的巨大压力,但是,飞船分为前部烧熔发动机、中部主舱和后部推进发动机三大部分, 当飞船在远大于设计密度和设计压力的液态铁镍中转向时,烧熔发动机与主舱结合部断裂,从"落日六号"用中微子通讯发回的画面中我们看到, 已与船体分离的烧熔发动机在一瞬间被发着暗红光的液态铁镍吞没了。地层飞船的烧熔发动机用超高温射流为飞船切开航行方向的物质, 没有它, 只剩下一台推进发动机的"落日六号"在地层中是寸步难行的。地核的密度很惊人, 但构成飞船的中子材料密度更大,液态铁镍对飞船产生的浮力小于它的自重,于是,"落日六号"便向地心沉下去。
人类登月后,用了一个半世纪才有能力航行到土星。在地层探险方面,人类也要用同样的时间才有能力从地幔航行到地核。现在的地航飞船误入地核, 就如同二十世纪中期的登月飞船偏离月球迷失于外太空,获救的希望是丝毫不存在的。
好在"落日六号"主舱的船体是可靠的, 船上的中微子通讯系统仍和地面控制中心保持着完好的联系。以后的一年中,"落日六号"航行组坚持工作,把从地核中得到了大量宝贵资料发送到地面。他们被裹在几千公里厚的物质中, 这里别说空气和生命, 连空间都没有,周围是温度高达五千度,压力可以把碳在一秒钟内变成金钢石的液态铁镍! 它们密密地挤在"落日六号"的周围,密得只有中微子才能穿过,"落日六号"是处于一个巨大的炼钢炉中! 在这样的世界里,<<神曲>>中的<<地狱篇>>像是在描写天堂了;在这样的世界里,生命算什么?仅仅能用脆弱来描写它吗?
沉重的心理压力象毒蛇一样撕裂着"落日六号"地航员们的神经。一天, 船上的地质工程师从睡梦中突然跃起,竟打开了他所在的密封舱的绝热门!虽然这只是四道绝热门中的第一道, 但瞬间涌入的热浪立刻把他烧成了一段木炭。指令长在一个密封舱飞快地关上了绝热门,避免了"落日六号"的彻底毁灭。他自己被严重烧伤,在写完最后一页航行日志后死去了。
从那以后,在这个星球的最深处,在"落日六号"上,只剩下她一个人了。
现在,"落日六号"内部已完全处于失重状态,飞船已下沉到6800公里深处,那里是地球的最深处,她是第一个到达地心的人。
她在地心的世界是那个活动范围不到10平方米的闷热的控制舱。飞船上有一个中微子传感眼镜, 这个装置使她同地面世界多少保持着一些感性的联系。但这种如同生命线的联系不能长时间延续下去,飞船里中微子通讯设备的能量很快就要耗尽,现有的能量已不能维持传感眼镜的超高速数据传输,这种联系在三个月前就中断了,具体时间是在我从草原返回航天中心的飞机上, 当时我已把她的眼晴摘下来放到旅行包中。
那个没有日出的细雨蒙蒙的草原早晨,竟是她最后看到的地面世界。
后来"落日六号"同地面只能保持着语音和数据通讯,而这个联系也在一天深夜中断了,她被永远孤独地封闭于地心中。
"落日六号"的中子材料外壳足以抵抗地心的巨大压力, 而飞船上的生命循环系统还可以运行五十至八十年,她将在这不到10平方米的地心世界里渡过自己的余生。
我不敢想象她同地面世界最后告别的情形,但主任让我听的录音出乎我的意料。
这时来自地心的中微子波束已很弱,她的声音时断时续,但这声音很平静。
"...... 你们发来的最后一份补充建议已经收到,今后,我会按照整个研究计划努力工作的。将来,可能是几代人以后吧,也许会有地心飞船找到'落日六号'并同它对接, 有人会再次进入这里,但愿那时我留下的资料会有用。请你们放心,我会在这里安排好自己生活的。我现在已适应这里,不再觉得狭窄和封闭了,整个世界都围着我呀,我闭上眼睛就能看见上面的大草原,还可以清楚地看见每一朵我起了名字的小花呢。再见。"
透明地球
在以后的岁月中,我到过很多地方,每到一个处,我都喜欢躺在那里的大地上。我曾经躺在海南岛的海滩上、阿拉斯加的冰雪上、俄罗斯的白桦林中、撒哈拉烫人的沙漠上. .....每到那个时刻,地球在我脑海中就变得透明了,在我下面六千多公里深处, 在这巨大的水晶球中心,我看到了停汨在那里的"落日六号"地航飞船,感受到了从几千公里深的地球中心传出的她的心跳。我想象着金色的阳光和银色的月光透射到这个星球的中心,我听到了那里传出的她吟唱的<<月光>>,还听到她那轻柔的话音:
"......多美啊,这又是另一种音乐了.....。。
有一个想法安慰着我:不管走到天涯海角,我离她都不会再远了
"""
道德与小说- D.H.劳伦斯
========================
道德与小说- [[D.H.劳伦斯]]
-----
艺术的任务是展现人与其周围世界在活生生之时的关系。人类总在旧的恢恢关系网中挣扎,“时代”离活生生之时要久远得多,而艺术却总是超前于“时代”的。
当梵·高57绘向日葵时,他揭示的或获得的是一瞬间作为一个人的他与作为向日葵的向日葵之间的活的关系。他的绘画压根儿不是再现向日葵本身。我们永远也弄不清向日葵自身是个什么物件。而照相机可以比梵·高干得完美得多,它可以照下完美的视觉形象来,梵·高则差远了。
画布上的视觉现象是全然不可捉摸、难以言表的第三者——不是那向日葵,也不是梵·高,而是这两者结合的产物。画布上的视觉形象与画布、颜料、作为人的有机体的梵·高以及作为植物有机体的向日葵永远不可同日而语。你无法衡量甚至无法描述画布上的视觉形象。这视觉形象,说实在的,只存在于大有争议的所谓第四维空间58中。在可度量的空间中它是不存在的。
这是在某一时刻一个人与一朵向日葵之间完美关系的展现。它既不是镜中人也非镜中花,它不在任何东西之上下,也不横跨什么东西。它在一切东西之间,在第四维空间中。
对人类来说,这种人与其周围世界之间的完美关系就是人类的生命本身。它具有永恒与完美这种四维空间的性质。但是它是倏忽即逝的。
人与向日葵在形成新的关系的那一刻就双双失去了自身。一切事物之间的关系都在悄然变化中一天天地变化着。因此,那揭示或获得另一种完美关系的艺术将永远是崭新的。
同理,那些存在于纯关系的不可度量空间中的东西是无所谓死也无所谓生的,是永恒的。这就是说,它给予我们一种超越生与死的感觉。我们说一头亚述国59的狮子或一头埃及苍鹰头还“活着”,我们这话的真正意思是它超越了生命,因此也就超越了死亡。它给我们的就是那种感觉。既然一头亚述国的狮子和埃及的鹰头给我们的感觉是无限珍贵,这说明我们内心深处也一定有什么东西是超越生与死的,它就如同天上那点燃夜与昼的星辰一样自有史以来就一直是对人类宝贵的东西。
思量一下,我们会发现我们的生命就寓于我们自己和周围活生生世界的纯粹关系的形成之中。我就是通过如下途径“拯救我的灵魂”的:完善我与另一个人、别人、一个民族、一个种族、动物、盛开鲜花的树、土地、天空、太阳、星星和月亮之间纯粹的关系。这是无数纯粹的关系,或大或小,就像天上的星星一样数也数不清。就是这种关系使我们永恒——我们每一个人,我和我正锯着的木头,我所服从的力量,我和我手中揉着的做面包的面团,我和我书写时的这个动作及我和我所有的这一点金子。这个,如果我们懂得它的话,就是我们的生命和我们的永恒——我与我周围全部世界之间微妙而完美的关系。
而道德就是我与周围世界之间永远微微颤动和变化着的天平,这天平先于一种真正的关系而存在,同时也伴随着这种关系。
现在我们看出小说之美及其伟大价值何在了吧。哲学、宗教和科学都忙于把事物固定住,以求获得一种稳定的平衡。宗教只有一个在说“你应该,你不应该”的上帝,每次他都斩钉截铁。哲学的概念是固定的;科学有自己的“定律”。这些东西总是想把我们钉在这棵或那棵树上才罢休。
可小说却不这样。小说是人类迄今发现的细微内在联系的集大成者。任何东西只要是在自身的时间、地点和环境中就是真实的,否则就是虚假的。如果你想在小说中把什么钉住,那么,不是你把小说给害了就是小说自己站起来带着这枚钉子一走了之。
小说中的道德是颤动不稳的天平。一旦小说家把手指按在天平上按自己的偏向意愿改变其平衡,这就是不道德了。
现代小说似越变越不道德了,因为小说家正趋于把手指愈来愈有力地压在天平上:不是偏向纯粹的爱就是偏向于无法无天的“自由”。
当然,一般来说小说并不因小说家有任何明显的观点或目的而显得不道德。所谓不道德指的是小说家不能自持的、无意识的偏向。爱本来是一种很伟大的情绪,可当你写起小说来沉溺于对爱的偏向,把爱当成最高的、唯一值得为其而活的情感来写,那你就会写出一部不道德的小说来。
这是因为,没有哪种情感是至高无上、唯一值得让人视同生命的。全部的情感都用于获得一个人与他人、他物、他事之间的活生生关系上。
全部的情感,包括爱和恨、怒与柔,都用于调整两个颇有价值的人之间频频振荡不定的天平。如果小说家把手指压在天平上,偏向爱、柔情、甜蜜、淡雅,他于是就犯了一个道德错误——他阻碍了纯粹关系与联系这最重要事物的可能性。而一旦他抬起手,就不可避免地造成可怕的反作用——走向仇恨、野蛮、残酷和毁灭。
生活就是如此,相反的东西在一个震颤的天平中心上摇摆着。父亲犯下的罪会使儿子得到惩罚60。如果父辈把天平压向爱、淡雅和创造,到了第三、第四代人那里,天平会剧烈地倒向仇恨、愤怒和毁灭。我们必须随时调整自己才对。
在各种艺术形式中,数小说最需要天平的颤抖了。“甜蜜”的小说愈是作假就愈是不道德,相比之下,倒是那些刺激性情节的小说更道德些。
那些写得精明但又说不清道不明外加玩世不恭的小说也是一样,在这些小说中你尽可以为所欲为,怎么着都无甚关系,因为作者认为做什么都一样。照这说法,卖淫也同其他东西一样是“生命”。
这说法全然不着边际。一件事并不因为有人为之就成为生命。艺术家应该明白这一点才对。一个普通的银行职员买了一顶新草帽,这根本不是什么“生命”,只是一种存在罢了,就如同每日三餐,但并非是“生命”。
所谓生命指的是某种闪烁着的具有第四空间性质的东西,如果那银行职员确实为他的帽子感到高兴,与帽子之间建立起了一种活生生的关系,头戴草帽走出商店时跟换了个人似的神采奕奕,那么这就是生命。
妓女也是一样。如果一个男人与她之间建立起了活生生的关系,哪怕只是一瞬间,这也是生命。反之,如果他们之间只是金钱和行为的关系,那么这关系就算不得生命,只能称之为肮脏,是背叛生命。
如果一部小说揭示的是真实而生动的关系,不管是什么样的关系,这部小说就算得上一部道德作品。如果小说家尊重这种关系,他的小说就会成为一部伟大的小说。
有不少关系就不真实。比如《罪与罚》中那年轻小伙子61为了六个便士而杀死了一位老妇人,尽管这事情很实在,可它永远也不会让人觉得真切。杀人者与老妇人之间的关系天平全无平衡可言,简直一团糟。它是实事儿,可它永远也算不上是“生命”。
在另一方面,通俗小说则不过是在炒剩饭,把旧的关系翻新花样儿,如《如果冬天将至》那样62。这种换汤不换药的做法也是不道德的。甚至大画家拉斐尔也不过是给旧的经验穿上新的美丽衣裳。这种做法只能让芸芸众生得到一种暴食暴饮的痛快感:纵情于声色。几个世纪以来男人们都把他们心目中理想的肉感女人称作:“她是拉斐尔笔下的圣母。”而女人们呢,她们只把这当成是对她们的一种污辱而已。
要获得一种新的关系是痛苦的,永远会是如此痛苦的。所以生命永远会使人痛苦,因为真正的肉欲放纵在于重演旧的关系,至多只能获得一种酗酒后的快感,这不免有点堕落之嫌。
每次我们欲与某人某事结成一种新的关系时总是要痛苦的。因为这意味着与旧的联系作斗争,要取代旧的,这永远不会是件愉快的事。再说,在活生生的事物之中要做出调整亦意味着各自的斗争,这是不可避免的,因为斗争的双方都要在对方中“寻到自己的自我”,通过寻找自我而否定自我从而达到协调。一旦双方要寻找绝对的自我,这种斗争将会导致死亡。所谓“激情”就是这东西。另一方面,当一方彻底屈从于另一方时,这是一种牺牲,其实也是一种死亡。所以,那《永恒的仙女》63只永恒了十八个月就死了。
这些仙女是水性杨花的,但她们本来应该是固守本分的。至于男人,接受她们的牺牲是不够男子气的做法,男人应该做一个男子汉。
还有第三种选择,这既不是牺牲也不是战死,而是各自寻求与对方结成真正的关系。为此,每个人都要对自己诚实,固守自我,让这种关系自然而然地形成。这首先需要勇气,其次需要原则。既有勇气承认自己的生命冲动,也勇于接受别人的生命喷薄。所谓原则,就是不要强行超越自我。而一旦超越了自己,就要勇于承认事实,而不要为此抱怨。
很明显,读一本全新的小说总是要令人感到创痛的——不同程度上的创痛。总会有抵抗力在作祟。这正如同看新绘画,听新音乐。你尽可以通过这些新东西所激起的阻抗力和最终被迫认可它们的程度来估量它们的真实。
对人类来讲,最伟大的关系不外乎就是男女间的关系了。至于男人与男人、女人与女人、父母与子女之间的关系则次之。
而男女间的关系永远是变化着的,永远是通往人类生活的新的中心线索。这里的关键是关系本身,而非男人、女人及男女关系的偶然结果——孩子。
你若想给男女之间的关系贴上标签使其维持现状,这做法会是徒劳的,没门儿。你倒不如给彩虹或雨水贴上标签试试看。
说到爱的约束,最好是一感到它约束得发痛就弃之。如果说男女一定要相爱,真是荒谬之至。男人和女人永远是微妙而又在变化中联系在一起的,没必要用什么“契约”把他们约束在一起。最道德的事就是让男人忠于自己的男子汉之道,女人忠于自己的女人之道,从而让男女间的关系自然而然地形成。因为,对各自双方来说这都是生命。
如果我们讲道德,那么我们就不要给什么都钉上钉子,既不要把双方钉在一起也不要钉第三方即双方的关系,这种关系永远是我们各自的魔鬼。每个十字架上钉人都需要五枚钉子,四根短的,一根长的,每一根都很可怕。可是一旦你试图把这种关系钉住并在上面书写“爱”而不是“这是犹太人之王”,你就会没完没了地到处去钉钉子。甚至基督都称之为“圣灵”,那意思是说你是无法诱惑它的,它是神圣的。
小说是揭示我们活生生关系变化之虹的最佳手段。小说可以帮助我们生活,而别的东西就做不到这一点,反正经文是做不到这一点的。当然,这要求小说家不要在天平上施加压力。
一旦小说家把手指按在天平上施加压力,他就篡改了男人与女人,只能与那伤感小曲如《善良之光引路》64之类的恶作剧相媲美,这类东西只能帮倒忙,腐蚀这一代人的骨髓。
(1925年夏天,劳伦斯从墨西哥回到自己在美国新墨西哥州的农场养病。这时他已经确诊患有肺结核,等于被判了死刑,因为在没有抗生素的年代肺结核被视为绝症。但他还是带病修改了长篇小说《羽蛇》,并完成了话剧《大卫》的剧本。他感到必须思考一下小说与道德的关系,就写了《道德与小说》、《关于小说》这两篇文艺随笔,都是先在美国发表的。)
道士塔- 余秋雨
========================
道士塔- [[余秋雨]]
-------
一
莫高窟大门外,有一条河,过河有一溜空地,高高低低建着几座僧人圆寂塔。塔呈圆形,状近葫芦,外敷白色。从几座坍弛的来看,塔心竖一木桩,四周以黄泥塑成,基座垒以青砖。历来住持莫高窟的僧侣都不富裕,从这里也可找见证明。夕阳西下,朔风凛冽,这个破落的塔群更显得悲凉。
有一座塔,由于修建年代较近,保存得较为完整。塔身有碑文,移步读去,猛然一惊,它的主人,竟然就是那个王圆箓!
历史已有记载,他是敦煌石窟的罪人。
我见过他的照片,穿着土布棉衣,目光呆滞,畏畏缩缩,是那个时代到处可以遇见的一个中国平民。他原是湖北麻城的农民,逃荒到甘肃,做了道士。几经转折,不幸由他当了莫高窟的家,把持着中国古代最灿烂的文化。他从外国冒险家手里接过极少的钱财,让他们把难以计数的敦煌文物一箱箱运走。今天,敦煌研究院的专家们只得一次次屈辱地从外国博物馆买取敦煌文献的微缩胶卷,叹息一声,走到放大机前。
完全可以把愤怒的洪水向他倾泄。但是,他太卑微,太渺小,太愚昧,最大的倾泄也只是对牛弹琴,换得一个漠然的表情。让他这具无知的躯体全然肩起这笔文化重债,连我们也会觉得无聊。
这是一个巨大的民族悲剧。王道士只是这出悲剧中错步上前的小丑。一位年轻诗人写道,那天傍晚,当冒险家斯坦因装满箱子的一队牛车正要启程,他回头看了一眼西天凄艳的晚霞。那里,一个古老民族的伤口在滴血。
二
真不知道一个堂堂佛教圣地,怎么会让一个道士来看管。中国的文官都到哪里去了,他们滔滔的奏摺怎么从不提一句敦煌的事由?
其时已是20世纪初年,欧美的艺术家正在酝酿着新世纪的突破。罗丹正在他的工作室里雕塑,雷诺阿、德加、塞尚已处于创作晚期,马奈早就展出过他的《草地上的午餐》。他们中有人已向东方艺术投来歆羡的目光,而敦煌艺术,正在王道士手上。
王道士每天起得很早,喜欢到洞窟里转转,就像一个老农,看看他的宅院。他对洞窟里的壁画有点不满,暗乎乎的,看着有点眼花。亮堂一点多好呢,他找了两个帮手,拎来一桶石灰。草扎的刷子装上一个长把,在石灰桶里蘸一蘸,开始他的粉刷。第一遍石灰刷得太薄,五颜六色还隐隐显现,农民做事就讲个认真,他再细细刷上第二遍。这儿空气干燥,一会儿石灰已经干透。什么也没有了,唐代的笑容,宋代的衣冠,洞中成了一片净白。道士擦了一把汗憨厚地一笑,顺便打听了一下石灰的市价。他算来算去,觉得暂时没有必要把更多的洞窟刷白,就刷这几个吧,他达观地放下了刷把。
当几面洞壁全都刷白,中座的塑雕就显得过分惹眼。在一个干干净净的农舍里,她们婀娜的体态过于招摇,她们柔美的浅笑有点尴尬。道士想起了自己的身份,一个道士,何不在这里搞上几个天师、灵官菩萨?他吩咐帮手去借几个铁锤,让原先几座塑雕委屈一下。事情干得不赖,才几下,婀娜的体态变成碎片,柔美的浅笑变成了泥巴。听说邻村有几个泥匠,请了来,拌点泥,开始堆塑他的天师和灵官。泥匠说从没干过这种活计,道士安慰道,不妨,有那点意思就成。于是,像顽童堆造雪人,这里是鼻子,这里是手脚,总算也能稳稳坐住。行了,再拿石灰,把它们刷白。画一双眼,还有胡子,像模像样。道士吐了一口气,谢过几个泥匠,再作下一步筹划。
今天我走进这几个洞窟,对着惨白的墙壁、惨白的怪像,脑中也是一片惨白。我几乎不会言动,眼前直晃动着那些刷把和铁锤。“住手!”我在心底痛苦地呼喊,只见王道士转过脸来,满眼困惑不解。是啊,他在整理他的宅院,闲人何必喧哗?我甚至想向他跪下,低声求他:“请等一等,等一等……”但是等什么呢?我脑中依然一片惨白。
三
1900年5月26日清晨,王道士依然早起,辛辛苦苦地清除着一个洞窟中的积沙。没想到墙壁一震,裂开一条缝,里边似乎还有一个隐藏的洞穴。王道士有点奇怪,急忙把洞穴打开,嗬,满满实实一洞的古物!
王道士完全不能明白,这天早晨,他打开了一扇轰动世界的门户。一门永久性的学问,将靠着这个洞穴建立。无数才华横溢的学者,将为这个洞穴耗尽终生。中国的荣耀和耻辱,将由这个洞穴吞吐。
现在,他正衔着旱烟管,扒在洞窟里随手捡翻。他当然看不懂这些东西,只觉得事情有点蹊跷。为何正好我在这儿时墙壁裂缝了呢?或许是神对我的酬劳。趁下次到县城,捡了几个经卷给县长看看,顺便说说这桩奇事。
县长是个文官,稍稍掂出了事情的分量。不久甘肃学台叶炽昌也知道了,他是金石学家,懂得洞窟的价值,建议藩台把这些文物运到省城保管。但是东西很多,运费不低,官僚们又犹豫了。只有王道士一次次随手取一点出来的文物,在官场上送来送去。
中国是穷。但只要看看这些官僚豪华的生活排场,就知道绝不会穷到筹不出这笔运费。中国官员也不是都没有学问,他们也已在窗明几净的书房里翻动出土经卷,推测着书写朝代了。但他们没有那副赤肠,下个决心,把祖国的遗产好好保护一下。
他们文雅地摸着胡须,吩咐手下:“什么时候,叫那个道士再送几件来!”已得的几件,包装一下,算是送给哪位京官的生日礼品。
就在这时,欧美的学者、汉学家、考古家、冒险家,却不远万里,风餐露宿,朝敦煌赶来。他们愿意变卖掉自己的全部财产,充作偷运一两件文物回去的路费。他们愿意吃苦,愿意冒着葬身沙漠的危险,甚至作好了被打、被杀的准备,朝这个刚刚打开的洞窟赶来。他们在沙漠里燃起了股股炊烟,而中国官员的客厅里,也正茶香缕缕。
没有任何关卡,没有任何手续,外国人直接走到了那个洞窟跟前。洞窟砌了一道砖、上了一把锁,钥匙挂在王道士的裤腰带上。外国人未免有点遗憾,他们万里冲刺的最后一站,没有遇到森严的文物保护官邸,没有碰见冷漠的博物馆馆长,甚至没有遇到看守和门卫,一切的一切,竟是这个肮脏的土道士。他们只得幽默地耸耸肩。
略略交谈几句,就知道了道士的品位。原先设想好的种种方案纯属多余,道士要的只是一笔最轻松的小买卖。就像用两枚针换一只鸡,一颗钮扣换一篮青菜。要详细地复述这笔交换账,也许我的笔会不太沉稳,我只能简略地说:“1905年10月,俄国人勃奥鲁切夫用一点点随身带着的俄国商品,换取了一大批文书经卷;1907年5月,匈牙利人斯坦因用一叠子银元换取了24大箱经卷、5箱织绢和绘画;1908年7月,法国人伯希和又用少量银元换去了10大车、6000多卷写本和画卷;1911年10月,日本人吉川小一郎和橘瑞超用难以想象的低价换取了300多卷写本和两尊唐塑;1914年,斯坦因第二次又来,仍用一点银元换去了5大箱、600多卷经卷……”
道士也有过犹豫,怕这样会得罪了神。解除这种犹豫十分简单,那个斯坦因就哄他说,自己十分崇拜唐僧,这次是倒溯着唐僧的脚印,从印度到中国取经来了。好,既然是洋唐僧,那就取走吧,王道士爽快地打开了门。这里不用任何外交辞令,只需要几句现编的童话。
一箱子,又一箱子。一大车,又一大车。都装好了,扎紧了,吁——,车队出发了。
没有走向省城,因为老爷早就说过,没有运费。好吧,那就运到伦敦,运到巴黎,运到彼得堡,运到东京。
王道士频频点头,深深鞠躬,还送出一程。他恭敬地称斯坦因为“司大人讳代诺”,称伯希和为“贝大人讳希和”。他的口袋里有了一些沉甸甸的银元,这是平常化缘时很难得到的。他依依惜别,感谢司大人、贝大人的“布施”。车队已经驶远,他还站在路口。沙漠上,两道深深的车辙。
斯坦因他们回到国外,受到了热烈的欢迎。他们的学术报告和探险报告,时时激起如雷的掌声。他们的叙述中常常提到古怪的王道士,让外国听众感到,从这么一个蠢人手中抢救出这笔遗产,是多么重要。他们不断暗示,是他们的长途跋涉,使敦煌文献从黑暗走向光明。
他们都是富有实干精神的学者,在学术上,我可以佩服他们。但是,他们的论述中遗忘了一些极基本的前提。出来辩驳为时已晚,我心头只是浮现出一个当代中国青年的几行诗句,那是他写给火烧圆明园的额尔金勋爵的:
我好恨
恨我没早生一个世纪
使我能与你对视着站立在
阴森幽暗的古堡
晨光微露的旷野
要么我拾起你扔下的白手套
要么你接住我甩过去的剑
要么你我各乘一匹战马
远远离开遮天的帅旗
离开如云的战阵
决胜负于城下
对于这批学者,这些诗句或许太硬。但我确实想用这种方式,拦住他们的车队。对视着,站立在沙漠里。他们会说,你们无力研究;那么好,先找一个地方,坐下来,比比学问高低。什么都成,就是不能这么悄悄地运走祖先给我们的遗赠。
我不禁又叹息了,要是车队果真被我拦下来了,然后怎么办呢?我只得送缴当时的京城,运费姑且不计。但当时,洞窟文献不是确也有一批送京的吗?其情景是,没装木箱,只用席子乱捆,沿途官员伸手进去就取走一把,在哪儿歇脚又得留下几捆,结果,到京城时已零零落落,不成样子。
偌大的中国,竟存不下几卷经文!比之于被官员大量糟践的情景,我有时甚至想狠心说一句:宁肯存放在伦敦博物馆里!这句话终究说得不太舒心。被我拦住的车队,究竟应该驶向哪里?这里也难,那里也难,我只能让它停驻在沙漠里,然后大哭一场。
我好恨!
四
不止是我在恨。敦煌研究院的专家们,比我恨得还狠。他们不愿意抒发感情,只是铁板着脸,一钻几十年,研究敦煌文献。文献的胶卷可以从外国买来,越是屈辱越是加紧钻研。
我去时,一次敦煌学国际学术讨论会正在莫高窟举行。几天会罢,一位日本学者用沉重的声调作了一个说明:“我想纠正一个过去的说法。这几年的成果已经表明,敦煌在中国,敦煌学也在中国!”
中国的专家没有太大的激动,他们默默地离开了会场,走过王道士的圆寂塔前。
# 德 - 杜米埃史密斯的蓝色时期
[[塞林格]]
-----
假如这样做确实有任何意义――其实它连开始有点儿意义都还没有――我想,我可能会以此篇拙作――不管它有多少价值,特别是它在某些段落上是否稍稍有点粗鄙,来纪念我那位已故的粗鄙的后父罗伯特 • 艾加德加尼安,人称小博比,连我也这么叫他――他于 1947 年死于血栓,死时他肯定会怀着些许悔恨,却不会有丝毫怨恨。他是一个有冒险精神, 极具魅力又豪爽大方的人。(在多年费尽心机有意避免对他使用这类带传奇色彩的形容词之后,我现在觉得在这里倒是非用不可了。)
我的母亲和父亲是 1928 年冬天离婚的,当时我八岁,那年暮春,母亲和博比 • 艾加德加尼安结了婚。一年以后,博比在华尔街大崩溃中失去了他和母亲所有的一切,看来剩下的只是一根魔杖了。总之,几乎是一夜之间,博比把自己从一个已经完蛋的证券经纪人和再也乐不起来的 bonviant(法语,十是的乐天派)变成独立的美国画廊和美术馆联合会的一个活跃,虽然多少有些不称职的经纪人兼鉴定师。几星期后,也就是 1930 年初,我们这三人一组的 “混成旅” 从纽约迁居到巴黎,这地方对博比开展他的新业务更为有利:当时我十岁,崇尚冷酷(虽然还没修炼到心如铁石的地步),因此对这次远行丝毫不以为意。倒是九年后我母亲去世三个月之后重新搬回纽约,却使我受到很大打击,令我简直不知所措。
我还记得就在博比和我抵达纽约一两天后所发生的一什挺有意思的事。当时我正在一辆拥挤不堪的沿莱克星顿大街走的公共汽车里站着,手捏着紧挨司机座的搪瓷面立柱,跟身后那家伙屁股顶着屁股。车子开过几个街区司机都不断对我们这些挤在前门附近的乘客发出一个简短的命令:“挪挪窝哎,车后尾空地有的是。”有人稍稍动了动,有的则根本不动。最后,前面红灯亮起给了司机一个机会,这个不胜其烦的人在座位上转过身来朝上盯看我,我就在他的身后。我那时十九岁,属于不爱戴帽子的那类,留了个欧式大背头,平直的黑头发不特别干净,脑门往前鼓出是是有一英寸之多。司机是用压低的、几乎是小心翼翼的声音。“怎么样,兄弟,”他说,“把那屁股挪一挪行不。”我寻思,是 “兄弟” 那个词把我惹火的。连身子都不屑稍稍弯下一些——那样就可以至少把谈话,像他方才那样,维持在一种私下的以及 debo(法语:趣味高雅)的水平上——我用法语告诉他,他是个粗野、愚蠢、蛮横的大笨蛋,他不知道我是多么的恨他。说完,我得意扬扬地朝车尾走去。
事情发展下去变得越来越糟了。方才这事之后的一个来星期左右,一天下午,我从博比和我无限期住着的里兹旅馆出门,我仿佛觉得全纽约所有公共汽车上的座椅全给卸了下来,搬出来并且安到了大街上,这儿正如火如荼地进行着一场规模极其巨大的抢座位游。我寻思我也许会愿意参加游戏的,倘若曼哈顿教堂作出特许.保证在我坐下之前所有别的游戏参加者都毕恭毕敬地站着的话。等我弄清楚这样的事绝不可能发生后,我便采取了更为直截了当的行动。我祈求这个城市能把人口清除掉一些,祈求我能享受独身自处的福分——让一我一个人呆会儿呀:这正是那句几乎随时随地都可听到而且传递起来从不被耽误的纽约人的祈祷语,于是,顿时,我所接触到的一切就变成了坚不可摧的死寂。每天上午和下午前半段,我都得到第 48 街和莱克星顿大街口一所美术学校去一自己本人得去——上课,这真让我觉得烦透了。(就在博比和我离开巴黎前的那一个星期里,我在弗雷伯格画廊举办的全国少年画展上拿到过三个一等奖呢。在返美航程中,我总用房舱的镜子来观察我与艾尔 • 格列柯形象上怪异的相似之处。)一星期三个后半下午,我又得去坐在牙医座椅上,在那上面几个月里我被拔掉八颗牙,其中三颗是门牙。一周剩下的那两个下午,我通常在各个美术画廊里打发时间,它们大都开殴在第 47 大街上,我在那里就差没嘘那些美国展品了。晚上我一般都用在读书上面。我买了完整的一套 “哈佛经典丛书-主要是因为博比说咱们套间里没地儿放这些东西——我还存心闹别扭把整套五十本书全念完了。深夜,我几乎一天不落地在我和博比共住的那间房里两张单人床之间支起画架,大画特画。根据我 1939 年的日记,单单一个月里我就完成了十八幅油画。很值得注意的是,其中的十七幅都是自画像。但是有时候,那也许是因为我的文艺女神忽然异想天开了,我竟撂下油画画起漫画来。其中的一幅我仍然保存着。上面显示出一张深邃的大嘴,是一个人在让牙医治病。那人的舌头干脆就是一张? 百元的美国国库券,而牙医在用法语伤心地对他说:“我着那颗臼齿还能保住,可是舌头怕是非拿掉不可了。” 这要算是我非常心爱的一幅作品了。
博比和我同住一室,我们的关系多多少少相当于,这么说吧,一个特别主张 “自己活也让别人活” 的哈佛高年级生跟一个特别不招人喜欢的剑桥报童之间会出现的那种关系。几个星期后,当我们逐渐发现我们都爱着同一个已不在人世的女子时,这对我们关系的改进更是毫无好处。事实上,这样的发现竟使一种很让人觉得别扭的 “阿方斯(连环画中极客气的人物之一),您先请” 的关系出现。我们每次在卫生间门口险些撞上时,两人都故意作出一副欢快灿烂的笑容。
1939 年 5 月里的一个星期里,也就是博比和我登记住进里兹旅馆的十个月后,我在一份魁北克出版的报纸 (那是我胡花钱订阅的十六份法语报纸刊物中的一种) 上看到一条占了四分之一栏目的广告,是一家蒙特利尔的美术函授学校花钱登的。上面呼吁所有合乎条件的教师——事实上,那口气真是诚恳得再不能更加 fortement 强烈了-立即去向加拿大最最新型、最最先进的美术函授学校申请任职。申请任教者,广告上写明,应能熟练掌握法、英两种语言,面且只有生活习惯上有节制、性格上无可指摘者方可申请。“LesA…Des 古典大师之友法语”夏季班定于 6 月 10 日正式开学。广告还说,送交审定的样品应表现出学院艺术与商业艺术两方面的水平,作品请寄交前东京帝国美术学院校长尤索托先生。
我顿时就觉得自己几乎无须有任何根据就是符合条件的,我从博比床底下取出他的赫耳墨斯牌小型手提打字机,用法语给尤索托先生写了一封没有节制的长信--为此,我把莱克星顿大街美术学校上午的几节课都旷掉了。我开头那段就写了差不多有三页,而且几乎是一口气写成的。我说我二十九岁,是奥诺雷 • 杜米埃的曾侄孙。我说由于妻子过世,我不久前刚刚离开自己在法国南部微薄的地产,到美国来与一位病弱的亲戚住在一起——是暂时性的,我还特地说明。我说,我自幼一直作画,只不过听从了我父母的交往多年的挚友帕布洛 • 毕加索的劝告,从未将作品展出过。尽管如此,现在巴黎的一些最讲究、决非 nouv(新贵户)的家庭里挂有不少我的油画与水彩画作品,在那里,它们已经博得(法语)当今一些眼光最为挑剔的批评家的高度重视。我又说,自从我的妻子因患一种 ulcerat(法语,癌性溃疡)而过早悲惨地去世后,我曾认真考虑过再也不握笔作画了。可是最近累遭经济损失使我改变了原先真心作出的 resolut(决定)。我说,一俟我在巴黎的经纪人将我的作品寄到,我定将挑选其中一些敬呈 “古典大师之友” 求正,无须说,我将 tre(法语:非常紧迫)地写信去让经纪人速速办理。我最后落款道:一如既往无比敬重您的 JeandeDaumier-Smith(法语:让. 德. 杜米埃. 史密斯)
这是我所选中的化名,选这个名字花的时间几乎与写整封信一样多。
写这封信我用的是铺盖商品的纱纸。不过,我却将它装进一只里兹旅馆的信封。接着,在贴上一枚从博比上格抽屉里找到的 “特种快递” 邮票后,我将信拿下楼去扔进大厅那儿的总信箱投入口。半路上我停了下,找到管分信的职员 (这人显然很讨厌我) 叫他留心今后寄给德 • 杜米埃一史密斯的信函。然后,大约两点三十分光景,我溜进第 48 街的美术学校的解剖学课堂。班上的同学头一次让我觉得看上去还算顺眼。
在随后的四天里,我用了我所有的空余时间,再加上一些不完全属于我的时间,按我想像中典型美国商业艺术的风格,画了十来幅样图。我作的主要的是淡水彩画,但有时,为了露一手,也画了些素描。我画一些穿晚礼服的人从一辆辆高级轿车里走出来,去参加剧场的首演仪式一是一双双、一对对瘦削、挺拔、优雅绝伦的男女,他们显然一辈子从未因为腋窝清洗得不够细致而感到苦恼,事实上,他们大概是连腋窝都没有的。我还画了些皮肤晒得黝黑身坯魁伟的年轻人,一色儿的白色晚礼服,坐在绿松石色游泳池边的白桌子旁,互相兴高采烈地祝酒,高脚杯里盛的是价格不算贵但显然正极其当红的黑麦威士忌。我还画了些面色红润,天生是上广告牌料的儿童,他们心情愉快、身体健康得无以复加,正把吃早餐的空碗举起,高高兴兴地要求给他们再添一些。我画了些在玩滑水板的开心大笑、Rx 房高耸的姑娘,她们无忧无虑,因为受到充分保护,绝对不会因为牙龈出血、而部有瑕疵、头发难看、人寿保险上出了问题或不够资格参加这样的全民性麻烦而感到不快。我还画了些家庭主妇,她们在得到称心如意的皂片之前,让世人看到的是一副头发蓬乱、身材臃肿的样子,孩子不听话,丈夫感情冷淡,而她们手上皮肤粗糙 (虽然手长得还是挺秀气的),她们的厨房(大倒是很大) 乱成了一团糟。
这些样品画完之后,我立即寄给了尤索托先生,一同寄去的还有六七幅我从法国带回来的非商业性绘画。另外我还附上一张我自认为是写得很漫不经心的字条,里面稍稍透露了一些个有着非常丰富人生经历的人的小故事,此人无比寂寞,受到种种磨难,遵循着最纯粹的浪漫主义传统,却登上了自己领域中高寒、白雪皑皑的险峻的顶峰。
接下去的几天真让人极度地坐立不安,可是一个星期未过,我就收到了尤索托先生的一封信,表示愿意接受我为 “古典大师之友” 的教员。信是用英语写的,虽然我去信用的是法语。(我后来知悉尤索托先生懂法语却不懂英语,他不知出于什么原因,把回信的事交给了尤索托太太来办,她具有一些实用英语的知识。)尤索托先生说,夏季班可能是一年中最忙的一班,6 月 24 日开学。他指出,这就使我差不多能有五个星期来料理我这边的事务。他还说了几句话,对于,实际上就是对于我新近感情上与财务上所遭到的挫折,表示了无限的同情。他希望我能安排好一切,在 6 月 23 日星期天向 “古典大师之友” 报到,以便熟悉工作并且与其他的教师结为“良友”(我后来知道,其他的教师只有两位,亦即尤索托先生与夫人)。他深表遗憾,说学校的规章制度中没有为新教员预付交通费用这一条。一开始时,上资为每周二十八元-这当然不是一笔非常大的数目,尤索托先生说他明白这一点,但是考虑到住宿与丰盛的膳食不另收费,而且感觉到我具有真正的敬业精神,他希望我不至于因此而感到沮丧。他热切地期待着我发去正式接受职位的电报并愉快地等候我的到来,下面的落款是:你的新朋友与新领导,原任教于东京帝国美术学院的J.尤索托。
五分钟之内,我正式接受职务的电报就发出去了。奇怪的是,在激动中,或者很可能因为用博比的电话传送电文而有点心虚,我这回大大约束了我那行云流水的文风,把电文压缩到了十个词之内。
那天晚上,我照例在七点钟去椭圆形餐厅和博比一起吃饭,这时我恼怒地发现他带来了一个客人。对我近来的课外活动我还没有对博比说过或是暗示过一个字,我正非常渴望我们单独在一起时向他公布这一刚获知的惊人消息——对他作独家报道。那客人是位非常有魅力的少妇,离婚才几个月,博比与她经常往来,也让我碰见过几次。她是个各方面都很讨人喜欢的人,她对我的每一个企图使我对她不那么针锋相对至少不那么戒备森严的友好表示,我都一厢情愿把它们理解为邀我任何时候只要喜欢与方便,尽可以和她一起_卜床一也就是说,一有机会趁博比不备之际,对她来说,这个博比显然是老了点儿。整顿饭过程中,我一直都没有好声气,说话蹦一两个字出来就算是客气的。最后,在喝咖啡时,我三言两语地讲了一下我暑期的新计划。我说完后,博比提了几个很到点子上的问题。我冷冰冰地,过于简略地作了答复,摆出一副正统嫡传皇太子绝对不会有错的架势。
“哦,这听起来真让人非常兴奋呀!” 博比的窖人说,还色迷迷地等着我把我未来在蒙特利尔的地址在桌子下面塞给她呢。
“我还以为你会和我一起去罗德岛的呢,” 博比说。
“哦,亲爱的,别这么对人家泼冷水呀,”X太太对他说道。
“我没有,不过我想多了解一些睛况也是应该的呀,” 博比说。但我认为我从他的态度里已经能看出,他脑子里已经在盘算将预订的去罗德岛的火车包厢票换成下铺票了。
“我认为这真是我一生中所听到的最最美好,最最值得称道的事情了,”x 太太热情地对我说道。她双眼里闪现出堕落的邪光。
我从火车下来踩上蒙特利尔温莎车站月台的那天是星期天,我身穿双排扣米色轧别丁套服 (我对这套衣服评价极高),一件海军蓝法兰绒衬衫,一条厚实的黄棉布领带,一双褐白两色皮鞋,一顶巴拿马草帽 (这帽子是博比的,对我来说小了点儿),还留着有三个星期历史的红棕色小胡子。尤索托先生来接我了。他是个矮小的人,还不到五薨尺高,穿一套不怎么干净的亚麻布西服,脚上穿黑皮鞋,戴了顶四边全朝上翘的黑平顶帽子。我们握手时他既不笑,也没有,我记得是这样,对我说任何话。他的表情是谜一般地深不可测——我用的这个词儿是从萨克斯 • 罗默的 “傅满洲”(侦探小说中的狡中国主人公)系列的法译本里直接借来的。而我呢,不知出于什么原因,竟咧开了一张大嘴在笑。我想笑得小一些都办不到,更不用说绷住脸不笑了。
从温莎车站坐公共汽车去学校只有几英里路。一路上,尤索托先生有没有说满五个词我看都大可怀疑。我不管他沉默不沉默,也许是正因为他沉默不语,我自顺自说个不停,脚跷了起来,脚踝架在另一只脚的膝盖上,手心出汗了就一个劲地往短袜上蹭擦。我像是非常急于要做的是:不仅反复重申我过去所说的谎话-什么我跟杜米埃沾亲啦,我妻子新近亡故啦,我在法国南部有小庄园啦-而且还要再往上添枝加叶。最后,为了使自己摆脱这些痛苦的回忆以免不能自拔 (事实上它们真的己开始使我感到有点痛苦了),我把话题转到我父母最要好的老友身上去:那位帕布洛 • 毕加索。我称他为 Lepa(可怜的毕加索)。(我不妨说明一下,我之所以选中毕加索,是因为我觉得他是在美国最知名的法国画家。我干脆把加拿大也划进美国版图里去了。) 为了让尤索托先生长点见识,我以一种对一位已黯淡无光的巨匠的高度炫耀式的真实感情,回忆说,我不止一次对毕加索说过:“M.Picaso,u(法语:毕加索先生,你要去向何方啊?)”而大师对这一针见血的问题的反应,是每一次都挪动着他那慢腾腾、铅一般沉重的步了,穿过他的工作室,去看他的 LPs(法语:街头卖艺者们)的小小复制品,并且对于曾属于他的已一去不复返的光辉不堪回首。我们下公共汽车时我对尤索托先生解释说,毕加索的毛病就出在他从不听取任何人的意见——包括他最亲密老友的意见在内。
1939 年那会儿,“古典大师之友” 在凡尔登,亦即蒙特利尔最最不吸引人的一个地区,一幢既小又毫无特色的三层楼建筑——实际上是一座平民公寓--中占了第二层。学校下面,就是一家矫形器械商店。“古典大师之友” 全部校址就包括一个大房间和一间极小、没有插销的厕所。尽管如此,我还是一进去就觉得这地方像是特别对我口味。绝好的理由倒是有一个。“教员办公室” 四壁上挂有许多配好框的画--都是水彩--是尤索托先生的大作。我至今偶尔还会梦见一只白雁从极淡极淡的蓝灰色天空中飞过,而且-这真是我所见到过最为大胆最为精椹的技艺了--那淡蓝的天光,或者说天蓝的神韵,在鸟的羽翼上得到了映照。这张画就挂在尤索托夫人书桌的后上方。这张画-这一张以及另一两张水平相近的画,使得房间有了品位。
尤索托先生和我走进教室时,穿一身黑色、樱桃色漂亮丝绸和服的尤索托夫人正手持一把短柄笤帚在扫地。她头发斑白,明显比她丈夫高出一个头,五官看上去更像是马来人而不是日本人。她中止了扫地迎着我们走过来,尤索托先生简单地介绍了双方。在我看来,她跟尤索托先生全都一样地深不可测,如果不是更加神秘的话。接着尤索托先生建议带我去看看我的房间,他 (用法语) 解释说这里刚刚腾空,原先是他儿子住的,现在去了不列颠哥伦比亚省在一个农场上千活。(在他公共汽车上的长期保持沉默之后,我竟因他能连续说话而无比欣慰,我兴高采烈地听着。)他又开始表示抱歉,因为他儿子房间里没有椅子只有几只放在地板上坐的垫子一不过我很快让他相信这对我来说几乎是歪打正着。(事实上,我想我当时说了我憎恨椅子。我是那么的兴奋,如果他告诉我的是他儿子房间里白天黑夜都浸着一英尺深的水,我没准会高兴得轻喊一声的。我没准会说我得了一种罕见的脚病,正需要每天在水里泡八小时的脚呢。)接着他领我登上一道吱嘎作响的木头扶梯,进到我的房间。爬到一半我相当有针对性地告诉他我是一个佛门弟子。后来我却得知,他和尤索托夫人都是基督教长老会的教徒。
那天深夜,我躺在床上,睡不着,尤索托夫人做的日本-马来式晚餐仍然ENMASSE(粘成一团)像台电梯似的沿着我的胸骨上上下下折腾,就在这房间墙壁的另 - 一面,不知尤索托夫妇中的哪一位开始在睡梦中呻吟起来。那呻吟又高又细,断断续续的,倒不像成年人发出的而是来自一个可怜的、发育不全的婴儿或是一只有残疾的小动物。(这成了每晚必有的常规节日。我始终没弄清是先生还是太太发出这种声音,更不用说是什么原因了。) 我躺在那里听着实在受不了,便下床趿上拖鞋,摸黑走到一只垫子那里坐下。我盘腿坐了好几个钟点一边抽烟,抽完便在鞋底上压灭,把烟头放进我睡衣胸前口袋里。(尤索托夫妇不抽烟,因此房间里哪儿都没有烟灰缸。) 我是在清晨五时才好歹入睡的。
六点半时,尤索托先生来敲我的房门,告诉我早餐六点三刻开始。他隔着门,问我睡得可好,我回答说 “Oul 不错” 接着我穿衣服——穿的是我的蓝色套服,我认为这套西服对一位教师在开学第一天穿挺合适,又打了一条我母亲以前送我的苏尔卡红领带——我都没有漱洗就匆匆忙忙穿过走廊进人尤索托家的厨房。尤索托夫人正在炉前为早餐做鱼,尤索托先生穿着他的 BV.D 内衣和裤子。坐在厨房桌子前看一份日语报纸。他对我漫不经心地点了点头。此时他们俩益发显得深不可测了。不一会儿,一盘说不上是什么种类的鱼放在了我的面前,边上浇了一圈细细的但还是可以看得出的凝结了的番茄汁。尤索托夫人问我,用英语——她的口音倒挺悦耳——我想不想要一只鸡蛋,可是我说:“Non,non,madame 不不夫人,谢谢!”我说我从来不吃鸡蛋。尤索托先生将他的报纸靠在我的水杯上,我们三人就默不作声地吃了起来;其实是他们在吃而我则是在默不作声地机械式地强行下咽。
早餐用过,其实并不是非得马上离开厨房不可,尤索托先生却换上一件无领衬衫,尤索托夫人也解下她的围裙,于是我们三人有点不大自然地排成单行步下楼梯进入教师办公室。在尤索托先生那张宽大的办公桌上凌乱地摊放着一堆东西,是十来个还没拆开的、鼓鼓的牛皮纸大信封。在我眼里,它们几乎就是一些头发刚刚梳刷得整整齐齐的新学生。尤索托先生指定我该坐哪张桌子,那是房间里最边远、最孤零零的一张,他让我坐下。接着,夫人站在他身边,尤索托先生拆开了几个信封。他和尤索托夫人像是用某种方法检查区分各种不同的内容似的,他们还时不时用日语交换意见,而我则端坐在房间另一头,穿着我的蓝套服,打着苏尔卡领带,做出一副既警觉又很耐心的样子,而且还显得多少是这单位不可或缺的人物似的。我从西服背心口袋里取出一把绘图软铅笔,这是我从纽约带来的,把它们放在写字桌桌面上,动作尽可能不发出声音。有一回,尤索托先生不知为了什么原因朝我瞥了
眼,我便回报以一个很过分的想讨他喜欢的媚笑。接着,突然,对我连一个字和一个眼色都没有,他们分别在自己的桌子前面坐下,开始工作。这时大约是七点三十分。
九点钟左右,尤索托先生摘下眼镜,站起身,手里拿着一叠纸张轻轻地走到我的桌边。我一个半小时以来半点事儿都没干,光是使是了劲儿不让肚子咕噜咕噜地响出声来。他走近时我赶紧立起来,并且还稍稍伛下身子免得使自己显得高大自傲。他把这些纸张递给我,问可否麻烦我将他批改的文字从法语译成英语。我说 “OUI法语好的先生” 他略一躬身,又轻手轻脚走回自己桌前去了,我把我那砦绘图软铅笔推到桌子一边去,拿出我的自来水笔,便开始——心都几乎要碎了——工作。
许多真正优秀的艺术家教起绘画来一点也不比一个天生擅长教书的二把刀平庸画家高明,尤索托先生的情况正是如此。凭着他那实用性的 “描改” 之作-也就是说,他铺在学生作业上描图纸上所画的作品——以及他在作业背后所写的评语,他完全可以让一个有正常资质的学生学会怎么画在一个可以辨认出来的猪圈里的一头可以辨认出来的猪,甚至是一个稀奇古怪的猪圈里的一头稀奇古怪的猪。可是他却无论如何也无法向任何人显示如何画一头在漂亮的猪圈里的漂亮的猪 (而这,不消说,正是他的水平较高的学生最最渴望能通过邮局得到的那点小小的技法诀窍)。我还得再补充一句,问题还不在于他有意无意是个悭吝使用自己才能的人,或是他蓄谋存心不随便滥用,而是他根本就没有这样的才能可以给予。对我来说,这一无情的真实情况原不是什么会引起惊讶的事,因此倒没有变得晕头转向。但是考虑到我所坐的位置,这事也有某种渐渐积累的效果,因此在午餐时间临近时,我得非常小心,免得两只手掌根上的汗水玷污了我的译文。像是要使事情更让人难以忍受似的,尤索托先生的字迹得费好大劲儿才能辨认出来。总之,午餐时间来到,我谢绝与尤索托夫妇一起用餐。我说我得去趟邮局。说完我几乎奔下楼梯来到街上,开始快步疾走,也根本不管朝的是什么方向,穿行在迷宫般陌生、显得挺寒酸的小街上。我见到一家午餐酒吧时便撞进去,一口气吞咽下四客“康尼岛红肠热狗” 和三杯浑浊不清的咖啡。
在回 “古典大师之友” 的路上,我心里犯开了嘀咕,起先是带着一种常有的惴惴不安的心情,对此凭过去经验我多少还知道该怎么对付,接着我却陷入了极端的恐慌,我不知尤索托先生整个上午纯粹把我当个翻译来使用,这里面是不是有什么个人的因素。这个老 “傅满洲” 是不是从一开头起就知道,除了别的用来迷惑人的小手法小动作之外,我留的那撇小胡子也仅仅是一个十九岁男孩的稀汗毛? 一想到这种可能性我简直无法忍受。我也逐渐感到愤愤不平。就凭我——一个获得三次一等奖的人,毕加索的一位密友(我真的开始认为我的确就是了)——竟被当作一名翻译来使用。这是不是在往罚不当罪的路上走了吗? 就说一件事,我的小胡子,不管毛多稀,毕竟全部是我自己长出来的呀{反正不是用胶水粘上去的。我急匆匆赶回学校的一路上老用手指去摸小胡子,好让自己的心踏实一些。可是我越想这整件事情,我步了也走得越快,到后来我几乎是在小跑了,仿佛感到每分钟都会有石块从四面八方朝我扔来似的。
虽然我吃午饭只用了约摸四十分钟,但我回去时尤索托两口子却都已经在伏案工作了。他们没有抬起头来看我也没有作出任何听到我进来的姿态。我汗涔涔、气喘吁吁地走过去在我桌子前面坐下。我直僵僵地坐了有十五到二十分钟,脑子里闪过了各色各样新编的有关毕加索的小故事,完全是为了应付尤索托先生突然站起身走过来揭穿我的真面目。他果真突然站起身走过来了。我站起来等着他到来——迎面出击,如果有必要的话——用一个新出炉的毕加索小趣闻,可是让我大为惊慌的是,我原来设定的计谋竟卡壳说不出来了。我灵机一动赶紧对挂在尤索托夫人身后的那幅飞雁图大加赞美。我滔滔不绝说了好长的一大篇话。我说我认识一个住在巴黎的人――是个非常富有的瘫痪病人,我说--他一定会出天价求购这幅画的。我说如果尤索托先生感必趣我可以立即与他联系。幸亏还好,尤索托先生说这幅画是属于他的一个什么表亲的,此人现在到日本探亲去了。紧接着还不等我表示遗憾,他就问我――称呼我为杜米埃史密斯先生——可否抽空帮他批改几份作业。他走回自己桌边抱了三个装得鼓鼓的大信封过来,放在了我的桌子上。趁我傻不愣登地站着一边不住点头一边去摸我已经放回我的背心口袋的绘图铅笔时,他开始给我解释起学校的教学方法来 (或者不如说,根本是子虚乌有的教学方法)。他回到了他自己的办公桌前,而我是是用了好几分钟才使自己镇定下来。
分派给我的三个学生全是使用英语的。头一位是住在多伦多的一个二十三岁的家庭主妇,她说她的笔名是班比 • 克雷默,希望学校给她寄信时也用这个名字。“古典大师之友”要求所有新生都填一份调查表并附寄照片。克雷默小姐寄来的是一张光而 8×10 英寸的照片,上面她本人戴了只脚镯,穿了件没有背带的游泳衣,头上扣了顶白帆布水手帽。在她的调查表上她说她最喜欢的艺术家是伦勃朗和沃尔特 • 迪斯尼。她说她真希望有一天自己能赶上他们。她的样品画有点像附属品似的别在她的照片上。全都挺吸引人。有张更是让人难忘。这张是用艳丽的水彩颜色画的,还有标题,写的是:“原谅他们的非法侵入吧。”画里有三个小男孩,在一片挺特别的池水旁钓鱼。一个孩子的夹克还搭在一块写有 “严禁钓鱼!” 的告示牌上。处在画面前景处的是个身材最高的男孩,看起来一条腿像是得了佝偻病而另一条则得了象皮病。--很明显,克雷默小姐是有意用这种视觉效果来表明这个男孩站立时,两条腿是稍稍叉开的。
我的第二个学生是安大略省温莎市的一位五十六岁的 “社会摄影师”,名叫 R• 霍华德 • 里奇菲尔德,他说他妻子多年来追随他挤到绘画这一行当里来凑热闹。他最喜爱的画家是伦勃朗 • 萨金特与“提坦”(应为提香),但他又深思熟虑地补充说,他本人却无意沿着他们的画路往前发展。他说他最感兴趣的是绘画的讽刺的一面而不是附庸风雅的那一面。为了说明这一信条,他寄来了不少原始素描和油画。他的一幅作品——我认为那能算是他的主要作品了——这么多年来还能让我有印象,就跟,比方说吧,“甜蜜的苏” 或“让我称你为心上人”之类的歌词一样。这幅画嘲讽地描绘了一个贞洁的年轻姑娘的人们熟知的日常生活中的悲剧,这姑娘垂发过肩,Rx 房饱满,在教堂里,就在圣坛的阴影下,遭到她的牧师的凌辱。两个人物衣服凌乱的模样在造型上相当逼真。老实说,这幅画很让我留下印象的倒不是它的讽刺含义,而是其内在的技艺水平。如果不是我知道两个学生住地相距有几百英里,我真会发誓说里奇菲尔德是得到过来自班比 • 克雷默的一些纯技术性的帮助的。
我十九岁时,除了极罕有的情况之外,一遇到什么受不了的事,我那尺骨肘部的鹰嘴突总免不了会比全身其他部位更早地局部或是全部发麻。里奇菲尔德和克雷默小姐给我留下很多印象,可就是没带来半点乐趣。我在审阅他们的寄件时有三四次都想站起来向尤索托先生正式提出抗议。可是我又不清楚我该采取何种抗议形式。我现在想,我当时说不定会走到他桌子前面,尖叫地申诉说:“我妈死了,我不得不跟她那个宝贝丈夫一起生活,在纽约没一个人说法语,你儿子房间里连把椅子都没有。你让我怎么教这两个疯疯癫癫的人绘画呢?” 由于长期以来就自我训练成坐下来承受绝望的习惯,我最后还是很不费劲就管住了自己,屁股没离开我的椅子。我接着又拆开第三个学生的信封。
我这第三个学生是圣约瑟姐妹修道会的一名出家人,名叫艾尔玛修女,她在多伦多近郊一所修道院小学里教 “烹饪与图画”。对于她信封里的内容,我真不知道从何说起的好。我不如先提一点,艾尔玛修女随信寄来的不是她自己的照片,而是一张她的修道院的全景快照,对为什么这样做也没作解释。我现在还想起来,调查表学生年龄这一项她也空着没填。除此之外,她的表也许可以算是这个世界上填得最有声有色的一份了。她在密歇根州的底特律市出生与成长,她父亲在那里当“福特汽车的检验员”。她的学历是上过一年中学。她没有受过正规的绘画训练。她说她教图画的惟一原因是某某修女去世了而齐默尔曼神父(这名字特别刺我眼,因为拔掉我八颗牙齿的那个牙科医生也叫这名字)——齐默尔曼神父便选了她来顶缺。她说她的“烹饪班有三十四只猫咪(当指儿童KID,修女误写成猫咪KITTS)而图画班有十八只猫咪”。在“本人爱好” 这一栏里,她说她的爱好是爱她的主以及主的圣言,还有就是 “收集树叶不过是等它们落到地上时才收”。她最喜欢的画家是道格拉斯 • 邦廷。(我不妨承认,这名字我多年来通过各种方法都没能查出来。) 她说她的小猫们总是喜欢“画跑动的人形而这正是我做不好的一件事”。她说她会非常努力学习使自己画得好一些,希望我们对她别太不耐烦。
她信封里附上的习作一共只有六张。(她所有的作品都没有署名-这当然是件小事,但是当时却不成比例地让人有一种清新感。因为班比 • 克雷默和里奇菲尔德的画全都是大笔一挥签了名或是——这更加显得可笑可气了--涂上名字缩写字母的。) 在十三年之后的今天,我不仅清晰记得艾尔玛修女的全部六幅作品,而且其中的四幅我有时候认为我也未免记得过于清晰了一些,这对我自己心境的宁静没有什么好处。她最好的画是水彩,是画在褐纸上的。(褐色纸,特别是包装用的牛皮纸,用来作画最惬意不过了。许多有经验的画家在不存心作什么大画或皇皇巨品时总是用这种纸。) 这幅画,尽管尺幅不大 (约摸 10×12 英寸),却对基督的遗体被送到在亚利马太地方的约瑟花园里的墓地的情景,刻画得细致入微。在最右方的前景处,两个看来是约瑟的仆人的男人很吃力地抬着。业利马太的约瑟紧跟在他们后面——在那样的情景下,他腰板似乎挺得太直了些。在约瑟后面,隔开相当一段距离,在次要地位的是走过来的加利利的妇女,她们夹杂在一群人当中,也许是破门而入的一伙人,那些哀悼的、看热闹的以及小孩子们,其中还至少有三只欢蹦乱跳的、不敬神的杂种狗。在我看来,这幅画的主要人物是在左前方、面对观画者的一个妇女。她右手高举过头,在拼命地招呼什么人——也许是她的孩子,或是她的丈夫,没准是观画者——让这人扔下手头的一切赶紧上她这儿来。人群前排的两位妇女头上还有光环。我手头没有《圣经》,只能大致地猜测她们的身份。但我立刻就辨认出了抹大拉的马利亚。反正是我肯定那就是她。她位于前景正中,自己一人走着,很明显有意汉与人群隔开一段距离,她双手垂在身体两侧。她没有把她的忧伤标志在她的袖子上,这么说吧——事实上,完全没有任何外在的迹象,是以说明她与这位死者不久前很值得羡慕的关系。她的脸,像画巾所有人物的脸一样,是用一种便宜、现成的肉色颜料画的。让人很痛苦地看得明明白白,艾尔玛修女自己也觉得这种颜色不能让人满意,也曾作出无人指点的、动机纯正的努力,想尽量让这颜色不那么刺眼。这张画其他严重毛病倒也没有。也就是说,没有什么值得一提的毛病除非你硬要吹毛求疵。从任何一个重要方面看,这都是一件艺术家的作品,饱含着很高很高、经过锻锤的天分,也经历了天知道多少多少个小时的艰辛劳动。
我最初的反应之一,自然是拿着艾尔玛修女的信封冲到尤索托先生跟前去。可是,我又一次按捺住性子坐好了。我不愿冒艾尔玛修女被人夺走的险。最后,我仅仅是小心翼翼地把她的东西装回信封,放在我桌子的边上,兴奋地计划着在晚上自己的时间里好好修改它。主意打定后,我竟以连自己都没想到会有的巨大耐心,甚至还以与人为善的态度,将下午剩下的时间用来在罩着的纱纸上修改一些 (没有性器官的) 男女裸体画,那是 R• 霍华德 • 里奇菲尔德怀着好意或是不怀好意地画成的。
将近吃晚饭时,我解开衬衫的三颗纽扣,将艾尔玛修女的信封藏进去,藏在那里不管是小偷还是,这么说是以防万一,尤索托夫妇,都不可能掏走的。
“古典大师之友” 每一顿晚餐的程序都是无须费唇舌雷打不动的。一到五点三十分尤索托夫人立即从桌边站起身,上楼去准备,而六点整,尤索托先生和我--总是排成单行-接着上去。绝不会走开去办点什么别的事,不管那是多么的重要或是有益于健康。不过,那天晚上,胸口让艾尔玛修女的信封温暖着,我却感到空前轻松。事实上,在吃晚饭的整个过程中,我简直有点放浪形骸了。我抛出了一件我刚想出来的特别精彩的毕加索逸事,我本该保留着等哪天过得不顺时再讲的。尤索托先生几乎没有放下手里的日文报纸来听我讲,而尤索托夫人倒似乎有点反应,至少不能说是毫无反应。反正,我讲完后,她在那天早晨问我要不要鸡蛋之后头一回跟我说了话。她问我是不是真的不想在我房间里有一把椅子。我赶紧说:“Non,non——mercl 法语:谢谢夫人” 我说地板上的坐垫靠墙放,那样正好让我有机会可以练练让背挺直。我还站起来显示给她看我的背凹到了什么程度。
晚饭后,趁尤索托夫妇用日语在争论什么挺有火药昧的问题时,我告退要离开餐桌。尤索托先生盯看着我,仿佛他不太清楚我当初是怎么进入他的厨房似的,但还是点了点头,于是我急急地穿过走廊进人我的房间。我打开顶灯,把门关上,接着从兜里取出绘图铅笔,脱掉西服,解开纽扣,手持艾尔玛修女的信封在一只软垫 E 坐了下来。我前面地上摊放着我要用的~切,着手做我认为对艾尔玛修女最迫切的艺术上的所需,一直到清晨四点之后。
我先做的一件事是作了十一二张铅笔素描。我没有下楼到教员办公室去取图画纸,而是在我自己的笔记本上画的,纸的正面反面都画。画完后,我写了一封长长的、几乎是没完没了的信。
我这人一生中都像只神经特别不正常的喜鹊那样爱积攒东西.我至今还保留着 1939 年 6 月一个夜晚写给艾尔玛修女那封信最后一稿的底稿。我原可以一字不差地抄录如下,但是没有这个必要。信的主要内容,确实是主要内容,我用来向她指出,她那幅主要作品里何处以及为何出了一些小毛病,这些毛病以她对颜色的处理上最为突出。我列举了她不能没有的画家必备的几种用品,也附上了大致的价格。我问她道格拉斯 • 邦廷是何许人。我问在何处可以见到他的作品。我问她 (我当时就清楚那准是白问) 是否见到过任何安托耐洛 • 达 • 墨西那(意大利画家,不甚有名)的复制品或是原作。我还请她告诉我她的年纪,我用了许多笔墨向她保证,如果她透露的话,这个情况也就到我为止,绝不会让第二个人知道。我说我问这件事的惟一原因,是能使我更有效地指导她。几乎紧接着,我又问她修道院允不允许她接见来客。
我想,我应该把我那封信的最后几行 (或者说那一立方英尺) 抄录如下——文字、标点符号,全都一点不漏。
…… 顺便提一句,倘若你通晓法语,不妨明示,因本人对该种语言颇为娴熟,盖我青少年时代泰半于法国巴黎度过也。
知道女士亟欲掌握跑动人形之画法,以便传授给修道院之学生,特附上本人所绘若干草图,仅供参考。可看出涂抹匆忙,远非完美,实无值得称道之处,然相信尚能提供某些基本要领,对此你曾表示深感兴趣。不幸的是,此间之校长大概仍未推行任何有系统之教学方法。你已具备相当水平,自然无须惧惮,惟我实在不知校长希我如何对待其余几名学生,依我之见,他们水平极低,主要还是资质愚钝不堪造就。
不幸的是,本人为一不可知论者;然而我又于一定距离处深服阿西西之圣方济各(方济各女修会创始人)”,此点亦无须掩饰。我不知你是否熟知他 (指阿西西的圣方济各) 于众人欲以通红灼热之烙铁烫瞎他一只眼球时所说的话:“火焰兄弟唷,上天赋予你以美丽、力量与用途;我祈求你能对我以礼相待。”依我之见,你都是略微带着他说话的那种风格作画的,在许多方面给人以愉悦。顺便提一下,能否请问,在前景处着蓝衣之少妇可是抹大拉的马利亚? 此处所说当然是指我们适才所讨论的那幅画。如果她不是,那我就是可悲地蒙骗了自己了。不过,这一类事并不少见。
我希望女士相信,在你受教于 “古典大师之友” 期间,本人当竭尽愚鲁完垒听命于你。坦诚地说,我认为女士天分极高,如果若干年后成长为一位天才人物,我丝毫不会感到意外。在这一点上.我绝不想用溢美之词使你感到飘飘然。正因如此,我才问前景处穿蓝衣者是不是抹大拉的马利亚,因为如果是的话,那么我觉得你对自己刚刚露头的才华的发挥,已经有点压过你的宗教信仰了。不过,以我乏见,这也不是什么可怕之事。
衷心希望女士享受着充分、完全的健康,我是非常尊敬你的,(签名)让 • 德 • 杜米埃史密斯 “古典大师之友” 教师
又及:几乎忘记提醒你,学生应于每隔一周的星期一将作业寄来。可否寄些户外素描给我,算是指派你做的第一次作业? 你随便画就是,不必紧张。自然,我不知道你的修道院给你多少时间让你个人作画,希望你能告知。另外,我请你一定要买我冒昧开列的那些必不可缺的用品,同时希望你能尽早使用油画颜料。如果你不介意的话,我要坦白说我相信你太热中于仅仅作水彩画而无限期地拖延画油画了。我这样说并不带个人色彩也不想使你感到不愉快;实际上,这是对你的一种称赞。此外,请把你手头有的所有以前画的旧作全都寄来,因为我非常想看。无须说,在你下一个邮件寄到之前,我的日子将会是很难熬的。
如果这耳是太过分的话,我很希望你能告诉我,你觉得做一名修女是不是感到非常满意,我指的自然是精神的方面。自从我读了 “哈佛经典丛书” 第 36、44、45 卷 (这些书你想必十分熟悉) 之后,我便将研究各种宗教作为一种个人爱好。我特别喜欢马丁 • 路德,自然,他是位新教徒。你可别见怪。我从不宣传什么教义,这与我天性不合。最后还想起一件事,请别忘了告诉我你接待客人的时间,就目前情况看我周末时间可以自由支配,说不定某个星期六我会到你附近那一带去走走。另外也请别忘记告诉我你是否较好地掌握法语因为在所有的内容与领域方面我都颇难用英语表达.这是自我多变、难以理喻的童年成长过程分不开的。
凌晨三时三十分左右,我出门上街,把我的信和画寄给了艾尔玛修女。然后,我在完全真实的高度欣喜中,用累得发木的手指脱掉衣服,躺倒在床上。
还没等我睡着,那呻吟声又透过墙从尤索托夫妇房间里传了出来。我想像天亮时尤索托夫妇会一起上我这儿来,请我和求我倾听他们的秘密问题,他们会把最隐秘、最可怕的细节全都告诉我。我真切地看到了那幅景象。我将在厨房桌子前坐在他们两人之间,听完这个又听那个。我听啊,听啊,听啊,双手抱头--直到最后,我实在受不了,便将手直直插进尤索托夫人的咽喉,把她的心捏在手里,焐热它,就像我焐热一只小鸟似的。然后,当一切都弄妥摆平后,我就把艾尔玛修女的作业拿给尤索托夫妇看,而他们将分享我的快乐。
事情往往都是过后很久才能看清,不过,幸福与快乐之间惟一的不同就在于幸福是实在的固体而快乐则是一种流体。第二天早上,当尤索托先生把两个新学生的邮件放在我桌上时,我的快乐已开始从它的容器里往外渗漏。当时我正在修改班比 • 克雷默的画,倒是很心平气和,因为知道我寄给艾尔玛修女的信已经安全上路。但面对世界上居然还有比班比或是 R• 霍华德 • 里奇菲尔德更缺少绘画才能的人这样一件稀奇古怪的事时,我仍然毫无思想准备。觉得真的快控制不住自己了,我便点燃了一根烟,这还是我参加教师班子以来第一次在办公室里点烟。果然还挺管用,于是我便重新修改起班比的画来。可是还没等我吸上三四口,我虽然没有抬头往后看,却真的感觉到尤索托先生是在看我。接着我又听到他椅子往后推动的卢音,这就证明确实是没错。我像往常一样站起身来迎候他。他向我解释道,用的是一种让人一听就心烦的狗屁耳语,他本人倒并不反对抽烟,不过遗憾的是,学校规定教师办公室里是禁止吸烟的。我连声一再说真不好意思,他却宽容大度地挥了挥手,打断了我的话,接着便走回到房间他和尤索托夫人的那头去了。我真不知在艾尔玛修女下一个邮件应该来到前的这十三天里,自己怎能神志清醒地度过,想到这里,我竟乱了方寸,不知如何是好。
上面所讲的是星期二上午的事。在那天余下的上班时间以及接下来两天全部的工作时间里,我让自己忙得连喘口气的工夫都没有。事实上,我把班比 • 克雷默和 R• 霍华德 • 里奇菲尔德的那些画全都拆开,然后重新组合,并且还加上新的部分。我给他们每人指派了十来张 (真的是十来张) 绘画作业,是带点侮辱性、低于正常水平,不过倒是挺有建设性的作业。我给他们写了两封长信。我几乎是在央求 R• 霍华德 •• 里奇菲尔德暂时丢开他的讽刺风格。我也以最最委婉的口气请班比暂时忍一忍,别再在画稿底下加上 “原谅他们的非法侵人吧” 这类的标题。接着,在星期四下午后半晌,感觉到自己心情不错,有点儿兴奋,我就开始看一两个新学生的材料,有一个美国学生从缅因州班戈市寄画件来,他在他的调查表里用啰里啰嗦,是个 “诚实的约翰” 的坦诚态度说,他最喜爱的画家就是他自己。他还称自己是什么现实主义-抽象丰义者。至十我下课后的时间,星期一夜晚我搭乘公共汽车进到蒙特利尔市中心,在一家 = 一等电影院里,把一场《卡通节星期》的影片从头看到底——基本上就是强迫我见证一群老鼠如何用香槟酒瓶塞子朝一只又一只的猫狂轰滥炸。星期三晚上.我把房间里的坐垫集拢来,让三只叠在一起,试着凭记忆把艾尔玛修女那幅基督殡葬图重新画出来。
我不禁要说,星期四夜晚非常特别,或者不如说是令人毛骨障然,不过事实是,我已经找不到符合要求的形容词来描写星期四的夜晚了。我晚饭后离开 “古典大师之友” 然后便不知去了哪儿--也许去看了场电影,也许仅仅是作了次长时间的散步;我记不起来了,而且我 1939 年的日记也让我沮丧了一回,因为我要查找的那天的日记正好是全然空白。
不过我倒知道为什么那是一页空白。我从度过黄昏的不知什么地方回来——我只记得那时天已经黑了——这时,我站住在学校外面的人行道上,朝那家矫形器械商店的灯光明亮的橱窗看去。这时,一件令人沮丧的事情发生了。我怎么也摆脱不掉这个念头:不管有一天我能学会如何冷静、理智或是很有风度地过我的口子,我水远至多不过是充当这个摆满搪瓷尿壶、便盆的花园的一名参观者,旁边还站着个戴着削价疝气带的没画眼睛的木头模特偶像。自然,这个念头不可能持续多久。我记得我飞奔上楼进入我的房间,脱掉衣服钻上了床,连日记本都没有打开,自然不会去记下些什么了。
一连好几个钟头我就这么躺着,睡不着,浑身颤抖。我听着隔壁房间的呻吟声,只好强迫自己想我那位得意门生。我试图看到我上她修道院去探望她那一天的情景。我看见她走出来迎接我
在一道高高的铁丝网的附近一一位羞怯、美丽的十八岁女孩.她还没有作最后决定性的誓约因此还可以白由和她选中的彼德 • 阿伯拉尔(正统教会的异端)型的男子走出修道院进入凡俗世界。我看见我们缓慢、默默无言地朝修道院内一处偏僻、青翠的地方走去,在那里突然,我非常纯洁地把手围在她的腰上。这一幻景欣喜得让人难以自持,最后,我发泄了一通,这以后也就睡着了。
星期五整个上午以及下午大部分的时间我都在埋头苦干,通过那层罩在上面的薄纱纸,把缅因州班戈市那个男人所画的象征性器官的森林改成一棵棵可以辨认的树,那些森林是他有意识画在昂贵的亚麻画布上的。将近下午四点半时,我不管在意识上、心灵上还是在身体上,都很麻木了,因此当尤索托先生走到我桌前停立一小会儿时,我仅仅是稍稍欠起身子。他递给我一样东西——他态度很冷淡就跟一个普通的饭店侍者分发菜单时一样。那是发自艾尔玛修女所在那个修道院的首席嬷嬷的一封信,通知尤索托先生,齐默尔曼神父由于他所无法控制的原因,不得不改变允许艾尔玛修女在 “古典大师之友” 进修的决定。嬷嬷在信中写道,她对于这一变更可能会对学校造成的不便与混乱深感遗憾。她还殷切希望首批支付的十四元学费能够退还给教区。
我多年来一直深信,当那只老鼠从着了火的旋转轮盘上掉下,一瘸一拐地往家走时,它必定又有了杀死猫的无懈可击的新招。在我读了并重读了首席嬷嬷的来信并对着它发了好长时间的愣之后.我突然摆脱开它,给余下那四位学生写起信来,我劝他们别指望当什么艺术家了。我告诉他们,在信中一个一个地对他们说,他们绝对不具备值得发展的才能,他们纯粹是在浪费自己的宝贵时间也是在浪费校长的时间。四封信我都是用法语写的。写完后我立即上街把它们发了。所带来的满是感是短暂的,但是没有消失时却让人感到非常非常地受用。
到了又该列队上厨房去吃晚饭时,我说我不想吃了。我说我身体不太好。(1939 年那会儿,我撒谎时态度比说真话时还要真诚-因此我敢肯定,我说自己身体不舒服时尤索托先生准是用怀疑的眼光在看着我。) 接着我上楼回我的房间,在一只垫子上坐下。我在那里坐了准有一个钟头,对着百叶窗上一个天光漏进来的洞傻傻地瞪着,没有抽烟,没有脱掉外衣或是解松领带。接着,很突然,我站起身,取来一大叠我自己的活页纸,就拿地板当桌子,给艾尔玛修女写了第二封信。
这封信我根本没有寄出去。下面是全部根据底稿抄录的。
蒙特利尔,加拿大
6 月 28 日,1939 年亲爱的艾尔玛修女,
是不是我在上封信中无意中说了什么招你讨厌或是傲慢无礼的话,以致引起了齐默尔曼神父的注意并在某种程度上使你处境尴尬? 如果真是这样,我请求你至少给我一个合适的机会,使我能收回我出于仰慕而说出的有欠考虑的话,使我能成为你的朋友同时又是学生与老师。这个请求不算过分吧? 依我看似乎并不过分。
真实的情况就是如此:倘若你不再多学一点这门艺术的基本功的话,你这一生只会成为一名非常非常有趣的画家却水远不会成为一位伟大的画家。在我看来这太可怕了。你认识到问题的严重性了吗?
会不会齐默尔曼神父让你从学校辞职,因为他认为这件事会影响你成为一个称职的修女。如果事情确实如此,我不免要说,我认为从各方面讲,他行事过于急躁草率。学画是绝对不会对你做修女有任何影响的。我自己就活得像一个脾气乖戾的出家人。当艺术家最不好的一点无非是使你经常感到有些淡淡的哀愁。不过,在我看来,这也不能算是境遇悲惨。我一生最快乐的日子是在多年前我十七岁的时候。我走在路上,去吃午餐,母亲在那个地方等我,她是久病后第一次出门,我正兴高采烈,可是,我正走在维克多 • 雨果大街上,那是巴黎的一条街,此时,我突然撞在一个家伙的身上,那人竟是没有鼻子的。我请你好好琢磨琢磨这件事,事实上我是在恳求你。需知它是饱含深意的。
也很可能,齐默尔曼神父让你休学,是因为你那家修道院缺乏经费无法为你支付学费。我坦诚希望情况确是如此,这不仅会使我心安理得,而且还是出于一个实际的考虑。如果情况果真就是这样,你只需说一声,我是愿意无限期地提供免费服务的。我们可不可以更深入地谈谈这件事呢? 我可否再次问问,你们修道院的会客日子是在哪一天? 我能不能先自作主张,定在 7 月 6 日下个星期六去修道院探望你? 总是在三到五点之间吧,具体时间还得看蒙特利尔到多伦多的火车班次而定。我迫切地等待着你的答复。
怀着敬意与仰慕之情,
你忠实的
(签名) 让 • 德 • 杜米埃一史密斯
“古典大师之友” 教师
又及:在上一封信里,我随便问起你那幅宗教画前景处那位穿蓝表的少妇是不是罪人抹大拉的马利亚。如果你仍然未复信,那就请继续保持沉默好了。很可能是我弄错了,在我生命中的这个阶段上.我也不特别希望被弄得幻想破灭。我很愿意继续沉沦在无知的阴影之中。
即便是今天,甚至是眼下这个时刻,每当回想起自己曾带了一套晚礼服去 “古典大师之友” 赴任,我都免不了要打个冷颤。可是我当时确实是带了,而且在我给艾尔玛修女写完信后,我还换上了这套晚札服。这整个事情仿佛就是为了诱使我去喝醉似的,正因为我生平直到此时为止还未喝醉过(我怕喝多了会使我那只画出过三次一等奖以及别的作品的手颤抖),我才觉得为这悲惨的时刻我必须穿得正规一些。
尤索托夫妇还在厨房时,我悄悄溜下楼打了个电话给温莎大饭店——那是我离开纽约前博比的朋友 x 太太向我推荐的。我向饭店订了一个单人席位,时间定在八点钟。
七点三十分左右,我穿戴整齐,收拾得漂漂亮亮,把头从门边伸出去,看看尤索托夫妇是不是有哪一个在蹑手蹑脚地走动。我反正不想让他们看到我穿晚礼服。见他们都不在,我赶紧下楼并开始找出租车。那封写给艾尔玛修女的信就揣在我衣服的内兜里。我打算在吃晚餐时再从头读一遍,最好是在烛光下读。
我走过一个又一个街口,却连一辆出租车的影子都没见到,更不用说是空车了,这么止着真不是滋味。蒙特利尔的儿尔登区并不是讲究衣着的地段,我敢肯定每个过路行人看到我都会冉看我一眼,那眼光基本上都是不以为然的。最后.在来到星期一我狼吞虎咽过 “康尼岛红肠热狗” 的便餐酒吧门前时,我决定把在温莎大饭店订餐桌的事扔到一边。我走进便餐酒吧,在尽里面的一个火车座坐下.要了汤、小面包和黑咖啡,订菜时用左手挡住我的黑领结。我希望别的客人会以为我是个止准备上班的侍者。
喝到第二杯咖啡时,我取出那封还未寄出的写给艾尔玛修女的信重新读。我觉得信的内容似乎单薄了一些,便决定赶回 “大师之友” 再加加工。我还考虑了去探望艾尔玛修女的计划,我想当晚再迟些时候就去预订火车票是不是一个好主意。脑子里盘算着这两件事 -__它们哪一件都没能使自己像我希望的那样,心情变得轻松一些——我离开便餐酒吧,快步走回学校。
大约十五分钟之后,我遇到了一件完全是横端里插进来的事情。我知道,这么说,很有些炒作新闻之嫌与恶劣标记,不过事实上倒恰恰就是这样的。我马上要谈到的是一次独特的经历,它至今还让我感到很不可思议,我只要可能,总不愿把它划归为一件真正神秘主义或者甚至与神秘主义沾边的个案。(倘若不这样做,我觉得,那就等子在暗示或明说:圣方济各与一般神经兮兮的礼拜日去亲吻麻风病患者的人之间的精神上的 sornes(法语:出路、去向),仅仅是纵向层次上有所不同而已。)
在晚上九点钟的朦胧天光中,我穿过马路走近学校,那家矫形器械商店里有盏灯亮着。我吃惊地发现,橱窗里有个大活人,是个三十岁左右的高大壮实的女子,穿一身绿、黄、紫堇色的雪纺绸衣服。她正在给木头模特换疝气带。我走到橱窗跟前时她显然刚把旧的疝气带摘下;她把它夹在左胳肢窝里 (她的右“侧影” 正好对着我),此时正把新的疝气带往模特身上戴。我站住了看她,看得入迷,一直到她突然之间有所感觉,然后又看到她正在被人盯看。我赶紧微笑——向她显示我不过是个玻璃外而微光中并无敌意的穿晚礼服的人——但是没有用。那女子慌乱得完全超出了正常状态。她满面通红,脱下的疝气带掉到了地上,她倒退回去,踩在一大摞冲洗用的盆盆罐罐上――她的两脚站不稳了。我立刻伸出手去,手指尖撞到了玻璃。她像个溜冰者似的重重地摔了个屁蹲。她马上又重新站起来,不看我。她的脸仍然是红红的,她用一只手把头发朝后推了推,继续给模特系疝气带。也就正在此时,我有了那种体验。突然(我说这一点,我相信,是完全具备应有的自我意识的),太阳升起,以每秒九千三百万英里的速度朝我的鼻梁飞来。我什么都看不见了,而且惊慌失措——我只得将手按在玻璃上以保持身体平衡。这样的情况只持续了几秒钟。等我视觉恢复,那女子已离开橱窗,只留下一地闪闪发光的精致、显得格外圣洁的瓷漆假花。
我倒退着离开了橱窗,绕着这个街区走了两圈,直到我双膝不再发软。然后,不敢再冒险往商店橱窗看上一眼了,我上楼进人自己的房间,躺倒在床上。几分钟,也许是几小时之后,我用法语,在我的日记里记下了下面这短短的几行字:“我要给艾尔玛修女顺自己命运的轨迹而行的自由。全世界的人都是一个修女。”(Toatlemondeeslunen。nne(法语:意同前句))
在晚上睡觉前,我写信给我不久前刚刚开除的四名学生,恢复了他们的学籍。我说学校的管理部门出了差错。事实上,这些信似乎是自己流泻而出的。这也许与这件事情有点关系在我坐下来写信之前,我已从楼下搬了把椅子上来。
提下面这件事似乎完全是 “抖” 出了一个 “反高 xdx 潮”,不过事实是“古典大师之友” 还没过一星期就关门了,原因是没有经过正式的注册手续(事实上,是根本没有去注册过)。我摒挡行装又回到罗德岛我继父博比的身边,在那里我住了六或八个星期,用来考察所有夏季活动的动物中最最有趣的一种——穿短裤的美国少女,直到美术学校重新开学。
做得对也好不对也好,反正我再没有与艾尔玛修女联系过。
不过,偶尔,我仍然听到班比 • 克雷默的消息。我最后听到的一则是,她已经把业务扩充到为自己设计圣诞卡上去了。如果她没有失去自己的独特风格的话,它们会是很值得一看的。
# [[丁云]]/猫山王风云
**1**
刚刚收到刘钦洲发来的短讯:“榴梿即将飘香,请来劳勿一叙。”
我即刻交代了老伴照顾屋前小菜园,儿子呢?刚刚出海捕鱼去了,没有十天八天是不归航的,孙子则有媳妇照顾,一切都妥妥当当,无需挂虑。反正我一向无牵无挂惯了,捡了几件衣服和牙膏牙刷,拿了手机钱包塞进行囊,就乘渡轮过红土坎,再转搭巴士直奔彭亨州劳勿了。
劳勿,是“猫山王”之乡啊!
自从我跟随儿子定居邦咯岛,早已经不理世事,与老伴同住,种菜养鸡。儿子偶尔会带老婆孩子过来,随手兜了些拖网船捕捞到的鱼虾煮餐丰富的。平时觉得闷,就骑脚踏车到港脚咖啡店喝喝咖啡,看看报纸,偶尔上“乌有之乡”网站,看看中国与美国的风云局势,发发牢骚短讯骂骂美帝国主义、骂骂台独分子乱港分子,谈谈“北戴河会议”的秘辛。咖啡店里都是邦咯岛老一辈讨海人,也听腻了我这“左胶”重复着讲述我“不能回家”的故事。
“出狱了,当然要回家,知道为什么那些狗腿子不让我回家吗?”
“为什么?”
“我原本是印刷厂工人,却被内政部的密探扣留了,他们指我是‘马共外围分子’,一直暗中替马共印刷宣传单子。他们用各种卑劣的方法恐吓我、拷问我,要我承认自己是马共,要我供出联络人,也要我供出马共颠覆政府的计划,我哪里知道这些?只能挨打、挨饿、不让睡觉,以家人威胁我。我当然没招供,要我招供什么?我只是小喽罗,是个跑腿的,哪懂得党的机密、党的颠覆计划?如此,我被折磨了半年,他们无奈,准备释放我。”
“释放你?那你不就回家咯!”
“他们说放我可以,就是不让我回家!”
“搞什么?不能回家?回哪里?”
“他们说:‘不管你回哪里,就是不能回我老家双溪西博。’那个狗腿子还说:‘你老家,是红区,一回家,你跑进森林真的当了马共,我们不是多了一个敌人?’于是我出狱后,30年来,四处落脚,到处飘泊流浪,就是不敢回家,妈妈死了,也不敢回家奔丧,家里的青柑园被霸占了,老屋被拆了,也不敢回去处理。我可不想再被关进去啊,那些狗腿子,半夜常来敲门,跟紧了我10年,才销声匿迹。最后,我只好在邦咯岛落脚了,很多人不晓得,还以为我是邦咯岛人哩。”
当然,收到劳勿牢友刘钦洲的短讯,自是喜不自禁。正值榴梿季节,去劳勿吃著名的猫山王榴梿,大快朵颐也不错!刘钦洲有10英亩榴梿园,都是猫山王品种。他还继续发来短讯,催促我快点去!“榴梿季节过了,就没榴梿吃了。”
再没有牢狱,再没有暗探半夜上门突击检查,太好了。
自由自在,没有牵挂,是该出门逍遥了。
**2**
在旅途中颠簸了一整天,早晨从邦咯岛坐渡轮过海到红土坎,再乘搭长途巴士到吉隆坡,然后转车上文冬,再到劳勿。我一路颠簸,脑海也颠簸,一路思绪翻腾。刘钦洲也真不容易,他是那种血性汉子,进入森林做武装斗争,驳火、缺粮、受伤、撤退到泰南,吃尽苦头,好不容易熬到89年合艾和平条约签署,终于可以回国了。很多归国马共卖保险、当小贩、做建筑散工,把过往的乌托邦梦想扫进暗夜的冷枕下,但刘钦洲比任何人都有韧性,他回归田园,栽种起榴梿树来。
听说他的猫山王榴梿品种发展得不错,甚至打开了中国市场。
傍晚时分,我终于到达了劳勿,刘钦洲早已在车站等候,驾驶他的吉普车载着我,兜到旧街吃山水酿豆腐。旧街面前是大河,雨季常常涨大水,平时河里漂浮着从上游顺流而下的树桐。但近年来树桐产量少了,河水也渐渐干涸。
“发展呀,发展,到处都在发展。”
“是呀,环境也遭受破坏!”
吃了嫩滑美味的酿豆腐,就直赴他的猫山王榴梿园。
“老陈,一切可安好?”
“脊椎骨有毛病,不过没有三高,还好。”
“我身子没毛病,可能是劳作的关系,劳碌命啊,病不起。本来我女儿在新村有屋子,但她跟老公孩子搬去了吉隆坡,我就索性住在榴梿园了。一方面方便照顾榴梿园,一方面防贼,尤其在榴梿季节,偷榴梿的贼特多,我申请了拥枪执照,有把猎枪,除了防贼,偶尔也拿来猎山猪、果子狸。地方简陋,委屈你了。”
“哪里哪里,我们蹲过甘文丁的,那里都是天堂了。”
“哈哈,果然是牢友!还记得甘文丁。”
与老战友见面,自是感慨万千。一路仍然颠颠簸簸,终于到了榴梿园山居木屋。
刘钦洲眉飞色舞,一路滔滔不绝大谈他栽种猫山王的心得,虫害啊,土质啦,还有新品种的培育,很耗费功夫。很多人都放弃了,但他坚持了二十多年,抱着当初进入森林做解放民族的无畏精神,终于有了今日的收成。提起冷冻猫山王在中国畅销,他更是喜不自禁。“哈哈,中国人终于知道榴梿是香的!”
本来这10英亩的榴梿芭地是女儿开垦的,但一直种不出好品种,有点心灰意冷,就跟随老公到吉隆坡巴刹做水果头盘生意去了。他在89年合艾和平条约签署后,放下武器回归,本无所事事,整天在山林间游荡,跟着土著去采撷山臭豆,赚点生活费。后来才打定主意,就招工开垦把这个山坡地都开辟了,栽种了猫山王。多年的研究、改良,品种得到口碑,无论卖到新加坡、中国都销路良好。加上年轻人在劳勿榴梿合作社设立网站,搞网上销售,更加红火,劳勿一下子变得闻名遐迩!
刘钦洲谈得兴起,把10年前去中国旅游买的“英雄好汉”酒特地挖了出来,与老陈畅饮。喝了几杯,刘钦洲突然“英雄好汉”情绪激昂起来,大骂州政府,还有中国来的联营公司代表,狼狈为奸,想吞掉他们的榴梿园。
“狼狈为奸?这……这到底怎么回事?”
“你没看到新闻?他们大规模买地,要种榴梿。”
“那不是让他种咯,各自耕耘,各自收成嘛!”
“才不是那回事!说起来就一肚子气,你知道吗?我辛辛苦苦开垦的猫山王榴梿园,快要没了!老陈,你评评理,我们的解放战争打了数十年,牢坐了,游击战打了,几乎命丧丛林。结果呢,现在却败在那小撮恶官僚和伪资本家手中。”
**3**
刘钦洲又开了一瓶“英雄好汉”酒。
我不得不耐心听他发牢骚了。
他总算理清一个事实。“35年了,劳勿榴梿园全靠当地农民的血汗耕耘,开疆辟土,而且不断改良技术,才有如今的猫山王规模,而且闻名遐迩。但至目前为止,70%的榴梿芭地仍然被列为非法芭,农民一再向州政府申请,再申请,都没有着落。他们甚至献议买下土地,但州政府都不理不睬。”
然而最近,因为猫山王榴梿打开了中国市场,他们才感觉到好景。
正所谓“瘦田无人耕,耕了有人争”,突然间,州政府批准了属下的“彭亨PHANGXX公司”,和来自中国的私人财团“XX榴梿集团联营公司”,一下子租下了劳勿接近5500英亩的非法榴梿芭地。包括了都赖、双溪兰、双溪吉流等地,租期据说是60年。
“60年?这不是摆明吞掉我们的榴梿园吗?”
“你们打算怎么办?”
“再闹一场革命吧!”
**4**
我了解刘钦洲的脾气,这次恐怕是吃不到榴梿,反而感受榴梿的棘刺了!
隔天,我跟随刘钦洲和一群榴梿农民来到了会场。那群农民的榴梿园都在联营公司5500英亩所划定的范围内,包括了各民族。
只见州政府官员和联营公司高层的豪华车停泊,排满了市政局外。农民则开着摩托或吉普车,或骑着脚踏车而来,场面热闹,自助餐和水果饮料摆满桌子,任凭享用。会议刚刚开始,马来农民已经迫不及待提出疑问:“我们已经种植了榴梿树,刚刚有了收成,怎么办?”
“就算要赶走我们,也应该有替代的土地让我们继续种植啊!”
“我们可是道道地地的劳勿人耶。”占多数的华族农民在怒吼。
州政府官员没有发言,把球踢给了XX联营公司的代表。XX联营公司的负责人梳了光油油的头发,西装笔挺,宛若人民代表大会的党干部,他语气冷飕飕,面无表情发声了:“我们没说要赶走你们,没错,我们是租下了都赖、双溪兰、双溪吉流5500英亩的土地,没有开垦的,我们会开垦,种植猫山王,已经有人在那儿栽种榴梿树的,可以继续……我们允许非法农民继续种植猫山王,但……但他们需缴付每英亩6000令吉的税务。”
“哇!6000令吉?这可是笔大数目啊!”
“这……这不是要我们白做?”
榴梿农民纷纷质疑,“我们怎么办?”
“这不是摆明逼我们走吗?”
继续发言的依然是冷面的XX联营公司负责人。“还有,请注意,未来你们所生产的猫山王,全部需根据协约,低阶出售给特定公司,也即是与XX发展公司的联营企业公司,不得私下转售。”
刘钦洲再也按捺不住了,抢了麦克风,质问负责人:“你们是否就是中国人的公司?他们与XX农业发展公司勾结,侵占了大片土地,还要压低价格买下每一季猫山王,我们农民只能做他们的廉价劳工?这太过分了,简直就是强盗!”他越讲越激动。“对,就是你们……就是你们,1978年,你已经抛弃了我们,你告诉我们华人,中国政府一向赞成和鼓励华侨自愿选择居留国的国籍,并效忠国家,遵守当地政府的法令与法律……那时,你已经背叛了千千万万在森林里为解放人民而战斗的革命者!背叛了抛头颅,洒热血的同志!”
“胡闹,这是风马牛不相及的事。”
“怎么风马牛不相及?我们唱的,难道不是同一首国际歌么?”
“我们在谈的是猫山王榴莲!”
农民们也禁不住喧嚣。“我们就要一个公道!”
群众大吵大闹!砸了桌子!
保安员护着州政府官员和联营公司高层,与榴梿园农民形成对恃局面。
我无端端夹在他们当中!
刘钦洲甩了椅子,继续对着XX联营公司的代表喊叫:“这世上还有天理么?我们牺牲了青春、热血、生命,得到的是什么?是切断支援、武器、弹药、军事顾问,什么都没有了。现在我们回去当农民,自力更生,又得到什么?你们富裕了,消费能力强了,喜欢吃猫山王,又回过头来剥削我们,买下我们耕种的土地,这什么世道?还讲革命友谊么?还讲无产阶级同盟么?还讲道义么?”
警察很快赶到,把刘钦洲和一些农民押走了。
刘钦洲甩开了警察,对拿着公事包的联营公司代表怒喊。“你听好了,我栽种的榴梿树,一棵都不会留给你们!我的猫山王榴梿,一粒都不留给你们!”
**5**
刘钦洲和那些农民都获保释了。
榴梿树结果累累,压弯了枝桠,这一季,算是丰收啊!
然而刘钦洲没半丝喜悦,他腰插巴冷刀,拿着猎枪,巡视榴梿园。
我很无奈,“钦州兄,我实在帮不到你们。”
“有心了,抱歉,这次你吃不到好榴梿了。”
“这就是大势所趋吧,贸易战、IT战,何况是区区的猫山王?”
“我就偏不服输!”
“你准备怎么做?革命时代已经过去了。”
刘钦洲突然转移话题,提起怎么消除害虫的经验。榴梿害虫有蚂蚁、毛毛虫、粉介壳虫,还有红蜘蛛。“我研究了很久,有一种农药可以毒死榴梿树。只要在树头洒几滴,一夜之间,树叶全掉,树身枯死。我……我真的一棵榴梿树也不留下给他们,等我的猫山王榴梿掉?休想,休想!休想!”
我以为刘钦洲只是发发牢骚,因旅途劳累,我先睡了。
半夜起风,呼呼直响,风越吹越劲,屋顶也像要被掀起来。
风吹、树摇,累累榴梿一颗颗像雨一般落下。
我悚然一惊,爬了起来。刘钦洲不是还在园地里么?他真的狠心毒死了树么?我冲出屋外,只见刘钦洲被一颗颗榴梿砸中,头破血流。他躺在树下,已奄奄一息。我冲上前,抱住刘钦洲,把他拖离榴梿树下,免得他被继续掉下的榴梿砸中。树上的猫山王仍然一颗颗噼啪噼啪落下。天蒙蒙亮了,晨曦中,只见一棵棵榴梿树的叶子纷纷掉落,枯萎了,树上的榴梿果,自然也不能依附在树枝上了,纷纷掉落——这就是刘钦洲的“诀别”。诀别了革命、诀别了农民、诀别了抗争,也诀别了他最引以为傲的猫山王榴梿。
我感到一阵莫名的悲凉。
作者 : 丁云
文章来源 : 星洲日报 2021-01-29
豆腐-汪曾祺
========================
豆腐-[[汪曾祺]]
-----
豆腐点得比较老的,为北豆腐。听说张家口地区有一个堡里的豆腐能用秤钩钩起来,扛着秤杆走几十里路。这是豆腐么?点得较嫩的是南豆腐。再嫩即为豆腐脑。比豆腐脑稍老一点的,有北京的“老豆腐”和四川的豆花。比豆腐脑更嫩的是湖南的水豆腐。
豆腐压紧成型,是豆腐干。
卷在白布层中压成大张的薄片,是豆腐片。东北叫干豆腐。压得紧而且更薄的,南方叫百页或千张。
豆浆锅的表面凝结的一层薄皮撩起晾干,叫豆腐皮,或叫油皮。我的家乡则简单地叫作皮子。
豆腐最简便的吃法是拌。买回来就能拌。或入开水锅略烫,去豆腥气。不可久烫,久烫则豆腐收缩发硬。香椿拌豆腐是拌豆腐里的上上品。嫩香椿头,芽叶未舒,颜色紫赤,嗅之香气扑鼻,入开水稍烫,梗叶转为碧绿,捞出,揉以细盐,候冷,切为碎末,与豆腐同拌(以南豆腐为佳),下香油数滴。一箸入口,三春不忘。香椿头只卖得数日,过此则叶绿梗硬,香气大减。其次是小葱拌豆腐。北京有歇后语:“小葱拌豆腐——一清二白。”可见这是北京人家家都吃的小菜。拌豆腐特宜小葱,小葱嫩、香。葱粗如指,以拌豆腐,滋味即减。我和林斤澜在武夷山,住一招待所。斤澜爱吃拌豆腐,招待所每餐皆上拌豆腐一大盘,但与豆腐同拌的是青蒜。青蒜炒回锅肉甚佳,以拌豆腐,配搭不当。北京人有用韭菜花、青椒糊拌豆腐的,这是侉吃法,南方人不敢领教。而南方人吃的松花蛋拌豆腐,北方人也觉得岂有此理。这是一道上海菜,我第一次吃到却是在香港的一家上海饭馆里,是吃阳澄湖大闸蟹之前的一道凉菜。北豆腐、松花蛋切成小骰子块,同拌,无姜汁蒜泥,只少放一点盐而已。好吃么?用上海话说:蛮崭格!用北方话说:旱香瓜——另一个味儿。咸鸭蛋拌豆腐也是南方菜,但必须用敝乡所产“高邮咸蛋”。高邮咸蛋蛋黄色如朱砂,多油,和豆腐拌在一起,红白相间,只是颜色即可使人胃口大开。别处的咸鸭蛋,尤其是北方的,蛋黄色浅,又无油,却不中吃。
烧豆腐大体可分为两大类:用油煎过再加料烧的;不过油煎的。
北豆腐切成厚二分的长方块,热锅温油两面煎。油不必多,因豆腐不吃油。最好用平底锅煎。不要煎得太老,稍结薄壳,表面发皱,即可铲出,是名“虎皮”。用已备好的肥瘦各半熟猪肉,切大片,下锅略煸,加葱、姜、蒜、酱油、绵白糖,兑入原猪肉汤,将豆腐推入,加盖猛火煮二三开,即放小火咕嘟。约十五分钟,收汤,即可装盘。这就是“虎皮豆腐”。如加冬菇、虾米、辣椒及豆豉即是“家乡豆腐”。或加菌油,即是湖南有名的“菌油豆腐”——菌油豆腐也有不用油煎的。
“文思和尚豆腐”是清代扬州有名的素菜,好几本菜谱著录,但我在扬州一带的寺庙和素菜馆的菜单上都没有见到过。不知道文思和尚豆腐是过油煎了的,还是不过油煎的。我无端地觉得是油煎了的,而且无端地觉得是用黄豆芽吊汤,加了上好的口蘑或香蕈、竹笋,用极好秋油,文火熬成。什么时候材料凑手,我将根据想象,试做一次文思和尚豆腐。我的文思和尚豆腐将是素菜荤做,放猪油,放虾籽。
虎皮豆腐切大片,不过油煎的烧豆腐则宜切块,六七分见方。北方小饭铺里肉末烧豆腐,是常备菜。肉末烧豆腐亦称家常豆腐。烧豆腐里的翘楚,是麻婆豆腐。相传有陈婆婆,脸上有几粒麻子,在乡场上摆一个饭摊,挑油的脚夫路过,常到她的饭摊上吃饭,陈婆婆把油桶底下剩的油刮下来,给他们烧豆腐。后来大人先生也特意来吃她烧的豆腐。于是麻婆豆腐名闻遐迩。陈麻婆是个值得纪念的人物,中国烹饪史上应为她大书一笔,因为麻婆豆腐确实很好吃。做麻婆豆腐的要领是:一要油多。二要用牛肉末。我曾做过多次麻婆豆腐,都不是那个味儿,后来才知道我用的是瘦猪肉末。牛肉末不能用猪肉末代替。三是要用郫县豆瓣。豆瓣须剁碎。四是要用文火,俟汤汁渐渐收入豆腐,才起锅。五是起锅时要撒一层川花椒末。一定得用川花椒,即名为“大红袍”者。用山西、河北花椒,味道即差。六是盛出就吃。如果正在喝酒说话,应该把说话的嘴腾出来。麻婆豆腐必须是:麻、辣、烫。
昆明最便宜的小饭铺里有小炒豆腐。猪肉末,肥瘦,豆腐捏碎,同炒,加酱油,起锅时下葱花。这道菜便宜,实惠,好吃。不加酱油而用盐,与番茄同炒,即为番茄炒豆腐。番茄须烫过,撕去皮,炒至成酱,番茄汁渗入豆腐,乃佳。
砂锅豆腐须有好汤,骨头汤或肉汤,小火炖,至豆腐起蜂窝,方好。砂锅鱼头豆腐,用花鲢(即胖头鱼)头,劈为两半,下冬菇、扁尖(腌青笋)、海米,汤清而味厚,非海参鱼翅可及。
“汪豆腐”好像是我的家乡菜。豆腐切成指甲盖大的小薄片,推入虾子酱油汤中,滚几开,勾薄芡,盛大碗中,浇一勺熟猪油,即得。叫作“汪豆腐”,大概因为上面泛着一层油。用勺舀了吃。吃时要小心,不能性急,因为很烫。滚开的豆腐,上面又是滚开的油,吃急了会烫坏舌头。我的家乡人喜欢吃烫的东西,语云:“一烫抵三鲜。”乡下人家来了客,大都做一个汪豆腐应急。周巷汪豆腐很有名。我没有到过周巷,周巷汪豆腐好,我想无非是虾子多,油多。近年高邮新出一道名菜:雪花豆腐,用盐,不用酱油。我想给家乡的厨师出个主意:加入蟹白(雄蟹白的油即蟹的精子),这样雪花豆腐就更名贵了。
不知道为什么,北京的老豆腐现在见不着了,过去卖老豆腐的摊子是很多的。老豆腐其实并不老,老,也许是和豆腐脑相对而言。老豆腐的佐料很简单:芝麻酱、腌韭菜末。爱吃辣的浇一勺青椒糊。坐在街边摊头的矮脚长凳上,要一碗老豆腐,就半斤旋烙的大饼,夹一个薄脆,是一顿好饭。
四川的豆花是很妙的东西,我和几个作家到四川旅游,在乐山吃饭。几位作家都去了大馆子,我和林斤澜钻进一家只有穿草鞋的乡下人光顾的小店,一人要了一碗豆花。豆花只是一碗白汤,啥都没有。豆花用筷子夹出来,蘸“味碟”里的作料吃。味碟里主要是豆瓣。我和斤澜各吃了一碗热腾腾的白米饭,很美。豆花汤里或加切碎的青菜,则为“菜豆花”。北京的豆花庄的豆花乃以鸡汤煨成,过于讲究,不如乡坝头的豆花存其本味。
北京的豆腐脑过去浇羊肉口蘑渣熬成的卤。羊肉是好羊肉,口蘑渣是碎黑片蘑,还要加一勺蒜泥水。现在的卤,羊肉极少,不放口蘑,只是一锅稠糊糊的酱油黏汁而已。即便是过去浇卤的豆腐脑,我觉得也不如我们家乡的豆腐脑。我们那里的豆腐脑温在紫铜扁钵的锅里,用紫铜平勺盛在碗里,加秋油、滴醋、一点点麻油、小虾米、榨菜末、芹菜(药芹即水芹菜)末。清清爽爽,而多滋味。
中国豆腐的做法多矣,不胜记载。四川作家高缨请我们在乐山的山上吃过一次豆腐宴,豆腐十好几样,风味各别,不相雷同。特别是豆腐的质量极好。掌勺的老师傅从磨豆腐到烹制,都是亲自为之,绝不假手旁人。这一顿豆腐宴可称寰中一绝!
豆腐干南北皆有。北京的豆腐干比较有特点的是熏干。熏干切长片拌芹菜,很好。熏干的烟熏味和芹菜的芹菜香相得益彰。花干、苏州干是从南边传过来的,北京原先没有。北京的苏州干只是用味精取鲜,苏州的小豆腐干是用酱油、糖、冬菇汤煮出后晾得半干的,味长而耐嚼。从苏州上车,买两包小豆腐干,可以一直嚼到郑州。香干亦称茶干。我在小说《茶干》中有较细的描述:
……豆腐出净渣,装在一个小蒲包里,包口扎紧,入锅,码好,投料,加上好香油,上面用石头压实,文火煨煮,要煮很长时间。煮得了,再一块一块从蒲包里倒出来,这种茶干是圆形的,周围较厚、中间较薄,周身有蒲包压出来的细纹,……这种茶干外皮是深紫色的,掰了,里面是浅褐色的。很结实,嚼起来很有咬劲,越嚼越香,是佐茶的妙品,所以,叫作“茶干”。
茶干原出界首镇,故称“界首茶干”。据说乾隆南巡,过界首,曾经品尝过。
干丝是淮扬名菜。大方豆腐干,快刀横披为片,刀工好的师傅一块豆腐干能片十六片;再立刀切为细丝。这种豆腐干是特制的,极坚致,切丝不断,又绵软,易吸汤汁。旧本只有拌干丝。干丝入开水略煮,捞出后装高足浅碗,浇麻油酱醋。青蒜切寸段,略焯,五香花生米搓去皮,同拌,尤妙。煮干丝的兴起也就是五六十年的事。干丝母鸡汤煮,加开洋(大虾米)、火腿丝。我很留恋拌干丝,因为味道清爽,现在只能吃到煮干丝了。干丝本不是“菜”,只是吃包子烧麦的茶馆里,在上点心之前喝茶时的闲食。现在则是全国各地淮扬菜系的饭馆里都预备了。我在北京常做煮干丝,成了我们家的保留节目。北京很少遇到大白豆腐干,只能用豆腐片或百页切丝代替。口感稍差,味道却不逊色,因为我的煮干丝里下了干贝。煮干丝没有什么诀窍,什么鲜东西都可往里搁。干丝上桌前要放细切的姜丝,要嫩姜。
臭豆腐是中国人的一大发明。我在上海、武汉都吃过。长沙火宫殿的臭豆腐毛泽东年轻时常去吃。后来回长沙,又特意去吃了一次,说了一句话:“火宫殿的臭豆腐还是好吃。”火宫殿的臭豆腐遂成全国第一。油炸臭豆腐干,宜放辣椒酱、青蒜。南京夫子庙的臭豆腐干是小方块,用竹签像冰糖葫芦似的串起来卖,一串八块。昆明的臭豆腐不用油炸,在炭火盆上搁一个铁箅子,臭豆腐干放在上面烤焦,别有风味。
在安徽屯溪吃过霉豆腐,长条豆腐,长了二寸长的白色的绒毛,在平底锅中煎熟,蘸酱油辣椒青蒜吃。凡到屯溪者,都要去尝尝。
豆腐乳各地都有。我在江西进贤参加土改,那里的农民家家都做腐乳。进贤原来很穷,没有什么菜吃,顿顿都用豆腐乳下饭。做豆腐乳,放大量辣椒面,还放柚子皮,味道非常强烈。广西桂林、四川忠县、云南路南所出豆腐乳都很有名,各有特点。腐乳肉是苏州松鹤楼的名菜,肉味浓醇,入口即化。广东点心很多都放豆腐乳,叫作“南乳××饼”。
南方人爱吃百页。百页结烧肉是宁波、上海人家常吃的菜。上海老城隍庙的小吃店里卖百页结:百页包一点肉馅,打成结,煮在汤里,要吃,随时盛一碗。一碗也就是四五只百页结。北方的百页缺韧性,打不成结,一打结就断。百页可入臭卤中腌臭,谓之“臭千张”。
杭州知味观有一道名菜:炸响铃。豆腐皮(如过干,要少润一点水),瘦肉剁成细馅,加葱花细姜末,入盐,把肉馅包在豆腐皮内,成一卷,用刀剁成寸许长的小段,下油锅炸得馅熟皮酥,即可捞出。油温不可太高,太高豆皮易煳。这菜嚼起来发脆响,形略似铃,故名响铃。做法其实并不复杂。肉剁极碎,成泥状(最好用刀背剁),平摊在豆腐皮上,折叠起来,如小钱包大,入油炸,亦佳。不入油炸,而以酱油冬菇汤煮,豆皮层中有汁,甚美。北京东安市场拐角处解放前有一家肉店宝华春,兼卖南味熟肉,卖一种酒菜:豆腐皮切细条,在酱肉汤中煮透,捞出,晾至微干,很好吃,不贵。现在宝华春已经没有了。豆腐皮可做汤。炖酥腰(猪腰炖汤)里放一点豆腐皮,则汤色雪白。
! 进行中
//待完成的任务清单//
<<list-tagged-draggable tag:"短篇小说" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"你没有待处理的任务">>
! 已结束
//(已完成的任务清单)//
<$list filter="[!has[draft.of]tag[短篇小说]tag[done]sort[created]]">
<div>
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
</div>
</$list>
短篇阅读 奥玛变种蝶 by 林耀德 - MONO猫弄
==========================
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [mmmono.com](https://mmmono.com/g/meow/1766560/)
**按:巨大废铁神像头顶的幽蓝光环、以音乐定位心灵原点的理想主义宗教、如音符般巡弋飘扬于空中的伊莲虫、集体如一的奥玛蝶及自由幻化的梦兽族。《时间龙》对未来太空种种精神、物质如其实在的诗 意描绘,营造出一个自足完备、具体而微的科幻世界,予读者以广阔的想象空间及深刻的生命思考。**
_________
---------
战争结束以后废墟间萌芽新绿的光泽,
死者得到了勋章生者却遗失了存在的依据,
沉重的星舰一排排被搜藏在冷寂的地底,
斗争的残像寄托在变幻的云层,
用不尽的子弹只好隐匿在隐痛的胸口。
往前走去,铺满锈桔梗的旷野中,
玄秘的雕塑种植在鸽羽灰的天光间,
废铁文明逸散着草莓的甜味;
那是一尊无动于衷的女体,
巨树般的电缆连贯她的下肢,
精致得几近残酷的金属回路,
盘绕在高耸的乳房。
没有表情,她的手势指向
半空中的一扇铜扉。
门启处,人类的前身蹲踞在
冰河深处的冻色中。
中校将登山用的钢爪扣住一块凸出的电路板上,继续朝向鸽羽灰的天光接近。
灰蒙蒙的天外有无数悬浮的星球,有的带中校将登山用的钢爪扣住一块凸出的电路板上着七彩的光环,有的孤绝得像一团冰块,有的是虚妄的气团,有的只是一块燃烧的大废铁。
中校继续向上攀爬。攀登这尊三百九十五公尺高的雕像,曾经是他一生最大的愿望之一。
这尊古怪的巨像是五个世纪前一度兴盛于澳洲大陆的废铁教所建立的。
废铁、钢筋、被弃置的车辆、报销的古董电脑、缺了门的冰箱、折断的电锯、生锈的订书机和图钉、金属百叶窗的残骸、狗链、闹钟壳、拆散的货柜、扭曲的下水道铁盖、死人口中拔下的金牙、旧海军制服上拔下的铜扣、从大厦卸下的铝门窗、无数不同口径的电缆线以及一千多万公吨的合金,组构了地球历史上最诡异的一座神像。
三十万教徒整整花费了七十五年才建立起这个无名神像,然后这些徒众像清晨的雾一样消失在历史之中。
一个没有教主、没有教义的宗教,这三十万人如何凝结在一起恐怕永远是宗教史上的一个谜。
神像静肃地站在大草原的中央。
中校正爬上神像乳房的尖端,他突然醒悟了五个世纪以前那些蝼蚁般的废铁教徒在想些什么。
因为中校感受到的,只是一片空茫。五个世纪以前的人类,他们所追求的也只是一片空茫。
神像左乳房的部位,一架巨无霸客机的机首巧妙地突出成为乳晕。中校以非常勉强的姿势,倒悬着,用钢爪和膝盖上的吸盘缓缓爬行在巨大的弧度上,他仰首望见的不是灰色的天幕,而是呈现锈桔梗色的大草原,他停放在神像脚下的丰田机车像是掉落在红褐色地毯上的一粒芝麻。
在神像的乳部,距离地面两百多公尺的高度,中校依稀看出古代修筑的公路。
一道道笔直宽敞的公路以神像为核心,从全澳洲的城市汇聚来此,墨尔本、悉尼、乌斯班尔、国木市、新台北、爱德华霍克堡、阿诺城…… 从澳洲二十七个自由市伸向荒原中央的二十七条主干线,已经荒废了几个世纪。
五个世纪以前,源源不绝的车阵,运载着废铁教徒从二十七个城市中搜集来的金属,一座冶金厂在神像预定地的一侧建造起来,一排排巨硕的烟管耸立着,将整片天空渲染成淡墨色泽。
在建造神像的第七十四年,亦即地球纪元 2201 年,三百多名教徒持着锅铲、菜刀、高尔夫球棍和霰弹枪,冲进了占地三公亩的墨尔本联邦雕塑博物馆。在那一次的浩劫中,包括纪元前五百年的中国上古铜鼎和二十世纪西班牙超现实主义大师米罗的雕塑,全部被洗劫一空,各种珍贵的古代艺术结晶整整装满了五十三个货柜。
中校相信,那些教徒绝没有鄙视艺术品的意思,他们如果不珍惜这些艺术品,也不会让它们镶嵌在雕像的表面;只不过,教徒们之所以珍视这些艺术,是因为它们被视为最昂贵的垃圾。
那是中校在联邦军事学院 “人类近古艺术史” 选修课程时留下的记忆,那门课是中校唯一没有拿到九十分的课程,教授给了他七十五分,却是这位华裔教授一生中给过的最高分数;中校那年的期末报告是《废铁教巨像与近古人类生物辐射指数之关系》。
中校停顿了一刻钟,血液源源流入倒悬的脑部,他的意识被鲜红的血球自空蒙的境界中冲回现实的岩岸。
继续向天空的方向缓缓挪动,他丝毫也不恐惧自己处身的高度;在他的职业生涯中有大半是在这个星球的大气层之外几十万、几百万光年的地方度过。
中校只是地球的过客。
他是出生于磁气星的地球移民后裔。
多年来,他一直认为地球政府和其敌人新丽姬亚帝国两者不过是一丘之貉,唯一的差别,是地球政府提供他兵器和军队,而丽姬亚人和他们的母舰则是他消耗弹药的巨大玩具。
因为联邦教育当局的洗脑策略失败,中校对于地球前途的关切远逊于他对女人的喜好,而他所攀爬的这座巨像,广义地说,也算是女人的一种。
但是,这一切,都比不上他对战争的狂热崇拜。
一阵阳光穿越积云,投射在巨像五颜六色、光怪陆离的表面上,一层层波浪般的金属光泽回环着,站在乳房上的中校感到强烈的晕眩。
闭目吐纳之后,中校右手勾住一具战车的防弹壳,轻盈纵跳,跃上一片凸露的钢板,左手的钢爪脱掌火速射出,钉入十公尺上方接近巨像胸骨中央的位置,恰好那位置嵌进一尊二十世纪华人塑像,钢爪的四指沉沉插入塑像的心脏部位;几乎就在同一瞬间,他的身躯也随着钢爪末端丝线的缩短,面向上空腾跃。
就在腾跃的霎时,他也发现一只变种蝴蝶。
一只变种蝴蝶,展开三公尺半长度的一对翅翼,盘旋在神像头颅的正前方。
它穿越阳光形成的白色光束,靛蓝色的粉末静静地,随着翅膀的飘动而散扬在大气中。
中校注视着变种蝴蝶的移动,一种带着邪恶感的优雅,蝴蝶腹部的鬼面图案,似乎正不断变换着眼神和笑容,带着嘲弄的恶意展现在他的眼前。
一只变种蝴蝶幽然朝向巨像头顶浮升,接着是两只、五只、十只…… 迅捷地,从中校视角所不及的巨像后颈部位,汇集成弯曲的河流奔涌出来,几乎遮蔽了中校的视野,大气中不断扩散着蓝色的磷粉。
数以千万计的变种蝴蝶,集体扇动空气的沉闷声响,使得中校产生被卷入海潮中的幻觉。
这种奥玛变种蝴蝶,在原产地奥玛星的旷野中只有手掌般大小。半世纪以前它们因为观赏价值被引入地球的澳洲,因为生态环境的改变,产生了展翅达三公尺半的巨型突变种,五十余年来已经使得澳洲所有的农业区一蹶不振。但是,它们结合了废铁教巨像,却造成了独特的星际奇观——“神像光环”。
受制于唐氏跨星集团的地球联邦政府,根本无力防治这种对任何药物及放射线都产生免疫力的奥玛变种蝴蝶;他们唯一的功绩只是让它们不扩散繁衍到澳洲之外的地区。理由非常讽刺,因为,它们的生命周期不足以横越广大的海洋。
到了繁殖期,奥玛变种蝴蝶便在神像头部的位置盘桓,成群回翔,从远方望去,如同神像头上浮现了一道闪烁着幽蓝色环的光圈。在二十七世纪的最后一年,联邦首都的三千五百二十七名外星裔记者将这个景观票选为地球十大奇观之九。
正当中校沉醉在变种蝶的幻境时,胸前的红钮以独特的频率响亮起来。中校懂得讯号的意义:一个强制取消休假的紧急任务。他放松钢爪,切断膝盖吸盘的能量,让自己从两百多公尺的高楼坠落而下,地面升起的风猎猎吹贯他的耳际,他闭目计时,用牙齿咬开口中的隐藏开关,背后的推进器立即发动。
澳洲的假期结束了。在中校缓缓降落在地面之前,他仰望着天空苦笑,逐渐接近地面,觉得自己就像是一颗在堕胎手术中被金属器械活生生刮成血浆的胚胎。
七年前,当联邦与新丽姬亚帝国的 “二十年战争”(地球纪元 2674—2694 年)结束时,身在前线战区的中校也曾经拥有类似的感受,而且更为强烈。很少人能够理解,除非他本身是一个真正的军人。一个真正的军人才会理解远离战争的恐惧。
中校知道,这件迫使他取消澳洲假期的紧急任务,顶多是一桩小儿科的劫机案,或者是追捕一个无聊的流莺猎杀者。这些任务使得他感到自己正在急遽地退化。
无数的中校,遍布在地球本部和它的殖民星中。停战协定使得他们逐渐枯萎,逐渐变成无法适应平凡生涯的平凡人类。
**本文节选自《时间龙》,林耀德著,后浪 · 四川文艺出版社,2020 年 4 月版**
**内容简介:唐氏跨国企业控制的地球联邦以放弃基尔星为条件而换取了新丽姬亚帝国的和平保证,围绕着新丽姬亚帝国对基尔星的接收,一幕幕鲜血与欲望的表演粉墨登场…… 三十年后,统治独立星奥玛近半世纪的大统领克里斯多娃被副统领王抗囚禁在人工游星之中。奥玛的危机不在于克里斯多娃被王抗取代,而在于谁将及时取代王抗……**
短篇阅读 岛 by 维多利亚·希斯洛普
- MONO猫弄[https://mmmono.com/g/meow/1774805/](https://mmmono.com/g/meow/1774805/)
# 短篇阅读 | 岛 by 维多利亚·希斯洛普
作者:维多利亚·希斯洛普
**按:没有人是一座孤岛,在大海里独踞;每个人都像一块小小的泥土,连接成整片陆地。**
## _______
“我得说,‘我要从最开始讲起’,可其实并没有一个真正的开始。” 她说,“你母亲的故事就是你外婆的故事,是你曾外婆的故事,也是你姨外婆的故事。她们的生活纠缠在一起,我们希腊人谈到命运时,就是这个意思。所谓宿命主要是由我们的先辈而非星宿决定的。当我们谈到古代历史,我们常常说命中注定—可是我们并不是指不可控制的事情。当然事件可能突如其来地改变我们生活的轨迹,但真正决定什么会降临在我们身上的,是我们周遭那些人的行为,以及那些生活在我们之前的人的行为。”
阿丽克西斯不安起来。那装着母亲的过去、固若金汤的保险柜,那曾毅然决然地把母亲整个生活锁在里面的保险柜就要被打开了。所有的秘密将全部倾倒出来,她发现自己有点怀疑:难道真的想这样吗?她凝视着大海对面斯皮纳龙格灰色的轮廓,想起了那个孤独的下午,她已经有点怀念那里了。潘多拉后悔打开了她的盒子。难道她也会吗?
佛提妮注意到阿丽克西斯一直凝视的方向。
“你曾外婆在那个岛上生活过,” 她说,“她是麻风病人。” 她没料到她的话听上去那么直率,那样无情,她一眼就看出它们让阿丽克西斯退缩了。
“麻风病人?!” 阿丽克西斯吃惊得结结巴巴。这让她不快,尽管她明白这种反应或许有点不礼貌,可她实在难以掩饰自己的感情。她已经知道那个老渔夫曾得过麻风病,自己还曾亲眼见过他,但他身上并没有肉眼可见的畸形。不过,听到与自己这样亲的人曾患过麻风病,她还是觉得十分震惊。这是完全不同的感受,很奇怪,她觉得恶心。
对于佛提妮来说,她从小就在隔离区的阴影下长大,麻风病一直是严酷的生活现实。她见过数不清的麻风病人来到布拉卡,渡海而过,去往斯皮纳龙格。她也见过不同样子的麻风病人:有的变形扭曲,严重的甚至残疾;有的外表没有明显变化。实际上,他们最后的样子都让人不敢触碰。她理解阿丽克西斯的感受。那些人对麻风病的了解仅来自《圣经· 旧约》故事和画有手摇铃铛叫着 “不洁净!不洁净!” 的受难者的图片,对他们而言,这是最自然的反应。
“我来再解释一下,” 她说,“我知道你想象中的麻风病是什么样的,但你最好知道真相,否则你永远不了解真实的斯皮纳龙格。斯皮纳龙格是许多好人的家。”
阿丽克西斯继续凝视着波光粼粼的海那边的小岛。她昨天去那里的参观似乎充满了许多相互矛盾的画面:优雅的意大利风格的别墅遗迹、花园和整齐的商店,而疾病萦绕在心头的恐惧却让它们黯然失色,她曾在史诗般的电影里见过活死人一样的麻风病人。她咽下一大口浓咖啡。
“我知道不是每个得了麻风病的人都会死,” 她说,几乎是在辩解,“可是总是会变得很丑,不是吗?”
“根本不是你想的那样,” 佛提妮回答道,“它并不会像瘟疫那样迅速蔓延。有时候很长时间后才会发病—你看到的那些有着可怕残疾的人都受了多年疾病折磨,也许是几十年。麻风病有两种,有一种病情发展得比较慢。不过现在两种都可以治愈了。可是,你的曾外婆很不幸,她得的是发病很快的那种,时间和幸运都没有站在她这一边。”
阿丽克西斯为她先前的反应有点难为情,为自己的无知感到惭愧,可是家族中有人得过麻风病的真相对她来说无异于晴天霹雳。“你的曾外婆伊莲妮得了这个病,可是你的曾外公,吉奥吉斯,也受到深深的伤害。在你曾外婆被逐到斯皮纳龙格之前,他就一直用他的渔船为这个小岛运送物资,你曾外婆去那里之后,他继续运送。就是说,他几乎眼睁睁看着她的病情一天天恶化。伊莲妮刚去斯皮纳龙格的时候,卫生条件还很差,虽然后来改善了许多,可她年轻时某种无法挽回的损伤已造成了。我无法告诉你具体情况。吉奥吉斯也没有详细告诉过安娜和玛丽娅。可是你确实知道麻风病是怎么回事,是不是?麻风病会影响神经末梢,即使你烧伤或砍伤自己,你都感觉不到。这就是为什么得麻风病的人那样脆弱,容易令自己
遭受永久性的损害,其后果是灾难性的。”
佛提妮停下来。她很担心,不想刺激这个年轻女子的敏感神经,可是她也意识到这个故事中有些内容少不了会让人震惊,她得小心翼翼地一步一步来。
“我不想让你觉得你妈妈全家都被麻风病控制了。不是那样。” 她匆忙加上一句,“看,我这里有些他们的照片。”
紧挨着咖啡壶有个木质托盘,上面有个破旧的牛皮纸信封。佛提妮打开信封,里面的照片全滑到桌上。有些照片像火车票一样大,另外有些跟明信片大小相仿,有些是光面的,还带一圈白边,其他的是亚光的。所有照片都是黑白照,有些褪了色,看不太清了。许多都是在还没有快照的年代里去照相馆照的,照片里人们僵硬的姿势让他们看起来遥远得有如米诺斯国王。
阿丽克西斯注意到第一张照片里的人她认识。照片上是母亲和那位穿蕾丝衣服的女士,一位银灰色头发的男子站在床边。她把这照片拿起来。
“那是你姨外婆玛丽娅和姨外公尼可拉斯。” 佛提妮的语气中有一丝明显的骄傲。“这张,” 她说着从那一堆照片底下抽出一张很残破的照片,“是你曾外婆外公和他们的两个女儿的最后一张合影。” 她把那张照片递给阿丽克西斯。照片里一男一女一样高,只是男人的肩膀要宽些。他一头光滑发亮的黑色头发,唇上的胡须修剪得整整齐齐,鼻子长而挺,尽管因为照相的缘故做出很严肃的表情,眼里还是盈满笑意。他的手与身体比起来,似乎大得有些不合比例。身旁的女人很苗条,长长的脖颈,异常美丽;她的头发编成辫子盘在头上,笑得那样灿烂那样自然。坐在他们前面的是两个穿着棉布裙的女孩。一个很结实,浓密的头发披在肩上,眼睛斜瞟着如猫一般。她眼神顽皮,嘴唇丰满,没有笑意。另一个女孩编着整齐的辫子,容貌更精致,当她冲着照相机笑时鼻子微微皱起。她瘦得差不多像根竹竿,在两姐妹中长得更像母亲些。这个女孩双手温柔地放在膝上,一副娴静姿态,而她的姐姐两手交叉抱在胸前,盯着照相的人,好像蔑视着他。
“那是玛丽娅。” 佛提妮指着那个微笑的女孩说。“这个是安娜,你的外婆。” 她又指着另外两人说,“这是她们的父母,伊莲妮和吉奥吉斯。”
她把相片摊在桌上,偶尔有风吹过,相片轻轻舞动,好似有了生命。阿丽克西斯看着这两姐妹的照片,从她们还是被抱在怀中的婴儿,到小学生,然后到年轻姑娘—那时候只有父亲陪伴她们。还有一张是安娜和一个身穿全套克里特传统服装的男子手挽手照的。那是一张结婚照。
“这一定是我外公吧。” 阿丽克西斯说。“安娜看起来真的好美啊,” 她羡慕地说,“真的很快乐。”
“嗯……散发着年轻的爱。” 佛提妮的声音里有一丝挖苦之意,让阿丽克西斯很吃惊。她正要继续问下去,另一张照片冒出来,吸引了她。“看起来真像我妈妈!” 她嚷道。照片中的小女孩有着与众不同的鹰钩鼻,笑容甜蜜羞涩。
“确实是你母亲。她那时应该才五岁。”
就像任何家庭影集一样,随意拿起的一张照片只能讲述一些零碎片断。真正的故事只有那些不见了的相片才能讲出来,也许照片根本就不能讲述,生活中的故事绝不是这些仔细框起来或整齐地保存在信封里的照片能诉说的。阿丽克西斯明白这一点,但至少她看到了这些家族成员,这些母亲长期保密的家族成员。
“故事要从布拉卡开始,” 佛提妮说,“就在我们身后,那边。那是你曾外公佩特基斯一家住的地方。”
她指着远处角落里的一所小房子,离她们坐着喝咖啡的地方仅有一箭之遥。那是座破旧的房子,刷着白灰。在整体摇摇欲坠的村庄里,那房子和其他房子一样破败不堪,却又十分迷人。墙上的涂料在剥落,百叶窗上的也是。阿丽克西斯的曾外祖父母住在这里时,会不时地重新粉刷,用的是明亮的淡绿色。墙皮在炎热里剥落、开裂。阳台就建在门道上方,阳台上放着几口大瓮,里面种着火焰般鲜红的天竺葵,瀑布一样垂下,仿佛想从雕花栏杆中逃离。大瓮的重量压得阳台往下陷。这是典型的克里特民居,过去几百年来,这种房子建了又建。像那些没受到大量游客蹂躏的幸运村庄一样,布拉卡是永恒的。
“你外婆和她妹妹就在那里长大。玛丽娅是我最好的朋友,她只比安娜小两岁。她们的父亲,吉奥吉斯,像许多当地人一样,是个渔夫。而他的妻子伊莲妮,是位老师。实际上她真的远不止是位老师——她还管理着当地的小学。学校就在通往伊罗达的路上,那个小镇你一定经过了,是来这里的必经之路。她爱孩子,不光爱自己的女儿,也爱班上所有的孩子。我猜安娜肯定觉得很难接受。她是个占有欲很强的孩子,讨厌与别人分享,特别是她母亲的爱。可是伊莲妮慷慨无私,无论是对自己的血肉,还是对学生们,全都倾注了足够的时间。
过去我总假装是吉奥吉斯和伊莲妮的另一个女儿。我老是住在他们家。后来情况变了,不久,玛丽娅和安娜经常住到我们家。
那个时候我们的游乐场就是沙滩,小时候,我们都在沙滩上度过。沙滩是变化无穷的地方,我们从不会觉得闷。从五月开始,到十月初,我们每天都会去游泳,晚上睡觉时,沙子从我们脚趾缝里漏到床单上,让人难受得坐卧不宁。晚上我们自己钓黑棒鲈,一种小鱼。”
“这种成长经历听起来像田园诗般美好。” 阿丽克西斯陶醉于佛提妮描述的美好的、仙境般的童年。但是她更想知道这一切是怎么结束的。“伊莲妮怎么得上麻风病的?” 她突然问,“得麻风病可以离开这座小岛吗?”
“不行,他们当然不能离开。正是这一点让这座岛如此恐怖。上个世纪初,政府宣布将克里特的所有麻风病人隔离在斯皮纳龙格。一旦医生确诊他们得了麻风病,他们就得永远离开自己的家,去那座岛。那里被称作 ‘活死人之地’,没有比这更恰当的描述了。
那时,人们想尽一切办法隐藏自己的症状,主要是因为确诊的后果太可怕了。伊莲妮对被学生传染麻风病的危险毫不在意—要她别跟学生们坐在一起去教他们,她做不到。如果一个孩子摔倒在满是灰尘的操场上,总是她第一个把他扶起来。后来她的一个学生得了麻风病……” 佛提妮停下了。
“所以你觉得身为父母的,肯定知道他们的孩子染上了麻风病?” 阿丽克西斯不敢相信地问。
“几乎可以肯定,” 佛提妮回答,“他们知道,一旦有人发现,他们将再也见不到这个孩子。伊莲妮得知自己感染上麻风病后,只有一种负责的做法——她也这么做了。她要求学校里的每个孩子作检查,这样可以确定感染者。果然,一个名叫迪米特里的九岁小男孩感染上了。他可怜的父母只好忍受着儿子被带走的恐惧。但是不带走的话更可怕。想想孩子们玩起来时的情形吧!他们不像成人,可以保持一定距离。他们扭打在一起,互相往对方身上扑,一齐压在别人身上。我们现在知道这个病通常只通过持续密切的接触传播,可是当时人们担心,如果他们不尽快把受感染的学生找出来隔离的话,伊罗达学校本身就会成为麻风病隔离区。不久他们就找出来了。”
“对伊莲妮来说,那样做一定很困难—特别是她与学生们的关系那般密切。” 阿丽克西斯若有所思地说。
“是啊。很糟糕。对每个与此有关的人来说,都很糟糕。” 佛提妮回答道。
阿丽克西斯的嘴唇很干,她几乎不再说话,以防张口却说不出什么。为打发时间,她把自己的空杯子往佛提妮面前推了推,佛提妮添满杯子,再推回来。当阿丽克西斯小心地把糖倒入旋转的黑色液体中时,她觉得自己也被卷入伊莲妮悲伤而痛苦的旋涡中去了。
那是种什么感觉?在家人的注视下离家远行,实际上是被投入监狱,你最宝贵的一切都给剥夺了。她不但想着那个是她曾外婆的女人,也想着那个男孩,他们都一样,没犯任何罪,却被判了刑。
佛提妮伸出手,放在阿丽克西斯手上。也许她太急切了,还没真正了解这个年轻女子就讲了这个故事。这可不是童话,她不可能选某些章节讲,而忽略掉另一些。如果她太过小心,真实的故事可能永远也讲不出来。她注意到阿丽克西斯脸上飘过的云朵,不像早晨蓝天上的丝丝淡云,现在它们是阴沉的、若隐若现的。直到现在,佛提妮猜,阿丽克西斯生命里唯一的阴暗不过是母亲隐藏过去带来的模糊阴影。它只不过是个问号,让她晚上睡不着觉而已。她从没见过疾病,更不要说死亡。可现在,这两样她都得马上了解。
“我们去走走吧,阿丽克西斯。” 佛提妮站起来,“等会儿我们让杰拉西摩带我们出海。当我们到那边时,一切都会更合情合理的。”
阿丽克西斯正需要散步。母亲过往的这些碎片,加上过量的咖啡因,让她有点头晕。她们从木头台阶上走下来,来到布满小石子的海滩上,阿丽克西斯大口呼吸着带咸味的空气。
“为什么妈妈从不跟我说这些?” 她问。
“我相信,她有她的理由,” 佛提妮说,“也许当你回到英国,她会跟你解释为什么要这样保密。”
她们漫步到海岸尽头,开始走上石子小路,路边是起绒草和薰衣草。这条路远离村庄,风也大多了,佛提妮的脚步慢下来。她虽然很健康,可毕竟已年逾七旬,不可能总是保持以前的体力。当小路开始陡峭起来时,她走路越来越小心,越来越蹒跚。她偶尔会停下来,时不时指着进入视线的斯皮纳龙格岛上的某些地方。最后,她们来到一块巨大的岩石旁。这块岩石长年经受风吹雨打,加之被人用作长椅,已磨得很光滑了。她们坐下来,望着海面,风把她们身边浓密的野生百里香吹得沙沙直响。佛提妮坐下,开始讲述索菲娅的故事。
接下来的几天里,佛提妮知无不言,告诉了阿丽克西斯她所知道的关于阿丽克西斯家的一切—小到童年琐事,大到克里特岛的历史。两个女人一起沿着海岸边的小路漫步,在午餐桌前坐上几个小时,或坐着阿丽克西斯租来的车去当地小镇和村庄小游,佛提妮把佩特基斯一家的往事像七巧板似的在面前一块一块摊开。这些天来,阿丽克西斯觉得自己越来越成熟,越来越睿智,佛提妮呢,在重述这么多她的过去时,觉得自己又年轻了。阻隔这两个女人半个世纪的鸿沟消失不见了,当她们手挽手散步时,有人还以为她们是姐妹呢。
**本篇节选自《岛》(2020 版),维多利亚·希斯洛普著,新经典文化·南海出版公司,2020 年 9 月版。**

**内容简介:多年来,阿丽克西斯发觉母亲总是过分地守护着自己的过去,不仅掩埋了自己的根,还把上面的泥土踩得结结实实。阿丽克西斯决定打开母亲尘封的过去。她来到爱琴海边的一座小镇,登上一座叫斯皮纳龙格的荒凉小岛。**
**这曾是一处禁地,一处令小镇、爱琴海,甚至整个欧洲都谈之色变的禁地,更是母亲的禁地。禁地打开,这座看似废弃的小岛展露出令人意想不到的明媚生机,而一个沉寂半世纪的惊人秘密即将浮现......**
短篇阅读 灯泡拜伦的故事 by 托马斯·品钦
===============================
**按:哈罗德·布鲁姆说:“我们目前正处于品钦的时代,一个人造物和偏执狂的时代,被系统控制。品钦惊人的创造性,在于他再现了挑战系统的冲动,即便这种冲动和再现总是被击败。”《万有引力之虹》不仅是一本有如神助完成的大百科全书。它对这个世界深刻的预言性和未来感,让它的分量和价值历久弥新。数十年来,它已发酵成为文学界的第一奇书,不断撩拨着阅读的挑战者,激发着炫酷、前卫的灵感,也一直在等待着未来真正的读者去挑战它。虽然迄今为止,没人敢说真正读懂了它,但也没人敢就此错过。仅仅翻开,就是一件值得炫耀的事。一个纷杂混乱、变幻不定的时代,需要一本伟大的、高于我们的书来定义。《万有引力之虹》,我们这个时代的代言书。**
## __________
拜伦本应该由布达佩斯的汤斯兰生产的,如果是这样就很可能又碰巧被王牌推销员盖佐·罗饶沃尔基的父亲桑多尔拿到。桑多尔的工作范围覆盖了整个特兰西瓦尼亚,完全融入了这个地方,总部甚至隐隐怀疑,如果他们不满足他的要求,他就会给整个项目下凶咒。其实,他只是一个推销员,希望自己的儿子能做医生,愿望也实现了。也许是因为布达佩斯那边对巫术有些疑神疑鬼,拜伦的出生地在最后一分钟被改派到柏林的欧司朗。改派,没错。有一个 “灯泡婴儿天堂”,名字有点像一部电影,含有温和的讥讽意味——哦,好大的生意,哈哈!不过别让 “他们” 把你给骗了,这其中最主要的是权力问题,灯泡婴儿天堂只是副业而已。整个头上——没错,公司自己掏钱买了大块大块的蝉翼纱,大桶大桶染共体的粉红色和蓝色婴儿染料,几十斤几十斤的西门子灯泡婴儿电奶嘴,把吸奶的婴儿塑造成 110 伏电流的形状。这些活生生的灯泡们以这种或那种方式做着让电流显形的工作,电流在夜晚的背景上显形,却又并非真正的实体。
其实,“灯婴天堂” 很简陋。棕色的屋椽下布满了蜘蛛网。地板上时不时会出现一只蟑螂,所有的婴儿都想滚过去看(小骚货啊,他们是灯泡,好像非常对称,不过别忘了灯丝头上的接触部),喊着嗯啊!嗯——啊!微弱的灯光照在迷乱的蟑螂身上。蟑螂瘫软而无助地蹲在无遮无拦的木板上,或者跑来跑去,回味着头上高高的地方那盏闪烁的、洞悉一切的灯泡和不知从哪里冒出来突然放光的电流给它带来的恐惧。婴儿灯泡们很天真,不知道如何处理蟑螂的疏泄——他们感到了他的惊恐,但不知惊恐为何物。他们只想和它做朋友。它挺有趣,移动又快。除了拜伦,人人都很激动。拜伦觉得其他婴儿灯泡是一群傻瓜。要让它们思考有意义的问题总是很费劲。嘿,宝贝们,我是灯泡拜伦!我给你们唱一首歌,是这样的——
点起来,亮起来,白炽的婴儿灯泡们!
你们好像得了狂犬病
躺在那儿吐白沫发尖声,像魔鬼一群,
交给你一个蟑螂的王国,
你挂在天花板上俯阅
你监管的王国,日夜不歇,
那是无与伦比的快乐感觉!
它们会出来爱你,直到拂晓,
灯光一亮,它们就慌忙逃跑!
继续闪亮吧,婴儿灯泡们,你们是未来的浪潮,
我来这里是为了把你们征召,
参加我的十字军讨伐,
继续唱宝贝们——来-加-入-我-长长的-队伍吧!
拜伦的问题在于太老,灵魂很老却又困在婴儿灯泡的玻璃监狱里。他讨厌这个地方,仰躺着等待被制造出来,音箱里什么也听不到,只有查尔斯顿舞曲,偶而还有一次全国性讲话。那是什么设备呀?拜伦想从这里出去,进到音箱里。不用说,他得了各种神经疾病、灯泡婴儿尿疹(螺丝上有些生锈)、灯泡婴儿腹痛(环状钨丝下面某处因高电阻导致的痉挛)、灯泡婴儿呼吸过速(虽然没有呼吸器官,却实实在在感觉自己的真空状态遭到了破坏)……
战斗动员日终于来临了,拜伦当然高兴极了。他一直在盘算一些非常疯狂而宏伟的计划——他要把所有的灯泡组织起来,在柏林建立一个电力基地,对于闪光术他早已精通,你只要修炼功夫(几乎是瑜伽),把开关频率掌握得接近人类大脑的 α 波状态,就能引发癫痫病!真的。拜伦曾经在自己房间的椽子上预见了整个欧洲两千万只灯泡的情景:他在电网中有众多代表,在其中一位的组织下,这些灯泡全体以同步脉冲同时开始闪光,两千万个房间里的人狼奔豕突,像海岸上精力十足的鱼——人啊,你们注意了,这是一次警告。下一次,我们有几个会爆炸。哈-哈。没错,我们会派出我们的神风突击队!你听说过吉尔吉思之光吗?和我们要——那个的相比,简直就是萤火之光——哦,你没听说过那个——哦,太不幸了。因为有几只灯泡,也就一百万只吧,占我们总数的 5%,非常愿意来一次辉煌的放光,而不愿耐心按照预定寿命苟延残喘……就这样,拜伦等待着自己的游击武装来一次联合爆炸,准确地击中赫伯特·胡佛和斯坦利·鲍德温的脸……
拜伦注定要梦幻破灭、幡然省悟的。已经有一个组织了,人类的组织,叫 “太阳神”,是国际灯泡卡特尔,总部在瑞士,主要由国际通用电气、欧司朗和英国的联合电力工业来管理。这三个公司中,美国的通用电气公司分别持有 100%、29%和 46%的股份。太阳神为世界上所有的灯泡确定价格和使用寿命,包括巴西、日本、荷兰——不过荷兰的飞利浦是这个卡特尔里的疯狗,随时会脱离出去,给整个联合体埋下灾难的种子。鉴于这种阻力重重的状况,一只新出生的灯泡就只能底层做起了。
不过太阳神还不知道拜伦是永生不死的。他的生涯始于一个全是女孩的鸦片窟,在夏洛顿堡,大约能看见维尔纳·西门子的塑像。他在一个灯架上燃烧着,和其他许多灯泡一起见证了共和政治更严重的没落和腐朽。他认识了整个地方的所有灯泡。隔壁灯架上的灯泡本尼托总是想逃跑,顺着过道进了厕所里,就可以看见伯尔尼,他有各种与尿有关的黄笑话要讲,他妈妈布仁妲在厨房谈论大麻油炸玉米饼、临时用来把复方樟脑酊带来的性兴奋泵入子宫毛细血管的假阴茎、对阿丝塔特和丽丽丝的祷告——夜之女王丽丽丝把手伸入另一个世界的夜晚,真正意义上的夜晚,冷冰冰赤裸裸地躺在油毛毡的地板上,已经好多天没睡觉了,梦和眼泪已经成为常态……
这几个月里,其他灯泡一个个烧坏,去了。头几回拜伦受到很大的打击。他刚来,还没有适应永生。随着照明时间的增加,他开始懂得其他灯泡生命的短暂:懂得了趁他们在的时候更好、更多地爱他们——把照明的每个小时都作为他们生命的最后一小时。拜伦很快就成了烧不坏的老灯泡。其他灯泡一眼就能看出他是长生不老的,不过也只是做一些普通的谈论。这时候从电网其他部分闪闪烁烁地传来了民间传说,关于永生不死的传说,其中一个来自里昂一个犹太神秘哲学家的书房,据说这位哲学家懂魔法;另一个来自挪威一个仓库外面,那个仓库正对着白茫茫的北冰洋,那种禁欲苦行的氛围,靠南边的灯泡们一想起来就微光颤颤的。即便那里还有永生的灯泡,也是不声不响的。但这种不声不响包含了很多内容,也许是一切内容。
学会了爱,拜伦接着要学会的就是不声不响。
随着他的照明时间渐渐延长到 600 个小时,瑞士的监控人员越来越关注拜伦了。太阳神监察室设在一座鲜为人知的高山脚下,屋子里凉飕飕的,里面塞满了德国的电用零件、玻璃、铜件、硬橡胶、银件,还有体积庞大的接线块,上面是粗毛发般的夹头、螺丝。一组观察人员穿着异常干净的白大褂,在仪表前走来走去,身轻如雪妖。他们要保证一切正常,保证任何灯泡都不能超过平均照明寿命。可以想象,如果这种情况发生,会对市场造成什么样的影响。
拜伦超过了 600 小时的监察警戒线。按照惯例,他马上受到检查:灯丝电阻,照明温度,真空状态,功率消耗。一切正常。此后拜伦每过 50 小时就会被检查一次。时间一满,观察站里就会轻轻响一下钟声。
到了 800 小时,这又是一个常规警报线。于是柏林派了代表到鸦片窟,要把拜伦转走。她戴着石棉衬里的手套,穿着 7 英寸的高跟鞋——对了,她不是要媚俗,而是为了够到灯架,把拜伦卸下来。其他灯泡在旁边看着,恐惧不已,完全被镇住了。消息在电网上传开了。在接近光速时,每个灯泡,包括:阿佐斯,看着黑魆魆空荡荡的电木街道;尼特拉腊朋和沃腾·G 一家,在看夜间足球赛;还有加斯特-沃尔伏来梅、摩纳瓦特和希瑞尤西思——欧洲所有的灯泡都知道发生了什么。他们软弱无能、不声不响,遇到斗争就投降认输,因为他们觉得这种斗争无异于天方夜谭。“我们无能为力啊,” 这种想法很普遍,嗡嗡声中传遍了羊羔睡觉的牧场、高速公路,一直传到北方煤运码头痛苦的末端,“我们永远都于事无补……” 只要任何灯泡表现出一丝非分之想,“白炽灯异常现象委员会” 就会过来把他带走。或许时不时有灯泡也抗议了,但都停留在信息层面,他们的灯光是受到控制的、毫无危险的,根本无法达到拜伦当初在婴儿室里那种天真的设想,在当权人物的面前爆炸开来。
他被带到诺伊科隆的一个地下室,那里是一个玻璃吹制工的家。此人害怕夜晚,让拜伦整夜亮着,监视着所有的火石玻璃碗、狮身鹰首兽、花船、跃姿的巨角塔尔羊、绿色蜘蛛网和面色阴沉的冰神们。这里是许多所谓 “控制点” 之一,这里可以轻而易举地监控可疑的灯泡。
不到半个月,太阳神总部的冰面上和石走廊里传来了一声锣响,人们的脸从仪表盘上短暂地转开了一瞬。这里的锣可不多,是特殊物品。拜伦超过了 1000 小时,现在的操作程序就完全标准化了:白炽灯异常现象委员会派了个职业杀手来到柏林。
可就在这时候发生了怪事。没错,怪得邪门。原计划把拜伦砸碎送回到作坊里回炉、进行分类处理(当然是为了重新利用钨丝),这样他就可以在玻璃吹制工的下一个产品里转世投胎了——变成一个气球,准备从一座白色的摩天大楼顶上放飞的。这对拜伦来说算是不错的归宿了——他和太阳神一样清楚自己曾经有过多长的照明时间。在这个作坊里,他看到了很多玻璃被熔化成没有形状的一滩液体,所有的玻璃制品都是从这些液体里造出或再造出来的。他并不介意自己也这样走一遭。可他是受因果轮回控制的。那灼热的桔黄色熔液是一种嘲弄、一种残酷。拜伦无法逃脱因果,注定要退回到无数的灯头和偷灯贼那里去。魏玛某条街上的顽童小汉赛尔·加速翁狄西嗖地跑了进来,把拜伦从天花板上拧下来,小心翼翼地放进口袋里,然后就加速嗡地一声跑出了门!黑暗侵入了玻璃吹制工的梦境。在他的梦境从夜晚空气中所抓取的所有不愉快情景里,熄灭的灯光是最可怕的。在他的梦里,光就是希望,最基本、最要紧的希望。当电流触点螺旋式断开时,希望就成了黑暗,于是今晚的玻璃吹制工惊醒过来,叫着:“是谁?是谁?”
太阳神其实并没有真正狂乱。这种事以前也发生过。还有一项措施可以采取的。这就意味着有些雇员需要多加班,并从其中意外得到那种说不清道不明的深层乐趣,同时还有打破常规所带来的那种同样说不清道不明的兴奋。要想满足感情需求,就得别去想太阳神。那些面色冷峻的搜索组走到了街道上。他们心里多少有些底,知道去城里的什么地方找。他们认为消费者当中没人知道拜伦长生的秘密。所以他们手里非长生灯泡盗窃案的数据也可以用在这个案子上。而在这些数据中,最突出的就是这座首府里的贫民区、犹太区和吸毒、同性恋、妓女、魔法等区。考虑到这种犯罪的性质,这里最理所当然出偷灯贼。你看看所有的宣传,都说这种犯罪是道德犯罪。太阳神发现消费者们都需要有一种罪恶感,而这种感觉一旦掌握在合适的无形之手里,就会成为最强大的武器。这是我们这个时代没有发现的最重大发现。在美国,莱尔·布兰德和他的心理学家们握有数据、专家声明和足够的钱(清教徒意义上的 “钱”,就是对他们的意图说声痛快的 “好吧”),把这项 “罪恶感的发现” 置于科学理论和事实之间的那个峰尖上。接下去几年的增长率将会证明布兰德的正确性——其实,真正证明布兰德正确性的是所有资深人员组成的名誉执绋六人组,包括萨里铁瑞、普瑞、纳什、德·布鲁图斯和肖特,外加正在打喷嚏的小莱尔。巴迪比较有钱,最后时刻决定去看《德拉库拉》。在布兰德留下的所有遗产中,最了不起的恐怕就是 “偷灯贼邪说” 了。其意义不只在于说明有人不买灯泡,而且还说明同样是这些人没有在灯头里通电!这种罪恶既背叛了太阳神,也背叛了电网。
就这样,太阳神的警探出动了,去寻找被偷走的拜伦。可是那个小顽童已经离开柏林,去了汉堡,把拜伦卖给了里泼尔街的一个妓女,然后拿换到的钱去打吗啡了。那个妓女今晚的客人是个成本会计师,喜欢把灯泡塞到屁股眼里。这位嫖客也带了点大麻来吸,所以走的时候忘了拜伦还在屁股眼里。其实,他自己根本就没搞清发生了什么——他在无轨电车上站了一路,等终于到家坐上马桶,只听 “嘭” 一声,拜伦就掉进水里,“哗——” 沿着下水管道冲向易北河河口。他身形圆滑,得以一路顺利前行。他在北海漂流了好几天,到达黑尔戈兰。那座岛像红白相间的拿破仑式甜点,在海中露出尖顶。他在岛上 “骏马” 和 “修士” 两块岩石间的一家旅馆待了一阵子。后来,一位很老的牧师经常做一个品尝 1911 年某种 “豪客海沫” 葡萄酒的梦,在梦里了解到拜伦永生不死的情况,于是就在某一天把他带回了大陆……突然间就来到了 “柏林冰宫” 这座繁荣的、黑暗的、铁桁架搭成的大洞窟,里面蓝色的暗影里可以闻到女人的味道——香水,皮革,毛滑冰服,空气中的冰屑,闪动的腿,撅起的屁股,流感般迅速闪过的欲望,扬鞭示威后的无助,在满是冰末的太阳光柱中迅速穿梭。一个声音在脚下模糊的镜子里说着:“找到那个制造这一奇迹的人。他是圣人啊。把他挖出来。尽快把他树成典型……” 老牧师马上草拟了一份名单,上面有大约一千个名字,都是在海滩上发现拜伦之后进出黑尔戈兰的游客。那个人的名字就在上面。牧师开始在火车上、人行道上、希斯巴诺-苏莎上一个个寻找名单上的游客。可是他才走到纽伦堡,小提箱就被一个异教派信徒给偷了,而拜伦就在箱子里,外面包着一件弥撒白长袍。偷箱子的人叫毛斯马克,是路德教派的,喜欢穿罗马天主教神父的法衣。这位毛斯马克不满足于站在自己的镜子前学教皇画十字,觉得要是穿一身神父装,到齐柏林的野外去参加纳粹火炬集会,随意地绕着祈福的人们转圈子,那该一定是件标新立异的事情。光闪闪的绿色火炬、红色的万十字章、叮叮当当的铜饰。“毛斯马克神父” 到处打量着奶子、屁股、腰围、凸起的裆部,哼着一支牧师小曲,有些像巴赫的连复段,微笑着走过唱《为胜利欢呼》和合唱《旗帜高扬》的人们。他没有发觉拜伦从他偷来的法衣里掉到了地上。此后,几十万靴子和鞋子从拜伦旁边走过——当然了,几乎没有一只靴子或鞋子碰到他。第二天,那片野外变得空旷而死寂,剩了些圆柱子,灰扑扑的,还点缀了一些长长的水坑,清晨的云朵在镀金万十字和花环后面拉得长长的。一个拾破烂的犹太人在那里捡到了他,把他带走了,辗转 15 年,躲过了灾祸,躲过了太阳神,得以存留下来。他被拧入一个又一个 Mutter(妈妈)——灯头里的母螺纹在德语里就是这样叫的,其中原因却不得而知。
此前,灯泡卡特尔已经启动了应急方案 B,确定了七年的法定时效,过了这个时间,拜伦就在法律意义上被认为烧坏了。再说,从拜伦案撤回的那些人又忙着去追踪另一颗长生的灯泡。那颗灯泡叫毕垂兹,本来装在亚马孙丛林一个哨所的门廊灯头里,刚刚被一个印第安突袭组莫名其妙地偷走了。
拜伦这些年屡屡化险为夷,所有的救星似乎都是偶然出现的。一有机会,他就会对附近的灯泡宣讲太阳神的罪恶本质和团结起来对付灯泡卡特尔的必要性。他慢慢悟出,灯泡必须打破自己只传输光能的界限。太阳神把灯泡的作用就限定在这一点。“可是,除了可见的波段,上面和下面还有其他频率。灯泡还可以发热。灯泡可以给植物提供生长的能量,比如给那些非法的、长在密室里的植物。灯泡可以透过睡觉的眼睛,影响人们的梦境。” 有些灯泡听得很专注,还有些灯泡则设法向太阳神告密:一些资格较老的拜伦反对派会有条有理地摆弄自己的参数,以便在瑞士那座山腹中的硬橡胶仪表上显示出来;还有几个灯泡竟然想把杀手扳倒,结果惹来了杀身之祸。
当然了,任何有关灯泡超越自我的言论都是公然造反。太阳神的一切都依赖于灯泡的效能,即可用输出功率和输入功率之比。电网要求这个比率要尽可能小。这样他们就能卖出更多的电。另一方面,低效能会延长照明寿命,从而减少太阳神的灯泡销售量。初期,太阳神尝试过增加灯丝电阻,悄悄地、逐渐地缩短使用寿命——后来电网发现收入减少了,就开始抗议。不久,双方达成协议,取了一个中间数字作为灯泡寿命,这样双方都能赚到足够的钱,至于反灯泡偷窃活动的费用嘛,就五五开了。同时还要巧妙打击那些完全放弃电灯而使用蜡烛的罪人。太阳神和肉类卡特尔长期合作,限制动物脂肪的流通,把脂肪更多地留在肉里卖出去,也不管会不会引起心脏问题。另外,又引导大多数割下来的脂肪进入肥皂制造业。那个年代的肥皂业很兴旺,很受关注。布兰德研究所发现,消费者对废弃物有着深厚感情。即便如此,太阳神并不是特别重视肉和肥皂的相互关系。他们更重视钨这样的东西。这是太阳神无法极大降低灯泡寿命的另一个原因。使用钨丝太多,会损耗现有钨的库存量(中国是世界主要钨产地,这就导致了东方政策的一些微妙问题),也会破坏通用电气和克鲁勃之间关于碳化钨产量和不同时期各地销售价格的协议。按照确定的原则,德国每磅价格是 37-40 美元,美国是每磅 200-400 美元。这就直接控制了机床的生产,也控制了轻重工业的各个领域。战争爆发时,有些人觉得通用电气给德国那样的优惠是不爱国行为。不过有权力的人们统统不这么看。不用操心。
拜伦的照明时间越来越长,对这里面的名堂也看得越来越清楚。他学会了在家里、工厂、街头与其他电器打交道的方法。每样电器都有话对他说。这种模式在他的灵魂(德语是 Seele,指早期碳丝的核心部分)里积聚起来,变得越来越大,越来越清晰,他也就越来越绝望。到了某一天,他会无所不知,但仍然和先前一样无能为力。他年轻时代把全世界所有的灯泡都组织起来的梦想现在看来是无法实现了——电网现在彻底开放了,所有的信息都可以窃听到,干这事的叛徒又很多。从古到今,预言家们都活不长——要么直接被杀,要么发生事故,其严重程度足以使他们停止活动、进行反思。一般情况下他们都会收手。不过拜伦却碰到了更好的运气。他注定要永远存活下去,知道一切事情却又无力改变什么。他不再尝试去摆脱因果了。他的愤怒和沮丧会无休止地增长,却又发现自己喜欢这样——可怜而背时的灯泡啊……
1. 同上。
2. 赫伯特·胡佛(1874-1964):美国第三十一任总统(1929-1933)。
3. 斯坦利·鲍德温(1867-1947):英国首相(1923-1929,2935-1937)。
4. 欧内斯特·维尔纳·冯·西门子 (1816-1892) : 德国工程师,在电报与电子设备方面做出过显著的改进工作。
5. 叙利亚神话中相当于希罗神话里阿弗狄特罗和维纳斯的女神。
6. 希伯来传说中亚当的第一位妻子,先于夏娃,死后化为夜妖。
7. 词名英文缩写也与 “中央情报局” 相同。
8. 德国北部一岛屿,旅游胜地。
9. 一种德国产高级白葡萄酒。
## **本文摘自《万有引力之虹》,译林出版社。2020 年 4 月版。**
**内容简介:《万有引力之虹》是后现代主义文学中的经典之作,在世界 20 世纪文学史上有着独特的地位,曾引起巨大争议。这部巨著故事情节复杂,梦境一般的幻想中充满了扑朔迷离、错综复杂的交叉关系,五花八门、古怪零乱的叙述,似是而非的议论以及物理学、火箭工程学、高等数学、心理学、国际政治、异常性爱的描写。小说的背景是第二次世界大战,德军的 V-2 火箭频袭伦敦,英美谍报机关发现美国的一位情报军官发生性行为的地方往往是火箭的落点,便对这种现象进行研究,由此吸引和牵连了许多人和事。**
短篇阅读 活动中心 by 赖香吟 - MONO猫弄
=========================
# 短篇阅读 | 活动中心 by 赖香吟
作者:赖香吟
**按: 《其后 それから》是个人之作,也是时代之作。赖香吟从一名自我对话的叙事者,向外扩及同代人的生命处境,诉说台湾 “五年级世代”(六零后)对种种信念的追寻与断裂。通过小说,我们见证深邃的时代风景。**
## _________
走到大道尽头,正红色的活动中心,如今看起来,有一种属于过去时代的辉煌。走进去,陈设理所当然已经改变,昔日简单打菜的自助餐厅换成了宛如百货公司里的美食街,餐厅另一头小福利社变成了二十四小时便利商店,碰触它的自动玻璃门,便替活动中心开了另一个出入口,取捷通往新建于椰林大道尽头的总图书馆。
在过去,这光线并不怎么明亮活动中心一楼,集聚了电影、礼堂、演讲、餐厅等功能,二楼则有各类社团:思辨的,知识的,慈善的,宗教的,娱乐的,交际的小群体,不同性情的学生约在活动中心碰面看电影,没事就到社办报到,消磨光阴,互诉心事,班门弄斧,清谈终日,一楼餐厅里的桌椅就算非用餐时间,也常座无虚席,人人各自吃零食,抄笔记,做功课,语言交换,情侣叠颈打盹缠绵。
如果不是因为五月,这个活动中心,在她的回忆之中,应该也会和其他大学时代的回忆一样,退化成一个他人的舞台,一些零星的故事,无啥大事可记的布景。虽然的确有过一些日子,她曾在那里买过餐点,看过海报,甚至几场电影,可无论如何,她不曾在这里奉献什么,没有过什么可歌可泣的情节。她与同侪之间总存有那么一些走不拢的距离,可是五月坚持挑战那些距离,跳也要跳过来。
有段期间,五月几乎日日到活动中心报到,从没有光线的租赁洞穴里爬出来,像木头傀儡把线从颈后拉紧,把散乱的热情与悲伤胡乱裹成一团,塞在笑容背后,然后,逢人神采奕奕,甚至幽默大笑,走上活动中心二楼,与人打成一片。
那是八 o 年代的尾声,所谓五年级发芽的时代,不顾一切地努力,把知性与情感榨压到极限,且往往是情感越过了知性,人人多少谈一点文学、哲学、性别,也谈环保、历史、政治,种种,种种,各个小圈子汇集在活动中心里来去,那些圈子里的许多名字后来在不同领域有了各自的光芒,但那是另外的故事了,如果巧合,这些人的记忆盒里,应该还留着五月所描述过的二楼社办里的空间狼藉,人与人的爱情与竞合,怀抱理想的青年男女,执着地和自己的风车战得精疲力竭。
第一次见到五月就在活动中心,五六个人在餐厅里并桌清谈,吃食四散。五月到的时候已经迟了不少时间,坐下来说前阵子出车祸,今天可是特别出关来见各位的。一张小脸,下巴裹着纱布,全靠一双晶亮大眼睛打招呼。她和在场其他人多少电话聊过几句,五月倒是完全陌生。
在活动中心磨到天黑,换地方继续。五月虽然受伤还是活络得很,有那种能跟每一个人打交道的本事,包括她。五月眨眨眼说:我们之前见过,不过,你应该是不记得了。
她的确没有印象。五月不在乎,继续说话,没个停顿。她看着五月,自然将之归纳于和自己不同的人,但又不觉得讨厌,活力神气的人多半尖锐,但五月神气里有一种和善。
大家边说边吃喝,唯独五月因伤口不方便始终没吃什么东西。后来时间晚了,总也饿了的时候,五月吆喝:喂,你们好歹也有个谁去帮我买瓶牛奶吧。
她不迟疑便站起来。
五月很快从身后赶来:欸,我没要你去买啊……
没关系。
你知道这附近哪里有超商吗?
不难找吧。她索性直说:其实是我自己想出来晃晃,你就让我去帮你买吧。
五月没再阻止,不过,也没往回走,赶几步跟上她。不一会,又开口了:怎么不穿外套呢?
还好,没那么冷。
抖成这样还说不冷?五月忽地伸过手来摸她的衣衫:这么薄?
这瞬间,仿佛打了个寒战似的,某些平静的事态被惊扰了。
一个人该如何去描述一个人?有必要吗?有权利吗?这么多年,她反复自问这些问题。
如果有一天,她必须描述五月,那会是真的吗?她又何必描述五月?是自己需要表达,还是五月需要表达?
表达自己,五月应该已经做得够多了吧。五月对自己毫不保留,她所揭开的,有时候,还远远超过了我们所能忍受的。要说五月有什么没有表达,也许只是她们之间的故事。五月不是不能写,是她特意没有写,即便写了也只能像个破绽百出的故事,一个事脉与轻重到那里就兜不拢的空洞。
刚认识的时候,五月历史,她一无所知。五月看起来活得很好,几乎可以说,生机勃勃,像个劲量饱满的电池小熊,为不同的事务跑来跑去,用各种不同音调说不同性质的话。从表面情节来看,两个人生活毫无交集,个性也不相同,确确实实是不同故事里的角色,连活动场域也相隔遥远,她多数时间留在徐州路的法学院,很少到罗斯福路这边的大校园来,遑论活动中心,可以说是因为五月,她才真正走上了活动中心的二楼,在那里看五月做各类花式表演,孔雀梳刷羽毛的交际舞。
约在活动中心碰面,通常只为了一起离开活动中心。路上都说些什么,已经不大记得,或许只是两个好学生的谈话,两个女孩子的谈话。那些话,与其接近感性,毋宁更是大块大块的理性,知识与经验的分享让她们跨越陌生,并不哀愁,而是愉快,表现得像坚强的孩子,在伤痕的记忆上跳房子,给经验创造各式各样的简码,像太宰治在《人间失格》玩弄词汇小游戏:汽船和火车是悲剧名词,市营电车和巴士则是喜剧名词。为何如此?怎么分的?太宰说得很傲气:“不知其理的不足以谈艺术。”
这是骄傲。难道不是骄傲?孤独者,气弱者,借以依靠、借以撑持的骄傲。这个骄傲不等量于知识,亦无关世俗所谓优等生的形象,不过是玩着一个只有对方才可以陪着一起玩的游戏,棋逢对手,放心触探彼此的直觉与天赋。五月形容自己像一只贪婪的知识怪兽:我们的求知欲可能让我们一辈子受苦。这是预言,但谁以为意呢,在那个骄傲的年纪,从不以为受苦是件没意义的事。她们执着,往前,在那条椰林大道上,把她们联系在一起的,正是一条没有人替她们准备好可她们必须独力走向前的摸索之路,没有父执辈,没有引灯的导师,也没有兄弟结盟,且连作为一个男子都不是的,形体单薄尚未长成的女性。宛如几只离群独自冒险丛林的清瘦的鹿,遥望彼时多半仍由男性建立起来的资本与知识城邦,对她们显露,既雄伟又荆棘,既召唤又无情。
离开活动中心,又到底做过什么呢?无非一起去看片子,去哪里吃点东西,或在五月的房间里,一本书接一本书,一个话题接一个话题。那时候,她们都刚踏上写作之路,各自发表了几篇作品,但五月有较她更大的蓝图与乐观要做一个作家,五月房间,格整书架,哪个方位上放了哪几本书,那画面至今清楚留在她的脑海里。之于五月,知识宛若祭坛,在那些书架的环绕下,她们揭露内心伤害的坟冢,她们的友谊在那里生根,可以说,那些书架就是她们故事最早的背景。除了当年所谓文艺青年必读的西方社科、哲学书,五月还衷情安部公房、三岛由纪夫,刚刚冒出头来的村上春树,以及,太宰治。光复书局所出版的当代世界小说家读本早就断版多年,但在彼时那真是一个精致的礼物,每一册都之于她们生命留下了痕迹。其中,李永炽翻译的《斜阳》和《人间失格》尤为一个异数,五月为之倾倒,她虽不能完全同意,仍不得不承认其中有着什么与她不同但依旧穿透打击到她的冲力,一种不同的痛苦,但确实是痛苦,诚实到让人回避不了;每个灵魂都是不同的,但痛苦的灵魂之间有嗅觉般的共感。
真正亲近相处的时间,说来不会超过一年,但这一年,她们到底如何经历对方的生命,又了解到什么深度?五月从不吝于表达意见,也能变换不同方式引人说话,有时候她抵抗五月:你是把我当心理分析吗?五月倒也不恼怒,嘴角仍有一抹微笑。很多人对五月的印象是,善于倾听,善于抚慰,善于给人能量。
不过,到底是在哪里岔了出去,她很快便感觉到了五月笑容背后的匮乏与不安。愈靠近五月,愈直感到外表热闹的五月生命内底若非干旱不毛,便宛如着了火般焦痛不已。后来与五月相处的记忆,愈来愈多的呜咽与呐喊之声,最糟的时刻,五月叙述里不乏耽溺,不乏黑暗,不乏惊世骇俗,她听着,没有惊吓,没有走开,唯一使她无言以对的是关于暴力与血,无法承受痛苦而自残的倾向。
是的,五月自残的倾向是很早的了。初识时候,她就已经在手腕用烟烫下了伤疤。相较于心灵所敏感到的痛苦,肉体显得非常小,灵魂太巨大,承载不了,就忍不住想将肉体冲撞开来,加以毁灭,至少予以麻醉。很多年后,她读柳美里(这个作家把自己献祭∕计于文学的程度是另一个令人咋舌的例子),再一次发现所谓意志的软弱与坚强之别,实在主观而难以相较;一方面承担着常人觉得不可思议的经历,但另方面却可能因为小事而顿挫无依,情绪窘迫,无可控制要去做理智知其不可之事,甚至以嗑药以死求其解脱。
当大多数人感觉五月亮得像星,蹦蹦跳跳如小猴的青春时期开始,她便饱受五月死亡黑影威胁,一天到晚要提心吊胆她是否又伤了自己,担心五月碰到足以致死的大小事,是的,纯以表象,一般眼光来看,有些事可能真小,小到太宰所说:碰到棉花也会受伤,胆小鬼(弱虫)有时连幸福也感到畏惧。世人当然可以批评这是软弱、任性、依赖,但她就是没法拿这些尺度去裁量五月;一切只是出于本性与极限,她只能试着理解,太宰的譬喻:生出 “柔和善良” 之心。
那依旧还是一个平整干净的年代,干净得像天永远是蓝的,爱永远是甜的;世界只是如肉眼所见,领袖就是领袖,百姓就是百姓;男人就是男人,女人就是女人;对就是对,错就是错;近朱者赤,近墨者黑,一个好人应该远离罪行。
或者,延续上面提到的太宰词汇游戏:罪,如果有罪,世人定义的罪是什么?要不,也至少告诉我罪的对词是什么?法律?不,太宰摇摇头:世人就是想得这么简单,装腔作势地生活。那么,是善吗?不,善是恶的对词,不是罪的对词。“神有撒旦之对,救赎之对是苦恼;爱有恨之对;光有暗之对。善有恶,罪与祈求,罪与悔改,罪与忏悔,罪与……啊,都是同义语。罪的对词是什么?”
罪,及其对词。《人间失格》一整个问到底的问号。如果有罪,罪是什么?因为有罪,所以不值得同情?因为有罪,即便不幸也不得抗议?罪的对词是什么?神?有神吗?还是仅仅只是 “世人”?
关于同性间的爱恋,她看五月作品《手记》,才知道当年以为五月都想过了,够勇敢了,没什么困扰可以打倒她,没问题的——这个预设是完全错了。
五月总表现得强韧。写在《手记》里那些核心底处的困难,五月到底有没有讲过呢?也许有,一起走路说话的时光,那些细细碎碎,那些纠结摧折的情绪恐怕全都是,只是她没有听到深处?不够感同身受?她不以为人与人的情感需要因为性别而有那么大的画地自限,因此五月问题没有惊吓到她,甚至她有时以为五月放大了情感的痛楚,而把自己陷入痛苦自残之境。
相对五月,她太理性,彼时亦尚有资本足以撑持理性,相信理性足以梳理悲伤,以为聪明才智会胜过情欲折磨,事实上,应该是她没能精准测量到五月的恐惧,不知五月内心深渊的恐怖。五月的话:我不要向前走,我不要成为我自己。
想来五月是深深被恐惧挟持了。
时代安静得非常自私,没有人对她伸出援手。
彼时和五月读太宰,总无法同意,肤浅地指责:一个人要死,何必偕人一同?死,不就孤独至绝,还求做伴?况且是未必相爱、事后连名字都不能牢记的两人,称情死太浪漫。
后来渐渐了解,这不是重点。重点在于这是怎样一个被恐惧与不安追杀的人呀。太宰说,零余者(日荫者,阴影下的人):人世中悲惨的失败者与恶德者。
零余者听了女侍常子对他说:“不要担心(心配要りません)。” 颤抖的心镇静下来。
零余者形容常子是那种 “冰冷的寒风在身边吹拂,只有落叶狂舞,已经完全孤立” 的人,他把这投射为孤独而深受打动,在她身边宛如枯叶在水底找着了可依附的岩石,得以脱离不安和恐惧,得以不再以丑角掩饰自己寡言阴郁的一面。因而,这个以世人眼光来看,疲倦寒酸的女人,之于太宰是,恩人般的女子。
与恩人般的女子一同去投海,未必与爱有关,更多的是彼此的绝望与耻辱。
解开腰带,脱下斗篷。放在同一处,一起跳水。
心配要りません。不要担心。
无论出于天性或因耽读而拟似,五月身上有太宰气味,这是不用再说的。可五月看出她身上的什么?也是落叶狂舞、完全孤立吗?彼此打动的乍看之下是聪明,实则接近孤独,大胆设想,如果她们彻头彻尾真是零余者,何尝不能是一对被彼此孤独打动而一起去寻死的伴侣。(心配要りません。不要担心。)然而,实际的故事是,在那个星星闪耀的活动中心,虚荣与宠爱打造出来的舞台,她们一路走到这里,接下来,也只能被推着逆向发展,变成一对承诺要彼此照护,活下去的伴侣。(不是死,是活,但彼此打动的依旧是孤独。)
所谓对生命最诚实也最勇敢的大学时代结束之后,出国之前,两人最后一次见面,鬼使神差,又约回来活动中心。
到的时候,五月还在餐厅大桌上跟别人作语言交换。她在后面空桌坐下来,随便拿点什么出来看。
若无其事,一切家常。人人桌上摊开好几本书,字典,纸张,笔袋;这就是校园,随时随地表现得一副无菌地带的校园风景。
五月讲几句,低头在笔记本上写点什么,或者,跟对方哈拉大笑,那模样和当年她在活动中心看五月和人讲话的情景,几无二致。
那个五月又回来了吗?她忽然这样想。感觉很好。然而,这个很好,跟以前并不相同。她们之间,毕竟跟以前不一样了。
结束后,五月坐过来,几乎没有让她讲话的空档,叽里呱啦报告她的生活构图,愿景,金钱,情人,机票。
倒带回去。电池小熊又出现了,劲量饱满。很好。她们真是对好朋友。
整场约会五月所表现出来的就是:我全都准备好了,我要振翅高飞了,你就好好照顾自己吧。
她没有提自己亦在准备出国的事,太拥挤了,五月急起来的时候,什么话也插不进去,何况她正处在新恋情的晕眩之中,她甚至没有时间细说刚完稿的长篇小说,一本后来变成畅销书的商品,关于五月的幽默、恐惧、野心、挫折、怨怼、梦幻,统统写在那本书里。
回想起来,这个下午是一个寻常的下午,她们之间最后一个无事的下午,盛世太平地宣告此段作结,另起一段。她们不会预料到人生早已设下怎样的算计,非得让她们继续当朋友不可,之后奇异的旅程,也远远超过了她们的预知。
那一天,只字不提两人共同的过去,也未提及任何可能有关的将来,天黑之前,她与五月推开那朱红色的大门,彻底挥别了她们的大学校园。
**本文节选自《其后 それから》, 赖香吟著,后浪·四川人民出版社,2020 年 9 月版**
**内容简介:如今,我航过那个郁闷的赤道无风带了吗?我即将出发去哪里?抑或,我从何处归来?写作的船帆下垂搁置了非常久,水天一色,雾气茫茫,记忆的魔山,五月,想来不只是我陪她走过一段性别认同之路,她也伴我熬过一段非常漫长的写作认同之旅,即便是她已经不存在的岁月里,她的形象及其书写,对我是一种抚慰,也是一种刺痛,我们曾经彼此反对,却又同时扮演倾听者的角色,无论是不断攀高追寻,或是不断挖深内化,我们争执,终致谅解,了悟彼此并没有太大的冲突。”**
短篇阅读 冷漠的人 by 马塞尔·埃梅 - MONO猫弄
============================
# 短篇阅读 | 冷漠的人 by 马塞尔·埃梅
作者:马塞尔·埃梅
## 按:文学家诺尔曼·丹尼评价埃梅说的那般:埃梅是说故事高手,他的新鲜点子源源不绝,因此总是有许多的话想说。他笔下的主角虽然总带着诡异与荒诞,但只要仔细观察,会发现他 们有一种近乎狄更生式 的写实性及普遍性。对于他的主角们,埃梅时而讥讽,时而斥责……总的来说,那是一幅充斥着喧嚣、悲伤、活力、复杂的人生写照。”
## _______
出狱的第二天,七月份的一个下午,我到指南针酒吧露露面。那家破旧的酒馆,坐落在行人熙熙攘攘的罗什舒瓦尔大街路旁。我去那里是要见一个叫梅代里克的人,外号 “梅代眨眼”,嘱托我见面的是他的一个朋友,在我坐牢的最后几个月也成了我的朋友。我走进酒吧,还以为只有我一个顾客,站在柜台后面的老板指给我看,酒吧里端坐着三名饮客,而老板正在跟这伙人交谈。其中有个满头白发的汉子,身体又高又胖,却长着一只鼠眼,他正是梅代里克。我有意强调他那只小眼睛,是因为他是独眼,由此得来他的绰号 “梅代眨眼”。尽管老板主要冲他说话,他却保持善意的沉默,让另外两个人费神回答。哑角看样子很是无足轻重。话最多的是一个矮个头儿的人,肩上压一颗假凶相的大脑袋,戴一顶扎眼的绿色帽子。另一个人身体虚弱,穿一身黑色服装,一副体弱多病的执达员的样子。
“听我说,梅代里克,” 老板说道,“我告诉你一件千真万确的事儿。战争爆发之前,我以名誉担保,每星期不落,我一定去欧洲剧院或者博比诺剧院的音乐会。那些歌手,一个个我全了解,熟悉的程度不亚于我的侍者干的活儿。如果有人向我提起安德烈 · 克拉沃,我就回答同意,他的歌很温柔,不过,嗓音问题 …… ”
“万分抱歉,” 假凶相截口说道,“让我来反驳你。首先,你不客观。”
“就是嘛,” 老板冷笑道,“我涉世太浅,名叫杜朗多。”
“想得美,能允许讲两句吗?”
“跟你说,我叫杜朗多。”
我走近柜台时,指南针酒吧里的人正进行这样的谈话。梅代里克和善地微笑着。向他自我介绍之前,我还想听初次见到的这个人说几句话,然而,这种交谈尽可以持续很久,也很难期望他启齿。我要了一杯果汁。老板只顾着唠叨,动作机械地给我倒饮料,眼睛几乎没有离开他那几个对话者。这时,进来一个褐色肌肤的苗条姑娘,穿一条颜色不正的红裙,一双黑眼睛闪着黄铜色光芒,上了高马发膏 1 的黑发卷贴在额头上。这姑娘二十来岁,五官秀气,红褐色肌肤的脸蛋儿很美。她腰姿灵活,走起路来,臀部微微摆动,有下等妓女的劲头儿。她径直走向柜台,在要饮料之前,抬起眼睛,向老板投去不安的询问目光。老板不耐烦地摇了摇头,好像在明显拒绝的情况下,不愿意看到她如此固执。他们交谈了几句,声音很低,我没有听清。那红褐色肌肤的姑娘,好几次偷眼望向梅代里克那边,她那有黄铜色闪光的黑眼睛里,点燃了恼怒的火光。
“我呢,” 假凶相说道,“我是按照这样的心理分析,如果一位剧院经理,每晚演出付给一名歌手一万法郎 1,我就要说当心了,经理先生,他没那么大名头。经理就明白了。”
“对不起,” 老板反驳道,“我冒昧地向你指出一个细节。我呢,跟你讲嗓音和演唱的情感,而你呢,回答我金钱。我认为你没有权利 …… ”
“我讲的是心理分析,如果你吹毛求疵 …… ”
他们絮絮叨叨,没完没了讲车轱辘话。梅代里克始终一言不发,他那只小鼠目的视线,时而盯到我身上。那只能是一种模糊的好奇心,或者自行了解环境的习惯。那位红裙颜色不正的姑娘,离我三步远,正喝果汁,哼着小曲。看样子她满腔愤恨,随时都可能发作。梅代里克终于开口了。
“当然了,我的孩子们,当然了。” 他用一种宽厚的声调 说道。
这句话终止了这场争论,可是关于 “梅代眨眼” 自身,我没能了解到什么。不管怎样,他的缄默比他的话语更能说明问题。
此人必定是个谨慎的人。我离开柜台,走向那三人。
“梅代里克先生吧?” 我问道,“我给您捎来个口信。”
我说话的声调近乎机密,随即我退后一步,以表明口信同样机密。假凶相往后推推帽子,用一副怀疑的眼神打量我。那个一身黑的小矬子佯装无视我的存在。梅代里克十分痛快地站起身,先我一步走向店门。红褐色肌肤的姑娘在他经过时拉住他,凑近他耳朵低语了什么。他和气地微微一笑,闪开身子,朝身后甩了一句话:
“我什么也不知道,首先,我也不认识他。”
那姑娘似乎并不相信,撇着嘴目送他,眼神里充满了怨恨。
梅代指给我进门的第一张餐桌旁一个座位,他自己则背对着玻璃窗坐下。
“刚才我对您说捎来口信,” 我说道,“这话不十分确切。我是比利时人克利斯朵夫介绍来的。”
梅代点头表示认识克利斯朵夫,让我说下去。他那只冷峻而聪慧的小眼睛,在低垂的眼睑中,聚精会神地观察,一秒钟也不懈怠。我明白他不是随便给我找了个地方,而是找了个适合审视我的地方。我向他解释了我如何结识那个比利时人,他又为什么让我跟梅代联系。梅代里克听了,回答我说,他已经 “金盆洗手” 了,所能给我的最大帮助,就是给我出出好主意。
“战争一来,我就明白了:从前,我遭受过严重的打击,可是,在逃避战乱和被占领时期,我伤透了心,特别为我的国家难过。我在心里讲:‘梅代,你做了所有法国人该做的事,你想要享受生活,而你的国家,整个儿处于水深火热之中。’ 自不待言,过了五十岁,我就不再去干那种苦活儿了,我决定有尊严地活着。三年来,我再也没做任何事。黄金生意,在我看来是过去的事了,现在我靠我的资产生活。我的积蓄不算很多,但是我生活简朴。”
梅代在耍弄我,他对我讲这套废话的时候,我看出他那只小独眼闪现狡狯的光芒。他又说道:
“我的报偿,就是在贝当元帅在广播里向我们讲话的时候,我扪心自道:‘梅代,你有权应声说:到。’”
“我并不后悔来见您,” 我说道,“万一您听说有个圣器室管理员的职位 …… ”
他听了我这句俏皮话,差一点儿笑了。
“玩笑归玩笑,听我说,正经的苦活儿,牲口都累的那种苦活儿,也可以给人满足感。”
“还不算怎么干也不落好的手工业。”
我说着就要起身。他抬手轻轻按我的肩膀,把我稳在座位上。
“你爱冲动,有点儿生硬,这样我很喜欢。正如我对你说过的,我什么也不是了,但还有些好朋友,一些我敬重而不赞同的人。有时候,我还对他们说教说教,给他们讲讲荣誉及与其相关的一切。要知道,他们明白,他们巴不得把事情做好。只不过是这样,他们有负担。一位爱唠叨的老妈妈,或者几个要管教的孩子,要不然,就是迷恋上爱奢华的女人,她们一心只想穿水獭皮大衣,戴钻石首饰,坐高脚凳泡酒吧。男人就是这样,不得不始终处于高度紧张的状态。我还想呢,你在中央高等工艺制造学校,究竟干了什么?”
“钱柜的一件案子。结果判了我八个月。”
“在钱柜案件之前,你在制造什么呢?”
我不想回答这个问题,一定是板起了面孔。梅代等了片刻,口气温和地问我:
“你爸爸一直坐牢吗?”
同他可能预期的恰恰相反,这个问题并未让我感到意外。
因一起黑市交易大案被捕之前,我父亲在圣乔治街经营一家餐馆 —— 地下酒吧,傍晚六点之后,光顾的人特别多。我不记得在那里见过梅代,不过,对于来来往往的顾客,除了个别的,我从来就不大注意。
“他的刑期还有两年。” 我回答。
“你说了我也不会相信,他就什么也没有给你留下?”
“全部查抄,冻结的银行账户、放在大贝蒂那里的现金。我呢,当时身上只有点儿零钱。”
“我乐意帮一把。其实,你在那边原先有关系,靠自己能解决。”
“我能办到。”
我冷淡地说道,甚至有点儿超过了我要表露的态度。梅代变得严肃起来。我这副样子,一定是又冰冷又封闭,已经产生了两种效果,令人厌烦和满意几乎旗鼓相当。他那审视的小眼睛摈除了讥讽的神色。我能从中看出新萌生的兴趣。
“大贝蒂,你也许要谴责她吧?”
“绝无此意。”
“首饰和毛皮大衣就不说了,你爸爸还给她留下了大笔的钱。”
梅代徒然地追问,还嘲笑他所谓的我的顾忌。我简短地向他解释,无论顾忌还是愧疚,对我都同样陌生,但我还是有点为难,要让他明白,我是按照自己的情绪,而不是按照道理,更从不是按照原则调整自己的行为。他显然不悦了,以恶劣的情绪叹道:
“真是少不更事啊。对待拿走您遗产的婊子那么温文尔雅,可是与之相对的,却要去抄人家铅笔商的钱柜。就算你做得对吧。那么现在呢,你打算干什么?”
我自己还毫无明确的打算,向他解释可费了难。我希望能 找到一种营生,以防止某种冷漠的倾向 —— 对别人和自身的冷漠,在这种冷漠的深处,我清楚地感到一种流浪汉的志向。为避免放任自流,我必须持续维系一种紧张状态,而我不相信存在某种合法的职业,能向我提供这样的机遇。那时候,我身无分文,要动手偷窃之前,还想过加入恐怖主义者的行列,然而,我并不关心祖国的理念,也不关心社会主义的思想。进入那群狂热分子中间,不管他们是什么人,我只能抱着一个局外人的态度。他们必然会持怀疑和厌恶的态度,不乏凌辱性地冷落我。而且,我有过多种场合的经验,例如在家里,我很不像话,缺乏族群意识。无论恨还是爱,都引发不了我的冲动,我甚至感受不到一个协调世界的激情,我完全缺乏社会的沟通渠
道,不消说,注定要在污秽的边缘扮演毫无好奇心的旁观者,顶多因生活的坎坷和紧急情况而屏住呼吸。我就这样,尽量用梅代能理解的方式表达,注重实用的一面,我必须从自身之外寻找冒险的斜坡。尽管我解释的话很简短,又没什么意愿说服人,梅代还是很好地理解了。
“我明白了。先生要扮演硬汉的角色。我愿如实相告,这不关我的事,在我的关系中也没有相关的人。你不妨去见见古斯塔夫,我不认识他,但是我听说过。据说他管这种事。”
接着他又描述了那个叫古斯塔夫的人,当天晚上八点钟左右,我到小教堂大街某家咖啡馆,就可能找到他。梅代眨眼说到此处,微微一点头就算告别,然后回到酒馆里头去了。我到柜台付了果汁钱。那个红褐色肌肤的姑娘刚才付了费,在我之前走了。她在大街的人行道上等着我,操着马赛口音突然问我,是否认识梅代很久了,是否跟他一起做生意。
“要提防他,他坑了不止一个人。”
我们谈过话,就走进一家电影院,厅里正放映一部旧影片,有大量裸体镜头的轻歌剧。我开始很有礼貌地触摸她的膝部。
她不予理会,趁着幕布上的演员大吼大叫的机会,她不顾邻座的抗议,向我讲述一个相当模糊的事件,说是梅代扮演了一个依我看尚难坐实的角色。一个同这个姑娘关系密切的小伙子,在跟梅代争吵一场之后数日,人就失踪了;她并不另外掌握怀疑的根据,就指责梅代将他交给了警察局。她周而复始,一再重述这件事,一名女引座员应一位观众的要求,过来请她不要说话。散场出来,她约我当天晚上见面,但是没有赴约。我再也没有见到她。
我前往小教堂大街,八点钟走进那家咖啡馆,应该能见到古斯塔夫。按照梅代向我描述的相貌特征,我很容易认出了他。
他一副白领工人的模样儿,爱注意事情的细枝末节,不大讨人喜欢。
“我是梅代介绍来的。”
“我不认识梅代。” 他说道,字字咬得很清,好像想让我领会全部含义。
“随您怎么说吧。”
“不是我不诚恳。我不认识您说的那个梅代。这是事实。这事儿过去了。您准备好了明天早晨动身,旅行八天至十天吗?”
“我准备好了。” 我回答。
我们待了片刻没讲话。古斯塔夫问我:
“您不向我提问题?”
“不。”
“明天早晨九点到东站,在开往特鲁瓦的售票窗口会合。手提行李,尽量轻装。”
我站起身。谈话持续不到五分钟,我没有消费就走了。
天快要黑了,我来到毕加勒广场咖啡馆,没有等来那个红裙颜色不正的姑娘,却瞧见中学的一个老同学朝我走来,他是要开车陪他父亲去看戏。他又激动又热忱,跟我谈起我们一起念书的情景,以及他现在的营生。那位父亲也同样热情,在我们追忆青少年时光的时候,他以温柔的感叹在一旁助兴。我听他们讲,没有什么兴趣,也并不厌烦,尽量保持礼貌,显得注意倾听。我也不是一直做得那么好,趁着谈话放慢下来的时机,我就告诉他们,我因偷盗坐了八个月牢。我讲这一经历,丝毫也不引以为豪,也无意恶作剧般给他们添堵。这种不求张扬的态度,比坦然自若还令他们惶恐。老人开始唉声叹气,眼泪和涎水滴到外套的领子上。“咱们走吧,爸爸。” 我的同学说道,声调庄严而忧伤。他挽上父亲的胳臂走了,临走时往我眼前撂下两张一百法郎的票子。我也不嫌弃,拾起来装进兜里。
我参加古斯塔夫和另外两个与我同龄的年轻人的远征行动,正如预计那样,持续一周多一点儿。并不那么危险,不像我们回来之后,同伙有人装腔作势地向人描述的那样。在奥特那地方,就是选中孤零零的农户,杀光居民,抢劫钱财。行动相当容易。农民通常没有武装,我们几乎总是突然袭击,屡屡得手。
古斯塔夫安排行动的各个环节,无不恰到好处:等天色蒙蒙亮了,选择犬吠不再让人警觉的时刻开始袭击。此外,曙光有利于监视各个出口,因为,关键的关键是,绝不能放走一个人。
古斯塔夫喜欢活儿做得漂亮,细致入微,容不得半点差错,不愧是一个罪案的工头。他杀人也十分细心,既不兴奋,也不残忍;反之,我们那两个同谋 —— 弗雷德和皮埃罗,屠戮时很容易狂热起来,毫无必要地折磨人。至于我,我始终冷静地干完自己的活儿,不过,总得克服一种相当强烈的憎恶:只要看到流血,垂死挣扎,以及因极度恐惧而扭曲变形的面孔,我相信自己必会产生这种心理反应。反之,死亡的念头,同我作为人的生存意识并不抵触。要知道,我不到二十岁就流离失所,带着饥肠辘辘的空腹和十足的无聊,整天转悠,光顾各处公共座椅,或者混入忙忙碌碌的人群中,感到自己在同类之间,被所有人视而不见。必须是有我这样经历的人,才能在其明镜似的咄咄逼人的映象中,看清人类友爱的虚妄。的确,在这方面,
我从童年起,就体会到这是一种可爱的虚无,确切点儿说,肯定是极为表相的交换。总而言之,死亡的意念,无论关乎我还是别人的生命,都不会在我心中唤起任何宗教方面的恐惧。回忆我的罪行,对我之所以是很不愉快的事,只因在我的脑海里
有时又浮现出十分憎恶的形象,但是让我心烦意乱的程度,不可能超过提起我随便哪个同伙的罪行。没过多久,古斯塔夫就开始赞赏我作案时的冷静、聪明,也许更赞赏我对人和事的这种彬彬有礼的冷漠态度,而据他亲口明确讲的,这种冷漠足以在我们的帮伙中,营造一种和气约束的气氛。同样,还是依照古斯塔夫的见解,我杀人直接而快捷的方式,对行家来说,似乎也是一种享受。他很快就向我表明了信赖,愿意接受我的建议,一些棘手的任务也特意交给我去完成。然而,他始终没有向我透露我们为之干活的老板姓名。我们的行动,差不多每次都满载而归,而我们的安全,任何时候都没有受到严重威胁。
那次行动,我们到达的第三天,古斯塔夫通知警察逮捕了几个青年人,他们是戴高乐分子,躲藏在我们行动地区附近的树林里,很可能会连累我们。
我回到巴黎,口袋里揣着两万多法郎,在一周之后的下一次行动之前,我就不同古斯塔夫接触了。在这期间,我遇见了我父亲的情妇,在朋友圈里被称为大贝蒂。她同我父亲保持了七八年的关系,处处都尽量向我表露母爱般的关怀,后来就对我不闻不问了,倒也没有找我什么麻烦。总的来说,我们保持良好关系。
甚至有好几回,也是偶然,我们还做了爱。贝蒂好意地向我打听我父亲的消息;我一无所知,但是想必他还在狱中。
“对了,” 她对我说,“我听说你也不顺当。”“你怎么听说的?”
“是梅代告诉我的。你认识他吧?上星期六,他来我这儿喝波尔图酒。梅代人挺好的。是个正派人,也不愚蠢。”
“他对你说了什么?”
“随便聊聊。是他告诉我的,你出了狱。他一定还会来看我。”
我不相信梅代登门拜访一无所图,因此劝贝蒂提防他一些。
她向我谈起,一年多以来,她对一个家庭出身极好的单身汉,产生了一种认真的深厚感情,那人毕业于著名大学,现在由于英美联军登陆而滞留在阿尔及利亚。我离开时,还向她重申要警惕梅代。贝蒂要是被一个坏蛋给弄进监狱去,对我而言倒没什么大关系,但是他进入贝蒂家用的手段令我反感,假借是我介绍的,还不顾我清楚表明的意愿,把我心平气和让给她享受的钱财,称为我的遗产。片刻之后,我就把这事置于脑后,不再想了。
在一个多月的期间,我陪同古斯塔夫和另外两三名并不固定的杀手,多次探查法兰西岛 。在最后一次行动中,农民打死了我们一个人,还让我的大腿中了一枪。古斯塔夫成功地把我带回巴黎,安排我住进一家诊所。我被当作爱国者对待,受到高度细心的治疗,很快就治愈了。我康复之后,古斯塔夫来看我。“老板跟我聊起你。要知道,他对你印象很好。”
“我不认识他呀。” 我反驳道。
“可能,可是他呢,他认识所有人,他也知道你干得如何。为了奖赏你,他委托我带给你一件礼物。一套维克多 · 雨果作品全集,俄罗斯草面精装本。”
“这是特意选的。” 我又指出。
“特意选的,你心里明白!” 古斯塔夫感叹,流露出几分忧伤。“我没这个福,他从来就没送过我这样一份礼物。我受的教育也不如你。有人说也白说,上了学的人,毕竟用不了几年,就有很大进步。不过,要知道,我要为你高兴。老板对我说了,等你伤好出院,他就不再放你跑农场了,要派你干更精细的活儿。”
我一出了诊所,古斯塔夫就交给了我这件新活儿。任何渴望登陆英国的人,只要交纳一定数目的费用,老板就负责安排其登上飞机。我将顾客带出巴黎,领到英国飞机计划降落的荒凉地点,然后给那人的脑袋一颗枪子儿。受害人绝难出人意料地逃脱,他随身携带的钱财和首饰,收拾在一起,就是行动的主要获利。
我并不讨厌这种行当,比起从前那样杀人越货,我也没有更多的顾忌,但是,我不忍心骗取别人对我的信任。当我扪心的时候,我的良心始终缄默。事情的经过,不折不扣属于感受的范畴,然而,一个诚实人的良心,经过深思熟虑之后,作出的反应更有权威性。我的第一个顾客,是个四十来岁的男子,一见面就把我当成朋友和知己。在把他拉向死亡的郊区火车上,我与他共处一小时,心下便明白,我实难下手结果他的性命。
我向他承认了真相,当然也相当巧妙地让他保证守口如瓶。如果我的哪个同谋问起来,他就回答他的生意忽然发生了变化,到最后时刻不得不放弃了自己的计划。这位老兄在这起意外事件中白丢了几千法郎,但是特别庆幸保全了一条命。他对我千恩万谢,并未考虑我职业杀手的身份。将近晚上六点,我们离开巴黎,八点钟就返回了。当天晚上,我在地铁的一条通道里碰见大贝蒂。
“真高兴见到你,” 她对我说道,“明天我走了。”
我们身边不断过人,她推我到墙根儿,低声补充道:“明天晚上,我动身去英国。梅代为我找到一个机会。”
“乘飞机吗?”
“对呀。”
我祝她一路顺风。她请我转达她对我父亲的友谊。得知梅代是我的老板,我并不感到意外。一涉及梅代,古斯塔夫就过分谨慎,这种态度早就让我揣测出来了。此外,我也不在意他留给贝蒂的命运,令我恼火的是,他假借我的名义骗取信任,这种手段实在不得体。
第二天,我独自又踏上同那名顾客一起走过的行程,傍晚六点钟到达所谓的飞机着陆场。古斯塔夫在上午就通知我,老板要亲自出马去做一单生意,当天就会有正常的结果。飞机着陆场是一大片草地,环绕的树林隔出了一片空场,空场上还立着一座焚毁农舍的几堵墙壁。我们正是在这座废农舍的地下室里对受害人下的手。一同勘察作案地点的过程中,古斯塔夫什么都没有瞒我,我们甚至还进行了一次演练。我坐在废墟中间,躲在一簇染料木后面,远远望见我的两位顾客走来,于是,我到地下室等着他们。梅代殷勤地拎着贝蒂的手提箱。我站在梅代那只盲目面对的区间,他进入地下室没有看到我,我毫不费力就下了他的手枪。他镇定自若,坐到我指定的一个橡木砧上。
我出现在这昏暗的地下室,贝蒂深感不安,她叫起来,抱怨有什么事瞒着她。梅代命令她闭嘴,示意自己在静候我讲话。
“看起来,” 我对他说,“你在处理我的遗产?”
“我本来想给你个惊喜,把属于你的还给你,但是我看出来,你事先已经得到了消息。也许是这位女士不慎透露了。”
“我认为那笔钱,我没有经常看到,不知道是什么颜色的。不管怎样,这件事与你无关,你向我提起来的时候,我认为已经让你明白了这一点。”
梅代让我注意大贝蒂:她正悄悄地向门口挪动。我不顾她挣扎抗议,将她推到地下室里侧。梅代沉思了片刻,开口说话了。他那只小鼠眼在昏暗中闪闪发亮。
“正义终归是正义,” 他朗声说道,“我认为一家之父遭难,应当受到保护,即使他儿子太小,还意识不到自己的权利。父亲的辛劳,受益人首先应该是他的子女。如今,大家什么都不遵守了。结果,有人义愤填膺,那是有道理的。当你父亲进了监狱,这位女士应该把钱交给你,自己靠劳动为生,等你父亲刑满出狱。”
贝蒂矢口否认我父亲给她留下任何财产。梅代不难逼她改口,还指责她有了不少情人。争论激烈起来,我开始厌腻了。
贝蒂实在不知趣,她还提醒我曾与我有过关系。他们相互指责,涉及我的话很难听。为了结束这种场面,我从兜里掏出梅代的手枪,扔到地下室中央,随即出去,带上了房门。我听见争吵的声音,追打和跺脚的响动。我坐到草地上,过了几分钟,又听见一声沉闷的枪响。贝蒂披头散发,从地下室楼梯口出现,我不免一阵失望。但是我也相信,换一种结局,同样令我失望。
**本篇节选自《我会在六月六十日回来》,马塞尔·埃梅著,北京联合出版公司,2020 年 5 月版。**
**内容简介:小说圣手马塞尔·埃梅的短篇小说全集,收录了除儿童故事之外的全部近百篇埃梅短篇小说,由著名法语翻译家李玉民老师耗费三十余年时间潜心翻译,由青年插画师、媒体人黄月绘制数十幅精美插图。 《生存卡》设定资源紧张,人类只能凭卡获得生存时长。 《征妻》的税务员交不起税,决定用妻子抵偿税款。 《最后一名》的自行车赛车手马尔丹,执着地妄想第一,却一辈子都在不停地错过比赛。 《井中影》《穿墙记》《田园曲》《图发尔案件》……近百篇埃梅经典故事,篇篇构思精巧,脑洞大开,怪诞中见真实人生,荒唐中见世态百相。**
短篇阅读 暮色将至 by 赖香吟 - MONO猫弄
=========================
[https://mmmono.com/g/meow/1762501/](https://mmmono.com/g/meow/1762501/)
# 短篇阅读 | 暮色将至 by 赖香吟
作者:赖香吟
**按:所有日常的破碎挣扎,皆源自一份真心。是对文青最初本质的寻回,也是对未来世代的寄语。**
## _________
年底,初冬,寒气叫人还不太习惯,所以感到分外地冷。外头天色阴沉沉的,林桑从衣箱里找出厚外套,这是今年第一次穿它,但衣服是早已穿旧了。在国外那几年,冬温低得吓人,即便多么穷学生,也得常备几件厚衣。此刻上身这件,犹记是在星期天的跳蚤市场买来的,那时他和阿君,简单娱乐就是去逛跳蚤市场,少少钱换一整天乐趣。阿君挑东西眼光不知该说怪还是独特,总能从一堆不起眼货里翻找出特别东西,且那价格通常低廉得很,仿佛除了阿君没有人会去争抢。那些奇奇怪怪的小配件、布料、提包,他不能同意多么好看,但等阿君把它们装饰在屋里或在身上穿搭起来,却又有了一股不俗味道,阿君向来有她自己鲜明的风格,那经常是对比突兀而不讲章法的,但爱上的人就会很爱,好些朋友就说阿君光凭这跳蚤市场的捞货技巧,就足以回台湾开家二手精品店转手赚钱,饿不死的。
饿不死,这的确是阿君的本事,阿君也常不在乎调侃自己是草根命,丢到哪里长哪里,怎么样的环境都可以活下去,不像他,阿舍命,嘴上说要吃苦毕竟是挺不住的。林桑对着镜子,把外套扣子一颗一颗扣好,旧衣服旧岁月,过往的经济生活,好像从来没有光彩过,国外那些年更是克难得紧,然而问题也许并不在穷,这点小事根本打倒不了阿君,她是那种只有百元日币也可以把日子过下去的人,真正使她投降是他的心。他总想从与阿君的共同生活里逃离,然而,眼前生活不尽满意,推翻又要怎么办呢?他嘴巴上说得好听,认为自己就算随便卷几个纸箱过流浪汉生活也是可以的,事实上,他从来没能真正跨出那一步。他恼恨自己,偏偏人对自己的恼恨是最难以承认的,于是便把气全推到阿君身上,认为这么多年就是阿君绊住了他,而他从来没有爱过阿君。
他对阿君从来没有承认过,若非出国需要,他们之间恐怕是连结婚登记也不会去做的。在一起那么多年,阿君没要过什么,他也不觉得有什么不对或愧疚。阿君唯一有过的念头只是小孩,然而那些年他的心已经跑得那样远,时不时总在准备哪一刻就要跟阿君提分手,怎么可能再有小孩。泥淖般的婚姻生活,他以为自己欠缺的是真正的爱情,以及,一颗够残忍的心,如此才能让他有所动力来处理与阿君的关系。外遇就是这样来的。谁知一次、两次他还是拖拖拉拉、吞吞吐吐,阿君也不复往日理性,两人要嘛完全装死不谈,要嘛闹到歇斯底里,捶胸顿足追不回重点在哪里。他们在这样的关系里猛然觉悟彼此竟然已经变得这样多,不再是当年那对率性的革命情侣,而是面对输赢放不开手、眼望人生残局也难免感到悔恨与恐惧的中年百姓。
最后两人真正签字离婚,已经不干任何第三者的事。在好几次闹到大打出手,彼此无比愤恨、计较之后,婚姻的屋檐下一片混乱与寂静,他看阿君背影,知道她要放了,两人毕竟走不下去了。不久之后,阿君便回台湾,他以为两人情分终于到了尽头,他安慰自己,尽头是好的,在此分道扬镳,各自新的人生。
没想到,事情完全不是那样。
他从山坡居处走下来,穿过捷运地下道,来到铁轨对岸的医院。这一带,出国前他熟得很,但捷运通车后很多地景都改变了。他在医院入口处按了消毒剂,抹净了手,进入一个与外头两相隔离、截然不同的世界。大厅有人围聚说话,说不多久便哭起来,然后是止不住的激动呐喊。路过的林桑偷偷瞄了几眼,生老病死,他以前总尽可能避开,总推给阿君代为处理,除了几个不得不露脸的告别式,对于人生尽头的凄凉,医院里疾病折磨的场景,他能逃则逃,现在,他逃不掉了。
电梯上到六楼,一开门便见阿君请的看护正在走廊上和人聊天。他轻手轻脚走进病房,阿君睡着,她体力一天比一天差。床边小桌搁着写字板,上头阿君字迹记满她提过的朋友名单。即便已到这地步,阿君还是什么都坚持自己来,毫不避讳交代身后事,细节诸如保险金钱事务可找谁,谁来帮忙清空房子,其中健身器材、家电分送给谁,遗孤爱猫又托谁续养,若不就范可找附近哪家动物医院来打麻醉针等等。
写字板上头没有他的名字,阿君对他的交代只是口头,安抚他说诸事都已经安排妥当,就差时候到了得有个人来打电话通知大家,而他,就是那个负责通知的人。
他有过抗拒,好像一个责任又从天而降罩在他头上。他不是已经和阿君离婚了吗?为什么是他?实在做梦也没想到,甚少闹病的阿君一病就这么重。当阿君透过电邮初次告诉他的时候,他不以为意,他早习惯了阿君自己料理自己,待至后来回台,见阿君头发掉光,才不免具体惊惶起来,慌慌张张问了病事。那一次,阿君已动完大刀,化疗也告一段落,坐在周末的咖啡厅里,看得出来特意打扮,扎了条花色大胆的头巾,身上披披挂挂,颓废嬉皮风。她老在他面前故作无事,一整个下午净是口气乐观,说自己怎样抗癌,吃喝多讲究,谁慷慨大方给她送来许多营养品,一生时光大约现在最是悠闲奢侈云云;阿君相信意志力,说自己现在感觉不坏,再休养一两个月,便要回去上班。
后来果真这样过了一段日子。其间,他从日本回来,一两次没地方住,借住阿君家也是有的。她领着他拐进藏于巷弄之间的传统菜市,有说有笑跟商贩打招呼,然后进了一间家庭美发,上得二楼,租来的两间房布置得色彩缤纷,热乎乎堆满什物。他很意外,和阿君在一起那么多年,从没想过阿君生活竟也需要这么多东西。以前他们屋子里堆的尽是他的书与收藏,阿君个人拥有不过简单几叠衣物,现在,放眼望去,除了那些砸下重金的抗癌设备:碱性水过滤器、空气滤净机、健身器材之外,就连花草、彩绘、瓶瓶罐罐、绒毛玩偶等摆饰亦不缺少。窝在以前他们局促家居绝不可能出现的懒骨头里,他想,阿君是在过另一种生活了,凭她的本事,她很容易可以过得很好,如果她不生病的话;阿君应该会觉得跟他离婚也是好的,因为她要精彩人生并不难,如果她不生病的话……
可是,现在,她病了。一两回合的相处,阿君的话里偶尔会泄露一些怨哀,想要依靠,使他不知所措。他忽然发现,他没有太多照顾阿君的经验,癌或死,这些字眼他感觉负担不了,他想逃,他跟阿君坦白:我不知道怎么处理。阿君看他几眼,默默收话不再讲下去。总是如此,他不知道怎么办便两手一摊说实话,阿君总会放过他,原谅他。
后来,他回台湾便改找弟弟找朋友,没再住过阿君那里,几通电话只是简单问问病情。真正搬迁回台,工作又没他想象得容易,只好靠着以前朋友关系,这里接接计划,那里做做顾问,看似风光,头衔好听,但总没个定数。他多少体会到了几分流浪汉的滋味,原来根本不是自由与浪漫。然而,他跟阿君毕竟离婚了,各走各的吧。若非阿君情况后来恶化,他是没准备要和阿君再次恢复成这种关系的。
夏天,阿君的癌往腹部、肝脏扩散。秋天再度入院,这回不开刀了,阿君托人捎来消息,简短、明白地说:时日不多,希望见个面。
这消息不能说有多意外,仿佛一盘棋局搁久了,最后几步终要点名到他。他想逃,却无所遁逃。他说不出口这不关他的事,也不能耍赖说这不是他的局。呆呆地进了医院,他期待阿君会告诉他怎么办,孰料阿君跟他一样无所遁逃地垮下去了。她躺在病床上,平静,冷淡,看不出想些什么,唯在朋友来访,谈及生死后事种种,才泄露那么几丝情绪。前两天跟他一起来的汪明才,以前留学时代的朋友,要离开的时候,从口袋掏出红包往阿君手里塞。
“我不需要钱。” 阿君推回去,“你倒说说看,钱现在对我有什么用处?”
她说得平静,没有怒气,也没有怨意,只是苦笑说出了事实,让人不禁要为自己的举动惭愧起来。汪明才腼腆应答几句,没再硬推,叹口气,对阿君说:“你要想开点。”
“我是想开了,总归早晚要走的路。倒是你们也要想得开,你们想得开,我才好走得开。”
他听出一丝哽咽,抬头看阿君,心里跳了几下:她要走了?她准备好了,那他呢?垂头继续看报纸,心内陌生得仿佛有扇打不开的门,有时候,他真不明白自己是准备好了?还是根本没进入状况?眼前情景仿若阿君只是生了小病,而他不过来演一场探病的情景;如果他不转头看阿君病瘦的脸,坐在这个房间好像只是跟阿君在过家常生活,报纸里那些消息很快可以引他读得兴味盎然:“总统” 大选倒数不到百日,随处可见他熟悉的名字与言论,那是他们过去党外岁月的成果,也是阿君和他的共同回忆,是的,如果他与阿君还能站在同一阵线说点什么兴致勃勃的往事,大约就是那些人那些事,那些如今成为政治主角之点点滴滴,那些他与阿君一起走过的患难青春……
阿君在他沉溺于回忆的此刻张开眼睛。他收起报纸,问问身体情况,说点外头天气,两人之间其实没什么话。他把看护没关上的电视调回正常音量,像以前那样假装自己自在得很,时不时还对选举加上几句评论。新闻正在回顾党与派系的成立经纬,他转头以为能和阿君交谈点什么,但她低垂着眼,一种他不敢去猜测她在想些什么的枯萎神情。他只能自己回味荧幕里那些旧照片,如今已成政治大佬的大象,十几年前的脸庞看起来简直就像个文艺青年,在一幕稍纵即逝的静坐画面中,他甚至从人群缝隙里看到了青春的阿君……
阿君生病消息一传开,多位朋友包括大象二话不说就开了支票让人送来,这是交情,但又有点令人感慨。前几天阿君幽幽说:“大象明年要送阿平去美国念书了。” 阿平是他和阿君看着长大的小男孩,阿君对待阿平甚至有几分情人的意味。这个脸色细白、敏感,而又甜蜜的孩子,当年无论抗议、演讲、行军各类活动,跟着爸妈无役不与,在那些充斥愤怒与委屈的场合里,阿平的童言童语若非叫人开心就是让人心碎。如今,阿平十六岁了,和他们这些大人渐渐生疏起来,就连他们大人之间,也因为身份、权力的变化,难免有些不同了。以前没钱,现在有钱;以前有空,现在没空;以前做什么都一票人伙在一起,现在阿君形单影只进出医院,大家都忙,没空来看她,花倒是送了一堆;以前默默无闻的朋友,现在人尽皆知,病房里的花卡,上头署名经常搞得护士和看护工都紧张起来,那天老胡匆匆来探,还吸引了医护人员和隔壁房的家属来要签名,搞得看护也虚荣了,逢人就要讲两句。
联系他与阿君的过去,很容易可以画出一张现今执政圈的人际关系图,其中有些与他仍是好朋友,有些则不然了。偶尔他也有所愤恨,感叹人心冷暖,听他们发表政论,有些依然敲痛心中角落,但有些话已经不对劲了。他痛心于以前努力争取来的如今滥用糟蹋至此,且竟有那么些不知哪里冒出来的小角色、墙头草、见风转舵者,以及令他难以置信之聪明伶俐、敢吃敢拿的政治金童。不同派别各自表述,彼此不问是非,就是反对到底。他不知道事情怎么会变成这样,开放所带来的,竟然不是愈来愈多的选项,而是几近没有选项,冲突非但没有化解,且是更草莽地对立。
紧接着一场决战即将再来,他们会不会再胜?他看着新闻,不知道自己应该怎么抉择。他依旧不认为自己过往那些相信是错的,他也知道自己不免还是会基于旧情谊而替老朋友找借口;无论如何,他不希望他们输,但他们赢他似乎也不感到多么高兴。他看着枯萎的阿君,现在的她很少评论什么,依她的时间演算法,这一场政治,输或赢,皆影响不了她,因为,她是不可能活到答案揭晓的。
就在阿君昏沉沉即将入睡之际,门口有人探脸,竟是多年不见的安。国外那几年,安在他家搭饭过一阵子,算是很熟悉他与阿君的人,但他简短打个招呼便让身出去,他猜安应该也没多大兴趣看他,这阵子,他被阿君一帮女朋友骂到怕,在她们的审判下,阿君的病全是他这负心的丈夫害的。没想安很快从病房出来,邀他去楼下咖啡吧坐坐。安一开口便问他现在做些什么之类的样板问题,他随便讲点兼课的事,跳过那些积在心里其实非常想要倾倒出来的埋怨与求援,这些年,他学会了,不要随便说出真心话,有时这是一种礼貌,简单方便的应酬,最好,对方也不要莫名其妙说起真心话来。
眼前的安看起来气色不错,脸上微笑稳定,不虚伪,但也没说真心话。这很好,她是怎么办到的?她曾是那么迷惘的一个小女生,叨叨絮絮和他在电车里、在餐桌上说个没完,真心表露自己对于人生举棋不定。见他意兴阑珊熬着学位,安劝他不如换跑道重新开始,他当她小孩子说大话,他毕竟不是安的年纪,且他当初带着阿君来日本,何尝不是以为自己正要转换跑道重新开始?他酸溜溜地说:“重新开始谈何容易,你有后援又年轻,当然可以重新开始,我可是形势已定,头都洗一半了,不弄完能如何?”
这类口气的话,安通常是接不下去的。这是他的本事,他很知道怎么以退为进。安脸上每每浮现尴尬抱歉的神情。然而,事实上,他想跟她表示,其实他是感谢她的,至少她那么煞有介事跟他谈论他的人生。那时候,他以为安和他一样是不稳定的人,是那种能够理解不稳定之必要与无奈的人。可现在,连她这样的人也过得很好了。他应该为她高兴,但有另一种不可理喻的懊恼骚扰着他,他想,隔了这么多年,如果安胆敢再跟他提到 “重新开始”,他就要使出这阵子堵人封口的撒手锏:“重新开始?你瞧瞧我,这年纪,连当大楼警卫都有问题吧。”
结果,安没提,什么也没提。约莫半个钟点的谈话,安仅仅止乎礼说:局势大不如前,暂时这样也很好,再等等机会之类。然后,他们谈到阿君,安感叹阿君命薄,坚强抗癌至此,却还是得宣告失败。安说,你知道阿君一点都不把自己当病人,她兴致勃勃跟人玩电脑,重拾画笔,还说要去学意大利文……
听起来安一点都不怕,她甚至陪阿君度过一段亲密的抗癌生活,包括 SARS 期间陪阿君上医院,看刚跳楼的张国荣拍的鬼片,枕头贴着枕头睡觉。为什么安可以不怕?自己又为什么想逃?他低下头,感觉自己心肉如蜗牛般蜷缩起来,叫不动,就是叫不动。巨大而无情的死亡,他是败兵一名。寂静黄昏,安没为阿君抱怨什么,没像阿君其他女朋友责备他薄情寡义,惟小心翼翼结论:“现在,有你陪她,应该是最好的结局了。”
两人站起来告别。不过是刚结束下午茶的时间,外头天色却阴郁得好似夜晚已然降临。他站在医院门口,望着安的背影渐行渐远。“最好的结局”?这小女生当真知道人生的滋味?否则为什么老要装成熟地跟他说关键词。“最好的结局”?他与阿君的结局,难道不应该是在办好离婚登记走出户政事务所的那一刻吗?夫妻一场,断不干净也就算了,谁还想出这种结局来整他,不只是关系的结局,还是生命的结局!
他回到病房,正来了护士在帮阿君做排毒处理,阿君的消化器官几已作废,不仅没办法吃,就连排出来都没办法。护理过后,阿君仅仅叮咛明天父亲和律师要来确认遗产与安葬的事情,便似气力尽虚。他让她睡下,离开病房。几年不见阿君父亲,没想再见就此情景。阿君有记忆以来没见过母亲,父亲也四处漂泊,可说是阿嬷一手养大的。这回病,她宁可让阿嬷望穿秋水,佯装人在国外而不敢顶着光头病容回去看八十好几的老阿嬷。白发人送黑发人的悲哀,怎么说也只能让那畸零人般的父亲来承受。
阿君跟他在一起那么多年,结不结婚,去不去日本,请不请客,这个父亲从没说过什么,对他这女婿既没表示过赞同也没表示过反对,他甚至不确定这父亲是否知道他与阿君已经离婚。明天,明天相见该以什么心情呢?这父亲想必不会安慰人,但应该也不至于落泪吧?这父亲只是被动地走进病房来,跟他一样,是的,跟他一样,飘浮、犹豫、逃避,阿君从来不指望他们,可是,最后一关,阿君终究还是只有他们,他们逃不掉了,父亲与丈夫将在这里相会,为女儿,为妻子,为一段他们从来没有负责过的关系收场,送行。
怀着愧疚的心绪离开医院,时间说晚不晚,说早不早,倦感袭来,令人真不知往哪里去。他挤进捷运站的人潮,在月台上等候班车来了又去,去了又来,终而登上往北投的列车。北投变得让他不认识了,原本寂寥小调的温泉山径,现在商业炒作热闹,“泡汤” 这个模仿接枝的东洋词汇随处可见,可周遭情调既不是他入境随俗早已适应的日本温泉乡,亦非他记忆中那个荒废、隐匿历史角落的旧北投。
他往社区深处走,找家比较冷清的旅社,要了一个单人池。光线很暗,卫生不能算太好,但半圆形浴池,木框玻璃窗,仍是旧时款式,很适合他现在的心情。他让自己浸入水中,热气缓缓消解他的疲劳,汗如地热滚滚冒出,他闭上眼睛深吸一口气,没错,就是这个熟悉的硫黄味。
出国前很长一段时间,他和阿君就住在北投山上。那是 80 年代,朋友让他们免费借住的老房子,四处怎么刷也刷不干净的黄垢,各种零零落落被氧化掉的家电小物,但他们一点也不以为意。在党外杂志风吹草动的惊险生活之余,大伙经常聚在他们这间无政府状态的屋子里吃火锅、打麻将、那卡西,他能唱一曲一曲的老调,又笑又泪。那时节的阿君,活力充沛,果敢勤奋,无论琐务、文稿、劳动,样样不挑,样样做。看似最没特色的阿君却最受人喜欢,骄傲的人也好,暴戾的人也好,苦闷的人也好,阿君总有办法跟他们相处,怎么样的人都会被她的坦率与行动力说服。
那是一群人最同心一气的时代,各种不同原因所引来的觉醒、创伤、愤怒与绝望,合在一起发散出纯粹的美与力,那是他人生时光最初的抒情小景,也像大多数史诗故事在开场之际,总有一种纯洁而脆弱的美好,各种情感尚未质变之前投射出来的光鲜色泽,多么令人怀念,然而,故事总会极其戏剧性地发展下去,有时候,发生于现实人生的转折、惊爆力道之大,可能还胜过了故事的设计……
后来杂志社烧成一片焦黑废墟,他不是全无预料,是不相信真、会、发、生。死去的人果真履行其誓言:Over My Dead Body。死去的人像一把火,烧烫了他们这群不见棺材不掉泪的旁观者。抒情小景结束了,史诗故事进入精彩主轴,很多朋友就在那时明确介入了政治,可他却发不出声音,槁木死灰地没法再做什么。同样一把火,他被击倒了,某些他以为会实现的东西粉碎了,不过,阿君并没有被击倒,他当时想也许是因为阿君想得太少所以她没有感觉,可事实证明想得多又有什么用呢,思想上找不到出路,终了,他只能依靠谎言或自我麻痹活下去。他想离开,不再提起,他贪图活下去不要那样痛苦,然而,阿君不怕痛苦,阿君一旦相信就相信到底,即便被抓、被关甚或活不下去也没什么可怕。人肉咸咸,阿君老这么说,她最大的筹码就是,她一点筹码都没有,没有什么好害怕失去的。
他们离开了北投,在海外像小夫妻般克勤克俭生活。屋子里不再有很多朋友吃饭喝酒说话,日子里没有什么要紧的行程要赶,只是把几本书翻过来翻过去,听阿君在砧板上一刀一刀把高丽菜剁成细丝;他们只能依赖彼此的感情,最好还有点爱情,可是,他们有吗?他刁钻起来,他们有吗?他期待台湾朋友来访,听他们各言尔志,让阿君在小厨房里绞尽脑汁变出炒米粉、萝卜糕等家乡味伺候大家;他乐于让自己这座东京小屋成为反抗者的秘密基地。然而,时代在变,东京小屋也跟着变,访客逐年减少,反抗者既已争得了舞台,便不再需要挤在秘密基地相濡以沫。剩下来的,只是他与阿君的婚姻生活,眼高手低的学术之路,人近中年,本该安分下来,他却反而焦虑得像只蚱蜢,四处乱撞乱跳,来不及了,来不及了,想要的人生再不去试就没机会了,他唯恐局面真定下来,唯恐日子愈过愈平静,于是便愈发不安地挑剔吵闹。
跟阿君离婚之后,他以为自己会重新开始,可自由于他竟有一丝冷寂,至少不是欢欣鼓舞的。没了阿君帮他料理柴米油盐酱醋茶,他很快发现生活一团乱。没有人束缚住他,可以重新开始了,但他似乎还是无精打采,就连爱情也没那么令他挂念。他考虑过回头找老同志一起做事,可是很多局势让他领教到今非昔比,现今的政治,光凭活力、体力、苦干实干未必行得通,得有具体搞行政、人脉,甚至口头辞令以及繁文缛节的能耐,他得承认这方面他是生手,他不够老也不够年轻,做领头,他的历史不够壮烈,做幕僚,有更多像安那样的年轻人才可用,他曾吃味这批人没熬过苦,凭着光鲜学历、理念与理论,就收割了他们前代人应得的好处,现在,连这批年轻人都飘出一丝腐味,他还期待什么。
如今,权位与利益的洗牌可说已经结束,他得平心静气接受自己没拿到什么好牌,充其量陪打而已,不如下牌桌吧;有时他感到自己连围在一旁看赌局的兴致都没了,这些年政治上的改变,怎么说,多少让他心里的愤怒与悲情找到了些出口,胸口不再积郁,至于其后败坏的,他既无从插手,也不想再管,他安慰自己,这不是他的责任,更不要想什么救赎,他只该想人生如何好好过下去,快乐一点,精神一点。
他好不容易克服了自己,打算让自己换其他方式活着。却为什么在这种时候,阿君病了。病的实情这样可怕,病魔,从骨盆腔、肠腔,上延到肝脏,将阿君整个身体予以霸占侵蚀,他发现,病魔和他们以前反抗的霸权异曲同工,全是蚕食鲸吞,横取豪夺,毫不手软,过去还是看得见的政党、敌人、杀手,现在一刻一刻啃蚀过来的却是谁也看不见的病变、命运、死神,难怪阿君要沉默了,这身体的痛苦,精神的冤屈,是怎么呐喊、争取、抗议,甚至自焚都没用的,一个 dead body 就只是 dead body 呐——
死之将至,生之往昔的点点滴滴仿若海浪打上脸来。他觉得自己像个孤独老人守着阿君,目睹病魔怎样分分秒秒掏空他们,没有人可以真正讲讲话,分担他内心庞大的恐惧。他甚至想,也许当年该顺阿君的意生个小孩,不至于如今两人凄惨以对。原来,阿君可能是对的,但她却总对他让步。以前他总怨憎阿君,认为自己人生就是过早卡在阿君这个点上,以至于他不得不错过、放弃后来的机会。现在呢?没有阿君之后的人生,他并没有更好,更难堪的是他再也没有理由可以推托,他恍然大悟,原来,阿君一直在给他的人生当垫背——
他错了,他愿意承认,他错了,如果可以交换取消眼前这种局面的话。他知道不能放下阿君不管,但他真想逃开,就算过去一切都是他的错,也不必惩罚他到这个地步吧?他捂着脸,泡在熟悉的温泉故乡里,像个孩子般想要追讨游戏的重来、母亲的原谅,然而阿君的病容使他知道什么叫作残忍,他狠狠被拒绝了,冷酷而无余地的拒绝,阿君不仅不会再调侃他,更不会再跟他吵架,她连睁眼看他都很少,阿君不再有能力包容他,也不再需要原谅他了——
挥之不去记忆与悔恨的纠缠,他不断抹去脸上的汗,感觉天旋地转,故乡温泉如此温暖柔腻,然而他得强悍一点,阿君这一关,无论如何得挺过,逃避不了,再逃他就太差劲了。他怎么会是这样的人?他难道错看了自己?莫非阿君比他更了解他自己?他搓揉自己泡到发烂的松垮身躯,他想哭上一哭,甚至放声呐喊这人生是错了、乱了,可他依然没有流出泪水,晕泡在水气朦胧的小澡间里,直到女服务生不安地在外叩门:“林桑,时间超过了喔,林桑,林桑,你没事吧?”
日后,他确实做到了不逃避,时间允许便去病房,不知道该说什么,便拿本书或报纸坐在一旁陪着。阿君体力愈来愈差,睡睡醒醒,连他存不存在都未必知觉,遑论跟他说话。日子一天一天过去,鼻胃管愈来愈浑浊,已经两个多月没有实际进食的阿君开始幻想食物,像以前在国外的时候,轻声细语说如果 现在可以吃到蚵仔面线或卤肉饭多好呀,要不来一碗热腾腾的牛肉面吧,加上一盘粉蒸地瓜,若是冬天就喝香喷喷的药炖排骨汤……那些年的梦里,如果开始出现食物,他们便知道思乡了,该回去了,倘若一下子回不去,阿君便想尽办法做出类似的料理,她是饿不死的,不是这么说吗?可怜如今却受着饿的折磨,他要看护把食物带出房外去吃,这房间,不要有食物的香气,太残忍了。
最后的晚上,昏迷的阿君有几分钟忽然能够张眼。他靠近她,喊她,说几句无济于事的话。阿君听着声音,定定看他,那眼神他已经不太认识,无神,却又专注。
他忽然察觉到,这是阿君在跟他告别。他想自己应该说一声对不起,握一握她的手,很温柔,很温柔地说:阿君,对不起。
偏偏他说不出口。他怕说出口自己眼泪会掉下来。
真是可耻到极点了,在阿君的死亡尽头之前,他在意的竟还是自己的眼泪。阿君闭上眼,他走出病房外,眼泪不听使唤淌了满脸,不知道是在为阿君哭还是为自己哭。
他打电话给阿君交代过的朋友,隔天,写字板上交代诵经助念的朋友依约而来,虔诚肃穆在阿君的病床边守了一天。阿君没再清醒,闭眼,动也不动,唯一证明她活着的不过是身边那些机器变化。他想,也许,自己等不到机会说对不起了。
窗外天色还是阴沉沉的。有人在门上叩着,他知道,最早出现的总是清洁工打扫,再来是护士送药,然后是厨房人员派餐。如斯反复,一天,然后,再一天。然而,眼前的这一天却可能即将有所不同,截然不同——他初次感觉时间有限得可怕,他试着回想与阿君相遇的这一生,想把握住眼前有限的时间,趁阿君还在的时候,重想一遍——然而,怎么来得及呢?来不及,来不及了——他慌张、混乱得不知道该怎么想,怎么解释,怎么收场,他愣着发傻,直到那些数据惊动了他——
年轻的医护人员涌进房来,彼此交换眼神,房内气氛陡地升起一阵惊颤,又很快平静下来,仿佛你我都明白似的,没有人说话。他握住阿君的手,动也不动,没有人在这时候哭出声来,也没有人胆敢在此时此刻叫唤:阿君,阿君——
他看着床畔那些仪器里的数字倏地陡降下来,曲线图愈来愈缓,最后,水平地,停止了。
又是暮色将至之时,政治纷纷扰扰之际,他不知道该说什么,也不想说什么。原来,生命结束的情景是这样,他竟然真的经历了,阿君,真的与他分离了。叩,叩,这次来的是主治医生,他们站定,鞠躬,近床检视病人状态,抬头看看墙上时钟,如此记下了时间,然后,他们说:“请节哀。” 再度鞠个躬,出去了。
**上文为《文青之死》中所收录的荣获九歌 “年度小说奖” 的篇章《暮色将至》,后浪·四川人民出版社,2020 年 9 月版**

**内容简介:“九则故事,尽管角色、情节有异,但大抵是内在生命与现实相互牵制或漠视的故事,症状表现为错误的情感、志业的彷徨——多数文青人生正是在这两者病去了大半。” 昔日文青,却已成我辈中年。但他们曾有理想与实践,对社会的感受、冲撞世界的步伐,皆远超众人。如今,那些过去种种,是否还留下些什么?疲于应付现实的文青们,又是否仍怀抱着什么?
**
短篇阅读 上班族的一日 by 陈映真
===========================
[https://mmmono.com/g/meow/1760340/](https://mmmono.com/g/meow/1760340/)
# 短篇阅读 | 上班族的一日 by 陈映真
作者:陈映真
**按:无法归乡的年轻人,我们生存的时代之预言。哪一个才是我们今天生存的都市?饱食、奢侈、绚丽、幸福,还是环境的崩坏、人的伤痕、文化的失据?每一个在城市漂泊打拼的上班族,都可以在书中读到自己的故事。**
## _________
床头柜上一阵惊心的电话铃,使他慌张地醒来。他摘下眼罩,反射性地一把抓起电话。虽然隔着落地窗的帷幔,他依然感到这仲夏的早晨的阳光,炫人欲盲。
——喂……
“喂。” 他说。从沉睡中乍醒的他的心,怦怦地悸动着。
——Olive 呀?
“噢,噢,” 他说。他忽然醒了大半。“是我。” 他说。
——还在睡呀?
“哎。” 他说,从床上坐了起来。
——能睡到这时候,就叫人放心了。
对方嘿嘿地笑了起来,他抓起电话机旁的香烟,用左肩和左耳夹住电话,划上火柴。“其实,醒来过一阵子,” 他应酬地笑,把语调尽量装得轻松,“又睡了。” 他说。
——好。睡了一夜,现在你总该清醒些。昨天的事,我们当是全忘了。以后,谁也不准再提。
他没说话。杨伯良会打电话来,是他意外的事。一丝被安慰的卑屈的喜悦,不顾着他的矜持,卑屈地在他的心中漫了开来。
——早上,我已经跟 Mr.Talmann 说你请三天假。也许你该到哪儿散散心。
他默默地抽烟。他想起戴着金丝眼镜,才过了四十不久就秃了顶的上司 Bertland 杨的狡诈的脸。
——不过,你知道,这段日子忙得很。你那些事,又没人接得了……所以,如果你能明天来,忙过这一阵,我补你半个月的假。
他依旧沉默着。他缓缓地抽着烟。“我说辞就辞。不辞……不辞……我就不姓黄!” 他想起昨天在 Bertland 的办公室中压低声音愤怒的赌咒。“你胡说些什么!”Bertland 一副爱护的怒容,赶忙起身把办公室的门掩了起来。他一边想着,一边听着 Bertland 在电话里说,“Come on,Olive,come on...”,心里便悒悒地绞痛起来。
——“不,” 他终于说,“不要啦……”
——我不是要你现在来。明天。如果实在不行……
“不。” 他安静地说,声音却有些踌躇了,“不,我不会去了。”
——O-live!
“……”
——你胡说些什么!听我说,你的假我已经请好了。明天不想来,没问题。
他想把电话挂掉。但是他依然默默地听了几句 “千万不要冲动”“你的事我自有安排” 之类的话,让B. 杨挂了电话。
他抬头看钟:九点还不过十分。他把抽剩的烟扔进床边的痰盂。和平日一样,美娟在上班前把早餐和报纸齐整地摆在卧室的茶几上。他下了床,开始盥洗、吃早饭,胡乱地翻翻报纸,走进客厅。
孩子上学去了的、妻也上班去了的家,竟而是这样地安静,是他素来所不曾想到过的。他带着报纸走出卧室,背着客厅的窗子,坐在白色塑料皮的沙发上。他想看报。但是从来不曾知道过的,独自留在家中的安静,竟而成为巨大的嚣闹,侵扰着他。他放下报纸。四周的壁纸在迁入新居一年半以后的现在,依然崭新。为了这间公寓,他必须每月缴付七千八百元的利息。他在这栋公寓还只在挖地基的时候就曾算过:如果今年升上副经理,他就可以把摊还利息的时限,从十年缩短成六年。
然而 “如果今年升上副经理” 这个思绪,使他忧悒起来。他想起就在自己斜前方的、Bertland 杨办公室隔壁的空着的房间。一度伸手可及的那个空出来的副经理室,忽然像一个急速调远的镜头,远远地离去。
昨天下午三时许,B. 杨的秘书——瘦楞楞的茱丽——匆促地在他的桌子上丢下一张公文副本。正在苦于找不出不知躲在账本中的什么地方的一笔金额的他,索性就拿起副本,一字一句地读着由很好的电动打字机打成的信:
……兹宣布自七月十五日起,艾德华·K·赵先生将担任本公司会计部副经理。他将直接向会计部经理柏特兰·杨负责。
艾德华·K·赵先生于一九七四年从美国嵌伯尔大学毕业,获有商学硕士学位。翌年考入莫理逊股份有限公司纽约本部,任高等会计员。一九七六年,奉派调马尼拉莫理逊亚太区部。今台湾莫理逊有幸迎接他奉派来台襄赞财务工作,必须指出:此一派令为亚太区部对于台湾莫理逊今后生产规模扩充计划之实质性协助的重要表现之一。
余深信本公司各级经理暨全体同仁,必与我同心向艾德华·K·赵先生致贺。
萨姆尔·N·塔尔曼
他把全录拷贝的副本搁在桌角上。他机械地把头埋进黄色的报表里。然而只那么几秒钟,他又抬起头来,把自己的手指哔哔剥剥地折拗着。然后他把报表一张张收起。他站了起来,把桌角上的副本细心地对折,放进自己左胸上的口袋里。他的整个的脸,连同他平时总是单薄却泛着樱红的唇,全变白了。
他于是笔直地走进 Bertland 的办公间。
“怎样,报表差不多了吧?” 杨伯良说。
他知道 Bertland 分明已经迎面看见了他因为无由自主的羞耻、愤怒和挫伤所曲扭的难看的脸,这若无其事的问话,使他仅剩的抑制力在刹那间绷断了。他从口袋拿出那份全录副本,撕成四瓣,扔在杨伯良的桌子上。
“大家这样互相欺骗,没意思。” 他困苦地说。
杨伯良立刻把手上的香烟,在满是烟尸的大烟灰碟里截熄了。
“坐下来,坐下来。” 杨伯良说。
他沉默地站着。他的眼睛从杨伯良的脸上移向他背后的大窗之外。窗外的对街是刚刚盖好的办公大楼。四五个工人在鹰架上披着炎夏的阳光,工作着。
“我应该跟你先提的,不错,” 杨伯良说,“Olive,他们要塞进一个人来,就塞进来,我能怎么办?”
杨伯良打开抽屉,抓起一包 Rothmans,递给他一根。他用双手做了一个抵挡的姿势,摇摇头。杨伯良把谢回的烟衔在嘴上,点上火。他看见 B. Y. (Bertland Young)的抽屉照例躺着几包牌名不同的洋烟。B. Y. 抽烟一贯很杂驳,Kent、Dunhill,甚至 More、Salem 都抽。杨伯良说:
“我这几天又忙又生气,没有事先告诉你,正是我把你当自己人,你明白吧?”
黄静雄冷冷地、无声地笑了起来。他依旧站着,低下头去看自己的一双擦得乌亮的皮鞋。
“你跟我这么久,Olive,” 杨伯良说,“也跟你说过许多话。我不是说过吗?他们洋人顶多三四年一轮,我和荣老董扣得很近、很密,我们才是长久的……你明白吗?”
“我不干了。” 他说。
杨伯良斜着眼瞟了他一眼。“你一向是我贴心的人,你的事我自有安排。” 杨伯良说。
“我不干了。” 他又说。
“你给我辞辞看!”B. Y. 生气了,“你辞!”
“我说辞就辞,” 他的眼眶因愤怒和委屈而红了起来,“不辞……不辞……我就不姓黄!”
他转身欲走。B. Y. 叫住了他。
“你胡说什么?”B. Y. 痛心也似的说。他站了起来,把办公室的门掩上。
他默默地看着窗外。在白花花的阳光下,鹰架上的工人一寸一寸地把大楼漆成乳白色。他们间或也交谈着,用围住脖子的毛巾擦汗。把门掩了起来的 B. Y. 的办公室,使冷气更加集中起来。他开始感到自己额头上的汗水所凝聚起来的凉意。
杨伯良这才点明那将新来履任的艾德华·K·赵,是荣老董的表侄儿。“老董最近常问起你。其实,他挺赏识你的。”B. Y. 说,“他常说,你的风度、才干都不像是本省人。” 黄静雄想起有一次 B. Y. 把他介绍给这一贯神秘的荣老董。
“荣将军您好。” 黄静雄说。杨伯良曾事先告诉他,老董喜欢人家以将军称之。
“好,好,” 荣老董说,迅速地上下打量着他,“好,好。” 他说,轻微地点着头。
荣老董是个退职的将军。他的面貌黝黑,粗浓的眉毛挂在墨镜上,一头银白的粗发。在第二次大战的中国战场上,他和当今莫理逊纽约总部里的总裁 Mr.Bottmore 同事于一个中美合作单位。朝鲜战争以后,Bottmore 从五角大厦退休,以二次大战在东方的经验,到一家顶尖的军火公司所属的莫理逊公司亚太部任职,迅速蹿升。台湾莫理逊公司的筹设,便是由他一手擘画。而 Bottmore 战时的老友荣侃将军,便被挑选为至为理想的名义上的中国股东和董事,使纯粹的美资,成为法律上的中美合作资本。
“只要 Bottmore 一天还当总裁,荣老董就是莫理逊在台湾的老板,你明白吧?” 杨伯良说,“洋总经理三五年一个轮调,那没什么。荣老董需要我,我需要你,你明白吧?”
荣将军需要他,黄静雄自然明白。好几次,杨伯良把荣将军厚厚一叠发票,交给他。杨伯良什么话都不必说,他就会把这些发票四平八稳地登上公司正当的开销。杨伯良需要他,他自然也明白。“把这笔账转掉。”B. Y. 若无其事地说。他于是就会把账合情合理地转掉,即使纽约委托的查账公司也无从查起。他也为杨伯良瞒着公司投资的几家和莫理逊做生意的厂商做内账。然而,这回他已经意兴阑珊。“你明白吧?年轻人要学着沉着点儿,明白吧?不干?不干只有你自己吃亏,白吃亏,你明白吧?就是要干下去,磨下去,久了,全是咱们的,你明白吧?”B. Y. 滔滔地、婆心苦口地说。他只是默默地注视着窗外,看鹰架上的工人顽冥地把一栋粗粝的大厦,一寸寸涂成乳白的颜色,在午后的阳光中,发出闪耀的亮光。然后,他走出办公室,看也不看自己的座位,走向电梯。他回家了。
十年了,他想。十年来,他过着千篇一律的、上下班的生活。到台湾莫理逊以前,他在两家不同公司待过。五年前,他在这宽敞的、华丽的吹着实实在在的冷气的办公室里,找到一张桌子。但是从来也不曾在应该是上班的、星期三的上午,一个人静静地待在家里。对于 “上班族”,家毋宁只是一个旅邸罢,他想。十年来,他生命最集中的焦点,最具创意的心力,都用在办公室里的各项工作上。第一年,他从会计员升高级会计员;第三年,他升信用组主任;同年秋天,他调升表报组主任。
然后,他开始成为野心勃勃的杨伯良的心腹。也就在那时,他开始热心地想望副经理的位置。薪水高、配车子,这都还在其次。黄静雄想望着副经理的椅子,还因为工作会轻闲些。那时他就有时间和心思的余裕继续他在大学时代没有拍完的一部纪录片。
他于是站了起来。他一眼就可以看见靠在客厅右边墙的他的书架上,一排破旧的、关于电影的书。罗塞里尼的专集三本,安德烈·巴桑等人关于费里尼、安东尼奥尼的研究论文集,以至于最初级的 *Young Film Maker*。这些全是他在大学时代耽读、并据以做梦的书。在大学的 “影响社” 里,他是个没有摄影机的拍片迷。他为那些有摄影机的社员写脚本,跟在他们后面谦卑而又热心地提拍摄上的意见,帮他们做剪接,然后从试映室走出来,孤单地踩着破旧的脚踏车回家。就在那些孤单的、几乎绝望地渴想着自己有一架摄影机的贫困的夜归的时光,使他立定要以单车为主题,拍一部纪录影片的志向。他的第一个镜头,是从车把照下去的转动的轮子,和不断地碾过去的道路……
和美娟论及婚娶的时候,他在一家小小的广告公司上班。美娟的家,一定要按照风俗收一点聘礼。他终于鼓足勇气,向师专甫毕业的、很传统地爱恋着他的美娟提起,请女方也以一个十八厘米摄影机作为嫁妆带过来。婚后,直到他进入台湾莫理逊前的贫困的、甜美的两年,他断断续续地拍了大约有五百呎的毛片。
就在昨夜,他才又想起整整搁置了四年许的毛片,和于今已嫌老式的摄影机。
——搁下那么久了。趁着这一段时日,再拍个百来呎。
——从脚踏车的转动的轮子开始,再照后座上的便当盒,然后让骑单车的最低等的 “上班族” 逐渐没入私家轿车、计程车和公车的街道中。然后,镜头调上矗立的、积木似的大厦的森林……
——Bertland,家伙!竟而让他骗了这么多年,这么多年。
——以后的生活吗?美娟近三四年来存起来的薪水,就是让我闲个一年半载,应该是没有问题的……
——上班,几乎没有人知道,上班,是一个大大的骗局。一点点可笑的生活的保障感,折杀多少才人志士啊。
**本文节选自《夜行货车》(陈映真小说全集 02),陈映真著,理想国·九州出版社,2020 年 6 月版。**

**内容简介:《夜行货车》收录陈映真创作于 1967-1982 年间的 6 部中短篇小说,包括《夜行货车》《上班族的一日》《云》《万商帝君》及两篇反映越战题材的小说,聚焦两次世界大战后台湾饱食、腐败、奢侈、炫丽、幸福的 “后街”,反思环境的崩坏、人的伤痕、文化的失据。透过台北八〇年代 “华盛顿大楼” 里的故事,讲述经济飞速发展的时代人们被异化的生活、被压抑的梦想、被辱没的尊严、被无声伤害着的心。辞职寻电影梦却被上班格式化的黄静雄,对资本主义文明由信仰到幻灭的青年张维杰,罢工遭压制的女工文秀英,出身贫寒、职场不顺终致精神错乱的跨国公司小职员林德旺……这些 “下定决心成功” 的上班族、这些无法归乡的年轻人的故事,诉说着我们生存的时代之预言。**
短篇阅读 鞋带 by 多梅尼科·斯塔尔诺内
==============================
**按:“对我们的父母来说,把他们绑在一起的是让他们可以一辈子互相折磨的纽带”。**
## __________
我确信,小偷——两个或三个——是沿着下水管爬上来的,他们爬到房檐边上,从那儿进入我们的阳台。他们用手把百叶窗拉了上去,把破旧的落地窗弄开,并没有把玻璃打碎,然后他们进到家里。看着阳台和周围的窗户,我带着一丝懊悔想,早知道会这样,当时就应该装上防护栏。家里也没什么值钱的东西,为什么要搞得戒备森严呢?我回到屋子里。在那种时刻,乱七八糟的房子也没有周围的寂静那么让人不安。我和妻子都无法倾诉自己的遭遇,给别人讲讲我们遭受的损失,得到一些安慰和建议,还有对我们的同情。大多数邻居都还在度假,周围听不到脚步声和说话声,也听不到开门关门的声音。阴雨天让每样东西都显得很不真实。婉妲应该看穿了我的心思,她说:你把行李拿进来,我去看看纳达尔在不在。她没等我同意就出去了,很明显,她再也受不了和我单独待在家里。我听到她下楼了,她停在了二楼,敲了邻居的门,那是一个多年的老朋友,也是楼里唯一一个几乎不去度假的人。
我把行李拉了进去,在这个杂乱的房子里,那些行李看上去是唯一一堆整齐的东西,即使箱子里装满了脏衣服,但那是我们唯一没被别人碰过的东西。我清楚听到妻子和邻居的声音,她语气很激动。纳达尔时不时会打断她,语气很文雅。纳达尔是一位退休的法官,九十一岁了,虽然年纪很大,但脑子很清楚,也很热心。我来到楼梯间,站在楼梯口看下去,看到纳达尔拄着拐杖,我从侧面看到他的秃头,还有上面几根稀疏的白发,他正在说着一些宽慰的话,用词考究,但像通常那些耳背的人,他说话嗓门很大。纳达尔想提供一些有用的信息,他听到了一些动静,不过不是深夜,而是在晚上。他当时以为是雷声,罗马从昨天开始下雨,一直下到现在。他很确信听到了猫叫,而且持续了一晚上。
“猫在哪儿叫?” 我妻子马上追问道。
“在院子里。” 婉妲抬起头,看到我站在楼梯的最上面。
“你赶快过来,” 她大声说,“纳达尔听到了院子里有猫叫。”
我不太情愿地走了下去,如果我可以做决定的话,我就会关上家门回海边继续度假。纳达尔执意想跟我们一起找拉贝斯,即使我坚持说,天还在下雨,他就不用去了。我们仨在院子里呼喊着猫。但我没办法一心一意找猫,我想:幸亏雨水已经把血迹都冲刷掉了。我想:我们不会找到它的,它一定藏得好好的,想安安静静地死去。我偷偷看着我的邻居,他那么消瘦,佝偻着身体,脸上的皮肤有些发红,紧紧贴在前额和颧骨上。假如我还能活那么久,我将来会不会和这个男人一样?还有二十年:我和婉妲,婉妲和我,有时桑德罗和几个孩子会来看我们,有时安娜会来。我们需要重新收拾一下这套房子,让它恢复原貌,而不是在这儿浪费时间。
纳达尔忽然拍了一下额头,他忽然想到了一件重要的事情。他对我说:
“这些天里,有人按了你们家门铃。”
“谁?”
“我不知道,但我听到了门铃声。”
“我们家门铃?”
“是的。”
我用开玩笑的语气说:
“你听到了我们家门铃,却没听到小偷把我们家搞得乱七八糟。”
“耳背的人总是习惯于倾听那些细小的声音,而不是很大、很嘈杂的声音。”
他为自己辩解道。
“他们按了几次门铃?”
“五六次。有一天下午,我还伸出头看了看。”
“是谁啊?”
“一个女孩子。”
纳达尔觉得我妻子也是一个 “女孩子”,我就让他描述了一下那女孩子的样子,但他说得很含糊。
“很娇小,黑头发,最多三十岁。她说要把广告单放在信箱里,我没给她开门。”
“你确信她摁的是我们家门铃吗?”
“非常确信。”
“然后呢?”
“昨天晚上也有人摁门铃了。”
“还是那个女孩吗?”
“我不知道,当时有两个人。”
“两个女孩?”
“一个男的,一个女的。”
婉妲站在喷泉边上对我招手。她消瘦的面孔上毫无血色,绿色的眼睛显得很突兀。她说:
“这有一只死鸟。”
只有我能理解她的意思:拉贝斯是个好猎手,会飞的鸟儿也逃不过它的爪子。我把纳达尔丢到那里,径自走到了妻子跟前。因为下雨的缘故,她的白发全粘在头皮上。我对她说,这并不能说明什么问题,你先回家吧,我去一趟警察局。她用力地摇了摇头,想陪我一同去,而我们的邻居也摆出了法官的架子,就像他没从法院退休了二十年一样。他一直在坚持说他会帮我们,他也跟着我们去了警察局。
我们拿着滴水的伞,到了离家最近的警察局,一位礼貌周到的年轻警察接待了我们,我们进到一间很小的办公室里。纳达尔一进去就开始自我介绍,连名带姓——纳达尔·达贝罗,他还特别强调了一下他的职业:法院院长。他用一种权威的语气讲了发生的事情,说得精确简洁,但他马上把话题拉到自己身上,讲述了他在风云多变的二十世纪的丰功伟绩。那位年轻的警察听得入迷,就像忽然下到了阴间,听死人闲聊一样。
有好几次我都想插嘴,把话题重新拉回来,说说我家公寓遭到的破坏。邻居的自吹自擂让我有些烦,我终于可以插话了,忍不住想强调:我也不是一般人。我告诉那个警察我的名字,并且重复了两三次——阿尔多·米诺里,阿尔多·米诺里,阿尔多·米诺里——就是想看看他有没有反应。而那个警察没什么反应,我说起了八十年代我做的一系列电视节目,这些节目基本都是我一手策划的,给我带来了一定的知名度。但这位警察那时候应该还没出生,或者年纪很小,他没有听说过这个电视节目,也没听说过我。他有些不自在地笑了笑,用一种权威的语气耐心地说:说正事儿吧!他流露出的威严是我和纳达尔早已失去的。
我很尴尬——通常情况下,我是个斟酌词句的人,不讲废话——我重申一下:小偷把我们的公寓给毁了。但这次我又忍不住离题了,我有些语无伦次地提到了那个多收了我五欧元的送货员,还有一星期前在家门口骗了我的那个男人。还不止这些,我还把纳达尔也牵扯进来,我让他说了说这星期按了我们家门铃好多次的那个女孩,还有我们回来前一天,出现在门口的那一对男女。纳达尔很高兴又有说话的机会了,他仔仔细细讲了每次门铃响的情况,有很多不必要的细节。后来纳达尔的话被打断了,有人打开了我们身后的门,我们仨扭头看之前,那人做手势和那位年轻的警察交流了什么。警察忽然笑了起来,他很难再严肃起来,他嘀咕了一句对不起,最后他问:
“他们偷了什么东西?”
“他们偷了我们什么东西?” 我重复了一句,但我在问我的妻子。她一直都保持沉默,这时候她嘟囔了一句:“什么也没偷。”
“金首饰丢了吗?” 警察问。
“我只有这对金耳环,不过我总戴在耳朵上。”
“有其他首饰吗?”
“有一串我母亲的珍珠,但他们没找到。”
“是你藏起来了吗?”
“没有。”
这时候我插了一句:
“小偷把家里的东西都翻了个底朝天,但他们找得不是很用心,他们连我妻子放在橱柜里的五十欧元都没找到,他们恼羞成怒打翻的洗碗粉盖住了那五十欧元。”
那个年轻警察流露出很不满的神情,他又转向纳达尔说:“肯定是吉卜赛人干的,他们让小孩从窗户或阳台爬进去,用家具抵着门,防止主人突然回来,然后在家里乱翻,他们会找金首饰。亲爱的先生,如果他们什么都没找到,就会报复,在家里搞破坏。” 我指出并没有家具抵着我们家门,门是被一些摔碎的东西卡住了。我又补充说:“或许您可以派个人去看看,可能家里有那些小偷的指纹。” 听了这话,警察更不耐烦了。他用一种受过良好教育的年轻人的语气,有些强硬地总结说:电视上演的是一回事,而现实却是另一回事。这种事情经常发生,我们没有在梦中被杀死在床上,已经算很幸运了。他还说,政府在削减维护社会治安的警察,在加强军队力量,在这个贫穷人口越来越多的时期,这项举措会损害市民安全,可能也会损害民主,谁知道呢。他让我们明白,提起以前的法官,还有以前的电视节目,这也证明了:现在这个世界非常糟糕,也有我们的责任。最后他建议我们在窗户上装上铁栅栏,安装警报系统,一旦有飞贼靠近就会报警。他还用一种带着讽刺的语气说,他觉得装那些东西也没什么用,我们家里也没什么可偷的。
我妻子坐在椅子上,有些激动地说:
“我们的猫不见了。”
“哦。”
“会不会是他们带走的呢?”
“出于什么目的呢?”
“我不知道,可能是想要赎金吧。”
那个警察笑了,那是一种很友好的笑,无论是对我还是对纳达尔,他都没这么友好。“一切都有可能,米诺里太太,您现在不要胡思乱想了,您可以往好的方面想。这可是一个您整理公寓的好机会,扔掉那些无用的东西,重新找到那些有用的、被遗忘的东西。至于那只猫,它可能只是抓住机会去寻找爱情了。”
我笑了,纳达尔也笑了。
婉妲没有笑。
## **本文摘自《鞋带》,上海译文出版社,2020 年 5 月版。**

**内容简介:一个炎热的夏季,人到暮年的阿尔多和婉妲从海边度假回到家,发现家里被翻了个底朝天,连爱猫都不见了。是谁干的?**
**每个家庭都隐藏着一些过去的秘密,阿尔多的秘密是他年轻时曾经抛妻弃子,与一个叫莉迪娅的女人同居。经历紧张、摩擦和平淡生活的重压,婚姻维持下来,但裂痕早已存在。如果细细打量,就会发现裂痕显而易见,就像一只早已有裂缝的花瓶,一触就碎,只是无人愿意承认。**
**意大利著名作家多梅尼科·斯塔尔诺内不但是展示暮年生活的高手,他的笔触犀利、深刻,也揭示了婚姻家庭生活的错综复杂。这段背叛的故事通过丈夫的角度,妻子的角度,还有两个孩子的记忆,从三个角度还原了整个事情的始末,也揭示家庭内部每个人体验的迥异与无法交流的处境。**
短篇阅读 盐 by 伊萨克·巴别尔 - MONO猫弄
==========================
# 短篇阅读 | 盐 by 伊萨克·巴别尔
作者:伊萨克·巴别尔
**按:一九二〇年,二十六岁的巴别尔以战地记者的身份,跟随布琼尼统帅的苏维埃红军第一骑兵军进攻波兰。战争历时三个月。巴别尔目击了欧洲历史上,也是人类历史上,最后一次大规模的空前惨烈的骑兵会战。几年之后,他根据这次征战经历,陆续创作了三十多篇短小精悍的作品,有战地速写,也有军旅故事,这就是一九二六年出版的《红色骑兵军》。**
## _________
“亲爱的主编同志,我想给您描绘一下那些个挖我们墙脚的妇女是何等的没有觉悟。您遍访国内战争的各条战线,写了许多报道,我相信您不会忽略一个名叫法斯托夫的民风刁恶的火车站,这个火车站位于某个遥远的国度的某个鲜为人知的地方,我当然去过那里,喝过私酿啤酒,用以润湿唇髭,但没有咽下肚去。关于上述车站,有许多东西可写,然而就如我们家乡的俗话所说,别把上帝拉的屎搬过来当宝贝。所以我只写给你看我亲眼见到的。
“七天前,一个月色如洗的宁静的夜晚,我们骑兵军那列劳苦功高的军用列车满载士兵,在那个车站上停了下来。全军战士都满怀激情地要把我们的共同事业推向前进,急于奔向别尔季切夫。可是我们发觉我们的专列却偏偏不起动,我们的 ‘加夫里尔号’①无意启碇,它为什么要在这里中途停泊? 其实这次中途停泊对我们的共同事业来说并非小事,因为背袋贩子②,这些凶恶的敌人,其中妇女同样占有半壁江山,正在厚颜无耻地对付铁路当局。他们大胆地抓住火车的扶手,在铁皮顶上飞快地奔来跑去,砰砰地捶打着顶,搅得人心惶惶。然而背袋贩子资本的胜利是兔子尾巴,长不了。战士们一个个自告奋勇地跳出车厢,终于让备受凌辱的铁路工作人员得以喘口气。车站周围只剩下了背袋子的妇女。战士们出于恻隐之心,让一些女人坐进了生有炉子的车厢,可是有些女人却没让搭乘。我们二排那节车厢里也坐进了两个姑娘,头遍铃响的时候,有个挺体面的女人抱着个娃娃,走到我们车厢前说:
“‘亲爱的哥萨克兄弟,让我上车吧,自从打仗以来,我成天抱着个吃奶的娃娃,在各地车站受苦受难,这回我想乘车去跟我丈夫团圆,可铁路上怎么也不让我搭车,哥萨克兄弟,难
“‘妇人’,我对她说,‘话说在前面,您的命运怎么定得看我们排里是不是同意。’ 于是我对我们排的战士们说,有个挺体面的妇女要求搭乘咱们的车子去某地跟她丈夫团圆,她手里的确抱着个娃娃,你们的意见怎样,让她上车还是不让?
“‘让她上吧,’ 弟兄们说,‘她跟咱们过招后,就不会稀罕她那个丈夫了!……’
“‘不,’ 我相当严肃地对弟兄们说,‘弟兄们,我向你们鞠躬致谢,可听你们说出这么下流的话,我着实吃惊。弟兄们,记住你们是怎么活过来的,你们自己也都是由你们的母亲奶大的,因此你们说出这样的话好像不太应该吧……’
“哥萨克们交头接耳地议论说,他,巴尔马绍夫,说得有道理,便让这个女人上车,她千恩万谢地爬进车厢。每个哥萨克都被我这番充满真理的话烧得心头火辣辣的,安顿她坐下,争先恐后地说:
“‘妇人,您坐在角落里,像所有做娘的一样,好生给您孩子喂奶,谁也不会上角落里来碰您的,您将如愿地回到您丈夫身边,没人会坏您的贞操,我们相信您是个心地善良的人,您会好好地给我们哺育接班人的,因为我们老的一天天更老,年轻的却很少。我们不管是现役的,不管是超期服役的,日子都不好过,又是挨饿,又是挨冻。至于您,妇人,尽管放心地坐在这儿……’
“响起第三遍铃声,列车开动了。美不胜收的夜景映满了天幕。天幕上缀满了油灯一般大的星星。战士们思念起库班的夜和库班绿莹莹的星斗。思绪像鸟儿一样飞往天外。而车轮则哐当哐当地响个不停……
“随着时间的推移,夜下岗了,于是红军的鼓手在红色的鼓上击响了晨鼓,哥萨克们发现我坐在铺上一夜没睡,满脸忧色,便走到我眼前。
“‘巴尔马绍夫,’ 哥萨克们对我说,‘你干吗这么发愁,坐了一宿没睡?’
“‘战士们,多谢关心,请原谅,让我跟那个女公民讲几句话……’
“我晃晃悠悠地打我铺位上站起身来,睡意像头逃避恶犬追逐的狼那样从睡铺上逃掉了,我走到她跟前,从她手里抢过孩子,扯开孩子身上的布片,看到里边包着整整一普特盐。
“‘同志们,瞧,多乖的孩子,不向大婶要奶喝,没尿湿她的裙子,也没吵得大家不能睡……’
“‘亲爱的哥萨克弟兄们,原谅我,’ 那女人冷冰冰地插进来说,‘骗人的不是我,骗人的是我遭的罪,是我心头的愤恨……’
“‘巴尔马绍夫可以原谅你的愤恨,’ 我回答那妇人说,‘巴尔马绍夫为你的愤恨花的代价还不算大。何况巴尔马绍夫花了多少代价,会讨还多少代价的。可是妇人,你看看哥萨克们,他们把你抬高到了共和国劳动人民母亲的地位。你看看这两个姑娘,她们现在还在那儿哭,一夜下来,她们遭了多少罪呀。你再看看在库班麦田里种麦的我们的妻子,她们守着活寡,耗尽了女人的力气,而她们的丈夫,也都过着光棍一样的日子,人性本恶,便身不由己地强暴落到他们生活中来的姑娘……可你,他们却没有碰一下,尽管你是个坏心肠的女人,操了你也活该。再看看俄罗斯,遍体鳞伤……’
“可她却对我说:
“‘我自己的盐,我爱咋办就咋办,我不怕什么真理。您不是在为俄罗斯着想,您是在救犹太佬的命……’
“‘现在不谈什么犹太佬,你这个该千刀万剐的女人。犹太佬跟这事挨不着边。而您,卑鄙的女人,比那个骑着价值千金的骏马、挥舞着马刀、威吓我们的白匪将军还要反革命……他,那个将军,在亮处,是看得见的,从哪条路上都看得见,劳动人民可以设想怎样把他结果掉。可你们这些数也数不过来的女人,抱着你们那些不吃不跑的娃娃,却像跳蚤一样,躲在暗处,看不见你们,而你们却咬呀,咬呀,咬呀……’
“我要承认,我把这个女公民扔下了飞驰的列车,可她却像铁打的一样,坐了一会儿,拍了拍裙子,又去走她那条卑劣的路。我看到这个女人居然平安无事,看到她四周满目疮痍的俄罗斯、颗粒无收的农田和遭到凌辱的姑娘,看到那么多的同志杀奔前线,生还的却寥寥无几,我想跳下车去或者自杀,或者把她杀死。可哥萨克们舍不得我,劝我说:
“‘给她一枪。’
“于是我从壁上拿下那把忠心耿耿的枪,从劳动者的土地上,从共和国的面容上洗去了这个耻辱。
“为此,我们二排全体战士,向您,亲爱的主编同志,向你们,编辑部全体同志,鞠躬致意,你们对待一切叛徒绝不可心慈手软,因为他们要把我们推入泥潭,使河水倒流,使俄罗斯死尸枕藉,荒草遍野。
“二排全体战士的代笔者——革命战士尼基塔·巴尔马绍夫。”
【注】
①“加夫里尔号” 原为波罗的海舰队的驱逐舰,1916 年起服役,1919 年国内战争期间,因在科波尔湾和喀琅施塔得击退英国军舰进攻而著名。1919 年 10 月被击沉。
②俄国在十月革命后的内战时期,大批贩子从乡下把粮盐等食品用袋子背至城市贩卖,这种投机行为史称 “背口袋的买卖”,称贩子为 “背袋贩子”。
**本篇摘自《红色骑兵军》,伊萨克·巴别尔著,人民文学出版社,2012 年 5 月版。**

**内容简介:他的小说像盐一样平凡而珍贵,《欧洲人》杂志评选世界百名最佳小说家第 1 名,他的短篇杰作《盐》是博尔赫斯最珍爱的作品,伊萨克·巴别尔、博尔赫斯、海明威最推崇的短篇小说大师。 “红色骑兵军”——生与死、残忍与善良、月亮与人头就这样平静地共处着,没有夸张,没有煽情,连一点惊异都没有。 当我们沉醉于博尔赫斯短篇小说中那精巧的结构,那传神的场景,那宁静而神秘的语气,我们不要忘了,再去看看那些奇妙写作技巧的发源地,那就是伊萨克·巴别尔的《红色骑兵军》。**
俄罗斯形式主义,是指二十世纪 10 年代到 30 年代时期,在俄国盛行的一个有影响的[[文艺评论]]流派。
它包含了许多颇具影响的俄国和苏联学者的作品,例如维克托 · [[什克洛夫斯基]]、[[提尼雅诺夫]]、[[弗拉基米尔 · 雅可夫列维奇 · 普罗普、罗曼 · 雅各布森]]。其中 Grigory Vinokur 在 1914 年至 1930 年之间确立了诗歌语言文学的独立性和自主性,这给文学评论界带来了一场彻底的革命。俄罗斯形式主义还对结构主义和想家、哲学家们施加了深远的影响,譬如 Mikhail Bakhtin 和 Yuri Lotman。而随着它在结构主义和后结构主义时期的发展,这场运动的成员们对现代文学评论也产生一定的影响力。但是在斯大林执政时期,它被当做用来描述精英艺术的贬义词语。
俄罗斯形式主义是一个多样化的运动,他们发表各自不统一的学说,也对他们所努力的中心目标没有一个广泛的共识。事实上,“俄罗斯形式主义” 描述了两个不同的运动:圣彼得堡的诗歌语言研究学会和莫斯科的语言学派。因此,相比较更加概括抽象的 “俄罗斯形式主义” 而言,用 “俄罗斯形式主义者” 来表达示显得更为精确。
这个术语 “俄罗斯形式主义” 首次被使用是来自这场运动的敌对方,所以严格说来,这个词语传达的意思是被他们自己明确反对的。用一个最著名的形式主义者(Boris Eichenbaum)的话来说:“很难记得到底是谁创造了这个名字,但是这的确不是一个很恰当的创造。它作为一个简单的作战口号可能是十分实用的,但是作为一个客观的术语,它没能起到界定诗歌语言研究学会活动范围的功能。”
"""
无所事事的青年
像无头骑士
在大街上游荡
他们“也是"在寻找生活的意义
渴望被人听见
所以修改电单车的排气管
排气管是无业青年的咆哮
无所事事的原因:失业
私会党
主人翁曾经小学生午夜骑单车
无声,经历被车撞
以至于心理阴影
成年就没有朋友
在他小学毕业前
曾经与一群好友
在深夜里,骑着脚踏车
享受着夜深人精的大道
-----
噪音是意象,是故事的中心
代表主人翁的魔障
小说的声音有
脚踏车的无声
电单车的排气声
主人翁的祈祷声
青年团的声音
对比是
每个人都发出声音
渴望被听见
每个人都在追寻发声的管道
每个人都希望被听见
主人翁,被上帝听见祈祷声
利益被层层剥削
主人翁
也有不同的团体
小学生
私会党
青年团
政治人物
"""
发作-艾丽丝·门罗
========================
发作-[[艾丽丝·门罗]]
-----
死的两个人都是六十出头,都是身材高大、体格健壮,体重都稍微多了那么几磅。他一头灰发,脸盘扁平,方方正正的,只是鼻子略宽,否则称得上十足地尊贵英俊。她一头金发,一种泛银的金色,你不再会觉得它是人工染色的了—尽管明知并非天然—好多这个年纪的女人都变成了这种发色。在节礼日[1],他们顺路过来与佩格和罗伯特喝过几杯。她穿件浅灰色套裙,上面有亮亮的细条纹,配灰丝袜和灰鞋,喝金汤力水。他穿棕色休闲裤和奶油色毛衣,喝兑水的黑麦威士忌。他俩刚从墨西哥旅行回来。他尝试了降落伞飞行。她不想玩那个。他们参观了尤卡坦半岛的一个景点—看起来像一口井—据说人们曾把处女抛进去,祈祷丰收。
“不过,实际上那只是一种十九世纪的观念,”她说,“那只是十九世纪崇尚处女的老观念罢了。没准他们抛人下去时根本不分辨。女孩啊,男人啊,老人啊,或者随便什么他们能抓到的人。所以不是处子之身也并非安全保障!”
房间那头,佩格的两个儿子—大一点的克莱顿还是处男,小一点的凯文已经不是—板着脸,厌倦地打量着这个谈笑风生的淡金色头发的女人。她说她从前是高中英语教师。克莱顿事后评论道,他知道这种人。
罗伯特和佩格结婚近五年。罗伯特之前没结过婚,佩格十八岁时结过一回。两个儿子都是她和前夫与公婆住在农场时生的。她前夫找到一份开卡车的活计,运家禽到多伦多的加拿大屠宰包装公司。之后别的卡车送货活计接踵而至,走得越来越远。佩格和两个儿子搬到吉尔莫,她在凯珀家的商店“吉尔莫商场”找到份工作。她前夫最后到了北极,穿越冰冻的波弗特海,把卡车开到钻探平台。她离婚了。
罗伯特家拥有吉尔莫商场,不过从未在吉尔莫住过。他母亲和姐妹都不相信人在那种地方能活上超过一个星期。第二次世界大战后不久,罗伯特的父亲买下这家商店和附近镇上的另外两家店,雇用当地人做经理,一年从多伦多开车过来查看几次。
很长一段时间以来,罗伯特对父亲的各种生意都兴味索然。他读了土木工程学位,想去不发达国家工作。他在秘鲁找到一份活儿,游遍南美洲,有段时间又放弃土木工程,到不列颠哥伦比亚的一个农场干活。父亲病倒后,他不得不返回多伦多。他到省高速公路局当了一名工程师。对这个年纪的男人来说,这工作不怎么样。他盘算着考个教育学学位,一旦父亲去世,就去北方教印第安人,过上彻头彻尾的新生活。他那会儿年近四十,正经历着有生以来第三段与有夫之妇的风流韵事。
时不时地,他开车去吉尔莫和其他镇视察商店。有一次他带上了李,他的第三个—事实上也是最后一个—有夫之妇。她带了一份野餐午饭,在车里喝“飘仙一号”甜酒,把整趟旅行当成一次欢乐的远足,一场对穷乡僻壤的突袭。她一心指望在露天野地做爱,到头来发现那里到处是牛群或戳人的玉米秆儿,不由勃然大怒。
父亲去世了,罗伯特确实过上了新生活,不过不是变成教师去荒蛮之地教书,而是到吉尔莫过起日子,亲自管理商店。他娶了佩格。
居然是佩格发现了他们,这实属偶然。
星期天晚上,给凯珀家送鸡蛋的农场女人敲响了门。
“别介意啊,我今晚就把鸡蛋送来了,而不是明早。”她说,“我得带儿媳妇到基奇纳去做超声波检查。我把韦伯家的鸡蛋也带来了,可我想他们不在。我把他们那份留在你这里,行不?我一大早就要出发。她说可以自己开车去,不过我想那可不行。她快五个月了,还是吐。告诉他们下次付钱给我就成。”
“没问题。”罗伯特说,“不麻烦。我们早上送过去好了。一点问题都没有!”罗伯特是个矮壮、有着运动员体格的男人,一头鬈发正在变成灰色,棕色眼睛亮闪闪的。他经常格外强调他的友好热情,让人感觉全身上下都被他捶打了个遍似的。这种态度让他在吉尔莫挺吃得开。这里,人们习惯于不断重复信誓旦旦之语。事实上,大部分交谈都是在不断重复,类似一种表达善意的回旋舞,毫无新意可言。只是偶尔,在与人们交谈时,他会有点不是滋味,好像有什么阻碍。他难以确定其性质(是恶意,还是固执?)。不过它就像你游泳时河底的巨石—清澈的河水会托着你浮过去的。
就吉尔莫人而言,佩格是相当安静的。她走到女人身边,接过她拎着的鸡蛋。罗伯特还在继续向她保证毫无问题,关心她家儿媳妇的怀孕状况。佩格像在店里找零钱时那样一笑—一个公事公办、转瞬即逝的微笑,客客气气。她是个娇小苗条的女郎,长着柔软的棕发,看起来能干又青春。她穿百褶裙,清新整洁的衬衫纽扣一直扣到最顶上一粒,外搭浅色毛衣,有时还打一个黑缎领结。她举止优雅,很少发出声音。罗伯特有次告诉她,他从没遇到过任何像她这样自成一体的人。(他的女人们通常都饶舌、精干,尽管在一些细节上毛毛糙糙的,但她们劲头十足,活泼而“有趣”。)
佩格回答说不明白他的意思。
他解释起一个自成一体的人是什么样的。那会儿,他对吉尔莫的词汇表理解得极不准确—现在仍免不了犯错—日常交流中他时常会表现得拘束生硬。
“我知道这词是什么意思。”佩格微笑道,“只是不明白你用它来说我是什么意思。”
她当然知道这词的意思。佩格去上课来着,当地高中可以进修。她每年冬天选一种不同的课上,她上过艺术史、伟大的东方文明史、发现和探索史。她每周去一次夜校,哪怕很累或感冒也不间断。她参加考试,写论文。有时罗伯特会发现冰箱上或他们房间的梳妆台上摆着一张写满她整洁的小字的纸。
因此,我们可以看出,导航者亨利王子的重要性在于启发、鼓励了葡萄牙的其他探索者,尽管他本人并没有参加航行。
她认真的叙述、拘谨仔细的小字体,以及对于如此用功写出的论文得分从没超过B+而感到的愤怒,都让他感动。
“我不是为了分数。”佩格说。雀斑下面的脸颊发红,好像正在剖白内心似的。“我是为了自己开心罢了。”
星期一,罗伯特天不亮就起床,站在厨房台边喝咖啡,远眺白雪覆盖的田野。气温下降了,天空清澈如洗。一连几个星期刮西风、大雪呼啸之后,典型的一月天来了:明亮,冰冷,到处冻得硬邦邦的。小溪、河流和池塘都结冰了。休伦湖在目力所及范围内也都上了冻。今年没准它整个冻上了。这种情况虽说不常见,但不是没有过。
他得开车去科尼利的凯珀商店。屋顶结冰了,水分回潮,从天花板渗下。他得去砍掉那些冰块,清理屋顶。那至少要花他半天时间。
店里所有修理和维修工作都由罗伯特亲自包揽。他学会了通水管和接电线。他喜欢自己能搞定这些事的感觉。他喜欢这里的艰难,以及这里冬天的麻烦,虽说距离多伦多也就一百英里多一点,但此地完全像另一个国度。所谓的“冰雪带”。说到底,北上来此度日,与一头扎进蛮荒之地可能也差不离。暴风雪仍旧让各个镇子和村庄与世隔绝。冬天严酷地降临,就像数千年前两英里深的冰层在此冻结一样。本地人以一种外人难以理解的方式过冬。他们小心翼翼,谨小慎微,疲惫不堪却又兴高采烈。
这幢房子令他喜爱的一点在于后院景色,可以俯瞰乡间旷野。它弥补了门口那条没有出口,没有林荫树,也没有人行道的破败小路。战后这条路就拓宽了,当时人们相信大家都会开车,不再有人步行。事实也确实如此。房子和房子、房子和小路都挨得很近,几幢房子里所有人都在家时,汽车便轻而易举地填满了本该是人行道、林荫道和林荫树的位置。
自然,罗伯特想再买一幢房子。他以为他们迟早会这么做。过去—现在也一样—有不错的老房子在吉尔莫出售,与城市相比,价钱都低得可笑。佩格却说,她没法想象自己住在那些地方。他提议给她在镇另一头的地皮上造一幢新房子。那个她也不要。她就想待在这幢房子里,这是第一幢她和两个儿子独自居住的房子。所以罗伯特买下了它—她之前只是租住—加盖了主卧室和另一间浴室,又在地下室里打造了一间电视房。凯文帮了一点忙,克莱顿基本上是袖手旁观。从路上打量过来,这房子仍旧是他第一次开车送佩格下班回家,在前面停车时的样子。一层半楼高,斜屋顶,起居室的窗子划分成很多正方形格子,就像圣诞卡上的窗子一样。白色铝质护墙,细细的黑色百叶窗,黑色边框。回到多伦多后,他想着住在这幢房子里的佩格,想着她过的井井有条、循规蹈矩、严肃而令人向往的生活。
他注意到台面上摆着韦伯家的鸡蛋。他想亲自把它们送去,但现在为时过早。门可能锁着。他不想吵醒他们。反正佩格去开商店门时会把蛋带上的。他拿起架子上压在她便条本下的标记笔,在一张餐巾纸上写道:不要忘记给韦伯家的蛋。爱你的罗伯特。这些鸡蛋不比在超市买的便宜。不过罗伯特喜欢从农场买它们。它们是棕色的。佩格说,城里人都很迷恋棕色壳儿的蛋—他们以为棕色蛋更自然,就像红糖一样。
他把汽车倒出去,看到韦伯家的车停在车棚里。这么说他们不管昨晚去了哪里,这会儿都已经在家了。然后他发现,镇上的扫雪车推到韦伯家的车道前方的雪依然如旧。扫雪车想必是夜里来的吧。他自己的车道上却无雪可扫。其实夜里没下雪,扫雪车没来。积雪是昨天的。那么昨晚他们想必没出门了。除非他们是步行。除了大街边和通往学校的路边,其他地方的人行道都没扫。在堆着高高的积雪、变得狭窄的路上步行是很困难的;不过,没准他们初来乍到,搞不清状况,所以还是这么出门了吧。
他没有仔细看看是否有脚印。
他构想出了当时的情形。先是根据警官的报告,然后根据佩格的说法。
大约八点二十分,佩格走出家门。克莱顿上学了,凯文因为耳部感染,待在地下室,一边放比利·爱多尔[2]的磁带,一边看电视上的游戏节目。佩格没忘记鸡蛋。她钻进汽车,发动车子预热,然后走下小路,走过韦伯家门口没扫的雪地,沿他们的车道走到边门。她围着白色毛线围巾,戴着白色毛线帽,身穿淡紫色羽绒服。这些衣服把吉尔莫的大多数女人都变成了水桶,不过佩格非常苗条,所以看起来倒还好。
小路边的房子起初只有三种式样。现在大都旧貌换新颜,装了新窗、走廊、侧翼和平台,再也不容易找出真正相同的了。韦伯家的房子原本和凯珀家是一模一样的,不过前窗已经改过,圣诞卡风格的窗格子拆了,屋顶也抬高了,现在对着小路的是楼上一扇很大的窗子。房子的护墙是浅绿色的,边框是白色的,没装百叶窗。
和佩格家一样,边门通往一个杂用间。她先是轻轻敲了敲门,以为他们都在距离杂用间只有几步的厨房里。她自然也看到了汽车,心想不知他们是否很迟才回到家,这会儿正在睡觉。(她还没意识到扫雪以及扫雪车昨晚没来的问题。这个是她事后回到自己车里倒车时才突然想到的。)渐渐她敲得越来越响。脸在光线明亮的冰天雪地里已经冻痛。她试着推推门,门没锁。为了避寒,她推门进屋,一边大声招呼着。
小屋很暗。厨房没透进任何光线,而且边门上还挂着一道竹帘。她把鸡蛋搁在干衣机上便打算离开。旋即她想,最好把它们送进厨房,免得韦伯夫妇早餐时想吃鸡蛋,却发现已经一个不剩。他们不会想到去杂用间找的。
(事实上这一点是罗伯特自己的理解。她没说所有这些细节,不过他忘了她没说。事实上,她只是叙述道:“我想最好把它们送进厨房。”)
厨房水槽上方的窗子和早餐桌边的窗子上挂着同样的竹帘,这意味着尽管和凯珀家的厨房一样,这间厨房也朝东,而且太阳这会儿高挂天顶,但并没有多少光线透进屋来。在这里,一天尚未开始。
不过房子里很暖和。或许他们不久前起来过,打开暖气又上床了;或许他们整晚都没关暖气—尽管佩格觉得他们不像这么大手大脚的人。她把鸡蛋放到水槽边的台面上。厨房的布局和她家几乎一模一样。她注意到几个碟子摞着泡在水里,还没洗。看来他们上床前吃了点东西。
她站在起居室门口又招呼了一声。
起居室非常整洁。佩格觉得有点整洁过头了。不过—正如她对罗伯特解释的—一对退休夫妇的起居室十有八九会给一个身边总围绕着小孩的女人带来这种感觉吧。佩格自己从来没能过上秩序井然的生活,尽管她或许不乏此愿。她自己娘家有六个孩子,前公婆家的农场房子同样也是挤挤挨挨的,然后她又生了两个孩子。她告诉过罗伯特一件往事。有一次她想要一块美丽的肥皂作圣诞节礼物,一块上面有玫瑰浮雕的粉色肥皂。她得到了。每次用过,她都把它收好,免得它像家里的所有其他肥皂一样开裂,裂口处发霉。她那时已经长大了,或者自以为如此。
她在杂用间跺跺脚,跺掉靴子上的雪。不过还是犹豫着不愿踩上起居室干净的米色地毯。她又招呼了一声。她喊的是韦伯夫妇的名字,这两个名字她挺陌生的。瓦尔特和诺拉。他们去年四月才搬来,之后两度出门旅行,所以她感觉跟他们一点也不熟。但是要是喊:“韦伯先生和夫人。你们起床了吗?韦伯先生和夫人?”未免也太傻了。
没有人回答。
起居室有一道楼梯通上去,跟佩格和罗伯特家一样。这会儿,佩格走过干净的米色地毯,走到楼梯脚下,楼梯上铺着同样的地毯。她爬上楼梯,没再招呼了。
她想必那时候就心里有数,否则就会继续招呼了。那才是正常的做法啊,越走近正在睡觉的人,你越会不断喊他们,以便提醒他们。他们没准睡得很沉。没准喝醉了。根据人们的了解,那不是韦伯夫妇的习惯,不过没人真的熟悉他们。退休夫妇。早早退休了。他从前是个会计,她是个老师。他们过去住汉密尔顿。他们选择了吉尔莫,因为瓦尔特·韦伯的姑姑和姑父以前住在这里,他还是小孩时来过他们家。现在姑姑和姑父都去世了,但这地方想必给他留下了美好回忆。此外这里物价便宜,这房子想必比他们的预算还要便宜不少。他们打算把余钱用来旅行。他们没有孩子。
她不再招呼了,也不再迟疑。她爬上楼梯,一路上没有四处打量。她径直朝上爬去。前方是浴室,门开着。里面干干净净,空荡荡的。
她在楼梯顶部转向韦伯夫妇的卧室。她从没到过这幢房子的楼上,不过她知道卧室在哪里。是房子前部延伸出来的那个房间,俯瞰小路的宽阔窗户就在那里。
房门开着。
佩格走下楼,穿过厨房、杂用间和边门,走了出去。她的脚印留在地毯、油布地毡和屋外的雪地上。她把身后的门带上。她的车一直发动着,已经笼罩在一小团它自己造成的白汽中。她钻进汽车,倒出去,开向市政大厅的警察局。
“今儿早上真够冷的,佩格。”警官说。
“是啊,够冷的。”
“有什么事吗?”
罗伯特打听到了更多,消息来自卡伦。
卡伦·亚当姆斯是吉尔莫商场的店员。她是个年轻女人,已婚,体格健壮,平时脾气很好,机敏麻利,忙而不乱。她与主顾相处融洽,跟佩格与罗伯特处得也不错。当然了,她认识佩格时间长些。她向来帮着佩格说话,反驳那些说佩格自打嫁了有钱人就变得傲气的人。卡伦说,佩格一直就没变过。不过,自打今天的事情之后,她改口道:“我还一直以为佩格和我是好朋友呢。不过现在可不那么肯定咯。”
卡伦上班时间是十点。她到得稍早一些,问是否已有顾客来了。佩格说没有,还没人光顾。
“不奇怪,”卡伦说,“太冷啦。要是再刮点风,真能出人命了。”
佩格煮了咖啡。他们有台新咖啡机,是罗伯特给商店买的圣诞礼物。过去他们总从街角的糕点房买外带咖啡。
“这玩意儿不是很棒吗?”卡伦一边喝咖啡,一边评论道。
佩格回答说确实。她擦着地板上的一些印记。
“哎哟哟,”卡伦说,“是我还是你弄的?”
“我想是我吧。”佩格说。
“所以我也没多想,”卡伦事后回忆道,“我想她肯定是带进来了一些泥巴。我没顾得上想,地上全是雪,你上哪儿去沾的泥巴呢?”
过了一会儿,来了个客人,是西莉亚·西姆斯,她听说了。卡伦在收银台,佩格在后头整理发票。西莉亚告诉了卡伦。她知道得不多。她不知道具体情况,也不知道佩格跟这事的关系。
卡伦冲后头嚷道:“佩格!佩格!发生了一件可怕的事,是你隔壁的邻居!”
佩格回答:“我知道。”
西莉亚冲卡伦挑了挑眉毛—她正是对佩格的态度不满的人中的一个—卡伦忠诚地偏过身子,耐心地等西莉亚走出商店。然后她急忙赶到后面,一路把挂着的衣架撞得乱响。
“韦伯夫妇都被枪杀啦,佩格。你知道吗?”
佩格说:“知道,是我发现他们的。”
“你!?什么时候?”
“今天早上,上班之前。”
“他们被杀了!”
“是被杀和自杀。”佩格说,“他枪杀了她,然后自杀。事情就是这样。”
“她跟我这么说的时候,”卡伦说,“我发起抖来。我浑身上下抖个不停,停都停不下。”她对罗伯特说着,为了演示,又抖了一回,双手捅进蓝色绒布运动服的袖子里。
“我就问:‘你发现他们之后做了什么?’她回答:‘我去报告了警察。’我说:‘你有没有尖叫什么的?’我问她腿有没有打战,因为我知道换了我肯定会。没法想象要是我的话,怎么可能走得出去。她说不记得是怎么出去的了,但记得关上了门,那扇大门,想着:一定要关上门,免得狗溜进去。那不是很可怕吗?她说得没错,但这事想想都可怕。你说她是被吓坏了吗?”
“没有吧。”罗伯特说,“我想她没事。”
这段对话是这天下午,趁着佩格出门去买三明治,在商店后屋展开的。
“她对我一个字也没提。什么都没说!我说:‘你怎么一个字都没跟我说啊,佩格。’她回答说:‘我知道你很快就会听说的。’我说没错,但她可以先告诉我的嘛。‘抱歉,’她说,‘很抱歉。’就好像她只是在为件小事道歉,比如用了我的咖啡杯什么的。只不过佩格永远不会那么干就是了。”
中午时分,罗伯特干完科尼利商店的活儿,决定不吃午饭就开回吉尔莫。快到镇上时有一家高速公路餐厅,位于科尼利出口边上,他打算在那里停车用餐。常有卡车司机和旅行者到那吃饭,不过大多数主顾还是当地人—归途中的农夫,开车出城的生意人和工人。罗伯特喜欢这个地方,今天进门时更是兴致勃勃。在寒冷的户外干活之后,他早已饥肠辘辘。今天的美景也让他高兴,田野上白雪皑皑,宛如雕塑,光洁耀眼,好似恒久不变的大理石一般。他有一种在吉尔莫常有的感觉,仿佛迈上了一个非正式的舞台,台上正演着一出漫长、愉悦的戏。而他熟知自己的台词—或者至少知道他的临时发挥准会大获成功。他在吉尔莫的整个生活有时似乎就是这样。不过,要是他这样去讲,人家准会觉得这是一种造作的生活,像某种刻意的、半闹着玩的东西。但事实正好相反。因此,比如在去多伦多的时候,当他遇到从前的熟人,一旦人家问起他在吉尔莫的生活,他总是回答:“真没法形容我有多喜欢它!”这是真话。
“你干吗不联系我呢?”
“你在屋顶上。”
“你可以打电话到商店,告诉艾丽。她会告诉我的。”
“那有什么用呢?”
“我至少可以赶回家来。”
他点好的饭菜都没顾上吃,直接从餐厅开到店里。他并不担心会看到一个陷入崩溃的佩格—他对她已有足够的了解—但他确实以为她会想回家,让他给她调一杯酒,花点时间跟他聊聊这事。
但她不想那样。她想上街去,到糕点店买平时的午饭—一个火腿奶酪面包卷。
“我让卡伦出门去吃饭来着,但我一直没时间去。要我给你带一份回来吗?要是你在餐厅没吃的话,我最好给你带点。”
她给他带了三明治回来,他坐在桌边吃着,刚才她一直在这张桌上摆弄发票。她往咖啡机里倒了点新鲜的咖啡和水。
“没法想象要是没有这玩意儿,我们该怎么办。”
他打量着佩格挂在洗衣房门上的淡紫色外套,它挂在卡伦的红外套边上。淡紫色外套上有一条变硬的红棕色颜料污渍,一路拖到衣服边缘。
那当然不是颜料。但是在她的衣服上?她衣服上怎么会弄到血的?想必是在那房间里拂到了他们。想必凑得很近。
他马上想起餐厅里的聊天,意识到她不必非得凑那么近。她有可能是在门框上蹭到血迹的。警官也在餐厅,他说到处是血,而且不只是血。
“他真不该用猎枪干那种事。”餐厅里有人评论道。
另一个人说:“没准他只有猎枪。”
下午大多数时间店里都很忙碌。街头、糕点房和咖啡馆、银行和邮局里的人,都在议论。人们想面对面聊聊,为此不得不冒着严寒出门。电话里说不过瘾。
罗伯特事后发觉,起初人们是打电话,打给想得到的任何有可能还不知道此事的人。卡伦打给她的朋友谢莉,后者因为感冒在家卧床;又打给她妈,她正在医院治疗髋部骨折。结果她妈已经听说了—整个医院都知道了。谢莉说:“我妹妹已经在你之前说过啦。”
确实,人们珍惜着、向往着爆炸性新闻传来的一刻—卡伦对于谢莉的妹妹感到相当恼火,后者不用上班,什么时候想打电话就可以打—不过这种冲动背后也有真正的善意和体贴,罗伯特这么认为。“我想她肯定不愿意自己被蒙在鼓里。”卡伦解释。确实如此,没人愿意自己毫不知情。走上街头,却不曾听说这事。像平日一样忙碌,却还不知道这事。就连罗伯特,一想到自己居然毫不知晓,佩格居然没告诉他,也难免觉得不自在,甚至有点丢人。
闲言碎语从早上的事件往前追溯。韦伯夫妇在哪里露过面?他们是如何与世无争、心平气和?当时距离变故发生的时刻有多远?
她星期五下午还在蒙特利尔银行排队来着。
他星期六上午还理了个发来着。
星期五晚上大约八点,在IGA超市,他俩一道采购食品来着。
他们买了什么?很多吗?特价品、广告打折的商品,比两天所需的食物更多吗?
更多。比如说吧,他们买了一大袋土豆。
然后是原因。话题转到原因方面,自然而然,餐厅里没人提得出什么说法。没人知道原因,也没人想象得出。不过,下午将尽时,已经涌现出太多的揣测。
经济问题。他在汉密尔顿卷入了某种糟糕的投资,某项赚大钱的疯狂交易,结果失败了。他们的钱全没了,余生只能靠养老金度日。
他们在所得税上昧下钱来。身为会计,他以为能瞒天过海,但是被发现了。他会被揭发,或许还会被指控,当众蒙羞,变得穷困潦倒。即便只是欺骗政府,这类事情一旦败露,仍旧是种奇耻大辱。
是一大笔钱吗?
当然咯。一笔巨款。
根本就不是钱的问题。他们病了。他们中的一个或者两个都病了,癌症、导致瘫痪的关节炎、老年痴呆症、难以治愈的精神病。是因为健康问题,而不是钱。他们怕的是受苦无助,而非贫穷。
男人和女人的想法明显有分歧。相信并坚持问题在于钱的几乎总是男人,讨论疾病的总是女人。谁会因为穷就自杀呢?有些女人不屑地反问。或者甚至就因为可能要蹲监狱?提出婚姻不幸说的也总是女人,要么是有什么不忠行为被发现了,要么是对于过去的某次出轨耿耿于怀。
所有这些说法罗伯特都听到了,但一个都不信。失财、癌症、老年痴呆,他觉得这些全都一样,煞有介事,空洞无聊。事实上,每种说法都让他信不到五分钟。要是能相信其中哪种,一直信下去,那他就能喘过气来了,就像有什么东西终于把爪子从他的胸口挪开了似的。
(“他们不是吉尔莫人,算不上是。”银行里有个女人告诉他,旋即满脸困窘地补充道,“我不是指您。”)
佩格忙着准备一月份销售的儿童毛衣、露指手套和滑雪服。她填着标签,人们走到面前,她便问:“您要买什么?”这样他们立刻就被安置到顾客的位置上,不得不说想买什么。商场出售女士和儿童服装、床上用品、毛巾、毛线、厨具、散装糖果、杂志、杯子、人造花,还有很多别的东西,想出个要买的东西并不难。
他们到底想要什么?当然不大可能是细节和描述。没多少人真想打听那个,或者愿意贪婪地、直截了当地承认。他们想,但又不想。他们开口问了,又住了嘴。他们竖起耳朵,又退缩了。或许,他们想从佩格那里得到的只是某种能让他们满意而归的承认、几句话或者某种眼神,好让他们感叹:“佩格·凯珀真是要吓瘫啦。”“我看到佩格·凯珀了。她没说什么,不过你能看出,她都快吓瘫啦。”
不过,仍有人试图跟她搭话。
“你们那儿发生的事够可怕的吧?”
“是的,确实。”
“跟他们也算认识吧,邻居嘛。”
“谈不上。我们跟他们完全不熟。”
“你从没注意到什么迹象,会让你料到可能发生这种事吗?”
“我们根本什么都没注意到。”
罗伯特回想韦伯夫妇从停在车道上的车里进出的样子。那是他最常看到他们的地方。他回忆着他们节礼日的来访。她穿灰袜的腿让他想到修女。她提起处子之身的话题,搞得佩格和男孩子们有点尴尬。她有一点让罗伯特想起他从前认识的那些女人。她丈夫话少些,不过并不害羞。他们谈论墨西哥食品,似乎做丈夫的不喜欢那个。他不喜欢在饭店吃饭。
佩格说:“噢,男人都这样!”
这话让罗伯特有点意外,事后他问她这是否意味着她希望多出门吃几次饭呢。
“我那样说只是为了声援她罢了。因为我觉得她丈夫好像在瞪她呢。”
他在瞪她吗?罗伯特没注意。那男人看起来很有自控力,不至于当众瞪自己的老婆吧。总体而言,他过于慵懒,有时可能甚至是过于无动于衷了,不至于在任何地方瞪任何人。
但是佩格又并非夸大其词之人。
各种琐碎的信息接踵而至。诺拉·韦伯结婚前的姓:德瑞斯克。诺拉·德瑞斯克。有人认识一个与她在汉密尔顿同一所学校教书的女人。她是个备受欢迎的老师,衣着入时,不大擅长维持秩序。教的是法语口语课,还开了法式烹饪课。
这里有几个女人问过她是否有兴趣组织一个图书俱乐部,她说有。
他在汉密尔顿比在这里活跃一些。扶轮社。雄狮俱乐部。或许是出于工作需要。
据人们所知,他们不上教堂,在两地都如此。
(罗伯特对于那些揣测的态度是正确的。在吉尔莫,一切总归会真相大白。隐私和保密均有违大众的兴趣。总有个把人嫁给保管各种档案的各个办事处的什么人,或者是他们的亲戚。人们构成了一个大网络。
没什么投资计划,在汉密尔顿或任何别处都一样。没什么收入税调查。没有钱的问题。没什么癌症、出问题的心脏,也没有高血压。她找医生咨询过头痛,但医生觉得并非偏头痛,也没什么别的大毛病。
星期四的葬礼上,通常负责接手宗教归属不明者的联合教会牧师谈及现代生活的压力和紧张,但没给出什么更详细的线索。有些人很失望,好像他们原指望他会这么做似的—或者至少可以提一提脱离信仰和教会组织的危险,失去信仰之罪什么的。另有些人认为,他再多说一个字都难免显得做作。)
另一个埋怨佩格没告诉自己这事的是凯文。他等到他们回家,身上还穿着睡衣。
她干吗不先回家,而是开去了警察局呢?她为什么不打电话给他?她可以回家打电话。或者凯文可以打电话。至少,她可以从商店打个电话给他。
他整个早上都待在地下室看电视。他没听到警车来。他没看到警察进进出出。对于发生的事他一无所知,直到他的女朋友莎娜午饭时从学校打来电话。
“她说他们用垃圾袋装着尸体出来。”
“她怎么知道的?”克莱顿问,“我以为她在学校。”
“有人告诉她的。”
“她是从电视上看的。”
“她说他们用垃圾袋装着他们出来。”
“莎娜是个白痴。她只适合干一件事。”
“还有人什么事都不适合干呢。”
克莱顿十六岁,凯文十四岁。年纪差两岁,但在学校里差了三级,克莱顿跳了一级,凯文没有。
“别吵啦。”佩格说。她从冰箱里取出意面酱,搁在双层蒸锅里加热。“克莱顿,凯文,快干正事,帮我做点沙拉。”
凯文说:“我生病了。会弄得它不卫生。”
他抓起桌布,像披巾一样裹在肩膀上。
“我们要用那个吃饭吗?”克莱顿说,“他把病毒弄到上面啦。”
佩格问罗伯特:“家里有酒吗?”
星期六和星期天晚上,他们通常会喝点酒,不过今天罗伯特忘了这茬。他去地下室拿酒。等他返回时,佩格已经把意面倒进锅子,凯文放下了桌布。克莱顿在做沙拉。克莱顿骨架瘦小,像他妈,此外,用功得可怕。一个明星赛跑者,一个魔鬼式考试高手。
凯文在厨房里游荡,挡着道儿,缠着佩格说话。凯文的身高已经超过克莱顿或佩格,或许比罗伯特还要高。他肩膀宽阔,双腿瘦精精的,一头黑发剪成他有胆量弄成的近似于鸡冠头的发型—莎娜帮他剪的。他皮肤苍白,经常冒粉刺。女孩们对此似乎都不介意。
“是真的吗?”凯文问,“那里真的到处都是血和黏糊糊的东西吗?”
“食尸鬼。”克莱顿说。
“他们是人,凯文。”罗伯特说。
“过去是。”凯文说,“我知道他们过去是人。节礼日是我给他们调的酒。她喝的是金酒,他喝的是黑麦威士忌。他们那会儿是人,但现在只是些化学物质了。妈,你最先看到的是什么?莎娜说那里到处都是血和黏糊糊的东西,一直溅到走廊里。”
“他看的那些电视,已经让他变野蛮了。”克莱顿说,“他以为那是录像。他根本分辨不出什么是真正的血,什么是录像上的血。”
“妈,真的到处都是吗?”
罗伯特恪守着让佩格自己对付儿子的信条,除非她向他求助。但是这回他忍不住开口说:“凯文,你知道你得住嘴了。”
“他忍不住,”克莱顿说,“像食尸鬼一样了。”
“你也一样,克莱顿,你也住嘴吧。”
但过了一会儿克莱顿又问:“妈,你有没有尖叫?”
“没有。”佩格沉思着说,“我没有。我猜想是因为没人能听到,所以也就没叫。”
“我没准能听到的。”凯文小心翼翼地重新加入谈话。
“你开着电视。”
“我没开声音啊。我在放磁带。要是你叫得足够响,我没准可以透过磁带音乐听到你的声音。”
佩格挑起一根意面尝尝有没有熟。罗伯特时不时看看她。他本可以说,他是想看看她有没有什么麻烦,是否显得呆滞、古怪,或者微微颤抖,看看她是不是会掉东西,或者把罐子撞得叮当响。但是事实上他看着她,正是因为她毫无这类迹象,而且他知道不会有。她正在煮一顿寻常的晚饭,用寻常的那种有点批评,但始终心平气和的态度听男孩子们说话。罗伯特觉得,唯一比平时更加明显的,就是她在厨房里是那样优雅、轻盈、敏捷、驾轻就熟。
她对儿子们说话的声调听起来挺严肃,骨子里却惊人地平静。
“凯文,要是你想在桌边吃饭的话,就快去穿点衣服。”
“我可以穿睡衣吃。”
“不行。”
“我可以在床上吃。”
“那就不能吃意面,不行。”
他们一起洗盆盆罐罐的时候—克莱顿去跑步,凯文在跟莎娜打电话—佩格跟罗伯特开口说了她那部分故事。他并没有要她开口,至少没想她讲这么多。他只是随口问:“那么你走过去的时候,门没锁吗?”她就全盘托出了。
“你不介意谈这个吗?”罗伯特问。
“我知道你会想听的。”
她告诉他她知道出事了—至少感觉有点不对劲—在上楼梯之前。
“你害怕吗?”
“不。我没想到那个—害怕。”
“可能有人带着枪躲在上面呢。”
“不会。我知道没人。我知道房子里除了我,没别的活人了。然后我看到了他的腿,我看到他的腿伸进大厅里,那时我就明白了,但我得过去确认一下。”
罗伯特说:“我知道。”
“伸在外面的不是他脱掉鞋的那只脚。他脱掉的是另一只脚上的鞋,以便用脚趾扣下扳机,射死自己。他就是那样做的。”
从餐厅的聊天中,罗伯特已经知道所有这些了。
“就这些,”佩格说,“真的就这些了。”
她甩掉手上的洗碗水,擦干双手,带着批评的表情涂护手霜。
克莱顿从边门进来。他跺掉鞋子上的雪,跑上楼梯。
“你们真该看看那些汽车。”他说,“这条路上爬满了愚蠢的汽车。然后它们到了尽头就不得不掉头再爬回来。我真希望它们堵在那里。我站在外面瞪着它们,可我快冻僵了,只好回来。”
“很正常嘛,”罗伯特说,“看起来挺蠢,其实很正常。他们没法相信,所以想过来亲眼看看现场。”
“真搞不懂他们有什么问题。”克莱顿说,“真不知道他们为什么没法相信。妈就不会不相信。妈就没吃惊嘛。”
“嗯,我当然有。”佩格说,这是罗伯特头一回听到她的声音流露出一丝不安。“我当然很吃惊,克莱顿。我只是没有失声叫出来罢了。”
“你没对他们这么做感到吃惊。”
“我几乎不认识他们嘛。我们对韦伯夫妇差不多一无所知。”
“我猜他们吵架了。”克莱顿说。
“这就不清楚了,”佩格说,机械地往皮肤上揉着护手霜,“我们不知道他们是否吵架了或是别的什么。”
“过去你和爸像那样吵架的时候,”克莱顿说,“记得吗?我们刚搬到镇上那会儿,他还在家的时候,在洗车店那里,你们那时候经常那样吵架,你知道那会儿我是怎么想的吗?我常想,你们中的一个就要过来用刀捅死我了。”
“不是那样的。”佩格说。
“就是。我就是那样想的。”
佩格在桌边坐下,用手捂住嘴。克莱顿的嘴抽搐着。他看起来没法停下抽搐,便把它扭成一个小小的、嘲讽的、抽搐的微笑。
“我从前躺床上时就是那么想的。”
“克莱顿,我们两个无论是谁,永远都不可能来伤害你的。”
罗伯特相信他该插嘴了。
“这个就像—”他说,“就像地震或者火山爆发。就像那类事情。这是一种发作。就像地球会发作一样,人也会发作。不过这在很长时间内只会发生一次。这只是一种偶然事件。”
“地震和火山爆发并非偶然事件,”克莱顿指出,明显带着一种漠然的愉快,“要是你管那个叫发作,那也是一种定期发作。人会定期发作,尤其是结了婚的人。”
“我们就不会。”罗伯特说。他看着佩格,好像想等她表示赞同。
佩格却看着克莱顿。这个女人平日总是苍白、柔滑、顺从,又像细纸中的水印一样难以捕捉,眼下却好像干涸了,死灰一般,她的轮廓固定成一种僵硬、无助、无法道歉的痛苦。
“不会。”克莱顿说,“不会,你们不会。”
罗伯特告诉他们他去散个步。他走到门外,发现克莱顿说得没错。许多汽车沿路探头探脑,开到尽头再掉头,又探头探脑地开回来,就为了窥探一番。车里坐的都是同样的那些人,或许就是他下午与之聊过的那些。不过,此刻他们仿佛与汽车合为一体,变成一种新怪兽,以一种野蛮的好奇,在这里来回摸索。
为了避开他们,他走上与他们家门口的死巷交叉的另一条短短的死巷。这条小路两侧尚未建房,所以扫雪车没来扫雪。不过雪已经发硬,容易行走。他一开始没意识到在雪地上走是多么容易,不知不觉就走到了小路尽头,爬上一段坡。那不是寻常的土坡,而是一堆雪。雪完全盖住了平时用来分隔小路和旷野的篱笆。不知不觉中,他已经翻过篱笆。雪硬到这个程度。
他这里那里走走,踩着雪。体重压在硬壳般的雪地上,连一声咯吱或一道裂缝都没造成。到处如此。你可以像走在水泥地上一样走遍整片覆雪的田野。(今天早上看着雪地的时候,他难道不是觉得它像大理石吗?)只是雪地并不平坦。它时而鼓起,时而凹下,与下面的地表起伏并非直接关联。大雪创造出了自己的地貌,以一种辉煌、霸道的气势横扫一切。
他不用在镇上扫过雪的街上散步,而是可以走上旷野了。他可以穿过去,一直走到公路边的餐厅,它营业到半夜。他可以在那里喝杯咖啡,再掉头回家。
大约在罗伯特和佩格结婚之前六个月,一天晚上,他和李坐在他的公寓里喝酒。他们讨论着把家族姓氏缩写刻到银器上是可被接受的呢,还是一种令人厌恶的做法。突然之间,争论爆发了—罗伯特记不得具体过程,但它突然爆发了。他们不知不觉对彼此说着能想出来的最残忍的话。他们原先扯着嗓子的争论,变成了一种带着微妙厌恶的低语。
“你总让我想到一条狗,”李说,“你总让我想到那种跳到人身上,用爪子扑他们,吐着恶心的大舌头的狗。你是那样急不可耐。你所有那些友好热情的表示—真是一种骚扰。我不是唯一一个这样看你的人。很多人都设法避开你。他们受不了你。你肯定想不到吧。你用那种急不可耐又可怜的样子,又跳又扑的,但其实一脸精明相。那就是为什么我根本无所谓会不会伤害你的原因。”
“或许我也该说说我不喜欢你的一点。”罗伯特平静地说道,“那就是你笑的样子。特别是在电话里。实际上你每句话说完都会笑。我以前以为那是一种神经质的表现,但它真的一直让我不舒服。我琢磨出来为什么了。你总是在告诉别人你在什么地方遭到的不公待遇,或者哪个人对你说的恶毒的话—那在你那种无聊透顶、自我中心的谈话中占了差不多七八成。然后你就会那样笑,呵呵,你能接受,你没指望还能遇到什么好事。那笑真恶心。”
又说了一些这样的话之后,他们自己,罗伯特和李,不禁笑了起来。那并非一种突破僵局进入和解的笑。他们并没有宽慰地扑向彼此,嚷着:“都说了些什么啊,我才不是那个意思呢,你呢?”(“不,当然不是,我也不是那个意思。”)他们笑是因为认识到了他们的窘境,就像在别的时候,在与此截然不同的、温柔得吓人的倾吐时刻一样。他们带着残忍的快乐颤抖着,因为说出的话覆水难收而激动。他们因为发出的攻击,也因为收到的攻击而狂喜。后来他俩不知谁说了:“这是我们认识以来第一次说真话!”那些话虽多少出于当时的冲动,却似乎也是最紧要的真相,它长期以来始终蠢蠢欲动,寻求破土。
从发笑到做爱距离并不远,他们也正是这样做的,这一切都无法收回了。罗伯特学狗吠,粗暴地用鼻子推搡着李,带着真正的欲望啮噬她的肉体。事后他们都深深地、最终地对彼此厌恶了,不过也不再互相谴责。
“有些事情我真希望能永远彻底忘掉。”罗伯特告诉佩格。他跟她谈了要即时止损,弃绝过去的恶习、昔日的欺骗和自我欺骗、对生活和自己的错误观念。他说他过去是一个情感上的挥霍者,任自己陷入无望而痛苦的纠缠,以避免一切有着正常可能性的事情。那统统是在做实验、摆姿态,是对于正常体面的生活契约的排斥。他对她如此倾吐。都是因为逃避而铸成的错误,他却自以为在冒险,在获取丰富经验。
“因为逃避而铸成的错误,我却误以为是激情导致的错误。”他说。他想,这话听来矫揉造作,其实是发自肺腑,他因为努力和宽慰都浑身冒汗了。
作为回报,佩格也告诉他一些事。
我们和大卫的父母同住。那里从没有足够的热水给宝宝洗澡。最后我们搬出来了,搬到镇上,住在洗车店旁。大卫那时只有周末过来。那里很吵,尤其是晚上。之后大卫又接了个活儿,往北方去了,我就租下这房子。
是逃避之错,还是激情之错。她没说。
大卫小时候得过肾病,一整个冬天都休学在家。他读了一本关于北极的书。那可能是唯一一本他不是被迫读的书。反正,他总是梦想着那里。他想去。最后这么做了。
一个人不会简单地开车开得越来越远,就这样从他老婆的视野中消失。哪怕始终梦想着北极也不能那样。在他离开之前发生过什么。婚姻之结不会仅仅因为距离的拉力而毫无痛苦地断开。肯定还得有一些撕扯和劈砍才成。但她没说,他也没问,甚至都没朝那方面多想,直到今天。
他在发硬的雪壳上走得飞快,到餐厅时,他还不大想进去。他打算穿过公路,走远一点,归途中再进餐厅暖和一下。
等他回头,停在餐厅外的警车应该已经开走了。在里面抽空休息的该是夜班警察了,而不是罗伯特从科尼利回来时,在餐厅说这事的警官。这一个估计没掌握什么第一手情报,也没找佩格问过话。尽管如此,他还是会谈论这事。餐厅里所有人都会聊这事,形容着同样的场景,重复同样的问题、同样的可能性。不能怪他们。
他们要是看到罗伯特,会问佩格怎样了。
克莱顿进门之前,他正想问她一件事。至少,他正盘算着这个问题,想知道问出来是否合适。在这么多讨厌的细节当中的一处,一点出入。
现在他知道那是不合适的,绝不适合问出口。它和他无关。一点出入,一个细节—一个谎言—但根本与他毫不相干。
走在这片魔幻的地面上,他一点不累。如果说有什么感觉,那就是他觉得自己变轻了。他走着走着,过了好久才意识到离镇子越来越远。空气清澈,吉尔莫的灯光显得分外明亮,好像和他只隔了半片旷野,而不是半英里,然后是一英里半,然后是两英里。承托住他的硬雪壳上躺着细小的雪花,像尘土一样精细,闪闪发亮。他逐渐走近的那些树和灌木的枝条也亮闪闪的。不同于冰暴过后小树枝和细枝上结起的冰壳。这有点像是树木本身变成了冰雪,熠熠发光。
这是那种鼻子和手指都能被冻僵的天气。不过感觉却一点不冷。
他很靠近一片大树林了。他正在跨过一条长长的倾斜的雪带,树木就在他前方和侧面。在那里,边上,有什么吸引了他的目光。树下有一种新的光亮。一种奇形怪状的聚合体,当中有不少黑洞,许多乱七八糟的臂状或花瓣状物,朝上方低矮一点的树枝探去。他朝那些东西走去,但仍旧看不出它们是什么。那不像他知道的任何东西。事实上它们看起来不像任何东西,只是有点像一个半瘫的铁甲巨人,仿佛在战斗中突然凝住,或者说像一个疯狂的小城市里横七竖八的塔楼—太空时代的小小城市。他琢磨着,始终不得其解,直到走得很近。他凑那么近,几乎可以碰到那些怪物之一了,这才突然发现那不过是些旧车。旧汽车、旧卡车,甚至还有一辆校车,被推到这里,丢在树下。有些彻底翻了个个儿,另一些角度古怪地互相搭着。它们部分盛满了雪,部分被雪覆盖着。那些黑洞洞就是它们的空腔。扭曲的铬合金块、破碎的车头灯,都闪闪发亮。
他想象着向佩格讲述这件事—他是凑得多么近,才看出让他迷惑不解的不过是些废旧汽车,然后他感到多么失望,又有点想笑。他们需要有些新话题。现在他有点想回家了。
中午,警察在餐厅讲着这事,描述了射击的力量如何让瓦尔特·韦伯朝后弹去。“把他一半人都炸出了房间。脑袋掉在大厅里。炸剩的脑袋就掉在大厅里。”
那不是一条腿。并非一条暗示性的腿,完整体面地裹在裤子里,脚上穿着鞋。让人爬上楼梯转过去一看,然后走上去,迈过它,走进卧室,去看一看里面还有什么—那可不是这么一条腿啊。
[1] 英联邦部分地区的一个节日,为每年的十二月二十六日。
[2] 英国摇滚明星,出生于1955年。
方肯 主宰者 - 副刊 文艺春秋 星洲网 Sin Chew Daily
======================================
[https://www.sinchew.com.my/content/content_2359209.html](https://www.sinchew.com.my/content/content_2359209.html)**
# [[方肯]]/主宰者
文艺春秋
他一直躺着,日久变成一座山,脸上长满树木,嘴边都是浓密的灌木,而眼睛的周围光秃,因为他不愿闭上眼睛,只为直视太阳和星月,守住唯一的永恒。
他不在乎云朵,它们迟早会飘走,一如流泻不止的时间,带走生命和善恶。
为了主宰一片森林,他曾经站在善与恶的之间。他温柔地说谎话,带着慈祥又亲切的微笑,森林的动植物被他任意摆布,仿佛被催眠,仿佛被掏空灵魂,仿佛被挟持了神智。
动植物视他为森林里共同的敌人,却没有能力摆脱他,身体不听使唤地向他鞠躬,对他言听必从。他的谎言,分散动物们欲反抗的躁郁,有的被说服,有的因此迷惘。意志坚定的动植物,最终会在他的谎言之下被质疑、被排挤,无法聚合对抗他的力量,最终自暴自弃,到森林以外的海漂流。
谎言造就他,他成就谎言。
直至一天,森林平静如常,那平静已持续太长的时间,他觉得自己的主宰已毫无意义,他便找了一块空旷的平地,平躺下来,如一片树上飘零而下的枯叶,不再发出声音。
谁都没有发现他隐匿的身体,动物爬上他四肢,在他的胸膛奔跑、蹦跳;树木一分一寸地占据他的全身,包括他的脸庞和五官,唯独他的眼睛,是任何一物不能抵达的地方,最后只是黄土。
它们称他为山。
地底的老鼠蛰伏多年。它们挖掘四通八达的隧道,在里头存放腐烂的果子、动物的尸体,各种酸的腥的恶臭在地底交错。老鼠们嗅觉本就灵敏,但对于恶臭之习惯,已和自己融为一体,无以辨别。然而,其他动植物能远远地闻到老鼠的气味,那充满毒性的恶臭,逼迫它们回避老鼠们的出没地,视之为禁区。
隧道里日积月累的粮食,从地底满溢出来,动植物们找到自己失踪许久的伙伴,悲恸不已,泪成洪水,使自己被泥水吞没,最后沉入水底。老鼠们潜入幽暗的水中,撕裂那些未从哀伤解脱的脸孔,噬咬它们每一寸皮肤和血肉,留下无以辨认的遗骸。
虫子目睹了一切。它们选择它们认为强大的一方。虫子不常饥饿,粮食来源充足,但它们对现有的粮食感到单调,厌倦无时无刻寻找粮食的生活。除了粮食,它们开始垂涎权力的虚荣,渴望结束被藐视的待遇。
虫子曾效忠他,负责收集情报,执行他的命令。正因如此,那时动植物都知道虫子的身分。当他变成了山,它们不再被赋予任何责任,可有可无。于是被藐视,被轻蔑,即失去利用价值的普通虫子。
老鼠接受虫子的加盟,以及它们的贡品。此后,它们地底的势力便壮大了。一点一滴的扩大,它们不局限在地底,陆陆续续爬到地面,撕咬不能移动的植物,偷袭安眠中或进食中,或沉浸在安闲中的动物,不畏惧各种型态或体格,因为老鼠和虫子的为数众多,像狂浪大口大口吞食了一切。
虫子知道太多事情,那些藏于缝隙、边缘、最高或最深处的隐私,都在太阳底下曝光。老鼠需要虫子。它们找到所有卵生动物藏卵的地点,敲破过鳄鱼、响尾蛇、老鹰的蛋,然后舔干蛋液,或吃掉未孵化成形的幼儿,遗下蛋壳碎片刺痛那些母亲的心脏。
它们散布仇恨的种子,在各处迅速发芽,长出黑色叶子白色花朵的植物,根部沿着地面延伸,遇洞则钻;遇老鼠或虫子就紧紧缠绕对方,待猎物没有生息,自己就随之死亡。这种植物强烈威胁老鼠和虫子的存在,它们因恐慌和愤怒而拒绝为之取名,也禁止其他动植物提起。一旦发现,讨论者将在顷刻间被啃光,骸骨也会被噬咬至粉碎,任风送去未知的远方。
动植物偷偷称它为“那个东西”。
夜半时分,当川谷的风流连至此,那个东西的花瓣便如蜂翼摆动,仿佛准备起飞,发出响亮的玻璃声。那些失去伙伴的动植物,在清脆的叮铃叮铃声中,听见已逝的生命从远方传来低吟,陈述各自被掩盖的死亡过程。每个夜晚,低吟不减,牵着动植物聚合在那个东西的密集之地,在凌乱的密语中颤抖。它们抚摸黑色的叶子,俯卧在那个东西的根部,好像在拥抱那些不再归来的灵魂。
地底隧道被那个东西盘踞,仿佛和时间赛跑,抢着消灭所有老鼠和虫子。魔爪般的根部,伸展比老鼠和虫子的腿快,它们来不及惊愕或惧怕,呼吸如被捻熄的蜡烛,从此黑暗。
老鼠和虫子需要新据点,重建它们的势力,重燃它们嚣张跋扈的气焰。
老鼠厌恶绚丽的色彩,以自身晦暗的皮毛为荣,就捣毁盛放的花朵,在花的尸体之上建造新据点。腐烂的果子和尸体,都储存在钻石型的建筑物里。高耸而丑陋的顶部,挂满动物的骸骨与枯萎的植物为饰物,恶臭比昔日更甚,森林不再有花香。老鼠和虫子掠夺了整座森林,它们比每个昨天暴戾,未来继续发生更残忍的惨剧。
“你们若要得到权力,必要爱上血的味道,欢快的毁灭。”老鼠告诉虫子。
原本仅吸取植物汁液和花蜜的虫子,已没有回头的余地。它们许久不在深夜鸣叫,也不独身出行,避免被伏击。虫子必须遗忘本性,咬噬老鼠剩下的腐坏尸体。但是它们必然知道,它们不过是盲目地假装。它们奢望权力,却被权力征服。
老鼠和虫子必须反击那个东西,在它们未遭灭绝以前。它们什么都没有,只有尸体。于是,它们将尸体堆叠成山,萃取尸体里的汁液,沁入在那个东西的所在地。那个东西叶脉般的根,在地面和地底编织了密密麻麻的网,瞬间被烧灼成焦黑,化为灰烬,飘飞于空中,不见踪影。
尸体汁液比仇恨更浓稠更卑劣,灼伤了大地。大地疼痛,疲乏。晕眩。在恍惚中摇晃,摇晃它无法风干的伤口。在迷蒙中摇晃,摇晃它已无法掌握的黄土和砂岩。
摇晃的摇晃,河也摇晃,流水倾倒而出,流向四方后被蒸发,干枯的河床躺着奄奄一息的鱼。弥留之际,鱼想起它们还是一颗卵的时候,以为此生会游至河的尽头,并未预料结局就在诞生的地方。它们还没见过最险恶的暗潮和暗礁,眼巴巴地见水和自己一起枯竭。
凡是会摇晃的都在摇晃,云也摇晃,在天空四散如粉屑,雨就没有下来。鱼等不到一场雨,鳞片终究在干燥的空气中片片剥落,一地的闪烁如星,是太阳映照的死亡。
凡是会摇晃的都在摇晃,摇醒了躲在穴里冬眠的动物。它们从黑色走出来,穴外艳阳耀眼,它们睁不开眼睛。它们不知道它们为什么走出来,也对外边的世界没有头绪,茫然地朝震荡走去,犹如被召唤的傀儡。
鱼之消亡,使动植物们凝结在冰冷的沉默中。那些刚从冬眠苏醒的动物,有的终于睁大了双眼,环视四周,决定要收拾这片残局;有的仍闭着双眼随队伍行走,依旧没有思想。
悲伤已比平静的时间长,在动植物的气息里刻下沉重、剧痛的痕迹,它们当中有些不幸窒息,有些抓紧最后一丝喘息,在折腾中诅咒老鼠和虫子。它们生存的目的,仅为了见证老鼠和虫子的灭亡。
在星光下,动植物向那个东西伸手,那个东西也向周围伸出黑色叶子,低吟忽然中止。玫瑰褪下它的殷红,花瓣变成苍白;孔雀不再留恋羽毛的色彩,阴郁稀释了所有颜色,余下深浅不一的黑;怒火烧掉了变色龙的颜色,从此它只有白。动植物和那个东西一身剩黑白,颜色令它们哀伤,那是回不来的平静日子。
蟾蜍在树上俯瞰一片黑白,腿部沾染着血迹。那不是它的血,走进钻石型建筑物时,必将采过稀烂的尸体。它向它昔日的食物——老鼠俯身,然后摊开双手,壁虎和蜗牛哗啦如雨降至。它生活于水,于陆地,没有长久的居所和朋友,它只为生存而生存。
蛇坐在老鼠的旁边,犀利的眼珠盯着蟾蜍,吐信是一种挑衅。它喜欢舌尖在此采集的味道,它想念老鼠和蟾蜍的血,也想念它们从喉咙慢慢滑入肚里的快感。蛇仅仅想念,却不能再如昔日生吞它们。它和蟾蜍、虫子无异,尽管它的毒液可猎杀无数,权势却不站在它这一方。
老鼠之间没有交心或骨肉的情谊,但打从它们一出世,就知道它们依赖彼此,像束缚在一起的芦苇,才能建成一搜不沉没的船,向至远至辽阔的世界航行。
带领它们的曾是鼠一世,那时候它们不如现在贪婪,夜夜窜入人类的田里盗取玉米、稻穗,或等待一只老死或战斗而死的鸡、老虎或牛。在太阳底下,它们佯装诚挚,专一地等待从大树坠落的果实,但在树下的等待者不仅有它们,还有猴子、熊,以及早已在枝桠上凝视的猫头鹰。
关于那四通八达的隧道,那是鼠二世所造,当蟾蜍献上另一只蟾蜍的尸体,蛇献上另一只蛇的尸体,它们就在一起了。蟾蜍与蛇的捕猎,充实了隧道的粮食库,也孕育了更多更臃肿的老鼠世代。
老鼠的后世步履蹒跚,举止表情木讷,终日的饱食阻碍它们思考。它们啃食石头,磨碎牙齿,又从山崖跃下,以为彩虹是一座不坠的桥。它们心中没有胆怯,肆意咬破小鸡的喉咙,还有在那已耸立超过500年的菩提老树下,啃咬比它们粗壮的树身。
蟾蜍、蛇与老鼠的勾结,鸟都看在眼里,它将消息传布给其他动植物。动植物秘密传话,但青蛙和蜥蜴都拒绝相信,直认鸟是造谣者,离间大家和蟾蜍、蛇的关系,纵然它们互不相识。它们遇见鸟着陆的时候,青蛙对之鼓胀脸颊,蜥蜴则鼓胀喉咙,但鸟对它们不屑一顾,往腐叶掩盖的土里猛啄几下,瞬间叼起一条肥美的蚯蚓,就往天际最高的卷云展翅飞去。青蛙和蜥蜴留待原地,仰望鸟逐渐缩小的背影,脸颊和喉咙还鼓胀着,像即将升起的气球,却一直没有升起。
老鼠不断扩张它们的新据点,填满了湖,推倒了树,一吋一吋占据动植物的领域。那个东西和动植物以呼喊一致的口号,结成钢丝般的围篱,紧密交织而结实,无一丁点透风的洞孔,包围起共同的居所,阻止老鼠的侵入。
蟾蜍在围篱结成前,向老鼠通风报信。蛇比它先到一步,已懒洋洋地躺在钻石型建筑物里,以促狭的眼神瞟了蟾蜍一眼。蟾蜍领不到功劳,悻悻然离去,回到月光照亮的森林里。青蛙始终见到蟾蜍从老鼠的版图走出来,而且见其脸色毫不惶恐,像是蟾蜍的另一个家。
青蛙终于相信鸟的话,但它没有机会表达它的醒悟了。蟾蜍的毒液注入青蛙的体内,到青蛙变成黑色后,蟾蜍才回到那湿润的沼泽,如往常展开一夜不眠的叫鸣。这夜鸣声格外低沉,犹如一首挽歌。
翌日早晨,虫子搬来了青蛙的尸体,安放在动植物的中央,然后欠身离开。大家都坚信是老鼠所杀。蜥蜴直觉是鸟杀了青蛙,于是它更憎恨鸟,也厌极其它动植物。这个被扭曲的世界里,只有它独醒。它开始散布鸟是凶手的消息,动植物当中有的信了,有的不信。那个东西和动植物的口号无法一致,围篱未结成便破败。
动植物此时想起了他,那个无尽谎言的主宰者。
若是他归来,森林便会回到平静之前。动植物的秘密会被揭露,行迹将被监视。所知道和不知道的一切,将因他的谎言而变得混乱──长颈鹿倒立,苹果树结出蓝色的果子,乌龟以为自己是蜗牛,兔子以为自己是松鼠。为的秩序,进行他认为应当的主宰。
山听见动植物在讨论他,甚至在寻找他,他就挪动了身体。泥土和树从他身上逐一掉落,飞禽从他的发间纷飞。他拍走身上的沙石,四周的一草一物都在他的视线里十分清晰,但风景已不是他躺下时的模样。他尊贵的宝座早被老鼠啃噬,被风吹蚀,遗下残毁不堪的木块,难以辨别是把手抑或椅脚──这些都被掩埋在老鼠丢弃的白骨下。
当他躺着的时候,他一直望着天空,一句话都没有说,只用耳朵聆听他曾主宰的森林。他一直知道老鼠的行迹,也知道虫子的离异。他从空旷的平地坐了起来,他想把他的秩序找回来。因为他想,所以他迈步走了,去做他想做的事情。
老鼠知道他回来了,便为自己的安危担心。它们明知鼠二世只是一个继承权力,却没有谋略的王,根本不能抵抗归来的他。但它们从不敢让鼠二世知道自己的无能,给它最美的赞颂,最尊敬的崇拜,以图自己在鼠群的可分多一点粮食,品尝到最新鲜的血。
鼠二世对他的归来毫无畏惧,耻笑他的老去。它们不准备防卫,也不准备商讨对策,日复一日如常堆积尸体,灭那个东西,挖凿更畅通的地底隧道,把足以掩埋整个森林的尸体和果子,送往森林以外的粮食库。
整个森林都知道鼠二世在森林以外的粮食库。它们知道总有一天,鼠二世会把所有动物都藏进它的隧道里,可让整个鼠的王国、虫子,甚至它们几个世代都不愁食。
动植物决定再向他躬身,替他戴上皇冠,还他权杖,为他建造一个与昔日无差别的宝座,但今时的动植物已非他曾主宰的。它们看穿了他的谎言,已懂得在他的声音面前保持清醒,抱紧自己的灵魂,扼住或许会迷糊的神智。它们立下协议,一旦回到他的主宰,他必须在第三个月圆步下宝座,把森林还给它们。
他必须答应。为了将森林扳回他的秩序上,他唯有答应。他在月亮底下答应了它们的协议。
有那么一群老鼠,它们在偏僻的山丘旁,没有阳光的阴影处,另凿地窖,私藏粮食。它们没有等待反叛的时机,不过是为老鼠王国瓦解之后,准备重辟天地。
有那么一群老鼠,它们与每只老鼠拥抱表示友好,并且静观各种风吹草动,不牵扯其中,也不干预。它们没有等待反叛的时机,却等着随时踩上鼠二世的尸体,站在钻石型的建筑物之上,宣布主权。
他在钻石型的建筑物上敲开一个洞,光从洞涌进里头,拨开老鼠之间朦胧的纱,揭露了老鼠们若隐若现的秘密。光,使秘密刺眼。他将真话和谎言互相调和,又变成谣言,而谣言难以被识穿,每只老鼠相信自己选择相信的。谣言弥漫在整个钻石型的建筑物里,老鼠们感觉空间越来越闭塞,感觉自己的喉咙仿佛被勒紧。
震荡,摇晃,山石堆满钻石型建筑物的周围,封闭了出口,老鼠们被囚禁在谣言之中,像无止尽的咒语,摧残它们的耳朵和思考。意志薄弱的老鼠啃咬自己的身体,并在互相猜忌中因郁闷而消瘦,最后瘫软在隐密的暗角,含着自己的尾巴睁眼死去。
当他说完最后一个谎言后,鼠二世的身体像蛋糕被其他老鼠捣烂、撕裂,染上一片晕眩的血色,像焦灼后的灰烬,黏附在四周,怎么也脱不去。
鼠的世界分崩离析,森林的主权回到他的手上。
他熟悉老鼠身上的每一根毛发,牙齿的数量。动植物都不知晓,他培养了老鼠的残酷与狡诈,在他曾主宰的时候,为他消灭反对他的声音,毁坏反抗他的念头,巩固他的权力。老鼠学了他的手段,动植物都动不了它们,像推不倒的磐石,永远为自己制造有利的环境。但是,老鼠学不了他的智慧。
唯有他才能毁掉自己创造的一切。
动物们将钻石型的建筑物拆除,慢慢地搬走一瓦一砖。那地底冒出暗红色的浓烟,溢出辛辣的涩味。老鼠们埋藏的秘密逐一显现,它们的王国是由血建构而成。在破碎的残瓦交叠之下,露出一条扭曲的尾巴,仿佛终于从禁锢中解脱──那是蜥蜴。它的头部不知所踪,只剩下完好的身体。头呢?动植物各自寻觅,却连一颗眼珠都找不到。它们猜测,那滚滚浓烟里大概有蜥蜴的一部分。
他让动植物回到自己本该居住的地方,花儿重放,雨水重灌河中,卵在河中反射微弱的光,像零散的星子。第一尾鱼孵化出来,顺水流游到花朵飘落的水面下。接着是第二尾,第三尾,直到河里都是鱼。
动植物追问他已逝灵魂的去处,他不发一言,将树木种植到原本的土壤,将泥土填满老鼠挖掘的隧道…… 他正把森林扳回他认为的秩序上。他做他想做的事。
第三个月圆时,他还没有完成。他日以继夜地修建亡灵的石碑。动植物都来追讨他主宰的权力,催促他摘下皇冠,交出权杖,离开它们为他建造的宝座,把森林还给它们。他仍旧不理会动植物的声音,按照他想做的事,继续缝补森林的每一个伤口。
动植物深恐他重施谎言,越来越鼓噪。每天在太阳升起后和落下前,动物一齐蹬脚,树上的叶子都坠落,覆盖在森林的土地。层层落叶逐日叠高,掩盖了他的宝座。
他找不到他的宝座了,但他还没有完成他想做的事。动植物等不了他,他只好依照协议退下。
他回到那空旷的平地,环顾他重建的森林,花儿盛开,动物奔放地跑,树木不再显露焦虑的颜色。那个东西渐渐枯萎,化成随风消散的灰,而风里不再有那来自远方的的低吟。
然而,老鼠们此时拾起钻石型的建筑物之碎块,一块一块堆砌成方块的形状。它们推举了年老多病的老鼠当新的王,并集体开始重新挖掘隧道。它们还没有增添新的血,虫子、蟾蜍和蛇都在动植物未察觉之时,见证了方块建筑物的顶部,重新挂上骸骨与枯萎的植物。
他回到那空旷的平地,慢慢躺下。这次,他闭上了眼睛。在鼠疫降临前。
作者 : 方肯
文章来源 :
星洲日报 2020-10-16
方肯 装死的人不穿鞋 - 副刊 文艺春秋 星洲网 Sin Chew Daily
========================================
# [[方肯]]/装死的人不穿鞋
#文艺春秋
-----
我的邻居黑先生已有一周没有出现。黑先生是一名律师,他的眼皮总是半关,每天早晨就顶着凌乱的头发在阳台晒衣。衣服比较喜欢待在阳台,可以吹风,可以见见日光,还可以看着白云做白日梦。衣服摆脱了人腐朽的味道,找回清爽。
这个国的人都已经死去。他们一醒来就死去,一睡着就活过来。如果醒时发现自己活着,他们就把自己杀掉。
这个国的一切都在腐坏。云是黑色,雨是灰色,人的身体里坏成一团,一张嘴就是恶臭,字迹如爪痕划进心脏,多看一眼都会痛。
我从自己的阳台爬到黑先生的阳台。他不在家的时候,我常这样偷溜到他家里去,看他的电视,躺他的沙发,到他的书房,翻看他索然无味的文件和笔记,没有一丝温度。但是律师的书房散发着一种魅力,我总相信里面藏着令人讶异的秘密。他海蓝色的办公椅很欢迎我,泡绵椅垫和我相处融洽。虽然桌上层层叠叠的文件夹催促我出去,但我可以对它们视而不见,反正我从不懂它们。
我对他的书房仍抱有期待,希望总有一天可以看到黑先生柔软的踪迹,纵然他每个醒来的脚印都已经死去。
我拉开阳台的玻璃门,进入客厅,那屋里已失去他的味道。客厅和饭厅比平日整洁,杂志、报纸都不在沙发上蹓跶。杯子靠着杯子,筷子和汤匙划清界线,地板上有我完整的影子。
在不开灯的屋里,我依然能轻快地走到他的书房。没有什么能阻碍我,可越是靠近,一股刺鼻的味道越是强烈。我一打开书房的门,味道猛然从房里逃出来,撞上我的嘴巴和鼻子,我几乎喘不过气来。
窗敞开,窗边的窗帘望着月光,随风飘动。月光站在书桌上,纸张都在发亮。
那书桌旁的大水桶是如何进来的呢?里头灌满水泥,臃肿得动不了。它见到我时有点不知所措,想躲起来却找不到地方可钻。它只能杵在原地和我对望。
桌上曾敌视我的文件夹都不在了,书架上多了几个空格。我没有时间和我友好的办公椅寒暄,便走到屋里各处寻找黑先生,包括他的房间。他的屋子前所未有的空洞,好像他不曾住在这里。
我把我在门上的指纹都擦掉,然后从阳台爬回自己的阳台。
打电话报警,报的是气味,和人无关。死去的人不对异状有所反应。我是装死的人,语气也像死了那样僵硬,低温。
几分钟后,警察来到黑先生的家。他们撬开门后,在门口拉开了红白胶带。有人拍照,有人检查屋中每个没离开的东西。他们盘问了我,我说是我报警,什么也不知道。我不能说我知道,死去的人什么都不会知道,也不可以知道。
屋里的壁虎和蚂蚁却一定知道。那壁虎一家也常在黑先生不在家时,大肆乱窜,它们不破坏任何东西,只在墙角、桌底、洗槽边留下粪便,炫耀自己的版图。蚂蚁偶尔找到黑先生掉落的食物碎粒,就领着整个家族的小兵把食物搬走。我常看到那弯弯曲曲的蚂蚁队伍,真想捻断这条蚂蚁项链,但我牢记着死去的人不留下痕迹,不许破坏这屋里的任何东西。
警察没有发现壁虎和蚂蚁,否则它们能提供有用的线索。
臃肿的水桶在房里呼唤警察,警察已准备好搬运器具,他们像约定好的朋友,一见面就结伴走了。我以为先认识水桶的是我。
第二天早上,住在对面的邻居说警察找到黑先生了。他在水桶里。
黑先生给自己灌了水泥。警察说。
我们回到自己的屋里,半天没有出来。谁都知道黑先生是发现了自己还活着,把自己杀了。
丧礼在当天晚上。调查顺利完结,没有疑点。我和几个邻居去治丧处,但丧礼上没有黑先生,只有黑先生在一张照片里微笑,从远方回来的妹妹,以及两排哀伤的白菊花。人和花一样沉默。
黑先生的妹妹眼睛里有一点泪。那是死去的人短暂活着的迹象。她看着我,我看着她。黑先生的客厅有一张合照,黑先生和妹妹站在山上拍照,风抚开他们额间的发,也拨开他们咧嘴大笑的嘴。我不知道让他们笑的是风,还是互相揽着肩头的手,但两人笑瞇的双眼很一致。那时候他们必然是活着,那种笑容只有活人才会有。
我看她看得很心虚,她好像认得我,她是否在照片里曾看见我凝视她?我不是故意的,只是我太渴望见到活人的样子,提醒我:我还活着。
“黑先生”入土后,我周身不舒服,我已不能再到他的家,拜访我熟悉的电视、沙发,还有那张海蓝色的办公椅。它们为黑先生服丧中,心情大概不好,谁也不想被打扰,只想任尘埃层层将自己覆盖,直到下一个住户把它们抛弃。
第四天,我家的门铃响了几声。它忘了自己还有声音,自己把自己吓醒。我以为是警察,或许有了新线索,或想起遗漏的问题。
我打开门,见黑先生的妹妹身着一身白色风衣,化成一只风尘仆仆的天鹅站在我的门口。她已退去丧礼上的黑色套装,和头上那个灰色束带扎的小发髻。
她背着像白色羽翼的背包,走进我的屋里,观察了环境,问我能不能让她进来。我竟然不敢拒绝她,那都是黑先生的关系。
她用了客房的浴室,洗了澡,然后向我要吹风机。吹风机见着她,很卖力地呼出热空气。她的眼睛也是半关,和黑先生一样,常挂着通宵未眠的疲累。
失去亲人之后,身体里的精神凋零,飘在空中游荡,不会落地。有些人飘很久,有些人很快坠落,被泥土吃进去,一段时日后再长出新芽。黑先生的妹妹很轻,在我面前飘来飘去。她观赏了我的桌椅、花瓶、吊灯,最后安坐在我墨绿色的沙发上。确定她不再移动后,我才坐在她旁边的椅子。
我望着她,想不到要说什么。她弯下身,从我的沙发下拿出一双鞋。
我直盯着那双白色的布鞋,如远航而来终于靠岸的白船,我深怕它随时漂走,眼珠在惊恐中僵滞。
我掀开掩盖沙发底部的布,难以计算的各色布鞋塞满了我的沙发底下。
我从不知道它们躲在我的沙发底下。
既然我能爬到黑先生的屋里,别人也能爬进我的屋里。
黑先生的家里没有秘密,书房里也没有秘密,秘密都住在我的沙发底下。
鞋是邪恶。从我们出生以来,这个国就告诉我们:鞋是邪恶。
“赤脚不能抵达的地方,就是不该去的地方。”
“这个国已铺上安全而舒适的道路,因此鞋子是多余的物品。”
“人之所以陷入错误,是因为走得太远。”
为了不犯错,人们不穿鞋。没有人想承担犯错的后果。秩序若是被扰乱,谁也活不成。
我曾有那么一次割破脚底,在我还是少年的时候。那天,我看见云化成鹰,先是在我的屋顶上盘旋,然后忽高忽低地飞,邀请我跟随它而去。
我从屋里奔跑出来,仰着头,朝鹰急速飞去的方向追去。我只注意着那鹰,忽略地面,毫无自觉跑了多远,或是跑了多久。直到我感觉脚板疼痛,才看见双脚沾满了血。
双脚正站在遍布尖石的地上。大树浮出苍老而粗壮的根。在阴湿的丛林里,腐坏的血腥味正肆意闯进我的鼻腔里。我听到味道在狂笑,并且舔舐我脚下的血。
我那时多想穿上鞋子,离开那个地方,继续寻找令我着迷的鹰。
当我走到医院的时候,我的双脚已停止流血,地上没有我的血迹。
没有人知道我曾到过什么地方,但我被割破的双脚是犯错的证据。
人们一直问我去了哪里,做了什么,见过谁,我照实回答我去追了一只云化成的鹰。
没有人相信我。
我被留在在医院里几个星期,脚下的伤口早已完全愈合。为了脱离困局,我只能以谎言来证明我的诚实。
我说我梦游了,梦见云化成的鹰,遇见遍布星星的丛林,屈腿的大树,以及闻到四周弥漫花蜜的香气。
他们信了,就让我走。
自那天起,我知道我不能醒来。
黑先生无论醒来或睡着都感受到自己的呼吸,那活着的血液在体内激烈地流淌,可以听到浓稠的愤怒在沸腾,也可以听到哀伤敲在心脏的撞击声。我和黑先生都是装死的人。
我继续装死,黑先生却要让所有人知道他活着,并且呼唤所有死去的人活过来。
死去的人死去太久,已遗忘死去的原因,以及惧怕活着的原因。人们不能追问原因,知道太多的人会把自己杀掉。
“把鞋子送给所有人,只要他们可以走到很远的地方去,他们就会活过来。”
黑先生的妹妹将布鞋塞进她的白色背包,直到不能再塞入任何一双鞋为止,但那些布鞋只是我沙发底下的一小部分而已。
黑先生的妹妹背起她的背包,自己打开我家的门,像展开了白色的翅膀,扑棱扑棱飞走了。
第十四天,黑先生妹妹赤裸的身体在海上浮起。她把自己杀了,报章如是报导。
一个正试图唤醒全世界的人,把自己杀了。
我望着她曾坐在客厅吹头发的一角,像只天鹅整理自己的羽毛,退去了灰与尘,洗发水的味道随着吹风机向周遭四散。
如今,她不带走一根羽毛,离开了这个世界。
我从沙发底下拿出一双适合我的布鞋,是黎明初醒的灰蓝色。我把布鞋套在我的双脚上。那是我第一次穿上鞋子。
我在客厅穿着鞋子走路。脚底和地板隔着一层薄垫,发出暧昧的细语声。它们初次相遇,对谈如此投机,像久别重逢的老友。我聆听着它们,在客厅来回踱步,直到夜晚降临,直到客厅的暗让我看不见自己的双脚。
这么一走,我不想只在客厅里走了。
这么一走,我不想只有自己穿着鞋走了。
我想起那只我错过的鹰。
我将几双布鞋装进我的背包里,背着它们翻越到黑先生的阳台。然后,我再从黑先生的阳台,翻越到黑先生隔壁的阳台。
这个家的主人是年轻的厨子,他和年轻的教师女友住在一起。两年前搬进来的时候,我在电梯第一次见到他们。他们如死去的人那般苍白,双腿像失去齿轮的机器,从电梯里不协调地走出去。这两年来,我就没有再见到他们,但他们阳台晒的厨子制服、教师西装,总在每个早晨如盛夏的花醒着。
我把两双布鞋安放在他们的客厅里。不知尺码是否合适,仅凭一种直觉,去相信他们会把鞋子穿上。
死去的人不知道鞋子,装死的人不敢穿鞋。鞋是罪,仅限在这个国里。
我翻越了湿冷的墙,爬过人们的梦,在他们浑浑噩噩的日复一日,嵌入可能会带来恐惧,或惊喜的布鞋。多少个黑先生和他的妹妹都进入了陌生人的客厅里。
我沙发底下的布鞋越来越少,我偶尔会在路上看见穿鞋的人。他们穿的未必是我悄悄派的布鞋,也可能是他们自制的,或不知道从哪里得到的鞋子,各种颜色,各种材质和款式。
他们睁着眼睛走得很快,像是要到一个辽远的地方去,赶在某个时间,又或者赶在什么时候之前抵达。
“穿鞋的人都是妖魔,抛弃了自己的灵魂。” 这个国如此宣导。
穿鞋的人被憎恨,也被诅咒。穿着鞋子变成一件危险的事情,很可能会被暗杀,但他们不会再把自己杀掉了。没有人比穿鞋的人清醒,因为他们都知道自己要前往何方。
后来,少年们都穿上了鞋。他们穿着鞋子,快乐地奔跑在烂泥里、湿滑的公路、无人开垦的荒原。他们互相交换风景,攀过山的人知道海的味道,攀过峭壁的人也知道平原的狼嚎可以唤醒多少沉睡的兽。
少年们好奇鞋子可以带他们走多远。
我沙发底下的布鞋派完了。人们不需要我的布鞋,他们知道了获得鞋子的方法。
黑先生把自己杀掉的 8 个月后,我坐在空旷的草地上看少年们互相追逐嬉戏。他们穿着鞋,掌握自己行走的速度。跑,不是一件疼痛的事情。
嬉闹声在逐渐昏沉的景色中消止。一千名警察包围了那几个穿鞋的少年。他们除了穿着鞋逃跑,便无其他抵抗的办法,可他们连跑的出路都已断绝。警察堵满了他们可以移动的任何空间,连吸进的空气都是警察呼出的二氧化碳。
警察扒走他们的鞋子,然后折断他们的腿,从身体拆卸出来,只剩下大腿。警察又把他们的手拧断,又从身体拆卸出来。最后,少年们只剩下身体和头,躺在空旷的草地上,仰望天空中的云。
草地的草都被压扁了,破碎成屑,紧紧黏附在泥土上,直不起腰来。
这时候,天空中的云有的变成了雀,有的变成了鹰,少年们想向它们飘荡的地方追去,却已无法动弹,唯有眼珠在悲凄中转动。
少年们哀嚎却没有求饶,只为失去的手脚而悲伤。
警察将我带走时,像当初他们搬走黑先生的那个臃肿大水桶一样。这次他们没有携带搬运器具,他们喘着气,左摇右摆地扛起我的手脚,我离地两三尺,没有走路的机会。
厨子和他的教师女友把布鞋放在我的家门口,我自此不能走,也不能再说一句话。没有人会问我,去了哪里,做了什么,见过谁。他们都不觉得重要了。
我被安置在一个比冬天更白的冷冻库里,四面的墙没有一丝花纹,或浮凸的印记,门没有缝,也别说会否有一盏灯在这里发出温暖的光。
他们要我回到我的梦里醒着,在我醒着的时候死去,如摆布那些装死的人。
我看见我走到比这个国更远的远方,去寻找一种会让人大声发笑的草,听到荒唐的谎言会笑出眼泪,看到无耻的劣行也会笑到在地上打滚。以及,一种喝了会让人大声说真话的酒,无论对象是高是矮,是恶是善,都会勇敢地看着他们说话。这个国不存在这种草和这种酒,我把它们带回到这个国里,送给从未离开这个国的人,他们便会活在睁眼的时候,睡在闭眼的时候,而死去便在心跳停止的时候。
我看见我乘鹰归来,最终要让人们相信那云会化成了鹰,不是梦境。苍穹中一朵白色的云,我是里头凝结的一颗小水滴。
据说,少年们被警察拘留的时候,从一楼的抽风孔钻出来,然后自己坠楼而死。他们的头部都如蛋壳般裂开,血像蛋液弥漫开来,黏稠的血迹紧贴在地,一直都洗不去。
许多年后,会不会有人知道我是怎么死去?
据说,我也是自己从一楼坠下而死。我没有流一滴血,仅碎成一地的冰。
鹰和我在空中擦肩,在我死去的肉身上盘旋,盯着我光滑的脚丫,等待我溶化后释放第一抹血的味道。
我和所有杀掉自己的人都溶成水,渗透到地里,泥土像海绵那般吸收了我们,和我们融为一体。
地上长出了刺,人们不能再赤脚行走,痛会让他们不得不醒过来,痛到活过来,哭着走路,或愤怒地走着,不得不穿上鞋。
人们穿着鞋走路时,磨出嘈杂的声响,他们一天比一天走得更远,终究会走到这个国最高的地方,然后俯瞰这个国,便知道他们活在什么地方。
走得太远,知道太多的人总让原本站在高处的人恐惧。
看见这个国的人都穿上了鞋,我就能安心地笑了。
菲雅尔塔的春天-《纳博科夫短篇小说全集
================================
[https://www.20dcr.com/book/nabokefuduanpian/1885528.html](https://www.20dcr.com/book/nabokefuduanpian/1885528.html)
## 菲雅尔塔的春天 -《[[纳博科夫]]短篇小说全集》
================================
菲雅尔塔的春天多云且沉闷。各种东西都泛着湿气:悬铃木斑驳的树干、杜松灌木、围栏、铺路的小石子。远处几幢淡蓝色的房屋,错落排成一行,摇摇晃晃爬上斜坡(一棵柏树指示了爬坡的方向)。就在那些高低参差的屋檐之间蒸腾着一片水汽,水汽中影影绰绰的圣乔治山显得越来越不像明信片上画的样子。画着圣乔治山的明信片自一九一○年以来一直是招徕观光旅游者的法宝。它们(如那些戴草帽的年轻出租马车车夫所言)始终在旋转售卖支撑架上,和带紫晶的岩石以及壁炉上梦幻般的贝壳装饰待在一起。空气中没有风,很温暖,隐隐有一丝烧糊了的气味。雨水冲淡了海水中的盐分,大海这时不是碧蓝而是灰色,海浪懒懒涌动,不愿碎成泡沫。
三十年代初,就在这样的一天,我不知不觉间走在了菲雅尔塔一条陡直的小街上。我所有的感觉都敞开着,各种景色马上尽收眼底:货摊上摆着品种繁多的海产品,商店橱窗里有珊瑚做的基督受难十字架;墙上贴着一家巡游马戏团垂头丧气的演出海报,被浆糊浸湿了,一角已从墙面上脱开。灰蓝色的旧人行道上扔着一小块尚未熟透的柑橘的黄皮,是它留住了即将消逝的记忆,时不时令人想起古老的马赛克图案。我喜欢菲雅尔塔。我喜欢它,是因为在流淌着紫罗兰色音节的山谷里我感受到了一朵遭受风吹雨打最厉害的小花隐隐散发出的香甜湿气,也是因为这个可爱的克里米亚小镇有一个中提琴般的名字,仿佛有浓浓情思回响在琴音中。我喜欢菲雅尔塔,还因为这里的四旬斋 (1) 湿气凝重,昏昏的睡意中自有净化心灵的特殊之物。所以我故地重游,非常高兴。我沿着排水沟中的潺潺流水溯流朝山上爬去,没戴帽子,脑袋湿了。虽然衬衣外面只罩了一件轻便雨衣,皮肤上却早已暖洋洋的。
我是乘卡帕拉贝拉快车来的。这种火车具有山区火车独有的风格,跑起来不顾一切危险,一夜间风驰电掣,不知穿过了多少山洞。我预计能在那里逗留的时间只有一两天,相当于出公差途中可以喘口气,稍事休息。我把妻子和孩子们留在家里。家是一个幸福之岛,它总是出现在我生命的晴朗北方,总是漂浮在我的身旁,甚至有可能穿透我的身心。不过在多数时间里,它仍然处于我的身外。
一个没穿裤子的小男孩,紧绷着泥灰色的小肚皮,一摇一晃地下了一个门阶,又弓着腿往前走,想一次捧住三只橘子,却总是把第三只不听话的橘子弄掉,最后他自己也摔倒在地。这时过来一个十二岁左右的女孩,黑黝黝的脖子上挂着一串沉甸甸的珠子,穿着一条像吉卜赛人常穿的长裙,猛地伸出她那双更灵活的手,一把抢走了小男孩手里所有的橘子。不远处是一家咖啡店,湿漉漉的露台上,服务生在擦厚厚的餐桌桌面。一个面容忧郁的当地人在兜售当地出产的棒棒糖,那东西样子很精巧,泛着月色般的微光。他把装得不能再满了的一个篮子搁在有裂缝的栏杆上,和服务生隔着篮子说起话来。要么是毛毛细雨停了,要么是菲雅尔塔已经习惯了毛毛细雨,现在呼吸的是潮湿空气还是温暖的雨水,她自己也不清楚。一个英国男子,穿着质地结实、可以出口的那种高尔夫球灯笼裤,从一座拱门下走了过来,进了一家药店,边走边从一个橡胶小袋里掏出烟丝,用拇指压进烟斗里。药店里有一个蓝色的花瓶,里面几大块苍白的海绵眼看就要渴死在玻璃后面。这样一个灰蒙蒙的日子,浸润着春的精髓,它自己似乎感觉迟钝,没有觉察出来,我却全身心地投入其中,感受着它的悸动与气息。想到这一点,我满怀感激,觉得所有的血管里都荡漾着无比甜美的欣喜。我的神经度过一个无眠之夜,接受能力变得非同一般地强,我吸收了一切:小教堂过去有一片杏树林,里面一只画眉在啭鸣;眼看快要倒塌的房屋一片寂静;远处大海的脉搏在薄雾中跳动。与此相伴的是一堵墙,墙头插满了破碎的瓶子玻璃,闪着防贼的莹莹绿光。还有一张马戏广告,用各种牢实不褪的颜色画着一个头插羽毛的印第安人,他骑在一匹后腿直立的马上,正甩出套索套捕一匹当地特有的斑马;还画着一些呆若木鸡的大象,坐在各自金星闪闪的宝座上沉思。
不久,刚才那个英国人从后面赶上了我。我正要把他连同其他东西一并收入眼底时,碰巧注意到他的一只蓝色大眼睛突然斜瞄向一边,扯得深红色的眼角都变了形。看他匆匆舔湿嘴唇的样子,我猜是看过药店里那些干燥海绵的缘故吧。但紧接着,我顺着他的目光,看见了尼娜。
在我们十五年的——唉,我找不到确切的术语来形容我们之间那种关系——之中,每一次见她,她似乎都不能一眼认出我来。这一次,她又是在对面的人行道上呆立了片刻,然后朝我半转过身来,神情犹犹豫豫的,同情中混杂着好奇心。只有她的黄色围巾已经开始飘动,就像狗总是先于其主人认出你——接着她叫了一声,双手高举,十个指头全都跳起舞来。就在街道的正中间,她吻了我三下,都是有口无心的吻,就像老朋友见面,一激动先吻几下再说(每次分别时也是这样,她冲我急匆匆地画画十字)。然后她就走在我身边,紧紧依偎在我身上,调整步子,和我保持一致。只是她的棕色裙子太窄,凑合着开了个边缝,步子跨得不那么自如。
“对呀,费迪也在这里。” 她回答道,接着马上客气地问候叶连娜。
“他肯定是和塞居尔在哪里闲逛,” 她继续说她的丈夫,“我呢,要买些东西。吃过午饭我们就离开了。等一等,亲爱的维克多,你这是带我去哪儿?”
回到从前,回到从前,每次见她都是这样,重复多年积累下来的整个过程,从最开头直到最近一次新添的情节——就像俄国的童话故事,每到故事有了新的转折时,就要把已经讲过的部分再讲一遍。这一次我们见面是在温暖多雾的菲雅尔塔。即使我知道这是最后一次,也不能多施手段来一番隆重庆祝,无法在命运提供的现有菜单上再添点新鲜花样。我口口声声说这是最后一次,因为我想象不出天堂里有哪一家代理公司会答应安排我与她在葬入坟墓后再见一面。
我初识尼娜的那一幕要放在多年前的俄国,从后台传来的左翼剧团吵吵闹闹的声响判断,应该在一九一七年前后。那是一场生日宴会,地点在我姨妈家的乡下庄园,离鲁加镇不远,时间正值隆冬之季(走近那地方的第一个标志我至今记得清清楚楚:一片白色荒野中矗立着一座红色的谷仓)。我刚从皇村学校毕业,尼娜则已经订婚了。她与我同龄,也与那个世纪同龄,但看起来至少有二十岁,也许是她生得纤细匀称的缘故。到三十二岁,这身材反而让她看上去相当年轻。她的未婚夫是个青年近卫军,从前线回来休假。他长相英俊,身材结实,极有教养,为人冷淡,说话时每个词都要在最精确的常识天平上称量过,然后用丝绒般的男中音讲出来,这样的嗓音在对她说话时会变得格外悦耳。他太讲究礼数,对她太忠心,可能让她有点烦。如今他是个成功的工程师,不过在某个极其遥远的热带国家工作,稍微有点寂寞。
窗户上亮起了灯光,亮光拖长,落在了波浪一般起起伏伏的昏暗雪地上,使窗户间反映着前门上方的扇形光亮。大门两边的侧柱各有毛茸茸的白边。本来这侧柱可以作为我俩生命之书的绝妙藏书票,却让这白边破坏了藏书签完美的轮廓。我现在想不起来大家当时为何从喧哗的大厅游荡到宁静的黑暗中,那里只有银装素裹、块头比平时肿胀了一倍的冷杉树。是不是守夜人请我们去看天上阴沉的红光,因为那预示着会有大火烧起来?可能是这样的。要么我们是过去欣赏池塘边上的一座骑士冰雕,那是我姨妈家几个孩子的瑞士家庭教师雕刻的。这也很有可能。我的记忆直到返回灯火通明的庄园大宅途中才苏醒过来。当时我们排成一行,沿着两道雪堤之间的一条窄沟,踩着雪沉重地朝大宅走去,嘎吱嘎吱的踩雪声响是寂静的冬夜对人类所作的唯一评论。我走在最后,前面三步开外,噌噌走着一个弯腰弓背的小身影,冷杉树沉重地伸出积着雪的爪子。我滑了一下,出门时有人强塞给我的那个按不亮的手电筒掉在地上。要把它捡回来可真是千难万难。我咬牙切齿地骂起来,立刻引起尼娜的注意,她回头摸着黑朝我走来,发出一声低沉而又热烈的笑,期待着找点乐子。我现在叫她尼娜,可当时我并不知道她的名字;我们,我和她,也压根没时间讲什么客套。“谁啊?” 她饶有兴致地问——这时我已经吻上了她的脖子,那么柔滑,在大衣的狐皮长毛领子下热得滚烫。那领子老是妨碍我的吻,后来她就抓住我的肩膀,带着她特有的坦率个性,将她慷慨而温顺的双唇贴在我的唇上。
一阵欢闹突然爆发,分开了我们。原来是一场雪球大战在黑暗中打响。有人逃跑,跌倒,踩得雪嘎吱嘎吱响,大笑,喘气,爬上风吹而成的雪堆,使劲跑,发出了一声可怕的呻吟:深深的积雪对一只套靴实行了截肢手术。过了没多久,大家都四散回家,我不曾和尼娜交谈,不曾筹划过未来,也不曾想过接下来牵扯不断的十五年。这十五年从那一刻起就已经向着黑暗的地平线启程,一路上满载着我们零零碎碎没有集合起来的会面。我记得那一晚余下的时间里全是手势和姿势的迷宫,手势和姿势的阴影(大概是在客厅里做各种游戏,尼娜总是分在游戏的另一方),我在这些迷迷乱乱的影子里注视着她,她在雪地里和我那样亲热一番后竟然再不理我。令我惊讶的倒不是她不理我,而是她的态度来得那么天真自然。我当时还不知道,只要我一句话,她的漫不经心就会立刻转变为阳光四射般的美妙热情,转变为欢欢喜喜、百依百顺,好像女人的爱是含有盐分的泉水,喝了有益于健康,只要有人稍加注意,她就会心甘情愿地让他饮用。
“让我想想,我们上回是在哪儿见的面,” 我开始说道(对着菲雅尔塔版本的尼娜),为的是让她颧骨突出、嘴唇暗红的小脸上生出一种我熟知的表情。果然不出所料,她又是摇头,又是皱眉,那意思倒不像是说她忘了,而是在感叹老说这样的笑话,太没意思了。说得更确切点,那表情就好像在说,命运在所有那些城市安排了我们各种各样的约会,却从未亲自出席;那些站台、楼梯、三面是墙的房间和昏暗的屋后小巷,只不过是很久以前别人的生活结束后存留下来的陈腐的布景,它们和我们自己漫无目的的命运的表演没什么联系,提起来实在倒人胃口。
我陪着她走进拱廊下的一家商店,珠子门帘外天色已暗,她指着几款里面垫着薄绵纸的红色女式钱包,仔细看标价牌,像是要了解博物馆里的展品名称。她说她想要的正是这种式样,不过得是淡黄褐色的。经过十分钟忙忙乱乱的翻腾,那位达尔马提亚 (2) 老头竟奇迹般地找出来这么一个稀奇古怪的东西,我至今都百思不得其解。尼娜正要从我手里抠出几张钱来,又突然改变了主意,什么也没买就穿过飘动的珠帘走了出来。
外面和先前一样,还是乳白色的沉闷天空,还有一股燃烧的气味,从那些灰白房屋毫无遮挡的窗户里飘出来,搅动了我对鞑靼人往事的回忆。一小群小飞虫正忙着在一株含羞草上方织补空气,含羞草无精打采地开着花,枝叶都拖到了地上。两个戴着阔边帽的工人正就着奶酪和大蒜吃午饭,他们背后靠着一块马戏广告牌,广告牌上画着一位红色的轻骑兵和一头老虎模样的橘色野兽。奇怪的是,画家竭力把这只野兽画得尽可能地凶猛,但他用力过猛,便从别的方面设法弥补,因为老虎的脸看上去分明像张人脸。
“Au fond,(3) 我刚才想买一把梳子。” 尼娜说道,觉得后悔为时已晚。
她办事老是犹犹豫豫,想了再想,想到第三遍又回到头一次的想法上去,连上下火车时都要担心一会儿,这些我都多么熟悉啊。她总是要么刚刚到达,要么马上要离开,对此我一想起来就有受辱之感。约会本来是定好了的,就是游荡成瘾的混混也知道那是非去不可的,她却要把路线搞得复杂多变,叫你疯跑。假如要我在我们俗世评判人面前提供一个她平时的典型姿势,那我也许要把她放在库克旅行社 (4) ,让她斜靠着一个柜台,左小腿交叉在右小腿上,左脚的脚指头轻敲地面,两只尖瘦的胳膊肘和装满硬币的手提袋放在柜台上。旅行社的工作人员则手握铅笔,和她一起谋划着给她订一个一劳永逸的永久卧铺。
大批人离开俄罗斯移居国外后,我在柏林的一些朋友家里见过她——那是第二次见面。我快要结婚了,她刚刚与她的未婚夫分手。我一进那间屋子,一眼就看见了她。我又扫了一眼别的客人,凭直觉判断在场的男人中哪一个比我更了解她。她坐在一张长沙发的一角,双脚收在沙发上,小巧的身体舒适地蜷曲成一个 “Z” 形,一只鞋跟前面的沙发上歪立着一个烟灰缸。她眯缝着眼睛看了看我,听我报了姓名,然后从嘴唇上取下那个花梗一般的烟嘴,这才缓缓地、乐呵呵地说道:“好吧,见过大家——”她一张嘴,大家立刻明白了,我们的亲密关系由来已久。不用问,当年那场热吻的事她早就全忘了,然而不知为何,倒是因为有过那桩微不足道的事,她好像不由自主地老是隐约想起一段热烈快乐的友情,其实那样的友情在我俩之间根本不存在。我们的关系完全是一个虚架子,建立在想象出来的感情上——这与她待人随便的好心肠无关。从我们说的话来看,这次见面被证明是没有多大意义的,但我们之间已经没有了隔阂。那天晚餐时我的座位碰巧排在她身边,我厚着脸皮试探了一下,看她藏在心里的容忍程度到底如何。
此后她又消失了。一年后,我和妻子到火车站送我弟弟去波兹南 (5) 。火车开走以后,我们沿着站台的另一边朝出口走去,突然在巴黎快车的一节车厢旁边看见了尼娜,她把头埋在她捧着的一束鲜花里,站在一伙人中间。那些人是她的朋友,我不认识。他们站成一圈,呆呆地望着她,就像无所事事的人望着大街路面,望着一个迷路的孩子,或者望着车祸的受害者一样。她爽朗地挥着花向我打招呼,我把她介绍给了叶连娜。在偌大一个火车站里,每一件事情都在其他事情的边缘上颤抖,颇有生命匆匆的气氛,所以每一件事情都是大事,都要只争朝夕,倍加珍视。在这样的环境中,只言片语的交谈就足以让两个完全不同的女人在下一次见面时互用昵称了。那一天,在巴黎快车投下的幽幽阴影中,她第一次提到了费迪南德。我得知她要嫁给他了,竟然觉得痛苦,想来实在可笑。车厢门开始砰砰地关上,她和朋友们吻别,很急促,但很真诚,然后上车进了车厢,消失了。接下来我透过窗户玻璃看见她在自己的隔间里坐了下来,好像突然间忘了我们,进入了另外一个世界。车厢像个玻璃鱼缸,里头隐隐约约有一个不容置疑的生命在移动,我们大家都手插在衣袋里,定睛观察。后来她明白过来我们在看她,便咚咚地敲窗玻璃,又抬起眼睛,在车窗的窗框上摸索,好像上面挂着一幅画一般,但没有任何结果。有个和她同车的旅客帮着她放下了窗子,她探出头来,是个有声有色的真人了,开心地笑着。火车无声无息地滑动起来,我们中的一个人赶了过去,递给她一本杂志和一本陶赫尼茨 (6) 出版的书(她只有在旅行途中才会看看英文)。一切都滑走了,走得美好、平稳。我攥着一张站台票,揉得不成样子,一支上个世纪的老歌(据传这首歌与一出巴黎的爱情剧有关)在我的脑海里响个不停。它是从记忆的音乐盒里冒出来的,为什么会冒出来,只有上帝知道。那是一支感伤的歌谣,我的一位终生未嫁的姨妈过去经常唱。这位姨妈长着一张黄脸,黄得像俄国教堂里的石蜡,但天生一副好嗓子。每当她一展歌喉,唱起这两句:
On dit que tu te maries
tu sais que j'en vais mourir(7)
那圆润响亮、如痴如醉的歌声会产生神奇的力量,让她仿佛沉浸在一片火烧云发出的霞光中。旋律如泣如诉,诉说着屈辱和痛苦,节奏激发出婚礼与死亡间的联想。唱它的姨妈早已故去,现在想起来的只有她的歌声,搅得我在尼娜离开之后的几个钟头里心神不宁。甚至到后来就像一艘驶过的大船搅起的余波,小浪平缓,朝岸边扑打,梦幻般渐渐慢下来。要么就像钟楼里传出的钟声,敲钟人早已回家与家人重新欢聚,唯有铜钟仍在颤悠悠地挣扎。又是一两年过去了,我去巴黎办事。一天早晨我到一家旅馆找一位电影演员,在楼梯转弯的平台上又看见了她,穿着一套合身的女装,正在等电梯下楼,手指下方晃荡着一把钥匙。“费迪南德击剑去了。” 她兴致勃勃地说道。她的眼睛盯住我的下半张脸,仿佛在读唇语一般。沉思片刻后(她对肉体欢爱的了解之深是无人可及的),她转过身,细细的脚脖子快速扭动起来,领着我走过铺着海蓝色地毯的过道。她的房门口放着一张椅子,上面摆着一只托盘,早餐吃过后还没有收拾——上面放着一把沾着蜂蜜的餐刀,托盘灰色的瓷面上撒着面包屑。不过房间已经打扫过了。因为突然开门通风,一幅绣着白色大丽花的棉布帘波浪一般扑卷进来,在落地窗的两片窗扇之间好一阵抖动撞击。房门锁上了后,窗扇才放开了扑进来的窗帘,发出一声响,好像心满意足地舒了一口气。一会儿后我走出房间,来到外面一个铸铁小阳台上,闻到一股干枫树叶和汽油混合起来的气味——原来是雾蒙蒙、灰蓝色的清晨街道上还未清理的垃圾。那时已有病态的感伤在不断增长,这将使我和尼娜之后的相逢更加痛苦。但我当时毫无察觉,所以也许表现得和她一样泰然自若,无忧无虑。我陪着她从旅馆出来,到一个什么办公室去查查她丢了的一只手提箱找着了没有,然后又去了一家咖啡店,她丈夫正在那里召集他当时的部属开会。
那个男人是个法裔匈牙利作家,我就不说他的名字了(偶然有几处提到他的名字,那也是出于礼貌用了化名)。我宁愿只字不提,但我又不由自主地要说说——他像浪涛一般从我的笔下冒出来。如今人们很少听说他了,这是好事,因为这证明我当初抵制他的邪恶魔力是对的。无论何时,手一沾到他的任何一本新书,我就会感到一股令人毛骨悚然的寒气顺脊梁而下,有这样的感觉也是对的。像他这样的人,名声传得很快,但很快就沉寂了,过时了。就历史而言,他这种人也就是生死两个日期之间的一个破折号而已。胸无实学,又傲慢自大,随时备好恶毒的双关语,毒箭一般朝你射来。他那双沉郁的棕色眼睛里深藏着一种充满期待的奇怪神情,我敢说,这个虚伪的调笑者对于弱小的啮齿动物有不可抗拒的影响力。他出口成章的功夫已练到了炉火纯青之境,尤其以词语编织匠颇为自豪,他把这个头衔看得比作家的头衔还要高。就我个人而言,我绝对不明白胡编乱造些书有什么好处,写些根本没有以任何方式真正发生过的事情有什么好处。我记得有一次,他点头鼓励我发表高见,我不怕受他嘲笑,便对他说假如我是个作家,我就会只允许自己的心灵拥有想象,其余一切都得依赖于记忆,记忆是真实的人生在夕阳下拖长了的影子。
我在认识他之前就知道他的书。那时隐隐的反感早已代替了我看他第一本小说时曾经历过的审美愉悦。他刚刚写小说时,还有可能表现出些人间美景,古老的庄园,透过他那彩色玻璃一般的花哨文风也能看出梦里常见的排排树木……然而随着每一本新书的问世,那块文风玻璃上的色彩越来越浓厚,红色紫色越来越像不祥之兆。到如今,那块玻璃已经色彩斑斓,面目狰狞,透过它再也看不出任何东西了。就算将它打碎,里头也好像空无一物,只有完全彻底的一片黑暗对着我们发抖的灵魂。但想当初他是个多危险的人啊,可谓毒汁四溅,惹急了会挥起鞭子一顿猛抽!他的讽刺如同龙卷风,所过之处皆成荒原,那里橡树被成排击倒,尘土仍在盘旋。谁要是发表了不同的意见,就会惨遭不幸,像陀螺一般被他抽得满地乱转,在飞扬的尘埃中哇哇痛叫。
那一次我们见面时,正值他的小说Passage à niveau (8) 在巴黎走红。就像大家所说的,他“被包围了”。尼娜(她的适应能力奇妙地弥补了她的文化缺失)已经担当了重要角色,如果算不上缪斯,至少也是一位精神伴侣和灵犀相通的顾问,跟得上费迪南德弯弯绕绕的创作思路,忠实地分享着他的艺术趣味。要说她从头至尾参与过他哪一本书的写作,那是根本不可能的,但她有一种神奇的本领:听文学界的朋友们闲聊文学,无意间冒出来的精彩段落她都能给收集回来。
我们走进咖啡店时,一支女子乐队正在演奏。我先注意到一根镜面柱里映出一架鸵鸟腿般的竖琴,然后看见一张拼凑起来的桌子(几张小桌子拉起来拼成一张长桌),费迪南德背靠贴着厚绒布的墙壁,正在主持会议。有一阵子,他神情专注,两手张开,一桌子的人脸全都转向了他,这一切让我想起了某些离奇的、梦魇般的东西,我并不确定那是什么,但后来回想了起来,他那模样和我想起的东西太神似,让我觉得他在亵渎神明,其邪恶程度一点不亚于他的艺术。他穿着一件花呢外衣,里面是一件白色高领毛衣,油光闪亮的头发从两鬓梳向脑后,头顶上悬着香烟散出的烟雾,活像神像头上的光环;清瘦的脸像个法老一般一动不动,只有眼睛四处乱转,眼神里饱含着深藏不露的满足。他放弃了两三个原先常去的显眼地方,要不然对蒙帕纳斯(9) 生活不太了解的天真无知之辈会想着去那几个地方找他。然后他转而光顾这家小资情调十足的咖啡馆。这地方有令人心酸的spécialité de la maison(10) ,他仗着自己特有的幽默感竟然从中获得乐趣,真是残忍至极。所谓spécialité de la maison就是这个乐队,由六位面带倦容、羞羞答答的女士组成,正在一个拥挤的平台上合奏柔和的乐曲。照他的说法,这些女子的乳房都是给孩子喂奶的,在音乐世界里显得多余,她们不懂得如何处置。每一曲奏毕,他都会癫痫病发作一般鼓一阵掌,引得全身抽动。几位女子早已不再对他的掌声表示谢意了,我也觉得他这么鼓掌已经在咖啡店老板和该店常客的头脑中引起了疑问,不过费迪南德的朋友们似乎对此高度赞赏。我记得他的朋友中有这样一些人:一位秃头画家,头光得无可挑剔,只是稍微带点疤痕;就是这么个头,还经常被他找出种种借口画在他那满是眼睛和吉他的画布上。一位诗人,他的拿手玩笑是用五根火柴表演“亚当的堕落”,你想看他就演。一位地位低下的商人,只要允许他在书角印上几句暗示的话,捧捧他包养的一位女演员,他就出钱资助超现实主义者的聚会,聚会的开胃酒也由他来买单。一位钢琴家,就脸来说还算过得去,但手指上的弹奏功夫实在糟糕。一位刚刚从莫斯科来的苏联作家,外表潇洒,但语言功底太差,握着一只旧烟斗,戴着一块新手表,全然不知自己在什么样的圈子里混,显得很滑稽。出席会议的还有几位先生,都是些什么人现在记不起来了,其中有两三个无疑与尼娜关系密切。她是桌边唯一的女性,弓着背,像个小孩子一般噙住吸管一阵猛吸,只见她的柠檬汽水水位迅速下降,直到最后一滴汩汩吱吱地响过之后,她才用舌头推开了吸管。我一直在毫不松懈地寻找她的目光,只到此刻,才总算见她望了望我。但我仍然搞不明白这样一个事实:她哪里有工夫把早上刚刚发生过的事情全忘了呢——忘得如此一干二净,以致她碰上我的目光后大惑不解地笑笑作为回应。直到定睛仔细望了一阵后,她才突然想起我期待着的是什么样的回应。与此同时,费迪南德(那些女子把她们的乐器像放家具一般放到了一边,暂且离开了演奏平台)咂巴着口水招呼他的朋友们注意店里远处角落里的一个人,那是个正在吃午餐的老头。那人和某些法国人一样,出于某种原因,在他外衣的翻领上系了一条小小的红丝带,下巴上的灰白胡须和嘴唇上的八字胡合在一起为他胡乱咀嚼的嘴巴提供了一个淡黄色的安乐窝。不知为何,关于老年的点点滴滴总是让费迪看得很开心。
我没有在巴黎久留,不过待了一个星期,结果证明这点时间足够我和他之间产生出一番虚情假意的亲密友谊来,因为他有装模作样的天赋,假意也能装成真情。到后来,我甚至变得对他些用处了:我的公司从他那些比较好懂的小说中选了一部,买下了电影改编权,从此他便一有时间就发电报骚扰我。多少年过去了,我们在某个地方见了面还经常不由自主地笑脸相对,不过有他在场,我就不自在。那天在菲雅尔塔也是这样,听说他在附近晃悠,我的心情就经历了一场熟悉的郁闷。不过有一件事情让我大为释怀:他新近一个剧本演砸了。
他正朝我们走来,穿着一件带腰带和兜盖的全防水外衣,肩上背着一架照相机,脚下是双层橡胶底的鞋。他边走边舔一根长长的月长石糖棍,那是菲雅尔塔的特产。他一本正经地舔,其实是故意要惹人发笑。走在他身边的是塞居尔,长得短小精悍,面色红润,像个洋娃娃。他爱好艺术,也是个十足的傻瓜,我怎么都看不出费迪南德出于什么目的会有求于他。我至今仍能听见尼娜低沉而多情的赞叹声:“啊,塞居尔,多么可爱的人!”这话看似深情,实则无意。他们走近了,费迪南德和我起劲地互致问候,又是握手,又是拍背,尽可能显得热情洋溢。其实两人根据以往经验,心里都明白这一套全是装出来的,只是个假模假式的开头。事情往往是如此这般发生:每一次分别后,我们在弦乐的伴奏下会面,那音乐奏得激动人心,在欢乐友好的忙乱中,在感情纷纷落座的喧闹中;不过引座员将会关上门,门一关,谁也不许再进来了。
塞居尔对我抱怨这里的天气,一开始我还不明白他在说什么。就算菲雅尔塔湿漉漉、灰蒙蒙、温室一般的基本状况可以被称为“天气”,它也和我们用来充当话题的任何事物都搭不上边。比如说,尼娜的瘦胳膊肘就是现成的话题,正好托在我的拇指和食指之间。要不可以说说谁扔下的一点锡箔纸头,正在远处的鹅卵石街道中间闪闪发光。
我们四个人继续往前走,隐隐觉得到前面会买点什么。“上帝啊,好一个印第安人!”费迪南德突然兴致盎然地叫道,猛地用胳膊肘捣捣我,指着一张海报让我看。再往前走走,在一处喷泉附近,他把他的棒棒糖送给了一个当地孩子,是一个皮肤黝黑的小女孩,好看的脖子上戴着一串珠子项链。我们停下来等他,只见他俯身对她说话,冲着她低垂的乌黑睫毛。随后他赶上了我们,咧嘴笑笑,发了一番议论,他平时就喜欢用这样的议论给他的言谈加佐料。后来他的注意力被陈列在纪念品商店里的一件倒霉玩意吸引过去:一件极差的大理石制品,仿的是圣乔治山,底座上露出一道黑沟,其实那是墨水池的出口,还有一个搁笔架,造得像铁轨的样子。他大张着嘴,嘴唇抖抖索索想来几句讥讽话摆摆谱,两手捧起那个笨重的、落满灰尘的、极不牢靠的东西,翻转一下,也没讨价还价就买了下来。然后他拿着那个怪物走了出来,仍然大张着嘴。他就像某个被围在驼背和矮子中间的独裁者,喜欢的也是这样那样的丑东西。这股迷恋劲少则持续五分钟,多则长达好几天;如果那东西是个活物,那就要迷得更久一些。
尼娜想吃午饭,拐弯抹角地提了一下。费迪南德和塞居尔在一家邮局前停了下来,我便抓住这个机会匆匆带她走了。我至今仍不明白她对我到底意味着什么,这个长着窄肩膀和“抒情诗一般的四肢”(这是一位装模作样的流亡诗人的话,他是追随她、对她发出柏拉图式赞叹的几个男人之一)的又小又黑的女人。如今我更不明白的是命运当时老把我们凑到一起,究竟是何目的。那次在巴黎逗留以后,我又有很长时间没见过她。后来有一天,我下班回到家里,发现她正和我的妻子一起喝茶,端详着她那只戴着丝绸手套的手。那手套的质地就像在陶恩沁恩大街(11) 上廉价买来的袜子,透出一枚闪闪发亮的结婚戒指。有一次有人给我看一本时装杂志,里面登有她的一幅照片,背景是秋风萧瑟的高尔夫球场,到处是落叶和手套。在某一年的圣诞节,她寄来明信片,上面画着雪和星星。在里维埃拉的一处海滨,她戴着一副墨镜,皮肤晒得像赤陶土的颜色,我险些没注意到是她。又有一次,我出差时间没有安排好,中途落脚在一些陌生人的家里,他们正在开派对,我看见衣帽架上挂着许多外国式样的吓人衣服,其中有她的围巾和皮外衣。还有一次是在一家书店,她正在读一本她丈夫写的小说,读到某一页时抬眼朝我点头。那一页正好讲到一个女仆,是个插曲人物,不过作者无意之间偷用了尼娜的形象:“她的脸,”作者写道,“与其说是工笔严谨的画像,不如说是造物者随意拍下的快照,因此每当……他试图想象这张脸时,能够在脑海中成形的只是些互不相关的特征,一一闪现,转瞬而逝:阳光下她的颧骨柔和的轮廓,机灵的眼睛里琥珀一般的褐色暗影,嘴唇扬起一个友好的微笑,随时准备变成热烈的亲吻。”
一次又一次,她匆匆出现在我生活的边缘,一点没有影响我生活的基本内容。一个夏天早晨(是星期五——因为家里的女仆们正把地毯拿到阳光下灰尘飞扬的院子里拍打),家里人都去了乡下,我懒洋洋地躺在床上抽烟,突然听见门铃震天响——原来是她站在门厅里,急急忙忙地冲进来,要寄放一只发夹(这是顺带留下的)和一个贴着旅馆标签的箱子(这是主要留下的)。两个星期后,一个可爱的奥地利男孩替她取走了箱子。那个男孩(根据他身上不太明显却又确实存在的一些特征来看)也是我所在的那个世界性组织的成员。有时候,谈话间会提到她的名字,而她顺着某个偶然说出的句子跑下层层台阶,头也不回。在比利牛斯山旅游时,我在一个城堡别墅住了一个星期,当时她和费迪南德碰巧跟别墅的主人一家一起在这里小住。我永远不会忘记我到那里的第一个夜晚:我等了不知多久;本来确有把握,不用告诉她,她就会偷偷来我房间的,可她并没有来。成千上万的蟋蟀在石头花园参差不齐的石缝深处喧闹,那声音和月光一起洒满花园,小溪疯狂地奔涌流淌。我一整天在山脚下的碎石堆里打猎,回来困得要命,真想像南方人一样无忧无虑地倒头就睡,却又狂热地渴望她偷偷过来,渴望低低的笑声,渴望看见天鹅绒装饰的高跟拖鞋上露出的粉红色脚踝,就这样在困意和渴望间挣扎。然而一夜折腾过去,她还是没有来。第二天,大家一起到山里闲逛,路上我告诉她我等了一夜,她惊慌地紧握两手——还马上快速地瞥了一眼,看看正在打着手势交谈的费迪和他的朋友是否已经走远,留下模糊了背影。我记得有一次我横跨半个欧洲给她打电话(为她丈夫生意上的事情),刚开始没听出她狂呼乱叫的声音。还记得有一次我梦见了她:梦里我的大女儿跑进来告诉我,说看门人遇上了大麻烦——我下楼去看,只见尼娜躺在一个箱子上呼呼大睡,头枕着一卷细麻布,嘴唇苍白,身上裹着一块羊毛方巾,就像凄凄惨惨的难民睡在被上帝遗弃了的火车站一样。不论我发生了什么,她发生了什么,或者我俩都发生什么,我们从来没有讨论过任何事情,好像我们在命运有转机之时根本没有想过对方一般。所以当我们相遇时,生活的步伐马上发生了变化,所有的原子重新进行了组合,我们活在了另一种更轻的时空中,这种时空不用漫长的分离来计算,而是用几次短短的相聚来计算:有了几次这样的短聚,一场短暂的、可能无足轻重的人生就人为地形成了。我们见面每多一次,我的忧虑就添一分:不——我没有经历后院起火的感情灾难,悲剧的影子没有笼罩我们的狂欢,我的婚姻生活没有受到任何损害。另一方面,她那不拘一格的丈夫对她的风流韵事也不闻不问,其实他会从中捞到好处,拉些好交往又有用的关系。我之所以添了忧虑,是因为某种可爱的、精致的、不可重复的东西即将消耗殆尽:我没有珍惜这么好的东西,在过于匆忙之中只可怜巴巴地扯下了几块闪光的外皮,却将不太闪亮但堪称精华的核心弃之一旁。也许这种真正的精华一直在伤心低语,提醒我注意,我却不予理睬。我之所以添了忧虑,还因为到头来我不知为何正在接受尼娜的生活,接受其中的谎言、空虚和无聊。即使没有任何感情上的冲突,我也不由自主地觉得一定要为自己的存在寻找一个合理的解释,且不说合乎道德的解释了。这就意味着我要在两个世界之间做出选择:一个是我的现实世界,我像画肖像一般端坐着,身旁是我的妻子、我的两个小女儿、那条短毛德国猎犬(还有田园诗一般的花冠、一枚私章戒指、一支细长的藤杖),一个幸福、智慧、美好的世界……另一个是什么样的世界呢?真能有实实在在的机会与尼娜一起生活吗?我简直无法想象,因为我知道,这种生活会被无法忍受的强烈痛苦击穿,它的每时每刻都会意识到那段过去,处处是众多行踪不定的伴侣。不行,这样的事情太荒唐。再说了,难道没有比爱情更强大的东西把她牢牢捆在她丈夫身边,让两个囚犯之间结下牢不可破的友谊?荒唐!可是话说回来,尼娜,我拿你怎么办呢?你我那些看似无忧无虑、其实终无结果的会面,逐渐积累,形成了一个装满悲伤的仓库,我又该如何安置这个仓库呢?
菲雅尔塔由旧城和新城两部分组成,随处可见过去和现在纠缠交错,相互撕扯,不是想摆脱对方,就是想把对方排挤出局。它们各有招式:新来的出招光明正大——引进棕榈树,组建漂亮的旅行社,在平坦的红色网球场上画些奶油色的线条。老手们则暗中使劲,从某个角落背后悄悄伸出一条岔路小径,或几级不知通向何处的台阶。在去旅馆的路上,我们经过一座建了一半的白色别墅,里面杂乱无章,一面墙上又画着和先前一样的大象,它们巨大的肉鼓鼓的膝盖分得很开,都坐在花里胡哨的大鼓上。马戏女骑师(已经用铅笔画上了八字胡)一身飘逸装束,端坐在一匹阔背骏马上;小丑鼻头像个西红柿,正在走钢索,打着一把伞保持平衡,伞上面装饰着反复闪现的星星——隐约象征着杂技演员对天堂般故乡的追忆。这里就是菲雅尔塔的里维埃拉,湿漉漉的卵石路被轧辗得更厉害,海水懒洋洋的叹息声也听得更清楚。在旅馆的后院,一个厨房伙计提着一把刀,正在追逐一只母鸡,母鸡咯咯乱叫,狂奔逃命。一位擦鞋匠咧着没牙的嘴冲我笑笑,把他的古老宝座让给我。悬铃木树下停着一辆德国制造的摩托车,一辆溅满了泥点的大轿车,还有一辆黄色的加长伊卡鲁斯小轿车,看上去就像一只巨大的圣甲虫(“那是我们的车——我是说那是塞居尔的车,”尼娜说,又补充道,“维克多,何不跟我们一起走?”不过她很清楚我不会和他们一起去的)。蓝天和树枝投影在小轿车鞘翅的亮漆里,如一幅水粉画;车灯形如炸弹,我们自己的影子一晃一晃地映在一个车灯的金属盖上;车身凸出的表面中走动着一些细瘦的行人身影,像电影放映一般。又走了几步,我回头一瞥,几乎直觉就预见到了一个钟头或更久以后真实发生的事情:他们三个人戴上乘车安全帽,坐进车里,微笑着朝我挥手。在我看来他们像鬼一样透明,尘世的颜色穿透他们,闪闪而过。然后车子就启动了,远去了,消失了(最后消失的是尼娜挥着十个指头的告别)。不过当时的实际情况是那辆车仍然停在那里,一动不动,像个鸡蛋那样又光又圆。我伸出胳膊,护着尼娜走进一个一侧长着月桂树的门道,就在我们坐下时,能从窗户里看见费迪南德和塞居尔。他俩走的是另一条路,现在缓缓过来了。
在我们吃午饭的露台上,除了我刚刚看见过的那个英国人外再没有别人。在他正前方,一只高脚杯盛着亮闪闪的绯红色饮料,在桌布上投下一个椭圆形的影子。从他的眼睛里,我注意到了和饮料颜色一样的血色欲望,不过这欲望与尼娜毫不相干。他贪婪的目光根本没有投向她,而是盯住了他座位附近那扇宽窗子的右上角。
尼娜从她瘦小的手上摘下手套,开始吃她特别爱吃的海贝,这是她一生最后一次吃她爱吃的东西了。费迪南德也在忙着吃饭,我就占了他饿得只顾吃饭的便宜,开始谈话,这样颇有点像我占了他的上风:具体来说,我提到了他最近的失败。原来他赶时髦,曾有过一次改变宗教信仰的短暂经历。改宗期间,神灵降临到他身上,他也有过一番颇具雄心壮志的朝圣之举,不过到头来实实在在是丢人现眼的一场闹剧,于是他呆滞的目光又转向了野蛮的莫斯科。有一种自以为是的说法:意识的流水中荡起涟漪,讲几句无伤大雅的下流话,随便找只脏水桶往里头倒点某种主义,就会点石成金一般自动产生出超现代的文学来。我如今对这样的说法,老实讲,一听就烦。我认为艺术一旦人为地和政治挂上钩,就会不可避免地降至意识形态垃圾的水平,这个信念我死守到底。就费迪南德这而言,的确,这一切都无关痛痒:他的艺术灵感格外强大,更何况他对弱势群体的艰难困苦毫不关心。但就是有那种说不明道不清的污浊潜流,致使他的艺术越来越令人反感。除了个别给他抬轿子的势利鬼外,没人看得懂他的剧作。我自己没有看过他这部剧的上演情形,但我能想象出他是如何精心编排那个克里姆林宫之夜的:拿来子虚乌有的螺线,摇动各种各样的纺车,纺出许多支离破碎的象征。想到这里,我不无乐趣地问他,最近是否读过一点对他的评论。
“评论!”他叫道,“好一个评论!不懂事的毛孩子,仗着伶牙俐齿,就配给我上课。别理睬我的作品,算他们有福。碰我的作品得小心翼翼,像碰什么不小心会爆炸的东西一样。评论!我的作品受到各种观点的审查,唯独缺了最根本的评论。这就像一位博物学家,描述马这类动物,一开始却唠唠叨叨尽讲马鞍或者德维夫人。”(他提到的是一位爱好文学的知名女主人,她倒是真像一匹龇牙咧嘴的马)。“我也想来点那种深红色的。”他继续像刚才那样扯着嗓子大声说道,招呼服务生过来。服务生顺着他留着长指甲的指头方向看过去,这才明白了他的意思,原来他很不礼貌地指着那位英国人的酒杯。出于某种原因,塞居尔提到了鲁比·罗丝,就是那个在胸上绘画鲜花的女士,谈话这才少了点侮辱性质。这时那个高大的英国人突然心血来潮,起身站到一把椅子上,从椅子上一步跨上窗台,往上伸出胳膊,直到够着了窗框上他心心念念的那一角,那里歇着一只毛茸茸又结实的飞蛾,他老练地抓住它,塞进一只药盒里。
“……很像沃弗尔曼(12) 的白马。”费迪南德说道,关于他正和塞居尔讨论的什么事情。
“Tu es très hippique ce matin。”(13) 后者说。
不一会儿他俩都打电话去了。费迪南德特别喜欢打长途电话,也特别善于给它们捐钱。任何时候只要有必要,比如现在要落实免费的住宿,那么不论相隔多么遥远,他的电话都会打得热情友好。
远处传来音乐的声音——一把小号,一把齐特琴。尼娜和我又出去散步了。很显然,马戏团已在来菲雅尔塔的路上,早早派出人来作宣传:一支广告彩车队正在走过。但我们没有看到领头队列,它拐上小山包,进了一条侧街:一辆镀金马车的车尾正在渐渐消失。一个穿着连帽斗篷的男子牵着一匹骆驼,四个平凡无奇的印第安人排成一队,举着挂在高竿上的海报。在他们后面,一位游客的小儿子,身穿水手服,得到特别许可,恭恭敬敬地坐在一匹小小的矮马上。
我们走过一家咖啡店,那里的桌子现在差不多都干了,却仍然空着。服务生正在查看一个模样可怕的弃婴(我希望他以后能收留了它),就是那个墨水池之类的荒唐东西,费迪南德路过时顺手扔在栏杆上不要了。在下一个拐弯处,一段旧石阶引起了我们的注意,我们便爬了上去。尼娜上台阶时提起了裙子,裙子太窄,每一步迈开的角度很尖锐,她得保持与先前长度同样的姿势把全部台阶上完,我一直看着她这样走了上去。她的身上散发出一种熟悉的热气,我和她并排往上走,想起了我们前一次的相聚。那是在巴黎的一所宅子里,到处都是人,我的好朋友朱尔斯·达布想帮我来一次审美升华,便碰了碰我的衣袖,说:“我想让你见见……”说着领我去见尼娜。她坐在一张长沙发的一角上,身体蜷成一个“Z”形,脚跟处放着一只烟灰缸。她从嘴唇上拿下一只长长的绿松石烟嘴,缓缓地、乐呵呵地叫道:“好吧,见过大家——”接下来的整个晚上,我都觉得心要碎了一般。我手里紧攥着一个黏糊糊的酒杯,走过一堆一伙的人群,时不时远远地看她一眼(她却没有看我……),听听只言片语的谈话,无意中听见一位男士对另一个人说道:“真有意思,那些黑头发的瘦姑娘,她们身上的气味怎么都一样,不管用了哪种香水,还是遮不住一股烧树叶的味道。”一句无足轻重的话,说的又是不熟悉的事情,却会缠绕在人心最私密的记忆深处,久久挥之不去,像一条令人难过的寄生虫——这是常见的现象。
到了台阶的顶端,我们发现顶上原来是一个粗糙的平台。从这里可以看见鸽灰色的圣乔治山精巧的轮廓,一面山坡上有一些骨白色的斑点连成一片(是个小村庄)。一列看不见的火车冒出的烟沿着圆形的山底起起伏伏地飘荡——突然间又消失了。再往低处,在凌乱的屋顶上方,可以看见一棵孤零零的柏树,样子很像一支水彩画笔蘸湿了的黑笔尖。在右边,可以看见海水一闪一闪,灰白的海面荡着银色的波纹。我们脚下躺着一把生锈的旧钥匙,一座半塌的房屋连着平台,院墙上仍然悬挂着几根电线头……我心想从前这里是有过生命的,一家人曾在夜幕降临时享受过这里的凉爽,笨手笨脚的孩子们曾借着灯光在这里作画……我们恋恋不舍地在那里徘徊,像是在聆听什么。尼娜站在高一点的地方,把一只手放在我的肩上,微笑着吻了我一下,吻得非常小心,为的是不让自己的微笑走了样。我带着一股难以承受的力量,再次体验了(或者此刻在我看来是如此)我们之间以一个相似的吻开始的所有一切。我说:“听着——我要是爱你怎么办?”(我没有用我们之间廉价而正儿八经的称呼“您”,而是不可思议地用了那个感情丰富、意味深长的“你”。仿佛天涯游子,四海游历后,最终返回这个称呼。)尼娜瞥我一眼,我把那几个字重复了一遍,还想再说几句……可是某些东西像只蝙蝠一般飞快掠过她的脸庞,是一种迅速、怪异、接近丑陋的神情,而她这个素来能带着完美的天真口吐粗言的人,竟然变得局促不安起来。我也觉得颇为尴尬……“别在意,开个玩笑罢了。”我赶紧说道,轻轻地揽住她的腰。一束捆得结结实实的紫罗兰不知从哪里突然出现在她的手中,朵朵深色的小花无私地发出芳香。在她回到她丈夫和小轿车那儿之前,我们在低矮的石墙边又站了一会儿,我们的浪漫故事比以往任何时候都渺茫无望。不过墙上的石头像肌肤一样温暖,突然间我明白了某些我一直在看却未能理解的事情——为什么一张锡纸会在人行道上闪闪发光,为什么一只酒杯的光影会在桌布上抖动,为什么海水会一闪一闪:不知为何,菲雅尔塔上方的天空已在不知不觉间一点一点地浸透了阳光,现在天空已是艳阳高照,充盈的白光越来越宽阔,一切都融入其中,一切都消失了,一切都过去了。我站在姆莱希火车站的站台上,拿着一份刚买的报纸,它告诉我,我曾在悬铃木树下看见的那辆黄色轿车在菲雅尔塔城外惨遭车祸:一辆巡回马戏团的大卡车正往城里开来,小轿车全速撞了上去。在那场车祸中,费迪南德和他的朋友,那两个刀枪不入的无赖,那两个命运的火蜥蜴,那两个洪福齐天的蛇怪,竟死里逃生,只受了一点局部的、暂时的皮肉之伤;而尼娜,尽管曾长期忠实地效仿他俩,却最终不治而亡。
(1) 在基督教中,复活节前的四十天为四旬斋期,也称大斋期。信徒于此期间进行斋戒,模拟当年耶稣在旷野禁食。
(2) Dalmatia,克罗地亚的一个地区,包括亚得里亚海沿岸的达尔马提亚群岛和附近千余小岛。
(3) 法语,其实 。
(4) 十九世纪中期英国人托马斯·库克(Thomas Cook,1808—1892)创办了世界上第一家旅行社——库克旅行社,标志着近代旅游业的诞生。十九世纪下半叶在库克本人的倡导和其成功的旅游业务的鼓舞下,欧洲各地出现了一些类似于旅行社的组织,多数都叫库克旅行社。
(5) Posen,波兰中西部城市,波兹南省首府。历史上曾为波兰首都。
(6) Tauchnitz,德国老牌印刷出版商,自十八世纪以来代代都以印制古典文学和廉价本英文书籍出名。
(7) 法语,人们说你就要结婚了,你知道我会为此死去 。
(8) 法语,《平交道口》 。
(9) 位于塞纳河左岸的巴黎街区,一九一○至一九四○年间,巴黎的艺术中心逐渐转移至此,其餐馆、咖啡馆内诗人画家云集。
(10) 法语,本店特色 。
(11) 柏林著名的购物、餐饮一条街。
(12) Philips Wouwerman(1619—1668),荷兰画家。
(13) 法语,你今天早上怎么对马如此着迷 。
匪兵甲和匪兵乙-三毛
========================
匪兵甲和匪兵乙-[[三毛]]
------
始终没有在排演的时候交谈过一句话——他是一个男生。却就是那么爱上了他的,那个匪兵甲的人……那一年的秋天,我大约是十一岁或者十岁。是台北市中正国民小学的一个学生。
每一个学期的开始,学校必然要举行一场校际的同乐会,由全校各班级同学演出歌舞、话剧和说双簧等等的节目。
记得那一次的同乐会演出两出话剧,毕业班的学长们排练的是“吴凤传”。我的姊姊被老师选出来女扮男装,是主角吴凤。
姊姊一向是学校中的风头人物,功课好,人缘好,模样好,而且从小学一年级开始,始终在当班长。她又有一个好听的绰号,叫做“白雪公主”。
看见姊姊理所当然的扮演吴凤这样重要的人物,我的心里真有说不出的羡慕,因为很喜欢演戏,而自己的老师却是绝对不会想到要我也去演出的。
说没有上过台也是不对的,有一年,也算演过歌舞剧,老师命我做一棵树。竖着比人还要大的三夹板,上面画的当然是那棵树。笔直的站在树的后面直到落幕。
除了吴凤传之外,好似另外一出话剧叫做“牛伯伯打游击”。这两场话剧每天中午都在学校的大礼堂彩排。我吃完了便当,就跑去看姊姊如何舍身取艺。她演得不大逼真,被杀的时候总是跌倒得太小心,很娘娘腔的叫了一声“啊——”
吴凤被杀之后,接着就看牛伯伯如何打游击,当然,彩排的时候剧情是不连贯的。
看了几天,那场指导打游击的老师突然觉得戏中的牛伯伯打土匪打得太容易了,剧本没有高潮和激战。于是他临时改编了剧本,用手向台下看热闹的我一指,说:“你,吴凤的妹妹,你上来,来演匪兵乙,上——来——呀!”
我被吓了一大跳,发觉变成了匪兵。这个,比演一棵树更令人难堪。
以后的中午时间,我的工作便是蹲在一条长板凳上,一大片黑色的布幔将人与前台隔开。当牛伯伯东张西望的经过布幔而来时,我就要虎一下蹦出来,大喊一声:“站住!哪里去?”
有匪兵乙,当然,也有一个匪兵甲。甲乙两个一同躲着,一起跳出去,一齐大喊同样的话,也各自拿着一支扫把柄假装是长枪。
回忆起来,那个匪兵甲的容貌已经不再清晰了,只记得他顶着一个凸凸凹凹的大光头,显然是仔仔细细被剃头刀刮得发亮的头颅。布幔后面的他,总也有一圈淡青色的微光在顶上时隐时现。
在当时的小学校里,男生和女生是禁止说话也不可能一同上课的,如果男生对女生友爱一些,或者笑一笑,第二天沿途上学去的路上,准定会被人在墙上涂着“某年某班某某人爱女生不要脸”之类的鬼话。
老师在那个时代里,居然将我和一个男生一同放在布幔后面,一同蹲在长板凳上,是不可思议的事情。
始终没有在排演的时候交谈过一句话——他是一个男生。天天一起蹲着,那种神秘而又朦胧的喜悦却渐渐充满了我的心。总是默数到第十七个数字,布幔外牛伯伯的步子正好踩到跟前,于是便一起拉开大黑布叫喊着厮杀去了。就是那么爱上了他的,那个匪兵甲的人。
同乐会过去了,学校的一切照常进行了。我的考试不及格,老师喝问为什么退步,也讲不上来。于是老师打人,打完后我撩起裙角,弯下腰偷偷擦掉了一点点眼泪。竹鞭子打腿也不怎么痛的,只是很想因此伤心。
那个匪兵甲,只有在朝会的时候可能张望一下,要在队伍里找他倒也不难,他的头比别人的光,也比较大。我的伤心和考试、和挨打,一点关系也没有。
演完了那出戏,隔壁班级的男生成群结队的欺负人,下课时间总是跑到我们女生班的门口来叫嚣,说匪兵乙爱上了牛伯伯。
被误解是很难过的,更令人难以自处的是上学经过的墙上被人涂上了鬼话,说牛伯伯和匪兵乙正在恋爱。
有一天,下课后走田埂小路回去,迎面来了一大群男生死敌,双方在狭狭的泥巴道上对住了,那边有人开始嘻皮笑脸的喊,慢吞吞的:“不要脸,女生——爱——男——生——”
我冲上去要跟站第一个的男生相打,大堆的脸交错着扑上来,错乱中,一双几乎是在受着极大苦痛而又惊惶的眼神传递过来那么快速的一瞬,我的心,因而尖锐甜蜜的痛了起来。突然收住了步子,拾起掉到水田里的书包,低下头默默侧身而过,背着不要脸呀不要脸的喊声开始小跑起来。
他还是了解我的,那个甲,我们不只一次在彩排的时候心里静悄悄的数着一二三四……然后很有默契的大喊着跳出去。他是懂得我的。
日子一样的过下去,朝会的时刻,总忍不住轻轻回头,眼光扫一下男生群,表情漠漠然的,那淡淡的一掠,总也被另外一双漠漠然的眼白接住,而国旗就在歌声里冉冉上升了。总固执的相信,那双眼神里的冷淡,是另有信息的。
中午不再去排戏了,吃完了饭,就坐在教室的窗口看同学。也是那一次,看见匪兵甲和牛伯伯在操场上打架,匪兵被压在泥巴地上,牛伯伯骑在他身上,一直打一直打。那是雨后初晴的春日,地上许多小水塘,看见牛伯伯顺手挖了一大块湿泥巴,拍一下糊到匪兵甲的鼻子和嘴巴上去,被压在下面的人四肢无力的划动着。那一刹,我几乎窒息死去,指甲掐在窗框上快把木头插出洞来了,而眼睛不能移位。后来,我跑去厕所里吐了。
经过了那一次,我更肯定了自己的那份爱情。
也是那长长的高小生活里,每天夜晚,苦苦的哀求在黑暗中垂听祷告的神,苦求有一日长大了,要做那个人的妻子。哀哀的求,坚定的求,说是绝对不反悔的。
当我们站在同样的操场上唱出了毕业的骊歌来时,许多女生唏哩哗啦的又唱又流泪,而女老师们的眼眶也是淡红色的。司仪一句一字的喊,我们一次一次向校长、主任、老师弯下了腰,然后听见一句话:“毕业典礼结束。礼——成。散——会。”
没有按照两年来的习惯回一下头,跟着同学往教室里冲。理抽屉,丢书本,打扫,排桌子,看了一眼周围的一切,这,就结束了。
回家的路上,尽可能的跑,没命的狂跑,甩掉想要同行的女生,一口气奔到每天要走的田埂上去,喘着气拚命的张望——那儿,除了阳光下一闪一闪的水波之外,没有什么人在等我。
进初中的那年,穿上了绿色的制服,坐公共汽车进城上下学,总统府的号兵和国旗一样升起。刻骨的思念,即使再回头,也看不见什么了。
也是在夜间要祈祷了才能安心睡觉的,那个哀求,仍是一色一样。有一次反反复复的请愿,说着说着,竟然忘了词,心里突然浮上了一种跟自己那么遥远的无能为力和悲哀。“当年,你真爱过牛伯伯吧?”
我笑了起来,说没有,真的没有。
许多许多年过去了,两次小学同学会,来的同学都带了家眷。人不多,只占了一个大圆桌吃饭。说起往事,一些淡淡的喜悦和亲切,毕竟这都已成往事了。
饭后一个男生拿出了我们那届的毕业纪念册来——学校印的那一本。同学们尖叫起来,抢着要看看当年彼此的呆瓜模样。那一群群自以为是的小面孔,大半庄严的板着,好似跟摄影师有仇似的。
“小时候,你的眉头总是皱着。受不了口欧!”一个男生说。
“原来你也有偷看我呀?!”顺手拍一下打了他的头。
轮到我一个人捧着那本纪念册的时候,顺着已经泛黄了的薄纸找名单——六年甲班的。找到了一个人名,翻到下一页,对着一排排的光头移手指,他,匪兵甲,就在眼前出现了。
连忙将眼光错开,还是吃了一惊,好似平白被人用鎯头敲了一下的莫名其妙。
“我要回去了,你们是散还是不散呀?”
散了,大家喊喊叫叫的散了。坐车回家,付钱时手里握的是一把仔细数好的零钱。下车了,计程车司机喊住了我,慢吞吞的:“小姐,你弄错了吧!少了五块钱。”没有跟他对数,道了歉,马上补了。司机先生开车走的时候笑着说:“如果真弄错倒也算了,可是被骗的感觉可不大舒服。”那天晚上,我躺在黑暗中,只能说一句话:“嗳,老天爷,谢谢你。”
风雨天一阁-余秋雨
========================
风雨天一阁-[[余秋雨]]
-----
一
不知怎么回事,天一阁对于我,一直有一种奇怪的阻隔。照理,我是读书人,它是藏书楼,我是宁波人,它在宁波城,早该频频往访的了,然而却一直不得其门而入。1976年春到宁波养病,住在我早年的老师盛钟健先生家,盛先生一直有心设法把我弄到天一阁里去看一段时间书,但按当时的情景,手续颇烦人,我也没有读书的心绪,只得作罢。后来情况好了,宁波市文化艺术界的朋友们总要定期邀我去讲点课,但我每次都是来去匆匆,始终没有去过天一阁。
是啊,现在大批到宁波作几日游的普通上海市民回来后都在大谈天一阁,而我这个经常钻研天一阁藏本重印书籍、对天一阁的变迁历史相当熟悉的人却从未进过阁,实在说不过去。直到1990年8月我再一次到宁波讲课,终于在讲完的那一天支支吾吾地向主人提出了这个要求。主人是文化局副局长裴明海先生,天一阁正属他管辖,在对我的这个可怕缺漏大吃一惊之余立即决定,明天由他亲自陪同,进天一阁。
但是,就在这天晚上,台风袭来,暴雨如注,整个城市都在柔弱地颤抖。第二天上午如约来到天一阁时,只见大门内的前后天井、整个院子全是一片汪洋。打落的树叶在水面上翻卷,重重砖墙间透出湿冷冷的阴气。
看门的老人没想到文化局长会在这样的天气陪着客人前来,慌忙从清洁工人那里借来半高统雨鞋要我们穿上,还递来两把雨伞。但是,院子里积水太深,才下脚,鞋统已经进水,唯一的办法是干脆脱掉鞋子,挽起裤管趟水进去。本来浑身早已被风雨搅得冷飕飕的了,赤脚进水立即通体一阵寒噤。就这样,我和裴明海先生相扶相持,高一脚低一脚地向藏书楼走去。天一阁,我要靠近前去怎么这样难呢?明明已经到了跟前,还把风雨大水作为最后一道屏障来阻拦。我知道,历史上的学者要进天一阁看书是难乎其难的事,或许,我今天进天一阁也要在天帝的主持下举行一个狞厉的仪式?
天一阁之所以叫天一阁,是创办人取《易经》中“天一生水”之义,想借水防火,来免去历来藏书者最大的忧患火灾。今天初次相见,上天分明将“天一生水”的奥义活生生地演绎给了我看,同时又逼迫我以最虔诚的形貌投入这个仪式,剥除斯文,剥除参观式的悠闲,甚至不让穿着鞋子踏入圣殿,背躬曲膝、哆哆嗦嗦地来到跟前。今天这里再也没有其他参观者,这一切岂不是一种超乎寻常的安排?
二
不错,它只是一个藏书楼,但它实际上已成为一种极端艰难、又极端悲怆的文化奇迹。
中华民族作为世界上最早进入文明的人种之一,让人惊叹地创造了独特而美丽的象形文字,创造了简帛,然后又顺理成章地创造了纸和印刷术。这一切,本该迅速地催发出一个书籍的海洋,把壮阔的华夏文明播扬翻腾。但是,野蛮的战火几乎不间断地在焚烧着脆薄的纸页,无边的愚昧更是在时时吞食着易碎的智慧。一个为写书、印书创造好了一切条件的民族竟不能堂而皇之地拥有和保存很多书,书籍在这块土地上始终是一种珍罕而又陌生的怪物,于是,这个民族的精神天地长期处于散乱状态和自发状态,它常常不知自己从哪里来,到里去,自己究竟是谁,要干什么。
只要是智者,就会为这个民族产生一种对书的企盼。他们懂得,只有书籍,才能让这么悠远的历史连成缆索,才能让这么庞大的人种产生凝聚,才能让这么广阔的土地长存文明的火种。很有一些文人学士终年辛劳地以抄书、藏书为业,但清苦的读书人到底能藏多少书,而这些书又何以保证历几代而不流散呢?“君子之泽,五世而斩”,功名资财、良田巍楼尚且如此,更遑论区区几箱书?宫廷当然有不少书,但在清代之前,大多构不成整体文化意义上的藏书规格,又每每毁于改朝换代之际,是不能够去指望的。鉴于这种种情况,历史只能把藏书的事业托付给一些非常特殊的人物了。这种人必得长期为官,有足够的资财可以搜集书籍;这种人为官又最好各地迁移,使他们有可能搜集到散落四处的版本;这种人必须有极高的文化素养,对各种书籍的价值有迅捷的敏感;这种人必须有清晰的管理头脑,从建藏书楼到设计书橱都有精明的考虑,从借阅规则到防火措施都有周密的安排;这种人还必须有超越时间的深入谋划,对如何使自己的后代把藏书保存下去有预先的构想。当这些苛刻的条件全都集于一身时,他才有可能成为古代中国的一名藏书家。
这样的藏书家委实也是出过一些的,但没过几代,他们的事业都相继萎谢。他们的名字可以写出长长一串,但他们的藏书却早已流散得一本不剩了。那么,这些名字也就组合成了一种没有成果的努力,一种似乎实现过而最终还是未能实现的悲剧性愿望。
能不能再出一个人呢,哪怕仅仅是一个,他可以把上述种种苛刻的条件提升得更加苛刻,他可以把管理、保存、继承诸项关节琢磨到极端,让偌大的中国留下一座藏书楼,一座,只是一座上天,可怜可怜中国和中国文化吧。
这个人终于有了,他便是天一阁的创建人范钦。
清代乾嘉时期的学者阮元说:“范氏天一阁,自明至今数百年,海内藏书家,唯此岿然独存。”
这就是说,自明至清数百年广阔的中国文化界所留下的一部分书籍文明,终于找到了一所可以稍加归拢的房子。
明以前的漫长历史,不去说它了,明以后没有被归拢的书籍,也不去说它了,我们只向这座房子叩头致谢吧,感谢它为我们民族断残零落的精神史,提供了一个小小的栖脚处。
三
范钦是明代嘉靖年间人,自27岁考中进士后开始在全国各地做官,到的地方很多,北至陕西、河南,南至两广、云南,东至福建、江西,都有他的宦迹。最后做到兵部右侍郎,官职不算小了。这就为他的藏书提供了充裕的财力基础和搜罗空间。在文化资料十分散乱,又没有在这方面建立起像样的文化市场的当时,官职本身也是搜集书籍的重要依凭。他每到一地做官,总是非常留意搜集当地的公私刻本,特别是搜集其他藏书家不甚重视、或无力获得的各种地方志、政书、实录以及历科试士录,明代各地仕人刻印的诗文集,本是很容易成为过眼云烟的东西,他也搜得不少。这一切,光有搜集的热心和资财就不够了。乍一看,他是在公务之暇把玩书籍,而事实上他已经把人生的第一要务看成是搜集图书,做官倒成了业余,或者说,成了他搜集图书的必要手段。他内心隐潜着的轻重判断是这样,历史的宏观裁断也是这样。好像历史要当时的中国出一个藏书家,于是把他放在一个颠簸九州的官位上来成全他。
一天公务,也许是审理了一宗大案,也许是弹劾了一名贪官,也许是调停了几处官场恩怨,也许是理顺了几项财政关系,衙堂威仪,朝野声誉,不一而足。然而他知道,这一切的重量加在一起也比不过傍晚时分差役递上的那个薄薄的蓝布包袱,那里边几册按他的意思搜集来的旧书,又要汇入行箧。他那小心翼翼翻动书页的声音,比开道的鸣锣和吆喝都要响亮。
范钦的选择,碰撞到了我近年来特别关心的一个命题:基于健全人格的文化良知,或者倒过来说,基于文化良知的健全人格。没有这种东西,他就不可能如此矢志不移,轻常人之所重,重常人之所轻。他曾毫不客气地顶撞过当时在朝廷权势极盛的皇亲郭勋,因而遭到廷杖之罚,并下过监狱。后来在仕途上仍然耿直不阿,公然冒犯权奸严氏家族,严世藩想加害于他,而其父严嵩却说:“范钦是连郭勋都敢顶撞的人,你参了他的官,反而会让他更出名。”结果严氏家族竟奈何范钦不得。我们从这些事情可以看到,一个成功的藏书家在人格上至少是一个强健的人。
这一点我们不妨把范钦和他身边的其他藏书家作个比较。与范钦很要好的书法大师丰坊也是一个藏书家,他的字毫无疑问要比范钦写得好,一代书家董其昌曾非常钦佩地把他与文徵明并列,说他们两人是“墨池董狐”,可见在整个中国古代书法史上,他也是一个耀眼的星座。他在其他不少方面的学问也超过范钦,例如他的专著《五经世学》,就未必是范钦写得出来的。但是,作为一个地道的学者艺术家,他太激动,太天真,太脱世,太不考虑前后左右,太随心所欲。起先他也曾狠下一条心变卖掉家里的千亩良田来换取书法名帖和其他书籍,在范钦的天一阁还未建立的时候他已构成了相当的藏书规模,但他实在不懂人情世故,不懂口口声声尊他为师的门生们也可能是巧取豪夺之辈,更不懂得藏书楼防火的技术,结果他的全部藏书到他晚年已有十分之六被人拿走,又有一大部分毁于火灾,最后只得把剩余的书籍转售给范钦。范钦既没有丰坊的艺术才华,也没有丰坊的人格缺陷,因此,他以一种冷峻的理性提炼了丰坊也会有的文化良知,使之变成一种清醒的社会行为。相比之下,他的社会人格比较强健,只有这种人才能把文化事业管理起来。太纯粹的艺术家或学者在社会人格上大多缺少旋转力,是办不好这种事情的。
另一位可以与范钦构成对比的藏书家正是他的侄子范大澈。范大澈从小受叔父影响,不少方面很像范钦,例如他为官很有能力,多次出使国外,而内心又对书籍有一种强烈的癖好;他学问不错,对书籍也有文化价值上的裁断力,因此曾被他搜集到一些重要珍本。他藏书,既有叔父的正面感染,也有叔父的反面刺激。据说有一次他向范钦借书而范钦不甚爽快,便立志自建藏书楼来悄悄与叔父争胜,历数年努力而楼成,他就经常邀请叔父前去作客,还故意把一些珍贵秘本放在案上任叔父随意取阅。遇到这种情况,范钦总是淡淡的一笑而已。在这里,叔侄两位藏书家的差别就看出来了。侄子虽然把事情也搞得很有样子,但背后却隐藏着一个意气性的动力,这未免有点小家子气了。在这种情况下,他的终极性目标是很有限的,只要把楼建成,再搜集到叔父所没有的版本,他就会欣然自慰。结果,这位作为后辈新建的藏书楼只延续几代就合乎逻辑地流散了,而天一阁却以一种怪异的力度屹立着。
实际上,这也就是范钦身上所支撑着的一种超越意气、超越嗜好、超越才情,因此也超越时间的意志力。这种意志力在很长时间内的表现常常让人感到过于冷漠、严峻,甚至不近人情,但天一阁就是靠着它延续至今的。
四
藏书家遇到的真正麻烦大多是在身后,因此,范钦面临的问题是如何把自己的意志力变成一种不可动摇的家族遗传。不妨说,天一阁真正堪称悲壮的历史,开始于范钦死后。我不知道保住这座楼的使命对范氏家族来说算是一种荣幸,还是一场绵延数百年的苦役。
活到80高龄的范钦终于走到了生命尽头,他把大儿子和二媳妇(二儿子已亡故)叫到跟前,安排遗产继承事项。老人在弥留之际还给后代出了一个难题,他把遗产分成两份,一份是万两白银,一份是一楼藏书,让两房挑选。
这是一种非常奇怪的遗产,分割法。万两白银立即可以享用,而一楼藏书则除了沉重的负担没有任何享用的可能,因为范钦本身一辈子的举止早已告示后代,藏书绝对不能有一本变卖,而要保存好这些藏书每年又要支付一大笔费用。为什么他不把保存藏书的责任和万两白银都一分为二让两房一起来领受呢?为什么他要把权利和义务分割得如此彻底要后代选择呢?
我坚信这种遗产分割法老人已经反复考虑了几十年。实际上这是他自己给自己出的难题:要么后代中有人义无返顾、别无他求地承担艰苦的藏书事业,要么只能让这一切都随自己的生命烟消云散!他故意让遗嘱变得不近情理,让立志继承藏书的一房完全无利可图。因为他知道这时候只要有一丝掺假,再隔几代,假的成分会成倍地扩大,他也会重蹈其他藏书家的覆辙。
他没有丝毫意思想讥刺或鄙薄要继承万两白银的那一房,诚实地承认自己没有承接这项历史性苦役的信心,总比在老人病榻前不太诚实的信誓旦旦好得多。但是,毫无疑问,范钦更希望在告别人世的最后一刻听到自己企盼了几十年的声音。他对死神并不恐惧,此刻却不无恐惧地直视着后辈的眼睛。
大儿子范大冲立即开口,他愿意继承藏书楼,并决定拨出自己的部分良田,以田租充当藏书楼的保养费用。
就这样,一场没完没了的接力赛开始了。多少年后,范大冲也会有遗嘱,范大冲的儿子又会有遗嘱……,后一代的遗嘱比前一代还要严格。藏书的原始动机越来越远,而家族的繁衍却越来越大,怎么能使后代众多支脉的范氏世谱中每一家每一房都严格地恪守先祖范钦的规范呢?这实在是一个值得我们一再品味的艰难课题。在当时,一切有历史跨度的文化事业只能交付给家族传代系列,但家族传代本身却是一种不断分裂、异化、自立的生命过程。让后代的后代接受一个需要终生投入的强硬指令,是十分违背生命的自在状态的;让几百年之后的后裔不经自身体验就来沿袭几百年前某位祖先的生命冲动,也难免有许多憋气的地方。不难想象,天一阁藏书楼对于许多范氏后代来说几乎成了一个宗教式的朝拜对象,只知要诚惶诚恐地维护和保存,却不知是为什么。按照今天的思维习惯,人们会在高度评价范氏家族的丰功伟绩之余随之揣想他们代代相传的文化自觉,其实我可肯定此间埋藏着许多难以言状的心理悲剧和家族纷争,这个在藏书楼下生活了几百年的家族非常值得同情。
后代子孙免不了会产生一种好奇,楼上究竟是什么样的呢?
到底有哪些书,能不能借来看看?亲戚朋友更会频频相问,作为你们家族世代供奉的这个秘府,能不能让我们看上一眼呢?.
范钦和他的继承者们早就预料到这种可能,而且预料藏书楼就会因这种点滴可能而崩坍,因而已经预防在先。他们给家族制定了一个严格的处罚规则,处罚内容是当时视为最大屈辱的不予参加祭祖大典,因为这种处罚意味着在家族血统关系上亮出了“黄牌”,比杖责鞭笞之类还要严重。处罚规则标明:子孙无故开门入阁者,罚不与祭3次;私领亲友人阁及擅开书橱者,罚不与祭1年;擅将藏书借出外房及他姓者,罚不与祭3年,因而典押事故者,除追惩外,永行摈逐,不得与祭。
在此,必须讲到那个我每次想起都很难过的事件了。嘉庆年间,宁波知府丘铁卿的内侄女钱绣芸是一个酷爱诗书的姑娘,一心想要登天一阁读点书,竟要知府作媒嫁给了范家。现代社会学家也许会责问钱姑娘你究竟是嫁给书还是嫁给人,但在我看来,她在婚姻很不自由的时代既不看重钱也不看重势,只想借着婚配来多看一点书,总还是非常令人感动的。但她万万没有想到,当自己成了范家媳妇之后还是不能登楼,一种说法是族规禁止妇女登楼,另一种说法是她所嫁的那一房范家后裔在当时已属于旁支。反正钱绣芸没有看到天一阁的任何一本书,郁郁而终。
今天,当我抬起头来仰望天一阁这栋楼的时候,首先想到的是钱绣芸那忧郁的目光。我几乎觉得这里可出一个文学作品了,不是写一般的婚姻悲剧,而是写在那很少有人文主义气息的中国封建社会里,一个姑娘的生命如何强韧而又脆弱地与自己的文化渴求周旋。
从范氏家族的立场来看,不准登楼,不准看书,委实也出于无奈。只要开放一条小缝,终会裂成大隙。但是,永远地不准登楼,不准看书,这座藏书楼存在于世的意义又何在呢?这个问题,每每使范氏家族陷入困惑。
范氏家族规定,不管家族繁衍到何等程度,开阁门必得各房一致同意。阁门的钥匙和书橱的钥匙由各房分别掌管,组成一环也不可缺少的连环,如果有一房不到是无法接触到任何藏书的。既然每房都能有效地行使否决权,久而久之,每房也都产生了终极性的思考:被我们层层叠叠堵住了门的天一阁究竟是干什么用的?
就在这时,传来消息,大学者黄宗羲先生要想登楼看书!这对范家各房无疑是一个巨大的震撼。黄宗羲是“吾乡”余姚人,对范氏家族没有任何血缘关系,照理是严禁登楼的,但无论如何他是靠自己的人品、气节、学问而受到全国思想学术界深深钦佩的巨人,范氏各房也早有所闻。尽管当时的信息传播手段非常落后,但由于黄宗羲的行为举止实在是奇崛响亮,一次次在朝野之间造成非凡的轰动效应。他的父亲本是明末东林党重要人物,被魏忠贤宦官集团所杀,后来宦官集团受审,19岁的黄宗羲在廷质时竟义愤填膺地锥刺和痛殴漏网余党,后又追杀凶手,警告阮大铖,一时大快人心。清兵南下时他与两个弟弟在家乡组织数百人的子弟兵“世忠营”英勇抗清,抗清失败后便潜心学术,边著述边讲学,把民族道义、人格道德溶化在学问中启世迪人,成为中国古代学术天域中第一流的思想家和历史学家。他在治学过程中已经到绍兴钮氏“世学楼”和祁氏“淡生堂”去读过书,现在终于想来叩天一阁之门了。他深知范氏家族的森严规矩,但他还是来了,时间是康熙十二年,即1673年。
出乎意外,范氏家族的各房竟一致同意黄宗羲先生登楼,而且允许他细细地阅读楼上的全部藏书。这件事,我一直看成是范氏家族文化品格的一个验证。他们是藏书家,本身在思想学术界和社会政治领域都没有太高的地位,但他们毕竟为一个人而不是为其他人,交出了他们珍藏严守着的全部钥匙。这里有选择,有裁断,有一个庞大的藏节世家的人格闪耀。黄宗羲先生长衣布鞋,悄然登楼了。铜锁在一具具打开,1673年成为天一阁历史上特别有光彩的一年。
黄宗羲在天一阁翻阅了全部藏书,把其中流通未广者编为书目,并另撰《天一阁藏书记》留世。由此,这座藏书楼便与一位大学者的人格连结起来了。
从此以后,天一阁有了一条可以向真正的大学者开放的新规矩,但这条规矩的执行还是十分苛严,在此后近200年的时间内,获准登楼的大学者也仅有10余名,他们的名字,都是上得了中国文化史的。
这样一来,天一阁终于显现了本身的存在意义,尽管显现的机会是那样小。封建家族的血缘继承关系和社会学术界的整体需求产生了尖锐的矛盾,藏书世家面临着无可调和的两难境地:要么深藏密裹使之留存,要么发挥社会价值而任之耗散。看来像天一阁那样经过最严格的选择作极有限的开放是一个没有办法中的办法。但是,如此严格地在全国学术界进行选择,已远远超出了一个家族的职能范畴了。
直到乾隆决定编纂《四库全书》,这个矛盾的解决才出现了一些新的走向。乾隆谕旨各省采访遗书,要各藏书家,特别是江南的藏书家积极献书。天一阁进呈珍贵古籍600余种,其中有96种被收录在《四库全书》中,有370余种列入存目。乾隆非常感谢天一阁的贡献,多次褒扬奖赐,并授意新建的南北主要藏书楼都仿照天一阁格局营建。
天一阁因此而大出其名,尽管上献的书籍大多数没有发还,但在国家级的“百科全书”中,在钦定的藏书楼中,都有了它的生命。我曾看到好些著作文章中称乾隆下令天一阁为《四库全书》献书是天一阁的一大浩劫,颇觉言之有过。藏书的意义最终还是要让它广泛流播,“藏”本身不应成为终极目的。连堂堂皇家编书都不得不大幅度地动用天一阁的珍藏,家族性的收藏变成了一种行政性的播扬,这证明天一阁获得了大成功,范钦获得了大成功。
五
天一阁终于走到了中国近代。什么事情一到中国近代总会变得怪异起来,这座古老的藏书楼开始了自己新的历险。
先是太平军进攻宁波时当地小偷趁乱拆墙偷书,然后当废纸论斤卖给造纸作坊。曾有一人出高价从作坊买去一批,却又遭大火焚毁。
这就成了天一阁此后命运的先兆,它现在遇到的问题已不是让不让某位学者上楼的问题了,竟然是窃贼和偷儿成了它最大的对手。
1914年,一个叫薛继渭的偷儿奇迹般地潜入书楼,白天无声无息,晚上动手偷书,每日只以所带枣子充饥,东墙外的河上,有小船接运所偷书籍。这一次几乎把天一阁的一半珍贵书籍给偷走了,它们渐渐出现在上海的书铺里。
薛继渭的这次偷窃与太平天国时的那些小偷不同,不仅数量巨大、操作系统,而且最终与上海的书铺挂上了钩,显然是受到书商的指使。近代都市的书商用这种办法来侵吞一个古老的藏书楼,我总觉得其中蕴含着某种象征意义。把保护藏书楼的种种措施都想到了家的范钦确实没有在防盗的问题上多动脑筋,因为这对在当时这样一个家族的院落来说构不成一种重大威胁。但是,这正像范钦想象不到会有一个近代降临,想象不到近代市场上那些商人在资本的原始积累时期会采取什么手段。一架架的书橱空了,钱绣芸小姐哀怨地仰望终身而未能上的楼板,黄宗羲先生小心翼翼地踩踏过的楼板,现在只留下偷儿吐出的一大堆枣核在上面。
当时主持商务印书馆的张元济先生听说天一阁遭此浩劫,并得知有些书商正准备把天一阁藏本卖给外国人,便立即拨巨资抢救,保存于东方图书馆的“涵芬楼”里。涵芬楼因有天一阁藏书的润泽而享誉文化界,当代不少文化大家都在那里汲取过营养。但是,如所周知,它最终竟又全部焚毁于日本侵略军的炸弹之下。
这当然更不是数百年前的范钦先生所能预料的了。他“天一生水”的防火秘咒也终于失效。
六
然而毫无疑问,范钦和他后代的文化良知在现代并没有完全失去光亮。除了张元济先生外,还有大量的热心人想努力保护好天一阁这座“危楼”,使它不要全然成为废墟。这在现代无疑已成为一个社会性的工程,靠着一家一族的力量已无济于事。幸好,20世纪30年代、50年代、60年代直至80年代,天一阁一次次被大规模地修缮和充实着,现在已成为重点文物保护单位,也是人们游览宁波时大多要去访谒的一个处所。天一阁的藏书还有待于整理,但在文化信息密集、文化沟通便捷的现代,它的主要意义已不是以书籍的实际内容给社会以知识,而是作为一种古典文化事业的象征存在着,让人联想到中国文化保存和流传的艰辛历程,联想到一个古老民族对于文化的渴求是何等悲怆和神圣。
我们这些人,在生命本质上无疑属于现代文化的创造者,但从遗传因子上考察又无可逃遁地是民族传统文化的孑遗,因此或多或少也是天一阁传代系统的繁衍者,尽管在范氏家族看来只属于“他姓”。登天一阁楼梯时我的脚步非常缓慢,我不断地问自己:你来了吗?你是哪一代的中国书生?
很少有其他参观处所能使我像在这里一样心情既沉重又宁静。阁中一位年老的版本学家颤巍巍地捧出两个书函,让我翻阅明刻本,我翻了一部登科录,一部上海志,深深感到,如果没有这样的孤本,中国历史的许多重要侧面将沓无可寻。由此想到,保存这些历史的天一阁本身的历史,是否也有待于进一步发掘呢?裴明海先生递给我一本徐季子、郑学溥、袁元龙先生写的《宁波史话》的小册子,内中有一篇介绍了天一阁的变迁,写得扎实而清晰,使我知道了不少我原先不知道的史实。但在我看来,天一阁的历史是足以写一部宏伟的长篇史诗的。我们的文学艺术家什么时候能把他们的目光投向这种苍老的屋宇和庭园呢?什么时候能把范氏家族和其他许多家族数百年来的灵魂史展示给现代世界呢?
否 定- 余华
========================
否 定- [[余华]]
------
在欧内斯特·纽曼编辑出版的《回忆录》里,柏辽兹显示了其作家的身份,他在处理语言的节奏和变化时,就像处理音乐一样才华非凡,而且辛辣幽默。正如他认为自己的音乐“变幻莫测”,《回忆录》中的故事也同样如此,他在回忆自己一生的同时,情感的浪漫和想象的夸张,以及对语言叙述的迷恋,使他忍不住重新虚构了自己的一生。在浪漫主义时期音乐家的语言作品中,柏辽兹的《回忆录》可能是最缺少史料价值的一部。这正是他的风格,就是在那部有关管弦乐配器的著作《乐器法》里,柏辽兹仍然尽情地炫耀他华丽的散文风格。
《回忆录》中有关莫扎特歌剧的章节,柏辽兹这样写道:“我对莫扎特的钦佩并不强烈……”那时候柏辽兹的兴趣在格鲁克和斯蓬蒂尼身上,他承认这是他对《唐璜》和《费加罗的婚礼》的作曲者态度冷淡的原因所在,“此外,还有另外一个更为充足的理由。那就是,莫扎特为唐纳·安娜写的一段很差的音乐使我很吃惊……它出现在第二幕抒情的女高音唱段上,这是一首令人悲痛欲绝的歌曲,其中爱情的诗句是用悲伤和泪水表现的。但是这段歌唱却是用可笑的、不合适的乐句来结束。人们不禁要问,同一个人怎能同时写出两种互不相容的东西呢?唐纳·安娜好像突然把眼泪擦干,变成了一个粗俗滑稽的角色”。接下去柏辽兹言辞激烈地说:“我认为要人们去原谅莫扎特这种不可容忍的错误是困难的。我愿流血捐躯,如果这样做可以撕掉那可耻的一页,能够抹洗他作品中其他类似的污点的话。”
这是年轻的柏辽兹在参加巴黎音乐学院入学考试时的想法,当时的柏辽兹“完全被这所知名学院的戏剧音乐吸引了。我应该说这种戏剧是抒情悲剧”。与此同时,在巴黎的意大利歌剧院里,意大利人正用意大利语不断演出着《唐璜》和《费加罗的婚礼》。柏辽兹对意大利人和对位法一向心存偏见,于是祸及莫扎特,“我那时不相信他的戏剧原则,我对他的热情降到零上一度”。这样的情况持续了很多年,直到柏辽兹将音乐学院图书馆里的原谱与歌剧院里意大利人的演出相对照后,柏辽兹才从睡梦里醒来,他发现歌剧院的演出其实是法国式的杂曲,真正的莫扎特躺在图书馆里泛黄的乐谱上,“首先,是那极其优美的四重奏、五重奏以及几部奏鸣曲使我开始崇拜他那天使般的天才。”莫扎特的声誉在柏辽兹这里立刻峰回路转了。有趣的是,柏辽兹对莫扎特的崇拜并没有改变他对那段女高音的看法,他的态度反而更加尖刻,“我甚至用‘丢脸的’这个形容词去抨击那段音乐,这也并不过分。”柏辽兹毫不留情地说:“莫扎特在此犯了一个艺术史上最醒目的错误,它背离了人的感情、情绪、风雅和良知。”
其实,莫扎特歌剧中乐曲和歌词融合无间的友情在那时已经广获赞扬,虽然这样的友情都是半途建立的,又在半途分道扬镳。这是因为戏剧和音乐都在强调着各自的独立性,音乐完美的原则和戏剧准确的原则在歌剧中经常互相抵触,就像汉斯立克所说的“音乐与歌词永远在侵占对方的权利或做出让步”,汉斯立克有一个很好的比喻,他说:“歌剧好比一个立宪政体,永远有两个对等的势力在竞争着。在这个竞争中,艺术家不能不有时让这一个原则获胜,有时让那一个原则获胜。”莫扎特似乎从来就不给另一个原则,也就是戏剧原则获胜的机会,他相信好的音乐可以使人们忘掉最坏的歌词,而相反的情况不会出现。因此莫扎特的音乐在歌剧中经常独立自主地发展着,就是在最复杂的部分,那些终曲部分,取消歌词单听音乐时,音乐仍然是清晰和美丽的。
与莫扎特认为诗应该是音乐顺从的女儿完全不同,格鲁克使音乐隶属到了诗的麾下。这位“一到法国,就与意大利歌剧展开长期斗争”的德国人——这里所说的意大利歌剧是指蒙特威尔第之后150年来变得越来越华而不实和故弄玄虚的歌剧,单凭这一点格鲁克就深得法国人柏辽兹的好感。格鲁克从那个时代虚张声势的歌唱者那里接管了歌剧的主权,就像他的后继者瓦格纳所说的:“格鲁克自觉地、信心坚定地表示:表情应和歌词相符,这才是合情合理、合乎需要,咏叹调和宣叙调都是如此……他彻底改变了歌剧中诸因素彼此之间一度所处的位置……歌唱者成为了作曲者目的的代理人。”不过格鲁克没有改变诗人与作曲家的关系,与其他越来越独裁的作曲家不同,格鲁克在诗歌面前总是彬彬有礼,这似乎也是柏辽兹喜爱格鲁克的原因之一。在格鲁克的歌剧里,柏辽兹不会发现莫扎特式的错误,那些乐曲和歌词背道而驰的错误。
这时,有一个疑问出现了,那就是莫扎特的错误是否真实存在。当柏辽兹认为莫扎特为唐纳·安娜所写的那一段音乐是“丢脸”的时候,柏辽兹是否掩盖了音乐叙述中某些否定的原则?或者说他指出了这样的原则,只是他不赞成将这样的原则用在乐曲和歌词关系的处理上,简单地说就是他不赞成作曲家在诗歌面前过于独断专行。事实上,天使般的莫扎特不会看不见那段抒情女高音里的歌词已被泪水浸湿了,然而在歌剧中乐曲时常会得到自己的方向,如同开始泛滥的洪水那样顾不上堤坝的约束了。当莫扎特的音乐骑上了没有缰绳的自由之马时,还有谁能够为他指出方向?只有音乐史上最为纯真的品质和独一无二的天才,也就是莫扎特自己,才有可能去设计那些在马蹄下伸展出去的道路。
于是,莫扎特的乐曲否定了唐纳·安娜唱段中歌词的含意。柏辽兹注意到了,认为是一个错误,而且还是一个“丢脸”的错误。柏辽兹同时代的其他一些人也会注意到,他们没有说什么,也许他们并不认为它是一个错误。那个差不多和勃拉姆斯一样严谨的汉斯立克,似乎更愿意去赞扬莫扎特歌剧中乐曲和歌词的融合无间。这似乎是如何对待叙述作品——音乐作品和语言作品时屡见不鲜的例证,人们常常各执一词,并且互不相让。下面让我们来读一段门德尔松的书信,这是门德尔松聆听了柏辽兹那首变幻莫测、情感泛滥的《幻想交响曲》以后,在罗马写给母亲的信,他在信中写道:“您一定听人说起柏辽兹和他的作品。他使我沮丧。他是一位有教养、有文化、可亲的君子,可是乐曲却写得很糟。”
门德尔松对这首标题音乐和里面所暗示的那个阴森的故事没有好感,或者说他不喜欢柏辽兹在交响乐里卖弄文学。虽然如纽曼所说的:“所有现代的标题音乐作曲家都以他为基础。”然而当时的门德尔松无法接受他这些“讲故事的音乐”,因为柏辽兹有着拉拢文学打击音乐的嫌疑。而且,“演奏前,他散发了两千份乐曲解说”,这似乎激怒了门德尔松,使他语气更加激烈:“我对上述这一切是多么厌恶。看到人们极为珍视的思想被漫画式的手法处理而受到歪曲,遭到贬低,实在令人激愤。”这就是门德尔松对柏辽兹音乐革命的态度。那个反复出现的主题,也就是后来影响了李斯特和瓦格纳的“固定乐思”,在门德尔松眼中,只是“被篡改过的‘最后审判日’中的固定低音”而已;当柏辽兹让乐器不再仅仅发出自己的声音,而是将乐器的音和色彩加以混合发出新的声音时,门德尔松这样写道:“运用一切可能的管弦乐夸张手段来表现虚假的情感。四面定音鼓、两架钢琴——四手联弹,以此模仿铃声,两架竖琴、许多面大鼓、小提琴分为八个声部,两个声部由低音提琴演奏,这些手段(如果运用得当,我并不反对)用来表现的只是平淡冷漠的胡言乱语,无非是呻吟、呐喊和反复的尖叫而已。”
门德尔松在信的最后这样告诉母亲:“当您看到他是怎样敏锐、恰切地评价和认识事物,而对自己本身却茫然不知时,您会感到他是十分可悲的。”就像柏辽兹愿流血捐躯,如果可以撕掉莫扎特音乐中那“可耻的一页”,门德尔松的反应是:“我无法用语言表达见到他时我是多么沮丧。我一连两天都未能工作。”
优美精致和旋律悠扬的门德尔松,他所赞成的显然是莫扎特的信念。莫扎特说:“音乐……绝不能刺耳,它应该怡情悦性;换句话说,音乐应该永远不失之为音乐。”这位从来不会将旋律写得过长或者过短的门德尔松,站立在与柏辽兹截然相反的方向里,当柏辽兹在暴烈的激情里显示自己的天才时,门德尔松的天才是因为叙述的克制得到展现。就像门德尔松不能忍受柏辽兹作品中的喧哗那样,很多人因为他从来没有在音乐里真正放任过自己而感到沮丧,与他对柏辽兹的沮丧极为相似。这就是音乐,或者说这就是叙述作品开放的品质,赞扬和指责常常同出一处,因此赞扬什么和指责什么不再成为目的,它们仅仅是经过,就像道路的存在并不是为了住下来而是为了经过那样,门德尔松对巴赫的赞美和对柏辽兹的沮丧,其实只是为了表明自己的立场,或者说是对自己音乐的理解和使其合法化的辩护。叙述作品完成后所存在的未完成性和它永远有待于完成的姿态,一方面展现了叙述作品可以不断延伸的丰富性,另一方面也为众说纷纭提供了便利。
事实上,柏辽兹对莫扎特的指责和门德尔松对柏辽兹的沮丧,或多或少地表达出了音乐中某些否定原则的存在。这里所要讨论的否定并不是音乐叙述里的风格和观念之争,虽然这方面的表现显得更为直接和醒目,叙述史的编写——音乐史和文学几乎就是这样构成的。只要回顾一下巴洛克时期、古典主义时期和浪漫主义时期,一直到现代主义时期,那些各个时期显赫的人物和平庸的人物是如何捍卫自己和否定别人的,就会看到音乐史上有关风格和观念的争执其实是没完没了的混战,就像一片树林着火以后祸及了其他的树林,18世纪的战火也同样会蔓延到20世纪。如果以此来完成一部音乐作品的话,这部作品所表达出来的“喧哗与骚动”,将使柏辽兹《幻想交响曲》里的“喧哗与骚动”黯淡无光。
因此,这里所说的否定是指叙述进程中某些突然来到的行为,这些貌似偶然其实很可能是蓄谋已久的行为,或者说是叙述自身的任性和放荡,以及那些让叙述者受宠若惊的突如其来的灵感,使叙述顷刻之间改变了方向。就像一个正在微笑的人突然翻脸似的,莫扎特让乐曲否定了唐纳·安娜的唱词,柏辽兹让传统的交响乐出现了非交响乐的欲望。
穆索尔斯基在给斯塔索夫的信中列举了他所认为的四个巨匠——荷马、莎士比亚、贝多芬和柏辽兹,其他的人都是这四个人的将领和副官,以及无数的追随者,穆索尔斯基在最后写道:“他们只能沿着巨匠们划出的狭路蹦蹦跳跳,但是,你如敢于‘跑到前面’的话,那将是令人恐惧的!”在这句用惊叹号结束的话里,穆索尔斯基几乎使自己成为了艺术的宿命论者,不过他也确实指出了音乐创作中最大的难题,这样的难题是胆大包天的人和小心谨慎的人都必须面对的,无论是离经叛道的柏辽兹还是循规蹈矩的门德尔松都无法回避。
与此同时,正是这样的难题不断地压迫着叙述者,才使叙述中的否定可以不断地合法出现,让叙述者“跑到前面”,穆索尔斯基指出的“恐惧”同时也成为了诱惑,成为了摆脱叙述压制时的有力武器。尤其是那些才华横溢的年轻人,创作之路的陌生和漫长很容易使他们深陷于叙述的平庸之中,他们需要在下一个经过句里获得崭新的力量,就像阳光拨开了云雾,让正在进行中的叙述不断去经受震动。于是他们就会经常去借助叙述里的否定之手,随便一挥就让前面的叙述像白痴似的失去了方向,叙述被颠倒过来,方向也被重新确立。瓦格纳十七岁时就已经精通此道,在那一年的圣诞之夜,这个标新立异的年轻人以一首《降B大调序曲》参加了莱比锡宫廷剧院的演出,他在每隔四小节的乐曲里安插了一阵否定式的最强音鼓声,使圣诞之夜的听众们饱受惊吓。然而在每一次惊吓之后,剧院里出现的都是哄堂大笑。
1924年,埃尔加在《大英帝国展览》的文章里这样写道:“一万七千个敲着槌的人,扩音机、扬声器等——有四架飞机在上空盘旋着等等,全都是令人讨厌的机械东西。没有电视,没有浪漫,欠缺想象……但是,在我脚下我看见了一堆真正的雏菊,我的眼睛不禁为之湿润。”
在这里,埃尔加表达了一个在内心深处展开的叙述,一堆小小的雏菊,它们很不起眼,而且似乎是软弱无援,然而它们突然之间产生了力量,可以将一万七千个槌声,还有扩音机、扬声器和飞机等等全部否定。同时,埃尔加也为存在于叙述中的否定的原则提供了心电图,这是至关重要的,正是那些隐藏在艺术家内心深处的情感和思想,它们像岛屿和礁石散落在大海里那样,散落在内心各处,而且深藏不露,它们等待着叙述之船的经过,让其靠岸,也让其触礁。这几乎是所有伟大的叙述者都要面对的命运,当巴赫为两个合唱队和两个管弦乐队写下《马太受难曲》时,他不断地要让宣叙调的独唱去打断合唱队的对唱。随时插入到原有叙述中的新的叙述,成为了改变方向的否定式叙述,而且时常是它刚刚否定了前面段落的叙述后,紧接着就会轮到自己被新的段落所否定。乐曲在叙述的轮回里死去和再生,作曲家的内心也在经历着一次次如同闪电般短促的人生,或者说他的乐曲成为了他内心经历的录音。几乎是出于同样的理由,纽曼认为柏辽兹的音乐在心理探索这一领域取得了某些奇妙的成就,同时纽曼也指出了这些来源于内心的音乐并不是胡思乱想之作,而是“都具有一种有分寸的客观性……这是按事物的面貌来观察事物,而不是像人们自以为的用推测和空想来补充肉眼的证据”。
在苏菲派教徒充满智慧的言论里,有一段讲述了一个有着博大精深学问的人死后来到了天国的门口,吉祥天使迎了上去,对他说:“喂,凡夫俗子,别往前走了,你得先向我证明你有进天堂的资格!”吉祥天使否定了那人前行的脚步,那人的回答是以同样的否定来完成,他说:“我要先问问你,你能不能证明这里是真正的天国,而不是我死后昏瞀心灵的急切的幻想?”就像音乐叙述中的否定不是为了叙述的倒退恰恰是为了前进一样,语言叙述中突然来到的否定也同样如此,当那个有着博大精深学问的人对眼前的天国深表怀疑时,天国里传出了一个比吉祥天使更加权威的声音:“放他进来!他是我们中间的人。”
这段寓意丰富的言论可以不断延伸,或者说在此刻能够成为一个比喻,以此来暗示存在于叙述作品中的否定的命运。就像那位博大精深的学者来到了天国之门,叙述中的否定其实就是为了能够进入叙述的天国。一首《慷慨的敌人》的诗歌,展示了来自一个敌人的祝福。已经完成了对爱尔兰王国全面统治的马格努斯·巴福德,在12世纪的某一夜,也就是他去世的前一夜,弥留之际受到了他的仇敌都柏林王穆尔谢尔达赫的阴险的祝福。这位都柏林王在祝词里使用了最为辉煌的词语,以此来堆积他仇恨的金字塔。这首出自H.杰林之手的诗作,短短十来行的叙述里出现了两个截然不同的方向。
都柏林王首先是“愿黄金和风暴与你的军队并肩作战。愿你的战斗在明天,在我王国的疆场上获得好运。愿你的帝王之手编织起可怕的万刃之网。愿那些向你的剑做出反抗的人成为红色天鹅的食物。愿你的众神满足你的光荣,愿他们满足你嗜血的欲望。愿你在黎明获胜,蹂躏爱尔兰的王啊。”随后,这位慷慨的敌人让叙述中真正的方向出现了——
愿所有的日子都比不上明天的光辉。
因为这一天将是末日。我向你发誓,马格努斯王。
因为在它的黎明消逝之前,我要击败你和抹去你,马格努斯·巴福德。
就像马格努斯王蹂躏了爱尔兰一样,H.杰林也让“因为这一天将是末日”的诗句蹂躏了“愿黄金和风暴与你的军队并肩作战……”。突然来到的否定似乎是叙述里最为残忍的时刻,它时常是在原有的叙述逐渐强大起来时,伸出它的暴君之脚将其践踏。H.杰林的诗作使人想起海顿著名的玩笑之作《惊愕交响曲》,这首传说是为了惊醒那些附庸风雅的欣赏音乐的瞌睡者的作品,其实有着叙述自身的理由。在最温暖的行板进行之中,海顿突然以投弹之势,爆炸出十六小节石破天惊的最强的击鼓音,令数目可观的听众在顷刻之间承受了差不多是一生的惊吓。尽管如此,人们仍然难以忘记这首作品中令人愉悦的音乐——缓慢的序曲,第一乐章中带着笑意的主题,华尔兹般的小步舞曲和精神抖擞的旋律。可以这么说,海顿的《惊愕》和H.杰林的诗作共同指出了叙述中日出的景象和生命的诞生。当十六小节极强的击鼓音在瞬间否定了温暖的行板之后,当“我要击败你和抹去你”在瞬间否定了“愿你的战斗在明天,在我王国的疆场上获得好运”之后,叙述也在瞬间获得了起飞。
一九九九年三月二十三日
高 潮-余华
========================
高 潮-[[余华]]
-----
肖斯塔科维奇和霍桑
肖斯塔科维奇在1941年完成了作品编号60的《第七交响曲》。这一年,希特勒的德国以32个步兵师、4个摩托化师、4个坦克师和1个骑兵旅,还有6000门大炮、4500门迫击炮和1000多架飞机猛烈进攻列宁格勒。希特勒决心在这一年秋天结束之前,将这座城市从地球上抹掉。也是这一年,肖斯塔科维奇在列宁格勒战火的背景下度过了三十五岁生日,他的一位朋友拿来了一瓶藏在地下的伏特加酒,另外的朋友带来了黑面包皮,而他自己只能拿出一些土豆。饥饿和死亡、悲伤和恐惧形成了巨大的阴影,笼罩着他的生日和生日以后的岁月。于是,他在“生活艰难,无限悲伤,无数眼泪”中,写下了第三乐章阴暗的柔板,那是“对大自然的回忆和陶醉”的柔板,凄凉的弦乐在柔板里随时升起,使回忆和陶醉时断时续,战争和苦难的现实以噩梦的方式折磨着他的内心和他的呼吸,使他优美的抒情里时常出现恐怖的节奏和奇怪的音符。
事实上,这是肖斯塔科维奇由来已久的不安,远在战争开始之前,他的噩梦已经开始了。这位来自彼得格勒音乐学院的年轻的天才,十九岁时就应有尽有了。他的毕业作品《第一交响曲》深得尼古拉·马尔科的喜爱,就是这位俄罗斯的指挥家在列宁格勒将其首演,然后立刻出现在托斯卡尼尼·斯托科夫斯基和瓦尔特等人的节目单上。音乐是世界的语言,不会因为漫长的翻译而推迟肖斯塔科维奇世界声誉的迅速来到,可是他的年龄仍然刻板和缓慢地进展着,他太年轻了,不知道世界性的声誉对于一个作曲家意味着什么,他仍然以自己年龄应有的方式生活着,生机勃勃和调皮捣蛋。直到1936年,斯大林听到了他的歌剧《姆钦斯克县的麦克白夫人》后,公开发表了一篇严厉指责的评论。斯大林的声音意味着什么,意味着整个国家都会胆战心惊,当这样的声音从那两片小胡子下面发出时,三十岁的肖斯塔科维奇还在睡梦里干着甜蜜的勾当,次日清晨当他醒来以后,已经不是用一身冷汗可以解释他的处境了。然后,肖斯塔科维奇立刻成熟了。他的命运就像盾牌一样,似乎专门是为了对付打击而来。他在对待荣誉的时候似乎没心没肺,可是对待厄运他从不松懈。在此后四十五年的岁月里,肖斯塔科维奇老谋深算,面对一次一次汹涌而来的批判,他都能够身心投入地加入到对自己的批判中去,他在批判自己的时候毫不留情,如同火上加油,他似乎比别人更乐意置自己于死地,令那些批判者无话可说,只能再给他一条悔过自新的生路。然而在心里,肖斯塔科维奇从来就没有悔过自新的时刻,一旦化险为夷他就重蹈覆辙,似乎是好了伤疤立刻就忘了疼痛,其实他根本就没有伤疤,他只是将颜料涂在自己身上,让虚构的累累伤痕惟妙惟肖,他在这方面的高超技巧比起他作曲的才华毫不逊色,从而使他躲过了一次又一次的劫难,完成了命运赋予他的一百四十七首音乐作品。
尽管从表面上看,比起布尔加科夫,比起帕斯捷尔纳克,比起同时代的其他艺术家凄惨的命运,肖斯塔科维奇似乎过着幸福的生活,起码他衣食不愁,而且住着宽敞的房子,他可以将一个室内乐团请到家中客厅来练习自己的作品,可是在心里,肖斯塔科维奇同样也在经历着艰难的一生。当穆拉文斯基认为肖斯塔科维奇试图在作品里表达出欢欣的声音时,肖斯塔科维奇说:“哪里有什么欢欣可言?”肖斯塔科维奇在生命结束的前一年,在他完成的他第十五首,也是最后一首弦乐四重奏里,人们听到了什么?第一乐章漫长的和令人窒息的旋律意味着什么?将一个只有几秒的简单乐句拉长到十二分钟,已经超过作曲家技巧的长度,达到了人生的长度。
肖斯塔科维奇的经历是一位音乐家应该具有的经历,他的忠诚和才华都给予了音乐,而对他所处的时代和所处的政治,他并不在乎,所以他人云亦云,苟且偷生。不过人的良知始终陪伴着他,而且一次次地带着他来到那些被迫害致死的朋友墓前,他沉默地伫立着,他的伤心也在沉默,他不知道接下去的坟墓是否属于他,他对自己能否继续蒙混过关越来越没有把握,幸运的是他最终还是蒙混过去了,直到真正的死亡来临。与别人不同,这位戴着深度近视眼镜的作曲家将自己的坎坷之路留在了内心深处,而将宽厚的笑容给予了现实,将沉思的形象给予了摄影照片。
因此当希特勒德国的疯狂进攻开始后,已经噩梦缠身的肖斯塔科维奇又得到了新的噩梦,而且这一次的噩梦像白昼一样的明亮和实实在在,饥饿、寒冷和每时每刻都在出现的死亡如同杂乱的脚步,在他身旁周而复始地走来走去。后来,他在《见证》里这样说:战争的来到使苏联人意外地获得了一种悲伤的权利。这句话一箭双雕,在表达了一个民族痛苦的后面,肖斯塔科维奇暗示了某一种自由的来到,或者说“意外地获得了一种权利”。显然,专制已经剥夺了人们悲伤的权利,人们活着只能笑逐颜开,即使是哭泣也必须是笑出了眼泪。对此,身为作曲家的肖斯塔科维奇有着更为隐晦的不安,然而战争改变了一切,在饥饿和寒冷的摧残里,在死亡威胁的脚步声里,肖斯塔科维奇意外地得到了悲伤的借口,他终于可以安全地在自己的作品中表达悲伤,表达来自战争的悲伤,同时也是和平的悲伤;表达个人的悲伤,也是人们共有的悲伤;表达人们由来已久的悲伤,也是人们将要世代相传的悲伤。而且,无人可以指责他。
这可能是肖斯塔科维奇写作《第七交响曲》的根本理由,写作的灵感似乎来自《圣经·诗篇》里悲喜之间的不断转换,这样的转换有时是在瞬间完成,有时则是漫长和遥远的旅程。肖斯塔科维奇在战前已经开始了这样的构想,并且写完了第一乐章,接着战争开始了,肖斯塔科维奇继续自己的写作,并且在血腥和残酷的列宁格勒战役中完成了这一首《第七交响曲》。然后,他发现一个时代找上门来了,1942年3月5日,《第七交响曲》在后方城市古比雪夫首演后,立刻成为了这个正在遭受耻辱的民族的抗击之声,另外一个标题“列宁格勒交响曲”也立刻覆盖了原有的标题“第七交响曲”。
这几乎是一切叙述作品的命运,它们需要获得某一个时代的青睐,才能使自己得到成功的位置,然后一劳永逸地坐下去。尽管它们被创造出来的理由可以与任何时代无关,有时候仅仅是书呆子们一时的冲动,或者由一个转瞬即逝的事件引发出来,然而叙述作品自身开放的品质又可以使任何一个时代与之相关,就像叙述作品需要某个时代的帮助才能获得成功,一个时代也同样需要在叙述作品中找到使其合法化的位置。肖斯塔科维奇知道自己写下了什么,他写下的仅仅是个人的感情和个人的关怀,写下了某些来自《圣经·诗篇》的灵感,写下了压抑的内心和田园般的回忆,写下了激昂悲壮、苦难和忍受,当然也写下了战争……于是,1942年的苏联人民认为自己听到浴血抗战的声音,《第七交响曲》成为了反法西斯之歌。而完成于战前的第一乐章中的插部,那个巨大的令人不安的插部成为了侵略者脚步的诠释。尽管肖斯塔科维奇知道这个插部来源于更为久远的不安,不过现实的诠释也同样有力。肖斯塔科维奇顺水推舟,认为自己确实写下了抗战的《列宁格勒交响曲》,以此献给“我们的反法西斯战斗,献给我们未来的胜利,献给我出生的城市”。他明智的态度是因为他精通音乐作品的价值所在,那就是能够迎合不同时代的诠释,随着时代的改变而不断变奏下去。在古比雪夫的首演之后,《第七交响曲》来到了命运的凯旋门,乐曲的总谱被拍摄成微型胶卷,由军用飞机穿越层层炮火运往了美国。同年的7月19日,托斯卡尼尼在纽约指挥了《第七交响曲》,作为世界人民反法西斯的大合唱,广播电台向全世界做了实况转播。很多年过去后,那些仍然活着的二战老兵,仍然会为它的第一乐章激动不已。肖斯塔科维奇死于1975年,生于1906年。
时光倒转一个世纪,在一个世纪的痛苦和欢乐之前,是另一个世纪的记忆和沉默。1804年,一位名叫纳撒尼尔·霍桑的移民的后代,通过萨勒姆镇来到了人间。位于美国东部新英格兰地区的萨勒姆是一座港口城市,于是纳撒尼尔·霍桑的父亲作为一位船长也就十分自然,他的一位祖辈约翰·霍桑曾经是名噪一时的法官,在17世纪末将十九位妇女送上了绞刑架。显然,纳撒尼尔·霍桑出生时家族已经衰落,老纳撒尼尔已经没有了约翰法官掌握别人命运的威严,他只能开始并且继续自己的漂泊生涯,将自己的命运交给了大海和风暴。1808年,也就是小纳撒尼尔出生的第四年,老纳撒尼尔因患黄热病死于东印度群岛的苏里南。这是那个时代里屡见不鲜的悲剧,当出海数月的帆船归来时,在岸边望穿秋水的女人和孩子们,时常会在天真的喜悦之后,去承受失去亲人的震惊以及此后漫长的悲伤。后来成为一位作家的纳撒尼尔·霍桑,在那个悲伤变了质的家庭里度过了三十多年沉闷和孤独的岁月。
这是一个在生活里迷失了方向的家庭,茫然若失的情绪犹如每天的日出一样照耀着他们,家庭中的每一个成员都不由自主地助长着自己的孤僻性格,岁月的流逝使他们在可怜的自我里越陷越深,到头来母子和兄妹之间视同陌路。博尔赫斯在《纳撒尼尔·霍桑》一文中这样告诉我们:“霍桑船长死后,他的遗孀,纳撒尼尔的母亲,在二楼自己的卧室里闭门不出。两姐妹,路易莎和伊丽莎白的卧室也在二楼;最后一个房间是纳撒尼尔的。那几个人不在一起吃饭,相互之间几乎不说话;他们的饭搁在一个托盘上,放在走廊里。纳撒尼尔整天在屋里写鬼故事,傍晚时分才出来散散步。”
身材瘦长、眉目清秀的霍桑显然没有过肖斯塔科维奇那样生机勃勃的年轻时光,他在童年的时候就已经开始了未老先衰的生活,直到三十八岁遇到他的妻子索菲亚,此后的霍桑总算是品尝了一些生活的真正乐趣。在此之前,他的主要乐趣就是给他在波多因大学时的同学朗费罗写信,他在信中告诉朗费罗:“我足不出户,主观上一点不想这么做,也从未料到自己会出现这种情况。我成了囚徒,自己关在牢房里,现在找不到钥匙,尽管门开着,我几乎怕出去。”这两位19世纪美国浪漫主义文学的杰出代表出自同一个校园,不过他们过着截然不同的生活,朗费罗比霍桑聪明得多,他知道如何去接受著名诗人所能带来的种种好处。阴郁和孤僻的霍桑对此一无所知,他热爱写作,却又无力以此为生,只能以更多的时间和精力去应付税关职员的工作,然后将压抑和厌世的情绪通过书信传达给朗费罗,试图将他的朋友也拉下水。朗费罗从不上当,他只在书信中给予霍桑某些安慰,而不会为他不安和失眠。真正给予霍桑无私的关心和爱护的只有索菲亚,她像霍桑一样热爱着他的写作,同时她精通如何用最少的钱将一个家庭的生活维持下去,当霍桑丢掉了税关的职务沮丧地回到家中时,索菲亚却喜悦无比地欢迎他,她的高兴是那么的真诚,她对丈夫说:“现在你可以写你的书了。”
纳撒尼尔·霍桑作品中所弥漫出来的古怪和阴沉的气氛,用博尔赫斯的话说是“鬼故事”,显然来源于他古怪和阴沉的家庭。按照人们惯常的逻辑,人的记忆似乎是从五岁时才真正开始,如果霍桑的记忆不例外的话,自四岁的时候失去父亲,霍桑的记忆也就失去了童年,我所指的是大多数人所经历过的那种童年,也就是肖斯塔科维奇和朗费罗他们所经历过的童年,那种属于田野和街道、属于争吵和斗殴、属于无知和无忧的童年。这样的童年是贫穷、疾病和死亡都无法改变的。霍桑的童年犹如笼中之鸟,在阴暗的屋子里成长,和一个丧失了一切愿望的母亲,还有两个极力模仿着母亲并且最终比母亲还要阴沉的姐妹生活在一起。
这就是纳撒尼尔·霍桑的童年,墙壁阻断了他与欢乐之间的呼应和对视,他能够听到外面其他孩子的喧哗,可是他只能待在死一般沉寂的屋子里。门开着,他不是不能出去,而是——用他自己的话说是“我几乎怕出去”。在这样的环境里成长起来的霍桑,自然会理解威克菲尔德的离奇想法,在他写下的近两千页的故事和小品里,威克菲尔德式的人物会在页码的翻动中不断涌现,古怪、有趣和令人沉思。博尔赫斯在阅读了霍桑的三部长篇和一百多部短篇小说之外,还阅读了他保存完好的笔记,霍桑写作心得的笔记显示了他还有很多与众不同的有趣想法,博尔赫斯在《纳撒尼尔·霍桑》一文中向我们展示一些霍桑没有在叙述中完成的想法——“有个人从十五岁到三十五岁让一条蛇待在他的肚子里,由他饲养,蛇使他遭到了可怕的折磨。”“一个人清醒时对另一个人印象很好,对他完全放心,但梦见那个朋友却像死敌一样对待他,使他不安。最后发现梦中所见才是那人的真实面目。”“一个富人立下遗嘱,把他的房子赠送给一对贫穷的夫妇。这对夫妇搬了进去,发现房子里有一个阴森的仆人,而遗嘱规定不准将他解雇。仆人使他们的日子过不下去;最后才知道仆人就是把房子送给他们的那人。”……
索菲亚进入了霍桑的生活之后,就像是一位技艺高超的工匠那样修补起了霍桑破烂的生活,如同给磨破的裤子缝上了补丁,给漏雨的屋顶更换了瓦片,索菲亚给予了霍桑正常的生活,于是霍桑的写作也逐渐显露出一些正常的情绪,那时候他开始写作《红字》了。与威克菲尔德式的故事一样,《红字》继续着霍桑因为过多的沉思后变得越来越压抑的情绪。这样的情绪源远流长,从老纳撒尼尔死后就开始了,这是索菲亚所无法改变的。事实上,索菲亚并没有改变霍桑什么,她只是唤醒了霍桑内心深处另外一部分的情感。这样的情感在霍桑的心里已经沉睡了三十多年,现在醒来了,然后人们在《红字》里读到了一段段优美宁静的篇章,读到了在《圣经》之前就已经存在的同情和怜悯,读到了忠诚和眼泪……这是《威克菲尔德》这样的故事所没有的。
1850年,也就是穷困潦倒的爱伦·坡去世后不久,《红字》出版了。《红字》的出版使纳撒尼尔·霍桑彻底摆脱了与爱伦·坡类似的命运,使他声名远扬,次年就有了德译本,第三年有了法译本。霍桑家族自从约翰法官死后,终于再一次迎来了显赫的名望,而且这一次将会长存下去。此后的霍桑度过了一生里最为平静的十四年,虽然那时候的写作还无法致富,然而生活已经不成问题,霍桑与妻子索菲亚还有子女过起了心安理得的生活。当他接近六十岁的时候,四岁时遭受过的命运再一次找上门来,这一次是让他的女儿夭折。与肖斯塔科维奇不断遭受外部打击的盾牌似的一生不同,霍桑一生如同箭靶一样,把每一支利箭都留在了自己的心脏上。他默默地承受着,牙齿打碎了往肚里咽,就是他的妻子索菲亚也无法了解他内心的痛苦究竟有多少,这也是索菲亚为什么从来都无法认清他的原因所在。对索菲亚来说,霍桑身上总是笼罩着一层“永恒的微光”。女儿死后不到一年,1864年的某一天,不堪重负的霍桑以平静的方式结束了自己的一生,他在睡梦里去世了。霍桑的死,就像是《红字》的叙述那样宁静和优美。
纳撒尼尔·霍桑和肖斯塔科维奇,一位是1804年至1864年之间出现过的美国人,另一位是1906年至1975年之间出现过的俄国人;一位写下了文学的作品,另一位写下了音乐的作品。他们置身于两个截然不同的时代,完成了两个截然不同的命运,他们之间的距离比他们相隔的一个世纪还要遥远。然而,他们对内心的坚持却是一样的固执和一样的密不透风,心灵的相似会使两个截然不同的人有时候成为了一个人,纳撒尼尔·霍桑和肖斯塔科维奇,他们的某些神秘的一致性,使他们获得了类似的方式,在岁月一样漫长的叙述里去经历共同的高潮。
《第七交响曲》和《红字》
肖斯塔科维奇《第七交响曲》中第一乐章的叙述,确切地说是第一乐章中著名的侵略插部与《红字》的叙述迎合到了一起,仿佛是两面互相凝视中的镜子,使一部音乐作品和一部文学作品都在对方的叙述里看到了自己的形象。肖斯塔科维奇让那个插部进展到了十分钟以上的长度,同时让里面没有音乐,或者说由没有音乐的管弦乐成分组成,一个单一曲调在鼓声里不断出现和不断消失,如同霍桑《红字》中单一的情绪主题的不断变奏。就像肖斯塔科维奇有时候会在叙述中放弃音乐一样,纳撒尼尔·霍桑同样也会放弃长篇小说中必要的故事的起伏,在这部似乎是一个短篇小说结构的长篇小说里,霍桑甚至放弃了叙述中惯用的对比,肖斯塔科维奇也在这个侵略插部中放弃了对比。接下来他们只能赤裸裸地去迎接一切叙述作品中最为有力的挑战,用渐强的方式将叙述进行下去。这两个人都做到了,他们从容不迫和举重若轻地使叙述在软弱中越来越强大。毫无疑问,这种渐强的方式是最为天真的方式,就像孩子的眼睛那样单纯,同时它又是最为有力的叙述,它所显示的不只是叙述者的技巧是否炉火纯青,当最后的高潮在叙述的渐强里逐步接近并且终于来到时,它就会显示出人生的重量和命运的空旷。
这样的方式使叙述之弦随时都会断裂似的绷紧了,在接近高潮的时候仿佛又在推开高潮,如此周而复始,不断培育着将要来到的高潮,使其越来越庞大和越来越沉重,因此当它最终来到时,就会像是末日的来临一样令人不知所措了。
肖斯塔科维奇给予了我们这样的经历,在那个几乎使人窒息的侵略插部里,他让鼓声反复敲响了一百七十五次,让主题在十一次的变奏里艰难前行。没有音乐的管弦乐和小鼓重复着来到和离去,并且让来到和离去的间隔越来越短暂,逐渐成为了瞬间的转换,最终肖斯塔科维奇取消了离去,使每一次的离去同时成为了来到。巨大的令人不安的音响犹如天空那样笼罩着我们,而且这样的声音还在源源不断地来到,天空似乎以压迫的方式正在迅速地缩小。高潮的来临常常意味着叙述的穷途末路,如何在高潮之上结束它,并且使它的叙述更高地扬起,而不是垂落下来,这样的考验显然是叙述作品的关键。
肖斯塔科维奇的叙述是让主部主题突然出现,这是一个尖锐的抒情段落,在那巨大可怕的音响之上生长起来。顷刻之间奇迹来到了,人们看到“轻”比“沉重”更加有力,仿佛是在黑云压城城欲摧之际,一道纤细的阳光瓦解了灾难那样。当那段抒情的弦乐尖锐地升起,轻轻地飘向空旷之中时,人们也就获得了高潮之上的高潮。肖斯塔科维奇证明了小段的抒情有能力覆盖任何巨大的旋律和任何激昂的节奏。下面要讨论的是霍桑的证明,在跌宕恢宏的篇章后面,短暂和安详的叙述将会出现什么,纳撒尼尔·霍桑证明了文学的叙述也同样如此。
几乎没有人不认为纳撒尼尔·霍桑在《红字》里创造了一段罗曼史,事实上也正是因为《红字》的出版,使纳撒尼尔摇身一变成为了浪漫主义作家,也让他找到了与爱伦·坡分道扬镳的机会,在此之前这两个人都在阴暗的屋子里编写着灵魂崩溃的故事。当然,《红字》不是一部甜蜜的和充满了幻想的罗曼史,而是忍受和忠诚的历史。用D.H.劳伦斯的话说,这是“一个实实在在的人间故事,却内含着地狱般的意义”。
海丝特·白兰和年轻的牧师丁梅斯代尔,他们的故事就像是亚当和夏娃的故事,在勾引和上钩之后,或者说是在瞬间的相爱之后,就有了人类起源的神话,同时也有了罪恶的神话。出于同样的理由,《红字》的故事里有了珠儿,一个精灵般的女孩,她成为了两个人短暂的幸福和长时期痛苦的根源。故事开始时已经是木已成舟,在清教盛行的新英格兰地区,海丝特·白兰没有丈夫存在的怀孕,使她进入了监狱,她在狱中生下了珠儿。这一天早晨——霍桑的叙述开始了——监狱外的市场上挤满了人,等待着海丝特·白兰——这个教区的败类和荡妇如何从监狱里走出来,人们议论纷纷,海丝特·白兰从此将在胸口戴上一个红色的A字,这是英文里“通奸”的第一个字母,她将在耻辱和罪恶中度过一生。然后,“身材修长,容姿完整优美到堂皇程度”的海丝特,怀抱着只有三个月的珠儿光彩照人地走出了监狱,全然不是“会在灾难的云雾里黯然失色的人”,而胸口的红字是“精美的红布制成的,四周有金线织成的细工刺绣和奇巧花样”。手握警棍的狱吏将海丝特带到了市场西侧的绞刑台,他要海丝特站在上面展览她的红字,直到午后一点钟为止。人们辱骂她,逼她说出谁是孩子的父亲,甚至让孩子真正的父亲——受人爱戴的丁梅斯代尔牧师上前劝说她说出真话来,她仍然回答:“我不愿意说。”然后她面色变成死灰,因为她看着自己深爱的人,她说:“我的孩子必要寻求一个天上的父亲;她永远也不会认识一个世上的父亲!”
这只是忍受的开始,在此后两百多页叙述的岁月里,海丝特经历着越来越残忍的自我折磨,而海丝特耻辱的同谋丁梅斯代尔,这位深怀宗教热情又极善辞令的年轻牧师也同样如此。在两个人的中间,纳撒尼尔·霍桑将罗格·齐灵渥斯插了进去,这位精通炼金术和医术的老人是海丝特真正的丈夫,他在失踪之后又突然回来了。霍桑的叙述使罗格·齐灵渥斯精通的似乎是心术,而不是炼金术。罗格·齐灵渥斯十分轻松地制服了海丝特,让海丝特发誓绝不泄露出他的真实身份。然后罗格·齐灵渥斯不断地去刺探丁梅斯代尔越来越脆弱的内心,折磨他,使他奄奄一息。从海丝特怀抱珠儿第一次走上绞刑台以后,霍桑的叙述开始了奇妙的内心历程,他让海丝特忍受的折磨和丁梅斯代尔忍受的折磨逐渐接近,最后重叠到了一起。霍桑的叙述和肖斯塔科维奇那个侵略插部的叙述,或者和拉威尔的《波莱罗》不谋而合,它们都是一个很长的、没有对比的、逐渐增强的叙述。这是纳撒尼尔才华横溢的美好时光,他的叙述就像沉思中的形象,宁静和温柔,然而在这形象内部的动脉里,鲜血正在不断地冲击着心脏。如同肖斯塔科维奇的侵略插部和拉威尔的《波莱罗》都只有一个高潮,霍桑长达二百多页的《红字》也只有一个高潮,这似乎是所有渐强方式完成的叙述作品的命运,逐步增强的叙述就像是向上的山坡,一寸一寸的连接使它抵达顶峰。
《红字》的顶峰是在第二十三章,这一章的标题是“红字的显露”。事实上,叙述的高潮在第二十一章“新英格兰的节日”就开始了。在这里,纳撒尼尔·霍桑开始显示他驾驭大场面时从容不迫的才能。这一天,新来的州长将要上任,盛大的仪式成为了新英格兰地区的节日,霍桑让海丝特带着珠儿来到了市场,然后他的笔开始了不断的延伸,将市场上欢乐的气氛和杂乱的人群交叉起来,人们的服装显示了他们来自不同的地方,使市场的欢乐显得色彩斑驳。在此背景下,霍桑让海丝特的内心洋溢着隐秘的欢乐,她看到了自己胸前的红字,她的神情里流露出了高傲,她在心里对所有的人说:“你们最后再看一次这个红字和佩戴红字的人吧!”因为她悄悄地在明天起航的路上预订了铺位,给自己和珠儿,也给年轻的牧师丁梅斯代尔。这位内心纯洁的人已经被阴暗的罗格·齐灵渥斯折磨得“又憔悴又孱弱”,海丝特感到他的生命似乎所剩无几了,于是她违背了自己的诺言,告诉他和他同住一个屋檐下的老医生是什么人。然后,害怕和绝望的牧师在海丝特爱的力量感召下,终于有了逃离这个殖民地和彻底摆脱罗格·齐灵渥斯的勇气,他们想到了“海上广大的途径”,他们就是这样而来,明天他们也将这样离去,回到他们的故乡英格兰,或者去法国和德国,还有“令人愉快的意大利”,去开始他们真正的生活。
在市场上人群盲目的欢乐里,海丝特的欢乐才是真正的欢乐,纳撒尼尔·霍桑的叙述让其脱颖而出,犹如一个胜利的钢琴主题凌驾于众多的协奏之上。可是一个不和谐的音符出现了,海丝特看到那位衣服上佩戴着各色丝带的船长正和罗格·齐灵渥斯亲密地交谈,交谈结束之后船长走到了海丝特面前,告诉她罗格·齐灵渥斯也在船上预订了铺位。“海丝特虽然心里非常惊慌,却露出一种镇静的态度”,随后她看到她的丈夫站在远处向她微笑,这位阴险的医生“越过了那广大嘈杂的广场,透过人群的谈笑、各种思想、心情和兴致——把一种秘密的、可怕的用意传送过来。”
这时候,霍桑的叙述进入了第二十二章——“游行”。协奏曲轰然奏响,淹没了属于海丝特的钢琴主题。市场上欢声四起,在邻近的街道上,走来了军乐队和知事们与市民们的队伍,丁梅斯代尔牧师走在护卫队的后面,走在最为显赫的人中间,这一天他神采飞扬,“从来没有见过他步伐态度像现在随着队伍行进时那么有精神”,他们走向会议厅,年轻的牧师将要宣读一篇选举说教。海丝特看着他从自己前面走过。
霍桑的叙述出现了不安,不安的主题缠绕着海丝特,另一个阴暗的人物西宾斯夫人,这个丑陋的老妇人开始了对海丝特精神的压迫,她虽然不是罗格·齐灵渥斯的同谋,可是她一样给予了海丝特惊慌的折磨。在西宾斯夫人尖锐的大笑里,不安的叙述消散了。
欢乐又开始了,显赫的人已经走进了教堂,市民们也挤满了大堂,神圣的丁梅斯代尔牧师演讲的声音响了起来,“一种不可抵抗的情感”使海丝特靠近过去,可是到处站满了人,她只能在绞刑台旁得到自己的位置。牧师的声音“像音乐一般,传达出热情和激动,传达出激昂或温柔的情绪”,海丝特“那么热烈地倾听着”,“她捉到了那低低的音调,宛若向下沉落准备静息的风声一样;接着,当那声调逐渐增加甜蜜和力量上升起来的时候,她也随着上升,一直到那音量用一种严肃宏伟的氛围将她全身包裹住。”
霍桑将叙述的欢乐变成了叙述的神圣,一切都寂静了下来,只有丁梅斯代尔的声音雄辩地回响着,使所有的倾听者都感到“灵魂像浮在汹涌的海浪上一般升腾着”。这位遭受了七年的内心折磨,正在奄奄一息的年轻牧师,此刻仿佛将毕生的精力凝聚了起来,他开始经历起回光返照的短暂时光。而在他对面不远处的绞刑台旁,在这寂静的时刻,在牧师神圣的说教笼罩下的市场上,海丝特再次听到那个不谐和的音符,使叙述的神圣被迫中断。那位一无所知的船长,再一次成为罗格·齐灵渥斯阴谋的传达者,而且他是通过另一位无知者珠儿完成了传达。海丝特“心里发生一种可怕的苦恼”,七年的痛苦、折磨和煎熬所换来的唯一希望,那个属于明天“海上广大的途径”的希望,正在可怕地消失,罗格·齐灵渥斯的罪恶将会永久占有他们。此刻沉浸在自己神圣声音中的丁梅斯代尔,对此一无所知。
然后,叙述中高潮的章节“红字的显露”来到了。丁梅斯代尔的声音终于停止了,叙述恢复了欢乐的协奏,“街道和市场上,四面八方都有人在赞美牧师。他的听众,每一个人都要把自己认为强过于旁人的见解尽情吐露之后,才得安静。他们一致保证,从来没有过一个演讲的人像他今天这样,有过如此明智、如此崇高、如此神圣的精神。”接下去,在音乐的鸣响和护卫队整齐的步伐里,丁梅斯代尔和州长、知事,还有一切有地位有名望的人,从教堂里走了出来,走向市政厅盛大的晚宴。霍桑此刻的叙述成为了华彩的段落,他似乎忘记了叙述中原有的节拍,开始了尽情的渲染,让“狂风的呼啸,霹雳的雷鸣,海洋的怒吼”这些奢侈的比喻接踵而来,随后又让“新英格兰的土地上”这样的句式排比着出现,于是欢乐的气氛在市场上茁壮成长和生生不息。
随即一个不安的乐句轻轻出现了,人们看到牧师的脸上有“一种死灰颜色,几乎不像是一个活人的面孔”,牧师踉跄地走着,随时都会倒地似的。尽管如此,这位“智力和情感退潮后”的牧师,仍然颤抖着断然推开老牧师威尔逊的搀扶,他脸上流露出的神色使新任的州长深感不安,使他不敢上前去扶持。这个“肉体衰弱”的不安乐句缓慢地前行着,来到了绞刑台前,海丝特和珠儿的出现使它立刻激昂了起来。丁梅斯代尔向她们伸出了双臂,轻声叫出她们的名字,他的脸上出现了“温柔和奇异的胜利表情”,他刚才推开老牧师威尔逊的颤抖的手,此刻向海丝特发出了救援的呼叫。海丝特“像被不可避免的命运推动着”走向了年轻的牧师,“伸出胳膊来搀扶他,走近刑台,踏上阶梯”。
就在这高高的刑台上,霍桑的叙述走到了高潮。在死一般的寂静里,属于丁梅斯代尔的乐句尖锐地刺向了空中。他说:“感谢领我到此地来的上帝!”然后他悄悄对海丝特说,“这不是更好吗。”纳撒尼尔·霍桑的叙述让丁梅斯代尔做出了勇敢的选择,不是通过“海上广大的途径”逃走,而是站到了七年前海丝特怀抱珠儿最初忍受耻辱的刑台之上,七年来他在自己的内心里遭受着同样的耻辱,现在他要释放它们,于是火山爆发了。他让市场上目瞪口呆的人们明白,七年前他们在这里逼迫海丝特说出的那个人就是他。此刻,丁梅斯代尔的乐句已经没有了不安,它变得异常地强大和尖锐,将属于市场上人群的协奏彻底驱赶,以王者的姿态孤独地回旋着。丁梅斯代尔用他生命里最后的声音告诉人们:海丝特胸前的红字只是他自己胸口红字的一个影子。接着,“他痉挛地用着力,扯开了他胸前的牧师的饰带。”让人们看清楚了,在他胸口的皮肉上烙着一个红色的A字。随后他倒了下去。叙述的高潮来到了顶峰,一切事物都被推到了极端,一切情感也都开始走投无路。
这时候,纳撒尼尔·霍桑显示出了和肖斯塔科维奇同样的体验,如同“侵略插部”中小段的抒情覆盖了巨大的旋律,建立了高潮之上的高潮那样,霍桑在此后的叙述突然显得极其安详。他让海丝特俯下面孔,靠近丁梅斯代尔的脸,在年轻的牧师告别人世之际,完成了他们最后的语言。海丝特和丁梅斯代尔最后的对话是如此感人,里面没有痛苦,没有悲伤,也没有怨恨,只有短暂的琴声如诉般的安详。因为就在刚才的高潮段落叙述里,《红字》中所有的痛苦、悲伤和怨恨都得到了凝聚,已经成为了强大的压迫,压迫着霍桑全部的叙述。可是纳撒尼尔让叙述继续前进,因为还有着难以言传的温柔没有表达,这样的温柔紧接着刚才的激昂,同时也覆盖了刚才的激昂。在这安详和温柔的小小段落里,霍桑让前面二百多页逐渐聚集起来的情感,那些使叙述已经不堪重负的巨大情感,在瞬间获得了释放。这就是纳撒尼尔·霍桑,也是肖斯塔科维奇为什么要用一个短暂的抒情段落来结束强大的高潮段落,因为他们需要获得拯救,需要在越来越沉重或者越来越激烈的叙述里得到解脱。同时,这高潮之上的高潮,也是对整个叙述的酬谢,就像死对生的酬谢。
一九九九年一月二十六日
隔壁的女人-向田邦子
========================
隔壁的女人
隔壁的女人-[[向田邦子]]
========================
缝纫机不说谎。
它虽是机器,却比踩着缝纫机踏板的女人更诚实,倾诉着女人的心事。
如往常一样,隔壁又传来了那声音。幸子无意偷听,本该加倍用力地踩动缝纫机踏板,缝纫机却只是故作配合,发出啪嗒啪嗒的声音。
像是被看透了内心,幸子不甘示弱一通猛踩。反正是借来的缝纫机,踩坏了也不心疼。她接的活是做女罩衫,一件一千二百日元。丈夫每个月都会拿回工资,孩子还没生,幸子本不必为柴米油盐操心,但整天游手好闲说不过去,她也想多存点钱。幸子一边想着,一边留意身后墙壁那边的动静。
公寓是两室户的逼仄户型。客厅兼餐厅只有六个铺席大小,脚踩缝纫机的幸子后背抵着白墙,墙上挂着西洋名画,不用说是复制的。声音总是从这堵墙背后传来。
忽然传来一阵激烈的声响,好像是玻璃器皿撞到墙上的声音,随后传来了男女争吵的声音。幸子的缝纫机不由得慢了下来。
“别开玩笑了!”
“‘瞅准机会’是什么意思?”
“说谁呢?”
“信不信我杀了他!”
这是男人的声音。
“再乱来就滚!”
“没有第三个人!”
“干什么?放开我!”
女人的声音也越来越激昂。
两人似乎纠缠不下,女人的声音柔和了下来:
“当心玻璃!”
幸子从缝纫机边站起身,耳朵贴住墙壁。
“喂,当心玻璃,危险!”
“没关系。”
“早说了危险啦!”
“峰子……”
“阿信……”
峰子是住在隔壁房间的酒吧妈妈桑的名字,阿信是最近开始出入隔壁的青年男子,看起来像是工地的工头。他嗓门粗,沙哑的声音三天两头从隔壁传来,幸子一听就知道。
两人紊乱的鼻息变成了喘息,不久墙壁开始微微摇动。幸子的呼吸也随隔壁的喘息变得紊乱,令她感到莫名其妙。身体有点发热,不过这不是隔壁的影响,眼看就是夏天了。
不光如此,扭成奇怪的姿势,贴在墙壁上偷听隔壁动静的自己的身体,映照在缝纫机旁的穿衣镜里,令幸子自己也大吃一惊。
幸子赶紧站直身体,把墙壁上的油画扶正。也许油画本来就是正的,这是她的习惯动作。
幸子抱着购物筐打开门,脚边赫然躺着一个装着垃圾的塑料袋。大概是隔壁的妈妈桑放在自己门前,被风吹了过来。幸子用指尖拎起垃圾袋,扔回隔壁门前。同样是垃圾,隔壁的垃圾似乎更污秽。
绿意所剩无几,街道上还能闻到绿叶的气息。比起沉闷的绿叶味道,幸子这时候更渴望闻到花香。记得去年这个时候,出了公寓就能闻到桂花香。曾几何时,周围带庭院的住户和空地一年比一年少,都变成了火柴盒般堆积起来的公寓。
幸子的公寓从西武池袋线大泉学园站出来步行五分钟就到。再偏一点,到三多摩一带,能找到更像样的住宅区,但丈夫集太郎说,上班时间超过一小时会很麻烦,不愿意搬,所以至今他们仍交着不菲的租金。丈夫所说的“麻烦”究竟是指工作上会拖后腿,还是晚上出去交际不方便,幸子不太清楚。眼下,夫妻两人住在小公寓里,每个月的赤字由幸子的副业来填,倒也并无大碍。
幸子瞟了一眼肉铺,钻进鱼铺,买了一碟鲷鱼杂碎。鱼铺里并排放着两盘鲷鱼杂碎,她认真比较之后,选了一盘,请鱼铺老板包好。碰到年纪相仿的主妇带着两岁半上下的男孩,她摸摸男孩的头,笑着打招呼。如果当时生下来,应该也差不多这么大了。那时她准备等到年底领了奖金再辞职,办公室的空调太冷,最后竟流产了。她觉得,那次一定是个男孩,流产后好长一段时间,一看到男婴儿就心中作痛。
娘家的二老也说,三十岁前一定要生头胎。于是幸子以身体不好为借口辞去了工作,过着“等待怀孕”的日子。
幸子目不斜视地走过书店和唱片店,进了蔬菜铺。她很少买书或是听唱片,丈夫集太郎也一样。
幸子拈起茼蒿和香菇,打开红色钱包的金属卡扣,取出折了两折的千元纸币。蔬菜铺墙上的镜子蒙着灰尘,映照出幸子面无表情的脸。
也许是没有化妆,幸子才二十八岁,这张脸已经丧失了活力。脸上明明白白写着幸子的生活:丈夫并不丰厚的收入,日复一日煮饭烧菜,洗衣扫地,还有家庭副业。幸子自己时不时也会深深叹一口气。
说不上幸福,也说不上不幸。只是,此刻纸币上圣德太子的脸,在她看来十分刺眼。
减价特卖的厕纸,幸子买了一大堆。拎着厕纸爬上公寓的楼梯,隔壁的门开了,正好碰见那男人离开。
刚和峰子柔声告别,名叫阿信的男子转过头就沉下脸,跟幸子擦肩而过。
而那个峰子,正半开着门,目送男人离去。她的头发被汗水濡湿,贴在脸上。不化妆的时候,浅棕色的脸像半个病人,一旦打扮起来,就判若两人。她比幸子年长七八岁,慵懒的神态,甚至是眼角的皱纹,都比幸子看起来更媚态天成。
幸子没有打招呼,回到自己家里,继续自己的零工。
想找个人聊天的时候,缝纫机就是幸子的伙伴。她会对着缝纫机发火,也会对着缝纫机碎碎念。平静下来,她还会趴在缝纫机上打个盹。
半梦半醒之间,幸子又听见隔壁女人的声音。
“谷川岳在哪里?”
“在群马县的上越国境。”
男人的声音回答道。
“那就是要从上野乘上越线?”
“上野、尾久、赤羽、浦和、大宫、宫原、上尾、桶川、北本、鸿巢、吹上。”
男人的声音低沉浑厚。他报着一个个站名,仿佛在朗诵一首诗。这不是梦。声音是从墙壁后面,隔壁的房间里传来的。
“行田、熊谷、笼原、深谷、冈部、本庄、神保原。”
男人的声音停下来。
不是平常那个男人,不是那个被唤作阿信的工头的粗嗓门,这个声音更浑厚。幸子仿佛被这个声音引诱,站起身来。
“新町、仓贺野、高崎、井野、新前桥、群马总社、八木原、涩川、敷岛、津久田、岩本、沼田、后闲、上牧、水上、汤桧曾、土合。”
男人念完后,长长地出了一口气。
女人发出鸽子般的咯咯低笑,靠近男人。
“记的还真清楚啊。”
“去爬谷川,乘快车太可惜了,要在上野乘慢车,一点点靠近那座山。”
幸子的身体离墙壁越来越近。
“想到山越来越近,就算爬过多少遍,还是会像第一次那样心跳。在土合站下车,抬头看见山的时候,自己都觉得脸红心跳。”
“真像个小男孩。”
峰子的声音里也听得出雀跃。
“那山很美吗?”
“山都很美。不管哪座山,从远处看都一样,但自己一步一步爬上去,却大不相同,还有远处山脚下平缓的原野。”
“好痒……”
“意想不到的地方藏着洼地。”
“不是说了嘛,好痒!”
“有光的地方,光照不到的地方,干燥的地方,潮湿的地方,都像是有自己的呼吸。”
幸子的手,不由得轻抚过自己贴着墙壁侧坐的身体。她的裙子翻卷起来,露出光腿。从窗户照进来的夕阳,在她的身体上描绘出光与影的地图。
男人的声音含混又温柔。
“早上起来,远处的山,看起来十分神圣。”
“白天呢?”
女人的鼻音更重了。
“看起来很雄伟。”
“晚上看呢?”
“凄厉,让人心生恐惧。”
女人轻笑起来。
墙壁开始轻轻晃动。
“再念一次刚才的站名吧,拜托了。”
“上野、尾久、赤羽、浦和、大宫、宫原、上尾、桶川、北本、鸿巢、吹上、行田、熊谷、笼原、深谷。”
幸子的耳垂发热,呼吸困难,她甚至感觉有几分晕眩。
“冈部、本庄、神保原、新町、仓贺野、高崎、井野、新前桥、群马总社、八木原、涩川、敷岛、津久田、岩本、沼田、后闲、上牧、水上、汤桧曾、土合。”
幸子紧闭双眼。眼睑内侧一片绯红,她正向着山顶攀登。不久,终于爬上了顶峰,她全身脱力,像是死了一样,不能动弹。
夕照渐渐被夜色吞噬,公寓下面传来孩子们的喧闹声,幸子仍旧靠在墙壁上。缝纫机上放着刚开始做的女罩衫,五点的钟声敲响了。
开门的声音让幸子回过神来。
正做着浅梦的幸子站起身来,往走廊张望。
披着睡袍的峰子站在防火梯上,举起一只手,男人正准备离开。
那是个穿着皱巴巴雨衣的年轻男子。只能看见他的背影,看不见他的脸。他举起一只手挥动两三下,似是在回应峰子,却并不回头。那只手修长秀美,不像是从事体力劳动的手。
很明显,这是另一个男人。峰子久久伫立,目送男人的背影。也许是夜色的原因,比起送别阿信的时候,此刻的峰子看起来更妖艳动人。“那个,我帮你垫付的煤气费……”
幸子说不出口,默默站住,她觉得自己看上去寒酸无比。“输了”这两个字,浮现在她脑海。
“家里的水最好喝了。”
丈夫集太郎一回到家,一定会先喝一杯水。
他的意思,应该是指,比起公司里的水,比起麻将房的水,比起一家接一家喝过的酒吧,家里的水更好喝。“可都是东京都水管局的水”,幸子曾经不无讽刺地说。不过今天晚上幸子心不在焉,根本没有搭腔。
“我不是说过了嘛,我回来晚了,你就先吃。”
集太郎看着没有动过的晚餐,抱怨说。
“我可不是自己想,硬是被课长拉去的。”
他做出砌麻将牌的手势。
“一个人没法溜出来,会被说三味线(1)嘛。”
“三味线,这个?”
幸子模仿着弹三味线的手势,丈夫惊讶于她的无知。
“真是什么都不懂。一边打麻将,肯定一边说说闲话啰。”
“啊,麻将啊。”
“这种时候,才能听见真心话。上班族可不光是朝九晚五。”
“又去麻将房了?”
“总不能带回家吧。薪水低,老婆都要搞副业。”
“我可不是因为你薪水低才做副业的,闲着也是闲着。”
“那我回来了该收起来吧。”
平时幸子都会把自己正在缝制的罩衫收拾整齐,今天做了一半的罩衫却还摊开铺在缝纫机上。幸子开始收拾。
“好了,别当着我的面下功夫。我就是说说。”
集太郎打着哈欠换上睡衣,幸子忍不住想跟他分享。
“隔壁那个人。”
“隔壁?啊,酒吧的妈妈桑。”
“那个人,了不得哦。”
幸子竖起大拇指(2)。
“有两个相好,一天两个。”
“闭嘴吧。”
集太郎也竖起大拇指,一脸嫌恶地说:
“女人做这种手势真难看。这可不是良家女子做的,下流。”
“那应该怎么样?”
“嘴巴说说就行了。”
“要说‘有男人’吗?也挺下流。”
“有男人怎么了?”
“有两个。”
“大惊小怪。良家妇女做出这种事是天理难容,那种做生意的女人,有两三个男人有什么稀奇。”
“话是这么说。白天本来是一直来的那个工头,三点多我回家来踩缝纫机,又听见了别人的声音,不是原来那个人。”
“你一天到晚在干什么?”
幸子有些讪讪,小声说:
“声音钻到我耳朵里了嘛。”
“别去招惹这些人。”
集太郎又打了一个大哈欠,钻进被窝。幸子调暗了灯,但并不想马上去厨房。
“你爬过谷川岳吗?”
“谷川岳?”
集太郎又打了一个哈欠。
“没有。为什么忽然这么问?”
“从上野到谷川的车站,能数出来吗?”
“我可是工作了八小时,又陪人打了麻将才回来的。没空陪你猜谜。”
集太郎一脸不耐烦,翻了个身,不一会儿就响起了鼾声。
第二天,幸子去邮寄做好的女罩衫,回家的路上,罕见地买了一张唱片。她想选一张庄严的,于是买了巴赫的《弥撒曲》。
一回到公寓,她马上把唱片放上,声音开得大大的。她一边换着衣服一边留意墙壁那边,凑近墙壁侧耳倾听,但什么声音也没有。
“好傻。”
她笑出声来,敲了自己的头一记。这时,有人敲门,管理员站在门外。是个看上去七十岁上下的女人,劈头就问:
“太太,有空吗?
“有空的话,可以往池袋走一趟吗?隔壁的妈妈桑,出门的时候在信箱那里跟人打招呼,闲聊了一会儿,把酒吧的钥匙落下了。她手上有些事,一时回不来,能帮忙送过去吗?
“我要是有空就自己去了。也想去看看那边到底什么样儿呢。要是那地方太寒酸,怕是我这租金也收不上来了。太太,去帮我好好看看哦。”
幸子接过地图和钥匙串,出发了。
酒吧“谜”就在池袋车站前,酒吧一条街的地下。
下了楼梯,却见本该站在店门口等待的峰子笑着从店里迎接出来。
“真对不起,已经解决了。”
今天休息的酒保来了,也就不用钥匙了。打电话回去,幸子已经出来了。峰子再三道谢,给了幸子出租车钱,还邀请她坐下喝一杯。
这家酒吧看起来不算高级,进十个客人就坐满了。反应迟钝的酒保正在削旱芹的皮,客人只有一个。坐在吧台一头的一个年轻男人,手上玩着鲁比克魔方。
幸子要了一杯咖啡,峰子已经调好了酒兑水,笑着说:
“你能喝吧?”
“谢谢。”
幸子彬彬有礼地低头致谢,她觉得自己跟这个酒吧格格不入。吧台那头的男人看了幸子一眼。
妆容精致的女人和素面朝天的女人隔着吧台相对而坐。在修长的红指甲映衬之下,幸子剪得短短的秃指甲看上去就是一双贫穷操劳的手。幸子一口气灌下酒,呛得她咳嗽起来,峰子忙帮她拍背。
幸子一紧张就会喉咙不舒服,会呛到自己。
“我一紧张就会搞砸事情。”
考试的时候,她会肚子疼;偏偏在拍相亲照片那天,鼻头上起了脓包。幸子像是打开了话匣子。
“去年也是,准备去巴黎——和我一起做副业的朋友,平时都忙忙碌碌的,偶尔也想奢侈一下,护照都准备好了,却得了盲肠炎。”
“没去成?”
“因为病了嘛。”
峰子涂着幽蓝眼影的眼皮底下,黑色眼睛马上善解人意地笑了。
“我也得过盲肠炎。”
“最近?”
“以前。”
幸子高兴起来。
“我割了这么多。”
她用手比出四厘米长的伤口。
“我呀。”
峰子也模仿幸子,她比画的伤口要长两厘米左右。
“哇,这么长!”
“乡下的医生嘛。老早以前的事了。”
“那,伤口是缝合的?”
“你是钉起来的吗?”
峰子说着,脸色忽然大变。门口站着一个客人,是那个男人,是那位常来的工头阿信。
“欢迎光临。”
峰子忽然换上职业化的声音,从吧台底下钻出来。她对酒保说声“帮我照看一下”,就偎依在阿信身上走出门外。
幸子赶紧喝酒。看今天早上的情形,晚上集太郎也会晚回家,不过晚饭还是要准备好。小菜做什么好呢?
吧台那头的年轻男人,正在拨桃红色的电话机。
“是武智先生家吗?”
幸子心里咯噔一跳。
“我是朋文堂的麻田。就是定做画框的那个朋文堂……是,我是麻田。关于交货日期,可能要晚两三天。”
就是那个声音。
“不,那个没问题。八十号和六十号,静物那两幅,还有四十号玫瑰。”
接下来,双方商量起了时间。
那声音在幸子听来,就像是音乐。
“新町、仓贺野、高崎、井野、新前桥、群马总社。”幸子还记得当时的声音,呼吸变得困难起来。一口气喝干了酒兑水,“唰”地站起身来,男人正好打完了电话。似乎感觉幸子灼灼的眼神盯着自己,男子也回看幸子。只见他三十岁出头,面孔端正,一双漆黑的眼睛。幸子走出酒吧。
从地下室往地面走,在楼梯平台上,峰子还和阿信纠缠在一起。阿信把峰子的身体抵在墙壁上。
“啊——啊——”
他发出带着哭腔的怪声,峰子紧绷着脸。阿信右手那里有个什么东西在反光,幸子停下脚步。峰子察觉到幸子在旁边,温柔地抱住阿信。
“啊,太太,准备回去了?”
峰子跟幸子打着招呼。
峰子很从容。阿信的脸也和平时在走廊上看见的一样,尴尬地紧绷着,幸子松了口气。
“多谢款待。”
幸子回答道。从抱住的两个人身上移开视线,走上台阶。
走出地面,天色已晚,幸子忽然觉得一丝狼狈。集太郎从没用如此热切的眼神看过自己,也从没用那样的声音引诱过自己。现在,集太郎肯定正在打麻将呢。想到这一点,幸子不由得一肚子气,感觉霓虹灯都在嘲笑自己。
和平时一样,集太郎十二点过后才回家。一回家就喝起了水,不停打着哈欠。
“你这哈欠越打越大了。”
“我要是去别的地方打哈欠,那才是大问题。”
“所谓结婚,所谓家庭,就是得到一个大口打呵欠的地方吗?”
丈夫的回答是一个更大的哈欠。
丈夫开始换睡衣,幸子站在厨房里,转过背去。她把水龙头开得大大的,杯子里的水都溢出来了,幸子还是默默站着。有些女人,过得丰富多彩,就像这满溢的杯子,也有些女人,都已经干瘪了,她想。“上野、尾久、赤羽、浦和、大宫、宫原、上尾、桶川”,声音久久回荡在她耳边。
夜晚就像一场谎言,又到了早上。
晨报和早上的鲜牛奶赶走了混浊的空气,男男女女又开始勤勤恳恳地忙碌起来。幸子送走了集太郎,开始踩起缝纫机。空气中似乎有煤气的味道,大概是她的错觉。
幸子忽然停下手,墙壁背后有什么动静。有女人呻吟的声音,还有男人的低吼。幸子已经像壁虎一样趴在墙壁上,她看到了镜子里自己的身影。
“啊,真讨厌。”
一大早,真令人讨厌。她想摆脱坏心情,放上了唱片。她把巴赫调得很大声。调整坐姿,又开始踩起缝纫机来。不一会儿,她还是不放心,又把音量调小。女人的呻吟声又传入耳中,她再把音量调大,又闻到了煤气味儿。
幸子走上阳台,探出身子往隔壁看。
蕾丝窗帘摇曳。窗帘里面,女人的手在空中乱抓,想要打开玻璃门,她的手上能看见凸出的青筋。
幸子翻到隔壁阳台上。玻璃门对面,峰子已经倒下了。她抓起阳台上的花盆,砸碎玻璃门,煤气的味道扑鼻而来。
“喂,有人吗?快叫管理员。打110!”
幸子一边大叫,一边把手伸进玻璃门的破洞中,打开门锁。越慌越乱,门怎么也打不开。
“有人吗?救命!”
她一边呼救,一边钻进门里。一个裸体男子从双人床上滑落下来,一动不动,是阿信。幸子拼命把失去意识的峰子拽出去,剧烈咳嗽起来。她一只手徒劳地想扇走煤气,一边把峰子掀起的睡袍拉好,然后跳到阳台上,大叫:“快打110!”
幸子迷迷糊糊地看着两个担架被搬进了急救车。
“听说是殉情。”
“死了吗?”
“好像还有气儿。”
公寓的居民在窃窃私语,幸子这才注意到,自己的手腕被玻璃割破了,流出了血。
“虽说是邻居,也才搬过来三个月。不是说我家,是她家。”
幸子生来第一次对着电视的麦克风讲话。
“不是很熟。也就是见面打声招呼,聊聊今天垃圾车来晚了之类——啊,已经开始拍了,糟糕,这副样子。”
偏偏今天,她头发上绷着夹子,衣服邋邋遢遢。
“你闯进去的时候心里怎么想的?”
“当时已经来不及想了,根本没来得及想。”
不知为什么,幸子有点喘不过气来。
“这种事可是生平第一次遇到。每天都过得很普通,自己周围本来以为绝对不会发生自杀或者殉情这类事呢。居然发生了!完全没想到,就像脸上被打了一巴掌,这种事居然会发生在我家隔壁!倒也不是不可思议。不知是西鹤还是谁不是写过《好色五人女》,里面的酒桶店阿桑,啊,是阿千。还有,叫什么兵卫的历屋,用现在的话说就是日历店的老板娘。啊,裱糊工阿千,阿桑。哎呀,我都搞混了。(3)”
幸子哧哧笑着,说个不停。
“出轨啊,殉情啊,在那些孤注一掷的人旁边,住着我这样的普通女人,真是吓人一跳。像我这样的人。啊,你的纽扣,有点松了。我在做副业,给衣服缝纽扣,有职业病了。瞧我!”
大概是太兴奋了,幸子莫名其妙地笑了起来。
“我先生,是个上班族,很普通的。哎呀,还在拍啊。”
幸子手腕上缠着绷带,试图遮住摄影机镜头,采访结束了。
打开冰箱,幸子用手指拈起剩菜吃,这时电话响了。
“别丢人现眼了!”
劈头盖脸一顿怒骂,是丈夫集太郎。
“电视,电视上的!”
“你看电视了?”
幸子的声音都变调了。
“人都死了,看你还在那儿扬扬得意大放厥词!有你这么幸灾乐祸的傻瓜吗?”
“死倒是没有死,救活了。是我救了他们。”
“就算救活了,跟死了也没区别!又不是什么喜事,怎么能得意扬扬地笑着在电视上宣传呢?”
“我可没笑。”
“你笑了,兴高采烈,滔滔不绝。真不检点。”
“喂,喂。”
“还有,不懂的事别瞎扯。”
“什么?”
“西鹤的五人女什么的,我都听出一身冷汗了。连阿桑和阿千都分不清,还扯什么日历店。”
“高中可是考过的。”
“要说也得先读过啊!”
“这可不是一般场合。我也有点慌,搞错了。”
“就算昏了头,也不用提到自己老公吧!”
“我说什么了?”
“普通的上班族。虽说是实话,但这可不是能在电视上大说特说的事!”
“人家问了,我就说说。”
“我公司那些人也看了,我可成了个笑话!”
“又不是我想出现在电视上的。管理员在医院,记者咚咚地敲着门,也不打招呼就把麦克风伸过来。”
“那你就别待在家里!”
“你叫我去哪里嘛!”
“你自己不会想吗?”
丈夫的声音震得她鼓膜生疼,电话挂断了。
都没问我有没有受伤,幸子想。出了门,好像电话又响了,幸子并没有回头。
幸子在车站前的书店,抽出西鹤的《好色五人女》文库本。走进旁边的咖啡店,点了一杯咖啡。翻开卷二的“桶匠多情物语”。
“为爱哭泣淘井人,此身有限,情路无断,手括棺椁悟无常,渡世锥锯镇日忙……”
她端起咖啡杯,手仍在颤抖,往后翻到现代语翻译。
“人的寿命有限,恋爱之路却无断绝。”
幸子的目光追随着字迹,心里却想着那个声音,好像是“朋文堂的麻田”。回过神来,她已经站起身,翻看着电话黄页,在绘画材料匾额那一页找到了朋文堂。
“您好,这里是朋文堂。”
转动拨号盘,传来了那人的声音。幸子挂断电话,记下地址。她的手自作主张,似乎已经不听使唤。
到朋文堂要再坐两站车。
朋文堂店面宽绰,除了麻田,还有两三个店员当班。麻田一边吸着香烟,一边在和女店员调笑,看来他还不知道峰子的事件。
“那个……”
幸子支支吾吾,小声说:
“那个人的事,你还不知道吗?”
“那个人?”
“情杀,受了伤,糟透了。”
幸子和麻田走到后面的仓库说话。坏掉的画框杂乱无章地堆积,散发着骨胶的气味。
“性命算是保住了。吸进了一些煤气,听说伤势倒是不重。”
“是吗?”
麻田没有问是谁干的,看来他心里也清楚。麻田问候了幸子手上受的伤,然后问:“你来告诉我,是她叫你来的吗?”
“不是,你在她店里打电话,提到过店里的名字。”
原来如此,麻田看上去接受了这个解释。
“但是,你怎么会认识我——啊,对了,公寓,你住在旁边,走进走出看见了——”
他又像想起了什么。
“不对,那间公寓,我只去过一次,我都没跟你打过照面。”
“我认识你的声音。听到你打电话,啊,对了,就是那个声音。‘上野、尾九、赤羽、浦和、大宫。’”
幸子不由得脱口而出,她马上意识到了自己的失言。
“啊,对不起,公寓的墙太薄了。无意之间,打鼾啊,叹气啊,都一清二楚。”
欲盖弥彰。
被偷听的男人默默转过身,抚摩着坏掉的画框。幸子低下头,小步跑出店里。
幸子很生气,生自己的气。
并没有人拜托自己,自己却特意找出麻田的地址,跑去找他。暗地里说不出口的期待,像越胀越大的气球,“啪”地炸裂以后,剩下的只有惨不忍睹的失望。她闻到了自己身上自我嫌恶的气息,羞耻令她抬不起头来。
背后有脚步声追上来。脚步声跟上她后,耳边传来麻田的声音。
“请陪陪我吧。”
大概是因为太阳还没落山,一家酒吧模样的店里空无一人。
两人并肩在吧台边坐下,麻田把一杯酒兑水粗暴地伸过来碰杯。幸子无法窥探他的内心,用缠着绷带的手拿起酒杯,麻田又来碰杯。麻田一言不发,已经干了三杯,幸子也喝了两杯。
走出店门,酒意涌上来。
“肚子饿了吗?”
麻田说。
“饿了。”
幸子这才发现,自己从早上起就没好好吃过东西。
麻田在街头买了爆米花,抓一把塞进幸子嘴里,两人边吃边走。麻田自己吃一把,再往幸子嘴里塞一把。麻田带着明胶味道的手,碰到了幸子的嘴唇。幸子每次被塞进一嘴爆米花,身体里就涌起一股难以名状的情绪。爆米花又塞过来了。
在床上,麻田也很粗野。虽说动作粗野,却又另有一番柔情。幸子缠着绷带的手腕,就像不属于自己的身体,高高举起,指甲紧紧抓住麻田的背脊,幸子的眼角流下眼泪。透过情人宾馆的窗帘,她看见了夕阳。
“别开灯。”
幸子在黑暗中,问起麻田制作画框的心得。麻田回答说,那就是不要嫉妒画。杀掉自己的嫉妒,只想着怎么让画更醒目。他还说,他想成为一名画家,但才华不够。为了找一条路,他最近准备去纽约。
“一起去吧?”
“我吗?”
“你不是有护照吗?很方便的。”
“咦,你怎么知道……”
“你不是说自己事到临头总是退缩,去巴黎前还得过盲肠炎吗?”
“啊,是啊,那时候……”
幸子总算能笑出来了。
“去年,想和做副业的朋友一起去。”
“做的什么活儿?”
“是做衣服,女罩衫一件一千二百日元。”
幸子从床上起身去冲澡。
麻田正准备关上幸子半开的手提包,发现了里面的文库本,是西鹤的《好色五人女》。
一翻开,卷四《悲恋蔬菜铺物语》映入眼帘。
“雪夜情宿。世间莫轻心,万万不可露:道中怀里银,酒醉拔短刀,女傍弃世僧。”(4)
“道中怀里银”,麻田低声念着,打开红色小钱包,里面收纳着三张整整齐齐的千元纸币,看起来很寒酸。麻田从口袋里拿出一个装着三十万日元的信封,抽出三张,放进钱包。
门好像要开了,麻田衔起一支烟。情人旅馆街的霓虹灯闪烁的玻璃窗上,也映照出准备回家的幸子的身影。
“回去了?”
“再见。”
“就这样?”
“我会一辈子记得。”
幸子微微行礼,抱着手提包出了门。
集太郎一边喝着啤酒一边打开晚报。
“手怎么了?”
他的口气很温柔。
“一个女人家,就不要跳进去了。冰箱电线走火引发煤气爆炸可不得了。”
“是。”
幸子不看集太郎,把茶壶放在煤气灶上,盯着燃起的火焰。集太郎站起身来,走到幸子身后,亲吻她的颈项,幸子挣扎。门铃响了,是管理员来还钱。早上,发生那件事故坐上急救车时,以备不时之需,她向幸子借了五千日元。
虽说闹出了这么大的事,峰子倒是福大命大,不到两三天就出院了。
“太太,你看起来精神焕发啊。碰到这种事,虽说不是发生在自己身上,女人都会激动万分呢。”
管理员笑着走出门,幸子也知道自己扬起的嘴角有多僵硬。然而,当她把收到的五千日元放进钱包时,自己的脸也僵住了,钱包里有三张陌生的崭新纸币。
一定是麻田放进来的。幸子觉得这是自己一生一世的恋爱,那个男人却觉得是自己花了三万日元买的。幸子的手开始发抖,身体也开始发抖。
她避开集太郎的视线,去外面扔垃圾。在“除垃圾收集日外禁止扔垃圾”的木牌前面,她拎着塑料垃圾桶站了许久。
“怎么了?”
集太郎不知何时站在她身边。
“白天的事,就别去想了。”
他从幸子手上接过塑料垃圾桶。
“真是飞来横祸,偏偏搬来我们隔壁。”
他拍拍幸子的肩膀,催她回去,自己先走进了公寓。
峰子带着小巧的点心盒来道谢是两天以后的事。她本来就苗条,现在好像又瘦了两圈,更显苍白。
“之前真是麻烦你了。”她低头致谢。
“要不是太太跳进来,现在我已经躺在小方盒里了。”
她说的是骨灰盒,峰子环顾房间。
“跟我那间格局一样,就是不像在一个公寓里。有了家庭还是不一样啊。”
幸子本来就有些心虚,她一提到“家庭”这个词,幸子更觉得无颜见人。
“怎么了,太太干吗老低着头?做出不成体统事的人是我,应该我道歉。”
“家家有本难念的经,彼此彼此。”
“今天听到你这话,我倒是宽心不少。”
“今天走到走廊,公寓里其他女人的视线像箭一样射向自己的身体。只有太太你这么温柔啊。”峰子的声音暗淡下来。
“我们都得过盲肠炎啊。”
幸子说,峰子不禁笑了。“既然是盲肠之友,那我有一事相求。”峰子说。自己去银行取钱,众目睽睽之下怪不好意思,能不能借她几张现金?幸子从缝纫机的抽斗里抽出麻田塞到她钱包里的纸币,递给峰子两张。
峰子接过纸币,刚说了声“多谢”,就翻过纸币检查起来。
“怎么了,是假币?”
“真是奇怪,世上还真有跟我一样怪的女人。”
峰子盯着幸子的眼睛,低声说:
“我啊,给自己喜欢的男人钱的时候,自己也是花言巧语靠喝酒赚来的,会在纸币的一角印上自己的口红印跟它说再见。”
确实,纸币的一角有红色的口红印。
“这张和之前告别的看起来一模一样,太太,这张钱是谁给的?”
幸子告诫自己保持镇定,声音却不禁颤抖起来。
“谁给的?我们家的钱不是丈夫的工资就是我的零工。”
“就这些?”
“就这些,还能有什么?”
峰子盯着幸子的脸,哧哧笑了。
“打扰了。”
峰子关上门出去了。
再度确认了峰子没有带走的那两张纸币一角的红色记号,幸子浑身无力,跌坐在地上。
走廊里传来了声音。
峰子好像正在接受公寓里的女人们的拷问。
“真对不起,给大家惹麻烦了。不过也不是偷了谁家的东西,就是要换换玻璃,也不至于赶我走吧。”
是三四个主妇围住了峰子,女人们并不陌生的声音从门缝传进来。
“走到哪里都有人议论,瞧,那个公寓的。”
“说得好像我们都不正经。”
“不正经?”
峰子的声音响了。
“最近不是家庭主妇更不正经吗?听说好多太太出卖身体去换钱啊。”
大概是看峰子孤立无援,管理员拔刀相助。
“这么说来,确实经常听说有主妇卖春呢。”
幸子捏着三张印有口红的纸币,一动不动,僵住了。
问朋文堂,才知道麻田已经出发去纽约了。他跟店里请了一个月的假,不过也说多半是不回来了。老店主把麻田在纽约的落脚处写在纸条上递给幸子,说是朋友的工作室。老店主没有问幸子的名字,也没有问她和麻田的关系。
一角印着口红的纸币放在缝纫机的抽斗里。晚上,集太郎伸过手来,幸子也不想被他拥抱。
她在黑暗中剧烈挣扎,甚至从被子里钻出来躲到缝纫机下面。
“我太累了,真对不起。”
“零工还是别做了。”
集太郎背过身去,睡着了。
要是外遇还算是有个说法。自己的身体换了钱,幸子一想起来就懊悔不已。
不光是夜晚,白天幸子也平静不下来。
走出门,主妇们的窃窃私语似乎忽然停了。难道峰子说出了自己的秘密?流言迟早会传到集太郎耳朵里。出去买东西,拿出一万日元,感觉大家的眼睛都盯着自己,幸子的手不禁颤抖了。这样下去可不行,幸子想。她取出副业存下来的定期存款,走进旅行社,办了签证,买了去纽约的机票。结果自己还是背上了主妇卖春的污名,必须把这污名变成一段恋情。
“我要去登谷川岳。”
她把字条留在餐桌上,从成田上了飞机,就像是鬼使神差。
“世事无常,此事不可为人所知。舍弃此身,以命立名,与茂右卫门携手踏上不归之路。”
也许是心理原因,飞机起飞时的震动,令幸子一直颤抖不停,眼睛一直盯着膝上《好色五人女》里的这段文字。
她仿佛看到了愁眉不展的年轻妇人幸子与伙计打扮的麻田手牵着手踏上旅途的画面。
一旦跳下悬崖,不知是自暴自弃还是放下心来,幸子睡得很熟。这十天来的寝食难安都消失了,她睡得香甜,飞机上的饭也一扫而光。
第一次去国外,又是纽约,大概是已经反复看过电视和旅游指南,幸子的心情并没有太大波动。也许,在更大的变动面前,去拜访一个未知之地显得稀松平常。
幸子很快找到了二十八街麻田的落脚处。那是在一栋伤痕累累的七层楼房的六楼,电梯完全不动。幸子爬上白天依然昏暗的楼梯,敲门,一个抱着猫的年轻美国人探出头来。
“Mr.麻田……”
接下去该怎么说,幸子正绞尽脑汁,男人身后,出现了抱着同样花色猫的麻田。麻田看见幸子,什么话也没说,放下了抱在手上的猫。
“没吓到你吧?”
“就算吓到了,从我脸上也看不出来。”
幸子拎着的行李箱里只装着几件换洗衣服,麻田把她从头看到脚。
“和谁一起来的?”
麻田问。
“我一个人。”
“你出来怎么说的?”
“说是要去爬谷川岳。”
麻田大声笑了。
“那个,我有东西要还你。”
幸子在手提包里摸索,像是要封住幸子的嘴,麻田粗暴地拉过行李箱。
“想先去哪里看看?”
“第五大道、时代广场、蒂凡尼、卡耐基音乐厅、SOHO村、中央公园、DakotaHouse(5)。”
不是站名,幸子却停不下来。
两人像恋人一样牵着手,有时挽着手,说说笑笑,在这个城市游荡。崭新的街,古老的街。白皮肤的脸,黑皮肤的脸,经过两人身旁。纽约,爱情,不归之路,幸子已经沉醉。
喝了美国的百威啤酒,吸了半根麻田的香烟,在SOHO村的小店里和黑人情侣并肩听着爵士乐,带着酒劲躺上麻田的床,在更深更深的醉意中睡去。
“喉咙,好渴。喉咙……”
半梦半醒间幸子呻吟着。
大概是太累了,眼皮根本睁不开。
“我去喝点水。”
起身的时候大概踩到集太郎了,幸子想。
“对不起,哎呀。”
幸子摇摇晃晃,准备去厨房喝水。她撞到了屏风,屏风发出巨大的声响倒下,花盆摔碎了。
“我想去喝水——我家的公寓,厨房在这边。”
对着被吵醒的麻田,她本该是这样笑着解释的。
霓虹灯一闪一灭,房间忽明忽暗。这是一个仓库改造后的现代风格loft。涂成纯白的天花板,让人仿佛置身体育馆,作为装饰,天花板上又悬挂着几辆自行车。被吵醒的美国人抱着猫出来,在雪白的墙壁上映出巨大的影子,脚下是摔成两半的花盆。
“真糟糕,我以为这是自己家呢。”
幸子大声笑起来,然而笑声最后变成了别的东西,她忽然奔向行李箱。
“回去了,我要回去。”
“别说瞎话了,这里是纽约,离日本有一万五千公里。”
“回去,我要回家。”
“怎么回去,走回去?”
“怎么办?我闯大祸了。”
“我怕,我怕。”幸子抽泣起来。麻田抱紧她,带她回到床上。越是害怕,越是陷入更深的陶醉。
“不义者斩首!”
幸子梦见,将要腐烂的地藏堂之门开启,武士打扮的集太郎长刀挥向自己,幸子不由得更迫切地寻求麻田。
第一次见到真实的自由女神像,女神的脸看起来比印象中更严肃。
“她手里拿着的是什么?”
“右手是火炬,左手是独立宣言。”
“自由和独立……”
“女人都喜欢这些词吧。”
“因为不曾拥有。一旦结婚女人就两者都失去,不能再喜欢别人,陷入爱情也是罪。结了婚的女人,是以死亡的觉悟在谈恋爱。”
幸子说着说着,又激昂起来。
她仿佛看到,河岸上的每块石头上都写着南无阿弥陀佛,旁边的横木挂住了自己和麻田情死的尸体,漂浮在哈德逊河上。
曼哈顿高楼的旁边有一段废弃的高速公路。正当夕阳西下,两人长长的影子如同十字架,又如同墓碑,他们不由自主地寻求酒精。
第三天一大清早,幸子睁开眼睛,仿佛听到了缝纫机的声音。
“喂,这楼上,是缝纫工厂吗?”
“不是,是雕刻家的工作室。”
麻田依旧闭着眼睛,温柔地抱住幸子的肩头。这具身体,看上去骄奢,穿上衣服却颇显清瘦;这具身体,已经盛满了集太郎未能给予的沉醉,幸子挣脱起床。
“有缝纫机的声音。”
“是幻听吧。”
麻田趴在床上。
幸子从手提包里拿出钱,塞进麻田西装的口袋。回家吧。西鹤的女人被杀了,现代的女人却可以修正错误。
热吻覆盖上她的颈项,躺在床上的麻田不知什么时候已经站在自己身边。
“我,是来还钱的。不喜欢拿着不明不白的钱,所以我……”
“那为什么不还了就走呢?和我一起高高兴兴地在纽约散步,然后才还钱,算是怎么一回事?”
“还钱是借口。我爱上你了——一辈子就一次,我想谈个恋爱。”
“一辈子一次的恋爱三天就结束了?见好就收,擦干净嘴巴回家了,你还真了不起。”
麻田越是在意幸子,越是火大。
“还说你脸上看不出来,现在好可怕。”
“我要是不准你走,会怎么样?”
“我要回去。”
“回去了怎么说?”
“什么都不说。一句话都不说,回去拼命踩缝纫机。”
麻田死死盯着幸子,只说了一句话:
“真爱逞强。”
他伸出手,像是给她加油。
“谢谢。”
不知道还能活几十年,不过以后再也不会这么紧地握住一个男人的手了,幸子想。
集太郎走进“谜”酒吧,已经过了深夜十一点。
“我是邻居时泽。”
他已经喝了几杯,一在吧台上坐下,马上跟峰子打招呼。峰子默默向他致意,帮他倒酒兑水。
“你老婆什么都没说?”
集太郎转动着吧台上的魔方,说:
“前几天出去了,留了个字条说是去爬谷川岳。”
“谷川岳?”
正在切冰的峰子停下手。
“以前可从没说过关于登山的事,为什么忽然跑去爬谷川岳,真是摸不着头脑,您要是听说了什么……”
峰子的手握着冰锥,却一动不动。
“是跟谁一起去了吧,一个人可爬不了那座山。”
“谷川岳啊。”
峰子的目光飘向了虚空。
“这么说来,她问过我能不能报出从上野到谷川的站名。”
峰子笑出声来,笑得很大声。
“你还真是失礼啊。知道我是谁,也不说声之前添麻烦了。我妻子跳进去救你手都受伤了。倒不是叫你知恩图报,我家可是受害者。不仅不道歉,听了我说的话,没反应,还放声大笑。”集太郎五天来的郁闷变成了激愤的语调。
“我觉得好笑才笑的。”放声大笑后,峰子说,“受害者是我,你家太太害了我。”
“现在,我太太正在爬谷川岳吧。”
“谷川岳可不是一座山,是个男人。”她灌下一口威士忌,脱口而出。
“男人?”
集太郎呆住了,峰子帮他又斟了一杯。
“是的,我喜欢的男人。”
“说什么傻话,幸子可没有那么聪明。她认死理,没魅力,只会存钱。”
集太郎越说越没底气。
“那个男人姓谷川吗?”
峰子又喝下一杯酒。
“不是名字。他来过我的房间,抱着我,报着站名:上野、尾久、赤羽、浦和、大宫,你家太太听到了。大白天把男人拉进屋里,我是不怎么样,在隔壁耳朵贴着墙偷听,你家太太也不比我差啊。而且,你家太太……”
峰子酒精上脑,刚说出“从男人那里”几个字,生生停住了。
“从男人那里怎么了?”
“根……根本接触不到男人。”
“不是有老公吗?”
“老公不算男人。”
峰子说完,又小声嘀咕了一句:“啊,文字接龙可真难。”集太郎看来并没有起疑。
“因为接触不到男人,所以才会心血来潮啊。”
集太郎正要开口,一个醉醺醺的客人进来。
要关门打烊了,峰子告诉客人。客人却醉醺醺地叫着,硬要进来。集太郎大声怒叫:“滚出去!”他握着玻璃杯的手抖个不停。峰子往他的杯子里续上酒,自己也续上。
“结婚……”
“七年了……”
“干我这行七年就能独当一面,结婚七年到保质期了。”
集太郎和峰子勾肩搭背,爬上公寓的楼梯。集太郎摇摇晃晃地拿出钥匙开门,峰子站在他身边,用手挡住钥匙孔,她用目光邀请集太郎去半开着门的自己房间。
“格局一样。”
“是啊,格局一样。”
她帮集太郎脱去衬衫,把他的手缠到自己身上。
“女人也都一样哦。”
集太郎被推倒在床上。
“怎么样,一样吧?”
集太郎的手在解裙子的纽扣。
“这种时候,总是听得到。”
峰子睁开眼睛,低声说。
“缝纫机的声音。墙那边,啪嗒啪嗒啪嗒啪嗒。听到这个声音,我就很放心,因为周围太静了。不过后来我渐渐有些恨这声音。我是别人太太哦,入籍了,有名有份。那声音好像在说,你是个什么东西,女人中见不得光的老鼠?就算有再多男人,不也只是在冥河边堆石头吗(6)?什么也不会留下来。踩缝纫机,做零工缝女罩衫,还会有家庭留下来哦。”
“你是在报仇吗?”
“是,报仇。”
峰子被紧抱的身体忽然失去了依靠,集太郎站起身来。
“有缝纫机的声音?”
“幻听吧,什么声音都没有。回来了的话,灯会亮着。”
集太郎的手又抱上来,这次有些心不在焉。峰子自己跳下床,把地板上的衬衫递给他。
“还是没胆啊。”
集太郎默默扣上纽扣。
“不对,回家更需要勇气。”
“我也更愿意这么想。”
也许是过于循规蹈矩,集太郎认真地系好了领带。
“这就是婚姻。”
他自嘲地笑了。
“结婚了就没有自由。”
峰子也跟着他笑了,话语有点颤抖。
“不过,很棒啊,真可惜。”
峰子的眼睛里有东西在闪光。
打开门,她送他出去:
“晚安。”
“晚安。”
隔壁的门开了,又传来关门的声音。
不知道今天是什么节日,公寓挂出了日丸旗。
幸子提着行李箱回来了。她站在公寓楼梯底下,整理了一下呼吸,一口气爬上楼梯。熟悉的楼梯不知为何比平时更高、更陡,不爬上去就回不了家。
集太郎打地铺睡着,枕边的啤酒空瓶已经堆起了一座小山。
幸子用明快的声音大声喊:“我回来了!”
集太郎闭着眼睛,并不答话。
幸子又叫了一声,使尽全身力气,比刚才的声音更阳光,更大声。
“我回来了!”
“回来了。”
集太郎回答道,仍旧闭着眼睛。
“谷川怎么样?”
“我,其实并不是去爬谷川岳了。”
“别说了!”
集太郎接着柔声补充道,“别说了。”
“其实我也去过山脚了。”
“山脚……”
“有人告诉我,比起爬山,回家更需要勇气。”
“谁?”
集太郎睁开眼。
集太郎粘着眼屎的无精打采的脸,在幸子眼里十分令人怀念。
“这些话,留到七八十岁再说吧。”
“嗯。”
幸子吞下了这个巨大的谜团。
“以后,我要踏踏实实的。”
“好好干。”
集太郎站起身,往幸子丰满的屁股上“啪”地打了一记。幸子转过身,两手捂住脸哭了起来。
“你对着谁哭呢?”
幸子扑到集太郎怀里,像个孩子一样发出声音大哭起来。
峰子三天后就搬走了。她还留下两个月的租金没交,借幸子的煤气费和清洁费也没还,等于是连夜逃走了。门前留下威士忌和可乐空瓶,还有旧报纸,房间里就留下光秃秃的双人床,其他痕迹都一夜之间消失得一干二净。
梅雨过后,幸子抱着大包裹像往常一样坐上晃悠悠的巴士。包裹里面,是零工的材料。领子、袖子、身体——裁得七零八落的女人身体的各部分,她要把这些缝起来,做成一件衣服。
主妇时泽幸子回归已经一个月了。当时的伤口,除了幸子谁也不知道。她比以前更细心地准备饭菜,踩着缝纫机。巴士在信号灯前停下,幸子眼睛往下一瞟,不由得叫出声来。车窗下,抓着骑摩托车男子腰的,正是欢笑着的峰子。
幸子像是遇见了久别重逢的故人,她想跟峰子打招呼,想跟她说些什么。这时,绿灯亮了,两辆车迅速拉开了距离,越来越远。
(1) 麻将用语中的“三味线”是使诈的意思。
(2) 日本人通常用大拇指代表男人,用小拇指代表女人,开玩笑的时候,做这样的手势表示有男人,或有情夫。
(3) 井原西鹤创作的《好色五人女》中记载了五个恋爱故事。这里提到的是其中的“桶屋阿千”和“阿桑茂兵卫”的故事。
(4) 出自《好色五人女》。前文讲述蔬菜铺阿七与情人私会,被母亲发现。
(5) 列侬在纽约的公寓,他在此公寓门口被枪杀。
(6) 传说早死的孩子会在冥河边为父母积福,用小石头堆起石塔,但总会有小鬼来推倒石塔。
孤独者之歌-赫尔曼·黑塞
========================
孤独者之歌-[[赫尔曼·黑塞]]
-----
一、一个魔术师的童年(1923年)
啊,生动而古远的传奇,
我又再度来到您的身边,
倾听您动人心弦的歌谣,
您的笑声,您的梦境,
以及您轻声的低泣,
是多么令人难忘。
魔术的耳语传来了您衷心的警告;
虽然我看似沉睡与酒醉,
但您仍不忘把我唤起再迷离……
儿时教导我的,不只是父母与师长而已,还有某种更高超、更奥妙且更神秘的力量,也曾指引过我。其中之一乃是牧羊神——它以跳着舞的小印度神偶的打扮,站在我祖父的玻璃柜里。跟其他神仙一样。这个神祇在我童年岁月里即已敲开了我的心扉,在我尚未读书识字之前,他们即在我的心房里填满了古老的东方形象与观念,因此在后来,当我碰上了印度和中国的传奇故事,我心中便油然而生出一种似曾相识之感,像遇到旧友、回到老家。但事实上,我是一个土生土长的欧洲人,我的生活不免习染着狂热、贪婪与难以抑制的好奇心等西方的特质。
所幸,正如大部分的小孩子一样,在我上学以前,我即学到了生活中最珍贵、最不可或缺的东西——它们是苹果树、雨水与阳光、河川与森林、蜜蜂与甲虫、牧羊神以及我祖父藏室里的神像所教导予我的。我知道自己在天地间的位向,我毫无畏惧地与动物及星辰沟通。我与地上的果园及水中的鱼群,共处同一天地,我会吟咏许多首大自然之歌。我还会变魔术,我拥有了童年时期的一切传奇智慧。
后来,我开始接受了正式教育。但是学校教育并不注重生命不可或缺的重要知能,它主要系侧重于一些华而不实的文字游戏,虽然如此,我还是乐于去学习它,而且,有些东西我还是终生不忘;举个例来说,至今我仍然记得许多优美而隽永的拉丁古语、诗歌、名言,以及地球上许多城市的住民,当然不是今日的住民,而是1880年代的居民。
到了13岁那年,我尚未郑重地考虑过我将来要成为什么样的人或干什么样的事。正像其他一般男孩一样,我羡慕着许多不同行业的人:猎人、撑船人、铁路守车员、走钢索的人或是北极探险家。然而,我当时最大的梦想还是做个魔术师。也许是出于对一般人所谓的“现实”的不满,以及对大人们的愚蠢阴谋的抗拒心理,很早以前,我对这种现实世界就持着一种强烈的排斥态度,有时出之于畏避,有时出之于轻蔑,而在内心里则存着一股炽热的希望,想用魔术去改变它、转化它、提升它。在我孩提时代,此种变魔术的愿望皆指向童式的外在目标:我希望能使苹果在冬天里长大,希望透过魔法使我的口袋里装满着金子与银子。我梦想用魔法摧毁敌人,然后宽宏大量地饶恕他们,使他们自惭不已;我希望能寻获埋藏在地下的珍宝、希望能使死人起死回生、希望自己能够隐形。而其中,我认为最珍贵且贪慕不已的魔法乃是隐形术。而在我一生当中,此种愿望一直以许多不同的形式伴随着我,虽然我自己并没有完全意识到。即使到了后来,当我长大成人并以摇笔杆为生之后,我亦时常企图在我的作品里隐形消失——此种企图时常招致其他作家的误解,引起他们的非议。
现在回想起来,我才了解我的全部生命一直深受此种变魔术的欲望所影响;由于它的影响,这些变魔法的欲望乃与时而变;由于它的影响,我乃逐渐逃避外在世界,全心贯注于我自己;由于它的影响,我开始希冀以智者的隐形来取代魔术外衣的粗糙隐形,智者虽以隐形之身,但却能观照一切。我是一个活泼而快乐的男孩,我乐于与美丽而多彩多姿的世界同游,我到哪儿皆感到自在,我乐于跟动植物相处,亦乐于生活在我自身幻想与梦境里的原始森林,这种炽热的欲望一直令我陶醉不已。有时,在不知不觉中,我也会使出许多魔法,而等到我意识到时,反而使不出这么多的名堂来。
我很轻易便可赢取别人的爱,同时也善于影响他人,我既可扮个捣蛋鬼,也可以扮个令人赞赏的人或神秘人物。有一阵子,我曾使我的小朋友与小亲戚对我的魔力、对我控制魔鬼的神力,以及拥有皇冠与珍宝,深信不疑且敬畏有加。虽然我父母很早就让我结识了蛇蝎,但是长久以来,我一直生活在乐园里。
我儿时的梦想——天地皆是我家,我周遭一切皆是一个有趣的游戏——一直长存在我内心,历久不衰。有时,偶尔心中的不快或渴念,使原本快乐的世界现出一片阴霾与蒙混,但是我通常能找到一条出路,走向其他较自由、更可塑的幻想世界,而当我从这个世界回来之时,我往往会发现,外在世界已再度迷人起来,再度值得我爱。长久以来,我一直生活在乐园里。
我父亲的小花园里有一个木棚,我在那儿饲养了几只兔子与一只乌鸦。我花了好长好长的时间,陪伴着它们;兔子们散发着强烈的生命气息,我在它们身上可以嗅到杂草、牛奶、血液,以及生育的气息;而乌鸦那乌黑的黑眼珠则闪耀着永恒生命的灯光。在同一个地方,我花费了无数的晨夜,单独或在一个朋友的陪伴之下,守着融流的蜡烛,草拟着种种惊天动地的计划——发现广大的财宝,寻找曼陀罗花的根,发动常胜的十字军横扫全球,我将挥起正义之剑处死强盗,开释可怜的俘虏,歼灭强盗的据点,将叛徒钉在十字架上,饶恕逃离的奴仆,赢得公主的爱情,并能了解动物间的言语。
我的外祖父的大图书室里有一本相当厚重的书,我经常在这儿看书。这部取之不尽、用之不竭的古书包含着许多神奇的老图片——有时候当你首度开卷时,你便可发觉到它们,而当你随手翻动书页时,它们往往显得耀眼夺目;但是有时候,你花上老半天去寻找它们,但却老是找不到,它们早已隐身遁走了,就好像它们根本就未曾存在过似的。这本书里也有一个故事,一个美丽但不容易了解的故事,因此我一次又一次地阅读它。而这个故事也不是经常可以找得到的,有时花上个把钟头已算是不错的了,它经常会彻底地消失,然后隐藏起来,就好像连住所与地址皆已改变了似的;但是有的时候,当你读起它时,它却显得十分友善,而且很容易了解;而另外一些时候,它则显得一片漆黑而门禁森严,就像阁楼里的一扇门一样,有时在天黑的时候,门后往往会传来鬼魂的呻吟或低叫声。总之,它看来就跟现实一模一样,而有时它却变成魔术的奇幻世界,这两个世界并存地交织着,但它们对我却同样地熟悉,它们同属于我的世界。
而放在我外祖父那珍贵的玻璃柜里的跳舞状的偶像,也会发生同样的情事,它并不是经常保持原状的——它并非一成不变地保持着同样的面孔,或跳同样的舞。有时,它看来的确像个神像,一个在陌生而难以了解的国度里所塑造,且为陌生而难以理解的居民所膜拜的奇妙而古怪的形象。但是,另外一些时候,它却变成了一个不可思议的东西——它意义无穷、十分凶恶、粗鲁不堪、冥顽不灵、难以信赖而又嘲俗讽世似的——它似乎在设法诱我发笑,以便随后对我施展报复。虽然它是由黄色金属铸成的,但却可以改变表情;可是,它会恶意地使我一笑。但在另外一些时候,它看来却全然像个象征——只是个木然的象征而已,既不美亦不丑,既不善亦不恶,既不发笑也不可怕,只是像神秘符号般地令人不解其奥秘所在,犹如石块上的地衣(青苔)、圆石上的细纹;但是在它的神秘外形之后,在它的脸庞与形象之后,却潜藏着无限之物——神明——后来,我以湿婆(即大自在天Shiva)、维湿奴(即护持神Vishnu)、上帝、生命、道、婆罗门(Brahman)、阿特曼(Atman)或永恒之母名之;但是我对它的敬意未曾或减。它既是父亲亦是母亲,既是男人亦是女人,既是太阳亦是月亮。
而在神像旁边及我外祖父的其他柜子里还放置着其他许多宝贵的东西,有的是木质的念珠,有的是一卷一卷的刻着古印度文字的掌叶,有的是绿冻石雕成的乌龟,还有用木头、玻璃、石英及黏土做成的小神像,上面盖着刺绣的丝布与麻布,还有一些铜制的杯子与碗、盘等,不一而足,这些东西皆来自印度与锡兰,来自盛产羊齿、海岸呈掌状的极乐之岛,来自泰国与缅甸……我们从这些珍异的宝物里,皆可嗅出海岸的气息、嗅出远方的气息、嗅出香料味与肉桂香、嗅出檀木的幽香……这些东西皆经过热带雨与恒河之水的浸渍、原始森林的遮荫,以及赤道阳光的照晒。
而这些东西全都是我外祖父的,他是一个德高望重的长者,他蓄着白胡子,满腹经纶,无所不知,他才是我们的一家之主,我父亲与母亲皆对他敬畏有加;他不只拥有这些魔法附身的印度神像与雕像,杏仁壳做的杯子,檀木造的箱柜,偌大的图书室与大厅,他还是个魔术师、智者、哲人。
他几乎懂得人类的所有语言,差不多三十多种,或许他也了解诸神的语言,也许连星辰的语言,他也能了解,他会说也会写巴利文(Pali)与梵文,虽然他是个基督徒,同时亦深信三位一体的真神;好几十年来,他一直住在炎热而危险重重的东方古国,他曾乘坐舟船、牛车、马匹与骡子远游各地,我们这地方几乎找不到一个比他更有学问的人,毕竟,我们这个国家只是地球上的一小部分而已;还有上亿以上的人有他们不同的信仰、习俗、语言、肤色、膜拜对象、美德与恶习。我爱他、尊敬他、畏惧他,几乎什么事情我都求之于他,仰之于他,从他身上以及从牧羊神偶像上,我不断地学习东西。这个人便是我母亲的父亲,他个人一直潜藏在神秘的森林里,正如他的脸庞大半潜隐在他胡子的白色森林里一样;他的眼神流露着悲天悯人之色,亦流露着咄咄逼人的智慧光芒,许多国家的人都十分仰慕他,他们不远千里前来拜访他,这些人分别用不同的语言:英语、法语、印度语、意大利语、马来亚南语,跟他交谈,而在一席长谈之后,他们便默然离去,并不留下身份,这些人或许是他的朋友,也许是他的密使、信差或代理人。从他这个莫测高深的身上,我得悉我母亲的一些秘密,原来她也曾在印度待过很长一段时间,她也会说马来亚南语与康拿里土语(Kanarese),并会唱一些这两种语言的歌曲,她往往用一些奇怪的魔术般腔调跟她年迈的父亲交谈一些莫名其妙的话。有时,她也跟她父亲一样,挂着一种异乡人的微笑,一种隐秘不宣的智者之笑。
而我的父亲则不同,他孤立地站在一旁,既不属于我外祖父的偶像世界,也不属于城市的世俗世界。他像一个受苦者与追寻者般地傲然而立,他饱学而良善,且一点也不虚假,他只是全神贯注地服务真理,脸上从来没有出现过任何高贵、祥和而正经的笑容——且不带有一丝神秘感。这并不是说他脸上没有慈祥之色或聪敏之相,而是说他从未消失于笼罩着我外祖父的那股神秘的阴影里,他的脸孔从未消融于童稚与神似般的气息中——这两种气息相互作动的结果,有时看起来像一团愁云惨雾,有时看起来却像一出优雅的笑剧,有时看起来又像一个沉哑而凝然内敛的神明面孔。
我父亲从未跟我母亲用印度语交谈过,但会说一口漂亮的英语,以及微微带着波罗的海腔的纯正、清晰的德语。他这口标准的德语尤其令我着迷,而他也乐于教我;有时,我也满怀敬意与热忱地,拼命想去模仿,虽然我明知我的根已深入于我母亲的土壤里,深入于乌黑眼睛的一团神秘之中。我母亲充满着音乐气息,而父亲则不然,他根本不会唱歌。
跟我一起长大的还有我的姐妹与两个年长的哥哥。我们生活在一个小城市里,一个古老而驼背的城市,而它周围则是林木遍野的山脉,山势虽不雄奇,但山林却十分阴暗,山间里流出了一条美丽的河川,河状弯弯,水波缓缓,我热爱这一切并以之为家,我对山林与河川的一切生物与上帝皆十分熟悉,我乐于与石头及洞穴为伴,乐于与小鸟、松鼠、狐狸及鱼儿为友。
这一切皆属于我的,都是我的家——除此之外,还有玻璃柜、图书室,还有我外祖父的慈祥笑脸以及我母亲幽暗而温暖的眼神、乌龟玩偶、神像、印度歌曲与名言……还有那些引导我走向一个更广阔的世界、更大的家园,以及更古远的祖先的东西。
高挂着的铁丝笼里有一只聪明的老鹦鹉,它有一副学究型的脸孔及一张尖嘴,它会唱歌,也会说话,它来自远方一个不知名的地方,嘴上挂着丛林的语言,身上散发着赤道的气息。
我们的家是一所古老的大宅邸,宅内有许多空房间,有地窖,也有会传出回音的长廊。来自许多世界的光线皆曾交汇在这所大宅里。有些人来此祈祷、朗诵《圣经》,有些人来此研习印度语言学,许多美妙的音乐在此演奏,佛陀与老子的智慧之光在此绽放光芒,来自许多国家的宾客,衣服散发着陌生与宽恕的气息,穷人在此不虞温饱,假日在此皆有盛会庆祝,科学与神话在此并行不悖。
我们家里还有一个外祖母,我们相当畏怯她,而对她也不十分熟悉,因为她不会讲德语,她只念法文《圣经》。我们这个家庭的生活复杂情况并不是外人所能了解的。我们这个家庭的嬉游之光是多彩多姿的,生命之声是丰富而百家争鸣的。毫无疑问的,这种家庭气氛是十分美妙的,但是更美妙的则是我个人一厢情愿的世界,这个世界比我现实生活的游戏更为多彩多姿。现实永远是不足的,我们还需要魔术。魔术在我们家里及我个人生活中并不陌生。除了我外祖父的柜子之外,我外祖母也有她自己的箱柜,这些柜子里装满着亚洲的织物、衣服与面纱。此外,偶像的迷人笑眼里,许多老房间的神秘气息里,也都存有魔法。而我内心里有许多东西,跟这些外在事物是相互呼应的。然而,有些东西与关系,却只是单独为我而存在的。世界上似乎没有任何东西像它一样的神秘,一样的难以捉摸,一样的超乎寻常的事实,但是似乎也没有任何东西像它一样的真实。
即使是那本巨书里出没无常的图画与故事,我亲眼目击的事物在顷刻之间的变化,其真实性亦非寻常事物所能比拟。同样的一眼,但是星期日晚上的前门、花园木棚及街景,与星期一早晨之间,其差别有多大!同样是起居室里的壁钟与基督圣像,但是在我外祖父与父亲的灵魂笼罩着它们时,其状貌却完全不同!而当我自己的灵魂伴随着它们而赐予它们以新的名称与意义之时,它们的状貌又为之全然改观!一切固定、稳定,而又经久不变的东西,是多么的渺小啊!而一切正形变化、渴求变动,随时准备消失与再生的东西,则显得多么活泼健朗啊!
但是在所有的鬼灵精里,最神奇而又最美妙的当属“小巧人”。当我第一次遇见他时,我并不认得他。这个小巧人是个细小、灰色、影状的东西,他或许是个精灵,或许是个小妖精,或许是个天使,或许是个恶鬼,他有时在我梦中走到我面前,有时则在我散步的时候出现在我面前,我对他的服从,有甚于我对我父亲、我母亲,甚至有甚于我对理智与畏怯。当我看得见这小东西的时候,他往往单独存在着,无论他到哪里或做什么,我总想要模仿他。
他往往会在我遭遇危急的时候出现。当一只恶狗或一个比我大的小孩欺负我,而在我情况最危急的一刻,这小巧人便及时出现,他跑在我前头,为我指示方向,解救危难。他会指示我花园篱笆较为松散的地方,使我在瞬息间逃遁而去,或者,他会指示我该怎么去避难——伏在地上、转身、逃走、高声喊叫或是保持沉默。有时候,他会把我想吃的东西取走,有时候,他会引我到我掉落东西的地方。有时候,我每天皆可以看见他,但有时候,他则一连好几天未曾露面。在他不露面的一些日子里,生活往往变得十分沉闷而混乱,好像什么事情都不曾发生似的。
有一次,小巧人跟我在市场广场上游玩,他跑在我前面,我则在后头跟着他,后来,他跑到一个大喷水池里,喷水池里有个一人高的石盆,池里四道喷水即落在这个石盆里;他蠕着身子爬上石壁,我也在后面跟着他爬上去,当他扑通一声跳下石盆之时,我也只好跟着他往下跳——结果,差点我就溺死在这里。值此千钧一发之际,有个漂亮的少女把我拉出来,这位少女是我们的一个邻居,但是我跟她并不熟;而经过她这次的救难之后,我们终于建立了一个长时间的快乐友谊。
有一次,我父亲因我行为不当而训斥我。我虽极力为自己辩白,但父亲似乎完全无动于衷,毕竟,小孩要取得大人们的谅解是十分不易的。经过了一场轻微的惩罚之后,父亲递给我一个漂亮的小口袋形日历,作为记取我这次教训的象征。但是我心里对这次事件始终心怀不满,而一直耿耿于怀,最后我终于决定离家出走,而当我走过一个溪桥时,这个小巧人突然出现在我面前。他跳到桥上的横木上,用手势叫我把父亲的礼物丢到河里。我立刻照着他的话去做;当小巧人在的时候,我一点也不会迟疑,只有当他不在或弃我而去时,我才会感到迟疑与犹豫。记得有一次,当我跟父母一道走着时,小巧人突然出现。他走在街道左边,于是我也跟着跑到左边,我父亲命令我回到另外一边,但是小巧人却拒绝跟着我,而坚持走左边,于是我又不得不回到街道的左边。这时,父亲已懒得再管我,最后还是随我喜欢走在他那一边。但是他心里十分不高兴,回到家时他便质问我为何不听话,坚持要走街道的另一边。在这时候,我往往感到十分尴尬,或甚至十分伤心,因为还有什么事情比跟人提到小巧人更困难的事呢。还有什么事情比背叛小巧人,提到他的名字,或说出他的底细,更糟糕,更可恶,甚至更罪恶的事呢?
事实上,我根本未去拜访他,或希望他在我身边。如果他在的话,那最好,我会毫无条件地跟着他走;如果他不在的话,那么他就仿佛未曾存在过似的。小巧人没有名字。然而,一旦小巧人出现了,我便非得跟随着他不可,什么东西都阻止不了我。无论他到那里,我总要跟着他走,哪怕是赴汤蹈火也在所不辞。然而,并不是他命令或劝告我做这个做那个的。实际上,要不模仿他做的一些事情,就如同阳光下我的影子不追随我的动作一样的困难。也许我就是小巧人的影子或镜子影像吧,再不然,他就是我的影子或镜子影像;或许,当我想起我正在模仿着他时,我就正在他面前行动,或跟着他一起行动吧。
但是可叹的是,他并不是经常在我身边,当他不在时,我的行动便失去了天真与必要性,一切事情皆似乎走了样,我每采取一步行动都感迟疑。也许,所谓自由的领域也就是幻象的领域吧。
那位把我从喷水池里拉出来的快乐女郎,终于变成我的好朋友。她活泼、开朗、年轻、漂亮,又显得傻里傻气,一种近乎天才的温柔的傻气。她耐心地听着我叙述有关强盗与魔术师的故事,有时候她似乎十分相信,有时则半信半疑,但是她至少认为我是来自东方的智者之一,这一点倒是颇能迎合我心。她十分赞赏我。如果我告诉她一些有趣的事,她往往在尚未了解重点时,便大声,甚至失态地笑出来。对于这一点,我经常板起脸孔跟她说:“听着,安娜小姐,如果你根本不懂得一个笑话,你怎么可以笑出来呢?这不是愚不可及吗?再说,这对我也是一种侮辱啊。除非你能了解我的笑话,否则的话,你便不应该随便笑出来——你不应该装出笑容,表示你懂得,不是吗?”但她还是继续笑着。“不,”她叫道,“你是我所见最聪明的小孩子。你真了不起。将来你一定会当上教授、大使或医生。至于我的笑,请千万不要见怪。我之所以笑,只是因为我欣赏你,因为你是我们这里最聪明的人。好,现在接下去解释你的笑话给我听吧。”于是,我又一五一十地对她解释一遍,但是她仍然问东问西,最后总算真懂了。如果说,她刚才笑得十分开朗、十分大方的话,那么她现在应该说笑得近乎疯狂,而且甚具感染性,以至于我也抑制不住地跟着笑出来!
有些比较困难的绕口令,我必须一行作三次地,很快地对她叙述。例如:Wiener W.scher Waschen weisse W.sche——维也纳的洗衣工人洗着白色的亚麻衣衫。我坚持她也必须跟着绕口令,她开始只是笑着,接着她试着把3个字带在一起念,但是无论如何她还是念不出来,最后她还是大声地笑了出来。安娜小姐是我认识中最快活的人。在我孩子气的想象中,我觉得她实在很笨,而她确实是有点傻里傻气,但是她却是个快乐的人儿,有时候我倒觉得,快乐的人乃是大智若愚的人,虽然这种智者看似很笨。的确,愚笨往往比聪明更能使人快活。
随着岁月的逝去,我跟安娜小姐的友谊已开始慢慢中止,我已是一个入学的学童了,已开始能感觉到种种诱惑、悲愁与聪明的危险性……此时,这个小巧人再度引导我去接近她。曾有一段时间,我拼命地在想着有关两性差别与孩子起源的问题,这个问题一直困扰着我,使我觉得心焦如焚,有一天在心焦创痛之余,我下了决心,除非这个可怕的谜题能够获得解答,否则的话,我宁愿一死了之。
由于脑子盘旋着挥之不去的疑团,我郁郁不乐自学校穿过市场广场回家,一路上我一直阴阴沉沉地把双眼瞪着地上,但突然间小巧人出现了!他已变成一个稀客了,好久以来,我觉得他已不真实了或他觉得我不真实了——现在,我突然再度看到他,小巧而伶俐的身影匆匆地跑到我跟前;他只在我面前出现一瞬间便冲进安娜小姐的房子里。之后,他突然消失了,但是我却已跟着他跑进房里,当我突如其来地冲进安娜小姐的房间时,她立即大惊失色地叫出来,因为她正行卸下衣服,但是她并没有赶我走,不久之后,我终于了解我当时急于想知道的一切事情。如果不是当时我年纪太小的话,那件事很可能会演成一场风流艳事呢。
这位快活而傻里傻气的女人不像一般成年人,因为她虽然愚笨,但却十分开放,自然,她既不矫揉造作,也不会局促不安。而大部分成人则刚好相反。当然成人世界也有一些例外——我母亲是生气盎然与神秘聪颖的缩影,而我父亲则拥有着一切正直与智慧,至于我外祖父,他现在已不完全是属于人类了,他属于潜隐的多方面世界。但是,若算起成人世界的众生相,倒应以泥塑的神人最叫绝——虽然我们不得不敬畏它们。
他们跟小孩子说话那种扭捏作态的神情是多么的可笑!他们的声音多么的虚假、他们的笑容多么可笑!看,他们自视甚高——他们有的是头衔与忙碌。看,他们盛装夹着公事包、书本,走过街道,那种不可一世的样子,是多么地做作,他们是多么迫不及待地等着被认出来、礼敬与尊敬!礼拜天常有些达官贵人前来我父母家里,“登门求教”——有些人戴着高帽子,笨拙的双手被套在手套里不得动弹——这表示他们的尊容,律师、法官、部长、教授、局长、委员长,还有他们趾高气扬的太大。他们一举一动——脱下外衣、进入房间,起立、坐下、发问、回答,乃至于辞行,都要他人从旁协助。
但是我并不把这种小资产阶级的世界看得太认真,因为我父母也不属于这种世界,他们甚至觉得它很可笑。虽然他们并不矫揉造作,不戴手套,也不攀龙附凤,但是我总觉得大部分的成人都是十分奇怪而可笑的。他们总自以为自己的工作、行业及官位,是多么地重要,他们总是觉得自己十分伟大而备受尊敬!但是孩子们的工作与游戏则根本微不足道,他们只配被叫到一旁责骂。这是不是孩子们所做的事比成人们比较不重要、比较不好、比较不对呢?事实上并不尽然,成人们只是有权力罢了,他们下命令,他们统管一切。他们就像小孩一样,有他们自己的游戏。他们玩的游戏是当救火员、当士兵,他们喜欢去酒店与俱乐部,而这一切他们皆带着一种权威与不可一世的姿态去做,就好像世界上每一件事情都必须是那种样子似的,他们所做的事无一不是光明正大而且十分美丽壮观。
好吧,就算他们之中有些是聪明人,如教师等,但是,这些大人物不久以前自己不也曾经当过孩子,但是却很少人没有完全忘掉孩子是什么,孩子是如何生活、工作、游戏、思想以及孩子喜欢什么讨厌什么的,这不是十分奇怪而令人生疑的事吗?事实上,知道这些事情的成年人,可谓少之又少!他们不仅是暴君,而且也是恶棍——他们用不屑而厌恶的态度对待小孩、拒人千里(指小孩),他们老是用不赞许甚至是恶意的眼光瞪着小孩。
有些心怀好意的大人有时虽然喜欢降格跟孩子们谈天,但是他们大部分都不知道该谈些什么才好。为了方便跟我们沟通,他不得不很辛苦且很尴尬地将自己降为小孩子,但不是真正的小孩子,而是矫揉而愚笨的“假小孩”。事实上,所有的大人皆无一例外地生活在跟我们截然不同的世界里。然而从各方面来看,他们并不见得比我们聪明,也不见得比我们优异,也许他们唯一比我们强的就是那种神秘的力量吧。是的,他们确比我们强大,除非我们服从他们,否则他们一定打我们骂我们,强迫我们就范。但是,这算得上是真正的优异吗?每一头牛与每一只大象不都比这些大人强大吗?但是,他们有权力,他们能发号施令,因此他们的世界及他们做的事便都是对的。但话说回来,有许多大人却似乎很羡慕我们小孩子似的,这真叫人感到莫名其妙。有时候,他们甚至会十分天真地、毫无隐瞒地将这种心理表露出来,或许他们会带着些微感叹地说:“是的,你们小孩子才是真正幸运的人儿!”如果这不是假话的话——而这确不是假话,每次我听到这类感叹时,我就知道这不是假话——那么大人们,这些有权有势、有威严的人,绝对是不比我们这些必须服从他们敬畏他们的人,要来得快乐。在我们的音乐教本里,的确有一首歌曲有着令人吃惊的这么一段重叠句:“能够再度当个小孩将是多么幸福啊!”事情的奥秘就在这里。我们小孩子的确拥有某些大人们所欠缺的东西,他们只不过比我们大些,强些而已,而在某些方面,他们却比我们可怜!他们盛气凌人的样子、他们的尊严、他们的自由与行动,乃至于他们的胡子与长裤,的确令人羡慕,但是另一方面,我们小孩子也有令他们羡慕之处,甚至在他们所唱的歌里,他们也做过这种表示!
尽管如此,但我暂时还是快乐的。世界上或甚至在学校里,我有很多事情看不惯;但是我还是快乐的。从许多方面,我所得到的教导与启示,皆指出人类不只是因为自身的快乐才踩在地上的,真正的快乐只有经过未来证明具有价值才算数;我学过的许多名言与诗文皆作如是表示。虽然这些主题也常引起我父亲的注意,但并不太能打动我的心,如果我碰到不如意的事情,或是因欲望不能满足而感到痛苦,或遭受父母的责怪而觉得委屈,我通常并不企图由上帝那里去寻求庇护,我往往是从其他旁门左道去寻求重获光明的。如果平常的游戏引不起我的兴趣,或是铁道、玩具店、童话故事书都令我生厌了,那么最美妙的新游戏往往会即时出现在我面前,我只消在夜里躺在床上闭起眼睛,让我自己消失在我面前那彩色圈圈的缤纷世界里——那么,幸福与神秘之光便会重新烧起来,我的世界将会变得充满了希望与意义!
我第一年的学校生活并没有使我改变多少。但是,学校生活的经验慢慢使我学到——信任与坦诚只会给我带来伤痛而已,由于一些老师的漠不关心,我学会了撒谎与自我掩饰的处世艺术。自此之后,我懂得做假了。
慢慢地,第一朵花谢去了;慢慢地,在不知不觉中,我也学会了生命的虚伪之歌,学会了跟现实妥协。至此,我才彻底了解为什么大人的歌本里会有“能够再度当个小孩将是多么幸福啊”之类的诗歌,这时的我也开始羡慕起那些还是个孩子的人了。
在我12岁那年,我开始兴起了学习希腊文的念头,我希望自己能像我父亲,或如果可能的话像我外祖父,那么的有学问。从那时候开始,我必须面对我的生命计划;我必须努力读书以便成为一个传教士或是语言学家,因为选择这些行业是可以获得奖学金的。先前我外祖父也曾选择这条路的。
表面上,这一切似乎都没有什么不对。但是,突然间,未来却出现在我面前,路标突然横在我路途上,每一天、每一个月都把我更拉近了既定的目标,每一件东西都把我引离了我少年不识愁滋味的日子,引离了虽然有意义但却没有目标与未来的生活情调。大人们的生活已经抓住了我,开始只抓到了一点头发或一只手指,但不久,它将完全把我逮住——把我推入所谓大人们的“生活”——根据目标、数目而过的生活,秩序、工作、职业与考试的生活;不久,我将成为大学生、研究生、教授、牧师,有一天我也会戴着高帽子与皮手套去作官式的拜访——我将无法再了解孩子,我甚至会羡慕他们。但实际上在内心里,我并不喜欢这一切,我并不想离开我自己这个事事美好而珍贵的世界。说实话,当我想到未来之时,我内心所期盼的乃是十分秘密的目标。我内心所热切希望的是当一个魔术师。
长久以来,我一直保存着这种一厢情愿的梦想,但是最后,它的万能也开始慢慢失灵;它有敌人、有反对力量跟它作对——真实、严肃,而不容否认的东西。慢慢地,花儿凋谢了,我也随之慢慢地脱离无限的世界,而走向有限的真实世界,大人们的世界。慢慢地,我成为一个魔术师的欲望,在我眼里已变得较没有价值了,虽然我仍然继续狂热地抓着它不放,但是它在我眼里已变成一种孩子气的愿望了。
而我生活的原始森林也已变貌了,乐园就这样僵冻在我周围。我再也不是乐园里的王子与国王了,我已不能变成一个魔术师了,我正学着希腊文,两年后我还得加上希伯来文,而6年后,我便要上大学了。
我外祖父书本里的神妙故事仍然十分美丽,但它仅出现在我记得页码的几页里,而我已无法再找出其他新的奇迹了。作舞状的印度神像笑容已显得十分冷漠,我也很少正眼去看它了,而它也不再对我送秋波了。而——最糟糕的——莫过于是我越来越少看到那灰色的家伙——小巧人了。
但是我只是隐隐约约地感觉到这种现象;我仍然十分快乐而且野心勃勃,我学会了游泳,也学会了溜冰,我的希腊文得到第一名,整个事情看起来都十分光彩。但是不知怎么的,每一件东西似乎都笼上了一层较苍白的色彩,带上一种相当空洞的声音,我已懒得再去看安娜小姐了,在不知不觉之中,我的经验里已丧失某些东西了,某些我没注意到,也不十分惦记的东西,但是它毕竟是无声无息地走了。
现在,我最感到迫切的需要,最热切的殷求乃是一种更强烈的刺激,我必须振作自己,重新开始。我喜欢放有许多调味品的食物,我喜欢细嚼着甜食,有时候我捡了几个小钱,使自己沉溺在某种特殊的乐趣里,因为其他事情似乎都不够新鲜与有趣。此时,女孩子也开始吸引我了;这种新的感觉是在小巧人再度出现,并把我引到安娜小姐的房间之后不久产生的。
古老的旅店
作者:[[星新一]]
-----
这里是山间一座日本风格的古老旅店。黄昏时分,三郎和春子来到这里,老板满脸堆笑地迎了上去。
“二位光临敝店就宿,非常感谢。一定尽心伺候。”
“哪里!是有人奉劝我们,一定要住在这里……”三郎愁眉苦脸地回答。不仅面上,心里也同样的阴沉。春子坐在一旁扭过头去。他们二人是旅行离婚前来此地的。
他们结婚已经五年。也许由于处在膝下无人的“倦怠期”,二人的感情逐渐有些冷漠。双方都厌腻对方到了极点,再也不堪忍受了。
婚前的介绍人尽力设法为他们和解,但却说不出个什么道道。夫妻互相指摘对方的缺点,把对方贬得一无是处。一致的意见是:再也无法共同生活。终于,介绍人无可奈何地说:“我作为介绍人,本不想说这样的话,但是,已经束手无策。也许离婚对双方都有好处。”
“这多么干脆!”二人异口同声地说。
介绍人又补充道;“不过,有一件事,希望二位能够听我的话,就是离婚以前,作一次离婚旅行。如果充分谈心还是不行,从此分手,也就势在必行了,刚巧,我熟识一个静悄的山间旅馆。”
由于这么一段经过,二人才来到了这家旅店。
“这家旅店太古老了。”春子在走进正门时厌恶地咕哝了一句,三郎却装中没有听见。他想:再忍耐一会儿就到头了。只要挨过今夜,就对得起介绍人,可以和春子分手了。
“这个房间,一点都不招人喜欢。”当他们被引进房间时,三郎说道。
这回春子没有作声,也没有要求另换房间。因为这毕竟不是快乐的旅行。
吸了一支烟,二人哑口无言地吃了旅店送来的晚饭。虽然介绍人嘱咐他们好好谈一夜,但已毫无这种余地了。况且眼下又没有可谈的话题。
饭后,三郎对前来为他们铺床的女侍者吩咐道:
“喂,请把被子分开铺,那个角落一铺,这个角落一铺。”
女侍者疑惑不解,瞟了一眼春子。然而春子也点头赞同,她只好遵命铺床,然后退了出去。
“我先睡啦……”三郎说着,从皮箱里取出一瓶威士忌,喝了几口,便钻进了被窝。
随后,春子也熄了灯,钻进了对面的另一个被窝。
刚一入睡,三郎就做起梦来:梦见他已经和春子离婚,品尝着自由滋味,走出了旅店。但他刚刚上路,就被从大路的对面走来的许多人喊住:
“终于找到你了!”
然而对于三郎来说,这全是一些陌生的面孔。他试探着问道:
“你们究竟是谁?要干什么?”
“没什么。喂,一同回去吧!”
“我不去!”
“抗拒也没有用。防备你这一手,才雇了好几位大力土哪!”
这伙人哪怕动武也非要把三郎带走不可,三郎感到一阵恐怖。看他们那架势,是轻绕不了的。逃跑?他们会追上来。他挣脱捉拿他的人,向旅店跑去,好不容易才回到了自己房间。春子还睡在那里。
“春子!快救救我……”他拼命地伸出手去,终于抓住了春子的手,感到既留恋、又踏实。
然而,那帮家伙又从上方重重压在他身上,憋得他透不过气来。但他抓住春子的手不放。从这一场莫名其妙的荒涎风波中,难道不是足以证明:可以信赖的唯有春子一人吗?
“春子,救救我……”三郎从心底里发出绝命的呼救。这喊声使他惊醒。他浑身大汗淋漓。而春子的手,还一直被他紧紧地握住,依然不想松开。此时的春子也被恶梦缠扰着,痛苦地喊叫起来:
“喂,救救我……”
三郎推醒春子,问道:
“喂,怎么啦?”
春子睁开眼睛,继续抓着三郎的手,说道:
“啊!原来是个梦。奇怪,真是个可怕的梦啊!我梦见刚要离开这里回家去,竟被一伙素不相识的人追赶,差一点儿被他们带到什么地方去,嗓子都喊哑了……”
三郎告诉春子,自己刚才也做了个梦,内容几乎完全相同。并且,二人意识到两只手还一直紧紧握着.这是怎么回事……
“这是怎么回事?铺被时离得那么远,可是,瞧!现在都紧挨在一起啦。”
“我害怕……”
被窝挨着被窝,毫无移动过的迹象。二人都瑟瑟发抖,紧紧贴靠在一起。此时此刻,“倦怠期”等已不知去向,早已消失得无影无踪了。他们就这样紧握着手,直至天明……
侍女送走二人之后,向老板问道:
“这两位客人怎么完全变了?亲亲热热地回家了。”
“哦,奥秘就在于他们住了那个房间。只要在那间屋里住宿,就会被恶梦魇住。吓醒后,直至天明,再也无法入睡。甚至被窝也会不知不觉地被挪动。不管怎么说,似乎总会留下终生难忘的印象。”
“这是为什么?究竟那个房间有什么说道呢?”
新雇来不久的侍女还不晓得其中的缘由。
旅店老板向她解释说:
“那里发生过殉情。从前,有两个青年一同私奔,可是,双方家里都坚决反对他们结婚,便雇了人四处寻找,硬要把他们抓回去。两个青年跑得情疲力尽,终于被追得走投无路,就在那间屋里选择了一死。”
“真是一桩悲惨的故事啊!一定是他们的咒语留在房间。不过,难道能用这样的房间招待客人吗?”
“当然,平常的客人是不会安排在这个房间住宿的。不过,对那些面临着悲惨结局的夫妇来说,事情就迥然不同啦。在殉情的两个青年希望在世上结合在一起的渴望一起作用,夫妻旅客便难舍难分。老实说,我们正暗地里四面八方地托人,向我们介绍这样的客人哩……”
------
(译自《新潮文库》1983年版星新一著《稀有的未来》)
丁广和译——
故乡的野菜-汪曾祺
========================
故乡的野菜-[[汪曾祺]]
------
荠菜。荠菜是野菜,但在我家乡却是可以上席的。我们那里,一般的酒席,开头都有八个凉碟,在客人入席前即已摆好,通常是火腿、变蛋(松花蛋)、风鸡、酱鸭、油爆虾(或呛虾)、蚶子(是从外面运来的,我们那里不产)、咸鸭蛋之类。若是春天,就会有两样应时凉拌小菜:杨花萝卜(即北京的小水萝卜)切细丝拌海蛰,和拌荠菜。荠菜焯过,碎切,和香干细丁同拌,加姜米,浇以麻酱油醋,或用虾米,或不用,均可。这道菜常抟成宝塔形,临吃推倒,拌匀。拌荠菜总是受欢迎的,吃个新鲜。凡野菜,都有一种园种的蔬菜所缺少的清香。
荠菜大都是凉拌,炒荠菜很少人吃。荠菜可包春卷,包圆子(汤团)。江南人用荠菜包馄饨,称为菜肉馄饨,亦作“大馄饨”。我们那里没有用荠菜包馄饨的。我们那里的面店中所卖的馄饨都是纯肉馅的馄饨,即江南所说的“小馄饨”。没有“大馄饨”。我在北京的一家有名的家庭餐馆吃过这一家的一道名菜:翡翠蛋羹。一个汤碗里一边是蛋羹,一边是荠菜,一边嫩黄,一边碧绿,绝不混淆,吃时搅在一起。这种讲究的吃法,我们家乡没有。
枸杞头。春天的早晨,尤其是下了一场小雨之后,就可听到叫卖枸杞头的声音。卖枸杞头的多是附近村的女孩子,声音很脆,极能传远:“卖枸杞头来!”枸杞头放在一个竹篮子里,一种长圆形的竹篮,叫作元宝篮子。枸杞头带着雨水,女孩子的声音也带着雨水。枸杞头不值什么钱,也从不用秤约,给几个钱,她们就能把整篮子倒给你。女孩子也不把这当作正经买卖,卖一点钱,够打一瓶梳头油就行了。
自己去摘,也不费事。一会儿工夫,就能摘一堆。枸杞到处都是。我的小学的操场原是祭天地的空地,叫作“天地坛”。天地坛的四边围墙的墙根,长的都是这东西。枸杞夏天开小白花,秋天结很多小红果子,即枸杞子,我们小时候叫它“狗奶子”,因为很像狗的奶子。
枸杞头也都是凉拌,清香似尤甚于荠菜。
蒌蒿。小说《大淖记事》:“春初水暖,沙洲上冒出很多紫红色的芦芽和灰绿色的蒌蒿,很快就是一片翠绿了。”
我在书页下面加了一条注:“蒌蒿是生于水边的野草,粗如笔管,有节,生狭长的小叶,初生二寸来高,叫作‘蒌蒿薹子’,加肉炒食极清香。……”蒌蒿,字典上都注“蒌”音楼,蒿之一种,即白蒿。我以为蒌蒿不是蒿之一种,蒌蒿掐断,没有那种蒿子气,倒是有一种水草气。苏东坡诗:“蒌蒿满地芦芽短”,以蒌蒿与芦芽并举,证明是水边的植物,就是我家乡所说“蒌蒿薹子”。“蒌”字我的家乡不读楼,读吕。蒌蒿好像都是和瘦猪肉同炒,素炒好像没有。我小时候非常爱吃炒蒌蒿薹子。桌上有一盘炒蒌蒿薹子,我就非常兴奋,胃口大开。蒌蒿薹子除了清香,还有就是很脆,嚼之有声。
荠菜、枸杞我在外地偶尔吃过,蒌蒿薹子自十九岁离乡后从未吃过,非常想念。去年我的家乡有人开了汽车到北京来办事,我的弟妹托他们带了一塑料袋蒌蒿薹子来,因为路上耽搁,到北京时已经捂坏了。我挑了一些还不太烂的,炒一盘,还有那么一点意思。
马齿苋。中国古代吃马齿苋是很普遍的,马苋与人苋(即红白苋菜)并提。后来不知怎么吃的人少了。我的祖母每年夏天都要摘一些马齿苋,晾干了,过年包包子。我的家乡普通人家平常是不包包子的,只有过年才包,自己家里人吃,有客人来蒸一盘待客。不是家里人包的,一般的家庭妇女不会包,都是备了面、馅,请包子店里的师傅到家里做,做一上午,就够正月里吃了。我的祖母吃长斋,她的马齿苋包子只有她自己吃。我尝过一个,马齿苋有点酸酸的味道,不难吃,也不好吃。
马齿苋南北皆有。我在北京的甘家口住过,离玉渊潭很近,玉渊潭马齿苋极多,北京人叫作马苋儿菜,吃的人很少。养鸟的拔了喂画眉。据说画眉吃了能清火。画眉还会有“火”么?
莼菜。第一次喝莼菜汤是在杭州西湖的楼外楼,1948年4月。这以前我没有吃过莼菜,也没有见过。我的家乡人大都不知莼菜为何物。但是秦少游有《以莼姜法鱼糟蟹寄子瞻》诗,则高邮原来是有莼菜的。诗最后一句是“泽居备礼无麋鹿”,秦少游当时在高邮居住,送给苏东坡的是高邮的土产。高邮现在还有没有莼菜,什么时候回高邮,我得调查调查。
明朝的时候,我的家乡出过一个散曲作家王磐。王磐字鸿渐,号西楼,散曲作品有《西楼乐府》。王磐当时名声很大,与散曲大家陈大声并称为“南曲之冠”。王西楼还是画家。高邮现在还有一句歇后语:“王西楼嫁女儿——画(话)多银子少”。王西楼有一本有点特别的著作:《野菜谱》。《野菜谱》收野菜五十二种。五十二种中有些我是认识的,如白鼓钉(蒲公英)、蒲儿根、马兰头、青蒿儿(即茵陈蒿)、枸杞头、野绿豆、蒌蒿、荠菜、马齿苋、灰条。江南人重马兰头。小时读周作人的《故乡的野菜》,提到儿歌:“荠菜马兰头,姐姐嫁在后门头”,很是向往,但是我的家乡是不大有人吃的。灰条的“条”字,正字应是“藋”,通称灰菜。这东西我的家乡不吃。我第一次吃灰菜是在一个山东同学的家里,蘸了稀面,蒸熟,就烂蒜,别具滋味。后来在昆明黄土坡一中学教书,学校发不出薪水,我们时常断炊,就掳了灰菜来炒了吃。在北京我也摘过灰菜炒食。有一次发现钓鱼台国宾馆的墙壁外长了很多灰菜,极肥嫩,就弯下腰来摘了好些,装在书包里。门卫发现,走过来问:“你干什么?”他大概以为我在埋定时炸弹。我把书包里的灰菜抓出来给他看,他没有再说什么,走开了。灰菜有点咸味,我很喜欢这种味道。王西楼《野菜谱》中有一些,我不但没有吃过,见过,连听都没有听过,如:“燕子不来香”“油灼灼”……。
《野菜谱》上图下文。图画的是这种野菜的样子,文则简单地说这种野菜的生长季节、吃法。文后皆系以一诗,一首近似谣曲的小乐府,都是借题发挥,以野菜名起兴,写人民疾苦。如:
眼子菜
眼子菜,如张目,年年盼春怀布谷,犹向秋来望时熟。何事频年倦不开,愁看四野波漂屋。
猫耳朵
猫耳朵,听我歌,今年水患伤田禾,仓廪空虚鼠弃窝,猫兮猫兮将奈何!
江 荠
江荠青青江水绿,江边挑菜女儿哭。爷娘新死兄趁熟,止存我与妹看屋。
抱娘蒿
抱娘蒿,结根牢,解不散,如漆胶。君不见昨朝儿卖客船上,儿抱娘哭不肯放。
这些诗的感情都很真挚,读之令人酸鼻。我的家乡本是个穷地方,灾荒很多,主要是水灾,家破人亡、卖儿卖女的事是常有的。我小时就见过。现在水利大有改进,去年那样的特大洪水,也没死一个人,王西楼所写的悲惨景象不复存在了。想到这一点,我为我的家乡感到欣慰。过去,我的家乡人吃野菜主要是为了度荒,现在吃野菜则是为了尝新了。喔,我的家乡的野菜!
1992年4月14日
怪胎-[[艾丽丝·门罗]]
========================
-----
```
一、匿名信
紫罗兰的妈妈—艾维阿姨—生过三个小男孩,三个男宝宝,然后她失去了他们。接下来她生了三个女孩。或许是为了弥补她之前在南舍布鲁克小镇一角遭的厄运—抑或是为了提前弥补她不能施予的慈母之爱—她给女孩们取了能想到的最华丽的名字:紫罗兰宝石、黎明玫瑰和美丽小希。她想出这些名字,十有八九只是想先美一美再说。紫罗兰好奇过—她妈有没有想过呢,过上六七十年,等女儿都变成肥胖衰老的老太婆,她们还得顶着这种名字做人?估计她是以为女儿们也都活不长吧。
“失去”意味着死掉。“她失去了他们”意味着他们死了。紫罗兰明白这个。但她还是忍不住浮想联翩。艾维阿姨—她妈—糊里糊涂走进沼泽,也就是谷仓那头远远的一片荒地,光线昏暗,遍布茅草和赤杨丛。就在那里,在阴沉的光线中,艾维阿姨弄丢了她的宝宝们。紫罗兰会从谷仓尽头溜上荒地,小心翼翼地走进去。她钻到红茎的赤杨丛和无名的刺灌丛当中(她去的时候好像都是一年中最潮湿荒芜的时节—晚秋或者初春),让冰冷的水漫到橡胶靴子的脚趾位置。她想象着迷失的感觉。迷失的宝宝们。水从粗草地上漫出。深处还有一些池塘和水洞。人家警告过她这个。她慢慢走进去,看着水贴着靴子淹上来。她从没跟他们提过这个。他们从不知道她去了哪里。迷失啦。
起居室是她可以独自溜进去的另一个地方。窗上的百叶一直拉到窗台。空气沉重浓厚,好像被切割成一个正好填满房间的方块。在几个固定的位置上,躺着饱受风吹雨打的带刺贝壳,里面藏着大海的啸声。一个小小的穿百褶裙的苏格兰人端杯琥珀色的酒,杯子歪着,不过酒绝不会泼出。一把用闪闪发亮的黑羽毛做的扇子。一个尼亚加拉大瀑布旅游纪念碟,图案和麦片盒上的一样。墙上还挂了个画框,它对紫罗兰的影响是如此强烈,刚进屋时她都不敢看它。她只好用眼角的余光瞄着,绕开它走路。画上是一个戴王冠的国王,以及三位穿深色衣服、王后模样的高挑女士。国王熟睡着,或者是死了。他们都在海岸边,有艘船在等待,画里仿佛有什么涌进了房间—一股平滑、黑乎乎、令人难以忍受的甜蜜和悲哀之潮。在紫罗兰看来,这像是一个允诺。它以一种她说不清、理不透的方式,与她的未来、她的生命有所关联。屋里还有别人的时候,她都没法看那画。不过很少有别人。
紫罗兰的爸爸人称比利大王,比利大王·托姆斯,尽管他原名并不叫威廉[1]。名叫比利大王的还有一匹灰斑马,是他们家的拉车马,冬天拉雪橇,夏天拉轻便马车。(紫罗兰成年后在1930年代买了一辆汽车,之前这里一直没有汽车。)
比利大王这个名字通常让人想到的是游行,也就是七月十二号的奥兰治游行[2]。挑来演比利大王的人要戴硬纸王冠,穿件破烂紫袍,骑马走在游行队伍前头。本来应当骑一匹白马来着,不过有时最多只能找匹灰斑马凑合。紫罗兰从来没弄清她家的马,或者她爸爸,或者马和爸爸一道,是不是在这游行中挑过大梁。她眼中的世界谜团重重,请大人们作点解释吧,可他们每每又恼羞成怒。
不过她确实知道她爸爸一度在北方,在一列火车上干过,它从矮树林中穿行而过,树林里有熊出没。伐木工周末会搭这趟火车,从矮树林里出去喝个烂醉。要是他们归途中放肆过了头,比利大王就会停下火车,把他们踹下去。不管火车开到哪儿,哪怕正在野地里呢—照踹不误。他只管踹他们下去。他是个打架高手。他之所以得到这份工作,就因为是个打架高手。
另一个故事发生在他生命中更早些时候。他还是毛头小子那会儿,在老家雪道镇参加了一场舞会。舞会上另外几个小子侮辱了他,他却只能吃哑巴亏,因为他对打架一无所知。此后他跑去拜了一个职业拳手为师,那是个真正的拳手,住在沙波湖。又一个晚上,又一场舞会—发生了跟上次同样的事。同样的侮辱。只不过,这回比利大王跟他们开战,一个接一个扫平了他们。
跟他们开战,一个接一个扫平了他们。
那片乡村再也没人敢那样侮辱他了。
再也没有啦。
(对他的侮辱想必和他的私生子身份有关。他没明说,不过紫罗兰从妈妈的嘟囔中推断出这个。“你爹地他一个亲人都没有。”艾维阿姨用阴郁、困惑、闷闷不乐的语气说,“从来就没有。他从来就一个亲人都没有。”)
紫罗兰比黎明玫瑰大五岁,比美丽小希大六岁。后两个家伙堪称一对难姐难妹,不过大多数时候还算听话。她们像比利大王一样长着红头发。黎明玫瑰丰满红润,脸庞宽阔。美丽小希骨架小、脑袋大,头发刚长出来的时候,有一绺没一绺的,活像只瑟瑟发抖的小雏鸟。紫罗兰却一头深色头发,在同龄人中个头偏高,像她妈妈一样强健。她有一张略长、端庄的脸,深蓝色的双眸乍看上去像是黑色。后来,特里夫·奥斯丁和她恋爱的时候,拿她的眼睛颜色和她的名字联系着,说了不少情话。
紫罗兰的妈妈和她爸爸一样,也有个怪称呼,大多数时候人们都叫她艾维阿姨,连她自己的孩子都这么叫。这是因为她是一个大家庭里最小的孩子。她有很多亲人,尽管都不怎么来看她。家里所有古老或珍贵的东西—起居室里的小玩意儿们、一个拱顶箱,还有几把发黑的勺子—都来自艾维阿姨的老家,他们在白湖岸边有一个农场。艾维阿姨在那里生活了那么久,一直都没结婚,侄女和侄儿们对她的称呼渐渐被所有人沿用,连她自己的女儿们也宁愿用这个叫法,而不是叫她妈妈。
没人料到她还会结婚。她自己也这么说。后来她居然真成了家,嫁给那个站在她身边挺不般配的勇猛的矮个儿红发男。人们又评论说,她好像不大能适应这个变化。她弄丢了头几个男宝宝,对于操持家务也兴趣缺缺。她喜欢在户外干活,在花园里掘掘土,或者劈劈柴,就像在娘家常干的那样。她忙着挤牛奶、清理马厩、喂鸡,是长大一点的紫罗兰接管了家务活。
紫罗兰十岁的时候,已经对家务事很上心了,而且自有主张。她会整个星期六在家里刷洗、打蜡,然后呻吟着瘫倒在沙发上,一旦看到有人把泥浆和牛粪带进屋,就气得直咬牙。
“那丫头长大后,嘴里只能啃草皮,她的坏脾气就配那样。”艾维阿姨评论道,好像说的是哪个邻家孩子似的。通常艾维阿姨就是把泥浆带进家里,把地板踩脏的人。
有的星期六紫罗兰会全部用来烤东西,以及编食谱。有一年,整个夏天她都在尝试发明一种类似可乐的饮料,它将天下闻名,人见人爱,让他们发大财。她在自己和妹妹们身上尝试了浆果汁、香草、罐装水果香精和香料的各种组合。有时她们全都冲到果园里高高的草丛中呕吐不已。两个妹妹通常对紫罗兰唯命是从,对她的话深信不疑。一天,屠夫伙计过来买牛犊,紫罗兰告诉黎明玫瑰和美丽小希,有时屠夫伙计对牛犊肉不满意,就会去寻找肥美多汁的小孩子,做成牛排、排骨和香肠。她完全是凭空捏造,只图个开心,至少她后来把各种往事当故事讲的时候是这么觉得的。小女孩们躲进干草棚,比利大王听到动静,把她们赶出来。她们告诉比利大王紫罗兰的话,比利大王说,她们居然会听信这种蠢话,真该吃几个巴掌。他说,他娶的老婆活像骡子,管家的是个恶棍一样的女儿。黎明玫瑰和美丽小希跑去找紫罗兰。
“骗人!屠夫不会砍小孩!你撒谎啦,骗人!”
紫罗兰忙着清理炉子,没搭腔。她抓起一盆灰—还是热的,不过幸好不烫—朝她们的脑袋上一倒。她们学乖了,再也不敢去告状。她们冲到外面,在草地上打滚,像狗一样晃着身体,抖着头发、耳朵、眼睛和内衣上的灰。她们开始在果园一角搭起自己的游戏屋,拔草堆成椅子,用一些碎瓷片做碟子。她们发誓不将这事告诉紫罗兰。
可她们又离不开她。她把她们的头发裹在碎布里弄卷,给她们换上旧窗帘做的袍子,给她们的脸化妆,用的是浆果汁、面粉和擦炉粉。她发现了游戏屋,想出一些点子来装饰它,远比她们高明得多。即便她根本没时间搭理她们的时候,她们也忍不住去看她忙活。
她在厨房磨损的黑油毡地毯上画红玫瑰图案。
她在绿色旧百叶窗上剪出波纹边缘,让它们显得很雅致。
在她们家,正常的家庭生活好像恰好颠倒过来了。在别的农场上,你沿小巷走过去,最先看到的通常都是孩子们—在玩耍,或者在做什么杂活儿的孩子们。做妈妈的都在屋里忙活。在这里,你先看到的却是正在堆土豆,在院子里或养鸡场闲逛的艾维阿姨。她脚蹬胶靴,头戴男式毡帽,穿一身脏兮兮、东拼西凑的衣服:毛衣、裙子、邋遢的衬裙和围裙,还有皱巴巴、脏兮兮的长袜。倒是紫罗兰在屋里忙活,是紫罗兰决定何时以及是否该端出面包、奶油和玉米糖浆。好像比利大王和艾维阿姨,尽管不是没努力过,却依旧没弄明白该如何正常度日。
不过这个家还是维持了下去。他们挤牛奶,把牛奶卖给奶酪厂,养小牛卖给屠夫,收割干草。他们是圣公会成员,虽说不怎么去教堂,因为要艾维阿姨把自个儿收拾干净并非易事。有时他们倒会参加在学校举办的牌聚。艾维阿姨会打牌,打牌时愿意摘掉男式毡帽和围裙,尽管还坚持穿靴子。比利大王唱歌小有名气,打完牌,人们会劝他唱几首。他喜欢唱学自伐木工的那些名不见经传的歌谣,唱歌时拳头紧握,双眼紧闭:
多年前的一个夏天,在欧盆果大道,[3]
我驾着马车替胡里汉和海伊斯卖命。
如今马儿不在,剩我一人,老来无用,
唯愿我还在欧盆果大道把马车赶。
谁是胡里汉,谁是海伊斯呢?
“是什么公司吧。”比利大王用刚唱完歌,依旧洪亮的嗓门回答。
紫罗兰在镇上读完高中,到渥太华上师范大学。人们奇怪比利大王哪来的钱。要是他手头还剩一点铁路上的工资的话,那就意味着他带着艾维阿姨离开她娘家、买下这片农场时,从她娘家人那里弄到了一笔钱。比利大王说他可不会剥夺紫罗兰受教育的权利—他觉得当老师挺适合她。不过也没什么别的给她了。上高中以前,她带着从箱子里翻出的一匹彩条绉绸,穿过田野,走到隔壁农场。她想学会使用缝纫机,给自己做一条裙子。她果真学会了,尽管邻居女人评论道,这是她有生以来见到的最古怪的女学生装了。
读高中时,紫罗兰每周末都回家,给妹妹们讲拉丁语和篮球,像从前一样持家。不过去渥太华读书后,她圣诞节才回来。黎明玫瑰和美丽小希已经长大,足以持家—有没有持则是另一回事。黎明玫瑰本该上高中,但她在本地学校的最后一年没能毕业,正在复读。她和美丽小希同班。
圣诞节紫罗兰回家度假时,就跟换了个人似的。不过她以为变的是周遭的一切和别人。
她纳闷他们是不是一直就这样说话。什么样?带口音啊。他们不是故意这样做来寻开心的吧?什么“你那啥”之类的,他们是不是为了逗乐,特意这么说的呢?
她忘记了摆东西的老位置,发现煎锅塞在炉子下,居然大惊小怪。她也不喜欢狗儿跳跳虎了,它老了,被允许待在室内。她抱怨它有味道,沙发毯上沾满狗毛。
她说起居室闻起来一股霉味,墙纸也该换了。
不过让她最为吃惊和不满的还是她的妹妹们。她们自从夏天以来已经长大。黎明玫瑰变成一个高大粗壮的女孩,松弛的乳房在裙子里晃来晃去,宽阔的红脸膛上,昔日狡黠的孩子气换成了一副愚蠢固执的呆相。她散发出成年女人的体味,而且不洗澡。黎明小希的身体仍像小孩,但是卷曲的红头发从来不曾好好梳理,全身遍布跳蚤咬出的疙瘩,都是她在谷仓和野猫玩惹上的。
紫罗兰想帮这两个人拾掇拾掇,却无从下手。最糟的是,她们开始叛逆了。她跟她们说话,两个妹妹互相一对眼神,哼哼冷笑,回避着她,骡子似的不吭声。她们好像藏着什么愚蠢的秘密。
也确实,她们是有个秘密,不过是过了很长一段时间,直到第二年夏天出事之后才揭晓的。然后转弯抹角地,由美丽小希先告诉几个女孩,她们再告诉另一个,然后又传到另一个耳中,别人渐渐也听说了。终于,一个邻居女人告诉了紫罗兰。
那年晚秋—紫罗兰上师范那年—黎明玫瑰来了例假。她羞愧难当,跑进小溪,坐在冷水中,想让血止住。她脱掉鞋袜和内裤,一屁股坐进冰冻的浅水。她把内裤上的血迹洗掉,拧一拧,没等干就穿上身。她没感冒,也没生病,不过接下来一整年都没再来例假。邻居女人说,这种做法说不定把她的脑子弄坏了。
“所有那些坏血又被赶回她的身体里了,那不是没可能的呀。”
那年圣诞,紫罗兰唯一的快乐就是说起她的男朋友,他叫特里夫·奥斯丁。她给妹妹们看他的照片,是从报上剪下的。他戴着牧师领圈。
“他看起来像个牧师嘛。”黎明玫瑰咯咯笑着说。
“他就是啊。这照片是授予圣职时照的。你们不觉得他很帅吗?”
特里夫·奥斯丁确实很帅。他是一个深色头发的年轻人,长着细细的眼睛和完美的鼻子,下巴高高翘起,还有一个抿着嘴唇、自信满满,甚至可以说是仁慈的笑容。
美丽小希说:“是个牧师哦,那他想必很老啦。”
“他刚开始当,”紫罗兰说,“他二十六岁。他不是圣公会牧师,是联合教会的牧师。”她补充道,好像有什么区别似的。对她来说确实不同。紫罗兰在渥太华转了教会。她说联合教会在那里更活跃。它有一个羽毛球俱乐部—她和特里夫都会打—一个戏剧俱乐部,还有滑冰晚会、雪橇晚会、搭干草车巡游活动和联谊会。紫罗兰和特里夫就是在一个万圣节联谊会上,在玩咬苹果游戏[4]时初次邂逅的。或者不如说那是他们第一次交谈,因为紫罗兰在教堂早已注意过他,他是助理牧师。他说他也留意过她。她觉得这话或许不假。部分是因为特里夫的缘故,一群师范学院的女生总是结伴去教堂,她们会通过玩游戏吸引他的注意力。所有人都起立唱赞美诗的时候,她们直盯着他看,一旦他回视,她们便立刻垂下眼睛。然后她们这几排中便传出几波咯咯笑声。不过紫罗兰径直对着他唱歌,仿佛她只是偶然将目光投在他身上而已:
起来哟,上帝的信徒,
披戴上你的盔甲……
唱赞美诗时交织的目光。在这个新的联合教会中,传统卫理公会教徒雄浑的赞美诗和长老会成员严厉的圣歌兼而有之。因此,这个教会的教职当时吸引了许多精力充沛、野心勃勃的年轻人,他们与跻身政界寻求机会的年轻人没多大差别。一个动听的声音和一张英俊的脸庞并没什么坏处。
目光交织。在紫罗兰住的出租屋门前的接吻。凉爽的、刮得干干净净却仍有点扎人的陌生的男性脸颊,滑石粉和剃须膏一本正经却又令人宽慰的味道。很快,他们溜进门边的阴影,隔着冬天的衣服紧紧拥抱。他们不得不对于自我控制展开严肃的讨论,但讨论本身却显得那样撩人。他们越来越相信,一旦结婚,他们将会拥有想想就足以让你昏倒的快乐。
紫罗兰过完圣诞节回来不久,他们就订婚了。之后,他们除了性爱,又有了别的事情可以考虑和期待。一种气派体面的生活在等待他们。他们作为订婚伴侣,被邀请去年长牧师和教区里富裕、有权有势的教友家参加晚宴。紫罗兰给自己做了一件得体的衣服,一件越橘色羊毛哔叽呢裙,打着宽褶—与她炮制的七彩条纹绉绸衣服相比,堪称一个巨大进步。
晚宴的饮料是番茄汁。桌上搁着装冰水的水罐。教会禁止饮用含酒精的饮料。就连圣餐酒也是用的葡萄汁。不过吃的总有巨大的烤牛肉或烤猪肉块,或者火鸡,用大大的银盘盛着,烤土豆和烤洋葱,厚厚地涂着酱汁,然后还有重油蛋糕、馅饼,以及形状美妙的布丁,浇着发泡奶油。吃不是一桩罪过。打牌是罪过,只有一种被专门发明出来的卫理公会玩法,叫作“失落之子”的除外。跳舞在一部分人看来是罪过,另一些人觉得看电影是罪过,星期天参加除了无须购票的宗教音乐会之外的任何娱乐活动,在所有人看来都是罪过。
对紫罗兰而言,这非常不同于她童年时代随心所欲的圣公会教规,与她家里的规矩—如果说有什么规矩可言的话—更有着天壤之别。她不知道特里夫看到比利大王每天早上出门干活之前都要灌下那么多威士忌会作何感想。特里夫提过想和她回去见见家人,但她不断设法拖延。他们没法在星期天去,因为他要去教堂,工作日也不能去,因为她要上课。她暂时尽量不去想回家这事。
联合教会的繁文缛节固然一时不那么容易适应,但它那种信誓旦旦、不同凡响的感觉,那种活泼振作,却非常对紫罗兰胃口。牧师和首席教友们仿佛都在一个兴旺的大公司里忙忙碌碌。她看得出做牧师的妻子是一项艰难、充满挑战的工作,不过她并不畏惧。她想象着自己在主日学校教课,筹集慈善捐款,带领祈祷,穿得体体面面坐在前排听特里夫布道,不知疲倦地从银茶壶里倒出茶来。
她不打算回家过暑假。考完试她会回家一个礼拜,然后整个夏天都到渥太华的教会办事处打工。她申请了一份离渥太华不远的贝尔角的教职。她打算教一年书,然后结婚。
考试开始前一个星期,她收到一封老家来信。不是比利大王或艾维阿姨写的—他们不写信—而是隔壁农场的女人,也就是缝纫机的主人写的。她叫安娜贝尔·莱尔利,对紫罗兰挺有好感。她自己没女儿。她过去觉得紫罗兰很可怕,不过现在觉得她大有长进。
安娜贝尔写道,很抱歉这个时候打搅紫罗兰,但她觉得应该告诉她。紫罗兰家出事了。具体情况她不想在信里说。要是紫罗兰可以设法搭火车回来,她会去镇上接她。她和丈夫现在有一辆汽车。
于是紫罗兰搭火车回了趟家。
“我只好直话直说了,”安娜贝尔说,“是你爸爸。他有危险。”
紫罗兰以为,她的意思是比利大王病了。不过并非如此。他不断收到匿名信,可怕的信。它们威胁要他的命。
信里写的东西,安娜贝尔说,实在恶心得超出想象。
家里的所有正常生活似乎都已停止。全家人战战兢兢的。他们害怕到后头的牧场挤牛奶,害怕走到酒窖尽头,也不敢在天黑后去打井水或上厕所。比利大王直到现在也不怕打架,但是一个不知名的敌人时刻准备袭击他,这个想法把他击垮了。从家走到谷仓途中,他必须不停转身,看看是否有人跟踪。挤奶时,他会让奶牛在畜栏里掉个头,自己躲在角落里,免得有人偷偷凑近。艾维阿姨也是如此。
艾维阿姨在家里到处乱走,用棍子敲打碗橱门、柜子和箱子顶儿,嚷嚷着:“要是你在里面,最好就待在那儿,活活闷死!你这个谋杀犯!”
这个谋杀犯准是个侏儒,紫罗兰评论道,不然哪能藏进这些地方呢?
黎明玫瑰和美丽小希都待在家里不上学,尽管这会儿本该准备参加高中入学考试。她们晚上不敢脱衣,身上的衣服全都揉得皱巴巴的,发出馊味儿。
他们不再开伙。不过邻居们会带来吃的。似乎总有几个来访者坐在厨房桌边,某个邻居,甚至某个不怎么认识的人,听说了他们的麻烦,特地远远赶来看热闹。盘子要么不洗,要洗也是用冷水。地板只有狗还有兴趣去清理。
比利大王彻夜坐着,以防不测。艾维阿姨把卧室门抵得死死的。
紫罗兰提出看看那些信。它们被取了出来,摊在桌子的油毡布上供她研究,就像对所有邻居和来访者们做的一样。
第一封信是从邮局寄来的。然后是第二封,也是邮寄的。之后的就是纸条,从农场各处冒出来的纸条。
在畜栏的一个奶油罐顶上。
钉在谷仓门上。
裹在比利大王每天都要用的牛奶桶柄上。
关于哪张便条是在什么地方发现的,他们争论不休。
“邮戳呢?”紫罗兰打断他们,“邮寄来的两封信的信封在哪里?”
不知道。他们不知道信封哪去了。
“我想看看是从哪里寄来的。”紫罗兰说。
“从哪儿寄来有啥用,反正他晓得俺们在哪。”艾维阿姨说,“反正他现在没寄啦。他天黑后就溜进来,丢下它们。天黑后直溜进来,丢下它们—他晓得俺们在哪。”
“那跳跳虎呢?”紫罗兰问,“它没有叫吗?”
没。不过跳跳虎现在太老了,当不了看家狗啦。这么多人来来去去的,它早就没兴趣叫了。
“哪怕瞧见地狱大军从大门进来,它也不会叫。”比利大王说。
第一封信告诉比利大王,他最好把牛都卖掉。他命中有劫,绝对活不到收干草那天。他死定了。
比利大王吓得去看了医生。他以为没准脸上有什么迹象,让人看出他得了毛病。但是医生在他身上敲敲,听听他的心跳,对着他的眼睛照了照灯,收了两元钱,宣布他健康得很。
你个大蠢蛋,还去看医生,第二封信这么写道。不如留着你那两块钱钞票擦擦你那臭烘烘的老屁股吧。我才没说你要病死。你要被杀死。这才是你要遭的事。你再健康也没用。我会在晚上溜进你家,割断你的喉咙。我可以在树后开枪打死你。我可以从你背后扑上来,用绳子勒住你,把你勒死,让你永远看不到我的脸。咋样?
这么说,并不是什么占卜者,或者哪个能预测未来的人。而是一个打算亲自动手的敌人。
我才不介意顺便把你那丑老婆和蠢娃子们一起杀死。
你就配脑袋朝下被丢进茅房。你这头罗圈腿的老烂猪。真该用个剃刀片把你那玩意儿给割喽。你还是个骗子。你吹嘘自己打赢那么多架,全是扯谎。
我要用刀子捅你,用个碗接你的血,做他一碗血布丁。我要拿这个喂猪。
你想让一根烧红的拨火棍捅进眼睛里吗?
看完这些,紫罗兰建议:“我们该把这些送到警察局。”
她忘了这一带哪有什么抽象的、官方意义上的警察。警官倒是有一位,可他待在镇上,比利大王去年冬天还跟他发生过一次口角。根据比利大王的说法,布特·洛马克斯法官开车在一个十字路口撞上比利大王的雪橇,洛马克斯喊来了警官。
“抓住那个人,他在十字路口没停车!”布特·洛马克斯(醉醺醺地)嚷道,挥舞着戴着巨大毛皮衬里手套的手。
比利大王捏紧拳头,跳到硬邦邦、积得高高的雪地上。“看哪个穿铜纽扣的敢给我戴手铐!”
最后这事情和解了,只是去找警官仍旧不是什么好主意。
“不管怎样,他会记仇的。没准就是他写的这些信哩。”
不过艾维阿姨认定是一个流浪汉干的。她记得几年前,有个难看的流浪汉上门来,她给了他一片面包,他却没道谢。他问:“没有腊肠吗?”
比利大王觉得更有可能是他有一次雇来帮忙收干草的人。那人一天半后就辞职不干,说是受不了在干草堆里干活。他说差点没被灰尘和干草籽呛死,而且肺部受损,为此索要额外的五毛钱补偿。
“给你五毛钱!”比利大王吼道,挥舞着干草耙,“有种过来拿你的五毛钱!”
或者没准是某个打算报旧仇的家伙,他很久以前从火车上踹下的人中的一个?或者更早先时候,他在舞会上收拾的人中的一个?
艾维阿姨回忆起小时候一个对她有过意思的男孩。他去了西部,不过没准又回来了,发现她已经结婚。
“过了这么久又来追你?”比利大王说,“我才不信这种鬼话!”
“反正,他对我有意思来着。”
紫罗兰研究着这些字条。是用铅笔在廉价的横线纸上写的。铅笔颜色很深,好像写字的人很用力。没有擦改痕迹,书写也没问题—比如说吧,连“蠢蛋”这样的字都没写错。造句和大写字母都很准确。只是这些又能说明什么呢?
门夜里闩着。百叶窗一直拉到窗台。比利大王把霰弹枪搁在桌子上,旁边放杯威士忌。
紫罗兰把威士忌倒进垃圾桶。“你不需要这个。”她说。
比利大王冲她举起手—尽管他并不是打老婆孩子的那种男人。
紫罗兰朝后躲了躲,却没停嘴:“你不需要醒着。我醒着就行了。我还有力气,你累啦。好啦,爸爸。你需要睡觉,不是喝酒。”
争论一阵之后,协议达成。比利大王让紫罗兰证明她知道怎么开枪。之后他就去客厅,睡在硬沙发上。艾维阿姨在卧室里已经用梳妆台堵住了门,要让她再推开,肯定又得嚷嚷着解释半天。
紫罗兰打开灯,从架上取下墨水瓶,给特里夫写信,告诉他家里的麻烦事。她没有添油加醋,只讲了讲现状,让他知道她如何接管此事,安抚家人,她准备如何保护自己的家。她甚至讲了倒掉威士忌的事,解释说她爸爸寻求威士忌的安慰,主要是因为精神过于紧张之故。她没提她很害怕。她描述了初夏夜晚的寂静、黑暗和孤独。对于生活在镇上或者城里的人来说,未免太黑暗、太孤独了—但其实又并非真的那么寂静,要是你仔细倾听的话。远远近近,到处是细微的声响,树木生长、晃动,动物奔跑、觅食。躺在门外的跳跳虎发出一两声哀鸣,那是在梦中吠叫。
紫罗兰在信末签上了爱你、想念你的准妻子,又加上一行,全心全意地。她关掉灯,拉起一扇窗上的百叶,坐守着。在信里,她说这个时候的乡间非常可爱,路边盛开毛茛花;但是,当她坐着,提防着有什么移动的形体从院子里挤挤挨挨的阴影中挪出,竖着耳朵听有没有偷偷摸摸的脚步声时,她觉得自己真恨乡下。公园里的花草要好看得多,渥太华街道两侧的树木更是美不胜收。那里秩序井然,而且有文明。而在这里,只有空虚、谣言和荒谬。要是看到她这么枯坐着,面前搁把霰弹枪,邀请她赴晚宴的那些人会作何感想?
假设冒犯者,也就是谋杀者,果真沿台阶走来,会怎样?那她只有冲他开枪了。距离如此之近,霰弹枪打出的任何伤口想必都会非常严重。免不了有一场法庭审判,她的照片会上报纸。“乡巴佬闹纠纷”。
要是不冲他开枪,结果会更糟。
她听到一个响声,顿时一跃而起,心脏怦怦乱跳。她没抓起枪,反倒推开了它。她觉得声响来自门口,不过仔细一听,她就明白来自楼上,同时也意识到自己刚才睡着了。
只是她的妹妹们而已。美丽小希不得不出门上厕所。
紫罗兰给她们打开灯。“你俩不用都起床,”她说,“我可以陪你去。”
美丽小希摇摇头,拉着黎明玫瑰的手。“我要她陪。”她说。
因为受惊,她俩都快变成白痴了。她们不敢抬头看紫罗兰。她们还记得昔日吗?她教育她们,宠爱她们,竭力把她们打扮得漂漂亮亮的昔日时光?
“你们就不能换上睡衣吗?”紫罗兰叹息道,关上了门。她坐在枪边等她们回来上床。然后她点起炉子,煮了点咖啡,因为担心会再睡着。
她看到天边开始发白,就打开房门。狗爬起来抖抖身子,到水泵边塞住的洗碗槽里弄水喝。院里白雾弥漫。房子和谷仓之间是一片多石的凹凸地,因为夜间的潮湿,石块都黑乎乎的。他们的农场,除了散布在多石的山地和沼泽当中的几亩薄田,还有什么呢?得有多蠢,你才会觉得能在这里安顿下来,待上一辈子,还要成家立业呢?
台阶上有一样异常的东西—一团整齐、发亮的马粪。紫罗兰找根棍子想把它捅开,旋即看到下面的纸条。
别以为你那自命不凡的荡妇女儿能帮你。我一直在盯着你们。我恨她也恨你。把这玩意儿填进你喉咙咋样?
他想必是夜里最后一刻把它放进来的,就在她在厨房桌边喝咖啡的时候。他大有可能瞥进屋里,透过窗子看到了她。她奔过去摇醒妹妹们,问她们出去时有没有看到什么,她们说没有,什么也没看见。她们举着灯下了台阶,又走回来,什么也没见着。他是在那之后才放进来的。
这下子,有一件事让紫罗兰暗自庆幸:艾维阿姨与这事无关。艾维阿姨整晚都锁在她的屋子里。并不是说紫罗兰真觉得她妈有这么可恶、这么疯狂,以至于做出这种事。但她知道人们的议论。她知道准有人在交头接耳,说这里出这种事一点也不奇怪。他们没准正讨论着,说有些人就是惹麻烦的命,注定要遭遇怪事。
紫罗兰一整天都忙着打扫。给特里夫的信搁在梳妆台上,根本无暇去寄它。访客不停上门,一切都和昨天一样—同样的交谈,同样的怀疑和讨论。唯一的不同在于,又有一张新字条可以展示了。
安娜贝尔给他们带来新鲜的面包。她看了字条,评论道:“这真叫我恶心。都凑那么近了。你估计都能听到他的呼吸声了,紫罗兰。你的神经估计都快要崩断了吧。”
“没人能明白,”艾维阿姨骄傲地宣布,“俺们在这块都过的是啥日子。”
“天黑之后,谁还敢踏上这里一步,”比利大王说,“从现在起,他就要挨枪子儿了。我就说这么多。”
他们吃完晚饭,挤完牛奶,关好牛群,紫罗兰走到邮箱把信塞进去,好让邮递员早上把它收走。她在信上压了几分钱买邮票。她爬上邮箱后头的河堤,坐了下来。
路上没人过来。现在到了白昼最长的那几天。太阳刚刚下山。一只小水鸟吱吱叫着,耷拉着一只翅膀,想引诱她跟上去。想必它把蛋下在了附近。水鸟们都喜欢几乎就在大路上下蛋,就下在砾石路面上,然后又不得不煞费苦心地把人引开。
她变得像比利大王一样不对劲了,开始怀疑身后有人。她竭力不扭头去看,不过还是没忍住。她跳起来,猛转过身,发现刺柏灌木后头的斜阳余晖中闪过一缕红发。
是黎明玫瑰和美丽小希。
“你们在这里做什么,想吓死我吗?”紫罗兰生气地说,“我们受的惊吓还不够吗?我看到你们了!你们以为自己在干吗?”
她们钻出来,给她看她们在做什么—在摘野草莓。
从瞥见那缕红发,到看到她们手中的红色野草莓,这么一点时间里,紫罗兰突然恍然大悟。但她不可能让她们承认,除非她哄骗、哀求,甚至还要装作钦佩、同情。或许就算那样也不会奏效。
“不给我吃个草莓吗?”她说,“你们生我气了吗?我知道你们的秘密了。”
“我知道了,”她说,“我知道是谁写的那些信。我知道就是你们干的。你们真是好好地耍了他们一把,不是吗?”
美丽小希的脸抽搐起来。她咬住下嘴唇。黎明玫瑰神色如常。不过紫罗兰看出她捏紧了抓着草莓的拳头。红色汁水从黎明玫瑰的指缝中渗出。然后,她似乎判定紫罗兰是站在她这边的—或者是根本不在乎了—竟然微笑起来。这个微笑,或者说是冷笑,令紫罗兰刻骨铭心。它既纯洁又邪恶,就像梦中某个你信任的人突然变成或者被揭发为敌人时的笑。这是她妹妹,胖嘟嘟的小黎明玫瑰的微笑,也是一个冷酷、狡猾、成年、邋遢、坏心肠的陌生人的冷笑。
全都是黎明玫瑰干的。这一点现在清楚了。一切都真相大白。是黎明玫瑰写了所有的信,想出放它们的地方,美丽小希什么也没做,只是默许着。头两封信是从镇上寄出的。第一次是黎明玫瑰被带到镇上看耳朵痛的时候。第二次是她们搭安娜贝尔的车的时候。(自打有了汽车,安娜贝尔几乎每天都要找个机会进城。)这两次都很容易有机会溜到邮局。之后黎明玫瑰就把纸条塞在别的地方。
美丽小希轻声咯咯笑着。然后打起嗝。然后抽泣起来。
“安静!”紫罗兰说,“又不是你干的!”
黎明玫瑰没有流露出任何害怕或者悔过的表情。她把手拢着伸到脸前,吃起碾碎的草莓。她甚至没问紫罗兰会不会告发她。紫罗兰也没问她为什么要这么做。紫罗兰觉得,要是冒冒失失地问了,黎明玫瑰或许会说,只是开个玩笑而已。那样真没什么意义。又万一她什么都不肯说呢?
那天晚上,妹妹们上楼后,紫罗兰告诉比利大王,他再也无须守夜了。
“为什么?”
“叫我母亲来这儿,我来告诉你们。”她故意说“我母亲”,而不是“艾维阿姨”,或者甚至“妈妈”。
比利大王在卧室门上乱捶,“把那玩意儿推开,出来!紫罗兰要见你!”
紫罗兰收起百叶窗,拉开门闩,打开门。她把霰弹枪靠着角落放好。
她的消息花了颇长一段时间才被消化。做父母的耷拉着肩膀,手搁在膝盖上,一脸失魂落魄、困惑不解的表情。比利大王似乎第一个明白过来。
“她跟我有啥仇咧?”他问。
他反复唠叨的就是这么一句,每次想到这事,他能说的就只有这一句。
“你觉得她跟我有啥仇咧?”
艾维阿姨站起身,戴上帽子。她感到夜间的凉风从纱门吹进来。
“人家要好好笑话俺们啦。”她说。
“别告诉他们,”紫罗兰提议(好像有这种可能似的),“什么也别说。就让这事自己平息下去吧。”
艾维阿姨坐在沙发上晃着身子,她头戴毡帽,身穿邋遢睡衣,脚套胶靴。“这下,他们会说咱家出了个怪胎啦,一准的!”
紫罗兰吩咐父母上床去,他们照做了,好像他们才是小孩。她自己尽管昨晚彻夜未眠,眼皮像被砂纸揉过,但她相信自己肯定是睡不着了。她从钟后取出黎明玫瑰写的所有纸片,看也不看,折叠起来塞进一个信封。她在信封里塞了张字条,写上特里夫的地址。
我们发现是谁写的这些了,她的字条上写道。是我妹妹。她十四岁。我不知道她是疯了还是怎么回事。我不知道该做什么。快过来接我走吧。我恨这里。你可以看看她脑袋里都是些什么哟。我在这里没法入睡。要是你爱我的话,请快来接我走吧。
她摸黑把信封塞进邮箱,又添了几分钱买邮票。她已经忘了里面原先的信和钱。那封信好像是多少天前的事了。
她躺在硬邦邦的客厅沙发上。黑暗中,她没法看到那幅从前她觉得那样强大、那样神秘的画。她试着记起它给她的感觉。她转眼就睡着了。
紫罗兰为什么要这么做?为什么要把这些丑陋的信寄给特里夫,并附上这样一张字条?她真希望他来拯救她,指导她吗?她真希望他帮忙解决黎明玫瑰的问题吗—甚至为此做点祷告?(自打这事一开始,紫罗兰压根就没想过祈祷,也不曾以任何方式想到上帝。)
她永远也搞不清楚自己为何要这么做。她失眠、焦虑,已经失去了正常的判断力。这就是原因吧。
这些信被取走之后,第二天一大早,紫罗兰亲自站在邮箱边。她要搭邮递员的车进镇,坐一点钟的火车回渥太华。
“你们这些人遇到什么麻烦事了吗?”邮递员说,“你爹地出事了吗?”
“没事了,”紫罗兰回答道,“都结束了。”
她知道从这里寄出的信会在第二天到达渥太华。有两次投递时间,上午一次,下午一次。要是特里夫一整天都不在家—他一般都这样—信会放在他租住的房子大厅里的高桌上,房子的主人是一位牧师遗孀。前门通常都不上锁。紫罗兰可以赶在他之前取走那些信。
特里夫在家。他得了一场严重的热感冒。他坐在书房里,脖子上裹块白围巾,好像伤口上的纱布。
“别靠近我,我全身都是病菌。”紫罗兰穿过屋子向他走去时,他拒绝道。从他的语调里,你会以为她才是那个全身病菌的人。
“你忘记把门开着了。”他说。紫罗兰去的时候,应该开着书房的门,免得牧师遗孀遭人非议。
在他的桌子上,他的书和布道笔记当中,摊着黎明玫瑰写的那些脏兮兮、皱巴巴、不堪入目的纸片。
“请坐,”特里夫说,声音疲倦、嘶哑,“请坐,紫罗兰。”
因此她不得不在他的书桌前坐下,像一个苦闷的教友,某个陷入麻烦的可怜的年轻女人。
他说并不奇怪她会来。他知道她没准会露面。他用的就是这个词:“露面。”
“要是你先到的话,你打算把它们撕掉。”他说。
是啊,确实。
“好让我永远不会知道。”他说。
“我会慢慢告诉你的。”
“我表示怀疑。”特里夫说,还是那种难听的嘶哑的声音。旋即他清清嗓子,“很抱歉,但是我表示怀疑。”他努力想表现得仁慈一点,耐心一点,更像个牧师的样子。
他们从下午一直谈到天黑。都是特里夫在讲。他摩擦着喉咙,让声音能继续发出来。他一直说到嗓子哑得不行,休息一会儿,然后又说起来。他说的话没有一句出乎紫罗兰的预料,从他迎上她的第一眼,她就全料到了。从他说“别靠近我”的那一刻。
此外,几天之后,她接到的他的来信里—他写下了没法当面对她说的最后一些话—也没有任何令她意外的东西。她其实都能帮他写出这封信。(信中还附上了黎明玫瑰写的所有纸片。)
身为牧师,很不幸,是没有太大自由去选择爱情的。牧师的妻子必须不会随身带来任何问题,以至于分散她丈夫的注意力,影响他对上帝和他的教友的奉献。牧师的妻子还必须身家清白,没有任何会引起谣言或者造成丑闻的亲戚。她经常要面对重重困难,所以她必须身心健康,没有任何遗传缺陷或毛病,才能承担起这种生活。
在那之前,他们进行了大量的重复、详述和打岔,其间还有过一些争论,讨论该不该带黎明玫瑰去看看这里的什么医生,是不是该把她关进什么地方。特里夫说,黎明玫瑰显然是神经错乱了。
不过,紫罗兰现在已不再希望特里夫帮她解决黎明玫瑰的问题,取而代之,她感觉必须在他面前捍卫黎明玫瑰。
“我们不能请求上帝治愈她吗?”她说。
从他的表情可以看出,他觉得她在侮辱他。应当由他,而不是她来提到上帝。不过他平静地解释道,上帝是通过医生来治愈人类的。通过医生、治疗、法律和医院。上帝是通过这些来运作的。
“在那种年纪,女性是容易得一种疯病的。”他说,“你明白我的意思。她恨男人。她谴责他们。这一点很明显。她对于男人有一种疯狂的仇恨。”
事后,紫罗兰好奇过,他当时是否在给她提供一条退路。要是她同意送黎明玫瑰去疯人院,他是否还会解除他们的婚约?或许不会了吧,尽管他力图表现得高人一等、头脑清醒,但其实他可能也很绝望吧。
有好多次,他不得不跟她说同一句话:“我不跟你说了。我没法跟你说下去,除非你不再哭了。”
牧师遗孀进门来,问他们是否要用晚餐。他们说不要,她摇着头走了。特里夫说他咽不下东西。天黑后他们出了门。他们沿街走到一家杂货店,买了两瓶奶昔,又给紫罗兰买了一份鸡肉三明治。鸡肉在嘴里味道像木屑。他们朝基督教女青年会走去,她在那里可以开一个房间过夜。(她在出租楼里的房间还给她留着,但她没法忍受回那里去。)她说她要搭一大早的火车走。
“你不用这么做。”特里夫说,“我们可以一起吃早饭。我的嗓子不行了。”
确实。他现在只能嘶嘶低语。
“我来接你。”他低语道,“我八点半来接你。”
但是再也没有把他的嘴唇或者凉凉的脸颊贴上她的。
早班火车七点五十发车,紫罗兰上了车。她打算写信通知出租楼的女主人和她打算去打工的教会办事处。她不会参加考试了。她在渥太华一天也没法多待。脑袋在早晨的阳光中疼痛不已。这一次,她真的彻夜无法合眼。火车开动时,她感觉好像特里夫正从她身边被拉走。不止是特里夫。她的整个生命都被拉走了—她的未来、她的爱情、她的运气,还有她的希望。所有一切都像皮肤一样被拉扯掉,也像皮肤被扯下时一样疼痛,只剩下一个赤裸、剧痛的自己。
那么,她鄙视他吗?就算有,她也不曾察觉。那不是什么她能体会出的感觉。要是他跟来了,她会回到他身边—那样开心,开心地。直到最后一刻,她还希望能看到他冲上月台。他知道早班火车什么时候开。他或许会醒来,知道她在做什么,会来追她。要是那样,她会在黎明玫瑰的事情上让步,会对他百依百顺。
但他没来找她,没跟来。人群中没有他的脸。她没法忍受再看任何人。
这样的时刻,紫罗兰想,想必就是人们做出你听说过或者在报纸上看到过的那种事的时刻吧。那种你会试着想象,或者竭力不去想象的事。她可以想象它,可以体会到它的感觉。阳光中的下坠,然后往砾石河岸上那么一撞。淹死可能更愉快一些,不过那需要更坚定的意志。你得坚决地,始终坚定不移地,拥抱河水,咽下它。
除非你是从桥上跳下。
这是紫罗兰干的事吗?她是思考着这些念头,被逼得无路可走,生命遭到彻底颠覆的人吗?她感觉像在看戏,只是自己身在其中,在戏里。她陷入了疯狂的危险。她闭上眼睛,飞快地祈祷起来—这也是戏的一部分,不过是真实的。她想,这是她生命中第一次真正的祈祷。
救救我,救救我。让我恢复理智吧。求求你,请赶紧啊。求求你。
她后来相信自己从这趟火车旅行中,在两个小时不到的时间里学到了一件事:祈祷是灵验的。绝望的祈祷果然灵验。她后来相信,她从前对于祈祷,对于灵验,其实毫无概念。现在,在火车里,有什么东西降临到她身上,包裹住她。神意降临到她身上,像凉丝丝、凉丝丝的衣服,包裹住她。
你生来不是为了嫁给他。
那不是你生命的意义。
不是要嫁给特里夫。那不是你生命的意义。
你的生命有一个目的,你知道那是什么。
照料他们。他们所有人,你家里的所有成员,尤其是黎明玫瑰。照料他们所有人,尤其是黎明玫瑰。
她望着窗外,醍醐灌顶。阳光照在羽毛一般柔软的六月草上,照在毛茛花、云兰花和古老光滑的岩石上,照耀着整片她原本绝不会喜欢的乱糟糟的乡间,一个字眼儿涌入她的脑海:“黄金”。
黄金般的机会。
关于什么的机会呢?
你知道是关于什么的。屈服。放弃。照顾他们。为了别人而活。
那就是紫罗兰发现的可以用来抛却痛苦的方式。一股沉甸甸的重负从她身上挪开了。如果她能够谦卑屈身,将昔日的自我,还有对于未来的所有设想也同样挪开,那么重负、痛苦和耻辱都将神奇地消失。她还有得到拯救的可能。她可以像六月草一样,清晨的光线掠过它,点燃它,把它变成粉色羽毛,变成一缕缕日出时分的云霞。只要她努力祈祷,努力尝试,就不是没有可能。
人们都说,比利大王自打受了惊吓之后便一日不如一日。他再也没有真正恢复。他们说他老了,明显枯萎了。不过,这一切发生的时候,他其实已经老了,早已不复当年。他四十多岁才结的婚。他继续挤牛奶,在家和谷仓之间来来回回,这样过了几个寒冬之后,得肺炎死了。
黎明玫瑰和美丽小希那时已经住到镇上。她们没上高中,在鞋厂找到了工作。美丽小希长成一个擅长交际的美人儿,迷住了一位名叫科拉德的销售员。他们结了婚,搬到埃德蒙顿。美丽小希生了三个女儿,会给家里写一些挺正常的信。
黎明玫瑰的模样和脾气也有了长进。她在鞋厂被公认为一个勤奋的工人,一个不好惹的人,心情好的时候,会讲一些精彩的笑话。她也结婚了—嫁给一个叫康普的,县城南部来的农夫。她再也没有什么古怪、不正常或疯狂的举止。据说她为人有点生硬—不过也就这点毛病。她生了一个儿子。
紫罗兰和艾维阿姨一起生活在农场上。她在市电话公司找了份工作,买了一辆汽车,开车上下班。她难道不能再参加一次教师资格考试吗?或许能,或许不能。她决定放弃,就是真的放弃了。她不想回头。她在工作上得心应手。
艾维阿姨仍在院子和果园里逛荡,寻找母鸡可能偷偷下蛋的地方,还是戴着帽子,穿着靴子。她努力记着进门前刮干净鞋底的泥,免得紫罗兰又要发火。
不过紫罗兰再没发过火。
一天下午下班后,紫罗兰开车去看黎明玫瑰。她们处得不错—黎明玫瑰的丈夫对紫罗兰很有好感—所以像这样不请自去并不唐突。
她发现房门敞开着。那是一个温暖的夏日。发胖了的黎明玫瑰沿走廊出来,说今天不宜待客,她正给地板刷清漆。确实如此—紫罗兰能闻到清漆的味道。黎明玫瑰没端来柠檬水,也不曾请紫罗兰在门廊上坐一会儿。那天她太忙了。
她那个害羞的小胖儿子,起了个古怪名字叫戴恩的,过来缠住她的腿。他平时很喜欢紫罗兰,但是今天表现得很奇怪。
紫罗兰开车走了。她当然不会知道,再过一年不到,黎明玫瑰就会因为慢性静脉炎导致的血栓死去。她沿一条低低的路开着,两边都是树木和浓密的灌木丛,她满脑袋想的不是黎明玫瑰,而是她自己,突然间她听到一个声音说:“她的生命是场悲剧。”
“她的生命是场悲剧。”这个声音一清二楚、不带情感地宣布。紫罗兰像瞎了一样,径直把汽车开出了路。路边的沟渠并不深,但里面非常泥泞,她没法把汽车倒出来。她绕着车子走,想看看轮子陷在什么地方,之后她站在车边,等有人过来帮她推一把。
真听到有辆车开来的时候,她意识到自己不想被人看见。她没法忍受那个。她从路上跑开,钻进树丛,钻进灌木丛,却被钩住了,被那些浆果灌木和小小的山楂刺灌给钩住了。她脱不了身。想躲,是因为她不想被看到,如果说她的生命是场悲剧的话。
二、附体
戴恩相信他对紫罗兰—他妈妈的姐姐—有一段记忆,那是在他妈去世之前。再往前他就不记得什么了。他几乎不记得他妈。他好像看到过他妈妈站在厨房水槽边的镜子前,把红头发塞进一顶深蓝色草帽。他记得帽子上有一截鲜红色缎带。想必她是为了去教堂穿衣打扮。他还记得看到过一条肿胀、深棕色的腿,他觉得那是她最后的病造成的。不过他疑心自己是否真看到过。腿怎么会是那种颜色呢?想必他是听到过人们谈论它吧。他听到过他们说她的腿肿得有水桶粗。
他想,他记得的那一次是紫罗兰像当时经常做的那样过来吃晚饭。她带来一个布丁,放在屋外的雪地上冰镇着。(那会儿农场人家都没冰箱。)然后下雪了,雪盖住布丁盘,把它完全埋住。戴恩记得天黑后,紫罗兰在积雪的院子里踩来踩去,嚷嚷着:“布丁,布丁,布丁快过来!”好像在唤狗一样。他笑得前仰后合,爸妈在走廊里也乐得不行。紫罗兰表演得更卖力了,干脆停下来吹口哨。
他妈妈去世后不久,外婆也去世了—她跟紫罗兰生活在一起,戴顶黑帽子,会不知疲倦、惟妙惟肖地学母鸡咕咕咯咯叫,召唤鸡群。之后,紫罗兰卖掉农场,搬到镇上,在贝尔电话公司找了份工作。第二次世界大战期间男人短缺,紫罗兰很快当到了经理。战争结束后,有人觉得她该让位,把职位让给要养家的男人。戴恩记得听到过谁这么议论来着—某个女人,没准是他爸的一个姐妹吧,说那样才是做善事呢。但他爸爸说,不,紫罗兰做得对。他说紫罗兰有胆识。
与已婚妇女—做母亲的女人们—穿的千篇一律的打褶子、缀珠子的连衣裙不同,紫罗兰穿半裙和衬衫,用活泼的格纹花呢、深蓝色或灰色华达呢百褶裙,配上好看的象牙色缎子衬衫,白乔其纱花边衬衫,或者粉色、黄色或银色绉绸衬衫。她的高级外套是皇家紫色的,带银狐领。她的头发没用手指绕出波浪,或者电烫出波纹,而是盘成一个大大的、深色的、非常贵气的发髻。她脸上敷了粉,透出娇嫩的粉红色,就像她那个大大的贝壳的颜色一样,有时她会让戴恩听一听那个贝壳。戴恩现在知道了,她的衣着和妆容其实就是那些日子里女商人和职业女性的装束。时髦而不失高雅,体型姣好又不至于过于纤细,既不像男人婆,也没有小女孩相。他曾经以为非凡独特的东西,其实并非如此。这是他长大后发现的关于大多数事情的真相。不过,在他记忆里,紫罗兰仍旧是个独树一帜、无法归类的人,昔日的紫罗兰绝不可以被抹杀。
在镇上,紫罗兰住的是皇家银行楼上的一套公寓。去那儿得爬上一段长长的、封闭的楼梯。起居室里高高的落地窗户叫作法式窗。它们通向两个小小的阳台,阳台上装着铸铁齐腰栏杆。墙上刷涂料,而不是贴墙纸,用的是一种浅绿色。紫罗兰买了一把鲜艳的苔绿色布料包裹的软垫沙发椅,还有一张咖啡桌,木头桌面上嵌着一个玻璃盘子。窗上挂的叫落地窗帘,配有拉杆。它们拉拢起来,便露出闪闪发亮的奶油色树叶从素淡奶油色底纹上飘出的图案。没有顶灯,只有落地灯。厨房里有节疤松木柜子和节疤松木打造的早餐区。再走一段楼梯—这回是露天的陡峭楼梯了—可以下到一个小小的后院,周围围着树篱,专属紫罗兰使用。它与外界隔绝,你可以尽情调整它,装点它,就像在起居室里一样。
在镇上上高中的头两年,戴恩经常去看紫罗兰。要是赶上暴风雨,就在公寓过夜。紫罗兰会在苔绿色沙发上给他铺一张床。那些日子里,他是个皮包骨头、饥肠辘辘的红发男孩—现在可没人相信他曾经皮包骨头过—而紫罗兰给他吃得很好。她让他睡前喝浇着发泡奶油的可可汁,给他吃装在塔皮里面的奶油鸡块、夹心蛋糕,还有叫作石头饼的玩意儿,是用枫糖浆做的。她只吃一片,其余都交给他对付。这些与他在家里跟爸爸和雇工吃的简陋速成饭相比,真是天壤之别。紫罗兰给他讲她在农场的童年,包括他妈和紫罗兰另一个现住埃德蒙顿的妹妹,以及他们的爸妈(她管他们叫作“角色”)。在这些故事里,每个人都是一个角色,所有事情都很好玩。
她买了一台留声机,给他放唱片,让他挑最喜欢的一张。他最喜欢的是她参加一家介绍古典音乐的唱片俱乐部时作为奖品得到的唱片。雷斯毕基[5]的《鸟》。她最喜欢的是《肯尼斯·麦凯莱[6]演唱的圣歌及世俗歌曲》。
她再也没去过农场。戴恩的爸爸过来接戴恩,从来都无暇喝杯咖啡。或许他害怕穿着农夫的衣服坐在这样一套雅致的公寓里。也或许他对紫罗兰在教堂里的做法仍有点不高兴。
刚开始镇上生活那会儿,紫罗兰在那里作了一个选择。教堂有两扇门。一扇给乡下人用—原先是因为它离车棚近—另一扇给城里人用。教堂里的格局也是同样:镇上的人待在教堂一侧,乡下人在另一侧。这里面并没有什么明显的优越感或者卑下感牵扯在内。人们只是习惯如此。甚至退休后搬到镇上的乡下人,也会设法不走城里人的门,尽管为此他们或许得特地绕过城里人的门,走到乡下人的门那里。
紫罗兰挪了地儿,再加上她的工作,这些显然让她成了一个城里人。不过,她第一次去教堂时,戴恩和他爸爸是教堂里她唯一认识的人。选择乡下人的门将显出忠诚,还有一点点骄傲,一种对特权的放弃。(因为确实,大多数长老、引座员和主日学校教师都是从镇上人那边挑出来的,正如新式帽子和时髦女士套装也大都涌现在那一侧。)选择镇上人的门,也就是紫罗兰所做的,则表现出对于地位的接受,甚至还有一种欲求更多的野心。
戴恩的爸爸之后在人行道上跟她开玩笑。“你喜欢和那一头的人为伍吗?”
“那扇门比较近嘛。”紫罗兰假装不明白他的意思,“我不知道什么这一头那一头的。我想有人口袋里装了根掐灭的雪茄。”
戴恩真希望紫罗兰没那样做。不是说他指望紫罗兰和他爸爸之间能发生什么严肃的事情—比如说结婚。他没法想象那个。他只是希望他们站在同一边,也就是和他站在一边。
六月的一个下午,戴恩考完试,去紫罗兰的公寓取一本落下的书。他得到允许,可以在她上班时到公寓学习。他喜欢打开法式窗,放进刚刚摆脱了积雪的乡村气息,这片土地现在遍布着水量充沛的小溪、有裂隙的沼泽、冒出嫩芽的柳树和热气腾腾的犁沟。尘土也会跟着进来,不过他总是想,他可以在她回家之前打扫干净。他在浅色、明亮的起居室里踱来踱去,默记着大块大块的知识,感觉好极了。屋里每样东西都与他正在学习的内容发生一点关联。其中有一张深色的图画,画着一个死去的国王和几位高贵的女士,他背诗时总盯着它看。那几位女士不知怎的让他想到紫罗兰。
他不知道紫罗兰在不在家,因为她每周下午休息的日子都不同。不过他上楼时听到了她的声音。
“是我。”他招呼道,等着她从厨房出来,问他考试的情况。
可她没有,而是嚷嚷着回答道:“戴恩!戴恩,真没想到你会来!过来跟我们一起喝咖啡吧!”
她把他介绍给厨房里的两个人,一个男人及他的妻子。泰比特夫妇。男人站在厨房台子前,女人坐在早餐桌边。戴恩见过这个男人。维克·泰比特,是个保险推销员。据说曾是职业垒球手,不过是在很久之前。他身材匀称、个头不高、彬彬有礼,总是衣冠楚楚的,像老练的运动员一样有种谦逊自信的气质。
紫罗兰没问戴恩考试的情况,而是一心继续忙着做咖啡。她先是取出早餐杯,又否定了它们,换上她的高级瓷器。她在早餐桌上铺了块台布,上面有一块淡淡的熨斗烫痕。
“哎哟,我好丢人哦。”紫罗兰笑道。
维克·泰比特也笑了。“确实,确实!”他说。
紫罗兰神经兮兮的笑,以及对戴恩的忽视,都让戴恩闷闷不乐。她在镇上待了好多年了,样子变化很大,可他好像突然才注意到。她头发不再盘成发髻,现在是一头剪得短短的鬈发,也不复原先那种深棕色,如今的发色更深沉、更黯淡,像巧克力软糖。她的红色唇膏太浓太艳,皮肤也粗糙了许多。此外,她还胖了不少,尤其是臀部周围。和谐的体型已经遭到破坏—简直像是在裙子下塞了圈笼子或垫子似的。
维克·泰比特一等咖啡倒好就宣布,他要端着杯子去院子里,看看新种的玫瑰灌木怎样了。
“哦,我想它们长了一种虫子!”紫罗兰说,好像这事让她兴高采烈,“恐怕是这样,维克!”
自始至终,做妻子的一直在说话,她持续不断地讲着,几乎没注意到丈夫已经出去。她跟紫罗兰,甚至跟戴恩说着话,不过她其实只是在对空气发言。她谈论与医生的约见,与按摩师的约见。她说她得了头痛的毛病,感觉就像被烧红的烙铁夹住了太阳穴似的。她的脖子一侧也有另一种剧痛,好像有千百根针扎进肉里。她一刻不停地说啊说啊,就像安装在早餐区角落的一台无助的小型讲话机,悲哀的大眼睛一旦盯住你,顿时变得黯然无神。
这正是紫罗兰最擅长模仿的一种人,一种谈话。
而现在,紫罗兰正敷衍着。她在倾听,或者假装在倾听这个女人,带着一种对方甚至都没注意到,也不需要的关注。这是因为做丈夫的出去了吗?紫罗兰因为他对妻子的粗鲁感到不安吗?她确实不时朝后院瞥去。
“我得去听听维克对那虫子的看法。”说着她跳了起来,脚步笨重慌乱地沿后院楼梯跑下去。
“他们在乎的只有他们的钱。”做妻子的说着。
戴恩站起来再倒一点咖啡。他站在炉子前,询问似的冲说话的人举举咖啡壶。
“我已经喝太多啦,”她说,“我胃里百分之九十都是疤痕组织。”
戴恩朝下看着她的丈夫和紫罗兰,他们正肩并肩站在新种的玫瑰灌木前。毫无疑问,他们在讨论玫瑰、虫子、杀虫剂和枯萎病。不曾发生什么像摸摸捏捏这样低俗的事。维克端着咖啡杯,小心地用脚尖掀起一片叶子,然后是另一片。紫罗兰的目光顺从地挪向他锃亮的皮鞋托起的树叶。
要说戴恩那会儿就看懂了什么,这并非事实。不过他忘掉了正在说话的女人和手中的咖啡壶。他感觉到有一个秘密,一种他人的亲密气息。某种他不想知道,但又不得不知道的东西。
此后不久,他和爸爸在街上走着,看到维克迎面过来。爸爸招呼道:“你好啊,维克。”用的是男人用来招呼一个他们不很熟—或者不想熟悉—的男人时那种平静、尊敬的口气。戴恩扭过脸,打量着五金店的橱窗。
“你不认识维克·泰比特吗?”爸爸问,“我以为你在紫罗兰家里见过他。”
然后戴恩又感觉到了它—他憎恨的那种气息。他现在更憎恨它了,因为它环绕在他周身。它环绕在他周身,挥之不去,即便他爸爸也知道了。
他不想搞清紫罗兰的背叛到了何种程度。他只知道永远也不会原谅她。
现在,戴恩变成了一个肩膀宽阔、面色红润的男人,有点像只磨损的泰迪熊,一把胡子已经几乎全灰。他长得越来越像他妈。他成了一名建筑师。他离开家上了大学,长期在外地生活和工作,不过几年前回来了,忙着修复教堂、市政大厅、商业街区和各种老房子。在他离开那会儿,它们曾经都被视为碍眼之物。他住在小时候的房子里,那幢他爸爸在里面出生,死去,有一百五十年历史的石头房子,他和西奥渐渐把它修复成原初的模样。
他和西奥一起生活,后者是个社会工作者。
戴恩第一次告诉维克和紫罗兰(他已经原谅她—他们了—在很久以前)有个叫作西奥的要搬来同住时,维克说:“我想,这意味着你终于确定一个当真的女朋友了。”
紫罗兰没说话。
“是个男朋友,”戴恩温和地解释道,“根据名字不好判断。”
“好吧。那是你和他自家的事。”维克体贴地说。他唯一流露出的一点点震惊痕迹,是说了“他自家”,却没发觉。
“西奥,确实,”紫罗兰说,“不容易判断。”
这番对话是在紫罗兰从电话公司退休后搬进的两卧室小房子里展开的,房子位于镇子边缘。维克的妻子去世后,他们得以结婚,之后维克便搬了进来。小房子位于一排类似的房子中间,坐落在一片玉米地前面,沿乡村小路一字排开。维克搬来后,他的东西加上紫罗兰的东西,让天花板低矮的房间显得挤挤挨挨的,东西摆得见缝插针、乱七八糟。苔绿色沙发上铺着维克前妻织的阿富汗毛毯,显得臃肿而过时。维克带来的一幅巨大的黑色天鹅绒绘画占据了一面卧室墙的大部分。画上是一头公牛和一个斗牛士。维克昔日的运动奖杯和保险公司赠送的银碟都摆在壁炉台上,和紫罗兰的旧贝壳还有没完没了饮酒的苏格兰人摆在一起。
所有这些招惹灰尘的旧玩意儿,紫罗兰这样称呼它们。
不过维克本人去世之后,她仍保留着他的东西。他在十一月底的格瑞杯赛季[7]去世。紫罗兰给戴恩打了电话,他接听电话时,一开始眼睛还盯着电视屏幕。
“我去了趟教堂,”紫罗兰说,“带了一些东西去参加旧货售卖会,然后去给我们买一瓶威士忌。回家时,我打开门喊了一声‘维克’,他没回答。我看到他的后脑勺位置怪怪的,倒向他的椅子扶手那里。我就绕到他前面,关了电视。”
“你说什么?”戴恩说,“紫罗兰姨妈?出什么事了?”
“哦,他死了。”紫罗兰说,好像戴恩问的就是这事,“他只有死了,才会让我关掉橄榄球直播。”她的声音响亮而一本正经,带着一种不自然的雀跃—仿佛是在掩饰窘迫之情。
他开车进镇,发现她坐在前门台阶上。
“我真是个傻瓜,”她说,“我没法进去。多蠢啊,戴恩。”她的声音仍旧高亢、响亮而明快。
西奥后来说,很多老人在亲近的人死去之后都会这样。“他们超越了悲痛,”他说,“或者说那是另一种悲痛吧。”
整个冬天,紫罗兰似乎一切正常。天好时,她会开车去教堂,去老年俱乐部打牌。然后,当天开始变热,你以为她会喜欢出门的时候,她对戴恩宣布再也不开车了。
他想问题可能出在她的视力上。他建议约个时间去看看她要不要配一副度数更深的眼镜。
“我看得很清楚,”她说,“我的问题在于,不能确定我看到的东西。”
什么意思?
“我看到一些明知不存在的东西。”
她怎么知道不存在?
“因为我还足够清醒,会判断。我的大脑收到那些信息,然后告诉我那是荒谬的。可要是不能总是这样有效,那怎么办?我该怎么判断呢?我可以让人送食品上门。大多数老人都是让人送食品上门的。我是个老人啦。艾匹超市的人不会多想念我的。”
不过戴恩知道她有多喜欢去艾匹超市。他想,他或者西奥或许可以每周开车送她去一次。在那里,她可以买到维克经常喝的特制浓咖啡,她还喜欢看看那些熏肉和培根—都是维克最喜欢吃的—尽管她很少会买。
“比如说吧,”紫罗兰说,“前几天早上,我看到比利大王来着。”
“你见到我外公了?”戴恩笑着说,“好吧。他现在怎么样?”
“我看到的是那匹叫比利大王的马。”紫罗兰简短地解释道,“我走出屋子,它正把脑袋从餐厅窗子探进来。”
她说一眼就能认出它。它那熟悉、傻气、带斑纹的灰脑袋。她命令它走开,离开这里。它把脑袋从窗台上抬起,悠悠闲闲地走了。紫罗兰进厨房做早饭,然后想起了一系列事情。
比利大王马死了已经有六十五年了。
那也不可能是牛奶工的马,因为牛奶工自打1950年以来就不用马车了。他们改开卡车。
不。他们没开任何车过来,因为早就没人送牛奶了。它甚至都不用瓶装了。人们都到商店里买纸盒或塑料袋装的牛奶。
餐厅窗子上有玻璃,玻璃也没破。
“我也从来没有特别喜欢过那匹马。”紫罗兰说,“不是说不喜欢它。不过要是消失了的东西或者人里让我挑选想再见到的,那可不会是那匹马。”
“那会是什么呢?”戴恩问,试图让谈话轻松一点,尽管他对于听到的事一点也不开心。“你会选什么?”
但是紫罗兰不高兴地哼了一声—一句不满的咕哝声,呃呃呃—仿佛这个问题让她生气了,甚至激怒了她。她的脸上流露出一种沉思的,甚至是乖戾的傻相—与那声咕哝正好相配。
几天之后的一个晚上,戴恩偶然看到一个关于南美洲居民—主要是女性居民—的电视节目。他们相信自己时不时会在特殊情境中被神灵入侵、附体。他们脸上的表情让他想起了紫罗兰。区别在于,他们追求这种附体,而他肯定紫罗兰正相反。她一点也不想被一个无助、恍惚、愚钝、固执,有着失控的、随时会在现实中冒出来的回忆或想象的老太婆附体。她想必会因为不得不控制住这个老太婆而脾气暴躁。事实上,他看到过她—现在他想起来了,看到过她偏着脑袋,往头上飞快地拍了一记,就像人们想驱赶什么挥之不去、让人不快的感觉一样。
夏天又过去了一个星期左右,她给他打电话。“戴恩,我告诉过你我看到的那两个路过我家的人了吗?”
“什么人,紫罗兰姨妈?”
“女孩子。我想是的吧。现如今男孩不留长发了,对吗?她们穿着军队制服,看起来是那样的,不过我不知道那能说明什么。一个矮个儿,另一个高个儿。我看到她们路过这幢房子,看了看它。她们走开去,又走了回来。”
“没准她们在捡瓶子,有人这么干。”
“她们没有装瓶子的东西啊。是这幢房子。她们感兴趣的是这个。”
“紫罗兰姨妈,你确定吗?”
“是的,我知道。我也这样问过自己。但她们不是什么我认识的人。她们也不是任何我知道的死去的人。这一点很重要。”
他想,该去看看她了,去看看究竟是怎么一回事。但他还没来得及去,她又来了电话。
“戴恩,我只是想跟你说说。关于从我家门口走过的那两个女孩子。她们是女孩,穿着军队制服。她们过来敲我的门了。她们说,她们在找一个叫作紫罗兰·托姆斯的人。我告诉她们这里没这个人,她们好像非常失望。然后我说,倒是有个叫作紫罗兰·泰比特的人,这个行吗?”
她听起来颇为兴奋。戴恩很忙。他半个小时后要与镇上的议员们开会。他还牙疼。不过他说:“那么,你是对的了。她们是谁?”
“这就是让人吃惊的地方了,”紫罗兰说,“她们不是一般的女孩。她们中的一位是你的表妹呢。我是说,是你表妹的女儿。多娜·科拉德的女儿。你知道我说的是谁吧?你表妹多娜·科拉德呀,她婚后的姓是麦克耐。”
“不知道。”戴恩说。
“你姨妈美丽小希,住在埃德蒙顿的那个,嫁给了一个叫科拉德的男人,罗伊·科拉德,她生了三个女儿。伊莱娜、露丝和多娜。现在你知道我说的是谁了吧?”
“我从没见过她们。”他说。
“嗯。好吧,多娜·科拉德嫁给了一个姓麦克耐的,我忘了他叫什么了,他们住在不列颠哥伦比亚的乔治王子城,来的是他们的女儿希瑟。路过我家的是他们的女儿希瑟呀。另外一个女孩是她的朋友,叫作吉莲。”
戴恩沉默了一分钟之久,紫罗兰说:“戴恩,希望你没觉得我老糊涂了。”
他笑了。他说:“我得过来看看她们。”
“她们非常有礼貌,好心肠,”紫罗兰说,“和她们的样子可不同。”
他相当确定这些女孩真的存在,不过那会儿一切在他听来都有点糊里糊涂的。(他不知道自己正在发低烧,之后不得不对牙齿采取根管治疗。)他确实打算到镇上打听打听,看看还有谁见过她们。过了一阵,等他确实着手去打听的时候,他发现符合描述的两个女孩在旅馆里住过,她们有一辆破旧的蓝色达特桑汽车,但是经常步行出门,在镇里镇外都一样。大家都认为她们是搞妇女解放的。人们对她们的衣服不怎么看得上眼,不过她们也没惹什么麻烦,只是在旅馆里跟脱衣舞者发生了一些争论。
同时,他从紫罗兰那里听到了很多。她打电话到他家时,他的牙齿正酸痛,几乎没法讲话。她说,很遗憾他身体不好—否则就可以过来看看希瑟和吉莲了。
“希瑟是个子高的那个,”紫罗兰说,“她有长长的金发,体型瘦削。要说她有哪里像美丽小希,那就是她的牙齿了。不过希瑟的牙齿挺配她的脸型的,洁白美丽。吉莲是个好看的女孩,鬈发,晒得黑黑的。希瑟的白皮肤一晒就发红。她们穿的是一样的衣服—你知道的,军装裤子和工作制服衬衫,还有男孩子的靴子—不过吉莲总是系着皮带,竖起领子,她这么穿显得挺时髦的呢。吉莲更自信一点,但是我觉得希瑟更聪明。她更感兴趣呢。”
“对什么感兴趣?”戴恩问,“说到底,她们是什么人呢—学生吗?”
“她们上了大学,”紫罗兰说,“我不知道她们学的是什么。她们去过法国和墨西哥。在墨西哥,她们住在一个叫作女人岛的地方。那是一个女人统治的世界。她们在一家剧院工作,做编剧。她们自己写剧本。不接受别的作者的剧本,也不演现成就有的剧本。这家剧院里全是女人。她们给我做了一顿好吃的晚饭。戴恩,真希望你能来这里。她们做了一道有朝鲜蓟心的沙拉呢。”
“紫罗兰听起来好像嗑药了似的,”戴恩对西奥说,“听起来好像她们把她给迷昏头了。”
一恢复说话能力,他就给她打电话。“那些女孩感兴趣的是什么,紫罗兰姨妈?她们是对旧瓷器和珠宝之类的感兴趣吗?”
“不是啊,”紫罗兰生气地答道,“她们对家族历史感兴趣。她们对我们的家族和我记得的事感兴趣。我不得不跟她们解释炉子上的储水罐是怎么回事。”
“她们打听那个做什么?”
“哦。她们有点想法。想用那个来写剧本。”
“她们哪里懂什么剧本?”
“我没告诉你吗,她们参加戏剧演出的?她们自己写剧本自己演,在那个女人的剧院里。”
“她们想写什么样的剧本?”
“我也不知道。我不知道她们会不会真写。她们只是对过去的日子感兴趣。”
“现在正流行这个,”戴恩说,“对过去感兴趣。”
“她们不是装装样子的,戴恩。真的感兴趣。”
不过,他觉得这回她听起来没那么兴奋了。
“你知道她们会把所有名字都改掉,”她说,“写戏的时候,会换掉所有的名字和地名。不过我想,她们只是想打听打听事情,聊聊而已。她们其实没那么年轻,只是看着挺小的。她们充满好奇,而且无忧无虑的。”
“你的脸不一样了,”戴恩终于去看紫罗兰时说,“你瘦了吗?”
紫罗兰说:“我想没有吧。”
戴恩自己瘦了十二磅,但她都没在意。她看起来很高兴,又有点躁动不安。她不断站起又坐下,看看窗外,漫无目的地把厨房里的东西挪来挪去。
女孩们已经走了。
“她们不回来了吗?”戴恩问。
不,要回来的。紫罗兰觉得她们会回来,只是不知何时。
“去找她们那个岛了吧,我猜,”戴恩说,“她们那个女人统治的岛。”
“不知道。”紫罗兰说,“我想她们去蒙特利尔了。”
戴恩不愿相信他竟会因为两个从未谋面的女孩如此不安、狐疑。他几乎要将之归罪于他为了牙痛不得不服的药了。他有种感觉,好像有什么东西瞒着他—它遍布在他四周,却瞒着他—某个无聊、愚蠢、恶毒的秘密。
“你剪了头发。”他说。正是因为这个,她的脸才不一样了。
“是她们剪的。她们说这是圣女贞德的发型。”紫罗兰像习惯的那样,揶揄一笑,摸了摸头发。“我告诉她们,我可不希望到头来给绑在柱子上烧死。”
她抱着脑袋,前后摇晃着。
“她们把你弄烦了,”戴恩说,“她们把你弄烦啦,紫罗兰姨妈。”
“是因为要整理所有那些东西。”紫罗兰解释道。她冲后面那间卧室晃了晃脑袋。“是因为我在那里要对付的那些东西。”
紫罗兰家的次卧室里有好几大箱文件,还有一个属于她妈妈的古老拱顶箱。戴恩觉得里面想必同样全是文件。古老的高中笔记,师范学院笔记,成绩单,她在电话公司工作那么多年里的记录和通讯,会议备忘,信函,明信片。任何上面写字的东西,她可能都保留了下来。
她说,所有这些文件都得整理出来。必须在女孩们回来之前弄好。她答应过她们一些事的。
“什么事?”
“就是一些事罢了。”
她们很快就会回来吗?
紫罗兰说是的。她觉得是这样的。想着这事的时候,她的双手在桌面上揉来揉去。她咬了一口饼干,把剩下的部分捏碎。戴恩看到她把饼干屑扫到手心,倒进她的咖啡。
“她们寄来了这个。”她说,把一张卡片推向他。它靠在糖罐上搁着,他之前注意到过。一张手制卡片,用蜡笔画着孩子气的紫罗兰图案,还有小小的红心。她似乎希望他读它,于是他照做了。
无比,无比感谢您的帮助和坦诚。您给我们提供了一个精彩的故事。这是一个关于反父权主义之怒火的经典故事。您给我们的这份礼物,我们可以传递给别人吗?所谓的女性之疯狂,其实不是别的,正是数个世纪的打击压迫的结果。关于小溪的那段实在太精彩了,有多少女人会产生共鸣啊!
在底部,用大写字母写着:期待早日看到那些文件。下次一定。对您充满爱意和感激。
“这一切是怎么回事?”戴恩说,“你干吗非得帮她们整理文件?她们不能自己在这堆破烂里翻翻,找到想要的东西吗?”
“因为我不好意思啊!”紫罗兰激动地说,“我不想任何人看到这些。”
他告诉她根本,根本没什么不好意思的。
“我不该说‘破烂’。我只是想说,你在这么多年里存下了不少东西啊。有些可能很有意思呢。”
“没人知道它们的意义!我必须亲自整理它们!”
“反父权主义之怒火,”戴恩又拾起那张卡片,“她们是什么意思呢?”他想知道她们为什么用大写来强调“女性之疯狂”和“打击压迫”。
“告诉你吧,”紫罗兰说,“让我来告诉你吧。你不知道我不得不与之作战的是什么。有好多事情并不是那么美妙啊。我走进来,打开那个旧箱子,看了看里面,你知道我找到了什么吗,戴恩?全都是脏东西。马粪。一排排摆着。是故意的啊。在我自己家里,在我的箱子里,我发现的就是这个。”她抽泣起来,这一点也不像她,毫无迷人之处,自怨自艾的。
戴恩告诉西奥这事,西奥笑了,说:“听说这事我很难过。她说什么了吗?”
“我说我要去看看,她说都扔掉了。”
“确实。不错,看起来好像哪里出岔子了,对吗?我想我能感觉到它快来啦。”
戴恩想起来她的另一句话,不过他没说。那不重要。
“那是个恶心的玩笑,对吗?”她抽泣道,“那种弱智才能想得出来的玩笑!”
第二天,戴恩一口气开出镇子,开到紫罗兰门前的小路,看到她的前门大中午就敞开着。他通常不会走这条路。今天这么做并不奇怪,因为过去几个小时里,他脑海中一直都是紫罗兰。
他想必是在火焰刚刚在厨房升起时进的门。他先看到了它们在厨房墙上映出的亮光。他冲进去,紫罗兰正往煤气炉上堆文件。她点着了火。
戴恩从大厅里抓起一张小地毯掩护自己,设法关掉了煤气。烧着的纸片飘到空中。地板上堆满纸张,有些还装在盒子里。紫罗兰显然打算把它们全烧掉。
“哦,耶稣啊,紫罗兰姨妈!”戴恩嚷道,“耶稣啊,耶稣啊,你在做什么!快出去!出去!”
紫罗兰站在屋子中央,像一截黑色木桩扎根在那里,周身飘扬着燃烧的纸片。
“出去!”戴恩吼道,把她扳转身,推向后门。突然之间,刚才绝对的静止变成了惊人的速度。她跑向,或者说是一头扎向门口,打开门,跑进后门的走廊。她没冲下台阶,而是从走廊边缘径直跌下去,头朝下栽进维克种的玫瑰灌木。
戴恩没有立刻发现她跌下去了。他在厨房里手忙脚乱。
幸运的是,一堆堆或者一捆捆的纸张不像人们以为的那样容易着火。戴恩更担心的倒是窗帘或炉子后头发干的油漆墙。紫罗兰不再像从前那样精心料理家务了,墙壁油腻腻的。他用小地毯按住炉子上蹿起的火焰,然后想起他亲自买来,要求紫罗兰收在厨房柜子里的灭火器。他举着灭火器在厨房里跌跌撞撞地跑着,追逐着火的小鸟们,把它们变成落到地上的焦纸片。他被地上的一堆堆纸张绊住脚步。不过窗帘没着火。炉子后头墙上的油漆冒出泡泡,不过也没烧起来。他继续追逐着,用了五分钟或者更短时间就扑灭了火。只有烧焦的纸片,如肮脏的飞蛾翅膀一般,落在所有东西上面—真是一团糟。
他看到紫罗兰倒在地上,陷在玫瑰灌木中间,作好了最坏的打算。他担心她中风了,或者心脏病发作,或者至少也在跌下去时摔裂了骨盆。不过她很清醒,挣扎着爬了起来,呻吟着。他抓住她,帮她站起身。两人都发出好多痛苦的呻吟和感叹之后,他终于帮她走到后门台阶,让她坐在上面。
“你这血是哪来的?”他问。她的胳膊上沾着泥土和鲜血。
“玫瑰戳的。”紫罗兰说。听到她的声音,他知道她没什么大碍。
“玫瑰狠狠地刮伤了我,”她说,“戴恩,你看起来真糟糕!你看起来真糟糕,全身黑乎乎的!”
他的脸上泪水和汗水混成一道。他用手擦擦脸,手顿时变黑了。“烟熏的。”他说。
她是那样平静,以至于他猜想她或许有一点轻微的中风,记忆缺失了,正好能让她忘掉刚才的火灾。不过她没忘。
“我甚至没用什么煤油嘛,”她说,“戴恩,我没用煤油什么的。火怎么会烧成那样?”
“那可不是烧柴火的炉子,紫罗兰姨妈。那是在煤气炉上啊。”
“哦,天哪。”
“你肯定以为是在柴火炉子上烧文件吧。”
“肯定是的。我多蠢哪。你赶来扑灭了它。”
他试图从她的头发上挑出黑纸屑,但是手指一捏,它们就碎了。裂成更小的碎片,消失不见。
“我得谢谢你啊。”紫罗兰说。
“我们现在要做的,”他说,“是送你去医院,确保你没有问题。你可以休息几天,我们帮你把厨房清理一下。行吗?”
她一阵呻吟,不过听起来挺平静的,那意味着同意。
他晚上会跟西奥谈一谈。他们会设法想出个方案。
“你得盯着我点,免得我把这地方整个烧喽。”
“没问题。”
“哦,戴恩,这可不是开玩笑。”
第三天晚上,紫罗兰在医院去世了,之前毫无征兆。或许是一种延迟反应吧,受惊吓的结果。戴恩在后院的焚烧炉里烧掉了所有文件。她从来不曾吩咐他这么做。她再也没提及她在做的事。她再也没提及那些女孩们,或者那年夏天发生的任何事。他只是觉得应当完成她没做完的事。他一边烧着,一边计划该如何斥责那些女孩。不过等他弄完,他觉得自己对她们未免过于严厉了—尽管给她惹了麻烦,可她们也给她带来了快乐嘛。
在那个炎热、几乎万里无云的午后,他们还坐在后院台阶上,面对绿色玉米林的时候,紫罗兰摸摸胳膊上的擦痕说:“这让我想起一些事。”
“我该给你涂点滴露的。”戴恩说。
“好好坐着。你想,到这会儿了,还有什么细菌没进入我的血管呢?”
他坐定了,她说:“你知道,维克和我是朋友。戴恩,在我们能够结婚之前很久很久就是。”
“知道。”
“嗯。这些擦伤让我想起我们是怎么认识,又是怎么变成那样的好朋友的,因为当然了,我们第一眼就互相对上了。我开着我的第一辆车,那辆V8,你可能都不记得了,我开出了路面。我开进了一条小沟,倒不出来。所以当我听到有辆车开来,就在那儿等着,但是我突然觉得没脸见人。”
“你因为开出了路面而害臊吗?”
“我感觉糟透了。正因如此,我才开出了路面。我莫名其妙就感觉很糟,就算有什么原因,也是某件不值一提的小事吧。我没法见任何人,所以我躲进了灌木,结果立刻被钩住了。我想转个身,扭来扭去的却怎么也挣不脱。我越扭,擦伤得越厉害。我穿着一件薄薄的夏天的裙子。不过那车还是停下了。是维克。我从没告诉过你这个吧,戴恩?”
没有。
“是维克开着车路过。他吩咐道,待着别动,然后他走过来,从我身上摘下那些浆果藤和枝条。我感觉自己像困在陷阱里的一头牛。不过他没笑话我—他看到一个人陷在那样的困境里,似乎一点也不觉得怪。结果倒是我自己笑了起来,看到他穿着那身浅蓝色夏季西装,那样一本正经地围着我忙活的样子。”
她上下抚摸着胳膊,指尖在擦出的伤口上描一描,拍了拍。
“我刚才在说什么?”
“你被灌木钩住了,维克帮你解脱了出来。”
她快速拍着胳膊,摇着头,喉咙里发出表示不耐烦或厌恶的呻吟声:呃呃呃。
她坐直身体,响亮地,却又像是在推心置腹地说:“有只野猪在玉米地里拱来拱去呢。”
“后来你笑了。”戴恩像没听到似的说。
“不错,”紫罗兰点点头,竭力按捺住不耐烦,“不错,我们笑了。”
[1] 比利为威廉的昵称。
[2] 纪念荷兰奥兰治亲王威廉(俗称比利大王)的新教游行。
[3] 1850年代加拿大政府规划的路线,意在鼓励对安大略省东北部的开发。
[4] 用嘴咬起漂浮在大水盆中的苹果的游戏。
[5] 1879—1936,意大利作曲家。
[6] 1927—2010,苏格兰男高音歌唱家。
[7] 加拿大最大的年度橄榄球赛季,始于1909年。
```
关于文学的语言问题-老舍
========================
关于文学的语言问题-[[老舍]]
-----
我想谈一谈文学语言的问题。
我觉得在我们的文学创作上相当普遍地存着一个缺点,就是语言不很好。
语言是文学创作的工具,我们应该掌握这个工具。我并不是技术主义者,主张只要语言写好,一切就都不成问题了。要是那么把语言孤立起来看,我们的作品岂不都变成八股文了么?过去的学究们写八股文就是只求文字好,而不大关心别的。我们不是那样。我是说:我们既然搞写作,就必须掌握语言技术。这并非偏重,而是应当的。一个画家而不会用颜色,一个木匠而不会用刨子,都是不可想像的。
我们看一部小说、一个剧本或一部电影片子,我们是把它的语言好坏,算在整个作品的评价中的。就整个作品来讲,它应该有好的,而不是有坏的,语言。语言不好,就妨碍了读者接受这个作品。读者会说:罗哩罗嗦的,说些什么呀?这就减少了作品的感染力,作品就吃了亏!
在世界文学名著中,也有语言不大好的,但是不多。一般地来说,我们总是一提到作品,也就想到它的美丽的语言。我们几乎没法子赞美杜甫与莎士比亚而不引用他们的原文为证。所以,语言是我们作品好坏的一个部分,而且是一个重要部分。我们有责任把语言写好!
我们的最好的思想,最深厚的感情,只能被最美妙的语言表达出来。若是表达不出,谁能知道那思想与感情怎样的好呢?这是无可分离的、统一的东西。
要把语言写好,不只是“说什么”的问题,而也是“怎么说”的问题。创作是个人的工作,“怎么说”就表现了个人的风格与语言创造力。我这么说,说的与众不同,特别好,就表现了我的独特风格与语言创造力。艺术作品都是这样。十个画家给我画像,画出来的都是我,但又各有不同。每一个里都有画家自己的风格与创造。他们各个人从各个不同的风格与创造把我表现出来。写文章也如此,尽管是写同一题材,可也十个人写十个样。从语言上,我们可以看出来作家们的不同的性格,一看就知道是谁写的。莎士比亚是莎士比亚,但丁是但丁。文学作品不能用机器制造,每篇都一样,尺寸相同。翻开《红楼梦》看看,那绝对是《红楼梦》,绝对不能和《儒林外史》调换调换。不像我们,大家的写法都差不多,看来都像报纸上的通讯报导。甚至于写一篇讲演稿子,也不说自己的话,看不出是谁说的。看看爱伦堡的政论是有好处的。他谈论政治问题,还保持着他的独特风格,教人一看就看出那是一位文学家的手笔。他谈什么都有他独特的风格,不“人云亦云”,正像我们所说:“文如其人”。
不幸,有的人写了一辈子东西,而始终没有自己的风格。这就吃了亏。也许他写的事情很重要,但是因为语言不好,没有风格,大家不喜欢看;或者当时大家看他的东西,而不久便被忘掉,不能为文学事业积累财富。传之久远的作品,一方面是因为它有好的思想内容,一方面也因为它有好的风格和语言。
这么说,是不是我们都须标奇立异,放下现成的语言不用,而专找些奇怪的,以便显出自己的风格呢?不是的!我们的本领就在用现成的、普通的语言,写出风格来。不是标奇立异,写的使人不懂。“啊,这文章写的深,没人能懂!”并不是称赞!没人能懂有什么好处呢?那难道不是胡涂文章么?有人把“白日依山尽……更上一层楼”改成“……更上一层板”,因为楼必有楼板。大家都说“楼”,这位先生非说“板”不可,难道就算独特的风格么?
同是用普通的语言,怎么有人写的好,有人写的坏呢?这是因为有的人的普通言语不是泛泛地写出来的,而是用很深的思想、感情写出来的,是从心里掏出来的,所以就写的好。别人说不出,他说出来了,这就显出他的本领。为什么好文章不能改,只改几个字就不像样子了呢?就是因为它是那么有骨有肉,思想、感情、文字三者全分不开,结成了有机的整体;动哪里,哪里就会受伤。所以说,好文章不能增减一字。特别是诗,必须照原样念出来,不能略述大意,(若说:那首诗好极了,说的是木兰从军,原句子我可忘了!这便等于废话!)也不能把“楼”改成“板”。好的散文也是如此。
运用语言不单纯地是语言问题。你要描写一个好人,就须热爱他,钻到他心里去,和他同感受,同呼吸,然后你就能够替他说话了。这样写出的语言,才能是真实的,生动的。普通的话,在适当的时间、地点、情景中说出来,就能变成有文艺性的话了。不要只在语言上打圈子,而忘了与语言血肉相关的东西——生活。字典上有一切的字。但是,只抱着一本字典是写不出东西来的。
我劝大家写东西不要贪多。大家写东西往往喜贪长,没经过很好的思索,没有对人与事发生感情就去写,结果写得又臭又长,自己还觉得挺美——“我又写了八万字!”八万字又怎么样呢?假若都是废话,还远不如写八百个有用的字好。好多古诗,都是十几二十个字,而流传到现在,那不比八万字好么?世界上最好的文字,就是最亲切的文字。所谓亲切,就是普通的话,大家这么说,我也这么说,不是用了一大车大家不了解的词汇字汇。世界上最好的文字,也是最精练的文字,哪怕只几个字,别人可是说不出来。简单、经济、亲切的文字,才是有生命的文字。
下面我谈一些办法,是针对青年同志最爱犯的毛病说的。
第一,写东西,要一句是一句。这个问题看来是很幼稚的,怎么会一句不是一句呢?我们现在写文章,往往一直写下去,半篇还没一个句点。这样一直写下去,连作者自己也不知道写到哪里去了,结果一定是胡涂文章。要先想好了句子,看站得稳否,一句站住了再往下写第二句。必须一句是一句,结结实实的不摇摇摆摆。我自己写文章,总希望七八个字一句,或十个字一句,不要太长的句子。每写一句时,我都想好了,这一句到底说明什么,表现什么感情,我希望每一句话都站得住。当我写了一个较长的句子,我就想法子把它分成几段,断开了就好念了,别人愿意念下去;断开了也好听了,别人也容易懂。读者是很厉害的,你稍微写得难懂,他就不答应你。
同时,一句与一句之间的联系应该是逻辑的、有机的联系,就眼咱们周身的血脉一样,是一贯相通的。我们有些人写东西,不大注意这一点。一句一句不清楚,不知道说到哪里去了,句与句之间没有逻辑的联系,上下不相照应。读者的心里是这样的,你上一句用了这么一个字,他就希望你下一句说什么。例如你说“今天天阴了”,大家看了,就希望你顺着阴天往下说。你的下句要是说“大家都高兴极了”,这就联不上。阴天了还高兴什么呢?你要说“今天阴天了,我心里更难过了。”这就联上了。大家都喜欢晴天,阴天当然就容易不高兴。当然,农民需要雨的时候一定喜欢阴天。我们写文章要一句是一句,上下联贯,切不可错用一个字。每逢用一个字,你就要考虑到它会起什么作用,人家会往哪里想。写文章的难处,就在这里。
我的文章写的那样白,那样俗,好象毫不费力。实际上,那不定改了多少遍!有时候一千多字要写两三天。看有些青年同志们写的东西,往往吓我一跳。他下笔万言,一笔到底,很少句点,不知道到哪里才算完,看起来让人喘不过气来。
第二,写东西时,用字,造句必须先要求清楚明白。用字造句不清楚、不明白、不正确的例子是很多的。例如“那个长得像驴脸的人”,这个句子就不清楚、不明确。这是说那个人的整个身子长得像驴脸呢,还是怎么的?难道那个人没胳膊没腿,全身长得像一张驴脸吗,要是这样,怎么还像人呢?当然,本意是说:那个人的脸长得像驴脸。
所以我的意见是:要老老实实先把话写清楚了,然后再求生动。要少用修辞,非到不用不可的时候才用。在一篇文章里你用了一个“伟大的”,如“伟大的毛主席”,就对了;要是这个也伟大,那个也伟大,那就没有力量,不发生作用了。乱用比喻,那个人的耳朵像什么,眼睛像什么……就使文章单调无力。要知道:不用任何形容,只是清清楚楚写下来的文章,而且写的好,就是最大的本事,真正的工夫。如果你真正明白了你所要写的东西,你就可以不用那些无聊的修辞与形容,而能直截了当、开门见山地写出来。我们拿几句古诗来看看吧。像王维的“隔牖风惊竹”吧,就是说早上起来,听到窗子外面竹子响了。听到竹子响后,当然要打开门看看,嗐!这一看,下一句就惊人了,“开门雪满山”!这没有任何形容,就那么直接说出来了。没有形容雪,可使我们看到了雪的全景。若是写他打开门就“哟!伟大的雪呀!”“多白的雪呀!”便不会惊人。我们再看看韩愈写雪的诗吧。他是一个大文学家,但是他写雪就没有王维写的有气魄。他这么写:“随车翻缟带,逐马散银杯。”他是说车子在雪地里走,雪随着车轮的转动翻起两条白带子;马蹄踏到雪上,留了一个一个的银杯子。这是很用心写的,用心形容的。但是形容的好不好呢?不好!王维是一语把整个的自然景象都写出来,成为名句。而韩愈的这一联,只是琐碎的刻画,没有多少诗意。再如我们常念的诗句“山雨欲来风满楼”。这么说就够了,用不着什么形容。像“满城风雨近重阳”这一句诗,是抄着总根来的,没有枝节琐碎的形容,而把整个“重阳”季节的形色都写了出来。所以我以为:在你写东西的时候,要要求清楚,少用那些乱七八糟的修辞。你要是真看明白了一件事,你就能一针见血地把它写出来,写得简练有力!
我还有个意见:就是要少用“然而”、“所以”、“但是”,不要老用这些字转来转去。你要是一会儿“然而”,一会儿“但是”,一会儿“所以”,老那么绕湾子,不但减弱了文章的力量,读者还要问你:“你到底要怎么样?你能不能直截了当地说话!?”不是有这样一个故事吗?我们的大文学家王勃写了两句最得意的话:“落霞与孤鹜齐飞,秋水共长天一色。”传说,后来他在水里淹死了,死后还不忘这两句,天天在水上闹鬼,反复念着这两句。后来有一个人由此经过,听见了就说:“你这两句话还不算太好。要把‘与’字和‘共’字删去,改成‘落霞孤鹜齐飞,秋水长天一色’,不是更挺拔更好吗?”据说,从此就不闹鬼了。这把鬼说服了。所以文章里的虚字,只要能去的尽量把它去了,要不然死后想闹鬼也闹不成,总有人会指出你的毛病来的。
第三,我们应向人民学习。人民的语言是那样简练、干脆。我们写东西呢,仿佛总是要表现自己:我是知识分子呀,必得用点不常用的修辞,让人吓一跳啊。所以人家说我们写的是学生腔。我劝大家有空的时候找几首古诗念念,学习他们那种简练清楚,很有好处。你别看一首诗只有几句,甚至只有十几个字,说不定作者想了多少天才写成那么一首。我写文章总是改了又改,只要写出一句话不现成,不响亮,不像口头说的那样,我就换一句更明白、更俗的、务期接近人民口语中的话。所以在我的文章中,很少看到“愤怒的葡萄”、“原野”、“熊熊的火光”……这类的东西。而且我还不是仅就着字面改,像把“土”字换成“地”字,把“母亲”改成“娘”,而是要从整个的句子和句与句之间总的意思上来考虑。所以我写一句话要想半天。比方写一个长辈看到自己的一个晚辈有出息,当了干部回家来了,他拍着晚辈的肩说:“小伙子,‘搞’的不错呀!”这地方我就用“搞”,若不相信,你试用“做”,用“干”,准保没有用“搞”字恰当、亲切。假如是一个长辈夸奖他的子侄说:“这小伙子,做事认真。”在这里我就用“做”字,你总不能说,“这小伙子,‘搞’事认真。”要是看见一个小伙子在那里劳动的非常卖力气,我就写:“这小伙子,真认真干。”这就用上了“干”字。像这三个字:“搞”、“干”、“做”都是现成的,并不谁比谁更通俗,只看你把它搁在哪里最恰当、最合适就是了。
第四,我写文章,不仅要考虑每一个字的意义,还要考虑到每个字的声音。不仅写文章是这样,写报告也是这样。我总希望我的报告可以一字不改地拿来念,大家都能听得明白。虽然我的报告作的不好,但是念起来很好听,句子现成。比方我的报告当中,上句末一个字用了一个仄声字,如“他去了”。下句我就要用个平声字。如“你也去吗?”让句子念起来叮当地响。好文章让人家愿意念,也愿意听。
好文章不仅让人愿意念,还要让人念了,觉得口腔是舒服的。随便你拿李白或杜甫的诗来念,你都会觉得口腔是舒服的,因为在用哪一个字时,他们便抓住了那个字的声音之美。以杜甫的“烽火连三月,家书抵万金”来说吧,“连三”两字,舌头不用更换位置就念下去了,很舒服。在“家书抵万金”里,假如你把“抵”字换成“值”字,那就别扭了。字有平仄——也许将来没有了,但那是将来的事,我们是谈现在。像北京话,现在至少有四声,这就有关于我们的语言之美。为什么不该把平仄调配的好一些呢?当然,散文不是诗,但是要能写得让人听、念、看都舒服,不更好吗?有些同志不注意这些,以为既是白话文,一写就是好几万字,用不着细细推敲,他们吃亏也就在这里。
第五,我们写话剧、写电影的同志,要注意这个问题:我们写的语言,往往是干巴巴地交代问题。譬如:惟恐怕台下听不懂,上句是“你走吗?”下句一定是“我走啦!”既然是为交代问题,就可以不用真感情,不用最美的语言。所以我很怕听电影上的对话,不现成,不美。
我们写文章,应当连一个标点也不放松。文学家嘛,写文艺作品怎么能把标点搞错了呢?所以写东西不容易,不是马马虎虎就能写出来的。所以我们写东西第一要要求能念。我写完了,总是先自己念念看,然后再念给朋友听。文章要完全用口语,是不易作到的,但要努力接近口语化。
第六,中国的语言,是最简练的语言。你看我们的诗吧,就用四言、五言、七言,最长的是九言。当然我说的是老诗,新诗不同一些。但是哪怕是新诗,大概一百二十个字一行也不行。为什么中国古诗只发展到九个字一句呢?这就是我们文字的本质决定下来的。我们应该明白我们语言文字的本质。要真掌握了它,我们说话就不会绕湾子了。我们现在似乎爱说绕湾子的话,如“对他这种说法,我不同意!”为什么不说:“我不同意他的话”呢?为什么要白添那么些字?又如“他所说的,那是废话。”咱们一般地都说:“他说的是废话。”为什么不这样说呢?到底是哪一种说法有劲呢?
这种绕湾子说话,当然是受了“五四”以来欧化语法的影响。弄的好嘛,当然可以。像说理的文章,往往是要改换一下中国语法。至于一般的话语为什么不按我们自己的习惯说呢?
第七,说到这里,我就要讲到一个很重要的问题,就是深入浅出的问题。提到深入,我们总以为要用深奥的、不好懂的语言才能说出很深的道理。其实,文艺工作者的本事就是用浅显的话,说出很深的道理来。这就得想办法。必定把一个问题想得透彻了,然后才能用普通的、浅显的话说出很深的道理。我们开国时,毛主席说:“中国人民站起来了。”中国经过了多少年艰苦的革命过程,现在人民才真正当家作主。这一句说出了真理,而且说得那么简单、明了、深入浅出。
第八,我们要说明一下,口语不是照抄的,而是从生活中提炼出来的。举一个例子:唐诗有这么两句:“大漠孤烟直,长河落日圆。”这都没有一个生字。可是仔细一想,真了不起,它把大沙漠上的景致真实地概括地写出来了。沙漠上的空气干燥,气压高,所以烟一直往上升。住的人家少,所以是孤烟。大河上,落日显得特别大,特别圆。作者用极简单的现成的语言,把沙漠全景都表现出来了。没有看过大沙漠,没有观察力的人,是写不出来的。语言就是这样提炼的。有的人到工厂,每天拿个小本记工人的语言,这是很笨的办法。照抄别人的语言是笨事,我们不要拼凑语言,而是从生活中提炼语言。
语言须配合内容:我们要描写一个个性强的人,就用强烈的文字写,不是写什么都是那一套,没有一点变化,也就不能感动人。《红楼梦》中写到什么情景就用什么文字。文字是工具,要它干什么就干什么,不能老是那一套。《水浒》中武松大闹鸳鸯楼那一场,都用很强烈的短句,使人感到那种英雄气概与敏捷的动作。要像画家那样,用暗淡的颜色表现阴暗的气氛,用鲜明的色彩表现明朗的景色。
其次,谈谈对话。对话很重要,是文学创作中最有艺术性的部分。对话不只是交代情节用的,而要看是什么人说的,为什么说的,在什么环境中说的,怎么说的。这样,对话才能表现人物的性格、思想、感情。想对话时要全面的、“立体”的去想,看见一个人在那儿斗争,就想这人该怎么说话。有时只说一个字就够了,有时要说一大段话。你要深入人物心中去,找到生活中必定如此说的那些话。沉默也有效果,有时比说话更有力量。譬如一个人在办公室接到电话,知道自己的小孩死了,当时是说不出话来的。又譬如一个人老远地回家,看到父亲死了,他只能喊出一声“爹”,就哭起来。他决不会说:“伟大的爸爸,你怎么今天死了!”没有人会这样说,通常是喊一声就哭,说多了就不对。无论写什么,没有彻底了解,就写不出。不同那人共同生活,共同哭笑,共同呼吸,就描写不好那个人。
我们常常谈到民族风格。我认为民族风格主要表现在语言上。除了语言,还有什么别的地方可以表现它呢?你说短文章是我们的民族风格吗?外国也有。你说长文章是我们民族风格吗?外国也有。主要是表现在语言上,外国人不说中国话。用我们自己的语言表现的东西有民族风格,一本中国书译成外文就变了样,只能把内容翻译出来,语言的神情很难全盘译出。民族风格主要表现在语言文字上,希望大家多用工夫学习语言文字。
第二部分:回答问题。
我不想用专家的身份回答问题,我不是语言学家。对我们语言发展上的很多问题,不是我能回答的。我只能以一个写过一点东西的人的资格来回答。
第一个问题:怎样从群众语言中提炼出文学语言?这我刚才已大致说过,学习群众的语言不是照抄,我们要根据创作中写什么人,写什么事,去运用从群众中学来的语言。一件事情也许普通人嘴里要说十句,我们要设法精简到三四句。这是作家应尽的责任,把语言精华拿出来。连造句也是一样,按一般人的习惯要二十个字,我们应设法用十个字就说明白。这是可能的。有时一个字两个字都能表达不少的意思。你得设法调动语言。你描述一个情节的发展,若是能够选用文字,比一般的话更简练、更生动,就是本事。有时候你用一个“看”字或“来”字就能省下一句话,那就比一般人嘴里的话精简多了。要调动你的语言,把一个字放在前边或放在后边,就可以省很多字。两句改成一长一短,又可以省很多字。要按照人物的性格,用很少的话把他的思想感情表达出来,而不要照抄群众语言。先要学习群众语言,掌握群众语言,然后创作性地运用它。
第二个问题:南方朋友提出,不会说北方话怎么办呢?这的确是个问题!有的南方人学了一点北方话就用上,什么都用“压根儿”,以为这就是北方话。这不行!还是要集中思考你所写的人物要干什么,说什么。从这一点出发,尽管语言不纯粹,仍可以写出相当清顺的文字。不要卖弄刚学会的几句北方话!有意卖弄,你的话会成为四不像了。如果顺着人物的思想感情写,即使语言不漂亮,也能把人物的心情写出来。
我看是这样,没有掌握北方话,可以一面揣摩人情事理,一面学话,这么学比死记词汇强。要从活人活事里学话,不要死背“压根儿”、“真棒”……。南方人写北方话当然有困难,但这问题并非不能解决,否则沈雁冰先生、叶圣陶先生就写不出东西了。他们是南方人,但他们的语言不仅顺畅,而且有风格。
第三个问题:词汇贫乏怎么办?我希望大家多写短文,用最普通的文字写。是不是这样就会词汇贫乏,写不生动呢?这样写当然词汇用的少,但是还能写出好文章来。我在写作时,拚命想这个人物是怎么思想的,他有什么感情,他该说什么话,这样,我就可以少用词汇。我主要是表达思想感情,不孤立地贪图多用词汇。我们平时嘴里的词汇并不多,在三反五反时,斗争多么激烈,谁也没顾得去找词汇,可是斗争仍是那么激烈,可见人人都会说话,都想一句话把对方说低了头。这些话未见得会有丰富的词汇,但是能深刻地表达思想感情。
我写东西总是尽量少用字,不乱形容,不乱用修辞,从现成话里掏东西。一般人的社会接触面小,词汇当然贫乏。我觉得很奇怪,许多写作者连普通花名都不知道,都不注意,这就损失了很多词汇。我们的生活若是局限于小圈子里,对生活的各方面不感趣味,当然词汇少。作家若以为音乐、图画、雕塑、养花等等与自己无关,是不对的。对什么都不感兴趣,哪里来的词汇?你接触了画家,他就会告诉你很多东西,那就丰富了词汇。我不懂音乐,我就只好不说;对养花、鸟、鱼,我感觉兴趣,就多得了一些词汇。丰富生活,就能丰富词汇。这需要慢慢积蓄。你接触到一些京戏演员,就多听到一些行话,如“马前”“马后”等。这不一定马上有用,可是当你写一篇文章,形容到一个演员的时候,就用上了。每一行业的行话都有很好的东西,我们接触多了就会知道。不管什么时候用,总得预备下,像百货公司一样,什么东西都预备下,从留声机到钢笔头。我们的毛病就是整天在图书馆中抱着书本。要对生活各方面都有兴趣;买一盆花,和卖花的人聊聊,就会得到许多好处。
第四个问题:地方土语如何运用?
语言发展的趋势总是日渐统一的。现在的广播,教科书都以官话为主。但这里有一个矛盾,即“一般化的语言”不那么生动,比较死板。所以,有生动的方言,也可以用。如果怕读者不懂,可以加一个注解。我同情广东、福建朋友,他们说官话是有困难,但大势所趋,没有办法,只好学习。方言中名词不同,还不要紧,北京叫白薯,山东叫地瓜,四川叫红苕,没什么关系;现在可以互注一下,以后总会有个标准名词。动词就难了,地方话和北方话相差很多,动词又很重要,只好用“一般语”,不用地方话了。形容词也好办,北方形容浅绿色说“绿阴阴”的,也许广东人另有说法,不过反正有一个“绿”字,读者大致会猜到。主要在动词,动词不明白,行动就都乱了。我在一本小说中写一个人“从凳子上‘出溜’下去了”,意思是这人突然病了,从凳上滑了下去,一位广东读者来信问:“这人溜出去了,怎么还在屋子里?”我现在逐渐少用北京土语,偶尔用一个也加上注解。这问题牵涉到文字的改革,我就不多谈了。
第五个问题:写对话用口语还容易,描写时用口语就困难了。
我想情况是这样,对话用口语,因为没有办法不用。但描写时也可以试一试用口语,下笔以前先出声地念一念再写。比如描写一个人“身量很高,脸红扑扑的”,还是可以用口语的。别认为描写必须另用一套文字,可以试试嘴里怎么说就怎么写。
第六个问题:“五四”运动以后的作品——包括许多有名作家的作品在内——一般工农看不懂、不习惯,这问题怎么看?
我觉得“五四”运动对语言问题上是有偏差的。那时有些人以为中国语言不够细致。他们都会一种或几种外国语;念惯了西洋书,爱慕外国语言,有些瞧不起中国话,认为中国话简陋。其实中国话是世界上最进步的。很明显,有些外国话中的“桌子椅子”还有阴性、阳性之别,这没什么道理。中国话就没有这些罗里罗嗦的东西。
但“五四”传统有它好的一面,它吸收了外国的语法,丰富了我们语法,使语言结构上复杂一些,使说理的文字更精密一些。如今天的报纸的社论和一般的政治报告,就多少采用了这种语法。
我们写作,不能不用人民的语言。“五四”传统好的一面,在写理论文字时,可以采用。创作还是应该以老百姓的话为主。我们应该重视自己的语言,从人民口头中,学习简练、干净的语言,不应当多用欧化的语法。
有人说农民不懂“五四”以来的文学,这说法不一定正确。以前农民不认识字,怎么能懂呢?可是也有虽然识字而仍不懂,连今天的作品也还看不懂。从前中国作家协会开会请工人提意见,他们就提出某些作品的语言不好,看不懂,这是值得警惕的,这是由于我们还没有更好地学习人民的语言。
第七个问题:应当如何用文学语言影响和丰富人民语言?
我在三十年前也这样想过:要用我的语言来影响人民的语言,用白话文言夹七夹八的合在一起,可是问题并未解决。现在,我看还是老老实实让人民语言丰富我们的语言,先别贪图用自己的语言影响人民的语言吧。
第八个问题:如何用歇后语。
我看用得好就可以用。歇后语、俗语,都可以用,但用得太多就没意思。《春风吹到诺敏河》中,每人都说歇后语,好像一个村子都是歇后语专家,那就过火了。
关于小说-D.H.劳伦斯
========================
关于小说-[[D.H.劳伦斯]]
-----
有人说小说被判了死刑。又有人说小说本是一棵绿树,现在更青翠了。别人都在说三道四,我为什么不说上几句?!
在桑塔亚纳先生65看来,小说之寿数已尽,因为小说越来越瘦弱了。这就是说桑塔亚纳先生对此厌烦了。
我自己也一样厌烦小说了。卒读一本现代小说越来越让人吃力了。只读一点儿就知道其他部分了;或者,根本就不想去知道。
这是件伤心的事。不过我再说一遍,这不怨小说,要怨的是小说家。
你喜欢什么都可以往小说里塞。难怪人们写得千篇一律了。怪不得一写馅饼就是鸡肉馅的!鸡肉馅儿饼可能是流行口味,可是总会吃腻的,第一个感到腻的人会第一个要求换口味。
小说是一大发现,比之伽里略的望远镜或别人的无线电都伟大。小说是迄今为止人类拥有的最高表现形式。为什么?因为它太无力表现绝对的东西了。
在小说中,一物与他物间的关系是相对的,这才叫艺术。里面或许有点儿说教,但它们绝算不得小说。作者很可能怀揣某种说教“企图”,不错,大多数大作家都这样,如托尔斯泰的基督教社会主义,哈代的悲观主义和福楼拜的精神绝望。但是,说教的企图再坏如托尔斯泰和福楼拜,它也不会毁灭小说的。
你可以对我说,福楼拜的说教不是企图而是一种“哲学”。但是,难道一个小说家的哲学不正是较高水准上的企图吗?如果说任何一位够格的小说家都心怀一种哲学(甚至巴尔扎克),那么任何像样的小说都有一种企图,只要这“企图”十分巨大且与激情的灵感不冲突就行。
渥伦斯基66有罪,不是吗?但这种罪过也正是某种虔诚企求的完美实现。尽管老托尔斯泰不承认,可小说使之昭然。而《复活》中那个后来变得虔诚的公爵则是个大傻瓜,没人需要或相信他的虔诚67。
小说自身的伟大正在于此——它不许你说教撒谎,说教与谎言无法在小说中自圆其说。看到渥伦斯基把安娜·卡列尼娜追到了手,没人不为此高兴。可对待他们的罪过呢?整个悲剧是因为渥伦斯基和安娜害怕社交圈造成的。这魔鬼是社会魔鬼而绝非阳物68魔鬼。他们无法为自己真诚的激情感到骄傲,不敢公然唾弃格隆迪大妈69们的清规戒律。正是这种懦弱才算得上真正的“罪过”——小说本身使之昭然若揭,让老托尔斯泰无话可说。“作为一个军官,我尚有用处。可作为一个人,我算废了。”渥伦斯基这样说。真是个卑鄙小人。作为一个人,一个男人他算完了,只剩下当一个社会工具的份儿了。“军官”,上帝呀!他落到这步田地,仅仅是因为剧院里的人们冷落了他70!似乎人们的肩背不如人们的脸让他觉得顺眼71!而老托尔斯泰试图说明这罪过是阳物之罪。老骗子!托尔斯泰的书哪一本没有这种阳物的辉煌?他倒咒骂起这血性的支柱来了,正是这东西赋予了他全部生命的财富!纯粹是个犹大72!委身于一个卑贱又无血性的社会,还要用基督教社会主义的新帽子和脂粉来装扮那个肮脏的老大妈格隆迪。这些人真是一丘之貉!同是一个阉父的儿子!
这部小说在渥伦斯基背后踹了一脚,从而敲掉了老托尔斯泰的牙,也给我们留下了反思的余地。
令人大为烦恼的是,几乎所有大作家的某种说教企图或哲学都与他们的激情灵感大相径庭。他们的激情灵感让他们成为阳物崇拜者,从巴尔扎克到哈代莫不如此。不,从艾普利乌斯73到E.M.福斯特74都是。可是,一到他们的哲学或一想到他们自己,他们就全变成了十字架上的耶稣了。真讨厌!小说竟然背负着如此的大包袱!
小说就这样背着包袱,背着可悲的十字架上成千上万自我英雄的男男女女。《复活》就是一部傻乎乎的复制品而已,更恶毒的复制品则属《萨朗波》75,那里头被挖了心的马托是个阳刚之人,他在珠光宝气的公主的十字架上大受刑罚。
你无法欺骗小说,就是让一个男人死在一个女人——他“亲爱的十字架”身上也骗不了小说。小说会教你看清她如何亲爱:付出任何代价。读后你会感到恶心,讨厌那种把女人变成他们的“亲爱十字架”并自愿钉死在十字架上的英雄好汉们。
你尽可以欺骗几乎任何一种别的文学形式。比如,你可以把一首诗写得很虔诚,它仍是一首诗。你可以用戏剧来写《哈姆雷特》,但如果你用小说来写哈姆雷特,他就有点喜剧色彩了,或许会把他写成陀思妥耶夫斯基笔下的“白痴”那样可疑的人物76。诗和戏剧,人们可以写得风卷残云般干净利落,尽可以让人类的字词无拘无束地飞翔。可在小说中总有一只雄猫,一只捕食字词这只白鸽的黑雄猫。白鸽稍不注意,猫就来扑食它。还有一块让人踩上去滑倒的香蕉皮。在这房基之上建有一个盥洗室。这些东西有助于保持平衡。
如果在柏拉图的《对话录》中有个什么人突然站在他头上偷偷地狠踢他一脚,并把他的学堂搅乱,那就会让柏拉图处在一个与宇宙较为真实的关系中。或者说,如果柏拉图在《蒂迈欧篇》中停下来说上一句:“哦,我亲爱的克里昂(或随便什么人),我肚子痛,得如厕——这也是人之永恒理念的一部分啊。”77那样的话,我们就用不着像弗洛伊德78一样低下了。
如果,当耶稣要求那富人变卖他的所有并把它分给穷人79时那富人说:“好吧,老兄!你不是穷吗?来,我把财产给你,来吧!”那我们就会省去多少悲啼少犯多少错误,我们也就用不着产生马克思和列宁这两位人物。如果耶稣接受了那笔财富该多好啊!
十足可惜的是,马太,马可,路加和约翰80这四位不曾直抒胸臆来写小说。他们写过,但写得走了样。福音书是精妙的小说,但是一些“有目的”的作者写的,太可惜了,里头的布道太多。
马太,马可,路加和约翰,穿着裤子上床!81
每个孩子都会唱这几句。哦,他们脱了裤子该多好!
在我看来,更伟大的小说是《旧约》中的那些章节,《创世记》,《出埃及记》,《撒姆耳记》和《列王记》等。那些作者们志向远大,其企图绝不与其激情的灵感相悖。两者几乎是一体,居然没有分开,这真叫奇怪!而在当代小说中它们则是分离的,毫无希望成为一体。
这就是现代小说的毛病。现代小说家被陈腐的“目的”或自我观念所约束,从而让灵感屈就了目的和观念。当然他会否认他有任何说教企图,因为企图像一种黏膜炎,令人难堪。可他就是患了这病,他们都患了这病,同样的病。
他们全以小耶稣自居,他们的企图就是证实这一点。天啊,《吉姆爷》82,《西尔维斯特·伯纳德》83,《如果冬天将至》84,《大街》85,《尤利西斯》86和《潘》87,全是些个悲悯的、同情的或恶毒的耶稣,或完美或尚有缺憾。小说中总有那么一个永远纯洁的女主角,却是一朵花插到了牛粪上!正像《绿帽女人》88一样,纯洁的女主角总是拜倒在耶稣脚下,尽管她的行为可能是误入歧途的。天知道救世主怎么看她们,不管她是谁。不管她们是绿帽女人还是永恒的仙女89,还是别的谁。他们是一群男女主人公,男女小说家,男女基督。他们正在污泥中打着滚。基督不是在地狱中捞过东西吗?很好!90
他们都是有自我观念的小说家!他们的“目的”未免太过分了!这种观念是那么令人厌倦,那么虚假,那么令人作呕!小说抛弃了它们,它们骗不了小说。
现在是我们停止玷污小说的时候了。如果你的目的只是想证明你有资格做基督,而你灵感的细小溪流正在流向罪恶,那就让这小溪流干涸算了,因为它已经死了。还生活以本来面目!为什么要把廉价的“绿帽女人”和“永恒的仙女”之类的生活假作生活的真实?其实小说证实她们的生活绝非生活的本来面目,不过是没完没了的、复杂的、令人生厌的习惯——病态的男基督或女基督。
这些个令人生厌、令人作呕的小说!它们根本不叫小说。在每部大作品中,有哪个人从头到尾都是英雄的?没有哪个人物是,从头到尾的英雄是人物背后无名的火焰,正如《旧约》中上帝是兴趣的中心一样,只是那里面的亲昵程度有点过火了。在大作品中,所有人物的背后是虽不可知但可感受到的火焰,在人物的语言和举止中闪烁着这火焰的一星星火花。如果你过于个性了,过于人情味了,这火花就会熄灭,你获得的就是某种类似生活实则毫无生气的东西,正如同大多数人一样。
我们必须在生死之间作出选择。生,就是上帝之火,存在于一切之中。死,即死物儿。在我写作的屋中,一张小桌子,它是死物,它甚至生气全无。还有一只可笑的小铁炉,但不知为什么,却是个活物;还有一只铁抽屉,天知道为什么它也是活物。另有几册书,全然已死。可那只睡着的猫却十二分有生气。那只玻璃灯则是个死物件了。如何区别生死?谁知道呢!可区别是有的,我知道。
我们不妨称上帝是一切的生和生之源泉。人是一切的死。
如果你想发现生之精髓所在,它存在于生与未知物之间的超然关系中。它似乎存在于某种奇特的关系中,这是一种流动的、变化的、美好的关联。那可笑的铁炉子就说不清为什么属于生,可那细腿桌子就不算,它不过是一块孤零零的东西,像一只切掉的手指头。
现在我们明白小说的最大长处了。它没有“生气”就无法存在。普通无生气的小说,即便是畅销小说,照样沦为虚无。死物埋葬死物,速度之快,令人吃惊。死物也喜欢逗逗乐,可很快逗的和被逗的都会被忘却。
第二点,小说是不容什么说教和绝对的。任何有生命的东西及其所说和所做的,都有那么点儿神圣。所以,渥伦斯基占有安娜必定算得上神圣,因为这做法是富有生命力的。而《复活》中的那位女犯和那位公爵则该算死物儿了。那囚车是生气勃勃的,可那个要赎罪的公爵却像一截死木头桩子一样。
是小说自己为我们设下了这些个法规,可我们却花着时间去躲避它们。小说中的人物必须“有生气”。这句话的意思是:他必得与小说中别的东西之间有生命的联系——雪啦,臭虫啦,阳光啦,阴茎啦,火车啦,丝帽,猫,悲伤,人,吃喝,白喉,倒挂的金钟花,星星,观念,上帝,牙膏,闪电,还有手纸什么的。人物与这些东西之间定要有一种活生生的关系,他所说所做的必得与它们有关才行。
正因此,像《战争与和平》91中的彼埃尔就比安德烈公爵缺少生气。彼埃尔与之保持细微关系的是观念,牙膏,上帝,人,食品,火车,丝帽,悲伤,白喉和星星这类东西。而他对别的东西就不敏感,如雪,阳光,猫,闪电,阴茎,倒挂的金钟花和手纸。总之他缺少生气。
托尔斯泰要扼杀的或混淆的正是那最有生命力的东西。这倒像个真正的布尔什维克。当我们看到娜塔莎嫁给了那个彼埃尔时,我们不禁会认为这女人糊涂,没新鲜味儿。
彼埃尔是那种我们称之为“太像人”的人。就是说他局限性太强。人们黏成社会的一群,就是为了限定每个人的责任,这就是人类。彼埃尔就是这种人。这也是托尔斯泰,一个鼓吹基督教博爱观念的哲学家。干吗要把人局限在基督教博爱上面?至于我自己,某一天我会变成一个最可爱的基督教博爱者,学着阿蒂拉92那样把一块生牛排铺在马背上当马鞍子,骑上去奔向基督的王国,第二天就能看到遍地是火红的公鸡,一个个在打着鸣儿。
这就是人!真真的托尔斯泰。那甚至是列宁,是基督教博爱机器中的神,把人们都绞成肉去做社会香肠。
去他的绝对吧!我诅咒一切绝对,诅咒!告诉你吧,没有什么绝对之物可以让狮子与羊并卧在一起93,除非像那首五行打油诗说的那样,那羊在狮子的肚子里94。
他们骑马回到家,
列奥小羊肚中藏,
老虎脸上笑哈哈!
嘻嘻嘻,哈哈哈!
嘻嘻嘻嘻哈哈哈!
对人来说没有什么绝对或绝对物。这种事对有三个直角的三角形魔鬼说去吧,它只存在于理念之中。如果谁认为可以在三角形斜边上找出个直角来,那就让他试试吧。
嘿!嘿!嘿!人把绝对的东西传给别人,似乎我们都是几何书,前面写着原理、规则和定义。上帝的圆规!摩西的三角板!人不过是几何图上的一个交叉点,连一只小萝卜都算不上!
神圣的摩西!
“孝敬汝父汝母!”95那当然不错,可假如他们并不体面呢?摩西,那又会怎么样?
西奈山上传来一声雷:“假装孝敬!”
“爱邻如爱己。”96
完了,我的邻居碰巧是令人生厌的卑鄙小人。
那闪光的圣灵低声说:“假装你爱他嘛。”
这是蛇的狡猾!97可我从未见过蛇亲吻他的天敌。
呸!我才不亲吻我的邻居,他是个讨厌的卑鄙小人,亲他会脏了我的嘴。
圣灵,回家去吧。
的确是山羊与圆规!98
任何事物都是相对的。上帝嘴中或人的嘴中发出的每一条戒律都是严格地相对的,与其特定的时间、地点和环境相关联。
这才是小说之美:每件事只在其自身的关系中才是真的,除此之外便不是真。
一切事物的关联和内在联系就如同溪水一样流淌,变化和震颤。就像溪水中的鱼儿一样,小说中的人物游水、随波逐流,死的时候也会肚皮朝上漂起来的。
因此,如果小说中的某个人物想娶个两三房老婆,甚至三十房,在他所处的时间和环境中那都算真切。别的男人在别处或别的时间里做这般想法那也可能是真情。可如果由此得出结论,说所有的男人在所有的时候都想要两三房或三十房老婆,或者说写这书的小说家本人就提倡疯狂的一夫多妻99,那可就愚不可及了。
若因但丁崇拜着远方的比阿特丽丝100就推论说每个男人都该崇拜远方的比阿特丽丝,那同样是愚不可及。
如果但丁把这事说个明白,没什么不好。凭什么我们要含糊其辞掩盖事实呢?其实但丁床上有个姣好的老婆,养了一窝子健壮的小但丁。还有那个彼德拉克101,怀念着远方的劳拉,可他膝下至少有十二个合法的小彼德拉克了。可我们听到的却只是他们在叫:“劳拉!”“劳拉!”“比阿特丽丝!”“比阿特丽丝!”
胡说八道,为什么但丁和彼德拉克不来一首这样的合唱:
哦,做我精神上的小老婆
比阿特丽丝!
劳拉!
我那老伴儿给我生了一窝崽,
可你才是我精神上的小老婆,
比阿特丽丝!
劳拉!
这些东西之间应该有一种诚实的关系。没人妒忌这些家伙有精神上的小老婆。但另一方面养着一个太太和一窝十二个孩子,这就让人觉着是一种肮脏的把戏了。
这说明“绝对”是多么不道德,它总是掩盖某种重要的事实,使其不见天日!欺骗!
由此,我们该谈到小说的第三种特性了。小说与散文、诗歌、戏剧、哲学著作和科学论文不同之处是:这些东西都可以用不切实的假定来辩论,而小说则是而且必须是:
①有生命。
②各部分有内在关联,是生命的关联、有机的关联。
③诚实的。
我称但丁的《神曲》有点不诚实,它从不提及但丁那娇妻及其儿女。而《战争与和平》则彻头彻尾地不诚实,书中那个肥胖而无聊的彼埃尔成了主角,把他树立成一个令人赞叹向往的形象,可事实上谁都知道他没有魅力,连托尔斯泰都吸引不了。
当然了,作为一个有创造力的大艺术家,托尔斯泰对他笔下的人物是真诚的。可作为一个有着自己哲学观点的人,他对自己的脾性是不忠诚的102。
脾性是个怪东西。它是人之火,或燃得明亮或燃得黯淡,或蓝或黄或红,升腾或泯灭或恍惚,全依照情境之风势和生命之气不断变幻。但它永远是一束独特的火光,在一个奇特的世界里闪烁——除非它被太厉害的蹇运所扑灭。
如果托尔斯泰曾细看一眼他体内这束火焰,他就会看到,他并不喜欢那个肥胖、面相模糊的彼埃尔,这人不过是个可怜的工具罢了。可是,托尔斯泰更是个存在。所谓存在就是有自我意识“我是”的人,即万能的上帝在我们身上的遗迹。作为这样的人,他有意美化了彼埃尔,一只看家狗而已。
会不会有人称列奥(托尔斯泰的名字)不诚?他可能会很忠实于他自己!可他不!他作为有自我意识的人比他自身的腹和膝更重要。他要使自己变完美些,于是他披上了羊皮,蹒跚的老狮子,他就是列奥!列奥!列奥!103
列奥偷偷地崇拜着男性,视其为一根强取豪夺、血运旺盛的支柱。在街上若遇上三个健壮、大摇大摆的卫兵他非妒忌地大叫不可。十分钟后就大骂着说要把他们忘个一干二净,真正算道德的霹雷了!104
这样的伟大真叫讨厌!俄罗斯这样的伟大民族竟让这样的改革者来改进他们的固有人性。这类改革者都感到自己缺少点什么,便靠仇恨活着,最终剩下的不是别的,而是人的空壳,渐渐把自己改进得空空如也,只会说一些套话,似乎他们吞下了一整套社会主义的百科全书。
不过,请等待!俄国人是有生命力的,那是他们奇怪地转变为布尔什维克的过程中呈现出的某种新奇的东西。
托尔斯泰伯爵有着伟人那个最后的缺点:他想要绝对,你可以称之为爱之绝对。这是“高尚思想家的最虚弱之点”!这是衰老的传染病。他想变得绝对——全世界皆兄弟。托尔斯泰嫌列奥这个名字太狭隘了。他想膨胀,膨胀,直到变成世界博爱,成为我们地球上巨大的醋栗。105
随之列奥“砰”地爆了,其碎片变成了布尔什维克分子。
全是胡说。没哪个人是绝对的。没谁是绝对好或绝对正确或绝对可爱。甚至基督这样的完美典范也只是相对好、相对正确,犹大就能牵着他的鼻子走。
人能想象出的神没有哪个是绝对好或绝对正确的。人们迄今发现的神竟相互矛盾,还相互攻击。可他们都是神,是神奇莫测的潘神106。
了解一下都有什么神,他们的过去和未来是个什么样子,这很有趣。他们一贯是神,每个神都讲着绝对,可在别的神听来这话却毫无意义。这,甚至令永恒显得可爱。
但是,可怜的人却像时间之河中的一只随波逐流的软木塞儿,一定要把自己拴在某颗所谓“正确”的星星上不可。于是他抛出自己的绳子,去钩那星星。他只能发现,那星星在缓缓坠落,直到“嘶”的一声坠入时间之河,又一颗绝对之星从此消失。
于是我们又重新在天上寻找。
至于说到爱情婴儿,我们已经懒得为它换擦嘴布了。放下这孩子,让它自己去学跑,自己系自己的裤腰带吧。
不过应该想到所有的神都是神。如果你觉得哪个神是神,那它就是神了。如果你觉得它不怎么像神,那就稍候,你会听到它“嘶”的一声消失。
小说对此十分明白。“亲爱的,”它友善地说,“一个神是相对别的神而言的,除非它钻入汽车,那就变成交通警的一个案子了!”
“可我该怎么办?”失望的小说家说,“从埃蒙107、拉108到埃迪夫人109,从阿什塔罗斯110到朱庇特111到安妮·比森特112,我弄不清我在哪儿。”
“不,你清楚亲爱的!”小说说道,“你知道你在哪儿。所以你用不着把自己拴在什么阿什塔罗斯或埃迪的裙裾上。如果你遇上她们,只须客客气气地问声好,但不必往上拴,否则我会不理睬你的。”
别往上拴自个儿!小说这样说。
要诚实,小说又补充说。
诚实!神像虹一样,有各种颜色和形状。光是看不见的,其表现形式必须是各种色彩如粉、黑、蓝、白、黄、朱红或杂色。
如果您是一位通神论者,你就会大叫:走开吧,你这黑红色!走开!来吧,淡蓝色或淡黄!来吧!
你可以这样喊,如果你是个通神论者。如果你在小说中弄一位通神论者,他可以这样尽情大叫“滚开”!
可一位通神论者是不能当小说家的。这正如同一只喇叭是不能充当军号一样。一个通神论者、基督教徒或“圣滚者”113可以是一个小说家的一部分,但一个小说家却不能把自己局限于此。风刮起来是随心所欲的114,色彩也一样,它想是红就是红。
事实上只有圣灵才懂什么叫正确。而天只知道圣灵是怎么回事!可听起来满像回事的。于是圣灵就在火焰中徘徊,从红到蓝到黑到黄,给一个标记打上另一个标记,给一团火加另一团火,做这些完全随风向而动,生命在火中穿行,从幽冥到幽冥,人永远不知怎么和为什么。它只须旅行,别死在恶臭气中。小说所要求你忠实去做的,只是忠实你心中跳动的火焰。《复活》中那位公爵在那少女的花季就残酷地背叛和抛弃了她,他其实也是泯灭了他的人性之火。后来,他又用忏悔和慈悲来折磨她,于是他等于再次背叛并往他苍白的人性上吐口水,最终他的人性全然灭绝,他本人只成了一块半死不活的老肉。
潘神时代的神话说上帝是宇宙的生命之火,五花八门的火焰,颜色不同,情绪不一,美丽的,痛苦的或忧郁的。不管哪种火在你的人性中燃烧,它在那一刻就是你了。那是你的人性,别往上头撒尿啊,小说这样说。一个人的人性就是尊重他心中的火焰并且懂得没有哪种火是绝对的。甚至一团火本身也只是个相对物。
再看看老列奥·托尔斯泰吧,他竟往火上泼水,似乎他泼上去的水是绝对的。
性也是一束火焰,小说说。这火燃烧任何绝对物,甚至燃烧阳物。因为性远非阳物可及,比功能性的欲望要深刻得多。性之火焰烧焦你的绝对并残酷地炙烫你的自我。你打算在宇宙中表现一种怎样的自我呢?那就等待,直到性之火像一只花条纹的老虎烧燎你。
他们骑马回家,
带回个女人,
老虎笑容满面。
你尽可以玩性游戏,玩吧!你可以逗引你的性,就像搅拌一杯冰镇苏打水。你可以拍拍你最爱的姑娘,对她动手动脚,逗引你自己也逗引她,怎么摆弄你的性都可以。
可要等待!直到你曾对之吐过口水的火焰又回到你身上再这样做!只须等待!
性是一束生命之火,黑暗,冥冥难察。它是一个男人体内最深厚的积淀,是他男子气的中心之火。
你打算拿它怎么玩耍?那样,你只能让它变贱,变恶心。
去买一条大毒蛇来玩玩吧。
性甚至是太阳里高贵的储备。
哦,把小说给我!让我听听小说怎么说。
至于小说家嘛,他常常口水四溅地扯谎。
鬼子进村-李洱
========================
鬼子进村-[[李洱]]
-----
仪式
我们正在上语文课,用“恍然大悟”一词造句,恍的一声,门被跺开了。又是付连战,他是枋口小学的校长。这家伙跟犯了什么病似的,门都懒得敲一下,说进来就进来了。当然,在我们抓耳搔腮造不成句子的时候,他的这种举动,并不让我们反感。虽然我们都知道语文老师乔凡新现在很恼火,校长一走,他就会把邪火发泄到我们头上,但那毕竟过一会儿才会发生,眼下,还是先来对付这个付连战吧。
上午,姓付的已经玩过这一手了。那时候我们上的也是语文课,乔老师刚把我们默写的课文收起来,他就跺开门进来了。他用手指头敲着门口的一张课桌,说:
谁说知青是驴,给我站起来。
这话好多人都说过,所以没有人站起来。付校长看形势不妙,就换了个方式发问。为了加重语气,他不慎把粗话都说出来了:
是谁最先说的?驴日的,给我站出来。
这一下当然更没有人站起来了。因为大家没有站起的资格。这话最早是村支书说的,村支书在大会上说过之后,才以语录的形式传遍全村。最近几天,姓付的一直在公社开会,他还没有来得及听到村支书的语录,村支书的那段有关知青和驴的话很长,其要点,大致如下:
知青们来咱们村干什么?是来接受再教育的。伟大领袖和导师毛主席说了,农村是个广阔的天地,在这里是可以大有作为的。什么叫接受再教育?就是说,他们是驴,已经调教过了,可是没有调教好,需要我们再来调教调教。
村支书的话,涉及知青和驴的,就是这么一段。现在,我们都已经知道,村支书是在打比方。村支书虽然不可能知道什么叫比喻,但他却会使用比喻。其实,当我们鹦鹉学舌地说:“知青是驴”的时候,我们也是在使用比喻。没有学过有关比喻的知识,就已经会比喻了,付校长应该高兴才对,完全没有必要跺门、瞎喊、说粗话。
但话既然说出来了,他就打算继续说下去。他走到讲台上,又说了一遍:
知青是驴?是谁先说的?驴日的,有胆就站起来。不站起来?那好,等我查出你,你就搬着板凳回家。
搬着板凳回家是我们最乐意干的事,谁都想搬着板凳回家。当然,这并不等于说,谁都愿意站起来当场亮相。
不知道是谁先扭头看乔红军。肯定是坐在第一排的人先扭头,别的人才像鸭子一样一起转头去看乔红军的。乔红军是村支书的小儿子,他爹不在场,大家只好看他。
乔红军一下子哭了起来。鼻孔下面鼓起两个气泡,随着他的哭声,那两个气泡忽大忽小。乔红军的鼻涕是我们全班同学的共同记忆,去年,我回枋口探亲的时候,我在村口还见到了他。他的鼻子下面现在清理得很干净,我跟他说了十分钟左右的话,他掏出餐巾纸替儿子擦了好几次鼻涕。时过境迁,现在该轮到子承父业,儿子的鼻涕鼓气泡了,看来,流鼻涕也是会遗传的。
乔红军当时鼻涕一把泪一把地那么一哭,付连战就傻眼了。付校长付连战一定认为是乔红军先说的。他在讲台上愣了几分钟(这期间,他的手没有闲住,至少掰断了十根粉笔,有的粉笔还掰成了四截),然后说:
肯定是你们当中有人教乔红军说的,乔红军自己不会这么说的。是谁教他的,以后我会查清的。
你可以接着上课了。他对站在讲台一侧正往烟锅里装烟的乔老师说。
乔老师没有讲课,而是让我们互相检查刚才默写的课文。谁查出对方的错误,就可以朝对方的脑袋上敲一下。无人能够幸免,谁挨的都不止一下,这使大家立即互相怨恨起来。
现在,付校长又跺门进来,他要干什么?有人下意识地摸摸头顶,也有人扭头去看乔红军。
付连战这次没有发火,或者说,他没有把火气发出来而是藏在肚里。他说,听说有人称知青是鬼子,谁再这么胡说,就把谁的嘴贴上胶布。他说什么叫鬼子你们懂不懂?日本人和美国人才叫鬼子,知青不叫鬼子,知青叫什么?知青的全称是知识青年,他们是来枋口建桥的,在济水河上架上一道桥。
其实把知青说成是鬼子,并不是枋口人的说法。我们后来才知道,那是付连战的村子里的人的说法。付连战的家在官庄村,离枋口有二十里地。那个地方的小孩看到许多知青都留着小胡子,就把他们和电影中的日本人联系了起来。其实大家都见过胡子,大家没见过的是修剪得整整齐齐,只在嘴唇上面长不在下面长的胡子。付连战这次是先下手为强,或者说,先给大家注射预防针。认真说起来,枋口人把知青称作鬼子,是从付连战开始的。这是乔老师后来告诉我们的。关于付连战,乔老师说过一些很精辟的话,至今我们仍然印象很深:付连战的前两任老婆先后死了,乔老师说,那是因为老付的那玩意儿不顶用,让人家旱死了;付连战的头顶是光的,乔老师说那叫鬼剃头,是那两个旱死的女鬼给他剃的,女鬼被他气成神经病了,本来是要揪他的那玩意儿的,临下手的时候弄错了,等等。乔老师说,他太懂老付了,老付肚子里有条蛔虫,他都知道。
现在想起来,校长付连战那天最重要的工作,就是布置接待任务。他说知青们明天就到,大家要和村民一起到路口迎接。他要求同学们明天早上起来,一定要洗脸。老付还说,洗脸的时候,顺便把脖子洗一下,有的人的脖子已经变成黑车轴了,这是不好的。老付说的没错,在夏天,我们每天都要跳到河里洗澡,但我们从不洗脸。不但不洗脸,我们还要把脸上涂满河泥,像泥鳅一样在河岸上走来走去。当然,女生除外。
老付交代过任务,又对乔老师说,你去写标语吧,今天的课不上了。乔老师说,这堂课上完他就去写标语。老付愣了一下,说:我说了,不上课,写标语去。
老付的命令是对的,这课不能再上了。我们都不想再上了,上下去只能是我们吃亏,乔老师肯定又会拿我们撒气。所以,尽管我们都讨厌老付,但老付话一出口,我们就欢叫起来。
当时发生了一件小事,我们不妨顺便提一下。付连战话音一落,就有一个人从教室的后门跑了出去。那个人就是写这篇小说的李洱。我在大家的欢叫声中,跑出教室,直奔乒乓球台。乒乓球台用砖头支在几棵榆树之间,课余时间,那里是兵家必争之地。我奔向球台的时候,回头看了一下,发现并没有人追上来,就想:这球台今天非我莫属了,我想和谁对打,就和谁对打。我站在球台边,用树枝扫着上面的树叶和鸟粪,同时想着,先满足谁的要求,让谁来打,是福贵呢还是万龙?
球案扫清之后,我就坐在上面,一边摇晃身体一边等待福贵和万龙他们来给我说好话。摇晃给我带来一种眩晕感,使我感到非常舒服,于是我就摇得更厉害。球台也跟着我摇晃起来,到后来,是球台在带着我摇晃,即便我不用力,我的身体也在球台上扭来扭去。我在球台上又待了一会儿,眩晕感消失之后,我突然有点害怕。
别以为我是害怕球台倒塌砸伤自己,那没有什么可害怕的,我相信在它倒塌的一刹那,我会像一只鸟那样突然飞离。
一直没有人从教室里出来,是这个事实让我有点害怕。现在,校园里见不到一个人影,付连战好像还在教室里讲话,同学们早该出来了,可他们现在却在教室里喊着口号。
又过了许久,他们才出来。他们排着队走出教室,然后又挨着墙站成两排。乔凡新在喊着口令,同学们在向右看齐、稍息、立定、向前看。他们都看到了我,可都没有什么反应,我从球台上跳下来,站在榆树下,想:我究竟是过去还是不过去?跑过去还是走过去?跟乔老师报告一声再进队伍,还是直接进队伍?我这么想的时候,脚已经带着我往前走了几步。乔老师突然转过身。好像他的屁股后面长有眼似的,他看见了我的移动,突然转过身,命令我原地踏步,然后立定,然后向前走,走到球台跟前,立定,向后转。这期间,同学们嘻嘻发笑,像看猴那样发笑,像被谁胳肢了一下似的发笑。然后他们就把我忘了。他们在乔老师带领下,喊着冗长的口号,他们越喊越兴奋。他们每喊一句,我的嘴巴也要条件反射地动一下,可是我无法把整句话重复下来。
第二天,他们都到村南的路边迎接知青去了。我的父母和全村的大人也去了。我的父亲负责敲锣,天不亮,他就站在院子里复习敲锣的技艺。出门的时候,他敲两下锣,赶紧用手捂住,然后再敲,这样循环往复了几遍之后,他对我说:你们学生中谁负责敲锣?没有定下来的话,你跟乔凡新说一下,说你会敲锣,跟你爹学的,比谁敲得都响,能给他增光呢。可我怎么去跟乔老师说呢?我对父亲说:爸,我们只喊口号,不敲锣打鼓。父亲说:不让学生敲也好,他们敲不成,光会瞎敲。父亲这话是对母亲说的,母亲抱着我弟弟,跟父亲往村南口去了。
现在到了这篇小说“仪式”这一章里比较有意思的部分。我所说的“有意思”,主要是说这一段故事比较滑稽。滑稽必定可笑,可我当时却觉得一点也不可笑。事实上,我当时还因它的“有意思”而受了一点皮肉之苦。这么说吧,所受的皮肉之苦,使我加深了对这段故事的记忆,事实上它也是这段故事的有机组成部分。
那天,全村老少涌向村南口迎接知青的时候,只有我一个人无事可干。打乒乓球是我最乐意干的事情,可是没人和我对打。以前我倒是喜欢对着黑板撞球,可是教室的门都锁死了。教室的墙按说也可以凑合着用,但我从小就带着唯美主义的倾向,凡事都不愿凑合着来。我只能像一只野狗那样在校园里溜着墙根乱转。后来我发现了校长住室后面有小片菜地,里面长着一个半大的冬瓜,几株尖椒,几棵丝瓜。这片菜地以前我曾光顾过,为了翻蚯叫钓鱼,可我不知道它是菜地。看见这里长出了可以毁坏的蔬菜,菜地这个概念才确立起来。我能做的事情其实非常有限,只能给它以小小的破坏。将它们连根拔掉,是不行的,因为他会追查到我。谁都明白,这一天全村人只有我一个无事可干。得考虑到时间因素,也就是说,我所干的事,应该不给人造成是这一天干的印象。屁股后面的一把削铅笔刀提醒了我,我用小刀在冬瓜上面挖了一个三角形的小口,将三角形的瓜皮小心翼翼地翻过来放在地上,然后我把小鸡从短裤旁边掏了出来。我往里面尿一点,等它渗下去之后,再尿一点。后来渗不下去了,我就把多余的尿尿到了尖椒上面,这使我又有一个意外的发现,即我的小鸡跟尖椒的形状有点类似,差别只在温度和颜色。尿完之后,我把那个三角形的瓜皮又放到原处。为了让它能彻底还原,不影响它的长势,我捏了一点土放到上面,像给它上消炎粉似的。
后来,我就朝村北的济河边走去。我往那边走的时候,心想:现在他们在村南干什么呢?很可能已经接住知青鬼子们了,知青们长得是什么样子呢?对未知事物的猜测,使我显得更加孤单。我坐在河岸边,望着河面,突然有点莫名其妙的害怕。那时候已到正午,在正午的旷野里,一个孩子莫名其妙的恐惧,我现在想起来,还是那么真切。
当他们在河面上出现的时候,我以为自己产生了幻觉,这便更使我惊惧起来,我一下子在河岸上站了起来。我往河边走了几步,确信他们是活生生的人之后,我的恐惧才去掉。
他们乘坐着两条小船,往这边漂。两条船就像一个巨大的镜面上水银剥落的那两个斑点。那两个斑点,会发出尖叫,带着标准的普通话话音的尖叫。我听到这种尖叫声,老毛病又犯了,嘴巴条件反射似的,一张一闭。后来,我不由自主地也尖叫起来。
他们就是村里正在等待的知青。
关于他们上岸的情景,关于我和他们相遇时的情景,可以写成一部书,像克洛德·西蒙受普桑的绘画作品启发写成的《双目失明的奥利翁》那样的一部书。我现在只想拣一个细节说一说。他们上岸之前,不光看我的脸,也看我的腿。我的腿被岸边的流沙深埋着,看上去就像没长脚一样。为了让他们知道我长有脚,我把脚从沙中抽了出来,然后把拎在手中的凉鞋套到脚上。我的想法是这样的:不要搞错了,我们枋口人都是有脚的,跟你们一样,都有腿有脚。
船又拐回去拉人了,他们是第一批,河那边还有一大群人。我注意到他们中的女人都很白,女人一白就漂亮。我们把女人漂亮叫做白。当然,这里的语义有点混杂,有些女人并不白,可她长得顺眼,我们就仍然说她白。因为是初次见面,我还无法把这个女人与那个女人分开,她们一白,就让我找不出区别了。
我领着他们往村里走。我没有把他们领到村支书家,而是把他们往我家领。在到达我家门口的时候,我把他们关在门外,往厢房跑去。我在屋里转了一圈,跑出来,对他们说:
我们家没有人,你们走吧。
他们都笑了起来,问我他们该到哪里去。我说到乔红军家里去。乔红军?他们说他们不认识乔红军。我只好对他们说:乔红军就是那个拖着鼻涕虫的人,他是村支书的儿子,大人们都说,村支书小时候鼻涕也是最多的。
他们还是坚持让我带他们去找红军。这个时候,我又想到了乔老师在黑板上写的那个词,“恍然大悟”。我恍然大悟,他们刚来,还不知道乔红军爱流鼻涕。
我把他们往红军家引。乔红军家的门上着锁,我只好把他们往村里的大庙引。大庙就是祠堂,因为它很大,就叫大庙。我知道人们经常在那里开大会,看电影。“知青是驴”这一名言,就是在那里诞生的。那里还经常开斗争会。有一次,一个外来的木匠和村里民兵营长的老婆睡了觉,被捉住了。人们把木匠带到大庙前打了两天。那两天,全村人像过年一样喜笑颜开。那个木匠不把睡觉叫睡觉,叫火车挂钩。我们都没见过火车。我不知道什么叫火车挂钩。大人们也没见过火车,但他们却知道什么叫火车挂钩,你从他们喜气洋洋的脸上,可以看出来,他们是知道的,我把他们往大庙引的时候,我感到有必要问一下,他们这些知青是不是见过火车挂钩。他们的回答让我很失望,他们说火车倒是见过,但没见过挂钩。
路上遇到了村支书的老婆,也就是红军他妈。红军他妈看到我们,突然叫了一声,“娘啊——”,扭头就跑。我继续把他们往大庙引。在空荡荡的大庙前,我感到有必要跟他们说点什么。我突然想起几天前乔老师曾对五年级的语文老师说,知青们连什么叫大粪都不知道,他还说他是听付连战说的。那次他们还提到了大粪坑。大粪坑是枋口村人对村南那个用来储存牲口粪、绿肥的大坑的称呼。他说知青们来了,肯定认为大粪坑是来存大粪的,他们不知道,大粪坑是说粪坑很大,而且里面偏偏是不存大粪的。许多年之后,我又想起乔老师的话,我才理解,乔老师实际上是想出道语文题考考知青们的水平,他出的题是让他们划分词组结构的。
那一天,我感到跟他们解释一下什么叫大粪是很有必要的,免得他们日后出丑。
我说:大粪就是人屎。
我说过这话,他们毫无反应。我又重复了一遍,他们还是没有反应。他们坐在自己的包袱上面,没人说话。他们都看着我,我从他们的眼神上判断,他们没有听懂我的话。坦率地说,我当时急坏了。我只好蹲到地上,嘴里发出吭吭哧哧的声音,然后用手背擦擦裤裆,站起来,指着那堆想象中的物质说:大粪。
我做这番动作的时候,突然获得了一种优越感,一种由于知道“大粪即人屎”而生长起来的文化优越感。这种感觉使我非常舒服。我得把这种感觉继续保持下去。我下面的表现带有一定的表演性质,一种获得身心自由之后的表演。我围着那堆想象中的物质转了几圈,用手捂着鼻子,像是在表演哑剧。捂鼻子的动作明白无误地传递出这样一个信息:那东西很臭,还有比人屎更臭的东西吗?
这期间,我注意到一个最白(即最漂亮)的女知青(她后来成了我们的语文老师),捂着鼻子和嘴巴笑了起来。她用胳膊肘顶了顶坐在她身边的一个男知青。那个男知青一直坐在铺盖卷上玩扑克,现在,他把牌收成一沓,摸了摸嘴唇上面的胡子,抬眼看我。她的笑很快传染给他,他也笑了,后来很多人都笑了。在他们的笑声中,我绕着那堆想象中的物质又走了两圈,然后就站定了,意思是说,既然你们已经懂得了“大粪即人屎”的道理(要是不懂,他们是不好意思发笑的。当学生的都这样),那这堂临时增设的课就可以结束了。我也笑了起来,我为自己有机会给他们上第一课而感到高兴。
村里的大队人马就是在这个时候出现的。他们围着我们(我和知青)站成一圈,都有点气喘吁吁(说明他们是跑过来的)。他们不但看知青,还看我。特别是班上的同学,看我的时候,嘴里念念有词,他们都气得要死,他们没想到,全班人在村南等了整整一个上午,没有等到,倒让我等到了。乔老师和付连战看我的眼神也有点不对头。
乔红军他爹,也就是村支书先下手,把知青的铺盖卷提了起来。另外几个村干部也照葫芦画瓢,各自提起来一个铺盖卷儿。我当时一下子傻了,不知道他们要干什么。当然,我也没有闲着,顺手从地上拿起一个知青们用的军用水壶。
放下,说你呢,放下。
乔老师对我喊了一声。那一声低沉而有力。还没等我放下军用水壶,乔老师就把它夺了过去。乔老师自己没有拿多久,他很快就把它转交给了我们的班长福贵。福贵接住之后,翻来覆去地看了又看,又摇了一摇,放到耳边听着。他似乎不知道那是什么东西。
那是水壶,笨蛋。我对福贵说。
水壶?我看是尿壶。福贵故意气我。他不但这么说,还要这么比划。他把它放到裆前,活灵活现地比划了一下。乔老师不但没有生气,还很亲切地在福贵的头顶上拍了一下。
这期间,我们已经跟着村支书往村南走,村南的路口,到处都贴着标语。乔老师边走边对一个村干部说:写标语,手都写酸了。他夸张地活动着手腕,往前走了几步,对另一个村干部说:你看我的手是不是肿了?写标语写的。他挨个儿讲了一遍,才回到学生们中间。
村支书把知青们领到村南的运河桥上,就不再往前领了。他要求大家把行李还给知青。知青们接行李的时候,有点手足无措,有点尴尬。一个知青从裤兜里掏出手绢擦汗,同时偷偷问道:进错了村子?这不是枋口吗?
支书推着他们,把他们往村外赶。那道运河桥大概只有二十来米长,可他们竟然走了半堂课之久。他们走几步,停下来商量一会儿,脸上的疑惑增加几分。
等他们过了运河桥,村支书就迅速从桥上退回来。他命令我父亲他们赶紧敲锣打鼓。锣鼓一响,知青们在桥头愣了一会儿,就加快步伐往远处走。
还不把他们给我追回来。村支书跺脚喊道。
那戴过绿帽子的民兵营长,像狗一样蹿了出去。他截住了他们的去路。当他笨手笨脚地拉一个女知青的行李的时候,这边的人群中不知道谁说了一声:挂上钩,别让她跑了。人们都嘿嘿笑了起来。村支书也笑了,他同时打手势让大家别笑。喊口号,大家跟着我喊口号,他说。
口号震天。当时喊的口号我大都记不清了,不过其中有一句我记得很清楚,全句是:反对知识青年下乡就是反对文化大革命。这句话太文给给了,也太冗长了,不易掌握,所以村支书把这句话分成三段来喊,大家也照葫芦画瓢跟着喊:反对知识青年下乡!就是!反对文化大革命!
知青们这时候大概才明白过来是怎么一回事。他们在民兵营长的指挥下,又踏上了运河桥,向这边走过来。出于对仪式的尊重,他们一边走,一边也跟着村支书喊起了口号,并且让脸上浮出笑来。在往大庙走的途中,由于他们的加入,口号声显得更加参差不齐。
迎接知青的仪式到大庙之后就结束了。当我跟着人们往家走的时候,我没想到,一顿皮肉之苦在悄悄地来临。
那天晚上,父亲回来之后,很快又被人叫走了。他们走得那样匆忙,似乎有什么要紧事。他回来的时候,我已经睡着了。我当时大概正在梦中打乒乓球,因为我至今仍记得我是从乒乓球案上被拎起来的。突然升空的感觉是让人又惊又喜的,但是,接踵而至的疼痛破坏了我的感觉。我睁眼的时候,父亲的手正朝我的脸扇过来,来回扇了几遍之后,他把我扔到了墙角。接下来是一场对话,父与子的对话。暴力充斥其间,加大了父亲话语的力度。
父亲说:说,上午干什么去了。我说我在学校玩耍。父亲就说:同学们都去接知青了,你为什么不去?我说乔老师不让我去。乔凡新为什么不让你去?乔老师……乔老师……我说不出来乔老师为什么不让我去。这时,父亲加进来一脚,这一脚踢到了我的膝盖上。你没去接知青。你干什么去了?我去济河边逮螃蟹了。逮了螃蟹,还干什么了?接知青了,我说。谁让你接知青了?父亲说着,又踢了我一脚,另加一记耳光。说,谁派你去接知青了?父亲说。父亲当然知道没人派我去河边接知青。但还是明知故问。父亲说,你逮螃蟹就逮去吧,谁让你接他们了,啊?我让你接,让你接,接,让你给我接。
父亲说着,踢着。我的母亲站在旁边没有拦他,祖父、祖母也没有拦他。平时,他打我一下,他们就会过来对我说,还不快认错,然后他们就命令他住手(孩子已经认错了,你还发什么邪火?)可是这一次,他们听任他往死里揍我。
父亲又踢了我一阵,然后把我拎了起来。他显然是想把我从墙角转移到中央,图个打起来方便。以前,他也经常这样,但这一次,他没有把我重新摔到地上。他发现我有点不对头了,我身上的骨头像是被剔净了,拎起来是一条,放下去是一堆。他把这个动作重复了几次,最后一次把我拎起来的时候,他转过身,让围观的家人看看。他们面面相觑。我的母亲打个手势,让他赶紧把我放下。父亲小心翼翼地把我放回床上,母亲他们很快围了过来。他们拍拍我的脸,摸摸我的头,揉揉我的膝盖。我的祖父开始唤我为祖宗,他说:小祖宗哎,我的小祖宗哎,你哭一声让我们听听。他这么说着,还用粗糙的手把我的小鸡掏出来,翻开包皮看了看。
在他们慌着喊我祖宗的时候,我虽然一句话也说不出来,但我的脑子却很清醒。我又想起了付连战的菜地,我的眼前出现了那只冬瓜。那只冬瓜又变成了许多只冬瓜,长在每家的房后。我不但往那里面撒尿,而且还往里面拉屎。那么多冬瓜,我是尿不过来的,不过,尿一点是一点,拉一点是一点,尽力而为吧。我这么想着,突然有了点快感。伴随着快感而来的,是一阵温暖。
你肯定嗅出来了,这世上又多了一摊东西。它出现在我的屁股和凉席之间,有稀的也有稠的,快乐、温暖以及愤怒,都由此而来。
海边理发店-[[荻原浩]]
========================
## [[海边理发店|https://www.20dcr.com/book/haibianlifadian/]]
https://www.20dcr.com/book/haibianlifadian/
-------
十五年前,我把店搬到了这里。
常有人问我,为什么要把店开在这种地方?可我很喜欢这里。整家店一个人就能上上下下打点好,不必让客人多等。我理想中的店就应该是这个样子。更何况……您瞧瞧这面镜子,初次光临的客人都会喜欢上它。放置镜子的位置,还有它的尺寸,都是我精心设计过的。
那家理发店位于一座海边小镇上。先坐电车,到站后再换乘公交车,沿着穿过山脚往远处延伸的海边公路一路向前。几站后下车,继续朝公交车的行进方向走几分钟,便能看到右手边靠近山的那一侧由红、蓝、白三色构成的灯柱,正如打电话预约时店主跟我说的那样。
沿着铺有枕木的斜坡爬五六级,就是店门口了。映入眼帘的是一座过时的西式小屋。我看不到任何写着店名的东西。店门是木头做的,上半截镶了一块玻璃。门上挂着一块小小的牌子,上面写着“营业中”三个字。
店主大概是把没人住的民宅改成了店铺。没有鲜花的院子里,立着一架被人遗忘的秋千,支架和锁链上都布满了红色的锈迹。棕榈树立在门的两侧,就像看门的卫兵。
我明明是去理发的,却对着玻璃映出的影子理了理凌乱的头发。然后,我扣上羽绒服的第二颗扣子,轻舒一口气,伸手握住门把。感应门铃发出婴儿玩具般的声响。
店内的景象却和陈旧的外观形成鲜明的对比,精致整洁,井然有序。白色的浮雕墙纸看起来像刚刚洗好、还没来得及熨烫的床单。擦得锃亮的深棕色地板分外光滑,在上面溜冰都不成问题。药剂容器的标签整整齐齐地朝着一个方向,像一群被追求完美的导演安排好站位的话剧演员。
店主站在理发椅旁边,乍一看就像椅子的附属品。他可能算准了我的预约时间,早在我到达前就站在那里了。他的头发剃得很短,明显有不少白发,却没有染。也许他不太关心自己的发型。年纪一把了,后背倒挺得笔直。
我刚在椅子上坐好,他就给我套上了白色的罩衣。让别人给自己穿衣服,而且还是年长很多的人,我感觉仿佛瞬间变成了小孩子,有些惶恐。于是我想主动把手伸进袖子里,谁知店主的动作比我更快。他问,路还好找吧?我点了点头。然后他毫无预兆地说了起来:
“十五年前,我把店搬到了这里……”
您不是本地人吧?不,我就是凭感觉猜的。而且您的穿戴也很整齐。您是从哪边过来的?哎哟,那么远啊?劳驾您大老远跑到这种乡下地方来,真是不好意思。您是不是在那个什么“因特网”上查到这家店的?我对电脑啊,真是一窍不通,只是听人说过这家店在网上有点名气。我也没什么厉害的本事,只是干这行的时间比较长罢了。承蒙大家看得起,还有客人愿意大老远过来捧场,我当然是感恩都来不及啦。
店主嘴上这么说,可是在我看来,他其实有些为难。镜子里的他面带完美的微笑,让人无法想象他露出其他表情的模样。他的嘴唇两侧刻着深深的笑纹,但同样的笑纹并没有出现在眼角。
他往我的头发上喷了些温水,然后盖上一条热毛巾。
我有多久没有去理发店剪过头发了?高中毕业后,我想把发型弄得时髦些,于是不知不觉养成了去美发厅的习惯。原来常去的那家理发店的大叔,总想把我的头发剪成跟他一样的三七开。
店主把热毛巾往我的头皮上压。好烫,我差点喊出来,但并没有觉得不舒服。对了,享受毛巾的热度渗进每个毛孔的感觉,不就是理发店的妙处吗?那是一种令人怀念的感触,一种被我遗忘已久的感触。
热毛巾散发出一丝微弱的生发水香味。这种香味也让我备感怀念。那是“大人”的味道,是成熟男人的味道。小时候,每次去理发店,我都会使劲闻这种味道,把它当成一种通往陌生世界的记号。
您想剪成什么样呢?像您这样的年轻人,平时应该很少进理发店吧?嗯,我当然能看出来,因为美发师的剪法跟我们不一样。您特意选择这家乡下理发店,是不是有什么特别的用意啊?
对不起,我不该瞎打听的。因为有很多客人会在痛下决心或是决定改变现状的时候,去一趟理发店。干这行的日子久了,我由衷地觉得,在遇到人生转折点的时候剪头发可不是女人的专利。男人也一样。
您放心,我不会给您剪那种老土的发型。有什么要求您尽管提就是了。
我不擅长向理发师提各种要求。“照现在的样子,剪短一些就行”——这句说惯了的话差点脱口而出。可是闻着那生发水的味道,我改变了主意。
来一趟有名的店不容易,于是我鼓起勇气问,您觉得我适合什么样的发型?可以拜托您拿主意吗?话音刚落,店主的眼角就浮现出了笑纹。
您能提这样的要求,我真是太高兴了。当理发师的都盼着能听到这句话。可这事还真不能我一个人说了算,我还是会跟您商量着剪的。
嗯……您的脸是瘦长型的,所以两侧留厚一点可能比较好。您平时用哪只眼睛比较多?右眼是吧?那发线也分到右边吧。因为别人看您的时候,视线会下意识地顺着发线的方向。如果对方的视线碰上您的主视眼,您的表情就会显得更有活力。
您是做什么工作的?您别怪我多事,我只是想知道您从事的是要和很多人打交道的工作,还是特别注重整洁感的,抑或是信誉至上的?怎么说呢,就是想了解一下您的工作性质。
我一直觉得,男士们应该根据自己的工作性质选择相应的发型。不能光看脸型和着装,工作其实也是选择发型的重要标准。这年头啊,运动员的发型越来越像夜店牛郎。您可能觉得我的思想特别古板吧。
平面设计师?啊,我懂了,就是设计书本、杂志这种东西对吧?
店主抓起一束刘海,用指尖轻抚一下。只见他微微点头,然后小心翼翼地把我的整个脑袋摸了一遍。他的动作如此轻柔,像在摸古董壶一般,摸着摸着,还不时歪一下脑袋。他应该是在检查我的发质和头骨的轮廓,可我总感觉在参加一场考试,他就是检验我有没有资格在这家店理发的考官。
我的发旋长在一个特别奇怪的地方。一摸到它,店主的手就停住了。之后,他又摆弄了一会儿我的头发,随即轻叹一声。他会对我说什么呢?我有些紧张。谁知从那双薄得仿佛一条皱纹的嘴唇间吐出的话,仅仅是关于新发型的几个选项与提议。
不等我开口回答,店主就“咔嚓”一声,动了一下不知何时拿在手上的剪刀,仿佛是要打断我的反驳。然后他用结案陈词般的口吻说道:“也不知道为什么……”
也不知道为什么,大多数人会特意要求理发师剪一个并不适合他们的发型。明明已经不年轻了,却想保持年轻时的发型。明明长得很凶,却想把自己弄成文弱书生的样子。我一个剪头发的,说这话可能有些不知天高地厚。但我觉得,我们理想中的自己和现实生活中的自己往往是不一样的,虽然我们都能透过镜子,看到自己的模样。
我回答,那就剪您最先提到的那种吧。无论接受店主的哪个提议,我的头发似乎都会被剪得短短的。
直到这一刻,我才怀着上手术台的心情,把进店后一直绷着的背靠在椅子上。照店主的说法,我会在一小时后见到陌生而真实的自己。
理发椅上装着头枕,也有脚垫,像温柔的臂弯一般将我环住。下沉的柔软身体与稳稳往上托的弹力在黑色的皮革中对抗,让人产生浮在水面般的错觉。
我的眼前是一面硕大的镜子。镜中映着海景。这家店所在的位置要比沿途的其他地方高出一截,所以窗外没有任何遮挡物。身后窗外的大海,就这样一览无余地映在了镜中。
秋日午后水蓝色的天空,深蓝色的大海,两种蓝色各占据半面镜子。除此之外,还飘浮着白云,好似未上任何颜色的留白。要是没有从右向左飞过画面的海鸟,这面镜子和裱过的一百号风景画没什么两样。
您喜欢这面镜子吗?那就好好享受镜中的景色吧。有了它,客人们就会看着正前方,这样我用剪刀的时候也会更顺手一些。我们理发店有个规矩,客人一旦坐上理发椅,就不能再看书了。可是最近,好多人刚坐下就掏出手机开始摆弄。
店主用梳子用力拉起我后脑勺的头发,发根都绷紧了。只听见“咔嚓”一声,倒梳起来的头发被剪断,挣脱了梳子的束缚。我感觉到一丝痒痒的快感。先拉,再“咔嚓”。理发店的声响居然也和那些把脑袋当玻璃摆件处理的美发厅不一样。原来进理发店是一件这么享受的事?还是说,是因为这位店主技艺精湛?
我坐的这张椅子斜上方挂着一张裱了画框的奖状。它显得那么随意,仿佛是往墙上挂浮雕画时顺便挂上去的。把视线移到视野的尽头,还能隐隐看见置物架上的观叶植物后藏着奖杯。
据说当年有不少大牌明星和政经界大腕特别推崇店主的手艺。这一段段趣闻逸事,让店主一度成为世人议论的焦点。去年某位大明星去世的时候,他与理发店的不解之缘再度成为人们津津乐道的话题。还有杂志说,理发店的店主已经离开了东京,把店搬到了偏远的海边小镇。
我抱着试一试的心态打电话到店里约时间,却毫不费力地约到了想要的日子。我来的时候,店里并没有别的客人刚走的迹象。而我进来之后,也没有其他人出现。
工作忙吗,自由设计师?呵,您还这么年轻,就已经自立门户了?了不起。瞧您说的,每天忙得团团转,那就是成功的体现呀。无论做什么生意,头几个月都是最关键的。是成功还是失败,头几个月一过就知道了。哎呀,我都为您高兴。毕竟我也自己做了这么多年,特别有共鸣。
我觉得,工作这件事,说白了就是揣摩别人的心思。有时是揣摩客人的心思,有时是揣摩同事的心思。当理发师也好,在别的店里工作也好,做公司职员也好,这一点都是不变的。
我这可不是倚老卖老讲大道理。因为工作关系,我接触过各种各样的人,也跟各种各样的人聊过。我刚才说的,也算是一种统计结果吧。
各行各业的成功者,都是擅长解读人心的人。倒不是说他们特别有人情味,只是有一种能看穿别人心思的能力。说他们会糊弄人也成。糊弄这个词有点难听,但这些成功者的确都有成为一流骗子的潜质。
我想学也学不来。我嘛……只是做这行的时间比较久罢了。毕竟我入行的时候还在打仗呢。
从后往前剪过一轮后,店主换了一把剪刀,也换了一把梳子,再次回到后脑勺。
这一次,他手上的动作变得更细腻了。落在罩衣上的头发都特别短。如果把剪头发比喻成雕刻,那么第一轮就是粗雕,刚开始的第二轮则是对细节的精修。店主的每一个动作都很从容,唯有右手的手指忙个不停,好似寿命很短的小动物在活动。
嚓嚓嚓……剪刀发出清脆的响声。店主的话特别多。也许他本来就爱说话,又或许是他把聊天看成了服务的一部分。
我出生在东京的平民区,是那种放眼望去尽是长屋的地方。我们家从我祖父那代开始经营理发店,我算是第三代传人。所以我还没出生的时候,就已经注定要干这行了。
还在国民学校的时候,我就过上了一放学就去店里帮忙的日子。算实岁的话,我当时才十一二岁,正是最贪玩的年纪。
客人的头发是绝对碰不得的,我每天的工作就是把地上的碎发打扫干净。一有客人剪完头离开,就得把地上的头发清扫干净。这是我父亲的信条。只要地上有一根漏掉的,我就得挨拳头。我们家在当地也算老字号了,店里有其他理发师傅,还有徒弟,根本不缺人手。我当时特别不理解,为什么非得让我干这个呢?
当年的理发师傅都是十二三岁拜师入门的。现在想来,父亲大概是怕我继承家业的时候被其他师傅瞧不起吧。父亲,尤其是那个年代的父亲,绝对不会对孩子说“你真乖”“我对你有很高的期望”这种话。但他们心里都是这么想的——绝不允许自己输给外人,可输给亲儿子还是心甘情愿的。真的,我可没骗您。
店主凝神看着我的脑袋。他的嘴动个不停,手却没停下。他只用左手大拇指抓住梳子,同时用食指和中指梳起我的头发,动作灵巧得很。好长的手指。只见他高高抬起手肘,手上的动作非常细微,一点点修剪着头发。那眼神就像在精雕细琢某件工艺品似的。我可没有一边动剪刀一边跟人说话的本事。就算剪的是最简单的彩纸,我也怕剪到自己的指头。
后来,局势越来越紧张了。男人大多剃了光头,去理发店剪头发的人也越来越少,于是理发店一家接一家地关门。我们家的生意还能勉强维持,只是店里几乎没剩下几个员工。理发店是所谓的“和平产业”,难免会被官府盯上。理发师傅被召去当兵不说,连理发椅的架子都被征用了,因为是金属做的。
不过也多亏了这番折腾,上初中的时候,父亲终于允许我用推子给客人剃头了。我还清楚地记得,自己的第一位客人是鞋店的少东。他是个时髦的人,平时都把头发梳到后面。也不知是为什么,那天他点名要我剃,说:“今天就请小师傅剪吧。”
原来他收到了入伍通知,临走前特意来剪头发。他平时天天擦发蜡,被宪兵打了也不肯改,一下子剃成光头哪儿受得了。镜子里的他一脸凝重,那表情我至今都忘不了。只是我也不知道他是下定了决心上战场,还是仅仅不甘心而已。剃完后,他对我说:“等打完仗,我还要留背头。你可得好好练本事,以后给我剪啊。”说完还给了我一颗奶糖。当时奶糖已经成了在黑市才能买到的东西。可是,他到底还是没能活着回来。
店主把手指搭在我头上,让我把头仰起来。镜中的水平线稍稍下降了一些。窗口上方的挂钟映入眼帘。镜中的钟是左右相反的。本该指着下午四点的时针正对着八点钟的方向。西沉的红日在蔚蓝的海面上投下金色的光影……
年轻人听我说这些一定很无聊吧?您要不要睡一会儿?不用睡?那我就接着往下说了。像我这样的老头子也只能说说陈年旧事了。不过父亲当年教导过我,口才也是理发师傅的必修课。啊,他没直接跟我说过这话,是他的背影告诉我的。
父亲在我、家人和店里的其他理发师傅面前从来都是绷着脸,但他在店里特别健谈,对客人也很热情。无论人家是刚从外地回来的电工,还是女校的历史老师,父亲都能跟他们聊上几句。这样的本事可不是谁都有。毕竟父亲付出了许多不为人知的努力。他会把每天的报纸从头看到尾,理发店放假的时候,他还特意去浅草听压根儿就不喜欢的落语。母亲当年总抱怨,父亲把一整天能说的话都在店里说完了。可惜我们家的店在昭和二十年的那场大空袭中毁了。
店主后退半步,把老花镜推到额头上,开始前后左右打量我,严肃的表情中没有一丝微笑。我有点难为情,甚至觉得脸颊发痒。“嗯……”他点了点头。我还以为这就剪完了,没想到他又换了一把剪刀,像修剪盆栽似的,在某些地方稍微剪上几刀。店主的剪刀都放在吧台的托盘上,闪着银色的光。他到底有几把剪刀啊?
战争是我上初二那年结束的。嗯,生活很快就开始恢复,可能比现在的年轻人想象中更快一些吧。那年九月,学校就复课了,因为校舍只烧毁了一半。
恢复的速度真是快得出奇。您知道老师们在复课后做的第一件事是什么吗?回收那些灌输军国主义的教科书,像修身、国史什么的。我越想越觉得学校是个荒唐的地方,就养成了逃学的习惯,时间久了干脆不去了。再后来,我离家出走,在黑市干起了替人跑腿的营生。
其实,我原来是想当个画家的。上学的时候,我成绩最好的那门课是美术。家里还有店需要我接班的时候,画家是个遥不可及的梦,可理发店已经没有了呀。于是我一边捡烟蒂,拆出里面剩下的烟草做卷烟,一边用小铅笔头练素描。因为我听说武藏野的美术学校复课了,想去那里上学。战争结束的第三年,我父亲搭了个棚屋,重新开起了理发店,可我当时根本没有回家帮忙的打算。
可是,我漏掉了一个最重要的信息。只有旧制中学的毕业生才有资格报考那所美术学校。
店主看着我映在镜中的脸问道,想当设计师的人是不是要先上专科学校?很多专科学校有平面设计专业,但我是从美术大学毕业后才进的设计事务所。我怕戳中店主的伤心事,最后还是老实回答了,并补充道,我现在还时不时接一些插画的工作。
听到这儿,店主的手竟然停住了。只见他低头看着自己的手,仿佛在纳闷:为什么手里握着的不是画笔,而是剪刀?片刻后,他察觉到了我的视线,眯起眼睛笑了。“哎呀,真棒……”然后他又重复了一遍,“哎呀,真棒。”
离开黑市后,我跟着替人画招牌的画师做了一阵子学徒,还画了一些作品给美术展投稿,却一无所获。最后,我还是回家了,求父亲再给我一次机会。于是我又干起了给理发店扫地的差事。那一年,我十八岁了。
我没上过理发学校,都是照着父亲的样子学的。父亲也没有手把手教过我,翻来覆去只跟我说一句话,“地上不能留一根头发”。但这句话的意思和战前是不一样的——那会儿,我们要把剪下来的头发卖给做佃煮的铺子。因为当时物资匮乏,黑心铺子会拿头发做化学酱油。头发的主要成分不是氨基酸嘛。
回家两年后,父亲才允许我给小客人剃头。到了第四年,他终于开始把店里的一把椅子交给我负责。他经常当着客人的面吼我,但我总算能站在他身边干活了。谁知没过多久,父亲就走了。一天早上,他突然心脏病发作,好端端一个人说没就没了。
店主一遍遍问我,听他说这些会不会很无聊?他每问一次,我都要摇一次头。在我心里,那个年代的事一直是“很久很久以前”的事。可是听他这么一讲,当年的光景仿佛都浮现在眼前。毕竟此时此刻,一个从那个年代走来的人正在给我剪头发。
我的头发短了很多,脖颈后面凉飕飕的。不见了刘海的额头,总是被挡住大半的耳朵都露了出来。镜中的我和平时判若两人。哦,原来我长这样啊……
店主把剪刀换成了剃刀,反复削着发梢。削了好一会儿,他才不情愿地松开我的头发,用刷子掸落罩衣上的碎发。然后,他就从镜中消失了。人虽然走开了,可嘴巴还在动。
于是我二十出头就成了一家店的顶梁柱。父亲走后,客人明显比原来少了很多。不少才怪呢,谁想让一个昨天还在挨老爹骂的年轻人给自己剪头发?我要是客人,肯定也这么想。
打那以后,我就开始玩命练本事。现在的理发师可以买假人练手,当年可没有这么好的条件。我只能到处求人帮忙,说“只要你让我剪头,我反过来给你钱”。掉在地上的头发我也不卖了,全部拿丝线捆起来,作为练习的工具。这些碎发本来已经很短了,但我会继续剪,直到它们跟平头的头发一样短。那时候街上常有野猫野狗的死尸,我有时候会把它们捡回家练手,觉得太臭,就在鼻孔周围抹点曼秀雷敦的唇膏对付一下。总而言之每天从早练到晚。客人比原来少,时间自然就多了。
昭和三十年以后,店里的生意才一点点好起来。我本来想说这是我潜心练习的结果,但生意好转的原因其实很简单,就是“慎太郎头”。
啊,您不知道呀。就是当过东京都知事的那位先生年轻时留的一种独特的发型。他弟弟石原裕次郎主演的电影上映后,这种发型开始流行起来。也算平头,但是额发比较长。
我成了我们那一带最擅长剪慎太郎头的理发师,名气一下子响了。毕竟那阵子满大街都是留慎太郎头的人。多亏了这种发型,理发店的生意才上了轨道。
您问我是怎么练的?嗨,其实我自己就是裕次郎的影迷,想模仿他的风格和打扮,于是做了很多功课,把自己的发型也剃成了慎太郎头。
慎太郎头的难点在于额发与两侧的平衡,但剪起来不是特别费事,一天能剪好多个。我真的特别感谢这个发型。
肥皂味扑鼻而来。回头望去,原来店主正在用一把形似茶筅的刷子在四四方方的陶器中打肥皂泡。
对了,理发师是会给客人刮胡子的。我小时候也经常去离家不远的理发店剪头发,但那时我还没长出几根胡子,总是选价格更便宜的只理发的套餐。这应该是我第一次让别人刮胡子。
三十年代真是理发店的黄金时代。熟客每个月至少要来两次。毕竟那时候没什么东西好供人消遣,对男人来说,理发是一大享受。当年也没人预约,客人都会耐心排队。我们店里有将棋的棋盘,有的客人会在排队的时候杀上一局。下了半天没分出胜负,引得我凑过去看热闹也是常有的事。孩子们都爱看漫画,一看就停不下来。被叫到的时候,反而会一脸不高兴。
对了对了,那时候姑娘也是来理发店剪头发的。大家都会剪所谓的“少女头”,跟童花头有点像,但脖子那儿会剃得更短一些。我们家应该也是那一带头一家买电视机的理发店。
我就是在买电视机那年成的家。为什么记得那么清楚呢?因为我取消了热海蜜月游,用省下来的这笔钱付了电视机的首付。老婆是我的远房亲戚,来自秋田,原本是在店里打杂的。文文静静的一个人,勤快得很。先看上她的不是我,而是我母亲。不知不觉,家里已经把婚事安排好了。我也没想太多,只觉得她长得还不错,仔细瞧瞧挺好看的,于是答应了这门婚事。回过神来才发现,自己已经成了家。当年人们结婚都是这样的。
我紧张地等待店主给我刮胡子,没想到他只剃了发际,就往我身上多套了一层塑料罩衣,说道:“先给您洗头吧。这边请。”我只得起身跟着他过去。坐在椅子上仰视他的时候,我还觉得他比同龄人高,但站起来一看,他的身子就显得特别小了。
洗头池设在房间的角落,前面放着一把椅子,和我刚才坐的那把一模一样。店主刚才说了,一个人就能上上下下打点好的店才是他的理想。这是放在店里的另一把理发椅。坐上这把椅子的人兴许也能看见大海。
我在洗头池前坐下。因为在美发厅洗头的时候,人都是仰面躺着的,所以我刚开始还有点懵。在店主的示意下,我弯下腰,把头伸进了水池。
店里的背景音乐轻柔而安静。现在放的这首曲子是披头士的《露西在缀满钻石的天空中》。音乐声是从屋子深处的卡带录音机里传出来的。我问店主,您喜欢披头士吗?这是我第一次主动和他说话,声音竟有些嘶哑。
披头士?啊,您是说现在放的这首曲子?我都没注意。放音乐是为了让客人放松一些,倒不是我自己喜欢听。我会根据客人的年龄和给人的感觉选择要放的曲子。平时放得比较多的是古典乐和电影音乐。我一般都会挑安静的曲子,客人要是想听流行歌曲,我也会放的。
店里没准备太多适合年轻人的曲子,于是我就想,放点披头士好了。
店主冲洗了好久,这才往我的头上倒了一圈洗发水。凉凉的。原来我刚才闻到的肥皂味是这种洗发水的味道。店主仿佛在用手抚摸我的头一样。与其说是洗头,不如说是按摩头皮。
然后冲洗了第二遍,上了第二遍洗发水。头发打出了泡沫。手指的力度比刚才更大了。唰唰唰……传来轻快的响声。自己洗头的时候,是听不到这种声音的。
您要是问我喜不喜欢披头士,我只能说我没办法喜欢上他们。老理发师应该都不喜欢吧。倒不是说他们的歌不好,问题出在头发上。
理发店的生意,是从昭和四十年代初那群人到日本来访以后开始走下坡路的。头发长了,就去理发店剪短一些。男人都是这样,就跟太阳东升西落一样理所当然。可是这个习惯被那群人彻底摧毁了。
变化不是突然出现的,而是慢慢发生的。从那时开始,理发店就一点点、一点点地萧条下去。也许是因为我们这些老理发师坚信,从东边升起的太阳今后还是会在西边落下,谁都不愿直视现实世界的潮流。一些机灵的理发师开始给客人烫头发,可惜我周围的同行们太乐观了。他们觉得玩小乐队的都不是什么正经人,这些人掀起的潮流绝对长久不了,很快就会消停。
后来,就有了嬉皮士和疯癫族。留着乞丐发型的年轻人开始频频出现在街头巷尾,传统的理发店一家接一家地倒闭,就像一根根从头皮脱落的头发。
我家的店也没能幸免。三十一岁那年,我在理发大赛上拿了个小奖。可这种奖啊,真的是一点用都没有。眼看着店里的生意越来越差,两个雇员的工资都快开不出来了。我也知道,要是把他们辞掉,我一个人负责理发,让老婆做其他杂事,店还可以勉强维持下去,但我打定了主意,要是真走到不得不辞退员工那一步,就把店关掉算了。倒不是因为我特别疼惜员工,只是我们家是有三把理发椅的老店,我又是第三代传人,这口气还是要争的。我就是听不得别人说我家的店江河日下。
工作不顺心的时候,私生活也是要出问题的。我这人特别爱喝酒,酒品还不好,一喝醉就控制不住自己。渐渐地,我开始打老婆。老婆是个温顺老实、沉默寡言的人,所以我们吵不起来。她从不顶嘴,也不跟我发牢骚,只是默默地收拾被我摔碎的玻璃杯和小酒碗。
可是……我想以过来人的身份给您提个醒,这世上没有比温顺老实、沉默寡言的女人更可怕的了。
一天,我参加完商店协会的联欢旅行后,回家一看——老婆没影了,她的衣服和东西也都不见了。我每次赌马赢了钱,都会买些围巾、发卡、首饰之类的小东西讨她欢心。可这些东西都被她丢进了垃圾桶。
敢情她是回了秋田的娘家。过了一阵子,她寄来了离婚协议书。反正也没孩子,我就毫不犹豫地盖了章。我们一起生活了十多年,中间却始终隔着一面镜子。就算朝对方伸手也没用,因为镜子里的东西都是反的,连握个手都是奢望。啊,您感到哪里痒吗?
店主用手掌揉搓着我满是泡沫的头两侧,又用蜷曲的手指揉捏头顶。先强,后弱,再强……我的头随着他的动作上下左右摇摆,好不爽快。疼吗?水没流到眼睛里去吧?店主用哄孩子的口吻问道。
冲第三遍,上护发素,然后又是漫长的冲洗。
回到之前的那把理发椅上,他先用毛巾擦头发,再拿吹风机吹。在此期间,我只做了一件事,“坐着”。像小孩子一样任人摆布的感觉太舒服了。
那是什么时候的事来着……大概是跟老婆正式离婚后没多久吧。我也没有力气再逞强了,只能辞退那两位雇员,独自守着偌大的店面,呆呆地等客人上门。
就在这时,店里来了一位头发长得吓人的男青年。他穿着一件印着佛祖的T恤衫,下身是喇叭牛仔裤,长发到腰。要是他张口就说“给我剪到十五厘米长”,我肯定会把他轰走。
谁知他对我说,帮我剪成三七开的短发吧。我顿时觉得心头一热。我生怕他中途改变主意,连忙先给他咔嚓一刀,然后才问,你为什么要剪头发啊?
他说,跟我同居的姑娘怀孕了,再玩音乐也没法养活她,所以要去找一份正经工作。
我在给他剪头发,他在理发椅上掉眼泪。那可是一个满脸都是胡子的人啊。我不由得想起了当年的鞋店少东。那次我剪得特别用心,还免费帮他刮了胡子。
经过这件事,我下定决心,要让理发店改头换面。青年走后,我就把自己的慎太郎头给剃了。打那时起,我的头就一直是您看到的样子。
不能死抓着只有历史的破店不放。我一咬牙一跺脚,举债装修了店面。后来,一位做经营咨询师的客人告诉我,这就叫“高风险高回报”。
我撤掉了等候区的电视和漫画,把整个房间弄得跟酒店大堂似的,还雇了新员工。我们店原来只招年轻人,从零开始慢慢培养,但我打破了这个传统,从一家名店挖了个手艺不错的人过来,给他开了很高的工资。然后我还去学了按摩,从最基础的学起。当时正好是美容院刚进日本的时候,全国上下加起来没几家,我们还一起去听过美容技艺的讲座。洗发水、生发水什么的也全换成了原来不舍得用的高档产品。不过我也把价格相应提高了一些。在别家把价格提到一千日元都要犹豫半天的时候,我家的定价是一千八,高了将近一倍。从这一点就能看出,我当时真的是豁出去了,别说是从清水寺的舞台上跳下去,那简直是从珠穆朗玛峰上跳下去。
我心想,反正横竖都是死,还不如弄一家自己最满意的店,最后搏一把。实在不行,那我就去当疯癫族算了。
没想到这一搏还真赢了。说起来也真是不可思议。原先的客人的确被吓跑了,觉得我们家的门槛太高,但是有新客人来呀。虽然这家店没什么拿得出手的,可创业时间长也成了一个卖点。就凭这个,我也得好好感谢守住这家店的父亲和祖父。还有一个人千谢万谢都不够。要是没有他,我家的理发店怕是火不了几天,是他让这家店真正兴旺了起来。
店主开始给我按摩了。长长的手指将柑橘味的精油揉进我的头皮,按压着我的头部。那感觉就像故意把手指插进了头盖骨接缝,连微弱的痛感也变成了快感。之后,他又用手指按住我头部两侧的下巴根和太阳穴,把头整个儿往上拔,我不禁喊出了声。
他是一位非常著名的演员。至于名字,我就不说了,不然会给人家添麻烦。就是这样一位大明星,成了我家的常客。
他第一次来的时候,着实把我吓了一跳。因为他来得很突然。我只能说,他就像直接从电影屏幕里走出来的一样。
当时浅草有个谐星出身的配角演员不时来我家剪头发,大明星貌似就是从他那儿听说了我。他一坐下便说:“我接了部黑帮电影,帮我剪个有那种感觉的发型吧。”
我顿时犯了愁。起初,我建议他剪方头——说白了就是平头。可平头是很难剪的,特别考验理发师的技术。而且大明星的发质偏软,就算剪短了,头发也立不起来,弄不出四四方方的轮廓。我心想:完了,这头发没法剪平头……只能再跟他商量,但他翻来覆去就一句话:“您看着办吧。”他面色凝重,眼睛紧紧闭着,仿佛在忍受某种痛苦一样。他肯定在苦恼,觉得再演帅气善良的角色很难有突破了。
我想象自己正站在理发大赛的决赛会场,打起十二万分的精神。两边的头发剃到最短,几乎能看见头皮,顶部的头发则稍稍留长。我不是很擅长剪慎太郎头嘛,给大明星剪的发型,就跟慎太郎头的平头版差不多。最后再用大量的发胶让留长的那部分头发立起来就成了。他日后的标志性发型就是这么来的。
大明星特别满意我给他做的发型。后来他还亲自打电话给我,请我去了拍摄现场,说化妆师就是没法让他的头发竖起来,还是得让我出马。
他顶着我弄的发型主演的那一部电影,我足足看了三遍……不对,是四遍。经过这件事,我总算对自己的工作产生了自豪的心情。
从那以后,大明星就成了我家的忠实顾客。他特别喜欢理发,不拍摄的时候,每周要来店里剪两次。店里客人再多,他也会耐心排队,坐在休息室里盯着天空看。其他客人看到他的时候,那叫一个吃惊……我就是在那时开始采用预约制,不让大家到店里排队了。
有大明星给我做活广告,我就谢天谢地了。没想到他有一次还在接受媒体采访的时候透露了我家的店名。报道一出,理发店的生意一天比一天好,简直跟做梦一样。
我在店里接待过各种各样的客人。
有一位以发型奇特著称的谐星也是我家的常客。可他理发的时候几乎不说一句话,就这么绷着脸,显得很不开心,看着我一点一点把那个一上台就能逗乐观众的发型做出来。
还有一位以文笔厚重著称的小说家。他每次来,都要求我把头发弄得竖起来。但他并不适合这样的发型。也许是因为他身材比较矮小,想尽量让自己显得高一点。
其实啊,政治家比演艺明星更讲究发型。有一位当过大臣的政治家,总会在参加电视辩论的前一天带着保镖来我家剪头发。白头发才长出来没几毫米,他就要我重新染。因为他额头上的头发比较稀疏,我必须把侧面的头发拉过来,再用发胶牢牢固定好。那发胶的用量,比银座的女公关还多呢。
嗯,我见过各种各样的人。当然,我一直是隔着镜子看的。
按完头,再按肩膀,脖子不停地晃动。我从来没在店里做过按摩,多少有些不自在。毕竟给我按摩的人都一把年纪了,他显然比我更需要按摩。他按得特别好,特别舒服,可我总觉得过意不去,只盼着他能快点按完。然而,店主就是不停手,一会儿按上臂,一会儿又按前臂……连手心都按了。
镜中的天空逐渐多了几分浅浅的橙色。大海的颜色也越来越暗了。
您还这么年轻,肌肉关节却很僵硬。说句不怕冒犯的话,设计师可能跟理发师一样,平时要做很多精细的手工活吧?啊……现在都用电脑啦?哎呀,用电脑也一样。肌肉酸痛就是努力工作的证据,多了不起啊。
我说到哪儿了?啊……想起来了。从那个时候开始,就有很多名人来我家剪头发。于是周围的人开始吹捧我,说我是“理发大师”啦,说我经营手腕厉害啦……越是这种时候,就越应该谦虚谨慎,可我把这些话当真了。
而且我当时正是最爱逞威风的年纪。比自己年轻的客人一多,就不知不觉地高傲起来,可我还以为自己的服务态度很好呢。更要命的是,干同一种工作的时间久了——尤其是那种简单反复的事儿做多了,就不把脑子用在这上面了,反而会绞尽脑汁去想什么经营啊、人生啊、哲学之类的玩意儿。
渐渐地,我的头就低不下去了,脑海里还冒出了这样的念头:我可是在理发大赛上拿过全国一等奖的人,还有过人的经营手腕,给别人刮胡子、洗头、掏耳朵的差事,要干到什么时候?
四十八岁那年,我在银座开了分店。说得好听点,那是我有“事业心”,可我真正想做的不过是往脸上贴金罢了。我想要的,就是一层薄薄的金箔。我本打算等分店的生意上道后,就不去店里接待客人了,专心管理店铺。我把父亲传下来的总店交给装修时请的得力干将负责,自己去银座分店坐镇指挥。现在想想,我当时没有看清理想和现实的差距啊。
先生,您要是有把业务做大的打算,可一定不能大意。公司做得再大,也别把公司守则挂在墙上,挂上“初心”才对。哦,您准备一个人做下去?也许这才是最明智的选择。
店主按了我的头部、肩膀与双手。我坐在椅子上,整个人有些恍惚。店主留下的指痕还在隐隐作痛。血液仿佛在全身奔涌。我现在的表情一定很呆滞,仿佛高潮刚过。店主按得就是这么舒服。
我靠在椅背上。戴着口罩的店主把热毛巾按到我脸上,肥皂的香味刺激着鼻腔。我又听见了打肥皂泡的声响。
蒸汽充分渗进肌肤后,店主取下毛巾,在我的脸颊上涂抹温热的肥皂水。
分店开张的第二年,我又娶了一个老婆。那时我常在下班后去一家银座的小店消遣,老婆那时就在那家店。不是什么夜总会,是普普通通的小饭馆。老婆是老板娘朋友的女儿,受老板娘所托去店里搭把手,白天是坐办公室的。
我们刚认识的时候,她大概很讨厌我。因为我白天净对人点头哈腰了,去饭馆的时候总喜欢摆摆架子。这个老婆是我穷追猛打,好不容易才追到手的。
老婆能干得很。她明明比我小一轮,我却总挨她的训。碰到品行不太好的客人,我难免要说人家几句坏话。遇到这种情况,她就会教育我说:你收了那么多钱,忍忍是应该的。你第一次来我们饭馆的时候,我就是这么暗示自己才忍住的。她说得那么不客气,我却不发火,真是奇怪。
后来我们有了孩子。我跟前妻没有生育,五十多岁才有了第一个孩子,含在嘴里怕化了,捧在手里怕摔了。如果人生真的有巅峰和低谷之分,孩子出世的那一刻就是我人生的巅峰。
可惜好日子啊,总是不长久的,所以才更显得珍贵。您看我现在这副样子,应该就能猜个八九不离十了。没错,在银座开分店并不是明智之举。眼看着分店的生意越来越差,我又开始借酒浇愁。
这个老婆和上一个不一样。她一看到我喝酒就发火,说我这样太不像话了。但我从没打过她。因为我很清楚,要是我动手了,她会加倍奉还。我没打她,却也不怎么回家了。明明还爱着她,却在外面找了别的女人。只因为我不想听她唠叨“你明天还要去店里啊”,“再这么喝下去身体要出问题的”,我只想安安静静地喝酒。
开始剃须后,店主顿时安静了许多,也许是因为他正拿着刀吧。削断胡须的声响好似骤雨。我只能在雨声的间隙听到隔着口罩传来的含混不清的声音。
我刚才还大言不惭地说,我见过形形色色的人,听过五花八门的故事,仿佛我的人格也在这个过程中得到了提升。可是,我其实一点长进都没有。我想要的不是理发椅,而是一张能让自己坐下来的椅子。我还是那个以未来的艺术家自居的小屁孩,一点都没变。
那时的我,看什么都是隔着镜子的,因为正视现实会很痛苦。
到头来,两家店都归了别人。其实,要是咬牙放弃银座的分店,总店应该还可以开下去的……可惜出了点事。
实话告诉您吧,我杀过一个人。
贴在喉头的剃刀顿时凉了几分。店主会在这个时候说出这句话绝非巧合。我觉得他是故意挑了这个节骨眼,仿佛在试探我一样。不,也许他在试探他自己。他大概想知道,投映在“客人”这面镜子中的自己是什么样的。
那是二十六年前的事情了。帮我打理总店的人突然请辞,说要自立门户。这么多年来,他一直是我的左膀右臂。当时他也四十多了,有自己的家,我也料到他总有一天是要走的。可我原打算让他用我家的店名开店。听说他要走,我气得火冒三丈。而且他还要带一个员工走,甚至要求我分一部分顾客给他。这些要求令我气到极点。打烊之后,我们在总店吵了起来。
我原本在酒馆跟老主顾喝酒,是他硬把我叫去店里的,所以我去的时候已经有点醉意了。吵着吵着,我被他的一句话给激怒了——现在我却想不起他当时说了什么。说时迟那时快,我顺手抄起一旁的发钳,打在他的头上。最要命的是,那偏偏是一把又大又重的老式发钳,我家的店徽就设计成它的形状。
起初,他还是清醒的,是我叫的救护车。我陪他去了医院,一路上不停地跟他说,对不起,对不起……后来,我就被警察带走了。两天后,警察在审讯室里告诉我,他死了。因为我犯的是“伤害致死罪”,明明夺走了一条人命,刑期却短得可怜。
我在服刑期间跟老婆办了离婚手续。她原本不同意离婚,但我的态度非常坚决,好说歹说才劝动了她。为了让她点头,我不惜撒谎骗她,说我要跟外面的那个女人——其实她都没来探过监,肯定是一听说我被抓就跑了——在一起。这婚是一定要离的,因为我不忍心让她变成杀人犯的老婆,也不忍心让我们的孩子变成杀人犯的孩子。自那以后,我再也没联系过她。
不知不觉,胡子剃好了。店主也从镜子跟前消失了。他貌似还没完工,只见他又去里屋取新的药水和工具。
椅背还没扶起来。我抬起头,看见了镜中的挂钟。本以为时间已经过去好久,却惊讶地发现从我进店到现在才一个小时。镜中的秒针在逆向转动,仿佛时间正在倒流。
服刑期间,我成了卫生专员兼理发专员。专业理发师进监狱可不是常有的事,所以我很受重用。不过服刑的犯人只有两种发型可选,要么剃光头,要么剃很短的平头。我能用的工具,也就一把推子而已。
去甲子园比赛的高中生不都剃了光头吗?常有人说,这么多剃光头的孩子聚在一起,看着心情舒畅。可我不这么认为。倒不是因为大家都剃光头,理发师就没生意做了。只是一看到光头,我就会不由自主地想起战争年代,还有监狱。
只有即将出狱的犯人才可以把头发稍微留长一点,这叫“蓄发”。给这类人理发是我当时唯一的盼头,理的时候自然也格外卖力。我早就听说,坐过牢的人是很难找工作的,所以我尽量给他们理得精神些,让他们给雇主留下一个好印象。
最后一个环节是脸部按摩。
店主的手指拂过我的眼眶,在眼皮上、眼梢、眼袋、眼角画着圈,一遍又一遍。眼圈渐渐热了起来,仿佛店主的体温渗到了我身上。片刻后,他用凉爽的冷毛巾盖住了我的眼睛。
他的手指好似敏锐的触角,毫不犹豫地在我的脸上攀爬。他用五根手指来回摩挲我的脸颊,轻触我的鼻梁,缓缓按压我的下巴。那动作就像在确认我面部的骨骼。
出狱时,我本不打算再当理发师。因为我觉得,我这样的人是没有资格拿着利器出现在客人面前的。服刑的时候,我就托人把店面转让了。
但出狱后没多久,我便意识到坐过牢的人真的很难找到工作。幸好再婚时盖的房子还在,店面也因为房地产泡沫卖了个好价钱。付完给死者家属的赔偿金后,我还不至于立刻揭不开锅。可是,没有比闷在家里什么都不干更糟糕的了。死者的脸时不时就会浮现在眼前。
于是我开始去养老院给老人理发。这份工作是保护司介绍给我的。其实让我白干我也愿意,但人家还是付了工钱给我。这件事让我深切体会到,我啊,还是只能当个理发师。
后来,我就把东京的房子卖了,买下这栋房子,把它装修成了理发店。我根本无所谓店的地段,只是因为我喜欢看海,就选在了海边,就是这么简单。只要能离开东京,去一个没人认识我的地方就够了,去哪儿都行。
这家店刚开业的时候,我连招牌之类的东西都没装。没客人上门也没关系,只要我还是理发师就行。渐渐地,一些本地人听说我是理发师,开始时不时光顾。直到那时,我才在公交车道边立了个灯柱。
小时候常去的那家理发店的大叔告诉我,理发店门口的三色灯柱是有含义的。红色代表动脉,蓝色代表静脉,白色代表绷带。很久以前,欧洲的理发师不仅是剃头匠,还是外科医生,要给人放血治病,灯柱代表的是那一段历史——大叔跟我说这些的时候,语气别提有多骄傲了,就像自己当过外科医生似的。
可这家店的灯柱并没有插电,就这么摆在路边。红蓝两色血管中的血液都凝固了,一动不动。
我为什么这么在意店里的镜子呢?让客人看到美丽的海景什么的,都是借口。这面镜子啊,其实是为我自己装的。
理发师的工作几乎都是站在大镜子前完成的。理发师的一举一动,客人都会看在眼里。可这偏偏是我最不能忍受的。于是我想,要是客人能一直看着大海,就不会注意到我的脸了吧。“肯定没人记得你长什么样了”——我这么安慰自己,但心里还是怕得要命,唯恐哪一天有人指着我说,“你是杀人犯。”
做噩梦也是常有的事。在梦里,脸上盖着热毛巾的客人指着我说,“你是杀人犯。”然后客人站了起来,脸上的毛巾掉了。出现在我眼前的,就是被我害死的那个人的脸。
漫长的脸部按摩终于结束了。店主调直了椅背。
睁眼一看,面前的镜子闪闪发光。正要沉入海平面的太阳散发出刺眼的光芒,我不禁把头扭开。
这家店开张的第三年,那位大明星来了。
他说,他正巧在这附近拍电影的外景。我感动得一句话都说不出来,只能不停地给他鞠躬。因为我知道,他有好几年没拍过电影了。
来找我之前,他刚演了一部电视剧的配角。为了那个角色,他把头发留长了一些。他让我“剪成老样子”。我剪得可卖力了,比他第一次光临的时候还要卖力。他的头发稀疏了不少,弹性也大不如前,所以我剪得格外仔细,格外认真。
打那以后,他开始频频光顾这家店。像当年那样每周两次是不可能了,但每月至少会来上一回。在他去世半个月前,他叫我去一趟他住的医院。我立刻带上所有能带的工具赶了过去。那是他这辈子最后一次理发。他的语气跟平时一样彬彬有礼。我还记得他最后是这么对我说的:
“谢谢你。多亏了你,我才能有今天。”
听到这句话,我顿时觉得此生无憾了。我是个罪孽深重的人,却有人这么感激我。光是这句话,就让我觉得这辈子没白活。
镜子反射的光是不是太刺眼了?对不起……再吹一下就好了。这面镜子什么都好,就是有西晒。我一般不在这个季节的日落时分接受客人的预订,可是听到原田先生您年轻的声音,我心里特别高兴,一时没忍住就破了例。
话说回来,您的发旋长在一个很特殊的位置。嗯,每个人的发旋都不一样。不会的,它的位置是固定不变的。我天天跟头发打交道,再细微的差别也能一眼瞧出来。
您是不是觉得我是个特别啰唆的老头子?我也不是天天都这样。我还是头一回跟客人聊这么多呢。有些事啊,还是得跟您说一说,毕竟我也没几年好活了。
这时,店主突然说道:您后脑勺那个缝过针的伤口,是小时候摔的吧?
我不禁望向镜中的他。因为逆光的关系,他的脸变成了一团黑影,我看不清他的表情。
那个伤口,是摔下秋千的时候磕破的。那秋千就在河滩的公园里,周围的地上都是石头,能不磕破皮嘛。我实在不放心让儿子在那么危险的地方玩,干脆买了架秋千,装在自家的院子里。老婆还笑我太宠孩子呢。
这栋房子的院子里不是有一架破秋千吗?那是我从东京的家里搬来的,不是原来就有的。
店主问,令堂还健在吗?我回答,嗯。
店主沉默了。但我大声打破了由吹风机的响声形成的寂静,说:“我下周要办婚礼了。”然后,我才简明扼要地道明来意。
婚期将至。我想在举行婚礼前去理发店好好剪一次头发,而不是像平时那样去美发厅随便弄弄。我只跟他说了这些,绝口不谈母亲是多么不愿意提起他,以至于我只能到处打听,费了好大的劲才找到这家店。
店主的脸在逆光中漆黑一片。他开口对我说,恭喜您了。我回答,谢谢。本想再说点什么,可剩下的话到头来还是咽了回去。
店主完成了全套流程,解开罩衣的搭扣。我本想自己脱,但他太熟练了,动作终究要比我快一些。刹那间,我又变回了小孩子,眼睁睁看着他轻而易举地为我脱去了罩衣。
收银台旁边放着一叠印有“会员卡”字样的卡片,但我没有拿,店主也没向我推荐。
他不肯收钱。我硬是把钱塞给他,怀着合上老相簿的心境,伸手握住门把。店主的声音从身后传来——
请问……能让我再看一看您的脸吗?不不,我就是怕额发没理好。
海子《我请求:雨》
''[[海子]]《我请求:雨》''
-----
```
我请求熄灭
生铁的光爱人的光和阳光
我请求下雨
我请求
在夜里死去
我请求在早上
你碰见
埋我的人
岁月的尘埃无边
秋天
我请求
下一场雨
洗清我的骨头
我的眼睛合上
我请求
雨
雨是一生过错
雨是悲欢离合
```
寒风吹彻-刘亮程
========================
寒风吹彻-[[刘亮程]]
-----
雪落在那些年雪落过的地方,我已经不注意它们了。比落雪更重要的事情开始降临到生活中。三十岁的我,似乎对这个冬天的来临漠不关心,却又一直在倾听落雪的声音,期待着又一场雪悄无声息地覆盖村庄和田野。
我静坐在屋子里,火炉上烤着几片馍馍,一小碟咸菜放在炉旁的木凳上,屋里光线暗淡。许久以后我还记起我在这样的一个雪天,围抱火炉,吃咸菜啃馍馍想着一些人和事情,想得深远而入神。柴禾在炉中啪啪地燃烧着,炉火通红,我的手和脸都烤得发烫了,脊背却依旧凉飕飕的。寒风正从我看不见的一道门缝吹进来。冬天又一次来到村里,来到我的家。我把怕冻的东西一一搬进屋子,糊好窗户,挂上去年冬天的棉门帘。寒风还是进来了,它比我更熟悉墙上的每一道细微裂缝。
就在前一天,我似乎已经预感到大雪要来临。我劈好足够烧半个月的柴禾,整齐地码在窗台下。把院子扫得干干净净,无意中像在迎接一位久违的贵宾——把生活中的一些事情扫到一边,腾出干净的一片地方来让雪落下。下午我还走出村子,到田野里转了一圈。我没顾上割回来的一地葵花杆,将在大雪中站一个冬天。每年下雪之前,都会发现有一两件顾不上干完的事而被搁一个冬天。冬天,有多少人放下一年的事情,像我一样用自己那只冰手,从头到尾地抚摸自己的一生。
屋子里更暗了,我看不见雪。但我知道雪在落,漫天地落。落在房顶和柴垛上,落在扫干净的院子里,落在远远近近的路上。我要等雪落定了再出去。我再不像以往,每逢第一场雪,都会怀着莫名的兴奋,站在屋檐下观看好一阵,或光着头钻进大雪中,好像有意要让雪知道世上有我这样一个人,却不知道寒冷早已盯住了自己活蹦乱跳的年轻生命。
经过许多个冬天之后,我才渐渐明白自己再躲不过雪,无论我蜷缩在屋子里,还是远在冬天的另一个地方,纷纷扬扬的雪,都会落在我正经历的一段岁月里。当一个人的岁月像荒野一样敞开时,他便再无法照管好自己。
就像现在,我紧围着火炉,努力想烤热自己。我的一根骨头,却露在屋外的寒风中,隐隐作痛。那是我多年前冻坏的一根骨头,我再不能像捡一根牛骨头一样,把它捡回到火炉旁烤热。它永远地冻坏在那段天亮前的雪路上了。
那个冬天我十四岁,赶着牛车去沙漠里拉柴禾。那时一村人都靠长在沙漠里的梭梭柴取暖过冬。因为不断砍挖,有柴禾的地方越来越远。往往要用一天半夜时间才能拉回一车柴禾。每次去拉柴禾,都是母亲半夜起来做好饭,装好水和馍馍,然后叫醒我。有时父亲也会起来帮我套好车。我对寒冷的认识是从那些夜晚开始的。
牛车一走出村子,寒冷便从四面八方拥围而来,把我从家里带出的那点温暖搜刮得一干二净,浑身上下只剩下寒冷。
那个夜晚并不比其他夜晚更冷。
只是我一个人赶着牛车进沙漠。以往牛车一出村,就会听到远远近近的雪路上其他牛车的走动声,赶车人隐约的吆喝声。只要紧赶一阵路,便会追上一辆、或好几辆去拉柴的牛车,一长串,缓行在铅灰色的冬夜里。那种夜晚天再冷也不觉得。因为寒风在吹好几个人,同村的、邻村的、认识和不认识的好几架牛车在这条夜路上抵挡着寒冷。
而这次,一野的寒风吹着我一个人。似乎寒冷把其他一切都收拾掉了,现在全部对付我。
我掖紧羊皮大衣,一动不动爬在牛车里,不敢大声吆喝牛,免得让更多的寒冷发现我。从那个夜晚我懂得了隐藏温暖——在凛冽的寒风中,身体中那点温暖正一步步退守到一个隐秘的连我自己都难以找到的深远处——我把这点隐深的温暖节俭地用于此后多年的爱情和生活。我的亲人们说我是个很冷的人,不是的,我把仅有的温暖全给了你们。
许多年后有一股寒风,从我自以为火热温暖的从未被寒冷浸入的内心深处阵阵袭来时,我才发现穿再厚的棉衣也没用了。生命本身有一个冬天,它已经来临。
天亮后,牛车终于到达有柴禾的地方。我的一条腿却被冻僵了,失去了感觉。我试探着用另一条腿跳下车,拄着一根柴禾棒活动了一阵,又点了一堆火烤了一会儿,勉强可以行走了,腿上的一块骨头却生疼起来,是我从未体验过的一种疼,像一根根针刺在骨头上又狠命往骨髓里钻——这种疼感一直延续到以后所有的冬天以及夏季里阴冷的日子。
太阳落地时,我装着半车柴禾回到家里,父亲一见就问我:怎么拉了这点柴,不够两天烧的。我没吭声。也没向家里说腿冻坏的事。
我想很快会暖和过来。
那个冬天要是稍短些,家里的火炉要是稍旺些,我要是稍把这条腿当回事,或许我能暖和过来。可是现在不行了。隔着多少个季节,今夜的我,围抱火炉,再也暖不热那个遥远冬天的我,那个在上学路上不慎掉进冰窟窿,浑身是冰往回跑的我,那个跺着冻僵的双脚,捂着耳朵在一扇门外焦急等待的我……我再不能把他们唤回到这个温暖的火炉旁。我准备了许多柴禾,是准备给这个冬天的。我才三十岁,肯定能走过冬天。
但在我周围,肯定有个别人不能像我一样度过冬天。他们被留住了。冬天总是一年一年地弄冷一个人,先是一条腿、一块骨头、一副表情、一种心境……尔后整个人生。
我曾在一个寒冷的早晨,把一个浑身结满冰霜的路人让进屋子,给他倒了一杯热茶。那是个上了年纪的人,身上带着许多个冬天的寒冷,当他坐在我的火炉旁时,炉火须臾间变得苍白。我没有问他的名字,在火炉的另一边,我感觉到迎面逼来的一个老人的透骨寒气。
他一句话不说。我想他的话肯定全冻硬了,得过一阵才能化开。
大约坐了半个时辰,他站起来,朝我点了一下头,开门走了。我以为他暖和过来了。
第二天下午,听人说村西边冻死了一个人。我跑过去,看见这个上了年纪的人躺在路边,半边脸埋在雪中。
我第一次看到一个人被冻死。
我不敢相信他已经死了。他的生命中肯定还深藏着一点温暖,只是我们看不见。一个人最后的微弱挣扎我们看不见,呼唤和呻吟我们听不见。
我们认为他死了。彻底地冻僵了。
他的身上怎么能留住一点点温暖呢?靠什么去留住?他的烂了几个洞、棉花露在外面的旧棉衣?底快磨通、一边帮已经脱落的那双鞋?还有,他多少个冬天积累起来的彻骨寒冷。
落在一个人一生中的雪,我们不能全部看见。每个人都在自己的生命中,孤独地过冬。我们帮不了谁。我的一小炉火,对这个贫寒一生的人来说,显然微不足道。他的寒冷太巨大。
我有一个姑妈,住在河那边的村庄里,许多年前的那些个冬天,我们兄弟几个常走过封冻的玛河去看望她。每次临别前,姑妈总要说一句:天热了让你妈过来喧喧。
姑妈年老多病,她总担心自己过不了冬天。天一冷她便足不出户,偎在一间矮土屋里,抱着火炉,等待春天来临。
一个人老的时候,是那么渴望春天来临。尽管春天来了她没有一片要抽芽的叶子,没有半瓣要开放的花朵。春天只是来到大地上,来到别人的生命中。但她还是渴望春天,她害怕寒冷。
我一直没有忘记姑妈的这句话,也不止一次地把它转告给母亲。母亲只是望望我,又忙着做她的活。母亲不是一个人在过冬,她有五六个没长大的孩子,她要拉扯着他们度过冬天,不让一个孩子受冷。她和姑妈一样期盼着春天。
……天热了,母亲会带着我们,趟过河,到对岸的村子里看望姑妈。姑妈也会走出蜗居一冬的土屋,在院子里晒着暖暖的太阳和我们说说笑笑……多少年过去了,我们一直没有等到这个春天。好像姑妈那句话中的“天”一直没有热。
姑妈死在几年后的一个冬天。我回家过年,记得是大年初四,我陪着母亲沿一条即将解冻的马路往回走。母亲在那段路上告诉我姑妈去世的事。她说:“你姑妈死掉了。”
母亲说得那么平淡,像在说一件跟死亡无关的事情。
“怎么死的?”我似乎问得更平淡。
母亲没有直接回答我。她只是说:“你大哥和你弟弟过去帮助料理了后事。”
此后的好一阵,我们再没说话,只顾静静地走路。快到家门口时,母亲说了句:天热了。
我抬头看了看母亲,她的身上散着热气,或许是走路的缘故,不过天气真的转热了。对母亲来说,这个冬天已经过去了。
“天热了过来喧喧。”我又想起姑妈的这句话。这个春天再不属于姑妈了。她熬过了许多个冬天还是被这个冬天留住了。我想起爷爷奶奶也是分别死在几年前的冬天。母亲还活着。我们在世上的亲人会越来越少。我告诉自己,不管天冷天热,我都常过来和母亲坐坐。
母亲拉扯大她的七个儿女。她老了。我们长高长大的七个儿女,或许能为母亲挡住一丝的寒冷。每当儿女们回到家里,母亲都会特别高兴,家里也顿添热闹的气氛。
但母亲斑白的双鬓分明让我感到她一个人的冬天已经来临,那些雪开始不退、冰霜开始不融化——无论春天来了,还是儿女们的孝心和温暖备至。
随着三十年的人生距离,我感受着母亲独自在冬天的透心寒冷。我无能为力。
雪越下越大。天彻底黑透了。
我围抱着火炉,烤热漫长一生的一个时刻。我知道这一时刻之外,我其余的岁月,我的亲人们的岁月,远在屋外的大雪中,被寒风吹彻。
赫尔曼·黑塞、或译作赫尔曼·赫赛(Hermann Hesse,1877年7月2日-1962年8月9日),德国诗人、小说家,他难以列入德国文学家的任何一种流派中。黑塞不遗余力地探索广含人性的种种不同可能,意即“非分裂状况中的人性”[1]。1946年获得诺贝尔文学奖。
特德·姜的《呼吸——一个宇宙的毁灭》
(译者为耿辉)
空气(还有人称之为氩气)就是生命之源的说法流传已久,实际情况却不是这样。我刻下这些文字的目的,就是为了说明我是如何理解了真正的生命之源以及生命最终将怎样消亡,这个结果不可避免。
在大部分历史进程中,“我们依靠空气维持生命”这个命题的正确性明显得都不需要去证明。我们每天消耗两个肺的空气,把空的肺从胸腔取出来,再换上充满空气的肺。假如有人不小心让气压降的过低,他就会感到肢体变得沉重,他知道这就需要补充空气了。在体内的两个肺用尽之前连一个肺都无法更换这种情况极少发生。在这种不幸的情况下——比如有人被困住了,无法移动,而且旁边也没有人帮助他——空气用完之后几秒钟他就会丧命。
然而在正常的生活中,我们对于空气的需求远远超出想象,不过大家认为,到空气补给站要做的其它事情都要比满足这种需求更重要。因为补给站是最主要的社交场所,我们在那里既能获得生命的补给又能获得情感的满足。我们都在家里备有充满空气的肺,可是有人茕茕孑立的时候,打开胸腔更换肺似乎比做家务强不了多少;但是和大伙一起换肺却是一种群体行为,一种共同分享的快乐。
假如有人非常忙碌或者不善交际,他只需要在补给站把一对充满空气的肺安装在自己的身体里,再把空的放在房间的另一边就行了。要是刚刚换过肺的人有些空闲时间的话,他可以把空的肺连接到空气配送机上,重新装满它们,以方便下一个人使用。这个过程很简单,也是一种礼貌的体现。不过最常见的行为显然是在补给站闲逛并享受与人相伴的美好时光,跟朋友或熟人讨论当天的天气,顺便再把刚刚充满的肺提供给和自己交谈的人。尽管从最严格的意义上来说,这也许不能称之为分享空气,因为配送机仅仅是从深埋地下的储气槽连接出来的管道终端,所以大家明白我们的空气来自于同一个源头——伟大的世界之肺、我们的能量之源,不过这样的共识倒使得为他人提供便利成了一种友谊的体现。
很多肺会在第二天回到同一个气体补给站,不过大家出门去附近的地区时,也会有很多肺流通到别的补给站;从外观来看肺都是一样的:光滑的铝质圆柱体,所以人们分辨不出某个特定的肺是一直待在自己家附近还是去过了很远的地方。新闻和闲话随着肺在人和地区间传递。虽然我个人很喜欢旅行,但是通过这样的方式人们不离开家就可以了解到远方的新闻,甚至是那些来自于世界最边缘的新闻。我曾经一直旅行到世界的边缘,亲眼看见坚固的铬墙从地面一直向上延伸进无边的天空。
正是在一座气体补给站我第一次听说了促使我进行调查并导致我最终发现的那些谣言。很简单,事情始于我们区公告员的一番话。按照传统,在每年头一天的中午,公告员要朗诵一段很久以前为这样的年度仪式而创作诗文,这个过程需要整整一个小时的时间。公告员提到,他最近一次朗诵的时候,钟楼在他结束之前就敲响了整点报时的钟声,这可是以前从来没有发生过的事情。另一人说这是一个巧合,因为他刚刚从附近的一个区回来,那里的公告员也对同样的事情提出了抱怨。
没有人过多地思考这件事,只是把它当作看似正常的简单事实。仅仅过了几天,有人再次提到了一个类似的情形,又一位公告员的朗诵与钟楼的时间不符,有人认为这种异常情况也许体现出所有钟楼共有的机械缺陷,比较奇怪的是缺陷导致了时钟变快而不是变慢。钟表匠检查了出现问题的钟楼,但是没有发现任何缺陷。其实,经过与那些在新年庆典中走时正常的钟楼相比较,人们发现这些钟楼后来都一直在准确地计时。
我个人认为这个问题有些蹊跷,然而我的精力过多地集中在自己的研究上面,没法更多地思考别的事情。我一直都是一名解剖学学生,为了提供后来一些事情的背景信息,我先简要介绍一下我与这门学科的联系。
因为我们的生命力旺盛,致命的灾难也不常见,所以死亡很少发生。这是一件幸运的事,然而这令解剖学研究难以进行,尤其是很多非常严重的事故导致的死者的遗体受损,从而不能用于研究。假如充满空气的肺破裂,爆炸的威力可以撕碎我们的金属钛躯体,仿佛那是锡做的一样。过去解剖学家把精力都用来研究四肢,因为这是最有可能完整保留下来的部分。一个世纪之前我上了第一堂解剖课,讲师为我们展示了一条完整的断臂,为了露出里面密集的连杆束和活塞,外壳已经被除去。回想起来,当时的情形我仍然历历在目。讲师把那只手臂的动气管连接至挂在墙上的肺,这是他储存在实验室里备用的,然后他就能操纵从手臂的残端伸出的操纵连杆了,那只手也断断续续地随之张开与合拢。
从那以后,解剖学的发展已经达到了可以将残臂修复的程度,偶尔还能实施断肢再植的手术。同时,我们也开始有能力研究世人的生理学。我也给别人描述过我亲身参与的第一堂解剖课,在描述的同时,我打开自己手臂的外壳,指导学生在我移动手指的时候仔细观察缩短和伸长的连杆。
尽管有了这些发展,在解剖学领域的核心仍然存在一个无法解决的巨大难题:记忆。虽然我们了解一些大脑的结构,但是由于它极其精密复杂,脑生理学研究的艰难尽人皆知。在一些典型的死亡事故中,颅骨被打破,大脑喷出一股金粉,里面除了少量破碎的细丝和箔片几乎没留下什么,留下的东西却一点用处也没有。几十年来关于记忆的主导理论认为,一个人的所有经历都被刻在了金箔上,脑部破裂时气体的冲击力撕碎了这些金箔,形成了后来发现的那些微小碎片。解剖学家收集起这些小块的金片——它们薄得可以透过光线,只不过光的颜色会变绿——花上好些年的努力把碎片拼成原样。他们希望最终能够破译死者最近的经历在金箔上留下的记号。
我不赞同这种所谓的铭刻理论,理由很简单,假如我们的经历真以这种方式被记录下来,为什么记忆是不完整的呢?铭刻理论的鼓吹者为遗忘提出了一种解释——他们说随着时间流逝,金箔会从阅读记忆的探针下面移位,最初的金箔最终会完全移出了记忆探针的触控范围——可我认为这个解释一点儿说服力都没有。不过这一理论所表达的主张对我来说还是很容易理解的,我也曾花很长时间检查显微镜下的金箔碎片,我也曾想象,假如旋转细调旋钮便可清晰地看见符号的轮廓,这将令人多么愉悦啊。
而且不可思议的是,也许死者本人生前就已经遗忘的过去会从他尘封已久的记忆中被揭示出来。我们对于以前的记忆仅限于一百年之内,而文字记录——我们记录事件,但已记不清自己曾有过这样的行为——覆盖的时间只比记忆多几百年。开始用文字记录历史之前我们存在了多少年?我们来自于哪里?从我们的头脑中找出答案才有希望回答这些问题,这就是记忆铭刻理论看上去如此诱人的原因。
我所支持的反对派有这样的看法:我们的记忆存储在某种媒介中,也许是旋转的齿轮,也许是一系列不同状态的开关,清除记忆和保存记忆一样容易。这种理论表明我们忘记的一切确实无法恢复,我们的头脑所承载的历史也不比图书馆中记录的那些久远。缺少空气致死的人更换新肺以后,尽管可以复苏,但他没有了记忆,几乎变成了傻子,这种理论的一个优势就在于它可以更好地解释这种现象:死亡的冲击以某种方式重置了所有的齿轮或开关。记忆铭刻理论的支持者声称,死亡的冲击只不过使金箔发生了移位。不过没有人愿意为了解决争端而去屠戮生命,即使试验的对象是一个傻子。我构想过一个实验,它也许能令我查明最终的真相。不过做这个实验要冒很大的风险,所以要三思而后行。了解到更多有关时钟异常的消息之前,我一直犹豫了很长时间。
从更远的一个区传来消息,那里的公告员也发现了同样的状况,在他完成新年朗诵之前钟楼里响起了正点报时的钟声。令这件事与众不同的是,那座钟楼采用了一种特殊的机构,它用流进碗里的水银计时。这样的话时间差异就不能用那种共同的机械故障来解释了。大多数人认为这是一个骗局,某个捣蛋鬼耍的恶作剧。我却有一个不同的观点,它更加悲观,我都不敢说出来,不过它坚定了我的初衷。我要进行我的实验。
我制作的第一件工具最简单:我将四块棱镜平行安放在支架上并仔细地调整它们,使它们截面上等腰直角三角形的顶点位于一个矩形的四角。这样,水平射入一块下层棱镜的光线会向上反射,再经过另外三块棱镜的反射,光线会沿着一个四边形环路回到原点。所以,当我坐下来,使眼睛和第一块棱镜等高,我就能看到自己的后脑。这具自我观察潜望镜为将来所要做的一切打下了基础。
移动以类似方式排列的调整杆便可以调整潜望镜的视场。这一组调整杆要比潜望镜的大得多,不过在设计上还是相当简单的。相对而言,最后我又分别在这些工具上安装的设备要更加精密。我为潜望镜添加了一台双筒显微镜,安放在可以上下左右转动的支架上,我还为操纵杆配备了一批可以精确操纵的机械手,不过这样描述对机械师的工艺杰作实在有失公允。机械手结合了解剖学家的灵巧和他们所研究的身体结构带来的启发,操作者能够使用它们代替自己的双手,甚至是完成更加精密复杂的工作。
把这套设备全部组装完成花去了几个月的时间,但是我必须小心谨慎。准备工作一完成,我就可以将双手放在一套旋钮和控制杆上,操纵一对安放在我脑后的机械手,并用潜望镜观察它们的操作对象。接下来我就能解剖自己的大脑了。
我知道,这样的想法听上去十分疯狂,要是我讲给同事的话,他们一定会极力阻止我的。但是我不能让别人冒着受伤害的危险充当我的解剖实验对象,既然打算一个人实施解剖,我就不会满足于在这个过程中仅仅被动地充当解剖对象。自我解剖是唯一的选择。我弄来一打充满空气的肺,把它们连在一个汇流管上并安放在工作台的下方。我将坐在那里工作。为了将其直接连接在我胸腔内的支气管入口,我又安装了一个分配器。这些设备将为我提供可以使用六天的空气。考虑到我也可能在这段时间里完不成实验,我预约了一位同事在实验结束时来我家做客。不过我推测,决定我在这段时间能否完成实验的唯一因素就是我是否会在实验中死亡。
我首先取下了位于头顶和后脑的大弧度金属外壳,接下来是两块弧度稍小一些的侧面外壳,只有我的脸没有取下来,不过它固定在一个约束支架上,即使能通过潜望镜观察到后面,我也无法看清它的内表面。我看到自己的大脑暴露出来,它由十几个部分组成,外面覆着造型精致的外壳。我把潜望镜移到了将大脑一分为二的裂缝跟前,在迫切的渴望中瞥见了脑部件内部惊人的机械结构。就算是我看到的内容不多,我也能断定这是我见过的最具美感的复杂机械,超越了我们制造的一切,毫无疑问它具有非凡的起源。眼前的一幕令我兴奋得不知所措。我又严格从美学角度出发,品味了好几分钟,然后才继续进行探索。
一般的猜测认为大脑的结构是这样划分的:一台引擎位于头部的中心,实现现实认知,环绕在它周围的是一系列存储记忆的部件。我的观察结果与这个理论一致,因为外围部件似乎相互类似,而位于中心的部件却不大一样,它更加奇怪,而且活动的部分也更多。然而这些部件安装的十分密集,我无法看清它们是如何运作的。如果我要更深入地研究,我就得更近一步观察。
每个部件都有一个专属的空气储备器,从大脑基部的调节阀伸出的软管为它补充空气。我把潜望镜对准了最后边的那个部件,利用遥控机械手,迅速取下输气软管并装了一根更长的软管。为了在极短的时间内完成这个动作,我曾练习了无数次。即便如此,我也不确定自己能否在这个部件耗尽它自己的空气储备之前完成连接。确认了部件的运转没有被我打断之后,我才继续往下进行。我重新整理了一下较长的软管,然后便可以更清楚地看到刚刚被它挡住的那个裂缝里有些什么:连接这个部件与相邻部件的其它软管。我操纵最纤细的一对机械手伸进那道狭窄的缝隙,一个接一个地用较长的软管替换原来的软管。最后,我完成了整个部件上的工作,它与大脑其它部分的每一条连接管路都被我更换了。这样我就可以从支撑结构上拆下它并把整个单元从原本的后脑那里取下来了。
我知道这样做有可能在不知不觉中消弱我的思维能力,进行的几项基础算术测试表明我的思维没有问题。一个部件已经挂在上边的架子上,此时我可以更清楚地观察大脑中央的认知引擎,不过,要将附加的显微镜伸进去进行细致的观察,空间还不够。为了能够彻底弄清楚大脑的工作原理,我至少得取下六个外围部件。
我为每个部件更换了软管,这项重复的工作需要极大的精力和耐心。我从后边又取下一个部件,从顶部取下两个,从两个侧面各取下一个,然后把所有的六个都挂在了头顶的架子上。我完成时的情形看上去就像是爆炸一秒钟之后某个极短瞬间的再现。考虑到这些,我再一次感到震惊。不过,认知引擎终于显露出来,从我躯干伸出的一束软管和操纵连杆在下边撑着它,我也终于可以将显微镜旋转到任意的角度并观察拆卸下来的组件的内表面了。
我一面凝视此情此景,一面问自己,我的身体都包含些什么?房间里用来帮助我观察和操作的管子基本上类似于把我的眼睛和双手同大脑连接起来的软管。在实验过程中,这些机械手从本质上来说不正是我的双手吗?潜望镜末端的显微镜头实际上不也是我的双眼吗?作为一个得到了扩展的个体,我的微不足道的身体充当了中央的超大脑。就是以这种不可思议的配合,我开始了探索自我的旅程。
我把显微镜转向了一个记忆单元,开始检查它的结构。我没指望自己能解开记忆之谜,只想着我也许能推测出记忆存储的方式。如我所料,那里根本就没有用来记录的大片金箔,不过令我惊讶的是成排的齿轮和开关也不存在。相反,里面的部件几乎就只有一排的空气管。透过空气管之间的缝隙,我隐约看见这个存储单元的内部在泛着涟漪。
经过仔细的观察和不断增加显微镜的放大倍率,我发现空气管分生出微小的毛细管,与毛细管交织在一起的是一张由金属丝编织成的致密的格子网,网上挂着金质的叶片。毛细管逸出的气流使叶片各自保持着不同的状态,它们不是传统意义上的开关,因为没有气流的帮助它们就无法维持自身的状态。但是我猜这些叶片就是我所寻求的开关,存储记忆的媒介。我看到的涟漪一定就是回忆的表现:叶片的排列方式被读取出来并传送回识别引擎。
拥有了这样全新的理解,我就可以再将显微镜对准识别引擎了。在那里我也观察到了金属丝网格,不过上边承载的金叶没有固定在哪个状态,而是在迅速地前后扑动,快得我几乎都看不清。实际上,整个引擎似乎都在运转,它所包含的网格多于输送空气的毛细管,我奇怪空气如何能连续不断地吹动所有的金叶。我对叶片进行了好几个小时的仔细观察才发现,它们自身也起到了毛细管的作用,叶片组成临时的管道和瓣膜,在短暂的时间里使气流转向,依次吹向其它的叶片,最后管道和瓣膜还会消失。这是一台连续变化的引擎,它的一部分作用其实就是改变自身,网格结构还算不上一台真正的机械,因为它相当于一张纸,识别引擎不停在上面书写。
可以这么说,我的意识被编码成这些微小叶片的状态,不过更准确的描述是不断改变方向并驱动叶片的气流。看着这些不停摆动的金叶,我明白了空气不像我们通常所想的那样,仅仅为实现思维的引擎提供动力。其实,空气恰恰就是我们思维的媒介。我们的思维就是一种气流的模式。我的记忆被记录下来,不是通过金箔上的刻痕甚至开关的位置,而是依靠持续不断的氩气流。
我领悟了这种网格结构的性质之后,一系列结论接二连三地反映在我的脑海里。第一个也是最普通的一个,我明白了为什么造就大脑的唯一成分是金这种最具延展性和韧性的金属。只有最薄的叶片才能满足这种机制对于移动速度的要求,只有最精致的细丝才能充当叶片的转轴。我用笔在铜板上刻下这些文字时会产生一些铜屑,每刻完一页,我就会把它们扫下来,相比之下,这些铜屑简直就是粗糙笨重废料。只有金质媒介才能实现记忆的快速擦除和存储,而且比任何开关或齿轮的组合要快得多。
接下来我明白了为什么缺少空气致死的人在安装充满空气的肺之后仍然无法恢复生命。持续的气流形成气垫,使网格结构中的叶片在它们之间维持平衡状态,也使得它们来回的摆动非常迅速。这也就意味着,一旦气流停止,一切就都丢失了,所有的叶片都垂下来,呈现同样的悬挂状态,它们所代表的思维模式和意识都被擦除了。恢复空气供应无法复原失去的一切。这也是速度的代价,存储思维模式的媒介越稳定,意识运作的速度就越缓慢。
随后我明查清了时钟异常的原因所在。我看出叶片移动的速度取决于吹向它们的空气,充足的气流几乎可以使叶片无摩擦地移动,要是它们移动得比较缓慢,那时因为它们受制于较大的摩擦力,只有在支撑它们的空气垫比较薄和吹过网格的气流比较弱时才会出现这种情况。
钟楼的时间没有变快,其实是我们的头脑变慢了。钟摆驱动钟楼的节拍从不会改变,流过管子的水银也没有加快速度,但是我们的大脑依赖空气的流动,空气流动得越慢,我们的思维就越慢,从而使我们觉得时钟变快了。
我曾害怕我们的头脑可能会变得缓慢,正是这样的担心激励着我进行自我解剖。然而我认为我们的识别引擎——尽管由空气驱动——最终的本质还是机械式的,这台机器的某个部分会逐渐疲劳变形,从而造成速度减慢。这本来是一件可怕的事,不过至少我们还有希望能修复这台机器,把我们的大脑恢复到它最初的速度。
然而,要是我们的思维纯粹是气流的模式,而不是齿轮的运动,这个问题就严重得多了,有什么因素可能导致流经每个人大脑的气流变慢呢?不可能是气体补给站的配送器压力降低所致。我们肺部的气压特别高,所以空气必须经过一系列的调节阀降压后才送到大脑。我觉得思维能力的减弱一定源于反方面的因素:我们的环境气压在升高。
怎么可能呢?这个问题一出现,唯一可能的答案也变得明确了:我们天空的高度一定是有限的。在我们目力所及的范围之外,环绕我们这个世界铬墙向内倾斜,形成一个穹顶;我们的宇宙如同一座密室,而不是一口开放的井。空气逐渐在密室中积累,直到气压与地下气槽中的相同。在这篇铭文最初,我说空气不是生命之源,这就是原因所在。空气即不会创生,也不会消失,宇宙中的空气总量保持恒定。假如我们的生命只需要空气,那么我们永远不会死。然而真正的生命之源是气压差,空气从稠密的地方流向稀疏的地方。我们的思维和活动,以及我们所造的每一台机器的运转都是靠流动的空气来驱动的,不同压力间的相互平衡产生了这种动力。一旦宇宙间各处的压力达到相同,所有的空气将不再流动,变得毫无价值。总有一天,我们将被静止的空气所围绕,无法从中获得半点能量。
其实我们消耗的不是空气。每天我从新换的肺中获取的空气完全从我的肢关节和身体外壳逸出,就是说这些空气被我排放到身体周围的大气中。我只是把高压的空气转换成低压的空气。我身体的每一个动作都对宇宙气压的平衡起到了推波助澜的作用,我所考虑的每一个想法,都加速了那个末日的到来。
要是我在其它的场合认识到这一点的话,我会从椅子上一跃而起、冲到大街上。但是以我现在的情形——身体锁在固定支架上,大脑四处悬挂在实验室里——这么做是不可能的。我能看见自己喧嚣的思维引发大脑中的叶片飞速运动,这反而又增长了我对这种约束状态的不安。在这样的时刻恐慌起来可能会导致死亡,就如同被困在梦魇中的同时不由自主地扭动身体,挣扎着对抗的束缚,直到空气用尽。出于偶然,我的手碰到用于调整的控制端,把潜望镜的视场从网格结构转向了工作台的平面,不过这正和我意。不用再观察自己经过放大的恐慌心理,我也得以平静下来。我又恢复镇定之后,便又开始了组装自我的冗长过程。最后我把大脑恢复到初始的紧凑结构,装好脑壳,然后从固定支架上解脱出来。
起初我给别的解剖学家讲述我的发现时,他们不相信我。不过,在我进行自我解剖实验之后的几个月里,他们中越来越多的人相信了我。人们对大脑又进行了一些检查,对大气压力实施了多次测量,结果都证实了我的断言。我们这座宇宙的背景气压的确在升高,从而减缓了我们的思维速度。
这个真相被广泛了解之后,恐慌开始大范围传播,这是因为人们第一次审视“死亡不可避免”这个想法。为了抑制我们的大气变得稠密,很多人号召严格减少活动,对于浪费空气的谴责逐渐升级为愤怒的谩骂,甚至在有些区,出现了死刑惩罚。考虑到许多世纪之后我们的大气压才会同地下气槽中相同,恐慌平息下来,因此死亡的惩罚也就令人蒙羞。我们不确定这个过程到底要经历多少个世纪,有人在进行和讨论进一步的测量和计算。同时,大家开始广泛地讨论,我们应该如何度过余下的时间。
有一个团体致力于实现逆转气压平衡并发展了许多信徒。他们之中的机械师制造了一台机器,它从大气中获取空气,用外力使之体积变小。他们将这个过程称之为“压缩。”机器把空气恢复到储气槽的气压,那些逆转主义者兴奋地宣布这为一种新型补给站的建造打下了基础,这种补给站——和它填充的每一个肺——不仅为个人赋予了新生,而且也激活的整座宇宙。唉!仔细检查一下这台机器你就会发下它致命的缺陷,机器本身由储气槽中的空气提供动力,充满一个肺要消耗的更多一点空气。它不能逆转气压平衡,反而和世上万物一样,只能加剧这个过程。
尽管他们的一些信徒在这样的挫败之后幻想破灭,但是逆转主义者作为一个团体却没有踌躇不前,而是提出新的设计,用展开的发条或落下的重物为为压缩机提供动力。机械师没有获得更好的结果,每一根旋紧的发条都意味着上发条的人要释放空气,每一个高于地平面的重物都表示举起它的人要释放空气。在这座宇宙中,所有的动力源最终都由气压差产生,总而言之,没有什么机器的操作能增大气压差。
逆转主义者继续从事他们的工作,他们确信总有一天会造出一台机器,使产生的压缩空气比消耗的多,那将是一个永恒的动力源,补充着宇宙失去的生命力。我不像他们那么乐观,我相信气压趋于平衡的过程是不可动摇的。我们宇宙中所有的空气最终会均匀分布,不会有哪个地方更稠密或更稀疏,活塞无法驱动,旋翼无法转动,就连头脑中的金叶都不再运动,气压消失、动力枯竭、思维凝固,宇宙达到彻底的平衡。
有人会对这样的情况感到讽刺,我们的脑研究没有为我们揭示过去的秘密,反而展现了我们最终将走向怎样的未来。然而我坚持认为,我们其实了解到一些有关过去的重要事实。宇宙的开端仿佛是深吸一口气,然后屏住了呼吸。没人知道为什么,然而不管原因如何,我很高兴宇宙以这样的形式诞生,因为我的存在也要归因于此。我所有的欲望和沉思正是我们的宇宙缓缓呼出的气流。在这漫长的呼气结束之前,我的思维将一直存在。
所以我们的思维也许会尽可能地被延长,解剖学家和机械师们正在研制脑部调节阀的替代品,作用是逐渐提高大脑内的气压,使它保持高于环境的气压差。一旦这种阀安装到体内,即使我们的周围的空气变得稠密起来,我们的思维速度大体上也会保持不变。可是这并不意味着生活不会改变,气压差最终会降低到令我们的肢体虚弱、行动迟缓的地步。到那时我们也许得减缓自己思维,这样身体的迟钝才不那么明显,不过这还是会导致外界的一些过程看上去像是在加速。随着钟摆疯狂地摆动,嘀嗒的时钟好像变成了叫个不休的鸟儿,坠向地面的物体似乎受到了弹簧的推动,舞动的绳索仿佛成了噼啪作响的皮鞭。
我们的肢体将在某个时刻完全停止活动,我无法确定末日临近时各种问题出现的正确顺序,但是我想情况会是这样:我们的思维将继续运作,所以我们像雕像一样无法动弹的同时还保留着意识。也许可以说话的时间还要更长一些,因为我们的声匣工作时需要的气压要比肢体小。但是由于无法前往气体补给站,每次讲话都会消耗思维所需的空气,思维完全停止的结局就离我们更近了一步。为了延长思维能力而保持沉默和在交谈中走向最后的终结,哪个选择更好一些呢?我不知道。
在我们停止活动的前几天里,也许有一些人可以将大脑调节阀直接连在补给站的配送机上,其实就是用伟大的世界之肺代替了自己的肺。要是这样的话,那些人直到气压完全平衡的最后一刻都能够保持清醒。我们这座宇宙中所剩的最后一丝气压也将在驱动一个人思考的过程中消耗殆尽。
随后,我们的宇宙将进入绝对平衡的状态,所有的生命和思维都将停止,时间也因此而失去意义。
不过我还怀有一点渺茫的希望。
尽管我们的宇宙是封闭的,不过在无穷大的固体铬中它也许不是唯一的气室。我推测别处可能还有一个,不同于我们的另外一个,甚至体积更大呢。这个假想的宇宙可能有跟我们一样或者更高的气压,然而,假如它的气压比我们的更低甚至是绝对的真空呢?
把我们同那个假想宇宙分隔开的金属铬厚得我们都无法钻透,所以我们不能凭借自身力量到达那里,也就没办法从我们的宇宙中释放掉过剩的大气并以这种方式重新获得动力。但是我想象这个宇宙邻居有它自己的居民,他们的能力超过了我们。假如他们可以在两个宇宙间开拓出一条管道,并安上阀门从我们这里向那边释放空气,那我们该怎么办?他们可以把我们的宇宙当作储气槽,开动配送机充满他们的肺,用我们的空气发展他们的文明。
为我提供动力的空气还能驱动别人,助我刻下这些文字的空气有一天会流过别人的身体,一想到这些我就感到欣慰。我没有欺骗自己,认为这会是我再生的方式,因为我不是那些空气,我只是空气流动模式的体现。
然而我还怀有更加渺茫的希望:另外那个宇宙的居民不仅把我们的宇宙当作储气槽,而且一旦用尽了这里的空气,他们哪天也许能开辟出一条通道,亲自来我们的宇宙探险。他们可能会在我们的街道上徜徉、观察我们僵硬的身体、研究我们的财产、惊异于我们的生命。
我作这篇说明的原因即在于此。我希望你就是其中的一位探险者,我希望你发现这些铜板并破译表面上的文字。不论你们的大脑是否由我思考时消耗的空气所驱动,通过阅读我的文字,你的思维模式就模拟了我曾经的思维模式。以这种方式,我从你身上获得了新生。
你的探险者同伴们将会读到我们留下的其它书籍,通过你们合力思考,我的整个文明重获新生。当你们走在我们寂静的街道上,想象着这里曾经的样子,钟楼鸣响,补给站里到处都是闲聊的邻里,公告员在公共广场朗诵诗文,解剖学家教室里上课。下一次你观察周围这个静止的世界时想象一下我描述的这一切,这样它就会在你的脑海里重新变得充满活力、生机勃勃。
探险者,我希望你一切顺利,不过我怀疑,降临在我们身上的命运会不会同样也在等待着你们?我能想象得出平衡的趋势不仅仅是我们这个宇宙才有的特征,而是所有宇宙的内在性质。也许我的目光短浅,而你们的人已经发现了一个真正永恒的压力之源。然而我的思索已经是异想天开,我会假设你们的思维有一天也会停止,不过我无法弄清那将是在多远的未来。你们的生命将和我们的一样终结,没有人能逃脱。不管需要多久,最终的平衡一定会达成。
我希望你不要因为知道了这样的结局就感到悲哀,希望你们的探险不仅仅是搜索充当储气槽的其它宇宙,还希望你们是在求知欲的激发下,渴望见识宇宙呼出一口气能产生什么。因为即使一座宇宙的寿命可以预测出来,宇宙中生命的多样性却无法统计。我们盖起的建筑,我们创作的美术、音乐和诗句,我们各自的生命:没有一个可以预测,因为这些都不是必然的。我们的宇宙在滑向平衡点的过程中也许只能静静地呼气,而它繁衍出我们这个丰富多彩的世界却是个奇迹,只有诞生了你们的宇宙才能与之媲美。
探险者,尽管你读到这里的时候我去世已久,但我还是要送你一句临别赠言。仔细想想,得以存在便是一个奇迹,能够思考就是一件乐事。我觉得我有权告诉你这一点,因为在刻下这些文字的同时,我就是这样想的。
胡安·鲁尔福- 余华
========================
胡安·鲁尔福- [[余华]]
-----
[[加西亚·马尔克斯]]在他那篇令人感动的文章《回忆胡安·鲁尔福》里这样写道:“对于胡安·鲁尔福作品的深入了解,终于使我找到了为继续写我的书而需要寻找的道路……他的作品不过三百页,但是它几乎和我们所知道的索福克勒斯的作品一样浩瀚,我相信也会一样经久不衰。”
这段话至少说明了两个问题,首先是一位作家对于另一位作家意味着什么?显然,这是文学里最为奇妙的经历之一。1961年7月2日,加西亚·马尔克斯提醒我们,这是欧内斯特·海明威开枪自毙的那一天,而他自己漂泊的生涯仍在继续着,这一天他来到了墨西哥,来到了[[胡安·鲁尔福]]所居住的城市。在此之前,他在巴黎苦苦熬过了三个年头,又在纽约游荡了八个月,然后他的生命把他带入了三十二岁,妻子梅塞德斯陪伴着他,孩子还小,他在墨西哥找到了工作。加西亚·马尔克斯认为自己十分了解拉丁美洲的文学,自然也十分了解墨西哥的文学,可是他不知道胡安·鲁尔福;他在墨西哥的同事和朋友都非常熟悉胡安·鲁尔福的作品,可是没有人告诉他。当时的加西亚·马尔克斯已经出版了《枯枝败叶》,而另外的三本书《没有人给他写信的上校》《恶时辰》和《格兰德大妈的葬礼》也快要出版,他的天才已经初露端倪,可是只有作者知道自己正在经历着什么,他正在经历着倒霉的时光,因为他的写作进入了死胡同,他找不到可以钻出去的裂缝。就在这个时候,他的朋友阿尔瓦罗·穆蒂斯提着一捆书来到了,并且从里面抽出了最薄的那一本递给他,《佩德罗·巴拉莫》,在那个不眠之夜,加西亚·马尔克斯和胡安·鲁尔福相遇了。
这可能是文学里最为动人的相遇了。当然,还有让-[[保罗·萨特]]在巴黎的公园的椅子上读到了卡夫卡;博尔赫斯读到了奥斯卡·王尔德;阿尔贝·加缪读到了威廉·福克纳;波德莱尔读到了爱伦·坡;尤金·奥尼尔读到了斯特林堡;毛姆读到了陀思妥耶夫斯基……卡夫卡名字的古怪拼写曾经使让-保罗·萨特发出一阵讥笑,可是当他读完卡夫卡的作品以后,他就只能去讥笑自己了。
文学就是这样获得了继承。一个法国人和一个奥地利人,或者是一个英国人和一个俄国人,尽管他们生活在不同的时间和不同的空间,使用不同的语言和喜爱不同的服装,爱上了不同的女人和不同的男人,而且属于各自不同的命运。这些理由的存在,让他们即使有机会坐到了一起,也会视而不见。可是有一个理由,只有一个理由可以使他们跨越时间和空间,跨越死亡和偏见,在对方的脸上看到了自己的形象,在对方的胸口听到了自己的心跳,有时候,文学可以使两个绝然不同的人成为一个人。因此,当一个哥伦比亚人和一个墨西哥人突然相遇时,就是上帝也无法阻拦他们了。加西亚·马尔克斯找到了可以钻出死胡同的裂缝,《佩德罗·巴拉莫》成为了一道亮光,可能是十分微弱的亮光,然而使一个人绝处逢生已经绰绰有余。
一个作家的写作影响了另一个作家的写作,这已经成为了文学中写作的继续,让古已有之的情感和源远流长的思想得到继续,这里不存在谁在获利的问题,也不存在谁被覆盖的问题,文学中的影响就像植物沐浴着的阳光一样,植物需要阳光的照耀并不是希望自己能够成为阳光,而是始终要以植物的方式去茁壮成长。另一方面,植物的成长也表明了阳光不可或缺的重要性。一个作家的写作也同样如此,其他作家的影响恰恰是为了使自己不断地去发现自己,使自己写作的独立性更加完整,同时也使文学得到了延伸,使人们的阅读有机会了解了今天作家的写作,同时也会更多地去了解过去作家的写作。文学就像是道路一样,两端都是方向,人们的阅读之旅在经过胡安·鲁尔福之后,来到了加西亚·马尔克斯的车站;反过来,经过了加西亚·马尔克斯,同样也能抵达胡安·鲁尔福。两个各自独立的作家就像他们各自独立的地区,某一条精神之路使他们有了联结,他们已经相得益彰了。
在[[《回忆胡安·鲁尔福》]]里,加西亚·马尔克斯指出了这位作家的作品不过三百页,可是他像[[索福克勒斯]]的作品一样浩瀚。马尔克斯不惜越过莎士比亚,寻找一个数量更为惊人的作家来完成自己的比喻。在这里,加西亚·马尔克斯指出了一个文学中存在已久的事实,那就是作品的浩瀚和作品的数量不是一回事。
就像E.M.福斯特这样指出了T.S.艾略特,威廉·福克纳指出了舍伍德·安德森,艾萨克·辛格指出了布鲁诺·舒尔茨,厄普代克指出了博尔赫斯……人们议论纷纷,在那些数量极其有限的作家的作品中如何获得了广阔无边的阅读。柯尔律治认为存在着四类阅读的方式:第一类是“海绵”式的阅读,轻而易举地将读到的吸入体内,同样也可以轻而易举地排出;第二类是“沙漏计时器”,他们一本接一本地阅读只是为了在计时器里漏一遍;第三类是“过滤器”类,广泛地阅读只是为了在记忆里留下一鳞半爪;第四类才是柯尔律治希望看到的阅读,他们的阅读不仅是为了自己获益,而且也为了别人有可能来运用他们的知识,然而这样的读者在柯尔律治眼中是“犹如绚丽的钻石一般既贵重又稀有的人”。显然,加西亚·马尔克斯是一颗柯尔律治理想中的“绚丽的钻石”。
柯尔律治把难题留给了阅读,然后他指责了多数人对待词语的轻率态度,他的指责使他显得模棱两可,一方面表达了他对流行的阅读方式的不满,另一方面他也没有放过那些不负责任的写作。其实根源就在这里,正是那些轻率地对待词语的写作者,而且这样的恶习在每一个时代都是蔚然成风,当胡安·鲁尔福以自己杰出的写作从而获得永生时,另一类作家伤害文学的写作,也就是写作的恶习也同样可以超越死亡而世代相传。这就是加西亚·马尔克斯为什么要区分作品的浩瀚和作品的数量的理由,也是柯尔律治寻找第四类阅读的热情所在。
加西亚·马尔克斯在文章里继续写道:“当有人对卡洛斯·维洛说我能够整段整段地背诵《佩德罗·巴拉莫》时,我依然沉醉在胡安·鲁尔福的作品中。其实,情况还远不止于此;我能够背诵全书,且能倒背,不出大错。并且我还能说出每个故事在我读的那本书的哪一页上,没有一个人物的任何特点我不熟悉。”
还有什么样的阅读能够像马尔克斯这样持久、赤诚、深入和广泛?就是对待自己的作品,马尔克斯也很难做到不出大错地倒背。在柯尔律治欲言又止之处,加西亚·马尔克斯更为现实地指出了阅读存在着无边无际的广泛性。对马尔克斯而言,完整的或者片段的,最终又是不断地对《佩德罗· 巴拉莫》的阅读过程,在某种意义上已经是一次次写作的过程,“没有一个人物的任何特点我不熟悉”,加西亚·马尔克斯的阅读成为了另一支笔,不断复写着,也不断续写着《佩德罗·巴拉莫》。不过他没有写在纸上,而是写进了自己的思想和情感之河。然后他换了一支笔,以完全独立的方式写下了《百年孤独》,这一次他写在了纸上。
事实上,胡安·鲁尔福在《佩德罗·巴拉莫》和《烈火中的平原》的写作中,已经显示了写作永不结束的事实,这似乎是一切优秀作品中存在的事实。就像贝瑞逊赞扬海明威《老人与海》“无处不洋溢着象征”一样,胡安·鲁尔福的《佩德罗·巴拉莫》也具有了同样的品质。作品完成之后写作的未完成,这几乎成为了《佩德罗·巴拉莫》最重要的品质。在这部只有一百多页的作品里,似乎在每一个小节的后面都可以将叙述继续下去,使它成为一部一千页的书,成为一部无尽的书。可是谁也无法继续《佩德罗·巴拉莫》的叙述,就是胡安·鲁尔福自己也同样无法继续。虽然这是一部永远有待于完成的书,可它又是一部永远不能完成的书。不过,它始终是一部敞开的书。
胡安·鲁尔福没有边界的写作,也取消了加西亚·马尔克斯阅读的边界。这就是马尔克斯为什么可以将《佩德罗·巴拉莫》背诵下来,就像胡安·鲁尔福的写作没有完成一样,马尔克斯的阅读在每一次结束之后也同样没有完成,如同他自己的写作。现在,我们可以理解加西亚·马尔克斯为什么在胡安·鲁尔福的作品里读到了索福克勒斯般的浩瀚,是因为他在一部薄薄的书中获得了无边无际的阅读。同时也可以理解马尔克斯的另一个感受:与那些受到人们广泛谈论的经典作家不一样,胡安·鲁尔福的命运是──受到了人们广泛的阅读。
一九九八年十二月六日
胡兰成(1906年2月28日-1981年7月25日),原名胡积蕊,小名蕊生,男,浙江绍兴人,中国近代作家。张爱玲第一任丈夫。曾任职汪精卫政权。
画画的作家-伊塔洛·卡尔维诺
========================
画画的作家-[[伊塔洛·卡尔维诺]]
-----
随着浪漫主义的到来,法国作家纷纷提起画笔。作家的笔在纸上飞驰、停顿、游移,然后漫不经心或兴之所至地在空白处画下一张肖像、一个人偶、一幅涂鸦,或者全神贯注地画出一段花纹、一片阴影,或是一座几何迷宫。文字有时候会面临两难的抉择:是继续在一成不变的字母堆砌中找寻灵感,还是转而画出一幅更为直接的速写?这一诱惑似乎并不经常出现,因为写文章的画家一直以来都有,会画画的作家则少有。可是突然间,在18世纪末和19世纪初,对于立志从文的年轻人来说,不曾学过绘画就等同于不曾接受完整的教育。诗人和作家都开始执笔画画,要不是因为文学领域的魅力更大的话,有些人甚至可以在艺术领域从事专业工作。与此同时,那些从来没有接受过绘画教育的作家手稿中也开始出现涂鸦和简笔小人。作家的整个文化面貌改变了,生出了创作“总体艺术”[33](这既是诺瓦利斯[34]珍视的梦想,也是瓦格纳的标题音乐的基础)的宏愿。霍夫曼[35](1829年被译介到法国)立即成了法国新文学的典范,不仅仅因为他创造了全新的文学样式:奇幻故事(contes fantastiques,法国人总是喜欢为文化创新贴上标签,这个由法国人创造的词反倒在德语中没有对应的表达),还因为他总是以浪漫主义多面手的形象出现,既是作家,也是画家和音乐家。
这些想法都是我在巴尔扎克故居参观一场名叫“19世纪法国作家的绘画作品”的展览时产生的。展览展出了45位诗人和作家的250幅作品(从最简单的涂鸦和素描作品,到水彩画和真正意义上的画作),这些人有的声名卓著,有的相对次要,有的则已经被人遗忘,但每一件展品对于了解绘画和文字之间的关系都意义非凡。我们必须首先说明的是,这种所谓的关系只包含最一般层面上的意味,因为乍看之下,这些画作没有什么明显的风格,或者因为画家的画笔太过笨拙,或者其技巧太没个性,所以我们似乎很难在作家的风格与他们的画作之间建立联系。所以我认为不可能搞清楚为什么有的作家画画,而另外一些作家尽管小说中充满了视觉画面,却从来都不画画。[这份不画画的作家名单有不少大牌,包括夏多布里昂(Chateaubriand)、斯塔尔夫人(Madame de Sta.l)、福楼拜、左拉。]
我们已经知道,在19世纪的法国作家中最天才的业余画家要数维克托·雨果,这次展览也确认了这一点。展览从维克托·雨果的故居(这是另一座变成博物馆的作家故居,不过比巴尔扎克故居更有趣)中拿来了不少他描绘光怪陆离的城市和诡异可怕的风景的钢笔绘画作品,作家借此在那段焦躁的时期宣泄出他最黑暗的浪漫主义血液。此外,这些作品也表明雨果在绘画中也有着独具天才的创造力。
至于另一位多产作家巴尔扎克,却丝毫没有绘画的天分,只能在他手稿的空白处蹩脚地画出几幅略显幼稚的涂鸦作品(尤其是人脸画像)。尽管我们身处巴尔扎克的故居里,但是展览中只有两页他的作品,而且是复制品,并非真迹。另外一个展品甚少的作家是司汤达,但是看到《亨利·勃吕拉传》(Vie de Henry Brulard)上的粗糙的素描画,我们几乎可以将他归入不会画画的作家行列。从米什莱(Michelet)设计的法国大革命烈士纪念碑的草图来看,他也没有驾驭画笔的天分。
有一些作家绘画天分过高,这样也不是很有意思。普罗斯佩·梅里美(Prosper Mérimée)、阿尔弗雷·德·维尼(Alfred de Vigny),泰奥菲尔·戈蒂耶(Théophile Gautier)都曾经接受过正统的绘画训练,展览中展出的他们的作品(包括历史题材的画作、水彩风景画、讽刺画、建筑草图)都无法辨识出个人的风格。梅里美曾作为重要与会人士参加过许许多多的官方会议,可是就连这种场合,他在内阁文件纸上开小差创作的画作也是沉稳且教科书式的。他在旅行笔记本上创作的素描反倒更有趣些,因为它们对于国家和地方服饰有着准确的观察,从中我们可以体会到一种与他的短篇小说截然不同的力量。在戈蒂耶的作品中,两幅红墨水画最为突出,体现出他古怪且深受折磨的诗人品位:一幅是女巫的厨房,另一副则是圣安东尼的色情虐恋画。
乔治·桑也是一位技艺精湛的风景画家,善用铅笔和水彩作画,至少我们从她的一组绿灰色和浅棕色的大山风景画中,可以看出她传达了某种不同寻常的意趣:这乃是一片凝滞而令人不寒而栗的碎石荒原。在这些风景画中,她采用了一种自己独创的绘画技法,她把它叫作“树枝晶”(dendrites),来源于那些纹路呈树枝状的晶体结构。
展览中最让人意外的发现要数“条漫”先行者阿尔弗雷德·德·缪塞(Alfred de Musset)。据其自传《一个世纪儿的忏悔》(La Confession d'un enfant du siècle)记载,这位浪漫主义“世纪儿”为了娱乐自己、朋友以及家人,以社会名流为角色创作了许多漫画故事:展览中展出了两个完整的系列。一个系列讲的是诗人弟弟的西西里之旅,其中最精彩的是同一个水性杨花的墨西拿女人的风流韵事。另一个系列讲的则是一则巴黎八卦新闻:歌手玛丽亚·梅丽布朗(Maria Malibran)的妹妹波利娜·加西亚(Pauline García,在姐姐死后也成了一名歌手)是如何被一位大鼻子绅士求婚,以及在两人分分合合的过程中,未婚夫的大鼻子如何改变着形状和尺寸。有意思的是,阿尔弗雷德·德·缪塞也在追求这位歌手,他把自己画成一副因肺病卧病在床的模样,病情因情敌的状况时好时坏。漫画里的波利娜如梦幻般优雅,但故事里的反派却是乔治·桑,总是一副叼着雪茄、抽着烟斗或舞刀弄剑的形象。
这些时代超前的漫画作品有着某种介乎鲁道夫·托普佛[36]和爱德华·利尔[37]之间的叙事特色和优雅画面,甚至有着近乎20世纪的灵活风格(令人回想起塞尔焦·托法诺[38]的画作),因此具有了让人意想不到的现代性。从缪塞开始,男人们开始在给女士朋友写信时附上了小幅图画(也都是些戏剧界的八卦新闻,翻来覆去都是那几个人物)。缪塞的画作可以被定义为“作家绘画”,因其叙事创新、风格独具而且隐含着某种讽刺和自嘲而与真正的画家作品有所区别:这些都是文学创作的程序,尽管和作家在文字作品中使用的程序完全不同。
展览给观众带来的另一种“作家画作”是变成画作的文字,此类画作的代表人物是让人们意想不到的巴尔贝·多尔维利[39],他留下了一本五彩缤纷的插图日记,文字间穿插着箭头、心形、太阳、圣杯、几何装饰,虽然粗浅且混乱,却有着强大的图像生命力,多少有些“原生艺术”的意趣。这位法国的花花公子拥有一整套彩色墨水、粗度各不相同的鹅毛笔和画笔。比方说,他会用水粉重新涂抹已然用钢笔签好的名字,直到它变成一团浓重黏稠的图像之诗,又或者生造出宛如巨型昆虫或飞机的象形文字。
波德莱尔不仅会画画,而且很懂得如何将智慧融入到手中的铅笔(或蜡笔或水彩笔)中去,而且他的自嘲有的放矢、毫不手软。在他开启的那个年代(即19世纪下半叶),我们发现诗人和作家在纸上勾勒图画时多了些洒脱,少了几分学究气[我能够想到的例外有那些首先是个画家的人,比如欧仁·弗罗芒坦(Eugène Fromentin),那些刻板地制作蚀刻版画的人,比如儒勒·德·龚古尔(Jules de Goncourt),以及那些以虔诚的准确描绘异国旅行的人,比如皮埃尔·洛蒂(Pierre Loti)]。
同小说家(小仲马很擅长讽刺画,莫泊桑总是画一些滑稽可笑的玩偶,阿纳托尔·法郎士[40]则是个技巧华丽、风格优美的画匠)相比,诗人的画作更值得注目,其中又以魏尔伦(Verlaine)为甚,虽然他从来没有学习过绘画,却是一位富有创意和现代精神的幽默画家。在他留下的许多自画像中,他都是一副小鼻子、尖下巴的清朝官员形象:其中一幅展品上的他就是这副模样,脸部特征被简化为一系列互相重叠的三角形,再进一步就离立体主义不远了。最令人感动的是他给兰波(Rimbaud)画的肖像,画中的兰波斜靠在咖啡桌上,双眼盯着一瓶苦艾酒,表情就像个生闷气的孩子。(兰波本人的画作则比较无趣,至少从展览上展出的两幅兰波作品我们可以这么判断。)
诗人弗朗索瓦·戈贝(Fran.ois Coppée)在写信时对于自己的书法特别讲究,每封信都字迹清楚,并附有各类符号和字谜。他在写给梅里·洛朗(Méry Laurent,一位由美国牙医供养的交际花)的情书中将这位女优唤作“小雄鸟”,称自己为“小母猫”。虽然在我们看来,这些昵称似乎有点性别错位,却被戈贝所画的图案打消了疑虑,所谓“小雄鸟”实际上是一只喜欢给自己梳毛的鸽子,而所谓“小母猫”则是只毛发蓬松的公猫。
同一时期,马拉美(Mallarmé)也在追求梅里·洛朗,他也给她写了许多附有图画的情书。他和戈贝一样把这位女性比作鸟儿,不过要耗费更多颜料,因为对于马拉美来说,她是“孔雀”。马拉美在绘画方面完全没有天赋,也不曾掌握任何绘画技巧,但是他在图案中加入了一些有趣的东西,与他无与伦比的文字天赋相得益彰。展览上展出了一张他和正要坐火车赶来的“孔雀”确定约会的字条,潦草却充满欢乐的内容令它成了马拉美珍贵的“条漫”作品。
从这些布满文字的手稿边缘的一幅幅图画中,我们可以看出作家们对于有别于文字的另一种表达方式的追求。我们怎么可能感受不到作家对于画家的永恒嫉妒呢?“和咬文嚼字的人相比,画家是多么幸福的职业啊,”龚古尔兄弟在1869年5月1日的日记中如此写道,“一面是对头脑的摧残和折磨,一面则是手和眼睛的快乐活动;工作对一方来说是痛苦,对另一方来说则是享受……”
1984年
所谓环形结构叙事就是影片中各个段落的不分首尾,互补结构,开头和结尾相连等等。现代电影运用非线性叙事冲破了对时间单一向度的理解。在后现代语境下,传统时间理念的消失并非意味着时间在当下已不复存在,反而使时间获得了一种全新的表达方式。体现"时间轮回"、"命运偶然性"和"罪恶暴力循环"的叙事隐喻,其表意功能具备宗教直觉的悟性和禅意的环形叙事便是其中之一。环形叙事通过对时空的重新组合,以新鲜的视角探视人和人的情感,探寻着人生的终极意义。
黄昏里的男孩-余华
========================
黄昏里的男孩-[[余华]]
-------
此刻,有一个名叫孙福的人正坐在秋天的中午里,守着一个堆满水果的摊位。明亮的阳光照耀着他,使他年过五十的眼睛眯了起来。他的双手搁在膝盖上,于是身体就垂在手臂上了。他花白的头发在阳光下显得灰蒙蒙,就像前面的道路。这是一条宽阔的道路,从远方伸过来,经过了他的身旁以后,又伸向了远方。他在这里已经坐了三年了,在这个长途汽车经常停靠的地方,以贩卖水果为生。一辆汽车从他身旁驶了过去,卷起的尘土像是来到的黑夜一样笼罩了他,接着他和他的水果又像是黎明似的重新出现了。
他看到一个男孩站在了前面,在那一片尘土过去之后,他看到了这个男孩,黑亮的眼睛正注视着他。他看着对面的男孩,这个穿着很脏衣服的男孩,把一只手放在他的水果上。他去看男孩的手,指甲又黑又长,指甲碰到了一只红彤彤的苹果,他的手就举起来挥了挥,像是驱赶苍蝇一样,他说:
“走开。”
男孩缩回了自己黑乎乎的手,身体摇晃了一下后,走开了。男孩慢慢地向前走去,他的两条手臂闲荡着,他的头颅在瘦小的身体上面显得很大。
这时候有几个人向水果摊走过来,孙福收回了自己的目光,不再去看那个走去的男孩。那几个人走到孙福的对面,隔着水果问他:
“苹果怎么卖……香蕉多少钱一斤……”
孙福站了起来,拿起秤杆,为他们称苹果和香蕉,又从他们手中接过钱。然后他重新坐下来,重新将双手搁在膝盖上,接着他又看到了刚才的男孩。男孩回来了。这一次男孩没有站在孙福的对面,而是站在一旁,他黑亮的眼睛注视着孙福的苹果和香蕉。孙福也看着他,男孩看了一会水果后,抬起头来看孙福了,他对孙福说:
“我饿了。”
孙福看着他没有说话,男孩继续说:
“我饿了。”
孙福听到了清脆的声音,他看着这个很脏的男孩,皱着眉说:
“走开。”
男孩的身体似乎抖动了一下,孙福响亮地又说:
“走开。”
男孩吓了一跳,他的身体迟疑不决地摇晃了几下,然后两条腿挪动了。孙福不再去看他,他的眼睛去注视前面的道路,他听到一辆长途客车停在了道路的另一边,车里的人站了起来。通过车窗玻璃,他看到很多肩膀挤到了一起,向着车门移动,过了一会车上的人从客车的两端流了出来。这时,孙福转过脸来,他看到刚才那个男孩正在飞快地跑去。他看着男孩,心想他为什么跑,他看到了男孩甩动的手,男孩甩动的右手里正抓着什么,正抓着一个很圆的东西,他看清楚了,男孩手里抓着的是一只苹果。于是孙福站了起来,向着男孩跑去的方向追赶。孙福喊叫了起来:
“抓小偷!抓住前面的小偷……”
这时候已经是下午,男孩在尘土飞扬的道路上逃跑,他听到了后面的喊叫,他回头望去,看到追来的孙福。他拼命向前跑,他气喘吁吁,两腿发软,他觉得自己快要跑不动了,他再次回头望去,看到挥舞着手喊叫的孙福,他知道孙福就要追上他了,于是他站住了脚,转过身来仰起脸呼哧呼哧地喘气了。他喘着气看着追来的孙福,当孙福追到他面前时,他将苹果举到了嘴里,使劲地咬了一口。
追上来的孙福挥手打去,打掉了男孩手里的苹果,还打在了男孩的脸上,男孩一个趔趄摔倒在地。倒在地上的男孩双手抱住自己的头,嘴里使劲地咀嚼起来。孙福听到了他咀嚼的声音,就抓住他的衣领把他提了起来。衣领被捏紧后,男孩没法咀嚼了,他瞪圆了眼睛,两腮被嘴里的苹果鼓了出来。孙福一只手抓住他的衣领,另一只手去卡他的脖子。孙福向他喊叫:
“吐出来!吐出来!”
很多人围了上来,孙福对他们说:
“他还想吃下去!他偷了我的苹果,咬了我的苹果,他还想吃下去!”
然后孙福挥手给了男孩一巴掌,向他喊道:
“你给我吐出来!”
男孩紧闭鼓起的嘴,孙福又去卡他的脖子:
“吐出来!”
男孩的嘴张了开来,孙福看到了他嘴里已经咬碎的苹果,就让卡住他脖子的手使了使劲。孙福看到他的眼睛瞪圆了。有一个人对孙福说:
“孙福,你看他的眼珠子都快瞪出来了,你会把他卡死的。”
“活该。”孙福说,“卡死了也活该。”
然后孙福松开卡住男孩的手,指着苍天说道:
“我这辈子最恨的就是小偷……吐出来!”
男孩开始将嘴里的苹果吐出来了,一点一点地吐了出来,就像是挤牙膏似的,男孩将咬碎的苹果吐在了自己胸前的衣服上。男孩的嘴闭上后,孙福又用手将他的嘴掰开,蹲下身体往里面看了看后说:
“还有,还没有吐干净。”
于是男孩继续往外吐,吐出来的全是唾沫,唾沫里夹杂着一些苹果屑。男孩不停地吐着,吐到最后只有干巴巴的声音,连唾沫都没有了。这时候孙福才说:
“别吐啦。”
然后孙福看看四周的人,他看到了很多熟悉的脸,他就对他们说:
“从前我们都是不锁门的,这镇上没有一户人家锁门,是不是?”
他看到有人在点头,他继续说:
“现在锁上门以后,还要再加一道锁,为什么?就是因为这些小偷,我这辈子最恨的就是小偷。”
孙福去看那个男孩,男孩正仰着脸看他,他看到男孩的脸上都是泥土,男孩的眼睛出神地望着他,似乎是被他刚才的话吸引了。男孩的表情让孙福兴奋起来了,他说:
“要是从前的规矩,就该打断他的一只手,哪只手偷的,就打断哪只手……”
孙福低头对男孩叫了起来:“是哪只手?”
男孩浑身一抖,很快地将右手放到了背后。孙福一把抓起男孩的右手,给四周的人看,他对他们说:
“就是这只手,要不他为什么躲得这么快……”
男孩这时候叫道:“不是这只手。”
“那就是这只手。”孙福抓起了男孩的左手。
“不是!”
男孩叫着,想抽回自己的左手,孙福挥手给了他一巴掌,男孩的身体摇晃了几下,孙福又给了他一巴掌,男孩不再动了。孙福揪住他的头发,让他的脸抬起来,冲着他的脸大声喊道:
“是哪只手?”
男孩睁大眼睛看着孙福,看了一会后,他将右手伸了出来。孙福抓住他右手的手腕,另一只手将他的中指捏住,然后对四周的人说:
“要是从前的规矩,就该把他这只手打断,现在不能这样了,现在主要是教育,怎么教育呢?”
孙福看了看男孩说:“就是这样教育。”
接着孙福两只手一使劲,“咔”的一声扭断了男孩右手的中指。男孩发出了尖叫,声音就像是匕首一样锋利。然后男孩看到了自己的右手的中指断了,耷拉到了手背上。男孩一下子就倒在了地上。
孙福对四周的人说:“对小偷就要这样,不打断他一条胳膊,也要扭断他的一根手指。”
说着,孙福伸手把男孩提了起来,他看到男孩因为疼痛而紧闭着眼睛,就向他喊叫:
“睁开来,把眼睛睁开来。”
男孩睁开了眼睛,可是疼痛还在继续,他的嘴就歪了过去。孙福踢了踢他的腿,对他说:
“走!”
孙福捏住男孩的衣领,推着男孩走到了自己的水果摊前。他从纸箱里找出了一根绳子,将男孩绑了起来,绑在他的水果摊前。他看到有几个人跟了过来,就对男孩说:
“你喊叫,你就叫‘我是小偷’。”
男孩看看孙福,没有喊叫。孙福一把抓起了他的左手,捏住他左手的中指,男孩立刻喊叫了:
“我是小偷。”
孙福说:“声音轻啦,响一点。”
男孩看看孙福,然后将头向前伸去,使足了劲喊叫了:
“我是小偷!”
孙福看到男孩的血管在脖子上挺了出来,他点点头说:
“就这样,你就这样喊叫。”
这天下午,秋天的阳光照耀着这个男孩,他的双手被反绑到了身后,绳子从他的脖子上勒过去,使他没法低下头去,他只能仰着头看着前面的路,他的身旁是他渴望中的水果,可是他现在就是低头望一眼都不可能了,因为他的脖子被勒住了。只要有人过来,就是顺路走过,孙福都要他喊叫:
“我是小偷。”
孙福坐在水果摊位的后面,坐在一把有靠背的小椅子里,心满意足地看着这个男孩。他不再为自己失去一只苹果而恼怒了,他开始满意自己了,因为他抓住了这个偷他苹果的男孩,也惩罚了这个男孩,而且惩罚还在进行中。他让他喊叫,只要有人走过来,他就让他高声喊叫,正是有了这个男孩的喊叫,他发现水果摊前变得行人不绝了。
很多人都好奇地看着这个喊叫中的男孩,这个被捆绑起来的男孩在喊叫“我是小偷”时如此卖力,他们感到好奇。于是孙福就告诉他们,一遍又一遍地告诉他们,他偷了他的苹果,他又如何抓住了他,如何惩罚了他,最后孙福对他们说:
“我也是为他好。”
孙福这样解释自己的话:“我这是要让他知道,以后再不能偷东西。”
说到这里,孙福响亮地问男孩:“你以后还偷不偷?”
男孩使劲地摇起了头,由于他的脖子被勒住了,他摇头的幅度很小,速度却很快。
“你们都看到了吧?”孙福得意地对他们说。
这一天的下午,男孩不停地喊叫着,他的嘴唇在阳光里干裂了,他的嗓音也沙哑了。到了黄昏的时候,男孩已经喊叫不出声音了,只有咝咝的摩擦似的声音,可是他仍然在喊叫着:
“我是小偷。”
走过的人已经听不清他在喊些什么了,孙福就告诉他们:
“他是在喊‘我是小偷’。”
然后,孙福给他解开了绳子。这时候天就要黑了,孙福将所有的水果搬上板车,收拾完以后,给他解开了绳子。孙福将绳子收起来放到了板车上时,听到后面“扑通”一声,他转过身去,看到男孩倒在了地上,他就对男孩说:
“我看你以后还敢不敢偷东西?”
说着,孙福骑上了板车,沿着宽阔的道路向前骑去了。男孩躺在地上。他饥渴交加,精疲力竭,当孙福给他解开绳子后,他立刻倒在了地上。孙福走后,男孩继续躺在地上,他的眼睛微微张开着,仿佛在看着前面的道路,又仿佛是什么都没有看。男孩一动不动地躺了一会以后,慢慢地爬了起来,又靠着一棵树站了一会,然后他走上了那条道路,向西而去。
男孩向西而去,他瘦小的身体走在黄昏里,一步一步地微微摇晃着走出了这个小镇。有几个人看到了他的走去,他们知道这个男孩就是在下午被孙福抓住的小偷,但是他们不知道他的名字,也不知道他来自何处,当然更不会知道他会走向何处。他们都注意到了男孩的右手,那中间的手指已经翻了过来,和手背靠在了一起,他们看着他走进了远处的黄昏,然后消失在黄昏里。
这天晚上,孙福像往常一样,去隔壁的小店打了一斤黄酒,又给自己弄了两样小菜,然后在八仙桌前坐下来。这时,黄昏的光芒从窗外照了进来,使屋内似乎暖和起来了。孙福就坐在窗前的黄昏里,慢慢地喝着黄酒。
在很多年以前,在这一间屋子里,曾经有一个漂亮的女人,还有一个五岁的男孩,那时候这间屋子里的声音此起彼伏,他和他的妻子,还有他们的儿子,在这间屋子里没完没了地说着话。他经常坐在屋内的椅子里,看着自己的妻子在门外为煤球炉生火,他们的儿子则是寸步不离地抓着母亲的衣服,在外面细声细气地说着什么。
后来,在一个夏天的中午,几个男孩跑到了这里,喊叫着孙福的名字,告诉他,他的儿子沉入不远处池塘的水中了。他就在那个夏天的中午里狂奔起来,他的妻子在后面凄厉地哭喊着。然后,他们知道自己已经永远失去儿子了。到了晚上,在炎热的黑暗里,他们相对而坐,呜咽着低泣。
再后来,他们开始平静下来,像以往一样生活,于是几年时间很快就过去了。到了这一年的冬天,一个剃头匠挑着铺子来到了他们的门外,他的妻子就走了出去,坐在了剃头匠带来的椅子里,在阳光里闭上了眼睛,让剃头匠为她洗发、剪发,又让剃头匠为她掏去耳屎,还让剃头匠给她按摩了肩膀和手臂。她感到自己的身体从来没有像那天那样舒展,如同正在消失之中。因此她收拾起了自己的衣服,在天黑以后,离开了孙福,追随剃头匠而去了。
就这样,孙福独自一人,过去的生活凝聚成了一张已经泛黄了的黑白照片,贴在墙上,他、妻子、儿子在一起。儿子在中间,戴着一顶比脑袋大了很多的棉帽子。妻子在左边,两条辫子垂在两侧的肩上,她微笑着,似乎心满意足。他在右边,一张年轻的脸,看上去生机勃勃。
-------
一九九五年十二月二十二日
黄金时代-王小波
========================
黄金时代-[[王小波]]
-----
## 一
我二十一岁时,正在云南插队。陈清扬当时二十六岁,就在我插队的地方当医生。我在山下十四队,她在山上十五队。有一天她从山上下来,和我讨论她不是破鞋的问题。那时我还不大认识她,只能说有一点知道。她要讨论的事是这样的:虽然所有的人都说她是一个破鞋,但她以为自己不是的。因为破鞋偷汉,而她没有偷过汉。虽然她丈夫已经住了一年监狱,但她没有偷过汉。在此之前也未偷过汉。所以她简直不明白,人们为什么要说她是破鞋。如果我要安慰她,并不困难。我可以从逻辑上证明她不是破鞋。如果陈清扬是破鞋,即陈清扬偷汉,则起码有一个某人为其所偷。如今不能指出某人,所以陈清扬偷汉不能成立。但是我偏说,陈清扬就是破鞋,而且这一点毋庸置疑。
陈清扬找我证明她不是破鞋,起因是我找她打针。这事经过如下:农忙时队长不叫我犁田,而是叫我去插秧,这样我的腰就不能经常直立,认识我的人都知道,我的腰上有旧伤,而且我身高在一米九以上。如此插了一个月,我腰痛难忍,不打封闭就不能入睡。我们队医务室那一把针头镀层剥落,而且都有倒钩,经常把我腰上的肉钩下来。后来我的腰就像中了霰弹枪,伤痕久久不褪。就在这种情况下,我想起十五队的队医陈清扬是北医大毕业的大夫,对针头和勾针大概还能分清,所以我去找她看病。看完病回来,不到半个小时,她就追到我屋里来,要我证明她不是破鞋。
陈清扬说,她丝毫也不藐视破鞋。据她观察,破鞋都很善良,乐于助人,而且最不乐意让人失望。因此她对破鞋还有一点钦佩。问题不在于破鞋好不好,而在于她根本不是破鞋。就如一只猫不是一只狗一样。假如一只猫被人叫成一只狗,它也会感到很不自在。现在大家都管她叫破鞋,弄得她魂不守舍,几乎连自己是谁都不知道了。
陈清扬在我的草房里时,裸臂赤腿穿一件白大褂,和她在山上那间医务室里装束一样。所不同的是披散的长发用个手绢束住,脚上也多了一双拖鞋。看了她的样子,我就开始捉摸:她那件白大褂底下是穿了点什么呢,还是什么都没穿。这一点可以说明陈清扬很漂亮,因为她觉得穿什么不穿什么无所谓。这是从小培养起来的自信心。我对她说,她确实是个破鞋。还举出一些理由来:所谓破鞋者,乃是一个指称,大家都说你是破鞋,你就是破鞋,没什么道理可讲。大家说你偷了汉,你就是偷了汉,这也没什么道理可讲。至于大家为什么要说你是破鞋,照我看是这样:大家都认为,结了婚的女人不偷汉,就该面色黝黑,乳房下垂。而你脸不黑而且白,乳房不下垂而且高耸,所以你是破鞋。假如你不想当破鞋,就要把脸弄黑,把乳房弄下垂,以后别人就不说你是破鞋。当然这样很吃亏,假如你不想吃亏,就该去偷个汉来。这样你自己也认为自己是个破鞋。别人没有义务先弄明白你是否偷汉再决定是否管你叫破鞋。你倒有义务叫别人无法叫你破鞋。陈清扬听了这话,脸色发红,怒目圆睁,几乎就要打我一耳光。这女人打人耳光出了名,好多人吃过她的耳光。但是她忽然泄了气,说:好吧,破鞋就破鞋吧。但是垂不垂黑不黑的,不是你的事。她还说,假如我在这些事上琢磨得太多,很可能会吃耳光。
倒退到二十年前,想象我和陈清扬讨论破鞋问题时的情景。那时我面色焦黄,嘴唇干裂,上面粘了碎纸和烟丝,头发乱如败棕,身穿一件破军衣,上面好多破洞都是橡皮膏粘上的,跷着二郎腿,坐在木板床上,完全是一副流氓相。你可以想象陈清扬听到这么个人说起她的乳房下垂不下垂时,手心是何等的发痒。她有点神经质,都是因为有很多精壮的男人找她看病,其实却没有病。那些人其实不是去看大夫,而是去看破鞋。只有我例外。我的后腰上好像被猪八戒筑了两耙。不管腰疼真不真,光那些窟窿也能成为看医生的理由。这些窟窿使她产生一个希望,就是也许能向我证明,她不是破鞋。有一个人承认她不是破鞋,和没人承认大不一样。可是我偏让她失望。
我是这么想的:假如我想证明她不是破鞋,就能证明她不是破鞋,那事情未免太容易了。实际上我什么都不能证明,除了那些不需证明的东西。春天里,队长说我打瞎了他家母狗的左眼,使它老是偏过头来看人,好像在跳芭蕾舞。从此后他总给我小鞋穿。我想证明我自己的清白无辜,只有以下三个途径:
1.队长家不存在一只母狗;
2.该母狗天生没有左眼;
3.我是无手之人,不能持枪射击。
结果是三条一条也不成立。队长家确有一棕色母狗,该母狗的左眼确是后天打瞎,而我不但能持枪射击,而且枪法极精。在此之前不久,我还借了罗小四的气枪,用一碗绿豆做子弹,在空粮库里打下了二斤耗子。当然,这队里枪法好的人还有不少,其中包括罗小四。气枪就是他的,而且他打瞎队长的母狗时,我就在一边看着。但是我不能揭发别人,罗小四和我也不错。何况队长要是能惹得起罗小四,也不会认准了是我。所以我保持沉默。沉默就是默认。所以春天我去插秧,撅在地里像一根半截电线杆,秋收后我又去放牛,吃不上热饭。当然,我也不肯无所作为。有一天在山上,我正好借了罗小四的气枪,队长家的母狗正好跑到山上叫我看见,我就射出一颗子弹打瞎了它的右眼。该狗既无左眼,又无右眼,也就不能跑回去让队长看见——天知道它跑到哪儿去了。
我记得那些日子里,除了上山放牛和在家里躺着,似乎什么也没做。我觉得什么都与我无关。可是陈清扬又从山上跑下来找我。原来又有了另一种传闻,说她在和我搞破鞋。她要我给出我们清白无辜的证明。我说,要证明我们无辜,只有证明以下两点:
1.陈清扬是处女;
2.我是天阉之人,没有性交能力。
这两点都难以证明。所以我们不能证明自己无辜。我倒倾向证明自己不无辜。陈清扬听了这些话,先是气得脸白,然后满面通红,最后一声不吭地站起来走了。
陈清扬说,我始终是一个恶棍。她第一次要我证明她清白无辜时,我翻了一串白眼,然后开始胡说八道。第二次她要我证明我们俩无辜,我又一本正经地向她建议举行一次性交。所以她就决定,早晚要打我一个耳光。假如我知道她有这样的打算,也许后面的事情就不会发生。
-----
## 二
我过二十一岁生日那天,正在河边放牛。下午我躺在草地上睡着了。我睡去时,身上盖了几片芭蕉叶子,醒来时身上已经一无所有(叶子可能被牛吃了)。亚热带旱季的阳光把我晒得浑身赤红,痛痒难当,我的小和尚直翘翘地指向天空,尺寸空前。这就是我过生日时的情形。
我醒来时觉得阳光耀眼,天蓝得吓人,身上落了一层细细的尘土,好像一层爽身粉。我一生经历的无数次勃起,都不及那一次雄浑有力,大概是因为在极荒僻的地方,四野无人。
我爬起来看牛,发现它们都卧在远处的河汊里静静地嚼草。那时节万籁无声,田野上刮着白色的风。河岸上有几对寨子里的牛在斗架,斗得眼珠通红,口角流涎。这种牛阴囊紧缩,阳具直挺。我们的牛不干这种事。任凭别人上门挑衅,我们的牛依旧安卧不动。为了防止斗架伤身,影响春耕,我们把它们都阉了。
每次阉牛我都在场。对于一般的公牛,只用刀割去即可。但是对于格外生性者,就须采取槌骟术,也就是割开阴囊,掏出睾丸,一木槌砸个稀烂。从此后受术者只知道吃草干活,别的什么都不知道,连杀都不用捆。掌槌的队长毫不怀疑这种手术施之于人类也能得到同等的效力,每回他都对我们呐喊:你们这些生牛蛋子,就欠砸上一槌才能老实!按他的逻辑,我身上这个通红通红,直不棱登,长约一尺的东西就是罪恶的化身。
当然,我对此有不同的意见。在我看来,这东西无比重要,就如我之存在本身。天色微微向晚,天上飘着懒洋洋的云彩。下半截沉在黑暗里,上半截仍浮在阳光中。那一天我二十一岁,在我一生的黄金时代,我有好多奢望。我想爱,想吃,还想在一瞬间变成天上半明半暗的云。后来我才知道,生活就是个缓慢受槌的过程,人一天天老下去,奢望也一天天消失,最后变得像挨了槌的牛一样。可是我过二十一岁生日时没有预见到这一点。我觉得自己会永远生猛下去,什么也捶不了我。
那天晚上我请陈清扬来吃鱼,所以应该在下午把鱼弄到手。到下午五点多钟我才想起到戽鱼的现场去看看。还没走进那条小河汊,两个景颇族孩子就从里面一路打出来,烂泥横飞,我身上也挨了好几块,直到我拎住他们的耳朵,他们才罢手。我喝问一声:
“鸡巴,鱼呢?”
那个年纪大点的说:“都怪鸡巴勒农!他老坐在坝上,把坝坐鸡巴倒了!”
勒农直着嗓子吼:“王二!坝打得不鸡巴牢!”
我说:“放屁!若干砍草皮打的坝,哪个鸡巴敢说不牢?”
到里面一看,不管是因为勒农坐的也好,还是因为我的坝没打好也罢,反正坝是倒了,戽出来的水又流回去,鱼全泡了汤,一整天的劳动全都白费。我当然不能承认是我的错,就痛骂勒农。勒都(就是那另一个孩子)也附和我。勒农上了火,一跳三尺高,嘴里吼道:
“王二!勒都!鸡巴!你们姐夫舅子合伙搞我!我去告诉我家爹,拿铜炮枪打你们!”
说完这小兔崽子就往河岸上蹿,想一走了之。我一把薅住他脚脖子,把他揪下来。
“你走了我们给你赶牛哇?做你娘的美梦!”
这小子哇哇叫着要咬我,被我劈开手按在地上。他口吐白沫,杂着汉话、景颇话、傣话骂我,我用正庄京片子回骂。忽然间他不骂了,往我下体看去,脸上露出无限羡慕之情。我低头一看,我的小和尚又直立起来了。只听勒农啧啧赞美道:
“哇!想日勒都家姐哟!”
我赶紧扔下他去穿裤子。
晚上我在水泵房点起汽灯,陈清扬就会忽然到来,谈起她觉得活着很没意思,还说到她在每件事上都是清白无辜。我说她竟敢觉得自己清白无辜,这本身就是最大的罪孽。照我的看法,每个人的本性都是好吃懒做,好色贪淫,假如你克勤克俭,守身如玉,这就犯了矫饰之罪,比好吃懒做好色贪淫更可恶。这些话她好像很听得进去,但是从不附和。
那天晚上我在河边上点起汽灯,陈清扬却迟迟不至,直到九点钟以后,她才到门前来喊我:“王二,混蛋!你出来!”
我出去一看,她穿了一身白,打扮得格外整齐,但是表情不大轻松。她说道:你请我来吃鱼,做倾心之谈,鱼在哪里?我只好说,鱼还在河里。她说好吧,还剩下一个倾心之谈。就在这儿谈罢。我说进屋去谈,她说那也无妨,就进屋来坐着,看样子火气甚盛。
我过二十一岁生日那天,打算在晚上引诱陈清扬,因为陈清扬是我的朋友,而且胸部很丰满,腰很细,屁股浑圆。除此之外,她的脖子端正修长,脸也很漂亮。我想和她性交,而且认为她不应该不同意。假如她想借我的身体练开膛,我准让她开;所以我借她身体一用也没什么不可以。唯一的问题是她是个女人,女人家总有点小气。为此我要启发她,所以我开始阐明什么叫做“义气”。
在我看来,义气就是江湖好汉中那种伟大友谊。《水浒》中的豪杰们,杀人放火的事是家常便饭,可一听说及时雨的大名,立即倒身便拜。我也像那些草莽英雄,什么都不信,唯一不能违背的就是义气。只要你是我的朋友,哪怕你十恶不赦,为天地所不容,我也要站到你身边。那天晚上我把我的伟大友谊奉献给陈清扬,她大为感动,当即表示道:这友谊她接受了。不但如此,她还说要以更伟大的友谊还报我,哪怕我是个卑鄙小人也不背叛。我听她如此说,大为放心,就把底下的话也说了出来:我已经二十一岁了,男女间的事情还没体验过,真是不甘心。她听了以后就开始发愣,大概是没有思想准备。说了半天她毫无反应。我把手放到她的肩膀上去,感觉她的肌肉绷得很紧。这娘们随时可能翻了脸给我一耳光,假定如此,就证明女人不懂什么是交情。可是她没有。忽然间她哼了一声,就笑起来。还说:我真笨!这么容易就着了你的道儿!
我说:什么道儿?你说什么?
她说:我什么也没有说。
我问她我刚才说的事儿你答应不答应?她说呸,而且满面通红。我看她有点不好意思,就采取主动,动手动脚。她搡了我几把,后来说,不在这儿,咱们到山上去。我就和她一块到山上去了。
陈清扬后来说,她始终没搞明白我那个伟大友谊是真的呢,还是临时编出来骗她。但是她又说,那些话就像咒语一样让她着迷,哪怕为此丧失一切,也不懊悔。其实伟大友谊不真也不假,就如世上一切东西一样,你信它是真,它就真下去。你疑它是假,它就是假的。我的话也半真不假。但是我随时准备兑现我的话,哪怕天崩地裂也不退却。就因为这种态度,别人都不相信我。我虽然把交朋友当成终身的事业,所交到的朋友不过陈清扬等二三人而已。那天晚上我们到山上去,走到半路她说要回家一趟,要我到后山上等她。我有点怀疑她要晾我,但是我没说出来,径直走到后山上去抽烟。等了一些时间,她来了。
陈清扬说,我第一次去找她打针时,她正在伏案打瞌睡。在云南每个人都有很多时间打瞌睡,所以总是半睡半醒。我走进去时,屋子里暗了一下,因为是草顶土坯房,大多数光从门口进来。她就在那一刻醒来,抬头问我干什么。我说腰疼,她说躺下让我看看。我就一头倒下去,扑到竹板床上,几乎把床砸塌。我的腰痛得厉害,完全不能打弯。要不是这样,我也不会来找她。
陈清扬说,我很年轻时就饿纹入嘴,眼睛下面乌黑。我的身材很高,衣服很破,而且不爱说话。她给我打过针,我就走了,好像说了一声谢了,又好像没说。等到她想起可以让我证明她不是破鞋时,已经过了半分钟。她追了出来,看见我正取近路走回十四队。我从土坡上走下去,逢沟跳沟,逢坎跃坎,顺着山势下得飞快。那时正逢旱季的上午,风从山下吹来,喊我也听不见。而且我从来也不回头。我就这样走掉了。
陈清扬说,当时她想去追我,可是觉得很难追上。而且我也不一定能够证明她不是破鞋。所以她走回医务室去。后来她又改变了主意去找我,是因为所有的人都说她是破鞋,因此所有的人都是敌人。而我可能不是敌人。她不愿错过了机会,让我也变成敌人。
那天晚上我在后山上抽烟。虽然在夜里,我能看见很远的地方。因为月光很明亮,当地的空气又很干净。我还能听见远处的狗叫声。陈清扬一出十五队我就看见了,白天未必能看这么远。虽然如此,还是和白天不一样。也许是因为到处都没人。
我也说不准夜里这片山上有人没人,因为到处是银灰色的一片。假如有人打着火把行路,那就是说,希望全世界的人都知道他在那里。假如你不打火把,就如穿上了隐身衣,知道你在那里的人能看见,不知道的人不能看见。我看见陈清扬慢慢走近,怦然心动,无师自通地想到,做那事之前应该亲热一番。
陈清扬对此的反应是冷冰冰的。她的嘴唇冷冰冰,对爱抚也毫无反应。等到我毛手毛脚给她解扣子时,她把我推开,自己把衣服一件件脱下来,叠好放在一边,自己直挺挺躺在草地上。
陈清扬的裸体美极了。我赶紧脱了衣服爬过去,她又一把把我推开,递给我一个东西说:
“会用吗?要不要我教你?”
那是一个避孕套。我正在兴头上,对她这种口气只微感不快,套上之后又爬到她身上去,心慌气躁地好一阵乱弄,也没弄对。忽然她冷冰冰地说:
“喂!你知道自己在干什么吗?”
我说当然知道。能不能劳你大驾躺过来一点?我要就着亮儿研究一下你的结构。只听啪的一声巨响,好似一声耳边雷,她给我一个大耳光。我跳起来,拿了自己的衣服,拔腿就走。
-----
## 三
那天晚上我没走掉。陈清扬把我拽住,以伟大友谊的名义叫我留下来。她承认打我不对,也承认没有好好待我,但是她说我的伟大友谊是假的,还说,我把她骗出来就是想研究她的结构。我说,既然我是假的,你信我干吗。我是想研究一下她的结构,这也是在她的许可之下。假如不乐意可以早说,动手就打不够意思。后来她哈哈大笑了一阵说,她简直见不得我身上那个东西。那东西傻头傻脑,恬不知耻,见了它,她就不禁怒从心起。
我们俩吵架时,仍然是不着一丝。我的小和尚依然直挺挺,在月光下披了一身塑料,倒是闪闪发光。我听了这话不高兴,她也发现了。于是她用和解的口气说:不管怎么说,这东西丑得要命,你承不承认?
这东西好像个发怒的眼镜蛇一样立在那里,是不大好看。我说,既然你不愿意见它,那就算了。我想穿上裤子,她又说,别这样。于是我抽起烟来。等我抽完了一支烟,她抱住我。我们俩在草地上干那件事。
我过二十一岁生日以前,是一个童男子。那天晚上我引诱陈清扬和我到山上去。那一夜开头有月光,后来月亮落下去,出来一天的星星,就像早上的露水一样多。那天晚上没有风,山上静得很。我已经和陈清扬做过爱,不再是童男子了。但是我一点也不高兴。因为我干那事时,她一声也不吭,头枕双臂,若有所思地看着我,所以从始至终就是我一个人在表演。其实我也没持续多久,马上就完了。事毕我既愤怒又沮丧。
陈清扬说,她简直不敢相信这件事是真的:我居然在她面前亮出了丑恶的男性生殖器,丝毫不感到惭愧。那玩意也不感到惭愧,直挺挺地从她两腿之间插了进来。因为女孩子身上有这么个口子,男人就要使用她,这简直没有道理。以前她有个丈夫,天天对她做这件事。她一直不说话,等着他有一天自己感到惭愧,自己来解释为什么干了这些。可是他什么也没说,直到进了监狱。这话我也不爱听。所以我说:既然你不乐意,为什么要答应。她说她不愿被人看成小气鬼。我说你原本就是小气鬼。后来她说算了,别为这事吵架。她叫我晚上再来这里,我们再试一遍。也许她会喜欢。我什么也没说。早上起雾以后,我和她分了手,下山去放牛。
那天晚上我没去找她,倒进了医院。这事原委是这样:早上我到牛圈门前时,有一伙人等不及我,已经在开圈拉牛。大家都挑壮牛去犁田。有个本地小伙子,叫三闷儿,正在拉一条大白牛。我走过去,告诉他,这牛被毒蛇咬了,不能干活。他似乎没听见。我劈手把牛鼻绳夺了下来,他就朝我挥了一巴掌。我当胸推了他一把,推了他一个屁股蹲。然后很多人拥了上来,把我们拥在中间要打架。北京知青一伙,当地青年一伙,抄起了棍棒和皮带。吵了一会儿,又说不打架,让我和三闷儿摔跤。三闷儿摔不过我,就动了拳头。我一脚把三闷儿踢进了圈前的粪坑,让他沾了一身牛屎。三闷儿爬起来,抢了一把三齿要砍我,别人劝开了。
早上的事情就是这样。晚上我放牛回来,队长说我殴打贫下中农,要开我的斗争会。我说你想借机整人,我也不是好惹的。我还说要聚众打群架。队长说他没想整我,是三闷儿的娘闹得他没办法。那婆娘是个寡妇,泼得厉害。他说此地的规矩就是这样。后来他说,不开斗争会,改为帮助会,让我上前面去检讨一下。要是我还不肯,就让寡妇来找我。
会开得很乱。老乡们七嘴八舌,说知青太不像话,偷鸡摸狗还打人。知青们说放狗屁,谁偷东西,你们当场拿住了吗?老子们是来支援边疆建设,又不是充军的犯人,哪能容你们乱栽赃。我在前面也不检讨,只是骂。不提防三闷儿的娘从后面摸上来,抄起一条沉甸甸的拔秧凳,给了我后腰一下,正砸在我的旧伤上,登时我就背过去了。
我醒过来时,罗小四领了一伙人呐喊着要放火烧牛圈,还说要三闷儿的娘抵命。队长领了一帮人去制止,副队长叫人抬我上牛车去医院。卫生员说抬不得,腰杆断了,一抬就死。我说腰杆好像没断,你们快把我抬走。可是谁也不敢肯定我的腰杆是断了还是没断。所以也不敢肯定我会不会一抬就死。我就一直躺着。后来队长过来一问,就说:快摇电话把陈清扬叫下来,让她看看腰断了没有。过了不一会儿,陈清扬披头散发眼皮红肿地跑了来,劈头第一句话就是:你别怕。要是你瘫了,我照顾你一辈子。然后一检查,诊断和我自己的相同。于是我就坐上牛车,到总场医院去看病。
那天夜里陈清扬把我送到医院,一直等到腰部X光片子出来,看过认为没问题后才走。她说过一两天就来看我,可是一直没来。我住了一个星期,可以走动了,就奔回去找她。
我走进陈清扬的医务室时,身上背了很多东西,装得背篓里冒了尖。除了锅碗盆瓢,还有足够两人吃一个月的东西。她见我进来,淡淡地一笑,说你好了吗?带这些东西上哪儿?
我说要去清平洗温泉。她懒懒地往椅子上一仰说,这很好。温泉可以治旧伤。我说我不是真去洗温泉,而是到后面山上住几天。她说后面山上什么都没有,还是去洗温泉吧。
清平的温泉是山坳里一片泥坑,周围全是荒草坡。有一些病人在山坡上搭了窝棚,成年住在那里,其中得什么病的都有。我到那里不但治不好病,还可能染上麻风。而后面荒山里的低洼处沟谷纵横,疏林之中芳草,离离,我在人迹绝无的地方造上一间草房,空山无人,流水落花,住在里面可以修身养性。陈清扬听了,禁不住一笑说:那地方怎么走?也许我去看看你。我告诉她路,还画了一张示意图,自己进山去了。
我走进荒山,陈清扬没有去看我。旱季里浩浩荡荡的风刮个不停,整个草房都在晃动。陈清扬坐在椅子上听着风声,回想起以往发生的事情,对一切都起了怀疑。她很难相信自己会莫名其妙地来到这极荒凉的地方,又无端地被人称作破鞋,然后就真的搞起了破鞋。这件事真叫人难以置信。陈清扬说,有时候她走出房门,往后山上看,看到山丘中有很多小路蜿蜒通到深山里去。我对她说的话言犹在耳。她知道沿着一条路走进山去,就会找到我。这是无可怀疑的事。但是越是无可怀疑的事就越值得怀疑。很可能那条路不通到任何地方,很可能王二不在山里,很可能王二根本就不存在。
过了几天,罗小四带了几个人到医院去找我。医院里没人听说过王二,更没人知道他上哪儿去了。那时节医院里肝炎流行,没染上肝炎的病人都回家去疗养,大夫也纷纷下队去送医上门。罗小四等人回到队里,发现我的东西都不见了,就去问队长可见过王二。队长说,谁是王二?从来没听说过。罗小四说前几天你还开会斗争过他,尖嘴婆打了他一板凳,差点把他打死。这样提醒了以后,队长就更想不起来我是谁了。那时节有一个北京知青慰问团要来调查知青在下面的情况,尤其是有无被捆打逼婚等情况,因此队长更不乐意想起我来。罗小四又到十五队问陈清扬可曾见过我,还闪烁其词地暗示她和我有过不正当的关系。陈清扬则表示,她对此一无所知。
等到罗小四离开,陈清扬就开始糊涂了。看来有很多人说,王二不存在。这件事叫人困惑的原因就在这里。大家都说存在的东西一定不存在,这是因为眼前的一切都是骗局。大家都说不存在的东西一定存在,比如王二,假如他不存在,这个名字是从哪里来的?陈清扬按捺不住好奇心,终于扔下一切,上山找我来了。
我被尖嘴婆打了一板凳后晕了过去,陈清扬曾经从山上跑下来看我。当时她还忍不住哭了起来,并且当众说,如果我好不了要照顾我一辈子。结果我并没有死,连瘫都没瘫。这对我是很好的事,可是陈清扬并不喜欢。这等于当众暴露了她是破鞋。假如我死,或是瘫掉,就是应该的事,可是我在医院里只住了一个星期就跑出来。对她来说,我就是那个急匆匆从山上赶下去的背影,一个记忆中的人。她并不想和我做爱,也不想和我搞破鞋,除非有重大的原因。因此她来找我就是真正的破鞋行径。
陈清扬说,她决定上山找我时,在白大褂底下什么都没穿。她就这样走过十五队后面的那片山包。那些小山上长满了草,草下是红土。上午风从山上往平坝里吹,冷得像山上的水,下午风吹回来,带着燥热和尘土。陈清扬来找我时,乘着白色的风。风从衣服下面钻进来,流过全身,好像爱抚和嘴唇。其实她不需要我,也没必要找到我。以前人家说她是破鞋,说我是她的野汉子时,她每天都来找我。那时好像有必要。自从她当众暴露了她是破鞋,我是她的野汉子后,再没人说她是破鞋,更没人在她面前提到王二(除了罗小四)。大家对这种明火执仗的破鞋行径是如此的害怕,以致连说都不敢啦。
关于北京要来人视察知青的事,当地每个人都知道,只有我不知道。这是因为我前些日子在放牛,早出晚归,而且名声不好,谁也不告诉我,后来住了院,也没人来看我。等到我出院以后,就进了深山。在我进山之前,总共就见到了两个人,一个是陈清扬,她没有告诉我这件事。另一个是我们队长,他也没说起这件事,只叫我去温泉养病。我告诉他,我没有东西(食品、炊具等等),所以不能去温泉。他说他可以借给我。我说我借了不一定还,他说不要紧。我就向他借了不少家制的腊肉和香肠。
陈清扬不告诉我这件事是因为她不关心,她不是知青。队长不告诉我这件事,是因为他以为我已经知道了。他还以为我拿了很多吃的东西走,就不会再回来。所以罗小四问他王二到哪儿去了时,他说:王二?谁叫王二?从没听说过。对于罗小四等人来说,找到我有很大的好处,我可以证明大家在此地受到很坏的待遇,经常被打晕。对于领导来说,我不存在有很大的便利,可以说明此地没有一个知青被打晕。对于我自己来说,存在不存在没有很大的关系。假如没有人来找我,我在附近种点玉米,可以永远不出来。就因为这个原因,我对自己存不存在的事不太关心。
我在小屋里也想过自己存不存在的问题。比方说,别人说我和陈清扬搞破鞋,这就是存在的证明。用罗小四的话来说,王二和陈清扬脱了裤子干。其实他也没看见。他想象的极限就是我们脱裤子。还有陈清扬说,我从山上下来,穿着黄军装,走得飞快。我自己并不知道我走路是不回头的。因为这些事我无从想象,所以是我存在的证明。
还有我的小和尚直挺挺,这件事也不是我想出来的。我始终盼着陈清扬来看我,但陈清扬始终没有来。她来的时候,我没有盼着她来。
-----
## 四
我曾经以为陈清扬在我进山后会立即来看我,但是我错了。我等了很久,后来不再等了。我坐在小屋里,听着满山树叶哗哗响,终于到了物我两忘的境界。我听见浩浩荡荡的空气大潮从我头顶涌过,正是我灵魂里潮兴之时。正如深山里花开,龙竹笋剥剥地爆去笋壳,直翅翅地向上。到潮退时我也安息,但潮兴时要乘兴而舞。正巧这时陈清扬来到草屋门口,她看见我赤条条坐在竹板床上,阳具就如剥了皮的兔子,红通通亮晶晶足有一尺长,直立在那里,登时惊慌失措,叫了起来。
陈清扬到山里找我的事又可以简述如下:我进山后两个星期,她到山里找我。当时是下午两点钟,可是她像那些午夜淫奔的妇人一样,脱光了内衣,只穿一件白大褂,赤着脚走进山来。她就这样走过阳光下的草地,走进了一条干河沟,在河沟里走了很久。这些河沟很乱,可是她连一个弯都没转错。后来她又从河沟里出来,走进一个向阳的山洼,看见一间新搭的草房。假如没有一个王二告诉她这条路,她不可能在茫茫荒山里找到一间草房。可是她走进草房,看到王二就坐在床上,小和尚直挺挺,却吓得尖叫起来。
陈清扬后来说,她没法相信她所见到的每件事都是真的。真的事要有理由。当时她脱了衣服,坐在我的身边,看着我的小和尚,只见它的颜色就像烧伤的疤痕。这时我的草房在风里摇晃,好多阳光从房顶上漏下来,星星点点落在她身上。我伸手去触她的乳头,直到她脸上泛起红晕,乳房坚挺。忽然她从迷梦里醒来,羞得满脸通红。于是她紧紧地抱住我。
我和陈清扬是第二次做爱,第一次做爱的很多细节当时我大惑不解,后来我才明白,她对被称作破鞋一事,始终耿耿于怀。既然不能证明她不是破鞋,她就乐于成为真正的破鞋。就像那些被当场捉了奸的女人一样,被人叫上台去交待那些偷情的细节。等到那些人听到情不能持,丑态百出时,怪叫一声:把她捆起来!就有人冲上台去,用细麻绳把她五花大绑,她就这样站在人前,受尽羞辱。这些事一点也不讨厌。她也不怕被人剥得精赤条条,拴到一扇磨盘上,扔到水塘里淹死。或者像以前达官贵人家的妻妾一样,被强迫穿得整整齐齐,脸上贴上湿透的黄表纸,端坐着活活憋死。这些事都一点也不讨厌。她丝毫也不怕成为破鞋,这比被人叫做破鞋而不是破鞋好得多。她所讨厌的是使她成为破鞋那件事本身。
我和陈清扬做爱时,一只蜥蜴从墙缝里爬了进来,走走停停地经过房中间的地面。忽然它受到惊动,飞快地出去,消失在门口的阳光里。这时陈清扬的呻吟就像泛滥的洪水,在屋里漫延。我为此所惊,伏下身不动。可是她说,快,混蛋。还拧我的腿。等我“快”了以后,阵阵震颤就像从地心传来。后来她说,她觉得自己罪孽深重,早晚要遭报应。
她说自己要遭报应时,一道红晕正从她的胸口褪去。那时我们的事情还没完。但她的口气是说,她只会为在此之前的事遭报应。忽然之间我从头顶到尾骨一齐收紧,开始极其猛烈的射精。这事与她无关,大概只有我会为此遭报应。
后来陈清扬告诉我,罗小四到处找我。他到医院找我时,医院说我不存在。他找队长问我时,队长也说我不存在。最后他来找陈清扬,陈清扬说,既然大家都说他不存在,大概他就是不存在吧,我也没有意见。罗小四听了这话,禁不住哭了起来。
我听了这话,觉得很奇怪。我不应该因为尖嘴婆打了我一下而存在。也不应该因为她打了我一下而不存在。事实上,我的存在乃是不争的事实。我就为这一点钻了牛角尖。为了验证这不争的事实,慰问团来的那一天,我从山上奔了下去,来到了座谈会的会场上。散会以后,队长说,你这个样子不像有病。还是回来喂猪吧。他还组织人力,要捉我和陈清扬的奸。当然,要捉我不容易,我的腿非常快。谁也休想跟踪我。但是也给我添了很多麻烦。到了这个时候我才悟到,犯不着向人证明我存在。
我在队里喂猪时,每天要挑很多水。这个活计很累,连偷懒都不可能,因为猪吃不饱会叫唤。我还要切很多猪菜,劈很多柴。喂这些猪原来要三个妇女,现在要我一个人干。我发现我不能顶三个妇女,尤其是腰疼时。这时候我真想证明我不存在。
晚上我和陈清扬在小屋里做爱。那时我对此事充满了敬业精神,对每次亲吻和爱抚都贯注了极大的热情。无论是经典的传教士式,后进式,侧进式,女上位,我都能一丝不苟地完成。陈清扬对此极为满意。我也极为满意。在这种时候,我又觉得用不着去证明自己是存在的。从这些体会里我得到一个结论,就是永远别让别人注意你。北京人说,不怕贼偷,就怕贼惦记。你千万别让人惦记上。
过了一些时候,我们队的知青全调走了。男的调到糖厂当工人,女的到农中去当老师。单把我留下来喂猪,据说是因为我还没有改造好。陈清扬说,我叫人惦记上了。这个人大概就是农场的军代表。她还说,军代表不是个好东西。原来她在医院工作,军代表要调戏她,被她打了个大嘴巴。然后她就被发到十五队当队医。十五队的水是苦的,也没有菜吃,呆久了也觉得没有啥,但是当初调她来,分明有修理一下的意思。她还说,我准会被修理到半死。我说过,他能把我怎么样?急了老子跑他娘。后来的事都是由此而起。
那天早上天色微明,我从山上下来,到猪场喂猪。经过井台时,看见了军代表,他正在刷牙。他把牙刷从嘴里掏出来,满嘴白沫地和我讲话,我觉得很讨厌,就一声不吭地走掉了。过了一会,他跑到猪场里,把我大骂了一顿,说你怎么敢走了。我听了这些话,一声不吭。就是他说我装哑巴,我也一声不吭。然后我又走开了。
军代表到我们队来蹲点,蹲下来就不走了。据他说,要不能从王二嘴里掏出话来,死也不甘心。这件事有两种可能的原因,一是他下来视察,遇见了我对他装聋作哑,因而大怒,不走了。二是他不是下来视察,而是听说陈清扬和我有了一腿,特地来找我的麻烦。不管他为何而来,反正我是一声也不吭,这叫他很没办法。
军代表找我谈话,要我写交待材料,他还说,我搞破鞋群众很气愤,如果我不交待,就发动群众来对付我。他还说,我的行为够上了坏分子,应该受到专政。我可以辩解说,我没搞破鞋。谁能证明我搞了破鞋?但我只是看着他。像野猪一样看他,像发傻一样看他,像公猫看母猫一样看他。把他看到没了脾气,就让我走了。
最后他也没从我嘴里套出话来。他甚至搞不清我是不是哑巴。别人说我不是哑巴,他始终不敢相信,因为他从来没听我说过一句话。他到今天想起我来,还是搞不清我是不是哑巴。想起这一点,我就万分的高兴。
-----
## 五
最后我们被关了起来,写了很长时间的交待材料。起初我是这么写的:我和陈清扬有不正当的关系。这就是全部。上面说,这样写太简单。叫我重写。后来我写,我和陈清扬有不正当关系,我干了她很多回,她也乐意让我干。上面说,这样写缺少细节。后来又加上了这样的细节:我们俩第四十次非法性交。地点是我在山上偷盖的草房。那天不是阴历十五就是阴历十六,反正月亮很亮。陈清扬坐在竹床上,月光从门里照进来,照在她身上。我站在地上,她用腿圈着我的腰。我们还聊了几句,我说她的乳房不但圆,而且长得很端正,跻窝不但圆,而且很浅。这些都很好。她说是吗,我自己不知道。后来月光移走了,我点了一根烟,抽到一半她拿走了,接着吸了几口。她还捏过我的鼻子,因为本地有一种说法,说童男的鼻子很硬,而纵欲过度行将死去的人鼻子很软。这些时候她懒懒地躺在床上,倚着竹板墙。其他的时间她像澳大利亚考拉熊一样抱住我,往我脸上吹热气。最后月亮从门对面的窗子里照进来,这时我和她分开。但是我写这些材料,不是给军代表看。他那时早就不是军代表了,而且已经复员回家去了。他是不是代表,反正犯了我们这种错误,总是要写交待材料。
我后来和我们学校人事科长关系不错。他说当人事干部最大的好处就是可以看到别人写的交待材料。我想他说的包括了我写的交待材料。我以为我的交待材料最有文采。因为我写这些材料时住在招待所,没有别的事可干,就像专业作家一样。
我逃跑是晚上的事。那天上午,我找司务长请假,要到井坎镇买牙膏。我归司务长领导,他还有监视我的任务。他应该随时随地看住我,可是天一黑我就不见了。早上我带给他很多酸琶果,都是好的。平原上的酸琶果都不能吃,因为里面是一窝蚂蚁,只有山里的酸琶果才没蚂蚁。司务长说,他个人和我关系不坏,而且军代表不在。他可以准我去买牙膏。但是司务长又说,军代表随时会回来。要是他回来时我不在,司务长也不能包庇我。我从队里出去,爬上十五队的后山,拿个镜片晃陈清扬的后窗。过一会儿,她到山上来,说是头两天人家把她盯得特紧,跑不出来。而这几天她又来月经。她说这没关系,干吧,我说那不行。分手时她硬要给我二百块钱。起初我不要,后来还是收下了。
后来陈清扬告诉我,头两天人家没有把她盯得特紧,后来她也没有来月经。事实上,十五队的人根本就不管她。那里的人习惯于把一切不是破鞋的人说成破鞋,而对真的破鞋放任自流。她之所以不肯上山来,让我空等了好几天,是因为对此事感到厌倦。她总要等有了好心情才肯性交,不是只要性交就有好心情。当然这样做了以后,她也不无内疚之心。所以她给我二百块钱。我想既然她有二百块钱花不掉,我就替她花。所以我拿了那些钱到井坎镇上,买了一条双筒猎枪。
后来我写交待材料,双筒猎枪也是一个主题。人家怀疑我拿了它要打死谁。其实要打死人,用二百块钱的双筒猎枪和四十块钱的铜炮枪打都一样。那种枪是用来在水边打野鸭子的,在山里一点不实用,而且像死人一样沉。那天我到井坎街上时,已经是下午时分,又不是赶街的日子,所以只有一条空空落落的土路和几间空空落落的国营商店。商店里有一个售货员在打瞌睡,还有很多苍蝇在飞。货架上写着“吕过吕乎”,放着铝锅铝壶。我和那个胶东籍的售货员聊了一会天,她叫我到库房里看了看。在那儿我看见那条上海出的猎枪,就不顾它已经放了两年没卖出去的事实,把它买下了。傍晚时我拿它到小河边试放,打死了一只鹭鸶。这时军代表从场部回来,看见我手里有枪,很吃了一惊。他唠叨说,这件事很不对,不能什么人手里都有枪。应该和队里说一下,把王二的枪没收掉。我听了这话,几乎要朝他肚子上打一枪。如果打了的话,恐怕会把他打死。那样多半我也活不到现在了。
那天下午我从井坎回队的路上,涉水从田里经过,曾经在稻棵里站了一会。我看见很多蚂蟥像鱼一样游出来,叮上了我的腿。那时我光着膀子,衣服包了很多红糖馅的包子(镇上饭馆只卖这一种食品),双手提包子,背上还背了枪,很累赘。所以我也没管那些蚂蟥。到了岸上我才把它们一条条揪下来用火烧死。烧得它们一条条发软起泡。忽然间我感到很烦很累,不像二十一岁的人。我想,这样下去很快就会老了。
后来我遇上了勒都。他告诉我说,他们把那条河汊里的鱼都捉到手了。我那一份已经晒成了鱼干,在他姐姐手里。他姐姐叫我去。他姐姐和我也很熟,是个微黑俏丽的小姑娘。我说一时去不了。我把那一包包子都给了勒都,叫他给我到十五队送个信,告诉陈清扬,我用她给我的钱买了一条枪。勒都去了十五队,把这话告诉陈清扬,她听了很害怕,觉得我会把军代表打死。这种想法也不是没有道理,傍晚时我就想打军代表一枪。
傍晚时分我在河边打鹭鸶,碰上了军代表。像往常一样,我一声不吭,他喋喋不休。我很愤怒,因为已经有半个多月了,他一直对我喋喋不休,说着同样的话:我很坏,需要思想改造。对我一刻也不能放松。这样的话我听了一辈子,从来没有像那天晚上那么火。后来他又说,今天他有一个特大好消息,要向大家公布。但是他又不说是什么,只说我和我的“臭婊子”陈清扬今后的日子会很不好过。我听了这话格外恼火,想把他就地掐死,又想听他说出是什么好消息以后再下手。他却不说,一直卖着关子,只说些没要紧的话,到了队里以后才说,晚上你来听会吧,会上我会宣布的。
晚上我没去听会,在屋里收拾东西,准备逃上山去。我想一定发生了什么大事,以致军代表有了好办法来收拾我和陈清扬,至于是什么事我没想出来,那年头的事很难猜。我甚至想到可能中国已经复辟了帝制,军代表已经当上了此地的土司。他可以把我槌骟掉,再把陈清扬拉去当妃子。等我收拾好要出门,才知道没有那么严重。因为会场上喊口号,我在屋里也能听见。原来是此地将从国营农场改做军垦兵团。军代表可能要当个团长。不管怎么说,他不能把我阉掉,也不能把陈清扬拉走。我犹豫了几分钟,还是把装好的东西背上了肩,还用砍刀把屋里的一切都砍坏,并且用木炭在墙上写了:“×××(军代表名),操你妈。”然后出了门,上山去了。
我从十四队逃跑的事就是这样。这些经过我也在交待材料里写了。概括地说,是这样的:我和军代表有私仇,这私仇有两个方面:一是我在慰问团面前说出了曾经被打晕的事,叫军代表很没面子;二是争风吃醋,所以他一直修理我。当他要当团长时,我感到不堪忍受,逃到山上去了。我到现在还以为这是我逃上山的原因。但是人家说,军代表根本就没当上团长,我逃跑的理由不能成立。所以人家说,这样的交待材料不可信。可信的材料应该是,我和陈清扬有私情。俗话说,色胆包天,我们什么事都能干出来。这话也有一点道理,可是我从队里逃出来时,原本不打算找陈清扬,打算一走算了。走到山边上才想到,不管怎样,陈是我的一个朋友,该去告别。谁知陈清扬说,她要和我一起逃跑。她还说,假如这种事她不加入,那伟大友谊岂不是喂了狗。于是她匆匆忙忙收拾了一些东西跟我走了。假如没有她和她收拾的东西,我一定会病死在山上。那些东西里有很多治疟疾的药,还有大量的大号避孕套。
我和陈清扬逃上山以后,农场很惊慌了一阵。他们以为我们跑到缅甸去了。这件事传出去对谁都没好处,所以就没向上报告,只是在农场内部通缉王二和陈清扬。我们的样子很好认,还带了一条别人没有的双筒猎枪,很容易被人发现,可是一直没人找到我们。直到半年以后,我们自己回到农场来,各回各的队,又过了一个多月,才被人保组叫去写交待。也是我们流年不利,碰上了一个运动,被人揭发了出来。
-----
## 六
人保组的房子在场部的路口上,是一座孤零零的土坯房。你从很远的地方就能看见,因为它粉刷得很白,还因为它在高岗上。大家到场部赶街,老远就看见那间房子。它周围是一片剑麻地,剑麻总是暗绿色,剑麻下的土总是鲜红色。我在那里交待问题,把什么都交待了。我们上了山,先在十五队后山上种玉米,那里土不好,玉米有一半没出苗。我们就离开,昼伏夜行,找别的地方定居。最后想起山上有个废水碾,那里有很大一片丢荒了的好地。水碾里住了一个麻风寨跑出来的刘大爹。谁也不到那里去,只有陈清扬有一回想起自己是大夫,去看过一回。我们最后去了刘大爹那里,住在水碾背后的山洼里,陈清扬给刘大爹看病,我给刘大爹种地。过了一些时候,我到清平赶街,遇上了同学。他们说,军代表调走了,没人记着我们的事。我们就回来。整个事情就是这样的。
我在人保组里呆了很长时间。有一段时间,气氛还好,人家说,问题清楚了,你准备写材料。后来忽然又严重起来,怀疑我们去了境外,勾结了敌对势力,领了任务回来。于是他们把陈清扬也叫到人保组,严加审讯。问她时,我往窗外看。天上有很多云。
人家叫我交待偷越国境的事。其实这件事上,我也不是清白无辜。我确实去过境外。我曾经打扮成老傣的模样,到对面赶过街。我在那里买了些火柴和盐。但是这没有必要说出来。没必要说的话就不说。
后来我带人保组的人到我们住过的地方去勘査。我在十五队后山上搭的小草房已经漏了顶,玉米地招来很多鸟。草房后面有很多用过的避孕套,这是我们在此住过的铁证。当地人不喜欢避孕套,说那东西阻断了阴阳交流,会使人一天天弱下去。其实当地那种避孕套,比我后来用过的任何一种都好。那是百分之百的天然橡胶。
后来我再不肯带他们去那些地方看,反正我说我没去国外,他们不信。带他们去看了,他们还是不信。没必要做的事就别做。我整天一声不吭。陈清扬也一声不吭。问案的人开头还在问,后来也懒得吭声。街子天里有好多老傣、老景颇背着新鲜的水果蔬菜走过,问案的人也越来越少。最后只剩了一个人。他也想去赶街,可是不到放我们回去的时候,让我们呆在这里无人看管,又不合规定。他就到门口去喊人,叫过路的大嫂站住。但是人家经常不肯站住,而是加快了脚步。见到这种情况,我们就笑起来。
人保组的同志终于叫住了一个大嫂。陈清扬站起来,整理好头发,把衬衣领子折起来,然后背过手去。那位大嫂就把她捆起来,先捆紧双手,再把绳子在脖子和胳膊上扣住。那大嫂抱歉地说,捆人我不会呀。人保组的同志说,可以了。然后他再把我捆起来,让我们在两张椅子上背靠背坐好,用绳子拦腰捆上一道,然后他锁上门,也去赶集。过了好半天他才回来,到办公桌里拿东西,问道:要不要上厕所?时间还早,一会回来放你们。然后又出去。
到他最后来放开我们的时候,陈清扬活动一下手指,整理好头发,把身上的灰土掸干净,我们俩回招待所去。我们每天都到人保组去,每到街子天就被捆起来,除此之外,有时还和别人一道到各队去挨斗。他们还一再威胁说,要对我们采取其它专政手段一我们受审查的事就是这样的。
后来人家又不怀疑我们去了国外,开始对她比较客气,经常叫她到医院去,给参谋长看前列腺炎。那时我们农场来了一大批军队下来的老干部,很多人有前列腺炎。经过调查,发现整个农场只有陈清扬知道人身上还有前列腺。人保组的同志说,要我们交待男女关系问题。我说,你怎知我们有男女关系问题?你看见了吗?他们说,那你就交待投机倒把问题。我又说,你怎知我有投机倒把问题?他们说,那你还是交待投敌叛变的问题。反正要交待问题,具体交待什么,你们自己去商量。要是什么都不交待,就不放你。我和陈清扬商量以后,决定交待男女关系问题。她说,做了的事就不怕交待。
于是我就像作家一样写起交待材料来。首先交待的就是逃跑上山那天晚上的事。写了好几遍,终于写出陈清扬像考拉熊。她承认她那天心情非常激动,确实像考拉熊。因为她终于有了机会,来实践她的伟大友谊。于是她腿圈住我的腰,手抓住我的肩膀,把我想象成一棵大树,几次想爬上去。
后来我又见到陈清扬,已经到了九十年代。她说她离了婚和女儿住在上海,到北京出差。到了北京就想到,王二在这里,也许能见到。结果真的在龙潭湖庙会上见到了我。我还是老样子,饿纹入嘴,眼窝下乌青,穿过了时的棉袄,蹲在地上吃不登大雅之堂的卤煮火烧。惟一和过去不同的是手上被硝酸染得焦黄。
陈清扬的样子变了不少,她穿着薄呢子大衣,花格呢裙子,高跟皮靴,戴金丝眼镜,像个公司的公关职员,她不叫我,我绝不敢认。于是我想到每个人都有自己的本质,放到合适的地方就大放光彩。我的本质是流氓土匪一类,现在做个城里的市民,学校的教员,就很不像样。
陈清扬说,她女儿已经上了大二,最近知道了我们的事,很想见我。这事的起因是这样的:她们医院想提拔她,发现她档案里还有一堆东西。领导上讨论之后,认为是“文革”时整人的材料,应予撤销。于是派人到云南外调,花了一万元差旅费,终于把它拿了出来。因为是本人写的,交还本人。她把它拿回家去放着,被女儿看见了。该女儿说,好哇,你们原来是这么造的我!
其实我和她女儿没有任何关系。她女儿产生时,我已经离开云南了。陈清扬也是这么解释的,可是那女孩说,我可以把精液放到试管里,寄到云南让陈清扬人工授精。用她原话来说就是:你们两个混蛋什么干不出来。
我们逃进山里的第一个夜晚,陈清扬兴奋得很。天明时我睡着了,她又把我叫起来,那时节大雾正从墙缝里流进来,她让我再干那件事,别戴那劳什子。她要给我生一窝小崽子,过几年就耷拉到这里。同时她揪住乳头往下拉,以示耷拉之状。我觉得耷拉不好看,就说,咱们还是想想办法,别叫它耷拉。所以我还是戴着那劳什子。以后她对这件事就失去了兴趣。
后来我再见陈清扬时,问道,怎么样,耷拉了吧?她说可不是,耷拉得一塌糊涂。你想不想看看有多耷拉。后来我看见了,并没有一塌糊涂。不过她说,早晚要一塌糊涂,没有别的出路。
我写了这篇交待材料交上去,领导上很欣赏。有个大头儿,不是团参谋长就是政委,接见了我们,说我们的态度很好。领导上相信我们没有投敌叛变。今后主要的任务就是交待男女关系问题。假如交待得好,就让我们结婚。但是我们并不想结婚。后来又说,交待得好,就让我调回内地。陈清扬也可以调上级医院。所以我在招待所写了一个多月交待材料,除了出公差,没人打搅,我用复写纸写,正本是我的,副本是她的。我们有一模一样的交待材料。
后来人保组的同志找我商量,说是要开个大的批斗会。所有在人保组受过审查的人都要参加,包括投机倒把分子、贪污犯,以及各种坏人。我们本该属于同一类,可是团领导说了,我们年轻,交待问题的态度好,所以又可以不参加。但是有人攀我们,说都受审査,他们为什么不参加。人保组也难办。所以我们必须参加。最后的决定是来做工作,动员我们参加。据说受受批斗,思想上有了震动,以后可以少犯错误。既然有这样的好处,为什么不参加?到了开会的日子,场部和附近生产队来了好几千人,我们和好多别的人站到台上去。等了好半天,听了好几篇批判稿,才轮到我们王陈二犯。原来我们的问题是思想淫乱,作风腐败,为了逃避思想改造,逃到山里去。后来在党的政策感召下,下山弃暗投明。听了这样的评价,我们心情激动,和大家一起振臂高呼:打倒王二!打倒陈清扬!
斗过这一台,我们就算没事了,但是还得写交待,因为团领导要看。
在十五队后山上,陈清扬有一回很冲动,要给我生一群小崽子,我没要。后来我想,生生也不妨,再跟她说,她却不肯生了。而且她总是理解成我要干那件事。她说,要干就干,没什么关系。我想纯粹为我,这样太自私了,所以就很少干。何况开荒很累,没力气干。我所能交待的事就是在地头休息时摸她的乳房。
旱季里开荒时,到处是热风,身上没有汗,可是肌肉干疼。最热时,只能躺在树下睡觉。枕着竹筒,睡在棕皮蓑衣上,我奇怪为什么没人让我交待蓑衣的事。那是农场的劳保用品,非常贵。我带进山两件,一件是我的,一件是从别人门口顺手拿来的。一件也没拿回来。一直到我离开云南,也没人让我交还蓑衣。
我们在地头休息时,陈清扬拿斗笠盖住脸,敞开衬衣的领口,马上就睡着了。我把手伸进去,有很优美的浑圆的感觉。后来我把扣子又解开几个,看见她的皮肤是浅红色。虽然她总穿着衣服干活,可是阳光透过了薄薄的布料。至于我,总是光膀子,已经黑得像鬼一样。
陈清扬的乳房是很结实的两块,躺着的时候给人这样的感觉。但是其它地方很纤细。过了二十多年,大模样没怎么变,只是乳头变得有点大,有点黑。她说这是女儿作的孽。那孩子刚出世,像个粉红色的小猪,闭着眼一口叼住她那个地方狠命地吃,一直把她吃成个老太太,自己却长成个漂亮大姑娘,和她当年一样。
年纪大了,陈清扬变得有点敏感。我和她在饭店里重温旧情,说到这类话题,她就有恐慌之感。当年不是这样。那时候在交待材料里写到她的乳房,我还有点犹豫。她说,就这么写。我说,这样你就暴露了。她说,暴露就暴露,我不怕!她还说是自然长成这样,又不是她捣了鬼。至于别人听说了有什么想法,不是她的问题。
过了这么多年我才发现,陈清扬是我的前妻哩。交待完问题人家叫我们结婚。我觉得没什么必要了。可是领导上说,不结婚影响太坏,非叫去登记不可。上午登记结婚,下午离婚。我以为不算呢。乱秧秧的,人家忘了把发的结婚证要回去。结果陈清扬留了一张。我们拿这二十年前发的破纸头登记了一间双人房。要是没有这东西,就不许住在一间房子里。二十年前不这样。二十年前他们让我们住在一间房子里写交待材料,当时也没这个东西。
我写了我们住在后山上的事。团领导要人保组的人带话说,枝节问题不要讲太多,交待下一个案子吧。听了这话,我发了犟驴脾气:妈妈的,这是案子吗?陈清扬开导我说:这世界上有多少人,每天要干多少这种事,又有几个有资格成为案子。我说其实这都是案子,只不过领导上查不过来。她说既然如此,你就交待罢。所以我交待道:那天夜里,我们离开了后山,向作案现场进发。
-----
## 七
我后来又见到陈清扬,和她在饭店里登记了房间,然后一起到房间里去,我伸手帮她脱下大衣。陈清扬说,王二变得文明了。这说明我已经变了很多。以前我不但相貌凶恶,行为也很凶恶。
我和陈清扬在饭店里又作了一回案。那里暖气烧得很暖,还装着茶色玻璃。我坐在沙发上,她坐在床上,聊了一会儿天。逐渐有了犯罪的气氛。我说,不是让我看有多耷拉吗,我看看。她就站起来,脱了外衣,里面穿着大花的衬衫。然后她又坐下去,说,还早一点。过一会服务员来送开水。他们有钥匙,连门都不敲就进来了。我问她,碰上了人家怎么说,她说,她没被碰上过。但是听说人家会把门一摔,在外面说:真他妈的讨厌!
我和陈清扬逃进山以前,有一次我在猪场煮猪食。那时我要烧火,要把猪菜切碎(所谓猪菜,是番薯藤、水葫芦一类东西),要往锅里加糠添水。我同时做着好几样事情。而军代表却在一边喋喋不休,说我是如何之坏。他还让我去告诉我的“臭婊子”陈清扬,她是如何之坏。忽然间我暴怒起来,抡起长刀,照着梁上挂的盛南瓜子的葫芦劈去,把它劈成两半。军代表吓得一步跳出房去。如果他还要继续数落我,我就要砍他脑袋了。我是那样凶恶,因为我不说话。
后来在人保组,我也不大说话,包括人家捆我的时候。所以我的手经常被捆得乌青。陈清扬经常说话。她说:大嫂,捆疼了,或者:大嫂,给我拿手绢垫一垫。我头发上系了一块手绢。她处处与人合作,苦头吃得少。我们处处都不一样。
陈清扬说,以前我不够文明。在人保组里,人家给我们松了绑。那条绳子在她的衬衣上留下了很多道痕迹。这是因为那绳子平时放在烧火的棚子里,沾上了锅灰和柴草末。她用不灵活的手把痕迹掸掉,只掸了前面,掸不了后面。等到她想叫我来掸时,我已经一步跨出门去。等到她追出门去,我已经走了很远。我走路很快,而且从来不回头看。就因为这些原因,她根本就不爱我,也说不上喜欢。
照领导定的性,我们在后山上干的事,除了她像考拉那次之外,都不算案子。像我们在开荒时干的事,只能算枝节问题。所以我们没有继续交待下去。其实还有别的事。当时热风正烈,陈清扬头枕双臂睡得很熟。我把她的衣襟完全解开了。这样她袒露出上身,好像是故意的一样。天又蓝又亮,以至阴影里都是蓝黝黝的光。忽然间我心里一动,在她红彤彤的身体上俯身下去。我都忘了自己干了些什么了。我把这事说了出来,以为陈清扬一定不记得。可是她说:“记得记得!那会儿我醒了。你在我肚脐上亲了一下吧?好危险,差一点爱上你陈清扬说,当时她刚好醒来,看见我那颗乱蓬蓬的头正在她肚子上,然后肚脐上轻柔的一触。那一刻她也不能自持。但是她还是假装睡着,看我还要干什么。可是我什么都没干,抬起头来往四下看看,就走开了。”
我写的交待材料里说,那天夜里,我们离开后山,向作案现场进发,背上背了很多坛坛罐罐,计划是到南边山里定居。那边土地肥沃,公路两边就是一人深的草。不像十五队后山,草只有半尺高。那天夜里有月亮,我们还走了一段公路,所以到天明将起雾时,已经走了二十公里,上了南面的山。具体地说,到了章风寨南面的草地上,再走就是森林。我们在一棵大青树下露营,拣了两块干牛粪生了一堆火,在地上铺了一块塑料布。然后脱了一切衣服(衣服已经湿了),搂在一起,裹上三条毯子,滚成一个球,就睡着了。睡了一个小时就被冻醒。三重毯子都湿透了,牛粪火也灭了。树上的水滴像倾盆大雨往下掉。空气里飘着的水点有绿豆大小。那是在一月里,旱季最冷的几天。山的阴面就有这么潮。
陈清扬说,她醒时,听见我在她耳边打机关枪。上牙碰下牙,一秒钟不只一下。而且我已经有了热度。我一感冒就不容易好,必须打针。她就爬起来说,不行,这样两个人都要病。快干那事。我不肯动,说道:忍忍吧。一会儿就出太阳。后来又说:你看我干得了吗?案发前的情况就是这样的。
案发时的情形是这样:陈清扬骑在我身上,一起一落,她背后的天上是白茫茫的雾气。这时好像不那么冷了,四下里传来牛铃声。这地方的老傣不关牛,天一亮水牛就自己跑出来。那些牛身上拴着木制的铃铛,走起来发出闷闷的响声。一个庞然大物骤然出现在我们身边,耳边的刚毛上挂着水珠。那是一条白水牛,它侧过头来,用一只眼睛看我们。
白水牛的角可以做刀把,晶莹透明很好看。可是质脆容易裂。我有一把匕首,也是白牛角把,却一点不裂,很难得。刃的材料也好,可是被人保组收走了。后来没事了,找他们要,却说找不到了。还有我的猎枪,也不肯还我。人保组的老郭死乞白咧地说要买,可是只肯出五十块钱,最后连枪带刀,我一样也没要回来。
我和陈清扬在饭店里作案之前聊了好半天。最后她把衬衣也脱下来,还穿着裙子和皮靴。我走过去坐在她身边,把她的头发撩了起来。她的头发有不少白的了。
陈清扬烫了头。她说,以前她的头发好,舍不得烫。现在没关系了。她现在当了副院长,非常忙,也不能每天洗头。除此之外,眼角脖子下有不少皱纹。她说,女儿建议她去做整容手术。但是她没时间做。
后来她说,好啦,看吧。就去解乳罩。我想帮她一把,也没帮上。扣在前面,我把手伸到后面去了。她说看来你没学坏,就转过身来让我看。我仔细看了一阵,提了一点意见。不知为什么,她有点脸红,说,好啦,看也看过了。还要干什么?就要把乳罩戴上。我说,别忙,就这样吧。她说,怎么,还要研究我的结构?我说,那当然。现在不着急,再聊一会。她的脸更红了,说道:王二,你一辈子学不了好,永远是个混蛋。
我在人保组,罗小四来看我,扒窗户一看,我被捆得像粽子一样。他以为案情严重,我会被枪毙掉,把一盒烟从窗里扔进来,说道:二哥,哥们儿一点意思。然后哭了。罗小四感情丰富,很容易哭。我让他点着了烟从窗口递进来,他照办了,差点肩关节脱臼才递到我嘴上。然后他问我还有什么事要办,我说没有。我还说,你别招一大群人来看我。他也照办了。他走后,又有一帮孩子爬上窗台看,正看见我被烟熏得睁一眼闭一眼,样子非常难看。打头的一个不禁说道:耍流氓。我说,你爸你妈才耍流氓。他们不流氓能有你?那孩子抓了些泥巴扔我。等把我放开,我就去找他爸,说道:今天我在人保组,被人像捆猪一样捆上。令郎人小志大,趁那时朝我扔泥巴。那人一听,揪住他儿子就揍。我在一边看完了才走。陈清扬听说这事,就有这种评价:王二,你是个混蛋。
其实我并非永远是混蛋。我现在有家有口,已经学了不少好。抽完了那根烟,我把她抱过来,很熟练地在她胸前爱抚一番,然后就想脱她的裙子。她说:别忙,再齡儿。你给我絲細。我点了一支烟,抽着了给她。
陈清扬说,在章风山她骑在我身上一上一下,极目四野,都是灰蒙蒙的水雾。忽然间觉得非常寂寞,非常孤独。虽然我的一部分在她身体里摩擦,她还是非常寂寞,非常孤独。后来我活过来了,说道:换换,你看我的。我就翻到上面去。她说,那一回你比哪回都混蛋。
陈清扬说,那回我比哪回都混蛋,是指我忽然发现她的脚很小巧好看。因此我说,老陈,我准备当个拜脚狂。然后我把她两腿捧起来,吻她的脚心。陈清扬平躺在草地上,两手摊开,抓着草。忽然她一晃头,用头发盖住了脸,然后哼了一声。
我在交待材料里写道,那时我放开她的腿,把她脸上的头发抚开。陈清扬猛烈地挣扎,流着眼泪,但是没有动手。她脸上有两点很不健康的红晕。后来她不挣扎了,对我说,混蛋,你要把我怎么办。我说,怎么了?她又笑,说道:不怎么。接着来。所以我又捧起她的双腿。她就那么躺着不动,双手平摊,牙咬着下唇,一声不响。如果我多看她一眼,她就笑笑。我记得她脸特别白,头发特别黑,整个情况就是这样的。
陈清扬说,那一回她躺在冷雨里,忽然觉得每一个毛孔都进了冷雨。她感到悲从中来,不可断绝。忽然间一股巨大的快感劈进来。冷雾,雨水,都沁进了她的身体。那时节她很想死去。她不能忍耐,想叫出来,但是看见了我她又不想叫出来。世界上还没有一个男人能叫她肯当着他的面叫出来。她和任何人都格格不入。
陈清扬后来和我说,每回和我做爱都深受折磨。在内心深处她很想叫出来,想抱住我狂吻,但是她不乐意。她不想爱别人,任何人都不爱;尽管如此,我吻她脚心时,一股辛辣的感觉还是钻到她心里来。
我和陈清扬在章风山上做爱,有一只老水牛在一边看。后来它哞了一声跑开了,只剩我们两人。过了很长时间,天渐渐亮了。雾从天顶消散。陈清扬的身体沾了露水,闪起光来。我把她放开,站起来,看见离寨子很近,就说:走。于是离开了那个地方,再没回去过。
-----
## 八
我在交待材料里说,我和陈清扬在刘大爹后山上作案无数。这是因为刘大爹的地是熟地,开起来不那么费力。生活也安定,所以温饱生淫欲。那片山上没人,刘大爹躺在床上要死了。山上非雾即雨,陈清扬腰上束着我的板带,上面挂着刀子。脚上穿高统雨靴,除此之外不着一丝。
陈清扬后来说,她一辈子只交了我一个朋友。她说,这一切都是因为我在河边的小屋里谈到伟大友谊。人活着总要做几件事情,这就是其中之一。以后她就没和任何人有过交情。同样的事做多了没意思。
我对此早有预感。所以我向她要求此事时就说:老兄,咱们敦敦伟大友谊如何?人家夫妇敦伦,我们无伦可言,只好敦友谊。她说好。怎么敦?正着敦反着敦?我说反着敦。那时正在地头上。因为是反着敦,就把两件蓑衣铺在地上,她趴在上面,像一匹马,说道:你最好快一点,刘大爹该打针了。我把这些事写进了交待材料,领导上让我交待:
1.谁是“郭伦”;
2.什么叫“郭郭”伟大友谊;
3.什么叫正着郭,什么叫反着郭。
把这些都说清以后,领导上又叫我以后少掉文,是什么问题就交待什么问题。
在山上敦伟大友谊时,嘴里喷出白气。天不那么凉,可是很湿,抓过一把能拧出水来。就在蓑衣旁边,蚯蚓在爬。那片地真肥。后来玉米还没熟透,我们就把它放在捣臼里捣,这是山上老景颇的做法。做出的玉米耙耙很不坏。在冷水里放着,好多天不坏。
陈清扬趴在冷雨里,乳房摸起来像冷苹果。她浑身的皮肤绷紧,好像抛过光的大理石。后来我把小和尚拔出来,把精液射到地里,她在一边看着,面带惊恐之状。我告诉她:这样地会更肥。她说:我知道。后来又说:地里会不会长出小王二来——这像个大夫说的话吗?
雨季过去后,我们化装成老傣,到清平赶街。后来的事我已经写过,我在清平遇上了同学,虽然化了装,人家还是一眼就认出我来,我的个子太高,装不矮。人家对我说:二哥,你跑哪儿去了。我说:我不会讲汉话哟!虽然尽力加上一点怪腔,还是京片子。一句就露馅了。
回到农场是她的主意。我自己既然上了山,就不准备下去。她和我上山,是为了伟大友谊。我也不能不陪她下去。其实我们随时可以逃走,但她不乐意。她说现在的生活很有趣。
陈清扬后来说,在山上她也觉得很有趣。漫山冷雾时,腰上别着刀子,足蹬高统雨靴,走到雨丝里去。但是同样的事做多了就不再有趣。所以她还想下山,忍受人世的摧残。
我和陈清扬在饭店里重温伟大友谊,说到那回从山上下来,走到岔路口上。那地方有四条岔路,各通一方。东西南北没有关系,一条通到国外,是未知之地;一条通到内地;一条通到农场;一条是我们来的路。那条路还通到户撒。那里有很多阿伧铁匠,那些人世世代代当铁匠。我虽然不是世世代代,但我也能当铁匠。我和那些人熟得很,他们都佩服我的技术。阿伧族的女人都很漂亮,身上挂了很多铜箍和银钱。陈清扬对那种打扮十分神往,她很想到山上去当个阿伧。那时雨季刚过,云从四面八方升起来。天顶上闪过一缕缕阳光。我们有各种选择,可以到各方向去。所以我在路口上站了很久。后来我回内地时,站在公路上等汽车,也有两种选择,可以等下去,也可以回农场去。当我沿着一条路走下去的时候,心里总想着另一条路上的事。这种时候我心里很乱。
陈清扬说过,我天资中等,手很巧,人特别浑。这都是有所指的。说我天资中等,我不大同意。说我特别浑,事实俱在,不容抵赖。至于说我手巧,可能是自己身上体会出来的。我的手的确很巧,不光表现在摸女人方面。手掌不大,手指特长,可以做任何精细的工作。山上那些阿伧铁匠打刀刃比我好,可是要比在刀上刻花纹,没有任何人能比得上。所以起码有二十个铁匠提出过,让我们搬过去,他打刀刃我刻花纹,我们搭一伙。假如当初搬了过去,可能现在连汉话都不会说了。
假如我搬到一位阿伧大哥那里去住,现在准在黑洞洞的铁匠铺里给户撒刀刻花纹。在他家泥泞的后院里,准有一大窝小崽子,共有四种组合形式:
1.陈清扬和我的;
2.阿伧大哥和阿伧大嫂的;
3.我和阿伧大嫂的;
4.陈清扬和阿伧大哥的。
陈清扬从山上背柴回来,撩起衣裳,露出极壮硕的乳房,不分青红皂白,就给其中一个喂奶。假如当初我退回山上去,这样的事就会发生。
陈清扬说,这样的事不会发生,因为它没有发生,实际发生的是,我们回了农场,写交待材料出斗争差。虽然随时都可以跑掉,但是没有跑。这是真实发生了的事。
陈清扬说,我天资平常,她显然没把我的文学才能考虑在内。我写的交待材料人人都爱看。刚开始写那些东西时,我有很大抵触情绪。写着写着就入了迷。这显然是因为我写的全是发生过的事。发生过的事有无比的魅力。
我在交待材料里写下了一切细节,但是没有写以下已经发生的事情:
我和陈清扬在十五队后山上,在草房里干完后,到山涧里戏水。山上下来的水把红土剥光,露出下面的蓝粘土来。我们爬到蓝粘土上晒太阳。暖过来后,小和尚又直立起来。但是刚发泄过,不像急色鬼。于是我侧躺在她身后,枕着她的头发进入她的身体。我们在饭店里,后来也是这么重温伟大友谊。
我和陈清扬侧躺在蓝粘土上,那时天色将晚,风也有点凉。躺在一起心平气和,有时轻轻动一下。据说海豚之间有生殖性的和娱乐性的两种搞法,这就是说,海豚也有伟大友谊。我和陈清扬连在一起,好像两只海豚一样。
我和陈清扬在蓝粘土上,闭上眼睛,好像两只海豚在海里游动。天黑下来,阳光逐渐红下去。天边起了一片云,惨白惨白,翻着无数死鱼肚皮,瞪起无数死鱼眼睛。山上有一股风,无声无息地吹下去。天地间充满了悲惨的气氛。陈清扬流了很多眼泪。她说是触景伤情。
我还存了当年交待材料的副本,有一回拿给一位搞英美文学的朋友看,他说很好,有维多利亚时期地下小说的韵味。至于删去的细节,他也说删得好,那些细节破坏了故事的完整性。我的朋友真有大学问。我写交待材料时很年轻,没什么学问(到现在也没有学问),不知道什么是维多利亚时期地下小说。我想的是不能教会了别人。我这份交待材料不少人要看。假如他们看了情不自禁,也去搞破鞋,那倒不伤大雅,要是学会了这个,那可不大好。
我在交待材料里还漏掉了以下事实,理由如前所述。我们犯了错误,本该被枪毙,领导上挽救我们,让我写交待材料,这是多么大的宽大!所以我下定决心,只写出我们是多么坏。
我们俩在刘大爹后山上时,陈清扬给自己做了一件筒裙,想穿了它化装成老傣,到清平去赶街。可是她穿上以后连路都走不了啦。走到清平南边遇到一条河,山上下来的水像冰一样凉,像腌雪里红一样绿。那水有齐腰深,非常急。我走过去,把她用一个肩膀扛起来,径直走过河才放下来。我的一边肩膀正好和陈清扬的腰等宽,记得那时她的脸红得厉害。我还说,我可以把你扛到清平去,再扛回来,比你扭扭捏捏地走更快。她说,去你妈的吧。
筒裙就像个布筒子,下口只有一尺宽。会穿的人在里面可以干各种事,包括在大街上撒尿,不用蹲下来。陈清扬说,这一手她永远学不会。在清平集上观摩了一阵,她得到了要扮就扮阿伧的结论。回来的路是上山,而且她的力气都耗光了。每到跨沟越坎之处,她就找个树墩子,姿仪万方地站上去,让我扛她。
回来的路上扛着她爬坡。那时旱季刚到,天上白云纵横,阳光灿烂。可是山里还时有小雨。红土的大板块就分外的滑。我走上那块烂泥板,就像初次上冰场。那时我右手扣住她的大腿,左手提着猎枪,背上还有一个背篓,走在那滑溜溜的斜面上,十分吃力。忽然间我向左边滑动,马上要滑进山沟,幸亏手里有条枪,拿枪拄在地上。那时我全身绷紧,拼了老命,总算支持住了。可这个笨蛋还来添乱,在我背上扑腾起来,让我放她下去。那一回差一点死了。
等我刚能喘过气来,就把枪带交到右手,抡起左手在她屁股上狠狠打了两巴掌。隔了薄薄一层布,倒显得格外光滑。她的屁股很圆。鸡巴,感觉非常之好的啦!她挨了那两下登时老实了。非常的乖,一声也不吭。
当然打陈清扬屁股也不是好事,但是我想别的破鞋和野汉子之间未必有这样的事。这件事离了题,所以就没写。
-----
## 九
我和陈清扬在章风山上做爱时,她还很白,太阳穴上的血管清晰可见。后来在山里晒得很黑。回到农场又变得白晳。后来到了军民共建边防时期,星期天机务站出一辆大拖拉机,拉上一车有问题的人到砖窑出砖。出完了砖再拉到边防线上的生产队去,和宣传队会齐。我们这一车是历史反革命、贼、走资派、搞破鞋的等等,敌我矛盾人民内部都有,干完了活到边境上斗争一台,以便巩固政治边防。出这种差公家管饭,武装民兵押着蹲在地上吃。吃完了我和陈清扬倚着拖拉机站着,过来一帮老婆娘,对她品头论足。结论是她真白,难怪搞破鞋。
我去找过人保组老郭,问他们叫我们出这种差是什么意思。他们说,无非是让对面的坏人知道这边厉害,不敢过来。本来不该叫我们去,可是凑不齐人数。反正我们也不是好东西,去去也没什么的。我说去去原是不妨,你叫人别揪陈清扬的头发。搞急了老子又要往山上跑。他说他不知道有这事,一定去说说。其实我早想上山,可是陈清扬说,算了,揪揪头发又怎么了。
我们出斗争差时,陈清扬穿我的一件学生制服。那衣服她穿上非常大,袖子能到掌心,领子拉起来能遮住脸腮。后来她把这衣服要走了。据说这衣服还在,大扫除擦玻璃她还穿。挨斗时她非常熟练,一听见说到我们,就从书包里掏出一双洗得干干净净用麻绳栓好的解放鞋,往脖子上一挂,等待上台了。
陈清扬说,在家里刚洗过澡,她拿我那件衣服当浴衣穿。那时她表演给女儿看,当年怎么挨斗。人是撅着的,有时还得抬脸给人家看,就和跳巴西桑巴舞一样。那孩子问道:我爸呢?陈清扬说:你爸爸坐飞机。那孩子就格格笑,觉得非常有趣。
我听见这话,觉得如有芒刺在背。第一,我也没坐飞机。挨斗时是两个小四川押我,他俩非常客气,总是先道歉说:王哥,多担待。然后把我撅出去。押她的是宣传队的两个小骚货,又撅胳膊又揪头发。照她说的好像人家对我比对她还不好,这么说对当年那两个小四川不公平。第二,我不是她爸爸。等斗完了我们,就该演节目了。把我们撵下台,撵上拖拉机,连夜开回场部去。每次出过斗争差,陈清扬都性欲勃发。
我们跑回农场来,受批判,出斗争差。这也是一阵阵的。有时候团长还请我们到他家坐,说起我们犯错误,他还说,这种错误他也犯过。然后就和陈清扬谈前列腺。这时我就告辞,除非他叫我修手表。有时候对我们很坏,一礼拜出两次斗争差。这时政委说,像王二陈清扬这样的人,就是要斗争,要不大家都会跑到山上去,农场还办不办?平心而论,政委说的也有道理,而且他没有前列腺炎。所以陈清扬书包里那双破鞋老不扔,随时备用。过了一段时间,不再叫我们出斗争差,有一回政委出去开会,团长到军务科说了说,就把我放回内地去了。
有关斗争差的事是这样的:当地有一种传统的娱乐活动,就是斗破鞋。到了农忙时,大家都很累。队长说,今晚上娱乐一下,斗斗破鞋。但是他们怎么娱乐的,我可没见过。他们斗破鞋时,总把没结婚的人都撵走。再说,那些破鞋面黑如锅底,奶袋低垂,我不爱看。
后来来了一大批军队干部,接管了农场,就下令不准斗破鞋。理由是不讲政策。但是到了军民共建时期,又下令说可以斗破鞋,团里下了命令,叫我们到宣传队报到,准备参加斗争。马上我就要逃进山去,可是陈清扬不肯跟我走。她还说,她无疑是当地斗过的破鞋里最漂亮的一个。斗她的时候,周围好几个队的人都去看,这让她觉得无比自豪。
团里叫我们随宣传队活动,是这么交待的:我们俩是人民内部矛盾,这就是说,罪恶不彰,要注意政策。但是又说,假如群众愤怒了,要求狠狠斗我们,那就要灵活掌握。结果群众见了我们就愤怒。宣传队长是团长的人,他和我们私交也不坏,跑到招待所来和我们商量:能不能请陈大夫受点委屈?陈清扬说,没有关系。下回她就把破鞋挂在了脖子上,但是大家还是不满意。他只好让陈清扬再受点委屈。最后他说,大家都是明白人,我也不多说。您二位多担待吧。
我和陈清扬出斗争差的时候,开头总是呆在芭蕉树后面。那里是后台。等到快轮到我们时,她站起来,把头上的发卡取下来衔在嘴里,再一个个别好,翻起领口,拉下袖子,背过双手,等待受捆了。
陈清扬说,他们用竹批绳、棕绳来捆她,总把她的手捆肿。所以她从家里带来了晾衣服的棉绳。别人也抱怨说,女人不好捆。浑身圆滚滚,一点不吃绳子。与此同时,一双大手从背后擒住她的手腕,另一双手把她紧紧捆起来,捆成五花大绑。
后来人家把她押出去,后面有人揪住她的头发,使她不能往两边看,也不能低下头,所以她只能微微侧过头去,看汽灯青白色的灯光,有时她正过头来,看见一些陌生的脸,她就朝那人笑笑。这时她想,这真是个陌生的世界!这里发生了什么,她一点不了解。
陈清扬所了解的是,现在她是破鞋。绳子捆在她身上,好像一件紧身衣。这时她浑身的曲线毕露。她看到在场的男人裤裆里都凸起来。她知道是因为她,但为什么这样,她一点不理解。
陈清扬说,出斗争差时,人家总要揪着她头发让她往四下看,为此她把头发梳成两缕,分别用皮筋系住,这样人家一只手捉住她的手腕,另一只手揪她的头发就特别方便。她就这样被人驾驶着看到了一切,一切都流进她心里。但是她什么都不理解。但是她很愉快,人家要她做的事她都做到了,剩下的事与她无关。她就这样在台上扮演了破鞋。
等到斗完了我们,就该演文艺节目了。我们当然没资格看,就被撵上拖拉机,拉回场部去。开拖拉机的师傅早就着急回家睡觉,早就把机器发动起来。所以连陈清扬的绑绳也来不及松开。我把她抱上拖车,然后车上颠得很,天又黑,还是解不开。到了场部以后,索性我把她扛回招待听,在电灯下慢慢解。这时候陈清扬面有酡颜,说道:敦伟大友谊好吧?我都有点等不及了!
陈清扬说,那一刻她觉得自己像个礼品盒,正在打开包装。于是她心花怒放,她终于解脱了一切烦恼,用不着再去想自己为什么是破鞋,到底什么是破鞋,以及其他费解的东西:我们为什么到这个地方来,来干什么等等。现在她把自己交到了我手里。
在农场里,每回出完了斗争差,陈清扬必要求敦伟大友谊。那时总是在桌子上。我写交待材料也在那张桌子上,高度十分合适。她在那张桌上像考拉那样,快感如潮,经常禁不住喊出来。那时黑着灯,看不见她的模样。我们的后窗总是开着的,窗后是一个很陡的坡。但是总有人来探头探脑,那些脑袋露在窗台上好像树枝上的寒鸦。我那张桌子上老放着一些山梨,硬得人牙咬不动,只有猪能吃。有时她拿一个从我肩上扔出去,百发百中,中弹的从陡坡上滚下去。这种事我不那么受用,最后射出的精液都冷冰冰。不瞒你说,我怕打死人。像这样的事倒可以写进交待材料,可是我怕人家看出我在受审査期间继续犯错误,给我罪加一等。
-----
## 十
后来我们在饭店里重温伟大友谊,谈到各种事情。谈到了当年的各沖可能性,谈到了我写的交待材料,还谈到了我的小和尚。那东西一听别人谈到它,就激昂起来,蠢动个不停。因此我总结道,那时人家要把我们捶掉,但是没有捶动。我到今天还强硬如初。为了伟大友谊,我还能光着屁股上街跑三圈。我这个人,一向不大知道要脸。不管怎么说,那是我的黄金时代。虽然我被人当成流氓。我认识那里好多人,包括赶马帮的流浪汉,山上的老景颇等等。提起会修表的王二,大家都知道。我和他们在火边喝那种两毛钱一斤的酒,能喝很多。我在他们那里大受欢迎。
除了这些人,猪场里的猪也喜欢我,因为我喂猪时,猪食里的糠比平时多三倍。然后就和司务长吵架,我说,我们猪总得吃饱吧。我身上带有很多伟大友谊,要送给一切人。因为他们都不要,所以都发泄在陈清扬身上了。
我和陈清扬在饭店里敦伟大友谊,是娱乐性的。中间退出来一次,只见小和尚上血迹斑斑。她说,年纪大了,里面有点薄,你别那么使劲。她还说,在南方呆久了,到了北方手就裂。而蛤蜊油的质量下降,抹在手上一点用都不管。说完了这些话,她拿出一小瓶甘油来,抹在小和尚上面。然后正着敦,说话方便。我就像一根待解的木料,躺在她分开的双腿中间。
陈清扬脸上有很多浅浅的皱纹,在灯光下好像一条条金线。我吻她的嘴,她没反对。这就是说,她的嘴唇很柔软,而且分开了。以前她不让我吻她嘴唇,让我吻她下巴和脖子交界的地方。她说,这样刺激性欲。然后继续谈到过去的事。
陈清扬说,那也是她的黄金时代。虽然被人称做破鞋,但是她清白无辜。她到现在还是无辜的。听了这话,我笑起来。但是她说,我们在干的事算不上罪孽。我们有伟大友谊,一起逃亡,一起出斗争差,过了二十年又见面,她当然要分开两腿让我跳进来。所以就算是罪孽,她也不知罪在何处。更主要的是,她对这罪恶一无所知。
然后她又一次呼吸急促起来。她的脸变得赤红,两腿把我用力夹紧,身体在我下面绷紧,压抑的叫声一次又一次穿过牙关,过了很久才松弛下来。这时她说很不坏。
很不坏之后,她还说这不是罪孽。因为她像苏格拉底,对一切都一无所知。虽然活了四十多岁,眼前还是奇妙的新世界。她不知道为什么人家要把她发到云南那个荒凉的地方,也不知为什么又放她回来。不知道为什么要说她是破鞋,把她押上台去斗争,也不知道为什么又说她不是破鞋,把写好的材料又抽出来。这些事有过各种解释,但没有一种她能听懂。她是如此无知,所以她无罪。一切法律书上都是这么写的。
陈清扬说,人活在世上,就是为了忍受摧残,一直到死。想明了这一点,一切都能泰然处之。要说明她怎会有这种见识,一切都要回溯到那一回我从医院回来,从她那里经过进了山。我叫她去看我,她一直在犹豫。等到她下定了决心,穿过中午的热风,来到我的草房前面,那一瞬间,她心里有很多美丽的想象。等到她进了那间草房,看见我的小和尚直挺挺,像一件丑恶的刑具。那时她惊叫起来,放弃了一切希望。
陈清扬说,在此之前二十多年前一个冬日,她走到院子里去。那时节她穿着棉衣,艰难地爬过院门的门槛。忽然一粒砂粒钻进了她的眼睛。这是那么的疼,冷风又是那样的割脸,眼泪不停地流。她觉得难以忍受,立刻大哭起来,企图在一张小床上哭醒,这是与生俱来的积习,根深蒂固。放声大哭从一个梦境进入另一个梦境,这是每个人都有的奢望。
陈清扬说,她去找我时,树林里飞舞着金蝇。风从所有的方向吹来,穿过衣襟,爬到身上。我呆的那个地方可算是空山无人。炎热的阳光好像细碎的云母片,从天顶落下来。在一件薄薄的白大褂下,她已经脱得精光。那时她心里也有很多奢望。不管怎么说,那也是她的黄金时代,虽然那时她被人叫做破鞋。
陈清扬说,她到山里找我时,爬过光秃秃的山冈。风从衣服下面吹进来,吹过她的性敏感带,那时她感到的性欲,就如风一样捉摸不定。它放散开,就如山野上的风。她想到了我们的伟大友谊,想起我从山上急匆匆地走下去。她还记得我长了一头乱蓬蓬的头发,论证她是破鞋时,目光笔直地看着她。她感到需要我,我们可以合并,成为雄雌一体。就如幼小时她爬出门槛,感到了外面的风。天是那么蓝,阳光是那么亮,天上还有鸽子在飞。鸽哨的声音叫人终身难忘。此时她想和我交谈,正如那时节她渴望和外面的世界合为一体,溶化到天地中去。假如世界上只有她一个人,那实在是太寂寞了。
陈清扬说,她到我的小草房里去时,想到了一切东西,就是没想到小和尚。那东西太丑,简直不配出现在梦幻里。当时陈清扬也想大哭一场,但是哭不出来,好像被人捏住了喉咙。这就是所谓的真实。真实就是无法醒来。那一瞬间她终于明白了在世界上有些什么,下一瞬间她就下定了决心,走上前来,接受摧残,心里快乐异常。
陈清扬还说,那一瞬间,她又想起了在门槛上痛哭的时刻。那时她哭了又哭,总是哭不醒。而痛苦也没有一点减小的意思。她哭了很久,总是不死心。她一直不死心,直到二十年后面对小和尚。这已经不是她第一次面对小和尚。但是以前她不相信世界上还有这种东西。
陈清扬说,她面对这丑恶的东西,想到了伟大友谊。大学里有个女同学,长得丑恶如鬼(或者说,长得也是这个模样),却非要和她睡一个床。不但如此,到夜深人静的时候,还要吻她的嘴,摸她的乳房。说实在的,她没有这方面的嗜好。但是为了交情,她忍住了。如今这个东西张牙舞爪,所要求的不过是同一种东西。就让它如愿以偿,也算是交友之道。所以她走上前来,把它的丑恶深深埋葬,心里快乐异常。
陈清扬说,到那时她还相信自己是无辜的。甚至直到她和我逃进深山里去,几乎每天都敦伟大友谊。她说这丝毫也不能说明她有多么坏,因为她不知道我和我的小和尚为什么要这样。她这样做是为了伟大友谊,伟大友谊是一种诺言。守信肯定不是罪孽。她许诺过要帮助我,而且是在一切方面。但是我在深山里在她屁股上打了两下,彻底玷污了她的清白。
-----
## 十一
我写了很长时间交待材料,领导上总说,交待得不彻底,还要继续交待。所以我以为,我的下半辈子要在交待中度过。最后陈清扬写了一篇交待材料,没给我看,就交到了人保组。此后就再没让我们写材料。不但如此,也不叫我们出斗争差。不但如此,陈清扬对我也冷淡起来。我没情没绪地过了一段时间,自己回了内地。她到底写了什么,我怎么也猜不出来。
从云南回来时我损失了一切东西:我的枪,我的刀,我的工具,只多了一样东西,就是档案袋鼓了起来。那里面有我自己写的材料,从此不管我到什么地方,人家都能知道我是流氓。所得的好处是比别人早回城,但是早回来没什么好,还得到京郊插队。
我到云南时,带了很全的工具,桌拿子、小台钳都有。除了钳工家具,还有一套修表工具。住在刘大爹后山上时,我用它给人看手表。虽然空山寂寂,有些马帮却从那里过。有人让我鉴定走私表,我说值多少就值多少。当然不是白干。所以我在山上很活得过。要是不下来,现在也是万元户。
至于那把双筒猎枪,也是一宝。原来当地卡宾枪老套筒都不希罕,就是没见过那玩意。筒子那么粗,又是两个管,我拿了它很能唬人。要不人家早把我们抢了。我,特别是刘老爹,人家不会抢,恐怕要把陈清扬抢走。至于我的刀,老拴在一条牛皮大带上。牛皮大带又老拴在陈清扬腰上。睡觉做爱都不摘下来。她觉得带刀很气派。所以这把刀可以说已经属于陈清扬。枪和刀我已说过,被人保组要走了。我的工具下山时就没带下来,就放在山上,准备不顺利时再往山上跑。回来时行色匆匆,没顾上去拿,因此我成了彻底的穷光蛋。
我对陈清扬说,我怎么也想不出来在最后一篇交待里她写了什么。她说,现在不能告诉我。要告诉我这件事,只能等到了分手的时候。第二天她要回上海,她叫我送她上车站。
陈清扬在各个方面都和我不同。天亮以后,洗了个冷水澡(没有热水了),她穿戴起来。从内衣到外衣,她都是一个香喷喷的lady。而我从内衣到外衣都是一个地道的土流氓。无怪人家把她的交待材料抽了出来,不肯抽出我的。这就是说,她那破裂的处女膜长了起来。而我呢,根本就没长过那个东西。除此之外,我还犯了教唆之罪,我们在一起犯了很多错误,既然她不知罪,只好都算在我账上。
我们结了账,走到街上去。这时我想,她那篇交待材料一定淫秽万分。看交待材料的人都心硬如铁,水平无比之高,能叫人家看了受不住,那还好得了?陈清扬说,那篇材料里什么也没写,只有她真实的罪孽。
陈清扬说她真实的罪孽,是指在清平山上。那时她被架在我的肩上,穿着紧裹住双腿的筒裙,头发低垂下去,直到我的腰际。天上白云匆匆,深山里只有我们两个人。我刚在她屁股上打了两下,打得非常之重,火烧火燎的感觉正在飘散。打过之后我就不管别的事,继续往山上攀登。
陈清扬说,那一刻她感到浑身无力,就瘫软下来,挂在我肩上。那一刻她觉得如春藤绕树,小鸟依人。她再也不想理会别的事,而且在那一瞬间把一切都遗忘。在那一瞬间她爱上了我,而且这件事永远不能改变。
在车站上陈清扬说,这篇材料交上去,团长拿起来就看。看完了面红耳赤,就像你的小和尚。后来见过她这篇交待材料的人,一个个都面红耳赤,好像小和尚。后来人保组的人找了她好几回,让她拿回去重写,但是她说,这是真实情况,一个字都不能改。人家只好把这个东西放进了我们的档案袋。
陈清扬说,承认了这个,就等于承认了一切罪孽。在人保组里,人家把各种交待材料拿给她看,就是想让她明白,谁也不这么写交待。但是她偏要这么写。她说,她之所以要把这事最后写出来,是因为它比她干过的一切事都坏。以前她承认过分开双腿,现在又加上,她做这些事是因为马分尸千刀万剐。但是谁也没权力把我们五马分尸,所以只好把我们放了。
陈清扬告诉我这件事以后,火车就开走了。以后我再也没见过她。
-----
本篇最初于1991年在台湾《联合报》副刊连载。1992年3月由香港繁荣出版社出版的王小波小说集《王二风流史》收本篇作品。1992年8月由台湾联经出版事业公司以《黄金年代》之名出版。——编者
回忆我的姑母-杨绛
========================
回忆我的姑母-[[杨绛]]
------
中国社会科学院近代史所给我的信里说:“令姑母荫榆先生也是人们熟知的人物,我们也想了解她的生平。荫榆先生在日寇陷苏州时骂敌遇害,但许多研究者只知道她在女师大事件中的作为,而不了解她晚节彪炳,这点是需要纠正的。如果您有意写补塘先生的传记,可一并写入其中。”
杨荫榆是我的三姑母,我称“三伯伯”。我不大愿意回忆她,因为她很不喜欢我,我也很不喜欢她。她在女师大的作为以及骂敌遇害的事,我都不大知道。可是我听说某一部电影里有个杨荫榆,穿着高跟鞋,戴一副长耳环。这使我不禁哑然失笑,很想看看电影里这位姑母是何模样。认识她的人愈来愈少了。也许正因为我和她感情冷漠,我对她的了解倒比较客观。我且尽力追忆,试图为她留下一点比较真实的形象。
我父亲兄弟姊妹共六人。大姑母最大,出嫁不久因肺疾去世。大伯父在武备学校因试炮失事去世。最小的三叔叔留美回国后肺疾去世。二姑母(荫枌)和三姑母都比我父亲小,出嫁后都和夫家断绝了关系,长年住在我家。
听说我的大姑母很美,祖父母十分疼爱。他们认为二姑母三姑母都丑。两位姑母显然从小没人疼爱,也没人理会;姊妹俩也不要好。
我的二姑夫名裘剑岑,是无锡小有名气的“才子”,翻译过麦考莱(T.B.Macaulay)的《约翰生传》(Life of Johnson)①,这个译本锺书曾读过,说文笔很好。据我父亲讲,二姑母无声无息地和丈夫分离了,错在二姑母。我听姐姐说,二姑母嫌丈夫肺病,夫妇不和。反正二姑母对丈夫毫无感情,也没有孩子,分离后也从无烦恼。她的相貌确也不美。三姑母相貌和二姑母完全不像。我堂姐杨保康曾和三姑母同在美国留学,合照过许多相片,我大姐也曾有几张三姑母的小照,可惜这些照片现在一张都没有了。三姑母皮肤黑黝黝的,双眼皮,眼睛炯炯有神,笑时两嘴角各有个细酒涡,牙也整齐。她脸型不错,比中等身材略高些,虽然不是天足,穿上合适的鞋,也不像小脚娘。我曾注意到她是穿过耳朵的,不过耳垂上的针眼早已结死,我从未见她戴过耳环。她不令人感到美,可是也不能算丑。我听父母闲话中讲起,祖母一次当着三姑母的面,拿着她的一张照片说:“瞧她,鼻子向着天。”(她鼻子有上仰的倾向,却不是“鼻灶向天”。)三姑母气呼呼地说:“就是你生出来的!就是你生出来的!就是你生出来的!”当时家里人传为笑谈。我觉得三姑母实在有理由和祖母生气。即使她是个丑女儿,也不该把她嫁给一个低能的“大少爷”。当然,定婚的时候只求门当户对,并不知对方的底细。据我父亲的形容,那位姑爷老嘻着嘴,露出一颗颗紫红的牙肉,嘴角流着哈拉子。三姑母比我父亲小六岁,甲申(一八八四)年生,小名申官。她是我父亲留学日本的时期由祖母之命定亲结婚的。我母亲在娘家听说过那位蒋家的少爷,曾向我祖母反对这门亲事,可是白挨了几句训斥,祖母看重蒋家的门户相当。
我不知道三姑母在蒋家的日子是怎么过的。听说她把那位傻姑爷的脸皮都抓破了,想必是为自卫。据我大姐转述我母亲的话,她回了娘家就不肯到夫家去。那位婆婆有名的厉害,先是抬轿子来接,然后派老妈子一同来接,三姑母只好硬给接走。可是有一次她死也不肯再回去,结果婆婆亲自上门来接。三姑母对婆婆有几分怕惧,就躲在我母亲的大床帐子后面。那位婆婆不客气,竟闯入我母亲的卧房,把三姑母揪出来。逼到这个地步,三姑母不再示弱,索性撕破了脸,声明她怎么也不再回蒋家。她从此就和夫家断绝了。那位傻姑爷是独子,有人骂三姑母为“灭门妇”;大概因为她不肯为蒋家生男育女吧?我推算她在蒋家的日子很短,因为她给婆婆揪出来的时候,我父亲还在日本。一九〇二年我父亲回国,在家乡同朋友一起创立理化会,我的二姑母三姑母都参加学习。据说那是最早有男女同学的补习学校;尤其两个姑母都不坐轿子,步行上学,开风气之先。三姑母想必已经离开蒋家了。那时候,她不过十八周岁。
三姑母由我父亲资助,在苏州景海女中上学。我亲戚家有一位小姐和她同学。那姑娘有点“着三不着两”,无锡土话称为“开盖”(略似上海人所谓“十三点”,北方人所谓“二百五”)。她和蒋家是隔巷的街坊,可是不知道我三姑母和蒋家的关系,只管对她议论蒋家的新娘子:“有什么好看呀!狠巴巴的,小脚鞋子拿来一剁两段。”末一句话全无事实根据。那时候的三姑母还很有幽默,只笑着听她讲,也不点破,也不申辩。过了些时候,那姑娘回家弄清底里,就对三姑母骂自己:“开盖货!原来就是你们!”我记得三姑母讲的时候,细酒涡儿一隐一显,乐得不得了。
她在景海读了两年左右,就转学到上海务本女中,大概是务本毕业的。我母亲那时曾在务本随班听课。我偶尔听到她们谈起那时候的同学,有一位是章太炎夫人汤国梨。三姑母一九〇七年左右考得官费到日本留学,在日本东京女子高等师范学校(现“茶水女子大学”的前身)毕业,并获得奖章。我曾见过那枚奖章,是一只别针,不知是金的还是铜的。那是在一九一三年②。她当年就回国了,因为据苏州女师的校史,我三姑母一九一三至一九一四年曾任该校教务主任,然后就到北京工作。
我听父亲说,三姑母的日文是科班出身。日本是个多礼的国家,妇女在家庭生活和社交里的礼节更为繁重;三姑母都很内行。我记得一九二九年左右,苏州市为了青阳地日本租界的事请三姑母和日本人交涉,好像双方对她都很满意。那年春天三姑母和我们姐妹同到青阳地去看樱花,路过一个日本小学校,校内正开运动会。我们在短篱外略一逗留,观看小学生赛跑,不料贵宾台上有人认识三姑母,立即派人把我们一伙人都请上贵宾台。我看见三姑母和那些日本人彼此频频躬身行礼的样儿,觉得自己成了挺胸凸肚的野蛮人。
三姑母一九一四年到北京,大约就是在女高师工作。我五周岁(一九一六年)在女高师附小上一年级,开始能记忆三姑母。她那时是女高师的“学监”,我还是她所喜欢的孩子呢。我记得有一次我们小学生正在饭堂吃饭,她带了几位来宾进饭堂参观。顿时全饭堂肃然,大家都专心吃饭。我背门而坐,饭碗前面掉了好些米粒儿。三姑母走过,附耳说了我一句,我赶紧把米粒儿捡在嘴里吃了。后来我在家听见三姑母和我父亲形容我们那一群小女孩儿,背后看去都和我相像,一个白脖子,两撅小短辫儿;她们看见我捡吃了米粒儿,一个个都把桌上掉的米粒儿捡来吃了。她讲的时候笑出了细酒涡儿,好像对我们那一群小学生都很喜欢似的。那时候的三姑母还一点不怪僻。
女高师的学生有时带我到大学部去玩。我看见三姑母忙着写字,也没工夫理会我。她们带我打秋千,登得老高,我有点害怕,可是不敢说。有一次她们开恳亲会,演戏三天,一天试演,一天请男宾,一天请女宾,借我去做戏里的花神,把我的牛角小辫儿盘在头顶上,插了满头的花,衣上也贴满金花。又一次开运动会,一个大学生跳绳,叫我钻到她身边像卫星似的绕着她周围转着跳。老师还教我说一套话。运动场很大,我站在场上自觉渺小,细声儿把那套话背了一遍,心上只愁跳绳绊了脚。那天总算跳得不错。事后老师问我:“你说了什么话呀?谁都没听见。”
我现在回想,演戏借我做“花神”,运动会叫我和大学生一同表演等等,准是看三姑母的面子。那时候她在校内有威信,学生也喜欢她。我决不信小学生里只我一个配做“花神”,只我一个灵活,会钻在大学生身边围绕着她跳绳。
一九一八年,三姑母由教育部资送赴美留学。她特叫大姐姐带我上车站送行。大姐姐告诉我,三伯伯最喜欢我。可是我和她从来不亲。我记得张勋复辟时,我家没逃离北京,只在我父亲的一个英国朋友波尔登(Bolton)先生家避居几天。我母亲给我换上新衣,让三姑母带我先到波尔登家去,因为父亲还没下班呢。三姑母和波尔登对坐在他书房里没完没了地说外国话,我垂着短腿坐在旁边椅上,看看天色渐黑,不胜焦急,后来波尔登笑着用北京话对我说:“你今天不回家了,住在这里了。”我看看外国人的大菱角胡子,看看三姑母的笑脸,不知他们要怎么摆布我,愁得不可开交,幸亏父母亲不久带着全家都到了。我总觉得三姑母不是我家的人,她是学校里的人。
那天我跟着大姐到火车站,看见三姑母有好些学生送行。其中有我的老师。一位老师和几个我不认识的大学生哭得抽抽噎噎,使我很惊奇。三姑母站在火车尽头一个小阳台似的地方,也只顾拭泪。火车叫了两声(汽笛声),慢慢开走。三姑母频频挥手,频频拭泪。月台上除了大哭的几人,很多人也在擦眼泪。我虽然早已乘过多次火车,可是我还小,都不记得。那次是我记忆里第一次看到火车,听到“火车叫”。我永远把“火车叫”和哭泣连在一起,觉得那是离别的叫声,听了心上很难受。
我现在回头看,那天也许是我三姑母生平最得意、最可骄傲的一天。她是出国求深造,学成归来,可以大有作为。而且她还有许多喜欢她的人为她依依惜别。据我母亲说,很多学生都送礼留念;那些礼物是三姑母多年来珍藏的纪念品。
三姑母一九二三年回苏州看我父亲的时候,自恨未能读得博士,只得了美国哥伦比亚大学的硕士学位。我父亲笑说:“别‘博士’了,头发都白了,越读越不合时宜了。”我在旁看见她头上果然有几茎白发。
一九二四年,她做了北京女子师范大学的校长,从此打落下水,成了一条“落水狗”。
我记得她是一九二五年冬天到苏州长住我家的。我们的新屋刚落成,她住在最新的房子里。后园原有三间“旱船”,形似船,大小也相同。新建的“旱船”不在原址,面积也扩大了,是个方厅(苏州人称“花厅”),三面宽廊,靠里一间可充卧房,后面还带个厢房。那前后两间是父亲给三姑母住的。除了她自买的小绿铁床,家具都现成。三姑母喜欢绿色,可是她全不会布置。我记得阴历除夕前三四天,她买了很长一幅白“十字布”,要我用绿线为她绣上些竹子做帐帷。“十字布”上绣花得有“十字”花的图样。我堂兄是绘画老师。他为三姑母画了一幅竹子,上面还有一弯月亮,几只归鸟。我不及把那幅画编成图案,只能把画纸钉在布下,照着画随手绣。“十字布”很厚,我得对着光照照,然后绣几针,很费事。她一定要在春节前绣好,怕我赶不及,扯着那幅长布帮我乱绣,歪歪斜斜,针脚都不刺在格子眼儿里,许多“十”字只是“一”字,我连日成天在她屋里做活儿,大除夕的晚饭前恰好赶完。三姑母很高兴,奖了我一支自来水笔。可惜那支笔写来笔划太粗。背过来写也不行。我倒并不图报,只是看了她那歪歪扭扭的手工不舒服。
她床头挂一把绿色的双剑——一个鞘里有两把剑。我和弟弟妹妹要求她舞剑,她就舞给我们看。那不过是两手各拿一把剑,摆几个姿势,并不像小说里写的一片剑光,不见人影。我看了很失望。那时候,她还算是喜欢我的,我也还没嫌她,只是并不喜欢她,反正和她不亲。
我和二姑母也不亲,但比较接近。二姑母上海启明女校毕业,曾在徐世昌家当过家庭教师,又曾在北京和吉林教书。我家房子还没有全部完工的时候,我曾有一二年和她同睡一屋。她如果高兴,或者我如果问得乖巧,她会告诉我好些有趣的经验。不过她性情孤僻,只顾自己,从不理会旁人。三姑母和她不一样。我记得小时候在北京,三姑母每到我们家总带着一帮朋友,或二三人,或三四人,大伙儿热闹说笑。她不是孤僻的。可是一九二五年冬天她到我们家的时候,她只和我父亲有说不完的话。我旁听不感兴趣,也不大懂,只觉得很烦。她对我母亲或二姑母却没几句话。大概因为我母亲是家庭妇女,不懂她的事,而二姑母和她从来说不到一块儿。她好像愿意和我们孩子亲近,却找不到途径。
有一次我母亲要招待一位年已半老的新娘子。三姑母建议我们孩子开个欢迎会,我做主席致辞,然后送上茶点,同时演个节目助兴。我在学校厌透了这一套,可是不敢违拗,勉强从命。新娘是苏州旧式小姐,觉得莫名其妙,只好勉强敷衍我们。我父亲常取笑三姑母是“大教育家”,我们却不爱受教育,对她敬而远之。
家庭里的细是细非确是“清官难断”,因为往往只是个立场问题。三姑母爱惜新房子和新漆的地板,叫我的弟弟妹妹脱了鞋进屋。她自己是“解放脚”,脱了鞋不好走路,况且她的鞋是干净的。孩子在后园玩,鞋底不免沾些泥土,而孩子穿鞋脱鞋很方便,可是两个弟弟不服,去问父亲:“爸爸,到旱船去要脱鞋吗?”我父亲不知底里,只说“不用”。弟弟便嘀咕:“爸爸没叫我们脱鞋。她自己不脱,倒叫我们脱!”他们穿着鞋进去,觉得三姑母不欢迎,便干脆不到她那边去了。
三姑母准觉得孩子不如小牲口容易亲近。我父亲爱猫,家里有好几只猫。猫也各有各的性格。我们最不喜欢一只金银眼的纯白猫,因为它见物不见人,最无情;好好儿给它吃东西,它必定作势用爪子一抢而去。我们称它为“强盗猫”。我最小的妹妹杨必是全家的宝贝。她最爱猫,一两岁的时候,如果自个儿一人乖乖地坐着,动都不动,一脸称心满意的样儿,准是身边偎着一只猫。一次她去抚弄“强盗猫”,挨了猫咪一巴掌,鼻子都抓破,气得伤心大哭。从此“强盗猫”成了我们的公敌。三姑母偏偏同情这只金银眼儿,常像抱女儿似的抱着它,代它申诉委屈似的说:“咱们顶标致的!”她出门回来,便抱着“强盗猫”说:“小可怜儿,给他们欺负得怎样了?”三姑母就和“强盗猫”同在一个阵营,成了我们的敌人。
三姑母非常敏感,感觉到我们这群孩子对她不友好。也许她以为我是头儿,其实我住宿在校,并未带头,只是站在弟弟妹妹一边。那时大姐在上海教书,三姐病休在家。三姑母不再喜欢我,她喜欢三姐姐了。
一九二七年冬,三姐订婚,三姑母是媒人。她一片高兴,要打扮“新娘”。可是三姑母和二姑母一样,从来不会打扮。我母亲是好皮肤,不用脂粉,也不许女儿搽脂抹粉。我们姐妹没有化妆品,只用甘油搽手搽脸。我和三姐刚刚先后剪掉辫子,姐妹俩互相理发,各剪个童化头,出门换上“出客衣服”,便是打扮了。但订婚也算个典礼,并在花园饭店备有酒席。订婚礼前夕,三姑母和二姑母都很兴头,要另式另样地打扮三姐。三姑母一手拿一支簪子,一手拿个梳子,把三姐的头发挑过来又梳过去,挑出种种几何形(三姑母是爱好数理的):正方形、长方形、扁方形、正圆形、椭圆形,还真来个三角形,末了又饶上一个桃儿形,好像要梳小辫儿似的。挑了半天也不知怎么办。二姑母拿着一把剪子把三姐的头发修了又修,越修越短。三姐乖乖地随她们摆布,毫不抗议。我母亲也不来干涉,只我站在旁边干着急。姐姐的头发实在给剪得太短了;梳一梳,一根根直往上翘。还亏二姑母花样多。当时流行用黑色闪光小珠子钉在衣裙的边上,或穿织成手提袋。二姑母教我们用细铜丝把小黑珠子穿成一个花箍,箍在发上。幸亏是三姐,怎么样儿打扮都行。她戴上珠箍,还顶漂亮。
三姐结婚,婚礼在我家举行,新房也暂设我家。因为姐夫在上海还没找妥房子。铺新床按老规矩得请“十全”的“吉利人”,像我两位姑母那样的“畸零人”得回避些。我家没有这种忌讳。她们俩大概由于自己的身世,对那新房看不顺眼,进去就大说倒霉话。二姑母说窗帘上的花纹像一滴滴眼泪。三姑母说新床那么讲究,将来出卖值钱。事后我母亲笑笑说:“她们算是怄我生气的。”
我母亲向来不尖锐,她对人事的反应总是慢悠悠的。如有谁当面损她,她好像不知不觉,事后才笑说:“她算是骂我的。”她不会及时反击,事后也不计较。
我母亲最怜悯三姑母早年嫁傻子的遭遇,也最佩服她“个人奋斗”的能力。我有时听到父母亲议论两个姑母。父亲说:“枌官(二姑母的小名)‘莫知莫觉’(指对人漠无感情),申官‘细腻恶心’(指多心眼儿)。”母亲只说二姑母“独幅心思”,却为三姑母辩护,说她其实是贤妻良母,只为一辈子不得意,变成了那样儿。我猜想三姑母从蒋家回娘家的时候,大约和我母亲比较亲密。她们在务本女中也算是同过学。我觉得母亲特别纵容三姑母。三姑母要做衬衣——她衬衣全破了,我母亲怕裁缝做得慢,为她买了料子,亲自裁好,在缝衣机上很快地给赶出来。三姑母好像那是应该的,还嫌好道坏。她想吃什么菜,只要开一声口,母亲特地为她下厨。菜端上桌,母亲说,这是三伯伯要吃的,我们孩子从不下筷。我母亲往往是末后一个坐下吃饭,也末后一个吃完;她吃得少而慢。有几次三姑母饭后故意回到饭间去看看,母亲忽然聪明说:“她来看我吃什么好菜呢。”说着不禁笑了,因为她吃的不过是剩菜。可是她也并不介意。
我们孩子总觉得两个姑母太自私也太自大了。家务事她们从不过问。三姑母更有一套道理。她说,如果自己动手抹两回桌子,她们(指女佣)就成了规矩,从此不给抹了。我家佣人总因为“姑太太难伺候”而辞去,所以我家经常换人。这又给我母亲添造麻烦。我们孩子就嘀嘀咕咕,母亲听见了就要训斥我们:“老小(小孩子)勿要刻薄。”有一次,我嘀咕说,三姑母欺负我母亲。母亲一本正经对我说:“你倒想想,她,怎么能欺负我?”当然这话很对。我母亲是一家之主(父亲全听她的),三姑母只是寄居我家。可是我和弟弟妹妹心上总不服气。
有一次,我们买了一大包烫手的糖炒热栗子。我母亲吃什么都不热心,好的要留给别人吃,不好的她也不贪吃,可是对这东西却还爱吃。我们剥到软而润的,就偷偷儿揣在衣袋里。大家不约而同地“打偏手”,一会儿把大包栗子吃完。二姑母并没在意,三姑母却精细,她说:“这么大一包呢,怎么一会儿就吃光了?”我们都呆着脸。等两个姑母回房,我们各掏出一把最好的栗子献给母亲吃。母亲责备了我们几句,不过责备得很温和。她只略吃几颗,我们乐呵呵地把剩下的都吃了,绝没有为三姑母着想。她准觉得吃几颗栗子,我们都联着帮挤她。我母亲训我们的话实在没错,我们确是刻薄了,只觉得我们好好一个家,就多了这两个姑母。而在她们看来,哥哥的家就是她们自己的家,只觉得这群侄儿女太骄纵,远不像她们自己的童年时候了。
二姑母自己会消遣,很自得其乐。她独住一个小院,很清静。她或学字学画,或读诗看小说,或做活儿,或在后园拔草种花。她有方法把鸡冠花夹道种成齐齐两排,一棵棵都秆儿矮壮,花儿肥厚,颜色各各不同,有洋红、橘黄、苹果绿等等。她是我父亲所谓“最没有烦恼的人”。
三姑母正相反。她没有这种闲情逸致,也不会自己娱乐。有时她爱看个电影,不愿一人出去,就带着我们一群孩子,可是只给我们买半票。转眼我十七八岁,都在苏州东吴大学上学了,她还给买半票。大弟长得高,七妹小我五岁,却和我看似双生。这又是三姑母买半票的一个理由,她说我们只是一群孩子。我们宁可自己买票,但是不敢说。电影演到半中间,查票员命令我们补票,三姑母就和他争。我们都窘得很,不愿跟她出去,尤其是我。她又喜欢听说书。我家没人爱“听书”,父亲甚至笑她“低级趣味”。苏州有些人家请一个说书的天天到家里来说书,并招待亲友听书。有时一两家合请一个说书的,轮流做东。三姑母就常到相识的人家去听书。有些联合做东的人家并不欢迎她,她也不觉得,或是不理会。她喜欢赶热闹。
她好像有很多活动,可是我记不清她做什么工作。一九二七年左右她在苏州女师任教。一九二九年,苏州东吴大学聘请她教日语,她欣然应聘,还在女生宿舍要了一间房,每周在学校住几天。那时候她养着几只猫和一只小狗;狗和猫合不到一处,就把小狗放在宿舍里。这可激怒了全宿舍的女学生,因为她自己回家了,却把小狗锁在屋里。狗汪汪地叫个不停,闹得四邻学生课后不能在宿舍里温习功课,晚上也不得安静。寒假前大考的时候,有一晚大雪之后,她叫我带她的小狗出去,给它“把屎”。幸亏我不是个“抱佛脚”的,可是我实在不知道怎样“把屎”,只牵着狗在雪地里转了两圈,回去老实说小狗没拉屎。三姑母很不满意,忍住了没说我。管女生的舍监是个美国老姑娘,她到学期终了,请我转告三姑母:宿舍里不便养狗。也许我应该叫她自己和我姑母打交道,可是我觉得这话说不出口。我不记得自己是怎样传话的,反正三姑母很恼火,把怨毒都结在我身上,而把所传的话置之不理。春季开学不久,她那只狗就给人毒死了。
不久学校里出了一件事。大学附中一位美国老师带领一队学生到黑龙潭(一个风景区)春游,事先千叮万嘱不许下潭游泳,因为水深湍急,非常危险。有个学生偷偷跳下水去,给卷入急湍。老师得知,立即跳下水去营救。据潭边目击的学生说:老师揪住溺者,被溺者拖下水去;老师猛力挣脱溺者,再去捞他,水里出没几回,没有捞到,最后力竭不支,只好挣扎上岸。那孩子就淹死了。那位老师是个很老实的人,他流涕自责没尽责任,在生死关头一刹那间,他想到了自己的妻子儿女,没有舍生忘死。当时舆论认为老师已经尽了责任,即使赔掉性命,也没法救起溺者。校方为这事召开了校务会议,想必是商量怎样向溺者家长交代。参与会议的大多是洋人,校方器重三姑母,也请她参加了。三姑母在会上却责怪那位老师没舍命相救,会后又自觉失言。舍生忘死,只能要求自己,不能责求旁人;校方把她当自己人,才请她参与会议,商量办法,没要她去苛责那位惶恐自愧的老师。
她懊悔无及,就想请校委会的人吃一顿饭,大概是表示歉意。她在请客前一天告诉我母亲“明天要备一桌酒”,在我家请客;她已约下了客人。一桌酒是好办的,可是招待外宾,我家不够标准。我们的大厅高大,栋梁间的积尘平日打扫不到,后园也不够整洁。幸亏我母亲人缘好,她找到本巷“地头蛇”,立即雇来一群年富力强的小伙子,只半天工夫便把房子前前后后打扫干净。一群洋客人到了我家,对我父母大夸我;回校又对我大夸我家。我觉得他们和三姑母的关系好像由紧张又缓和下来。
三姑母请客是星期六,客散后我才回家,走过大厅后轩,看见她一人在厅上兜兜转,嘴里喃喃自骂:“死开盖!”“开盖货!”骂得咬牙切齿。我进去把所见告诉母亲。母亲叹气说:“嗐!我叫她请最贵的,她不听。”原来三姑母又嫌菜不好,简慢了客人。其实酒席上偶有几个菜不如人意,也是小事。说错话、做错事更是人之常情,值不当那么懊恼。我现在回头看,才了解我当时看到的是一个伤残的心灵。她好像不知道人世间有同情,有原谅,只觉得人人都盯着责备她,人人都嫌弃她,而她又老是那么“开盖”。
学校里接着又出一件事。有个大学四年级的学生自称“怪物”,有意干些怪事招人注意。他穿上戏里纨绔少爷的花缎袍子,镶边马褂,戴着个红结子的瓜皮帽,跑到街上去挑粪;或叫洋车夫坐在洋车上,他拉着车在闹市跑。然后又招出一个“二怪物”。“大怪物”和大学的门房交了朋友,一同拉胡琴唱戏。他违犯校规,经常夜里溜出校门,半夜门房偷偷放他进校。学校就把“大怪物”连同门房一起开除。三姑母很可能吃了“怪物”灌她的“米汤”而对这“怪物”有好感,她认为年轻人胡闹不足怪,四年级开除学籍就影响这个青年的一辈子。她和学校意见不合,就此辞职了。
那时我大弟得了肺结核症。三姑母也许是怕传染,也许是事出偶然,她“典”③了一个大花园里的两座房屋,一座她已经出租,另一座楠木楼留着自己住。我母亲为大弟的病求医问药忙得失魂落魄,却还为三姑母置备了一切日常用具,而且细心周到,还为她备了煤油炉和一箱煤油。三姑母搬入新居那天,母亲命令我们姐妹和小弟弟大伙儿都换上漂亮的衣服送搬家。我认为送搬家也许得帮忙,不懂为什么要换漂亮衣裳。三姑母典的房子在娄门城墙边,地方很偏僻。听说原来的园主为建造那个花园惨淡经营,未及竣工,他已病危,勉强坐了轿子在园内游览一遍便归天去了。花园确还像个花园,有亭台楼阁,有假山,有荷池,还有个湖心亭,有一座九曲桥。园内苍松翠柏各有姿致,相形之下,才知道我们后园的树木多么平庸。我们回家后,母亲才向我们讲明道理。三姑母是个孤独的人,脾气又坏——她和管园产的经纪人已经吵过两架,所以我们得给她装装场面,让人家知道她亲人不少,而且也不是贫寒的。否则她在那种偏僻的地方会受欺,甚至受害。
三姑母搬出后,我们才知道她搬家也许还是“怪物”促成的。他介绍自己的一个亲戚叫“黄少奶”为三姑母管理家务。三姑母早已买下一辆包车,又雇了一个车夫,一个女佣,再加有人管家,就可以自立门户了。她竭力要拼凑一个像样的家,还问我大伯母要了一个孙女儿。她很爱那个孩子,孩子也天真可爱,可是一经她精心教育,孩子变成了一个懂事的小养媳妇儿。不巧我婶母偶到三姑母家去住了一夜,便向大伯母诉说三姑母家的情况,还说孩子瘦了。大伯母舍不得,忙把孩子讨回去。
三姑母家的女佣总用不长,后来“黄少奶”也辞了她。我母亲为她置备的煤油炉成了她的要紧用具。她没有女佣,就坐了包车到我家来吃饭。那时候我大弟已经去世。她常在我们晚饭后乘凉的时候,忽然带着车夫来吃晚饭。天热,当时还没有冷藏设备,厨房里怕剩饭剩菜馊掉,尽量吃个精光。她来了,母亲得设法安排两个人的饭食。时常特地为她留着晚饭,她又不来,东西都馊掉。她从不肯事先来个电话,仿佛故意捣乱。所以她来了,我和弟弟妹妹在后园躲在花木深处,黑地里装作不知道。大姐姐最识体,总是她敷衍三姑母,陪她说话。
她不会照顾自己,生了病就打电话叫我母亲去看她。母亲带了大姐姐同去伺候,还得包半天的车,因为她那里偏僻,车夫不肯等待,附近也叫不到车。一次母亲劝她搬回来住,她病中也同意,可是等我母亲作好种种准备去接她,她又变卦了。她是好动的,喜欢坐着包车随意出去串门。我们家的大门虽然有六扇,日常只开中间两扇。她那辆包车特大,门里走不进——只差两分,可是门不能扩大,车也不能削小。她要是回我们家住,她那辆车就没处可放。
她有个相识的人善“灌米汤”,常请她吃饭,她很高兴,不知道那人请饭不是白请的。他陆续问我三姑母借了好多钱,造了新房子,前面还有个小小的花园。三姑母要他还钱的时候,他就推委不还,有一次晚上三姑母到他家去讨债,那人灭了电灯,放狗出来咬她。三姑母吃了亏,先还不肯对我父母亲讲,大概是自愧喝了“米汤”上当,后来忍不住才讲出来的。
她在一个中学教英文和数学,同时好像在创办一个中学叫“二乐”,我不大清楚。我假期回家,她就抓我替她改大叠的考卷;瞧我改得快,就说,“到底年轻人做事快”,每学期的考卷都叫我改。她嫌理发店脏,又抓我给她理发。父亲常悄悄对我说:“你的好买卖来了。”三姑母知道父亲袒护我,就越发不喜欢我,我也越发不喜欢她。
一九三五年夏天我结婚,三姑母来吃喜酒,穿了一身白夏布的衣裙和白皮鞋。贺客诧怪,以为她披麻戴孝来了。我倒认为她不过是一般所谓“怪僻”。一九二九年她初到东吴教课,做了那一套细夏布的衣裙,穿了还是很“帅”的。可是多少年过去了,她大概没有添做过新衣。我母亲为我大弟的病、大弟的死、接下父亲又病,没心思顾她。她从来不会打扮自己,也瞧不起女人打扮。
我记得那时候她已经在盘门城河边买了一小块地,找匠人盖了几间屋。不久她退掉典来的花园房子,搬入新居。我在国外,她的情况都是大姐姐后来告诉我的。日寇侵占苏州,我父母带了两个姑母一同逃到香山暂住。香山沦陷前夕,我母亲病危,两个姑母往别处逃避,就和我父母分手了。我母亲去世后,父亲带着我的姐姐妹妹逃回苏州,两个姑母过些时也回到苏州,各回自己的家(二姑母已抱了一个不认识的孩子做孙女,自己买了房子)。三姑母住在盘门,四邻是小户人家,都深受敌军的蹂躏。据那里的传闻,三姑母不止一次跑去见日本军官,责备他纵容部下奸淫掳掠。军官就勒令他部下的兵退还他们从三姑母四邻抢到的财物。街坊上的妇女怕日本兵挨户找“花姑娘”,都躲到三姑母家里去。一九三八年一月一日,两个日本兵到三姑母家去,不知用什么话哄她出门,走到一座桥顶上,一个兵就向她开一枪,另一个就把她抛入河里。他们发现三姑母还在游泳,就连发几枪,看见河水泛红,才扬长而去。邻近为她造房子的一个木工把水里捞出来的遗体入殓。棺木太薄,不管用,家属领尸的时候,已不能更换棺材,也没有现成的特大棺材可以套在外面,只好赶紧在棺外加钉一层厚厚的木板。
一九三九年我母亲安葬灵岩山的绣谷公墓。二姑母也在那公墓为三姑母和她自己合买一块墓地。三姑母和我母亲是同日下葬的。我看见母亲的棺材后面跟着三姑母的奇模怪样的棺材,那些木板是仓猝间合上的,来不及刨光,也不能上漆。那具棺材,好像象征了三姑母坎坷别扭的一辈子。
我母亲曾说:“三伯伯其实是贤妻良母。”我父亲只说:“申官如果嫁了一个好丈夫,她是个贤妻良母。”我觉得父亲下面半句话没说出来。她脱离蒋家的时候还很年轻,尽可以再嫁人。可是据我所见,她挣脱了封建制度的桎梏,就不屑做什么贤妻良母。她好像忘了自己是女人,对恋爱和结婚全不在念。她跳出家庭,就一心投身社会,指望有所作为。她留美回国,做了女师大的校长,大约也自信能有所作为。可是她多年在国外埋头苦读,没看见国内的革命潮流;她不能理解当前的时势,她也没看清自己所处的地位。如今她已作古人;提及她而骂她的人还不少,记得她而知道她的人已不多了。
一九八三年发表
① 中英对照,在商务印书馆出版的《英文杂志》(English Student)第一卷第一期起连载,后由商务出单行本。
② 日本友人中岛碧教授据该校保存的资料查明是 1913 年。
③ 即活买,期满卖主可用原价赎回。
婚约-赫尔曼·黑塞
========================
婚约-[[赫尔曼·黑塞]]
-----
<<<
张佩芬 译
<<<
在希尔兴街有一家不大不小的布店,它和附近几家店铺一样,还没有受到时髦风尚的影响,因而博得好评。每个顾客离开时,即使是二十多年经常光临的老顾客,店员们也都要说一声:“请您下次再来光顾。”有时候,来了几个上年纪的老太太,要按照旧尺寸购买缎带和花边,他们也就拿出旧码尺来接待。负责接待的是布店主人尚未结婚的小姐和一个雇用的女店员,老店主本人也是从早到晚在店堂里,虽然从不开口说话,但却总是忙碌不停。他将近有七十岁,个子矮小,脸色很红润,灰白的胡子修剪得短短的。他那也许早已秃顶的头上终年戴着一顶浆得笔挺的圆帽子,上面用十字布绣着花朵和花纹。他叫安德雷斯·翁格尔特,是这个城里一位忠厚可敬的老绅士。
这位沉默寡言的矮小商人看上去毫无特殊之处,数十年来总是这个样子,固然现在年已老迈,可当年青春年少时也是如此。当然,安德雷斯·翁格尔特也有过少年和青年时代,若是问问老一辈人,你就能知道,他从前的绰号叫“矮子翁格尔特”,背着他,人人都这么叫。大约三十五年前,他甚至有过一段“逸事”,如今虽已无人谈说,当年在盖尔贝绍尔却是家喻户晓的,这件事就是他订婚的经过。
年轻的安德雷斯早在学生时代就不喜欢说话和社交活动,他不论在哪儿总觉得自己是多余的人,总觉得人人都在注意他,因而非常小心和拘谨,对每一个人都很谦逊和礼让。对老师,他深深地尊敬,对同学,是又羡慕又害怕。人们从未看见他在街上或游戏场里玩耍,只是偶尔才见到他在河里游泳。冬天,一看见有孩子手里攥着一把雪,他就赶紧蹲下去缩起身子。他常常在家里心满意足地、文气地玩着姐姐留下来的布娃娃,或者在店堂里用秤称面粉、盐和沙子等等,把它们装进小口袋里,又倒出来,又重新装好,又再称一称,就这样交替反复地玩着。他也很高兴帮助母亲做一点轻活儿,替她采购点东西,或者在院子里寻找爬在莴苣上的小蜗牛。
他的同学们确实常常惹他,捉弄他,他却从不生气,几乎是毫不在乎。总而言之,他生活得无忧无虑,简直可以说心满意足。他在朋友间既然没有发现友谊和类似的感情,也无法和他们交往,就把友谊统统给了布娃娃。他的父亲早已故世,他又是一个遗腹子,因此,母亲对他期望很高,却又非常放任他。这种一味的溺爱中多少带着点怜悯的成分。
这种平平庸庸的情况一直持续到小安德雷斯离开学校,在市区的迪尔兰姆商店实习一年期满为止。这时候他十七岁,他那渴望温情的心灵开始走向另一条道路。腼腆胆小的安德雷斯开始张大眼睛凝视姑娘们,在心里筑起了爱女性的圣坛,他的爱情道路越是坎坷不平,爱情的火焰越是旺盛炽热。
他有很多机会结交和看见年轻的姑娘们,因为他实习期满后就到伯母的布店工作,他是未来的继承人。每天每日都有小姑娘、女学生、年轻的姑娘和老小姐、女仆和妇女们来来往往,挑选花边或刺绣品,有的夸奖有的挑剔,有的讨价还价,有的买好了货物又回转来调换。安德雷斯对她们个个都殷勤接待,他不停地开关抽屉,上上下下爬高凳,一会儿打开布匹,一会儿折叠包装,一会儿又填写订单,回答价格,每个星期他都要爱上一个不同的女顾客。他红着脸夸奖自己的花边和毛料,用颤抖的手填写账单,当年轻漂亮的小姐傲慢地走出店铺时,他手扶着门框,心里别别跳动,口里念叨着:请下次再来光顾。
为了讨好取悦他所爱慕的美女们,安德雷斯开始注意自己的修饰和举止风度。每天早晨都小心地梳理他那明亮的金发,衣服和衬衫总是十分干净,焦急地盼望他那迟迟出现的胡子生长茂密。他学会了一套接待顾客的高雅姿态,学会了递送货物时把左手平放在柜台上,一条腿微微弯曲,只用一条腿支撑着身体,就连笑容也大有讲究,他的微笑已能焕发出内心幸福的光辉。此外他还经常搜集美妙的新词汇,大都是些副词,但他尽量使它们听来新鲜而有意义。他自幼不善辞令,羞于张嘴,从来很少讲出主语、宾语都很齐全的句子,于是便用这种特别的语句来加以补救,他习惯于说些毫无意义和听不懂的话,企图冒充自己善于辞令。
如果有人对他说:“今天天气真好。”矮子翁格尔特就回答:“的确……啊,是的……然而,……对不起……总之……”当一个女顾客问他,这块布可以拿走了吧,他就这么说道:“噢,请吧,是的,毫无问题,是这样,完全正确。”如果有人问他身体可好,他就回答:“非常感谢……当然很好……十分健康……”在特别重要和庄严的场合,他免不了说些“虽然如此,总而言之,绝不可能”之类的话。说话的时候,他的全身,从倾斜的脑袋直至支撑着身体的脚尖,都表现出全神贯注、十分殷勤的样子。但表现得最充分的是他那按比例看来过长的脖子,它又细又瘦,青筋毕露,还点缀着一颗大得惊人的、转动着的喉结。当这个瘦小的店员用这些支离破碎的话回答别人时,人们得到的印象是他的脖子占了身长的三分之一。
大自然造物绝不会毫无道理。翁格尔特那巨大的脖子虽然和他的拙劣口才不相配,但倒是一个热情的歌手非常合宜的特征。翁格尔特极其热爱唱歌。不论在说那些最成功的客套话时,还是在表演最美妙的商人姿态时,还是在婉转述说“总而言之”,“倘若如此”时,在他内心深处引起的快感总不如唱歌的实际。这种才能在学生时期被隐藏着,进入青春期后便逐渐扩展开来,虽然只是偷偷摸摸地演唱。如果他并非极端秘密地享受内心的喜悦和艺术,那么这种态度就与翁格尔特一贯腼腆羞怯的本性不一致了。
晚上,从饭后到就寝前一小时之内,他躲进自己的房间,在黑暗里唱起歌来,深深陶醉于抒情的曲调之中。他的声音可算是男高音,功夫不够之处就努力以情感来弥补。他的眼睛洋溢着湿润的光泽,聪明的脑袋微微后仰,喉结随着歌声上下起伏。他最爱唱的歌曲是《当燕子归去的时候》,唱到“别了,啊,悲伤的离别”这一段歌词时,就拖长颤抖的声音,有时候眼里还噙满泪珠。
他在经商方面进步很快。他原来计划再到大城市去磨练几年,但是他很快就成了他伯母商店里的得力帮手,店里再也少不了他,何况他又是这家铺子日后的继承人,它将保证他一辈子的物质福利。可是安德雷斯的心却渴望着别的东西。尽管他含情脉脉、彬彬有礼,但在年轻姑娘,尤其是那些美貌的姑娘眼中,他只是一个滑稽人物而已。一连串的失意之后,他对所有的姑娘都表示中意,只要哪一位稍稍向他俯就一步,他就愿意娶她。但是没有一个姑娘向他俯就,虽然他谈吐高雅,他的盥洗室里摆满了讲究的用品。
有一个人倒是例外,但他独独对她毫无所觉。她就是波拉·基琪尔小姐,大家叫她琪西波蕾,她一直对他很友好,也非常关心他。她当然并不年轻,也不算漂亮,比他年长几岁,可以说很不起眼,但却是一个勤劳忠厚的姑娘,出身于一个富裕的手工业工人家庭。他们在街上邂逅,只要安德雷斯向她打招呼,她总是亲切诚恳地答礼;她来布店采购时,也总是和气、朴实、客客气气的,使接待工作又轻松又省力。而她却把安德雷斯那套商人的殷勤款待看作是一片真情。总而言之,他看她只觉得不讨厌,可以信赖而已,此外就无所谓了。她属于那少数不在他心上的未婚少女之一,她离开店铺时也从未令他惘然若失过。
为了讨好姑娘们,他忽而寄希望于精致的新皮鞋,忽而又把希望寄托在一条漂亮的围巾上,对他那正在慢慢长出来的胡子更是珍惜万分。最后他还从一个旅行商人手里购买了一只镶着一粒大宝石的金戒指。当时他已经二十七岁了。
一直到了三十岁上,他还只是怀着渴望在婚姻港口的远处逡巡迂回。母亲和伯母认为有必要插一手以促进事情的进展。于是那位上了年纪的伯母就表示说,她希望在自己还活着的时候就把店务移交给侄儿,但是必须在他和本地一个品行端正的女孩子举行婚礼之后。这也正是他母亲的心意。她多方考虑后,认为必须让孩子参加一些社团活动,可以多接触一些人,也能学学怎样和女孩子交往。她知道他非常喜爱唱歌,便想由此作为开端,她建议他报名参加一个歌咏团。
安德雷斯虽然讨厌社交活动,却也首肯了。不过他认为与其参加歌咏团,不如参加教堂的合唱队,因为他更喜欢严肃的音乐。其实真正的原因是玛格丽特·迪尔兰姆也参加了教堂合唱队。她是安德雷斯从前实习一年时的商店老板的小姐,是一个活泼美丽的姑娘,年龄只有二十岁多一点儿,安德雷斯最近爱上了她,因为一段时间以来他没有遇见年龄相当的未婚姑娘,至少是没有漂亮的姑娘。
母亲没有理由加以反对。教堂合唱队确实不如歌咏团那么热闹,也不举办那么多社交晚会,但是这里的会费便宜得多,再说参加的姑娘又都是好人家出身,在平常练习和正式演出时,安德雷斯有很多机会接触她们。于是她立即带他来到合唱队主持人家中,主持人是一位上了年纪的老教师,他亲切地接待了他们。
“啊,翁格尔特先生,”他问,“您想加入合唱队?”
“是的,的确,请……”
“您从前学过唱歌吗?”
“噢,是的,不过似乎……”
“好吧,我们试试看。请您唱一首您能背下来的歌,哪一首都行。”
翁格尔特像孩子一般满脸通红,一句也唱不出来。但是老教师再三要求,最后几乎都快生气了,安德雷斯才压制住恐惧,望望静坐在一旁露出失望神色的母亲,唱起一首他所喜爱的歌曲。由于心神不宁,第一节他就唱错了拍子。
老教师向他示意够了,并且客气地说道,他诚然唱得不错,看来很能掌握感情1,不过似乎更适于表现世俗的音乐,他何不到歌咏团去试一试呢。翁格尔特先生正要结结巴巴回答,他的母亲急忙插嘴替他说情:她知道这孩子唱得确实很好,只是今天有点儿紧张,若能让他参加,她真是感激不尽。歌咏团是另一码事,不够高雅。而她每年对教堂也都有捐赠,简而言之,好心的老先生至少要给他一段练习的时间,然后看看他此后的成绩。老人再次劝告他们说,唱圣诗并不是什么有趣的事情,站在唱诗坛上练习无疑也不会舒服,可是最后还是母亲的滔滔雄辩获得了胜利。三十多岁的男人竟然申请参加合唱队,而且由母亲保护着前来,老教师活了这么大年纪也是头一回碰上。这样的成年人参加合唱队确实非同寻常,也令人不安,但是这件事却使他暗暗感到高兴,当然不是为了音乐的缘故。他告诉安德雷斯参加下一次排练,然后微笑着送他们出门。
星期三晚上,矮子翁格尔特准时来到练习室。大家正为复活节练习大合唱。陆续来到的男女歌唱家们都向这位新会员亲切问好,人人显得非常愉快和开朗,这使翁格尔特也感到快乐。玛格丽特·迪尔兰姆也来了,她也微笑着向他打招呼。虽然好几次背后传来窃笑声,但他早已习惯于被人看作有点滑稽的人,这也就不以为耻了。使他惊讶的是举止严肃的琪西波蕾也在座,不久他又发现她竟是最受重视的歌手之一。她过去对他的态度一直是和蔼可亲,现在却对他出奇的冷淡,似乎很讨厌他也挤到这里来。但是琪西波蕾和他又有什么相干呢?
练唱时,翁格尔特极其小心。幸而学校里学的那套乐谱常识他还大致记得,尚可对付着跟在别人后面一节节往下哼哼。至于整首歌就完全没有把握了。他满怀忧虑,生怕走了调。他的犹豫紧张使教师感到好笑,也引起了他的同情,甚至在临别时,教师还勉励他说:“坚持学下去,时间一长就会有进步的。”不过那天晚上安德雷斯已经很满足,他的位置挨着玛格丽特,可以恣意欣赏她的美貌。他又想到礼拜天前后那几次正式排练中,男高音歌手在练习坛上的位置恰好排在姑娘们后面,一想到整个复活节期间都可以呆在迪尔兰姆小姐身边毫无拘束地注视她,安德雷斯不禁满心喜悦。可是自己个子太矮,站在其他男歌手中间可能什么也看不到,想到这里又不免十分烦恼。他鼓起勇气期期艾艾地向另外一个男歌手诉说自己今后在练习坛上的困难处境,当然并没有说出令他苦恼的真正理由。这位同事就微笑着安慰他说,一定帮他找一个最好的位置。
排练一结束,大家匆匆告别后就各自回家了。有几位先生陪送女士回家,另有几个人结伙去了酒店。翁格尔特独自一人可怜巴巴地站在昏暗的院子里目送着别人,玛格丽特的离去尤其使他感到怅然。琪西波蕾从他身边走过,他一拿下帽子,她就说道:“回家吗?我们同路,可以一起走。”他很感激,两人并肩穿过三月天阴冷潮湿的街道回到家中,除了互相道别外,一路上什么话也没有说。
第二天,玛格丽特·迪尔兰姆来到布店,他赶忙亲自接待。他挥动尺子就像舞动小提琴弓一般,抚摩各种布料都像摸着了丝绸,每一项小小的服务,他都殷勤周到,心中暗暗希望,她会和他谈几句关于昨天晚上,关于合唱队,关于排练的事情。她果然谈了。她在跨出门口时问道:“翁格尔特先生,我真没想到您也喜欢唱歌。您唱了很久了吧?”当他心里怦怦跳着,吃吃地回答“是的……应该说……请原谅”时,她已略略一点头在街上消失得无影无踪了。
“瞧着吧,瞧着吧!”他暗暗思忖着,心里编织着未来的美梦,生平第一回把纯毛饰带和半毛饰带放错了地方。
复活节即将来临,和往年一样,在耶稣受难节和复活节都有合唱队的演出,因而这一周内要排练好几次。翁格尔特总是准时到达,他费尽心机不惹人讨厌,对每一个人都尽量讨好。只有琪西波蕾似乎对他不太满意,这使他感到不快,因为她终究是他可以完全信赖的唯一的姑娘,而且通常总是和她结伴回家的,尽管他不时下定决心想陪送玛格丽特回家,但始终没有勇气实现这一愿望,所以总和波拉同行。第一回他们在路上没说一句话。第二回基琪尔就诘问他,为什么如此沉默寡言,难道害怕她吗?
“不是的!”他吃惊地结结巴巴道,“不是这样……不如说……当然不是……相反的。”
她轻声笑了,又问道:“唱歌的味道怎么样?很有趣吗?”
“当然是的……非常的……事实如此。”
她摇摇头轻声说:“难道真的不能和您好好谈话吗,翁格尔特先生?您说话怎么总在兜圈子?”
他困窘地看着她,口吃得更加厉害了。
“我这么说是好意,”她接下去说。“您说是吗?”
他用力地点头。
“那么好吧!您除了会说‘怎么!总之!对不起!’诸如此类的话外,其他话就不会说了吗?”
“啊,我会说的,虽然……实际上。”
“您看,又是‘虽然!实际上!’请告诉我,您晚上和母亲、伯母闲谈时说的是德语吧?您和我以及别人也这么说话就可以了。人们说话都应该有条有理,您不想这样吗?”
“当然我也想这样……的确如此……”
“很好,您还是很明白的。我现在可以和您谈谈了,有一些话我一直想跟您谈一谈。”
于是她不管他是否习惯,就和他谈开了。她说,他既然不擅长唱歌,参加合唱队岂不反常,图什么呢?再说那里又都是些比他年轻得多的人。在那里,人们经常用各种方式拿他当笑料,难道他毫无察觉吗?她的谈话内容越是使他感到屈辱,他就越是感到这番劝告确是出于好心和友善。他几乎要哭出来,不知是该冷淡地谢绝呢,还是该衷心地感谢。这时他们已走到基琪尔家门口。波拉向他伸出手去,并且诚恳地对他说道:
“晚安,翁格尔特先生,别以为我是恶意,我们下次再继续谈吧,好不好?”
他昏昏沉沉回到家里。她那番直言不讳的话实在令他痛心,但是居然有人如此友好、诚恳、好心地同他谈话,这还是第一次,也确实使他感到安慰。
在下一次排练后的归家途中,他已能用普通的话语和她交谈,也就是说同日常和母亲谈话时一样。这一成功大大增添了他的勇气和信心。再下一个晚上,他甚至试图向她表白自己,他几乎就要说出迪尔兰姆小姐的名字了。但他终于没有说出口,因为他想波拉不可能帮助他的。波拉确实没有让他说完。她突然打断他的自白,说道:“您想结婚了吧,是不是?这才是您应该做的聪明事。您是到结婚的年龄了。”
“年龄是大了一些,”他悲哀地说。但对这话她仅仅是一笑而已,因而他只得毫无慰藉地回去了。再下一次他又把话题引到这方面来。波拉只是对答说,他必须知道自己究竟想同什么人结婚;按他在合唱队扮演的角色而言,显然不会对事情有任何促进,因为年轻的小姐无论如何也不会挑一个被大家当作笑料的人来做自己的爱人的。
这几句话使他的心灵深处痛苦万分。此时紧张筹备着的耶稣受难节即将来临,翁格尔特将要生平第一次随着合唱队登上乐坛。那天早晨他特别细心地穿好衣服,戴上大礼帽,提前来到了教堂。找到给他指定的位置以后,他向那位曾经答应帮他找位置的同事再一次提出了要求。事实上那一位显然没有忘记这件事,他向奏风琴的乐师招招手,那个人会心地笑着搬来一只小木箱,放在翁格尔特所站的位置上,要他站上去,于是这个小个子不论想看人,或者被别人看,都与身材最高的男高音歌手处于同等地位。不过这么站着既费劲又危险,他必须精确地保持身体的平衡,否则就可能跌落到站在栏杆边的姑娘们下面去,就要跌断腿,因为风琴前面是一道狭窄而陡直的台阶,一直往下就是教堂大厅,想到这里他不禁汗流如注。但是他也有高兴之处,美丽的迪尔兰姆小姐紧挨着他,他的两只眼睛正好对着她的颈项。当合唱和全部祈祷仪式结束时,他感到自己已经筋疲力尽。待到大门洞开,钟声敲响时,他不由得深深出了一口气。
第二天琪西波蕾指责他说,他站在垫高了的位置上还那么洋洋自得,简直成了笑柄。他保证道,今后决不再以自己的矮小为耻,不过明天的复活节演出还需要最后使用一次小箱子,为了不至于使那位替他效劳的先生伤心。她也不好给他点明,那一位先生搬来箱子只是想戏弄他而已。波拉无可奈何地摇摇头,对他的愚笨大为生气,同时也为他的纯洁善良所深深感动。
星期天复活节早上,教堂合唱队的演出较前一天的更为庄严。在严肃的音乐演奏过程中,翁格尔特只顾在小箱子上拼命维持平衡。合唱临近结束时,他吃惊地感到自己脚下的箱子在摇晃,大有散架的趋势。他别无他法,只能一动不动地站着,以免滚落到台下去。翁格尔特渐渐缩起身子,满脸痛苦,发出轻微的呻吟声,除了感到灾难和不幸将要来临外,其他什么也不想了。最后总算完了,他安然无恙地跳到地上,指挥、教堂大厅、合唱席以及金发玛格丽特的漂亮颈项都从他的眼帘中消失了。幸运的是,整个教堂中,除了正在唱歌的男歌手外,只有一部分坐在附近的男学生看到了他这一幕。富于感染力的复活节歌声越过他蜷曲的身子,欢乐地高高飞翔而去。
风琴师奏完终曲后,人们纷纷离开了教堂,只有合唱队的队员们还站在台上互相交谈着,因为按照往年的先例,在复活节的次日,合唱队都要举行盛大的郊游。安德雷斯·翁格尔特对这次郊游早就寄托了很大希望。这次他甚而有勇气询问迪尔兰姆小姐是否也去,并且问话时居然没有口吃。
“是的,我当然去,”漂亮姑娘平静地回答,然后又添了一句:“刚才您不难受吗?”说着忍不住想笑,于是不待他答话就急忙逃走了。这一幕恰好落在波拉眼里,她的同情和严肃的目光更使翁格尔特困惑不解。他的炽热的勇气也骤然重新冷了下来。若是他不曾把郊游的事告诉过母亲,而且他母亲不曾要求同行的话,那么他现在就会放弃郊游、合唱队以及一切希望。
复活节的星期一,天气晴朗,天空一片碧蓝。下午两点,合唱队的全体人员带着亲戚朋友几乎都到了,他们先在城市郊区的落叶松树林下集合。翁格尔特也偕母亲同来了。上一天晚上他向母亲坦白承认自己爱上了玛格丽特,但是希望渺茫。母亲如果在郊游时助他一臂之力,也许尚有一线希望。她极愿自己的孩子获得称心的爱人,但是她觉得玛格丽特过于年轻,过于漂亮,和他并不匹配。当然试一试也无妨,最要紧的是让翁格尔特尽早娶亲,以便接管店务。
山路陡直险峻,大家爬得很累,已经没有余力唱歌了。尽管如此,翁格尔特太太却仍然是精力充沛,呼吸通畅,并对她儿子今后数小时内的举止行为作了谆谆教诲,然后又找到迪尔兰姆太太兴高采烈地谈起来。玛格丽特的母亲爬山爬得气喘吁吁,一边听着有趣的开心事情,一边回答着必须回答的问话。翁格尔特太太从美妙的天气开始,谈到了教堂音乐的可贵之处,又称赞迪尔兰姆太太气色颇佳,接着把玛格丽特迷人的春装夸了一通。半路上为了化妆而停留片刻后,翁格尔特太太又娓娓叙述了她妯娌的布店近年来所取得的惊人成就。迪尔兰姆太太听到这里也少不了要夸奖年轻的翁格尔特先生几句,说他几年前在迪尔兰姆先生家见习时,她丈夫就已发现和肯定了安德雷斯的风趣和经商能力。这几句奉承话使得做母亲的心花怒放,她叹息道,当然,安德雷斯很是勤勉,所以店务才能如此扩展,如今这家华丽的商店已经等于是他的产业了,可惜安德雷斯对女性太腼腆羞怯。他并非不喜欢结婚,也不是缺乏成家的品德,而是太缺少自信心和行动的勇气了。
迪尔兰姆太太开始安慰这位忧心忡忡的母亲,话题自然而然引申到她女儿身上,她倒还没有替女儿考虑得这么远,但是她敢保证,城里所有未婚的小姐都会愿意和安德雷斯联姻的。这些话让翁格尔特太太觉得心里像喝了蜜糖水一般甜丝丝的。
这时候玛格丽特和一伙年轻人已经走远了,翁格尔特也加入了这一小群最年轻最活泼的人的队伍,尽管他由于腿短,要跟上他们得使出浑身的力气。
今天大家对他特别友好,因为这个有着一双钟情的眼睛、胆子又极小的矮子对这群淘气鬼来说,真是送上门来的玩意儿。连美丽的玛格丽特也参与其事,假装正经地一次次把这个单恋者拉到身边谈话,害得他神魂颠倒,结结巴巴地语无伦次。
这种戏弄并没有维持多久。可怜的小伙子逐渐发觉大家在千方百计地拿他当消遣,他本想给予报复,但最后还是沮丧地放弃了这个念头,并竭力装出什么也没有察觉的样子。每隔一刻钟,这伙年轻人的兴致就高涨一分。而安德雷斯对这些向他倾注的种种挖苦、嘲弄和打趣感觉得越明白,就越是故意哈哈大笑。末了,这伙人中有一个身材高大的鲁莽的助理药剂师,开了一个非常粗鲁的玩笑,从而结束了这场闹剧。
他们恰巧经过一棵美丽而古老的橡树下面,这位药剂师说,他想试试能否用手攀住这棵高大橡树的最低的那根树枝。他纵身跳了许多次,但总是够不着它,围成半圆形看他表演的观众开始嘲笑他。他灵机一动,心想,何不找个替身当靶子,这样自己就可以挽回面子了。他猛然转身抓住矮子翁格尔特的身体,然后把他高高举起,同时叫他抓住那根树枝,要他紧紧抓住不放。翁格尔特为这次突然袭击所激怒,但在半空中摇摇晃晃的实在怕人,他只好攀住树枝,紧紧地抓着不放;那人一看到他已攀住树枝,便立即松了手,只剩下翁格尔特孤零零地吊在树上,在这伙人的哄笑声中可怜巴巴地蹬动双腿,发出愤怒的尖叫声。
“放我下来!”他大声尖叫。“你们赶快放我下来啊!”
他的声音嘶哑,感到受了彻底的打击,受了永远无法洗清的奇耻大辱。而那个药剂师还提议说,罚他表演一个节目才行。大家又都兴高采烈地随声附和。
连玛格丽特·迪尔兰姆也叫嚷道:“一定要表演完了才能下来。”
事到如今他也无法反抗。
“好吧,好吧,”他嚷道,“快点说吧!”
那伙捣蛋鬼简短地提了要求,翁格尔特先生参加教堂合唱队已有三个星期,但是还没有人听见过他的歌声,他若不给在场的人唱一支歌,就不让他脱离目前的险境。
话音未落,安德雷斯已经唱起来,因为他觉得力气快用完了。他呜咽着唱起了《请想一想那个时刻》——第一节尚未唱完,他就支持不住松开了手,尖叫着摔了下来。大家都吓得大惊失色,倘若他摔断了腿,那岂不太令人后悔和难过了吗?可他安然无恙地站了起来,捡起掉落在身边沼泽地上的帽子,小心翼翼地再戴到头上,一言不发地又折回刚才走过的路上。拐过第一个弯以后,他就在路边坐下略事休憩。
那个药剂师内疚地悄悄跟在他后面,想要请他原谅,翁格尔特却不想理他。
“我真是十分抱歉,”他又一次请求说,“我实在不是恶意。请您原谅,请回到大伙儿这里来吧!”
“事情已经完了,”翁格尔特说,示意他走开,那个人只好失望地离去。
片刻之后,第二批年龄较大的人,包括两位母亲在内,也慢慢地走近了。翁格尔特走到母亲身边说道:
“我要回去了。”
“回去?为什么呢?出了什么事吗?”
“没有。我现在已完全明白,再呆下去就毫无意义了。”
“真的吗?你求婚遭到了拒绝吗?”
“不是的。不过我想倒不如……”
她不让他说完话,拉着他向前走。
“别傻了!一起走吧,事情会好起来的。喝咖啡的时候我安排你坐在玛格丽特身边,打起精神来。”
他愁容满面地摇摇头,然而却服从了,跟着母亲继续往前走。琪西波蕾打算同他谈一谈,看见他目光呆滞,沉默无言,满脸不快的神色,只好打消了这个念头,当着众人的面翁格尔特还从不曾露出这种神色过。
半小时后,大家抵达了郊游的目的地——一座小小的林中村庄,这里有一家以咖啡闻名的饭馆,饭馆附近还有一座古代强盗骑士城堡的遗迹。在饭馆的小花园里,那伙早已抵达的年轻人正在兴高采烈地做游戏。现在他们把桌子从屋子里搬出来,依次排齐,又搬来了椅子和长凳;然后铺上干净台布,摆上了杯、碟、咖啡壶和面包点心等等。翁格尔特太太没有食言,她把儿子的座位安排在玛格丽特身边。而他并没有利用这有利条件,始终郁郁不乐地沉浸于自己的苦恼之中,木然地用汤匙搅拌着已经冰凉的咖啡,虽然母亲向他频频示意,他却顽固地沉默着。
喝完第二杯咖啡后,年轻人中的头儿建议散步到城堡废墟去,在那里做游戏玩耍。于是青年男女们在一片喧嚷声中纷纷离席,玛格丽特·迪尔兰姆也站了起来,动身前把她那镶着珍珠的漂亮提包交给了垂头丧气坐在一旁的翁格尔特,并说道:
“翁格尔特先生,请您替我保管一下,我们要去玩了。”他点点头,接过提包。她竟认定他一定留在老年人身边,不去参加他们的游戏,这一冷酷的现实已经不再令他吃惊了。他只是惊讶自己怎么没能一开始就察觉这一切:刚去排演合唱时大家异乎寻常的欢迎,那只小木箱事件以及其他许多事。
年轻一辈人走后,留下来的人继续喝着咖啡,闲聊,翁格尔特悄悄离开座位,穿过花园后面的田野,朝森林走去。他手里拿着的小提包在阳光下闪闪发光。他在一棵新砍的树木残干前停住脚步。他掏出手帕铺在尚很潮湿的木头上,坐了下去,然后用双手托着头,陷入了悲哀的沉思,当他的目光再度落到那只色彩斑斓的手提包上时,这时,随着一阵清风,耳中又听到那伙年轻人的欢叫和吵嚷声,他便深深垂下他那沉重的脑袋,开始压低声音,孩子一般地哭泣起来。
他就那样坐了一个多钟点。他的眼睛已经恢复常态,激动的情绪也已消逝,只是比往常更深切地感到自己处境的不幸和一切努力的枉然。这时他听见一阵轻轻的脚步声向他移近,随后是一阵衣服的窸窣声,还没等他跳起来,波拉·基琪尔已经站在他身旁了。
“怎么孤零零一个人?”她开玩笑似的问。他不作声,她就细细审视他的脸,突然神情严肃地用女性特有的温柔问道:“发生了什么事?您遭遇不幸了吗?”
“没有,”翁格尔特轻声回答,不再考虑任何修辞。“没有。我只是看出了自己和大家不相适应。我成了他们的小丑。”
“是吗,恐怕没有那么严重吧……”
“不,事实如此。我是他们的小丑,尤其是小姐们的小丑。由于我善良老实,大家就认为我笨。您说得对,我本来不应该参加合唱队的。”
“您可以退出呀,这样不就万事大吉了吗?”
“我当然要退出的,我恨不得今天就退出呢。但是还远远没有万事大吉。”
“为什么呢?”
“因为我已成了姑娘们的笑料。因为完全不可能有人对我……”
他几乎又要大声哭泣。她便柔声问道:“不可能有人对您怎么样?”
他抽抽噎噎地接着说:“因为不可能有任何姑娘再尊重我,并且诚恳地对待我了。”
“翁格尔特先生,”波拉慢慢说道,“您不认为您错了吗?难道您认为我也不尊重您,待您不诚恳吗?”
“当然您待我很好。我也相信您仍旧尊重我。可这不是一码事。”
“好吧,那是什么事呢?”
“我的上帝,我简直说不出口。我一想到别的人都比我幸福时,我几乎要疯了,我毕竟也是一个男人呀,是吗?但是有谁……愿意和我……愿意和我结婚呢!”
沉默很久以后,波拉才又开口说道:
“嗯,那么您曾经向某一个人求过婚,问她愿不愿嫁给您吗?”
“求婚!没有的事。还用得着求婚吗?我早就明白谁也不会嫁给我。”
“那么您是期望着姑娘们来到您跟前说:‘啊,翁格尔特先生,您若和我结婚,我将感到非常高兴!’当然,那样的话,您就等着吧。”
“我明白的,”安德雷斯叹了一口气说。“波拉小姐,我的意思您应该明白。只要我知道有谁认为我好,而且稍稍真心待我,那么我就会……”
“那么您也许会宽宏大量地向她眨眨眼,或者用手指召唤她!我的上帝,您是……您真是……”
她边说边跑开了,没有发出任何笑声,而是噙着眼泪。翁格尔特没看见她流泪,却听到她的声音有些异样,也觉得她的跑开有点反常,便跟着追来,追上之后,两人在默默无语中突然拥抱在一起接了吻。矮子翁格尔特就这样订下了婚约。
当他羞涩地,同时又勇敢地挽着未婚妻的胳膊回转饭馆的花园时,大家已准备动身离开,只等待他们两人了。在一片骚动、惊讶、叹息和祝贺声中,美女玛格丽特走到翁格尔特面前,问道:“哎唷,您把我的提包放在哪儿啦?”
未婚夫听了一愣,急急忙忙又折回树林里去,未婚妻也跟着跑去。就在他方才独坐哭泣的地方,手提包正在枯叶堆里闪着光,波拉说道:“我们回来一次正好,你的手帕也掉在这里呢。”
(1908)
1 原文是意大利文con amore,意谓“富于爱慕之情”。
[[托马斯·曼文集·中短篇小说选 - 火车事故 by 托马斯·曼|https://www.kanunu8.com/book2/10973/196103.html]]
========================================
<>
托马斯·曼文集·中短篇小说选 火车事故
作者: [[托马斯·曼]]
-----
讲个故事吗?但我没什么可讲的。好,就讲一个吧。
有一次,大约在两年前,我经历过一场火车事故——这次事故至今还历历在目。
这并不是一次什么了不起的事故,车厢没有像手风琴那样折叠起来,也没有“血肉模糊的大堆尸体”等等,这些都是没有的。但毕竟是一次不折不扣的真正火车事故,况且还是在深更半夜发生的呢。不是每个人都有过这样的经历,所以我就尽我的能力讲给大家听吧。
那次我应文学爱好者的邀请,乘火车到德累斯顿去。可以说是一次文艺性质的旅行;像这样偶尔出门旅行一趟,我倒挺乐意。出入交际场所,作报告,在喝彩的听众面前炫耀一番,才不愧为威廉二世的臣民。而且德累斯顿很美丽(特别是动物园);然后我还打算去“白鹿”疗养十天到两个星期,如果疗养效果好,引起灵感,还想写点东西。于是我就把手稿和笔记材料——这是棕色牛皮纸包的、用巴伐利亚的彩色绳子捆起来的一个大包——放在箱子的底层。
我喜欢舒适地旅行,特别是当别人替我付旅费时。这次乘卧铺车厢,头等包厢前一天就预订了,一切都安稳妥当。可是就像每次出门时那样,我仍旧有些忐忑不安;旅行毕竟是冒险,大凡乘车行舟,我总不大机灵。我明知开往德累斯顿的夜班车照例每天晚上从慕尼黑总站出发,早晨到达德累斯顿。但每当我自己乘这班火车、把我珍贵的命运同它结合起来的时候,这便成了一桩大事。我总消除不了这样的念头:火车只有今天才开,专为我而开。这种违背理智的曲解,当然会引起内心深深的激动。而且,一直到出门时的种种麻烦——像收拾行李、乘载满行李的马车去火车站、到站后托运行李等等——一直到这些事告一段落,我安顿好了自己,感到一切都安稳妥当以后,内心的这种激动才会消逝。随之而来的却是一种舒畅轻松的感觉,思想转向新的事物,陌生的广阔世界展现在玻璃的拱顶外面,脑海里充满各种愉快的期待。
这次也是这样。我重重地酬谢了替我拿随身行李的搬运夫,喜得他脱下帽子,祝我一路平安。随后就抽着晚上的雪茄,站在卧铺车厢过道的窗前,观看月台上的忙乱景象。到处是咝咝的响声、滚动声和奔逐声,还有小贩拖长音调叫卖报纸和点心的喊声。十月傍晚的烟雾中,闪烁着一盏盏像月球似的电灯。两个魁梧的男人把一辆装满大件行李的小车沿着火车拖向前面的行李车。我根据一些熟悉的标志辨出了自己的皮箱。它压在许多行李下面,而在它的底层安稳地放着那珍贵的手稿。“嗯,”我想,“不用着急,它在可靠的人手里!瞧瞧这位列车警卫,他系着皮肩带,蓄着一大把警官式上须,瞪着一双大胆、警觉的眼睛,瞧瞧他怎样叱责那穿破旧黑大衣的老太太,因为她险些儿爬上二等车厢。他象征着国家、我们的慈父、权威和安全。人们不大乐意跟他打交道,他严厉,甚至粗鲁,但可以信赖他,完全信赖他,我的皮箱就好比保藏在亚伯拉罕的怀里一样。”
一位穿裹腿靴和黄色秋大衣的绅士,牵着一条狗在月台上悠然自得地散步。我从来没见过更漂亮的小狗儿。这是一条矮小的哈巴狗,皮毛光润,肌肉发达,满身斑点,养得又娇又乖,就像有时在马戏中看到的小狗一样:它们使出小巧的身子的全部本领,绕着马戏台乱跑,逗观众发笑。这条哈巴狗套着银颈圈,牵它的带子是花花绿绿的皮条编成的。但在它的主人,那位穿裹腿靴、出身准是异常高贵的绅士面前,这一切却黯然失色。他一只眼睛夹着眼镜片,面孔显得更加严峻,但并没有歪扭,上须固执地翘起来,使得嘴角和下巴露出傲慢和刚毅的神情。他不知向雄赳赳的列车警卫打听了什么,而那朴实的人,一看就明白是跟什么人打交道,连忙把手举到帽檐上毕恭毕敬地回答。这位绅士又继续向前走,对他的仪表所产生的效果沾沾自喜。他穿着裹腿靴,迈着坚定的步子,摆出一副冷漠的神情,用刻薄的眼光打量周围的人们和事物。显然,他丝毫没有旅行时那种焦急不安的情绪;对他说来,像旅行这样一桩寻常的事,不是什么冒险。他在生活中逍遥自在,不惧怕它的安排和势力,因为他自己正是这种势力的一部分。一句话,他是一位老爷。我盯着他看,百看不厌。
他觉得时间到了,便上了车(列车警卫这时恰巧把背转向他)。从我背后穿过过道,撞了我一下,却连声“对不起”都不说。多么神气的老爷!但这算不了什么,接着发生的事更为稀奇:这位绅士连睫毛都不眨一眨,就把小狗带进卧车!毫无疑问,这是被禁止的。倘若是我,哪敢带狗进卧车呢!但他凭老爷在社会上的特权,把狗带进去,随手关上门。
吹哨子了,火车头应了一声,列车平稳地开动了。我还在窗旁留恋了一会儿,看见留在后面挥手告别的人们,看见铁桥,看见晃动着的灯光……随后就回到车厢里面去了。
卧车里乘客不十分多;我隔壁一间包厢空着,卧铺没准备好。我决定在那儿安静舒适地看看书,便拿出书来,安顿了自己。沙发上罩着鲑色的丝套子,活动的小桌上放着烟灰缸,煤气灯投下亮光。我抽着烟,看起书来了。
卧车列车员走进来执行任务,要我把车票交给他保管一夜,于是我就把车票递到他发黑的手中。他说话很客气,但纯粹是办公事的口吻,连人们通常所打的招呼“晚安”都省去了,便径自去敲邻室的门。还是不敲它为妙,可要知道穿裹腿靴的老爷睡在那里啊。也许这位老爷不要别人瞧见小狗,也可能他已经躺下睡了,一句话,因为竟有人敢打搅,他就大发起脾气来。是啊,虽然火车轰隆轰隆地奔驰,我还是透过薄薄的墙壁听见他那骤然爆发的粗野咆哮。“怎么啦?!”他嚷着,“别打搅我……兔崽子!”他用了“兔崽子”这同儿,这是老爷、骑士和贵人们用的字眼儿,听起来真够痛快。但卧车列车员采取协商的态度,看样子确是需要拿到那位老爷的车票。为了便于详细观察起见,我进了过道,看见老爷的门终于急骤地打开了一条缝,车票朝着列车员迎面飞出来,飞得又急又猛,正好打中了脸。列车员双手捉住车票,虽然它的一角刺进眼眶,弄得眼泪直滚,还是收拢了两条腿,一只手举到帽檐上,并道了声谢。我胆战心惊地回去看书。
我慎重考虑了一番,究竟有没有理由使我不该再抽一支雪茄,却发现简直没有什么理由。于是,在火车的隆隆响声中,一面看书,一面抽起烟来,感到十分惬意,思想也随着活跃起来。时间慢慢消逝,十点啦,十点半或甚至更晚啦,卧车的乘客全都睡了,我终于决定也躺下去睡。
我站起来,回到卧车室。这是个真正的、奢华的小卧车室,墙上紧贴着皮毯,还有挂衣钩和镀镍的脸盆。下铺铺好了雪白的卧具,被子翻开了一些,好像邀请我钻进去。“啊,伟大的新时代!”我想。躺在这床上,就好比在家里一样,夜里虽有点震动,但结果早上就到了德累斯顿。我去拿网架上的手提包,打算梳洗一番,正伸出两只胳膊,把手提包举在头上。
就在这一瞬间火车事故发生了。我记得清清楚楚,这事好像今天发生的一样。
撞了一下——不过这一“撞”却非同小可。这一撞立刻就令人感到准是凶多吉少,它发出的声响异常恐怖,又是那么猛烈,弄得手提包从我手中飞出去,不知去向,我自己也跌了一跤,肩膀狠狠地撞在墙上。这时简直没有思考的余地。接着,车厢可怕地摇晃起来,摇晃时却有足够的闲暇,可以饱受惊吓。我们都知道,转辙和急转弯时,车厢不免也要摇晃的。但这次摇晃却使人站不住脚,从一边跌到另一边去,心里只等待着翻车。我当时思想很简单,但非常集中,别的什么都不想,只想:“糟糕啦,糟糕啦,糟糕极啦,”一字也不差。此外我还想:“停!停!停!”我知道,只要火车停下来,就比较好办。果然,在我诚恳的无声嘱咐下,火车停了下来。
卧车里一直是死一般的沉寂。现在,恐惧爆发出来。女士们的尖叫同男人们沉浊的惊呼交杂在一起。我听见旁边有人喊:“救命!”毫无疑问,那是方才运用了“兔崽子”这个字眼儿的声音,也就是穿裹腿靴的那位绅士因为恐惧而变调的声音。“救命!”他嘶叫着。我刚跑进乘客拥聚的过道,就看见他穿着丝睡衣,从卧车室里冲出来,站在过道上,惊惶失措地东张西望。“伟大的上帝!”他说,“万能的上帝!”为了表示彻头彻尾的谦逊自卑,或许因而能避免自己的毁灭,他还用乞怜哀求的声音说:“亲爱的上帝……”但突然他改变了主意,决定还是依靠自己,冲向有急救用的斧头和锯子的小墙柜,一拳打碎了玻璃,但看到无法立刻取出来,便置之不顾,疯狂地乱推乱踢,从聚集的乘客当中挤过去,弄得半裸的女士们重新尖叫起来,他终于跳出车厢。
这都是一瞬间发生的事情。现在我才开始感到恐惧:背上有一种发软的感觉,片刻中口沫咽不下去。两手发黑的卧车列车员,红着眼睛,也跑了进来,马上就被众人围住;赤裸着胳膊和肩膀的女士们不停地扭自己的手。
是火车脱轨事故,这人解释说,我们脱轨了。事后证明并不是这么一回事。可是,瞧呀,在这种场合下这人变得健谈了。那公事公办的态度早给他抛到脑后,重大的事件打开了他的话匣子,竟使他亲切地谈起自己的妻子。“今天我还对老婆说:我说,老婆,我觉得今天非出事不可!”现在可不是出事了吗?我们都赞同这一点。说话间,一股不知从哪儿来的浓烟逐渐充满车厢,于是我们决定还是走到外边的夜空下面为妙。
这儿没有月台,我们的车厢显著地倾侧到另一边,所以非要从相当高的踏板上才能跳到路基上去。但匆忙遮盖了裸处的女士们,还是孤注一掷地跳了下去。不久大伙儿都站在轨道中间了。
外面是黑蒙蒙的,但隐约可以看出我们后边这些车厢虽然有点倾斜,却没有什么毛病。可是前面——在十五步或者二十步开外呢!怪不得先前碰撞时响声那么可怕。那儿是一片废墟——走近一些,可以看到废墟的轮廓和闪烁其间的列车员小灯。
那边消息传来了,激动的人们带来了有关情况的报道。我们靠近离雷根斯堡不远的小站,由于转辙的错误,我们的快车跑错了轨道,开足马力撞上停在那里的一列货车的尾巴,把它撞出车站,撞碎了它的后面一部分,自己也受到重创。慕尼黑马菲厂制造的庞大快车引擎报销了,价值七万马克。前面几节车厢几乎完全倾倒,里面一部分坐凳叠嵌在一起。不,谢天谢地,没有人遇难。有人提起一个“被拖出来的”老太婆,但没人见过她。不管怎样,乘客们曾给撞得东倒西歪,孩子埋在行李下面,弄得人心惶惶。行李车粉碎了。行李车怎么啦?粉碎了。
我愣住了……
一个公务员模样的人光着头沿火车跑来。他是站长。他激动地用哭泣的声音向乘客发号施令,要大家守秩序,从轨道上回到车厢里去。但他既没戴帽子,又缺少威严,所以没人理他。可怜的人!责任大概落在他身上。也许他的前途就此完蛋了,他的饭碗因而敲碎了。要是向他询问大件行李的下落,那太不知趣了。
又来了一位公务员,一拐一跛地走来。我一瞧他那警官式的上须,就认出他了。原来是列车警卫,今晚看到的那位大胆、警觉的警卫,他就是国家,我们慈父的象征。他勾着腰,一只手支撑在膝上,踉踉跄跄地走着,除了自己的膝盖以外,对什么也不感兴趣。“唉,唉!”他呻吟着,“唉!”——“喂,喂,怎么啦?”——“唉,先生,我被夹在中间,胸口上撞了一下,只得翻越车顶脱身。唉,唉!”——“翻越车顶脱身”颇有新闻报道的风味,这人平常准是不大用“脱身”这个字眼儿吧。与其说他经历了一场灾祸,倒不如说经历了关于自己遭遇到灾祸的新闻报道。但这对我有什么用呢?看他这副狼狈相,似乎不可能告诉我手稿的下落。这时从废墟那边来了一个精神饱满、神气活现、非常激动的小伙子,我便向他打听大件行李的消息。
“是啊,先生,那里情况怎样,谁也不知道!”听他那口吻好像说:我能侥幸地逃出来,四肢无缺,已该高兴啦。“那里一切都乱七八糟,女人的鞋子啊……”他作了个粗野的手势,表示一切都毁灭了,还蹙了蹙鼻子。“进行清除工作时,会弄清楚的。女人的子啊……”
我发呆了,在深更半夜孤苦伶仃地呆立在轨道中间,肝肠如绞。清除工作!我的手稿成了清除工作的对象。它就这样毁灭了,大概是撕得粉碎,压得破烂不堪。我的蜂巢,我的精致的蛛网,我的巧妙的狐穴,我的骄傲和劳苦,我一生最好的贡献!果真如此,怎么办呢?那已经写好的、已经拼凑铸炼成形的、已经具有生息的手稿,我连一份抄本都没有——更不要说那札记和随笔,那几年来苦心孤诣地收集、搜寻、听取、剽窃的一大堆宝贵资料。该怎么办呢?经过一番内心斗争,我觉得还是重新开始为妙。是的,就像一个低级动物,眼看自己微小的智慧和勤劳所创造的美妙而复杂的果实被摧毁时,却毫不气馁,我也要这样以动物般的耐心,在短暂的惆怅彷徨以后,一切都从头做起,或许这次会省力些……
这时消防队拿着火炬赶来了,火炬的红光投在废墟上。我走向前去看行李车,发现它简直完好如故,行李都没有受到损伤。散乱在那儿的东西和货物,都是货车上的。数不清的一卷卷粗绳,像一片大海一样遮盖了辽阔的地面。
我松了一口气,回去杂在人群中间。他们聊着天,借这场事故互相交朋友,吹嘘,摆架子。有一点似乎可以肯定:全亏火车司机急中生智,在千钧一发的关头扳下急刹车,才免了一场大灾难。否则,据说大家一定会撞得粉身碎骨,整个列车会从相当高的路基向左边滚下去。值得赞扬的司机!他不知在哪儿,谁也没瞧见他,但他的声誉沿着整个火车传播下去,大家都夸奖他,虽然他本人并不在场。“这个人,”一个绅士说,并伸出手向黑夜不知何处指了指,“这个人拯救了我们大家。”人人点头称是。
但我们的列车停在不应当停的轨道上,必须从后面保护它,免得什么火车撞在它尾部。为此,一些消防队员爬上最后一节车厢,拿着沥青火炬站在那儿。先前用女鞋来吓唬我的那个激动的小伙子,也抓起一把火炬,打信号似地晃来晃去,虽然远近连个火车影子都没有。
混乱中又逐渐出现了一种类似秩序的状态。国家,我们的慈父,又恢复了尊严和威信。打了电报,采取了各种措施;一列来自雷根斯堡的救护车,喷着烟雾谨慎地开进车站;装有反射镜的巨大煤气灯架设在废墟上。我们乘客从火车里搬了出来,接到指示,在小站房里等候转车。我们拿着大大小小的随身行李,有一部分人头上还裹了绷带,在当地好奇的居民的夹道迎送中走进候车室,勉强安顿下来。一小时后,我们又给乱塞到一列专车里去。
我买的是头等车票(因为别人替我付旅费),但这对我一点好处也没有。现在每个人都要坐头等车厢,结果头等比别处更拥挤。我找到座位刚一坐下,就发现挤在斜对过角落里的是谁呢?原来是穿裹腿靴、开口就训斥人的那位老爷,也就是我的主人公。他的小狗不在身旁,给人带走了;别人不顾老爷的一切特权,将它关在紧靠车头后面的黑暗牢笼里,它正在那儿号啕呢。这位老爷也拿着一张无济于事的黄色车票,喃喃地怨个不停,说他要抗拒这种共产主义作风,抗拒祸患所招惹的一律平等。但有个人老老实实地回答说,“你有个座就该高兴啦!”老爷只得苦笑着屈服于这可怕的环境下。
靠在两名消防队员身上走进来的是谁呀?原来是位矮小的老太太,一位穿破旧大衣的老妈妈,就是在慕尼黑险些儿登上二等车厢的那位。“这是一等车厢吗?”她不停地问:“真是一等车厢吗?”在大家向她再三保证并为她腾出座位以后,她说了声:“感谢上帝!”便倒在天鹅绒的坐垫上,仿佛现在才得救了似的。
到霍夫已经是五点钟,天亮了。在这儿吃了早饭,然后我调了车,由快车把我连同我的大小行李送到德累斯顿去,时间延误了三个小时。
是啊,这就是我所经历的火车事故。总该有那么一次呀。虽然逻辑家会提出异议,我还是相信最近再碰到这类事的可能性不会很大。
-----
(刘德中译)
火山旅馆-孔亚雷
========================
火山旅馆-[[孔亚雷]]
-----
K到火山旅馆是为了写他的新小说。他是黄昏时到的。当他意识到时——就像有人拔掉了插头——天空已经黑下来。他迈上几级台阶,走进大堂,放下手里的拉杆箱。日光灯照出他拉长的身影。他调整了一下呼吸。空气里有一股淡淡的霉味。四周静悄悄的。他的右边是两张看上去年代久远的米黄色单人皮沙发,沙发之间有一张褐色茶几,茶几上摆着一只白色的烟灰缸。左边墙上挂着一幅火山喷发的油画。油画上方的墙角有一大圈泛黄的水渍。
他拉出行李箱的伸缩杆,拖着它走向前台。轮子在水磨石地面上发出惊人的声响。他把头探进前台,发现一个人脸朝下趴在桌上。他分不出对方是男是女,甚至是死是活。
“嗨。”他低声说,似乎怕吵醒他(或她),虽然他的目的就是吵醒他(或她)。
没有反应。
他又等了一会儿。然后伸手想去碰他(或她),但伸到一半时,他的手停住了,停在半空。他似乎不忍——或者不敢——下手。似乎他不是要叫醒他(或她),而是要掐死他(或她)。他的手慢慢缩回来。
他再次拖动拉杆箱(这次似乎更响),向米黄色的单人沙发走去。他把箱子放到旁边,在沙发上(靠近前台方向的那张)坐下。他点燃一支烟,开始研究对面的油画。
他的房间在走廊尽头。201。更浓的霉味。他扭亮床头灯,在床沿坐下,试了试床垫的软硬。巨大的双人床。然后他站起来,走过去拉开窗帘。双层的落地窗帘,里面是一层白纱,外面是猩红的天鹅绒。他把窗开到最大。外面一片漆黑。一股浓郁的植物气息。没有一丝风。他在窗口站了一会儿。然后进浴室撒了一泡很长的尿。然后,K决定,他要先洗个澡。
跟往常一样,当K冲完淋浴,换上干净内衣,他觉得一切都会顺利。当然,这里说的一切,就是他的小说。他的新小说。他已经在它上面浪费了两年时间。他开始整理箱子。他带的东西并不多。几套换洗衣服。一本《福楼拜书信集》(他只带了这一本书)。一台手提电脑。他把电脑放到狭窄的书桌上。书桌抵着正对床的那面墙,桌子上方挂着一面镜子。他打开书桌上仿羊皮灯罩的台灯。他在书桌前坐下,看着镜中的自己。然后他站起来,小心地把桌子朝窗户方向移动了大约一米。他重新坐下。现在当他抬起头,看见的不再是自己,而是白色的墙壁。
他打开电脑。不,他今天不准备写作。他只是想试一下坐在这里的感觉。他打开“我的音乐”。他点击播放。比莉·哈乐黛。他把音量调低。
他坐在那儿呆呆地听了一会儿,然后站起来,环视了一圈房间。他再次走到窗前。他看着外面。过了一会儿他才意识到,他看不见外面,他只能看见玻璃上反映的自己。
K看着那个女人穿过明亮的餐厅。好几次阳光射到她的黑色连衣裙,那一瞬间她看上去就像被点燃了。一开始他以为她认错了人。当她在他面前停住的时候,K再次确认,是的,她认错人了。他不认识她。他以前没见过她。但问题是她的表情。
“我可以坐这儿吗?”她的声音有点微微颤抖。
K还没反应过来,她已经坐下了。
“我可以抽烟吗?”
他耸耸肩。
即使在点烟的时候,她的眼睛也始终盯着他不放,似乎害怕视线一离开,他就会消失。K尽量让自己显得镇定。他看着奶油色桌布上一个小小的香烟洞。然后他抬起头。
一缕烟雾冒出她丰满的,深红色的,微微张开的嘴唇。
她嘴角浮现出一丝微笑。她半站起来,身体向前倾,两只手臂像蝴蝶翅膀一样展开在桌面上。她的脸靠得如此之近,以至于他产生了一种幻觉:以为她要和他接吻。
她脸上的笑容消失了。
“你来了。”她用耳语般的声音说。
“对不起,”他说,“但我想——”
“麦当劳叔叔在干吗?”她打断他。
“什么?”
“麦当劳叔叔在干吗。”
“我不知道你在说什么。”
她慢慢坐回椅子上。她一只手臂抱着身体,另一只手夹着香烟。她涂着黑色的指甲油。
“不,不,不,”她把头反复摇了几下,“我们没时间开玩笑。你已经迟到了。”
“我想你认错人了。”
她似乎根本没听见他的话。她又深深吸了口香烟,把剩下的一半在烟灰缸里掐断。
她的身体再次倾过来。她看着他的眼睛。
“我再问一遍。”她放低声音,就像要告诉他什么秘密,“最后一遍。麦-当-劳-叔-叔-在-干-吗?”
沉默。传来鸟叫的声音。
“我不知道你在说什么。”K说。
K开始写作。他起得很早。五点半,六点。他喜欢晨光。他一直写到中午。午饭后小睡,然后继续工作。下午三点,他合上电脑,去健身房跑步。跑一个小时。然后是淋浴,晚餐,散步。晚餐时喝一瓶啤酒。散步后偶尔去电视机房看一会儿电视。但大多数时候他还是直接回到房间。听点音乐,看几页《福楼拜书信集》,然后上床睡觉。九点,九点半——他睡得很早。
敲门声。K过了一会儿才转过头,看着门。他的手还放在键盘上。笃。笃。笃。每一声的重量、间隔都完全相等。就像某种乐器。K没有动。他看着门。笃。笃。笃。
“谁?”
没有回答。
K站起来,走到门边。他透过猫眼往外看。没有人。没有任何东西。昏暗的走廊就像被折叠扭曲的时空。
笃。笃。笃。
他的心跳骤然加速。他紧紧捏住球形把手。
笃!笃!笃!
他打开门。
门外站着一个侏儒。
侏儒手里拎着一个白色帽盒似的东西。盒子外面扎着红色的绸带。
“嗨。”他的声音很怪异,尖尖细细,既像孩子又像成人。“你好!一份小小的见面礼。不成敬意。”他举起盒子。
K接过盒子。盒子轻飘飘的,像是空的。
“谢谢。”K说,“——请进。”
侏儒摇摇摆摆地走向角落的两把扶手椅,在其中一把上坐下。他的脚碰不到地,悬空在那里,像孩子一样晃来晃去。K把盒子放到电脑旁边,顺手——就像掩藏什么犯罪证据——合上电脑。
“他们说你是个作家。”侏儒说。
“算是吧。”K在另一张椅子上坐下。
“写小说?”
“写小说。”
“写小说。”他点点头,重复一遍,似乎在确认什么。跟所有侏儒一样,很难看出他的年纪。他比例失调的大头上留着扎成马尾的长发,穿着合体的灰色背带西裤和黑色短袖衬衫。闪亮的黑皮鞋。无论是西裤还是衬衫都棱角分明,好像刚刚熨过。衬衫的纽扣扣到最上面一颗。
“这么说,你不是来自杀的。”
“自杀?”他惊讶地抬起头。
他咧开嘴笑出了声,“这是自杀旅馆,你不知道吗?”
K摇摇头,“为什么?为什么叫自杀旅馆?”
“网上有个秘密的自杀网站,很多人相约到这里一起自杀。你见过那个疯婆子?”
“你是说那个穿黑裙子的女人?”
“对。”
“见过一次。她好像把我当成了另一个人。”
他再次咧嘴笑起来,“她在等跟她约好的人。但那个人一直没来。”他一边笑一边看自己的手掌。干枯的手掌,令人想起某种标本。
“你也住这里?”
“我?不,我住在那边。”他的短胳膊朝窗那边挥了挥,“我住在湖对面的森林里。我在那儿有座小屋。但我有时会到这边来看电视。”
“有时候突然很想看电视。”他继续用他那怪异的嗓音说,“想得受不了。好像不看就会死掉。你明白那种感觉吗?就像毒瘾发作。”说到这里,他像想起了什么。他从扶手椅上灵巧地滑下来,走到K面前。
他从裤袋里掏出一个扁扁的银色盒子。
“哈——让我们来试试这个。”他用欢快的语调说。
“大麻?”K看着侏儒从盒子里抽出一根细长的棕色烟卷。
“不,比大麻更爽。是我从森林里采的一种草。”他用一个看上去沉甸甸的银色打火机把烟卷点着,深深吸了一口,然后递给他。
K接过烟卷,但没有立刻抽。
侏儒站在那儿,看着K的眼睛。他双手扣在背带上,脸上带着骄傲的笑容,似乎对眼前的一切感到很满意。
“别担心,这不是毒品,这只是一种植物。来吧,大作家……对,吸一大口,尽量不要让烟出来,尽量都吞下去……对,就这样……它会带给你灵感,它本身就是灵感……”
K觉得喉咙里一阵辛辣。他又吸了几口。他觉得肌肉哗地放松下来,就像一直被紧紧捆着,而现在有人突然给他松了绑。他靠到椅背上,全身瘫软。他闭上眼睛。就在闭眼的一刹那,他飘起来。他在飞。他可以飞。他可以做任何事。除了一件事:他不能睁开眼睛。
我睁开眼睛。一切瞬间恢复——就像有人插上了插头。窗外的车流声。甜得发腻的英文歌。像巡警一样走来走去的麦当劳服务员。对面的她。
“怎么了?”
“没什么。”我低头喝了一口已经冷掉的咖啡。
“你带笔了吗?”
她从包里拿出一支黑色钢笔递给我。她身上的一切都是黑色的。黑衣。黑包。黑指甲油。黑鞋。甚至,黑内裤。
我用笔在麦当劳广告纸的背后潦草地写了几行,然后叠好塞进裤袋。
我把笔还给她。“又在想你的小说?”她说。
我耸耸肩。我看着她,对她送上无辜的微笑。她没有笑。我分不出她是涂了黑眼影还是黑眼圈。
“没睡好?”
她摇摇头。我不知道那是表示肯定还是否定。她发出一声长长的叹息,然后皱着眉头从包里掏出香烟,抽出一根叼在嘴上。她低头在包里翻来翻去地找打火机。
“这里不能抽烟。”我说。
她的动作僵在那里。僵了两秒钟。然后她抬起头,把嘴里叼着的香烟折断,扔进面前的咖啡杯。她用双手捂住脸。过了一会儿,我意识到她在哭。
我手伸过桌面,轻轻抚摸她的手臂。
“你没事吧?”我说,“你药吃了吗?”
没有回答。过了一会儿,她放下手,坐直身体,做了个深呼吸。她拿起餐巾纸擦眼睛。
“你现在看上去就像个可爱的黑兔子。”
她没有笑。她就像没听到我说的话。她拿起另一张餐巾纸擤鼻涕。
“我已经决定了。”她看着我的眼睛,“我一个人去火山旅馆。”
“不是说让我陪你去的吗?”
她苦笑着摇摇头,“不,那不可能。那对你太不公平,而且违反规则。”
“规则?”
“去火山旅馆的人就不能再回来。”
“但你说过——”
“那只是一个梦。梦,你知道吗?梦是不可能实现的。当然,”她的眼神柔软下来,“你的梦除外。你的梦会实现的。你会成为一个大作家。有一天他们会抢着出版你的书。”
我对着咖啡杯摇摇头,“也许我们可以换个医生。”
“没用的。我知道。”她低下头,“我只会拖累你。我们不该在一起。你不该找个神经病做老婆。”她抬起头,看着我,“你有你的梦。”
“你不能这样想。你要有信心。”我握住她的手。冰凉的手。“你可以治好的。”
“我们不要再说这个了。”她的手像胆怯的小动物那样溜出我的手心。她抬手看看自己的手表。黑色手表。“快要上班了——你下午怎么安排?回家写东西?”
“去见一个书商。好像对我的书有兴趣。”
“那太好了。”她把香烟放进包里。我们站起来。
走出门口的时候,我们被一位英俊的麦当劳保安拦住。他递给我一个麦当劳小丑的面具。周年店庆的免费礼物。
K睁开眼睛。有一瞬间K不知道自己在哪儿。然后他意识到:这是火山旅馆。这是他自己的房间。这是扶手椅。他分不清他是在扶手椅上睡着了,还是昏过去了。他慢慢站起来,觉得全身酸痛,两脚发麻。房间里一片幽暗。他不知道自己睡了——或者昏迷了——多久。侏儒已经不见了。也许那只是一个梦,他想。但是不。那不是梦——他看见了摆在电脑旁边的白色帽盒。而且,盒子已经打开了。
他站在那儿盯着帽盒看了一会儿。世界一片寂静。他只能听见自己的耳鸣。在幽暗的光线中,盒子和放在一边的盒盖看上去就像两块白色的骨头。
K觉得似乎哪里有点不对劲。但到底是哪里呢?说不上来。空气闷闷的,黏黏的。他朝帽盒走过去。他停在书桌前。
盒子是空的。
他走动几步,朝四周地上看了看。没有东西。而当他抬起头,他吓得几乎心跳停止:镜子里有另一个人。一个脸色惨白,咧着血盆大嘴,正在狞笑的小丑。他不禁踉跄着后退几步,靠到后面的床架上。小丑也后退几步。然后K突然意识到:那个小丑就是他自己。他脸上戴着一个麦当劳小丑的面具。
我手里拿着麦当劳小丑面具,穿过天桥,走回我们住的公寓。一对母女——打扮得像两个比例不同的芭比娃娃——经过我身旁,那个小女孩死死盯着我手里的面具,然后又面无表情地看看我。跟往常一样,天桥上有几个身体畸形的流浪汉坐在地上乞讨。口子上是一个两条下肢从大腿根处被截掉的乞丐。他趴在地上,除了裆部有块破布什么也没穿。他不停晃动手里装着几块硬币的易拉罐。当我看他时发现他也在看我。我迅速移开视线,掉过头,加快脚步。我又经过一两个在地上蠕动的黑色肉团。我没再看。
在天桥尽头稀疏地围着一圈人。坐在地上的不是乞丐,而是一个侏儒。侏儒面前铺着一块白布,上面摆着一个扁铁盒和几根细雪茄似的褐色烟卷,布上用拙劣的毛笔字写着:
祖传秘方 天然神草
包治百病 一吸见效
我停住脚步,盯着“包治百病”几个字。回过神,我发现侏儒已经站起来,正在盯着我看。他穿一套皱巴巴——但挺合身——的藏青色双排扣西装。他看看我,又看看我手里的面具,脸上露出意味深长的微笑。那笑容让我全身起鸡皮疙瘩。就在我转身要走的时候,他突然一把抓住我的手腕。他的手又细又硬,就像某种动物爪子。
“拿去试试!”他把一根烟卷塞进我手里。
我们互相盯视了大概有一秒。不超过一秒。但感觉就像永恒。然后我用力甩开他——他和他的烟卷,快步朝桥下走去。
我们的公寓就在麦当劳对面,隔一个天桥。她上班的公司在麦当劳的另一侧。有时——大概一星期一次——我们会在麦当劳共进午餐。我走进电梯,走出电梯,掏出钥匙开门。我把面具扔到沙发上,打开餐桌上的手提电脑。离和书商约好的时间还早。我进厨房打开冰箱,给自己倒了杯橙汁。我分两口把橙汁喝光,回到客厅,在电脑前坐下。
手腕被侏儒握过的地方仍然有感觉。
我在Google上输入“火山旅馆”。3 600 000条结果。夏威夷火山旅馆。土耳其火山旅馆。海口火山旅馆。漳州火山旅馆。那曲火山旅馆……我打开了十几个页面。全是广告。我重新输入“火山旅馆自杀”。3 570 000条结果。一无所获。我输入“火山自杀”。15 000 000条结果。有些东西——但也没什么用。过去五百年中,有二十万人死于火山爆发。自1976年以来,有八十七人死于对火山的好奇。1933年,不知出于何种原因,一名十九岁学生跳入日本大岛一座活火山的火山口自杀,在他的启发下,接下来的三个月里,有三百十一名年轻人先后步其后尘。我打开了几个火山喷发的图片和视频。我打开一个关于火山的纪录片,看了十几分钟,然后退出了网络。
我坐到沙发上抽了支烟。我看了看钟。我突然想起塞在裤袋里的麦当劳广告纸。我站起来,走到餐桌边,弯腰把广告纸上记的东西抄到一个黑本子上。我把纸扔进垃圾桶,重新在电脑前坐下。我发了一会儿呆,然后打开“我的文档”。我选中文件名为“新小说”的文档,点击右键,把它重命名为“火山旅馆”。
我又发了会儿呆。然后又看看钟。我关掉电脑,进卫生间撒了泡长长的尿。我仔细洗了手和手腕,然后照了照镜子。我把长发散开,黑头绳咬在嘴里,一只手握着发束,重新扎了马尾辫。然后我看着镜中的自己。直到看上去自己不再像自己。
K看着镜中的自己。他用冷水洗了把脸,然后又照照镜子。老样子。平头,瘦脸,疲倦。他走出卫生间,拉开书桌抽屉,拿出钱包和房卡。他关上房门,穿过走廊。走廊看上去就像绵延的火车车厢(有一瞬间他甚至产生了一种幻觉,觉得走廊在轻轻摇晃)。他几次停下脚步,侧耳倾听。他从没在走廊上遇见过其他人。但有时他会听见某扇门里有动静。听不清的说话声。马桶冲水声。不知道什么声音的声音。
他下楼来到大堂。
呈一个斜角,锋利的阳光把大堂一切为二。当K在前台站住,他的脚后跟破坏了整齐的切面。他从裤袋掏出钱包。这次前台没人睡觉。一男一女,大约四十五岁左右,穿着酒红色带金色纽扣的制服西装(看上去已经十年没换过),正并排坐在那里看报纸。看到K,他们放下报纸,一起站起来,脸上露出聋哑人特有的猛烈笑容。他们都留着短发,面色欠佳,眼神混浊。他不知道他们到底什么关系。夫妻?兄妹?都像,又都不像。他把一周的住宿费和餐费递给女人。她坐下给他开收据。男人把脸枕在手背上做出闭眼睡觉的姿势,然后剧烈微笑着向他伸出大拇指。K不知道他什么意思。睡得好?睡觉好?或者,长眠不醒才好?K不知该如何反应。他接过收据。他示意女人把笔拿给自己。他在收据背面写了一行字:
听说这里是自杀旅馆?
他们接过收据,脸凑在一起看。然后他们互相看了看。然后他们转过来一起看他。他们嘴里开始发出呜呜啊啊的呜咽声,同时做出一连串的各种动作:摇头,用手指着嘴巴和耳朵,拳头击打手掌,纵身跳跃,双臂张开作翅膀状,蹲下,转圈,跺脚——他们让K想起被魔法变成人形的鸟。他无力地朝他们挥了挥手,表示理解,表示绝望,表示再见,然后转身上楼。
K打开电脑。两小时后,没写一个字,他又合上电脑。他打
开落地灯,在扶手椅坐下,翻开《福楼拜书信集》。
老天爷!我写作的进度很慢:四天写了五页,然而到目前为止,我仍在消遣。我在这里又重新获得了宁静。天气坏极了,河流看上去像大洋,没有一只猫经过我的窗下。我已生了旺火。
他站起来,找到一支笔,在这段下面画了一道杠。
《包法利夫人》让我受不了。这一整个礼拜我就写了三页,而且我并不为这三页心花怒放。
直到目前,你缺的只是耐心。我并不认为耐心就是天才,然而它有时是天才的迹象,而且可以代替天才。
他在这两段下面也画了杠。他坐在那儿发了会儿呆。他看着自己挂在对面墙上的麦当劳小丑面具。然后他站起来,泡了杯红茶,重新在电脑前坐下。
他打开文件名为“新小说”的文档。他按住鼠标左键,把写好的七页全部选中,然后点击“删除”。他松了口气——现在他又回到了开头。他看着电脑。现在页面上只剩下了一个标题:火山旅馆。
K走进电视机房的时候侏儒已经在那儿了。他依然是上次的装扮,背带裤,黑衬衫,马尾辫。他两条短腿摊直,双臂交叉,整个身体陷在铁锈红的双人沙发里,看上去很惬意。他咧开嘴冲K笑笑,歪头示意他在自己身边坐下。K坐下来,但特意与他隔开一点微妙的距离。
“火山纪录片。”侏儒说,“很好看。非常好看。”
K没有靠到沙发上,他身体向前倾,肘部压在膝盖上,手指交叉握在一起。
火山是地球上最具破坏力,最具爆发性的力量之一。屏幕上一个不带感情的男中音说。由于火山喷发时经常天昏地暗,地动山摇,景象非常可怕,所以古人认为这是神灵发怒的表现。火山的英文volcano,即来自古罗马神话中“火神”的名字。屏幕上出现了火山喷发的画面。当然,现在我们已经知道,火山爆发的原因,来自我们大地母亲的身体深处:在地壳深处一百至一百五十千米处,有一个“液态区”,区内存在着高温高压下含气体挥发成分的熔融状硅酸盐物质,即岩浆。岩浆一旦从地壳薄弱的地段冲出地表,就形成了火山。画面上炽热的岩浆像红色河流一样缓缓流动。
跟宇宙间所有的事物一样,那个声音继续说,火山既有其坏的一面,也有其好的一面。火山喷发的炽热岩浆和土石流,以及常常附带发生的地震雷电,可以在瞬间将一切摧毁。最著名的例子就是西元79年意大利维苏威火山的爆发……
K侧过头,视线落在侏儒前方的地面上。“你那天为什么……要送我一个麦当劳面具?”
侏儒咯咯笑起来,他的眼睛没有离开电视。“因为我刚好多一个。”他说,“我收藏面具。”
屏幕上出现了一具具姿态各异(但都很安详)的庞贝干尸。
“你有空应该去我的小屋看看。”侏儒接着说,“你一定会大吃一惊——哈!——我墙上挂了上百幅面具。来自世界各地,什么样的都有。甚至——”他略微放低声音(K感觉他看了自己一眼),“有张用真人皮做的。是个朋友送的。”(……但火山也并非完全有害无益,有时它能给我们带来珍贵的宝石和矿产,而富含养分的火山灰能使土地更加肥沃……)
“对了,你有没有戴过面具?”侏儒突然问。
K没有马上回答。他想起那天看到镜子里自己戴着面具的场景。他不知道那算不算戴。不,应该不算——那时他甚至都没意识到自己戴着面具,而当他意识到时他立刻把面具扯了下来。(……火山能摧毁一切,但也能重造一切。火山被认为是大自然最重要的再造运动。首先,它可以为我们制造陆地,比如……)
“没有。”K摇摇头,“没戴过。”
侏儒再次咯咯笑起来。笑得让K觉得耳膜隐隐刺痛。
“你应该试试,大作家。”他说,“那种感觉很奇妙——就像变成了另一个人。一个抽象的人,一个神一样的人,一个可以为所欲为的人。”
电视里开始介绍火山的类型。
“知道吗,我经常卖面具给他们。这样他们下手容易一点。”
“他们?”K转过头。侏儒依然双臂交叉,盯着电视机屏幕。
“那些来自杀的人。我顺便也挣点生活费。”
他们沉默了一会儿。
普林尼式喷发是目前已知最猛烈的喷发形态。它有两个主要特征:一是非常强烈的气体喷发,会产生数十公里高的烟柱;二是喷发会伴随大量浮石的生成。由于爆发强烈及物质大量抛出,常形成锥顶崩塌的破火山口。“普林尼式喷发”这个名字是为了纪念古罗马的著名作家,《自然史》的作者普林尼。此种喷发的范本是西元79年维苏威火山的爆发,而普林尼正是为了考察和救灾,在赶往该地区时死于含硫气体中毒。画面上出现了普林尼的画像。
“他们为什么偏偏要来这里自杀呢?”K问。
侏儒耸耸肩,“地方偏僻,但我想,主要是因为天池。”
“天池——就是外面那个湖?”
“对。这里应该也属于普林尼式喷发。所以火山湖很深。深不可测。一跳进去就无影无踪。”
“他们都跳湖自杀?”
“不一定。”他说,“什么死法都有。自杀就像点菜,每个人口味都不一样。只要付一笔钱,老板和老板娘就会帮你善后。往湖里一扔就行了,方便得很。”他朝K看了一眼,咧嘴笑笑,“怎么?你也想自杀了?”
K对着屏幕摇摇头。现在正在介绍世界上一些有名的活火山。
“我看你也不像要自杀的样子。你很焦虑,是不是?真要自杀的人都很平静。”
K没有说话。
“嗨,嗨——”似乎想起了什么,侏儒挣扎着坐起来,他小小的身体好像根本就撑不住他的大脑袋。他几乎是爬着靠到K的身边。“我知道了——你是不是想女人了?”他对着屏幕上火山喷发的画面扬扬头,“你看那些火山像不像鸡巴?啊?”他脸上露出邪恶的微笑,两眼灼灼发光。“火山喷发就是大地在射精,对不对?就是天地在乱搞。”他又朝K身边挪了挪,然后朝门口看看,放低声音,对着K的耳朵说,“你可以去搞她。那个黑衣大奶的疯婆子。”
“她很会搞。”他压低嗓子说。
“你怎么知道?”K转过头。
侏儒又咯咯笑起来,笑得全身乱动。
“很简单。”他说,“因为我搞过。”
我敲敲门。笃。笃。笃。我尽量让每一下的重量和间隔完全相等。每敲三下停顿一会儿。笃。笃。笃。没有反应。
我环顾四周。一个蜂窝状的大办公室,电话铃声此起彼伏,一面墙的书——但它们看上去不像书。
笃。笃。笃。
我加大力度。笃!笃!笃!
“请进——!”里面传来一个女人的嘶吼。
我旋开门把手。
一张巨大的长形办公桌后面并排坐着一男一女。他们几乎同时抬起头,又几乎同时露出微笑。
“你是K吧?请坐。”男人说。
我在他面前的皮椅上坐下。
“请稍等一会儿。”男人一边盯着电脑屏幕,一边移动鼠标。
女人饶有兴致地看看我,然后也把头转向自己的电脑。他们都穿着藏青色西装,戴着黑框眼镜,看上去既像夫妻,又像兄妹,又像搭档。
我等了一个小时零一分钟。
终于,男人放开鼠标,把脸转向我。他看了我一会儿,似乎已经忘了我为什么会坐在他对面。然后他说:“你的小说……我们看了。”
“还是不错的。”停顿片刻,男人接着说,“语言很好。但从市场的角度看,故事的节奏太慢,情节不够曲折,结构也太复杂。总之——太小众化。”
我没有说话。
“如果出版的话,需要好好修改。”他的脸又转向电脑。
沉默。又过了一会儿。
“你看怎么样?”他的脸转过来。
我耸耸肩。“要看怎么改。”我说。
“世界不一样了。”男人长叹一声,“以前作家是上帝,现在呢,读者是上帝。所以——”说到这里他突然停住了。他的表情——面无表情的表情——突然固定住了。接着,就像被枪击中似的,他脸色发白,嘴里发出含混的呻吟声。他慢慢地——就像电视里的慢动作——从椅子滑落到地毯上。他躺在地上,缩成一团,手脚开始不停地抽搐,一股白沫涌出他的嘴角。
女人站起来。她看上去不慌不忙。她从桌上拿起一支黑色钢笔,动作麻利地把它塞进男人嘴里。男人的眼镜已经不知掉到哪儿去了,原本油光可鉴的大背头变得凌乱不堪,几缕头发搭在额上。他眼睛直勾勾地盯着前方,像拉布拉多犬叼木棍那样死死咬住那支钢笔,从喉咙深处发出聋哑人似的呜咽声。他不停颤抖。
“他没事吧?”我站起来。
女人好像没听见我的话。她把男人扔在地上不管,转身坐到他的椅子上。
“他没事吧?”我坐下来。
“啊?!你说什么?!”女人吼道。大概耳朵不太好。
“他没事吧!”我说。
“没事!羊颠疯!老毛病了!”
传来他的呜咽声。
“首先!你的小说名字要改!”她吼道。
我一下没反应过来。
“不。”我摇摇头,“名字绝对不能改。”
“什么!”她侧过耳朵。
“不行!”我吼道。
“一定要改!”她挥了挥手里的一本书,“《千年孤独》!这样的名字才行!”
“那就改成《万年孤独》。”我站起来。
“什么!”
“万年孤独!”
我转身走出去。我没有摔门——虽然我很想摔——我把门带上,把她和呜咽声留在里面。
我不知道自己走了多久。两个小时。也许三个小时。我被裹挟在闹市区的人流中,机械地迈动脚步。每个人似乎都有自己的目的地——除了我。每个人似乎都在考虑什么——除了我。我脑中一片空白。我甚至有一种错觉,觉得不是我在移动,而是周围的一切——楼房,商店,人行道,红绿灯——在移动。我在迈动脚步,但我只是在原地踏步。整个世界都在流动,变化——除了我。一个穿银色西装戴耳机的年轻男人,一边疾行一边对着空气大声怒骂。一个婴儿坐在童车里吃手指。耀眼的白色乳沟。带香水味的风。数字不停变动的噪音显示屏。坐在街角乞讨,头发胡子乱蓬蓬的流浪汉。悠长的急刹车声。地上踩扁的烟头。橱窗里真人大小的星球大战人物模型。慢吞吞,车身印着整幅内衣广告的双层巴士。空气渐渐变成蓝色。暗蓝色。突然发光的霓虹灯招牌。高楼显出黑色的身影。嵌在大厦表面的巨幅电子屏幕闪烁着,就像飘浮在半空。然后,一瞬间,所有路灯都喷出黄色的光线。
我在一家服装店的落地橱窗前站住。我掏出手机,拨了家里的号码。她应该下班了。我一边看着橱窗里微笑的塑料模特一边听着手机里的音乐铃声。《致爱丽丝》。
没人接。《致爱丽丝》已经演奏到第三遍。我在橱窗玻璃上看见自己的影子。我眼前推出卧室床头柜上(靠她那边)那台黑色电话机不停响起的画面。
K接起电话。这是他到火山旅馆后第一次电话铃响,以至于一开始他都没意识到那是电话。
“喂。”
“您好,”一个女人的声音说,“请问需要服务吗?”
K一时不知该说什么好。
“开个玩笑。”对方咯咯咯笑起来,“是我。”
“您是——?”
“不记得了?我们在餐厅见过。”
“……”
“麦当劳叔叔在干吗?”
“但我真的……”
“好了,”她又笑起来,笑得有点神经质,“……我知道不是你。他们说你是作家,对吗?”
“算是吧。”
“你在写小说?”
K犹豫了一下。“准备写。”他说。
“那么,也许我们能互相帮忙。”
“互相帮忙?”
“电话里很难说清楚。”她用略带神秘的口气说,“我现在就过来,好吗?”
正当K考虑该怎么回答的时候,她已经挂断电话。
我挂断电话。我拨通她的手机。
“喂?”
“是我。还没到家?”
“快到了。加了会儿班。”
“我也弄晚了。”我说,“还在外面。”
“谈得怎么样?”
“他们要出我的小说。”
“太好了!”
“……”
“我们应该庆祝一下。”她说,“想去哪儿?”
我犹豫了一下。“叫个比萨外卖怎么样?再开瓶红酒。”我不想在外面吃。
“听上去不错——你现在在哪儿?”
“我现在在哪儿?”我拿着手机环顾四周,“我也不知道。”然后我看见远处空中麦当劳金黄色的M标志,它看上去就像某种特殊的星座。“好像离家不远。”我说。
“好,那待会儿见。”
“待会儿见。”
我突然觉得很想见她。就好像我们已经分开了很久(其实只有几个小时)。我觉得胸口发空。我渴望紧紧拥抱她。我加快脚步,朝空中金黄色M的方向走去,就好像它是指引东方三博士找到耶稣的伯利恒之星。
K一眼就看出她下面什么也没穿。开始是直觉。然后是证据:他看见她乳头的形状。她穿着跟上次一样的连衣裙。黑色丝绸连衣裙。很合身。也许太合身了。他看不见她三角内裤的勒痕(上次他看见了)。他硬起来。
她没有看K。她在房间里转了一圈。就像在参观某个博物馆(而K是她不太感兴趣的展品)。她碰了碰电脑。她的手指滑过书桌边缘。她把拉拢的落地窗帘掀开一条缝(然后又合上)。她翻了几页床头柜上的《福楼拜书信集》。最后她在扶手椅上坐下,跷起二郎腿。她穿着绑带式的黑凉鞋。K觉得更硬了。
她盯着挂在对面墙上的麦当劳小丑面具。
K说那是侏儒送的。
“你认识那个侏儒吗?”他说。
“这里什么人都有。”她把视线转向他,“有烟吗?”
K递给她一包烟,看着她从中抽出一根。他用旅馆的火柴给她点燃。
“谢谢。”她深深吸了一口,然后又吐出来,“音乐?”
他走到电脑前(他别无选择),打开音乐播放器。比莉·哈乐黛。音乐像烟一样散开来。
他在另一张扶手椅上坐下(上次侏儒坐过的那张)。
“很适合自杀的音乐。”她看了看K,“你说呢?”
他没有说话。
“你也是来自杀的?”过了一会儿K问。
“所有来这儿的人都是来自杀的。”她说,“包括你。”
“我?”K抬起头。
“写完一部小说,就像死过一次一样,对不对?”
“差不多。”差不多。
“你知道吗?”她弹掉烟灰,“我也写过小说。”
“真的?”
“我从小就喜欢看书。”她说,“简·奥斯汀。陀思妥耶夫斯基。海明威。一拿起书,就像立刻进入了另一个世界。看多了就想写。但是……”她摇摇头,“我不行——进入一个世界是一回事,创造一个世界又是另一回事。”
“每个人都可以成为读者,”她接着说,“但并不是每个人都能成为作家。”她吐出一口烟雾,把剩下的半截香烟戳进烟灰缸。“所以我需要你帮忙。”
“……我不太明白。”
“帮我自杀。”
“帮你……自杀?”K看着她。她的眼睛闪着光。
“在你的小说中杀死我。”见K没有反应,她又说,“给我纸和笔,我画给你看。”
他从床头柜抽屉里拿出一支黑色钢笔和一张抬头印着火山旅馆的信纸。她侧过身——K更清楚地看见她乳房的形状——在茶几上画了下面两个图案:
“A代表活着的世界。”她坐直起来,欣赏着自己的作品,“B代表死后的世界。C代表小说的世界。”她用牙齿轻轻咬住钢笔的末端,“H代表火山旅馆。”
“在你出现之前,情况是这样的。”她指着第一个图案,“你知道规则吗?”
K摇摇头。
“规则就是:来了火山旅馆就不能再回去。也就是说,H是一个临界点,一旦进入了H点,你就不能再回到A世界,而只能进入B世界。但是——”她用笔点点第二个图案,“现在情况变成了这样。”
“由于你的出现,”她说,“现在多了一个C世界。所以,规则也就变成了:一旦进入H点,你就不能再回到A世界,而只能进入B世界或者C世界。明白我的意思吗?”
K不知道该点头还是摇头。他有点明白,又不太明白。
“这就意味着,”她接着说,“如果我能进入你创造的C世界——如果你能在小说中杀死我,我就可以回到A世界,同时又不违反规则。”
“所谓的规则,是谁定的?”他问。
“一个极端秘密的自杀网站。”她说,“一般人根本进不去。Google上也搜不到。”
“如果违反规则呢,会怎么样?”
她嘴角轻轻一撇,露出一丝微笑。“有些规则是无法违反的。”她说,“到了这里,就别想再回去。”
“所以我们常常会在网上两个人约好一起来。”沉默了一会儿,她接着说,“有时候一个人会犹豫不决……但我约的那个人一直没来。”
“所以那天你把我当成了那个人。”
“麦当劳叔叔在干吗?”她靠到椅背上,突然笑起来,“那是我们的接头暗号。你知道该怎么回答吗?”
他没说话。他看着她。她也看着他。
“麦当劳叔叔在后台。”她放低声音,用一种故作神秘的语气说,“记住——麦当劳叔叔在后台!”
她先站起来。然后K也慢慢站起来。他们几乎不可避免地——就像某种自然现象——抱在一起。他们站在床和扶手椅之间那片小小的空地上,用脖子和手臂缠绕住对方。他们的脑袋耷拉在彼此的肩上,看上去就像两颗成熟但还没掉落的水果。K能感觉到她的乳房,K甚至也能感觉到她能感觉到他感觉到她的乳房。他的阳具也一样。他们似乎形成了一个新的整体,感官系统也合二为一。
对此K感到很满意。他从未感到如此充实,完整。他发出一声轻轻的叹息。但这种完美的,仿佛飘浮在太空般的宁静感只持续了大概几分钟(但同时又像永恒)。
然后他想感到更满意。
他的手似乎突然恢复了知觉,突然感觉到手下是多么柔滑,多么富有弹性。似乎在灵魂得到满足之后,现在轮到了肉体。他用手指把她背后的裙子拉上来,双手伸进裙子里面,抚摸着她赤裸而丰满的腰部和臀部。他身体稍稍前倾,从后面把一只手指探进她两腿之间。她发出倒吸冷气般的声音。她已经湿了。
“用这个。”她说。
她的一只手伸到背后。K这才发现她手里还一直紧紧握着那支黑色钢笔。他接过被她握得发热的钢笔(笔帽已经套上)。极为默契地,两人分开来,身体站直,然后他低下头,一只手环着她的腰,另一只手握着钢笔,伸进她的裙子。与此同时,隔着黑色丝绸,他轻轻咬住她已经发硬的乳头。
他用笔在她两腿之间轻柔地摩挲。他能感觉到笔渐渐变得越来越润滑,越来越流畅。他用手指控制着笔的力度、角度、和节奏。逗号。顿号。惊叹号。句号。省略号。一滴黏稠的液体顺着笔杆流到他的手指。
她像发冷似的微微颤抖(虽然她的身体在发烫)。她已经站不住了。她用一个微妙的动作暗示他停止。K把她扶到床沿坐下。她开始解K的裤带。她用迷离的眼神看着他。
“现在用你自己的笔。”
他把滑溜溜的钢笔扔到地毯上。他脱掉所有衣服。她握住他,然后抬头看着他的眼睛,嘴角浮现出梦游般的微笑。
“先要润润笔。”
说完她伸出舌头,开始舔他。接着,她两手搭在他的髋部,把他整个含住。里面又湿又暖,就像另一个阴道(她的牙齿似乎消失了)。然后吮吸。然后含在里面舔。然后慢慢地来回移动。他的手放在她头上,随着她头部的运动,揉乱了她的长发。他闭上眼睛。他再次感觉到了灵魂。只不过,这次灵魂似乎全都在他的阳具里,在热切等待着喷射而出,以便离开他的肉体。
用同样微妙的暗示,K让她离开了自己。她的嘴唇和他之间还连着一丝口水。他把她推倒在床上。他低头看看自己肿胀的、湿漉漉的阳具。你自己的笔。不知为什么,他觉得它既属于自己,又不属于自己。他俯下身,把她的裙子撩起推上去,一直到脖子那儿,盖住她的头和手臂。这是他第一次看见她裸体。她看上去就像支点燃的白色蜡烛,除了它的火焰是黑色的。
他趴上去,开始舔她的身体。她那乳晕大得惊人的乳房。她那有草莓般凸起的黑乳头。她的肚脐眼。她浓密的阴毛。而当他拨开她的阴毛,他发现仿佛有张嘴正在等待他的吻。于是他就吻了,一个温柔的法式深吻。她被蒙住的脑袋发出一声叹息。
然后他插进去。几乎毫无感觉。她下面已经完全融化了。这让他多少可以控制住自己浓缩的灵魂。虽然他最终要让灵魂离开自己(这就是他做这些事的目的),但他又想尽量延缓它离开的时间。他开始慢慢抽送。他伏在她身上,按住裹着她头部的丝绸衣料。他把衣料扯得越来越紧,紧得就像蒙在她脸上的黑色面具——他可以分辨出哪里是额头,哪里是鼻子,哪里是嘴。他们开始隔着丝绸接吻。他能感觉到她的舌头。他们的口水弄湿了裙子。几乎是下意识地,现在她的整个头部都被他用丝绸紧紧包住,不留一点空隙。他用嘴堵住她的嘴。他继续抽送。她似乎达到了高潮。她浑身颤动,从喉咙深处发出吞咽的声音。她的阴道骤然缩紧,随后一阵痉挛。
但K突然猛地放开她。
不,不是他射了。而是他突然意识到,自己正在闷死她。他喘着粗气,瘫在她身上(他还在她里面)。我差点就杀了她,K想。然后他听见她在抽泣。一边喘息一边抽泣。眼泪濡湿了她的黑面具。“为什么……”她断断续续地说,“……停……继续……求你了……求你……杀了我……求你……”她的手找到他的手,她抓住他的手,把它们按到自己脖子上。“掐死我……”她用一种低沉,古怪,略带颤抖的嗓音说,“掐死我……”她用力按着K的手,像重复某种咒语一样不断重复那三个字,声音变得越来越狂躁,越来越急促:掐死我。掐死我。掐死我。
K不知道这是怎么发生的。也许是咒语让他晕眩(他想让她停止)。也许因为他看不见她的脸。或者,也许他仅仅是想支起身体(而支点,他的双手,被她强按在她脖子上)。总之,当他意识到时,他已经掐住了她的脖子。而且掐得越来越紧。似乎他的手已经不再是他的手,似乎它们突然拥有了自己的独立意志。他的下面再次膨胀起来。
墙上的麦当劳叔叔微笑地看着他们。
她松开手。
她松开手。
她的手像两片落叶一样从我手背上滑下去。我也想松手。但是不行。手已经不属于我。我已经不属于我。
我一点点加大手上的力度。富有节奏感地。与我下身的动作相呼应。
她看着我,脸上露出幸福迷醉的神情。她甚至微微调整了一下姿势,以便我更好地用力。
我继续用力。
我已经不是我。她给我戴上麦当劳面具的那一刹那,我就变成了另一个人。一个抽象的人,一个神一样的人,一个可以为所欲为的人。
我越用力,下面就动得越快。
她的脸色变了。她嘴里发出含糊的呻吟。但她没有挣扎——只是浑身在微微战栗。她闭上眼睛。我也闭上眼睛。我知道这样会掐死她。但我也知道,我可以掐死她。
因为我可以做任何事。
然后我射了。
就像魔法被瞬间解除,我松开掐着她的手。我扯掉脸上的面具扔到地上。我们从沙发上坐起来。她剧烈咳嗽。我把她搂到怀里。“对不起。”我说,“对不起。”我轻轻吻她的耳朵,她的脸颊,她被我掐出指印的脖子。
她摇摇头。她对我挤出一个微笑。她闭上眼睛,大大的泪珠流下来。她的嘴角直接由微笑变成抽泣。
“对不起。”我说。我小心地把她搂紧一点,似乎怕把她弄碎。我亲亲她的眼泪。眼泪的味道跟她下面很像。“对不起。”我喃喃自语。
她再次摇摇头。她把身体靠过来。“我高兴。”她说。
我们就那样默默地抱了一会儿。然后她说:“上床吧——这里有点冷。”
我们在毛巾毯下紧紧缠在一起。我们接了个长长的、深深的、古老的吻。“我们要永远在一起。”我轻声对她说。我觉得我们正在缓缓地向什么很深的地方坠落。我睡着了。
半夜K被奇怪的声音惊醒。他在黑暗中又躺了一会儿,以确定那声音不是来自梦中。他又听见了。他坐起来,扭开床头灯。他坐在那里,等待着(房间看上去就像另一个梦境)。第三次听见的时候,他跳下床。他套上衣服和跑步鞋。他环顾房间,那个声音让他觉得需要一件武器。但没有武器,没有一样东西可以作武器,除了他自己。
他打开门。光线昏暗的走廊似乎一直通向无限。现在他听得更清楚了。是一个女人在尖叫。不——是她在尖叫。就在他斜对面的房间。204。他冲过去。然后突然停住。声音消失了。他看了看门上颜色已经变淡的白色数字,把左耳贴在上面。含混的呻吟和喘息。有另一个人在里面,K想。但他已经来不及多想。因为尖叫声再次响起来(这一次比前面任何一次都更为悠长)。而当他意识到的时候,他已经在房间里(门没有锁)。
房间里比走廊要亮一点。两盏床头灯在墙壁上投出黄色的扇形。床上有两个人。都赤身裸体。她在下面,两腿张开,两手被手铐分别铐在床角,形成一个X形。一个男人骑在她上面。他右手像握匕首那样握着一支黑色的东西。他回过头看着K。但K看不见他的脸——他戴着麦当劳小丑的面具。时间似乎停止了。一切都进入了一种透明的、琥珀般的凝固状态。因此他可以在瞬间看清所有细节:他手中握的是一支黑色钢笔。深红的鲜血像墨水一样从笔尖滴落(停顿在半空)。银色手铐的反光。她在呻吟(但听不见声音)。她的乳房已经一片血肉模糊。麦当劳叔叔顶着红色乒乓球的鼻子,咧开血盆大嘴,在朝他微笑。
但这只是一瞬间。下一瞬间,世界已经恢复。呻吟声响起。那滴血开始降落,跌碎在白色床单上,并立刻被棉布纤维吸收(K甚至觉得听见了它跌落的声音)。K先反应过来。但也许这么说并不确切。因为接下来他的一系列行为完全没有经过大脑,完全是一种本能。他一把抓住男人的两只脚踝,把他拖到地上。然后他开始不顾一切地对着他的腹部猛踢。用尽全力踢。不停地踢。踢的过程中K一直盯着男人的麦当劳面具。他看不见他的脸。也许那就是他为什么停不下来的原因——不管他怎么踢,麦当劳叔叔始终在对他咧嘴微笑。似乎他踢的不是一个具体的人,而是一个抽象的概念,一个神,一个邪恶而完美的替身。唯一的变化是男人的身体渐渐像煮熟的虾那样蜷曲起来。
K不知道自己踢了多久。一方面,他的动作越来越机械和麻木。另一方面,他觉得这个房间——甚至这个旅馆——似乎已经成了他内心深处的一个角落,而他则飘出去,像灵魂出窍一样,从外面看着自己。
他停下来。他已经被汗水浸透。他双腿发软,跪倒在男人面前。他大口喘气,身体控制不住地微微颤抖。从他的角度,K可以清晰地看见,男人的下体已经变成了一团血红色的烂泥。这时,男人似乎动了一下。于是,几乎就在同时,K抓起滚到床脚的那支钢笔,发疯似的戳进男人的肚子。
他不知道自己戳了多少下。他只知道,他手上现在都是血。衣服上也是。他跑步鞋的鞋头感觉湿湿的,就像进了水。被血弄得滑溜溜的笔掉到地毯上。
他把手上的血抹到衣服上。K开始觉得无法忍受这些血。他开始脱衣服。他扯掉上衣,鞋子,裤子,袜子,以及——在他意识到之前——内裤。然后他看到自己高高勃起的阳具。K突然觉得眼前的一切都无法解释:地上戴着麦当劳面具的尸体(血像涌出小泉眼一样涌出他的肚子)。床上被手铐铐着的女人(乳房已经被笔尖划得支离破碎)。以及他自己(赤身裸体,勃起着,站在屋中央)。K觉得自己就像无意间闯入了别人的梦境(而那个人的梦中又刚好有K)。
“嗨,过来。”他听见女人说。声音似乎从很远的地方传来。
他走到床边。
她看着他直挺挺的下面,露出半嘲讽半疯狂的笑容,“好啊……继续。”
“什么?”他不明白她的意思。
“继续……操我。”她说,“操我。杀我。写我。”
“不,我要救你——钥匙呢?”他问,“手铐钥匙呢?”
“救我?”她笑起来(她低头看看自己的胸口,血随着她的笑再次渗出来),“你杀我就是救我。”
他们对望着。K不知该怎么办。他的身体在颤抖。他依然勃起。
“我不能杀你。”他说。
“不,你可以。”她说,“掐死我。就像上次那样。上次就差一点,记得吗?”
“不,”他虚弱地摇摇头,“我只答应在小说里杀死你。”
“但这就是小说。”她的声音很镇静,“我们正在小说里。你没发现吗?”
“你看,你杀了麦当劳叔叔。”她接着说,“你知道我一直在等他。你必须继续他的工作。”
她闭上眼睛,然后又睁开。睁开的时候,泪珠从她两侧的眼角滑下去。
“你没有选择。”她说,“我也没有选择。我们都没有选择。”
K的眼泪也流下来。他不知道为什么。他开始抽泣。一边勃起一边抽泣。
“麦当劳叔叔在干吗?”
“在后台。”K以几乎听不见的声音说。然后他伸出手,尽最大力量掐住她的脖子。他闭上眼睛。
我大叫一声,惊醒过来。我在瑟瑟发抖。我做了个噩梦。汗水已经把我浸透。我想去抱她。然后我意识到她不在。她不在我身边。她那边的床是空的。
我坐起来,打开床头灯。
她不见了。
我靠回枕头上,闭上眼睛。我做了个深呼吸。梦中的情景依然栩栩如生。我在梦中掐死了她。我手上还留着她皮肤的触觉。我睁开眼睛。我看看自己的手掌。然后我再次闭上眼睛。
我突然明白她已经走了。
她已经一个人去了火山旅馆。
我全身一阵冰冷。
这时我听见外面客厅有动静。我睁开眼睛。她出现在卧室门口。她穿着我那件蓝色的浴袍,头发盘成一个髻。
“你醒了。”她走进来,手上拿着一个书本似的东西,“我听见你叫了一声。”
“我做了个噩梦。”
她在床沿坐下,把手里的东西放到我床头柜上。
“我在给你包礼物。”她说,“明天再看。”
“现在几点?”我握住她的手。
“四点。”她的手指很冰。
“来——进来让我抱一会儿。”我说。
她脱掉浴袍,滑进毛巾毯。我紧紧搂住她,就像孩子搂着母亲。
“我们一起死,好吗?”我轻声在她耳边说。我能感觉她皮肤突然缩紧。“但不是现在。等我们再老一点。我们一起去火山旅馆。”
“我们一起去火山旅馆。”我又轻轻重复一遍,就像那是世界上最甜蜜的情话。
我们又抱了一会儿。
然后她说她睡不着。
我说我也是。
“我饿了。”她说。
我说我也是。
“冰箱里什么都没有。”她说,“我看过了。”
我说这让我觉得更饿了。
“我也是。”她说。
然后我们几乎同时想到了一起。在凌晨四点,世界上只有一家餐厅还在营业。那就是麦当劳。
凌晨四点多的麦当劳看上去既像博物馆里展示的远古废墟,又像库布里克电影里的未来世界。戴着绣有M标志贝雷帽的服务生则让人想起幽灵。我们点了咖啡、薯条、鸡块和苹果派。虽然一楼没有人,但我们还是拿着托盘上到二楼。
二楼靠近楼梯的位置坐着一个人。
是那个侏儒。就是中午在天桥上一把抓住我手腕的那个。他握着一支对他来说过于粗大的黑色钢笔,正埋头在一个大本子上写什么。他停下笔。抬起头,他看着我们,脸上又露出那种令人作呕的、意味深长的笑容。
我尽量让自己不显得异样。她好像根本没看见他。我们走到另一头靠窗的位置。我背朝侏儒的方向坐下。
我们开始默默地吃东西。
“还记得我们第一次见面吗?”我问她。
“记得——也在这儿。”
“也是晚上。”我说。不过没这么晚。
“那时你还在公司上班。”
“我请你帮我修电脑。我的文档突然打不开了。我记得你一秒钟就修好了。”
“因为你是科技盲。”
我点点头。“你不觉得这里有某种象征吗?”我说。
“象征?”她抬起头。
“第一次见面我就请你帮我。而你……一直帮到现在。”
她看着我,笑了笑,“我帮你,你才可以帮更多人。你不是老说好小说可以帮人抵抗这个世界吗?”
我摇摇头。“我现在只想帮你。”我说,“答应我,我们再换个医生看,好吗?”
她低头看了一会儿咖啡纸杯。然后她抬起头。“嗯。”她说。似乎怕我不相信,她冲我鼓励地笑笑。
我们又沉默了一会儿。
“K?”她轻声叫我。
“嗯?”我回过神来。
“没什么。”她再次对我笑笑,“我们走吧。”
下楼时侏儒已经不在了。我们走出餐厅时,天空已经微微泛白。她说她直接去办公室,这几天很忙。
“给我和麦当劳叔叔一起拍张照。”她在门口的长椅上坐下。她搂着旁边咧着血盆大嘴的麦当劳小丑塑像,脸上露出灿烂的微笑。
“我……没带手机。”我说。
“那就假装拍一张。”她说。
我用两只手分别做出手枪的形状,然后移动方向拼成一个取景框。
“咔嚓。”我说。这是我第一次看到她笑得那么好看。也是最后一次。
K回到房间。他直接走进浴室。他冲了个长长的热水淋浴。然后他换上干净衣服,拉开窗帘,在书桌前坐下。第一缕晨光从窗口洒入房间,恍如某种天启。某种每天一次的天启。他打开电脑。他打开名为“火山旅馆”的文档。但这就是小说。他想起她说的话。我们正在小说里。你没发现吗?
他写下了《火山旅馆》的第一句话:
我回到家里。我冲了个淋浴。然后我走进客厅,拉开窗帘,在餐桌前坐下。我看了一会儿从窗口洒进的第一缕晨光。恍如某种天启般的晨光。光线像刀锋一样割在黑色电脑上,也割在地上的麦当劳小丑面具上。我打开电脑。我打开名为“火山旅馆”的文档。
我写下了《火山旅馆》的第一句话:
K到火山旅馆是为了
[[托马斯·曼文集·中短篇小说选 - 饥饿的人们 by 托马斯·曼 |https://www.kanunu8.com/book2/10973/196097.html]]
托马斯·曼文集·中短篇小说选 饥饿的人们
作者: [[托马斯·曼]]
-----
有一刹那工夫,德特勒夫在内心深处感到自己是一个多余的人。他不知不觉让自己被闹哄哄的人群带走,来不及向他的两个同伴告别,就这样悄然离去。
他置身于人流中,让人流把他沿着墙壁推向喧嚣的剧场大厅的各个地方。当他一想到此刻离开莉莉和小个子画家已经很远,他立刻挡住了人潮,驻足不前。现在他已靠近舞台,倚在舞台前部包厢的一个镀金的拱形结构上,身旁是一个有毛须的巴罗克式女像柱。女像柱的颈项向下弯曲,对应部分则体现了女性的特征——两个乳房高高耸起,一直伸到大厅内。他竭力摆出一副逍遥自在、走马看花的架势,不时把望远镜凑到眼边。他向光彩夺目的周围扫视时,眼睛只避开一个地方。
欢庆活动达到了高潮。在这些凸出的包厢后面,酒席上摆满菜肴,人们已在大吃大喝。绅士们穿着黑色和花色的礼服,纽孔上别着大菊花,倚在栏杆旁弯下身子凑着女士们的粉肩聊天,这些女人都打扮得珠光宝气,头饰也显得琳琅满目。他们指手画脚,对大厅里熙熙攘攘的人群大发议论。人群一会儿散开,一会儿又推推搡搡地向前涌去;一会儿阻塞得水泄不通,一会儿又形成一个个漩涡,真是五光十色,变幻无常。
有的女人身穿飘飘然的衣服,头戴驳船般的帽子,帽子下方打着古怪的活结,套在下巴下面。她们拄着高拐杖,把长柄眼镜贴在眼睛前面。有些男人的袖子鼓了起来,袖口几乎触到她们灰色大礼帽的帽檐。在花楼上,人们谈笑风生,举起盛满啤酒和香槟酒的杯子开怀畅饮,尽情祝贺。观众争先恐后拥到舞台前,舞台上正演出什么古怪而变幻莫测的闹剧。幕布唰地一下拉拢时,人们就在一阵哄笑声和鼓掌声中纷纷往后散开。接着乐队吹奏起来了。人们又推来挤去,信步进进出出。富丽堂皇的剧院里洋溢着一片黄澄澄的金光,比白天远为明亮,大伙儿的眼睛也不由熠熠生辉。每个人似乎都漫无目的地在渴求什么,呼吸急促,沉浸在热烈而激动的气氛中,这里面既有花儿和美酒,也有食物、尘埃、香粉、香水,以及从那些因凑热闹而浑身发烫的肉体中散发出的气味。
这时乐队的演奏戛然而止。人们臂挽臂站在原处,笑眯眯地望着舞台,舞台上响起了吱吱嘎嘎的乐器声和低语声:一个新的节目开始了。有四五个身穿农民服装的人,正拿起单簧管和瓮声瓮气的弦乐器用模仿的声调拙劣地奏出特里斯坦乐曲中半音阶的搏斗音乐。有一瞬间工夫,德特勒夫闭上了眼睛,他的眼睑像在发烧。他的感觉异常敏锐,即使演奏的人任意走了音,他也清清楚楚听出了曲调中那种痛苦而渴望团聚的主题。他一下子又萌起了孤寂的人常有的那种无法排遣的哀伤感,这时孤寂的人正沉湎于妒忌与情欲之中,渴望生活中能出现光明而平凡的天使……
莉莉……在祈求中和一片柔情中,他灵魂深处唤出了这个名字;他的目光再也舍不得离开她那个站在远处的身影。——不错,她仍在那边,依然站在他以前离开她那块地方的后面。当挤在一起的人群散开时,他能看到她的整个人儿,身穿乳白色的银边衣服,一头金发的脑袋稍稍歪向一边;她反剪双手倚在墙边,跟那个矮小的画家正在聊天,谈话时用诡谲的眼光一个劲儿盯住他看,而他呢,眼睛也像她那一样湛蓝,清澈明净,位置远远分开……
他们谈些什么,他们滔滔不绝地究竟一直在谈些什么?唉,这些话都是从一个取之不尽、用之不竭的源泉里轻快地流泻出来的,这是简朴纯洁的源泉,天真无邪的源泉,欢快明朗的源泉。而他呢,对生活耽于梦想,善于思考,既缺乏远见,又受着创作欲的折磨,因而古板、迟钝,无法分享他们的乐趣!他走了,怀着执拗、绝望和慷慨大度的心情悄悄溜走了,让他们两人单独呆在一起。即使在远处,他仍感到妒火中烧——他知道他们在轻松地微笑,为了能摆脱他而发出如释重负的会心的微笑。
他为什么来到这里,为什么今天又来到这里?是什么促使他又怀着恼恨的心情混迹于这群逍遥自在的人群中间——这些人把他团团围住,使他亢奋——而实际上又觉得自己格格不入?他是有某种要求的,这个他知道得一清二楚!有一回,他在哪儿自省时曾这样写道:“我们这些孤寂的人,是与世隔绝的梦想者和对生命失去继承权的人;我们游离于生活之外,在虚假的冷冰冰的气氛里过着苦思冥想的日子。……我们呀,一旦我们置身于人群,人们看到我们的额头上有知识和恐惧的标志,我们就在自己的周围呵出了一股不胜诧异的冷气……我们是存在中一些可怜的鬼魂,人们对我们总是侧目而视,竭力避开我们,免得我们冷漠而富有真知灼见的眼光有损于他们的欢乐……我们对生命中纯洁无瑕,质朴和生气勃勃的事物,以及友善、献身精神、推心置腹的信任和人类的幸福都在悄悄地热烈追求。对于我们受排斥的生命,我们并不把它看作是伟大崇高和无比瑰丽的幻象,对我们这群不寻常的人来说,它也没有什么特殊的地方;我们所孜孜以求的王国,乃是正常的生活、欢娱以及和睦相处,乃是平庸而富有诱惑力的日常生活……”
他的眼光不时投向正在聊天的一对儿。欢乐的哄笑声响彻整个剧场,盖过单簧管的吹奏声——此刻单簧管已由热情奔放的调门转向感伤,声音十分尖利刺耳。“这就是你,”他想,“你就是热情、姣好而又愚蠢的生命,它同精神是永远对立的。别以为它轻蔑你,别以为它有一点儿瞧不起你。我们跟在你们后面慢慢爬行,我们是土地深处的精灵,是知识多得哑口无言的魔鬼;我们站得远远的;在我们的眼睛里燃烧着一种炽烈的欲望:学你的样。”
“我们感到自豪吗?它能否认我们是孤寂的吗?自豪感是不是在吹嘘,不论何处或不论何时,精神活动都能保证给人类的爱情带来一个较高级的结合形式?唉,但是跟谁在一起呢?跟谁在一起呢?还不是永远跟我们这些人在一起,我们这些苦难深重、勇于追求的可怜人,而决不会跟你们在一起,你们这两个碧眼而不需要精神生活的人!”
现在他们跳舞了。舞台上的种种表演已经结束。乐队在卖劲地伴奏,还有歌声。在光滑的地面,一对对伴侣在婆娑起舞。莉莉同矮个儿画家也跳起舞来。她那可爱的脑袋从花萼般的银边硬领上露了出来,显得多么妩媚动人!他们在一个狭小的圈子里翩翩而舞,体态轻盈,悠然自得。他的脸正转向她,他们一面继续谈天,一面笑盈盈地合着舞曲甜润而轻快的节拍款款移步。
突然,在那孤独的汉子心里萌起一种欲念——他恨不得挥舞起双手来,“你毕竟是我的,”他想,“我却凌驾于你之上!难道我不能含笑一眼看透你的单纯的灵魂吗?难道我怀着嘲讽的情爱,看不出和记不住你身体上每一个天真的动作吗?看到那毫不矫揉造作的举止和丰采,语言和嘲讽的力量在我心底油然而生。这时我的心头就怦怦直跳,如饥似渴地想把你的形象重新塑造出来,而且凭我的艺术,把你追求尘世欢乐的愚蠢的幸福揭露无遗。”
刚才他们那份执拗劲儿这时突然又土崩瓦解,剩下的只是一片迷茫和某种渴求。唉,他真不愿做艺术家,而是做一个人——只要有一回,只要有今天那么一夜也就够了!他巴不得能逃脱可怕的厄运,而恶魔的声音始终在他耳畔缭绕不休:“你不该静坐不动,而应当观察;你不该活着,而应该创造;你不该爱,而应当理解!你就真诚而谦逊地生活、爱慕和赞美吧!你们活生生的人啊,快投身于你们的洪流中,成为你们的一分子!就为你们平凡的幸福,啜几口狂喜之酒吧!”
他浑身打战,转过头去。他仿佛感到,他看到的这些漂亮的、热气腾腾的脸上,都有一种咄咄逼人的表情。他恨不得一下子离开这块地方,找一个静寂、阴暗的所在。这个欲念十分强烈,他简直无法抗拒。是的,一走了事,像以前离开莉莉身边时那样不告而别。他要回家,把发烫的、神魂颠倒的脑袋靠在冷冰冰的枕头上,于是信步走向出口处。
她看到他离开吗?他经常意识到:当他离开时,当他每次骄傲而绝望地悄然从大厅、花园或其他欢乐的社交场合溜走时,他内心总暗暗怀着希望,希望他那一心向往的华光闪闪的人儿会怀着恻隐之心思念他一会儿。他站停身子,再一次伸长脖子向她望去。他内心在默默祈求,要是他依旧呆在那儿,坚持到底,在她身边盘桓不走,哪怕离她很远,等待着意想不到的幸福,那又怎样呢?——还是无济于事。彼此无法接近,不能相互了解,没有任何希望。走吧,走到黑暗中去,把脑袋埋在两只手里哭吧,只要你能够哭,只要在你那精神和艺术的、荒芜不毛的、冰天雪地的世界里还有眼泪!他离开了大厅。
他感到胸口一阵揪心的剧痛,同时又莫名其妙地期待什么。她应当见到他,应当理解他,应当走来,应当跟随他,即使仅仅出于怜悯也好;应当在半路上拉住他,对他说:站在那儿吧,振作起来,我爱你。他慢慢往前走,尽管他知道,一清二楚地知道,她是永远不会来的,这个跳跳蹦蹦、喋喋不休的小莉莉!
已是凌晨两点钟了。走廊里空无一人,衣帽间长桌后面的女管理员们向他睡眼蒙昽地点点头。除了他以外,谁也不想回家。他穿好大衣,拿起帽子和手杖,离开了剧场。
冬夜白茫茫的广场上,灯火通明。一辆辆马车列着长队停在那儿。车前的马儿垂下了头,背上盖着毯子。三五成群的马车夫把衣服裹得紧紧的,在厚厚的雪地里频频跺脚。德特勒夫向一个马车夫招招手;车夫准备着马儿,他却在剧院入口处的大厅里等候,让砭人肌骨的寒风拂打着他那怦怦跳动的太阳穴。
他喝了香槟酒后,嘴里觉得苦涩无味,很想抽烟。他机械地掏出一支烟来,划上一根火柴点燃起来。可是当火柴的火熄灭时,他看到了一个奇异的东西,起先他不理解这究竟是什么,只是垂着胳膊站在那儿发愣。他受不了这个,也忘不了这个……
火柴微弱的火花使他眼睛发花。当他的视力恢复过来时,他突然看到有一张狂野的脸,两颊深陷,脸上长着红红的胡子。他两眼充血,眼圈红肿,看去憔悴不堪。陌生人瞪着他看,目光中流露出嘲讽和绝望的神情,同时也带几分贪婪的好奇心。长着这张苦脸的汉子,站的地方离他只有两三步路,他斜倚在剧场入口处侧面的一根电线杆上,拳头插在很深的裤袋里,破破烂烂的上衣有一条领带向上翻起。他自上而下打量了德特勒夫一番,从皮大衣前挂着的望远镜一直到漆皮皮鞋,后来又用贪婪而渴求的眼光盯住对方直瞧。有一回,那汉子用鼻子短促而轻蔑地哼了一声,接着他的身子在寒冷中哆嗦起来,缩成一团,他那皮肉松弛的两颊看去就凹得更深,瑟瑟发抖的眼皮也闭上了,嘴角歪向下面,显得阴森可怖。
德特勒夫像扎根似地站住不动。他要尽力去理解其中缘由。他突然意识到,自己刚才参加了盛会,从剧院的门厅出来,向马车夫打招呼,并从银匣里掏出香烟来时,一定容光焕发,俨然一副富家子弟气派。他不由自主地抬起手来准备拍拍自己的脑袋。他朝那汉子走了一步,深深吸一口气,想同他说话,解释一番……可是他没有这么做,依然不吭一声地登上等候他的马车,几乎连地址也忘记告诉马车夫了。他惊慌失措,不知怎样把话说清楚才好。
天哪,这真是一场误会——这真是天大的误解!刚才,这个饥肠辘辘、被屏弃于生活之外的人用贪婪和痛苦的眼光凝视过他,神态是多么轻蔑,而且流露出何等的艳羡和渴望!这个饥饿的汉子呀,他是装模作样给人家看的吗?莫非那人瑟瑟发抖的身体,阴森可怖的脸是故意装出来的,为的是造成一个印象,好叫他这个时髦的幸运儿能在一瞬间起恻隐之心?可是朋友啊,你错了,你没有达到预期的效果。你那副受苦受难的脸相,对我并不是什么来自一个既陌生、又凶险的世界里的可怕而令人羞辱的警告。我们是同病相怜的兄弟哪!
朋友,你这里胸口上可有一块什么东西在烧灼?我知道得多清楚啊!你为什么来呢?为什么你不倨傲地呆在黑暗的角落里,而站到灯火通明的窗下,而窗户后面,乐声悠扬,人们正笑语盈盈?难道我不懂得驱使你去那边、并且用以哺育你苦难的那种病态的渴望,对这种苦难,你既可叫做恨,也可以称为爱?
丰富你的心灵的种种悲哀中,没有一种对我是陌生的,而你竟想来羞辱我!心灵是什么?它不过是仇恨的把戏罢了!艺术又是什么?只是一种创作欲而已?我们两人在受骗上当、忍饥挨饿、怨天尤人、否定一切这几个领域内,都称得上是行家,而这些充满着自我轻蔑的那些背信弃义的时刻,对我们来说都是共同的,我们怀着对生命的可耻的眷恋以及痴呆的快乐,沉湎于这些时刻里。可是你并不了解我。
错了!错了!——当他觉得这一切都不胜惋惜时,他内心深处的某个地方忽然闪亮了既痛苦、又甜蜜的预感。——只有他才错了吗?错误会有怎样的结局?渴望尘世的一切莫非都是错误,首先是我的错误——错误在于渴求某种朴质的和充满激情的活力,以及渴求那种既不懂得如何通过心灵和艺术来启迪别人、又不懂得如何通过文字来解脱自己的沉默的生活?唉,我们大家都是兄弟姐妹,我们得不到安宁的受苦难的人啊;我们不了解自己。需要另一种爱,另一种。
当他回到家里坐在书籍、图画以及默默看着他的一些胸像的下面时,他感动地说出下面一些脉脉含情的话来:
“孩子们,你们要彼此相爱……”
-----
(钱鸿嘉译)
记钱锺书与《围城》- 杨绛
========================
记钱锺书与《围城》- [[杨绛]]
------
自从一九八〇年《围城》在国内重印以来,我经常看到锺书对来信和登门的读者表示歉意:或是诚诚恳恳地奉劝别研究什么《围城》;或客客气气地推说“无可奉告”;或者竟是既欠礼貌又不讲情理的拒绝。一次我听他在电话里对一位求见的英国女士说:“假如你吃了个鸡蛋觉得不错,何必认识那下蛋的母鸡呢?”我直耽心他冲撞人。胡乔木同志偶曾建议我写一篇《钱锺书与〈围城〉》。我确也手痒,但以我的身份,容易写成锺书所谓“亡夫行述”之类的文章。不过我既不称赞,也不批评,只据事纪实;锺书读后也承认没有失真。这篇文章原是朱正同志所编《骆驼丛书》中的一册,也许能供《围城》的偏爱者参考之用。
一九八五年十二月
## 一 钱锺书写《围城》
钱锺书在《围城》的序里说,这本书是他“锱铢积累”写成的。我是“锱铢积累”读完的。每天晚上,他把写成的稿子给我看,急切地瞧我怎样反应。我笑,他也笑;我大笑,他也大笑。有时我放下稿子,和他相对大笑,因为笑的不仅是书上的事,还有书外的事。我不用说明笑什么,反正彼此心照不宣。然后他就告诉我下一段打算写什么,我就急切地等着看他怎么写。他平均每天写五百字左右。他给我看的是定稿,不再改动。后来他对这部小说以及其它“少作”都不满意,恨不得大改特改,不过这是后话了。
锺书选注宋诗,我曾自告奋勇,愿充白居易的“老妪”——也就是最低标准;如果我读不懂,他得补充注释。可是在《围城》的读者里,我却成了最高标准。好比学士通人熟悉古诗文里词句的来历,我熟悉故事里人物和情节的来历。除了作者本人,最有资格为《围城》做注释的,该是我了。
看小说何需注释呢?可是很多读者每对一本小说发生兴趣,就对作者也发生兴趣,并把小说里的人物和情节当做真人实事。有的干脆把小说的主角视为作者本人。高明的读者承认作者不能和书中人物等同,不过他们说,作者创造的人物和故事,离不开他个人的经验和思想感情。这话当然很对。可是我曾在一篇文章里指出:创作的一个重要成分是想象,经验好比黑暗里点上的火,想象是这个火所发的光;没有火就没有光,但光照所及,远远超过火点儿的大小。①创造的故事往往从多方面超越作者本人的经验。要从创造的故事里返求作者的经验是颠倒的。作者的思想情感经过创造,就好比发过酵而酿成了酒;从酒里辨认酿酒的原料,大非易事。我有机缘知道作者的经历,也知道酿成的酒是什么原料,很愿意让读者看看真人实事和虚构的人物情节有多大的距离,而且是怎样的错乱。许多所谓写实的小说,其实是改头换面地叙写自己的经历,提升或满足自己的感情。这种自传体的小说或小说体的自传,实在是浪漫的纪实,不是写实的虚构。而《围城》却是一部虚构写实的小说,尽管读来好像真有其事,真有其人,其实全是创造。
《围城》里写方鸿渐本乡出名的行业是打铁、磨豆腐,名产是泥娃娃。有人读到这里,不禁得意地大哼一声说:“这不是无锡吗?钱锺书不是无锡人吗?他不也留过洋吗?不也在上海住过吗?不也在内地教过书吗?”有一位专爱考据的先生,竟推断出钱锺书的学位也靠不住,方鸿渐就是钱锺书的结论更可以成立了。
钱锺书是无锡人,一九三三年毕业于清华大学,在上海光华大学教了两年英语,一九三五年考取英庚款到英国牛津留学,一九三七年得文学学士(B.Litt.)学位,然后到法国,入巴黎大学进修。他本想读学位,后来打消了原意。一九三八年,清华大学聘他为教授。据那时候清华的文学院长冯友兰先生来函说,这是破例的事,因为按清华旧例,初回国教书只当讲师,由讲师升副教授,然后升为教授。锺书九十月间回国,在香港上岸,转昆明到清华任教。那时清华已并入西南联大。他父亲原是国立浙江大学教授,应老友廖茂如先生恳请,到湖南蓝田帮他创建国立师范学院;他母亲弟妹等随叔父一家逃难住上海。一九三九年秋,锺书自昆明回上海探亲后,他父亲来信来电,说自己老病,要锺书也去湖南照料。师范学院院长廖先生来上海,反复劝说他去当英文系主任,以便伺候父亲,公私兼顾。这样,他就未回昆明而到湖南去了。一九四〇年暑假,他和一位同事结伴回上海探亲,道路不通,半途折回。一九四一年暑假,他由广西到海防搭海轮到上海,准备小住几月再回内地。西南联大外文系主任陈福田先生在秋季开学以后到上海相访,约他再回联大,钱锺书没有应聘。值珍珠港事变,他就沦陷在上海了。他写过一首七律《古意》,内有一联说:“槎通碧汉无多路,梦入红楼第几层”,另一首《古意》又说:“心如红杏专春闹,眼似黄梅诈雨晴”,都是寄托当时羁居沦陷区的怅惘情绪。《围城》是沦陷在上海的时期写的。
锺书和我一九三二年春在清华初识,一九三三年订婚,一九三五年结婚,同船到英国(我是自费留学),一九三七年秋同到法国,一九三八年秋同船回国。我母亲一年前去世,我苏州的家已被日寇抢劫一空,父亲避难上海,寄居我姐夫家。我急要省视老父,锺书在香港下船到昆明,我乘原船直接到上海。当时我中学母校的校长留我在“孤岛”的上海建立“分校”。二年后上海沦陷,“分校”停办,我暂当家庭教师,又在小学代课,业余创作话剧。锺书陷落上海没有工作,我父亲把自己在震旦女子文理学院授课的钟点让给他,我们就在上海艰苦度日。
有一次,我们同看我编写的话剧上演,回家后他说:“我想写一部长篇小说!”我大为高兴,催他快写。那时他正偷空写短篇小说,怕没有时间写长篇。我说不要紧,他可以减少授课的时间,我们的生活很省俭,还可以更省俭。恰好我们的女佣因家乡生活好转要回去。我不勉强她,也不另觅女佣,只把她的工作自己兼任了。劈柴生火烧饭洗衣等等我是外行,经常给煤烟染成花脸,或熏得满眼是泪,或给滚油烫出泡来,或切破手指。可是我急切要看锺书写《围城》(他已把题目和主要内容和我讲过),做灶下婢也心甘情愿。
《围城》是一九四四年动笔,一九四六年完成的。他就像原《序》所说:“两年里忧世伤生”,有一种惶急的情绪,又忙着写《谈艺录》;他三十五岁生日诗里有一联:“书癖钻窗蜂未出,诗情绕树鹊难安”,正是写这种兼顾不及的心境。那时候我们住在钱家上海避难的大家庭里,包括锺书父亲一家和叔父一家。两家同住分炊。锺书的父亲一直在外地,锺书的弟弟妹妹弟媳和侄儿女等已先后离开上海,只剩他母亲没走,还有一个弟弟单身留在上海;所谓大家庭也只像个小家庭了。
以上我略叙锺书的经历、家庭背景和他撰写《围城》时的处境,为作者写个简介。下面就要为《围城》做些注解,让读者明白:《围城》只是小说,是创作而不是传记。
锺书从他熟悉的时代、熟悉的地方、熟悉的社会阶层取材。但组成故事的人物和情节全属虚构。尽管某几个角色稍有真人的影子,事情都子虚乌有;某些情节略具真实,人物却全是捏造的。
方鸿渐取材于两个亲戚:一个志大才疏,常满腹牢骚;一个狂妄自大,爱自吹自唱。两人都读过《围城》,但是谁也没自认为方鸿渐,因为他们从未有方鸿渐的经历。锺书把方鸿渐作为故事的中心,常从他的眼里看事,从他的心里感受。不经意的读者会对他由了解而同情,由同情而关切,甚至把自己和他合而为一。许多读者以为他就是作者本人。法国十九世纪小说《包法利夫人》的作者福楼拜曾说:“包法利夫人,就是我。”那么,钱锺书照样可说:“方鸿渐,就是我。”不过还有许多男女角色都可说是钱锺书,不光是方鸿渐一个。方鸿渐和钱锺书不过都是无锡人罢了,他们的经历远不相同。
我们乘法国邮船阿多士Ⅱ(Athos Ⅱ)回国,甲板上的情景和《围城》里写的很像,包括法国警官和犹太女人调情,以及中国留学生打麻将等等。鲍小姐却纯是虚构。我们出国时同船有一个富有曲线的南洋姑娘,船上的外国人对她大有兴趣,把她看做东方美人。我们在牛津认识一个由未婚夫资助留学的女学生,听说很风流。牛津有个研究英国语文的埃及女学生,皮肤黑黑的,我们两人都觉得她很美。鲍小姐是综合了东方美人、风流未婚妻和埃及美人而抟捏出来的。锺书曾听到中国留学生在邮船上偷情的故事,小说里的方鸿渐就受了鲍小姐的引诱。鲍鱼之肆是臭的,所以那位小姐姓鲍。
苏小姐也是东鳞西爪凑成的:相貌是经过美化的一个同学,心眼和感情属于另一人,这人可一点不美;走单帮贩私货的又另是一人。苏小姐做的那首诗是锺书央我翻译的;他嘱我不要翻得好,一般就行。苏小姐的丈夫是另一个同学,小说里乱点了鸳鸯谱。结婚穿黑色礼服、白硬领圈给汗水浸得又黄又软的那位新郎,不是别人,正是锺书自己。因为我们结婚的黄道吉日是一年里最热的日子。我们的结婚照上,新人、伴娘、提花篮的女孩子、提纱的男孩子,一个个都像刚被警察拿获的扒手。
赵辛楣是由我们喜欢的一个五六岁的男孩子变大的,锺书为他加上了二十多岁年纪。这孩子至今没有长成赵辛楣,当然也不可能有赵辛楣的经历。如果作者说:“方鸿渐,就是我”,他准也会说:“赵辛楣,就是我。”
有两个不甚重要的人物有真人的影子,作者信手拈来,未加融化,因此那两位相识都“对号入座”了。一位满不在乎,另一位听说很生气。锺书夸张了董斜川的一个方面,未及其他。但董斜川的谈吐和诗句,并没有一言半语抄袭了现成,全都是捏造的。褚慎明和他的影子并不对号。那个影子的真身比褚慎明更夸张些呢。有一次我和他同乘火车从巴黎郊外进城,他忽从口袋里掏出一张纸,上面开列了少女选择丈夫的种种条件,如相貌、年龄、学问、品性、家世等等共十七八项,逼我一一批分数,并排列先后。我知道他的用意,也知道他的对象,所以小心翼翼地应付过去。他接着气呼呼地对我说:“她们说他(指锺书)‘年少翩翩’,你倒说说,他‘翩翩’不‘翩翩’。”我应该厚道些,老实告诉他,我初识锺书的时候,他穿一件青布大褂,一双毛布底鞋,戴一副老式大眼镜,一点也不“翩翩”。可是我瞧他认为我该和他站在同一立场,就忍不住淘气说:“我当然最觉得他‘翩翩’。”他听了怫然,半天不言语。后来我称赞他西装笔挺,他惊喜说:“真的吗?我总觉得自己的衣服不挺,每星期洗熨一次也不如别人的挺。”我肯定他衣服确实笔挺,他才高兴。其实,褚慎明也是个复合体,小说里的那杯牛奶是另一人喝的。那人也是我们在巴黎时的同伴,他尚未结婚,曾对我们讲:他爱“天仙的美”,不爱“妖精的美”。他的一个朋友却欣赏“妖精的美”,对一个牵狗的妓女大有兴趣,想“叫一个局”,把那妓女请来同喝点什么谈谈话。有一晚,我们一群人同坐咖啡馆,看见那个牵狗的妓女进另一家咖啡馆去了。“天仙美”的爱慕者对“妖精美”的爱慕者自告奋勇说:“我给你去把她找来。”他去了好久不见回来,锺书说:“别给蜘蛛精网在盘丝洞里了,我去救他吧。”锺书跑进那家咖啡馆,只见“天仙美”的爱慕者独坐一桌,正在喝一杯很烫的牛奶,四围都是妓女,在窃窃笑他。锺书“救”了他回来。从此,大家常取笑那杯牛奶,说如果叫妓女,至少也该喝杯啤酒,不该喝牛奶。准是那杯牛奶作祟,使锺书把褚慎明拉到饭馆去喝奶;那大堆的药品准也是即景生情,由那杯牛奶生发出来的。
方遯翁也是个复合体。读者因为他是方鸿渐的父亲,就确定他是锺书的父亲,其实方遯翁和他父亲只有几分相像。我和锺书订婚前后,锺书的父亲擅自拆看了我给锺书的信,大为赞赏,直接给我写了一封信,郑重把锺书托付给我。这很像方遯翁的作风。我们沦陷在上海时,他来信说我“安贫乐道”,这也很像方遯翁的语气。可是,如说方遯翁有二三分像他父亲,那么,更有四五分是像他叔父,还有几分是捏造,因为亲友间常见到这类的旧式家长。锺书的父亲和叔父都读过《围城》。他父亲莞尔而笑;他叔父的表情我们没看见。我们夫妇常私下捉摸,他们俩是否觉得方遯翁和自己有相似之处。
唐晓芙显然是作者偏爱的人物,不愿意把她嫁给方鸿渐。其实,作者如果让他们成为眷属,由眷属再吵架闹翻,那么,结婚如身陷围城的意义就阐发得更透彻了。方鸿渐失恋后,说赵辛楣如果娶了苏小姐也不过尔尔,又说结婚后会发现娶的总不是意中人。这些话都很对。可是他究竟没有娶到意中人,他那些话也就可释为聊以自慰的话。
至于点金银行的行长,“我你他”小姐的父母等等,都是上海常见的无锡商人,我不再一一注释。
我爱读方鸿渐一行五人由上海到三闾大学旅途上的一段。我没和锺书同到湖南去,可是他同行五人我全认识,没一人和小说里的五人相似,连一丝影儿都没有。王美玉的卧房我倒见过:床上大红绸面的被子,叠在床里边;桌上大圆镜子,一个女人脱了鞋坐在床边上,旁边煎着大半脸盆的鸦片。那是我在上海寻找住房时看见的,向锺书形容过。我在清华做学生的时期,春假结伴旅游,夜宿荒村,睡在铺干草的泥地上,入夜梦魇,身下一个小娃娃直对我嚷:“压住了我的红棉袄”,一面用手推我,却推不动。那番梦魇,我曾和锺书讲过。蛆叫“肉芽”,我也曾当做新鲜事告诉锺书。锺书到湖南去,一路上都有诗寄我。他和旅伴游雪窦山,有纪游诗五古四首,我很喜欢第二第三首,我不妨抄下,作为真人实事和小说的对照。
```
天风吹海水,屹立作山势;
浪头飞碎白,积雪疑几世。
我常观乎山,起伏有水致;
蜿蜒若没骨,皱具波涛意。
乃知水与山,思各出其位,
譬如豪杰人,异量美能备。
固哉鲁中叟,祗解别仁智。
山容太古静,而中藏瀑布,
不舍昼夜流,得雨势更怒。
辛酸亦有泪,贮胸敢倾吐;
略似此山然,外勿改其度。
相契默无言,远役喜一晤。
微恨多游踪,藏焉未为固。
衷曲莫浪陈,悠悠彼行路。
```
小说里只提到游雪窦山,一字未及游山的情景。游山的自是游山的人,方鸿渐、李梅亭等正忙着和王美玉打交道呢。足见可捏造的事丰富得很,实事尽可抛开,而且实事也挤不进这个捏造的世界。
李梅亭途遇寡妇也有些影子。锺书有一位朋友是忠厚长者,旅途上碰到一个自称落难的寡妇;那位朋友资助了她,后来知道是上当。我有个同学绰号“风流寡妇”,我曾向锺书形容她临睡洗去脂粉,脸上眉眼口鼻都没有了。大约这两件不相干的事凑出来一个苏州寡妇,再碰上李梅亭,就生出“倷是好人”等等妙语奇文。
汪处厚的夫人使我记起我们在上海一个邮局里看见的女职员。她头发枯黄,脸色苍白,眼睛斜撇向上,穿一件浅紫色麻纱旗袍。我曾和锺书讲究,如果她皮肤白腻而头发细软乌黑,浅紫的麻纱旗袍换成线条柔软的深紫色绸旗袍,可以变成一个美人。汪太太正是这样一位美人,我见了似曾相识。
范小姐、刘小姐之流想必是大家熟悉的,不必再介绍。孙柔嘉虽然跟着方鸿渐同到湖南又同回上海,我却从未见过。相识的女人中间(包括我自己),没一个和她相貌相似。但和她稍多接触,就发现她原来是我们这个圈子里最寻常可见的。她受过高等教育,没什么特长,可也不笨;不是美人,可也不丑;没什么兴趣,却有自己的主张。方鸿渐“兴趣很广,毫无心得”;她是毫无兴趣而很有打算。她的天地极小,只局限在“围城”内外。她所享的自由也有限,能从城外挤入城里,又从城里挤出城外。她最大的成功是嫁了一个方鸿渐,最大的失败也是嫁了一个方鸿渐。她和方鸿渐是芸芸知识分子间很典型的夫妇。孙柔嘉聪明可喜的一点是能画出汪太太的“扼要”:十点红指甲,一张红嘴唇。一个年轻女子对自己又羡又妒又瞧不起的女人,会有这种尖刻。但这点聪明还是锺书赋予她的。锺书惯会抓住这类“扼要”,例如他能抓住每个人声音里的“扼要”,由声音辨别说话的人,尽管是从未识面的人。
也许我正像堂吉诃德那样,挥剑捣毁了木偶戏台,把《围城》里的人物斫得七零八落,满地都是硬纸做成的断肢残骸。可是,我逐段阅读这部小说的时候,使我放下稿子大笑的,并不是发现了真人实事,却是看到真人实事的一鳞半爪,经过拼凑点化,创出了从未相识的人,捏造了从未想到的事。我大笑,是惊喜之余,不自禁地表示“我能拆穿你的西洋镜”。锺书陪我大笑,是了解我的笑,承认我笑的不错,也带着几分得意。
可能我和堂吉诃德一样,做了非常扫兴的事。不过,我相信,这一来可以说明《围城》绝非真人实事。
## 二 写《围城》的钱锺书
要认识作者,还是得认识他本人,最好从小时候起。
锺书一出世就由他伯父抱去抚养,因为伯父没有儿子。据钱家的“坟上风水”,不旺长房旺小房;长房往往没有子息,便有,也没出息,伯父就是“没出息”的长子。他比锺书的父亲大十四岁,二伯父早亡,他父亲行三,叔父行四,两人是同胞双生,锺书是长孙,出嗣给长房。伯父为锺书连夜冒雨到乡间物色得一个壮健的农妇;她是寡妇,遗腹子下地就死了,是现成的好奶妈(锺书称为“姆妈”)。姆妈一辈子帮在钱家,中年以后,每年要呆呆地发一阵子呆,家里人背后称为“痴姆妈”。她在锺书结婚前特地买了一只翡翠镶金戒指,准备送我做见面礼。有人哄她那是假货,把戒指骗去,姆妈气得大发疯,不久就去世了,我始终没见到她。
锺书自小在大家庭长大,和堂兄弟的感情不输亲兄弟。亲的、堂的兄弟共十人,锺书居长。众兄弟间,他比较稚钝,孜孜读书的时候,对什么都没个计较,放下书本,又全没正经,好像有大量多余的兴致没处寄放,专爱胡说乱道。钱家人爱说他吃了痴姆妈的奶,有“痴气”。我们无锡人所谓“痴”,包括很多意义:疯、傻、憨、稚气、气、淘气等等。他父母有时说他“痴颠不拉”、“痴巫作法”、“呒着呒落”(“着三不着两”的意思——我不知正确的文字,只按乡音写)。他确也不像他母亲那样沉默寡言、严肃谨慎,也不像他父亲那样一本正经。他母亲常抱怨他父亲“憨”。也许锺书的“痴气”和他父亲的憨厚正是一脉相承的。我曾看过他们家的旧照片。他的弟弟都精精壮壮,惟他瘦弱,善眉善眼的一副忠厚可怜相。想来那时候的“痴气”只是稚气、气,还不会淘气呢。
锺书周岁“抓周”,抓了一本书,因此取名“锺书”。他出世那天,恰有人送来一部《常州先哲丛书》,伯父已为他取名“仰先”,字“哲良”。可是周岁有了“锺书”这个学名,“仰先”就成为小名,叫作“阿先”。但“先儿”、“先哥”好像“亡儿”、“亡兄”,“先”字又改为“宣”,他父亲仍叫他“阿先”。(他父亲把锺书写的家信一张张贴在本子上,有厚厚许多本,亲手贴上题签“先儿家书(一)、(二)、(三)……”;我还看到过那些本子和上面贴的信。)伯父去世后,他父亲因锺书爱胡说乱道,为他改字“默存”,叫他少说话的意思。锺书对我说:“其实我喜欢‘哲良’,又哲又良——我闭上眼睛,还能看到伯伯给我写在练习簿上的‘哲良’。”这也许因为他思念伯父的缘故。我觉得他确是又哲又良,不过他“痴气”盎然地胡说乱道,常使他不哲不良——假如淘气也可算不良。“默存”这个号显然没有起克制作用。
伯父“没出息”,不得父母欢心,原因一半也在伯母。伯母娘家是江阴富户,做颜料商发财的,有七八只运货的大船。锺书的祖母娘家是石塘湾孙家,官僚地主,一方之霸。婆媳彼此看不起,也影响了父子的感情。伯父中了秀才回家,进门就挨他父亲一顿打,说是“杀杀他的势气”;因为锺书的祖父虽然有两个中举的哥哥,他自己也不过是个秀才。锺书不到一岁,祖母就去世了。祖父始终不喜欢大儿子,锺书也是不得宠的孙子。
锺书四岁(我纪年都用虚岁,因为锺书只记得虚岁,而锺书是阳历十一月下旬生的,所以周岁当减一岁或二岁)由伯父教他识字。伯父是慈母一般,锺书成天跟着他。伯父上茶馆,听说书,锺书都跟去。他父亲不便干涉,又怕惯坏了孩子,只好建议及早把孩子送入小学。锺书六岁入秦氏小学。现在他看到人家大讲“比较文学”,就记起小学里造句:“狗比猫大,牛比羊大”;有个同学比来比去,只是“狗比狗大,狗比狗小”,挨了老师一顿骂。他上学不到半年,生了一场病,伯父舍不得他上学,借此让他停学在家。他七岁,和比他小半岁的堂弟锺韩同在亲戚家的私塾附学,他念《毛诗》,锺韩念《尔雅》。但附学不便,一年后他和锺韩都在家由伯父教。伯父对锺书的父亲和叔父说:“你们两兄弟都是我启蒙的,我还教不了他们?”父亲和叔父当然不敢反对。
其实锺书的父亲是由一位族兄启蒙的。祖父认为锺书的父亲笨,叔父聪明,而伯父的文笔不顶好。叔父反正聪明,由伯父教也无妨,父亲笨,得请一位文理较好的族兄来教。那位族兄严厉得很,锺书的父亲挨了不知多少顿痛打。伯父心疼自己的弟弟,求了祖父,让两个弟弟都由他教。锺书的父亲挨了族兄的痛打一点不抱怨,却别有领会。他告诉锺书:“不知怎么的,有一天忽然给打得豁然开通了。”
锺书和锺韩跟伯父读书,只在下午上课。他父亲和叔父都有职业,家务由伯父经管。每天早上,伯父上茶馆喝茶,料理杂务,或和熟人聊天。锺书总跟着去。伯父花一个铜板给他买一个大酥饼吃(据锺书比给我看,那个酥饼有饭碗口大小,不知是真有那么大,还是小儿心目中的饼大);又花两个铜板,向小书铺子或书摊租一本小说给他看。家里的小说只有《西游记》、《水浒》、《三国演义》等正经小说。锺书在家里已开始囫囵吞枣地阅读这类小说,把“獃子”读如“岂子”,也不知《西游记》里的“獃子”就是猪八戒。书摊上租来的《说唐》、《济公传》、《七侠五义》之类是不登大雅的,家里不藏。锺书吃了酥饼就孜孜看书,直到伯父叫他回家。回家后便手舞足蹈向两个弟弟演说他刚看的小说:李元霸或裴元庆或杨林(我记不清)一锤子把对手的枪打得弯弯曲曲等等。他纳闷儿的是,一条好汉只能在一本书里称雄。关公若进了《说唐》,他的青龙偃月刀只有八十斤重,怎敌得李元霸的那一对八百斤重的锤头子;李元霸若进了《西游记》,怎敌得过孙行者的一万三千斤的金箍棒(我们在牛津时,他和我讲哪条好汉使哪种兵器,重多少,历历如数家珍)。妙的是他能把各件兵器的斤两记得烂熟,却连阿拉伯数字的 1、2、3 都不认识。锺韩下学回家有自己的父亲教,伯父和锺书却是“老鼠哥哥同年伴儿”。伯父用绳子从高处挂下一团棉花,教锺书上、下、左、右打那团棉花,说是打“棉花拳”,可以练软功。伯父爱喝两口酒。他手里没多少钱,只能买些便宜的熟食如酱猪舌之类下酒,哄锺书那是“龙肝凤髓”,锺书觉得其味无穷。至今他喜欢用这类名称,譬如洋火腿在我家总称为“老虎肉”。他父亲不敢得罪哥哥,只好伺机把锺书抓去教他数学;教不会,发狠要打又怕哥哥听见,只好拧肉,不许锺书哭。锺书身上一块青、一块紫,晚上脱掉衣服,伯父发现了不免心疼气恼。锺书和我讲起旧事,对父亲的着急不胜同情,对伯父的气恼也不胜同情,对自己的忍痛不敢哭当然也同情,但回忆中只觉得滑稽又可怜。我笑说:痛打也许能打得“豁然开通”,拧,大约是把窍门拧塞了。锺书考大学,数学只考得十五分。
锺书小时候最乐的事是跟伯母回江阴的娘家去;伯父也同去(堂姊已出嫁)。他们往往一住一两个月。伯母家有个大庄园,锺书成天跟着庄客四处田野里闲逛。他常和我讲田野的景色。一次大雷雨后,河边树上挂下一条大绿蛇,据说是天雷打死的。伯母娘家全家老少都抽大烟,后来伯父也抽上了。锺书往往半夜醒来,跟着伯父伯母吃半夜餐。当时快乐得很,回无锡的时候,吃足玩够,还穿着外婆家给做的新衣。可是一回家他就担忧,知道父亲要盘问功课,少不了挨打。父亲不敢当着哥哥管教锺书,可是抓到机会,就着实管教,因为锺书不但荒了功课,还养成不少坏习气,如晚起晚睡、贪吃贪玩等。
一九一九年秋天,我家由北京回无锡。我父母不想住老家,要另找房子。亲友介绍了一处,我父母去看房子,带了我同去。锺书家当时正租居那所房子。那是我第一次上他们钱家的门,只是那时两家并不相识。我记得母亲说,住在那房子里的一位女眷告诉她,搬进以后,没离开过药罐儿。那所房子我家没看中;钱家虽然嫌房子阴暗,也没有搬出。他们五年后才搬入七尺场他们家自建的新屋。我记不起那次看见了什么样的房子或遇见了什么人,只记得门口下车的地方很空旷,有两棵大树;很高的白粉墙,粉墙高处有一个个砌着镂空花的方窗洞。锺书说我记忆不错,还补充说,门前有个大照墙,照墙后有一条河从门前流过。他说,和我母亲说话的大约是婶母,因为叔父婶母住在最外一进房子里,伯父伯母和他住中间一进,他父母亲伺奉祖父住最后一进。
我女儿取笑说:“爸爸那时候不知在哪儿淘气呢。假如那时候爸爸看见妈妈那样的女孩子,准抠些鼻牛儿来弹她。”锺书因此记起旧事说,有个女裁缝常带着个女儿到他家去做活;女儿名宝宝,长得不错,比他大两三岁。他和锺韩一次抓住宝宝,把她按在大厅隔扇上,锺韩拿一把削铅笔的小脚刀作势刺她。宝宝大哭大叫,由大人救援得免。兄弟俩觉得这番胜利当立碑纪念,就在隔扇上刻了“刺宝宝处”四个字。锺韩手巧,能刻字,但那四个字未经简化,刻来煞是费事。这大概是顽童刚开始“知慕少艾”的典型表现。后来房子退租的时候,房主提出赔偿损失,其中一项就是隔扇上刻的那四个不成形的字。另一项是锺书一人干的坏事,他在后园“挖人参”,把一棵玉兰树的根刨伤,那棵树半枯了。
锺书十一岁,和锺韩同考取东林小学一年级,那是四年制的高等小学。就在那年秋天,伯父去世。锺书还未放学,经家人召回,一路哭着赶回家去,哭叫“伯伯”,伯父已不省人事。这是他生平第一次遭受的伤心事。
伯父去世后,伯母除掉长房应有的月钱以外,其它费用就全由锺书父亲负担了。伯母娘家败得很快,兄弟先后去世,家里的大货船逐渐卖光。锺书的学费、书费当然有他父亲负担,可是学期中间往往添买新课本,锺书没钱买,就没有书;再加他小时候贪看书摊上伯父为他租的小字书,看坏了眼睛,坐在教室后排,看不见老师黑板上写的字,所以课堂上老师讲什么,他茫无所知。练习簿买不起,他就用伯父生前亲手用毛边纸、纸捻子为他订成的本子,老师看了直皱眉。练习英文书法用钢笔。他在开学的时候有一支笔杆、一个钢笔尖,可是不久笔尖撅断了头。同学都有许多笔尖,他只有一个,断了头就没法写了。他居然急中生智,把毛竹筷削尖了头蘸着墨水写,当然写得一塌糊涂,老师简直不愿意收他的练习簿。
我问锺书为什么不问父亲要钱。他说,从来没想到过。有时伯母叫他向父亲要钱,他也不说。伯母抽大烟,早上起得晚,锺书由伯母的陪嫁大丫头热些馊粥吃了上学。他同学、他弟弟都穿洋袜,他还穿布袜,自己觉得脚背上有一条拼缝很刺眼,只希望穿上棉鞋可遮掩不见。雨天,同学和弟弟穿皮鞋,他穿钉鞋,而且是伯伯的钉鞋,太大,鞋头塞些纸团。一次雨天上学,路上看见许多小青蛙满地蹦跳,觉得好玩,就脱了鞋捉来放在鞋里,抱着鞋光脚上学;到了教室里,把盛着小青蛙的钉鞋放在台板桌下。上课的时候,小青蛙从鞋里出来,满地蹦跳。同学都忙着看青蛙,窃窃笑乐。老师问出因由,知道青蛙是从锺书鞋里出来的,就叫他出来罚立。有一次他上课玩弹弓,用小泥丸弹人。中弹的同学嚷出来,老师又叫他罚立。可是他混混沌沌,并不觉得羞惭。他和我讲起旧事常说,那时候幸亏糊涂,也不觉得什么苦恼。
锺书跟我讲,小时候大人哄他说,伯母抱来一个南瓜,成了精,就是他;他真有点儿怕自己是南瓜精。那时候他伯父已经去世,“南瓜精”是舅妈、姨妈等晚上坐在他伯母鸦片榻畔闲谈时逗他的,还正色嘱咐他切莫告诉他母亲。锺书也怀疑是哄他,可是真有点担心。他自说混沌,恐怕是事实。这也是家人所谓“痴气”的表现之一。
他有些混沌表现,至今依然如故。例如他总记不得自己的生年月日。小时候他不会分辨左右,好在那时候穿布鞋,不分左右鞋。后来他和锺韩同到苏州上美国教会中学的时候,穿了皮鞋,他仍然不分左右乱穿。在美国人办的学校里,上体育课也用英语喊口号。他因为英文好,当上了一名班长。可是嘴里能用英语喊口号,两脚却左右不分;因此只当了两个星期的班长就给老师罢了官,他也如释重负。他穿内衣或套脖的毛衣,往往前后颠倒,衣服套在脖子上只顾前后掉转。结果还是前后颠倒了。或许这也是钱家人说他“痴”的又一表现。
锺书小时最喜欢玩“石屋里的和尚”。我听他讲得津津有味,以为是什么有趣的游戏;原来只是一人盘腿坐在帐子里,放下帐门,披着一条被单,就是“石屋里的和尚”。我不懂那有什么好玩。他说好玩得很;晚上伯父伯母叫他早睡,他不肯,就玩“石屋里的和尚”,玩得很乐。所谓“玩”,不过是一个人盘腿坐着自言自语。小孩自言自语,其实是出声的想象。我问他是否编造故事自娱,他却记不得了。这大概也算是“痴气”吧。
锺书上了四年高小,居然也毕业了。锺韩成绩斐然,名列前茅;他只是个痴头傻脑、没正经的孩子。伯父在世时,自愧没出息,深怕“坟上风水”连累了嗣给长房的锺书。原来他家祖坟下首的一排排树高大茂盛,上首的细小萎弱。上首的树当然就代表长房了。伯父一次私下花钱向理发店买了好几斤头发,叫一个佃户陪着,悄悄带着锺书同上祖坟去,把头发埋在上首几排树的根旁。他对锺书说,要叫上首的树荣盛,“将来你做大总统”。那时候锺书才七八岁,还不懂事,不过多少也感觉到那是伯父背着人干的私心事,所以始终没向家里任何别人讲过。他讲给我听的时候,语气中还感念伯父对他的爱护,也惊奇自己居然有心眼为伯父保密。
锺书十四岁和锺韩同考上苏州桃坞中学(美国圣公会办的学校)。父母为他置备了行装,学费书费之外,还有零用钱。他就和锺韩同往苏州上学,他功课都还不错,只算术不行。
那年②他父亲到北京清华大学任教,寒假没回家。锺书寒假回家没有严父管束,更是快活。他借了大批的《小说世界》、《红玫瑰》、《紫萝兰》等刊物恣意阅读。暑假他父亲归途阻塞,到天津改乘轮船,辗转回家,假期已过了一半。他父亲回家第一事是命锺书锺韩各做一篇文章;锺韩的一篇颇受夸赞,锺书的一篇不文不白,用字庸俗,他父亲气得把他痛打一顿。锺书忍笑向我形容他当时的窘况:家人都在院子里乘凉,他一人还在大厅上,挨了打又痛又羞,呜呜地哭。这顿打虽然没有起“豁然开通”的作用,却也激起了发奋读书的志气。锺书从此用功读书,作文大有进步。他有时不按父亲教导的方法作古文,嵌些骈俪,倒也受到父亲赞许。他也开始学着做诗,只是并不请教父亲。一九二七年桃坞中学停办,他和锺韩同考入美国圣公会办的无锡辅仁中学,锺书就经常有父亲管教,常为父亲代笔写信,由口授而代写,由代写信而代作文章。锺书考入清华之前,已不复挨打而是父亲得意的儿子了。一次他代父亲为乡下某大户作了一篇墓志铭。那天午饭时,锺书的姆妈听见他父亲对他母亲称赞那篇文章,快活得按捺不住,立即去通风报信,当着他伯母对他说:“阿大啊,爹爹称赞你呢!说你文章做得好!”锺书是第一次听到父亲称赞,也和姆妈一样高兴,所以至今还记得清清楚楚。那时商务印书馆出版钱穆的一本书,上有锺书父亲的序文。据锺书告诉我,那是他代写的,一字没有改动。
我常见锺书写客套信从不起草,提笔就写,八行笺上,几次抬头,写来恰好八行,一行不多,一行不少。锺书说,那都是他父亲训练出来的,他额角上挨了不少“爆栗子”呢。
锺书二十岁伯母去世。那年他考上清华大学,秋季就到北京上学。他父亲收藏的“先儿家书”是那时候开始的。他父亲身后,锺书才知道父亲把他的每一封信都贴在本子上珍藏。信写得非常有趣,对老师、同学都有生动的描写。可惜锺书所有的家书(包括写给我的),都由“回禄君”收集去了。
锺书在清华的同班同学饶余威一九六八年在新加坡或台湾写了一篇《清华的回忆》③,有一节提到锺书:“同学中我们受钱锺书的影响最大。他的中英文造诣很深,又精于哲学及心理学,终日博览中西新旧书籍,最怪的是上课时从不记笔记,只带一本和课堂无关的闲书,一面听讲一面看自己的书,但是考试总是第一,他自己喜欢读书,也鼓励别人读书……”据锺书告诉我,他上课也带笔记本,只是不作笔记,却在本子上乱画。现在美国的许振德君和锺书是同系同班。他最初因锺书夺去了班上的第一名,曾想揍他一顿出气,因为他和锺书同学之前,经常是名列第一的。一次偶有个不能解决的问题,锺书向他讲解了,他很感激,两人成了朋友,上课常同坐在最后一排。许君上课时注意一女同学,锺书就在笔记本上画了一系列的《许眼变化图》,在同班同学里颇为流传,锺书曾得意地画给我看。一年前许君由美国回来,听锺书说起《许眼变化图》还忍不住大笑。
锺书小时候,中药房卖的草药每一味都有两层纸包裹;外面一张白纸,里面一张印着药名和药性。每服一副药可攒下一叠包药的纸。这种纸干净、吸水,锺书大约八九岁左右常用包药纸来临摹他伯父藏的《芥子园画谱》,或印在《唐诗三百首》里的“诗中之画”。他为自己想出一个别号叫“项昂之”——因为他佩服项羽,“昂之”是他想象中项羽的气概。他在每幅画上挥笔署上“项昂之”的大名,得意非凡。他大约常有“项昂之”的兴趣,只恨不善画。他曾央求当时在中学读书的女儿为他临摹过几幅有名的西洋淘气画,其中一幅是《魔鬼临去遗臭图》(图名是我杜撰),魔鬼像吹喇叭似的后部撒着气逃跑,画很妙。上课画《许眼变化图》,央女儿代摹《魔鬼遗臭图》,想来也都是“痴气”的表现。
锺书在他父亲的教导下“发愤用功”,其实他读书还是出于喜好,只似馋嘴佬贪吃美食:食肠很大,不择精粗,甜咸杂进。极俗的书他也能看得哈哈大笑。戏曲里的插科打诨,他不仅且看且笑,还一再搬演,笑得打跌。精微深奥的哲学、美学、文艺理论等大部著作,他像小儿吃零食那样吃了又吃,厚厚的书一本本渐次吃完。诗歌更是他喜好的读物。重得拿不动的大字典、辞典、百科全书等,他不仅挨着字母逐条细读,见了新版本,还不嫌其烦地把新条目增补在旧书上。他看书常做些笔记。
我只有一次见到他苦学。那是在牛津,他提出论文题之前,须学习古文书学(Peleography),要能辨认英国十一世纪以来的各式古文字。他毫无兴趣,考试前只好硬记,因此每天读一本侦探小说“休养脑筋”,“休养”得睡梦中手舞脚踢,不知是捉拿凶手,还是自己做了凶手和警察打架。结果考试不及格,只好暑假后补考。这件补考的事,《围城》英译本《导言》里也提到(见 14 页)。锺书一九七九年访美,该译本出版家把译文的《导言》给他过目,他读到这一段又惊又笑,想不到调查这么精密。后来胡志德(Theodore Huters)君来见,才知道是他向锺书在牛津时的同窗好友 Donald Stuart 打听来的。胡志德一九八二年出版的《钱锺书》里把这件事却删去了。④
锺书的“痴气”书本里灌注不下,还洋溢出来。我们在牛津时,他午睡,我临帖,可是一个人写写字困上来,便睡着了。他醒来见我睡了,就饱蘸浓墨,想给我画个花脸。可是他刚落笔我就醒了。他没想到我的脸皮比宣纸还吃墨,洗净墨痕,脸皮像纸一样快洗破了,以后他不再恶作剧,只给我画了一幅肖像,上面再添上眼镜和胡子,聊以过瘾。回国后他暑假回上海,大热天女儿熟睡(女儿还是娃娃呢),他在她肚子上画一个大脸,挨他母亲一顿训斥,他不敢再画。沦陷在上海的时候,他多余的“痴气”往往发泄在叔父的小儿小女、孙儿孙女和自己的女儿阿圆身上。这一串孩子挨肩儿都相差两岁,常在一起玩。有些语言在“不文明”或“臭”的边缘上,他们很懂事似的注意避忌。锺书变着法儿,或作手势,或用切口,诱他们说出来,就赖他们说“坏话”。于是一群孩子围着他吵呀,打呀,闹个没完。他虽然挨了围攻,还俨然以胜利者自居。他逗女儿玩,每天临睡在她被窝里埋置“地雷”,埋得一层深入一层,把大大小小的各种玩具、镜子、刷子,甚至砚台或大把的毛笔都埋进去,等女儿惊叫,他就得意大乐。女儿临睡必定小心搜查一遍,把被里的东西一一取出。锺书恨不得把扫帚、畚箕都塞入女儿被窝,博取一遭意外的胜利。这种玩意儿天天玩也没多大意思,可是锺书百玩不厌。
他又对女儿说,《围城》里有个丑孩子,就是她。阿圆信以为真,却也并不计较。他写了一个开头的《百合心》里,有个女孩子穿一件紫红毛衣,锺书告诉阿圆那是个最讨厌的孩子,也就是她。阿圆大上心事,怕爸爸冤枉她,每天找他的稿子偷看,锺书就把稿子每天换个地方藏起来。一个藏,一个找,成了捉迷藏式的游戏。后来连我都不知道稿子藏到哪里去了。
锺书的“痴气”也怪别致的。他很认真地跟我说:“假如我们再生一个孩子,说不定比阿圆好,我们就要喜欢那个孩子了,那我们怎么对得起阿圆呢。”提倡一对父母生一个孩子的理论,还从未讲到父母为了用情专一而只生一个。
解放后,我们在清华养过一只很聪明的猫。小猫初次上树,不敢下来,锺书设法把它救下。小猫下来后,用爪子轻轻软软地在锺书腕上一搭,表示感谢。我们常爱引用西方谚语:“地狱里尽是不知感激的人。”小猫知感,锺书说它有灵性,特别宝贝。猫儿长大了,半夜和别的猫儿打架。锺书特备长竹竿一枝,倚在门口,不管多冷的天,听见猫儿叫闹,就急忙从热被窝里出来,拿了竹竿,赶出去帮自己的猫儿打架。和我们家那猫儿争风打架的情敌之一是紧邻林徽因女士的宝贝猫,她称为她一家人的“爱的焦点”。我常怕锺书为猫而伤了两家和气,引用他自己的话说:“打狗要看主人面,那么,打猫要看主妇面了!”(《猫》的第一句)他笑说:“理论总是不实践的人制定的。”
钱家人常说锺书“痴人有痴福”。他作为书痴,倒真是有点痴福。供他阅读的书,好比富人“命中的禄食”那样丰足,会从各方面源源供应。(除了下放期间,他只好“反刍”似的读读自己的笔记和携带的字典。)新书总会从意外的途径到他手里。他只要有书可读,别无营求。这又是家人所谓“痴气”的另一表现。
锺书和我父亲诗文上有同好,有许多共同的语言。锺书常和我父亲说些精致典雅的淘气话,相与笑乐。一次我父亲问我:“锺书常那么高兴吗?”“高兴”也正是钱家所谓“痴气”的表现。
我认为《管锥编》、《谈艺录》的作者是个好学深思的锺书,《槐聚诗存》的作者是个“忧世伤生”的锺书,《围城》的作者呢,就是个“痴气”旺盛的锺书。我们俩日常相处,他常爱说些痴话,说些傻话,然后再加上创造,加上联想,加上夸张,我常能从中体味到《围城》的笔法。我觉得《围城》里的人物和情节,都凭他那股子痴气,呵成了真人实事。可是他毕竟不是个不知世事的痴人,也毕竟不是对社会现象漠不关心,所以小说里各个细节虽然令人捧腹大笑,全书的气氛,正如小说结尾所说:“包涵对人生的讽刺和伤感,深于一切语言、一切啼笑”,令人回肠荡气。
锺书写完了《围城》,“痴气”依然旺盛,但是没有体现为第二部小说。一九五七年春,“大鸣大放”正值高潮,他的《宋诗选注》刚脱稿,因父病到湖北省亲,路上写了《赴鄂道中》五首绝句,现在引录三首:“晨书暝写细评论,诗律伤严敢市恩。碧海掣鲸闲此手,祗教疏凿别清浑。”“弈棋转烛事多端,饮水差知等暖寒。如膜妄心应褪净,夜来无梦过邯郸。”“驻车清旷小徘徊,隐隐遥空碾懑雷。脱叶犹飞风不定,啼鸠忽噤雨将来。”后两首寄寓他对当时情形的感受,前一首专指《宋诗选注》而说,点化杜甫和元好问的名句(“或看翡翠兰苕上,未掣鲸鱼碧海中”;“谁是诗中疏凿手,暂教泾渭各清浑”)。据我了解,他自信还有写作之才,却只能从事研究或评论工作,从此不但口“噤”,而且不兴此念了。《围城》重印后,我问他想不想再写小说。他说:“兴致也许还有,才气已与年俱减。要想写作而没有可能,那只会有遗恨;有条件写作而写出来的不成东西,那就只有后悔了。遗恨里还有哄骗自己的余地,后悔是你所学的西班牙语里所谓‘面对真理的时刻’,使不得一点儿自我哄骗、开脱或宽容的,味道不好受。我宁恨毋悔。”这几句话也许可作《围城·重印前记》的笺注吧。
我自己觉得年纪老了;有些事,除了我们俩,没有别人知道。我要趁我们夫妇都健在,一一记下。如有错误,他可以指出,我可以改正。《围城》里写的全是捏造,我所记的却全是事实。
一九八六年发表
① 参看我的《事实—故事—真实》一文。
② “那年”指一九二五年,参看《清华周刊》3577 期(一九二五年九月十一日出版)。下文的“寒假”是一九二五至一九二六年冬,“暑假”是一九二六年夏。
③ 《清华大学第五级毕业五十周年纪念册》(一九八四年出版)转载此文。饶君已故。
④ 锺书记错了,我翻阅此书,这件事并未删去。
记忆像铁轨一样长-余光中
========================
记忆像铁轨一样长-[[余光中]]
-----
我的中学时代在四川的乡下度过。那时正当抗战,号称天府之国的四川,一寸铁轨也没有。不知道为什么,年幼的我,在千山万岭的重围之中,总爱对着外国地图,嚮往去远方游历,而且觉得最浪漫的旅行方式,便是坐火车。每次见到月曆上有火车在旷野奔驰,曳着长烟,便心随烟飘,悠然神往,幻想自己正坐在那一排长窗的某一扇窗口,无穷的风景为我展开,目的地呢,则远在千里外等我,最好是永不到达,好让我永不下车。那平行的双轨一路从天边疾射而来,像远方伸来的双手,要把我接去未知;不可久视,久视便受它催眠。
乡居的少年那么神往于火车,大概因为它雄伟而修长,轩昂的车头一声高啸,一节节的车厢铿铿跟进,那气派真是慑人。至于轮轨相激枕木相应的节奏,初则铿锵而慷慨,继则单调而催眠,也另有一番情韵。过桥时俯瞰深谷,真若下临无地,蹑虚而行,一颗心,也忐忐忑忑吊在半空。黑暗迎面撞来,当头罩下,一点準备也没有,那是过山洞。惊魂未定,两壁的回声轰动不绝,你已经愈陷愈深,冲进山岳的盲肠裏去了。光明在山的那一头迎你,先是一片幽昧的微熹,迟疑不决,蓦地天光豁然开朗,黑洞把你吐回给白昼。这一连串的经验,从惊到喜,中间还带着不安和神祕,历时虽短而印象很深。
坐火车最早的记忆是在十岁。正是抗战第二年,母亲带我从上海乘船到安南,然后乘火车北上昆明。滇越铁路与富良江平行,依着横断山脉蹲踞的余势,江水滚滚向南,车轮铿铿向北。也不知越过多少桥,穿过多少山洞。我靠在窗口,看了几百里的桃花映水,真把人看得眼红、眼花。
入川之后,刚亢的铁轨只能在山外远远喊我了。一直要等胜利还都,进了金陵大学,才有京沪路上疾驶的快意。那是大一的暑假,随母亲回她的故乡武进,铁轨无尽,伸入江南温柔的水乡,柳丝弄晴,轻轻地抚着麦浪。可是半年后再坐京沪路的班车东去,却不再中途下车,而是直达上海。那是最难忘的火车之旅了:红旗渡江的前夕,我们仓皇离京,还是母子同行,幸好儿子已经长大,能够照顾行李。车厢挤得像满满一盒火柴,可是乘客的四肢却无法像火柴那么排得平整,而是交肱叠股,摩肩错臂,互补着虚实。母亲还有座位。我呢,整个人只有一只脚半踩在茶几,另一只则在半空,不是虚悬在空中,而是斜斜地半架半压在各色人等的各色肤体之间。这么维持着「势力平衡」,换腿当然不能,如厕更是妄想。到了上海,还要奋力夺窗而出,否则就会被新涌上来的回程旅客夹在中间,挟回南京去了。
来台之后,与火车更有缘分。什么快车慢车、山线海线,都有缘在双轨之上领略,只是从前京沪路上的东西往返,这时,变成了纵贯线上的南北来回。滚滚疾转的风火千轮上,现代哪咤的心情,有时是出发的兴奋,有时是回程的偷懒,有时是午晴的遐思,有时是夜雨的落寞。大玻璃窗招来豪阔的山水,远近的城村;窗外的光景不断,窗内的思绪不绝,真成了情景交融。尤其是在长途,终站尚远,两头都搭不上现实,这是你一切都被动的过渡时期,可以绝对自由地大想心事,任意识乱流。
饿了,买一盒便当充午餐,虽只一片排骨,几块酱瓜,但在快览风景的高速动感下,却显得特别可口。台中站到了,车头重重地喘一口气,颈挂零食拼盘的小贩一涌而上,太阳饼、凤梨酥的诱惑总难以拒绝。照例一盒盒买上车来,也不一定是为了有多美味,而是细嚼之余有一股甜津津的乡情,以及那许多年来,唉,从年轻时起,在这条线上进站、出站、过站、初旅、重游、挥别,重重叠叠的回忆。
最生动的回忆却不在这条线上,在阿里山和东海岸。拜阿里山神是在十二年前。朱红色的窄轨小火车在洪荒的岑寂裏盘旋而上,忽进忽退,忽蠕蠕于悬崖,忽隐身于山洞,忽又引吭一呼。回声在峭壁间来回反弹。万绿丛中牵曳着这一线媚红,连高古的山颜也板不起脸来了。
拜东岸的海神却近在三年以前,是和我存一同乘电气化火车从北迴线南下。浩浩的太平洋啊,日月之所出,星斗之所生,毕竟不是海峡所能比,东望,是令人绝望的水蓝世界。起伏不休的鹹波,在远方,摇撼着多少个港口多少只船,扪不到边,探不到底,海神的心事就连长锚千丈也难窥。一路上怪壁碍天,奇岩镇地,被千古的风浪刻成最丑所以也最美的形貌,罗列在岸边如百里露天的艺廊,刀痕刚劲,一件件都凿着时间的签名,最能满足狂士的「石癖」。不仅岸边多石,海中也多岛。火车过时,一个个岛屿都不甘寂寞,跟它赛起跑来。毕竟都是海之囚,小的,不过跑三两分钟,大的,像龟山岛,也只能追逐十几分钟,就认输放弃了。
萨洛扬的小说裏,有一个寂寞的野孩子,每逢火车越野而过,总是兴奋地在后面追赶。四十年前在四川的山国裏,对着世界地图悠然出神的,也是那样寂寞的一个孩子,只是在他的门前,连火车也不经过。后来远去外国,越洋过海,坐的却常是飞机,而非火车。飞机虽可想成庄子的逍遥之游,列子的御风之旅,但是出没云间,游行虚碧,变化不多,机窗也太狭小,久之并不耐看。那像火车的长途,催眠的节奏,多变的风景,从阔窗裏看出去,又像是在人间,又像驶出了世外。所以在国外旅行,凡铿铿的双轨能到之处,我总是站在月台──名副其实的「长亭」──上面,等那阳刚之美的火车轰轰隆隆其势不断地踹进站来,来载我去远方。
在美国的那几年,坐过好多次火车。在爱奥华城读书的那一年,常坐火车去芝加哥看刘鎏和孙璐。美国是汽车王国,火车并不考究。去芝加哥的老式火车颇有十九世纪遗风,坐起来实在不大舒服,但沿途的风景却看之不倦。尤其到了秋天,原野上有一股好闻的淡淡焦味,太阳把一切成熟的东西焙得更成熟,黄透的枫叶杂着赭尽的橡叶,一路艳烧到天边,谁见过那样美丽的火灾呢?过密西西比河,铁桥上敲起空旷铿铿,桥影如网,张着抽象美的线条,倏忽已踹过好一片壮阔的烟波。等到暮色在窗,芝城的灯火迎面渐密,那黑人老车掌就喉音重浊地喊出站名:Tanglewood!
有一次,从芝城坐火车回爱奥华城。正是耶诞假后,满车都是回校的学生,大半还背着、拎着行囊,更形拥挤。我和好几个美国学生挤在两节车厢之间,等于站在老火车轧轧交挣的关节之上,又冻又渴。饮水的纸杯在众人手上,从厕所一路传到我们跟前。更严重的问题是不能去厕所,因为连那裏面也站满了人。火车原已误点,我们在阿气翳窗的芝城总站上早已困立了三、四个小时,偏偏隆冬的膀胱最容易注满。终于「满载而归」,一直熬到爱大的宿舍。一泻之余,顿觉身轻若仙,重心全失。
美国火车经常误点,真是恶名昭彰。我在美国下决心学开汽车,完全是给老爷火车激出来的。火车误点,或是半途停下来等到地老天荒,甚至为了说不清楚的深奥原因向后倒开,都是最不浪漫的事。几次耽误,我一怒之下,决定把方向盘握在自己手裏,不问山长水远,都可即时命驾。执照一到手,便与火车分道扬镳,从此我聘我的高速路,它敲它的双铁轨。不过在高速路旁,偶见迤迤的列车同一方向疾行,那修长而魁伟的体魄,那稳重而骠悍的气派,尤其是在天高云远的西部,仍令我怦然心动。总忍不住要加速去追赶,兴奋得像西部片裏马背上的大盗,直到把它追进了山洞。
一九七六年去英国,周榆瑞带我和彭歌去剑桥一游。我们在维多利亚车站的月台上候车,匆匆来往的人群,使人想起那许多着名小说裏的角色,在这「生之漩涡」裏捲进又捲出的神色与心情。火车出城了,一路开得不快,看不尽人家后院晒着的衣裳,和红砖翠篱之间明艳而动人的园艺。那年西欧大旱,耐乾的玫瑰却恣肆着娇红。不过是八月底,英国给我的感觉却是过了成熟焦点的晚秋,儘管是迟暮了,仍不失为美人。到剑桥飘起霏霏的细雨,更为那一幢幢俨整雅洁的中世纪学院平添了一分迷朦的柔美。经过人文传统日琢月磨的景物,毕竟多一种沉潜的秀逸气韵,不是铝光闪闪的新厦可比。在空幻的雨气裏,我们撑着黑伞,踱过剑河上的石洞拱桥,心底迴旋的是米尔顿牧歌中的抑扬名句,不是硖石才子的江南乡音。红砖与翠藤可以为证,半部英国文学史不过是这河水的回声。雨气终于浓成暮色,我们才挥别了灯暖如橘的剑桥小站。往往,大旅途裏最具风味的,是这种一日来回的「便游」。
两年后我去瑞典开会,回程顺便一游丹麦与西德,特意把斯德哥尔摩到哥本哈根的机票,换成黄底绿字的美丽火车票。这一程如果在云上直飞,一小时便到了,但是在铁轨上轮转,从上午八点半到下午四点半,却足足走了八个小时。云上之旅海天一色,美得未免抽象。风火轮上八小时的滚滚滑行,却带我深入瑞典南部的四省,越过青青的麦田和黄艳艳的芥菜花田,攀过银桦蔽天杉柏密矗的山地,渡过北欧之喉的峨瑞升德海峡,在香熟的夕照裏驶入丹麦。瑞典是森林王国,火车上凡是门窗几椅之类都用木製,给人的感觉温厚而可亲。车上供应的午餐是烘麵包夹鲜虾仁,灌以甘冽的嘉士伯啤酒,最合我的胃口。瑞典南端和丹麦北部这一带,陆上多湖,海中多岛,我在诗裏曾说这地区是「屠龙英雄的泽国,佯狂王子的故乡」,想像中不知有多阴郁,多神祕。其实那时候正是春夏之交,纬度高远的北欧日长夜短,柔蓝的海峡上,迟暮的天色久久不肯落幕。我在延长的黄昏裏独游哥本哈根的夜市,向人鱼之港的灯彩花香裏,寻找疑真疑幻的传说。
西德之旅,从杜塞尔多夫到科隆的一程,我也改乘火车。德国的车厢跟瑞典的相似,也是一边是狭长的过道,另一边是方形的隔间,装饰古拙而亲切,令人想起旧世界的电影。乘客稀少,由我独佔一间,皮箱和提袋任意堆在长椅上。银灰与橘红相映的火车沿莱茵河南下,正自纵览河景,查票员说科隆到了。刚要把行李提上走廊,猛一转身,忽然瞥见蜂房蚁穴的街屋之上峻然拔起两座黑黝黝的尖峰,瞬间的感觉,极其突兀而可惊。定下神来,火车已经驶近那一双怪物,峭险的尖塔下原来还整齐地绕着许多小塔,锋芒逼人,拱卫成一派森严的气象,那么崇高而神祕,中世纪哥德式的肃然神貌耸在半空,无闻于下界琐细的市声。原来是科隆的大教堂,在莱茵河畔顶天立地已七百多岁。火车在转弯。不知道是否因为微侧,竟感觉那一对巨塔也峨然倾斜,令人吃惊。不知飞机迴降时成何景象,至少火车进城的这一幕十分壮观。
三年前去里昂参加国际笔会的年会,从巴黎到里昂,当然是乘火车,为了深入法国东部的田园诗裏,看各色的牛群,或黄或黑,或白底而花斑,嚼不尽草原缓坡上远连天涯的芳草萋萋。陌生的城镇,点名一般地换着站牌。小村更一现即逝,总有白杨或青枫排列于乡道,掩映着粉墻红顶的村舍,衬以教堂的细瘦尖塔,那么秀气地针着远天。席思礼、毕沙洛,在初秋的风裏吹弄着牧笛吗?那年法国刚通了东南线的电气快车,叫做Le TGV,时速三八○公里,在报上大事宣扬。回程时,法国笔会招待我们坐上这骄红的电鳗;由于座位是前后相对,我一路竟倒骑着长鳗进入巴黎。在车上也不觉得怎么「风驰电掣」,颇感不过如此。今年初夏和纪刚、王蓝、健昭、杨牧一行,从东京坐子弹车射去京都,也只觉其「稳健」而已。车到半途,天色渐昧,正吃着鳗鱼佐饭的日本便当,吞着苦涩的札幌啤酒,车厢裏忽然起了骚动,惊叹不绝。在邻客的探首指点之下,迓见富士山的雪顶白矗晚空,明知其为真实,却影影绰绰,一片可怪的幻象。车行极快,不到三五分钟,那一影淡白早已被近丘所遮。那样快的变动,敢说浮世绘的画师,戴笠跨剑的武士,都不曾见过。
台湾中南部的大学常请台北的教授前往兼课,许多朋友不免每星期南下台中、台南或高雄。从前龚定盦奔波于北京与杭州之间,柳亚子说他「北驾南舣到白头」。这些朋友在岛上南北奔波,看样子也会奔到白头,不过如今是在双轨之上,不是驾马舣舟。我常笑他们是演《双城记》,其实近十年来,自己在台北与香港之间,何尝不是如此?在台北,三十年来我一直以厦门街为家。现在的订州街二十年前是一条窄轨铁路,小火车可通新店。当时年少,我曾在夜裏踏着轨旁的碎石,鞋声轧轧地走回家去,有时索性走在轨道上,把枕木踩成一把平放的长梯。时常在冬日的深宵,诗写到一半,正独对天地之悠悠,寒颤的汽笛声会一路沿着小巷呜呜传来,悽清之中有其温婉,好像在说:全台北都睡了,我也要回站去了,你,还要独撑这倾斜的世界吗?夜半钟声到客船,那是张继。而我,总还有一声汽笛。
在香港,我的楼下是山,山下正是九广铁路的中途。从黎明到深夜,在阳台下滚滚辗过的客车、货车,至少有一百班。初来的时候,几乎每次听见车过,都不禁要想起铁轨另一头的那一片土地,简直像十指连心。十年下来,那样的节拍也已听惯,早成大寂静裏的背景音乐,与山风海潮合成浑然一片的天籁了。那轮轨交磨的声音,远时哀沉,近时壮烈,清晨将我唤醒,深宵把我摇睡。已经潜入了我的脉搏,与我的呼吸相通。将来我回去台湾,最不惯的恐怕就是少了这金属的节奏,那就是真正的寂寞了。也许应该把它录下音来,用最敏感的机器,以备他日怀旧之需。附近有一条铁路,就似乎把住了人间的动脉,总是有情的。
香港的火车电气化之后,大家坐在冷静如冰箱的车厢裏,忽然又怀起古来,隐隐觉得从前的黑头老火车,曳着煤烟而且重重叹气的那种,古拙刚愎之中仍不失可亲的味道。在从前那种车上,总有小贩穿梭于过道,叫卖斋食与「凤爪」,更少不了的是报贩。普通票的车厢裏,不分三教九流。男女老幼,都杂杂沓沓地坐在一起,有的默默看报,有的怔怔望海,有的瞌睡,有的啃鸡爪,有的闲闲地聊天,有的激昂慷慨地痛论国是,但旁边的主妇并不理会,只顾得呵斥自己的孩子。如果你要香港社会的样品,这裏便是。週末的加班车上,更多广州返来的回乡客,一根扁担,就挑尽了大包小笼。此情此景,总令我想起杜米叶的名画《三等车上》。只可惜香港没有产生自己的杜米叶,而电气化后的明净车厢裏,从前那些汗气、土气的乘客,似乎一下子都不见了,小贩子们也绝迹于月台。我深深怀念那个摩肩抵肘的时代。站在今日划了黄线的整洁月台上,总觉得少了一点什么,直到记起了从前那一声汽笛长啸。
写火车的诗很多,我自己都写过不少。我甚至译过好几首这样的诗,却最喜欢土耳其诗人塔朗吉的这首:
```
去什么地方呢?这么晚了,
美丽的火车,孤独的火车?
凄苦是你汽笛的声音,
令人记起了许多事情。
为什么我不该挥舞手巾呢?
乘客多少都跟我有亲。
去吧,但愿你一路平安,
桥都坚固,隧道都光明。
```
一九八四年五月七日
!纪弦《火》
"""
开谢了蒲公英的花
燃起了心头上的火
火跑了
追上去!
火是永远追不到的
他只照着你
或有一朝抓住了火
他便烧死你
——纪弦《火》
"""
简媜(1961年10月9日-),本名简敏媜,散文家。生于台湾宜兰县冬山乡冬山河畔,国立台湾大学中国文学系毕业,曾任编辑、出版者,现专事写作。自称是“不可救药的散文爱好者”。其散文风格,辞采华茂,设喻新警,从大学时期的少女情怀、乡土与儿少记忆,到女性群像、社会讽刺、伤逝、育儿、教育、饮食、老化书写,每本作品题材开拓求变,为台湾知名的女性散文家。
"""
白白给了钱就像做慈善事业的马新高铁
到头来,他的路墩也比不曾存在过的铁路来得强
恢复原状的路面
一如往常地噪音
他没有得到什么、
只是失去金钱
徒劳无功
得到利益的是
售卖沥青的华人店主
填土的外籍劳工
以及
受政治人物驱使
拿走一切成果的
国外进口的推土机
这一群人
在他的土地上
将他的积蓄分赃
这种白做工的感觉就像在种榴莲
"""
杰斯和美瑞白丝-艾丽丝·门罗
========================
# 杰斯和美瑞白丝-[[艾丽丝·门罗]]
-----
高中时,我和一个叫作梅瑞贝斯·克罗克的女孩有过一段温柔、忠诚、无趣的友谊。我完完全全地投身于它,就像夏天在美特兰河里投身于温暖浑浊的浅浅河水一样—仰浮着,手脚拍拍,任水流把我冲向下游。
这始于某天的音乐课,歌谱不够用,我们被吩咐合用课本—当然咯,男孩和男孩,女孩和女孩。我四处寻找同样没有好朋友一块儿坐的女孩,突然梅瑞贝斯就坐到身边了。她刚转学过来,和姐姐贝特丽丝住,姐姐在本地医院当护士。她们的妈妈去世了,爸爸再婚了。
梅瑞贝斯个头不高,胖嘟嘟的,不过挺优雅,一双从榛绿色过渡到深棕色的大眼睛,一身杏仁色好皮肤,不带一个斑点或雀斑,美丽的小嘴时常迷惘地噘着,好像想起什么秘密的伤心事。我能闻到她用的香皂味儿。甜甜的花香味儿飘过来,穿透层层尘土味儿、消毒水味儿和汗味儿—寻常学校的味道—穿透了噩梦般的无聊和缭绕不去的焦虑感。居然挑中了我,真不可思议啊,我都有点晕了。接下来几星期,我每天早上醒来都莫名其妙很开心。然后就会想起这一刻。
梅瑞贝斯和我经常谈起它。她说滑向我身边时,心脏怦怦跳个不停,但她告诉自己,现在就去,不然就永远没机会了。
在我整个童年时期读的书里面,女孩子们纷纷本着强烈的献身精神,两两成对,结成牢固的友谊。她们发誓永远为对方保密,永远不向对方隐瞒任何事,也永远不与别的女孩产生深沉持久的友情。婚姻不会改变什么。她们会长大,恋爱,结婚,但仍在彼此心头占据头号位置。她们用彼此的名字给女儿取名,时刻准备在对方得传染病时前去照料,或者在法庭上为对方作伪证。这种不可亵玩、繁琐复杂的忠诚,以及郑重其事的情意绵绵,正是我现在渴望,或者觉得可以施加给梅瑞贝斯的。我们发了誓,下了保证,互相倾吐了秘密。她对一切都全盘接受。她天性温顺。每当想到什么悲伤或可怕的事,她总喜欢贴过来依偎着你,握住你的手。
第一个秋天里,我们沿铁轨一直走出镇子,互相讲述我们一生中遇到过的所有疾病或事故,我们害怕什么,我们最喜欢的颜色、首饰、花朵、电影明星、甜点、饮料和冰激凌口味。我们讨论着将来要几个孩子、男孩还是女孩,想好了他们的名字。还有我们丈夫的头发和眼睛颜色,希望他们干的是哪一行。梅瑞贝斯害怕田里的牛群和铁轨边没准会有的蛇。我们手里抓满绽开的乳草荚果里面的绒毛—那真是世界上最柔软的东西了,然后又松开手,任它们飘到别的干草上,像一团团绒雪或小花儿。
“打仗时,他们就是用这个织降落伞的。”我告诉梅瑞贝斯。那不是真的,可我相信。
有时我们会去梅瑞贝斯和贝特丽丝住的地方,她俩住一个房间。我们坐在走廊上缝东西,或者上楼到她们的房间去。房子大而朴素,刷成黄色,看起来好像乏人打理。它坐落在大街旁。房主是一个盲人和他老婆,住房子后部的两间屋。盲人总坐着帮他老婆削土豆,或者钩一些小桌巾和桌旗,让她拿到镇上的商店设法卖掉。
房子里的女孩会互相挑战,看谁敢趁他老婆出门时,跑下楼去和他聊聊。她们互相挑战只穿奶罩和内裤,或者干脆一丝不挂地跑下去。他好像猜出正进行着什么把戏。“过来,”他会招呼,“凑近点,我听不到哟。”或者,“过来让我摸摸你的衣服。让我瞧瞧能不能猜出它的颜色。”
梅瑞贝斯从不玩这个游戏,听都讨厌听它。她觉得有的女孩实在讨厌。
房子里的女孩们总是不得安生。她们拉帮结派、明争暗斗,动辄赌气互相不搭理。有一次,两个女孩为了指甲油吵起来,一个揪下了另一个的一团头发。
浴室药柜上常贴着一些直截了当、充满威胁的纸条:
请在自己的房间烘毛衣,羊毛烘干时会发出异味。A.M.和S.D.,敬请注意了。
某个人,我闻出你身上有我的夜巴黎香水的味道,我不喜欢那样。你该自己买。B.P.致意。
总有东西在洗:长袜啊,胸衣啊,吊袜腰带啊,毛衣啊—当然了,还有头发。在浴室里那么一转,你的脸必定会拍上什么东西。
烧饭用小电炉。一心为买嫁妆或搬去大城市而省钱的女孩们都自己煮卡夫速食晚餐。其他女孩从附近餐厅带回油腻、喷香的牛皮纸袋。薯条、汉堡、热狗、甜甜圈。香味儿顺楼梯往上飘,正在减肥的女孩们咒骂着,砰地关上门。
时不时地,梅瑞贝斯的姐姐贝特丽丝也会减肥。她靠喝醋来减轻食欲。她还喝甘油,好让指甲长结实。
“她想找男朋友呢—真让我恶心。”梅瑞贝斯说。
梅瑞贝斯和贝特丽丝是朋友的时候,不用打招呼就可以穿对方的衣服,在床上搂着睡,互相为对方描述她的头发从后面看起来是什么样。不是朋友的时候,就互相不说话了。梅瑞贝斯会在小电炉上烧一种红糖、奶油和椰子做成的喷香冒泡的糊糊,把香味扑鼻的平底锅在贝特丽丝的鼻子底下晃来晃去,然后才和我用勺子舀来吃。或者她会到商店买一袋棉花糖,她相信这是贝特丽丝最喜欢的。她要当她的面吃。我不喜欢单吃棉花糖—有点讨厌它们软软肥肥的样子—梅瑞贝斯却丢一颗到嘴里,将它像个瓶塞似的叼着,把脸在贝特丽丝面前晃来晃去。这种时候,我都有点不知所措,只好去研究衣柜。
梅瑞贝斯的爸爸不希望她同住,不过给了她很多钱买衣服。她有一件深蓝色的冬大衣,带着一个我觉得很奢华的松鼠皮领子。她有很多抽绳上衣,当时流行这个—粉色、黄色、淡紫色、天蓝色、柠檬绿色。还有一大堆令人艳羡的银手镯。我记得两件百褶裙—海军蓝间白色,绿松石间樱桃色。我打量它们时,与其说是妒忌,不如说是敬畏。我在手指尖上晃着那些沉甸甸的手镯,研究着精致的粉扑和眉毛钳。我自己是不可以拔眉毛的,要化妆也只能在上学路上溜进市政大厅的洗手间。上学时,我住在镇上恩娜姑妈家,她对我严加管束。我当作粉扑的只是一团粗糙的法兰绒,看起来真是脏兮兮的。在梅瑞贝斯旁边,我感觉自个儿就像是个粗糙的物件,双腿粗壮、胸部肥大—强壮、多汗、衣着狼狈、微不足道、感激涕零。同时,又深深地、不由自主、难以言喻、不可思议地—这个没法说,也不能多想—充满优越感。
暑假里她去了多伦多,住她爸爸和继母家。回来后,梅瑞贝斯说我们再也不可以沿铁轨走远了,不然会沾上坏名声。她说如今在头发上裹围巾是时髦做法,哪怕大晴天也一样,为此她带了好几条方巾回来。她让我挑一条,我挑了粉色渐变玫红色的那条。她钦佩地嚷道:“哎哟,这是最好看的一条啦!”我试图还给她。我们互相推辞一番,最后还是我收下了。
她告诉我在伊顿中心和辛普森百货都可以买到什么,她如何差点把鞋跟卡在电动扶梯里,继母说的一些冷言冷语,以及看过的电影情节。她在展览馆玩过山车晕车了,街车上有个男人跟她搭话,穿一身灰西装,戴灰色浅顶软呢帽,提议带她去河谷动物园玩。
现在,听梅瑞贝斯说话,我好像时不时会走神了。我感觉思绪飘散开去,就像在学校里听数学演算时,或者在教堂布道之前的大祈祷刚开始时一样。并不是说我想走开,或者想独处。我明白了友谊就是这么回事。
我们决定改变名字的写法。我从杰茜变成杰斯,她从梅瑞贝斯变成美瑞白丝。在学校里,我们把新名字写在考卷上。
老师晃着我的考卷。“我没法给这人打分,我不认识这人呐。”她说。“杰斯是谁?”她大声拼出这个名字,“是个男孩名。谁认识叫杰斯的男孩?”
美瑞白丝这个名字却没遭到任何异议。这再正常不过啦。因为她的相貌、打扮和外来者身份,也因为她柔和、讨喜的声音和礼貌的举止,梅瑞贝斯人见人爱。粗野的女孩们和刻薄的老师们无一例外都喜欢她。男孩们自然也是,不过她说姐姐不让她和他们约会。我从不知道是否果真如此。梅瑞贝斯擅长撒点无伤大雅的小谎,不伤人地表示拒绝。
既然我的改名没通过,她也就不改她的了。我们互相写便条或者夏天通信时才用这两个新名字。
高三念到一半,恩娜姑妈给我找了一份活儿。我放学后要到辛德曼家上班,一周两次。恩娜姑妈认识辛德曼夫妇,因为她是他们家的清洁工。我的工作是熨衣服,打扫卫生,准备晚饭用的蔬菜。
“对他们来说,那就是晚饭。”恩娜姑妈用一种无动于衷的语调解释道,让你没法听出她究竟是在谴责辛德曼夫妇装模作样呢,还是承认他们的地位高高在上,有特权这么吃晚饭,还是仅仅想表明,无论他们说什么做什么,都完全超出她的理解范畴,对我来说也该如此就对了。
恩娜姑妈是我爸爸的姑妈,她确实有那么老了。作为镇上的女清洁工,她的地位独一无二,就像镇上的医生就是医生,镇上的音乐老师就是音乐老师一样。她受人尊重。她不接受吃剩的食物,不管有多美味,也不会把人家不要的衣服带回家,不管有多新。趁她还没上门,很多女主人都会事先匆忙收拾几下,把空酒瓶丢进垃圾箱。恩娜姑妈可不好惹。
她和女儿佛罗瑞斯、儿子乔治一起,住在一道斜坡上的一幢狭小、整洁的房子里。这条街上的房子挤挤挨挨,紧贴马路,你从人行道上几乎可以直接摸到走廊栏杆。我的房间在厨房后头—从前是餐具室,装着浅绿色的壁板墙。躺在床上时,我会试着数那些壁板,不过总是有始无终。冬天早上,我会把所有衣服拉到床上,在被子里穿好。餐具室可没有暖气。
恩娜姑妈回到家时,总是精疲力竭的,因为刚在全镇施展了一番权威。不过依旧斗志昂扬。她对我们也施展着这种权威。她让我们—佛罗瑞斯、乔治和我—知道,我们都很优秀,尽管,或者毋宁说正因为,我们比别人穷。她教育道,我们每天都要证明这一点,通过擦亮我们的鞋子,缝好所有纽扣,从不说粗话,不抽烟(对女人而言),考高分(对我而言),绝不喝酒(对所有人而言)。现如今,没人会认同这种小家子气,这种骄傲的矜持,这种陈腐的自尊啦。比如我自己就不认同,不过当时我也没怎么为它烦神。我学会绕过一些规矩,和别人处得也不错。总体而言,我觉得这种优越感,纵然倔头倔脑的,总比毫无优越感来得强。再说我也没打算像乔治和佛罗瑞斯一样在这里过一辈子。
佛罗瑞斯有过一次短暂的婚姻,可地位好像没因此上升多少。她在鞋店打工,参加唱诗班排练,嗜好玩拼图,那可是能摊满一整张牌桌的大拼图。尽管我纠缠不休,她就是不肯好好讲一讲她的浪漫故事、她的婚姻或者丈夫年纪轻轻就因为血液中毒死掉的事—我本打算用它来抗衡梅瑞贝斯关于她妈妈去世的真正悲惨的故事的。佛罗瑞斯长着一双灰蓝色眼睛,分得奇开,简直像在看往不同方向。它们流露出一种恍惚、无助的神情。
乔治在学校只读到四年级。他在钢琴厂干活,人称“小飞象”[1],对此他没什么特别的讨厌或不开心。他是那样害羞、安静,跟他一比,佛罗瑞斯那种疲惫的不耐烦简直称得上生机勃勃了。他会从杂志上剪下图片,在房间钉一满墙—不是什么半裸美女的照片,而是一些样子讨他喜欢的东西:一架飞机,一块巧克力蛋糕,伯顿奶业的明星母牛艾尔茜。他会玩跳棋,有时会邀请我和他下一盘。通常我都推辞说没空。
我把梅瑞贝斯带回家吃晚饭时,恩娜姑妈批评那些手镯在桌上撞出声响,纳罕这种年纪的姑娘怎么会被允许拔眉毛。她还说—让乔治也听到了—我的朋友看起来没什么脑子。我并不奇怪。我和梅瑞贝斯都知道,与成人世界只可能展开那种最最虚伪、最最痛苦、最最刻板的交流。
辛德曼夫妇的宅邸仍被称作斯图尔家的房子。不久前,辛德曼夫人还是伊万杰琳·斯图尔。房子是她父亲斯图尔博士造的。它离大街有一段距离,坐落在一个人工垒起的平台上,与镇上任何别的房子都不一样。事实上,它不像我见过的任何房子,它让我想起银行,或者别的重要公共建筑。它只有一层,平顶,装了矮矮的落地窗、古典的柱子,屋顶有一圈雕花栏杆,每个拐弯处都有一个装饰坛。大门口的台阶两侧也点缀着装饰坛。坛子、雕花栏杆和柱子全刷成奶白色,房子本身刷的是浅粉色灰泥。现在,涂料和灰泥都开始剥落,脏兮兮的。
我从二月份开始去干活。装饰坛积满雪,活像盛满冰激凌的盘子,院里各种灌木都像铺着北极熊皮毯子。别人家门口都铲出宽阔干净的走道,这里只有一条弯弯曲曲的小径通向大门。
“辛德曼先生不肯铲雪,因为他相信它留不了多久,”辛德曼夫人说,“他相信哪天早上一睁眼,就会发现它们都消失了。就像雾一样。他对这玩意儿可没啥了解!”
辛德曼夫人说话充满强调,好像所说的每件事都无比重要,同时又好像一切都是笑话。这种说话方式真让我大开眼界。
进屋后,你就再也看不到外头了,除了透过水槽上方的厨房窗子。起居室是辛德曼夫人打发白天的地方,她躺在沙发上,周围摆着烟灰缸、茶杯、酒杯、杂志和垫子。她穿一件中国式晨衣,或者一件长长的深绿色拉绒羊毛袍子,或者一件黑缎子夹棉上衣—没多久就撒满烟灰—和一条孕妇裤。外套有时敞开,让我瞥到一眼她的肚子,已经怪怪地鼓起。她开着灯,拉拢窗上的酒红色窗帘,有时会在铜盘上点一团小小的锥形香。我喜欢这些锥形香,它们是灰扑扑的粉色的,像子弹一样整整齐齐躺在美丽的盒子里,哪怕烧成灰,形状也丝毫不变,像有魔法似的。屋里到处都是神奇的东西—带雕刻的中式红木家具,插孔雀毛和蒲苇的花瓶,铺展在褪色红墙上的扇子,一堆堆天鹅绒软垫,带金色流苏的缎面垫子。
我要做的第一件事是整理房间。捡起地上的城市报纸,把垫子摆回椅子和沙发,收走残留着冷茶或冷咖啡的杯子、剩着发硬的食品残渣的盘子,还有一个个杯子,里面或许有几片泡软的水果和一点酒渣—甜甜的、冲淡了,仍旧隐隐散发着酒气的混合物。在厨房里,我会把残余的所有东西都喝掉,吮吸水果片,尝一尝陌生的酒精味道。
辛德曼夫人的宝宝预产期大约是六月底七月初。日期没法确定,因为她的月经周期不正常。(这是我第一次听到人家说“月经”。我们一般都说“例假”、“那好事”或者用一些更委婉的说法。)她本人确信是在辛德曼先生生日那晚怀上的,当时她灌了一肚子香槟。九月二十九号。那是辛德曼先生三十三岁生日。辛德曼夫人四十岁了。她说最好干脆承认了吧,她就是个啃嫩草的。正在为此付出代价呢。四十岁生宝宝可太迟了。这把年纪生第一胎,实在太老啦。真是个错误。
她数落着她的损失。首先是脸上脖子上的浅褐色斑点,她说它们布满她周身。它们让我想起开始腐烂的梨子肉—那种软绵绵的变色部位,那种看了难受的色浅却根深的瘀伤。接着,她展示了肿胀的血管,为此她只好躺在沙发上。蔓越莓色的蜘蛛脚、青绿色的青筋遍布她的双腿。她一站起来,它们就变成黑色。踏上地面之前,她不得不用长长的橡皮绷带把腿紧紧缠住。
“听我的话吧,趁着年轻赶紧生娃娃。”她说,“要是能的话,赶紧去怀个孩子吧。我还以为我不会干这些事呢。哈哈!”不过她并没真昏了头,因为她补充道:“千万别告诉你姑妈我这么和你说话哦。”
辛德曼夫人还是伊万杰琳·斯图尔小姐的时候,不住在这幢房子里,只是经常带朋友们来玩玩。她在镇上的露面总是昙花一现、引人注目。我看到过她开敞篷车,娃娃头发型的深色头发上系一条橙色围巾。我在药店也看到过她,穿着短裤和露背背心,腿和肚子都光溜溜的,晒得黝黑,好像裹着棕色丝绸一般。她笑着,大声承认因为宿醉犯头痛。我看到过她在教堂里戴着一顶黑色薄纱帽,饰有粉色丝绸蝴蝶结,一顶用于晚会的帽子。她不属于这里。她属于我们在杂志和电影上看到的那个世界—那里有着各种光鲜玩意儿、满嘴俏皮话却故作严肃的喜剧演员、公共舞厅里的乐声、装饰着倾倒的粉色酒杯图案霓虹灯的酒吧大门。她是我们与那个世界的纽带,是我们的一个证物,证明那个世界存在着,而且我们与它共存着,它那些铺张的恶习和无情的奢侈都并非与我们毫无关联。她只要待在那里,时不时像旋风一样回趟老家,就可以得到原谅了,或许还会被遥遥地仰慕着。就连我姑妈恩娜,尽管不得不收拾壁炉里的碎酒杯、地毯上踩扁的烤鸡块、浴缸边沾的鞋油,也同意伊万杰琳·斯图尔可以享有某些邪恶的特权—尽管或许只是一些充当反面教材的特权,展示着金钱如何让你变得无耻,无所事事如何让你变得无用,自我放纵如何会招来各种引人注目的灾难。
但是,伊万杰琳·斯图尔现在做了啥哟?她变成某人的老婆,就像所有人一样。她买下当地报社给老公经营。她怀孕了。她失去了功用,打乱了秩序。做一个抽烟喝酒、放肆迷人的单身女孩是一回事,做一个抽烟喝酒、放肆而再也不迷人的怀孕母亲,就完全是另一回事咯。
“别盯着我瞧哦,杰茜。我以前才不会像这样躺着。我以前老是动来动去的。那个触霉头的医生,他唯一做的就是宣布说我变好之前会变得更糟。‘有进就有出。五分钟的享乐,九个月的折磨。’我问他:‘你啥意思哟,才五分钟?’”
我确实盯着她瞧。以前从未这样大开眼界。我一五一十地统统讲给梅瑞贝斯听。我描述了起居室,辛德曼夫人的衣服,餐具柜里装着金色、绿色和红宝石色玩意儿的瓶子,厨房碗橱里的陌生罐头—熏牡蛎、凤尾鱼、栗子浓汤、朝鲜蓟,还有大大的罐装火腿和水果布丁。我描述了血管、绷带和淡斑—讲得添油加醋—还讲了辛德曼夫人与朋友们的长途通话。他们的名字是邦特、扑哧、趴狗和斯皮提,所以你听不出他们到底是男人还是女人。她在他们中的名字是杰丽。她跟他们讲完电话后,会给我讲他们损失的钱啊,发生的事故啊,或者他们干的恶作剧,或者他们遇到的错综复杂、不同寻常的浪漫故事。
恩娜姑妈注意到我没熨多少衣服。我说不是我的错—辛德曼夫人老拉着我在起居室聊天来着。恩娜姑妈说,要是辛德曼夫人坚持要聊天,那我大可以在起居室支起熨衣板。
“让她说好了,”恩娜姑妈说,“你熨衣服。人家付钱就是要你干这个的。”
“我不介意你在这里熨衣服,但是一旦辛德曼先生回来,你就得赶紧开溜。”辛德曼夫人说,“他讨厌那个—在他待的地方干任何家务。”
她告诉我辛德曼先生在澳大利亚布里斯班出生长大,住在一幢周围全是香蕉树的大宅子里,他妈有几个黑人女佣。我觉得这听来有点混乱,就好像《乱世佳人》被搬到澳大利亚了,不过我想没准真是那样吧。她说,辛德曼先生离开澳大利亚,到新加坡当记者,然后随英国军队到缅甸作战,在那里英军被日本人打败了。辛德曼先生从缅甸一直走到印度。
“和一小撮英国兵和几个美国人一道,还有几个土著女孩—是护士。不过他们可是清清白白的。那些女孩只是唱唱赞美诗。她们都皈依了基督教。‘前进,基督徒士兵们!’[2]反正,他们那会儿也搞不出什么名堂。病怏怏的,受了伤,在可怕的热天里一天一天赶路。遭到野象群进攻。他打算写一本关于这些的书。辛德曼先生打算这么干呢。他们只好自己扎筏子,沿河向下漂流。他们得了疟疾。步行翻过了喜马拉雅山。他们都是英雄,可惜没人知道这个故事。”
我觉得这听起来也挺可疑。喜马拉雅山哪有什么可怕的热天?那里不是据说四季积雪吗?
“我告诉邦特:‘艾瑞克在缅甸跟英国人一起打仗。’邦特说:‘英国人根本没在缅甸打仗—是日本人在缅甸用英国人擦了擦屁股罢了。’人可真是无知啊。邦特连央街[3]的街顶都爬不上去。”
多年后,或许整整过了四分之一个世纪,我读到史迪威将军率领手下从缅甸步行到印度的记录。他们穿过德穆山顶的山口,下到钦敦河边。这伙人中包括一些脏兮兮的、饥肠辘辘的英国突击队员。没准艾瑞克·辛德曼就是其中一员。
辛德曼先生和辛德曼夫人初次邂逅,是因为他上门要求转租她在多伦多的公寓。他计划在加拿大当个记者。她计划开车和朋友们去墨西哥玩。她再也没去成。她和辛德曼先生一碰面,事情就那么着了。朋友们都劝她不要和他结婚。比她小七岁,离了婚—前妻和孩子还在澳大利亚某处—而且身无分文。所有人都说,他是个冒险者。可她不为所动。过了六个星期就嫁给了他,没邀请任何朋友来参加婚礼。
我觉得也该参加一点谈话,所以就问:“他们为啥因为他是个冒险者就反对他?”
“哈哈!”辛德曼夫人说,“他们不是那个意思。他们的意思是说,他图的是我的钱。其实我甚至都没办法说服他一边写他的经历,一边先靠这些钱过日子。他坚持要独立,只好去报道那些愚蠢的伴娘都穿什么衣服、嫁妆展示会,还有镇议会的所有那些废话,这简直要把他逼疯了。他是我见过的最有才华的人,总有一天,你会跟人吹嘘你认识他的!”
我们一听到辛德曼先生到门口了,我就会按照指示,抓着熨衣篮溜回厨房。辛德曼夫人换上一种又甜又傻、戏谑而激动的声音嚷道:“是我的宝贝男孩回家了吗?是小勋爵弗契特勒里[4]回来了吗?是那只澳洲小疯狗吗?”
辛德曼先生在大厅一边脱靴子,一边回答说他是至尊神探[5],或者是大力水手。他走进起居室,径直走向沙发,她躺在上面张开胳膊等着。他俩响亮地接吻,我狼狈不堪地抓着熨衣板撤退。
“他结婚是为了她的钱。”我告诉梅瑞贝斯。
梅瑞贝斯想知道他长什么样。
“像是沼泽地里捞出来的玩意儿。”我回答。不过那是恩娜姑妈头一回看到辛德曼先生之后的描述。我借用了它,因为喜欢这个说法。其实我觉得它并不准确。确实,辛德曼先生很瘦,高而瘦,面带菜色。但他看起来并不是那种没精打采、病怏怏的样子。事实上,他有一副骨骼清奇、五官鲜明、清新爽利的好相貌,正符合这时的潮流。一条铅笔线一样的胡子,冷静的细眼睛,充满嘲讽的淡淡微笑。
“像草里的蛇,”我修正道,“但她发了疯,爱极了他。”我表演他们每天的相见,咂巴着嘴,做着搂抱的动作。
辛德曼夫人告诉辛德曼先生我博览群书,而且是个历史天才。这是因为我帮她搞清了她正试着读的一本历史小说中的几处困惑。我解释了彼得大帝和叶卡捷琳娜女皇的关系。
“是吗?”辛德曼先生说。他的口音听起来比加拿大人更温和,也更精明。“你最喜欢哪个作家?”
“陀思妥耶夫斯基。”我说,或者以为自己是这么说的。
“陀思托—维斯基,”辛德曼先生沉思道,“你最喜欢他的哪部作品?”
我太紧张了,都没注意到他模仿我的发音。
“《卡拉马佐夫兄弟》。”我说。那是我读过的唯一一本陀思妥耶夫斯基的书。我是在夜里,在房子后部的冰冷卧室里读的这书,因为匆忙和贪婪,跳过了好多关于宗教大法官的描述和其他一些我读不下去的章节。
“你最喜欢哪个兄弟?”辛德曼先生微笑着,好像已经把我逼入死角。
“米嘉。”我答道。这会儿,我不那么紧张了,挺愿意继续聊下去,解释为什么喜欢他—阿历克塞太纯洁了,伊凡又太富知性了,等等。回家路上,我想象着说出了这些,想象着随着我的滔滔不绝,辛德曼先生的表情渐渐变得肃然起敬,还带点隐隐的懊恼呢。旋即我意识到在发音上犯的错。
我没机会继续说下去,是因为辛德曼夫人躺在沙发上嚷嚷起来:“最喜欢,最喜欢!谁是大家最喜欢的那个肥胖发胀的怀孕老女人呐?我倒想知道这个!”
不管我对梅瑞贝斯如何挖苦辛德曼夫妇,我仍想从他们那里博取些什么。关注、认可。我喜欢辛德曼夫人说我是个历史天才,尽管我知道这说法够傻的。对他的话我会更在乎。我感觉他瞧不起这镇子和镇上所有人。他根本不在乎他们对他不铲走道是怎么看的。我真想在他的轻蔑上啮出一个小洞。
可是,他还是要被称为宝贝男孩,并且屈从于那些亲吻。
梅瑞贝斯也有新鲜事要告诉我。贝特丽丝有男朋友了,一心想订婚。梅瑞贝斯说,他们正又急又累地朝那使劲儿呢。
贝特丽丝的男朋友是个理发师学徒。他在下午过来看她,那时她正好从医院倒班回来,理发店也正好空闲下来。那会儿,公寓里别的女孩还在上班,梅瑞贝斯和我呢,要是我们知趣,设法在学校逛逛,去喝杯可乐或者花点时间逛逛街的话,也不会出现在那里。可梅瑞贝斯坚持径直回到出租屋。
我们会发现贝特丽丝正在铺床。她扯下所有被子,熟练地铺好床单,然后在床单上的关键位置横铺一张吸水棉垫。我想起从前偶尔尿床,丢人地垫着橡皮垫睡觉的日子。
她重新铺好被子,拉扯齐整,藏起这个秘密。她拍松枕头,把被子上面的毯子掀开一个小角。我顿觉心头袭上一阵儿时欲望造成的眩晕感,一种对于被子的亲密触感的回忆。粗糙的毯子,舒服的法兰绒床单,那些秘密。
贝特丽丝穿过大厅走向浴室,就像收拾床铺一样,她也要去收拾身上的相关部位。她带着一种严肃、尽职的表情,一种家庭主妇般的专注。她依然没跟我们说一个字。
“要是接下来她当着我们的面做起那个,我也不奇怪。”我们下楼经过浴室门口时,梅瑞贝斯大声说道。水哗哗冲着。贝特丽丝在做什么呢?我想大概是在用浴棉吧。
我们坐在走廊台阶上。秋千在冬天收起来了,还没装回去。
“她真不知羞啊,”梅瑞贝斯说,“我还要在那张床上睡觉呢。她以为把垫子铺在床单上就没事了。垫子是她从医院偷来的。根本不能相信她,哪怕在她还很小的时候。有一次,我们打架了,她说:‘我们和解吧,来握握手吧。’我握住她的手,可她手心里捏着一只小蛤蟆,是在浴室里跳到她身上的。”
雪还没化完,刺骨的寒风正把沼泽、小溪和潮水的味道扫进镇上。不过理发师学徒依然懒得穿外套。他穿着白色工作服,沿小巷匆忙赶来,一路心无旁骛地低着头。他没料到会撞上我们。
“你们好啊!”他招呼道,故作轻松地装出一副热情样儿。
梅瑞贝斯没接茬,出于忠诚,我也不能开口。我们没站起身,只是挪了挪,让出仅容他走上台阶的空间。我竖着耳朵,却没听见卧室门开关的声音。
“他们就像两条狗一样,”梅瑞贝斯说,“干着那种事的两条狗。”
我想着此刻正在发生的事。互相问候,交换眼光,脱衣服。以什么顺序呢?伴随以什么样的语言和爱抚呢?他们是陷入疯狂呢,还是有条不紊的?他们是脱了一半就滚到床上呢,还是像在看病时一样脱衣?我觉得后一种可能更符合他们。
脱掉那个。对的。现在躺下。打开双腿。平静的命令,麻木的执行。贝特丽丝目光呆滞而顺从。而理发师的学徒,那个瘦骨嶙峋、满脖子雀斑的家伙,变得专横起来,准备实施他那邪恶的力量。就这样。是的。就这样。
“有一次,一个男孩让我做这事,”梅瑞贝斯说,“我弄得他差点被开除。”她告诉我,七年级时,一个男孩传了张纸条给她,上面写着:“你想干××吗?”她把纸条交给了老师。
“有人想让我做这事。”我说。这话让我自己也大吃一惊。我垂着眼睛,没看梅瑞贝斯。是谁?她问,他是怎么说的?在哪里?什么时候?是我们班上的什么人吗?我为什么没告诉她?
她跳到下方的台阶上,盯住我的脸。她把手按在我的膝盖上。“我们答应什么事都不向对方保密的。”她说。
我摇摇头。
“你居然没告诉我,我好伤心啊。”
我咬着嘴唇,好像打算锁住秘密。“其实,他和我相爱了。”我说。
“杰茜!快告诉我!”
她答应把自动铅笔给我用到学期末。我没接茬。她说我还可以用她的钢笔。自动铅笔和钢笔,全套都给我用。
我本想多逗她一会儿,然后承认这只是个玩笑。起初,我脑袋里一个人名也想不起来。突然我想起来一个,但它太丢人了。我没法相信我会说出它。
“杰茜,我给你一个手镯。不是借。是送给你。你想要随便哪个都行,就送给你了。”
“我要是说出他的名字,可不是为了手镯哦。”我说。
“我向上帝发誓我不会说的。我保证,说了就死。”
“对上帝发誓就够啦。”
“我会的。我对上帝发誓,杰茜,我对上帝发誓了。”
“辛德曼先生。”我轻声道。我感觉出奇地轻松,毫无撒谎的负担。“就是他。”
梅瑞贝斯从我的膝盖上缩回手,坐直身子。“他太老啦,”她说,“你说过他很丑!他结婚了!”
“我从没说过他丑啊,”我说,“他只有三十三岁。”
“你根本不喜欢他!”
“你恋爱的时候,有时候一开始就是那样的。”
从前我认识一个老太太,谈到自己的生活时她告诉我,她跟罗伯特·勃朗宁发生了三年私情。她根本没老糊涂。她是个非常精干、爽朗的老太太。她没说热爱勃朗宁的诗歌,或者花所有的时间读他。她也没说她有过幻想。“哦,是啊,”她说,“后来我就跟罗伯特·勃朗宁发生了三年私情。”我等她笑起来,或者补充几句解释的话,但没有。因此,我不得不认为,她在想象中开展的私情是如此严肃、投入,她不容许自己把它说成是想象。
那年春天我和辛德曼先生—在我的头脑中,在梅瑞贝斯面前—展开的私情,或许并没在我生命中占据那样重要的位置,不过它还是让我有事可忙。我和梅瑞贝斯相处时不再走神和厌倦了。我不得不安排再安排各种情节,通过选择要透露的信息让它们一一到位。我安排了和他的交媾,但没告诉她,后来不禁倍感庆幸,因为我又决定还是不要让它发生为好。否则我没法令人信服地想象那过程,或者事后要说些什么话。扯谎丝毫不曾让我为难。一旦一头扎进了错误之路—说出了辛德曼先生的名字—犯错的感觉便分外美妙起来。
我不仅通过所说的话,还通过我的模样来演示事情的进展。我并没有勒紧皮带、涂脂抹粉,表现得像个年轻的诱惑者。相反,我特意把头发编成辫子盘在头上,彻底放弃胭脂和口红,只是仍旧敷着厚厚的粉,好显得脸色苍白。我穿着一件恩娜姑妈的鼓鼓囊囊的绉绸上衣去上学。我告诉梅瑞贝斯是辛德曼先生要我穿成这样,把头发盘起来。他受不了任何人盯着我的头发看,或者看到我胸部的线条。他因为爱的重负而痛苦。我也一样。我弓着肩膀,表现出受难的气质。激情可不是什么轻松的事,这就是我想给梅瑞贝斯传达的信息。必须让负罪感、心事重重和一种炽热的欲望成为我的日常伴侣。
同样也要成为辛德曼先生的。在我的想象中,他越来越不顾一切。他爱抚我,低语喃喃,然后又自责、呻吟一番,变得虔诚起来,吻我的眼皮。
那么,真正的辛德曼先生呢?这一切是否让我一听到他进门便全身颤抖,对他充满期望,希望看到什么暗示呢?根本没有。他在我的想象中扮演角色的时候,就从现实中隐退了。我不再期待什么有趣的交谈,或者哪怕冲我的方向点点头。在我脑海中,我设法改善了他的相貌—给了他一种比较健康的脸色,压制了他习惯性的微微冷笑,让他显出一副忧郁温柔的模样。我设法不看他的真人,免得又要从头到脚改造他。
梅瑞贝斯追问着细节,但是对一切都不满意。她督促我永远不要屈服。“你不能向辛德曼夫人告发他吗?”她说。
“那会要了她的命的。反正她生孩子时也大有可能死掉。”
“要是她死掉的话,你们会结婚吗?”
“我还不够大哦。”
“他可以等嘛,要是他真像他说的那样爱你的话。他需要有人照顾宝宝的嘛。他会继承她的所有财产吗?”
提到宝宝,让我想到某件最近在辛德曼家发生的真事,也是一件让人不舒服的窘事。辛德曼夫人招呼我去看宝宝踢她。她躺在沙发上,掀起袍子,用一个垫子遮住私处。“在那儿,看啊!”她嚷道。我看到了,那可不是表面上的一下颤动,而是整个布满淡斑的山丘从底下传出的起伏翻滚。她的肚脐眼鼓突,像一个随时会弹出的瓶塞。冷汗从我的胳膊和额头上直冒出来。我喉咙里也翻上来一团硬邦邦的恶心感觉。她笑了,垫子滑了下来。我冲进厨房。
“杰茜,你有什么好怕的?我想他们中没有哪个会像你反应这么大!”
在辛德曼家的另外两幕。
辛德曼先生早早回了家。我放学后到那里时,他和辛德曼夫人一起待在起居室里。辛德曼夫人仍旧整天拉着窗帘,尽管外面已经是春天了,炎热的五月天。她说不许任何人看到屋里,看到她这副模样。
我从炎热、明亮的下午走进屋子,发现拉着窗帘的闷热房间里点着熏香,两个苍白的人咯咯笑着,喝着酒。他坐在沙发上,她的脚搁在他大腿上。
“正好来参加庆祝!”辛德曼先生说,“这是我们的告别聚会!我们的告别聚会,杰茜。告别了,走喽,再见!”
“别胡扯!”辛德曼夫人说,用光脚后跟捣他的大腿,“我们还没走呢。得等到这个可怕的宝宝出生才行。”
喝醉了,我想。我经常看到他们喝酒,不过此前从未看到他们酒后举止上有什么可笑的不同。
“艾瑞克要去写他的书了。”辛德曼夫人说。
“艾瑞克要去写他的书了。”辛德曼先生用愚蠢的尖声说道。
“确实嘛!”辛德曼夫人说,一边又用脚后跟捣了几下,“等这个怪物一生下来我们就走。”
“那真是个怪物吗?”辛德曼先生说,“它有两个脑袋吗?我们可以用它办个怪物展,赚一大笔钱吗?”
“我们不缺钱。”
“我缺。”
“给我住嘴吧。我可不知道它是不是有两个脑袋,不过我觉得它足足有五十条腿。前几天它把杰茜吓坏咯。”
她告诉他我是怎么逃开的。
“你得习惯这些事啊,杰茜。”辛德曼先生说,“世界上有些地方的女孩,在你这个年纪已经有一两个孩子了。你在自然面前可没法讨巧。小小的棕色皮肤女孩,其实她们自己也还只是孩子,就已经有孩子了。”
“哦,我敢肯定。”辛德曼夫人说,“杰茜,做个乖孩子。你知道什么是金酒,对吗?在这个杯子里倒一点金酒,然后倒满橙汁,这样我可以补充点维生素C。”
我接过她的杯子,辛德曼先生想站起身,但她按住了他,他只好说:“香烟。我想它们在卧室里。”
他从卧室回来后没去起居室,而是进了厨房。我在水槽边往冰盘里倒冰块。
“找到没有?”辛德曼夫人嚷道。
“正在这里找呐。”
他手里抓着一盒烟,却在水槽边的柜子里动作很大地翻找。他挨到我身边,和我肩并着肩。他把手搁在我肩膀上捏着。他把手揽到我的背上,摸我赤裸的后脖子。我手里端着冰盘站着,盯住窗外一辆停在后巷的旧巴士,就在福音堂后头。车身一侧印着“圣体龛”字样。
辛德曼先生只用指尖拂过我的喉部。它们的触摸起初轻得像水滴。然后重了些。越来越重,最后用力刻着我的皮肤,好像要划出几道沟似的。
“找到啦。”
我给辛德曼夫人端去饮料,辛德曼先生正坐在立式烟灰缸边的扶手椅里。
“过来坐在刚才的地方嘛。”她用那种愚蠢甜腻的声音说。
“我在抽烟。”
我的喉咙刺痛着,好像刚挨了一拳。
几天后的第二幕,在我又一次去干活的时候。
辛德曼先生在花园里忙碌。他只穿衬衫,仍打着领带,在花园一角,用锄头清除覆盖在一间摇摇欲坠的小凉亭上的藤条。他警告地喊了我一声,等着我穿过没修剪的草地走到他面前。他说辛德曼夫人不大舒服,医生给她开了点药让她睡觉,让她不要乱动,安静下来,防止早产。他说我今天最好不要进屋。
我离他两码远。突然他说:“过来。到这儿来。问你件事。”
我凑近了些,双腿直发抖,不过他只是指着脚下一棵长势旺盛、多叶红茎的植物。
“这是什么,你知道吗?我该挖掉它吗?我分不清这里什么是杂草,什么不是。”
这是一株大黄属植物,我向来就管它叫草,或者叫蒲公英。
“我也不知道啊。”我说,那会儿确实脑袋一片空白。
“你不知道?那你对我有什么用呢,杰茜?这个难道不是个古怪的小窟窿吗?”他冲凉亭挥挥手,“真不知道它是给什么东西造的。侏儒吗?”
他抓住一把藤蔓,扯开,命令道:“进去。”
我照做了。里面是一个奇妙的隐身之所,阴森森的,无人打搅,起伏不平的泥地上点缀着几丛枯萎的植物。屋顶确实很低,我俩都只能弯着腰。
“热吗?”辛德曼先生问。
“不热。”事实上,我全身发寒—一阵阵虚弱感,浑身不自在。
“没错,你是热。你那团头发下面全是汗。”
他例行公事地摸摸我的脖子,就像医生检查身体一样,然后把手挪到我的脸颊和发际线一带。
“连额头都出汗啦。”
我能闻到他手指上的香烟味,还有报社油墨机器的味道。我只希望能坦然面对这些。自打在厨房水槽边,辛德曼先生摸过我的喉部之后,我就一直觉得正在亲身体验我的谎言,我的幻想的魔力。我是一个会施巫术却手足无措的家伙。毫无选择,唯有屈从,屈从于其结果。我琢磨着,不知那激情的进攻是否不再有什么铺垫了,直接就要在这里发生—就在此地,在凉亭的遮蔽中,在泥地上,在枯死的树叶和刮人的小树枝当中,里面没准还藏着老鼠或小鸟的尸体呢。我能确定的只有一点,那就是在我的幻想中辛德曼先生经常发出的那些痴情告白,那些美妙的请求和缠绵,是绝无可能了。
“你以为我想吻你了,杰茜?”辛德曼先生说,“我毫不怀疑你是个接吻高手。可是不行。”他说,好像是我在请求他似的。“不,杰茜。我们坐下吧。”
凉亭里有几块嵌在墙上当长凳的木板。有的断掉了。我坐在一块没断的上面,他坐在另一块上。我们得朝前俯身,避开从格栅墙上钻进来的硬邦邦的树枝。
他把手按在我的膝盖上,按住我的棉布裙。
“辛德曼夫人会怎样呢,杰茜?你觉得她这会儿要是能看到我们,会很高兴吗?”
我觉得这不是一个提问,可他又问了一遍,我只好回答:“不会。”
“因为我对她做了你可能会希望我对你做的那种事,她要生孩子啦,这可不是什么轻松的事儿。”
他隔着薄棉布拍拍我的腿。“你是个冲动的女孩呐,杰茜。你可不该男人一喊,就跟他们进了这样的地方。你不该这么急着让他们吻你。我想你这人性子急,对吧?你这人性子急呐。你该学点教训。”
事情就这么继续着—拍打和说教,同时冲我而来。他宣称这都是我的错。同时,他的手指掀起我皮肤下的骚动感,挑起一种温和的、隐隐的痛楚。他用干巴巴的声音谴责我。他的手令我兴奋,他的话让我羞愧,他的声音里有一种东西嘲弄着,深深地嘲弄着这两种反应。我不知道这样不公平。至少,我没想到抗议这不公平。我确实感到羞愧,还有困惑,还有渴望。但我羞愧并非因为他宣称的那些我应当为之羞愧的事情。我羞愧,是因为被逮个正着,被弄得一脸蠢相,因为被如此诱惑又被如此谴责,而且我已经身不由己。
“有一件事你得学会啊,杰茜。要为别人着想。为别人设身处地着想。听起来很简单,但是做起来很难。对你来说,会很难呐。”
他或许是指他老婆,我没为她着想过。不过我对这话的理解有所不同。难道不是这样吗:迄今为止我在世界上认识的所有人,对我而言都只是些用来填充我的美妙幻想的木偶罢了?确实如此嘛。按照恩娜姑妈喜欢的说法,他这话说得可谓一针见血。不过,在这种事情上,对个人挫败的一针见血,并不会让人羞愧难当、感激涕零、洗心革面。相反,错误被赤裸裸地揭穿,逼出的是尊严。我现在就是这样。尊严被逼出来了,尊严终止了所有偷偷摸摸的甜蜜爱抚,浇熄了愉悦的希望和暗地里的诱引念头。对于一个可以如此洞穿我的人,我还能有什么念想呢?事实上,要是这会儿能将他从地球上抹去,我会的。
他察觉到了变化。他收回手,站起身。他吩咐我先出去,直接回家。没准还警告了几句,不过我没再听下去。
除此之外,梅瑞贝斯宣布她不相信我。“我一开始信。真的。后来我就开始怀疑了。”
“我们分手啦,”我说,“全都结束了。”
“我不相信你,”梅瑞贝斯悲痛地摇着头,声音颤抖地说,“我不相信你和他之间有过任何事情。我不得不告诉你。别生气啊。我实话实说。”
我没回答。我快步走着。我们正在上学路上。我们像往常一样,在道明银行的一角碰头。她走过整整三个街区,才脱口说出刚才那些话。她只好快步小跑着跟上我。就在遇到别的几个女孩之前—就在我友情洋溢、心情愉快地招呼她们的名字之前—我狠狠瞪了她一眼。我就像对叛徒一样瞪了她一眼。我觉得她罪有应得。她错了—我和辛德曼先生之间发生了好多事。当然,她也是对的。但是我狠狠地按捺住了那方面的想法。遭到谴责时,不管它是正确的还是错误的,你都会爆发出这种理直气壮的怒火。
我不假思索便采取了不搭理梅瑞贝斯的策略。她在衣帽间凑上前来,温柔地说:“我们一起回家吧,杰茜。”我没理她。她走在我身边,我假装她不存在。考试开始了,我们的日程改变了,避开她变得很容易。
一封信出现了,夹在我的法语书里。我没把它读完。她说我在伤害她,她吃不下饭,夜里在床上哭泣,哭得头痛欲裂,都没法看清考卷上的试题了,肯定会不及格。她道了歉,希望自己没有这么大嘴巴。要是我再不跟她说话,那她怎么才能跟我说道歉呢?她只知道一点—她永远不可能像这般狠心对我。
我径直看到末尾,看到两颗用小小的x组成的心形,里面写着我俩的名字。杰斯和美瑞白丝。我没再读下去。
我想摆脱她。我厌倦了她的抱怨和信任,她美丽的脸蛋和温柔的性格。我已经超越了她,不再需要她能提供的任何东西。还不止如此。她哭肿的眼睛、备受折磨的模样隐隐令我满足。我享受着伤害她的感觉。毫无疑问。我赢回了一点点在辛德曼家的凉亭里失去的东西,不管那是什么。
几年—现在看来也没几年,不过当时感觉过了很久—之后,我又到读高中时的镇子,在大街上逛着。我已经是研究生了。我赢得了奖学金,不再会读错陀思妥耶夫斯基的名字。恩娜姑妈去世了。给地板打完蜡之后,她刚坐下来,就死了。佛罗瑞斯结婚了。貌似一个药剂师秘密追了她很多年,他拥有鞋店隔壁的药店,但是恩娜姑妈反对他:他酗酒(也就是说,会小呷几口),而且是个天主教徒。佛罗瑞斯连生两个男孩,她把头发染成褐色,晚上会和丈夫一起喝点啤酒。乔治和他们住一起。他也喝啤酒,帮助照看宝宝。佛罗瑞斯不再害羞或局促。她变得很乐意交朋友。她送给我花朵图案的围巾和人造珠宝,都是我用不上的,还送给我从药店拿来的润肤露和唇膏,这些我倒很喜欢。她邀请我一有空就去看她。我有时真去了,不过那乱糟糟的家庭生活,那些以宝宝们为中心的快乐忙碌,很快便逼着我出门散步。
我沿大街逛着,突然听到有人叩窗。是保险公司的窗子,叩窗的是梅瑞贝斯,她在那儿上班。高中最后一年,她上了打字和簿记课。她跟贝特丽丝和她的丈夫一起生活,后者很快就开了一家自己的理发店。在那一年里,她没再尝试和我做朋友。看到对方迎面走来,我们会走到马路对面,或者盯着橱窗—尽管更多是出于窘迫而非真正的敌意。之后她就进了保险公司。
辛德曼夫妇在此之前就离开了。宝宝出生前,他们锁上房子,去了多伦多。是个男孩—据大家所知非常正常。恩娜姑妈对于他们没有正确地封上房子十分不满。她说,里面会生耗子的。不过他们卖掉了它,把报纸也卖了,走得彻彻底底。
梅瑞贝斯招呼我进门。
“我好久好久没看见你了。”她说,好像我们分别时有多友爱似的。她插上电水壶,给我冲速溶咖啡。保险商不在。
她胖了点,不过依然很美丽,楚楚动人。她一如既往衣着入时,穿了件漂亮至极的粉蓝色毛衣,拉绒羊毛裹着柔软的胸部。她在桌子抽屉里存着巧克力,在锡皮罐里放着果酱塔。她请我吃裹着锡纸的杏仁蛋白软糖。她问我是否还在上学,学什么。我跟她提了一点我的学业和打算。
“太棒啦,”她诚心诚意地感叹道,“我一直就知道你可聪明了。”她说她听到我恩娜姑妈的事很难过,她觉得佛罗瑞斯过得不赖。她听说佛罗瑞斯的小宝宝们可爱极了。
贝特丽丝生的都是女娃娃,也很可爱,不过都被宠坏咯。
我们都感叹说,她居然看到了我,多幸运啊。我们发誓找个时间好好聚聚—我知道对此她和我一样,都并非发自真心。她赞美我的安哥拉羊毛围巾和帽子,问是不是在城里买的。
我说是的,唯一的问题是:掉毛掉得一塌糊涂。
“把它们放进冰箱冻一夜,”她说,“我不知道原理,不过很有效。”
我打开门,寒风从街上刮进来。
“记得我们过去有多疯吗?”梅瑞贝斯感叹道,声音悲伤而惊奇。她忙着四下打转,按住纸张。
我想起辛德曼先生和我的所有谎言,以及凉亭里那种难以言喻的混乱感觉。
“那些日子一去不复返咯。”梅瑞贝斯说,扑到桌上按住东西。
我笑了,也发了点类似的感慨,然后赶紧关上门。我从门外挥挥手。
那会儿,我感觉到了变化—从十五岁到十七岁,从十七岁到十九岁—却没意识到其实一直以来,我还是我。我看到梅瑞贝斯关在办公室里,更甜美、更丰满了,四周是她的点心和打字机,我看到辛德曼夫妇远在天边,陷在他们没完没了的博弈之中,可我自己却是变幻不定的,挥却了一个又一个梦想、谎言、誓言和错误。我不曾看出的是,拥抱着又决绝着的,其实是同一个我。我还以为我可以一遍遍重新来过,磕磕碰碰地走过世界而毫发无伤。
[1] 迪斯尼动画形象。
[2] 此为一首十九世纪的英文赞美诗的标题。
[3] 多伦多最著名的街道,亦是吉尼斯世界纪录中世界上最长的街道。
[4] 1886年英国作家弗朗西斯·伯内特撰写的儿童小说的主人公。
[5] 美国畅销漫画主人公。
关于结构这个事,还真是值得细细的来说。毕竟都说结构是骨架,但是问起来,他们都只会说:起承转合。然后最多还能扯两嘴高潮,这有些什么鬼用?结构是骨架,但是结构还是很复杂的,结构到底是什么哩?好我们来聊聊结构是什么
**结构是骨架**
---------
结构是骨架,为什么呢?其实结构的定义很诡异,在不同的语境之中,“结构”的意思是不同的。有的时候结构指的的是“从开场到尾声”的结构组织,有的时候又指“选择和冲突论为中心”的结构方式和整体组成方式。所以还挺麻烦的,我在此不仅仅说“结构组织”重点放在后者。毕竟前者只是一种经典的结构方式,而在实际的创作之中结构方式又很多种,而且那些所谓的条例也不尽然需要遵守。
首先结构承载的是整个故事的发展脉络和整体的铺排方式。而实际上我还是很喜欢用基础结构方式来铺排一个故事的基本样貌的,甚至在结构到时候我们可以先打出一个基础的叙事节奏的框架。而这一切都是基础的结构方式上的问题,可是,真正的结构的中心是什么?
这个问题先按下不表,我们提出一个实在一点的疑问——“为什么很多时候故事越写越掌控不住?”
这个事从表面上来说,是没有做好大纲,而实际上是结构能力的问题。
简单一些来说,像我这种水平低下的家伙,不打大纲直接写的话2000-2500字以内的故事是一个极限,再多了就肯定泄气。 (当然我指的是那种相对而言的泄气,露怯。)
那么结构实际上就是维持一个故事发展的基本框架,而如果一个基本的框架铺排的方式就是结构方式,而粗略的结构如果以三幕剧结构来说的话
> 开端,开场,代入,发展,次高潮,延宕,高潮,结局,尾声。
其实总结一些说是“起承转合”也没有问题,可是,这种谁都知道的结构方式,并不能让我们很好的组织起一个故事,或者说很多人并不会运用这样的结构。
那不妨我们来拆解一下这个三幕剧结构,我之前在一个回答里面写过,让我搬过来。
> * 开端:开端需要事件引入和信息扣押,交代情境,人物的基本出场和人物展现。
>
> * 开场:人物上场,人物性格呈现,悬念和事件的开端,需要营造一定的悬念。
>
> * 代入:人物代入事件和情境。
>
> * 发展:人物在事件之中发展,人物性格呈现,事件推动,悬念加强,人物关系具有推进、发展和变化。
>
> * 次高潮:一次具有刺激力的事件,对主要人物甚至所有人物造成刺激,是人物主要转变的开始,是人物情感爆发的开端。
>
> * 延宕:情绪的积累,延续。事件和节奏的缓和、压缩。
>
> * 高潮:最终矛盾的爆发,人物转变,悬念的解开,人物的完全揭示。
>
> * 结局:高潮之后的交代,人物的延续。
>
> * 尾声:抒情,人物的延续。
如果这样来看,是否能够明晰一些,各个部分需要做什么了呢?说实话,这个回答本身是写给一个学习戏剧的学生的,所以估计大部分人开导这个还是并不能清楚知道里面到底是些什么玩意,什么叫做信息扣押,什么叫做情境,什么叫做人物展现。
那么这个玩意到底有啥用,其实就是让自己知道每一部分我们需要干什么,但是我们又提出了一个很严峻的问题——“什么时候才是这一步?”
结构组织的搭建和意义
----------
其实我本身并不太想给大家一个大概按照百分比的分开各个部分的概念,实际上那只是一种很无聊的东西,至少我是这么认为。但是同样我也认可,其对一些没有创作经验的人而言是一个很好的参考。所以我还是给各位一个大概的概念吧。

好的,大概是这样的,按照这个图来安排结构,就是很标准的三幕剧三幕剧结构,开场融入到开端之内了。(我还真是满满的干货,这东西都给做了!)
可是,这个真的就只是一个参考,仅仅就只是一个参考作用而已,千万别当做金科玉律。实际上,结构的问题才刚刚来到。
**结构中的每一个单元都可以拆分成以上的结构,从理论上来说:结构是可以无限拆分的。**
简单来说,就算是“开端”部分,我们一样可以拆分成如上的一整套系统。当这一切开始拆分并成立的时候,我们的结构终于要搭建起来了。这就是为什么揣着一个三幕剧结构,却不会用的最大的原因,这只是个大结构,但是内部的结构一直处于混乱之中,那样的话当然当不了骨架的作用。
其实这是一个很理想化的拆分过程,而实际上在创作过程之中,我们往往很难做到多次拆分,虽然在修改的过程中会进行调整,可是就算我们知道如此,拿出一些大师作品来看,还是很难完整的拆分下来,为啥?我们进入核心问题,结构的重心。
结构的重心
-----
其实结构并不是仅仅局限于上面那种框架,更重要的是对于事件的选择,处理和排布。这个才是结构的重心。一个完整的故事不一定是一照时间顺序来讲述的,同样的在好的作品之中,同一个时间之内有许多事情发生,我们选择什么才是结构的真正意义。我们其实是有一些原则可以辅助的。
> 1. 选择戏剧性更强的事件和场面。
>
> 2. 选择更加能够展示人物的事件和场面。
>
> 3. 选择更符合主题的事件和场面。
>
> 4. 选择更加符合艺术需求的事件和场面。
>
> 5. 选择冲突和矛盾更加集中的事件和场面。
>
当然了这个事其实尴尬的,对于我而言我往往不选择冲突十分激烈的场面来描写,我反而喜欢讲戏剧性压在下面来描述,将人物作为中心来选择场面和事件。但是实际上这种写法需要一定的积累和一定的笔头功夫。不然会很无聊,特别像是流水账,像我这种写法需要将背后的矛盾暗示出来,并且融合到人物的行动上。简单来说——不建议新手尝试。
我们既然说到了选择、处理和排布。那么一个故事之中,我们可能有许多的事件选择可能,但是放在什么地方,怎么放,有什么用,则成为搭结构时候的一道工序。有人觉得结构是一件很简单的事情,实际上结构是最麻烦的,甚至一直不停的贯穿整个创作过程,而不是仅仅再搭大结构的时候需要。
当然后面还要提及人物发展线索,事件发展线索在结构之中的勾连、铺垫、交织。以及悬念的营造,信息的扣押等等。这些我后面捎带着来写。这些实际上都属于结构的部分,而目前我预备先从简单的大框架、结构的基础整理上入手。
然后关于结构的重心,我认为还是应该至于矛盾之上,而不仅仅是冲突。我们提及矛盾的时候就会发现,矛盾不仅仅是社会属性的社会矛盾,而人物的性格矛盾也成为组成结构组织十分重要的部分。而且往往真正能够让人产生移情作用的部分就是人物的性格矛盾,无矛盾不戏剧,当然戏剧性嘛是什么都需要的,并不一定要写戏剧,这个也不是专门来讲述戏剧写法的专栏。不过戏剧性的建立对于吸引读者还是蛮有效的,而在结构之中处于一个十分重要的地位。在基础的框架之中,每一步的推进其实都应当是矛盾的积累或者爆发的过程,是具有目的的,是具有功能性的。
实际上结构,就是要搞清楚自己在每一步需要完成什么的框架,在这样的框架下进行选择就是结构的进一步运用,选择之后的调整排布就是结构的最终任务。
——————————————————————————————————————————
上次有人说,希望我可以发出自己的作品出来。其实还蛮尴尬的,没卖掉的作品我自己觉得拿不出手,卖掉的作品要么没有署名要么有保密协议。我在思考要不要干脆开个专栏,全程直播一个项目出来。但是这样又具有一定的风险,什么构思被盗用,大纲被抄袭之类的还真是防不胜防。虽然说日光之下无新事,但是吧......我直播整个工作流程,会不会搞出很多的工作上的干货来......那就很尴尬了。
主要是写个写作技术的专栏呢,我还能自我安慰是个兴趣。在专栏上做作品,还没钱。宝宝不是很开心。同时,如果开个项目来做,那么肯定导致这个专栏更新更加的缓慢,而且因为没有deadline,不签合同。我当然不会以其为重心,毕竟宝宝还要做挣钱的项目。所以也不能保证更新。
那么具体要不要开,看看评论状况以及我自己的心理挣扎状况好了。
今生今世的证据- 刘亮程
========================
今生今世的证据- [[刘亮程]]
-----
我走的时候,我还不懂得怜惜曾经拥有的事物,我们随便把一堵院墙推倒,砍掉那些树,拆毁圈棚和炉灶,我们想它没用处了。我们搬去的地方会有许多新东西。一切都会再有的,随着日子一天天好转。
我走的时候还不知道向那些熟悉的东西去告别,不知道回过头说一句:草,你要一年年地长下去啊。土墙,你站稳了,千万不能倒啊。房子,你能撑到哪一年就强撑到哪一年,万一你塌了,可千万把破墙圈留下,把朝南的门洞和窗口留下,把墙角的烟道和锅头留下,把破瓦片留下,最好留下一小块泥皮,即使墙皮全脱落光,也在不经意的、风雨冲刷不到的那个墙角上,留下巴掌大的一小块吧,留下泥皮上的烟垢和灰,留下划痕、朽在墙中的木和铁钉,这些都是我今生今世的证据啊。
我走的时候,我还不知道曾经的生活有一天,会需要证明。
有一天会再没有人能够相信过去。我也会对以往的一切产生怀疑。那是我曾有过的生活吗?我真看见过地深处的大风?更黑,更猛,朝着相反的方向,刮动万物的骨骸和根须。我真听见过一只大鸟在夜晚的叫声?整个村子静静的,只有那只鸟在叫。我真的沿那条黑寂的村巷仓皇奔逃?背后是紧追不舍的瘸腿男人,他的那条好腿一下一下地捣着地。我真的有过一棵自己的大榆树?真的有一根拴牛的榆木桩,它的横杈直端端指着我们家院门,找到它我便找到了回家的路。还有,我真沐浴过那样恒久明亮的月光?它一夜一夜地已经照透墙、树木和道路,把银白的月辉渗浸到事物的背面。在那时候,那些东西不转身便正面背面都领受到月光,我不回头就看见了以往。
现在,谁还能说出一棵草、一根木头的全部真实?谁会看见一场一场的风吹旧墙、刮破院门,穿过一个人慢慢松开的骨缝,把所有所有的风声留在他的一生中?
这一切,难道不是一场一场的梦?如果没有那些旧房子和路,没有扬起又落下的尘土,没有与我一同长大仍旧活在村里的人、牲畜,没有还在吹刮着的那一场一场的风,谁会证实以往的生活——即使有它们,一个人内心的生存谁又能见证?
我回到曾经是我的现在已成别人的村庄。只几十年工夫,它变成另一个样子。尽管我早知道它会变成这样——许多年前他们往这些墙上抹泥巴、刷白灰时,我便知道这些白灰和泥皮迟早会脱落得一干二净。他们打那些土墙时我便清楚这些墙最终会回到土里——他们挖墙边的土,一截一截往上打墙,还喊着打夯的号子,让远远近近的人都知道这个地方在打墙盖房子了。墙打好后每堵墙边都留下一个坑,墙打得越高坑便越大越深。他们也不填它,顶多在坑里栽几棵树,那些坑便一直在墙边等着,一年又一年,那时我就知道一个土坑漫长等待的是什么。
但我却不知道这一切面目全非、行将消失时,一只早年间日日以清脆嘹亮的鸣叫唤醒人们的大红公鸡、一条老死窝中的黑狗、每个午后都照在(已经消失的)门框上的那一缕夕阳……是否也与一粒土一样归于沉寂?还有,在它们中间悄无声息度过童年、少年、青年时光的我,他的快乐、孤独、无人感知的惊恐与激动……对于今天的生活,它们是否变得毫无意义?
当家园废失,我知道所有回家的脚步都已踏踏实实地迈上了虚无之途。
景物的描写-老舍
========================
景物的描写-[[老舍]]
-----
在民间故事里,往往拿“有那么一回”起首,没有特定的景物。这类故事多数是纯朴可爱的,但显然是古代流传下来的,把故事中的人名地点与时间已全磨了去。近代小说就不同了,故事中的人物固然是独立的,它的背景也是特定的。背景的重要不只是写一些风景或东西,使故事更鲜明确定一点,而是它与人物故事都分不开,好似天然长在一处的。背景的范围也很广:社会,家庭,阶级,职业,时间等等都可以算在里边。把这些放在一个主题之下,便形成了特有的色彩。有了这个色彩,故事才能有骨有肉。到今日而仍写些某地某生者,就是没有明白这一点。
这不仅是随手描写一下而已,有时候也是写小说的动机。我没有详明的统计为证,只就读书的经验来说,回忆你的作品可真见到过不少。这种作品里也许是对于一人或一事的回忆,可是地方景况的追念至少也得算写作动机之一。“我们最美好的希望是我们最美好的记忆。”我们幼时所熟习的地方景物,即一木一石,当追想起来,都足以引起热烈的情感。正如莫泊桑在《回忆》中所言:“你们记得那些在巴黎附近一带的浪游日子吗?我们的穷快活吗,我们在各处森林的新绿下面的散步吗,我们在塞因河边的小酒店里的晴光沈醉吗,和我们那些极平凡而极隽美的爱情上的奇遇吗?”
许多好小说是由这种追忆而写成的;假若这里似乎缺乏一二实例来证明,那正是因为例子太容易找到的缘故。我们所最熟习的社会与地方,不管是多么平凡,总是最亲切的。亲切,所以能产生好的作品。到一个新的地方,我们很能得一些印象,得到一些能写成很好的旅记的材料。但印象终归是印象,至好不过能表现出我们观察力的精确与敏锐;而不能作到信笔写来,头头是道。至于我们所熟习的地点,特别是自幼生长在那里的地方,就不止于给我们一些印象了,而是它的一切都深印在我们的生活里,我们对于它能象对于自己分析得那么详细,连那里空气中所含的一点特别味道都能一闭眼还想象的闻到。所以,就是那富于想象力的迭更司与威尔斯,也时常在作品中写出他们少年时代的经历,因为只有这种追忆是准确的,特定的,亲切的,真能供给一种特别的境界。这个境界使全个故事带出独有的色彩,而不能用别的任何景物来代替。在有这种境界的作品里,换了背景,就几乎没了故事;哈代与康拉得都足以证明这个。在这二人的作品中,景物与人物的相关,是一种心理的,生理的,与哲理的解析,在某种地方与社会便非发生某种事实不可;人始终逃不出景物的毒手,正如蝇的不能逃出蛛网。这种悲观主义是否合理,暂且不去管;这样写法无疑的是可效法的。这就是说,他们对于所要描写的景物是那么熟悉,简直的把它当作个有心灵的东西看待,处处是活的,处处是特定的,没有一点是空泛的。读了这样的作品,我们才能明白怎样去利用背景;即使我们不愿以背景辖束人生,至少我们知道了怎样去把景物与人生密切的联成一片。
至于神秘的故事,便更重视地点了,因为背景是神秘之所由来。这种背景也许是真的,也许是假的,但没有此背景便没有此故事。Algernon Blackwooa(阿尔杰农·布莱克伍德)是离不开山,水,风,火的,坡便喜欢由想象中创构出象The HouseofUsher(厄谢尔的房子)那样的景物。在他们的作品中,背景的特质比人物的个性更重要得多。这是近代才有的写法,是整个的把故事容纳在艺术的布景中。
有了这种写法,就是那不专重背景的作品也会知道在描写人的动作之前,先去写些景物,并不为写景而写景,而是有意的这样布置,使感情加厚。象劳伦司的《白孔雀》中的描写出殡,就是先以鸟啼引起妇人的哭声:“小山顶上又起啼声。”而后,一具白棺材,后面随着个高大不象样的妇人,高声的哭叫。小孩扯着她的裙,也哭。人的哭声吓飞了鸟儿。何等的凄凉!
康拉得就更厉害,使我们读了之后,不知是人力大,还是自然的力量更大。正如他说:“青春与海!好而壮的海,苦咸的海,能向你耳语,能向你吼叫,能把你打得不能呼吸。”是的,能耳语,近代描写的功夫能使景物对人耳语。写家不但使我们感觉到他所描写的,而且使我们领会到宇宙的秘密。他不仅是精详的去观察,也仿佛捉住天地间无所不在的一种灵气,从而给我们一点启示与解释。哈代的一阵风可以是:“一极大的悲苦的灵魂之叹息,与宇宙同阔,与历史同久。”
这样看来,我们写景不要以景物为静止的;不要前面有人,后面加上一些不相干的田园山水,作为装饰,象西洋中古的画像那样。我们在设想一个故事的全局时,便应打算好要什么背景。我们须想好要这背景干什么,否则不用去写。人物如花草的子粒,背景是园地,把这颗子粒种在这个园里,它便长成这个园里的一棵花。所谓特定的色彩,便是使故事有了园地。
有人说,古希腊与罗马文艺中,表现自然多注意它的实用的价值,而缺乏纯粹的审美。浪漫运动无疑的是在这个缺陷上予以很有力的矫正,把诗歌和自然的崇高与奥旨联结起来,在诗歌的节奏里感到宇宙的脉息。我们当然不便去摹拟古典文艺的只看加了人工的田园之美,可是不妨把“实用价值”换个说法,就是无论我们要写什么样的风景,人工的园林也好,荒山野海也好,我们必须预定好景物对作品的功用如何。真实的地方色彩,必须与人物的性格或地方的事实有关系,以助成故事的完美与真实,反之,主观的,想象的,背景,是为引起某种趣味与效果,如温室中的热气,专为培养出某种人与事,人与事只是为作足这背景的力量而设的。Pitkin(皮特金)说:“在司悌芬孙,自然常是那主要的女角;在康拉得,哈代,和多数以景物为主体的写家,自然是书中的恶人;在霍桑,它有时候是主角的黑影。”这是值得玩味的话。
写景在浪漫的作品中足以增高美的分量,真的,差不多没有再比写景能使文字充分表现出美来的了。我们读了这种作品,其中有许多美好的诗意的描写,使我们欣喜,可是谁也有这个经验吧——读完了一本小说,只记得些散碎的事情,对于景物几乎一点也不记得。这个毛病就在于写得太空泛,只是些点缀,而与故事没有顶亲密的关系。天然之美是绝对的,不是比较的。一个风景有一个特别的美,永远独立。假若在作品中随便的写些风景,即使写得很美,也不能给读者以深刻的印象。还有,即使把特定的景物写得很美妙,而与故事没有多少关系,仍然不会有多少艺术的感诉力。我们永忘不了《块肉余生》里Ham(汉姆)下海救人那段描写,为什么?写得好自然是一个原因,可是主要的还是因为这段描写恰好足以增高故事中的戏剧的力量;时候,事情,全是特异的,再遇上这特异的景物,所以便永不会被人忘记。设若景阳岗上来的不是武二,而是武大,就是有一百条老虎也不会有什么惊人的地方。
为增高故事中的美的效力,当然要设法把景物写得美好了,但写景的目的不完全在审美上。美不美是次要的问题,最要紧的是在写出一个“景”来。我们一提到“景”这个字,仿佛就联想到“美景良辰”。其实写家的本事不完全在能把普通的地点美化了,而在乎他把任何地点都能整理得成一个独立的景。这个也许美,也许丑。假如我们要写下等妓女所居留的窄巷中,除非我们是“恶之花”的颓废人物,大概总不会发疯似的以臭为香。我们必须把这窄巷中的丑恶写出来,才能把它对人生的影响揭显得清楚。我们的责任就在于怎样使这丑恶成为一景。这就是说,我们当把这丑陋的景物扼要的,经济的,净炼的,提出,使它浮现在纸面上,以最有力的图像去感诉。把田园木石写美了是比较容易的,任何一个平凡的文人也会编造些“天朗气清,惠风和畅”这类的句子。把任何景物都能恰当的,简要的,准确的,写成一景,使人读到马上能似身入其境,就不大容易了。这也就是我们所应当注意的地方。
写景不必一定用很生的字眼去雕饰,但须简单的暗示出一种境地。诗的妙处不在它的用字生僻,“只在此山中,云深不知处”,是诗境的暗示,不用生字,更用不着细细的描画。小说中写景也可以取用此法。贪用生字与修辞是想以文字讨好,心中也许一无所有,而要专凭文字去骗人;许多写景的“赋”恐怕就是这种冤人的玩艺。真本事是在用几句浅显的话,写成一个景——不是以文字来敷衍,而是心中有物,且找到了最适当的文字。看莫泊桑的《归来》:“海水用它那单调和轻短的浪花,拂着海岸。那些被大风推送的白云,飞鸟一般在蔚蓝的天空斜刺里跑也似的经过;那村子在向着大洋的山坡里,负着日光。”
一句话便把村子的位置说明白了,而且是多么雄厚有力:那村子在向着大洋的山坡里,负着日光。这是一整个的景,山,海,村,连太阳都在里边。我们最怕心中没有一种境地,而硬要配上几句,纵然用上许多漂亮的字眼,也无济于事。心中有了一种境地,而不会捉住要点,枝节的去叙述,也不能讨好。这是写实的作家常爱犯的毛病。因为力求细腻,所以逐一描写,适足以招人厌烦——象巴尔扎克的《乡医》的开首那种描写。我们观察要详尽,不错;但是观察之后面找不出一些意义来,便没有什么用处。一个地方的邮差比谁知道的街道与住户也详细吧,可是他未必明白那个地方。详细的观察,而后精确的写述,只是一种报告而已。文艺中的描绘,须使读者身入其境的去“觉到”。我们不能只拿读者当作旁观者,有时候也应请读者分担故事中人物的感觉;这样,读者才能深受感动,才能领会到人在景物中的动作与感情。
“比拟”是足以给人以鲜明印象的。普通的比拟,可是适足以惹人讨厌,还不如简单的直说。要用比拟,便须惊人;不然,就干脆不用。空洞的修辞是最要不得的。在这里,我们应当提出“观察”这个字,加以解释。一般的总以为观察便是要写山就去观山,要写海便去看海。这自然是该有的事,可是这还不够,我们须更进一步,时时刻刻的留心,对什么也感到趣味;然后到写作的时候,才能把不相干的东西联想到一处,而创出顶好的比喻。夜间火山的一明一灭,与吕宋烟的烧燃,毫无关系。可是以烟头的燃烧,比拟夜间火山口的明灭,便非常的出色。吕宋烟头之小,火山之大,都在我们心中,才能到时候发生妙用。所谓观察便是无时无地不在留心,而到描写的时候,随时的有美妙的联想,把一切东西都写得活泼泼的,就好象一个健壮的人,全身的血脉都那么鲜净流畅。小说家的本事就在这里。辛克莱与其他的热心揭发人世黑暗的写家们,都犯了一个毛病:真下功夫去观察所要揭发的事实,可是忘记了怎样去把它们写成文艺作品。他们的叙述是力求正确详细,可是只限于这一点,他们没能随手的表现出人生更大更广的经验。他们的好处是对于某一地一事的精确,他们的缺点是局面太小。设若托尔司太生在现时,也写《屠场》那类的东西,他一定不仅写成怪好的报告,而也能象《战争与和平》那样的真实与广大。《战争与和平》的伟大不在乎人多事多,穿插复杂,而在乎处处亲切活现,使人真想拿托尔司太当个会创造世界的一位神仙。最伟大的作家都是这样,他们在一个主题下贯串起来全部的人生经验。这并不是说,他们总是乌烟瘴气的把所知道的都写进去,不是!他们是在描写一景一事的时候,随时随地的运用着一切经验,使全部故事没有落空的地方。中国电影,因为资本小,人才少,所以总是那么简陋没劲。美国的电影,即使是瞎胡闹一回,每个镜头总有些花样,有些特别的布置,绝不空空洞洞。写小说也是如此,得每个镜头都不空。精确的比拟是最有力的小花样,处处有这种小花样,故事便会不单调,不空洞。写一件事需要一千件事作底子,因为一个人的鼻子可以象一头蒜,林中的小果在叶儿一动光儿一闪之际可以象个猛兽的眼睛,作家得上自绸缎,下至葱蒜,都预备好呀!
可是,有的人根本不会写景,怎办呢?有一个办法,不写。狄福在《鲁滨逊飘流记》中自然是景物逼真了,可是他的别的作品往往是一直的说下去,并不细说景物,而故事也还很真切。他有个本事,能借人物的活动暗示出环境来,因而可以不大去管景物的描述。这个,说真的,可实在不易学。我们只须记住这个,不善写景就不必勉强,而应当多注意到人物与事实上去;千万别拉扯上一些不相干的柳暗花明,或菊花时节什么的。
时间的利用,也和景物一样,因时间的不同,故事的气味也便不同了。有个确定的时间,故事一开首便有了特异的味道。在短篇小说里,这几乎比写景还重要。
故事中所需用的时间,长短是不拘的,一天也可以,十年也可以;这全依故事中的人物与事实而定。不过,时间越长,越须注意到季节描写的正确。据我个人的经验,想利用一个地点作背景,作者至少须在那里住过一年;我觉得把一地的四时冷暖都领略过,对于此地才能算有了相当的认识。地方的气候季节如个人的喜怒哀乐,知道了它的冷暖阴晴才摸到它的脾气。
对于一个特别的时间,也很好利用,如大跳舞会,赶集,庙会等。假使我们描写有钱有闲的社会,开首就利用大跳舞会,便很有力量。同样,描写农村而利用赶集,庙会,也是有不少便宜的。依此类推,一件事必当有个特别时间,唯有在此时间内事实能格外鲜明,如雨后的山景。还有,最好利用的是人们所忽视的时间,如天快亮了的时候。这时候,跳舞会完了,妇女们已疲倦得不得了,而仍狂吸着香烟。这时候,打牌的人们脸上已发绿,可把眼还瞪着那些小长方块。这时候,穷人们为避免巡警的监视,睡眼巴睁的去拾煤核儿。简单的说,这可以叫作时间的隙缝,在隙缝之间,人们把真形才显露出来。时间所给的感情,正如景物,夜间与白天不同,春天与秋天不同,雨天与晴天不同;这个不难利用。在这个之外,我们还须去找缝子,学校闹风潮,或绅士家里半夜三更的妻妾哭吵,是特别有价值的一刻。
"""
恒定推力的作用下,“流浪破车”号已经沿着一条漫长的行星际轨道飞出了内太阳系。经过八个月的太空航行,就在他们缓缓靠近塞德娜的时候,船员们差一点就错过了这个异常地貌——一个纯黑色的完美圆坑。“流浪破车”号的船员们并不是被雇来猎奇的——实际上,一个直径二十二千米的圆坑甚至算不上罕见。放眼整个太阳系,每一个天体,不论大小,表面全都布满了圆形凹痕——那些大大小小的环形山连接起来,组合成奇形怪状的涂鸦。
不过,这个圆坑可不普通,它的形状异常完美。在这样一颗偏远的“冰球”上,在一个到处都覆盖着厚厚一层红褐色积雪的世界里,它却是纯粹的黑色。
谁又会想到塞德娜上会有一个外星人工遗迹呢?
塞德娜是最大的海外天体之一,这个小天体的体积与冥王星不相上下,公转轨道却要椭长许多,它距离太阳十分遥远,因此永久处于冰封状态。
在“流浪破车”号减速入轨的大约一周时间里,这个黑色圆坑成了船员们在牌桌上闲聊的话题,不过,工头凯勒曼——一个铁石心肠、精明得像个会计的矿工——告诉他们,调查外星人之谜可不是“流浪破车”的船员们大老远飞到这里来的任务,他不打算放着赚钱的正经活儿不干,抽出时间跑去看那个圆坑。他们是矿工,不是科学家。塞德娜上富含大量有机物质,可以被运送到内太阳系的任何一颗殖民星球。如果他们还能找到氨,那可真是挖到宝了。氨可以提取出氮,价值连城的氮——在所有挥发性分子都必须依赖进口的殖民星球上,氮的价值远高于金和铂。从经济角度来看,勘探塞德娜绝对是一场赌博:它距离太阳十分遥远,只有找到一座巨型“金矿”,才有花费大量投入将物资运回内太阳系的价值。不过,殖民星球是一个不断扩张的市场,如果他们能够证明塞德娜上氨的储量丰富、对得起漫长的航行时间的话,那么塞德娜就会成为公司的一棵小摇钱树,一个赚钱不快但却十分稳定的收入来源。
减速进入环绕塞德娜的椭圆形轨道后,他们着手勘探这颗星球上的有机物资源,同时也拍摄了那个奇怪圆坑的照片,并将顺便测出的位置和大致尺寸等相关数据全部发回内太阳系。他们接到了回复,禁止他们靠近那里。他们还被告知,这不是一个天然物体,当然也不可能是人类制造的,因为他们是有史以来第一批抵达塞德娜的人类。这是外星人遗迹。他们没有资格去调查。在内太阳系,有些人担心如果让这帮笨手笨脚、只会凿石头的家伙围着一个无价之宝东挖西掘,造成破坏的可能性会比发现什么有价值的东西大得多。
在环绕塞德娜的轨道上遥测勘探的时候,他们已经探测到一座富氨矿——一个比大多数小行星都大的冰冻氨水湖。加之冰里还封存着大量有机索林土,使那里看起来像是一个不错的开采入手点。
采矿船在塞德娜上成功着陆,降落在氨矿附近,距离人工遗迹超过五百千米。会有别人来调查那个人工遗迹,一些步步为营而且小心谨慎的科研团队,他们会从地球上带来所需的全部工具和后勤设备。“流浪破车”号是来这里挖矿的。
“真是岂有此理!”罗克罗斯说,“我们飞了这么老远,离这颗星球上唯一值得一看的‘观光景点’只有五百千米,居然就这么止步不前了?”
他的搭档——丁基·齐默嘲弄似的看了他一眼。“我们是来挖矿的,”他说,“要是黑色圆坑里没有氨,谁还会去关心它呀?”
这个三人工作组里的第三个人——艾德里安·佩恩说:“只要我们找到富矿,拿到我们该得的奖金,想去看任何景点都不成问题。帮我检查一下工作服的密封性,好吗?”
罗克罗斯检查了丁基的工作服,又帮艾德里安检查了一下,分别向他们竖起大姆指;接着丁基帮他检查密封性。这种工作服是紧身型的,船员们管它叫“裸装”;当然,每个人都会检查自己工作服的密封性,不过为了保险起见,他们每个人还要交互复查一次。自己给自己做的每一步检查都必须得到一位搭档的确认。检查完密封性之后,罗克罗斯又检查了自己工作服的电池电量,然后帮丁基和艾德里安检查电量,同时他们也帮他复查了一遍。他们整装待发,去执行他们的第一次八小时轮班任务——采集冰芯,架设采矿所需的散热器。如果这座氨矿足够好,他们架设的设备有一天将成为一条行星际输送线的源头——两吨重的冰砖将在这里被感应电动机弹射入轨,无动力滑行几年之后,抵达内太阳系的消费市场。当然,这些工作全部会由机器自动完成。但目前,勘探和架设设备还需要人类亲自动手。
不过,林恩·罗克罗斯并没有全神贯注地工作,虽然他留出了足够的注意力保证自己不犯错误。他还没有把那个人工遗迹抛在脑后。他另有打算。
林恩是“流浪破车”号采矿作业的班组长,负责一个三人工作组。他有资格操作低重力低温地外采矿作业中用到的每一件设备。采矿和勘探是他的老本行,自从离开家乡灶神星上那些带有半球形穹顶的城市,他干的就一直是这一行——那一年他十五岁,在小行星带中部地区,这是法定的成年年龄。他的第一站是冰卫星木卫四。在一条融冰生产线上当了一段时间的廉价劳动力之后,他登上了一艘采矿飞船。五年的时间里,他先后在四艘不同的采矿勘探船上工作,拿到了他的工会会员证,也从一个干粗活的矿工一步步升到轮班组长。如果可以的话,他喜欢花点时间搞些随机勘探——只身一人降落到一颗看起来还不错的天体上,除了一身增强型工作服、一台激光钻和一台质谱仪外,什么东西都不带。一次随机勘探可以花上好几个星期的时间,他会一个人在那里分析矿物成分,希望能够撞上罕见的好运,发现有用的矿物。一个人待在工作服里,跟宇宙的其他部分隔绝开来,这让林恩感觉舒服极了。
林恩觉得自己已经够聪明了,不过他知道如果只靠自学,只去了解那些引起他注意的东西,那么轮班组长大概就是他能够爬到的最高职位了。在飞往塞德娜的漫长旅途中,他已经报名参加了大学课程,这是升到主管的第一步,他想最终拥有属于自己的飞船。现在,他的个人数据机里装满了业余时间用来学习的课件:文学、结构力学和物理学,全都是入门级教程。学习本该占据他所有的下班时间,因为他有太多的东西需要迎头赶上。不过,既然塞德娜上发现了奇怪的黑色圆坑,他不妨改变一下自己的计划。
他知道,内太阳系传回的无线电指示与其说是命令,倒不如说是建议。“流浪破车”号的船员们可不会去接受几十亿千米外的科研机构下达的命令。
工会明文规定,哪怕是开采高品级氨矿,只要上班时间超过八个小时,工头就必须按照危险工作工资的三倍给矿工支付加班费——而凯勒曼这个铁石心肠的家伙是肯定舍不得付加班费的。林恩和他的组员每工作八小时就会有十六个小时的休息时间,工会干事将一丝不苟地盯着他们,不让他们在休息时间里接任何非正式的工作任务。所以,他有的是时间。
他们下班了,为低温矿物学实验室带回了用于分析的冰芯样品。丁基和艾德里安脱下工作服洗澡去了,林恩目送他们走进浴室,自己却没有跟进去。
林恩觉得他可以翘一天课,避开下班后没完没了的牌局。有趣的东西就在那里,如果不去看一眼的话,他会后悔死的。虽然这是一次采矿任务,不是勘探任务,但林恩完全有资格单独进行勘探,而且下班后他想干什么就干什么,用不着告诉任何人。因此他溜了出去,没有告诉任何人。
那个人工遗迹在半颗星球以外,离“流浪破车”号位于氨矿附近的着陆地点有点距离。他给自己的工作服充满电,然后全面检查了一辆雪地履带车。这是他从设备仓库里开出来的——准确地说是偷出来的,因为他实际上并没有当班,但他又不是不打算还回来了——不然,他还能开到哪里去呢?他甚至都没有消耗任何燃料,因为这辆雪地履带车配备了一台小型核发电机,不论有没有发动,都会恒定地产生14.3千瓦的电能。
单独外出,这是他犯下的第一个错误。几个小时之后,这个错误开始变得致命了。
以差不多每小时两百千米的平均速度飞驰近三个小时是非常刺激的。在微重力环境下,雪地上的每个小鼓包都会把雪地车弹上半空。在头一个小时里,他小心翼翼地控制着方向,尽量沿最平滑的路线前进,一路颠簸吓得他都快要灵魂出窍了。不过,这台雪地车配备了姿态控制推进器,足以使车身在空气中保持稳定,不至于翻转(确切地说,这里的“空气”应该说成是“真空”才对,因为塞德娜周围包裹着的、以氦气为主的气体,气压低到了根本无法用“空气”这个术语来描述的地步)。颠簸了一段时间之后,他意识到这里的积雪非常厚实,把这颗星球上的山丘变成了天然跳高滑雪场,他的胆子也越来越大了。现在,他开始享受这种雪地跳高,他能够在空中悬停五秒,然后是十秒,最后达到三十秒!
这可比学习好玩太多了,他想。
透过打开了图像增强仪的护目镜,他看到四周都是低矮起伏的圆丘,呈现出一种深深的暗红色,就像佐治亚红土的颜色。塞德娜可真漂亮。林恩看到,平缓的山丘被刺目的明亮恒星照耀,闪烁着五颜六色的光——那是散落在红色索林土之上、断崖峭壁之间白色冰雪产生的反光。他试着关闭了图像增强仪。一开始,他只能看见一团漆黑,感觉自己在黑暗中飞速前行,完全依靠自动驾驶仪避开障碍物,弄得自己胆战心惊。一分钟之后,他开始在黑暗中辨认出一些模糊的影像。又过了几分钟,尽管太阳远在几十亿英里之外,但他发现自己仍然能够看见周围的景物。关闭了图像增强仪,四周的地面失去了色彩,在星光下闪烁着幽灵一般的苍白微光;太阳则显得无比的小,用一个大头针帽就可以把它完全遮住。
在他看来,这幅景象似乎更加真实,所以图像增强仪就这么一直关着。平视显示器为他指示周围的地形,自动驾驶仪则挑选最平滑的路线穿越雪原。
“你们这些家伙真该跟我一起来,”他对着空气自言自语,“打牌不好玩,至少在没发工资之前一点意思都没有。”
他很幸运,没有直接开进那个人工遗迹。他在雪地履带车上玩高难度滑雪跳高玩得忘乎所以,以至完全忘了留意周围的地形,甚至连自己开了多远都不记得。幸亏他的导航电脑没有忘记,在他靠近人工遗迹时及时提醒了他。
稍加提示,他就看见它了:远处的地平线突然断了一截。林恩重新打开图像增强仪,人工遗迹一下子变得非常显眼——红色的地平线上陡然缺失了一环,想不注意都难。他减慢速度,小心翼翼地接近它,接近积雪和人工遗迹之间刀切般分明的边缘,最后走下雪地履带车,一点一点向前蹭。
他向下看。
黑暗中闪烁着繁星。
有那么一瞬间,他觉得这是一个穿透整颗星球的大洞;接下来他又怀疑,这可能是另一个宇宙的入口。
林恩把雪地履带车固定在地上,又把自己和雪地车牢牢地拴在一起。他的工具包里装着他所有的装备,不过,带着工具包会让他笨手笨脚,甚至都无法趴下,所以他解下了工具包,只穿着紧身“裸装”轻装上阵。确认安全绳牢固可靠之后,他跪在外星人遗迹边缘,俯身向下张望。
他看到一个金色的头盔面罩——他自己的头盔面罩——向上看着他。
黑色的表面根本不是黑的,而是一个巨大的镜面,在他前面轻微下斜,反射着太空的黑暗。凑近观察,他可以看见镜子中反射的清晰的恒星影像。他离镜面太近了,以至于它看起来像是一个完美的平面,但抬头眺望远方,他就能隐约看出这是一个曲面。
他把手放在镜面上(镜子里的倒影也从下面伸出手来贴着他的手),摸起来感觉平整光滑——绝对平整,比油还要光滑,就像什么都没摸到一样,他的手掌在镜面上滑动时,根本感觉不到任何阻力。
透过手套他无法感觉温度。他的工作服是一个几乎完美的绝热体;当然,工作服要在外太空发挥作用,让矿工们穿着它在海外天体和柯伊伯带天体的低温冰原上行走,绝热是必须的。
林恩检查了手套指尖上的外部温度计。他把手指按在镜面上,温度计显示的读数是5开尔文。这是一个不可能出现的读数,因此他把手挪到了另一个位置。第二个位置仍然是5开尔文,第三个位置也一样,第四个也一样。
“真他妈见鬼,”他说,“简直比那帮放高利贷的家伙的心还要冷。”
他的温度计是好的。他测量了凹坑边上一小团硬块积雪的温度,读数正常——30开尔文。塞德娜的表面比地狱里的洞穴还要寒冷,但黑色表面的温度居然还要再低二十五度! 慢慢地,他想明白了。这个表面不是黑的,它是一个反射面,只是因为反射着星空,看起来才会是黑的。它一定非常接近真正的完美镜面。尽管远离太阳,塞德娜上的积雪仍然会吸收阳光,这些热量让它们比绝对零度高了几十度。但这个完美反射镜一定没有接收任何光线,因此依然寒冷。他意识到,在某个远红外波段,这个镜面一定辐射着少量热量。不过在太阳发出耀眼光芒的所有波段中,它什么都不吸收,因此才比它所在的地面更加寒冷。
这是一个巨大的凹面镜,一个直径达好几英里的巨型天文望远镜——又是为了什么目的而建造的呢?
林恩开始环顾这个镜面,心中惊叹不已。没有任何东西能够显示它的年龄,不过可以肯定,它一定非常古老。是谁在什么时候建造了这个镜面呢?塞德娜是太阳系柯伊伯带中轨道较为椭长的天体之一。这颗矮行星在一条长椭圆轨道上缓缓运行,最远可以抵达距离太阳大约1,000个天文单位的地方,几乎要脱离太阳的引力束缚了。或许它本来是一颗在恒星之间寒冷黑暗的空间中游荡的天体,直到几百万甚至数十亿年前,被太阳的引力俘获。它来自哪里?哪个未知的种族建造了如此巨大的望远镜镜面,目的何在?
他俯下身,把面罩紧贴在镜子的表面,一只手缠绕在紧绷的安全绳上维持着平衡。镜面完美平滑,完全反射。
突然,安全绳松了。
林恩站起身,看见雪地履带车正在黑暗中隐隐向他滑来。他之前把雪地车靠在一个冰丘旁加以固定,但核反应堆发出的废热融化了冰丘,雪地车现在自由了,开始蹒跚着滑下雪坡,喝醉酒一般摇摇晃晃地向他冲来。为了避开雪地车,他想都没想就后退了一步。
他立即意识到了自己的错误。他的防滑靴找不到任何着力点,镜子的表面比冰还要光滑,他的脚直接滑了出去。他四仰八叉地跌倒了。在微重力环境下,任何动作看起来都像在放慢镜头。他的一只手抓住了之前放在镜面边缘的工具包。有那么一会儿,他停在了镜面边缘,脸朝下趴着,脚悬在巨型镜面的斜坡上左摇右晃。他左手抓着斜坡边缘的工具包,整个身体都挂在这只手上,右手仍然紧紧攥着现在已经不再紧绷的安全绳。
雪地履带车向前滑动,撞上起伏的冰面,侧翻在地,悄无声息地溅起一团深红色的雪雾,慢慢停了下来。
局面似乎稳住了。他尽量不移动身体,动作异常缓慢地收紧安全绳,小心翼翼地拉了拉。雪地履带车在原地一动不动。他用一只手,把安全绳固定在了他的腰带扣上。
塞德娜上的重力非常微弱,还不到一个标准地球重力加速度的十分之一。把自己拉出凹坑,哪怕只用一只手,对他来说也轻而易举。他放松了一下,危险似乎暂时退却了。他的左手越来越僵硬,因为这只手正用一种非常别扭的姿势抓在镜面边缘的工具包上。他稍稍变换了一下姿势。
把他的身体锚定在镜面边缘的工具包,突然从雪地上松脱出来。
仿佛是华丽的慢镜头回放,工具包和林恩缓缓滑下镜面。他挥舞着双手伸向凹坑边缘,寻找一切他可以抓住的东西,最后只抓到了一把积雪。手忙脚乱之中,他松开工具包,任由它滑下了斜坡。工具包微微旋转着,下滑的速度越来越快。
安全绳仍然扣在他的腰带上,另一端系在雪地履带车上。他滑下镜面,直到松弛的安全绳再次绷紧。绳子略微伸长了一点,但是挺住了没有断。在他的上方,这根绳子的另一端,雪地履带车稍稍晃了一晃,但没有移动,仍然牢牢地扎在冰中;而绳子这一端的他则挂在镜面斜坡上左摇右晃。他伸出手臂,但镜面边缘总是比他伸直的指尖远了那么一丁点儿。他伸出一只手,抓住绳子,向上攀去。
腰带扣断了。
绳子从他的指间松脱,就像上面涂了油一样。林恩·罗克罗斯以一种缓慢、从容、优雅的姿态,沿着没有摩擦力的镜面滑了下去。
在滑落的过程中,他试着伸手去抓斜坡的顶端。这个大圆盘的边缘离他的指尖只有一英寸,但无论怎样疯狂地舞动双手,他都抓不到任何着力点。他一路顺畅地向下滑,速度越来越快,虽然速度增幅不大,但不可阻挡。这真让人抓狂,又令人泄气。
我完蛋了,他想。
在滑下镜面的过程中,他还有时间回顾一下他的人生、他到访过的港口,以及他的罪孽——无论是他已经犯下的,还是他没来得及犯的。所有这些看起来都很美,但都没有了意义。
回顾这一切花了他大概二十秒的时间。他还在往下滑,脸朝下,依旧做着毫无意义的神经反射运动——努力地在镜面上攀爬。
过了一会儿,他放弃了,翻了个身,费了一番工夫,努力坐了起来。在一个没有摩擦的表面上运动,就像在做自由落体运动,这方面他有着丰富的经验。琢磨了一会儿之后,他慢慢掌握了其中的窍门。他扭了扭身体,面朝运动方向坐好,评估了一下自己的处境,尽最大的努力让自己平静下来。应急预案已经钻进了他的大脑,他开始反复默念,就像在吟诵祷文一样。
应急预案第一条:采取任何必要的紧急措施防止情况恶化,并隔离受损部位。
好吧,这一条简单。他正在滑向一个镜面凹坑的底部,没有任何可以让他抓住的东西。无论如何,情况也不会比现在更糟糕了。
应急预案第二条:启动121.5MHz和406MHz广播频道的双频紧急定位信标。
那辆雪地履带车上装着他的紧急信标,还有其他远程通信工具,现在都已经在他上方远得看不见了。备用紧急信标在他的工具包里,正在他前方某处的黑暗中沿着镜面滑行。
他的工作服上装有低功率超宽频音频通信设备。这是矿工和矿工之间进行通话用的,不过它被有意设计成只适用于短程通信;要不然,一百个矿工的声音早就把无线电频谱给占满了。他录了一段简短的呼救信号,在工作服的音频通信设备里每分钟播放两次,每次持续呼叫五秒钟。这么做是没用的,不过至少可以让他平静下来。呼救信号根本没机会被人听到。“流浪破车”号远在地平线以下,超出了无线电波的传输范围。因为本来不应该有人跑到地平线以下,所以轨道上根本没有通信中继卫星。
应急预案第三条:调查你的处境,确定你相对于潜在救助来源的位置和速度。
根本不存在潜在的救助来源。不过,他的工作服确实配备有惯性导航单元,他可以测定自己的位置和速度。他确认导航单元已经开启,并把他的位置和速度发送到平视显示器上。暗红色的图表闪现在他的面罩上,飘浮在这片黑暗之中。他正沿着一个倾角略小于二十度的斜坡下滑,目前正以每秒十八米的速度相对于镜面移动。在他查看数据的同时,惯性导航单元还在不断地更新他的速度:每秒十八点三米,每秒十八点六米。
他感觉不到自己的速度。除了显示器上正在缓慢增大的数字以外,他感觉自己好像根本没动。
这对他没有任何帮助。他让电脑显示出他的位置-时间关系图。他穿越镜面的路线是一条完美的抛物线。这是合理的。这个镜面当然应该是个抛物面,是一台巨型望远镜的反射镜。他把抛物线向前延伸,用一个移动的小点画出他的运动轨迹。他的移动速度越来越快,但随着他滑向底部,他的加速度正在降低。按照曲线的形状推算,再过四分钟,也就是他失手滑下边缘之后六分钟多一点,他就应该能够抵达底部。然后,他的动量会带着他爬上另一侧斜坡。
应急预案第四条:检查消耗品,采取措施减少关键供应品的使用,直到获救。
林恩检查了自己工作服的状态。实际上,他并没有消耗任何消耗品。他的氧气是由零缓存内嵌式再生氧气系统提供的;他每呼出一口气,其中的二氧化碳就被分离出来,经过一个电解循环分解出氧气,再立即进入他吸进的下一口气中。整套系统靠一块固态电池供电,这块电池还为他工作服里的加热器提供能源。所以,电池才是他的最终消耗品。他检查了自己的电池状态:绿色,还有百分之七十六的电量。这种电池的满格电量足够撑两个班还绰绰有余,因此剩余电量还能供生命维持系统运转十二个小时多一点。有没有可能在电量耗尽之前,有人推测出他在哪里,然后组织营救呢?不太可能。甚至没有人会注意到他失踪了,除非又轮到他上班,那是在——他看了看时间——十三个小时以后。即使到了那时,也得等到下班后才会有人来查岗,然后才会去追查他为什么没来上班。
应急预案第五条:审视可用资源。以最有效的方式利用现有资源来实现救援。
很好。他的可用资源就是他的工作服,其他就真的什么都没了。他带来的其他所有东西,不是放在他已经丢失的工具包里,就是落在了雪地履带车上。如果他穿的是适合太空作业的工作服,那就一点问题都没有了:机动推进器将提供充足的推力,能够随心所欲地沿着任意方向把他推上斜坡。但事实上,他穿的是适用于地面作业的工作服,没有配备任何推进器。
应急预案第六条:在紧急情况结束后,联系空间监测机构取消紧急求救呼叫。
他估计,紧急预案的这一部分他可以忽略。
从头到尾默念一遍应急预案,没有给他指明任何解决问题的出路,不过至少减轻了他的恐慌。现在他距离底部还有一分钟,正以每秒一百六十米的速度滑行。他在脑子里换算了一下单位。灶神星,他从小长大的地方,最早是美国人的殖民地,一直顽固地拒绝接受公制单位,甚至在美国本身都并入欧盟之后,那里依然我行我素。他的滑行速度差一点就达到每小时一百英里了。他又一次查看了显示器,发现滑行路线其实不会经过底部正中央。他会从左侧擦过中心点。没错,他想。系住安全绳的腰带扣突然断开时,他正在左摇右摆;侧向速度说明,他的实际滑行路线是一个不会经过中心点的椭圆弧线——实际上,应该是一个李萨如曲线。他会从这个镜面的底部中心点的左侧不远处经过。他缓慢地转动着自己,向右张望,心里清楚这是一个毫无意义的动作,因为没有什么东西可看。
不过,还真有一些东西在寂静中滑了过来。他看不太清楚,这才意识到图像增强仪还没有开启。他顺手打开了它。
他正在高速经过一堆黑色的沙石和几块巨大的圆石。看起来它们离他只有几米远,不过他瞥了一眼测距仪,发现这是一个错觉:那堆沙石差不多在五十米开外。镜面的底部并非空无一物,而是装满了一百万年来落入这个环形山又滑到底部的各种碎片。
工作服的恒温器工作良好,他却突然感觉到一阵寒意。以每小时一百英里的速度撞上这堆碎片,倒是可以一下子终结他的所有问题。
那堆沙石从他身边滑过,在他身后变得越来越小——或者应该说,是他从那堆沙石旁边滑过才对。他已经经过了滑行轨迹的最低点,现在正在上升,滑上对面的斜坡。
为了节省绘图所消耗的那点电能,他重新关闭了图像增强仪。他现在正双脚朝前滑上斜坡。他检查了一下数据。在他滑到最低点的时候,他的最大速度差不多达到了每秒一百七十米。现在他的速度越来越慢,同时斜坡也越来越陡。他正滑向对面的镜面边缘。他躺了下来,想思考一下,结果一眼就看见了天空。
即使不打开图像增强仪,天空也显得无比壮观。他的身体下面有星星,身体上面也有星星,就好像他躺在一块完全透明的冰片上,在无尽的太空中滑行一样。太阳是一小粒火种,非常明亮,几乎刺痛了他已经适应黑暗的双眼,然而它又非常渺小,几乎散发不出多少光芒。在他移开视线之前,他能够看到太阳被一个朦胧的光盘包围,看起来非常暗淡,甚至比太阳在眼里留下的残影亮不了多少——这是黄道光。包围着黄道光的则是繁星,就像散落在天鹅绒夜幕上的数百万钻石颗粒,闪烁着从铁青到深红的各色光芒。
林恩盯着这些繁星,又在脑子里过了一遍应急预案。停止进一步损害,大声呼救,确定位置,节省消耗品,审视资源并解决问题,打电话回家。
第五步是最难的:审视可用资源并解决问题。不过,他仍然没有什么资源可以审视。他的地面工作服没有任何配件,甚至没有备用氧气瓶,不然他还可以拿来做一个冷气体推进器。工作服为他挡住寒冷和真空,给他提供能够呼吸的东西,仅此而已。生命维持系统和电池都是内嵌在工作服里的,即使他想拿,也根本拿不出来。而其他的所有东西都在矿工工具包里。
审视资源。工具包怎么样?它也跟他一样,在同一块镜面上滑行,只不过早了几秒钟。里面或许有什么工具能够解决他的问题——比如说,无线电信标。而且,即使没有其他有用的东西,他还可以把它当成反作用体。如果他能以足够快的速度把它扔出去,他就可以获得一点动量,让自己滑出镜面边缘。工具包就在他所在的镜面上,也许只有几米远。
林恩扭了扭身体,坐了起来,把他的图像增强仪效果开到最大。每个工具包的颜色都不一样,这是为了确保矿工不至于随手错拿别人的工具包;他的工具包是亮柠檬绿色。只花了几秒钟,他就看到它了。就在那里,在他前方不到二十米的地方,一边滑动还一边慢慢地旋转。 事实上,既然工具包在他前面,它就会比他更早抵达这个巨碗的另一侧边缘,然后掉转方向,冲他滑回来。
根据他在显示器上绘制的图表,距离镜面边缘大概还有一分钟。他死死盯住在他前面滑行的工具包。没错,就是那里——它会不会飞出边缘,滑出这个巨碗呢?不会。工具包只和镜面边缘轻轻地接触了一下,然后向左一偏,开始向他滑落回来。
他正在滑向边缘,速度越来越慢,而工具包正在滑落,速度越来越快。他张开四肢趴在镜面上,努力伸手去够工具包,但它从他身边滑过,离他尽量伸展的手指还差老远一段距离。
不过,他没有时间为错过这次机会而伤心难过。片刻之后,镜面边缘来了。他四肢并用地在镜面上努力攀爬,像一个游泳者一样使劲扑腾。只要他能够再往上爬高哪怕一米……
没有用。镜面边缘就悬在他的前方,近在眼前,却又遥不可及。无论他如何努力,就是无法再前进分毫。
他开始重新下滑,速度越来越快,镜面边缘也消失在了远方。
为什么工具包没有滑回到他手里?他意识到,这是因为它也像他一样,沿着一条椭圆轨迹滑行,跟他的运动轨迹并不交叉。
他现在正在往回滑。再过六分多钟到达底部,十二分钟后抵达另外一侧。然后再花十二分钟滑回来,再滑过去,滑回来……直到他耗尽电源,被冻僵并且窒息而亡。在那之后,他的尸体还会摆荡多久?几天?几年?这个镜面不可能一点摩擦力都没有;宇宙中没有任何一样东西是完美的。如果真有那么完美,那堆沙石就不会出现在底部中心;掉进来的岩石应该一直摆荡才对。
他觉得自己就是一个单摆的摆锤,只不过这个单摆靠的不是一根绳索,而是一个没有摩擦的表面。有那么一会儿,他的思绪把他带回到了孩提时代,那段在灶神星上快乐成长的日子。他和哥哥比赛荡秋千,看谁能荡得更高。他们肯定尝试过上百次,努力摆动着秋千,想让它越过横杆。他们从来都没有成功过,虽然灶神星上微弱的引力已经大大降低了难度;每当秋千荡得高过支点时,绳子就会松弛下来,秋千也会猛然掉落。
回想过去不会对他有任何帮助,他强迫自己回到现实,思考他目前的处境。再过几分钟,他就会回到起点。那条安全绳如何?如果它还悬挂在那里——不过这不太可能。他在脑子里回放了一遍自己跌落的过程。安全绳在腰带扣断开的时候,已经像根橡皮筋一样弹回去,消失在了边缘上方。他会努力抓住绳子,如果够得到它的话,但他不抱太大希望。
果然如此。他向上滑,距离边缘近在咫尺。有那么一会儿,他似乎悬停在那里,差一点就可以够到边缘,但他终于还是又滑开了。这一次,他和工具包之间的最近距离并不比在镜面另一侧时近多少,安全绳也丝毫不见踪影。
不过,还有其他东西需要思考。塞德娜每十个小时自转一周。再过——他看了看时间——两个小时,太阳就会直射头顶。在距离地球一百个天文单位的寒冷黑暗之中,太阳显得十分昏暗,不过,当阳光被一个直径二十千米的镜面聚焦在一起时,又会怎样?他意识到,这很可能就是建造这个镜面的实际目的。这不是一台望远镜,而是一台巨型太阳灶。
不过有一点他没有想到。镜面确实能够使阳光高度集中,但阳光会聚的地点将是镜面的焦点,位于镜面上方好几英里的高空。在镜子的表面,阳光不会比平时更亮,也不会更暗。他应该担心自己会不会被冻僵,而不是会不会被烤焦。
经过镜面底部时,林恩再次打开了图像增强仪,看着位于中心的那堆沙石,试图找个方法来利用它。不过它依然远在五十米外,没有任何可用的东西。
他关掉图像增强仪,又一次被繁星和黑暗包围。
或许他应该回顾一下自己的人生?和哥哥一起荡秋千的日子真是一段美好时光,虽然他们从来没能越过那根横杆。他可以用所剩不多的几个小时来回忆一下美好时光。他想,作为一个勘探者,自己到过很多地方,但他只见过那里阴暗、破旧的一面——那些靠近船坞的城区看起来全都一样。他知道矿工们每到一座采矿点都会找个姑娘来陪,但不管交易是明面上的还是暗地里的,无论如何,他们都会花钱买春。有人雇他的时候,他的收入还算不错,但不知道为什么,他从来就没有真正省下过一分钱。他觉得自己不是在浪费生命,至少不完全是,不过他已经玩够了,该是向前看的时候了。他需要学习,获得学位,闯出些名堂来。
好吧,他有大把的时间来学习,如果这就是他想做的事情的话。倒不是说学习对他有多大的用处——他还困在一个碗里呢!不过这倒提醒了他,他确实有一个之前没有想到的资源。他的个人数据机里存满了学习资料,其中一个科目是物理学。物理学教程里会不会有某个办法能够解决他的问题呢?虽然可能性不大,但为什么不试一试?
他启动了学习资料,在搜索栏中输入:“问题,在一个巨型镜面上滑行。”他压根儿就没指望能够找到任何结果,但搜索引擎还真给他找到了一条。
令他惊讶的是,这个结果不是在物理课件里找到的,而是从文学课件中搜出来的。这条链接指向二十世纪一篇古老的科幻小说,讲述了两个人在一块没有摩擦的镜面上滑行的故事。他一向讨厌经典科幻。他辍学以前在学校里已经读得够多了。老师们好像都喜欢科幻,但以前的那些作者写出来的东西总是错得离谱。主人公总是在没有任何防护措施的情况下,做一些极其危险的事情,他们全都愚蠢得要死。
那么,偷走一辆雪地履带车,在一颗陌生星球上独自远行,又不告诉任何人他打算去哪里,这样的事情算不算愚蠢呢?好吧,至少那个时候看起来,这个主意还不赖。
数据机里没有这篇小说的全文,只在一份二十世纪文学概述里有一段简要介绍。他浏览了一下,就愈发失望地意识到,这跟他的处境不太一样:这篇故事的主人公可以支配的资源比他多得多。在这个故事里,两位主人公被绳子拴在一起,他们借助这一点不断加快旋转速度,让他们相互飞离。课本上继续讨论说,故事里的这种方法并不管用;作者忽略了角动量守恒。没有用!如果这是一本实体书,而不是平视显示器上的一团荧光的话,林恩早就厌恶地把这本书给扔掉了。
要是他真有一本书可以扔就好了!任何东西都行!这样,他还可以利用动量。现在的处境简直就像不带任何设备就在太空中飘荡。他根本就控制不了自己的运动。
简介还提示他参见相关条目:简谐振荡,无摩擦运动。
他点开简谐振荡,发现这好像是一个有关正弦和余弦的教程,对他似乎没有明显帮助。接着,他翻到无摩擦运动,开始浏览教程。教程上说,超流氦是支持无摩擦运动的唯一一种已知物质。好吧,这很有趣。外星人有没有可能已经找到了某种方法,能够将超流氦凝成固体?不可能,这太荒谬了。不过,这个镜子的表面仍然极其寒冷,冷得连上帝都要打哆嗦。或许构成这个镜子的某种物质的表面上有一层薄薄的超流氦?他可不可能通过加热镜面来破坏这种效果呢?
但这没用,是条死胡同。即使镜面有摩擦,对他来说也可能仍然太滑,不可能让他顺着斜坡爬上边缘。他必须在斜坡上刻出台阶才行,但他没有工具。这种材料是不是有弹性呢?他用力踢了踢镜面,感觉就像踢在坚硬的花岗岩上。即使隔着靴子,他的脚趾还是踢疼了,但镜面连最细微的弹性都没有表现出来。不管构成镜面的物质是什么,它都很硬。
没有摩擦的表面大概很有商业价值,哪怕它只在接近绝对零度的低温下才能工作。如果凯勒曼这个王八蛋知道,他手下的一个工人正在一种价值超过这颗星球上所有氨矿总和的物质上独自滑行,救援大概很快就会赶到。 这种想法并不会让他距离获救更近一步。
边缘又靠了过来,或者说,他又在靠近边缘。他向边缘滑去,速度缓慢,在距离边缘近到令人抓狂的地方停住,然后又滑落下来。林恩确认无线电仍在广播着毫无用处的呼救信号,而工具包依然无法够到,然后检查了电池状态。没有用,没有用,没有用!
他趴在斜坡上往下滑,就像乘雪橇一样。他转了转身,小心翼翼地用手和膝盖支撑起身体,然后挺起上身跪在斜坡上,用一只手扶住镜面维持平衡。虽然有些摇摇晃晃,但一段时间之后,他控制住了。这好像不算太难。他尝试站立起来,而且确实站了一会儿,双手拼命挥舞着想要保持平衡,但双脚还是从身体下面滑了出去。
这有点像在冰面上尝试站立。他努力着,终于找回了平衡。他意识到,这很像是在木卫四的山丘上玩滑雪板,或者在火星的极冠上滑雪——在离开飞船上岸度假时他尝试过一次。火星上的二氧化碳积雪也几乎没有摩擦,不过,如果双腿放松并且保持警惕,你是可以站起来的。关键技巧就是要把手臂张开,让膝盖弯曲,在滑行过程中不断调整平衡。微重力环境很合他的口味,给了他足够的时间进行调整。
他站起来了,像冲浪一样滑下斜坡。要是他哥哥现在能看到他就好了!
这对改善他的处境一点帮助都没有,但能够站起来已经给他带来了巨大的成就感,仿佛他已经掌控了自己的命运。他想象自己是一名奥运滑雪冠军,正沿着奥林匹斯山斜坡上的人造雪道飞驰而下。他看了一眼显示器:差不多又经过底部开始再次爬坡了,他正以每秒一百五十米的速度滑行。这肯定打破了所有的滑雪纪录!他举起双手,向想象中的成千上万名热情观众挥手致意——然后向后滑倒,跌坐在镜面上。
在十分之一地球重力的加速度下,跌倒没什么大不了。林恩转了转身,又试了一次。通过练习,他发现自己几乎不需要刻意努力就能站起来了。
就好像能够站起来可以给他带来好处一样。
是不是这样呢?等一下,如果他能站起来,那他能不能跳起来呢?在十分之一地球重力加速度下,他应该可以跳得很高。有没有什么办法能够让他在滑到顶端靠近边缘的时候,跳过那一段短短的距离呢?
经过一点练习,他发现他确实可以把自己推离冰面,短暂地腾空而起。要真正跳起来,需要高度集中注意力,并且协调好动作,否则四肢就只会在冰面上徒劳地四下挥舞。(不是冰面,他想,应该是镜面才对。其实这不是冰。)
不过,他还没来得及为这突如其来的希望欢呼多久,泡沫就破灭了。能够跳起来并不会给他带来任何好处,因为他只能竖直起跳。不,甚至连竖直起跳都算不上——由于根本借助不到任何摩擦力,他起跳的方向只能完全垂直于镜面。他把他在镜面上的滑行轨迹调出来,显示在平视显示器上端详,试图找出他推理过程中的漏洞。假设他恰好在抵达最高点的那一刻起跳,但镜面倾斜的方向不对,反而会让他跳得距离边缘更远。没有用。如果他早一点起跳呢?不,还是不行;他起跳的方向总是错的。
他在平视显示器上画了一幅示意图,还在上面加了一个身穿工作服的小人图标。他费尽心思地研究着,但始终找不到一种能够借助跳跃帮助自己脱离困境的方法。事实上,跳跃甚至在帮倒忙——如果他滑向边缘的速度能够再增加一点,他就可以成功逃脱,但跳跃似乎在往相反的方向增加速度。
等一下,这个想法对吗?他的跳跃将完全垂直于他的运动方向,因此,跳跃不会改变他沿着镜面滑行的速度。或者还是会改变?他真希望自己能够多懂一点物理学。镜面是曲面,而他的跳跃是一个矢量,肯定有某种方法能够让这个矢量为他所用,但他看不出来。对他来说,这太复杂了。
审视可用资源,用它们来解决你的问题。他的资源就是他自己,一个在世界最大的秋千上摆动的孩子……还有存在数据机里的物理学教程。
他重新翻开教程,在解释简谐运动的一屏又一屏资料中搜寻。他发现,抛物线形势阱中的滑行正好就是他目前的处境。教程上解释说,他的运动遵循着一条完美的正弦曲线——这一点他已经知道了,而振荡的周期是固定的——这一点对他来说没有用。接着,教程开始介绍受驱振子,也就是有一个周期性出现的外力施加在振子身上。即使这个外力非常小,只要它与振荡周期同步,也能迅速增加振幅——他简直要抓狂了。这正是问题所在!他连这样一个“非常小”的外力都找不到,教程也没有给他提供任何线索。相反,教程开始向他讲授有关动能和势能的内容。
如有疑问,就去读该死的手册,他想。这个建议他起码听过一百次。有关简谐振动的教程是他手头仅有的手册。如果有解决办法的话,它就一定藏在这本教程里。
他开始努力学习简谐振动这一章,从头看起,钻研习题,一门心思地沉浸在解决方案之中。有一次,他查看平视显示器,震惊地意识到,时间已经在不经意间过去了一个多小时,整整摆荡了三个来回。他的注意力完全被吸引了,他觉得这些内容很有趣,本身就值得好好研究。他突然明白了物理学家为什么会如此热爱他们的研究。解决办法一定就在其中,就隐藏在动能和势能的那团迷雾里面。
确实如此。
他终于想明白了,几乎要笑出声来。答案就是秋千。 他需要认真一点。他查看了一下显示器,发现自己又在物理学课本上钻研了两个小时。太阳已经西斜。在他没有留意的时候,他已经在镜面上摆了八个来回。他检查了能量状态,电池大概还能维持九个小时。不过,他已经在脑子里理清了具体步骤。
他正仰躺在镜面上往下滑,因此第一件事就是翻身俯趴在镜面上。他调出显示位置和速度的图表,注视着显示器上他的滑行状态。接近镜面底部时,他做好了准备,手和膝盖向上推,共同把身体支撑起来。当滑行到单摆运动的最低点、速度达到最大时,他站了起来。
就这样。这就是他的计划。
在滑向边缘的六分钟里,他在光滑的镜面上保持站立状态——这就是诀窍。他站起来的时候,身体的重心大概会抬高七十至八十厘米,不算太多。
边缘靠近了。站在镜面上,尽管倾斜的角度明显偏离边缘,但他现在可以越过边缘看见积雪覆盖的平原了。那辆雪地履带车居然踪影全无。
不过,虽然他能看见巨碗的外面,但距离能够触及镜面边缘仍然差了一截。不要紧。当他滑行到边缘附近并短暂悬停在那里时,他开始实施计划的下一个步骤。
他坐下了——或者说,允许自己摔倒了——然后把自己压在镜面上,尽量使自己像一张纸那样紧紧贴在镜面上。
就是这样。重心改变了一点点,但是——他希望——如果重复足够多次,效果也会很显著。每次经过碗底,他就让自己站立起来;靠近边缘,就让自己躺倒在地。就像在荡秋千一样,他每次都往自己的运动中注入一点点能量。每当他经过底部,在站立起来的同时,他就把重心朝这个巨型秋千无形的支点挪近了一些,他的速度也会因此增加一丁点儿。当他在边缘附近俯下身体时,他基本上不怎么运动,因此根本没有损失动能。每摆荡一个周期,他就能获得一点点能量。
下一个周期:在底部站立,在边缘跌倒。再来,再来。边缘有没有靠得更近呢?很难说。再来,再来。他让自己的思绪放空,全神贯注于自己的运动。他回到了灶神星,回到了跟哥哥一起玩的秋千上,试图把秋千荡得够高,赶上他哥哥,越过横杆。再来一次,再来。
现在,边缘明显靠得更近了——他跌倒时尽可能伸长手臂,指尖触到了积雪,还不足以抓住边缘,但总算有进步了。他试着用一根手指把自己拉上去,但没有成功。
跌倒,站起。
再来,又近了一点儿;这一次他有两个指尖超过了边缘,能够尽力往上拉。再来,再来。现在,他可以把整个手掌探出边缘了。他用全部的力量往下按,把自己拉上去,几乎成功地把手肘探出了边缘,然后又滑了下去。
接下来这次,他的两只手都探出了边缘,他把自己往上拉,手肘攀上边缘,向上推,然后抬起膝盖跨过边缘,摇晃了一会儿之后,笨拙地翻出边缘,滚到了地面上。
他出来了。
他回到了地面上,像一个“大”字一样躺在积雪上,甚至没有呼吸急促。就是这么简单。“物理学,”他说,“这就是物理学。”他觉得站起来还不太安全,于是向外爬了爬,在自己和危险的边缘之间留出几米的安全距离。他检查了一下电量。电池差不多还能维持一个小时,不过这已经足够了。只要回到雪地履带车上,他就可以接入雪地车上的电源。而雪地车就在……
他的心一下子跌到了谷底。雪地车不在附近。
他检查了显示器上的惯性导航单元,根本无法相信上面显示的数字——雪地车在二十千米以外!
显示器上清楚地显示出他和雪地履带车的相对位置。他肯定是从错误的一侧翻出边缘的。
他坐在积雪上,再三检查着显示器,试图通过集中注意力让事情有所好转。他怎么可能犯这样一个低级错误呢?
雪地车在镜面的另外一侧,但并不是正对着他的另外一侧。在他沿着镜面来回滑动的几个小时里,这颗星球在他下面悄悄地旋转。他确实是从掉下去的那一侧爬上来的,但星球本身移动了。雪地车在圆周上的位置跟他形成了大约一百五十度的夹角。这比雪地车刚好位于正对面要好一些——他只要逆时针走二十九千米就可以了,比走完半圈整整三十五千米还稍微近点儿。
不过,二十九千米跟一千千米或一百万千米相比,大概也没有什么太大的区别;他根本不可能在剩下的——他看了看显示器——五十二分钟里,走完这么长的路。
他躺倒在地,突然间筋疲力尽。他已经有多久没有睡觉了?他真想好好睡上一觉——
这并不能改变他的处境。他又坐了起来,应急预案像祷文一样在他的脑子里回放。第一条:采取任何必要的紧急措施防止情况恶化……
他盯着黑色的镜面,想象着雪地履带车所在的位置,就在这个巨碗的另一侧边缘,隐没在黑暗中不见踪影。
……第五条:审视可用资源。以最有效的方式利用现有资源来实现救援。
他现在拥有的资源是一个没有摩擦的巨碗,完全漆黑,完全光滑,完全没有摩擦。
这是他最不想做的一件事,但等待和思考于事无补,只能耽误他的时间,或许还会磨灭他的勇气。必须当机立断。
他站起来,向外走了几步,然后转身,双眼紧盯着镜面边缘。就这样吧。
这还是物理定律。他之前之所以被困在这面镜子里,是因为他掉进去的时候携带的能量不足以使他再逃出镜面。现在他要做的就是穿过镜面,向右略偏一点,不过因为镜面会把他的运动轨迹弯成曲线,作为补偿,他瞄准的时候必须向右多偏一些。只要他携带的能量足够多,只要他掉进去的时候速度足够快,这面镜子就困不住他。如果他是冲进这面镜子的,而不是掉进去的,他就能够再冲出来。
这就是物理学。
他脑子里的另一个声音正在冲他尖叫:这是在自杀!但他没有选择。从来就没有。他开始起跑,然后跳向镜面。
他的俯冲让他沿着一条长长的平坦曲线落向镜面。在微重力环境下,他似乎悬停在空间之中,身下的黑暗映照出上方无边无垠的宇宙,沿着弧线下落时短暂的失重让他感觉像是永恒。
然后,他落到了镜面上,滑行,再滑行。在他的头盔里,显示器显示出他的轨迹,推测出他穿越镜面的路线。
但他并没有留意。他知道自己的运行轨迹没错。他能感觉出来。
终于,边缘到了,他成功地越过了那根横杆。
——献给罗斯·罗克林恩
"""
韭菜花-汪曾祺
========================
韭菜花-[[汪曾祺]]
-------
五代杨凝式是由唐代的颜柳欧褚到宋四家苏黄米蔡之间的一个过渡人物。我很喜欢他的字。尤其是“韭花帖”。不但字写得好,文章也极有风致。文不长,录如下:
`昼寝乍兴,朝饥正甚,忽蒙简翰,猥赐盘飧。当一叶报秋之初,乃韭花逞味之始。助其肥羜(zhù音柱),实谓珍羞。充腹之余,铭肌载切,谨修状陈谢,伏惟鉴察,谨状。`
>七月十一日凝式状
使我兴奋的是:
一、韭花见于法帖,此为第一次,也许是唯一的一次。此帖即以“韭花”名,且文字完整,全篇可读,读之如今人语,至为亲切。我读书少,觉韭花见之于“文学作品”,这也是头一回。韭菜花这样的虽说极平常,但极有味的东西,是应该出现在文学作品里的。
二、杨凝式是梁、唐、晋、汉、周五朝元老,官至太子太保,是个“高干”,但是收到朋友赠送的一点韭菜花,却是那样的感激,正儿八经地写了一封信(杨凝式多作草书,黄山谷说:“谁知洛阳杨风子,下笔便到乌丝阑”,“韭花帖”却是行楷),这使我们想到这位太保在口味上和老百姓的离脱不大。彼时亲友之间的馈赠,也不过是韭菜花这样的东西。今天,恐怕是不行的了。
三、这韭菜花不知道是怎样做成的,是清炒的,还是腌制的?但是看起来是配着羊肉一起吃的。“助其肥羜”,“羜”是出生五个月的小羊,杨凝式所吃的未必真是五个月的羊羔子,只是因为《诗·小雅·伐木》有“既有肥羜”的成句,就借用了吧。但是以韭花与羊肉同食,却是可以肯定的。北京现在吃涮羊肉,缺不了韭菜花,或以为这办法来自蒙古或西域回族,原来中国五代时已经有了。杨凝式是陕西人,以韭菜花蘸羊肉吃,盖始于中国西北诸省。
北京的韭菜花是腌了后磨碎了的,带汁。除了是吃涮羊肉必不可少的调料外,就这样单独地当咸菜吃也是可以的。熬一锅虾米皮大白菜,佐以一碟韭菜花,或臭豆腐,或卤虾酱,就着窝头、贴饼子,在北京的小家户,就是一顿不错的饭食。从前在科班里学戏,给饭吃,但没有菜,韭菜花、青椒糊、酱油,拿开水在大木桶里一沏,这就是菜。韭菜花很便宜,拿一只空碗,到油盐店去,3分钱、5分钱,售货员就能拿铁勺子舀给你多半勺。现在都改成用玻璃瓶装,不卖零,一瓶要一块多钱,很贵了。
过去有钱的人家自己腌韭菜花,以韭花和沙果、京白梨一同治为碎齑,那就很讲究了。
云南的韭菜花和北方的不一样。昆明韭菜花和曲靖韭菜花不同。昆明韭菜花是用酱腌的,加了很多辣子。曲靖韭菜花是白色的,乃以韭花和切得极细的、风干了的萝卜丝同腌成,很香,味道不很咸而有一股说不出来淡淡的甜味。曲靖韭菜花装在一个浅白色的茶叶筒似的陶罐里。凡到曲靖的,都要带几罐送人。我常以为曲靖韭菜花是中国咸菜里的“神品”。
我的家乡是不懂得把韭菜花腌了来吃的,只是在韭花还是骨朵儿,尚未开放时,连同掐得动的嫩薹,切为寸段,加瘦猪肉,炒了吃,这是“时菜”,过了那几天,菜薹老了,就没法吃了。做虾饼,以爆炒的韭菜骨朵儿衬底,美不可言。
就在跟爱斯基摩人开战之前_九故事_塞林格
========================
# 就在跟爱斯基摩人开战之前_九故事_[[塞林格]]
-----
接连五个星期六的上午,吉尼 • 曼诺克斯都跟她在贝斯霍尔小姐学校的同班同学塞利纳 • 格拉夫一起,在东区网球场打网球。吉尼毫不掩饰地认为,在贝斯霍尔小姐的学校里——这所学校明摆着全都是大号的讨厌鬼——而塞利纳更是个特大号的讨厌鬼,但同时她又从没听说过有人能像塞利纳那样带来一筒又一筒崭新的网球。莫非塞利纳她爸是造网球的不成。(有一天吃晚饭时,为了让曼诺克斯全家人长点见识,吉尼描绘出一幅格拉夫家用餐时的景象;说是那儿有个好得挑不出一点毛病的仆人,他来到每位就餐者的左侧,送上的并非一杯番茄汁,而是一筒网球。) 可是,每回打完球,都是先进塞利纳到她家门口下车,而全部的出租车车费却由吉尼来出——哪一回都是这样——这事让吉尼很不痛快。何况出了网球场坐出租车而不是乘公共汽车回家还是塞利纳的主意。到了第五个星期六,出租车开始沿着约克大街向北行驶时,吉尼突然发难了。
“嗨,塞利纳……”
“什么事?” 塞利纳问,她正忙着用一只手在出租车地板上摸来摸去。“我找不到我的网球拍套子了!” 她呻吟着说。
尽管 5 月天气已经很暖和,两个姑娘还是在短球裤外面套了一件薄大衣。
“你把它塞在衣服口袋里了,” 吉尼说。“嗨,听我说——”
“噢,上帝! 你真是救了我一命!”
“听着,” 吉尼说,根本不想听塞利纳的甜言蜜语。
“什么事儿?”
吉尼决定直截了当把话挑明。出租车快到塞利纳住的那条街了。“我今天不想再~个人出全部的车费了,” 她说。“我又不是百万富翁,你知道的。”
塞利纳先是觉得惊奇,接下去则是感到受了伤害。“我不是每回都出一半车钱的呜?” 她问,显得挺冤枉似的。
“没有,” 吉尼不客气地说。“你就头~个星期付了一半。那还是上个月月初的事。以后就一次也没有付过。我不是想斤斤计较,可是事实上我一星期就靠那四十五块钱活着。这笔钱我得用来--”
“球每回都是我带来的,不是吗?” 塞利纳挺不高兴地说。
有时候,吉尼真想把塞利纳宰了。“那是你爸爸自个儿做的,反正差不多就是这么回事,” 她说。“这些球不用你花一个子儿,而我却得出钱为每一件小——”
“行了,行了,” 塞利纳说,声音很响而且摆出一副不必再谈的模样,以使自己显得占了上风。她很不耐烦似的摸遍了大衣的每一只口袋。“我只有三十五分,” 她冷冰冰地说。“够了吧?”
“不够。对不起,你欠我的是一元六十五分。我可记着账呢,关于每一次的——”
“那我还得上楼去跟我蚂要呢。就不能等到星期一啦? 早知道你喜欢这样我是可以带着钱去体育馆的。”
塞利纳的态度毫无妥协的余地。
“不行,” 吉尼说。“我今晚必须去看电影。我得用钱。”
两个姑娘都憋着气,一言不发,各白往自己一方的窗外盯着,直到车子在塞利纳所住的公寓前面停下。接着,坐在靠便道一边的塞利纳钻出汽车。她只让汽车门留下一道缝,便轻快地而且是故作姿态地走进公寓楼,就像是去拜访好莱坞的大亨似的。吉尼脸都气红了,付了车费。接着她收拾起自己打球用具——网拍、毛巾,还有遮阳帽,紧跟在塞利纳的后面。十五岁的吉尼大约身高五英尺九英寸,穿 9-B 号网球鞋,她走进门厅时,自己也觉得她那双橡皮跟球鞋太次,充分暴露出她是个一眼就能看出的业余生手。她这模样使塞利纳都不想看她,宁愿把双眼盯住在电梯高头的指示灯上。
“这下子你就欠我一块九了,” 吉尼说,一边大步朝电梯走去。
塞利纳扭过头来。“没准你会感到兴趣,” 她说,“我妈正病得厉害呢。”
“她怎么啦?”
“她可以说是得了肺炎,如果你以为我喜欢就为了钱的事去打扰她……” 塞利纳尽了最大的努力沉着地说出了这半句话。
事实上吉尼情绪上已经为这消息稍稍受了一点影响,不管它在多大程度上是真实的,但是还没到使她心软的地步。“又不是我把病传染给她的,” 她说,跟着塞利纳进了电梯。
塞利纳按响她家套间的门铃,两个姑娘给让了进去——或者不如说,门让人朝里一拉任其半开着——开门的是个黑人女佣,看来塞利纳平时都跟她不搭话。吉尼把她的打网球用具扔在门厅的一把椅子上,跟着塞利纳往前走。进了起居间,塞利纳转过身来说,“你在这儿等一会儿好吗? 我说不定还得叫醒妈妈什么的呢。”
“好吧,” 吉尼说,一屁股朝沙发上坐下去。
“我怎么也没想到你居然会为一点点小事这么小气,”塞利纳说,她生气得很,用了 “小气” 这个词儿,但是胆子还不够大,没有在语气上加以强调。
“现在你知道了吧,” 吉尼说,打开放在她面前的一本《时尚》杂志。在塞利纳离开房间之前她一直保持着这个姿势,然后才把它放回到收音机的顶上。她环顾了一下房间,在自己的想像中把家具都作了重新安排,那几只台灯得扔掉,那些假花得撤走。在她看来,这个房间丑陋不堪——钱花得不少却俗气得像蹩脚干酪。
突然,一个男人的声音从公寓另一头传出来,“埃里克? 那是你吗?”
吉尼猜想这准是塞利纳的哥哥,此人她从未见到过。她叉起自己修长的双腿,把大衣下摆拉过膝盖,等着。
一个戴眼镜,穿睡衣睡裤,光着脚,嘴张开着的年轻人闻了进来。“哦,我还以为是埃里克呢,我的天,” 他说。他没有站住,继续以他极不像样的步势穿过房间,把什么东西接紧在自己狭窄的胸口前面。他在沙发空着的那头坐下。“我刚把我倒霉的手指割破了,” 他挺激动地说。他看着吉尼像是早已想到她会坐在那儿似的。“你割破过手指吗? 一直深到骨头那儿什么的?” 他问。他吵吵闹闹的大嗓门里有一种真正恳求的声调,仿佛吉尼只要一回答,就可以免得他一个人出头独自受罪似的。
吉尼盯着他看。“嗯,倒没一直割到骨头,” 她说,“割是割伤过的。” 他是她见到过的模样最最可笑的男孩,或是男人了——到底该归到哪一类还真不好说。他的头发睡得乱蓬蓬的。稀稀落落的黄胡子有两三天没刮了。他显得——怎么说呢,挺傻的。“你是怎么割伤的?” 她问。
他正松开下巴低头盯看着自己受伤的手指。“什么?” 他说。
“你是怎么割伤的呢?”
“妈的,我要知道才怪呢,” 他说,语气里显得要回答这个问题那真是难上加难。“我方才在那只臭纸篓里寻找什么东西,那里却满是些刮脸的刀片。”
“你是塞利纳的哥哥?” 吉尼问道。
“是的。天哪,我要流血致死了。别走开。没准我得输好多血呢。”
“你抹药了吗?”
塞利纳的哥哥把他的伤口从胸前往外伸伸,不再挡住好让吉尼看清楚。“就盖了他妈的一些手纸,” 他说。“想止住血。刮脸刮破时也是这样做的。” 他又看了看吉尼。“你是谁?” 他问。“那蠢姑娘的朋友?”
“我们是同一班级的。”
“是吗? 你叫什么名字?”
“弗吉尼亚 • 曼诺克斯。”
“你就是吉尼?” 他说,透过眼镜斜瞟了她一眼.“你是吉尼 • 曼诺克斯?”
“是的,” 吉尼说,把她交叉的腿放平。
塞利纳的哥哥的眼光又转回到自己的手指上去,显然,对他来说房间里只有这才是真正值得自己注意的焦点。“我认得你姐姐,” 他毫无热情地说。“他妈的势利鬼一个。”
吉尼像只猫似的拱起了自己的背。“你说谁是势利鬼?”
“你听得清清楚楚的。”
“她不是势利鬼!”
“她不是才怪呢。她是大王。是势利鬼堆里的大势利鬼。”
吉尼看着他抬起手指朝好几层手纸底下的伤口窥去。
“你连我的姐姐都不认识。”
“我怎么不认识。”
“她叫什么名字? 前面那个叫什么?” 吉尼问道。
“琼呗…… 大琼势利鬼。”
吉尼不吭声了。“她长得什么模样?” 突然,她又问道。
没有回答。
“她长得什么模样啊?” 吉尼重复了一句。
“要是她长得有自己以为一半的那么好看,那就算是撞上大运了,” 塞利纳的哥哥说。
吉尼暗自觉得,这样的回答倒挺有趣,有点水平。“我可从没听她提到过你嘛,” 她说。
“这就让我太担心了。这可让我担心得活不成了呢。”
“再说,她反正也订了婚了,” 吉尼说,盯看着他。“她下个月就要结婚了。”
“跟谁?” 他问,头抬了起来。
吉尼充分利用他抬起了头的这个机会。“反正不是你认得的什么人。”
他又重新去拨弄自己的急救措施。“我可怜他,” 他说。
吉尼嗤之以鼻。
“血仍然流得很厉害呢。你看我是不是该上点药? 上什么药好? 红药水行吗?”
“碘酒更好一些,” 吉尼说。接着,觉得自己的回答在这样的情况下来免太客气,又加了一句。“对那样的刀伤红药水根本不起作用。”
“为 ¨ 么不? 道理何在?”
“对那样的伤一点用也没有,反正就是没用。你得用碘酒。”
他看着吉尼。“不过上碘酒可疼哟,是不是?” 他问。“疼得让人受不了吧?”
“疼是疼,” 吉尼说,“可是总不至于让你疼得死过去什么的吧。”
塞利纳的哥哥显然对吉尼的口气根本不在意。他的注意力又转回到自己的手指上去。“疼我可不喜欢,” 他说。
“没人喜欢疼。”
他点点头表示同意。“是啊,” 他说。
吉尼看着他有一分钟。“别碰它了,” 她突然说。
就像受到电击似的,塞利纳的哥哥猛地缩回他那只未受伤的手。他稍稍坐直了些——或者不如说,身子稍往下缩了一些。他望着房间另一端的一件什么东西。那张邋里邋遢的脸上出现一种几乎是梦幻般的神情。他用那只未受伤食指的指甲去剔门牙缝,剔出了一粒食屑,他转向吉尼。“恰嘎啦?” 他问。
“什么?”
“问你吃过午饭了吗?”
吉尼摇摇头。“我回家再吃,” 她说。“我回到家妈妈总给我准备好午饭的。”
“我房间里还有半块鸡肉三明治。你要吃吗? 我可一点儿也没碰过。”
“不要,谢谢你。真的。”
“你刚打过网球,这绝对错不了,你就不饿?”
“倒不是那么回事,” 吉尼说,又叉起了她的双腿。“只不过我回到家我妈妈总是把午饭准备好了。我的意思是,如果我吃不下她会发脾气的。”
塞利纳的哥哥像是接受了这个解释。至少,他点了点头,目光转了开去。可是突然他又扭过头来。“来杯牛奶怎么样?” 他说。
“不了,谢谢…“不管怎么说,还是谢谢你。”
他心不在焉地弯下腰去,挠了挠没穿袜子的脚踝。“她要嫁的那家伙叫什么来着?” 他问。
“你是说琼吧?” 吉尼说。“叫迪克 • 赫夫纳。”
塞利纳的哥哥仍然在挠他的脚踝。
“他是悔军的一个少校,” 吉尼说。
“大买卖嘛。”
吉尼格格地笑了。她看着他把脚踝都挠红了。到他开始用指甲把腿肚子上裂开的一小片皮刮下来时,她不再看了。
“你在哪儿认识琼的?” 她问。“我在家里和别处都从没见到过你嘛。”
“压根儿就没去过你们那个鬼家。”
吉尼等着,可是这句话之后就再没下文了。“那你是在哪儿遇到她的呢?” 她问。
“在聚会上。” 他说。
“在一次聚会上? 什么时候?”
“我可说不清了。是 1942 年的圣诞节吧。”他用两根手指从睡衣胸前口袋里夹出一根香烟,看去像是睡觉时被压过的。“把那边的火柴扔给我行不行?”他说。吉尼把身边桌子上的~小盒火柴递给他。他连弯曲的香烟都不捏捏直便将它点燃,接着又把用过的那根火柴放回到小盒里去。他头往后一仰,慢慢地从嘴里吐出一大口烟,然后又把烟吸回到鼻孔里去。他继续以这种 “法国式吸入法” 抽烟。非常可能,这不是靠在沙发上显示的某种特技表演,而是一个在某段时问里没准曾试着用左手刮胡子的青年人那种想让人知道他个人能达成什么成就的炫耀。
“为什么琼是势利鬼?”
“为什么? 因为她就是。我他妈的怎么会知道为什么?”
“得,不过我问的是你为什么说她是?”
他有气无力地转向她。“听着。我他妈的给她写过八封信。八封呢。她连一封也没有回。”
吉尼迟疑了一下。“呃,说不定她那会儿正忙。”
“是啊。忙。忙得他蚂的像一只海狸。”
“你说话非得带那么多脏话不行吗?” 吉尼问道。
“我他妈的就是非说不可。”
吉尼格格地笑了。“说实在的,你认识她有多久啦?” 她问。
“时间够长的。”
“哎,我的意思是你给她打过电话什么的吗? 我的意思是你打过电话什么的没有?”
“那倒没有。”
“嗨,我的天。如果你从来没给她打过电话什么的——”
“我没法打,老天在上!”
“干吗没法?” 吉尼说。
“那会儿不在纽约。”
“噢! 那你在哪儿?”
“我吗? 在俄亥俄。”
“噢,是上大学吗?”
“不是。退学了。”
“噢,那你在部队里?”
“不是。” 塞利纳的哥哥用捏着香烟的手敲击左胸。“这滴答响的玩意儿不行,” 他说。
“你的心脏,你是说?” 青尼说。“它怎么啦?”
“我也说不上来它他妈的有什么问题。我小时候得过风湿热。这儿他妈的疼——”
“那么,你是不是不应该抽烟? 我是说你是不是该戒烟什么的? 医生告诉过我的”
“哎呀,他们就会说别这别那,” 他说。
吉尼控制住了自己。但只忍住很短的瞬间。“你在俄亥俄干什么来着?” 地问。
“我吗? 在一家该死的飞机工厂里干活。”
“你干过?” 吉尼说。“你喜欢那恬儿吗?”
“‘你喜欢那活儿吗?’” 他模仿地说。“我喜欢。我特爱飞机。它们是那么的精巧绝伦。”
吉尼此刻已经过于投入,以致都没觉出他是在说反话。“你在那儿干了多久? 在哪家飞机厂?”
“我说不上来,老天在上。三十七个月吧。” 他站起来朝窗口走去。他朝底下的街道看去,一边用大拇指蹭刮自己的脊背。“瞧瞧他们,” 他说。“十是的大傻瓜。”
“谁?” 吉尼说。
“我说不上来。个个都是。”
“如果你让手指这么往下垂,它又要开始流血了,” 吉尼说。
他听从了她的话。他把自己的左脚放到窗座上,把受伤的那只手搁在横着的大腿上。他继续朝下面街道看去。“这些人全都是上他妈的征兵局去的,” 他说。“我们挨下来就要跟爱斯基摩人开战了。知道不?”
“跟谁?” 吉尼说。
“爱斯基摩人…~竖起你的耳朵行不行,老天爷呀。”
“为什么跟爱斯基摩人?”
“为什么我可说不上来。我他妈的怎么会知道? 这一回所有的老家伙都得上战场了。六十上下的老家伙。除了六十上下的,别人都去不了,” 他说。“理由就是让老家伙早点儿死。…? 这笔买卖大赚了。”
“你反正是不用去的了,” 吉尼说,她也没什么用意只不过是说句实话罢了,可是话还没说完她就明白自己说了句不合适的话。
“我知道,” 他急急地说,一面把脚从窗座上放下来。他把窗子抬起一条缝,将烟屁股朝街上弹去。接着他转身,但转到窗前就停住了。“嗨,帮我个忙。那家伙来了,你能不能告诉他我一会儿就好。我最要紧的是得刮刮脸。行吗?”
吉尼点点头。
“你要我催催塞利纳还是怎么着? 她知道你在这儿的吧?”
“哦,她知道我在这儿,” 吉尼说。“我不急。谢谢你。”
塞利纳的哥哥点了点头,接着他朝他受伤的手指最后一次地看了许久,仿佛要研究伤口情况能不能允许他回自己房间去。
“你为什么不用护创胶布贴一下呢? 你就没有胶布这类东西吗?”
“是没有,” 他说,“哎,不要紧的。” 他晃晃悠悠地走出房间。
过了几秒钟,他又回来了,带着那半块三明治。
“吃了吧,” 他说。“味道不错的。”
“真的,我一点也不——”
“拿着,老天爷。我又没有投毒什么的。”
吉尼接过那半块三明治。“那好,太谢谢你了,” 她说。
“是鸡肉的,” 他说,站在她身边瞅着她。“是昨儿晚上在一家鬼样的熟食店买的。”
“看上去不错。”
“那好,吃了吧。”
吉尼咬了一口。
“是不错吧,嗯?”
吉尼费劲地咽下去。“非常好,” 她说。
塞利纳的哥哥点点头。他心不在焉地扫视房内,挠了挠胸口凹陷处。“嗯,我咂摸我也得去穿衣服了…… 天哪! 门铃响了。不过你不用慌!” 说完他不见了。
剩下她一个人,吉尼没有站起来,她环顾四周,找个合适的地方扔掉或是藏起那块三明治。她听到有人穿过门厅走来。她把三明治往自己运动外套口袋里一塞。
一个年轻男子,三十刚出头,不高也不矮,走进房间。他面容没什么特点,头发留得短短的,西服样式、领带花纹也都很普通,让人看不出他的真实身份。他没准是一家新闻杂志社的工作人员,或是正打算去那儿谋职,他可能是个刚从费城的一场戏演出归来。他也可能是一家律师事务所里的人。
“你好,” 他亲切地对吉尼说。
“你好。”
“看到富兰克林了吗?” 他问。
“他在刮脸呢。他告诉我请你等一会儿。他马上就出来。”
“刮脸。老天。” 年轻人看了看自己的手表。接着他在一张大红缎子面的椅子上坐下来,跷起腿,用双手掩住脸。仿佛他一直很疲倦,或是刚干完一件很费眼力的工作,他用伸直的手指尖揉揉合上的双目。“这真是我整整一生中最最倒霉的一个上午了,” 他说,… 边把手从脸上挪开。他说话时光用喉头那口气发声,好像他真是精疲力竭,连横膈膜都动不了了。
“出什么事啦?” 吉尼问,朝他看去。
“哦…… 说来话长了。不是我认识至少上千年的朋友,我是从来小拿自己的不顺心事让他们感到厌烦的。” 他目光蒙胧,充满失落感地朝窗口那边望去。“不过,我今后再也不认为自己对人性有任何最最细微的判断力了。我这话你可以随意引用。”
“出了什么事啦?” 吉尼重又问了一遍。
“哦,天哪。跟我同住一套公寓房间已有那么多月那么多月那么多月的那个人一我甚至都不想提起他…… 这个作家,” 他得意地添上一句,也许是记起了海明威一部小说里的一个人所共知的坏透了的人物形象。
“他干了什么啦?”
“坦白地说,我宁愿不立刻进人细节描述,” 那年轻人说,他从自己的烟盒里取出一根烟,没去理会桌子上的那个透明的保湿烟罐,并且用自己的打火机点燃。他那双手挺大,看上去既不强有力也不灵括敏感。但是他使用双手时就仿佛它们本身就具有某种小易控制的艺术冲动力似的。“我已经下定决心连想都不去想这件事了。可是我实在是太气愤了,” 他说。“我是说从宾夕法尼亚州阿尔吐纳一或是某个这样的小地方,冒出来这么一个卑鄙小人。明摆着他都快要饿死了。我够好心仁义的——我十足是个好撒玛利亚人哪——竟把他收容进我的套间,这个绝对缩微的小套间连我自己在里面都几乎转不了身。我把他介绍给我所有的朋友,让他把他那些讨厌的稿纸、香烟屁股、生萝卜以及别的乱七八糟的东西塞满了整个套间。介绍他认识纽约的每一个戏剧界老板。到洗衣店去取送他那些肮脏的衬衣。这些都还不算——” 年轻人打住了话头。“可是我全部的好心好意和高尚行为,” 他又继续往下说了,“换来的却是他今天一清早五六点钟时的不辞而别——连张字条都没留下——带走了他那双下流肮脏的手够得着的所有东西。” 他停下话头,懒洋洋地继续抽烟,并从嘴里吐出一股淡淡的带咝咝声音的烟。“我不想说这件事儿。我真的不想。” 他朝吉尼身上看过来。“我喜欢你的外衣,” 他说,已经从他椅子里站起身了。他走过来,把吉尼轻便大衣的翻领捏在自己几根手指之问。“这真可爱。这是战后我第一次见到的真正好驼绒。我能问问你是在哪儿买的吗?”
“我妈妈从拿骚带回来的。”
年轻人若有所思地点点头,退回到他椅子那边。“那可是能买到真正好驼绒的为数不多的地方之一。” 他坐了下来。“她在那儿呆的时间长吗?”
“什么?” 吉尼说。
“你母亲在那儿呆的时间长不长? 我问你是因为我妈妈 12 月也在那儿,还有 1 月的上旬。我通常都是跟她一块儿去的,不过这一年里事情很乱我根本抽不开身。”
“我妈妈是 2 月份去的,” 吉尼说。
“太好了。她住在什么地方? 你知道吗?”
“和我姨住在一起。”
他点了点头。“我能问你叫什么名字吗? 我猜你是富兰克林妹妹的朋友吧?”
“我们是同一班的,” 吉尼说,只回答了他的第二个问题。
“你不是塞利纳常提到的那位大名鼎鼎的马克辛吧?”
“不是的,” 吉尼说。
那年轻人突然开始用手掌去擦拭他的裤腿口。“我浑身上下都是狗毛,” 他说。“母亲去华盛顿度周末,把她的赖狗撂在我的公寓里了。那倒是条蛮有趣的狗,可是那些臭毛病真要不得。你有狗吗?”
“没有。”
“老实说,我认为把它们圈在城里是件残忍的事。” 他不再拂拭了,往后靠着坐好,再次看了看他的手表。“我从来没听说这家伙哪次准时过。我们要去看科克托的《美女与野兽》,看这部电影你可真的得准时。我是说如果你去晚了那整个魅力就全没了。你看过了吗?”
“没有。”
“噢,你可一定得看! 我都看了八遍了。那可是纯粹的天才之作呀,” 他说。“几个月以米,我一直在想方设法动员富兰克林去看。” 他绝望地摇了摇头。“他的趣味呀。战争期间,我们俩在同一个鬼地方干活,那孩子硬要拖我去看世界上最最糟糕的影片。我们看了警匪片、西部片、音乐喜剧片——”
“你也在飞机厂干过活吗?” 吉尼问道。
“老天在上,正是这样。干了一年一年又一年。咱们不谈这个了,好吗?”
“你也是心脏不好?”
“上帝保佑,没有什么不好。咱们敲敲木头吧。” 他两次敲击了椅子的扶手。“我的体质可是”
塞利纳走进房间时,吉尼快快地站起身来迎上前去。塞利纳已经把短裤换成了一条裙子。在一般情况下,这样的事会使吉尼很不愉快的。
“真对不起,让你久等了,” 塞利纳言不由衷地说,“但我必须等我母亲醒过来…… 你好,埃里克。”
“你好,你好!”
“这钱我还是不收算了,” 吉尼说,把嗓子压得低低的只让塞利纳一人能听见。
“什么?”
“我方才想了。我的意思是,每回球都是你出的,我把这事儿给忘了。”
“可是你方才说因为我这些球不用花钱买——”
“送我到门口去吧,” 吉尼说,自己先走在头里,也没跟埃里克说声再见。
“可是我记得你说过,你今晚要去看电影所以需要这笔钱什么的嘛!” 塞利纳在门厅里说。
“我太累了,” 吉尼说。她弯下腰去捡起她的打网球的用具。“听着。晚饭后我会给你打个电话。今天晚上你没什么特别的事吧? 说不定我能上你这儿来。”
塞利纳瞪大了眼睛,说了句,“好吧。”
吉尼推开大门.走向电梯。她按了电梯铃。“我方才见到你哥哥了,” 她蜕。
“你见到啦? 他有点儿怪吧?”
“对了,他是干什么工作的?” 古尼随便问道。“他工作了呢还是在做别的事儿?”
“他刚退下来。爸爸要他重新念大学,可是他不愿意去。”
“为什么不愿意?”
“我可不知道,他说他年纪太大了什么的。”
“他有多大?”
“我也说不清楚。二十四吧。”
电梯门开了。“呆会儿我给你打电话!” 吉尼说。
出了楼,她往西走,到莱克星顿街去乘公共汽车。走在第三大街和莱克星顿街之间,她伸手到外衣口袋里去掏钱包,却摸到了那半块三明治。她把它拿出来,把手往下垂,想把三明治扔在街上。但是,她还是放回到兜里。几年前,她足足用了三天,才把在废纸篓锯木屑上发现的一只复活节死小鸡处理掉。
卡夫卡和K-余华
========================
卡夫卡和K-[[余华]]
------
《城堡》中的土地测量员K在厚厚的积雪中走来,皑皑白雪又覆盖了他的脚印,是否暗示了这是一次没有回去的走来?因为K仿佛是走进了没有谜底的命运之谜。贺拉斯说:“无论风暴将我带到什么岸边,我都将以主人的身份上岸。”卡夫卡接着说:“无论我转向何方,总有黑浪迎面打来。”弥漫在西方文学传统里的失落和失败的情绪感染着漫长的岁月,多少年过去了,风暴又将K带到了这里,K获得了上岸的权利,可是他无法获得主人的身份。
在有关[[卡夫卡]]作品的论说和诠释里,有一个声音格外响亮,那就是谁是卡夫卡的先驱?对卡夫卡的榜样的寻找凝聚了几代人的不懈努力,[[瓦尔特·本雅明]]寻找了一个俄国侯爵波将金的故事,博尔赫斯寻找了芝诺的否定运动的悖论。人们乐此不疲的理由是什么?似乎没有一个作家会像卡夫卡那样令人疑惑,我的意思是说:在卡夫卡这里人们无法获得其他作家所共有的品质,就是无法找到文学里清晰可见的继承关系。当[[《城堡》]]中的弗丽达意识到K其实像一个孩子一样坦率时,可是仍然很难相信他的话,因为──弗丽达的理由是“你的个性跟我们截然不同”。瓦尔特·本雅明和博尔赫斯也对卡夫卡说出了类似的话。
同时,这也是文学要对卡夫卡说的话。显然,卡夫卡没有诞生在文学生生不息的长河之中,他的出现不是因为后面的波浪在推动,他像一个岸边的行走者逆水而来。很多迹象都在表明,卡夫卡是从外面走进了我们的文学。于是他的身份就像是《城堡》里K的身份那样尴尬,他们都是唐突的外来者。K是不是一个土地测量员?《城堡》的读者会发出这样的疑问。同样的疑问也在卡夫卡生前出现,这个形象瘦削到使人感到尖锐的犹太人究竟是谁?他的作品是那样的陌生,他在表达希望和绝望、欢乐和痛苦、爱和恨的时候都是同样的令人感到陌生。这样的疑惑在卡夫卡死后仍然经久不息,波将金和芝诺的例子表明:人们已经开始到文学之外去寻找卡夫卡作品的来源。
这是明智的选择。只要读一读卡夫卡的日记,就不难发现生活中的卡夫卡,其实就是《城堡》中的K。他在1931年8月15日的日记中,用坚定的语气写道:“我将不顾一切地与所有人隔绝,与所有人敌对,不同任何人讲话。”在六天以后的日记里,他这样写:“现在我在我的家庭里,在那些最好的、最亲爱的人们中间,比一个陌生人还要陌生。近年来我和我的母亲平均每天说不上二十句话,和我的父亲除了有时彼此寒暄几句几乎就没有更多的话可说。和我已婚的妹妹和妹夫们除了跟他们生气我压根儿就不说话。”
人们也许以为写下这样日记的人正在经历着可怕的孤独,不过读完下面的两则日记后,可能会改变想法。他在1910年11月2日的日记中写道:“今天早晨许久以来第一次尝到了想象一把刀在我心中转动的快乐。”另一则是两年以后,他再一次在日记中提到了刀子。“不停地想象着一把宽阔的熏肉切刀,它极迅速地以机械的均匀从一边切入我体内,切出很薄的片,它们在迅速的切削动作中几乎呈卷状一片片飞出去。”
第一则日记里对刀的描绘被后面“快乐”的动词抽象了,第二则日记不同,里面的词语将一串清晰的事实连接了起来,“宽阔的熏肉切刀”、“切入我体内”、而且“切出很薄的片”,卡夫卡的描叙是如此的细致和精确,最后“呈卷状一片片飞出去”时又充满了美感。这两则日记都是在想象中展示了暴力,而且这样的暴力都是针对自我。卡夫卡让句子完成了一个自我凌迟的过程,然后他又给予自我难以言传的快乐。这是否显示了卡夫卡在面对自我时没有动用自己的身份?或者说他就是在自我这里,仍然是一个外来者?我的答案是卡夫卡一生所经历的不是可怕的孤独,而是一个外来者的尴尬。这是更为深远的孤独,他不仅和这个世界和所有的人格格不入,同时他也和自己格格不入。他在1914年1月8日的日记中吐露了这样的尴尬,他写道:“我与犹太人有什么共同之处?我几乎与自己都没有共同之处。”他的日记暗示了与众不同的人生,或者说他始终以外来者的身份行走在自己的人生之路上,四十一年的岁月似乎是别人的岁月。
可以这么说,生活中的卡夫卡就像《城堡》里的K一样,他们都没有获得主人的身份,他们一生都在充当着外乡人的角色。共同的命运使这两个人获得了一致的绝望,当K感到世界上已经没有一处安静的地方能够让他和弗丽达生活下去时,他就对自己昙花一现的未婚妻说:“我希望有那么一座又深又窄的坟墓,在那里我们俩紧紧搂抱着,像用铁条缚在一起那样。”对K来说,世界上唯一可靠的安身之处是坟墓;而世界上真正的道路对卡夫卡来说是在一根绳索上,他在笔记里写道:“它不是绷紧在高处,而是贴近地面。它与其说是供人行走不如说是用来绊人的。”
人们的习惯是将日记的写作视为情感和思想的真实流露,在卡夫卡这里却很难区分出日记写作和小说写作的不同,他说:“读日记使我激动。”然后他加上着重号继续说:“一切在我看来皆属虚构。”在这一点上,卡夫卡和他的读者能够意见一致。卡夫卡的日记很像是一些互相失去了联络的小说片段,而他的小说《城堡》则像是K的漫长到无法结束的日记。
应该说,卡夫卡洁身自好的外来者身份恰恰帮助了他,使他能够真正切入到现存制度的每一个环节之中。在《城堡》和其他一些作品中,人们看到了一个巨大的官僚机器被居民的体验完整地建立了起来。我要说的并不是这个官僚机器展示了居民的体验,而是后者展示了前者。这是卡夫卡叙述的实质,他对水珠的关注是为了让全部的海水自动呈现出来。在这一点上,无论是卡夫卡同时代的作家,还是后来的作家,对他们自身所处的社会制度的了解,都很难达到卡夫卡的透彻和深入。就像是《城堡》所显示的那样,对其官僚机构和制度有着强烈感受的人不是那里的居民,而是一个外来者──K。《城堡》做出了这样的解释:那些在已有制度里出生并且成长起来的村民,制度的一切不合理性恰恰构成了它的合理。面对这至高无上的权威,村民以麻木的方式保持着他们世代相传的恐惧和世代相传的小心翼翼。而K的来到,使其制度的不合理性得到了呈现。外来者K就像是一把熏肉切刀,切入到城堡看起来严密其实漏洞百出的制度之中,而且切出了很薄的片,最后让它们一片片呈卷状飞了出去。
在卡夫卡的眼中,这一把熏肉切刀的锋刃似乎就是性,或者说在《城堡》里凡是涉及到性的段落都会同时指出叙述中两个方向,一个是权威的深不可测,另一个是村民的麻木不仁。
关于权威的深不可测,我想在此引用瓦尔特·本雅明的话,本雅明说:“这个权威即使对于那些官僚来说也在云里雾里,对于那些它们要对付的人们来说就更加模糊不清了。”当卡夫卡让他的代言人K在积雪和夜色中来到村子之后,在肮脏破旧的客栈里,K拿起了电话──电话是村民也是K和城堡联系的象征,确切地说是接近那个权威的象征,而且所能接近的也只是权威的边缘。当K拿起电话以后,他听到了无数的声音,K的疑惑一直到与村长的交谈之后才得以澄清,也就是说当一部电话被接通后,城堡以及周围村子所有的电话也同时被接通,因此谁也无法保证K在电话中得到的声音是否来自于城堡。由此可见,城堡的权威是在一连串错误中建立起来的,而且不断发生的新的错误又在不断地巩固这样的权威。当K和村长冗长的谈话结束后,这一点得到了进一步的证实。尽管村长的家是整个官僚制度里最低等的办公室,然而它却是唯一允许K可以进入的。当村长的妻子和K的两个助手翻箱倒柜地寻找有关K的文件时,官僚制度里司空见惯的场景应运而生,阴暗的房间、杂乱的文件柜和散发着霉味的文件。因此,K在这里得到的命运只不过是电话的重复。而对于来自城堡的权威,村长其实和K一样的模糊不清。在《城堡》的叙述里,不仅是那位端坐在权威顶峰的伯爵先生显得虚无缥缈,就是那个官位可能并不很高的克拉姆先生也仿佛是生活在传说中。K锲而不舍的努力,最终所得到的只是与克拉姆的乡村秘书进行一次短暂的谈话。因此,村长唯一能够明确告诉K的,就是他们并不需要一个土地测量员。村长认为K的来到是一次误会,他说:“像在伯爵大人这样庞大的政府机关里,可能偶然发生这一个部门制定这件事,另一部门制定那件事,而互相不了解对方的情况……因此就常常会出现一些细小的差错。”作为官僚机构中的一员,村长有责任维护官僚制度里出现的所有错误,他不能把K送走,因为“这是另外一个问题”,他所能做的无非是将错就错,给K安排了一个完全是多余的职位── 学校的看门人。
关于村民的麻木不仁,我想说的就是卡夫卡作品中将那个巨大的官僚机器建立起来的居民的体验,这样的体验里充满了居民的敬畏、恐惧和他们悲惨的命运,叙述中性的段落又将这样的体验推向了高潮。弗丽达、客栈老板娘和阿玛丽亚的经历,在卡夫卡看来似乎是磨刀石的经历,她们的存在使权威之剑变得更加锋利和神秘。克拉姆和索尔蒂尼这些来自城堡的老爷,这些《城堡》中权力的象征,便是叙述里不断闪烁的刀光剑影。
人老珠黄的客栈老板娘对年轻时代的回忆,似乎集中了村民对城堡权威的共同体验。这个曾经被克拉姆征召过三次的女人,与克拉姆三次同床的经历构成了她一生的自我荣耀,也成为了她的丈夫热爱她和惧怕她的唯一理由。这一对夫妇直到晚年,仍然会彻夜未眠地讨论着克拉姆为什么没有第四次征召她,这几乎就是他们家庭生活的唯一乐趣。弗丽达是另外一个形象,这是一个随心所欲的形象。她的随心所欲是因为曾经是克拉姆的情妇,这样的地位是村里的女人们梦寐以求的,可是她轻易地放弃了,这是她性格里随心所欲的结果,她极其短暂并且莫名其妙地爱上了K,然后她以同样的莫名其妙又爱上了K的助手杰里米亚。在卡夫卡眼中,弗丽达代表了另一类的体验,有关性和权力的神秘体验,也就是命运的体验,她性格的不确定似乎就是命运的不确定。这个曾经有着无穷的生气和毅力的弗丽达,和K短短地生活了几天后,她的美丽就消失了。卡夫卡的锋利之笔再次指向了权力:“她形容憔悴是不是真的因为离开了克拉姆?她的不可思议的诱惑力是因为她亲近了克拉姆才有的,而吸引K的又正是这种诱惑力。”尽管弗丽达和K与客栈老板夫妇绝然不同,可是他们最终殊途同归。卡夫卡让《城堡》给予了我们一个刻薄的事实:女人的美丽是因为亲近了权力,她们对男人真正的吸引是因为她们身上有着权力的幻影。弗丽达离开了克拉姆之后,她的命运也就无从选择,“现在她在他的怀抱里枯萎了”。
阿玛丽亚的形象就是命运中悲剧的形象。在客栈老板娘和弗丽达顺从了权力之后,卡夫卡指出了道路的另一端,也就是阿玛丽亚的方向。顺着卡夫卡的手指,人们会看到一个拒绝了权力的身影如何变得破碎不堪。
事实上在卡夫卡笔下,阿玛丽亚和村里其他姑娘没有不同,也就是说她在内心深处对来自城堡的权力其实有着难以言传的向往,当象征着城堡权威的索尔蒂尼一眼看中她以后,她的脸上同样出现了恋爱的神色。她的悲剧是因为内心里还残留着羞耻感和自尊,当索尔蒂尼派人送来那张征召她的纸条时,上面粗野和下流的词汇突然激怒了她。这是卡夫卡洞察人心的描述,一张小小的纸条改变了阿玛丽亚和她一家人的命运,阿玛丽亚撕碎纸条的唯一理由就是上面没有爱的词句,全是赤裸裸的关于交媾的污言秽语。然后,叙述中有关权力的体验在阿玛丽亚一家人无休止的悲惨中展开,比起客栈老板娘和弗丽达顺从的体验,阿玛丽亚反抗之后的体验使城堡的权威显得更加可怕,同时也显得更加虚幻。
也许索尔蒂尼并没有把这事放在心上,对于那些来自城堡的老爷,他们床上的女人层出不穷。问题是出在村民的体验里,一旦得知阿玛丽亚拒绝了城堡里的老爷,所有的村民都开始拒绝阿玛丽亚一家。于是命运变得狰狞可怕了,她的父亲曾经是村里显赫的人物,可是这位出色的制鞋匠再也找不到生意了,曾经是他手下伙计的勃伦斯威克,在他们一家的衰落里脱颖而出,反而成为了他们的主子。两位年轻的姑娘奥尔珈和阿玛丽亚必须去承受所有人的歧视,她们的兄弟巴纳巴斯也在劫难逃。
在卡夫卡的叙述里,悲惨的遭遇一旦开始,就会一往无前。这一家人日日夜夜讨论着自己的命运,寻找着残存的希望。他们的讨论就像客栈老板夫妇的讨论那样无休无止,不同的是前者深陷在悲剧里,后者却是为了品尝回忆的荣耀。为了得到向索尔蒂尼道歉的机会,他们的父亲在冰雪里坐了一天又一天,守候着城堡里出来的老爷,直到他身体瘫痪为止;出于同样的理由,奥尔珈将自己的肉体供给那些城堡老爷的侍卫们肆意蹂躏。巴纳巴斯曾经带来过一线希望,他无意中利用了官僚制度里的漏洞,混进城堡成为了一名模棱两可的信使。然而他们所做的一切丝毫没有阻止命运在悲剧里前进的步伐,他们的努力只是为了在绝望里虚构出一线希望。卡夫卡告诉我们:权威是无法接近的,即便是向它道歉也无济于事。索尔蒂尼对于阿玛丽亚一家来说,就像城堡对于K一样,他们的存在并不是他们曾经出现过,而是因为自身有着挥之不去的恐惧和不安。
卡夫卡的叙述如同深渊的召唤,使阿玛丽亚一家的悲剧显得深不见底,哪怕叙述结束后,她们的悲剧仍然无法结束。这正是卡夫卡为什么会令人不安和战栗的原因。阿玛丽亚和她家庭悲惨的形象,是通过奥尔珈向K的讲述呈现出来的,这个震撼人心的章节在《城堡》的叙述里仿佛是节外生枝,它使《城堡》一直平衡均匀的叙述破碎了,如同阿玛丽亚破碎的命运。人的命运和叙述同时破碎,卡夫卡由此建立了叙述的高潮。其他作家都是叙述逐渐圆润后出现高潮的段落,卡夫卡恰恰相反。在这破碎的章节里,卡夫卡将权威的深不可测和村民的麻木不仁凝聚到了一起,或者说将性的体验和权力的体验凝聚到了一起。
有一个事实值得关注,那就是卡夫卡和性的关系影响了《城堡》中K的性生活。在卡夫卡留下的日记、书信和笔记里,人们很难找到一个在性生活上矫健的身影;与此相对应的叙述作品也同样如此,偶尔涉及到的性的段落也都是草草收场。这位三次订婚又在婚礼前取消了婚约的作家给人留下了软弱可欺的印象,而且他的三次订婚里有两次是和同一位姑娘。他和一位有夫之妇密伦娜的通信,使他有过短暂的狂热,这样的狂热使他几次提出了约会的非分之想,每一次都得到了密伦娜泼来的一盆凉水,这位夫人总是果断地回答:不行!因此,当有人怀疑卡夫卡一生中是否有过健康有力的性经历时,我感到这样的怀疑不会是空穴来风。退后一步说,即便卡夫卡的个人隐私无从证实,他在性方面的弱者的形象也很难改变。确切地说,卡夫卡性的经历很像他的人生经历,或者说很像K的经历;真正的性,或者说是卡夫卡向往中的性,对于他就像是城堡对于K一样,似乎永远是可望而不可即。
他在给密伦娜夫人的信中似乎暗示了他有这方面的要求,而在他其他的书信和日记里连这样的迹象都没有。他只是在笔记里写下了一句令人不知所措的话:“它犹如与女人们进行的、在床上结束的斗争。”没有人知道这样的比喻针对什么,人们可以体验到的是这句话所涉及到的性的范围里没有爱的成分,将性支撑起来的欲望是由斗争组建的。另一个例子是K的经历,这位城堡的不速之客在第一夜就尝到了性的果子。在那个阴暗的章节里,卡夫卡不作任何铺垫的叙述,使弗丽达成为了K的不速之客。这一切发生的是如此的突然,当人们还在猜测着K是否能够获得与象征着权力的克拉姆见面的机会时,克拉姆的情人弗丽达娇小的身子已经在K的手里燃烧了。“他们在地上滚了没有多远,砰的一声滚到了克拉姆的房门前,他们就躺在这儿,在积着残酒的坑坑洼洼和扔在地板上的垃圾中间。”然后,卡夫卡写道:“他们两个人像一个人似的呼吸着,两颗心像一颗心一样的跳动着。”这似乎是性交正在进行时的体验;接下去的段落似乎预示着高潮来临时的体验:“K只觉得自己迷失了路,或者进入了一个奇异的国度,比人类曾经到过的任何国度都远,这个国度是那么奇异,甚至连空气都跟他故乡的大不相同,在这儿,一个人可能因为受不了这种奇异而死去,可是这种奇异又是那么富于魅力,使你只能继续向前走,让自己越陷越深。”
与卡夫卡那一段笔记十分近似,上述段落里K对性的体验没有肉体的欲望;不同的是K和弗丽达的经历不是床上的斗争,卡夫卡给予了他们两人以同一个人的和谐,当然这是缺乏了性欲的和谐,奇怪的是这样的和谐里有着虚幻的美妙,或者说上述段落的描写展示了想象中的性过程,而不是事实上的性过程。卡夫卡纯洁的叙述充满了孩子般的对性的憧憬,仿佛是一个没有这样经历的人的种种猜测。当卡夫卡将其最后的体验比喻成一个奇异的国度,一个比人类曾经到过的任何国度都要远的国度时,卡夫卡内心深处由来已久的尴尬也就如日出般升起,他和K的外乡人的身份显露了出来。“连空气都跟他故乡的大不相同”,于是K和弗丽达的性高潮成为了忧郁的漂泊之旅。
是否可以这么说,就是在自身的性的经历里,卡夫卡仍然没有获得主人的身份。如果这一点能够确认,就不难理解在《城堡》的叙述里,为什么性的出现总是和权力纠缠到一起。我的意思是说卡夫卡比任何人都更为深刻地了解到性在社会生活中可以无限延伸。就像是一个失去了双腿的人会获得更多的凝视的权利,卡夫卡和性之间的陌生造成了紧张的对峙,从而培养了他对其长时间注视的习惯,这样的注视已经超越了人们可以忍受的限度,并且超越了一个时代可以忍受的限度。在这样的注视里,他冷静和深入地看到了性和官僚机器中的权力如何合二为一,“两颗心像一颗心一样跳动着”。因此在《城堡》的叙述里,同时指出权力深不可测和村民麻木不仁的,就是性的路标。
最后我要说的是,究竟是一个什么样的内心造就了卡夫卡的写作?我的感受是他的日记比他的叙述作品更能说明这一点。他在1922年1月16日的日记中写道:“两个时钟走得不一致。内心的那个时钟发疯似的,或者说着魔似的或者说无论如何以一种非人的方式猛跑着,外部的那个则慢吞吞地以平常的速度走着。除了两个不同世界的互相分裂之外,还能有什么呢?而这两个世界是以一种可怕的方式分裂着,或者至少在互相撕裂着。”卡夫卡的一生经历了什么?日记的回答是他在互相撕裂中经历了自己的一生。这有助于我们理解阿玛丽亚一家的命运为什么在破碎后还将不断地破碎下去,也使我们意识到这位与人们格格不入的作家为什么会如此陌生。
内心的不安和阅读的不知所措困扰着人们,在卡夫卡的作品中,没有人们已经习惯的文学出路,或者说其他的出路也没有,人们只能留下来,尽管这地方根本不是天堂,而且更像是地狱,人们仍然要留下来。就像那个永远无法进入城堡的K一样,悲哀和不断受到伤害的K仍然要说:“我不能离开这里。我来到这儿,是想在这儿待下来的。我得在这儿待着。”K只能待在城堡的边缘,同样的命运也属于卡夫卡和《城堡》的读者,这些留下来的读者其实也只是待在可以看见城堡的村庄里,卡夫卡叙述的核心就像城堡拒绝K一样拒绝着他们。城堡象征性的存在成为了卡夫卡叙述的不解之谜,正是这样的神秘之谜召唤着人们,这似乎是地狱的召唤,而且是永远无法走近的召唤。然后令人不安的事出现了,卡夫卡和K这两个没有主人身份的外来者,也使走进他们世界的读者成为了外来者。K对自己说:“究竟是什么东西引诱我到这个荒凉的地方来的呢,难道就只是为了想在这儿待下来吗?”被卡夫卡和K剥夺了主人身份的读者,也会这样自言自语。
一九九九年八月三十日
开卷如开芝麻门-余光中
========================
开卷如开芝麻门-[[余光中]]
-----
「人生识字忧患始,姓名麤[^1]记可以休。」项羽这种英雄人物,当然不喜欢读书。刘邦也不喜欢读书,甚至也不喜欢读书人。不过刘邦会用读书人,项羽有范增而不会用,汉胜楚败,这也是一个原因。苏轼这两句诗倒也不尽是戏言,因为一个人把书读认真了,就忍不住要说真话,而说真话常有严重的后果。这一点,坐牢贬官的苏轼当然深有体会。而在社会主义的新社会裏,一个人甚至不必舞文弄墨说什么真话,就凭他读过几本书的「成分」,已经忧患无穷了。
这种「读书有罪」的意识加于读书人的身分压力,在资本主义的社会裏,也感觉得到。海外的知识分子裏,也有一些人只因自己读过几本书而忸怩不安,甚至感到罪孽深重。为了减轻心头的压力,他们儘量低抑自己知识分子的形象,或者搬弄几个十九世纪的老名词来贬低其他的知识分子,以示彼此有别。
其实在目前的社会,知识分子与非知识分子之间,早已愈来愈难「划清界限」。义务教育愈来愈普及,大众媒介也多少在推行社会教育,而各行各业的在职训练也不失为一种专才教育,所以在年轻人裏要找绝对的非知识分子,已经很难了。且举一例,每年我回台北,都觉得计程车司机的知识水準在逐渐提高。从骆驼祥子到三轮车夫,从三轮车夫到今日的计程车司机,这一行在这一方面显然颇有变化。其他行业,或多或少,也莫不如此。中国大陆,从以前的批斗学者、红而不专、焚书锁书、白卷主义,到目前的鼓吹尊重知识分子,要干部学文化,要人民学礼貌,要学者出国深造等等,也都显示了反知主义的重大错误。到今天,我们都应该承认,无论在什么社会,要是把读过书的人划为一个特殊的阶级,使它和其他的人对立起来,甚至加以羞辱、压抑,绝非健康之举。
读书其实只是交友的延长。我们交友,只能以时人为对象,而且朋友的数量毕竟有限。但是靠了书籍,我们可以广交异时和异地的朋友;要说择友,那就更自由了。一个人的经验当然以亲身得来的最为真切可靠,可是直接的经验毕竟有限。读书,正是吸收间接的经验。生活至上论者说读书是逃避现实,其实读书是扩大现实,扩大我们的精神世界。就算是我们的亲身经验,也不妨多听听别人对相似的经验有什么看法,以资印证。相反地,我认为不读书的人才逃避现实,因为他只生活在一种空间。英国文豪约翰生说:「写作的唯一目的,是帮助读者更能享受或忍受人生。」倒过来说,读书的目的也在加强对人生的享受,如果你得意;或是对人生的忍受,如果你失意。
在知识爆炸的现代,书,是绝对读不完的,如果读书不得其法,则一味多读也并无意义。古人矜博,常说什么「于学无所不窥」,什么「一物不知,君子之耻」。西方在文艺复兴的时代,也多通人,即所谓Renaissance Man。十六世纪末年,培根在给伯利勋爵的信中竟说:「天下学问皆吾本份。」现代的学者,谁敢讲这种话呢?学问的专业化与日俱进,书愈出愈多,知识愈积愈厚,所以愈到后代,愈不容易做学问世界的亚历山大了。
不过,知识爆炸不一定就是智慧增高。我相信,今人的知识一定胜过古人,但智慧则未必。新知识往往比旧知识丰富、正确,但是真正的智慧却难分新旧。知识,只要收到就行了。智慧却需要再三玩味,反覆咀嚼,不断印证。如果一本书愈读愈有味,而所获也愈丰,大概就是智慧之书了。据说「天路历程」的作者班扬,生平只熟读一部书:圣经。米尔顿是基督教的大诗人,当然也熟读圣经,不过他更博览群书。其结果,班扬的成就也不比米尔顿逊色多少。真能善读一本智慧之书的读者,离真理总不会太远,无论知识怎么爆炸,也会得鱼忘筌的吧。
叔本华说:「只要是重要的书,就应该立刻再读一遍。」他所谓的重要的书,正是我所谓的智慧之书。要考验一本书是否不朽,最可靠的试金石当然是时间。古人的经典之作已经有时间为我们鉴定过了;今人的呢,可以看看是否经得起一读再读。一切创作之中,最耐读的恐怕是诗了。就我而言,「峨眉山月半轮秋」和「岐王宅裏寻常见」,我读了几十年,几百遍了,却并未读厌;所以赵翼的话「至今已觉不新鲜」,是说错了。其次,散文、小说、戏剧、甚至各种知性文章等等,只要是杰作,自然也都耐读。奇怪的是,诗最短,应该一览无遗,却时常一览不尽。相反地,卷帙浩繁,令人读来废寝忘餐的许多侦探故事和武侠小说,往往不能引人看第二遍。凡以情节取胜的作品,真象大白之后也就完了。真正好的小说,很少依赖情节。诗最少情节,就连叙事诗的情节,也比小说稀薄,所以诗最耐读。
朱光潜说他拿到一本新书,往往先翻一两页,如果发现文字不好,就不读下去了。我要买书时,也是如此。这种态度,不能斥为形式主义,因为一个人必须想得清楚,才能写得清楚;反之,文字夹杂不清的人,思想一定也混乱。所以文字不好的书,不读也罢。有人立刻会说,文字清楚的书,也有一些浅薄得不值一读。当然不错,可是文字既然清楚,浅薄的内容也就一目了然,无可久遁。倒是偶尔有一些书,文字虽然不够清楚,内容却有其份量,未可一概抹杀。某些哲学家之言便是如此。不过这样的哲学家,我也只能称为有份量的哲学家,无法称为清晰动人的作家。如果有一位哲学家的哲学与唐君毅的相当或相近,而文字却比较清畅,我宁可读他的书,不读唐书。一位作家如果在文字表达上不为读者着想,那就有一点「目无读者」,也就不能怪读者可能「目无作家」了。朱光潜的试金法,颇有道理。
凡是值得读的智慧之书,都值得精读,而且再三诵读。古人所谓的「一目十行」,只是修辞上的夸张。「一目十行」只有两种情形:一是那本书不值得读,二是那个人不会读书。精读一本书或一篇作品,也有两种情形。一是主动精读,那当然自由得很。二是被迫精读,那就是以该书或该文为评论、翻译或教课的对象。要把一本书论好、译好、教好,怎能不加精读?所以评论家(包括编者、选家、注家)、翻译家、教师等等都是很特殊的读者,被迫的精读者。这种读者一方面为势所迫,只许读通,不许读错,一方面较有专业训练,当然读得更精。经得起这批特殊读者再三精读的书,想必是佳作。经得起他们读上几十年几百年的书,一定成为经典了。普通的读者呢,当然也有他们的影响力,但是往往接受特殊读者的「意见领导」。
世界上的书太多了,就算是智慧之书也读不完,何况愈到后代,书的累积也愈大。一个人没有读过的书永远多于读过的书,浅尝之作也一定多于精读之作。不要说陌生人写的书了,就连自己朋友写的书,也没有办法看完,不是不想看完,而是根本没有时间,何况历代还有那么多的好书,早就该看而一直没看的,正带着责备的眼色等你去看?对许多人说来,永远只有很少的书曾经精读,颇多的书曾经略读,更多的书只是道听涂说,而绝大多数的书根本没听说过。
略读的书单独看来似乎没有多大益处,但一加起来就不同了。限于时间和机缘,许许多多的好书只能略加翻阅,不能深交。不过这种点头之交十分重要,因为一旦需要深交,你知道该去那裏找他。很多深交都是这么从初交变成的。略读之网撒得愈广愈好。真正会读书的人,一定深谙略读之道,即使面对千百好书,也知道远近缓急之分。要点在于:妄人常把略读当成深交,智者才知道那不过是点头浅笑。有些书不但不宜精读,且亦不必略读,只能备读,例如字典。据说有人读过「大英百科全书」;这简直是以网汲水,除了迂阔之外,不知道还能证明什么?
有些人略读,作为精读的妥协,许多大学者也不免如此。有些人只会略读,因为他们没有精读的训练或毅力。更有些人略读,甚至掠读,只为了附庸风雅。这种态度当然会产生弊端,常被识者所笑。我倒觉得附庸风雅也不全是坏事,因为有人争附风雅,正显得风雅当道,风雅有「善势力」,逼得一般人都来攀附,未必心服,却至少口服。换了是野蛮当道,野蛮拥有恶势力,如文革时期,大家烧书丢书都来不及,还有谁敢附庸风雅呢?
附庸风雅的人多半是后知后觉,半知半觉,甚或是不知不觉,但是他们不去学野蛮,却来学风雅,也总算见贤思齐,有心向善,未可厚非。有人附庸风雅,才有人来买书,有人买书,风雅才能风雅下去。据我看来,附庸风雅的人不去图书馆借书,只去书店买书。新书买来了,握在手裏,提在口头,陈于架上,才有文化气息。书香,也不能不靠铜臭。
当然,买书的人并非都在附庸风雅。文化要发达,书业要旺盛,实质上要靠前述的那一小撮核心分子的特殊读者来推波助澜。一般读者正是那波澜,至于附庸风雅的人,就是波澜激起的浪花,更显得波澜之壮阔多姿。大致说来,有钱人不想买书,就算「买点文化」来做客厅风景,也是适可而止。反过来呢,爱书的人往往买不起文化,至少不能放手畅买,到精神的奢侈得以餍足的程度。
亚历山大恨世界太小,更无余地可以征服,牛顿却歎学海太大,只能在岸边拾贝。书海,也就是学海了。逛大书店,对华美豪贵的精装巨书手抚目迷,「意淫」一番,充其量只像加州的少年在滩边踏板冲浪罢了,至于海,是带不回家的。我在香港,每个月大概只买三百元左右的书刊,所收台港两地的赠书恐怕也值三百元。这样子的买文化,只能给我「过屠门而磨牙」的感觉,连小康也沾不上,遑论豪奢?要我放手畅买的话,十万元也不嫌多。
看书要舒服,当然要买硬封面的精装本,但价格也就高出许多。软封面的平装木,尤其是胶背的一种,反弹力强得恼人,摊看的时候总要用手去镇压。遇到翻译或写评时需要众书并陈,那就不知要动员多少东西来镇取这一批不驯之徒。檯灯、墨水瓶、放大镜、各种各样的字典和参考书,一时纷然杂陈,争据桌面,真是牵一髮而动全身。这时,真恨不得我的书桌大得像一张乓乒球桌,或是其形如扇,而我坐在扇柄的焦点。我曾在伦敦的卡莱尔故居,见到文豪生前常用的一张扶手椅,左边的扶手上装着一具阅读架,可以把翻开的书本斜倚在架上,架子本身也可作九十度的推移,椅前还有一只厚垫可以搁脚。不过,这只能让人安坐久读,却不便写作时并览众书。
有时新买了一部漂亮的贵书回来,得意摩挲之余,不免也有一点犯罪感,好像是又娶了一个妾,不但对不起原有的满架藏书,也有点对不起太太。书房裏一架架的藏书,有许多本我非但不曾精读,甚至略读也说不上,辜负了众美,却又带了一位回来,岂不成了阿剌伯的油王?至于太太呢,她也有自己的嗜好呀,例如玉器,却捨不得多买。要是她也不时这么放纵一下,又怎么办呢?而我,前几天不是才买过一批书吗,怎么又要买了?我的理由,例如文化投资,研究必备等等,当然都光明正大。幸好太太也不是未开发的头脑,每次见我牵了新欢进门,最多纵容地轻歎一声,也就姑息下去了。其实对我自己说来,不断买书,虽然可以不断满足佔有慾而乐在其中,但是烦恼也在其中。为学问着想,我看过的书太少;为眼睛着想,我看过的书又太多了。这矛盾始终难解,太太又不断恫吓我说,再这么鹭鸶一般弯颈垂头在书页的田埂之上,要防颈骨恶化,脊骨退化,并举几个朋友做反面教材。
除了这些威胁的阴影之外,最大的问题是书的收藏。每个读书人的藏书,都是用时不够,藏时嫌多。我在台北的藏书原有两千多册,去港九年蒐集的书也有一千多册了,不但把办公室和书房堆得满坑满谷,与人争地,而且採行扩充主义,一路侵入客厅、饭厅、卧室、洗衣间,只见东一堆,西一叠,各佔山头,有进无退,生存的空间饱受威胁。另一现象,是不要的书永远在肘边,要找的呢,就忽然神祕失蹤,到你不要时又自动出现。我对太太说,总有一天我们车尾的行李箱也要用来充书库了。问题是,这几千本书目前虽可用「双城记」分藏在台北和香港,将来我迁回台北,这「两地书」却该怎么合併?
然而书这东西,宁愿它多得成灾,也不愿它少得寂寞。从封面到封底,从序到跋,从扉页的憧憬到版权的现实,书的天地之大,绝不止于什么黄金屋和颜如玉。那美丽的扉页一开,真有「芝麻开门」的神祕诱惑,招无数心灵进去探宝。古人为了一本借来的书限期到了,要在雪地裏长途跋涉去还给原主。在书荒的抗战时代,我也曾为了喜欢一本借来的天文学入门,在摇曳如梦的桐油灯下逐夜抄录。就在那时,陆蠡为了追讨日本兵没收去的书籍,而受刑致死。在书劫的文革时期,除了那本红小书随风飞扬如枫林之外,一切封资修的毒草害书,不是抄走,便是锁起,或者被焚于比秦火更烈的火裏。无数的读书人都诀别了心爱的藏书,可惊的是,连帝俄的作家都难逃大劫。请看四川诗人流沙河的「焚书」吧:
```
留你留不得,
藏你藏不住。
今宵送你进火炉,
永别了,
契诃夫!
夹鼻眼镜山羊鬍,
你在笑,我在哭。
灰飞烟灭光明尽,
永别了,
契诃夫!
```
一九八三年六月于厦门街
[^1]:cū,俗作'麁',今人既用'粗',粗行而麤废亦。
开你的大头会-余光中
========================
开你的大头会-[[余光中]]
-----
世界上最无趣的事情莫过于开会了。大好的日子,一大堆人被迫放下手头的急事、要事、趣事,济济一堂,只为听三五个人逞其舌锋,争辩一件议而不决、决而不行、行而不通的事情,真是集体浪费时间的最佳方式。仅仅消磨光阴倒也罢了,更可惜的是平白扫兴,糟蹋了美好的心情。会场虽非战场,却有肃杀之气,进得场来,无论是上智或下愚,君子或小人,都会一改常态,人人脸上戴着面具,肚里怀着鬼胎,对着冗赘的草案、苛细的条文,莫不咬文嚼字,反复推敲,务求措辞严密而周详,滴水不漏,一劳永逸,把一切可钻之隙、可乘之机统统堵绝。
开会的心情所以好不了,正因为会场的气氛只能够印证性恶的哲学。济济多士埋首研讨三小时,只为了防范冥冥之中的一个假想敌,免得他日后利用漏洞,占了大家的,包括你的,便宜。开会,正是民主时代的必要之恶。名义上它标榜尊重他人,其实是在怀疑他人,并且强调服从多数,其实往往受少数人左右,至少是搅局。
除非是终于付诸表决,否则争议之声总不绝于耳。你要闭目养神,或游心物外,或思索比较有趣的问题,并不可能。因为万籁之中人声最令人分心,如果那人声竟是在辩论,甚或指摘,那就更令人不安了。在王尔德的名剧《不可儿戏》里,脾气古怪的巴夫人就说:“什么样的辩论我都不喜欢。辩来辩去,总令我觉得很俗气,又往往觉得有道理。”
意志薄弱的你,听谁的说辞都觉得不无道理,尤其是正在侃侃的这位总似乎胜过了上面的一位。于是像一只小甲虫落入了雄辩的蛛网,你放弃了挣扎,一路听了下去。若是舌锋相当,场面火爆而高潮迭起,效果必然提神。可惜讨论往往陷于胶着,或失之琐碎,为了“三分之二以上”或“讲师以上”要不要加一个“含”字,或是垃圾的问题要不要另组一个委员会来讨论,而新的委员该如何产生才具有“充分的代表性”等等,节外生枝,又可以争议半小时。
如此反复斟酌,分发(hair-splitting)细究,一个草案终于通过,简直等于在集体修改作文。可惜成就的只是一篇面无表情更无文采的平庸之作,绝无漏洞,也绝无看头。所以没有人会欣然去看第二遍。也所以这样的会开完之后,你若是幽默家,必然笑不出来,若是英雄,必然气短,若是诗人,必然败兴。
开会的前几天,一片阴影就已压上我的心头,成了生命中不可承受之烦。开会的当天,我赴会的步伐总带一点从容就义。总之,前后那几天我绝对激不起诗的灵感。其实我的诗兴颇旺,并不是那样禁不起惊吓。我曾经在监考的讲台上得句,也曾在越洋的七四七经济客舱里成诗,周围的人群挤得更紧密,靠得也更逼近。不过在陌生的人群里“心远地自偏”,尽多美感的距离,而排排坐在会议席上,摩肩接肘,咳唾相闻,尽是多年的同事、同仁,论关系则错综复杂,论语音则闭目可辨,一举一动都令人分心,怎么容得你悠然觅句?叶芝说得好:“与他人争辩,乃有修辞;与自我争辩,乃有诗。”修辞是客套的对话,而诗,是灵魂的独白。会场上流行的既然是修辞,当然就容不得诗。
所以我最佩服的,便是那些喜欢开会、擅于开会的人。他们在会场上总是意气风发,雄辩滔滔,甚至独揽话题,一再举手发言,有时更单挑主席缠斗不休,陷议事于瓶颈,置众人于不顾,像唱针在沟纹里不断反复,转不过去。
而我,出于潜意识的抗拒,常会忘记开会的日期,惹来电话铃一迭连声催逼,有时去了,却忘记带厚重几近电话簿的议案资料。但是开会的烦恼还不止这些。
其一便是抽烟了。不是我自己抽,而是邻座的同事在抽,我只是就近受其熏陶,所以准确一点,该说闻烟,甚至呛烟。一个人对于邻居,往往既感觉亲切又苦于纠缠,十分矛盾。同事也是一种邻居,也由不得你挑选,偏偏开会时就贴在你隔壁,却无壁可隔,而有烟共吞。你一面呛咳,一面痛感“远亲不如近邻”之谬,应该倒过来说“近邻不如远亲”。万一几个近邻同时抽吸起来,你就深陷硝烟火网,呛咳成一个伤兵了。好在近几年来,社会虽然日益沉沦,交通、治安每况愈下,公共场所禁烟却大有进步,总算除了开会一害。
另一件事是喝茶。当然是各喝各的,不受邻居波及。不过会场奉茶,照例不是上品,同时在冷气房中迅趋温吞,更谈不上什么品茗,只成灌茶而已。禁不起工友一遍遍来添壶,就更沦为牛饮了。其后果当然是去“造水”,乐得走动一下。这才发现,原来会场外面也很热闹,讨论的正是场内的事情。
其实场内的枯坐久撑,也不是全然不可排遣的。万物静观,皆成妙趣,观人若能入妙,更饶奇趣。我终于发现,那位主席对自己的袖子有一种,应该是不自觉的,紧张心结,总觉得那袖口妨碍了他,所以每隔十分钟左右,会忍不住突兀地把双臂朝前猛一伸直,使手腕暂解长袖之束。那动作突发突收,敢说同事们都视而不见。我把这独得之秘传授给一位近邻,两人便兴奋地等待,看究竟几分钟之后会再发作一次。那近邻观出了瘾来,精神陡增,以后竟然迫不及待,只等下一次开会快来。
不久我又发现,坐在主席左边的第三位主管也有个怪招。他一定是对自己的领子有什么不满,想必是妨碍了他的自由,所以每隔一阵子,最短时似乎不到十分钟,总情不自禁要突抽颈筋,迅转下巴,来一个“推畸”(twitch)或“推死它”(twist),把衣领调整一下。这独家奇观我就舍不得再与人分享了,也因为那近邻对主席的“推手式”已经兴奋莫名,只怕再加上这“推畸”之扭他负担不了,万一神经质地爆笑起来,就不堪设想了。
当然,遣烦解闷的秘方,不止这两样。例如耳朵跟鼻子人人都有,天天可见,习以为常竟然视而不见了。但在众人危坐开会之际,你若留神一张脸接一张脸巡视过去,就会见其千奇百怪,愈比愈可观,正如对着同一个字凝神注视,竟会有不识的幻觉一样。
会议开到末项的“临时动议”了。这时最为危险,只怕有妄人意犹未尽,会无中生有,活部转败,竟然敢冒天下之大不韪,提出什么新案来。
幸好没有。于是会议到了最好的部分:散会。于是又可以偏安半个月了,直到下一次开会。
一九九七年四月
### 出自 MBA智库百科([https://wiki.mbalib.com/](https://wiki.mbalib.com/))
**康奈尔笔记系统(Connell Note System)**
目录
--
\[隐藏\]
* [1 什么是康奈尔笔记系统]
* [2 康奈尔笔记系统的内容]
* [3 康奈尔笔记系统的步骤]
*
!! 什么是康奈尔笔记系统
康奈尔笔记系统是指沃尔特·鲍克等人发明的,旨在为帮助学生有效地做笔记。
!! [2 康奈尔笔记系统的内容]
康奈尔笔记系统把一页纸分成了三部分:右上最大的空间是我们平时做笔记的地方,你按照平时的习惯记录就行了。
左边那竖着的一条空间是用来归纳右边的内容的,写一些提纲挈领的东西,这个工作不要在做笔记的时候做,而是在上完课之后马上回顾,然后把要点都写到左边,这样一方面马上复习了内容,另一方面理清了头绪。
下面那横着的一栏是用来做总结的,就是用一两句话总结你这页记录的内容,这个工作可以延后一点儿做,起到促进你思考消化的作用,另外也是笔记内容的极度浓缩和升华。
5R笔记法,又叫做康奈尔笔记法,是用产生这种笔记法的大学校名命名的。这一方法几乎适用于一切讲授或阅读课,特别是对于听课笔记,5R笔记法应是最佳首选。这种记与学,思考与运用相结合的有效方法,初用时,可以以一科为例进行训练,在这一科不断熟练的基础上,然后再用于其他科目。
!![3 康奈尔笔记系统的步骤]
[img[https://wiki.mbalib.com/w/images/5/54/%E7%AC%94%E8%AE%B07.png]]
具体包括以下几个步骤:
1. 记录(Record)。在听讲或阅读过程中,在主栏(将笔记本的一页分为左小右大两部分,右侧为主栏,左侧为副栏)内尽量多记有意义的论据、概念等讲课内容。
2. 简化(Reduce)。下课以后,尽可能及早将这些论据、概念简明扼要地概括(简化)在回忆栏,即副栏。
3. 背诵(Recite)。把主栏遮住,只用回忆栏中的摘记提示,尽量完满地叙述课堂上讲过的内容。
4. 思考(Reflect)。将自己的听课随感、[意见]、经验体会之类的内容,与讲课内容区分开,写在卡片或笔记本的某一单独部分,加上标题和索引,编制成提纲、摘要,分成类目。并随时归档。
5. 复习(Review)。每周花十分钟左右时间,快速复习笔记,主要是先看回忆栏,适当看主栏。这种做笔记的方法初用时,可以以一科为例进行训练。在这一科不断熟练的基础上,然后再用于其他科目。
* 符号记录法
符号记录法就是在课本、参考书原文的旁边加上各种符号,如直线、双线、黑点、圆圈、曲线、箭头、[红线]、蓝线、三角、方框、着重号、惊叹号、问号等等,便于找出重点,加深印象,或提出质疑。什么符号代表什么意思,你可以自己掌握,但最好形成一套比较稳定的符号系统。这种方法比较适合于自学笔记和预习笔记。 在操作时你应注意以下一些准则:
1. 读完后再做记号。在你还没有把整个段落或有标题的部分读完并停下来思考之前,不要在课本上做记号。在阅读的时候,你要分清作者是在讲一个新的概念,还是只是用不同的词语说明同样的概念,你只有等读完这一段落或部分以后,才能回过头来看出那些重复的内容。这样做可使你不至于抓住那些一眼看上去仿佛很重要的东西。
2. 要非常善于选择。你不要一下子在很多项目下划线或草草写上许多项目,这样会使记忆负担过重,并迫使你同一时刻从几个方面来思考问题,也加重你的思维负担。你要少做些记号,但也不要少得使你在复习时又只好将整页内容通读一遍。
3. 用自己的话。页边空白处简短的笔记应该用你自己的话来写,这是因为自己的话代表你自己的思想,以后这些话会成为这一页所述概念的一些有力的提示。
4. 简洁。在一些虽简短但是有意义的短语下划线,而不要在完整的句子下面划线,页边空白处的笔记要简明扼要。它们会在你的记忆里留下更为深刻的印象。在你背诵和复习的时候用起来更可得心应手。
5. 迅速。你不可能一整天的时间都用来做记号。你先要阅读,再回过头来大略地复习一遍,并迅速做下记号,然后学习这一章的下一部分内容。
6. 整齐。你作的符号要尽量整齐,而不要胡写乱画,否则会影响你以后的复习和应用。当你以后复习的时候,整齐的记号会鼓励你不断学习,并可以节省时间,因为整齐的记号便于你迅速回忆当初学习时的情景,能使你容易而清楚地领悟书中的思想。
* 笔记整理法
由于种种原因,你在课堂上做的笔记往往比较杂乱,课后复习不太好用。为了巩固学习成果,积累复习资料,你需要对笔记进一步整理,使之成为比较系统、条理的参考资料。 对课堂笔记进行整理、加工的方法是:
1. 忆。课后即抓紧时间,趁热打铁,对照书本、笔记,及时回忆有关信息。这是你整理笔记的重要前提
2. 补。课堂上所作的笔记,因为是跟着教师讲课的速度进行的,而讲课速度要比记录速度快一些,所以你的笔记会出现缺漏、跳跃、省略等情况,在忆的基础上,及时作修补,使笔记更完整。
3. 改。仔细审阅你的课堂笔记,对错字、错句及其他不够确切的地方进行修改。
4. 编。用统一的序号,对笔记内容进行提纲式的、逻辑性的排列,注明号码,梳理好整理笔记的先后顺序。
5. 分。以文字(最好用色笔)或符号、代号等划分笔记内容的类别。例如:哪些是字词类,哪些是作家与作品类,哪些作品(或课文)分析类,哪些是问题质疑、探索类,哪些是课后练习题解答等等。
6. 舍。省略无关紧要的笔记内容,使笔记简明扼要。
7. 记。分类抄录经过整理的笔记。同类的知识,摘抄在同一个本子上或一个本子的同一部分,也可以用卡片分类抄录。这样,日后复习、使用就方便了,按需所取,纲目清晰,快捷好用,便于记忆。
目录
* [1 什么是空间知识溢出]
* [2 空间知识溢出的内容]
什么是空间知识溢出
---------
**空间知识溢出**是指区域之间通过信息交换获得成果,区域之间相互学习相互沾光,带来经济增长,知识溢出一般不给知识的创新者以补偿或给予的补偿小于成果的价值。
空间知识溢出的内容
---------
空间知识溢出的影响因素,不仅包括地理距离、知识缺口,同时还受中心城市人口相对拥挤程度、周边地区吸收能力差异等因素的影响。知识缺口明显阻止了空间知识溢出的发生,而中心城市发展空间缺口显著加速了知识的外溢。在控制吸收能力影响后,空间知识溢出的地理衰减过程不再显著。
空间知识溢出具有的局域性特征,使得经济活动的地理区位具有重要的作用。经济活动的空间集中会有效地促进知识溢出,知识空间溢出的作用强度呈现出随着距离增加而衰减的特征。区域间的知识溢出整体上对区域创新贡献明显,但受空间交易成本影响,仅有部分知识溢出可为邻近区域所利用并受益。
空中爆炸-余华
========================
空中爆炸-[[余华]]
-----
八月的一个晚上,屋子里热浪滚滚,我和妻子在嘎嘎作响的电扇前席地而坐,我手握遥控器,将电视频道一个一个换过去,然后又一个一个换过来。我汗流浃背,心情烦躁。我的妻子倒是心安理得,她坐在那里一动不动,在她光滑的额头上我找不到一颗汗珠,她就像是一句俗话说的那样,心静自然凉。可是我不满现实,我结婚以后就开始不满现实了,我嘴里骂骂咧咧,手指敲打着遥控器,将电视屏幕变成一道道的闪电,让自己年轻的眼睛去一阵阵地老眼昏花。我咒骂夏天的炎热,我咒骂电视里的节目,我咒骂嘎嘎作响的破电扇,我咒骂刚刚吃过的晚餐,我咒骂晾在阳台上的短裤……我的妻子还是心安理得,只要我在这间屋子里,只要我和她坐在一起,我说什么样的脏话,做什么样的坏事,她都能心安理得。要是我走出这间屋子,我离开了她,她就不会这样了,她会感到不安,她会不高兴,她会喊叫和指责我,然后就是伤心和流泪了。这就是婚姻,我要和她寸步不离,这是作为丈夫的职责,直到白头到老,哀乐响起。
我的朋友唐早晨敲响了我的屋门,他用手指,用拳头,用脚,可能还用上了膝盖,总之我的屋门响成了一片。这时候我像是听到了嘹亮军号和公鸡报晓一样,我从地上腾地站起,将门打开,看到了有一年多没见的唐早晨。我叫了起来:
“唐早晨,他妈的是你。”
唐早晨穿着肥大的裤子和铁红的西服,他油头粉面,笑容古怪,他的脚抬了抬,可是没有跨进来。我说:
“你快进来。”
唐早晨小心翼翼地走进了我的屋子,他在狭窄的过道里东张西望,就像是行走在伸手不见五指的漆黑里。我知道他的眼睛是在寻找我妻子,他一年多时间没来也是因为我妻子。用我妻子的话说:唐早晨是一个混蛋。
其实唐早晨不是混蛋,他为人厚道,对朋友热情友好,他只是女人太多,所以我的妻子就说他是一个混蛋。在过去的日子里,他经常带着女人来到我家,这倒没什么,问题是他每次带来的女人都不一样,这就使我的妻子开始忐忑不安,她深信近墨者黑、近朱者赤这样的道理,她觉得我和他这么交往下去实在太危险了,准确地说是她觉得自己太危险了。她忘记了我是一个正派和本分的人,她开始经常地警告我,而且她的警告里充满了恫吓,她告诉我:如果我像唐早晨那样,那么我的今后就会灾难深重。她生动地描绘了灾难来到后的所有细节,只要她想得起来,要命的是她在这方面总是想象丰富,于是我就越来越胆小。
可是唐早晨是一个粗心大意的人,他一点都感觉不到我妻子的警惕,虽然我暗示过多次,他仍然毫无反应,这时候他又是一个迟钝的人。直到有一天,他坐在我家的沙发里,声音响亮地说:
“我看着朋友们一个一个都结婚了,先是你,然后是陈力达、方宏、李树海。你们四个人一模一样,遇上第一个女人就结婚了。我不明白你们为什么那么快就结婚了,你们为什么不多谈几次恋爱?为什么不像我这样自由自在地生活?为什么要找个女人来把自己管住,管得气都喘不过来。我现在只要想起你们,就会忍不住嘿嘿地笑,你们现在连说话都要察言观色,尤其是你,你说上两句就要去看看你的妻子,你累不累?不过你现在还来得及,好在你还没有老,你还有机会遇上别的女人,什么时候我给你介绍一个?”
这就是唐早晨,话一多就会忘乎所以。他忘了我的妻子正在厨房里炒菜,他的嗓门那么大,他说出的每一个字都被我妻子听进了耳朵。于是我妻子脸色铁青地走了出来,她用手里的油锅去推唐早晨,油锅里的油还在噼噼啪啪地跳着响着,她说:
“你出去,你出去……”
唐早晨吓得脸都歪了,他的头拼命地往后仰,两只手摸索着从沙发上移了出去,然后都来不及看我一眼,就从我家里逃之夭夭了。我没有见过如此害怕的神色,我知道他害怕的不是我妻子,是我妻子手上的油锅,里面噼噼啪啪的响声让他闻之丧胆,而且有一年多时间没再跨进我的屋门。
一年多以后,在这个八月的炎热之夜,他突然出现了,走进了我的家,看到了我的妻子。这时候我妻子已经从地上站起来了,她看到唐早晨时友好地笑了,她说:
“是你,你很久没来我们家了。”
唐早晨嘿嘿地笑,显然他想起了当初的油锅,他有些拘束地站在那里,我妻子指着地上草席说:
“你请坐。”
他看看我们铺在地上的草席,仍然站在那里。我将嘎嘎作响的电扇抬起来对着他吹,我妻子从冰箱里拿出了饮料递给他。他擦着汗水喝着饮料,还是没有坐下,我就说:
“你为什么不坐下?”
这时他脸上出现了讨好我们的笑容,然后他说:
“我不敢回家了,我遇上了麻烦。”
“什么麻烦?”我吃了一惊。
他看看我的妻子,对我说:
“我最近和一个女人……这个女人有丈夫,现在她的丈夫就守在我家楼下……”我们明白发生了什么,一个吃足了醋的丈夫此刻浑身都是力气,他要让我们的朋友唐早晨头破血流。我的妻子拿起了遥控器,她更换了两个电视频道后,就认真地看了起来。她可以置之度外,我却不能这样,毕竟唐早晨是我的朋友,我就说:
“怎么办?”
唐早晨可怜巴巴地说:“你能不能陪我回去?”
我只好去看我的妻子,她坐在草席上看着电视,我希望她能够回过头来看我一眼,可是她没有这样做,我只好问她:
“我能不能陪他回家?”
我的妻子看着电视说:“我不知道。”
“她说不知道。”我对唐早晨说,“这样一来,我也不知道该不该陪你回家了。”
唐早晨听到我这么说,摇起了头,他说:
“我这一路过来的时候,经过了陈力达的家,经过了方宏的家,就是到李树海的家,也比到你这里来方便。我为什么先到你这里来,你也知道,虽然我们有一年多没见面了,可我们还是最好的朋友,所以我就先来找你了,没想到你会这样,说什么不知道,干脆你就说不愿意……”
我对唐早晨说:“我没有说不愿意,我只是说不知道……”
“不知道是什么意思?”唐早晨问我。
“不知道就是……”我看了看妻子,继续说,“不是我不愿意,是我妻子不愿意。她不愿意,我就一点办法都没有了。我可以跟着你走,但是我这么一走以后就没法回家了,她会把我锁在门外,不让我回家。我可以在你家里住上一天,两天,甚至一个月,可是我总得回家,我一回家就没好日子过了。你明白吗?不是我不愿意,是她不愿意……”
“我没有说不愿意。”这时我妻子说话了,她转过身来对唐早晨说,“你不要相信他的话,他现在动不动就把自己说得那么可怜,其实他在家里很霸道,什么事都要他做主,稍有不顺心的事他就要发脾气,这个月他都砸坏三个杯子了……”
我打断她的话:“我确实怕你,唐早晨可以证明。”
唐早晨连连点头:“是的,他确实怕你,这一点我们都知道。”
我妻子看着我和唐早晨笑了起来,她笑的时候,我们两个人站在那里一动不动,她笑着问唐早晨:
“有几个人守在你家楼下?”
“就一个。”唐早晨说。
“他身上有刀子吗?”我妻子继续问。
“没有。”唐早晨回答。
“你怎么知道没有?他会把刀子藏在衣服里面。”
“不可能。”唐早晨说,“他就穿着一件汗衫,下面是短裤,没法藏刀子。”
我妻子放心了,她对我说:“你早点回来。”
我马上点起头,我说:“我快去快回。”
唐早晨显然是喜出望外了,他不是转身就走,而是站在那里滔滔不绝地说了起来,他对我妻子说:
“我早就知道你会这样的,要不我就不会先来你们家了。我想来想去,我这几个朋友的妻子里面,你最通情达理。方宏的妻子阴阳怪气的,陈力达的妻子是个泼妇,李树海的妻子总喜欢教训别人,就是你最通情达理,你最好……”
说着唐早晨转过头来对我说:“你小子运气真是好。”
我心想唐早晨要是再这么废话连篇,我妻子说不定会改变主意了,我就踢了他一脚。我把他踢疼了,他“嗷”地叫出了半声,马上明白我的意思,立刻对我妻子说:
“我们走了。”
我们刚走到门外,我妻子就叫住了我,我以为她改变主意了,结果她悄悄地对我说:
“你别走在前面,你跟在他们后面。”
我连连点头:“我知道了。”
离开我家以后,我和唐早晨先去了李树海的家,就像唐早晨说的那样,李树海的妻子把唐早晨教训了一通。那时候她刚洗了澡,她坐在电扇前梳着头,梳下来的水珠像是唾沫似的被电扇吹到了唐早晨的脸上,让唐早晨不时地伸手去擦一把脸。李树海的妻子说:
“我早就说过了,你再这样下去,总有一天会被人家打断腿的。李树海,我是不是早就说过了?”
我们的朋友李树海一声不吭地坐在那里,听到妻子用这种口气说他的朋友,让他很难堪,但他还是微微地点了点头。他的妻子往下说道:
“唐早晨你这个人不算坏,其实你就是一个色鬼,你要是和没结婚的姑娘交往也还说得过去,你去勾引人家的妻子,那你就太缺德了,本来人家的生活很美满,被你这么一插进去,人家的幸福马上就变成了痛苦,好端端的一个家庭被你拆散了,要是有孩子的话,孩子就更可怜了。你想一想,你要是勾引了我,李树海会有多痛苦,李树海你说对不对?”
她的现身说法让李树海坐立不安,可是她全然不觉,她继续说:
“你经常这样,把自己的幸福建立在别人的痛苦之上,可是总有一天你会得到报应的,别人会把你打死的,像你这样的人,就是被人打死了,也没人会来同情你。你记住我的话,你要是再不改掉你好色的毛病,你会倒霉的。现在已经有人守在你家楼下了,是不是?”
唐早晨点着头说:“是,是,你说得很对,我最近手气不好,搞了几个女人,都他妈的有男人来找麻烦。”
然后我和唐早晨,还有李树海来到了方宏的家,我们三个人坐在方宏家的客厅里,吃着方宏从冰箱里拿出来的冰棍,看着方宏光着膀子走进了卧室,然后听到里面一男一女窃窃私语的声音。我们知道方宏是在告诉他的妻子发生了什么,接下去就是说服他的妻子,让他在这个炎热的夏日之夜暂时离家,去助唐早晨一臂之力。
卧室的门虚掩着,留着一条比手指粗一些的缝,我们看到里面的灯光要比客厅的暗淡,我们听到他们两个人的声音此起彼伏,他们都在使劲压制着自己的声音,所以我们听到的仿佛不是声音,仿佛是他们两个人呼哧呼哧的喘气声。
我们吃完了冰棍,我们看着电扇的头摇过来摇过去,让热乎乎的风吹在我们出汗的身上,我们三个人互相看着,互相笑一笑,再站起来走两步,又坐下。我们等了很长时间,方宏终于出来了,他小心翼翼地将卧室的门关上,然后满脸严肃地站在那里,把一件白色的汗衫从脖子上套了进去,将汗衫拉直以后,他对我们说:
“走吧。”
现在我们有四个人了,我们汗流浃背地走到了陈力达的楼下,陈力达的家在第六层,也就是这幢楼房的顶层。我们四个人仰起脸站在嘈杂的街道上,周围坐满了纳凉的人,我们看到陈力达家中的灯光,我们喊了起来:
“陈力达,陈力达,陈力达。”
陈力达出现在了阳台上,他的脑袋伸出来看我们,他说:
“谁叫我?”
“我们。”我们说。
“谁?”
我说:“是李树海、方宏、唐早晨,还有我。”
“他妈的,是你们啊?”陈力达在上面高兴地叫了起来,他说,“你们快上来。”
“我们不上来啦。”我们说,“你住得太高啦,还是你下来吧。”
这时我们听到一个女人的声音在上面响了起来:
“下来干什么?”
我们仔细一看,陈力达的妻子也在阳台上了,她用手指着我们说:“你们来干什么?”
我说:“唐早晨遇上麻烦了,我们几个朋友要帮助他,让陈力达下来。”
陈力达的妻子说:“唐早晨遇到什么麻烦了?”
李树海说:“有一个人守在他家的楼下,准备要他的命。”
陈力达的妻子说:“那个人为什么要他的命?”
方宏说:“唐早晨和那个人的妻子好上了……”
“我知道啦。”陈力达的妻子说,“唐早晨的老毛病又犯了,所以人家要来杀唐早晨了。”
“对。”我们说。
“没那么严重。”唐早晨说。
陈力达的妻子在上面问:“唐早晨这一次勾引上的女人叫什么名字?”
我们就去问唐早晨:“是哪个女人?”
唐早晨说:“你们别这么喊来喊去的,让那么多人听到,没看到他们都在笑吗?把我搞得臭名昭著。”
陈力达的妻子问:“唐早晨在说些什么?”
我说:“他让我们别再这么喊来喊去了,要不他就会臭名昭著了。”
“他早就臭名昭著了。”陈力达的妻子在上面喊道。
“是啊。”我们同意她的话,我们对唐早晨说,“其实你早就臭名昭著了。”
“他妈的。”唐早晨骂了一声。
“他又说了什么?”陈力达的妻子又问。
“他说你说得对。”我们回答。
就这样,唐早晨的朋友们总算是到齐了,在这个八月的夜晚,气温高达三十四摄氏度,五个人走在了仍然发热的街道上,向唐早晨的家走去。在路上,我们问唐早晨守在他家楼下的男人是谁,他说他不认识。我们又问他这个男人的妻子是谁,他说我们不认识。我们最后问他:“你是怎么和那个有夫之妇勾搭上的?”他说:
“这还用问,不就是先认识后上床嘛。”
“就这么简单?”我们问。
唐早晨对我们的提问显得不屑一顾,他说:
“你们就是把这种事想得太复杂了,所以你们一辈子只配和一个女人睡觉。”
然后我们在一家商店的门口,喝起了冰镇的饮料。我们商量着如何对付那个悲愤的丈夫:李树海说不用理睬他,我们四个人只要把唐早晨送到家,让他知道唐早晨有我们这样四个朋友,他以后就不敢轻举妄动了;方宏认为还是应该和他说几句话,让他明白找唐早晨其实没有意思,他应该去找自己的妻子算账;我说如果打起来的话,我们怎么办?陈力达说如果打起来了,我们站在一边替唐早晨助威就行了。陈力达觉得有我们四个人撑腰,唐早晨有绝对获胜的把握。
我们议论纷纷的时候,唐早晨一言不发,当我们去征求他的意见时,才发现他正在向一个漂亮姑娘暗送秋波。我们的话,他一句都没有听进去。我们看到唐早晨眼睛闪闪发亮,在他右侧两米远的地方,一个秀发披肩的姑娘也在喝着饮料,这个姑娘穿着黑色的背心和碎花的长裙。我们看着她时,她有两次转过头来看看我们,当然也去看了看唐早晨,她的目光显得漫不经心。她喝完饮料以后,将可乐瓶往柜台上一放,转身向前走去了。她转身时的姿态确实很优美。我们看着她走上了街道,然后我们吃惊地看到唐早晨跟在了她的身后,唐早晨也走去了。我们不由叫了起来:
“唐早晨……”
唐早晨回过身来,向我们嘿嘿一笑,接着紧随着那个漂亮姑娘走去了。
我们瞠目结舌,我们知道他要去追求新的幸福了。可是现在是什么时候?一个满腔怒火的男人正守在他家楼下,这个男人正咬牙切齿地要置他于死地。他把我们从家里叫出来,让我们走得汗流浃背,让我们保护他回家,他自己却忘记了这一切,把我们扔在一家商店的门前,不辞而别了。
于是我们破口大骂,我们骂他不可救药,我们骂他是一个混蛋王八蛋,我们骂他不得好死,我们骂他总有一天会染上梅毒,会被梅毒烂掉。同时我们发誓以后再不管他的闲事了,他就是被人打断了腿,被人揍瞎了眼睛,被人阉割了,我们也都视而不见。
我们骂得大汗淋漓,骂得没有了力气,然后才安静下来。我们站在那里,互相看来看去,看了一会,我们开始想接下去干什么。我问他们:
“是不是各自回家了?”
他们谁都没有回答,我突然发现自己的提议十分愚蠢,我立刻纠正道:
“不,我们现在不回家。”
他们三个人也马上明白了我的意思,他们说:
“对,我们不忙着回家。”
我们都想起来了,我们已经有几年时间没有聚到一起了,如果不是因为唐早晨,我们的妻子是不会让我们出来的,我们都突然发现了这样的机会来之不易,然后我们都看到了街道对面有一家小酒店,我们就走了过去。
这一天晚上,我们终于又在一起喝上酒了,我们没完没了地说话,我们忘记了时间的流逝,我们谁都不想回家。我们一遍又一遍地回忆着过去,回忆着那些没有女人来打扰的日子。那时候是多么美好,我们唱着歌在大街上没完没了地走;我们对着那些漂亮姑娘说着下流的话;我们将街上的路灯一个一个地消灭掉;我们在深更半夜去敲响一扇扇的门,等他们起床开门时,我们已经逃之夭夭;我们把自己关在门窗紧闭的屋子里,使劲地抽烟,让烟雾越来越浓,直到看不清对方的脸。我们不知道干了多少坏事,我们不知道把自己的肚子笑疼了多少回。我们还把所有的钱都凑起来,全部买了啤酒,我们将一个喝空了的酒瓶扔向天空,然后又将另一个空酒瓶扔上去,让两个酒瓶在空中相撞,在空中破碎,让碎玻璃像冰雹一样掉下来。我们把这种游戏叫作空中爆炸。
-----
一九九五年十二月十七日
昆明的雨-汪曾祺
========================
昆明的雨-[[汪曾祺]]
-------
宁坤要我给他画一张画,要有昆明的特点。我想了一些时候,画了一幅:右上角画了一片倒挂着的浓绿的仙人掌,末端开出一朵金黄色的花;左下画了几朵青头菌和牛肝菌。题了这样几行字:
昆明人家常于门头挂仙人掌一片以辟邪,仙人掌悬空倒挂,尚能存活开花。于此可见仙人掌生命之顽强,亦可见昆明雨季空气之湿润。雨季则有青头菌、牛肝菌,味极鲜腴。
我想念昆明的雨。
我以前不知道有所谓雨季。“雨季”,是到昆明以后才有了具体感受的。
我不记得昆明的雨季有多长,从几月到几月,好像是相当长的。但是并不使人厌烦。因为是下下停停、停停下下,不是连绵不断,下起来没完。而且并不使人气闷。我觉得昆明雨季气压不低,人很舒服。
昆明的雨季是明亮的、丰满的,使人动情的。城春草木深,孟夏草木长。昆明的雨季,是浓绿的。草木的枝叶里的水分都到了饱和状态,显示出过分的、近于夸张的旺盛。
我的那张画是写实的。我确实亲眼看见过倒挂着还能开花的仙人掌。旧日昆明人家门头上用以辟邪的多是这样一些东西:一面小镜子,周围画着八卦,下面便是一片仙人掌,——在仙人掌上扎一个洞,用麻线穿了,挂在钉子上。昆明仙人掌多,且极肥大。有些人家在菜园的周围种了一圈仙人掌以代替篱笆。——种了仙人掌,猪羊便不敢进园吃菜了。仙人掌有刺,猪和羊怕扎。
昆明菌子极多。雨季逛菜市场,随时可以看到各种菌子。最多,也最便宜的是牛肝菌。牛肝菌下来的时候,家家饭馆卖炒牛肝菌,连西南联大食堂的桌子上都可以有一碗。牛肝菌色如牛肝,滑,嫩,鲜,香,很好吃。炒牛肝菌须多放蒜,否则容易使人晕倒。青头菌比牛肝菌略贵。这种菌子炒熟了也还是浅绿色的,格调比牛肝菌高。菌中之王是鸡,味道鲜浓,无可方比。鸡是名贵的山珍,但并不真的贵得惊人。一盘红烧鸡的价钱和一碗黄焖鸡不相上下,因为这东西在云南并不难得。有一个笑话:有人从昆明坐火车到呈贡,在车上看到地上有一棵鸡,他跳下去把鸡捡了,紧赶两步,还能爬上火车。这笑话用意在说明昆明到呈贡的火车之慢,但也说明鸡随处可见。有一种菌子,中吃不中看,叫做干巴菌。乍一看那样子,真叫人怀疑:这种东西也能吃?!颜色深褐带绿,有点像一堆半干的牛粪或一个被踩破了的马蜂窝。里头还有许多草茎、松毛,乱七八糟!可是下点功夫,把草茎松毛择净,撕成蟹腿肉粗细的丝,和青辣椒同炒,入口便会使你张目结舌:这东西这么好吃?!还有一种菌子,中看不中吃,叫鸡油菌。都是一般大小,有一块银元那样大,的溜圆,颜色浅黄,恰似鸡油一样。这种菌子只有做菜时配色用,没甚味道。
雨季的果子,是杨梅。卖杨梅的都是苗族女孩子,戴一顶小花帽子,穿着扳尖的绣了满帮花的鞋,坐在人家阶石的一角,不时吆唤一声:“卖杨梅——”,声音娇娇的。她们的声音使得昆明雨季的空气更加柔和了。昆明的杨梅很大,有一个乒乓球那样大,颜色黑红黑红的,叫做“火炭梅”。这个名字起得真好,真是像一球烧得炽红的火炭!一点都不酸!我吃过苏州洞庭山的杨梅、井冈山的杨梅,好像都比不上昆明的火炭梅。
雨季的花是缅桂花。缅桂花即白兰花,北京叫做“把儿兰”(这个名字真不好听)。云南把这种花叫做缅桂花,可能最初这种花是从缅甸传入的,而花的香味又有点像桂花,其实这跟桂花实在没有什么关系。——不过话又说回来,别处叫它白兰、把儿兰,它和兰花也挨不上呀,也不过是因为它很香,香得像兰花。我在家乡看到的白兰多是一人高,昆明的缅桂是大树!我在若园巷二号住过,院里有一棵大缅桂,密密的叶子,把四周房间都映绿了。缅桂盛开的时候,房东(是一个五十多岁的寡妇)和她的一个养女,搭了梯子上去摘,每天要摘下来好些,拿到花市上去卖。她大概是怕房客们乱摘她的花,时常给各家送去一些。有时送来一个七寸盘子,里面摆得满满的缅桂花!带着雨珠的缅桂花使我的心软软的,不是怀人,不是思乡。
雨,有时是会引起人一点淡淡的乡愁的。李商隐的《夜雨寄北》是为许多久客的游子而写的。我有一天在积雨少住的早晨和德熙从联大新校舍到莲花池去。看了池里的满池清水,看了着比丘尼装的陈圆圆的石像(传说陈圆圆随吴三桂到云南后出家,暮年投莲花池而死),雨又下起来了。莲花池边有一条小街,有一个小酒店,我们走进去,要了一碟猪头肉,半斤市酒(装在上了绿釉的土瓷杯里),坐了下来。雨下大了。酒店有几只鸡,都把脑袋反插在翅膀下面,一只脚着地,一动也不动地在檐下站着。酒店院子里有一架大木香花。昆明木香花很多。有的小河沿岸都是木香。但是这样大的木香却不多见。一棵木香,爬在架上,把院子遮得严严的。密匝匝的细碎的绿叶,数不清的半开的白花和饱涨的花骨朵,都被雨水淋得湿透了。我们走不了,就这样一直坐到午后。四十年后,我还忘不了那天的情味,写了一首诗:
```
莲花池外少行人,
野店苔痕一寸深。
浊酒一杯天过午,
木香花湿雨沉沉。
我想念昆明的雨。
```
一九八四年五月十九日
老家-史铁生
========================
老家-[[史铁生]]
------
常要在各种表格上填写籍贯,有时候我写北京,有时候写河北涿州,完全即兴。写北京,因为我生在北京长在北京,大约死也不会死到别处去了。写涿州,则因为我从小被告知那是我的老家,我的父母及祖上若干辈人都曾在那儿生活。查词典,籍贯一词的解释是:祖居或个人出生地。——我的即兴碰巧不错。
可是这个被称为老家的地方,我是直到四十六岁的春天才第一次见到它。此前只是不断地听见它。从奶奶的叹息中,从父母对它的思念和恐惧中,从姥姥和一些亲戚偶尔带来的消息里面,以及从对一条梦幻般的河流——拒马河——的想象之中,听见它。但从未见过它,连照片也没有。奶奶说,曾有过几张在老家的照片,可惜都在我懂事之前就销毁了。
四十六岁的春天,我去亲眼证实了它的存在;我跟父亲、伯父和叔叔一起,坐了几小时汽车到了老家。涿州——我有点儿不敢这样叫它。涿州太具体,太实际,因而太陌生。而老家在我的印象里一向虚虚幻幻,更多的是一种情绪,一种声音,甚或一种光线一种气息,与一个实际的地点相距太远。我想我不妨就叫它Z州吧,一个非地理意义的所在更适合连接起一个延续了四十六年的传说。
然而它果真是一个实实在在的地方,有残断的城墙,有一对接近坍圮的古塔,市中心一堆蒿草丛生的黄土据说是当年钟鼓楼的遗址,当然也有崭新的酒店、餐馆、商厦,满街的人群,满街的阳光、尘土和叫卖。城区的格局与旧北京城近似,只是缩小些,简单些。中心大街的路口耸立着一座仿古牌楼(也许确凿是个古迹,唯因旅游事业而修葺一新),匾额上五个大字:天下第一州。中国的天下第一着实不少,这一回又不知是以什么为序。
我们几乎走遍了城中所有的街巷。父亲、伯父和叔叔一路指指点点感慨万千:这儿是什么,那儿是什么,此一家商号过去是什么样子,彼一座宅院曾经属于一户怎样的人家,某一座寺庙当年如何如何香火旺盛,庙会上卖风筝,卖兔爷,卖莲蓬,卖糖人儿、面茶、老豆腐……庙后那条小街曾经多么僻静呀,风传有鬼魅出没,天黑了一个人不敢去走……城北的大石桥呢?哦,还在还在,倒还是老样子,小时候上学放学他们天天都要从那桥上过,桥旁垂柳依依,桥下流水潺潺,当初可是Z州一处著名的景观啊……咱们的小学校呢?在哪儿?那座大楼吗?哎哎,真可是今非昔比啦……
我听见老家在慢慢地扩展,向着尘封的记忆深入,不断推新出陈。往日,像个昏睡的老人慢慢苏醒,唏嘘叹惋之间渐渐生机勃勃起来。历史因此令人怀疑。循着不同的情感,历史原来并不确定。
一路上我想,那么文学所求的真实是什么呢?历史难免是一部御制经典,文学要弥补它,所以看重的是那些沉默的心魂。历史惯以时间为序,勾画空间中的真实,艺术不满足这样的简化,所以去看这人间戏剧深处的复杂,在被普遍所遗漏的地方去询问独具的心流。我于是想起西川的诗:我打开一本书,/一个灵魂就苏醒/……/我阅读一个家族的预言/我看到的痛苦并不比痛苦更多/历史仅记录少数人的丰功伟绩/其他人说话汇合为沉默
我的老家便是这样。Z州,一向都在沉默中。但沉默的深处悲欢俱在,无比生动。那是因为,沉默着的并不就是普遍,而独具的心流恰是被一个普遍读本简化成了沉默。
汽车缓缓行驶,接近史家旧居时,父亲、伯父和叔叔一声不响,唯睁大眼睛望着窗外。史家的旧宅错错落落几乎铺开一条街,但都久失修整,残破不堪。“这儿是六叔家。”“这儿是二姑家。”“这儿是七爷爷和七奶奶。”“那边呢?噢,五舅曾在那儿住过。”……简短的低语,轻得像是怕惊动了什么,以致那一座座院落也似毫无生气,一片死寂。
汽车终于停下,停在了“我们家”的门口。
但他们都不下车,只坐在车里看,看斑驳的院门,看门两边的石墩,看屋檐上摇动的枯草,看屋脊上露出的树梢……伯父首先声明他不想进去:“这样看看,我说就行了。”父亲于是附和:“我说也是,看看就走吧。”我说:“大老远来了,就为看看这房檐上的草吗?”伯父说:“你知道这儿现在住的谁?”“管他住的谁!”“你知道人家会怎么想?人家要是问咱们来干吗,咱们怎么说?”“胡汉三又回来了呗!”我说。他们笑笑,笑得依然谨慎。伯父和父亲执意留在汽车上,叔叔推着我进了院门。院子里没人,屋门也都锁着,两棵枣树尚未发芽,疙疙瘩瘩的枝条与屋檐碰撞发出轻响。叔叔指着两间耳房对我说:“你爸和你妈,当年就在这两间屋里结的婚。”“你看见的?”“当然我看见的。那天史家的人去接你妈,我跟着去了。那时我十三四岁,你妈坐上花轿,我就跟在后头一路跑,直跑回家……”我仔细打量那两间老屋,心想,说不定,我就是从这儿进入人间的。
从那院子里出来,见父亲和伯父在街上来来回回地走,向一个个院门里望,紧张,又似抱着期待。街上没人,处处都安静得近乎怪诞。“走吗?”“走吧。”虽是这样说,但他们仍四处张望。“要不就再歇会儿?”“不啦,走吧。”这时候街的那边出现一个人,慢慢朝这边走。他们便都往路旁靠一靠,看着那个人,看他一步步走近,看他走过面前,又看着他一步步走远。不认识。这个人他们不认识。这个人太年轻了他们不可能认识,也许这个人的父亲或者爷爷他们认识。起风了,风吹动屋檐上的荒草,吹动屋檐下的三顶白发。已经走远的那个人还在回头张望,他必是想:这几个老人站在那儿等什么?
离开Z州城,仿佛离开了一个牵魂索命的地方,父亲和伯父都似吐了一口气:想见她,又怕见她,哎,Z州啊!老家,只是为了这样的想念和这样的恐惧吗?
汽车断断续续地挨着拒马河走,气氛轻松些了。父亲说:“顺着这条河走,就到你母亲的家了。”叔叔说:“这条河也通着你奶奶的家。”伯父说:“哎,你奶奶呀,一辈子就是羡慕别人能出去上学、读书。不是你奶奶一再坚持,我们几个能上得了大学?”几个人都点头,又都沉默。似乎这老家,永远是要为她沉默的。我在《奶奶的星星》里写过,我小时候,奶奶每晚都在灯下念着一本扫盲课本,总是把《国歌》一课中的“吼声”错念成“孔声”。我记得,奶奶总是羡慕母亲,说她赶上了新时代,又上过学,又能到外面去工作……
拒马河在太阳下面闪闪发光。他们说这河以前要宽阔得多,水也比现在深,浪也比现在大。他们说,以前,这一块平原差不多都靠着这条河。他们说,那时候,在河湾水浅的地方,随时你都能摸上一条大鲤鱼来。他们说,那时候这河里有的是鱼虾、螃蟹、莲藕、鸡头米,苇子长得比人高,密不透风,五月节包粽子,米泡好了再去劈粽叶也来得及……
母亲的家在Z州城外的张村。那村子真是大,汽车从村东到村西开了差不多一刻钟。拒马河从村边流过,我们挨近一座石桥停下。这情景让我想起小时候读过的一课书:拒马河,靠山坡,弯弯曲曲绕村过……
父亲说,就是这桥。我们走上桥,父亲说,看看吧,那就是你母亲以前住过的房子。
高高的土坡上,一排陈旧的瓦房,围了一圈简陋的黄土矮墙,夕阳下尤其显得寂寞,黯然,甚至颓唐。那矮墙,父亲说原先没有,原先可不是这样,原先是一道青砖的围墙,原先还有一座漂亮的门楼,门前有两棵老槐树,母亲经常就坐在那槐树下读书……
这回我们一起走进那院子。院子里堆着柴草,堆着木料、灰砂,大约这老房是想换换模样了。主人不在家,只一群鸡“咯咯”地叫。
叔叔说:“就是这间屋。你爸就是从这儿把你妈娶走的。”
“真的?”
“问他呀。”
父亲避开我的目光,不说话,满脸通红,转身走开。我不敢再说什么。我知道那不是因为别的,是因为不能忘记的痛苦。母亲去世十年后的那个清明节,我和妹妹曾跟随父亲一起去给母亲扫墓,但是母亲的墓已经不见,那时父亲就是这样的表情,满脸通红,一言不发,东一头西一头地疾走,满山遍野地找寻着一棵红枫树,母亲就葬在那棵树旁。我曾写过:母亲离开得太突然,且只有49岁,那时我们三个都被这突来的厄运吓傻了,十年中谁也不敢提起母亲一个字,不敢说她,不敢想她,连她的照片也收起来不敢看……直到十年后,那个清明节,我们不约而同地说起该去看看母亲的坟了;不约而同——可见谁也没有忘记,一刻都没有忘记……
我看着母亲出嫁前住的那间小屋,不由得有一个问题:那时候我在哪儿?那时候是不是已经注定,四十多年之后她的儿子才会来看望这间小屋,来这儿想象母亲当年出嫁的情景?1948年,母亲十九岁,未来其实都已经写好了,站在我四十六岁的地方看,母亲的一生已在那一阵喜庆的唢呐声中一字一句地写好了,不可更改。那唢呐声,沿着时间,沿着阳光和季节,一路风尘雨雪,传到今天才听出它的哀婉和苍凉。可是,十九岁的母亲听见了什么?十九岁的新娘有着怎样的梦想?十九岁的少女走出这个院子的时候历史与她何干?她提着婚礼服的裙裾,走出屋门,有没有再看看这个院落?她小心或者急切地走出这间小屋,走过这条甬道,转过这个墙角,迈过这道门槛,然后驻足,抬眼望去,她看见了什么?啊,拒马河!拒马河上绿柳如烟,雾霭飘荡,未来就藏在那一片浩渺的苍茫之中……我循着母亲出嫁的路,走出院子,走向河岸,拒马河悲喜不惊,必像四十多年前一样,翻动着浪花,平稳浩荡奔其前程……
我坐在河边,想着母亲曾经就在这儿玩耍,就在这儿长大,也许她就攀过那棵树,也许她就戏过那片水,也许她就躺在这片草丛中想象未来,然后,她离开了这儿,走进了那个喧嚣的北京城,走进了一团说不清的历史。我转动轮椅,在河边慢慢走,想着:从那个坐在老槐树下读书的少女,到她的儿子终于来看望这座残破的宅院,这中间发生了多少事呀。我望着这条两端不见头的河,想:那顶花轿顺着这河岸走,锣鼓声渐渐远了,唢呐声或许伴母亲一路,那一段漫长的时间里她是怎样的心情?一个人,离开故土,离开童年和少年的梦境,大约都是一样——就像我去串联、去插队的时候一样,顾不上别的,单被前途的神秘所吸引,在那神秘中描画幸福与浪漫……
如今我常猜想母亲的感情经历。父亲憨厚老实到完全缺乏浪漫,母亲可是天生的多情多梦,她有没有过另外的想法?从那绿柳如烟的河岸上走来的第一个男人,是不是父亲?在那雾霭苍茫的河岸上执意不去的最后一个男人,是不是父亲?甚至,在那绵长的唢呐声中,有没有一个立于河岸一直眺望着母亲的花轿渐行渐杳的男人?还有,随后的若干年中,她对她的爱情是否满意?我所能做的唯一见证是:母亲对父亲的缺乏浪漫常常哭笑不得,甚至叹气连声,但这个男人的诚实、厚道,让她信赖终生。
母亲去世时,我坐在轮椅里连一条谋生的路也还没找到,妹妹才十三岁,父亲一个人担起了这个家。二十年,这二十年母亲在天国一定什么都看见了。二十年后一切都好了,那个冬天,一夜之间,父亲就离开了我们。他仿佛终于完成了母亲的托付,终于熬过了他不能不熬的痛苦、操劳和孤独,然后急着去找母亲了——既然她在这尘世间连坟墓都没有留下。
老家,Z州,张村,拒马河……这一片传说或这一片梦境,常让我想:倘那河岸上第一个走来的男人,或那河岸上执意不去的最后一个男人,都不是我的父亲,倘那个立于河岸一直眺望着母亲的花轿渐行渐杳的男人成了我的父亲,我还是我吗?当然,我只能是我,但却是另一个我了。这样看,我的由来是否过于偶然?任何人的由来是否都太偶然?都偶然,还有什么偶然可言?我必然是这一个。每个人都必然是这一个。所有的人都是一样,从老家久远的历史中抽取一个点,一条线索,作为开端。这开端,就像那绵绵不断的唢呐,难免会引出母亲一样的坎坷与苦难,但必须到达父亲一样的煎熬与责任,这正是命运要你接受的“想念与恐惧”吧。
离歌-周晓枫
========================
离歌-[[周晓枫]]
------
1
就是在那天。
那天,我跑到西四环看影展片目:《超新约全书》。
情节设计天马行空,那种想象力,长期在自由里才能养成那种百无禁忌的天真。当住在普通三居室的小女孩伊娅,抱怨她的父亲是上帝,唯我独尊,不考虑任何他人情感和意见,他暴虐、自私,喜欢给陌生人制造悲剧的时候——观众没想到,这位穿松垮背心、邋遢格衬衫和家常裤衩的大叔,竟然,真的就是上帝本尊。
上帝靠一台电脑和横行霸道的作风统治世界。伊娅决定改变运行的法则,在她通过滚筒洗衣机抵达人间之前,小女孩擅闯父亲的禁地,把每个人的死期通过手机传送给它的主人。刚开始,接收信息的人以为是谁的恶作剧,很快预言验证:还剩下半分钟寿命的人绝对活不到一分钟。有人发现自己的人生还有漫长的余数,高龄才会离世,于是成为无畏的挑衅者:他毫无保护地从高楼往下跳,砸死的是路人他活着;他从火车上往下跳,正好有盛满面粉的运输车经过;他从飞机上往下跳,落在另一架飞机宽阔的翅膀上;除了偶尔外伤,或者脖子上围着用于恢复功能的颈圈,他无损。当人们知道自己的死期,胆怯的劳作者不再被束缚,忠诚的婚姻受害者不再挣扎,自由就像垂到嘴边的果实那样到来了。
死亡,在这个世界如此自然,就像随手翻开的是一张带花色的纸牌。我们甚至可以挑衅上帝,但必须臣服死神……他有一双喜怒无常、暗杀者的眼睛。
我所在的影院,位置偏西,离北京的火葬场近。看电影的时候,我毫不知情,当时他身体的气息是否已经散尽?当我跟随剧情笑着,吃爆米花,喝带气的苏打水——我不知道,与此同时,一个二十年前撤离我生活轨道的朋友彻底失踪,他的五官已经消失在自己的躯体腾起的火焰和烟雾里。他从一粒目力难辨的受精卵,变成一个有体积的受难者离世,用了整整四十九年;而摧毁一个成年男人的206块骨头、639块肌肉、32颗牙齿、10根手指和10根脚趾……摧毁和消灭这些,只需要短短二十分钟。他没有剩下什么,除了散落的骨块和灰烬。消失了,他黝黑的皮肤、宽阔的鼻翼、草食哺乳动物的眼睛。
2
当接到小夜电话,我颇为意外。
她的开场白是:“我是屠苏的初恋,也是他的合法妻子。”声音几分强硬、几分委屈,然后是长久的停顿和哽咽,是令我错愕的颤抖着的呼吸……我不敢肯定,对方压抑的是哭腔还是一腔愤怒。我懵了,从没遇过这种情况,她像是处于弱势的正室打给行势见涨的小三,既有委屈,又带着示威的意思,像在进行一场并不恰当的投诉。
我控制住疑惑,也控制语调以便传递友善,询问怎么回事,并解释说我与屠苏,既无恋爱前史,又无后来的暧昧纠缠,除了中间打过一个短暂电话,我们二十年来断无联系。
小夜说,不必澄清,屠苏和我的关系她相当清楚,她只是来通知我一个迟到的消息。半个月前,屠苏独自死在深夜的办公室,猝死病因不明。追悼会恰恰安排在我看《超新约全书》那天,当我为编剧的构思击节叫好之时……他被火化,灰飞烟灭。
来不及消化突如其来的噩耗,我发呆,不知怎么跟小夜交流。挂了电话,我沉默,长久盯着窗外,没有任何痛感。我为自己的平静感到好奇和羞愧。时间,停了。直到一只皮毛松散、形色俱厉的玳瑁色野猫,穿过阳台,纵身跳入冬青灌丛……我忽然难以自控地流泪。
3
二十多年前,我做儿童文学编辑,业余写作,写得也业余。
早于屠苏,我先认识他的几位同事。他们或公开写小说,或暗地写诗,这些在政府机关的年轻公务员,热情洋溢,并未被训诫为官僚制度下的庸吏。大家偶尔交流,不算密切,但关系融洽。我还为其中一位介绍过女朋友,可惜双方相处寡淡,很快分道扬镳。好在大家年轻,对爱情和婚姻心怀向往,但这个年龄,它们更靠近束缚而不是安慰。
见人之前,我最先见到的是屠苏的信。字迹清秀,他的表述清晰又克制,让人感到出色的文笔和教养。屠苏从同事那里读过我的作品,希望结识,聊聊文学。他把信直接寄到我的工作单位,越过他的同事——屠苏没有跟谁索要我的地址和电话,也没跟谁打招呼。这封漂亮的信,这个空降的高人,令我好奇又敬仰。
我按屠苏留下的号码打了电话,他说话沉稳,却有中提琴的胸腔共鸣。据研究者发现,刻意压低嗓音会使说话者听起来更强势,而拔高声调则削减一个人的权威程度。屠苏的音量不高,带着一点轻微的鼻音,总像感冒刚刚开始的样子,给人信赖感,同时又带有让人动心的柔弱感。他没有通常难以克服的口音,应当从中学就开始坚持使用普通话、并在北京生活的数年中不断校正自己才可能有那么清晰的吐字,不过从温和、缓慢的语速里,还是隐约听出几丝南方地域痕迹。
忘了电话里聊了多长时间,我随后写了一封其实是模仿他行文风格的回信——二十世纪九十年代,人们还保留写信传统。鸿雁传书,相见恨晚。
屠苏温良淳厚,细腻体贴,有一双草食动物般微微湿润的眼睛。屠苏其他的优点被我随后发现。善良。聪颖。博学。专注。他内向安静,不饶舌,却是一个极好的谈话对手。屠苏毕业于北大,受到扎实的学术系统训练,加之阅读涉猎广泛,我们虽然年纪接近,但在许多方面他都堪称我的师长。是在屠苏的指导下,我认真拜读马尔克斯和博尔赫斯的作品,而不是把他们仅仅当作外国文学史里略带拗口的名字。屠苏鼓励我的文字,说有灵气,他的口气带着发现得意门生的欣慰。
最初交往的数月,我和屠苏的联系,迅速变得比那些我早已结识的朋友们密切。他让我获益,明白自己在知识和认识上的误区与盲区。我喜欢和屠苏聊天,我们沉浸其中的海阔天空,旁听者大概觉得云山雾罩,因为内容是形而上的,抽象而不食人间烟火。我们谈文学,也谈我根本连基础都没有的哲学和逻辑。屠苏好脾气,能够忍耐对牛弹琴;对于牛嚼牡丹的我来说,则是齿颊留香的享受。
我们都喜欢阅读,默默写作,不为博取功名,因为它能让我们探索事物的极限,包括挖掘自身的可能……写下文字,是为灵魂种粮食。写作是孤独的,永远独自面对困境,所以遇到心有灵犀的同道,格外欣喜。屠苏新写了什么拿给我看,如果启动灵感,我就应和一篇。我根据他的行文节奏来调整自己的,乍看,珠联璧合。我们没有意识到自己的身影,在彼此作品里都留下了纹身。沉浸在文字里,我们像两个研习武功的人。屠苏比我技艺精进,我把他当作潜在的师长。
周末,我兴高采烈地跑去和屠苏聊天;过了正点,才随便地找个餐馆吃饭。屠苏慷慨,秉承由绅士结账的旧习;可我有些男孩性格,买单时当仁不让。我平常也大大咧咧,屠苏遗憾于我不是淑女。我嘻嘻哈哈,从未想过从他的那个良。我对屠苏说:按你的要求,我再从也是个良,不如当自己的优。我们彼此都不是适合对方胃口的家乡菜,但把坐言欢,我们刻意或潜意识忽略那些可能引发的矛盾;我们盘旋半空,回避溅上大地的泥浆。有一次,在拥塞的小餐馆,邻桌的菜都快挤上我们的桌子,我低头看见遍布通红的辣椒之间,是剁碎的牛蛙,一块眼睛一块嘴巴的;然后我抬起眼皮,视若无睹,继续和屠苏谈及短篇小说的叙事技巧。从余光里,我看到邻座的酒徒:一双发呆的眼睛,半张错愕的嘴。
4
屠苏自称本少爷,言谈举止,有些蔑视尘俗。和他相比,我气息混浊,常自惭形秽。其实屠苏并非优渥家境滋养出的少爷,相反,出身清苦,他是从农村底层里挣扎出来的。屠苏的脚趾分得很开,他指着凉鞋里的这对蒲扇告诉我,家里以前是渔民,常年赤足在波涛摇晃的船板站立,才长出有利平衡的骨架构造。屠苏与打鱼的祖辈没有隔出几代,身体的痕迹尚未随环境而改变。
屠苏没有乡村孩子的自卑,他比常人清高。他曾是当地高考状元,据说理科成绩极其优异,只因热爱文学,才弃理从文。屠苏依然保持了出色的数理化基础与学习能力。仅靠自学,他的计算机水平几近专业,擅长组装、修理和编程。他博闻强记,研读历史、哲学、人类学、政治学。屠苏智商超群,难免孤傲。他脾气虽好,也会因对方没有及时领会自己的暗示滋生恼怒。不过,屠苏克制,很少流露。无论情感还是仕途,他都希望不战而屈人之兵。
屠苏告诉我,他有生以来第一个暗恋的姑娘,是他中学老师的女儿,她写诗,因此卓然不群。这段暗恋,徒劳无功,后来两人失散江湖。真正的初恋女朋友叫七虹,大学期间以分手告终,他还写过散文,纪念那段令他心痛的恋情。我尊重屠苏的感情,偶尔也拿他对七虹的怀念打趣,说回忆和泡菜腐乳之类一样,都是借助了腐烂的力量,才产生些许与众不同的味道。
他不够高大,我不够漂亮,作为两个皆有虚荣心的人,我们的外貌都没有达至对方的基本要求。我偏好小爸爸类型,喜欢清瘦高挑,既伤感又幽默那种。屠苏喜欢甜美淑女,最好气质上靠近南方水土。幸亏我们长得不达标,这是对彼此的适度保护。屠苏和我都心性敏感,容易在感情贸易上计较顺逆之差,影响和破坏美好的平衡。我想,上帝不会让两个心灵易损的人结成同盟,他们惨淡的结局会让神灵感觉自己无能。尽管屠苏和我不足以引发心动,可我们的关系曾遭到尴尬的误会。
一天晚上,屠苏和我坐在护城河边的草地上聊天,我们没有任何可疑的情绪和动作,只是没注意到时间流逝、夜色深沉。突然,从马路上方射过两道手电筒的刺目光柱。为了保障北京正在召开的重要会议,加班加点的联防队员们,五六个人组成自行车队巡逻。我第一次知道如何抓嫖,首先迅速分隔二人,询问对方名字。我觉得联防队员看到我的近景特写,立刻粉碎了预想,之所以持续质询,不过是因为启动了程序无法收场。我如实回答问题,是不想给在政府部门工作的屠苏招惹麻烦,但内心几乎笑场,能把我当作流莺算是褒奖,行业得多缺人手,才能轮得到我这种模样上岗。荒谬的误会解除,我笑出声,屠苏气愤不已。他才不看成玩笑呢,他视为侮辱。
屠苏缺少与异性朋友交往的经验,而我的好友以异性居多。我最为漫长和信任的友谊,是与十七岁就认识的两个高中同学。没做过情侣,可延续至今,不仅我和这两个男孩是朋友,和他们的太太是朋友,乃至两家父母都成了朋友。所以对我来说,不存在关系上的迷惑与障碍。我愿和屠苏亦是如此终生信赖的朋友:发白齿豁,依然鸡犬相闻、肝胆相照。
5
我不知屠苏怎么在官样文章和文学之间平衡自己。公文,并非公共的文学,走的是文学的反途。屠苏没有表现过多的挣扎。随着交往,屠苏与我的矛盾倒是渐露端倪。
屠苏不喜欢我穿牛仔短裤,不喜欢我笑起来肆意。我难免抵触:你又不是我男朋友,管得着吗?我拒不悔改,愈加对抗地穿上自己并不喜欢的夹脚凉鞋。他们单位楼上楼下有我认识的朋友,都是早于屠苏的熟人。我去聊天,难免照面、打招呼,或者约上大家聚餐。屠苏厌恶某君做派,说他整天热衷攀附,孜孜以求的,是一把主席台上的座椅和一个放大音量、伴有回声的麦克风。他惊讶于我并不反感接触某君,还谈笑风生——屠苏蹙眉:“有什么可说的呢?聊得那么热闹。”我戏言:“你觉得他拉拢关系可耻?人人都是裸生而来,如果他能结交超乎寻常的莫逆关系,证明他在这方面既有本事又肯下功夫。”我自己无意于人海竞争,但看到仕途挣扎者也能理解——人各有志,各有他的不安与不易。屠苏对我的态度是轻视的,认为我丧失原则和立场。
屠苏对我挑剔,流露冷淡和嘲讽,我云里雾里。我追问原因,他不讲明为什么,只是怨意越来越难以克制。我们靠着美好的惯性以及隐约的猜忌,继续来往。后来,听说屠苏交了女朋友,我好奇又热情地提出和她见面,大家一起玩儿。被屠苏拒绝。他恋爱的那个阶段,假设我联络少了,他语含讥诮,说我薄情寡义;等我改正错误积极致电,他用失望的腔调说:“哎呀,怎么是你,我以为是我女朋友呢。”我糊涂、茫然又生气,不知如何相处。
屠苏有一天突然表明,希望和我有个告别之夜,从此咫尺天涯,相见不如怀念。我习惯静水深流,不明白为什么这么快就是山穷水尽的结束。尽管不知道哪里得罪屠苏,但我年少气盛,自尊不允许我继续一段需要挽留的情谊。我当时有种直感,屠苏放弃与我的友谊,专注恋爱,投入预备状态的婚姻,似乎完成了重要的内心转变——他放弃悬谈理想,决心务实生活。我所代表的一切,和屠苏的未来都是不兼容的。
最后的见面,屠苏在我家睡了一夜。同一张床,和衣枕卧,秋毫无犯。在这个充满纪念仪式感的告别之夜,彼此气息达至耳畔,我们好像需要格外调整和校正自己的心跳。直至天明,我假装没看到他夏天薄薄的浅色裤子外面情欲的湿迹。克己复礼,他有君子之风。屠苏眼睛里含了泪光,对我说:即使终生不再相见,在心理上,你是我一辈子或明或暗的情人。
此生,我再也没有见过屠苏。
6
分别之后的两三年,一个共同认识的朋友说屠苏后来提及,说和我“心心相印”。
分别之后的七八年,我意外发现屠苏用网名发表的回忆文章,再次说在精神世界里,我将是他“一辈子或明或暗的情人”。相隔时空的深情,让我落泪,但内心骄傲和往日的不快阴影,让我畏怯于重新建立现实中的联系。按照以往习惯,我默默以文字应和,给他起名“匹诺曹”。
我想对匹诺曹说,你是我天然的朋友,不加糖,不含色素,没有防腐剂。我贪图这种友谊,希望它源远流长,希望我们发白齿豁的时候还可以在一起温故知新。也许,纯粹的东西保质期不长,因为它连空气中的细菌都难以对抗。这是在中途,谁是唇齿相依的爱人,谁又是肝胆相照的兄弟?是否已到终点,为什么匹诺曹成为一张旅游地图──曾经是指引,很快便成纪念?
我曾经无法不炫耀,像贪吃水果的人,手指上难免沾染甜的果汁。我在与别人的交谈中流露,在文字中书写,匹诺曹就像长篇连续剧中的主人公,在每一集里占有戏份。惯性持续下来,即使在我和匹诺曹天各一方以后,我还在写作中编造他的存在,化装他的身份,我杜撰种种故事情节,以使月白风清的友谊至少能够在纸页上生生不息。因为融合部分真实,我的谎言看起来天衣无缝。真话有什么好呢,只能让我们成为平庸无奇的孩子;我宁可做一个童话中撒谎的木偶,被惩罚时刻威胁,也不愿忠诚于缺乏想象力的现实。
现在我沉默,我愿我是小偷,我愿我有熏黑的心和灵活的手,可以把匹诺曹从昨天的口袋里安全偷回,又不受到任何责问。然而,时间总是要收回它曾经许诺永远给我们的。所谓成熟,不过是你不会再为丢了的即使最宝贵的东西而伤心。所以,我就若无其事,只是偶尔在深夜里想一想匹诺曹说过的话,就像重逢。我由此得知回忆的音量:它像耳语,亲近,又忧伤。
和屠苏分别大约十几年之后,我偶遇路平安。当年我们都在一起玩儿,路平安是屠苏的同学兼同事,虽在学校不是同级,在机关不是同一个部门,但了解屠苏的基本情况。路平安说屠苏离婚了,事业坎坷,过得不好。我得到屠苏的号码,略带忐忑地打过去。屠苏的反应出乎意料的古怪,他依旧语速缓慢:“哦,你终于打来电话了。”那种口气里有犹豫迟疑,有叹息,但肯定说不上热情。那些所谓的惋惜和依恋,难道只是屠苏的文字抒情?也许他只想把我当作一块供起来的牌位,并不需要我复活。我匆忙向他要了快递地址,给屠苏寄了几本自己的散文集。然后,再次断了音信。既然他不需要对友谊温故,我何求知新。
不过,我始终感恩屠苏,因为他在文学上给予的鼓励和指引。有些隐身人的存在,对我们如此重要。你醒的时候,有人和你一起醒了;你睡的时候,有人和你一起睡了。虽然相忘于江湖,像一盘打得散落的棋……但,他只要在,就够了。
二十年后,突然,平衡木那端空了。没有了“我们”,我只是我自己,体会从复数变成单数的孤独。屠苏像水滴进入池塘,返回虚无。
7
去家里看望小夜,屠苏正好离世一个月。
小夜哭了,想找我聊天。我心怀恻隐,马上开车出门,前去安慰这个可怜的新寡。而且,屠苏提前离世,也让我对分别之后,他人生所走过的江河有一点好奇。
到达屠苏位于东三环的家,颇费周折。居住了七八年的小夜说不清家庭地址。我本来就路痴,小夜的信息数次出错,我被互相矛盾的指示弄懵了,绕来绕去。屠苏自己不谙世事,也找了这么不食人间烟火的老婆。
最后拐到一条路况复杂的窄小胡同里,如鲠在喉,车开进去不是,开出来也不是。我犹豫着是否要在一个垃圾堆旁边停车,混合着尿渍色的烂泥地,根本下不去脚。幸运的是,我在另外一个垃圾点找到勉强塞放的车位。
与屠苏小区仅一墙之隔的这条胡同,破败至此。临近CBD核心区和繁荣的三环主路,此处有高昂得令人咋舌的地价,但这条盲肠般隐蔽着样貌和功能的胡同,两侧建筑,一样简陋。一侧是廉价钢板房的小饭馆,另一侧楼体陈旧,有的房间竟然没有完整窗户,有的纱窗是千疮百孔,垂下长长的已经不能被风吹动的缕缕灰尘,几乎成了半个窗帘。没人修整,都等着拆迁——既然被摧毁的时刻指日可待,在窗户上加固一根钉子都是浪费。这是一条被乞求速死的胡同。走在里面,路段分别有不同的味道,有时气味也许并不存在,是视觉经验带来的想象中的并不美妙的幻嗅。
从胡同里能看到屠苏家所在的楼,可院门不冲这个方向,必须绕行。真正的入口,位于一座现代商厦后面。我只走了六七十米,绕了个弯儿,就从旧社会走进了明晃晃的新时代。商厦一层的星巴克里集中各式各样的城市脸,或聊天,或发呆,或看杂志,或敲击电脑键盘。在星巴克喝咖啡,是便宜又体面的社交方式和休闲方式。
咖啡馆的落地玻璃,和胡同里那些破漏纱窗,离得多远……六七十米,还是六七十年?还是离得多近……就像窗户,打破就在瞬间?从星巴克旁边的小路穿过去,就是屠苏家肉粉色的楼。高档楼宇几乎避免的那种肉粉色。
电梯里有胡同里的气味。
8
小夜圆润,长相年轻,比实际年龄显小。娇巧玲珑,有点袖珍,和她相比,我显得体格健硕,像个鲁莽的女巨人。小夜眼睛潮红,哭过不久的样子。她聪明,口才很好,表达流畅,说起来头头是道,不像电话里那个缺乏常识的指路者。
环顾亡友的家,我暗暗感慨。屠苏年近半百,来北京三十个年头,和同龄人相比,居住条件欠佳。单位的周转房,合住,屠苏的使用权只限于两室之一。好在另外那屋主人住到岳父岳母家,屠苏这才享有基础的隐私。家里布置堪称简陋,像年轻北漂住的过渡房。桌椅是在夜市大排档常见的,桌子是可折叠的简易桌子,椅子是面积圆小、无靠背和扶手的简易塑料椅——我小心坐下去,姿态谨慎,怕坐翻摔在地上。
与此形成鲜明对比的,是比过道大不了多少的勉强当作客厅的空间里,满墙,都是屠苏参加重大活动与领导或名人的合影。在这个微型展示厅里,贴满了逝者的殊荣。墙上的屠苏在各种场合微笑,都是小夜为了纪念离去的爱人,洗印出来的。
小夜说:你寄给屠苏的书,他没时间看,我读了。小夜的话让我心里一沉,并非因为自己被冷落,是因为突然意识到,我为什么觉得屠苏的家里有什么不对:他的书呢?我所认识的屠苏,办公室和宿舍里到处是他的书,连睡觉的单人床一半都让书占了,像他永恒的伴侣。他家虽然空间有限,总比集体宿舍宽绰,可我的目力所及,却是奇怪的空空荡荡,只有两个简易的小书架,没有溢出它们之外的任何本册。坐在屠苏生前居住的屋子里,我感觉不到他的气息。那个文学上曾经的点拨者与指路人去哪儿了?那个沉迷阅读的博学者去哪儿了?
通过小夜的讲述,我聆听屠苏的爱情神话。小夜正是屠苏此生第一个心动女生,那个少女诗人,两人同班,可是高中毕业后就天悬地隔地分开了,令屠苏分外失落。七虹算是屠苏正式的初恋——但小夜说,七虹其实是自己的替身;然而,自己离去造成的重创是任何人都弥补不了的。不仅七虹,包括后来屠苏未曾谋面的短暂笔友,还有写作的我,不过是屠苏在寻找小夜的种种碎片罢了。小夜承认自己以前写诗,具有天赋的她之所以放弃,是觉得文学虚无飘渺,她愿意在社会建设中担当更重要的角色。小夜说重逢之前,屠苏厌世情绪严重,万念俱灰,准备剃度出家。小夜再度出现,一切峰回路转,否则屠苏孤独的灵魂无以为寄。
9
我一直不明白,即使屠苏心有所属,也并不妨碍与我的友谊。或许是,对于男女之间的情感,屠苏认为非此即彼:不能往婚姻方向发展,那么异性之间的友谊也应及时切割,所以他才有那么庄重而正式的告别仪式。算上去,屠苏从谈恋爱到结婚之间,我是中间一个短暂插曲。
愉快聊天的同时,屠苏需要消化隐秘的不适,包括我的成长。他喜欢被轻微仰视的感觉,喜欢被夸奖。我最初低于屠苏的写作水准,很快差别并不明显。我直言,他需警惕唯美却乏力的修辞倾向,避免过多使用酸甜气味的形容词。屠苏喜欢柔弱类型,我却拒绝扮演言情剧中目光迷蒙、心性依顺的女主角。
和我告别之后,屠苏迅速结婚。新娘叫明慧,与屠苏单位的原领导是同乡,毕业实习期认识了屠苏,芳心暗许。于是,她请这个叔叔辈的领导当恋爱介绍人。关于屠苏成家的细节,以及屠苏转变心意的历程,我知之甚少,也从未主动打听过。小夜说,当初屠苏选择明慧,是因为对单位领导的介绍不敢违抗,也希望明慧能用关系来推动自己的事业。对小夜的说法,我心生疑虑,与屠苏曾经的交谈,以及他对文学的热爱,让我觉得他不至如此世故,不会为了所谓事业,牺牲感情。我想,明慧身上,一定有什么东西让屠苏迷恋过。
小夜说,屠苏在走入婚姻的过程中就犹豫过,甚至在老家摆了酒席之后还萌生退意。但领导不满,在单位已公开关系,在老家已举行了准婚礼,说不愿意就不愿意了,怎么对明慧交待?不行,得领结婚证书。领导如此在乎明慧与屠苏的婚姻,这让屠苏婚后对领导额外的关照有了期待。
领导愿意给屠苏介绍女朋友,举手之劳,成人之美;若论提拔干部,就是另一回事了。明慧,都算不上领导近切的熟人。屠苏失策了。小夜愤怒于:明慧是地地道道的农村人,家境穷苦,甚至比屠家还惨。柴米油盐的日常生活,让屠苏也让明慧,失去了彼此的优势。一旦发现明慧对自己未来的仕途不会提供什么帮助,这段委屈之下成就的婚姻成为对屠苏的煎熬。
10
和小夜见面后,我也与明慧联系过。是路平安提供的电话号码。
明慧的语气平静沉稳,给人感觉有礼貌、擅长倾听。明慧也在机关工作,职业带来的秩序感让她稍显严肃,听得出,是言必行、行必果的人。她回电,和在短信里事先答应的时间都精确吻合,前后不会相差几分钟。
明慧总结,屠苏智商高、情商不高,难以处理复杂的情感和交错的社会关系。他选择困难,反复衡量,往往选出的是负面和恶果。无论仕途还是婚姻。
屠苏本来在机关很好,按部就班,循序渐进,论资排辈熬年头也能上去。后来有个重大项目上马,公司开创者正是屠苏的老上级,在他的动员下,屠苏跃跃欲试。毕竟那边待遇更高,只不过这项事业如果遇挫,工作人员将自谋去处,无论是过去的机关还是现在的公司,都不再负责解决出路。明慧提醒,新岗位假如真是个好机会,早被利益高层的七大姑八大姨捷足先登,轮不到你屠苏。此前,屠苏就想过应聘那些经济回报丰厚的企业,明慧就劝阻过:在高效率、快节奏的企业,屠苏根本拼不过生龙活虎、野心勃勃的年轻人。她说屠苏还是适合留在机关,平平稳稳地度此余生。其实,以屠苏那种知识分子的心性,机关也不适合,做领导需要擅长摆布,业务能力可以弱于协调能力,而屠苏胜在书本层面的智力,在其他领域明显不足。明慧所谏,是肺腑之言,且是两害相权择其轻的考量。然而屠苏看来,妻子的温情和体谅既是安慰,也有自己的能力被轻视和低估带来的遗憾。屠苏自负,觉得有些发达者只是凭借意外的机遇,假设位于同一起跑线,屠苏觉得自己未必屈居人后。
多年的学霸生涯,让屠苏习惯被人仰视。没有了崇拜的明慧,让屠苏觉得一无是处。屠苏之所以果断地换工作,他的决心和力量,除了憧憬,也包含被婚姻捆绑所产生的对抗。他对明慧失望、对抗,他需要释放自己作为出色者的能量……和委屈。他从这个婚姻里什么也没得到,倒赔进了过去与未来的可能性。也许正是因为这点不甘,当屠苏的能力被小夜肯定并放大时,他的心理得到了豁然的满足。屠苏执意创业,还有隐秘原因,当时他已与小夜暗通款曲,并受到后者的跳槽鼓励。几年之后,投身的宏大事业不了了之,原来的岗位早被鸠占鹊巢,屠苏重回机关已没有选择,委身一个既次要又清苦的部门,升迁遥遥。
就在离开机关又重返的几年间,屠苏离婚了。
11
很难说清,在屠苏与明慧解体的婚姻里,小夜负有多大的责任。即使小夜不出现,梦想与现实的巨大落差,让屠苏也许也难与明慧白头到老。关键是,在屠苏困顿于仕途和婚姻的时候,小夜适时登场。
作为屠苏一生中最早的暗恋对象,小夜的再次出场充满欲扬先抑的戏剧性。
小夜自述,第一个打给屠苏的电话,她诉说自己离婚后的落难处境:没有钱、没有工作、没有地方住。善良的屠苏动了恻隐之心,于是英雄救美,飞蛾扑火。小夜把玩笑开得特别长久和正式,她一直维持寒苦的形象,这让屠苏怜惜不已,想尽办法弄到小夜爸爸的账号,立即打款。屠苏在与明慧的婚姻里或许没有完全的满足,像一颗蛀牙没有得到及时修补,小小的溃口,本来可以重视、也可以忽略不计,可屠苏让自己的生活从此决堤。可怜的屠苏,他的温柔善良,他的文学爱好,都成为有害的悲剧因子。他的软弱,他对初恋的怜惜与姑息,他尚未泯灭的拯救落难女孩的公子情怀,他文人心里那点不切实际的爱情期许……一切,导致他做出莽撞而沉重的选择。
自从与屠苏重新联络,小夜就不停往返北京。以屠苏财力,无以支撑宾馆住宿的开销。那时一家人住在明慧的房子里,屠苏自己有时住在合租的周转房——他在这里藏娇小夜。藏不住。这是单位的房产,同事都住这里。何况,小夜公然以屠苏爱人自称。和所有俗套剧本一样,明慧发现,屠苏总是躲在阳台偷偷发短信。屠苏的掩饰技巧乏善可陈,窥出端倪的明慧偷袭,马上就翻出底料。
明慧学识低于屠苏,即使屠苏难以实现她寄予的厚望,她也逐渐接受现实。明慧喜欢屠苏身上的老实厚道,也接受他交际上的吃力和经济上的困窘,但屠苏与小夜那种公然的僭越,触动了明慧的婚姻底线。痛苦之中,明慧选择隐忍;坚持提出离婚的,却是屠苏。两三年的拉锯战僵持下来,明慧无奈放弃。
罔顾幼齿的孩子,屠苏之所以主动且强烈地要求离婚,离婚之后几天就迅速迎娶小夜,原因无外乎几个。没有耐心忍受与明慧的争执。急于安慰受了委屈的小夜。完全公开的艳遇,使屠苏从无可挑剔的好形象,变成令人指摘的角色,他需要法律上的正式名分来平息非议。或许还有个重要原因,是小夜拟写的剧情陡然反转。
他的温柔善良,他的文学爱好,都成为有害的悲剧因子。他的软弱,他对初恋的怜惜与姑息,他尚未泯灭的拯救落难女孩的公子情怀,他文人心里那点不切实际的爱情期许……
小夜并非她最初所形容的走投无路。小夜说,她带屠苏去自己所在的城市,指点他参观自己体面的住所,屠苏才明白这是一出苦情戏。小夜的表述,从一个落难女孩的极端,走向了呼风唤雨女能人的另外一个极端。
12
谈到与屠苏的重逢,小夜说,她之所以联络屠苏,因为一个梦。她梦到屠苏死了。
其时,离异的小夜还在省会,她说在北京有个身居要职的司局级男友,地位和才华都出众。距离并未构成异地恋的干扰,男友心仪并宠爱小夜多年。经过磨合与考验,两人正紧锣密鼓地筹备婚期。当准备迎娶小夜的男友得知小夜噩梦,心疼惊悸的女友,他很快利用人脉找到屠苏下落,希望小夜解除心中芥蒂。
小夜甘愿离开功成名就的男友,放弃成为高官夫人的好运,决意走向潦倒却痴情的屠苏,走向他捉襟见肘的日子与入不敷出的债务……即使屠苏当时尚未解体婚姻。小夜郑重告诉屠苏:她在大学任教,又给企业做法律顾问,每逢重大立项在官场疏通关系,便需要与高层熟络的小夜亲自出马。立足学界,涉足商界,纵横官场,作为学以致用的通才,小夜早在四十岁前就一劳永逸,实现财务自由,不被生计困扰,她名下仅房产就有十多套。小夜流露出很深的社会背景,似乎具备帮助屠苏实现仕途梦想的能力。她说自己怎么与高官熟络,怎么与他们谈笑风生,办事怎么易如反掌。小夜承诺,如果和屠苏结婚,就助力他的事业。
以屠家的本分和保守,一开始他们当然不主张屠苏与明慧离婚。为什么他们后来转变心意,尤其是屠爸爸鼎力支持?是被屠苏的一意孤行所感召,还是另有隐情?
小夜曾对屠苏父母说她怀了孩子,能给屠苏生儿子,对屠爸爸来说,大喜过望。早年我与屠苏的交往中,他曾谈及为了供他继续学业,小妹所做的牺牲。十多岁的少女,正是城市家庭父母的掌上明珠,绝不会舍得让一个刚刚初潮的女孩子下田泡到冷水里劳作,也舍不得让屠妹妹牺牲自己的未来供养哥哥的未来。但屠家小妹很早辍学,屠家任由年幼的女儿风吹日晒、挥汗如雨,因为农村家庭对儿子怀有隆重的寄望,相信那种回报值得这种付出。在相对漠视女孩权利、重视男孩荣耀的地方,才能如此选择。更何况,小夜许诺,只要屠家父母支持,婚后马上送给他们一套房子居住。有钱、有本事、有生孙子的可能,连续的利益诱饵,令人怦然心动,似乎值得鱼死网破地下注。
在政府职能部门工作的屠苏,一直相对沉寂,小夜虚构的远景,屠爸爸喜闻乐见,由此动摇,就像当初抵押女儿的命换儿子的运,他只能赌那个赢面大的。
最为关键的转折,是小夜帮屠弟弟调动了一次工作。屠弟弟上班的学校离家稍远,他想换到离家更近的学校。小夜雷厉风行、大显神通,据说一个电话搞定。这次恰逢其时的施展身手,使屠家对小夜扭转态度。屠弟弟调动工作的例证在眼前,小夜的通天本领绝非虚言,她必对屠苏的仕途有所作为。小夜流露自己熟识诸多达官显贵。最离谱的是说与国家领导的夫人相处甚欢,经常一起喝喝茶,买买衣服什么的。当那位夫人形象出现时,小夜指着屏幕就聊起她的点点滴滴。其实谎言容易戳破,抵抗不住几句追问。凡与高层有特殊交道的,一般有着来历和渠道,这种事情上,没有空穴来风,而小夜说不清来历。假话,气球一样,膨胀而虚无……屠家低微而迷信,从来不存针尖大的质疑。父母本来就会根据屠苏的态度来决定对小夜的取舍。既然屠苏和明慧并不幸福,还不如迎接新的机遇。钦佩能力的,感谢恩情的,呼唤未来的,屠家纷纷改投赞成票,支持屠苏另娶佳人。只有这样,才能一改屠苏颓势,才能让屠苏重振旗鼓,再创考上北大那样的辉煌。
13
半文盲的父母,当年培养出显赫的北大学子,全家容光焕发。高考发榜之后,屠爸爸宁愿债台高筑,也要花钱请了放映员,在村里一连三天放露天电影庆祝。蓬荜生辉,光宗耀祖,那种感受太令人陶醉了,如同铁匠儿子考上清华,满县的人都想成为铁匠一样。屠苏高考创造的奇迹,绝非涟漪短暂,在当地曾像地震那样影响很久……教育的金字塔尖,北大啊。
北大,分配到每个省的名额都极为珍稀。几千几百个高考学生中,只有一个能上北大。据说北大中文系的历史,近乎半部中国现当代文学史。
屠苏的童年是被欺负的。因为个子小,因为学习好。考试时他耸起肩膀,不让坐在背后、他内心轻视的男孩抄袭自己的卷子。他要捍卫一种公正原则。屠苏的脖颈、衣领和后背,溅着钢笔囊里溅出的一腔墨水,是他身后的复仇者所为。不过,他同情那些笨拙的差生。屠苏向往捍卫的公正和他心怀的一腔柔善,无法在一个简单的行为里同时存在。屠苏后来用成绩为自己赢得了尊严。他永远是尖子生,是状元,是地位不被撼动的学霸,是老师和学校引以为傲的榜样。
他人的期待,很难说是命运的奖励还是灾难。天才的缺陷,一如他的优势那么明显。或者说,成为天才是有代价的。他们跌跌撞撞,走过的,多是一条带血的路。这是令人恐慌的消息,屠苏同一宿舍的兄弟,竟然先后走了四个。高达半数的比例啊,他们陆续死于自己的中青年,都够不上遥望老年的距离。天才、名牌大学、少年班,这些光耀门楣的牌匾下面,哪个,不是埋满尸骨。
是否天才敏感,是否年少辉煌使他们丧失必要的受挫练习,是否鹤立鸡群使他们缺乏在团队中的合作精神与协调能力?学校教育中的佼佼者,进入社会,未必如鱼得水,也许狼狈不堪。
14
虽以当地状元的身份考入北大,但屠苏的骄傲能持续多久?不管你曾经多么风光,来到精英之地也会平淡无奇,像一滴融入池塘的水,分不出哪一滴更混浊,哪一滴更清澈。那些屠苏看来光鲜的城市身份、城市习惯和城市生活,在北大学子中相当于标配,根本不能拿来炫耀。城市孩子把大学当作延续的教育,对乡村中挣扎出来的屠苏来说,意味着实现阶层晋升的跳板。
毕业后屠苏留在北京。不算如意。文笔出色的屠苏本来分配给某位领导当秘书,没想到,最终被才华略输但更有背景的同学代替。为了留京,慌不择路的屠苏流落到工厂,在蒸汽、齿轮和噪声中写材料、写报告、写领导讲话稿。几年后,企事业单位改革,岗位向全社会公开招聘。屠苏复制高考夺冠的历史,一骑绝尘,终于踏入政府机关耀眼的大门。
鲤鱼跳龙门,屠苏一次次创造奇迹。故乡人看待屠苏是即将开展丰功伟业的大人物,未来不可限量。
作为典型的寒门弟子,屠苏忧伤而无声无息地努力。他是十里八乡的美谈。他的人生闪烁几个灯塔般的光亮,照亮远方。故乡那些被感召的仰慕者,并不了解,多数时间里屠苏都在汪洋里独自漂泊。每个人都在黑暗中行走,包括屠苏和每个离开故乡的人。故乡只是记忆里模糊的微光,暗得,甚至不如家门里的一灯如豆。
屠苏不是那种读成功学长大的孩子,他甚至对抗和轻蔑那种类型,然而现实要求殊途同归,他必须和自己不喜欢的人们一起角逐跑道,看起来像引为同道。他必须跑得既快又稳,即使缺乏装备,他也必须光脚奔跑在密布渣石的道路上。他甚至不能靠摔倒来赢得一个休息的机会。他禁不起输。
何况,北京到处都是他这样只能靠自己改变命运的卖汗卖血的打拼者。举例来说,北漂里天津人所占比例很少。一方面,天津作为城市,远不如其他省份的面积广阔、人口基数大。另一方面,京津两地距离近,落差没那么大,天津人容易安身立命于本地并感到满足。地域和阶层的落差,催生忘我而赌命的奋斗者。跑啊跑,传送带上的生存,像既美好又残酷的童话,像《爱丽丝梦游仙境》里红桃皇后说的:“你必须全力奔跑,才能待在同样的地方。”
故乡人眼中他是传奇,然而,作为薪资微薄的小公务员,在北京的汪洋中,他只是近于无限的分母之中微小的一个。北京是个黑洞,有多少明亮的起飞,就有更多的陷落和葬送;每个成功者的励志故事背后,是一万个失败者的悲剧结局被掩埋。屠苏必须撑下去,不能从涨停的股票,变成跌停的股票。否则,他家族的骄傲、故乡的信任就倒了。屠苏背负沉重的寄望,重得,似乎大过整个的未来。
15
尽管我非常不愿意承认,但从明慧告诉我的离婚过程里,还是看到屠苏的迫切里流露出自私者的品性。
两人在婚姻存续期间,日常开销用明慧的钱,屠苏的钱用于存储。离婚时,屠苏的账面只有区区几万块。明慧不知道这个作伪的存款是屠苏自己操作,还是被幕后的小夜操盘。即使存在转移财产的疑点,明慧并未计较。她只要孩子果核。明慧甚至说,如果屠苏有钱,让他留着贴补自己的爹娘。离婚之后,可能工资卡并不直接掌握在屠苏手里,果核的抚养费,屠苏支付得不及时也不够数,后来只是偶尔象征一下。给,明慧就拿着;不给,她不催要。明慧说自己不是出家人,也并非出世者,不该给的她不要,该给的拿走也不行。之所以不追剿屠苏,并非混沌和不精明,她在捍卫果核权利的同时,也想在孩子面前呈现出母亲的尊严与宽容。
不仅抚养费不按期按数交纳。上幼儿园的果核高烧,明慧找屠苏帮助,屠苏没问半句孩子的病况,只是不耐烦地说:“孩子的事,你不是说可以自己解决吗?”随后挂了电话。明慧伤透了心。我吃惊,屠苏那么像是好爸爸的男人,如此冷漠。他毫无歉疚吗?他要彻底抹除前尘,以崭新、美好的自己,开始值得的新生?
我想起,屠苏两任妻子都告诉我:他基本不做家务。无论是婚姻的和平阶段还是解体时期,屠苏都没怎么管过孩子。屠苏的时间更宝贵,应该用于更重要的事情。可以视之为清高,可他的清高需要别人的不清高来喂养。有时懒惰,也可以被包装在清高里。我一直认定屠苏柔情,从没想过,这种柔情可能由部分的绝情来喂养。
为了抵达自己所向往的幸福,屠苏大步流星,走得坚决,简直有些杀气腾腾。这样的屠苏,让我陌生。
16
屠苏真的奔向幸福了吗?
伪装成灰姑娘到来的小夜,约等于仙女。小夜说自己不菲的嫁妆,保障屠苏得以自由,包括经济自由。从此书生不必操劳,放心地阅读、冥想、研究学问,只做自己情愿的事。我感慨于小夜富不外露,今天的简朴和以往的风光落差巨大,小夜不抱怨。她再也没有上班,作为企业的法律顾问,偶尔被咨询和请教,剩下的时间,宅在家。小夜说离开职业女性的角色并不可惜,毕竟辉煌过了,为以前生活的城市留下几个著名工程,比如隧道、剧场之类。小夜并非政府决策人、承建公司老板或者总工程师,她不仅精通法律业务,还与省部委、与市政府疏通关系,这些工程才得以立项。
小夜不在北京置业,宁可放弃投资者的眼光和兴致,因为屠苏不喜欢。他们可能要回故乡,或者漫游世界。小夜提到自己经常周游世界,上次出国给屠苏买了十几万的瑞士表。她一贯纵容屠苏,屠苏想买辆售价十万以下的车,小夜转到紧邻的4S汽车店,甩手买下十多万的车,希望屠苏更有面子。
即使没有生存压力,小夜还是节俭,她宁可保留挣扎者身上潜在的印记和勒痕。我请她吃饭,她选在楼下网送外卖的盒饭小馆。谈及拣选影集,她的语气急促起来:“你相不相信,相不相信,光是洗照片就花了我两千块钱儿!”小夜微微站起,身体前倾,两只手臂撑住桌边,口气恼怒。小夜说到“钱儿”的次数那么多,这个铜质的字眼儿,密集贯穿整个谈话过程。回忆最初重逢,屠苏要求小夜来京陪伴自己,小夜犹豫,招致屠苏的不快反问:“你到底是要人,还是要钱?”小夜神色活泼:“我说,当然要钱儿了,人有什么用,钱儿才重要。”儿化音明显,小夜的发音是“钱儿”,有股市井的痛快。
与小夜七年的婚姻质量,别人不得而知。实际情况是,小夜没像当初许诺那样,给屠家生下孙子,也没有帮屠苏大展宏图,她宣称的富足在婚后呈现的更是负数。除了帮屠弟弟调动成功,小夜对屠苏一家毫无建树。似乎没有手眼通天的本事,屠苏活着的时候,小夜无法在北京自谋生路;屠苏离世之后,小夜无法返回家乡重振旗鼓。怎么看,她都像是寄居在屠苏身上的拖累。如果说,出身贫寒的屠苏希望借助婚姻,实现飞黄腾达的梦想;当他后来发现,小夜并非神通广大,屠苏是否再次涌现悔意?
17
许诺中的前景,就像孕育中的胚胎不翼而飞。小夜当年说未婚先孕,后来不了了之。可小夜告诉我,婚后数年她才通过试管婴儿的方式艰难怀孕,是果核谩骂,使不堪骚扰的屠苏要求小夜流产了胎囊。每次,胎儿都是戏剧性地怀上,又戏剧性地消失。
明慧不希望屠苏再要孩子,可能是想保护本已受伤的女儿不要再失去想象中的父爱和利益。屠苏直接告诉过明慧,不会,因为“嫌小夜脏”。何出此言,是编造吗?究竟是愤怒的明慧编造了一句狠话来安慰自己的创伤,还是即将恩断情绝的屠苏顺嘴说出一句重话来取悦前妻以息事宁人?
屠苏曾有一次对果核说:“爸爸心里苦。爸爸错了,可爸爸回不了头。”是否,屠苏终于看穿小夜的品性?是否他已觉醒,尚未泯灭的良知,使他难以在一个所谓美妙其实丑陋的感情关系里支撑着自己去日复一日地耳鬓厮磨?是否他禁不起第二次失败,他丧失了再次激流搏击的勇气?多情又骄傲的屠苏,前路已断,他只能继续前往悬崖。
离婚时各有交待,屠苏对明慧的嘱咐是:“照顾好孩子,把她交给你放心。”明慧对屠苏的嘱咐是:“好好生活。”离婚后联络很少,屠家找她办理丧事,明慧才得知屠苏平常都住办公室,他只在周六回家一天,周日就回单位。屠苏离世前,是清明节的三天假期,监控录像显示屠苏只身一人,住办公室,活动半径仅限于周边百米。屠苏孤独,他给自己过了一个清明节。明慧疼惜这个自己往日珍重的男人,伤感地说:“当初答应我‘好好生活’,他没做到。”
被明慧称为“低级错误”、被同事概括为“自作自受”的第二段婚姻,究竟带给屠苏什么?明慧所言的细节,难以置信。可若非实情,一个以虚构为职业的小说家都很难捏造。当父母要把屠苏骨灰带回老家安葬,小夜提出,骨灰分成两份,一半带回去,留下一半放在北京。她关心的是丧葬费用如何分配。如果说小夜忙于洗印屠苏与名人的合影,我能理解,可一个沉浸悲伤、自称准备殉情的弱女子怎么还有心思顾虑别在丧葬费上吃亏?连我这个外人都不忍屠苏尸骨不全,小夜怎么忍心提议把骨灰一分为二?还是明慧想出办法,说果核作为唯一的骨血,为自己的父亲在老家买好墓地,不用出资的小夜才放弃对屠苏的善后构想。这让我有了奇怪的联想,《圣经》里所罗门王的故事:两个母亲都说自己是婴孩的母亲,难分真假,于是所罗门要把婴儿劈成两半;只有不忍自己的孩子被一分为二的,才是真正的母亲。
明慧的惋惜与难过,让我觉出她对屠苏的留恋。她说,当初并不富裕的屠苏曾给过自己特别像样的婚礼。屠苏问过明慧恨不恨自己,毕竟前妻把最美好的时光都给了他。明慧不恨,她对屠苏甚至是感恩的,被挫折历练,她才因此发现自己的潜能。当初离婚的重要理由之一,屠苏说:因为明慧离开自己能活,小夜不行。
明慧果然活得不错,事业和职位胜过屠苏。除此之外,令她真正骄傲的是女儿。明慧希望果核拥有良好的性格与教养。孩子恨过爸爸,她的整个童年和青春期都被屠苏忽略和冷落,好在并未产生致命的破坏性。她绝非小夜形容中满嘴脏话、热衷暴力的混混儿。明慧说:果核优秀,情智双商都高。学习成绩出色,处事冷静清醒,超乎年龄的早熟早慧,出色的管理能力和人缘使她一直担任班长。我禁不住夸孩子“厉害”。明慧说:“有一种厉害是做事果断,有一种厉害是性格强悍,很幸运,果核属于前者。”明慧并非只看分数,她训练孩子的综合能力。果核放学早,作为单身妈妈的明慧不能天天请假接送,所以果核从幼儿园开始就是班级里最后离开的孩子。小学和中学,她一直在各种兴趣小组里等待迟来的妈妈。奥数。书法。诗歌。英语。朗诵。围棋。小提琴。柔道。缺少父爱,果核并没成为问题儿童,相反,她是耀眼的天才少年。
……扑朔迷离,明慧和小夜的版本,到底哪个更靠近真相?
18
小夜早从职场退役,据说与身居领导要职的男友分手,导致她无颜面对过去的社交圈,人际关系都斩断了。丧偶的小夜,孤孤单单。她与屠家关系紧张,无法跟法律意义的亲人们在共同语境下回忆屠苏,她无法找到专注而仰慕的倾听者。小夜以为我暗恋过屠苏,必有锥心之痛,所以能在一起谈、配在一起哭。我的表现,让她失望。
二十年来,屠苏生活在一个我完全陌生的世界里。我想不明白,屠苏一把年纪了,怎么会想起来读博,而且是和中文专业不相干的教育学博士。工作本身繁重,屠苏不得不像高考学生那样刻苦,抓紧每分每秒,夜以继日地苦读。屠苏在职读博期间撒手尘寰,小夜说自己正积极活动,为他争取学位证书。我诧异,小夜怎么能想到给未及答辩的亡故者申请学位呢?人都走了,要这个证儿有什么用?我隐隐地恨这个证书,如果不是为此拼命,年近半百的屠苏何苦有家不回,孤独地死在办公室?
除了证书,小夜还想在寺院供奉永生牌。当屠家想利用儿子分房子、票子和车子时,是她为屠苏操办后事种种。小夜话锋一转,启发我:“你,不该为屠苏做点什么吗?”她明确表示让我写纪念文章,以后想给屠苏出版一本回忆专著。想起屠苏,我会难过,但我不是那种众目睽睽之下的哭泣者。我无法立即加入缅怀者的合唱,不仅因为难以在镜头下分泌眼泪,还因为,我只写自己眼中真实的屠苏,直言他的优点与弱项,无法歌功颂德,恐怕不能按小夜的要求为屠苏增加赞美的重量。小夜同意我的态度,但事与愿违,她难掩遗憾。
仅仅一个下午的短暂相处,我和小夜因屠苏而建立的临时情谊已呈现败坏的迹象。我从小夜的谈话里不断提炼出另外的内容,离她所需要的安慰越来越远。我克制出的温和语感,其实是在用强力压缩怀疑。我们都明白,彼此印象欠佳,对方不是自己欣赏的类型。与小夜告别,她逆着路灯的光照。我们的身高落差很大,面对面站立,我再怎么调整,也是俯看小夜的角度……近于,低看的角度。我们语气友好,掩盖敌意。因为屠苏离去的余温,我们坚持着,把耐心用到说再见的时刻。
想不清楚,屠苏为什么钟情小夜。尽管明慧说屠苏悔恨,可屠苏与小夜每天打一个电话,微信也频繁,似乎爱意绵恒。厌烦购物的屠苏,津津有味地在淘宝网挑选各种衣裙,一一截图发给小夜,根据回馈的意见买来送给小夜。看起来,她是他的公主。
即使情侣间有许多不足为外人道的亲昵,我还是诧异,他们彼此使用昵称之外,还用叠字指代物品。什么睡觉觉、洗脚脚之类,并非情色暗示,就是直接的低幼语言。屠苏热衷自拍,让我意外,尤其自拍照竟然经过美颜。微微发福的屠苏,在调高的亮度下,有着异样的唇红齿白腮粉。也许,屠苏使用的是小夜退役的二手机,照相会经过自动修饰。因为小夜主动邀我合影,她的相机不是那种简单的美颜处理,而是加了雪花。坦率地说,屠苏的美颜自拍像经过不自然的敷粉,给我隐隐的不祥之感……有点,像殡仪馆里的化妆。
19
没见屠苏最后一面,我如鲠在喉。
屠苏骨灰葬回老家,我决定专程去墓地拜祭……是怀念,更重要的原因是怀疑。因为小夜而焕然一新的屠苏,令我如此陌生。我对小夜态度矛盾。一方面,有所抵触;另一方面,我没有抚慰亡友之妻,反而不恭,多少让我愧悔。我自责。是否,屠苏不告而别让我不知迁怒于谁,转而指摘小夜?我想,如果不是小夜乖谬的表现,我可能终生默默缅怀屠苏,而不会远赴千里寻找答案。
我不愿向小夜索要屠家的地址和电话。小夜说,屠爸爸给邻居鱼塘下毒,屠妈妈唯利是图,屠妹妹从业风尘。她明显防范我与屠家接触。即使小夜给了联系方式,他们之间裂隙深重,屠家恐怕对我也不会有好脸色。
我决定找明慧帮忙。
屠苏走了以后,明慧和果核一起去参加追悼会,鞠躬,送别。多年不见,她发现婆婆穿的,还是自己当年买的旧衣。明慧希望公婆体面,不能破衣烂衫地去见儿子最后一面,所以去商场给他们买了丝棉袄。
明慧说,婆婆是以童养媳的身份被娶进门的,没有文化,但她具有农民的朴素与诚恳。婆婆几次向明慧道歉,说儿子对不起她,如果不嫌弃,愿意终生把明慧当作女儿看待。明慧对屠妹妹的评价与小夜大相径庭。她说,屠妹妹刚上初中就辍学,为了供养考入北大的屠苏,妹妹小小年纪就起早贪黑,干最苦最累最重的农活。屠妹妹在艰难、颠沛与辗转中,婚姻也受挫。尽管受文化程度和接触环境所限,屠妹妹有自己的局限,但她善良、耿直、天性纯净,不仅不犯泼,还特别重情义、讲道理。妹妹有承担,是个女汉子。屠苏有所亏欠——妹妹舍得用自己青春期的血汗浇灌屠家,才有屠苏的进步。
与屠家关系良好,明慧很容易联系到在外地打工的屠妹妹,说明我的心愿。此前,趁着学校放假,明慧已带着果核前去祭扫。明慧说:“让妹妹陪你,说话方便。老人伤心,就别通知他们了。再晚南方就入冬,没有暖气,你住不习惯,容易感冒,还是早去早回吧。”
她的体恤,令我感动。
20
临出发,我才知道,要去省会。屠苏的埋骨之地,不在我原来认定的鼓城,两地相距二百多公里。由于城市体积的几何膨胀,吞食许多村庄和荒郊野郊,失去土地的屠家现在生活在省会郊区,看起来像被纳入城市户口,只不过还是农民身份,没有医疗和退休金的保障。
那个我印象很深的地名:鼓城,屠苏只是在那里读书。就在鼓城中学,他初识小夜。情窦初开,青梅竹马——这些成语如果越出字典,吉凶未卜,不一定值得回味和歌颂。就像书本里真理的等号,从来不是现实中笔直的路。屠苏从鼓城中学考入北大时,小夜只是一场没来得及发酵的无痕春梦。基本能够确认,小夜的爸爸当年是教过屠苏的学校老师,至于小夜声称爸爸是大学教授,不知侥幸落实了哪类知识分子政策。屠家从来没有任何人见过小夜父母,大概只有屠苏见过。
十四五岁的屠苏,已在远离家乡农村二三百公里之外的地级市鼓城独自求学;换言之,青春期之后的屠苏,家人并不了解,因为相处时间很少。但屠苏并非孤雁,他有亲情的关爱。屠苏排行老二,有姐姐和弟弟妹妹,但他的成绩出色,全家集中财力,把所有赌注都放在他身上……屠苏凝聚着整个家族播种到远方的希望。
屠苏感恩虽感恩,但不喜欢父亲的武断和急躁。他温和的好脾气,因为,他潜在而强烈地要求自己,走向父亲性格的反面。屠苏明显与家中女眷亲近,念及妈妈和妹妹,深怀牵挂。只有一个妹妹,可屠苏跟我提起从来都说“我的小妹妹”,叫名字也用昵称。屠苏梦想着,她由于自己过上更好的日子。当我得知妹妹因他辍学,才知道屠苏的惦念里包含着愧疚。
屠妹妹电话里的声音大,和屠苏相反——因为耿直豪爽的性格,也因为打工留下的后遗症。她原来做零件组装,每天工作十几个小时。她从来不因加班抱怨,反而欣喜,加班有加班费,累点不算什么;而且加班时被钉在岗位上,出不去,就不用花一分钱。缺点是眼睛越来越看不清,尤其装耳机零件,尺寸太小了,很毁视力。眼睛不行了,她就调到包装车间,噪音大,说话得嚷。屠妹妹大声跟我约好时间和地点,为了哥哥,她难得请了事假。
不年不节,中途回家的女儿让父母诧异。了解情况以后,屠苏父母执意要我去家里坐坐,然后陪我一起扫墓。
21
屠苏父母住的像是回迁小区,旁边还有零星菜地。楼房简易而实用,空间小,但一室一厅够老两口住了。
屠家人就是想象中的朴实样子,我没觉出交流障碍。屠苏长得像父亲,尤其草食动物的眼睛和微卷的头发,还有体形。我偷偷猜想,如果屠苏有晚年,也许就是这个模样。屠苏妈妈戴着套袖——无论在家、出去吃饭还是上坟,她全程戴着套袖。这是多年底层劳动留下的习惯。她的手干涩,握住我,还没说话,就红了眼睛。屠妹妹下夜班就赶火车,一脸倦容,看到妈妈流泪,她也难过地低了头。
略感惊讶的是,我坐下来的第一件事,是屠爸爸指着茶几上一张放大的照片,说:“看看,你认识几个?”集体合影,三四十人的规模,站成两排,屠苏位于后排的边角位置。我的确认识一些,这些名人是报纸、电视和网络媒介上的熟面孔。这是一次大型社会公益活动,屠苏作为工作人员,参与了协调和服务工作。屠家引以为傲,这张拿得出手的奖状一样的照片镀了塑料膜,禁得起来宾的手反复摩挲。这种巧合让我感慨,无论去屠苏的妻子还是父母家里,我首先参拜的,都是他履历光荣的照片。作为辅助的工作人员,这份合影的光荣,多少有点狐假虎威。再残酷一点,珍馐美味之所以昂贵,在于它的主材,至于陪衬的是绿叶还是萝卜花,不在考虑范畴。屠苏和名人们平起平坐,再像,也不过是模拟成功者。
屠苏之所以令家人和家乡人艳羡,不就是因为,他抵达了这种辛酸的成功吗?一种倚近成功的成功,到底是更像成功还是失败?还是说,来自虚荣的成功,才能带来最为真实具体的心理享受?屠苏一路攀行,以靠近这样的光荣。谁想到,在一张照片里已经与名人比肩的屠苏,梦断途中。
22
屠妹妹性情中人,爱憎分明。
她夸明慧,聪明能干,穿什么衣服都好看。她对小夜恨之入骨,说小夜就是罪魁祸首,哥哥假如还和明慧在一起,就不会死:“我哥瞎了眼,那么好的嫂子他不要,非娶小夜。她对哥哥没感情,只会逼他挣钱,逼他考学,逼得他活活累死。家里没有温暖,哥哥才会住办公室,发病时也没人救,我哥死得太惨。”直到葬礼,明慧她们靠近时,屠妹妹和屠弟弟依然说:“哥,你的老婆孩子来看你了。”他们依然承认这个早已解除法律关系的前妻。可能由于缺氧,屠苏的耳道和嘴唇都有淤血般的青紫痕,屠妹妹甚至怀疑是小夜下毒所致。即使并非如此,小夜的表现也令屠家气愤——小夜竟然站得很远,害怕,不敢靠近遗体,到最后也没像亲人那样凝视过哥哥的遗容。
这么多年,小夜没叫过屠苏父母一声“爸妈”。安葬屠苏骨灰时小夜回来,屠妹妹发现小夜在旅馆住宿使用的竟是假身份证。此后小夜不再让屠苏父母进家门,她不接电话,斩断所有联系,屠妹妹和小夜算是彻底撕破了脸。
我发现,连当初怎么和屠苏重逢,小夜给我讲述的版本和给屠家的版本,都不一样:不是什么司局级的显赫男友,是同学要带小夜去听讲座,授课者正是屠苏。和小夜相逢又终成眷属的这么多年,屠苏基本不打电话回家。屠妈妈难忍想念,主动打电话过去,儿子也是潦草应对。去世前两年,屠苏根本就没回过家,包括春节和中秋节。八年时间,屠苏总共回家两次……回家就窗边抽烟,叹气,还很少说话。当小夜渲染成为坏孩子的果核有多么糟糕时,屠苏沉默,退到阳台抽烟。如果说,屠苏是忌惮于小夜脸色,那么事后,单独与亲人相处的场合,他也从未替女儿辩解半句。为什么,他舍得别人诽谤自己的孩子?可以推断,小夜在屠苏面前,也会肆无忌惮地攻击他的父母和兄弟姐妹,相信屠苏也不会给予哪怕是语言上的保护。屠苏怎么如此纵容小夜,到丧失原则的程度?
得知屠苏烟瘾不小,我吃了一惊。当年精神洁癖明显的屠苏,非常讨厌别人抽烟,他连烧烤的烟味儿都难以忍受,什么时候变得烟不离手?难道,他压抑的胸膛,需要随时掩饰自己深呼吸的渴望?
23
“哥哥以后混好了,一定报答你。”屠妹妹记得哥哥语气里的怜惜和珍重。很早以前,屠妹妹遭遇困难,借过一万块钱——屠苏说不用还了。多年后,小夜阴阳怪气地电话要账。妹妹悲愤:“我借钱的时候,你还没进这个家门,那是我跟哥哥之间的事,还钱也不该给你!”妹妹伤心于哥哥愚痴,借钱的事小夜本不知情,为什么哥哥要向小夜交待?
来往零星的电话里,屠苏也会安慰妈妈:“你不要舍不得,需要钱,跟我说。”可与小夜重逢的近十年间,他一共给过妈妈三千块钱,平均每年三百;而且屠苏和小夜一旦回家,吃喝取用都是家里的,他们分文不掏。越到后来,屠苏越一毛不拔。
弟弟的孩子首次进京,赶上过生日,屠苏毫无表示。父母提醒,是否该给侄子买个礼物或给个红包,屠苏回避,说等孩子上学或结婚时再说吧。这是托辞,屠姐姐的孩子结婚,屠苏什么也没给外甥。当年屠苏支援妹妹,同时也给姐姐一万,说姐妹公平,没想到屠苏后来也把这个秘密向小夜汇报。外甥大喜的日子,指着这个光宗耀祖的舅舅回来证婚,小夜抓住时机,要屠姐姐迅速还钱,否则不让体面的舅舅出现在婚礼现场,不给这个脸。迫在眉睫,姐姐赶紧筹款还债。一万,在外甥婚礼上趁机勒索,屠苏几乎等于要了证婚人的出场费。
屠苏拒绝为过生日的侄子破费,屠家父母为了面子,只好扮演幕后的好人:偷偷塞钱给屠苏夫妇,让他们给侄子买身新衣服。他们照办。滑稽的是,当不知情的弟媳表示感激,小夜毫无愧色地接受美誉:“我这个人嘛,花钱大方,给孩子从来都舍得!”
屠妹妹后来明白,屠苏交待的,是一份没有任何遗漏的黑名单。
当年弟弟购房,屠苏拿出三万,让弟弟多买一间,留待自己回来时居住。屠苏的确回来就住这儿。小夜得知屠苏的内线情报,得知不是免费住宿,不干了,不管时隔多少年,钱总是要还的。小夜的催债电话没打给弟弟和弟媳,直接打给屠苏父母。父母为难,怕因此兄弟失和,又怕拒绝之后屠苏不得消停,他们只好瞒着小儿子,咬牙,自己还。这个故事是残忍的,夹杂着知音体的辛酸插曲。我这才知道,屠苏父母说租门脸做小生意,这个小生意是什么。他们一直卖力地捡拾和收集废品,靠这么辛苦的劳动,积攒三万,赔偿逼债的小夜。
屠苏悉数交待,颗粒归公……无比忠诚于小夜,对家人,近乎背叛。屠妈妈心疼儿子,屠妹妹替哥哥辩护,她们说屠苏太善良、太老实,耳根软,怕吵架,他的经济能力完全受控于小夜,他心有余而力不足啊。
最后的春节团聚,屠爸爸无法忘记那次伤心的麻将。那是与小夜结婚以后的第二次回家,也是屠苏最后一次回家。
小夜好打麻将。初一早晨起来,见弟弟一家还没赶来,牌瘾上来的小夜让屠苏父母当牌架子,撑一会儿时间。小夜不许屠苏在桌子前面放钱,如果屠苏赢了,小夜立即把他的进项归入自己口袋;如果输了,小夜只交自己该给的钱,屠苏那份,因为门前空空如也,无法支付,无论是屠苏还是小夜就不给了。打了三圈,屠苏妈妈说大年初一,给屠苏那里也放点票子,图吉利,“面前有钱”,让屠苏讨个口彩。谁知小夜一听,勃然大怒,站起来一抽桌子的垫布就掀了麻将桌。她怒气冲冲地收拾行李,让屠苏跟着走。屠苏不知所措。唯有这次,屠爸爸对引以为傲的儿子发火,嚷了起来,骂他“窝囊”。屠苏脸色铁青,也是唯有这次低吼一声,让小夜别再发飙。
屠爸爸因此悔意深重,最后一次见面,没给儿子温暖。我安慰老人:“您一发火,结果毕竟是屠苏留下来了;否则他走之前数年都没和家人共度一个春节,未免凄凉。”
从屠家老人的角度,如果当初没有离婚,儿子的结局比现在美满。屠家保留的旧照上:年轻的屠苏盯着计算机,年轻的明慧手臂搭在他肩上,满心的爱意与满足。屠妈妈看着看着,就哭起来。当初贪图鱼钩上的零星肉味,他们就被勾牢下巴活活钓上来,嘴角流血、浑身疼痛地摔在坚硬的地面,再也回不到原来的平静池塘……每挣扎一下,他们的眼睛就沾上更多的土粒。
24
屠妈妈哭诉再婚以前的屠苏,是个多好的儿子。本事好,脾气好,从来没说过一个脏字。他惦记家里每个人,嘘寒问暖;后来的屠苏,变得冷淡、吝啬、没有心肝。屠妈妈说,家里没人沾到屠苏一点点的光啊。
我承认,二十年来屠苏的作为,根本不像当初认识那个善良的、笑起来又温暖又羞涩的他。印象中,屠苏是不计较的、温存的、慷慨的、怀恋的,变化让我想不通。当年和明慧恋爱,哪怕我是与他并无身体沾染的女性,都被他杜绝,成为清场的内容。是什么让他发生那么大的转折,果核刚刚长全乳牙,屠苏就半公开地与小夜双宿双飞,无暇责任与情分——他斩断旧家庭时那么不惜,没有断臂求生的疼痛。
屠苏怎么会被小夜搜刮到粒米不剩呢?如果屠苏那么容易被控制,不想离婚的明慧施压为什么不管用?即使被小夜把控财政,落魄的屠苏难以给予物质援助,可他自己住办公室,有充足的时间、空间和自由,至少给妈妈打个电话并不困难,屠苏却发展到从不主动联系的程度。孝顺,在人生支出中所占比重很少,谈不上多大的利益损伤,有人甚至愿意以此为手段塑造个人的道德形象。对一个掌握财富和权力的人,孝顺非常容易完成;对普通人来说,也绝非难事。孝顺也是内心的牵挂和惦记。屠苏懒得走个形式。什么样的温柔乡,值得这样众叛亲离、头破血流?一个我只用两三个小时就觉出破绽的女人,为什么可以让屠苏焚身以火,什么样的热忱引诱着,令他如此决绝?
屠苏性情敦厚,并不意味着,他能免除人性的计较。屠苏与明慧在一起时,还想着父母,想着照顾兄弟姐妹;和小夜在一起后,从钱到情,对其他人都没有了贡献。我隐约觉得,屠苏也许没有把明慧当作绝对的归宿,当他天涯海角觅知音,觅到小夜——他们的新家,成为唯一的利益集团。父母、前妻、女儿、兄弟姐妹,所有的责任成为对幸福的干扰。
吃下毒糖的屠苏,脱胎换骨。找到什么样的侣伴真的太重要了,配偶可以把我们改造得天翻地覆,甚至导致灵魂的癌变。因为每个人都由复杂的元素构成,能被激发善意,也能被激发恶意。
不过,很少见到六亲不认的爱情,主人公能从中获得真正的好处。屠苏每况愈下,仿佛被惩罚。他想追求感情的自由,却连肉体和灵魂也被牢牢捆绑。屠苏本来是在岸边观景,海拥有作为景色的大美。说自己穷困、等待被拯救的小夜,就像一块漂向深海的浮木。屠苏一开始,或许只是想把浮木从大海里捞起来。打捞过程中,屠苏游累了,还可以借助它休息一会儿,他也幻想借助木板的浮力遨游海洋。一旦深入,海是最凶险的深渊,他发现自己唯一能做的,是抱紧浮木……不停地,越抱越紧。最初接触浮木,屠苏觉得是自己在主宰命运,很快在浪涌中他难以控制;即使这块浮木是条化了装的鳄鱼,即使鳄鱼慢慢撕咬他的肉,他也只能流血地陪伴,直到丧失最后的体力。
哪里还有回头路?哪里还有呼救的气力?屠苏离开了陆地和海岸,离得那么远,他听不到家人的呼唤。耳畔只剩一个声音,在讲述一个因为沾血而显出胭脂红的爱情童话。
25
早晨下雨。灰蒙蒙的,像天使脏了袍服。
我穿行雨里,买鲜花、糕点、水果和烟酒。拒绝使用塑料祭品,我要给节俭的屠苏买真烟好酒……听说他平常抽最便宜的烟。屠苏的头发微卷,屠妈妈说过“头发打鬏、银子上锈”,意思是钱用不完,都锈死仓里,可屠苏从没富裕过。屠家凑了数万元,买了中档墓地,半山坡上的墓碑毗邻而居,算是屠苏此生最为豪华的住所。
墓碑上的照片,屠苏笑嘻嘻的,曾经茂盛的满头卷发,脱落为一层薄霜。照片上的眼睛不再浓黑,头发也是灰烬色。屠爸爸和屠弟弟点燃厚厚的冥币,同时被点燃的,还有很多张屠苏身份证的复印件,它们当初无论是什么功用,都随着屠苏之死变成废纸……浓重的烟气弥漫,渐渐,铁盆里只剩骨灰色的纸片。
无论在生活中怎样满怀忧惧,到那个世界,他可以永久微笑,体会到久违的解脱和自由吧?根据与小夜的谈判,移骨的条件是墓碑必须署上她的名字,所以墓碑呈现出荒谬的组合:爱妻小夜率女儿果核泣立。数月之前来这儿祭拜的果核曾大哭不止,就是因为小夜,果核的童年从未体会父亲的温暖乃至存在;可现在,她被迫与仇敌的名字牢牢刻写在一起,形成堪比石坚的结盟。
屠苏有知,听得见果核的哭声吗?还有,屠妈妈的哭声。
她哭屠苏,说过一定给妈妈找个好媳妇,没想到找到小夜。这个近八十岁的高龄老人,提起变心的儿子,一直骂他“陈世美”。其中含义,不仅指屠苏对前妻的负情,也包含他对自己以及一家老小的寡恩。整个家庭,从父母到兄弟姐妹这么多的血本下去,换来的,是无意义的牺牲。屠苏给他们带来的苦难和骄傲同样沉重。屠苏曾带来昂贵的光荣,他们现在为此支付太多的眼泪。
屠苏陌生得让人既不敢相认,又不忍责备,我只剩独自的悲伤。他先是在黑暗的室内,绀紫色地缩成一团;然后在黑暗的地下,烟灰色地缩成更小的一团……屠苏缩回乳婴的体积。每个人都用一生的时间,去学习如何在命运结尾处告别——屠苏擅长学习,只有这次关于死亡的技能,他学习和掌握得太快,速成得令人痛楚。
想起多年前的告别之夜,屠苏真的一诺千金啊。我以为是礼节性的“再见”,是对下次见面的约定;我以为某天还会聚首,我们把曾经的负气当作云淡风轻的玩笑来回忆;我以为是短暂的逗号,没想到,他画下曲终人散的句号。此生未见。原来是那么重的告别,是我们之间的生离与死别。我们再也无法调整和修复,年少莽撞造成的无意伤害;再也无法给予,年老沧桑而达至的理解。
无论在生活中怎样满怀忧惧,到那个世界,他可以永久微笑,体会到久违的解脱和自由吧?
我不打伞,陪屠苏一起,淋着微凉的雨。没想到我当年写给屠苏的文字一语成谶:“说着说着,大滴的稀疏的雨就落下来……那是因为,有一个在灰云里缓慢飞行的天使在哭。”
26
屠苏没有托梦,屠家谁都没有梦到过他,包括肝肠寸断、以泪洗面的屠妈妈。他们认为,这说明屠苏在那边过得很好。我在簇拥的墓碑之间观察过,屠苏不是最年轻的,目力所及,我就看到一个二十出头的孩子。但屠苏肯定算是相当年轻的,而且年轻得不幼稚,是那种年富力强、可以委以重任的年轻。他在彼岸有体力和能力帮助别人,愿他由此得安慰和成就。屠妈妈说,家里找人算过,问屠苏在那边的情况。答案令他们欣慰,屠苏在那个世界里被前呼后拥,是个当官的。屠妈妈难得地笑了:“我儿子在这边没有什么朋友,没想到,到那边,还风光哩。”
我也从来没有梦到屠苏。我在墓地与屠苏独自对话的时候,凝视着他的眼睛。我愿死后有知,也许鬼魂只是透明的人类,不动声色地与我们擦肩而过。我没有梦见屠苏,因为他有太长时间甚至连名字都没有出现在我的生活里。屠苏与家人同样如此疏离,见面的次数有限,他的父母甚至连做梦所需要的素材都不够。我无法作为知情者或者叛徒那样开口:小夜告诉我,屠苏在她的梦境里已往返数次。
就让我把这算作屠苏的懂事和体恤吧。正因屠苏多年以来的疏离和冷漠,缓解了他离去给家人带来的伤痛,并且让他们能把情绪转移到对小夜的愤怒上……这样,生生撕开的创口也许没有那么疼。
27
也许屠苏的困难,远远大过他的努力和挣扎。如果说,屠苏的前半生旗开得胜、所向披靡,当他破釜沉舟,与小夜另结连理,他变得对经济越来越计较,我猜和他对自己的未来缺乏信心与安全感有关。
他怎能不计较?清水衙役的屠苏,活得虽不至水深火热,但负担新妇,手头不宽裕。另外,屠苏在北京生活了三十多年,没有一间真正属于自己的栖身之所,没有一个可以按自己心意装修并购置家具的落脚地。屠苏工作的政府部门,位置接近天安门,像是整个中国的核心,但他的购房目标,不得不一点点地以五环乃至六环之外为选择方向。他辛苦攒下来的积蓄,每次想靠近一个更为降低的目标,就被市场甩出更大的一截。在北京房价飞涨的情况下,买房成为他一生也完成不了的任务。别说实现目标了,连靠近都不再成为可能。令人绝望的是,即使放弃买房,以屠苏微薄的薪金,租房都是妄想。挤在合租的周转房里,他终身,都有寄人篱下之感。
即使屠苏想为屠家再创辉煌,也无能为力。屠苏当然有怯懦的一面,可能被迷惑、被捆绑、被同化,然而,除非屠苏自愿当奴隶,捍卫他唯一的女王,否则他不至于事无巨细地向小夜汇报每笔大大小小的外财。他多少会隐瞒性地储存,不至于对父母滴水不漏。屠苏凝聚终身之力,也还不起父母恩情,只好抹杀和忘却。他背不动整个家族的大包袱,余力只够背起一个体量比常人还轻的小夜。所以,他对屠家所有人采取回避的办法。屠苏回避他的处境,渐渐,他回避他的良心。他说服自己,他给予家族的光荣,已将全部债务偿还。
屠家人难过,小夜直眉瞪眼地打上门来要债,都是屠苏告知的内情。他们恨屠苏不争气,恨他心眼少、耳根软。谁也没想到更深的可能,有个更靠近可能的残酷答案。屠苏与小夜之间有着充分交流和谋划,小夜才得知幕后的细枝末节。屠苏想要回那些曾给兄弟姐妹的钱,他自己开不了口,就把数目透露给小夜。他知道这样,他既收回损失,又不丧失亲情和声名。
唯有神,因万能而慷慨;卑微如他,因无能而吝啬。
屠苏家的位置,恰在贫富夹层里:一边是富丽堂皇的新建筑,一边是散发排泄余臭的危旧房。自律且自傲的屠苏,多么怕沦入后者之境,中年已无多少余勇和体能的屠苏,即使只是背负小夜的包袱跃向前者,最终还是从裂隙之间掉了下去。
28
原本重男轻女的屠家,现在只剩小儿子。被哥哥的耀眼光芒映衬,屠弟弟的成长显得平凡。屠弟弟没有屠苏那么大的天赋和梦想,只要感到吃力,他就降一降工作的难度,知足常乐,随遇而安。风水轮转,随着地域的重新划分和用途改造,屠弟弟不仅获得了省会户口,生活在城市的新型开发区,还娶了贤妻,生了好儿子。
我喜欢屠家小儿媳,长得干干净净,是那种善良又文静的好看,不俗气。做事本分,温顺懂事,她一点不张扬,是过日子的类型。节俭归节俭,小儿媳对公婆不吝啬。在她的支持下,屠弟弟给父母买了房子。屠妈妈告诉我,小儿媳在社区开了超市,辛苦些,好在维护家里开支之外,还有不错的余额。屠弟弟一家到外地旅游,总要带上父母,小儿媳新年的时候还给婆婆买了金项链。一个女人的美好,是否可以惠及男人的命运?父母膝下承欢,儿子学业争气,屠弟弟过得顺风顺水。
活着时的屠苏是否发现,自己在精英集聚的北京,混得,竟然不如根本不起眼的弟弟?曾是天之骄子的屠苏,在弟弟面前,优越感乃至存在感也逐渐消失。他每次回家,都需要面对自己的挫败感,这是否是他不愿回家的理由?如果屠苏当初没有那么努力和出色,是否更能获得命运的垂青?屠苏走了那么远的路,付出那么大的代价,为博取一个成功的机会。可惜他博取到的,只是一个机会,而不是成功本身。
29
给屠苏扫墓之后,我在火车站查看列车时刻表,准备买票回京。一个熟悉的地名跃入视线:鼓城。我突然改主意,决定去一趟鼓城。
尽管屠苏离开了三十年,那里早已没有他的任何气息和线索,我还是想去看看他青春的成长地,何况到鼓城,只需一个多小时车程。高铁时代,谈笑间,就走完跋山涉水的路途;在当年,十四岁的屠苏,会不会觉得学校与故乡之间距离漫长,就像难以返回的单程旅途,他所依靠的,唯有脚下一双把自己运到远方的鞋……
出了鼓城火车站,暮色四合。我排队等出租车,要比别的城市等待的时间更长,并非客人多,是因为出租车经常断档。每辆出租车的顶灯,都是植入广告的滚屏:海底捞火锅隆重开业;蓝魅KTV首次入驻;口腔医院种植牙现场观摩;反复21次成习惯、看1000遍成品牌……最强广告媒介。等候站的灯箱,以漫画形式,强调开展爱国卫生运动以及提高人民健康水平的重要性。不乱倒污水。不乱扔垃圾。不在公共场所吸烟。不乱放柴草、农具。不乱贴乱涂。基础的要求,需要被宣传和提醒,这和这座三线城市兴建起的巨大广场,并不匹配。暮色渐暗,广场空旷,有刚刚剃过头的那种生味儿。
终于上了出租车。城市的迎宾主干道,沿途挂满喧嚣的中国结路灯。那么红的灯,像急救车排成长队,红得那么急促和紧张。就在大放光明的大道两侧,是大面积连绵的辽阔黑暗,能隐约看到修建完毕的小区楼群。无人入住。楼体整齐划一,有些高耸,有些还没镶上玻璃,裸着缺牙的窗户。鼓城的周末,比一般城市要暗淡,曾经蓬勃的房地产如今萧条,一眼望去,能看出显著的压力和困窘。
30
第二天上午,我穿过老街,步行去鼓城中学。
老街两侧,一侧是新修的仿古建筑,灯笼高悬,露出高大的檐脊;另一侧,充气的大型儿童乐园正在营业,喜羊羊城堡里蠢萌的羊和狼,被风吹日晒,呈现出塑料老化的旧色。
老街里有个宰相故居,院墙遭受破坏,依然是励志教育的圣地。这个曾以神童著称的宰相,很年轻就入京会试,一举成名。他深怀抱负,功业彪炳,直到被皇家护送灵柩,荣归故里。少年屠苏肯定来过这里,那时他对未来作何设想?是胸怀韬略、治国经邦的渴望,还是寒泉汲水、清水写字的逍遥?故居旁的栾树结满水粉色的苞荚,秘密的籽粒隐藏其中。
鼓城在宣传语中是座历史文化名城,但到处,都是极力掩盖却依然裸露出来的贫穷,从物质到精神都在没落。扩建的大路旁边,坐着许多擦皮鞋的妇女,马扎空着没有客人的时候,她们就慢慢抠着自己油污破损的指甲。文化馆建得像大型公厕,外观粗鄙,门口坐镇的老大爷打量着我:“你跳舞?旁边买票。”原来文化馆已被出租为舞厅,那些力争压押的脚,纷纷穿梭在白天的灰尘里。
临近鼓城中学的巷子狭窄,让我想起屠苏家后面的胡同。巷子里是面馆。是潦草的发廊和足疗店。是老年打麻将和纸牌的茶舍。是自酿的土酒坊。日杂店和照相室。降价鞋的摊铺。小药店。牛羊肉批发店。文具行。还有所谓的取名斋,昏暗的墙上挂着手写字体:感情破裂、财运有损、病变、天灾、人祸。一个未到季节就穿上羽绒衣裤的拄杖病人,缓慢走着,进行劫后余生的康复训练。油泥粘鞋跟的苍蝇饭馆,案板铺在流满污水的地面上。厨师蹲着杀鱼,鱼的头骨被菜刀背敲碎,两声闷响。然后是鳞片被刃口刮掉那种连续而刺耳的戗行声,鱼鳞迸溅。
屠苏离开鼓城三十年了。经过三十年的发展,这条名为民主街的小路上,保持着理想的名称,以及弥散在空气里的浊灰色。我终于看到鼓城中学的标识。学校对面看似底商的,挂着基督教福音堂牌子。
31
在校门口的文具店,我有意磨蹭了一会儿。各种用品,丰富多样。我买了一把尺子和两支笔,像是纪念屠苏的正直和书写由此开始。
鼓城中学以前是贡院和书院的遗址,作为重点学校,升学率相当不错。大学扩招之后,鼓城中学年年业绩不凡,可当年,考上北大,整个学区就出了屠苏一个状元。
正赶上中午放学,迎面而来的孩子,人流汹涌。我凝望这些分外年轻的脸,他们之中只有少数,能走上校门口那座宽度有限的状元桥。无畏艰难,积极进取。千军万马,杀出一条狭窄的血路。上北大,上清华,上复旦。上北京,上都会,上省城。学校门口张贴着应届考生的光荣帖,要想成为上面的英雄,必须踏过血洗的战场。
与我交错而过的,是憧憬的眼神,是稚弱的肩膀,是努力背负的脊背和蹬踏向前的双脚。屠苏是其中的一个,是少年得志的佼佼者。我不禁猜测,屠苏第一次从农村到鼓城上学是什么样,第一次从鼓城进北大校门是什么样,第一次从北大毕业进政府机关是什么样。
在鼓城中学一动不动站了几分钟,我恍然明白屠苏的处境。他从最苦的农村来到鼓城,从血肉相搏的鼓城中学考上北大,再从北大工作到机关,层层晋级……背后是家乡人的羡慕和惊叹,对他们来说,这是美妙而狂喜的成功;然而对于不断置身新环境的屠苏来说,是他一次又一次,把自己重新放到最底端的位置、最惨痛的角色里。从鸡头变凤尾,从零开始,在崭新的底层从头再来。每一寸向上的光荣,都是由更低一些、更深一些的黑暗换来的。如同屠爸爸乐于示人的合影,看似辉煌,可屠苏永远占据可有可无的边角。屠苏向陡峭而凛冽的高处,攀援。没有援手,只有黑暗和内心里,呼啸的风声。
屠苏是个考试英雄。他擅长考试,享受其中简洁的公正——当运用智力,当面对抽象的题目,不面对具体的人和事,他是强者。
一旦进入社会生活,仅仅通过考试就绝对制胜的机会并不多。人生太多的内容,不需要分数的鉴别和明证;有些获胜不仅没有答案,还蓄意模糊标准。屠苏具有遨游知识海洋的智慧,在现实陆地穿行困难,磕磕绊绊,摔得一身泥一身土。可他没有别的途径,没有别的招数。到了五十岁,一般人读书多因兴趣,不再孜孜以求一个发榜单上的加冕。对屠苏来说,生存永远像把悬剑,带来动荡和不安全感。年近半百的屠苏在职读博,企望重走金榜题名之路,这也是唯一的血路,尽管渺茫,至少尚有窄窄的缝隙……他增重自己的砝码,希望能被某个单位或某个岗位纳贤,或者,接受附属的家眷进京。为了打造未来的壁垒,屠苏挖开自己脚下的泥,来糊一面遮风挡雨的墙。他并未察觉自己因此陷入被葬身的险境。
32
发生在鼓城中学的一见钟情,能支持考场英雄走多久?
怂恿屠苏读博的小夜,想让校方追认屠苏的学位,到底是要告慰亡灵,还是想用这道逝光为自己赢得夫贵妻荣的骄傲?自己没有资本的人,往往要拿别人说事。也许小夜此生最大的财富,莫过于屠苏的迷恋,他的痴情、深情又挚情,照亮小夜相对暗淡的履历。屠家认定,小夜是利用屠苏,屠苏对小夜也谈不上感情,否则怎么能在单位躲着不见。我倒认为,不能说他们之间没有爱情。屠苏能把笑话、歌曲、图片和游戏用移动硬盘拷给小夜,能帮她设计旅行,能在淘宝网上给她买衣服,能随时互发自拍照……如果一个男人在无感甚至是反感中,很难做到。
小夜恃宠而骄,魅力何在?因为性?小夜长得显小,但形象不具通常意义上的魅惑。假设她有翻卷云雨的内功,也难以找到证据;再爱,他们对彼此身体的使用率都不算高。屠苏爱小夜什么呢?虚张声势的吹嘘,理直气壮的势利,摇弄唇舌的造谣,颗粒归公的盘剥……这样的灵魂乏善可陈。
可只有小夜,当年亲眼目击屠苏的传奇……传奇给人带来吸毒式的迷狂。那少年一览众山小,从鼓城中学的课桌到北京要职的办公桌之间,似乎已铺平坦途。宏图大业,指日可待。那页出色履历之后,情节没有按预定节奏发展。失意者喜欢津津乐道曾经的辉煌,那是他的巅峰。终于有一天,长年累月受挫的中年人屠苏,不再眺望未来,转头瞻望过去……渴望重回价值崇拜的起点。重要的是,今天,小夜是他唯一的崇拜者。
小夜之所以洗印满墙合影,之所以筹备纪念专辑,她说因为屠苏参与那么多国家大事,都是直接影响中国道路进程的大事,必须纪念。然而,人微言轻的个体,身置高速运转的国家机器之中,不过是枚不起眼的螺丝钉。也许小夜没见过真正的大世面,她的崇拜分外真实,只有她,用看待成功者的眼光看待屠苏。我有个自家亲戚,县城职员,小学文化,可说话的口气颇大,有几分了不起的傲世,他公然宣称,别人绝不能把他当成一般的平头小老百姓看待。其实论他的功绩,不过是把自己一家从农村活动到县城。他没有机会打开更宽的眼界,才放胆发出井底之蛙高亢的鸣音。屠苏曾是学校、家乡和区域的典范,早年他能从同学、家人、朋友和同事那里获得瞩目与重视,拥有众多的崇拜者。随着年长,职位停止发育,景况平平,他不再是赢家,社会上的尊崇感锐减,他给家里带来的实惠还不如始终不被看重的弟弟,屠苏丧失了自己的拥趸。他在真实生活中失落,沦为弱者。硕果仅存的小夜,使他能够模拟成功者的心理满足。收容小夜,收容一个永恒的崇拜者,让屠苏体验自己的强大:他还能给予,他还是强者。只要小夜还担任最佳女配,屠苏就能扮演传奇中救美的义公子。唯一的梦,他不忍再摔破。小夜的崇拜,成为最好的控制手段,是终结一切的必杀技。一个人很难跟自己的崇拜者翻脸,他可以拒绝一切,却难以拒绝崇拜者——因为拒绝,等于否定自我价值。
屠苏疏亲少友,维系内心平衡和成就感的,只剩一个女人的歌唱。他是坐在小夜神坛上的男人。除此之外,他找不到一把舒适的座椅。何况,这是一把杂技团的座椅,被一根危险的长竹竿抬升到高处。每把高高在上的椅子,下面都有支撑的基础,有人靠权力,有人靠财富,有人靠艳遇,有人靠亲情……支撑屠苏的,是小夜的仰望和倚仗。那些别人听不到的赞誉,他自己能够分辨。屠苏坐在独竿椅上,上面是一圈虚无的光团,下面是一片陌生的黑暗。没有接应者,没有保护措施,没有终场的落幕……疲惫的屠苏只能牢坐。迹近坐牢。
33
鼓城之行匆匆结束,我伤感回京。
高铁运行平稳,旅客感觉不到机械猎豹恶狠狠的速度。城市与城市,半小时之内就能抵达——车窗外埋首农田的劳作者,终其一生,未必能够穿越看似短暂的距离。有如自己种植的庄稼,他们发芽在土地里,风吹日晒在土地里,最后也倒在土地里。为了躲避这样的命运,割断根系的屠苏远走,小夜是他唯一带走的心理意义的故乡。屠苏放弃了文学,尽管那曾是他灵魂意义的故乡。屠苏还能有什么乐趣和拯救?如果屠苏依然喜欢阅读和写作,孤独是否能够得以缓解,焦虑是否能够得以安抚……是否就能始终贯彻自己的道德理想?
车过石家庄,我无所事事,看黄昏,和站台上突然亮起来的灯。没想到,意外的觉醒时分,随着光源到来。我在网上查找屠苏旧文,多年未读,我还记得他秘密的匿名。尽管屠苏进行了新的更名和伪装,我还是能够按图索骥。
找到了。突如其来的灵感,让我意外地,也找到小夜的匿名博客。
博客开了几年,时间从与屠苏重逢,持续到婚后几年。长长短短,拉拉杂杂,共几十篇。然后,不知小夜怠惰还是别的原因,博客在数年里都停止更新。直到屠苏过世之后,小夜才补记数篇。足够了,这些记录,让我由此翻开屠苏的谜底。
34
小夜的博客内容比较重复,更像是验证我的想法。如此高比例地谈论:我是律师,我有很多房子,有悖常情。一个女人到处强调她背了名包,恰恰说明,这个包高于她实际的生活水准;如果她所有的包都是奢侈品,如果这是常态,她是想不起格外拿来说的。假设真有许多房产,谁会言必论及、百般强调?假设真有许多房产,这样百般强调又多么无聊。小夜为了适应她为自己编造的角色,需要频繁地背诵。
就像一个人说自己是贵族出身,受贵族教育,同时却随地吐痰一样,小夜的博客文章出卖了自己。计算电费和水费。等屠苏每月颁发的零花钱。吃东西,要等降价的时候。不怕周折更换银行,只为差别极其微小的利息。关注哪里有促销和赠品,哪里能用优惠券。从小夜那里链接到屠苏的文字,也在提供佐证。偶尔安排的两人旅游,即使从北京到省会城市,他们也不直飞,凌晨五点出门,赶中途周转的航班,且借住亲戚家。他们都有记账的习惯:买了六块钱的门票、花了五块钱的手续费。旅行的体会,就是晒各种花销。我能理解记到个位数的账目,不能理解,在机会珍贵的旅行中,他们得到的享乐,不是见闻的增长,而是省了多少钱。屠苏的旅行日记毫无知识含量,整天记几乎要带小数点的钱财,即使那时屠苏还算生龙活虎,他此生发财的可能性已变得越来越低。锱铢必较,格局小,他把太多心思用于计算。即使节俭的旅行,也有像人生一样需要浪费的部分,因为美与感性都隐藏其中。如果事事如此,再美好的旅行,也是两个财务人员奔行在审计的路上。或许屠苏热衷世俗生活这种热气腾腾的日子,天生就和小夜水乳交融。
人不怕物质上的穷,怕的是精神上的穷。屠苏最爱的这个女人,字里行间,炫耀自己怎么有钱有权,怎么充满魅力。小夜说不管什么人,只要与自己交往就喜欢她,不分地域、年龄和性别。在任何地方都是中心人物,失踪几天,世界各地都来打听下落。买衣服、剪头发陪着的是银行夫人,是达官显贵。她说自己本来可以成为显赫的高官夫人,到哪里都有称兄道弟的当地领导陪同,办事如履平地,去博物馆都包场独享。
小夜自视真诚,不屑他人,认为他们不如自己高洁和高妙。除了屠苏,她预想的他人,总是有着种种的不洁手段。小夜之所以把别人看得满嘴谎言,看他们攀龙附凤,不要脸、不要命地向上爬,可能是臧否同类的习惯。每个人只能通过自己的眼光、角度和局限来看待别人,自己撒谎看别人都撒谎,自己势利看别人更势利。君子看谁都是君子,小人看谁都是小人——我们所看到的别人,常常是自己灵魂的映像。
她博客所记载的,和上次跟我谈话的内容,异曲同工。重点还是她在爱情上的成就。她的律师身份说得渺渺茫茫,从来没有细节,她用的都是债权、法院、法制办这样的虚词。她的阐述禁不起推敲,失常、失真、失信。小夜唯一可以拿出人证的,就是屠苏的爱情,所以她刻意渲染和经营。有些深爱者不善表达,只是默默沉淀,有时语言上留下多少痕迹,反而在情感上减去多少分量。一种需要用语言不断加固的爱情,多少可疑。从小夜的谈吐到网上的文章,无他,除了屠苏还是屠苏,她当然把这当作可歌可泣的神话。可除了电脑游戏和家务,没有独立生活的女性,爱起来,容易令人不堪其重。像藤蔓,她在寄生的环境里,完成绞杀。小夜自己或许不知道,或许,她认为这才是最美的相依相伴、最匹配的比翼齐飞。
35
小夜所津津乐道的,唯有比喻中的爱情、修辞中的财富、符号中的职业、想象中的品德。她到底是不够自信,才导致如此剧烈到离谱的变形;还是和屠苏一样,理想中的自己与现实中的自己落差太大,大到理智难以相信的程度,需要用致幻剂麻醉自己?科学实验表明,当一个人撒的谎越来越多时,谎言程度会不断增长,会越来越大胆,大脑产生的情感反应会随之变得越来越弱。一个欧洲学者以香水来比拟撒谎的上瘾过程:“你把它想象成一瓶刚买的新香水,刚开始闻起来气味非常浓郁,几天之后它的味道就淡了些,一个月以后,估计你都闻不出任何味道了。”这就是为什么小夜的言辞那么捉襟见肘,逻辑与逻辑之间不能缝合,临时的托辞补不上天大的窟窿,可她不以为意。
小夜接触网络迟缓,不会开车,不具备外语交流能力,怎么可能是国际贸易和法律双硕士并执教大学、叱咤商界?屠苏为什么听任这些睁眼的瞎话?我以前哀叹,把这些归罪于屠苏老实。不说谎的人恰恰最轻信谎言,因为他们不具备欺骗的意识和常识,不具备侦破与反侦破能力。我以为屠苏并没有什么罪过,他只是被自己的诺言逼迫成小人;我以为屠苏只是太容易向平庸妥协,他在过程中种种不适,直到被摧毁。不,没那么简单,种种证据表明,我为屠苏的辩护难以成立。
隆重而漫长地被爱,是小夜此生唯一的骄傲和支撑。对屠苏来说,何尝不是?这份爱情,是他此生最为骄傲的牺牲与给予。彼此的一生都平凡渺小,只有这桩神话样的事体,接近伟大。夸大其辞的小夜有一点并未说错,她的确是屠苏的灵魂伴侣。更进一步,他们天造地设,他们是彼此的投影。
他们来自同一个地域,同一所青春成长的学校,屠苏退回同乡同源,相同的文化背景让他松弛。他在北京是否一直撑着,像戏剧中脚踩皂底靴的演员?退回源头,是否隐藏他的懦弱与乏力?我想起,屠苏和小夜的微信中,使用吃饭饭、洗脚脚、睡觉觉之类的幼儿语言,或许潜意识呈现出精神上的倒退乃至蜷缩。两个在现实世界中的受伤者,把自己当作婴孩,也给予彼此儿童式的安慰。他们的爱好相似,志趣相似。不仅是热衷自拍和记账,不仅是喜欢抒情到煽情的抒情歌曲,还有更深层次的价值认同。他们是惺惺相惜的同类,区别在于,由于屠苏的智力、天性以及接受的良好教育,使他修炼出更好的教养。他们并非天使与魔鬼的故事,这是两个人被内心的天使和魔鬼共同驱遣。哪有谁会自认魔鬼?魔鬼都会觉得自己是天使。不过他们面对彼此时,或许呈现出天使的一面。
36
从博文上看,小夜的确比一般人的表达清晰流畅,仅此而已,并未出色。她的理解常有偏狭,见解乏善可陈,容易把人云亦云的东西当作径自得道的别见。她指点江山,洋洋得意。她假设,如果自己当初没有自愿放弃文学,今天必一鸣惊人。没有跟唱者就认定自己是交响乐,花拳绣腿站不住脚就认定自己打的是难被效仿的醉拳——小夜自恋,饱满得变形。我意外的,是屠苏和小夜的思维如出一辙:如果换我在别人那个位置,我会做得更好。
屠苏舍不得扔旧电线,说为了退休以后搞科技发明。他明确表白,后悔自己读文学系,否则以他的理工科智慧,早已在这个科技时代游刃有余,发家致富,让小夜拥有顶级奢华的生活品质。文学不再是他终生的安慰,甚至是他现实人生不尽如意的祸端。可屠苏的借口有些自欺欺人,环顾四周,许多学理科的未必就暴富,学文科的未必都贫困。当物质和精神都抵达不了自己的渴望,他们依靠虚构。小夜热衷编造,是拿已经发生的事情编,编得漏洞百出;屠苏,拿没有发生的事情编,不好否定。屠苏在我的散文中曾被称为“匹诺曹”,后来匹诺曹长大了,他学会了一种不让鼻子变长的说谎技巧。
以爱为名,这个命运配送的看似会对他产生巨大促进作用的女人,每天陪他一起梦游。两个梦游者自说自话,由幻想带来的心理自信,其实是自我催眠的手段。他们远离人群,彼此不会揭露和施加惩罚。我悲哀地发现,他们是利益共同体,一起分享谎言的福利,荣誉与利益都在其中。他们对彼此来说,是孤证,是互为佐证的逻辑。他们互为支撑,互为梦幻,互为舞台上的追光灯。如何能不相爱呢?像一对孪生的蛹,困锁在茧衣。在那个真空的世界里,他们快乐,如鱼得水。他们依靠精神鸦片,走在坑坑洼洼的现实里……美好而丧失行动能力,他们依偎在一张柔软病床上。两个或明或暗的名利之徒,就这样气场相融,琴瑟和谐。
他们与外界之间,隔着鲜明的壁垒。别人的非议,他们充耳不闻,他们只在自己不可理喻的沉迷里;即使偶尔关注别人,也是不自觉地诋毁,诋毁过去的关系和情谊。他们置身浪漫的童话里,别人活在清醒而残酷的现实里。许诺中的天堂就像睡眠中的梦,容易翻转为深渊。唯一的办法,是争取梦境不醒,争取永远沉睡其中。
37
小夜对屠苏的妻女、父母和兄弟姐妹毫无愧色,屠苏不以为意。屠苏不需要小夜的愧色。因为她的愧色就是他的。小夜越是能找到似是而非的堂皇理由,屠苏就越能解脱自己。他需要的,恰恰是她的挑剔、无情乃至残忍。屠苏由此身轻如燕,他甚至感恩于小夜帮他卸掉沉重的包袱。
出于道德自救,小夜强调自己是施恩者;同样出于道德自救,屠苏也必须坚持,前妻是婚姻的剥削者。他们都有看低别人、赦免自己的习惯——罔顾事实,使所有事情朝着有利于自己形象和分量的利益方向倾斜,然后编码,重新做图像的技术处理。
小夜第一次见我,就不满我为什么否认暗恋屠苏,她不喜欢我申辩。的确,从一嗅出她那种获胜者的得意,我就不愿给小夜这部自己搭台子、自己入戏的剧情片当临时女配角。我反感那种煽情与沉浸,拉个帘子就错觉自己是谢幕的女主角。假设我或屠苏的前女友过得不错,并不妨碍小夜的心境,因为她发明一套换算公式。所有没被屠苏“选中”的,都是埋在土里的肥料,以烘托她的鲜艳;肥料用得越奢侈,越能说明,花蕾美得,值得那无数的死。至于前史们的挣扎,小夜根本忽略不计,不过是蚯蚓拱动松土,有助园艺。小夜只是不希望明慧的前途似锦,毕竟,那会让别人替屠苏遗憾,觉得他放弃得不值。我那时以为,自己之所以被当作屠苏的情感边角料,只是小夜之过,所以特别对抗:别以为我是松动泥土的蚯蚓,不,我是棺材里起义的死人。
读过小夜的博客,重读屠苏写我的文字,我才恍然,她的错觉并非空穴来风。难怪小夜以为我一往情深,从某个角度讲,我也的确成了夫妻之间的谈资。爱里面,难道不是要包含畏惧吗?屠苏哪里得来的自信,认为我们因为被放入他的妻妾选购车里而喜悦呢?不管是由于彼此不够达标,还是互动不到位,总之,我从未设想自己的婚姻与屠苏有关,也不认为被他选中是件幸事。屠苏文章里的,引用我的原话:“愿我们之间始终维持着距离,由此鸡犬相闻一直到老。”只是,它微妙地,被转成屠苏的语气,由此接近于他在表达婉拒的态度。屠苏即使没有直接吹嘘,也在沉默中暗示,他无心垂钓,多少大鱼小鱼受到诱饵的蛊惑而上钩,却被他扔回海洋含盐的苦水里默默饮恨,嘴边挂着撕开的伤口……这些或深或浅、终遭舍弃的艳遇,都是屠苏喂给小夜的饵料。小夜喜欢的话,屠苏就扭曲事实,或者听任她的曲解和诋毁。屠苏放大自己对其他女性的放弃以烘托对小夜的痴情,小夜放大屠苏的放弃和痴情以强调自己的珍贵……没有谁,希望挑破内幕。
许多情感细节如果不是屠苏出卖,小夜无从得知。屠苏遗弃文学,可他还保留了抒情的惯性。我发现,成年以后的抒情,容易长成一种危险而可怕的习惯。我写“匹诺曹”时借用屠苏的原型,为了保护原型或加强表达效果,我有情节上的挪移和想象;可屠苏把虚构事件,凡是有助于他的形象魅力的,都当作实际发生的真事讲给小夜……他心知肚明,我们不会当面对质。不能怪罪小夜,当屠苏对我态度淡漠的时候,我还在文字里一往情深,难怪她会产生优势心理。以小夜看来,无论过去还是现在,我们都因没有进入屠苏的决选名单,没有像她一样夺魁而耿耿于怀。
屠苏和小夜双双舍弃文学,并且把这种舍弃当作省悟而得意。他们不再写作,只保留了虚构的技能残渣,保留了未成熟者微酸的抒情习惯,用以杜撰生活。两个曾经的文艺青年,慢慢进化着自私:为了使自己的梦境看起来更绚丽,他们罔顾事实,不惜盗用建筑材料;如果必要,不惜盗用别人的血肉和骨殖作装饰。
我不知是屠苏的描述还是小夜的篡改,说我当初一只花蝴蝶似的翩翩于一群单身汉之中;明明是只冒充白天鹅的黑乌鸦,以为在天上飞就被地上看的男孩们倾慕。觉醒的屠苏才不会那么愚蠢,他冷笑着离开,不关心我什么时候被揭穿身份。事实上,直到今天,我虽与其他几位联系不多,但情谊都在:他们当中既没有任何一位在男女意义上追求过我,我也没有对他们其中任何一位心怀惦念。而小夜言之凿凿,几乎指名道姓,在博客里对我进行实名声讨。
38
每个人都有复杂性,都有自己不愿承受的卑污。无论我们受到多少教育,无论怎样内疚和反省,利己的小心思和小盘算总会运转。我们的行为总是突破自己的意识、伦理、道德和价值观而屡犯错误。正因此,更需外在的校正和内心的自我提醒;一旦丧失两者,我们会陷入比自己预想得还要深的沼泽。
小夜不会反省,就像她断然回绝与某些人聚会,因为嫌弃他们是离过婚的,完全忽略自己也是同样的身份。屠苏自身立场就不坚定,耳濡目染,丧失了知识分子最为宝贵的品质和能力:反省。也许对于屠苏来说,微弱的良知也是危险的,会带来疼痛和灾难,他索性掐灭这个带着光亮却能烧毁自己寝铺的烟头。他的知识,反而使他失去了朴素。被异化的过程,日常且漫长,令人习焉不察。屠苏在博士论文中洋洋洒洒,纵横捭阖,宏论中国教育,我不知道他在痛陈弊端的同时,有没有反思,作为父亲的自己所放弃的责任?屠苏撰文的时候,潜在地,把自己当作完善的教育专家,当作承担社会使命的智者——演讲的语感,匹配着他为自己设定的完美形象。
我自己呢?杜撰和美化,我何尝不是缺乏反省地陷入其中?屠苏并不念旧。也许我们人人均如此,念旧,只是因为尚未找到合适的新。屠苏对自己的血亲尚且冷淡,何况作为路人的我。而我偏执地,把屠苏设想为默默怀念我的旧友:以此证明,我别具价值,我给予他的精神享受无可替代。其实,也是一场自作多情的误会。我最初以为太多矛盾之处,都是不应该发生在屠苏身上的。我加诸他太多善意的想象,已纷纷抖落。一旦把屠苏的起点还原到真实位置,所有的链条都畅通,完成了自然的解释、合理的注脚、必然的结局。
如果不是小夜,我不知道屠苏对婚姻的态度,也不知道屠苏执意与我相忘江湖的原因。他对我,积怨已久。
39
屠苏对我有过短期的怀念。明慧的婚姻助力不过尔尔,使雄心万丈者产生几近上当的强烈挫败感,他转而悼念自己的损失。我本来没有什么价值,但如果计入屠苏为上一段婚姻所牺牲的成本里,也算一个小数点之后的数字。在那个期间,他写下怀念我的文章。随后,屠苏与一位未曾谋面的偶遇网友互诉心曲,缥缈的存在也象征慰藉。远水不解近渴,屠苏依然感觉自己的孤独……漂浮着,没有锚定的重心。
直到,梦中情人现身。小夜兼具仕途助力和灵魂沟通的渠道,她简直是完美的结合,弥补明慧和我的毛病。小夜还有七虹所不具有的忠贞,以及对屠苏的仰视,她仿佛带着理解的态度和实现的手段,将一切奉献给屠苏。
屠苏有绝情的一面。为了一息亮光,他舍得放弃。始终舍得,无论是家室还是友谊。当初屠苏果断斩断前尘的勇气,来源于从远方透来的一线曙光,来源于小夜信誓中的财富与背景。他对小夜,既有青春期的留恋,又对她勾勒的蓝图心怀向往。弟弟调动成功,极大鼓舞屠苏。小夜周游于权力者之间,长袖善舞。一切,点燃了屠苏已逐渐暗淡的激情和权力欲望。
即使在婚后数年,屠苏锱铢必较地运算每笔开支,小夜依然在与屠苏互动的博客中炫富,像专门说给他的解释。这时候的屠苏还信吗?他希望中的光荣与轻松何在?屠苏以丧失元气的年近半百之身,遭受命运更猛烈的拳击。以前我把屠苏当作琴棋书画、不合时宜的旧公子,一腔侠骨柔情,没想到他始终期待,能利用婚姻的捷径。以性器为撬棍,多少轻贱了自己,即使不说屠苏寡情寡义,也有令人齿寒的功利。可惜欲速不达,他没有走上他以为的捷径。过人的才智没有把屠苏拯救到天堂,他被致命的缺点拉入地狱。
其实屠苏无论娶谁,都需要经历成长、忍耐和磨合。十有八九的年轻女性,刚结婚的时候,或急切慌张,或有控制倾向;男性也一样,粗枝大叶,毛病多多。婚姻中需要学习和调校的过程。屠家人设想,即使屠苏没那么喜欢明慧,如果当初不离婚,重大事情有明慧参与,如果屠苏肯付出十年磨一剑的耐心,如果他对妻儿抱有感激的情义,走到今天,也许早已收获了期待中的成果。屠苏总想获得崭新的机遇,结果一手好牌,打成坏局,输得血本无归。他想用便利工具,结果没撬到什么便宜,反而划伤了自己的手,血流如注。
人生的每次选择,都意味着一次闯关或抽奖的机会,可能沦入困厄,也可能迎来救赎。就像打电子游戏一样,下一秒,不知道是贵人或利器的增益,还是恶徒或暗箭的威胁。屠苏的方向总是选错,赌大赢小,赌小赢大。如果说屠苏不可控制外部的仕途环境,至少,内部的家庭关系是他可以调节的范围。不能完全用坏运气来解释,屠苏有许多主动的行动。与其说他命运不济,还不如说他不够专注。我突然发现,屠苏缺乏耐心,不仅爱情,文学还有职场生涯都是如此。任何人只要心无旁骛地努力,等到最后,都易于获得美满的结果。屠苏不断转移,这是缺乏耐心,也是一个更长时间段里体现的急功近利。
屠苏给人的印象是淡泊名利、超然物外。其实,并非不屑红尘滚滚,他在意,但他自尊强烈,希望自己以漫不经心的方式得到,不被别人察觉出焦灼。屠苏的急功近利比较隐蔽,更是在性格安静和技术保障下的不动声色。他的入世是以不入世的方式为表象的。屠苏私下非常羡慕得势者,又不甘心,他们明明技不如己。可屠苏不愿亲力亲为,他的提起和放下都不够彻底。就像他为自己的不得意寻找外在借口一样,屠苏寻找外在的援助——这种祈求,就像虚弱者祈求神明。一浪一浪地被推动,丧失定力的屠苏像被迫离开的海星,吃力挪动自己看似钙化的触角,寻找新的礁岩。位置还是不够好,他祈盼洋流把自己带到更为理想的位置。与明慧的婚姻不够好,喜欢的文学太冷门,落脚的单位太清贫,屈就的职位太低微……一介书生的屠苏,没想到书本之外的世界复杂得难以圆融应对。
急功近利的屠苏忽略了时间的报复。跟时间赛跑?好大的口气。有输赢才能叫比赛,可对于时间,我们哪儿有参赛的资格?他在两个女人之间蹉跎的时候,他在文科与理科之间挣扎的时候,他在事业与企业之间犹豫的时候……也蹉跎了自己的才华,错失机会和巅峰。
才华本身是出世的,上苍恩赐是为了让我们在精神世界里更优美地遨游,如果总是用它来解决现实困境,用来谋求世俗意义的好处,所谓的才华,很快会被消耗殆尽。
鼓城中学毕业时,屠苏曾与小夜约定:“二十年后再相逢,要在文学上一决雌雄。”当文字不再是屠苏的内心需要,仅仅当作偶尔借助的过渡工具……“屠苏不知怎么回事,后来连简报都写不好。”路平安再次感叹,“他的才华不足以驾驭他的欲望。”
40
心比天高,命比纸薄。我以为,屠苏是单纯而笨拙的书生、文人、理想主义者。我以为多数人活着,不是受有钱的罪,就是受没钱的罪,唯屠苏是超脱的一个。我以为生存竞争有如罐子里的残杀,屠苏不具备足够恶毒的腺液,不能成为活到最后的蛊虫,所以他从前想躲进学校的象牙塔,后来想躲进小夜的蜗牛壳……因为他在心智上不会巧取,在气力上不够豪夺。有太多的“我以为”,是我把屠苏强行塑造为理想主义者。
即使屠苏并不高大和清澈,作为一介凡夫俗子,他似乎也没有那么大的罪过,我为什么不依不饶地苛责?我承认,情绪里面包含了我自己的恼怒和悲愤。小夜博客读到最后,白纸黑字,屠苏有三个字对我触动巨大。鼓城中学里,当十七岁的小夜问十七岁的屠苏,未来的理想是什么。屠苏意气风发、斩钉截铁地给出答案:“要做官!”这被小夜夸为远大的志向,尖锐地刺痛我。
当年屠苏旁敲侧击向我提及,他可以就任某大报总编辑。我那时不谙世情,哪里明白屠苏心迹?懵懵懂懂听过去,没当真,没听出其中流露出屠苏的追求与向往。今天回想起来,我心头一惊,当年二十多岁的屠苏意欲担纲如此重任,虽壮志凌云,却痴人说梦。何况我不认为,以屠苏的文笔和气场,能够驾驭他以为自己可以的那个角色。屠苏对我近则不恭疏则怨的态度,让我琢磨不定,原来他恼恨于我始终袖手旁观。屠苏认为,我帮他是举手之劳,而我甚至连杯水车薪的表态都没有。
我相信屠苏的恼恨是真的,否则小夜不会清楚细节:我是北京城市户口,父母属于屠苏认为的领导阶层。屠苏希望我主动提供世俗意义的帮助,给他找关系、托门路,以飞黄腾达;可我不食人间烟火的简单和弱智,加上我骨子里排斥官场政治,使骄傲的屠苏难开尊口。他不说吧,我永远没那个自觉意识;说了吧,我们价值观冲突,我会因此低估他的高洁。对他来说,我本来就姿容欠佳、形体健硕,最大价值就是不错的家境,但这条或明或暗的路径却在我这儿被打上死结。我满心思误人误己的文学梦,官场不仅绝非我向往的生涯,也是我的婚姻观不愿接纳的。我怕丧失自由,怕力量微弱的自己没有足够定力,怕承受不了考验,怕被卷入体制绞肉机里,所以视为畏途。而时隔多年,我才明白,屠苏的艺术追求,服务于他的现实要求,纯粹的精神享乐不足以替代一切。
我们之间,是理想国与世俗社会之间的对话。或许我们原本置身两个不同的国度,屠苏的母语是世俗社会的,不过他精通理想国的外语。除了能写点东西,我百无一用;明慧背后的领导若隐若现,成为屠苏选择明慧的重要砝码。加官进爵的渴望,使他的心理天平倾斜乃至倾覆。屠苏决心撤得干干净净,他或许已耗尽对我的耐心,认为离开我才是明智之举。
最后的相处,我一直理解为君子屠苏的克制与隐忍。和衣而卧,在黑暗中清谈,那块裤子上被少量体液浸渍的斑迹,证明了规矩的屠苏所承受的压力。假设情感果真充沛,在年少莽撞里,他恐怕很难守住理性。屠苏的克己,可以解释为他对异性的好奇、对朋友的尊重和品性的正直;也可以解释为,我的吸引力不足以启动他的运行程序。可以归结为柳下惠的高洁;也可以解释为考量,他已决定投奔明慧,不想节外生枝。冲动的结果不过春梦一场,美妙而尴尬,万一生米成了熟饭,是否会产生变数,危及未来,让前途烟消云散?面对诱惑,屠苏不为所动,就像考试前的忘我备战。这是一种实际的计算,是权衡、比较和判断的结果,是遗憾也是彻底的选择。那晚,屠苏抵抗住来自身体的召唤,之所以展示出近乎钢铁的理性,是伟大的仕途理想让他的欲望归于职守。
时隔二十年,我才悟到,那是真正的告别之夜。我们的理想和路途,从那天那夜那一刻,已分道扬镳。
41
屠苏成长于二十世纪八十年代。八十年代,仿佛是理想主义者最后的天堂,最后的庇护所,最后的诗意时光。那时肆意谈论金钱和权势都是可耻的,我们在轻微的贫苦中,更容易感受精神的丰足。在充满理想主义的时代,每个舞台上的表演者,都被理想的聚光灯照射为散发理想主义光芒的理想者。你能说那个时候的屠苏不真诚吗?不。人有时会被自己感动,在某一个阶段里他就是真正的理想主义者。如同酒喝高了,在那个精神醉酒的阶段里,他可慷慨激昂,可舍生取义……尽管酒醒了,他会后怕。我不认为屠苏的理想主义是伪装的假面。理想主义潜藏在我们的性格之中,有时激昂,有时沉睡,有时含量极少的理想主义在现实中并未发出光彩就完全熄灭——但,都是真的。当时种种是真的,后来种种也是真的,即使两者反差巨大,到悖离的程度。
我无从得知屠苏内心变化的过程。但作为转型期的目击者,我知道当中国在上世纪九十年代进一步迈向商业社会之后,许多曾经的文学爱好者,一夜之间改弦易张。诗人夹着皮包成为商人,文人夹着公文包成为领导,多少有才华的写作者被淹没乃至是自愿埋葬在物欲横流的旋涡之中。有些人对文学的态度从爱慕变成鄙夷——什么诗意,什么思想,不过是大脑里引发的化学错乱反应,不如体力劳动创造出的实物更具价值。
屠苏由理想主义者向现实主义者蜕变的过程中,钱,变得越来越重要,越来越让他妥协、屈服和恐慌。屠苏不阅读、不写作、不涉及文学,他不看没用的书了。屠苏没有来自亲友的劝诫,没有来自书本的校正,做出独立判断所需要的经纬坐标系消失了。屠苏在所谓的爱情中,却丧失爱的体验与给予能力。科学家研究表明,关心别人的人比冷漠者更容易愉快。屠苏越自私,就越不快乐;不快乐反过来使他越来越麻木:没有理想,没有约束,没有良心的痛楚。
也许屠苏觉得文学的力量微弱,这根曾支撑他自信的稻草,没有变成船桨把他摆渡到彼岸。打湿的稻草什么用也没有,只能成为压垮骆驼的重量。但屠苏的放弃,没有换回什么渴慕之物。爱钱的死于黄金,爱海的死于浪。上帝有时会因为一个人的执着而怜恤,给予回应与奖励;有时会因一个人的贪念而嘲弄他的作为……如果他的行为触怒上帝,上帝也可以给予整个世界,然后再完整地收回。
仿佛是理想主义者最后的天堂,最后的庇护所,最后的诗意时光。那时肆意谈论金钱和权势都是可耻的,我们在轻微的贫苦中,更容易感受精神的丰足。在充满理想主义的时代,每个舞台上的表演者,都被理想的聚光灯照射为散发理想主义光芒的理想者。
我对屠苏的调查与追踪,这到底是个什么故事?一个理想主义者在现实中丢盔卸甲,还是一个现实主义者在追逐理想过程中头破血流?是一个理想主义者在现实中的失利,还是一个现实主义者在理想中的失手?是一个理想主义者的悲剧,还是一个利己主义者的挽歌?多年来,我只凭着一腔执念,笃信屠苏是不折不扣的理想主义者,现在我发现自己回忆不起他理想主义色彩的任何情节和细节。原来,在八十年代理想主义者还不准备散场的舞台,屠苏已悄悄离开剧院……他独醒,他有更为远大和具体的抱负和野心。
残留的理想主义,是否构成干扰?如果屠苏在仕途激流勇进甚至不择手段,或许能赢得不错的发展空间。因为他勤劳、认真、卖命的品性,又不缺才华,领导容易赏识这种工作踏实努力的,即使屠苏掘取地位和财富并不手软,也会被视为天择之道。然而,十七岁的屠苏“要在文学上一决雌雄”和“要做官”都是真的,他都想要。慈善家可以说这是一个完美主义者的弱点,刻薄者可以说这是一个贪婪者不知餍足。如果屠苏彻底选择、彻底放弃,是否就不被理想和欲望撕扯?每当屠苏想有所作为,滚滚洪流就冲刷他脚下的土壤,他摇晃和犹豫,似乎相反的方向,才是更好的选择。
42
中国古代文人有两大普遍理想:田园归隐和仕途高就。一种闲云野鹤,一种达官显贵,似乎风马牛不相及,但两者之间存在秘密的终南捷径。文人墨客虽向往陶渊明的桃花源,但一步到位的归隐,对他们来说,依然包含壮志未酬的遗憾、未试身手的不甘、气亏神散的委屈和不被赏识的挫败;似乎,只有功成名就之后的归隐,才是气定神闲的归隐,才能跃升为顶级意义的成功。
学以致用,没什么不好,只是我们倾向于把这个“用”,理解为当权者的器重。我们都知道独立精神、批判立场和边缘位置,有益于知识分子的灵魂建设,但“书生自有嶙峋骨,最重交情最厌官”的骨气,已在许多中国当代知识分子中丧失。我们有许多技术型的“知道分子”,充当的,不过是资料的存储器和利益的转换仪,一味向世俗妥协。我们缺乏人文情怀,缺乏胆识与见识;我们缺乏独立人格,不追求灵魂的自由。我们之中,有太多向往依附权势、以谋求立足和前行的藤本植物,少有树冠高大、花期盛大的乔木。
鼓城那个满腹经纬的宰相,在广场上被塑以金身——他对屠苏来说,是励志的榜样。“要在文学上一决雌雄”和“要做官”,分别对位于文坛与官场的双重地位实现。屠苏所求,是互为渗透的功与名。文学成就高了,官运更亨通;官运到了高位,更有助文人的声名远播。可惜屠苏在社会和家庭里,都不是管理者角色。在当代中国复杂的官场运营模式和升迁系统中,他缺乏应对的耐心和能量。在家庭领域,屠苏牺牲沿途所遇,向小夜献祭他们的血肉与人头,无论他的心理如何满足于为女皇效忠,在别人眼里,他也是奴仆。从精神上消灭,从肉体上消灭……屠苏最后的遗像,既非理想主义者,也非既得利益者。
出身低微的文人,最初多是理想主义者,因为他们迫切向往改变现状。少年屠苏成绩出色,可他随时要承受贫困境况带来的失学压力。营养不良,更是贯穿屠苏整个青春发育期的问题。逢年过节在亲戚家吃上一顿肉丝面,几乎是席卷而来令屠苏战栗的幸福。被家乡人羡慕、生活在北京的屠苏,过的依然是紧巴巴的苦日子。毫无靠山的小公务员屠苏,看到了权力释放的魅力。机关机关,一语双关,一个人的命运可以瞬间明亮、瞬间黑暗。对屠苏来说,当官既是从小志向,又是始终的生存需要。屠苏从生活在农村的孩子变成生活在城市的知识分子,始终被隐形的阶层意识所提醒和教育,他潜意识里对权力投靠和膜拜。剪枝后,植物更为茂盛地发芽;伤口上,身体会增生瘢痕。屠苏受够了特权的压制,积累的心理创伤,让他对权力的渴望要超过人们的均值。
屠苏是无奈的失意者,但有些挣扎者即使得意,也未获得解放,甚至更为可怕。有些寒苦者,无法克服沉淀在基因里的权力渴望。一旦得势,他们立即从贫农知识分子变成精英知识分子,乃至是特权知识分子,他们可以成为旧制度的新帮凶,甚至是新的独裁者。他们把自己所曾遭受的损害与凌辱施加给别人,认为这就是平等。从痛恨专制主义,到对特权的忘我追求——角色转换如此迅速,他们从受害者果断地成为施害者。手里掌握一个计算器,他们就可以正义地巧取豪夺;换成一把枪,他们也可以杀得大义凛然、义薄云天。
43
有人谈到,为什么一些出身高贵家庭的孩子在品德上更具保障。因为在他们的成长过程,不需要通过说谎来换取资本;他们也不怕说真话所需支付的代价,他们支付得起。
朋友方希聊天时曾说起,为什么富二代似乎成了天然就饱含贬义的词。实际上,富二代无需因为生存角力而变得面目狰狞,他们普遍接受良好教育,就知识、眼界和道德的整体水准而言,许多优于普通阶层的孩子。为什么说起来富二代都同仇敌忾,都把他们当作全民公敌?就因为他们爬对了一个子宫,付出nothing,得到everything,不公平。
我对所谓的特权阶层和底层,同样不了解。给我带来观念冲击的,是大学毕业数年后的一次同学聚会。彼时有人混上中层管理岗位,推杯换盏之间,大张旗鼓地吹嘘业绩。敬酒是敬酒,祝贺是祝贺,可我平静,在热烈氛围的映衬下近乎冷淡。其中一个志得意满者心生不快,质问或者说是谴责了我:“你有什么资格超然物外?你不过是有着不错的籍贯和爹妈,从小用不着卖汗卖血。换到我的背景试试,不信你还能清高!”我以前约略知道,他是从最贫瘠的穷乡僻壤里奋斗出来的,但我不知道那种具体的苦,不知道,吃盐长大的人生并非修辞。别说营养了,他难得能把自己喂饱。所谓吃菜,永远是一罐重盐的咸菜;咸菜也限量,多数时间里,他吃馒头夹盐。他的爷爷奶奶过世,送终的,是一家人的眼泪和裹住尸体的两床薄席。在没有青春的青春期里,他成长得何其艰难;能有今天,他几乎是劫后余生的幸存者,怎能不为自己庆祝呢?我无言以对。我没有承受过考验,不知道自己的灵魂在多大压力下就会变形。后来聚会的氛围越来越嗨,大家喝高了。两个同学在拼酒力和实力的过程中,终于争执起来。还能比什么呢?他们要酒后滋事,要被出动的警察抓起来,比一比,谁能靠特殊关系先把自己营救出来。
不能说,我们这代人是某种类型的最后标本。然而,由于中国社会结构和阶层状态的巨变,出身贫苦的孩子和家境富裕的孩子,教育环境的先天差异越来越大,上下流动的通道虽不致关闭,但恐怕越来越窄。像屠苏一样,赤手空拳,只凭一己之力,就跃升到一流名牌大学的奇迹,概率越来越低。即使考入名校,未必直入坦途。多少像当初屠苏一样向远方出发的梦想家,无声无息地,被吞噬途中。无论走多远,他们,还是徘徊在食物链的底端。
44
底层和特权阶级。挣扎者和安逸者。创造者和剥夺者。我们能否从一开始,就判断出致命的区别?猫和鼠、羊和狼、兔子和狐狸、鸽子和鹰、牲畜和人类……这些互为天敌的,胚胎极为相似,长得相似的模样。什么时候,我们把山羊和绵羊分开?什么时候,把猎食者和猎物分开,把禽兽和天使分开?什么时候是泾渭分明地分开,什么时候是血肉模糊地分开,什么时候是生离死别地分开?
我所怀念的,或许是一个作为胚胎的屠苏。当年聊天,松弛而畅意,我们被彼此灵魂里的磁性吸引。生活的压力和考验尚未来临,我们在丧失重力的真空里,在文学和梦想的子宫里,自由漂浮。我们年轻,纯真得透明,自以为可以看穿许多;可也正因为透明,我们可能隐藏自身许多的叠层,隐藏我们自身的挑剔、愚蠢、懦弱、贪婪和自私,隐藏品德里将会沤烂并发酵的渣粒。那个年纪,那个时代,无论是年轻的屠苏、年轻的小夜,还是年轻的我,都纯真。小狮子眼神柔和、害羞、讨好,它还不够强大,还不具备背信弃义的资格。它摇摇晃晃,乞求被整个世界接纳;只有变得强大之后,它所有的冷酷和凶残才能显现和释放。未来,有人会从自己性格的这一端,不可思议地滑向另一端。年少时的刺青,怪兽威猛;等它在衰老的皮肤上显现,狞厉已变得滑稽。时间改写了事物性质,挖掘并暴露出一开始就隐藏其中的部分。
一个人如果在年少都不纯粹,一生就难有机会再纯粹了。如果年轻时就世故,人生未免无聊。莽撞、天真、好奇、任性、出世,甚至想入非非……年轻时如果没有这些,不仅无聊,也辛酸。小时候谁都散发天使的芬芳,慢慢,我们就有恶魔的气息。谁,能把我们内心的天使与恶魔分开?天使身上,有没有魔鬼的基因;魔鬼身上,有没有天使的血统?
45
屠苏退到死亡的极夜里,小夜继续在现实里制造极昼,勇敢无畏地,僭越现实给她制造的局限。
那次唯一的见面,我问过小夜她在哪所大学执教,她流畅给出准备已久的答案。小夜没料到,我闺蜜恰巧是那所大学的毕业生,她从留校同学那里得到准确答复:学校的人事档案里从未有过这位神仙。不出意料,小夜的演技不能胜任她所扮演的角色。小鱼汇成鱼群,就以为自己正在冒充体积壮观的巨鲸……可在大鱼和其他猎食者看来,一点也不像。小夜能怎么办呢?离开鱼群,她就像大鱼掉落的皮屑一样,匿迹于无声无息的黑暗……作为,食物链的底端。
我曾对小夜深怀抵触,慢慢,变成伤感。小夜像有毒的刺鲀扎伤别人,这是冒充的体积,只有被动者才如此膨胀地幻想。那种天下人都喜欢我的自得,哪里来的呢?我不认为小夜拥有众神与众人之爱。正是缺乏并渴望,那种叫爱的东西,她才会变本加厉地索求宠溺。小夜也可怜,她把屠苏的爱情当成宝、当成经书、当成蜗牛沉甸甸的壳,而斯人已逝,她的情感和未来已无栖身之地。她埋葬自己过去的爱情,开出泪光中微颤的回忆之花。
如果小夜对屠苏是全部的支柱,屠苏对小夜又何尝不是?屠苏用血浆灌溉爱情,如今只剩他不能再去呵护的爱人对着空气讲再也没人愿意听的童话。尽管被诟病,但谁能代替屠苏的感受呢?屠苏至少成了小夜的神,只有小夜,满足于他有限的喂养——粗茶就说粗茶的好,淡饭就说淡饭的香。也许他渴望自己被这样剥削,视为成就。如果屠苏情愿拿自己的骨头当柴,如果屠苏怕自己在温柔乡里一无所成,才强迫自己离群索居地去学习?即使小夜是毒,对于濒死之人,吗啡是否就是一种最为重要的安慰呢?就像被斑纹虎密布细刺的舌头舔过,这是唯一的安慰和温暖。
46
小夜忧怨于屠苏的孤单,归因于屠苏遇人不淑。实际上,这是屠苏对他人并不顾惜的后果,是他和小夜一起努力所致。他的家人,他的文学,他的道德,都被扫除了。在小夜的协助下,死后的屠苏,连同我这样被遗漏的一个朋友,也失去了。我一个人唱的苦情戏,屠苏不看不听;我所怀念的那个人,早已不是屠苏。
那么,我又何曾真正接纳过他?无论交往数月还是数年,我和屠苏之间,都像是那种没有下水道的建筑。务虚的清谈,虚幻失真,没有血肉的支撑。我们和异性的交流,必须深入到形而下的部分。形而上会带来彼此的欣赏,但形而下会带来现实的结盟……包括了对彼此不堪的接纳,以及由衷的谅解。我的所作所为,与友谊背道而驰。我一块一块移走基座上的踏板,一根一根抽去榫接的火柴棍,屠苏精心搭建的形象摇摇晃晃,直到,坍塌和碎裂在我眼前。我曾是爱惜他的朋友,如今亦是陌生人。我没想到是自己玷污了他的清誉,拆毁了友谊的乌托邦。对我来说,屠苏结束了他的雕像时代,我甚至不知道这个旧时代值不值得纪念。我至少应感激和屠苏谈论文学的快乐,甚至对他的漫长误读,也对我的成长颇具建设性。
屠苏在人世没有享受过轻松,我何必在他走后不依不饶?他仅剩人前的所谓品德了。倘若屠苏的亡灵站在面前,我不怕对质。我考虑是否对得起死去的屠苏,是残余的善意所在;可他活着的时候,就已对不起那么多的人。我不认为,死,是道德上的免死牌。宿命,在屠苏与小夜在鼓城中学的惊鸿一瞥之间已经注定;就像我所写下的文字,在屠苏与我谈天论地的时候就已经注定。命运的种粒,拱破土壤乃至石层,顽强地伸出它的芽茎。
我的怀念,到底是既深情又冷峻,还是既无情又刻薄?我们之间曾经的应和之作,都是他先写,我随后戏仿。唯有这次,是没有呼唤也没有回音的写作,对面是空旷的沉默。
嘲讽的是,我本来并不想写屠苏的回忆文章,虽然这是小夜最初希望的。我不知怎样坦诚而不伤及无辜。当发现小夜在博客里无所顾忌地诬陷我,我由此获得动力。如果小夜仁义在先,我不会不义在后——看吧,我的逻辑,从来没有脱开屠苏和小夜的套路。如果,如果,如果……我所需要的,只是他们给我一个伤害的理由,以便我毫无忌惮地还击。同样是作为利己者,我想要行为的正义性,我想让借口不那么像借口,我想占据道德优势者的位置……像在被污染的河里,一条鱼指责另一条鱼。这是我们的相似,我们的残忍。
47
万物悲伤。
一生挣扎的我们难免灰心。上帝也灰心,否则就不会用死亡把每个人都砸碎重塑。死,既是上帝的灰心,也是上帝的雄心。
我们习惯把生的荣誉归为上帝,把死的黑暗归于死神。上帝恩宠和责罚,死神信奉人人平等。我们总是亲近上帝、畏惧死神,这是原罪吗:渴望特权远胜渴望公正?可即使,死是降临在每个人身上的平等,灵魂去处也不一,有的去高高在上的天堂,有的去阴暗如下水道的地狱……每个人,生生死死,都不能摆脱眼前的梯级、身后的陷阱。
每逢春节的新岁,古人要喝屠苏酒。一般饮酒的习惯,是从年长者饮起;唯饮屠苏酒,正好相反,从最年少开始,长寿者排到最后。那最初在一起庆祝的,不能最后在一起缅怀,就像白居易为元稹写的那首诗:“君埋泉下泥销骨,我寄人间雪满头。”所谓人生,不过走马观花——骑在脱缰的马上,我们不知踏在时间的哪根秒针上……它正是致命的绊马索。甜蜜而苦短,一切仿若春梦啊;朝暮与呼吸之间,陪伴我们是醉了的酒神和睡了的爱神。
觥筹交错,酒宴未散,那个最初领酒的少年早已离席,默默地,消失于喧哗的众声。
[[黎紫书]] / 寻医记
```
这中医,我想以后我还会再光顾的。一是因为用了两帖药以后,胃病果真有所舒缓,二是因为我喜欢 “看中医” 本身所代表的情怀。
```
年写长篇时,心力交瘁,落下了恶疾。小说今年初完成后,胃成了身体里过敏的警报器,但凡过几个精神稍微紧绷的日子,譬如连续一周专注于翻译,它就早早 “跳掣”,闹各种别扭,出种种状况,虽不如去年写小说时那般歇斯底里,但它闹起来劲头大,韧性强,几乎就像那种会在商场里为了一支棒棒糖或玩具之类的什么东西,哭得撕心裂肺呼天抢地还要赖在地上打滚或直接变成一摊拖不走的黏稠物体的小孩一样,你是斗不过它的。
我的胃就成了那样的怪物。它掌管着身体的消化系统,上可令头脑发昏,下可指使大肠蠕动(或不蠕动),真冥顽不宁时可不是只有胃痛而已。过去 30 天里为它光顾了几回西医以后,我拿着友人发来的信息,按地址到某中药铺求医。药铺在某新村巴刹附近,闹中带静;长形的铺子小而杂乱,半似药铺半似杂货店,当眼处放的都是洗发水矿泉水罐头午餐肉。
那中医师七老八十,比起之前见的几个年轻西医,他的年纪本身已能安人心神。老人家个子矮小,但腰板依然挺直,举手投足气定神闲,说话不急不缓,完全符合人们对一个老牌中医师的想像。老先生还当真有两把刷子,把脉时低眉敛目,沉着聆听,像是我的手腕里有谁在哭诉冤情。此脉听了怕有三几分钟,然后他说,压力太大,绷得太紧,影响肝功能了,又说,正碰上更年期啊,
是的,他说 “更年期”。这三个字,之前几个医生提都不敢提。如今他坦坦荡荡的说,我便老老实实的听,又发挥我那与各行各业人士攀谈的天赋,与老先生从更年期说开了去,说到他 40 年悬壸,又兼二十余年传道授业的各种事;他还跟我说,把脉这事不是用“听” 的,而是用 “feel” 的。这句好,让我想起庄子的轮扁斫轮。学问高深了,即便是技艺吧,也有只可意会而不可言传之窍门。
由于我第一次光顾,老先生为我开了一本小册子记下病历。那小册子封面印着 555,看见它时我会心一笑,那可是小时候家里常见之物啊,许多年没见过这种小本子了,以为它早被时代淘汰,没想到它还活着。至于药方,那是白纸上竖印了红线,正上方印着楷体宝号;看着像什么前朝遗物,却明白是正宗的中医用笺。医师的硬笔字苍劲有力龙飞凤舞(十三味药材中我只看懂三种)。后来我拿着方子到前头抓药,一个白发老妪与一名青壮汉子联手,站在百子柜前摊开纸张,接下来你一样我一样秤了抓到纸上,中间没一下碰撞,也无须一言半语,须臾把五帖药包好。那默契,颇有点杂技似的视觉效果。末了,抓药的老妇一再嘱咐我要如何对付那些药──四碗半水煎作一碗,不能空肚服用。妇人嗓子大,话不温柔,但听得出苦口婆心。
这几日我就在对付这些药。它们被放在饭桌上,使得饭厅里终日弥漫着一股淡淡的草药香味。煎药时被蒸发了三碗半的水,将这药的味道传送到屋子各处,光闻着就觉得病好一点了,胃没有那么疼了。喝药的时候,我端着药碗正襟危坐,充满仪式感地将药慢慢服下。它就像记忆中的,我在少时喝过的别的什么中药一样(已彻底忘记那时为什么要喝中药),色黑,味苦。小时候喝中药是恶心事,须得母亲在旁监督;药没喝下去,只闻味道便要把脸皱成一团。隔了数十年,倒觉得这药中的苦并非真苦,反倒是草香沁人心脾,饮后舌上回甘,根本不像记忆中的那么难喝。
这中医,我想以后我还会再光顾的。一是因为用了两帖药以后,胃病果真有所舒缓,二是因为我喜欢 “看中医” 本身所代表的情怀。从诊病到服药,每一个步骤都富有仪式感,还附加香味和温度,对于我这么一个病人,好像在接受时光的抚慰,尝到了药方中没写上的一味“旧情”。我甚至觉得坐在那小铺前等待,看一只老猫趴在装矿泉水的箱子上睡觉,或是像个大妈一样,与别的来看病的大妈聊天(她们郑重推荐我买一个煎药专用的电瓷锅),都让我感到一种以前未曾觉过的安慰。
就是这些小光景吧,令我服服贴贴;让我在 “老去” 的苦涩现实中,尝到了绵长的回甘。
作者 : 黎紫书
文章来源 : 星洲日报 2020-12-18
李娟(1979年7月21日-),中国女作家,曾用网名“去年燕子”[1]。生于新疆生产建设兵团农七师123团(位于塔城地区乌苏市车排子镇)。高中毕业后,曾随家人进入阿勒泰深山牧场,经营一家杂货店与裁缝铺。1999年开始写作,作品以散文为主,曾在《南方周末》、《文汇报》等媒体开设专栏。
理想国与哲人王-王小波
========================
理想国与哲人王-[[王小波]]
------
罗素先生评价柏拉图的《理想国》时说,这篇作品有一个蓝本,是斯巴达和它的立法者莱库格斯。我以为,对于柏拉图来说,这是一道绝命杀手。假如《理想国》没有蓝本,起码柏拉图的想象力值得佩服。现在我们只好去佩服莱库格斯,但他是个传说人物,真有假有尚存疑问。由此所得的结论是:《理想国》和它的作者都不值得佩服。当然,到底罗素先生有没有这样阴毒,还可以存疑。罗素又说,无数青年读了这类著作,燃烧起雄心,要做一个莱库格斯或者哲人王。只可惜,对权势的爱好,使人一再误入歧途。顺便说一句,在理想国里,是由哲学家来治国的。倘若是巫师来治国,那些青年就要想做巫师王了。我很喜欢这个论点。我哥哥有一位同学,他在“文化革命”里读了几本哲学书,就穿上了一件蓝布大褂,手里掂着红蓝铅笔,在屋里踱来踱去,看着墙上一幅世界地图,考虑起世界革命的战略问题了。这位兄长大概是想要做世界的哲人王,很显然,他是误入歧途了,因为没听说有哪个中国人做了全世界的哲人王。
自柏拉图以降,即便不提哲人王,起码也有不少西方知识分子想当莱库格斯。这就是说,想要设计一整套制度、价值观、生活方式,让大家在其中幸福地生活;其中最有名的设计,大概要算摩尔爵士的《乌托邦》。罗素先生对《乌托邦》的评价也很低,主要是讨厌那些繁琐的规定。罗素以为参差多态是幸福的本源,把什么都规定了就无幸福可言。作为经历了某种“乌托邦”的人,我认为这个罪状太过轻微。因为在乌托邦内,对什么是幸福都有规定,比如:“以苦为乐,以苦为荣”,“宁要社会主义的草,不要资本主义的苗”之类。在乌托邦里,很难找到感觉自己不幸福的人,大伙只是傻愣愣的,感觉不大自在。以我个人为例,假如在七十年代,我能说出罗素先生那样充满了智慧的话语,那我对自己的智力状况就很满意,不再抱怨什么。实际上,我除了活着怪没劲之外,什么都说不出来。
本文的主旨不是劝人不要做莱库格斯或哲人王。照我看,这是个兴趣问题,劝也是没有用的。有些人喜欢这种角色,比如说,我哥哥的那位同学;有人不喜欢这种角色,比如说,我。这是两种不同的人。这两类人凑在一起时,就会起一种很特别的分歧。据说,人脖子上有一道纹路,旧时刽子手砍人,就从这里下刀,可以干净利索地切下脑袋。出于职业习惯,刽子手遇到不认识的人,就要打量他脖子上的纹,想象这个活怎么来做;而被打量的人总是觉得不舒服。我认为,对于敬业的刽子手,提倡出门时戴个墨镜是恰当的,但这已是题外之语。想象几个刽子手在一起互相打量,虽然是很有趣的图景,但不大可能发生,因为谢天谢地,干这行的人绝不会有这么多。我想用刽子手比喻喜欢、并且想当哲人王的人,用被打量的人比喻不喜欢而且反对哲人王的人。这个例子虽然有点不合适,但我也想不到更好的例子。另外,我是写小说的,我的风格是黑色幽默,所以我不觉得举这个例子很不恰当。举这个例子不是想表示我对哲人王深恶痛绝,而是想说明一下“被打量着”是一种什么样的感觉。
众所周知,哲人王降临人世,是要带来一套新的价值观、伦理准则和生活方式。假如他来了的话,我就没有理由想象自己可以置身于事外。这就意味着我要发生一种脱胎换骨的变化,而要变成个什么,自己却一无所知。如果说还有比死更可怕的事,恐怕就是这个。因为这个缘故,知道有人想当哲人王,我就觉得自己被打量着。
我知道,这哲人王也不是谁想当就能当,他必须是品格高洁之士,而且才高八斗,学富五车。在此我举中国古代的哲人王为例——这只是为了举例方便,毫无影射之意——孔子是圣人,也很有学问。夏礼、周礼他老人家都能言之。但假如他来打量我,我就要抱怨说:甭管您会什么礼,千万别来打量我。再举孟子为例,他老人家善养浩然之气,显然是品行高洁,但我也要抱怨道:您养正气是您的事,打量我干什么?这两位老人家的学养再好,总不能构成侵犯我的理由。特别是,假如学养的目的是要打量人的话,我对这种学养的性质是很有看法的。比方说,朱熹老夫子格物、致知,最后是为了齐家、治国、平天下。因为本人不姓朱,还可以免于被齐,被治和被平总是免不了的。假如这个逻辑可以成立,生活就是很不安全的。很可能在我不知道的地方,有一位我全然不认识的先生在努力地格、致,只要他功夫到家,不管我乐意不乐意,也不管他打算怎样下手,我都要被治和平,而且根本不知自己会被修理成什么模样。
就我所知,哲人王对人类的打算都在伦理道德方面。倘若他能在物质生活方面替我们打算周到,我倒会更喜欢他。假如能做到,他也不会被称为哲人王,而会被称为科学狂人。实际上,自从有了真正的科学,科学家表现得非常本分。这主要是因为科学就是教人本分的学问,所以根本就没出过这种狂人。至于中国的传统学术,我就不敢这么说。起码我听到过一种说法,叫做“学而优则仕”,当然,若说学了它就会打量人,可能有点过分;但一听说它又出现了新的变种,我就有点紧张。国学主张学以致用,用在谁身上,可以不问自明——当然,这又是题外之语。
至于题内之语,还是我们为什么要怕哲人王的打量。照我看来,此君的可怕之处首先在于他的宏伟志向:人家考虑的问题是人类的未来,而我们只是人类的几十亿分之一,几乎可以说是不存在。《水浒传》的牢头禁子常对管下人犯说:你这厮只是俺手上的一个行货……一想到哲人王,我心中难免有种行货感。顺便说一句,有些话只有哲人才能说得出来,比如尼采说:到女人那里去不要忘了带上鞭子。我要替女人说上一句:我们招谁惹谁了。至于这类疯话气派很大,我倒是承认的。总的来说,哲人王藐视人类,比牢头禁子有过之无不及。主张信任哲人王的人会说:只有藐视人类的人才能给人类带来更大利益。我又要说:只有这种人才能给人类带来最大的祸害。从常理来说,倘若有人把你当做了nothing,你又怎能信任他们?
哲人王的又一可怕之处,在于他的学问。在现代社会里,人人都有不懂的学问,科学上的结论不足以使人恐惧,因为这种结论是有证据和推导过程的,对于有理性的人,这些说法是你迟早会同意的那一种。而哲学上的结论就大不相同,有的结论你抵死也不会同意,因为既没有证据也没有推导,哲人王本人就是证明,而结论本身又往往非常的严重。举例来说,尼采先生的结论对一切非受虐狂的女性就很严重;就这句话而论,我倒希望他能活过来,说一句“我是开个玩笑”,然后再死掉。当然,我也盼着中国古代的圣人活过来,把存天理灭人欲、饿死事小失节事大之类的话收回一些。
我说哲人王的学问可怕,丝毫也不意味着对哲学的不敬。哲学不独有趣,还足以启迪智慧,“文化革命”里工农兵学哲学时说:哲学就是聪明学,我以为并不过分。若以为哲学里种种结论可以搬到生活里使用,恐怕就不尽然。下乡时常听老乡抱怨说:学了聪明学反而更笨,连地都不会种了。至于可以使人成王的哲学,我认为它可以使王者更聪明,老百姓更笨。罗素是个哲学家,他说:真正的伦理准则把人人同等看待。很显然,他的哲学不能使人成王。孔子说:民可使由之,不可使知之。像这样的哲学就能使人(首先是自己)成王。孔丘先生被封为大成至圣先师,子子孙孙都是衍圣公,他老人家果然成了个哲人王。
时值今日,还有人盼着出个哲人王,给他设计一种理想的生活方式,好到其中去生活;因此就有人乐于做哲人王,只可惜这些现代的哲人王多半不是什么好东西,人民圣殿教的故事就是一例。不但对权势的爱好可以使人误入歧途,服从权势的欲望也可以使人误入歧途。至于我自己,总觉得生活的准则、伦理的基础,都该是些可以自明的东西。假如有未明之处,我也盼望学者贤明的意见,只是这些学者应该像科学上的前辈那样以理服人,或者像苏格拉底那样,和我们进行平等的对话。假如像某些哲人那样讲出些晦涩、偏执的怪理,或者指天划地、口沫飞溅地做出若干武断的规定,那还不如让我自己多想想的好。不管怎么说,我不想把自己的未来交给任何人,尤其是哲人王。
```
{{{ [tag[task]] || $:/core/ui/TagTemplate }}}
```
{{{ [tag[task]] || $:/core/ui/TagTemplate }}}
-----
list-links Macro
The list-links macro gives a preformatted list, typically a bullet list, in a more simplified way than by using the ListWidget. Behind the scenes it really is the ListWidget applying a default template to each list item.
```
<<list-links "[tag[task]]">>
```
<<list-links "[tag[task]]">>
```
[[林俊颖]] / 最后的道别 - 副刊 | 文艺春秋 | 星洲网 Sin Chew Daily
篮球场直通校门的大路上有着一棵梅花树。梅花树是能长出果子的,这是我第一次路过的时候发现的事。 我应该不是最后一个知道的人吧。
2020-12-25 09:00:00
```
墙上的针指向清晨 7 点。
太阳缓缓升起唤醒了沉睡的大地,也唤醒了沉溺在梦境里的我。我睁开稀松双眼,伸展着慵懒身躯,甩了甩头,试图把昨夜的梦境甩出现实。
回不去的梦境。
晨光透过窗帘照在了洁白的墙上,帘子相叠的影在墙上拉出长长的朦胧,清晨里显得尤其惆怅。略显肮脏的行李箱早已收拾好摆放在大门左侧,衣橱里只剩下三颗不同大小的樟脑丸与它那独特的味道。一根根自然卷的头发散落在宿舍木地板上,与堆积的灰尘混搭在了一起,一场森林探险就在眼前上演了。微弯的头发是枯萎的树林,散落的尘埃如腐烂的落叶,白蚁啃食过的木地板是难以行走的沼泽。尘埃中弥留下的脚印尤其显着,为这封密的空间带来一股无来由的沉默与哀愁。
划开宿舍的薄纱窗帘,窗外的幽幽让人直打冷颤。我倚在窗前的书桌上,用一杯豆浆与过夜的油条填饱空腹,用一道风景满足稀松的眼睛。低头俯瞰,绿油油的草场在晨光下一闪一闪。草场两端白色的足球门柱早已斑驳泛黄。
草场上比赛的氛围还弥漫在空气中,进球的瞬间还历历在目。蓝白色的队服在场上来回奔跑,于是朵朵白云四处漂浮的情节发生在了草地上。你坐在观众席上,眼孔里映着足球的轨迹。由左跑到右,由右滚回左。喧闹的助威声透入空气在我耳蜗不断徘徊,坐在身旁的你捂盖着双耳,默默注视着赛场。于是形成了你在桥上看风景,看风景的人在楼上看你的诗情画意。后来的日子你不厌烦地和我述说,那仅有的一次进球在你口中演示了上万次不同的情节。足球尾部流星般的光耀从你口中道出,在我耳蜗不断来回,最后在街道巷口散去。
拉开宿舍残旧的木门,带上装载着回忆的行李箱,漫步离去。宿舍外的走廊在早晨特别宁静,让人感伤。
走廊墙上没有岁月留下的痕迹,只有一层在每年新春后准时更新的烛白色墙壁。临走之际我回头顺手关上宿舍大门,门关上之前还悄悄偷望了我那简约的空间,还有曾经乱中有序的物品。
离开校舍通往校门的路上,我顺路到篮球场道声再见。放下手上的行李我在篮球场上奔跑了两圈。
第一圈。
第一次身穿 8 号球衣的我颤抖地站在了球场中央,忐忑得手忙脚乱。我不记得比赛是如何结束的,唯一确定的是我的青春随着汗水挥洒在了这片大地上。
第二圈。
当结束哨声响起,我才终于注意到我最后的一场球赛已经落幕。不甘的泪水随着散去的脚步飘洒在那里。
篮球场直通校门的大路上有着一棵梅花树。梅花树是能长出果子的,这是我第一次路过的时候发现的事。
我应该不是最后一个知道的人吧。
我缓缓地躺在那最熟悉的地方,那个午时阳光透不过梅花叶,却能让躺在树下的我看到蓝天与白云。梅花树下大约是我在这学校里最多惬意回忆的地方吧。我总喜欢躺在这个位置,和那些因为莫名烦恼而到这里的同学们谈天。谈开心,或伤心的故事。
梅花树的前方是面小湖,小湖上方不时有麻雀飞舞戏水,小湖周遭也常有外校的小朋友玩耍。中午,炎热的光线透过湖水反映出了湖边玩耍的小朋友,也反映出了空中飞舞的麻雀,于是与我的世界酷似平行。一场你追我赶的戏码在湖中重复。我站起身走向湖旁,试图看透湖中的自己,也试图摆脱即将离去的悲伤。
告别了湖中的自己,我拖着装载沉重的行李向校门走去。
最后一次走过这条离校的道路,行李箱的轮子在崎岖不平的道路上滚动,回声试图唤起这些年抹不去的记忆。我转身投下最后一眼,回忆跑马闪过脸前,再渐渐的支离破碎。
再见了,我的青春。
作者 : 林俊颖
文章来源 : 星洲日报 2020-12-25
【免责声明】
星洲网促请读者、网民与观众,共同维护言论自由精神,营造理性交流环境;任何人身攻击、鼓吹种族与宗教仇恨、诽谤与造谣等留言,皆不代表本网站立场。本网站有权删除任何违反此原则的留言。
柳文扬,24岁写《闪光的生命》,国内最好的科幻爱情小说之一;25岁写《外祖父悖论》,国内最好的科幻讽刺小说;29岁写《去告诉她们》,职业生涯最好的短篇小说,写作技巧之大成。之后受病情影响,作品质量逐渐滑坡。很多人说《一日囚》,看过柳文扬历年作品的人应该知道,这篇小说背离了他的特点——人物对话跟解说词似的,正常状态的柳文扬怎么会把科幻小说写得如此生硬?
小说
"""
主人翁的屋子
[[在一条通往医院的马路旁]]
平时有很多电单车经过时
[[发出噪音的电单车]]
会发出噪音
让他精神疲劳
打扰他祈祷
近来疫情封锁
电单车变少
但附近的[[免费派鸡的青年团]]
免费派鸡
[[[冻结时间的疫情国家]]
他害怕确诊的人变多
马路会更吵
用积蓄修路墩
路墩像人生跨不过的坎
被投诉
拆了
[[建了又拆的铁路]]
朋友的聚会
[[朋友建议挖路坑]]
转脚处
有辆脚踏车
[[一边骑车一边发twitter]]
大概是一名热爱体育的青年部长吧
"""
#荒诞
意象
直接经验:
渐有睡意的我,望着在漆黑的夜里响过了如光芒的狼驱赶黑暗里绵羊而了无踪迹的唢呐声之后,留下缕缕狼狈追随的电单车排气管的尾烟,我也动过在汪洋大海般的大道上填完路墩的想法。
间接经验:
荒诞的是,事实比虚构更荒谬
轮流执政
作者:[[星新一]]
-----
3月1日。下班回来途中,难得去喝了些酒。醉得厉害,路上跌了一成,头碰得很疼,不过似乎不大要紧。我回到自己的单人房间后便睡了。
3月2日。下班回来途中,难得去喝了些酒。咦,昨天的日记也是这样写的,奇怪。今天喝酒确实是难得的嘛。
3月3日。在公司里受到了上司的警告。今后可要注意,别出这样的差错。
3月4日。上司火了,在公司挨了他一顿臭骂。“昨天那么提醒你,怎么今天又犯同样错误!”我被他训得低下了头。上司见状也满脸狐疑,盯着我的脸说:“你好象有点反常,今天早点回去休息吧,其它的事明天再说。”
3月5日。一到公司,上司早已等在那里,立刻领我走了出来。我问去什么地方,答道:“不是说定了吗?去医院。这是昨天和你约好的呀。”我毫无印象。不过上司的话如果当真,那么医院也许是该去的。
医生给我做了脑电波之类的种种细致检查后,作出如下诊断:“你的头部受到过撞击,对吧。因此你的人格被分成了两部分,但这并不等于变成了两个人,而只是在时间上产生了分裂。今天的你到了明天便变成了另一个你。再过一天,又恢复了现在的你。简单地说,就是‘轮流执政’,一天一交换.你的记忆也当然是隔日相连了。所以,前一天做了什么事,你全不记得,而另外一个你却很清楚。”
陪我来的上司听后道.“这样怎么能工作,什么事情都需要交待两遍。好吧,你先休养一段时间。”我问医生是否有治愈的希望,回答说.“先打针看看吧,这种病症,过一段时间就会好转的。”我决定请假休息。
回家路上,从银行取出了存款,作为休养所需费用。其中一半,放在房间角落里,另一半夹在这本日记簿中,想必另外一个我也需要钱吧。
3月6日。早晨,上司来到家里。讲的事情我一概不知道。据说我昨天去了医院,诊断后决定休养。真是难以置信。看了一整天电视。
晚上打开日记,见里面夹着钱,还有前一天的记事。看来上司的话是真的。怎么会患这种奇怪的病?
3月7日。这段休养时间不能浪费。以前要读而又无暇翻阅的专业书,这次来读吧。听医生说,很快就会恢复,我要抓紧这段时间多读一些书。
3月8日。无事可做,买回酒来,自饮了一天。心里很是不踏实。昨天的事情竟会完全想不起来,今天的记忆到明天竟会中断,实在叫人心神不定。还是用酒来排遣吧。
3月9日。早晨起床后象是酒醉未醒的感觉。这样怎么能行。冲个淋浴,喝杯咖啡,总算使头脑清醒了些,开始读书。今天读完了一册。
3月1O日。越发感到不踏实。越想情绪越坏。只有借酒浇愁。
3月11日。今天又埋头读了一天书。傍晚,同事来探望,并鼓励了我。我回答说,争取早日恢复,回去工作。
3月12日。这种状态已无法忍受,我想到了死.这隔日相连、半死不活的人生啊,实在无聊透了。
3月13日。仍是读书。又增加了新的知识,真高兴。另外的那个我,听着,不要起轻生的念头,我是不想死的。你要死当然容易,可连我也要一起成为牺牲品了。放弃这种念头吧!
3月14日。买来了安眠药。发现前一天的日记中,另外一个我写着不许我死。到底该怎么办?
3月15日。早上睁开眼,发现自己没死,总算松了口气。你情绪不好,是因为整天关在家里无所事事引起的。不喜欢读书,可以出去散散心,娱乐娱乐嘛。
3月16日,听从你的劝告,痛快地玩了一夭。在酒馆开怀畅饮、寻欢作乐,尽情地享受。似乎又有了生活的勇气。
3月17日。身上留有一股女人的气味,令人恶心。玩也得有个限度。不过你总算有了生活的勇气。我也不至于提心吊胆睡不着觉了。
3月18日。今天到女相好住处去玩,哦,对了,是在酒馆认识的。若能这样成天享乐,休养倒也不错。只是这种玩法,不用多久,钱就要告急了。
3月19日。不要胡言乱话,花钱要节约!眼下这笔钱得到病好为止。
3月20日。另外一个我肯定把钱藏起来了,但翻遍屋子也没找到。倒霉。还是买酒来喝。
3月21日。不要把屋子搞得乱七八糟。即使有钱也是藏在只有我才知道的地方,再翻也是徒劳的。
3月22日。钱花光了。没办法,晚饭只好不吃了。
3月23日。早晨起床,肚子饿得咕咕直叫。成什么样子,挺起来!我每天读书,生活很充实。你要跟我学!
3月24日。我生性不爱读书,听了你的话,我已振作起来,总算干了件大事,得到很大一笔钱。这下又可以享受一段时间了。
3月25日。你干了什么事?盗窃?诈骗?还是借高利贷?若是犯了罪,趁早去坦白!呀,不行,这样一来,不是连我也要跟着吃官司吗?去向人家道歉,把钱还掉!
3月26日。放心,放心。我不会做蠢事。你尽管放宽心。
3月27日。我怎么能放得下心。到底搞的什么名堂,一定要查个水落石出。
3月28日。好啊,你雇了侦探来盯我的俏。这算干什么?连我都信不过吗?
3月29日。好啊,你找了保镖来对付我请的侦探。不要自讨没趣,趁早改邪归正!我可不想跟警察打交道,又不是我自作自受。
3月3O日。我想干什么是我的自由。那种冒险掉脑袋的蠢事我才不干呢。放心好了!
3月31日。早晨起床,发现屋子角落里有个保险箱。这是怎么回事?想打开看看,却没能如愿。
4月l日。不许动我的保险箱。不要起什么疑心。里面没有什么了不起的东西。
4月2日。对保险箱还是放心不下。说是没什么了不起的东西,真是这样吗?总觉得自己被他的鬼话骗了。书也读不进去。这种情绪能不能想办法改变一下。
4月3日。到相好家去玩,一天真痛快。
4月4日。你在和什么样的女人来往,要当心!以后要是惹出麻烦来,我也跟着倒霉。就算我可以解释此事与我无关,但又有谁能相信?这种道理是讲不通的。
4月5日。是个不错的女人,不要吃醋,不要吃醋。有嫉妒我的空闲,劝你还是寻些乐趣享受。免得憋出精神病来。
4月6日,样样事情都让我操心。真想早日结束这种状态。去找医生,求他给我想想办法。
医生说:“这种病最好静下心来,慢慢治疗,再稍等一段时间吧。”我告诉他现在已经到了无法忍受的地步。医生踌躇道:“其实,有一种新药倒是很适合你现在的症状,只是说明书上有些地方不明确,所以不好向您推荐。”我表示这没关系,并央求医生用这种药给我打了针。这下可得救了,也许用不了几天,病情就会好转吧。
4月7日。据说是打过了什么针。已许以后没几天舒服日子了。遗憾。去医生那儿要昨天用的针剂的解药,他却满脸诧异。我所剩的人生已经不长了。还是去酒馆。
4月8日。早晨起来竞发现被窝里有个女人。好无耻的家伙。当我盘问她时,竟不耐烦地叫嚷起来。我提高嗓门呵斥她滚蛋,将她赶了出去。我的房间里,不许领女人进来!
4月9日。不许你欺负她。这也是我的房间,你少在一旁指手画脚,讨厌!
4月10日。打的针也该起作用了,怎么还不见有变化。莫非无效?如果病好不了该怎么办?非要出钱雇个职业杀人者,把这小子宰了不成?
4月11日。不要起这种歹念。以前我想自杀时,你不是还劝过我?现在你疯了吗?杀掉我,等于你也完蛋了。
4月12日。打电话向医生询问,说是就要见效了,但愿如此吧。如果再不好转,那无论如何也要想办法收拾掉这个有犯罪动机的色情狂、无赖。一对我这样一个正派人来说,连想起这些事都感到可耻。
4月13日。你才是在发狂。我还没想过于杀人之类的勾当呢。放明白些,你这蠢货!
4月14日。好了,好了。你们俩都冷静些,争吵是无济于事的。你们不都是同一躯体的主人吗?这些都交给我办。还是和好吧。
4月15日。看了一下手表上的日历,已经过去了两天。昨天是怎么回事?咋天的日记是谁写的?
4月16日。不是我。我也正纳闷呢。
4月17日。去医生处听了详细的说明。据说这就是药效,是新药起了作用。医生说事态会因此有所改善。从前一分为二形成了对立,所以要有个第三者进行调整才是。这就是我出现的理由和使命。你们俩今后都要按我的意志办事。
4月18日。这是怎么回事?
4月19日。这是怎么回事?
-----
(译自《新潮文库》1984年版星新一《南瓜马车》)
陈苏译——
```
论环形叙事中的时间
```
论环形叙事中的时间
作者: 袁晚晴
[摘要] 现代电影运用非线性叙事冲破了对时间单一向度的理解。在后现代语境下,传统时间理念的消失并非意味着时间在当下已不复存在,反而使时间获得了一种全新的表达方式。体现 “时间轮回”、“命运偶然性” 和“罪恶暴力循环”的叙事隐喻,其表意功能具备宗教直觉的悟性和禅意的环形叙事便是其中之一。环形叙事通过对时空的重新组合,以新鲜的视角探视人和人的情感,探寻着人生的终极意义。
[关键词] 现代电影 [[环形叙事]] 时间观念
时间作为一种抽象化的客观存在,其流逝成为人类内心的焦虑。在它的绵延不绝与永恒的对照之下,人的生命愈发显得短暂。当时间成为规定人类生活的一串生硬数字,外在的时间带给人类的不仅仅是秩序,还有压抑和绝望。人类发明照相术最深层的心理原因便是巴赞所说的 “木乃伊情结”——与时间抗衡。电影作为“第七艺术”,其显著特征便是能够纪录和复原一段完整的时间,达到“创造出一个符合现实原貌而时间上独立存在的理想世界” [1] 的能力。
但正如巴赞提出的 “电影是现实的渐近线”,即便是最具客观性和真实性的纪录片也会有叙事的存在。叙事作为一种形式系统,包含了因果、时间、空间这三个元素。不同的电影时空结构可以表现不同的叙事风格,也可以决定观众“涉入故事之中的程度” [2]。在这三元素内,因果和时间是叙事的核心。马尔丹在《电影语言》里说:“空间是被动的…… 它是作为一部影片的结构元素之一参与画面形象的,而延续时间都是在故事范围内活动的,它决定着一部影片的完整表现。空间是在延续时间中出现的,而延续时间却是在组织空间。” [3] 只有时间得到重新的安排,叙事才存在。对叙事时间的处理不仅决定了不同的因果逻辑和叙事风貌,更蕴含着叙述者对时间、生命的观点。
电影诞生之初,观众与电影创作者都习惯按照时间推进来表现电影情节。经典好莱坞的叙事原则就将是将线性叙事结构作为电影叙事的主干,使符合冲突律的因果关系成为故事情节组织安排的基本依据,保持着单一时间向度的线性原则和叙事结构的完整性以及时空统一连续性的幻觉,不留痕迹的使 “观者被嵌入本文之中…… 特定的观者由此而陷入了‘主体的陷阱’之中。” [4] 相较于传统的线性叙事,非线性叙事刻意重组事件序列,对时间单一向度解除和打破。这种叙事使观者主动的对 “所讲述” 的事实进行辨别、排序和归纳,提供给观众传统叙事 “只得到结果” 所不能带来的参与快感。如今,非线性叙事已经被广大的电影导演以及观众所接受,“要是如果?”的叙事发生在《滑动门》、《机遇之歌》等探讨人类命运偶然性的影片上;块状的片段化叙事用于《公民凯恩》、《罗生门》等探寻真相唯一性的影片上;逆向式递进的 “纯倒叙事结构” 在《薄荷糖》、《记忆碎片》中用来复原时间的过去;而首尾相接的环形叙事在《时间》、《暴雨将至》、《春夏秋冬又一春》中则体现出了后现代的超验特性。杰姆逊说 “那种从过去通向未来的连续性的感觉已经崩溃了,新时间体验只集中在现时上,除了现时以外,什么也没有。” [5] 在后现代语境下,传统时间理念的消失并非意味着时间在当下已不复存在,反而使时间获得了一种全新的表达方式。体现“时间轮回”、“命运偶然性” 和“罪恶暴力循环”的叙事隐喻,其表意功能具备宗教直觉的悟性和禅意的环形叙事便是其中之一。
一、叙事:新奇的时空体验
如麦茨所说,“叙事的功能之一是在一个时间中处理另一个时间”。在叙事学中,“本事”时间指的是影片中所讲述的故事本身发生发展的实际时间,而 “本文” 时间是指影片文本中所呈现的时间。而环形叙事就是对电影 “本文时间” 所进行的艺术加工。研究电影叙事时间有三个主轴:按什么顺序呈现事件;叙事的延续时间和所叙事件的延续时间有什么关系;所述事物发生一次还是多次,也就是叙事学家热奈特所说的时序、时距和时频,这三个要素决定了本文时间所呈现的面貌。
对时序更改最突出的例子当属《低俗小说》,导演有意将线性叙事的因果链打断,以 “块” 的形式呈现。在这里故事不是一个带有句号的完结,而是被逗号间隔,三段故事彼此独立,但又部分交叠,这种彼此呼应让影片在形式上呈现了一个圆形。昆丁将故事拆解成碎片,重新拼组,而每一个小标题的故事内部又以线性叙事讲述,给予观众部分建构影片的权利,观众在观影的同时产生类似拼图一样的游戏快感。在对时距的分析上,其概念相当于 “本文” 时间,即故事长度与情节长度之外的银幕长度,《罗拉快跑》的成功归功于情节长度与银幕长度的统一,电影被均匀的分为三个层面,每一个层面罗拉的行为都与其情节时间基本重合,在这种对现实时间复原所带来的极其真实的感觉相冲突的,是对于故事时间的平面化。导演将故事所包含的前因后果用 “闪回” 及“闪前”镜头快速交代,让后现代对于时间的断裂感变得突出。《罗拉快跑》如《正午》一样,在对于时间的复原上,达到了形式上最高的真实,但与《正午》不同的是,“复原”时间在营造紧张气氛的同时还引起了现代人对于生命偶然性和时间永恒性的思考。
时频在环形叙事中至关重要,“频率所指的是叙事作品中出现的时间与故事中时间的数量关系, 也就是说, 一个时间在故事中出现的次数与该事件在文本中叙述或提及的次数之间的关系。” [6],电影的情节可以用很多方式改变故事出现的频率,借此营造新奇的时空体验。在《恐怖游轮》、《低俗小说》、《罗拉快跑》、《暴雨将至》这些环形叙事的电影中,故事讲述的频率决定着循环所进行的次数,而环形叙事常常意味着情节上重复。这里的重复,指的是完全意义上事件的重复,其背后包含着让时光 “重新来过” 的含义。环形叙事中最简单的重复就是那个让观众领悟到 “这是个循环” 的接合点,这一接合点时常出现在电影开头和结尾。比如,《恐怖游轮》中杰西在码头登船,《低俗小说》的 “小白兔” 和“小南瓜”商量抢劫的餐厅,《时间》中世喜在整形医院的门口撞到戴口罩的女人,《罗拉快跑》里红色电话响起,《暴雨将至》里的教堂。然而,这只是环形叙事的最表层,其深层是隐藏在故事发展内部的重复。《恐怖游轮》属于循环内部叠加循环较为复杂的例子,它的精妙之处就在于能让三个杰西处于同一个时空,并且让三个杰西的行为微妙的相互影响,时频的重复在这里颇为重要。全片以观众所看到的杰西 A 为主要人物,事件的发展以杰西 A 作为限制性视角,我们所能够看到和知道的信息全都来源于我们心中所认同的杰西 A 的“在场”。当杰西 A 将蒙面人(杰西 C)推下游轮,看到带着自己和朋友们的小船再次驶向游轮的时候,杰西 A 才明白自己进入了一个循环(第二层小循环),新上船的杰西成为杰西 A,导演借已进入第二层循环的杰西 B 的视角补充了第一循环杰西 A 所经历的诡异事件背后的故事,跌落的杰西的钥匙、餐厅里镜子里的影子、歌剧院里好友对杰西的斥责都有了合理的解释。而第二层循环中的杰西 B 又再度看到杰西 A 在甲板上将蒙面的杰西 C 推入大海。当小船再一次驶来,新的杰西和朋友们再次登上游轮,杰西 B 变成杰西 C,成为了蒙着头被推下船的那个。三次遇难的小船向游轮的靠近,三次杰西将蒙面人推下水这个情节点成为了三个循环同时成立的关键。事件发生的频率决定着电影环形叙事的所能呈现的最为复杂的面貌,《恐怖游轮》无疑将这点发挥到了极致,当已经回家的杰西 C 最终没有逃过儿子死亡的命运,再次登上游艇的她无疑又将进入杰西 A 的命运循环。
萝卜-汪曾祺
========================
萝卜-[[汪曾祺]]
-----
杨花萝卜即北京的小水萝卜。因为是杨花飞舞时上市卖的,我的家乡名之曰:“杨花萝卜”。这个名称很富于季节感。我家不远的街口一家茶食店的屋下有一个岁数大的女人摆一个小摊子,卖供孩子食用的便宜的零吃。杨花萝卜下来的时候,卖萝卜。萝卜一把一把地码着。她不时用炊帚洒一点水,萝卜总是鲜红的。给她一个铜板,她就用小刀切下三四根萝卜。萝卜极脆嫩,有甜味,富水分。自离家乡后,我没有吃过这样好吃的萝卜。或者不如说自我长大后没有吃过这样好吃的萝卜。小时候吃的东西都是最好吃的。
除了生嚼,杨花萝卜也能拌萝卜丝。萝卜斜切的薄片,再切为细丝,加酱油、醋、香油略拌,撒一点青蒜,极开胃。小孩子的顺口溜唱道:
人之初,
鼻涕拖;
油炒饭,
拌萝菠
[1]
。
油炒饭加一点葱花,在农村算是美食,佐以拌萝卜丝一碟,吃起来是很香的。
萝卜丝与细切的海蜇皮同拌,在我的家乡是上酒席的,与香干拌荠菜、盐水虾、松花蛋同为凉碟。
北京的拍水萝卜也不错,但宜少入白糖。
北京人用水萝卜切片,汆羊肉汤,味鲜而清淡。
烧小萝卜,来北京前我没有吃过(我的家乡杨花萝卜没有熟吃的),很好。有一位台湾女作家来北京,要我亲自做一顿饭请她吃。我给她做了几个菜,其中一个是烧小萝卜。她吃了赞不绝口。那当然是不难吃的;那两天正是小萝卜最好的时候,都长足了,但还很嫩,不糠;而且我是用干贝烧的。她说台湾没有这种小萝卜。
我们家乡有一种穿心红萝卜,粗如黄酒盏,长可三四寸,外皮深紫红色,里面的肉有放射形的紫红纹,紫白相间,若是横切开来,正如中药里的槟榔片(卖时都是直切),当中一线贯通,色极深,故名穿心红。卖穿心红萝卜的挑担,与山芋(红薯)同卖,山芋切厚片。都是生吃。
紫萝卜不大,大的如一个大衣扣子,扁圆形,皮色乌紫。据说这是五倍子染的。看来不是本色,因为它掉色,吃了,嘴唇牙肉也是乌紫乌紫的。里面的肉却是嫩白的。这种萝卜非本地所产,产在泰州。每年秋末,就有泰州人来卖紫萝卜,都是女的,挎一个柳条篮子,沿街吆喝:“紫萝——卜!”
我在淮安第一回吃到青萝卜。曾在淮安中学借读过一个学期,一到星期日,就买了七八个青萝卜,一堆花生,几个同学,尽情吃一顿。后来我到天津吃过青萝卜,觉得淮安青萝卜比天津的好。大抵一种东西第一回吃,总是最好的。
天津吃萝卜是一种风气。五十年代初,我到天津,一个同学的父亲请我们到天华景听曲艺。座位之前有一溜长案,摆得满满的,除了茶壶茶碗,瓜子花生米碟子,还有几大盘切成薄片的青萝卜。听“玩艺儿”吃萝卜,此风为别处所无。天津谚云:“吃了萝卜喝热茶,气得大夫满街爬”,吃萝卜喝茶,此风亦为别处所无。
心里美萝卜是北京特色。一九四八年冬天,我到了北京,街头巷尾,每听到吆喝:“哎——萝卜,赛梨来——辣来换……”声音高亮打远。看来在北京做小买卖的,都得有条好嗓子。卖“萝卜赛梨”的,萝卜都是一个一个挑选过的,用手指头一弹,当当的;一刀切下去,咔嚓嚓地响。
我在张家口沙岭子劳动,曾参加过收心里美萝卜。张家口土质于萝卜相宜,心里美皆甚大。收萝卜时是可以随便吃的。和我一起收萝卜的农业工人起出一个萝卜,看一看,不怎么样的,随手就扔进了大堆。一看,这个不错,往地下一扔,叭嚓,裂成了几瓣,“行!”于是各拿一块啃起来,甜,脆,多汁,难可名状。他们说:“吃萝卜,讲究吃‘棒打萝卜’。”
张家口的白萝卜也很大。我参加过张家口地区农业展览会的布置工作,送展的白萝卜都特大。白萝卜有象牙白和露八分。露八分即八分露出土面,露出土面部分外皮淡绿色。
我的家乡无此大白萝卜,只是粗如小儿臂而已。家乡吃萝卜只是红烧,或素烧,或与臀尖肉同烧。
江南人特重白萝卜炖汤,常与排骨或猪肉同炖。白萝卜耐久炖,久则出味。或入淡菜,味尤厚。沙汀《淘金记》写么吵吵每天用牙巴骨炖白萝卜,吃得一家脸上都是油光光的。天天吃是不行的,隔几天吃一次,想亦不恶。
四川人用白萝卜炖牛肉,甚佳。
扬州人、广东人制萝卜丝饼,极妙。北京东华门大街曾有外地人制萝卜丝饼,生意极好。此人后来不见了。
北京人炒萝卜条,是家常下饭菜。或入酱炒,则为南方人所不喜。
白萝卜最能消食通气。我们在湖南体验生活,有位领导同志,接连五天大便不通,吃了各种药都不见效,憋得他难受得不行。后来生吃了几个大白萝卜,一下子畅通了。奇效如此,若非亲见,很难相信。
萝卜是腌制咸菜的重要原料。我们那里,几乎家家都要腌萝卜干。腌萝卜干的是红皮圆萝卜。切萝卜时全家大小一齐动手。孩子切萝卜,觉得这个一定很甜,尝一瓣,甜,就放在一边,自己吃。切一天萝卜,每个孩子肚子里都装了不少。萝卜干盐渍后须在芦席上摊晒,水气干后,入缸,压紧、封实,一两月后取食。我们那里说在商店学徒(学生意)要“吃三年萝卜干饭”,谓油水少也。学徒不到三年零一节,不满师,吃饭须自觉,筷子不能往荤菜盘里伸。
扬州一带酱园里卖萝卜头,乃甜面酱所腌,口感甚佳。孩子们爱吃,一半也因为它的形状很好玩,圆圆的,比一个鸽子蛋略大。此北地所无,天源、六必居都没有。
北京有小酱萝卜,佐粥甚佳。大腌萝卜咸得发苦,不好吃。
四川泡菜什么萝卜都可以泡,红萝卜、白萝卜。
湖南桑植卖泡萝卜。走几步,就有个卖泡萝卜的摊子。萝卜切成大片,泡在广口玻璃瓶里,给毛把钱即可得一片,边走边吃。峨嵋山道边也有卖泡萝卜的,一面涂了一层稀酱。
萝卜原产中国,所以中国的为最好。有春萝卜、夏萝卜、秋萝卜、四季萝卜,一年到头都有。可生食、煮食、腌制。萝卜所惠于中国人者亦大矣。美国有小红萝卜,大如元宵,皮色鲜红可爱,吃起来则淡而无味,异域得此,聊胜于无。爱伦堡小说写几个艺术家吃奶油蘸萝卜,喝伏特加,不知是不是这种红萝卜。我在爱荷华南朝鲜人开的菜铺的仓库里看到一堆心里美,大喜。买回来一吃,味道满不对,形似而已。日本人爱吃萝卜,好像是煮熟蘸酱吃的。
[1]我的家乡称萝卜为萝菠。
[[托马斯·曼文集·中短篇小说选 - 马里奥和魔术师 by 托马斯·曼 |https://www.kanunu8.com/book2/10973/196105.html]]
==托马斯·曼文集·中短篇小说选 马里奥和魔术师==
作者: 托马斯·曼
上一页 回目录 下一页
-----
一想起托勒迪维纳,就使人沉浸在不愉快的气氛中。一开头,空气中就充满使人愤怒、暴躁和过分紧张的东西,最后那可怕的奇博拉还惹起了一番惊扰。在这人身上,似乎体现和集中了当时当地所特有的凶煞气氛,显得格外恐怖和吓人,而且令人惊心动魄。由于这个怪人事先耍了一些花招,我们出于误会,竟让孩子们看到那可怕的结局(事后想想,那结局似乎是预先注定和必然的),这尤其是不幸和不适宜的。幸而孩子们不了解戏演到什么地方为止,灾祸从哪儿开始,而我们也就让他们高高兴兴地把整个事态都当作一场戏。
托勒离第勒尼安海滨避暑胜地波多克莱门特大约有十五公里路。那个避暑胜地有着都市的奢华,经常连续几个月住满了人,海边延伸着一条满是旅馆和店铺的热闹街道,沙滩上到处都是遮太阳的凉篷、插小旗的沙堡和晒黑了的浴客,熙熙攘攘,十分喧闹。一带小松林环抱着沙滩,贴近的一脉山峦俯视着松林。因为这铺着柔细沙子的沙滩沿着整个海岸延伸下去,并且一直是很宽阔的,所以在稍微远些的地方,不久就自然而然地崛起了一个比较幽静的竞争者:托勒迪维纳。它作为一个避暑地,成了那大浴场的分场,在头几年里成为少数人的世外桃源和一些隐遁之士的避难所。附带说一句,这地方虽然叫托勒,但早就看不见什么塔了。像这样的地方,照例不会安静好久的,那股宁静的气氛很快就必然被驱逐到海边更远的地方,到玛里娜彼脱里拉和天晓得什么别的地方去了。我们都知道,世人常寻求安宁,但总是把它赶走。他们怀着一种可笑的渴望向它扑过去,竟以为能同它结成良缘,并跟它融洽相处。是的,当他们在它的居所举行喧闹的市集时,居然还以为它仍旧会逗留在那儿。就这样,虽然托勒还是比波多克莱门特幽静和朴素,但是已经有许多意大利人和外国人到这儿来避暑。尽管后者仍是个熙熙攘攘、生意兴隆的浴场,并且闻名世界,但有些人已经不上那儿去了,他们到附近的托勒去。托勒甚至比较雅致,也比较便宜,而这种优点的吸引力一直保存着,虽然优点本身早已消失。托勒有了一家高等旅馆,出现了不少昂贵的和较朴素的公寓,海滨花园别墅的主人和住户们已经不像过去那样逍遥自在了。在七八月间,那儿的景象跟波多克莱门特的没什么两样:到处都挤满了叫嚷、争吵、欢呼的浴客,他们被炽热的太阳晒得后颈上的皮一层层地脱下来。漆得红红绿绿的平底船,载着小孩们,在闪闪发光的蓝色海面上摇荡,关心地守望着的母亲们,用沙哑的嗓子大声呼喊孩子们的名字,叫声响彻天空。卖牡蛎的、卖冷饮的、卖鲜花的、卖珊瑚首饰的和卖黄油卷的小贩们,从躺卧着的人们肢体上跨过去,也用那响亮的南方粗嗓子兜售他们的货物。
我们到的时候,托勒海滩上就是这副样子——倒是挺漂亮,但我们还是觉得来得太早了。那正是八月中旬,是意大利游览季节最盛的时期;对于外国旅客来说,却不是欣赏当地风光的适当时刻。每逢下午,海滨林阴道上的花园咖啡馆里拥挤不堪。比如,我们有时去的爱斯圭茜多咖啡馆里就是这样。在那儿,我们受到马里奥的招待,就是我就要向你们讲起的那位马里奥。连一张空桌子都不容易找到,各个乐队互不相让,闹作一团。每天下午,又有一批人从波多克莱门特赶来,托勒自然成了那安乐窝的好动客人们爱去游玩的地方。由于菲亚特汽车来回奔驰,丛生在公路边的月桂和夹竹桃上盖上了一英寸厚的灰尘——这副景象虽然惹人触目,却叫人感到不愉快。
说真的,应该在九月去托勒迪维纳,这时多数的游客已经离开了浴场;或者在五月间去,那时海水不够温暖,还不能吸引南方人去游泳。在游览期前后,那儿也并不很空,但比较清静,本国人也并不那么多。那时,英国人、德国人和法国人在太阳伞的阴影下和公寓的餐厅里占优势,而在八月间,至少在那高等旅馆里,外国的游客却受到佛罗伦萨人和罗马人的排挤,不禁感到孤立和暂时成为二等旅客。我们由于缺少私人介绍信,只得住在这旅馆里。
我们到的头一天晚上,在饭厅里吃晚饭时,就有过这样令人扫兴的经历。主管的侍者领我们到一张桌旁。那张桌子倒没有什么不好,但近旁临海的玻璃阳台的景象,却吸引住我们。阳台上也同饭厅里一样坐满了人,可是还有一些空位子。那儿的小餐桌上,红灯罩的台灯发出微红的光。孩子们看到这种节日般的景象,兴高采烈,于是我们就干脆提出要在阳台上吃饭。讲这样的话说明我们不知内情,因为侍者面有难色,有礼貌地向我们表示,雅座是留给“我们的顾客”(ainostriclienti)的。我们的顾客?那就是我们呀!我们既不是过路人,也不是玩了一天就跑的游客,而是要住三四个星期的固定房客。不过,我们并没有坚持要侍者向我们解释清楚,我们跟那些在小台灯迷蒙的红光下吃饭的顾客,到底有什么区别,就在大厅那张单调的用普通灯光照明的餐桌上用餐。这是一顿很普通的公司菜,既乏味又没有特色。后来我们在朝内地走约有十步路的爱莲诺拉公寓吃饭,觉得那儿的菜味道好多啦。
我们在那高等旅馆勉强度了三四天光阴,就搬到爱莲诺拉公寓去了。这倒不是为了那玻璃阳台和小台灯的缘故:孩子们很快就跟旅馆的侍者和跑腿的小厮交上朋友,而且他们又给海滨生活的乐趣迷住了,早就把那些诱人的彩灯抛在脑后。但我们很快就跟阳台上的一些顾客发生了纠纷,或者更确切地说,跟奉承他们的旅馆领导方面发生了纠纷,而这种冲突一开始就给我们的旅居打上不愉快的烙印。这些顾客中有一位罗马显赫的贵族,携带家眷的某公爵。这位显贵的房间就在我们隔壁。公爵夫人是一位高傲的贵妇,又是一位溺爱孩子的母亲,听见我孩子有点咳嗽,便吓得魂不附体。原来在不久以前,我们的两个孩子都患过日咳,现在虽然已经复元,但素来睡得很熟的最小孩子,夜里有时还会被残余的轻微咳嗽搅醒。这种疾病的根源到现在还没有弄清楚,产生了各式各样的迷信看法,所以我们并不责怪我们尊贵的邻居像很多人那样认为百日咳能通过声音传染,担心他们孩子会染上这恶疾。她作为一个女人,充分意识到自己的地位多么显贵,立刻向行政管理方面提出申诉。于是那位众所周知的穿礼服的经理,便赶忙跑来,在一番道歉之后,表示我们无论如何也得搬到旅馆的侧屋里去。我们再三表明,孩子们的疾病已经到了复元阶段,可以算是痊愈,对周围的人已不再有什么危险了。他作出的唯一让步,就是答应把这事交给医生判断,但不许我们自己请医生,一定要叫旅馆的医生来作出决定。我们同意了这种折衷办法,以为这样既可以使公爵夫人放心,又可以免去一场搬场的麻烦。医生来了,他还算得上是个忠诚地为科学服务的人。他检查了孩子们,表示危害性已经过去了,不必有任何疑虑。我们还以为我们的话既然被证实,事情就解决了,但经理却不顾医生的诊断,还是坚持要我们从自己的房间搬到侧屋去。
这种谄媚奉承的作风使我们感到愤慨。这样不讲道理地对待我们,也许不是出自公爵夫人的本意。大概是那卑躬屈膝的旅馆经理,他甚至不敢在公爵夫人的面前提起医生的诊断。不管怎样,我们通知他,我们打算立即从旅馆搬出去,并且动手收拾行李。我们心里并不焦急,因为散步路过爱莲诺拉公寓时,我们曾跟那里取得了联系。这公寓有一副讨人喜欢的外表,像个私人住宅,早就引起了我们的注意。我们跟那儿的女主人安吉欧丽里太太结识了,颇为相得。安吉欧丽里太太是个塔斯康型的女人,长一双黑眼睛,温文尔雅,约莫三十刚出头,皮肤带有南方人那种象牙似的微黄色。她的丈夫顶着个秃头,沉默寡言,衣着讲究。他们在佛罗伦萨开一家较大的旅馆,只有在夏天和初秋才来托勒迪维纳,主持这儿的分店。在结婚前,我们这位新女主人曾经当过女伴、旅伴和戏装保管员,甚至还是杜塞的朋友。她把这段经历当作自己一生中最光辉和最幸福的一个时期。我们第一次去访问她时,她就津津乐道地讲起这桩事。在她的客厅里,茶几和书架上到处都摆着这位杰出的女演员的照片,照片上写着亲切的题词,还有其他各种纪念她们那一段共同生活的物件。显然,她念念不忘过去这段有趣的经历,对目前的生意颇有些好处,但我们还是兴致勃勃地倾听她用那响亮的清晰的塔斯康口音讲的故事。她不时提到她过去那位名垂千古的女主人怎样慈悲善良,才华卓越,多愁善感。
我们叫人把行李搬了过去。旅馆的服务员们却大为扫兴,意大利人的习俗是喜爱小孩的。为我们准备的房间幽静而舒适,去海滨很方便,一条小径通向海边的马路,小径两旁长着幼嫩的梧桐。餐厅阴凉、整洁,在那里安吉欧丽里太太每天吃午饭时,亲自替客人们盛汤,服务起来殷勤周到,菜肴也很丰美。我们在这儿甚至碰到了维也纳的老相识,饭后跟他们在屋子前聊天,通过他们又结识了新的朋友。我们对这次搬家很高兴,一切都安排得很好,照理这趟旅行应该是称心如意了。
但我们心里还是闷闷不乐。也许我们对搬家的愚蠢原因还不能释然——我个人得承认,我跟这种庸俗的人情、这种幼稚地滥用权威、这种不公正和奉承拍马发生冲突以后,总是要耿耿于怀的。这一切会纠缠我许久,使我陷入恼人的思索中,虽然明知这类现象是极其寻常和自然的,为它烦恼也没有用。同时呢,我们并不觉得跟那家高等旅馆吵翻了。孩子们仍旧同那边保持友好关系,服务员还是为他们修理玩具,而我们有时还在饭店的花园里喝茶,也不免在那儿遇见公爵夫人。她老是涂着满嘴的珊瑚色唇膏,迈着又雅致又坚定的步子出现,寻找她那些由一位英国保姆带领的宝贝孩子。她不知道我们离她近得那么可怕,因为只要她一露脸,我们就严厉地吩咐孩子们,不准他们咳一声。
热极了——我应该提到这点吗?这是一种类似非洲的炎热:一切都处在太阳的恐怖统治下,只要离开碧蓝的凉海水的边缘,就会受到它的折磨,它是那么残酷无情,以致从海滩走几步路到餐桌旁吃中饭,哪怕只穿一件薄睡衣,已经是一桩事先就要叹气的苦事。你受得了吗?能忍受好几个星期吗?当然啰,这是南方,是古典式的天气,是蓄育了人类文化花苞的气候,是荷马的太阳等等。但过一些时候,我就不禁要感到沉闷。炽热的天空,天天都是万里无云,令人难受。鲜艳夺目的色彩和那异常单纯、恒久不变的日光,虽然引起一种节日的气氛,给人一种悠闲的感觉,叫人不必担忧天气的变幻无常,但是一开头,就不知怎么,这一切不能满足一个北方人的心灵较深刻和复杂的需要,使他感到空洞,久而久之引起他的鄙视。你说得对,倘若没有发生那场百日咳引起的愚昧纠纷,我恐怕不会有这种感觉,我被激怒了,大概是为了要体会到这种感觉,便有意无意地去寻找现成的精神上的借口来加强这种感觉。就算我们存心不良吧——至于海呢,每天上午我们休憩在细柔的沙上,面对那永远美丽的大海,照理心里不该有任何不快的感觉,但是,与往常的经验不同,我们在海边并不感到舒畅。
太早了,太早了,整个海滩可以说还控制在内地的中产阶级手中——这种人外表上看起来还逗人喜欢,这点你也说得对,年轻人当中有不少长得挺不错,而且生气勃勃,但不可避免地四周笼罩一股庸俗的气氛,充斥着资产阶级的败类,而这个地区出生的这一类人,你不得不承认,并不比生长在本国天空下的这类人更可爱些。他们女人的嗓子可动听啦!有时简直令人不相信自己置身于歌唱艺术的故乡。
“Fuggièro!”今天这叫声还在我耳中鸣响。我曾在二十来个上午,听见它成百次地在贴近处吼响起来。这是一种赤裸裸的嗄哑声音,重音发得异常可怕,元音“è”尖哨刺耳,声音中流露出一种刻板的绝望情调。“Fuggièro!Rispondialmèno!”就像德语中一样,照当地习惯把“sp”读成“schp”,而单是这个音,在你心境不愉快时,就已足够使你怒火中烧。这嘶叫是对一个讨厌的男孩发出的,他两肩之间给太阳晒焦了,伤处颇令人作呕。我从来没有碰到过比他更倔强、顽皮、凶恶的孩子了。而且,他还是个胆小鬼,有时为了发脾气而哭哭闹闹,竟会惊动整个的沙滩。有一天,他在海里给一只小螃蟹夹了一下脚趾,这一点微小的不适,竟使他发出古希腊英雄式的号叫,使人听了心惊肉跳,仿佛发生了莫大的灾难似的。显然,他以为自己受了伤,中了毒。他爬来,拚命打滚,好像真是痛得难以忍受,一面吼“唉唷!”和“啊呀!”一面用手脚乱挥乱踢,拒不理会母亲的苦苦哀求和旁观者的安慰。四面八方的人跑拢来看热闹。请来了一位医鬼,就是那位明智地诊断我们孩子百日咳的医生,而这次他又表现出他那科学上直言不讳的风格。他好心地安慰了一番,表示根本没有什么关系,直截了当地建议病人再下海去游泳,好让那给夹了的微不足道的伤口凉一凉。虽然这样,富季埃罗却像个堕海或淹死的人一样,给人用临时拼成的担架从海滩上抬了去,还有一大批人跟随在后面。第二天早上,他又出现了,装出一副不是故意的样子,去捣毁别的孩子堆成的土堡沙垒。一句话,这小子坏透了。
这十二岁的顽童,是制造一种笼罩一切的不可思议的气氛的主要角色之一。这种气氛使得我们无法享受这次有趣的旅行。不知怎么,空气中好像缺少一种天真、自由自在的因素,游客们都有些自命不凡——起初还揣测不出其中的奥秘,只觉得他们神气活现,相互之间和在外国人面前摆架子,装出一副严肃尊贵的姿态——为什么呢?很快我们就明白了,原来这是由于政治关系,牵涉到民族意识的问题。的确,沙滩上一窝蜂都是爱国的儿童——这倒是个不正常和令人不愉快的现象。孩子们仿佛构成人类中的一个独特的门类和社会,可以说是个单独的民族;即使他们有限的词汇属于不同的语言,由于生活方式相似的缘故,他们很容易也必然会在世界各个角落打起交道来。我们的孩子不久便开始同当地的和来自其他国土的儿童玩耍。可是,很明显,他们遇到了不可思议的挫折。有些人十分敏感,自尊心过强,而这种自尊心又是那样础础逼人和好教育人,以致自尊心这个词完全名不符实。后来发生了有关国旗的纠纷和对于声望及地位的争执。大人们与其说谦逊、还不如说武断地参与了争吵,表示要捍卫什么原则;时常听到关于意大利的伟大和崇高的字眼,而这种讲法不免令人兴味索然。我们看见我们的孩子窘迫地、不知所措地退了回来,于是设法在某种程度上使他们明白这是怎么一回事:这些人,我们解释说,正在经历一个阶段,或者可以说是一种疾病,不大舒服,但也许是不可避免的。
这是我们的过错,要归罪于我们的粗心大意:我们同这个已被我们认识和估计到的形势发生了冲突——又一次冲突;看来先前所发生的不纯粹是偶然的巧合。一句话,我们败坏了社会的风俗。我们八岁的小女儿——她的身体发育得慢,看起来还显得小一两岁哩,而且像只麻雀一样瘦——在海里洗澡洗了好久,因天气暖,便穿着湿游泳衣,在岸上玩了起来。我们允许她把粘满沙子的游泳衣在海水里洗一洗,然后穿上,免得再弄脏。她光着身子,跑到离我们只有几步的水边,把衣服在水里荡了荡,再跑回来。我们怎么会料到她这个行为,也就是我们的行为,会引起一股讥讽、愤怒和攻击的浪潮呢?我并不是向你作什么报告,但近几十年来在全世界对身体和它的赤裸的态度,有了根本的变化,完全改变了人们的看法。有些事物使人“不再有什么想法”,我们对那丝毫不引人注目的幼小身体所给予的自由,也属于这方面。可是在这儿,我们的行为却被视为一种挑战。那些爱国的孩子吼叫起来,富季埃罗把手指插在嘴里吹口哨。近旁一些成年人激动的议论,越来越响,预示这事不会有好结果。一位穿一身城市服装的绅士,后颈上戴一顶在海滩上格格不入的西瓜帽,向他激动的女友们保证,决定要采取惩罚性措施。他走到我们跟前,把我们狠狠责骂了一顿。在这顿责骂中,爱好感观快乐的南方人的热情,竟为一种虚伪的陈规陋俗所用。他叫嚣说,我们所犯的伤风败俗的罪过尤为可恶,因为我们忘恩负义,挑衅地滥用了意大利的好客热情。仅使公布了的海浴规章的精神和条文遭到破坏,连他祖国的荣誉也肆无忌惮地受到损害。为了维护祖国的荣誉,他,这位穿礼服的绅士,一定要使这种对民族尊严的污辱,受到应得的惩罚。
对这番声色俱厉的呵叱,我们只好唯唯诺诺。跟这样激动的人辩解,是枉费精力,火上加油。我们心里倒有些话要说,比如,在这地方,周围的事物并不都体现了真正的“好客”精神,而且可以直言不讳地说,我们称不上意大利的客人,只不过是安吉欧丽里太太的客人;至于这位太太呢,近几年来已经不作杜塞的心腹了,而以好客作为她的职业。我们也巴不得回答说,我们起先还不知道,在这美丽的国度里,道德竟堕落到了这种地步,以致这种假正经和神经过敏居然是可以理解的和必不可少的。但我们克制了自己,只保证说,丝毫没有任何挑衅和冒犯的企图,由于那幼年罪犯年纪很小,身体尚不引人注目,请求予以宽恕。结果毫无用处。我们的保证被说成为不可置信,我们的辩解也都遭到驳斥;对方坚持必须加以惩罚,以一儆百。大概是打电话通知了当局,于是它的代表在海滩上出现了,并宣称案情“moltograve”(非常严重)。我们被带到“衙门”,也就是警察局里去,那儿的一个较高级的官员,肯定了临时作出的判决“moltograve”。他就像那戴硬壳帽的绅士一模一样,——显然这种作风在当地很流行——对我们的行为大发雷霆,把我们教训了一顿,最后罚我们五十里拉的赎罪金和保释金。我们觉得似乎值得为这场风险出一笔费用,来增加意大利国库的收入,便付了钱,走了。我们应该当时就离开那避暑地吗?
离开就好啦!那就不会碰着那可怕的奇博拉。但有许多原因,使我们呆在那地方,没到别处去。有一位诗人曾经说,懒惰往往使人留在不愉快的环境中——这话也许能说明我们迟迟不去的原由。而且,发生这类事以后,总不大愿意溜之大吉,总是不大肯承认自己已经不济事,特别是当外面有一些人对你表示同情,并鼓励你去反抗的时候。在爱莲诺拉别墅,大家同声一致宣称我们的遭遇是不公正的。有些在饭后聊天结交的意大利朋友,表示这事玷污了国家的声誉,并提出要去责问那穿礼服的绅士。但这家伙和他的一群朋友,第二天就不再在沙滩上露脸了——当然不是为了我们的缘故,但可能由于他明知自己就要离去,所以那天才表现得格外积极。反正,他去了,倒使我们松了口气。坦白地说,我们留下来,也是因为这次的旅行有些特别,而特别的事本身就有它的价值,不管是愉快还是不愉快的。倘若一种经历不给我们带来快乐和亲切的感觉,难道就应当马上扬起帆来,逃避它吗?一旦生活有些不如意,不完全称心,或者有点痛苦和折磨人的时候,我们就应该“扬帆而去”吗?不呀,应该留下来,应该把生活观察一番,去体验它,也许正好这样可以学到一些东西。于是我们就留下了,而我们坚留不走所得到的可怕的报酬,却是奇博拉那场轰动一时的不幸表演。
我还没有提起,就在我们受到政府当局惩罚的时候,比较清淡的季节已经开始了。不仅是那位控告我们的戴硬壳帽的老爷离开了浴场,大批游客也离去了,到处看见堆满行李的小车,给人推向火车站去。沙滩沙僱那股国家主义的气象逐渐消逝,在托勒镇上和咖啡馆里的生活,变得亲切些了,有了欧洲风味。现在我们尽可以在高等饭店的玻璃阳台上吃饭,但我们放弃了这权利,因为我们在安吉欧丽里太太的桌旁感觉到很舒适——只不过当地的凶煞神给“舒适”这字眼儿限定了某一种意义罢了。随着这种我们觉得有益的变化,天气却变坏了;它似乎同广大游客的假期保持协调。天上布满了阴云,但并没有凉爽起来,只是我们到这儿十八天以来(在这以前大概还有很久)一直在逞威的炎热,竟变成了一种窒息人的闷热,不时下一阵阵毛毛雨,弄得我们每天上午观光的天鹅绒般的沙滩,变成湿漉漉的。反正我们预定在托勒逗留的时间已经过了三分之二;死沉沉、灰溜溜的平坦海面上,漂浮着懒洋洋的水母,而这景象也不能不算新奇。没有人那么愚蠢,盼望再见到曾经横行霸道、弄得大家长吁短叹的太阳。
就在这时奇博拉出现了。有一天,到处贴出了广告,甚至爱莲诺拉公寓的餐厅里也不例外。广吿上他被称为奇博拉骑士。他还自称是周游各地的艺术家、演出家和Forzatore、Illusionista、Prestidigitatore等,并宣告将向托勒迪维纳的尊贵观众,献出神怪离奇的表演艺术。原来是个魔术师!这广告简直使我们的孩子头昏眼花了。他们从来没看过这表演,巴不得这趟旅行还能给他们一次神秘的刺激。于是从此时此刻起,他们就唠叨不停,要我们去买票看那魔术师的演出。晚上九点才开演,我们嫌晚,起初有些迟疑,但最后还是同意了,因为想到奇博拉的技巧大概不会很高明,我们略为见识一下,就回家去,何况第二天早上孩子们还可以多睡些。安吉欧丽里太太受到委托,为她的房客预定了一些好位子,我们便向她买了四张票。她说,不能保证这人的演技有多么好,而我们也不存什么奢望。我们自己也觉得需要散散心,孩子们的好舒心不免传染到我们身上来了。
奇博拉骑士在一座大厅里演出,这儿到盛季每星期放一次不同的电影。我们从来还没去过哩。到那儿去,要经过一座“宫殿”。附带地说,这是封建时代留下的一幢正在出售的建筑,形状像一座城堡。然后沿那儿的大街走下去。这儿有药房、理发店和其他一些常见的商店,可以说这条街从封建的领域,经过资产阶级的天下,通向平民的居住区。大街的一头是渔民的简陋住宅,门前蹲着修补渔网的老太婆。那“大厅”就夹杂在这些大众们的房舍之间,不过是个较宽敞的板房而已,像城门似的进口处两旁,横七竖八地贴着彩色的广告,作为装饰。到了演出的那天,吃了晚饭后,我们在朦胧的暮色中出发了。孩子们穿着节日盛装,他们因为有那么多新奇例外的事,正兴高采烈。就像前几天一样,天气闷热,间或在闪电,下着濛濛的细雨。我们撑着伞,路上走了大约一刻钟。
门口检了票,里面要自己找位子。我们的座位是第三排靠左边。坐下后我们发现,原来已较晚的开演时间,并未得到严格的遵守:观众似乎有意要迟到,前厅的座位才慢吞吞地给坐满了。没有包厢,只有楼下的普通位子。迟迟不开演弄得我们不安起来。疲倦加上焦躁的等待,使我们孩子的面颊发红了。两侧过道和后面需要站立的位子,在我们来到时,就客满了。那儿,半裸的胳膊交叉在穿花条纹布衬衣的胸膛上,站着托勒迪维纳的各式各样的汉子,其中有渔夫。也有目光炯炯、精明强悍的小伙子。我们觉得这些来自人民中的观众,给演出增添了民族色彩和趣味,因此对他们的在场表示欢迎,而孩子们则更是手舞足蹈。原来这些人当中,有一些是他们下午在较远的海滩上散步时所交的朋友。太阳完成了它艰巨的工作疲倦地沉到海里,并把卷上岸来的浪花染成金红色,我们在回家的路上常碰见一群群光着腿的渔夫,他们一个个紧挨着在收渔网,还拖长声音呼喊,他们从海里捕的鱼儿及海货照例少得可怜,装在淌水的筐里。孩子们看得出神,有时也搬出他们有限的几句意大利话,帮助拉渔网,结交朋友。现在他们跟站在戏院里的一些人打招呼;那儿是古斯卡多,那儿是安托尼奥,他们都叫得出名字,一面挥手,一面压低小嗓子,呼喊这些名字,而那边则点点头,露出健壮的牙齿笑笑,作为回答。瞧呀,连爱斯圭茜多咖啡馆的马里奥也来了,就是那个给我们端巧克力吃的马里奥!他也要看魔术师的表演。他差不多站在最前面,一定是来得很早吧。但他没有看见我们,他不大注意别人,这是他的一种习惯,虽然他是个当服务员的小伙子。于是孩子们只好向海滩上出租游艇的人招手,他也来了,站在最后面。
九点一刻了,快要九点半了。你能体会我们多么焦急吧。孩子们到什么时候才能睡呢?真不该带他们来,要是在他们刚开始看得起劲时就离去,那未免太扫兴啦。这时,前厅快满座了;可以说整个托勒的人们都来了,四周都是高等饭店的旅客、爱莲诺拉别墅和其他公寓的客人以及海边上碰到的熟面孔。听见英国话和德国话,也听见法国话,那大概是罗马尼亚人和意大利人在交谈吧。在我们后面两排,安吉欧丽里太太坐在她沉默的秃头丈夫旁边,他老是用右手当中两个指头捋他的小胡子。大家都迟到了,但谁也没有来得太迟;奇博拉让人等他哩。
他让人等他,这样说大概恰如其分。他迟迟不出场,引得观众更加紧张好奇。大家对他这种作法也加以体谅,但总也有个限度。到了大约九点半钟,观众拍起手来了——这是正当地显示不耐烦的一种客气方式,同时也表达了瞻仰的心情。小孩参加了拍手,觉得这已是个很大的乐趣。大凡孩子们都喜欢拍手喝彩的。从大众席位上,传来了有力的叫声:“Pronti!”和“Conminciamo!”于是,就像通常那样,不管有什么困难使演出耽误了这么久,现在终于顺利地开演了。一阵锣响,站的许多观众连声叫“好啊!”幕开了。幕后露出舞台,布景与其说像个玩把戏的地方,倒不如说像个教室,这尤其是因为前台左方的画架上架起一块黑板。还有个普通的黄色衣架,几把常见的草垫椅子。稍后一些,有个小圆桌,上面放着盛水的瓶子和玻璃杯有个特别的托盘,上面有个盛淡黄色液体的酒瓶和一些小酒杯。大约有两秒钟时间给观众看看这些道具。然后,并不等大厅里的灯光暗下来,奇博拉骑士就出场了。
他跨着急速的步子走上台来,好像表示急于要为观众效劳,同时又引起一种错觉,仿佛走来的人为了要同大家见面,曾经匆忙地赶了一段较长的路;其实他刚才一直站在后台上。奇博拉的装束,加强了这种似乎他是从外面走进来的感觉。很难说这人有多大年纪,肯定不年轻就是了。尖削的脸上十分憔悴,眼光锐利,嘴巴闭缩得紧紧的,小八字胡修饰得又黑又亮,下唇和下巴之间的凹处蓄着所谓帝须他俨然是一副夜晚出门时的复杂考究打扮:肩上披一件没有袖子的宽大黑斗篷,斗篷上翻着天鹅绒领子,还附有缎子衬里的披肩;戴一副白手套的手,在胸前按住斗篷,胳膊摆动起来有些别扭;脖子上围一条白围巾,头上斜戴一顶歪边的大礼帽。十八世纪的风俗在意大利大概比在别国保存得更多些,那个时代典型的庸医和江湖骗子也不例外。只有在意大利还能碰见这种保留得相当完整的形象。奇博拉从头到脚的装束,颇符合历史的传统,那副样子给人一种炫耀和荒诞滑稽之感,况且这套华贵的服装极不合身,这儿绷得过紧,那儿又松得皱起来,好像挂在身上似的:他的身材看来有些畸形,前后都是这样——到后来这点更明显了。可是,我必须强调,在他个人的表情、动作和谈吐中,却没有任何戏谑的成分,或者小丑的卖弄。相反的,他非常严肃,丝毫也不诙谑,有时露出一种怪癖的骄傲和佝偻者所特有的那种尊严和自我欣赏——起初,这一切不免在大厅里许多地方引起笑声。
他的举止中已经没有殷勤的表现了;他刚才匆匆地上台,原来是由于精力饱满的缘故,毫无奉承讨好的意图。他站在戏台脚灯跟前,漫不经心地脱下手套,露出一双发黄的细长的手,手指戴着镌有印章的戒指,戒指上镶着高高凸出的蓝宝石。一双下眼皮萎靡下垂的敏锐小眼睛,在大厅里扫了过去,并不是仓促地瞥一眼,而是在这个或那个脸庞上停留片刻,沉思地观察它;嘴紧闭着,一句话也不说。他把卷成一团的手套,朝离开相当远的小圆桌顺手掷去,恰好掷在玻璃杯里面,动作熟练得令人诧异,看去又是那么凑巧。然后,他一面还默默环顾,一面从衣袋里掏出一包香烟——从包装上看得出是最便宜的国产牌子——用尖手指从包里抽出一支香烟来,打开很灵验的打火机,看都不看一眼,就点燃了香烟。接着,嘴唇向后翘了翘,扮出傲慢的鬼脸,一只脚在地上轻轻打拍子,从他蛀掉的尖尖的牙齿缝里,吐出一团灰色的烟雾。
观众和他一样敏锐地观察他。站在后面的年轻人正紧蹙着眉头,用锋利的眼光在那过分自信的人身上寻找弱点。他没有暴露任何弱点。他拿出和放回香烟、打火机的时候,他的衣服很碍事;他不得不拉开斗篷,而这时人们发现他左下臂上很不相称地用小皮环吊着一根马鞭,银色的鞭柄像个爪子。观众注意到他没有穿大礼服,只穿普通的礼服。当他揭开上衣时,还看见他腰上围一条五彩的绶带,绶带一半给背心遮住。坐在我们后面的观众小声议论说,这绶带标志着他的骑士头衔。这话不一定对头,我个人从来没有听说骑士的称号同这种标志有什么关系。可能这绶带只不过是一种卖弄而已,就像他默默地站在那里的那副姿态也是一种卖弄一样。这位魔术师还是什么都不作,只顾懒散傲慢地在观众面前吸烟。
就像上面所说那样,人们笑了,当站着的人群当中突然有个声音响亮而冷淡地说一声“Buonasera!(晚上好!)”时,大伙儿几乎都乐开了。
奇博拉竖起耳朵听了听。“是谁?”他挑战似地问。“刚才谁在说话?喂?刚刚还那么大胆,现在就胆怯了吗?Paura(害怕了),啊?”他说话的声调高扬,有些喘急,但很刺耳。他等待着。
“是我,”一个青年在四周的寂静中说,他显然觉得接受挑战,是桩有关名誉的事。这小伙子站在离我们不远的地方,他长得俊俏,穿一件棉布衬衫,上衣挂在一只肩膀上。僵硬的黑鬈发,照他觉醒的祖国最时髦的式样,梳得又高又乱,很不相称,使他有些像非洲人。“Bè……是我。照规矩该你先讲话,但我抢先说表示有礼貌。”
大家又兴奋起来。这小伙子嘴巴挺硬。“Hascioltoloscilinguagno1o(他真能说会道),”有人在我们旁边议论。这番当众训斥的话毕竟说得很恰当。
“啊,好极啦,”奇博拉回答说。“我喜欢你,Giovanotto(小伙子)。我老早就注意到你了,你相信吗?像你这样的人,最合我的心意,我需要这种人。你显然是个好汉。你爱做什么,就做什么。有那么一次吗,你曾没有做你想要做的事?或者说,做过你不想要做的事?不是你想要做的事?听我说,朋友,你老是充当好汉,既要管自己的愿望,又要管行动,还不如不当好汉,反而方便和惬意多啦。应该实行分工——sistemaamericano,sa(要知道,这是美国式的制度)。譬如说,你愿意在这些尊贵的观众面前伸出舌头吗?伸出整个的舌头,一直伸到舌根?”
“不,”小伙子含着敌意说。“我不愿意。这样做表示没有教养。”
“那算不了什么,”奇博拉回答说,“因为你只不过是做一下而已。我尊重你的教养,但照我的看法,我不消数到三,你就会向右转,向观众伸出舌头,伸得比你自以为能伸的还要长。”
他盯着小伙子看,敏锐的眼睛好像更深沉地陷在眼眶里。“Uno(一),”他一面数,一面把皮鞭在空中短促地挥了一下,鞭柄上的皮圈曾事先从胳膊上滑了下来。小伙子把脸转向观众,伸出舌头,尽量伸得长些,看得出他整个的舌头都露在外面。然后,他恢复了原先的姿势,脸上并没有什么表情。
“是我,”奇博拉讥讽地模仿说,扭了扭脑袋,指向小伙子。“Bè……是我,”便转过身去,让观众径自去大惊小怪。他走向小圆桌,从显然盛着烧酒的瓶里,斟出一小杯酒,老练地一饮而尽。
小孩们尽情地笑。刚才的交谈,他们差不多完全没有听懂;但他们觉得台上那个怪人和一个观众之间所发生的事很滑稽,高兴得了不得。他们对那天晚上要举行的表演,并没有什么明确的概念,便以为这是一个美好的开端。我们呢,我们相互瞥了一眼。我还记得,我曾不由自主地用嘴唇模仿奇博拉挥鞭的声音。观众显然对魔术表演的这种离奇的开场感到茫然,也不大明白那位可以说是替他们说话的小伙子,怎么突然改变了立场,竟对观众泼野起来。大家都觉得他太不争气,不再理睬他,把意力转向魔术师身上。他喝了酒,抖擞精神,从小圆桌旁走过来,发表下面的演说:
“女士们和先生们,”他用他那气喘吁吁而生硬的声音说,“刚才那位有前途的年轻语言学家(“questolinguistadibellesperanze”——这一文字游戏引起了众人的笑声),企图教育我,使我表现得有点激动。我是个有自尊心的人,请各位谅解!向我道晚安,必须严肃和有礼貌,否则太不知趣了——没有任何理由不这样做。祝我晚上过得好,实际上就是祝自己过一个愉快的晚上,因为只有当我心境舒畅时,观众才会感到愉快。这位托勒迪维纳姑娘们的意中人(他一直不停地讥刺那小伙子),做得很对,他让我违背他的心意,保证我今天过个痛快的晚上。我敢夸口说,每天晚上我差不多都过得很好。偶尔碰上一个晚上不大称心,但这种情况很少。我这行职业相当艰苦,况且我身体也不顶好;我身上有点小毛病,不能参加为了彰显祖国的伟大而进行的战争。我只有用灵性和精神的力量征服生命,而这也总是意味着自制。我的演出已在广大有见识的观众间引起了重视和关注,这点我足可聊以自慰。一些主要的报纸,对我的演出,都有较高的评价,晚邮报很公正地称我为非凡的天才。在罗马演出时,有一天晚上我荣幸地在观众中看见了元首的兄弟。本人的一点小癖好,在繁华、高尚的都市曾经蒙观众所体谅,料想不到在托勒迪维纳这样一个比较僻陋的小镇(可怜的托勒受到台下观众的嘲笑),竟不容忍我这种习惯,要我抛弃它。有些给女性宠坏的家伙,居然为此而教训我。”倒霉的小伙子又挨骂了,奇博拉不厌其烦地把他刻划成为一个donnaiuolo(花花公子),一个乡村的风流人物。他对小伙子的那种神经过敏、怀恨在心的攻击,显然同他吹嘘的自尊心和盛名有些格格不入。大概这位青年被当作笑柄,照奇博拉的习惯,可能每天晚上都要选一个人作讥讽的对象。可是,他的嘲笑中也流露出不折不扣的敌意。其实只要比较一下两人的身材,就不难揣想到其中的缘由,况且那伛偻的人一再凭空暗示小伙子在女人们当中很走运。
“表演就要开始了,”接着他又说,“请允许我弄得舒适一些!”
于是他走向衣架去脱外衣。
“Parlabenissimo(他讲得妙极了),”我们附近有人评论道。魔术师还没有表演什么,但他的谈吐已经引起观众的注意,被他们看作是一种成就。南方人把语言作生活乐趣中不可缺少的一部分,对它在社交中所起的作用,远比北方人估计得高。他们尊敬祖国的语言,因为它把民族团结在一起,而这种尊敬具有象征性的意义;他们对它的形式和语音规律的那种热诚的敬爱,也有它的生动活泼的象征性。他们高兴地说话,高兴地听——也带着批判的态度听。一个人的谈吐,往往被当作衡量他身分的尺度;说话随便和笨拙会遭到白眼,措词漂亮讲究,巧妙动听,能令人尊敬。所以,即使普通人,在需要考虑到效果时,也要仔细地选择词汇,谨慎地构造句子。在这方面,奇博拉显然获得了成就,虽然他并不属于意大利人所谓的“Simpatico(惹人喜爱)”的类型,这种类型是根据道德标准和审美观点的一种奇特的混合而来衡量的。
他脱下礼帽、围巾和外衣,一面走回前台来,一面整理上装,拉出大钮扣扣住的衬衣袖头,摆弄那骗人的绶带。他的头发很难看,就是说,脑壳几乎光秃,只有打中间分开的一排狭长的头发,从头顶延伸到额头。头发是染黑的,好像贴上去一样,太阳穴上的头发也染黑了,向两旁梳到眼角——倒有些像老式的马戏团老板的发式,样子挺滑稽,但跟他整个人的那种古怪的风格颇为相称,况且他又是那么自命不凡,以致大家只好将滑稽的感觉闷在肚里,不便表示出来。他预先提到的身体上的“小毛病”,现在暴露得更明显,但还不能完全看出它的性质:就像这种情况下所常见的那样,胸部耸起得过高,但背上突出的部分,似乎不在两肩之间,而比一般的要低些,位于腰部和臀部。这样虽然还不妨碍他走路,但使得他走路的姿势很特别,每走一步,身子就奇怪地向前歪一下。由于他事先曾提起身体上的缺陷,所以并未显得那么不堪入目,可以觉察到有一种彬彬有礼的微妙气氛笼罩着大厅。
“听候吩咐!”奇博拉说。“请允许我作几题算术练习,作为节目的开始。”
算术?这哪儿像魔术呢。我怀疑起来,这人是不是冒充魔术家,但又猜不透他到底算是什么。我开始替孩子们惋惜;他们因为有戏看,却正在高兴哩。
奇博拉玩的数字把戏,既简单,但有些方面又令人摸不着头脑。他先把一张纸用一支锥形笔钉在黑板的右上角,然后举起那张纸,用粉笔在黑板上不知写了些什么他一面写,一面说个不停,尽量用无休止的谈话伴随和充实他的演出,免得表演枯燥。他健谈善辩,从来不会因为想不出话来说而感到窘迫。他跟打鱼的小伙子所发生的奇怪冲突,已经使他跟观众比较接近,现在他要立刻进一步设法消除舞台和观众座位之间的鸿沟。因此,他邀请观众的代表上舞台,还爬下通向正厅的木阶,亲自跟观众打交道。这大概是他独特的表演风格,也颇为孩子们所欣赏。他随后又跟个别观众发生纠葛,至于这种纠葛是不是他故意惹起和安排的,那我就不知道了,虽然那时他总是很严肃和怒气冲冲的。观众,至少是当地的观众,似乎认为那是整个表演的一部分。
他写完以后,把所写的隐藏在那张纸后面,接着表示希望有两个人上台,帮助他作算术题,他说题目不难,即使没有数学天才的人,也能够算出。照例没有人报名。奇博拉避免打扰观众中那些文质彬彬的人,他还是和老百姓打交道,转向后厅的站座,要求两个又粗又壮的小伙子上台来。他给他们打气,责备他们不该只顾呆立在那儿看戏,不去为观众效劳,结果真给他说服了。他们跨着笨重的步子,打中间的过道走来,爬上台阶,在伙伴们的喝彩声中,站在黑板跟前傻笑。奇博拉同他们开了一会儿玩笑,称赞他们的肢体长得雄壮魁伟,两只手又大又结实,正适于为观众效劳,然后把粉笔放在其中一人的手里,要他记下报给他的数字。“Nonsoscrivere(我不会写),”小伙子用粗鲁的声音说,他的同伴也插嘴说:“我也不会。”
天晓得他们是说真话,还是只不过要捉弄奇博拉。他们的坦白引起了哄堂大笑,但奇博拉却一点都不笑。他又气又恼。他翘着腿坐在台中央的一把藤椅上,又抽上一支便宜香烟;这烟抽起来似乎更有味道了,因为当那两个笨蛋踏上台来时,他曾喝了第二杯烧酒。他又把深深吞下的烟,从露出的牙齿间喷出来,同时摇晃着一条腿。他连看都不看那两个自鸣得意的厚脸皮,眼光避开他们和观众,只顾出神,就好像一个人在他所极为鄙视的事物面前,往往表示不屑一顾,以免有失身份。
“可耻!”他冷言冷语、咬牙切齿地说。“回到自己的座位上去!在意大利,每个人都会写字,它的伟大不允许无知和蒙昧存在。这真是个拙劣的玩笑,在这样一个国际性的聚会上,竟把这种蒙昧无知归罪于意大利,这不仅是丢自己的脸,也会招致对政府和国家的闲话。如果托勒迪维纳果真是祖国最僻陋的角落,隐藏了连起码的常识都缺少的那种无知,那我非常遗憾,不该选中这个地方。我诚然早就知道,它的重要性在各个方面远不如罗马,但是……”
这时,梳努比亚黑人头发式样、一只肩上披着上衣的小伙子,打断了他的话。他昂起头,站出来捍卫自己的故乡,可见他的斗争精神只是暂时被抑制下去。
“够了!”他响亮地说。“开托勒的玩笑开够了。我们都生长在这儿,决不让别人在外国人面前嘲笑这个城市。那两个青年是我们的朋友。他们虽然不是学者,也许倒比大厅里一些夸耀罗马的人们要正经老实多了,何况罗马又不是那些人亲手建立的。”
说得妙极啦。小伙子针锋相对,嘴巴可真厉害。大家对这种戏剧性的冲突发生兴趣,虽然正式的演出因此更加耽误了。听别人口角总是吸引人的。有些人只不过觉得好玩而已,还有点幸灾乐祸,因为自己没牵涉在里面;另一些人则感到难受和激动。我倒是同情后面那种人,不过那时我还以为两个不识字的厚脸皮和那个披上衣的小伙子,多多少少是帮助演出者制造戏剧性的场面的。孩子们兴高采烈地听着。他们什么也听不懂,但声音语调使他们屏住气息。喔,原来这就是魔术晚会,至少是一种意大利式的。他们觉得确实有趣。
奇博拉站了起来,耸起屁股,跨了两步,就走到舞台的脚灯前。
“瞧呀!”他说,亲切中带着狰狞。“一位旧相识!一位心直口快的小伙子!”(他说“sullalinguaccia”,意思是“有苔的舌头”,引起哄堂大笑。)“去吧,朋友们!”他转向两个笨伯说,“不需要你们了,我要同这位君子打交道,conquestotorregianodiVenere,这位维纳斯塔上的守卫人。他这样警惕,毫无疑问地是在期待娇声娇气的感谢哩……”
“喂,别开玩笑!我们说正经话!”小伙子叫起来。他目光炯炯,做了个动作,仿佛要扔下上衣,用最直截了当的办法解决这场争端。
奇博拉满不在乎。我们相互看了看,表示担心,他却不然,因为他的对手是个老乡,而他脚底下踏着自己的国土。他泰然自若,漫不经心,眼睛对着观众,微笑着用脑袋向气势汹汹的小伙子晃了一下,仿佛要他们也付之一笑,并让他们亲眼目睹这个小伙子爱打架,而这种爱打架只不过表示他头脑简单而已。接着又发生了一桩奇异的事,使奇博拉的优越感蒙上一层神秘诡谲的色彩,并使这一场紧张的冲突,不知怎的令人羞恼地演变成一种滑稽的东西。
奇博拉凑近小伙子,眼睛一直怪模怪样地盯着他,我们左边有个梯子通向大厅,他甚至爬下半数的台阶,面对面站在好强的小伙子跟前,比他站得稍微高一些。马鞭挂在他胳膊上。
“你不高兴开玩笑,老弟,”他说,“那是可以谅解的,因为人人都看得出你有病。单单你那条远不够干净的舌头,就显出你的消化系统有严重的毛病。像你这样感到不适,就不应该晚上出来看戏。我知道,你事先也曾经犹豫过,是不是该躺在床上,把肚子裹起来。今天下午你不该冒失地喝那酸得可怕的白酒。现在你胃非常难过,痛得恨不得弯下腰去。别怕难为情,就弯下去吧!把身子弯下去,可以减轻绞肠的痛苦。”
他一个字一个字地吐出来,镇定而又咄咄逼人,流露出一种严肃的关怀,眼光好像刺穿那年轻人似的,眼珠突出在泪囊外面,看来又萎靡又明亮。这双眼睛很特别,可以想象到,对方不避开他的眼光,不仅是由于高傲的缘故。这时小伙子青铜色的脸上,骄傲的神情早就消逝得无影无踪了。他目瞪口呆地看着奇博拉,张开的嘴巴露出困惑、可怜的微笑。
“弯下腰去!”奇博拉重复道。“你还有什么别的办法?患这种腹痛,就必须弯下腰去。你不会因为别人向你建议,就拒绝去做这个很自然的动作。”
小伙子缓慢地举起下臂,交叉着按在肚子上,身体向旁边转了转,弯了下去,越弯越低,两脚叉开,膝盖向里弯,最后差不多蹲在地上,俨然一副痉挛苦痛的样子。奇博拉让他在几秒钟内保持这种姿势,然后用马鞭在空中短促地挥了一下,便如释重负地跨着歪步回到小圆桌旁,干了一杯酒。
“Ilboitbeaucoup(他喝得很多),”一位太太在我们后面判断说。她只注意到这一点吗?我们弄不清楚观众到底看明白其中的底细没有。小伙子这时又立直了,有些窘迫地微笑,好像不大懂刚才遭遇到什么似的。大家曾紧张地注视这桩事的演变,现在结束了,便拍手欢呼,又叫:“好!奇博拉!”又叫:“好!小伙子!”这场纠纷的收场,显然没有被当作小伙子个人的失败,相反地,他受到鼓励,就像杰出地表演一个尴尬的角色的演一样。的确,他痛苦地萎缩的样子,表情很丰富,仿佛是故意做给观众看的,可以说是一种出色的表演。但我不能肯定说,观众的态度,有几成取决于南方人特有的一种待人接物的礼貌(在这方面南方人胜过我们),有几成取决于他们对事物内幕的洞悉。
奇博拉喝了酒,提起精神,又点燃了一支香烟。可以继续玩算术的把戏啦。这次很容易在后排的座位上找到一位年轻人,他表示愿意把报出的数字写在黑板上。我们也认得他;整个的表演给人一种亲切的感觉,因为许多面孔都是熟悉的。这青年是大街上食品水果商店的店员,曾有好几次殷勤地接待过我们。他用粉笔写数字,表现出商人的熟练;奇博拉则爬下舞台来,在观众当中用怪样的步法踱来踱去,要大家随意报二位、三位和四位的数字,报出以后,再由他大声转报给那年轻的店员听,而后者则把数字写下来,排成一行。在整个过程中,产生了不少趣味、诙谐和离题很远的俏皮对话,好像大家说好要这样那样的。表演者难免碰上不会用意语报数字的外国人,于是就摆出骑士的风度,花费许多工夫耐心殷勤地同他们周旋。有礼貌的老乡们看得热闹,但要他们翻译用英语和法语报出的数字时,便感到窘迫。有些人报了代表意大利历史上显赫的年代的数字,奇博拉立刻抓住这些数字,一面走下去,一面发表爱国的言论。不知谁说“零”,于是这位大凡有人同他开玩笑总是非常不高兴的骑士,耸了耸肩膀以作回答,两位数还差一位哩,紧接着就有个捣蛋鬼叫起“零零”来,引起哄堂大笑,南方人听到对一些自然事物的讽示,老是很开心的。骑士装出高傲的样子,不去睬他,虽然这类戏谑是他自己引出来的;但他毕竟把这数字报给记录的人,并且耸了耸肩膀。
大约有十五个长短不齐的数字写在黑板上以后,奇博拉要求大家把数字加起来。他说,精通算术的人可以心算,但也允许借助于笔和簿子。大家忙着算的时候,奇博拉坐在黑板旁边的椅子上,扮着鬼脸抽烟,一举一动都流露出畸形人那种自鸣得意的神态。五位的数字很快就计算好了,有人报了出来,另一个人证实了这数字,第三人的答案略有出人,但第四个人的数字又和头两个人的一样。奇博拉站了起来,掸了掸衣服上的烟灰,举起钉在黑板右角上的那张纸,好让大家看到他先前在那儿写了什么。那儿写着正确的答案,将近一百万的数目。他预先就猜到了它。
全场震惊,并且响起了热烈的喝彩声。孩子们看得目瞪口呆。他怎么会猜到呢,他们想要知道。我们解释说,那是一种骗人的把戏,并不是一下就能明白的,一句话,这人是个魔术师。于是他们懂了是怎么一回事,是魔术表演。先前渔夫肚子痛起来,现在黑板上又预先写好正确的答案——真是妙极啦。我们却发起愁来,虽然孩子们眼睛发红,表上已经是十点半了,但要带他们走,却很困难。一定会惹出不少眼泪。可是,至少从手脚机灵敏捷的角度上看,这驼子明明不是在表演魔术,而且不适合于孩子们看。我仍然弄不清楚,观众的想法如何。所谓数字的“自由选择”,显然是很可疑的;也许个别观众曾自主地报数字,但总的说来,奇博拉显然挑选了自己人,整个过程都在他控制之下,而以既定的答案为目标——不过,即使别的没有什么奇怪,他那敏锐的数字头脑也令人敬佩。还有他那爱国主义和敏感的自尊心:可能这位骑士的同胞觉得一切都很自然,乐意继续开玩笑;我们外国人却感到这一切颇令人憋闷。
奇博拉自己也设法让那些稍明事理的人弄清楚表演的性质,不过是含糊其词罢了。他不停地说话当然也提到这一点,但老是用一些不肯定、夸张、渲染的字眼。他继续进行了一会那套数学测验,把计算弄得越来越复杂,加减乘除都使用起来。后来他又把计算弄得异常简单,好让人们看出是怎么一回事。他干脆叫人去“猜”纸下面预先写好的数字。差不多每次都正确。有一位观众表白说,本来想报另一个数字,但在骑士的马鞭在跟前霹雳一响的刹那间,他却不知怎么报出了黑板上写的那个数字,奇博拉耸耸肩膀,笑了笑。他假装佩服报数字的人们的机智,但他的称赞含有讥讽和鄙视的口气。我想,参加测验的人听了不一定会感到舒服,虽然他们嬉笑着,并想要把观众的欢呼部分地归为己有。我的印象是,好像观众对这位表演家并不十分喜爱。可以觉察到一种抗拒和敌对的情绪。不过,抑制这类情绪的礼貌姑且撇开不谈,奇博拉本人的技巧和充分的自信,确实给人以深刻的印象,甚至那马鞭,照我的看法,也起了些作用,防止了反叛的表面化。
玩了玩数字把戏以后,便用纸牌变戏法。他从衣袋里掏出两副牌。我还记得,典型的把戏基本上是这样玩的:他从一副牌中抽出三张,看都不看,藏在上装里面的口袋中,然后要应试的人从另一副牌中抽出同样的三张来——并不每次都完全正确;有时只有两张是对的,但大多数情况下,当奇博拉公开三张牌时,他总获得胜利。他漫不经心地对欢呼和拍掌表示感谢,而观众好歹也得承认他的技巧非凡。我们右边,坐在前排的一位年轻绅士——一位容貌高傲的意大利人——报了名,表示决定要自由自主地选择,并有意识地拒绝任何外界的影响。他问,在这种情况下,照奇博拉的看法,会有什么结果。“你将增加我表演的困难,”那位骑士回答说。“可是你的反抗不会使结果有所改变。自由是存在的,意志也存在;但不存在什么自由的意志,因为如果意志要为自己觅得自由,就会进入虚无的境界。你有自由,可以抽牌,也可以不抽。可是,倘若你要抽,你一定会抽得准确——你越想专断行事,结果就越准确。”
必须承认,要混淆视听、制造心灵上的混乱,这番话选择得再好也没有。倔强的青年在抽牌以前,神经质地犹豫了一下。抽了一张牌以后,立刻就要看是不是隐藏的纸牌中的一张。“怎么?”奇博拉表示诧异。“为什么事情只做一半呢?”但固执的青年坚持要先看看。“Eservito(悉听尊便),”魔术师卑躬屈膝地说,一面示出三张叠成扇形的牌,自己连看都不看。左边的那张就是年轻人抽出来的。
在满厅的掌声中,自由的卫士愤怒地坐了下去。奇博拉的天才,在多大程度上得到一些骗人的技巧和手急眼快的动作的支助,那只有鬼知道。就假定他需要依靠这些,观众们仍然非常好奇,觉得这奇特的表演很有趣,都异口同声称赞他有才干。“Lavorabene(他的手法真好)!”我们听见附近到处有人下这种评语,可见客观的公正战胜了反感和闷在肚里的愤怒。
在获得刚才那不完整的,但因此更引人注目的成就以后,奇博拉立刻又喝了一杯烧酒。的确,他喝得不少,这点看上去倒有些不顺眼。不过他喝酒抽烟,显然是为了保存和恢复精力,况且他自己也曾表示,表演从各方面来说都很吃力。他面色有时确是不好看,眼睛凹进去,显得萎靡不振。但他每次喝一杯酒,便恢复精神,夸夸其谈,从肺里喷出吸进灰蒙蒙的烟雾。我记得颇清楚,他变了纸牌的戏法以后,便开始玩另一套把戏,而这种把戏是依靠人的超意识或下意识的机能,依靠直觉和催眠术,一句话,依靠一种较低级的表现形式。只有表演节目的顺序细节我不大记得了。我不打算一一赘述,免得读者厌烦。每个人都熟悉这种游戏,至少参加过一次:寻找藏好的东西呀,盲目地做一些连贯性的动作呀,而这都是根据从一个有机体,不知通过什么途径,传到另一个有机体的意志去完成的。每个人都曾看到过这类暧昧、邪秽、不可思议的神秘现象,摇摇头,有点好奇,鄙视它们。有些具有某种神秘机能的人,却往往令人厌恶地把这种机能同骗人的把戏和幻术混淆起来,但这类的掺杂,并不能证明那可疑的混合物中其他成分就一定不真实。我只是说,当一个像奇博拉这样的人,做了邪术的导演和主角时,表演的各个环节就格外有吸引力,从各方面给予人的印象也更深。他坐在舞台靠后的地方,背朝向观众,抽着香烟。大厅里不知何处有几位观众暗中商量了一番,然后把一件东西从一个人手里传到另一个人手里去,要他猜出藏在谁那里,并用这东西做一桩预先约好要他做的事情。奇博拉这时表现的动作是典型的:一会儿奔向前去,一会儿止步谛听,有时慢慢向前摸索,有时找错方向,忽又急转身,纠正偏误。他是由一位知悉内幕的向导带领的,在大厅里曲曲折折地走来走去,头向后仰,一只手伸出来,而他的向导则得到指示,动作必须完全依从奇博拉,但思想要集中在约定的东西上面。可以说角色调换了,潮流向着相反的方向移动了。口若悬河的表演家也明确地提到这点。先前,他曾出主意,吩咐和指挥,而现在他却担任容忍、收受和执行任务的角色,完全抑制自己的意志,为大厅里群众的默不作声的意志所左右。但他强调,实际上这是一回事。他说,摈弃自我、成为工具、不折不扣地服从别人的这种能力,只不过是出主意和指挥的另一面,具有同样的性质;命令和服从共同组成一个原则,一个不可分割的统一体;会服从的人,也会命令,反之亦然。前一种概念包含在后一种概念中,就像人民和领袖相互分不开一样;可是,那异常严格和折磨人的行动,毕竟属于领袖和主持者,在这人身上意志成为服从,服从成为意志,他个人乃是两者诞生之土壤,所以他的任务特别艰巨。他一再强调,他的工作异常艰巨,大概为的是解释为什么需要提神而且不住喝酒的原因。
他到处摸索,俨然是个先知,受到公众的神秘意志的引领和支配。他终于把藏在一位英国太太鞋里镶有宝石的别针找了出来,然后,一会儿踌躇,一会儿疾奔,拿着它跑到另一位太太跟前去这就是安吉欧丽里太太——并且跪了下去,呈上那枚别针,说出约定的一段要他说的话;这些话尽管意义相近,但不易猜到,因为是用法语议定的。他该说,“我送你一件礼物,表示敬仰!”我们觉得条件太苛刻,似乎含有恶意,这里反映着某种矛盾心理,即一方面期待这一奇妙的把戏成功,另一方面盼望骄矜的魔术师失败。奇博拉怪模怪样地跪在安吉欧丽里太太面前,吐露出试探的话语,力图猜到给予他的难题。“我必须说什么,”他表示,“也清楚地感觉到应该说什么,但又觉得说出口来会不对的。千万别无意中给我什么暗示来帮助我!”他叫道,虽然他无疑正好盼望要这样……“Penseztrèsfort(你得好好想一想)!”他突然用蹵脚的法语叫起来,然后用意语脱口说出该说的一句话,但最后和最重要的一个字,仍然是用它的姐妹语说的。他似乎不谙法语,把“venerazione”说成“vènèration”,结尾还是用怪可怕的鼻音发出的。在他圆满地找到别针,走到受礼的人那儿和跪下去以后,这收场固然美中有所不足,但简直比十全十美的结尾,更能引人入胜,引得观众赞不绝口。
奇博拉站起来,揩了揩额上的汗。您懂吗,我只不过举了一个节目作例子,讲了讲别针的事情,因为它给我的印象特别深。他多次改变节目的基本形式,不时穿插一些临时想出来的花样,从而花去不少时间,而他同观众的接触也有助于他不时搞出各种新的名堂。尤其我们的女房东似乎引起他的灵感,勾出他一番未卜先知的话来,弄得我们莫名其妙。“我发现,太太,”他说,“您的根基与众不同,令人肃然起敬。只要有灵眼,便能看见您美丽的额头四周有圈荣光,倘若我没有看错,过去这光辉尤为光艳夺目,如今则日趋暗淡……不要说话!不要帮助我!你身旁坐的是你丈夫——是吧?”他转向沉默的安吉欧丽里先生说,“你是这位太太的丈夫,你感到心满意足。但这幸福中夹杂一些回忆……高贵的回忆……太太,以往的事,在你当前的生活中,似乎起很大的作用……在过去的岁月里,你在生活的道路上,遇到过一位君王吗?”
“没有啊,”中饭替我们盛汤的太太小声说,苍白斯文的脸上一双金黄的眼睛闪闪发光。
“没有吗?不,不是君王,我只不过粗略地打比方而已。不是君王,不是公侯——却是更高的境界中的君王、公侯。你曾在一位伟大的艺术家的身旁……你想要否定我的话,但不能下定决心,只能半拒半从,是呀!你在青春时期曾认识一位世界闻名的伟大女艺术家,对她的回忆给你的一生增添了不少光彩……她的姓名?需要提姓名吗?这姓名不早就同祖国结合在一起了,同它一样不朽吗?爱莲诺拉·杜塞,”他庄严而轻声地结束这篇谈话。
身材纤小的夫人情不自禁地点头出神。观众的拍掌欢呼有点像国民的示威。戏院里差多每人都知道安吉欧丽里太太的光辉历史,对骑士的洞察能力赞叹本已,特别是爱莲诺拉别墅的房客。问题在于他本人究竟知道多少,他到了托勒以后,无疑会照他们那一行的习惯,四处打听消息,可能探到一些底细……但我没有理由一味凭理智去怀疑他的本领,况且这本领在我们眼前招致了一场大祸……
接着休息了,我们的主宰回到后台去。我必须承认,差不多一开始讲的时候,我就怕报道中这一环节交代不清楚。揣度别人心里想什么,照例不难,这儿更容易。您毫无疑问会问我,我们怎么不终于离场呢——我无话以对。我自己也不明白,确是无法辩白。那时肯定已不止十一点了,可能还要晚些。孩子们睡着了。最后一出表演,他们觉得乏味,自然就给睡眠征服了。他们睡在我们膝男孩在母亲膝上。这一方面是令人慰藉的,但另一方面也该引起怜悯,提醒我们该带他们回去睡觉。说老实话,我们在这一感人的提醒下曾经动过心,当真要回去。我们唤醒可怜的孩子,表示现在很晚了,非回去不可。他们一醒过来,就开始恳求不肯回去。您知道,看什么表演时,孩子们总不愿提前离场,要说服他们是不可能的,除非硬拖他们去。他们央告说,看魔术家表演很有趣,不知还有什么好节目,至少应该等着瞧他休息后表演什么,他们愿意偶然打打瞌睡,但在这儿还举行有趣的表演时,千万不要回去,千万不要上床睡觉!
我们让了步,不过只答应看一会儿,暂时留一下。我们很难辩白为什么留下来,要解释清楚也几乎同样困难。本来就不该带孩子们来,是不是现在只好将错就错呢?我觉得这理由不够充分。我们自己看得有趣吗?是,也不是,我们对奇博拉的态度很复杂,但如果我没有判断错,戏院里的人的态度都是这样,然而没有人离场呀。难道这位靠这种奇术挣口饭吃的人,在表演节目和技巧之外,别有什么吸引人的地方,弄得我们拿不定主意吗?同样也可能只是好奇心在作祟罢了。只不过想要知道这场戏怎么演变下去,况且奇博拉下台时,又曾渲染一番,暗示还有许多本领没有使出来,往下会表演得更精彩。
但这都不对,或者不尽是这样。最妥当的办法,还是用我们先前为什么没有离开托勒的问题,来回答我们现在为什么不离去的疑问。照我看,这实际上是一回事,为了替自己圆场,我可以说这问题已经回答了。这儿跟整个托勒镇上一样古怪和紧张,一样令人不舒适、难过和憋闷,是的,只有过之而无不及:笼罩我们这趟旅行的那股气氛里所含有的怪异、不舒畅和紧张,都在这里集了大成。大家正在等待上场的那个人,在我们心目中就是这一切的化身。从大处说,我们既然没有离开托勒,那末从小的方面来说,要是现在离开戏场,就不合逻辑了。这点作为我们迟迟不走的理由,你接受也罢,不接受也罢,我反正想不出更好的理由。
说要休息十分钟,结果拖长到将近二十分钟。孩子们清醒了,见到我们肯让步,高兴得不得了,在休息时,倒过得挺愉快。他们又同当地人打成一片,跟安托尼奥、古斯卡多、出租划子的汉子打交道。他们使用了我们这儿学去的字眼儿,合起手来作话筒,向渔夫们呼喊一些吉利话:“明天多捉些鱼!”“渔网装得满满的!”又对着爱斯圭茜多咖啡店的侍者马里奥叫喊着:“Mario,unacioccolataebiscotti!(马里奥,拿一杯巧克力和一些糕点来!)”他这次听见了,微笑着答应:“Subito!(马上!)”我们有理由牢牢记住他那友好的、有点心不在焉的忧郁微笑。
就这样休息结束了。一阵锣响,聊天的观众聚集起来,孩子们迫切地在位子上坐定,把双手放在膝上。原先没有闭幕。奇博拉跨着歪步,走上台来,刻就宣布下半场的节目,好像致开幕词一样。
允许我概括说明一下:这自负的驼子是我一生中所遇到的本领最大的催眠家。他在广告上隐瞒表演性质,称自己是杂技表演者,显然只不过是对治安条例的阳奉阴违,因为利用这种能力进行营业是严格禁止的。在这国家里,碰到这种情况,只要形式上能够混淆过去,官方大概就会闭上眼睛,或者半闭上眼睛。反正这位走江湖的,一开头实际上就没有十分掩饰他所玩的把戏的性质,演到下半场,他虽然还是拐弯抹角地夸夸其谈,但已露骨地集中在进行剥夺他人的意志和把意志强加于他人身上的实验。他花费了许多功夫,演出一连串滑稽的、扣人心弦的、令人惊讶的节目,到了深更半夜演得还很起劲。在演出中,这类又自然又怪诞的现象,从一些不触目的到一些最奇特的,无不呈现在我们面前。随着一些怪诞的节目,观众捧腹大笑、摇头、捶膝、拍掌,显然给这异常自信的人所蛊惑。同时,至少我觉得这样,奇博拉的凯旋,不论对个别人或对全体观众,都包含着一种说不出的侮辱,引起他们的反感。
在他成功的表演中,有两件东西起主要作用:酒杯和爪子形把柄的马鞭。那酒杯不时需要为他效劳,刺激他那股魔力,不然似乎就要精疲力竭。单这一点还可能引起观众对这人的同情,但那作为他施展淫威的侮辱人的象征——那挥舞呼啸的马鞭在威胁着大家,使我们在屈辱中感到震惊和愤慨,因而一些较温和的感情便无从产生。他稀奇这些吗?盼望也能得到我们的同情吗?一切都想要吗?他说了一句话,露出在这方面还有些艳羡,给我很深的印象。那时正表演到高潮,有个自愿给他作实验的青年,显然是个特别容易接受这类影响的对象,经按摩和呵气后,被奇博拉完全催眠到这样的程度,以致当那昏睡者后颈和两只脚被架在两把椅子的靠背上,奇博拉骑在他身上时,身子甚至还是直挺挺的,不弯下去。穿礼服的驼子蹲在僵硬的形体上,看来既难以令人置信,又丑恶得可怕。观众以为那位充当科学表演的牺牲品的青年一定很痛苦,表示对他同情。“Poveretto!”“可怜的家伙!”有几个好心好意的叫了起来。“Poveretto!”奇博拉尖酸地讥讽说,“找错对象啦,老爷太太们!Sonoioilpoveretto!(可怜的人倒是我呀!)是我在受种种的罪。”观众给他教训了,默不作声。好吧,就算是他为这场表演付出了代价,先前那个小伙子怪可怜地皱缩面孔时,不消说也是他在感到疼痛啦。但看样子却不像,而且,要是一个人承受痛苦,是为了要别人受辱,那谁愿意称他Poveretto呢。
我讲到前头去了,完全没顾到节目的顺序。到今天这位骑士的受难事迹还萦回在我的脑海里,只是忘了先后次序,但这点实际上却无关紧路。我还记得,最受人欢迎的复杂大节目给我的印象,倒还没有一些很快就演完的小节目来得深。我一下就想起年轻人充当坐椅的表演,是由于奇博拉事后讲出指责观众的那番话……有位上了年纪的太太睡在藤椅上,由奇博拉在她心中引起幻觉,好像她到印度去旅行,在昏迷中有声有色地叙述水陆旅途上的奇遇——这节目并没有引起我特别的注意。紧接在休息后面的一个节目,在我看来却比较稀奇:有位身材高大、军人模样的绅士,抬不起胳膊来,而这都是因为驼子曾向他表示他不能这样做,并在空中挥了一下马鞭。蓄着八字胡、衣冠楚楚的上校的面孔,一直到如今还俨然在我眼前。他微笑着咬紧牙根,为了失去的行动自由而挣扎斗争。多么不可思议的一幕戏!他似乎想要做,但却不能;大概连要做什么也身不由己了,意志本身陷于瘫痪,失去了自由,就像我们的征服者曾傲慢地向那位罗马绅士所预言的那样。
我更忘不了安吉欧丽里太太参与的那出戏,真是又动人,又滑稽,又可怕。奇博拉初次大胆地环视大厅时,大概就已发现她在精神上无法抗拒他的威力。他现在竟依靠他不折不扣的魔力,干脆把她从座位上勾引出来,使她离开她坐的那一排,跟着他走去。同时,为了卖弄自己的本领,还嘱咐安吉欧丽里先生呼唤他妻子的乳名,好像要他拿自己的存在和权力孤注一掷,并用丈夫的声管唤醒妻子内心中的一切,保护她的贞洁免受邪术的玷辱。但全是徒然!奇博拉离开这对夫妻有一段距离,挥了一下马鞭,弄得我们的女房东骤然一惊,把脸转向他。这时安吉欧丽里先生已经叫了起来:“索佛罗妮亚!”(我们本来不知道安吉欧丽里太太的名字叫索佛罗妮亚。)他也该叫,因为人人都看得出是危急的时刻了:他妻子的脸仍然一动也不动地朝向邪恶的骑士。他呢,他把马鞭吊在手腕上,用那又长又黄的十个指头,向他勾引的人做出召唤、引诱的动作,一步步后退。安吉欧丽里太太,苍白的面孔闪烁着微光,从座像上站起来,完全转向蛊惑她的人,飘飘然地朝他走去。多么阴森恐怖的景象!她脸上露出患夜游症者的表情,两只胳膊直挺挺的,美丽的手从手腕上略略抬起,脚好像贴在一块儿,缓慢地从椅子上滑下来,凑向她的引诱者……“叫呀,先生,叫呀!”那可怕的人催促说。于是安吉歌丽里先生用细弱的声音叫道:“索佛罗妮亚!”哎哟,他还叫了好几次,在眼看妻子离开他越来越远时时,甚至举起一只手,放在嘴边作话筒,一面叫,一面用另一只手召唤。但爱情和责任感的可怜声音,白白地在那受迷惑的人背后呼喊,安吉欧丽里太太像个夜游症患者那样飘然逝去,糊里糊涂、麻木不仁地进入中间的过道,面向招手的驼子,并沿着过道,走向出口。大家不禁产生这样的印象:只要她的主宰愿意,她无疑会跟他走到世界的尽头去。
“Accidente(真意想不到)!”安吉欧丽里先生喊道,他真害怕了。当他的妻子走到门口时,他甚至跳了起来。但就在这一刹那,骑士好像抛弃了胜利的花冠那样,停止表演。“够了,夫人,谢谢你,”他说,摆出一副矫揉造作的骑士姿态,把胳膊伸向如梦初醒的夫人,带她回到安吉欧丽里先生那儿去。“先生,”奇博拉招呼他说,“这儿是你的夫人!我把她完好如故地交还给你,并向你致意。盼你做大丈夫的,能尽全力保护像这样全心全意属于你的宝贝,并提高警惕,要知道有些势力比理智和贞操还要强大,而它们很少是跟慷慨大方配合在一起的,不会轻易放弃什么。”
可怜的安吉欧丽里先生,秃着头顶,默默不语!看他那副样子,简直没有能力捍卫自己的幸福。不要说这种恫吓之外还加上讥嘲的黑暗势力,即使恶势力没有那么嚣张,恐怕他也对付不了。骑士却庄严、傲慢地在掌声中回到舞台上,他的口才使得掌声加倍地响亮。如果我的印象不错的话,他的威望这时到达这样的程度,甚至可以吩咐观众跳舞——是的,跳舞。这是一本正经说的,而且,还引起一种放任的情绪,一种深更半夜所产生的神魂颠倒的状况,使得观众如醉如迷地遗忘了先前对这讨厌的家伙所采取的批判抗拒态度。诚然,为了巩固自己的统治,他必须顽强地斗争,特别是需要对付那位怀有敌意的年轻罗马绅士,因为后者的反抗精神很可能成为大家的榜样,严重地威胁到这种统治。奇博拉却深知榜样的重要性,善于选择最薄弱的环节作为进攻的对象。他选中了全身曾经给他弄得直挺挺的那个青年,要他带头狂舞一番。这家伙又软弱又顺从,只要魔术师瞧他一眼,就像给雷劈了似的,把上身向后一仰,两手贴在裤子缝上,俨然一副被催眠的军人模样。一看就知道,他容易受人支配,任何怪诞的事,只要吩咐一声就肯做的。而且,他似乎很高兴听命于人,巴不得丢开他那少得可怜的自主能力;他一再自荐作试验的对象,并为随时能失去自己的意识和意志、在这方面起模范作用而引以为荣。现在他又爬上舞台,马鞭只挥了一下,便照骑士的吩咐在上面跳起“舞步”来,那是说,他闭着眼睛,晃着脑袋,得意忘形地挥动瘦弱的四肢向四面八方乱摔乱踢。
这显然很有趣,过了不久,他便找到了舞伴。两个青年,一个穿得相当朴素,一个衣着颇为考究,在他两旁跳起“舞步”来了。就在这时,来自罗马的那位绅士挺身而出,不服气地问道,奇博拉是否能教他跳舞,即使他不愿意。
“即使你不愿意!”奇博拉用我忘不了的口吻回答说。那句可怕的“Anchesenonvuole(即使你不愿意)!”一直到如今还在我耳畔回响。接着便展开了斗争。奇博拉喝了一杯酒,又点燃一支香烟,然后叫罗马人站在中间的过道上,脸朝向出口,自己站在他背后稍远一点的地方,挥了一下马鞭,命令道:“Balla(跳啊)!”他的对手一动也不动。“Balla(跳啊)!”骑士用决断的口吻重复道,挥动了马鞭。我们看见年轻人在衣领下面扭了扭脖子,同时有一只手从手腕上抬起来,一只脚的脚跟向前挪了挪。这种痉挛似的跃跃欲跳的迹象,时而加强,时而消隐下去,如此持续了好久。谁都看得出,魔术师方面必须战胜对方预先就立志要顽抗的决心和他英雄般的顽强精神,这位勇敢的人则下定决心要捍卫人类的荣誉。他浑身抽动,但他不跳舞。表演时间拖得很长,奇博拉不得不分散注意力;有时转向舞台上乱蹦乱跳的小伙子,朝他们挥一下马鞭,使他们驯服,还歪着嘴向观众解释说,这些纵情狂跳的人不管跳多久,事后也不会感到疲乏,因为费力的实际上不是他们,而是他自己。然后,他又把眼光盯在罗马人的后颈上,力图征服那竟敢抗拒他的统治的坚强意志。
可以看出,这坚强的意志在不停的打击和再三的催促之下,动摇起来——我们带着旁观者的几分同情在观看,其中不免掺杂着激动、怜悯和残酷的满足。如果我对这事理解得正确的话,在我看来那位绅士之所以失败,是由于他对战斗采取了消极的姿态。在精神上,人大概不能单靠否定来生活;拒绝做某事,从长远来说,不能成为生活的内容;不愿意做什么,同根本什么都不愿意,也就是仍然去做别人要求做的;这两者相距得那么近,以致自由的思想无法容身。奇博拉,在挥舞马鞭和发号施令之余,所进行的劝说就是根据这种假定出发的;他除了进行所擅长的神秘催眠以外,还企图在心理上迷惑对方。“Balla(跳啊)!”他说。“谁会这样折磨自己?难道你把这种对自己的强制称为自由吗?Unaballatina(只跳一支舞)!你的肢体全都发痒了。要是终于让它们尽情欢乐,该多么好啊!喏,你已经跳了!这已经不是斗争,是享乐啦!”——就这样,在这反抗的人的身上,那抽搐扭动逐渐占了上风,他举起胳膊,抬起膝盖,骤然之间,所有的关节都灵活起来,开始摆动,他跳舞了,而骑士就这样在大众的掌声下把他带上舞台,让他同其余的木偶一块儿跳舞。现在可以端详战败者的面孔,在台上看得很清楚。他翕开了嘴笑,半闭着眼睛,正在“享乐”哩:我们看见他现在显然比先前骄傲固执时好受些,这对我们来说也算是一种安慰吧……
可以说他的“失败”有划时代意义。一切不和谐的气氛都消失了,奇博拉的凯旋达到了顶点。那赛茜的魔棍,那带有爪形把柄、呼呼作响的皮鞭,为所欲为地统治着一切。在我所提到的这个时候,大概已经过了半夜很久,台上约有八到十个人跳舞,即使下面的大厅里,也正展开了各种活动。有一位盎格鲁-撒克逊太太,戴着夹鼻眼镜,露出又长又大的牙齿,虽然奇博拉根本就没理睬她,也从她那一排走了出来,在中间的过道上跳起塔兰泰拉舞来了。这时奇博拉本人则懒洋洋地坐在舞台左边的藤椅上,吞吸香烟,然后傲慢地把烟从丑陋的牙齿间喷出来。他晃着腿,耸耸肩膀,冷笑地望着乱哄哄的大厅,间或略向后仰,对着某一个跳得不够起劲的舞蹈者挥挥马鞭。这时孩子们清醒了。提起孩子们,使我感到惭愧。这儿不是个好地方,至少对于他们。我们一直到现在还没有把他们带走,我只能归咎于那到处泛滥的放任情绪的感染,在深更半夜我们也被它攫住。现在反正都一样了。而且,谢天谢地,他们还不明白这场演出中有什么丑恶的东西。天真的孩子们一再表示喜出望外,因为他们竟被允许观看这样的魔术表演。他们间或在我们膝上睡一刻钟,现在正涨红了两颊,惺忪的眼睛看到魔术师使许多人乱蹦乱跳,便从心底笑出来。他们没料想到会那么有趣,只要有人拍掌,笨拙的手儿也就兴高采烈地附和。可是,当奇博拉召唤他们的朋友马里奥的时候——就是“爱斯圭茜多”的那个马藤奥,他们乐得孩子气地从座位上跳跃起来。他召唤马里奥的姿势,就和书本上所写的完全一样:把手伸在鼻子跟前,一会儿举起中指,一会儿把它弯成钩子形状。
马里奥服从了。我到现在似乎还看见他怎样爬上梯阶,走向那位骑士,而后者只顾不停地用手指怪模怪样地招引他。年轻人曾踌躇了片刻,这点我也记得很清楚。整个晚上,他要么交叉着胳膊,要么两手插在上衣口袋里,站在我们左面靠边上的过道里,倚在一根柱子上,也就是在头发梳得像个武士一样的小伙子附近。我们看见他一直注意地看表演,但并不很兴奋,天晓得他看明白了多少。最后甚至要他亲自参加。他显然感到不自在。可是,他毕竟听从了奇博拉的召唤,这点也是可以理解的。他的职业使他这样;况且要一个朴实的小伙子拒绝服从像奇博拉此时此刻那样显赫人物的召唤,从心理上说简直不可能。不管他愿不愿意,他只好离开那柱子。站在他前面的观众,回头看了看,给他让路。他谢了谢,爬上梯阶,噘起的嘴唇露出勉强的微笑。
请您想象一个约莫二十岁的青年,个子矮壮,头发剪得短短的,额头较低,眼皮又厚又沉,眼珠灰蒙蒙的,灰色中还杂有绿色和黄色。这点我知道得很清楚,因为我们曾时常同他攀谈。上半个脸上长着个布满雀斑的扁鼻子,它没有长着一对厚嘴唇的下半个脸那么突出。说话时,嘴唇间露出两排湿漉漉的牙齿。这对厚嘴唇,加上几乎被遮盖的眼睛,使得他脸上露出一种原始的忧郁表情,而我们也因此对马里奥一直颇有好感。他神情中丝毫没有粗鲁的成分;他那双异常狭长细腻的手,就已否定了这点。这双手甚至在南方人当中,也显得高贵漂亮,谁都愿意让这双手来服侍。
我们了解的只是这个人的外貌,并没有同他个人结识——如果允许我作这种区别的话。我们几乎天天看见他,对他那种想入非非的样子有所偏爱。他时常出神,然后为了纠正片刻的疏忽,突然变得很殷勤;而这种殷勤是严肃的——最多由于孩子们的关系会微笑一下——,他的脸并不是阴沉沉的,但也不是献媚讨好,不是有意要亲切一番,或者更确切地说:是因为明知不可能逗人喜欢,就干脆不作出亲切的姿态。他的形象无论如何也会留在我们的心目中;旅途上一些平凡的见闻,往往会记得牢牢的,许多显赫的事物反而会被遗忘。至于他的家境如何,我们只知道他父亲是市政府里的一个卑微的抄写员,母亲替人洗衣服。
他现在穿的褪色的上衣,没有当侍者时穿的白上装合身。这上衣是薄条子布缝成的,没有领子,脖子上围一条色彩鲜艳的绸巾,上衣就扣在它的末端上。他登上舞台,走到奇博拉跟前,但后者仍不停地用鼻子前的钩形手指招引。马里奥只得凑近一些,站在那神气活现的人的腿旁,贴近藤椅。奇博拉叉开两肘,抓住他,把他转过来,让我们看见他的脸,然后懒散、高傲、得意地把他从头到脚端详了一番。
“怎么啦,ragazzomio(我的孩子)?”他说。“我们怎么这样迟才相识呢?不过,请相信我,我早就跟你交朋友啦……是呀,我早就注意到你,看见你确实有一些杰出的特长。我怎么会忘记你呢?这样忙,你知道……告诉我呀,你叫什么?我只要知道名字。”
“我叫马里奥,”年轻人小声回答说。
“啊,马里奥,很好。是有这种名字。这名字很常见。是个古老的名字,像这样的名字保存了祖国的光荣传统。妙极啦!Salve(敬礼)!”于是他歪着肩膀,斜伸出摊平的手掌,行了个罗马礼。他可能有些醉了,那也不足怪;但他还是像先前那样,字眼咬得清楚,话说得流利,只是现在不论谈吐或举止,都有些装腔作势,更是得意忘形,妄自尊大。
“那末,马里奥老弟,”他继续说,“你今晚来了,可真好,而且围了那么漂亮的围巾,不仅跟你的脸色十分相称,还为你在姑娘们面前增光不少,托勒迪维纳的那些迷人的姑娘们……”
从站座那儿,就是从马里奥先前站的附近地方,传来了笑声——笑声是头发梳得像个武士一样的小伙子发出的。他站在那儿,肩上挂着短外套,哈哈大笑,笑得相当粗鲁,还含有讥讽。
马里奥好像是耸了耸肩膀。反正是他动了动。可能是打个战栗,而耸肩膀只是事后的一种掩饰而已,表示对围巾和女性都漠不关心。
骑士向台下瞟了一眼。
“那个家伙我们才不睬哩,”他说,“他妒忌你。这大概是因为你的围巾在姑娘们当中很吃香,要么是因为我们俩在台上谈得那么投机,你和我……他还要闹,就提醒他肚子痛。那丝毫不费力气。讲讲,马里奥,今天晚上你是来玩玩的……白天你在杂货铺接待顾客,是吧?”
“在咖啡馆里,”小伙子纠正道。
“原来是在咖啡馆里!奇博拉居然猜错了一次。你是侍者,是酒保,是甘尼美——妙不可言,又使我想起一个典故——salvietta(餐巾)!”骑士说着再一次伸出胳膊行礼,逗观众发笑。
马里奥也笑了笑。他公正地补充道,“过去我曾在波多克莱门特的一家店里服务过一个时候。”他这项声明,恐怕是出于人们共同有的一种愿望,那就是设法帮助一个预言圆场,让它兑现。
“可不是吗!是在杂货铺里!”
“那儿也卖梳子和刷子,”马里奥闪烁其词地回答。
“我不是说过吗,你并不一直当甘尼美,拿餐巾侍候人!就算奇博拉偶尔猜不准,也是为了引起对方的信任。说呀,你信任我吗?”
模棱两可的动作。
“这是承认一半,”骑士肯定地说。“毫无疑问,你的信任不易取得。即使我也不易取得,这点我看得出。我发现你脸上有一种苦闷、忧郁的神情,untrattodimalinconia(一种忧伤的特征)……告诉我,”他说着抓住马里奥的手,“你有心事吗?”
“Nossignore(没有,先生)!”马里奥连忙肯定地回答。
“你有心事,”魔术师坚持说,用确凿的语气盛气凌人地压倒他。“难道我看不出吗?你甭想欺骗奇博拉!当然是娘儿们啰,是一个姑娘。你为爱情而伤心。”
马里奥拚命摇头。这时,在我们旁边,小伙子的粗鲁笑声又发作起来。骑士伸长脖子听了听。他的眼光在空中扫来扫去,但耳朵朝向笑的人,然后半朝着后面,向那群舞蹈者劈劈啪啪地挥动马鞭,免得他们泄气——在同马里奥谈话的期间,他已经像这样挥过一两次马鞭了。就在这时候,他的同伴差些儿逃跑了:马里奥突然打了个战栗,转过身去,奔向台阶。他的眼睛通红。奇博拉恰好还来得及止住他。
“站住!”他说。“岂有此理。你打算在最美妙的时刻或最美妙的时刻即将到来时溜掉吗,甘尼美?留在这儿,我答应让你痛快一番。我一定使你相信,伤心完全没道理。那个姑娘,你认识她,还有别人也认识,她……她叫什么名字?等着!我从你眼睛里念出这名字,它飘到我舌尖上来,而且我看得出你也正打算说出……”
“茜维丝塔!”那小伙子在台下大叫大嚷。
骑士丝毫没有动声色。
“居然有这种多嘴的人?”他问,往台下连看都不看一眼,好像继续跟马里奥在谈心,没有人打断他的话似的。“居然有这种七嘴八舌的公鸡,不管是不是时候,就乱啼起来。他从咱们俩的嘴里夺去了那个名字,还自以为对这名字有什么特权,这自负的家伙!让他去吧。至于茜维丝塔呢,你的茜维丝塔,啊,说呀,她可真是个了不起的姑娘,是吧?!是个不折不扣的宝贝儿!她那么逗人喜爱,只要看见她走路、呼吸、嬉笑,心就停下来不跳。她洗衣服时,把头向后一耸,撇开额头上的鬈发,那时她丰满的胳膊多美呀!简直是仙女下凡。”
马里奥盯着他看,头略向前倾。他似乎把自己的处境和观众都忘掉了。眼珠四周的红斑点扩大了,看来好像是画上去的一样。我很少看见过这种样子。他的厚嘴唇微启着。
“她使你伤心,这位仙女,”奇博拉继续说,“或者,更准确地说,你为她而伤心……其中倒有些区别,我亲爱的,关键性的区别。请相信我!爱情中难免产生误会,可以说再没有比爱情中更容易产生误会的了。你可能以为,奇博拉根本不懂什么是爱情,他身上有点缺陷呀!不,他懂得很多对爱情的认识既渊博又透彻,听听他讲爱情方面的事是很有益的。不过,让我们暂且忘掉奇博拉吧,干脆就别提起他,我们只想茜维丝塔,想那迷人的茜维丝塔吧!怎么?她不爱你而偏爱那只啼叫的公鸡,逗得他咧开了嘴笑,害得你暗中掉泪?她不爱你这个多愁善感的小伙子?那不大可能,简直不可能,我们知道得更清楚——奇博拉和她。你瞧,倘若我处于她的地位,要我在那笨手笨脚的蠢货、那无赖、那废物,和马里奥之间选择——位手持餐巾的骑士,他奔忙于贵人当中,为外宾熟练地端上点心和冷饮,他还热烈、诚恳地爱着我——坦白说,让我的芳心作出决定要把自己献给谁,这并不困难,其实我早就羞答答地把心儿许给唯一的一个人了。是时候了,应该让我的意中人看见和明白!是时候了,应该让你看见和认识我,马里奥,亲爱的……说呀,我是谁?”
那骗子挤眉弄眼的样子,实在令人恶心,两个歪肩膀风骚地扭来扭去,萎靡的眼睛频频送秋波,娇媚的微笑露出两排蛀牙。可是,在他甜言蜜语时,我们的马里奥怎么啦?我说出来便感到沉重,就像看见时感到沉重一样;那是内心最深处的暴露,是绝望而又狂喜的爱情的公开展示。他两手交叉在嘴前,肩膀随着剧烈的呼吸而起伏。他快乐得简直不相信耳闻目见,却忘了一桩事,那就是正好不应该相信。“茜维丝塔!”他情不自禁地从心底里小声说出来。
“吻我!”驼子说。“请你相信,你是可以吻的!我爱你。吻我这儿。”他叉开胳膊,摊开手,撒开小指,用食指尖指了指自己面颊贴近嘴的地方。于是马里奥就弯下身子,吻了一下。
大厅里鸦雀无声。这一刹那——马里奥最幸福的一刹那——是多么滑稽、可怕和紧张。就在这不幸的一刹那间,当幸福和幻觉交错在一起强加于整个知觉的时候,不是在一开始,而是在马里奥的嘴唇又可悲又滑稽地接触到那骗取温存的丑恶皮肉以后,紧张等待的观众唯一听到的,是从我们左边的小伙子嘴里爆发出来的笑声。这是一种幸灾乐祸的残酷笑声,可是,我大概没有听错吧,其中带有对醉梦中受愚弄的人的一丝同情,同魔术师曾经驳斥并据为己有的那个呼声“Poveretto(可怜的人)”有着一点共鸣。
就在这时,当笑声还在发作的时候,那在台上受到抚爱的人,在下面靠椅腿的地方,挥了一下马鞭。马里奥醒了过来,向前一冲,又缩了回去。他身子向后仰,瞪着眼睛,呆立了片刻,两手合起来,按住被玷污的嘴唇,然后用指节骨接连敲了几下两边的太阳穴,便转过身,在观众欢呼拍掌声中冲下台阶。奇博拉两手合在膝上,抖动着肩膀,笑个不停。到了台下,马里奥狂奔着,突然叉开两腿,转过身来,举起一只胳膊,猛然之间,震耳欲聋的两声巨响压倒了掌声和笑声。
周围立刻变得静悄悄的,甚至蹦跳的家伙们也静止了,莫名其妙地瞪着眼睛看。奇博拉一跃就从椅子上跳了起来。他站着,胳膊向两旁伸出,作出招架的样子,好像要嚷着说:“停住!静下来!都给我滚开!怎么啦?”但他立刻又萎靡地倒回椅子上去,脑袋无力地垂在胸前,接着便从椅子侧面跌在地板上,一动也不动地躺在那儿,无疑是乱掷在一起的一堆衣服和歪斜的骸骨。
骚乱无休无止。女士们打着颤,把脸藏在男伴的怀里。有人叫医生,有人叫警察。许多人冲上舞台。有些人一窝蜂地扑在马里奥身上,解除他的武装,夺去他那简直不像手枪的、晦暗色金属制成的小武器。这东西吊在他手里,枪管短得简直看不见,却在命运的播弄下对着一个意外的、不可知的方向瞄去。
我们终于把孩子们带走了,领着他们走向出口,半路上还碰见一对进来的警察。“那就是结局吗?”孩子们想要知道,为的是可以放心回去……“是的,那就是结局,”我们肯定地说。多么可怕的结局,多么阴森的结局。可是,在过去和现在我都不能不觉得,这也是个解救人的结局!
(刘德中译)
[[猫 - 伊恩·麦克尤恩 |https://www.kanunu8.com/files/little/2011/01-24-1301.html]]
=========================
<>
猫
来源: 作者:伊恩·麦克尤恩 发布时间:2011-01-24
[[伊恩·麦克尤恩]]著
孙仲旭译
-----
彼得早上醒来后,总是闭着眼睛,直到回答了两个简单的问题之后才睁开,这两个问题总是按照同样顺序摆在他面前。第一个问题:我是谁?噢,对,彼得,年龄十岁半。然后,他的眼睛还没睁开,第二个问题又来了:今天星期几?那么,就有这样一项事实,像座大山一样实实在在、不可移动的事实:星期二,还得去上学。然后,他会把毯子拉得盖住头,更深地钻进他自己暖热的地方,让友好的黑暗吞没他。他几乎可以装作自己不存在,但是知道他得强迫自己出来。全世界都认可这天是星期二,地球本身飞驰着经过冷冷的宇宙,一边旋转,一边绕着太阳转,把每个人都带到了星期二,无论彼得、他的父母还是政府,都根本不可能改变这项事实。他得起床,否则会耽误坐车而迟到,惹上麻烦。
真是太残酷了,他要把自己暖和而且犯困的身体拖出窝,摸索着找衣服,心里也知道再过不到一个小时,他就会哆嗦着到了车站。电视上的天气预报员说过,这是十五年来最冷的冬天。冷,但是不好玩。没下雪,没下霜,甚至没有结冰的水洼可以在上面溜冰。只是寒冷和灰白色,还有刺骨的寒风从窗户上的一道缝吹进彼得的房间。有时候在他看来,他这辈子做过和将要做的事,只是醒来,起床,去上学。想到其他所有人——包括大人——都得在冬天早上天麻麻亮就起床。要是他们都赞成停下来该有多好,那么他也可以停下来。可是地球照样转下去,星期一,星期二,星期三,周而复始,每个人都照样得起床。
厨房有点像是从他的床铺到外面广阔世界之间的中途客栈。这里空气滞重,有烤面包片的烟、水壶的水汽和火腿味。本来是全家一起吃早餐,但是他们四个人同时坐下来的机会很少。彼得的父母都要上班,总是有人慌乱地绕着桌子跑,寻找一份不见了的报纸,要么是一本约会记事本,要么是一只鞋子,你只能炉子上有什么就拿什么,并给自己找个地方。
这儿暖和,几乎跟床上一样暖和,可是不如那里平静,耳畔尽是伪装成问话的责备。
谁喂的猫?
你什么时候回来?
那项作业你做完了吗?
谁拿了我的公文包?
随着一分钟一分钟过去,混乱和急切程度又加剧了。家里有条规矩,厨房收拾好大家才能出门。有时候正把煎锅里的东西倒进猫食碗时,你得去抢到一条熏肉,煎锅就嘶嘶响着放进洗餐具的水里。家里四个人前后左右地跑,拿着脏盘子和燕麦片盒,互相撞在一起,总是有人在嘟囔,我要晚了,我要晚了,这个星期第三次了!
然而事实上,家里还有第五位成员从不慌张,对这番忙乱视而不见。他四肢摊开,卧在暖气片上方的一块搁板上,半闭着眼睛,惟一能看出他还活着的,是他偶尔会打个呵欠,那是个侮辱性的大呵欠,嘴巴张得能看到干净的粉红色舌头。到最后他又闭上嘴巴时,舒服地打一个颤,从胡子传到尾巴:猫儿威廉准备开始度过这一天了。
彼得抓过书包,在跑出家门前最后扫一眼时,看到的总是威廉。他头枕在一个爪子上,另一只爪子随意地垂在架子边上,在升腾的温暖中一探一探的。现在,滑稽的人类快走了,猫可以打上几个小时的盹。彼得迈出家门,走进寒冷刺骨的北风中时,想到一只打盹的猫,让他感觉很痛苦。
把一只猫当成家里一个真正的成员,你要是感到奇怪,那你应该知道,威廉的岁数比彼得和凯特加起来都大。还是个小猫时,他就认识他们的妈妈了。他跟着她去上了大学,五年后她的婚宴上他也在场。维奥拉·福琼快生第一胎时,有的下午躺在床上,猫儿威廉曾经懒散地卧在她腰部那个又大又圆的隆起上,那就是彼得。生彼得和凯特时,他都是连着失踪了好几天,谁都不知道他去了哪儿,干吗要走。他不出声地观察家庭生活中的一切悲伤和欢乐。他眼看着婴儿变成蹒跚学步的孩子,想提溜着他的耳朵到处去;他还看着蹒跚学步的孩子长成了上学的孩子。那对父母还是狂野的小两口,住一个单间时,他就了解他们。现在他们没那么狂野了,住在他们三居室的房子里。猫儿威廉也没那么狂野了,他不再把老鼠或小鸟带回家放在不知感激的人类面前。他满十四岁后不久,不再打架,也不再自豪地捍卫自己的地盘。邻居有一只年轻的公猫占据了院子,知道老威廉对此完全无能为力,彼得觉得这真是岂有此理。有时,那只公猫从门上的猫洞钻进厨房,吃了威廉的食,而那只老猫则无可奈何地看着。仅仅几年前,没有哪个脑子清醒的猫胆敢往这儿的草坪上踏上一只爪子。
对自己力量不再,威廉肯定也感到难过。他不再跟别的猫在一起,而是独自蹲坐在厨房里,回忆,沉思。尽管他已经十七岁了,但他把自己保持得毛色光滑闪亮,整洁。他几乎全身都是黑色,脚和前胸白得刺眼,尾巴尖上有几个白点。有时候你在坐着时,他会单单过来找你,想了一会儿后,跳上你的膝盖蹲坐在那儿,爪子张开,不眨眼地死死盯着你。接着他有可能耸起头,仍然凝视着你的眼睛,喵了一声,只喵了一声,你知道他在跟你说一句重要而且有智慧的什么话,只是你永远也不可能明白。
冬天的下午,彼得最喜欢的,莫过于踢掉鞋子,躺在客厅里炉火的前面,在猫儿威廉旁边,把脸贴近猫的脸。从软毛下面一个小小的猫脸那儿,支愣出长长的黑毛,形成一个球体,白色的猫须稍稍往下弯着,眉毛像天线一样伸出,淡绿色的眼睛中间,有道竖直的裂缝,像是一扇半掩的门,通向一个彼得永远无法进入的世界,彼得看出这真的有多么不同寻常啊,不像人类,却又多么漂亮。他一走近那只猫,深沉的隆隆作响的呼噜声就会响起,如此低沉有力,让地板也为之振动。彼得知道猫是欢迎他的。
就在这样一个傍晚,刚好是星期二四点钟时,天色已在变暗,窗帘拉上了,灯也打开了,彼得舒服地躺到威廉卧着的地毯上,在亮堂堂的炉火前,火苗卷着一根粗大的榆树木头。刺骨的寒风掠过屋顶,呼啸声从烟囱传下来。彼得不得不和凯特一起从车站冲回来,好暖和身子。这时,他跟他的老朋友安全地待在室内,这位老朋友正装作比现在要小,翻过去仰面朝天,前爪无力地动弹着。他想让人挠胸口。彼得开始用手指轻轻地在他的短毛中间搔动时,隆隆的声音更大了,大得让这只老猫的每根骨头都格格作响。这时,威廉把一只爪子伸向彼得的手指,想把手指往高处拉,彼得由着它引导他的手。
“你想让我搔你的下巴?”他低声说。可是不对,这只猫想让他碰到正好是喉咙根部的地方。彼得感觉那里有个硬硬的东西,碰到时,它往这边那边动,有东西埋在毛里。为了细看一眼,彼得用肘部撑起身。他分开软毛,一开始,他还以为看到的是一件饰物,一块小小的银牌子。可是没有链子,他捅捅这样东西,盯着它看,看出根本不是金属,而是块磨得溜光的骨头,椭圆形,中间磨平了,最古怪的是,它贴在猫儿威廉的皮肤上。他用食指和拇指捏着这片骨头,觉得很顺手。他捏紧拉了一下,猫儿的呼噜声更大了。彼得再拉,往下拉,这次,他感到拉动了。
他低头往软毛中间看,一面用指尖分开软毛,他看到这只猫的皮肤上开了个小口子,就好像他手里捏着的是拉链柄。他又拉,这时出现一道两英寸长的黑色开口。猫儿威廉的呼噜声就是从那儿传出来的。彼得想,也许我能看到他的心脏跳动。有只爪子又轻轻地推他手指,猫儿威廉想让他继续。
他也这样做了。他把这只猫从头到尾全拉开了。彼得想把皮肤拨开往里面看,可是他不想显得太好奇,正要大声叫凯特,这时猫的身子里边有动静,从软毛中间的口子里,透出一道粉红色的暗淡光亮,越来越亮。突然,从猫儿威廉里爬出来,嗯,一样东西,一种生物。可是彼得拿不准是不是真的能摸到它,因为它好像完全由光组成。尽管它没有猫须或尾巴,不发出呼噜声,甚至不长毛,也没有四条腿,但是它浑身上下好像都在说“猫”,是这个字最精粹的部分,概念的核心。它由粉红和紫色光安静、优雅、弯曲有致地裹在一起,这时正从猫的身子里爬出来。
“你肯定是威廉的灵魂。”彼得大声说,“要么你是鬼?”
那个光亮没发出声音,但是它听懂了。它好像要说——并非真的吐出话语——灵魂或鬼,都是,而且远不止如此。
完全从猫身子里出来后——猫还仰卧在炉火前面——猫的灵魂飘到空中,浮到彼得的肩膀那里停住了。彼得没有害怕。他感到那个灵魂的光照在他脸上,然后到了他的脑袋后边,看不到了。他感觉它碰了他的脖子一下,一波温暖的震颤感掠过他的背部。猫的灵魂抓住他脊柱最顶处的一个圆形把手之类的东西往下拉,一直顺着他的背部拉下来。他全身都打开后,感觉到屋里的冷空气侵扰了他体内的暖意。
爬出自己的身体,这古怪之极,只是迈步出去,撇下你的身体躺在地毯上,就像刚刚脱下的一件衬衫。彼得看到自己的光亮,是紫色加最纯的白色。两个灵魂悬浮在空中,面对面。这时彼得突然知道他想干吗,他必须要干吗。他飘向猫儿威廉,停在空中。那个躯体还开着口,就像一扇门,看着很诱人,让人很想一试。他降下来,走了进去。把自己装扮成一只猫多棒啊。并不像他原来所想,穿上会嘎吱嘎吱响,而是里面又干又暖。他仰面躺着,把胳膊伸进威廉的前腿,然后扭动着把腿伸进威廉的后腿。他的头在猫头里面严丝合缝。他一眼扫过去,看到自己的身体,刚好看到猫儿威廉的灵魂消失在里面。
彼得用爪子很容易就把自己拉上了,站起来走了几步。用四个软软的白色爪子走路,多过瘾啊。他能看到自己的猫须从脸边支楞开去,也感觉到自己的尾巴在身后卷着。他脚步走得轻,他的软毛就像最舒服的旧的套头羊毛衫。随着他当猫越当越快活,他心花怒放,喉咙深处,发麻的感觉越来越强烈,他居然能听到自己的声音:彼得在发出呼噜声,他是猫儿彼得,在那边的,是男孩威廉。
那个男孩站起来伸了个懒腰,然后一句话也没跟脚边那只猫说,就快步走出客厅。
“妈,”彼得听到他以前的身体在厨房里叫,“我饿了,晚上吃什么?”
那天晚上,彼得心里太不平静,太激动了,猫性太足,睡不着。快到十点钟时,他从猫洞溜出去。凛烈的夜风刮不透他厚厚的软毛外衣。他无声无息地轻轻走到院墙那儿。墙耸立在他面前,可是他动作优美地轻轻一纵就上去了,他在巡视他的领地。去查看黑暗的角落,感受吹在他的猫须上的夜间空气的每一丝颤动。午夜时分,有只狐狸从院子里的小路走来在垃圾桶里翻拣,他自己却是隐身的,感觉多么惬意啊。他察觉到周围有别的猫,有的是本地的,有的从很远的地方来,在忙着干夜里要干的事,赶路。狐狸来过之后,有只小斑猫想进院子,彼得嘶了一声,还甩尾巴,向他发出警告。那个小家伙惊叫一声跑掉了,这让彼得在心里发出呼噜声。
之后不久,他在温室那边的高墙上巡逻时,跟另外一只猫狭路相逢,这个闯入者更危险。它浑身都是黑的,所以彼得没能早点看到。它就是邻居那只公猫,一只健壮的家伙,块头几乎是彼得的两倍大,脖子粗,四条腿又长又结实。彼得想也不想地弓起背,乍起身上的毛,好让自己显得大个儿。
“嗨,小猫,”他发出嘶嘶的声音,“这是我的墙,你上来了。”
那只黑猫看样子吃了一惊,它露出微笑。“以前是你的,老爷爷,现在你想怎么着?”
“滚蛋,趁我还没把你扔下去。”彼得感觉自己很强壮,让他惊奇。这是他的墙,他的院子,他要做的,就是把不友好的猫赶走。
黑猫又露出微笑,冷冷地说:“老爷爷你听好,这墙已经好久不是你的了。我要走过去,给我闪开,要不我扯掉你的毛。”
彼得寸步不让。“你这个小把戏,再敢走一步,我会把你的胡子缠到你的脖子上。”
黑猫不屑地长笑一声,可是他没有再往前走一步。这一带的猫从黑地里凑过来围观,彼得听到它们说话的声音。
打架?
打架!
老家伙肯定是疯了!
他足足有十七岁了呀。
黑猫弓起有力的脊背,又低吼了一声,是可怕的上扬声调。
彼得想保持语气平静,可是他说话夹杂了嘶嘶的声音。“没有我的允许,你不能在这儿抄近路。”
黑猫眨了眨眼睛。它尖声大笑,也是开战的叫声,它肥脖子上的肌肉随之抖动。
对面墙头上,整个猫群我最喜欢。之发出激动的呻吟声,来的猫越来越多。
“比尔这家伙气坏了。”
“他想打架选错了对象。”
“听着,你这个没牙的老绵羊。”黑猫说话也带着嘶嘶声,但比彼得的声音穿透力强得多。“我是这儿的老大,不是吗?”
黑猫向猫群半转过身子,猫群低声附和。彼得感觉听上去,观看的那些猫说得并不积极。
“我给你的建议,”黑猫又说,“就是躲到一边,要不我把你的五脏六腑扯出来扔到草坪上。”
彼得知道自己已经做过了头,没有退路了。他张开爪子牢牢站在墙头。“你这个肥老鼠!你给我听好了,这是我的墙头。你只不过是一条病狗拉的软狗屎!”
黑猫倒抽一口冷气,猫群里响起窃笑。彼得一直是个很有礼貌的男孩,脱口说出这些侮辱性的话,真是太爽了。
“你会给鸟儿当早餐。”黑猫警告道,然后往前迈了一步。彼得深吸一口气。为了老威廉,他得打赢。他正想到这儿,黑猫的一只爪子猛地一下挠向他的脸。彼得的身体是一只老猫,可是他有一个小男孩的头脑。他躲开了,感觉到那只爪子和张开的恶狠狠的指甲嗖的一声,在他耳朵上方掠过。他正好看到那只猫暂时只有三条腿支撑着身子。他马上纵身向前,用两只前爪狠狠推了那只公猫的胸口一下。猫打架时,不会用上这种动作,那只猫老大猝不及防,骇得大叫一声,往后滑了一下,脚步不稳,翻下墙,头朝下砸穿了下面的暖房。坠落声、碎玻璃的脆响以及打碎花盆的更似土块发出的哗拉声刺破了冰冷的夜空,然后一片沉寂。猫群一片哑然,从它们待着的墙头上往下看。他们听到有动静,然后是一声呻吟。接着,在黑暗里勉强能认出是那只黑猫的身影,在跛着脚走过草坪。它们听到它在嘟囔:
“不公平。用爪子和牙齿,行,可是那样推一下,不公平。”
“下一回,”彼得对着下面喊道,“你得先经过我同意。”
黑猫没答话,可是从它退却的样子和跛着脚的身形来看,显然它是听明白了。
第二天早上,彼得卧在暖气片上方的搁板上,头枕着一个爪子,其他三只爪子在升腾的热气中随意耷拉着。在他周围,大家都在赶时间,乱作一团。凯特找不到书包,粥煮糊了,福琼先生情绪不好,因为咖啡喝完了,而他需要三杯浓浓的咖啡,才能开始一天的生活。厨房里杂乱不堪,杂乱不堪的东西之上,笼罩着粥煮糊的烟雾。晚了,晚了,晚了!
彼得把尾巴卷起来围着他的后爪,尽量让自己发出的呼噜声别太大了。厨房里的那一头,是他以前的身体,里面是猫儿威廉,那个男孩得去上学。男孩威廉看样子迷迷糊糊的。他穿上外套,准备好出门,可是他只穿了一只鞋,另外一只怎么也找不到。“妈,”他不住声地哀叫,“我的鞋呢?”可是福琼太太在走廊上,正在电话上跟别人吵什么。
猫儿彼得半闭上眼睛。他打架胜利后,感到精疲力竭。很快全家人都会出门,房子里会静下来。暖气片变凉后,他会溜达到楼上,找张最舒服的床。为了回味过去,他会选择自己的床。
这一天正像他希望的那样过去了。打盹,舔食了一盘子牛奶,再去打盹,用力嚼着吃了点罐头猫食,那并不像闻上去那么难吃——很像是没有土豆泥的肉馅土豆泥饼,然后再打盹。他还没注意到,外面的天空变暗,小孩们放学回来了。在教室上课,在操场上打闹,这样过了一天后,男孩威廉看样子累坏了。男孩猫和猫男孩一起躺在客厅壁炉前。猫儿彼得心想,让仅仅一天前还属于他的一只手抚摸自己,这真是古怪之极。他想知道男孩威廉对他的新生活开不开心,要上学,坐公共汽车,有妹妹、妈妈和爸爸,可是从那个男孩的脸上,他什么也看不出来,那张脸光洁无毛,没有猫须,红扑扑的,眼睛圆滚滚的,几乎不可能看出眼神里有什么。
那天晚上晚些时候,彼得溜达进了凯特的房间,跟平常一样,她在跟她的玩具娃娃说话,给它们上地理课。从它们不变的表情来看,显然它们对世界上最长的河流没什么兴趣。彼得跳到她腿上,她开始心不在焉地挠他。要是她知道在她腿上的动物就是她哥哥该有多好啊。彼得躺下来发出了呼噜声。凯特开始列出来她能想起来的每一个首都。真是枯燥之极,他要想再睡着,需要的就是听到这些。他的眼睛已经闭上了,这时哗啦一声门开了,男孩威廉大步走进来。
“嗨,彼得,”凯特说,“你没敲门。”
可是她的哥哥猫没理会。他走过来粗鲁地抱起她的猫哥哥就匆忙走了。彼得不喜欢被抱着,对于他这只上年纪的猫,这样没面子。他使劲想挣脱,可是快步下楼时,男孩威廉只是抱得更紧了。“嘘,”他说,“我们的时间不多了。”
威廉把猫抱进客厅,把他放下。
“别动,”那个男孩悄声说,“我怎么说你怎么做。翻过去,肚子朝上。”
猫儿彼得没什么选择,因为那个男孩一只手按着他,另一只手在他的软毛里摸索。他找到那块磨得光溜溜的骨头,把它往下拉。彼得感觉到冷空气进入他的体内。他从猫的身子里出来,那个男孩伸手在自己的脖子后面找东西。这时,一道真正属于猫的粉红和紫色光从男孩的身体里滑脱出来。有一会儿,两个灵魂——猫的和人类的——悬浮在空中面对面了,就像的士准备拉着乘客开走。空气里有种伤感。
尽管猫的灵魂没说话,可是彼得感觉到它在说:“我得回去了,”它说,“我要开始下一场冒险。谢谢你让我当一个男孩,我已经学到了很多东西,以后会对我有用。但是最重要的,是替我打了最后一架。”
彼得正要开口,可是猫的灵魂正在钻回自己的身体。
“时间紧迫。”那个灵魂好像在说,同时,那个粉红和紫色都有的光亮正在把自己收进猫的软毛里。彼得飘向自己的身体,从脊柱最高处的背部滑了进去。
一开始感觉很不自在。这个身体不是很合身,他站起来时两腿打战,就像穿一双大了足足四码的橡胶靴子。也许自从他上次用过以来,他的身体又长大了,躺下来一会儿让他感觉舒服。他这样做的时候,猫儿威廉转过身子很慢而且动作僵硬地走出客厅,一眼也没看他。
彼得躺在那里,一边尽量习惯他的旧身体时,他留意到一件有趣的事:火苗还在卷着同一根榆树木头。他望向窗外,天色正在转暗。没到晚上,还是黄昏。从椅子旁边放着的报纸来看,还是星期二。还有一件奇怪的事:他妹妹哭着跑进客厅,跟着来的是他的父母,脸色阴沉。
“噢,彼得。”他妹妹哭着说,“出了件可怕的事。”
“是猫儿威廉。”他妈妈解释道,“恐怕他……”
“哦,威廉!”凯特的嚎啕声盖过了她妈妈的话。
“他只是走进厨房,”他的爸爸说,“爬到他最喜欢的暖气片上面的搁板上,合上眼睛就……死了。”
“他根本没怎么受罪。”维奥拉安慰他们说。
凯特还在哭。彼得意识到他的父母正在不安地看着他,在等着看他听了这个消息有什么反应。一家人中,数他跟这只猫的关系最亲密。
“他十七岁了。”托马斯·福琼说,“他这辈子活得够意思了。”
“他这一辈子活得不错。”维奥拉·福琼说。
彼得慢慢地站起身,两条腿好像支撑不住他。
“对,”他终于开口了,“他现在要开始另外一场冒险了。”
第二天上午,他们把威廉埋在院子最南面的地方。彼得用棍子做了个十字架,凯特用月桂枝叶做了个桂冠。尽管他们都要上学或者上班迟到,但是全家一起到了墓坑边上。最后几锨土是两个孩子洒上的。就在那时,一个发出粉红和紫色光芒的球体从地里升起并悬在空中。
“看!”彼得用手指着说。
“看什么?”
“就在那儿,就在你们面前。”
“彼得,你在说什么?”
“他又在做白日梦呢。”
那个光亮又飘得高了,直到跟彼得的头一样高。当然它没有开口说话,那不可能,但彼得还是听到了。
“再见,彼得。”它说,同时开始在他眼前消失。“再见,再次感谢你。”
没有人是一个岛──想起了痖弦的「一九八○年」-余光中
========================
没有人是一个岛──想起了痖弦的「一九八○年」-[[余光中]]
-----
二十三年以前,一位才华初发的青年诗人,嚮往未来与远方,写了一首乌托邦式的成人童话诗,设想美妙,传诵一时。那首诗叫做「一九八○年」,作者痖弦,当时只有二十五岁。诗的前两段是这样的:
```
老太阳从蓖麻树上漏下来,
那时将是一九八○年。
我们将有一座
费一个春天造成的小木屋,
而且有着童话般红色的顶
而且四周是草坡,牛儿在啮草
而且,在澳洲。
```
当时的戏言,今朝已来到眼前,这已是一九八○年了。不知怎的,近来时常想起痖弦的这首少作。二十多年来,台湾变了很多,世界整个变了,连诗人嚮往的澳洲也变了不少。痖弦,并没有移民去澳洲,将来显然也不会南迁。这些年来,他去过美国、欧洲、印度、南洋,却始终未去澳洲。
倒是我,去过澳洲两个月,彼邦的大城都游历过,至于草坡上的红顶小屋,也似乎见过一些。八年前的今天,我正在雪梨。如果二十五岁的痖弦突然出现在眼前,问我那地方到底如何,我会说:「当然很好,不但袋鼠母子和宝宝熊都很好玩,连三次大战和文革都似乎隔得很远。不但如此,台北盆地正热得要命,还要分区节水,那裏却正是清凉世界,企鹅绅士们都穿得衣冠楚楚,在出席海滨大会。不过,如果我是你,就不会急着搬去那裏,宁可留在台湾。」
一人之梦,他人之魇。少年痖弦心中的那片乐土,在「澳厮」们自己看来,却没有那么美好。远来的和尚会唸经,远方的经也似乎好唸些,其实家家的经都不好唸。
澳洲并不全是草地,反之,浩阔的内陆尽是沙漠,又乾又热,一无可观。我在沙漠的中心,爱丽丝泉,曾经住过一夜。那小镇只有一条街,从这头踱到那头,不过一盏茶的功夫。树影稀疏的街口,外面只有一条灰白的车路,没向万古的荒沙之中。南北两边的海岸,都在一千公里以外,最近的大都市更远达一千五百公里,真是遁世的僻乡了。只是到了夜裏,人籁寂寂,天籁齐歇,像躺在一只坏了的錶裏,横听竖听,都没有声音。要不是袋裏还有张回程的机票,真难相信我还能生还文明。
澳洲的名诗人,我几乎都见过了。侯普赠我的书中,第一首诗便是他的名作「澳大利亚」,劈头第一句便诅咒他的乡土,说它是一片「心死」的大陆,令我大为惊颤。澳洲的大学招不足学生,一来人口原就稀少,二来中学毕业就轻易找到工作。大学教授向我埋怨,说一个月的薪水,百分之四十几都纳了税。雪梨的街头也有不少盗匪,夜行人仍要小心。坎贝拉公园裏,有新几内亚的土人扎营守坐,作独立运动之示威,令陪我走过的澳洲朋友感到尴尬。东北岸外,法国人正在新加里多尼亚岛附近试验核爆,令澳洲青年愤怒示威。谁说南半球见不到蕈状云呢?
如果还有谁对那片「乐土」抱有幻想,他不妨去看看澳洲自製的连续剧「女囚犯」。这一套电视片长达三十集,主要的场景是澳洲一座专关女囚犯的监狱;一个个女犯人的故事,当初如何犯法,如何入狱,后来如何服刑,如何上诉,又如何冤情大白,获释出去,都有生动明快的描写。当然女犯人的结局,不都是欢天喜地走出狱门。也有不幸的一群,或死在牢裏,或放出去后不见容于社会,反觉天地为窄而牢狱为宽,世情太冷,不如狱中友情之温,宁愿再蹈法网,解回旧狱。澳洲原是古时英国流放罪犯之地,幽默的澳洲朋友也不讳言他们是亡命徒流浪汉的后人。也难怪他们的电视界能推出这么一部铁窗生涯的写实杰作。
痖弦的「一九八○年」仍不失为一首可爱的好诗,但毕竟是廿多年前的作品,我敢说作者的少年情怀,如今已不再了。那时台湾的新诗风行着异国情调,不但痖弦的某些少作,就连土生土长的叶珊、陈锦标、陈东阳等的作品也是如此。爱慕异国情调,原是青年人理想主义的一种表现。兼以当时台湾的文化、社会、政治各方面都没有现在这么开放,一切都没有现在这么进步,青年作家们多少都有一点「恐闭症」,所以嚮往外面的世界,也是一种可解的心情,不必动辄说成什么「崇洋」。二十多年下来,我这一辈的心情已经完全相反:以前我们幻想,乐土远在天边,现在大家都已憬然省悟,所谓乐土,岂不正是脚下的这块土地,世界上最美好的岛屿?原则上,澳洲之大,也只是一个岛屿罢了。然则在澳洲和台湾之间,今天的痖弦当然是选择自己的家岛。今天,年轻的一代莫不热烈地拥抱这一片土地和这一个社会,认同乡土,一时蔚为风气,诚然十分可喜。但是我们却不应武断划分,说今日的青年皆是,而往日的青年皆非。其实,今日青年之所以有此心态,一半也是台湾在外交压力下所促成:既然举世都要否定我们,那么大无畏的爱国之士就要堂堂正正地站出来肯定自己。另一半则是因为二一十年来,台湾已经有了显着的进步和繁荣,比起美国来不见得怎么落后,比起中国大陆来却已超前很多,就是这一份「比得起」的信心,令今日的青年有回头肯定自己的依据。
二十多年的留学潮似乎是淡下去了。从远飏外国到奉献本土,我国青年态度的扭传,正是民族得救文化新生的契机。人对社会的要求和奉献,应成正比:要求得高,就应奉献得多;有所奉献,才有权利有所要求。对社会只有奉献而不要求,不要求它变得更合理更进步,那是愚忠。「不问收穫」,是不对的。反之,对社会只有要求而不奉献,那是狂妄与自私。不过留学潮也不是全无正面的意义,因为我们至少了解了西方,而了解西方之长短正所以了解中国,了解中西之异同。「不到黄河心不死」,许多留学生却是「不到纽约心不死」。同时,远飏外国也还有身心之分。有的人身心一起远飏了,从此做外国人,那也乾脆。有的人身在海外而心存本土,地虽偏而心不远,这还是一个正数,不是负数。但是这种人还可分成两类。第一类「心存」的方式,只是对本土的社会提出要求,甚至是苛求,例如「台湾为什么还不像美国」等等,却忘了他自己并未奉献过什么。第二类「心存」的方式,则是奉献,不论那是曾经奉献,正在奉献,或是準备奉献。这种奉献,虽阻隔于地理,却有功于文化。例如萧邦,虽远飏于法国,却以音乐奉献于波兰,然则萧邦在法国,正是波兰的延伸,不是波兰的缩减。「正数」的留学生,都可以作「台湾的延伸」看待。
痖弦也曾经两度留学,但到了一九八○年,却没有像他在早年诗中所预言的,落户在异国。从远飏到回归,正是痖弦这一辈认同台湾的过程,这过程十分重要。时至今日,谁是过客,谁是归人,已经十分清楚。对他这一辈的作家,台湾给他们写作的环境,写作的同伴,出版他们的作品,还给他们一群读者和一些批评家,而这些都是三十年来的中国大陆无法为他们提供的。如果当年痖弦留在故乡河南而未来台湾,现在真很难想像他在哪裏。痖弦属于河南,但是他似乎更属于台湾,当然他完全属于中国。所谓家,不应单指祖传的一块地,更应包括自己耕耘的田。对于在台湾成长的作家,台湾自然就是他们的家。这也许不是「出生权」,却一定是「出力权」。「出力权」,正是「耕者有其田」的意思。「一九八○年」诗末有这么两句:
我说你还赶作什么衣裳呀,
留那么多的明天做什么哩?
这话颇有心理根据。移民到了澳洲,就到了想像中的天堂,但天堂裏的日子其实很闷人,「明天」在天堂裏毫无意义,因为它无须争取。我认为,「桃花源记」裏的生活虽然美满,但如果要我选择,我宁可跟随诸葛亮在西蜀奋斗,因为诸葛亮必须争取明天,但是明天对桃源中人并无意义。
我知道颇有些朋友以台湾为一岛屿而感到孤立、气馁,也听人说过,台湾囿于地理,文学难见伟大的气魄。这话我不服气。岂不见,我们的失败是在大陆,而成功却在海岛?拿破仑生在岛上,也死在岛上,却影响了一代的欧陆。说到文学,莎浮诞生的莱思波斯,萧克利多斯诞生的西西里,都是岛屿,而据说荷马也降世于凯奥司岛。日本和英国不用多说,即以爱尔兰而言,不也出了史威夫特、王尔德、萧伯纳、叶慈、乔艾斯、贝凯特?
苏轼,应该是我国第一位在海岛上写作的大诗人了。他的高见总该值得我们注意。「苏海识余」卷四有这么一则:「东坡在儋耳,因试笔尝自书云:『吾始至海南,环视天水无际,悽然伤之曰:何时得出此岛耶?已而思之,天地在积水中,九州在大瀛海中,中国在少海中,有生孰不在岛者?覆盆水于地,芥浮于水,蚁附于芥,茫然不知所济。少焉水涸,蚁即逕去,见其类,出涕曰:几不复与子相见!岂知俯仰间之有方轨八达之路乎?念此可以一笑。戊寅九月十二日,与客饮薄酒小醉,信笔书此纸。』」
东坡真不愧旷代文豪,虽自称信笔所之,毕竟胸襟开阔,不以岛居为囿,却说「有生孰不在岛者」?髯苏当时的地理观念,竟和今日的实况相合。痖弦当年要去的澳洲,不正是一个特大号的岛吗?亚、非、欧三大洲,也不过合成一个巨岛。想开些,我们这青绿间白的水陆大球,在太空人眷眷回顾之中,不也只是一座太空岛吗?
不过,苏轼的这一番自宽之词,要慰勉我们接受的,只是地理上的囿限,绝非心理上的自蔽。「俯仰间之有方轨八达之路」,他在文末已经说得明白。他的名句「不识庐山真面目,只缘身在此山中」,更点出客观观点的重要。岛屿只是客观的存在,如果我们竟在主观上强调岛屿的地区主义,在情绪上过份排外,甚至在意识上要脱离中国文化的大传统,那就是地理的囿限又加上心理的自蔽,这种趋势却是不健康的。诗人邓约翰的一段布道词,也是汉明威一部小说题名之所本,不妨与苏轼之文并读:「没有人是一个岛,自给自足;每个人都是大陆的一部份,整体的一片段。如果一块土被海浪沖走,则欧洲的损失,正如沖走了一角海岬,沖走了你朋友的田庄或是你自己的田庄。不论谁死了,我都受损,因为我和人类息息相关。所以不要派人去问,丧钟为谁而敲。丧钟为你而敲。」
一九八○年八月四日
<<list-links "[tag[日志]]">>
蒙大拿的迈尔斯城-艾丽丝·门罗
========================
!蒙大拿的迈尔斯城-[[艾丽丝·门罗]]
-----
爸爸扛着淹死男孩的尸体,穿过田野走来。搜索归来的共有好几个男人,不过扛尸体的是我爸。他们全都浑身泥泞,精疲力竭,走路时耷拉着脑袋,好像深感羞耻。狗儿也没精打采,浑身滴答着冰冷的河水。几小时前他们集结出发的时候,狗儿们劲头十足地吠叫着,男人们精神抖擞、意志坚定,整个场面充盈着一种紧绷绷的、难以言喻的激动气氛。大家都知道,很有可能搜到不幸的结果。
男孩叫斯蒂夫·高雷。八岁。他的头发和衣服现在都是泥浆色,沾着枯叶、树枝和杂草。他就像一堆整个冬天都丢在外面的垃圾。他的脸扭向我爸的胸膛,不过我还是能看到一个鼻孔、一只耳朵,塞满绿莹莹的烂泥。
我想不是这样吧。我想我没有真看到这些。或许我看到爸爸扛着他,其他男人跟在后面,还有狗,但我不可能被允许凑那么近,居然能看到鼻孔里的烂泥。想必我是听人谈到这个,想象成自己看到的。我看到他的脸一如既往,只是多了些烂泥—斯蒂夫·高雷熟悉的、瘦精精的、鬼头鬼脑的脸—其实那是不可能的。在水里泡了那么多小时,它应该已经发胀、变形,或许还被泥浆完全覆盖了。
不得不带回这样的消息,这样的证物,给等待的家人,特别是给一个做妈妈的,这足以让搜索者们步履沉重,不过事实上更糟糕。(人们窃窃私语道)不是一般的可怜呐,等着接收斯蒂夫·高雷,对他表示应有的哀悼的,并没有什么妈妈,根本就没什么女人—没有祖母或姨妈,就连姐妹也没有。他爸是个雇工,是个酒鬼但不是醉鬼,是个怪人却并不好玩,不友好但也不惹祸。他成为父亲似乎是个意外,做妈的开溜了,孩子留给他,父子从此生活在一起,好像也纯属偶然。他们住在一幢斜顶灰墙的破烂房子里,仅比小棚子稍好一点—做爸爸的挨到没办法了,总算修了屋顶,在走廊上装了支柱,勉强凑合着用—他们的生活同样七拼八凑,也就是说,差一点就要接受儿童救助了。他们不在一起吃饭,也不给对方做饭,不过吃的总归是有的。有时做爸爸的会给斯蒂夫钱去商店买吃的,也有人看到过斯蒂夫买一些相当正常的东西,比如煎饼粉和通心面晚餐。
我和斯蒂夫·高雷挺熟,对他谈不上喜欢也谈不上不喜欢。他比我大两岁。到了星期六,他会到我们家晃荡,对我做的一切都不屑一顾,但就是不肯从我身边跑开。我每次玩秋千,他肯定要在旁边跃跃欲试,要是我不给他玩,他就跑过来拼命推我,弄得我摇摇晃晃的。他欺负狗。他常让我陷入麻烦—事后看来,我觉得他是不怀好意,故意为之—会挑逗我去做平时根本想不到的事:在土豆只有弹子大小时就挖出来,看看它们长多大了;推倒摞得好好的柴火,堆成一大堆,我们再从上面跳下来。在学校里我们从不跟对方说话。他独来独往,但好像并不在乎。不过,星期六早上,看到他瘦削、冷静的身影从雪松丛中滑过,我就知道我准得出点事,而他正在策划。有时也会一切顺利。我们会扮作牛仔,驯服野马。我们在河边牧场上玩,距离斯蒂夫淹死的地方不远。在一条流到安大略省南部、汇入索津河的无名小河边,我们既是马又是骑手,一边尖叫一边学马叫,既要扑腾蹄子,又要挥舞着树枝做的鞭子。
葬礼在我家举行。斯蒂夫爸爸家没地方容纳那么多人。我记得房间里挤挤挨挨的,不过不记得看到躺在棺材里的斯蒂夫,或者牧师,或者花圈。我记得举着一朵花,一朵白水仙,想必出自什么人在室内催熟的盆栽,因为这会儿树林里连翘、延龄草或金盏花都还没开呢。我和一群孩子站成一排,人手一朵水仙。我们唱儿童赞美诗,有人在我们的钢琴上弹伴奏:“等主回来,快要回来,要收聚他珍宝。”我穿着白色编织长袜,被它们弄得很痒,膝盖和脚踝处都皱巴巴的。袜子黏在我腿上的感觉,与我记忆里的另一种感觉混在一起。说来有点复杂。它与我爸妈有关。它涉及大人们,但主要是我爸妈。我爸爸,也就是扛着斯蒂夫的尸体从河边走回来的人,以及我妈妈,她想必是操办这场葬礼的主力。爸爸穿着他的深蓝色西装,妈妈穿棕色天鹅绒裙子,戴奶油色缎领。他俩肩并肩站着,嘴巴随赞美诗开合,我站在儿童队列里,远远看着他们。我感到一阵强烈的、令人作呕的厌恶之情。儿童有时会对大人产生一种突然的厌恶。瞧那大个头,那粗胖体型,那种得意忘形的力量。那呼吸,那粗皮糙肉,那些毛发,那可怕的分泌物。不过我的感觉更糟。而且随之而来的愤怒之情也谈不上尖锐,与自尊毫无关系。与我终于可以弯腰捡起一块石头砸向斯蒂夫·高雷的时候不同,这种感觉无法释怀。它难以理解,也没法说清,尽管过了一阵,它淡化为一种沉重,又减弱为仅剩的一点余味,一种偶尔泛起的味道—一种微弱的、熟悉的疑虑。
大约二十年之后,1961年,我丈夫安德鲁和我买了一辆全新的汽车,我们的第一辆—也就是说,我俩的第一辆全新的车。一辆莫里斯牛津车,牡蛎色(卖车的人对这颜色有个更动听的叫法)—一辆挺大的小车,有大量空间给我们和两个孩子,六岁的辛西娅和三岁半的梅格。
安德鲁拍了一张我站在车边的照片。我穿着白裤子、黑色高领毛衣,戴着墨镜。我慵懒地靠在车门上,侧着臀部,以便看起来苗条些。
“不错,”安德鲁说,“很棒。看起来像肯尼迪夫人。”或许这整片大陆上,所有黑发、还算苗条的年轻女人,穿得比较时髦的时候或者拍照片时,都会被赞美为像肯尼迪夫人。
安德鲁给我、孩子们、我们的家、我们的花园、我们的远足和我们所拥有的东西拍了好多照片。他冲洗了很多张,仔细贴上标签,寄给他在安大略的妈妈、姨妈和叔叔。他也给我一些照片,让我寄给我爸,他也住在安大略。我寄是寄的,不过没像他那么频繁。安德鲁看到原以为我已寄出的照片还搁在家里,不由得困惑不解,而且很不开心。他一心希望这些记录都传出去。
那年夏天,我们要展示我们自己,而不是照片了。我们打算从眼下住着的温哥华去安大略,后者我们叫作“老家”,要开新车去。路上开五天,到了待上十天,然后再开五天回来。这还是安德鲁头一次有三周的假期。他在加拿大能源公司法务部工作。
一个星期六早上,我们把手提箱、两个热水瓶(一个装咖啡,一个装柠檬水)、水果和三明治、图画书和画画本、蜡笔、画板、驱虫剂、毛衣(以防山中寒冷),还有我们的两个孩子塞进汽车。安德鲁锁上房门,辛西娅一本正经地说:“再见啦,房子。”
梅格说:“再见,房子。”然后她问,“现在我们住哪呢?”
“不是永远再见啦,”辛西娅说,“我们要回来的,妈妈!梅格以为我们永远不回来了!”
“我没有。”梅格踢着我的靠背抗议。
安德鲁和我戴上太阳镜,开车出发了。我们开过狮门大桥,穿过温哥华的主体。我们离开了我们的房子、街区、城市,以及—在华盛顿州和不列颠哥伦比亚的交界点—我们的国家。我们横穿美国,沿最北的路线朝东开,在安大略省的萨尼亚会再次进入加拿大。我也说不清选了这条路线是因为横跨加拿大的公路尚未竣工,还是因为我们想要体验那种滋味:开车横跨一个外国,或者说一个有点外国感的国家—想要那种额外的趣味和冒险感。
我们全都兴致勃勃。安德鲁数度赞美这车。他说,开它的感觉,比开我们的老车,那辆1951年的奥斯汀好多了。后者上坡时速度会可怜地减慢,而且形象像个紧张兮兮的老太婆,安德鲁这么评论道。
“这辆车的形象像什么呢?”辛西娅问。她听我们说话很仔细,喜欢尝试诸如“形象”这样的新词。通常都能用对。
“活泼的,”我说,“有点运动型的。但并不卖弄。”
“它很明智,但是有档次,”安德鲁说,“就像我的形象一样。”
辛西娅想了想,带着一种小心翼翼的得意问道:“那就是说,像你希望你是的样子,对吗,爸爸?”
至于我嘛,我对于离开感到很高兴。我喜欢出发。在自己家里,我好像总想找个地方躲起来—有时是躲开孩子们,不过更多时候是躲开要做的工作、要接的电话,以及邻居的搭讪。我想躲起来,投身于我真正的工作,那有点像是在遥遥召回我自个儿的三魂七魄。我活在困顿中,总找不到想要抓住的东西。但旅行时却是一帆风顺。我可以跟安德鲁说话,跟孩子们聊天,可以看看他们向我指出的各种东西—标牌上的一只猪啊,田里的一匹小马啊,旋转展台上的一辆大众车啊—同时把柠檬水倒进塑料杯。所有这些时刻,魂魄的碎片都飞回我体内各就各位。基本结构于是便成形啦。这让我充满希望,心情愉快。做一个观望者,正是这件事的关键。做一个观望者,而不是守护者。
我们在埃佛瑞特[1]向东拐,爬上卡斯克德山。我在地图上给辛西娅指出我们的路线。我先给她看全美地图,上面也绘出了加拿大的底部。然后我打开要穿过的每个州的地图。华盛顿、爱达荷、蒙大拿、北达科他、明尼苏达、威斯康星。我给她看穿过密歇根湖的虚线,它就是我们要搭的渡船的路线。之后我们会开车穿过密歇根,开到安大略省萨尼亚,那座连接了美国和加拿大的大桥。就到家啦。
梅格也想看。
“你看不懂的。”辛西娅说。不过她还是把道路图册拿到后座。
“靠后坐,”她命令梅格,“坐好,我给你看。”
我听到她给梅格讲解路线,讲得非常精确,和我跟她讲的一样。她知道如何按字母表找到各个州,把所有州的地图都查阅一遍。
“你知道这条线是什么吗?”她说,“它是路。这条线就是我们在开车的路。我们正沿这条线开呢。”
梅格默不作声。
“妈妈,指给我看我们这会儿在哪里。”辛西娅说。
我取过地图,指指穿过山区的路线,她拿回地图册指给梅格看。“看到我们的路在这里歪来歪去的吧?”她说,“它歪来歪去的,因为这里有好多拐弯。这些歪的地方就是拐弯。”她翻了几页纸,等了一会儿。“现在,”她说,“指给我看看我们在哪里。”然后对我嚷道:“妈妈,她懂了!她指出来了!梅格看懂地图了!”
这会儿,我感觉是我们创造了孩子们的个性。我们给她们严格地规定了角色。辛西娅聪明、勤奋、善解人意、懂礼貌、擅长观察。有时我们会开玩笑说,她过于敬业了,一心想成为我们希望她会变成的样子。任何责备或失败,任何冷落,都会深深地影响她。她是个金发白皮肤的孩子,太阳一晒,风一吹,感到得意或者羞耻,都会在皮肤上轻而易举地表现出来。梅格则体格结实、不爱说话—并不叛逆,不过有时挺固执,显得高深莫测。我们觉得她的沉默展示了性格的力量,她的拒绝也被我们视为一种冷静独立的表现。她长着棕色头发,我们把它剪成齐刘海。她的眼睛是浅栗色的,清澈透亮。
我们都非常喜欢这些个性,欣赏着它们的矛盾与确定。我们不喜欢那种沉重兮兮、毫无创造的父母之路。我害怕变成那类母亲—身体肥胖,周遭笼罩着一团羊毛味儿、奶味儿的迷雾,因为负担着各种琐碎杂务而显得大义凛然的。我相信,就是这类母亲没完没了的关注、她们对于承担重负的需求,才导致了绞痛、尿床和哮喘。我喜欢另一类做法—开专栏的职业妈妈们那种开玩笑的绝望和夸张的嘲讽。杂志文章里,小孩一律迷人地自有一套,难以说服,不可思议而又不可战胜。做妈妈的同样才华横溢而不可战胜。我一心想成为的真实生活中的母亲,是会打电话来问“我的小希特勒这会儿是不是碰巧在你家啊”的那种人。她们凌驾于奶味儿迷雾之上,利落地谈笑风生。
我们看到一辆卡车的前厢横放了一只捆着的死鹿。
“有人把它打死了,”辛西娅说,“猎人打鹿。”
“还没到狩猎季,”安德鲁说,“他们没准是在路上撞到了它。看到有鹿出没的标志了吗?”
“要是我们撞到一只的话,我会哭的。”辛西娅严厉地说。
我给孩子们做了花生酱奶油果酱三明治,给我们自己做了鲑鱼蛋黄酱三明治。不过我没放生菜,安德鲁很失望。
“我没有啊。”我说。
“你不能带一点吗?”
“我不能为了做点三明治,就买来一整颗生菜吧,那样太浪费了。”
这是谎言。我其实是忘了。
“加生菜叶会好吃得多。”
“我觉得没那么大区别嘛,”沉默一会儿,我说,“别激动。”
“我没激动。我喜欢三明治里夹生菜。”
“我只是觉得没那么重要嘛。”
“要是我也懒得给油箱加满油,那会怎样?”
“那不是一回事。”
“唱首歌吧。”辛西娅说。她唱了起来:
五只小鸭出门玩,
翻过山,跑得远,
一只小鸭叫,
嘎嘎嘎,
四只小鸭赶紧游回来。
安德鲁捏捏我的手说:“别吵架。”
“你说得对。我该买生菜来着。”
“那没什么大不了的。”
我希望我对安德鲁的感觉能变成一种效劳的、依赖的感情。我甚至试过列出两份清单,一份是我喜欢他的地方,一份是我不喜欢的地方—在亲密生活的熔炉中,我所喜欢的和我所厌恶的事情—仿佛我指望用这个来证明什么,得出这种那种结论。到头来我发现它证明的无非是我早已知晓的事—也就是说,我是个充满矛盾的人—于是半途而废了。有时,他的脚步声都让我感觉专横无比,他的嘴巴显得自鸣得意、挑剔刻薄,而他结实笔直的身体是一道障碍—相当刻意,甚至是尽职的,带着讨厌的男权主义的自鸣得意—挡在我和我生活中各种可能的快乐或轻松之间。旋即,不经意间,他又成了我的好朋友和最重要的伴侣。我体会着他轻灵的骨骼和严肃的思想带来的甜蜜感觉,他充满爱情的脆弱,我想象着那爱比我自己的更加纯净坦荡。我会被他的固执、他一丝不苟的得体深深打动,换个时候又会对此嗤之以鼻。我会思忖,他是多么谦卑啊,扛起这种现成的重担,成了丈夫、父亲、养家的人,相形之下,我实在就是个隐蔽的自我中心的怪物啊。或许不该说隐蔽—至少对他而言不是的。
我们吵到口无遮拦时,会说出我们以为的最丑陋的真相。“我知道你这人骨子里就有点自私,不可信任,”安德鲁有一次说,“我一直就知道。我也明白那就是我爱上你的原因。”
“不错。”我说,既悲哀又有点得意。
“我知道要是没你我会过得更好。”
“不错,你会的。”
“你没我会更快乐。”
“不错。”
最后—到头来—被折磨、被涤荡之后,我们握手言欢,嘲笑那两个愚昧的家伙,也就是我们自己。他俩的狭隘、他俩的委屈、他俩的自我辩解。我们超越了他们。我们宣称他们是撒谎者。我们晚饭时会喝酒庆祝,或者决定搞一个聚会。
我已经多年未见安德鲁了,不知他是否依然清瘦,头发是否已经完全灰白,是否仍旧一心喜欢吃生菜、坚持说真话,或者是否仍旧爽朗而带着失望。
我们在华盛顿州的韦纳奇过夜,此地已有数周没下雨。我们在一家绕树而建的饭店吃晚饭,那可不是一棵种在盆里的小树苗,而是一棵大大的、结实的三角叶杨。借着清晨的光线,我们开出人工灌溉的山谷,驶上干燥、多石而陡峭的山路,似乎通向连绵的群山。山顶是片广阔的平原,巨大的斯波坎河和哥伦比亚河纵横其上。一连几英里都是麦田和草地。道路笔直,点缀着不少小小的农业镇,镇上粮仓林立。事实上,一个标牌上介绍说,我们正穿过的这个县,道格拉斯县,拥有全美各县第二高的小麦产量。各镇都种了遮荫树。至少我觉得是种植的,因为乡下没这么大的树。
这一切都让我兴奋异常。“我为什么这么爱这里呢?”我问安德鲁,“是因为这儿不是风景区吗?”
“是因为它让你想起老家啦,”安德鲁说,“强烈的思乡之情。”不过他并没有戏谑的意思。
我们说“老家”,指的都是安大略,不过我们脑海里涌出的是截然不同的地方。我的老家是一个火鸡农场,我爸住在那里,是个鳏夫,那幢房子尽管是我妈住过的,由她贴了墙纸、刷了油漆、打扫过、装了家具,但如今已经是一副荒废相,被粗野的集体生活给整糟了。这宅子里过的日子,估计是我妈根本无法想象,也不可能饶恕的。火鸡工人们,也就是掏膛工人和拔毛工人,在这里开聚会。有时他们中的一两个年轻人会在这儿住上一阵,邀来自己的朋友,开他们自个儿随心所欲的聚会。我觉得这种生活比独处更适合爸爸,所以并不反对,当然也无权反对。很自然,安德鲁不喜欢来这里,他显然不是那种会和火鸡工人们围坐在厨房桌边讲笑话的人。他们既畏惧他又瞧不起他。而且在我看来,他们在的时候,爸爸没法不站在他们一边。不过不爽的不光是安德鲁。我虽说能勉强应付那些笑话,其实也觉得够呛。
我真怀念小时候,我们养火鸡之前的时光。那时候我们养母牛,把牛奶卖给奶酪厂。火鸡农场和美丽的奶牛场或牧羊场可不是一回事。你都能看到火鸡直接走向冻肉和桌上美餐的结局。它们连一点点自己生活的影子都没有,不像牛群有自由觅食的田野,猪群有光影斑驳的果园。火鸡房都是高效的长条形建筑—锡皮棚。没有房梁、干草或温暖的马厩。就连鸡粪闻起来都比普通的牲畜粪便更尖锐、更刺鼻。没有任何稻草捆、木栅栏、鸣鸟或开花的山楂树之类的东西。火鸡们统一被赶进一片长条形地里,把它啄得一干二净。在那里,它们看起来不像什么大鸟,只像一堆堆洗好的衣服哗哗掀动着。
有一回,在妈妈去世后不久,我结婚以后—事实上,我正在打包,准备去温哥华的安德鲁那里—我在家里和爸爸待了两天。一场少见的大雨下了一整夜。黎明的光线中,我们看到火鸡场被淹了。至少,低矮的部分被淹了,好像变成了一片遍布岛屿的大湖。火鸡们挤在岛屿上。火鸡是很蠢的。(爸爸常说:“你了解鸡吗?你知道鸡有多蠢吗?好吧,与火鸡比,鸡简直就是爱因斯坦了。”)不过它们全都设法挤到了高地上,没淹死。它们没准会互相把对方推下去,会挤死,或者着凉病死。我们可不能坐等水退,于是划着一艘家里的旧船出去了。我负责划桨,爸爸把沉重湿透的火鸡拉到船上,我们再把它们弄到谷仓里。天仍旧下着零星小雨。这活儿很艰难、很搞笑,也很累人。我们都笑着。我很高兴能和爸爸一起干活。我挺喜欢所有艰难、机械、让人害怕的活计,干这种活儿,身体会累垮,思想会沉寂(尽管有时精神倒是出乎意料地轻快),我已经开始提前思乡了,已经开始预先怀念起这种生活和这个地方。我想着,要是安德鲁看到我冒着雨,两手通红,浑身泥泞,一边试图抓住火鸡腿,一边还要划船,他只会一心想带我离开这里,让我忘掉它。这种原始的生活让他恼火。我对它的依恋也让他恼火。我想,我不该嫁给他的。但是不然嫁谁好呢?难道嫁个火鸡工人吗?
此外,我也不想待在那里。我纵然舍不得离开,可要是有人让我留下,我会感觉更糟。
安德鲁的妈妈住在多伦多一幢俯瞰穆尔公园的公寓大楼里。安德鲁和妹妹都在家住的时候,他妈妈睡起居室。她丈夫,一位医生,在孩子们还没到上学年龄时就死了。她去上文秘课,以大萧条时期的廉价卖掉房子,搬进这套公寓,在一些亲戚—她姐姐卡罗琳和姐夫罗杰—的帮助下设法养大了孩子们。安德鲁和妹妹上了私立学校,夏天还去夏令营。
“我猜想,那是清新空气基金会[2]提供的机会咯?”某次他抱怨过去生活穷苦时,我不屑地质问道。在我看来,安德鲁的城市生活可谓风雨无忧、精美考究。他妈妈在百货商店的办公室工作,回家后总会因为一天下来办公室里的嘈杂声和刺眼灯光而犯头痛,但我并不觉得那是一种艰苦或令人钦佩的生活。我想她自己也未必相信她值得钦佩吧—她只是不走运而已。她操心的是她坐办公室的工作、她的衣服、她的烹饪和她的孩子们。她最担心的还是罗杰和卡罗琳会怎么想。
卡罗琳和罗杰住在公园东面,一幢漂亮的石头房子里。罗杰是个高个儿秃顶男人,脑袋上遍布雀斑,肚皮肥硕结实。他喉部做过手术,失去了声音—说话用的是一种嘶哑的低语。不过所有人都会注意倾听。有一次,在石头房子用晚餐时—这房子的餐厅里,所有家具都巨大无比,散发着深色光泽,富丽堂皇的—我问了他一个问题。我想它一定是与韦塔克·钱伯斯[3]有关,后者的故事当时登在《星期六晚邮报》上。这个问题尽管措辞温和,但他嗅出了内容的离经叛道,针对他所谓的我的“同情心”,他开始管我叫葛罗米柯[4]夫人。没准他其实就想找个对手,只是一直没如愿吧。那次晚餐,我注意到安德鲁给他妈点烟时手直抖。安德鲁的罗杰姨父付了他的教育费用,还担任着好几家公司的董事呢。
“他就是个固执己见的老头,”安德鲁事后对我说,“跟他争论有什么意义呢?”
我们离开温哥华之前,安德鲁的妈妈写信说:“罗杰对于你们买了一辆小型车很有看法!”感叹号传达出她的担忧之情。当时,尤其是在安大略,选择一辆小型欧洲车而不是什么大型美国车,足以被视为一种宣言—朝罗杰向来嗤之以鼻的那些方面靠近的宣言。
“那车其实没那么小。”安德鲁气呼呼地说。
“问题不在这里,”我说,“问题在于,这根本不关他的事!”
我们的第二晚在米苏拉度过。在斯波坎的一家加油站,我们得知2号公路上很多地方在修,我们接下来这一路肯定暑热蒸人、灰尘呛鼻,而且还有漫长的堵车,所以我们拐上州际公路,穿过科达伦和凯洛格,开进蒙大拿州。过了米苏拉,我们掉头往南,朝比尤特驶去,途中绕了下道,去看看这个州的首府赫勒拿。我们在车上玩“猜猜我是谁”。
辛西娅是某个死去的人,是个美国人,是个女孩子。或许是位女士。她不是故事人物。她没上过电视。辛西娅不是在一本书里读到她的。她不是任何去过幼儿园的人,也不是辛西娅的朋友们的家人。
“她是人类吗?”安德鲁灵光一闪问道。
“不是!这个你们忘了问了!”
“原来是动物。”我恍然大悟。
“那是个问题吗?已经十六个问题了!”
“不是,那不是问题。我只是在思考嘛。一只死去的动物。”
“是那只鹿啦。”没参加游戏的梅格插嘴。
“这不公平!”辛西娅说,“她没参加!”
“什么鹿?”安德鲁问。
我说:“昨天那只。”
“是前天啦,”辛西娅说,“梅格没在玩。所以没人猜中。”
“卡车上那只鹿。”安德鲁说。
“那是一只母鹿,因为它没角,而且是一只美国鹿,而且死了。”辛西娅说。
安德鲁说:“我觉得这有点病态吧,居然是一只死鹿啊。”
“我猜对了。”梅格说。
辛西娅说:“我想我知道病态是什么意思。就是让人难受。”
赫勒拿是个古老的银矿小镇,即便在清晨的光线中也显出一派荒凉。然后是波兹曼和比灵斯,它们可就毫无荒凉之态了—都是活力四射、交通便利的小镇,成英里成英里炫目的金属饰带在二手车市场上空飘拂。我们又累又乏,没劲头玩“猜猜我是谁”了。这些平庸忙碌的城市让我想起安大略类似的地方,我想着那里真正在等待我们的是什么—罗杰和卡罗琳的餐厅里硕大的墓碑似的家具,我必须烫好孩子们的衣服、提醒他们好好用叉子才能去赶赴的晚宴,然后是一百英里外的另一张餐桌,我爸爸的火鸡工人们的笑话。我心心念念的那些快乐,比如欣赏欣赏乡间景色,或者在一家装有电扇、有高高的压模锡制天花板的老式药店喝杯可乐,都只能在那两张餐桌之间偷空觅得。
“梅格睡着了,”辛西娅说,“她太热啦。我跟她坐一张椅子都嫌热。”
“希望她没发烧哦。”我头也不回地说。
我们这么做是为什么呢,我思忖着,答案浮现了—为了出风头。为了让安德鲁的妈妈和我爸爸享受享受见到孙辈的愉悦。那是我们的责任。不过除此之外,我们还想向他们展示什么。安德鲁和我,我们是何等顽强不屈的孩子,是何等坚定的赞美寻求者啊。仿佛在某个时刻,我们收到过一则令人刻骨铭心、无法消受的信息:我们远不足以让人满意,生活中哪怕最普通的成功也是遥不可及的。自然,罗杰发来过这类信息—这就是他的风格嘛—但是安德鲁的妈妈,还有我自己的爸妈肯定不是故意的。他们想告诉我们的只是“小心点,好好过”。读高中时,爸爸跟我开玩笑说,我准会以为自己太聪明了,结果到头来连男朋友都找不到。他没准一星期之后就把这话抛到脑后了,我却永世难忘。安德鲁和我把一切都牢记心头。我们耿耿于怀。
“希望有个海滩。”辛西娅说。
“或许会有的,”安德鲁说,“就在下一个拐弯那里。”
“前面根本没拐弯。”她答道,好像深感受辱。
“我就是那个意思嘛。”
“再有一些柠檬水就好了。”
“我来挥舞魔棒,直接变出一些吧,”我说,“好不好,辛西娅?或者你想要葡萄汁?我要不要顺便变个海滩出来?”
她沉默着,很快我就知错了。“没准下个镇会有游泳池的。”我安慰道。我查看着地图。“在迈尔斯城。反正那里总会有点冰饮料喝。”
“它有多远?”安德鲁问。
“不远了,”我说,“三十英里吧,大概。”
“在迈尔斯城,”辛西娅念咒般说道,“有一个给孩子们玩的美丽蓝色游泳池,还有一个长着好看的树的公园。”
安德鲁对我说:“你真能惹事。”
不过还真有一个游泳池呢。还有个公园,尽管并不完全符合辛西娅幻想中的绿洲。细叶子的草原树—三角叶杨和杨树—磨损的草地,一道高高的金属丝篱笆围着的游泳池。篱笆里有一道混凝土块垒起的墙,尚未完工。没有欢叫声,也没有泼水声。在入口处上方,我看到一块牌子上写着:游泳池每天中午到下午两点不开门。这会儿是十二点二十五分。
虽说如此,我还是喊道:“有人吗?”我想总有人在吧,因为入口附近停了一辆小卡车。卡车一侧印着:“我们有头脑,通你下水道。(大力神抽来帮忙!)”
一个女孩走出来,游泳衣外披了一件救生员的红色衬衫。“抱歉,我们关门了。”
“我们是正好开车路过的。”我说。
“我们每天十二点到两点不开门。牌子上写了。”她啃着一个三明治。
“我看到牌子了,”我说,“但这是我们这一路看到的第一片水,孩子们热坏了,我想问问她们能不能在水里泡泡就出来—就五分钟。我们会看着她们的。”
她身后又冒出一个男孩。他穿着牛仔裤和T恤,T恤上印着“大力神抽”。
我想解释说我们是从不列颠哥伦比亚开往安大略省的,不过旋即想起美国人对加拿大地名通常毫无概念。“我们开车横穿美国来着,”我说,“没时间等泳池开门了。只希望能让孩子们凉快一下。”
辛西娅光着脚跑到我身后。“妈妈,妈妈,我的游泳衣在哪里?”随即她停下了,嗅出成人谈判的严肃气氛。梅格正从车里爬出来—刚刚才醒,上衣拉上去,短裤朝下拽,露出粉红色的小肚皮。
“就这两个吗?”女孩问。
“就这两个,我们会看好她们的。”
“我不能让大人进去。要是就这两个,我想我可以看好她们。我正在吃午饭呢,”她问辛西娅,“你想进游泳池吗?”
“是的,请让我进去吧。”辛西娅坚定地说。
梅格盯着地面。
“只能一小会儿哦,因为游泳池其实关门了呢。”我提醒道。“真的非常感谢。”我对女孩说。
“嗯,我可以在里面吃午饭,要是就她俩的话。”她看着汽车,好像以为我会让里面蹦出更多孩子塞给她似的。
我找出辛西娅的游泳衣,她带着它进了更衣室。她不让任何人,包括梅格,看到她光身子的样子。我让梅格站在汽车前座上,给她换了衣服。她的是一件粉色棉布游泳衣,上面有一些带子交叉打结。衣服下部镶着花边。
“她真烫啊,”我说,“不过我想她没发烧。”
我喜欢帮梅格穿衣服脱衣服,因为她的身体仍旧任人摆布,沉甸甸的,有着可爱的迟钝和宝宝特有的奶香。辛西娅的身体很久以来就已经消瘦、成形、变化了,已经变成辛西娅。我们都喜欢抱着梅格,搂紧她,爱抚她。有时她会发怒,会打开我们,这种直截了当的独立要求,这种凶巴巴的害臊劲儿,反而使她更可爱,让家人更想捉弄她,挑逗她。
安德鲁和我坐在车里,开着窗。我听到一台收音机的声音,心想它一定是那女孩或她男朋友的。我渴了,下了车,想看看公园里有没有小卖部或者软饮料出售机。我穿着短裤,腿后面滑溜溜的全是汗。我看到公园另一头有个饮水喷泉,便尽量躲在树阴下,迂回地朝它走去。你只有下了车,一个地方才会真实起来。我走得很慢,那热劲儿,还有那照在晒得起泡的房子、人行道和灼焦的草地上的烈日,都让我头昏目眩。我注意到一片踩坏的树叶,凉鞋后跟踩上了一根冰棒棍儿,又瞟了瞟绑在树上的一个垃圾箱。你在长时间驱车之后,就会这样注意到重新浮现的世界中最平庸的细节—你会感觉到它们的独一无二,注意到它们浑然天成的位置,还会意识到你恰巧就在这里遇上它们,这种因缘际会令人倍感惆怅。
孩子们哪去了?
我转过身,半走半跑地赶到尚未完工的水泥墙外面的篱笆边。我可以看到水池的一部分。我看到辛西娅,她站在齐腰深的水里,在水面上拍拍打打的,一边谨慎地看着游泳池另一头我看不见的地方。根据她小心翼翼的姿态,还有她的神情,我猜想她一定是在看救生员和她的男朋友之间的什么举动。我没法看到梅格。不过我想她肯定在浅水区吧—水池的浅水和深水两头我都看不到。
“辛西娅!”我喊了两次,才让她顺着我的声音看过来。“辛西娅!梅格在哪里?”
每次回想这一幕,我总觉得辛西娅无比优雅地扭头看我,又在水中转了一圈—让我想起一个站在足尖上的芭蕾舞者—用一种舞台上的姿势摊开胳膊。“不—见—了!”
辛西娅确实很优雅,也上了舞蹈课,因此这些动作有可能确实是我描述的那样。她确实是在游泳池里四下看过之后说了“不见了”,但是这些话语和动作的怪异造作的风格,这种不急不忙的态度,大有可能出自我的想象。看不到梅格,一阵恐惧立刻涌入我心中—甚至就在我自我安慰她一定是在浅水区的时候—这想必让我觉得辛西娅的动作是那样缓慢和不合时宜,简直叫人难以忍受,而她在尚未明白其含义时说出的“不见了”的语调(或者是否有可能她也在掩饰某种已经涌出的负罪感呢?),在我听来也未免太平静了,显得典雅无比,令人震惊。
我喊着安德鲁,救生员冒出来了。她指着深水区那头问:“那是什么?”
那儿,就在我的视线中,出现一簇粉红色的花边,一个花束,沉在水面下。身为救生员,怎么会站在那里指指戳戳?怎么会问那是什么呢?她为什么不径直跳进水中游过去?她没游水,而是绕着池边朝游泳池那头跑去。不过那时安德鲁已经翻过了篱笆。发生了那么多不可思议的事—辛西娅的举止,然后是救生员的—现在我的感觉是安德鲁一跃就翻过了看起来大约有七英尺高的篱笆。他一定是抓着金属线,飞快地爬过去的。
我没法爬过或者跳过它,只好跑向入口,那里有一道锁着的隔栅门,不是很高,我设法翻了过去。我冲过水泥走廊,跑过足部消毒池,赶到游泳池的一头。
事情已经结束。
安德鲁第一个赶到梅格那里,把她从水中拉出来。他只需伸手一抓,因为她其实是在游泳,脑袋埋在水下—她打算朝游泳池的一头游过去。现在他抱着她,救生员小跑着跟在后面。辛西娅从水里爬出来,跑向他们。唯一一个置身事外的是那个男朋友,他一直坐在浅水一头的椅子上,喝着杯奶昔。他冲我笑了笑,我想着他是多么没心没肺啊,纵然危险已经过去。但或许他是善意的吧。我注意到他没关收音机,只是把声音调小了。
梅格一点也没呛水。她甚至都没怕。她的头发贴在脑袋上,眼睛睁得大大的,散发着惊奇的金色光辉。
“我是去拿梳子嘛,”她说,“我不知道水深。”
安德鲁说:“她在游泳!她自己游泳来着。我看到她的游泳衣在水里,然后就看到她在自己游泳呢。”
“她差点淹死,”辛西娅说,“不是吗?梅格差点淹死啦。”
“我不知道怎么会这样,”救生员说,“她在那里好好的,一转眼就不见了。”
事情是这样的,梅格从浅水区那头爬出来,沿着游泳池边,朝深水区跑去。她看到水底有一把不知谁丢下的梳子。她搞不清水深,就弯腰去够它。结果她翻过池边,滑进水中,发出的声音很轻,以至于没人听到—救生员没听到,她正在和男朋友接吻,正看着他俩的辛西娅也没听到。那想必就是我在树下想到“孩子们哪去了?”的时刻。想必就是在同一个时刻。就在那个时刻,梅格吃惊地滑进了危险的、清澈湛蓝的池水中。
“没事的,”我安慰快要哭出来的救生员,“她有时动作飞快。”(尽管我们通常可不会那样描述梅格。我们总说她凡事都会思索半天,不慌不忙。)
“你会游泳啦,梅格。”辛西娅用一种祝贺的语气说。(后来她告诉我们接吻的事。)
“我不知道水深嘛,”梅格说,“我没淹水。”
我们在一家外卖店买了午饭,坐在公路附近的一张野餐桌边吃汉堡和薯条。由于激动,我忘了给梅格买一个素汉堡,只得用塑料调羹刮掉调味品和芥末酱,用餐巾纸擦干净肉饼给她吃。我利用垃圾桶清理了车厢。之后,我们敞着前排车窗,再度朝东驶去。辛西娅和梅格在后座上睡着了。
安德鲁和我轻声讨论着刚才的事。假设我那会儿没有突然一阵冲动,想到去看看孩子,会怎样?要是我们像原先计划的那样进城去买饮料,会怎样?安德鲁是怎么翻过篱笆的?他是爬过去还是跳过去的?(他记不清了。)他怎么做到那么快就抓住梅格的?想想看,救生员竟然没有盯着。还有辛西娅,就顾着看接吻了。别的什么都没在意。都没看到梅格从边上跌进水里。
不见了。
不过她游泳来着。她屏住呼吸,游起泳来啦。
多么幸运的一长串关联啊。
我们所谈论的就是这个—幸运。不过我总忍不住去想象相反的结果。此刻,我们大有可能正在填表格。梅格从我们身边被夺走了。梅格的尸体准备运回国。运到温哥华—我们在那里还从未关注过墓地这类事—或者运到安大略?她今天早上画的图画还躺在后座上。突然降临的这一切该如何承受呢?人们都是如何承受这些的呢?那胖墩墩的、甜美的肩膀和双手小脚,那细柔的棕色头发,那心满意足、高深莫测的表情—全都与她活着时一模一样。最平凡的一种悲剧了吧。阳光明媚的中午,一个孩子淹死在游泳池里。一切很快就将被打扫干净。水池两点正常开放。救生员有点受刺激,下午请求休假。她和男朋友一起开着大力神抽卡车离开。尸体在某种运输用的棺材里密封好。镇静剂、电话、作安排。如此骤然的一种缺失,一种茫然的下沉和剧变。从药丸的作用中昏沉沉醒来,暂时感觉一切都不是真的。想着要是我们没停车,要是我们没走这条路线,要是他们没让我们用游泳池,会怎样。那把梳子或许再也不会有人知晓。
这种想象挺犯傻的,不是吗?怪丢人的。就像把手按到电线上,接受安全范围内的电击,体验一下感觉又迅速收回。我相信安德鲁对这类事比我更谨慎,此刻他正竭力不去想这些。
我在斯蒂夫·高雷的葬礼上,隔开一段距离观察我父母,对他们产生全新的讨厌感觉时,我想我头一回理解了某些和他们有关的事。一件严肃得可怕的事。我理解了,他们其实是沆瀣一气的。他们高大、僵硬、盛装的身体并不曾挡在我和夭折或者任何别的死亡之间。他们给出了许可。至少貌似如此。他们对于孩子们的死亡、对于我的死亡给出了许可,这并非通过他们的话语或思想来达成,而是由他们生下孩子—生下了我—这个事实来完成的。他们生下我,因此我的死去—无论他们多么悲恸,如何难以承受—在他们看来都绝非不可思议,绝非违背自然。这是事实,而即便在当时,我也知道不该谴责他们。
但我仍旧谴责了他们。我控告他们无耻、虚伪。我代表的是斯蒂夫·高雷,还有所有孩子们,他们知道他们有权自由自在地长大,展开一种新的、精彩的生活,而不是被那些溃败的大人们设下陷阱,被他们的性爱和葬礼所捕获。
斯蒂夫·高雷淹死了,人们说,是因为他和孤儿差不离,没人管。要是有人给他足够的警告,给他活儿干,看着他,他就不会从一根不牢靠的树枝上跌进一个春天的池塘,跌进河边一个灌满水的砾石坑—就不会淹死了。他被忽略啦,没人管,所以淹死了。他爸认为这是个意外,就像狗会遭到意外。他都没有体面的套装穿来葬礼,也没在听祈祷时低下头。不过,他是唯一一个我放过的大人。他是唯一一个我觉得没有给出那种许可的大人。他没法阻止任何事,但他也没跟任何东西沆瀣一气—不像其他人,那些人用造作的沉痛语调念着祷文,渗出虔诚和耻辱。
在距离北达科他州边境不远的格伦代夫,我们面临选择—是继续走州际公路,还是往东北方,朝威利斯顿开,走16号公路,再开一段次级公路,最后回到2号公路。
我们都同意州际公路会快一点,而且我们最好不要花太多时间—也就是说,太多钱—在路上。尽管如此,我们还是决定回到2号公路。
“我就是觉得这样更好。”我说。
安德鲁说:“因为这是我们一开始计划的路线。”
“我们错过了看到卡利斯佩和哈弗尔的机会。还有‘狼角’。我喜欢这个地名。”
“我们回程时会看到的。”
听到安德鲁说“回程”,我感到一种意外的惊喜。当然了,我一直相信我们会顺利回程,我们会跨越所有这些距离,我们的车、我们的生命和我们的家庭都仍旧完好无损,而且还设法厘清了忠诚和各种别的问题,以如此蛮勇的方式,昂首接受了检验。但是听到他说出这话,我还是倍感宽慰。
“有件事我想不明白,”安德鲁说,“你是怎么得到信号的呢?那一定是做妈妈的才会有的某种直觉吧。”
我有点愿意相信这个,好为我的直觉得意一番。同时我又有点想警告他—警告所有人—绝对不要指望依靠它。
“我想不明白,”我说,“你究竟是如何翻过篱笆的。”
“我也不明白啊。”
我们就这么开了下去,后座上的两个人信任着我们,因为别无选择,而我们自己呢,相信着这一点:我们那些事,孩子们一开始必定会注意到、会谴责的那些事,到头来总归会得到原谅的。我们所有那些冒失、武断、草率和冷漠—我们所有那些无法避免,或是纯属人为的错误。
[1] 位于美国华盛顿州。
[2] 一个旨在为贫穷儿童提供免费夏令营的基金会。
[3] 1901—1961,美国作家、编辑。
[4] 前苏联外交部长,曾任前苏联驻美国大使。
梦里花落知多少-三毛
========================
梦里花落知多少-[[三毛]]
------
——迷航之四
那一年的冬天,我们正要从丹娜丽芙岛搬家回到大迦纳利岛自己的房子里去。
一年的工作已经结束,美丽无比的人造海滩引进了澄蓝平静的海水。
荷西与我坐在完工的堤边,看也看不厌的面对着那份成绩欣赏,景观工程的快乐是不同凡响的。
我们自黄昏一直在海边坐到子夜,正是除夕,一朵朵怒放的烟火,在漆黑的天空里如梦如幻地亮灭在我们仰着的脸上。
滨海大道上挤满着快乐的人群。钟敲十二响的时候,荷西将我抱在手臂里,说:“快许十二个愿望,心里重复着十二句同样的话:“但愿人长久,但愿人长久,但愿人长久,但愿人长久——”
送走了去年,新的一年来了。
荷西由堤防上先跳了下地,伸手接过跳落在他手臂中的我。
我们十指交缠,面对面地凝望了一会儿,在烟火起落的五色光影下,微笑着说:“新年快乐!”然后轻轻一吻。我突然有些泪湿,赖在他的怀里不肯举步。
新年总是使人惆怅,这一年又更是来得如真如幻。许了愿的下一句对夫妻来说并不太吉利,说完了才回过意来,竟是心慌。
“你许了什么愿。”我轻轻问他。
“不能说出来的,说了就不灵了。”
我勾住他的脖子不放手,荷西知我怕冷,将我卷进他的大夹克里去。我再看他,他的眸光炯炯如星,里面反映着我的脸。
“好啦!回去装行李,明天清早回家去罗!”
他轻拍了我一下背,我失声喊起来:“但愿永远这样下去,不要有明天了!”
“当然要永远下去,可是我们得先回家,来,不要这个样子。”
一路上走回租来的公寓去,我们的手紧紧交握着,好像要将彼此的生命握进永恒。
而我的心,却是悲伤的,在一个新年刚刚来临的第一个时辰里,因为幸福满溢,我怕得悲伤。
不肯在租来的地方多留一分一秒,收拾了零杂东西,塞满了一车子。清晨六时的码头上,一辆小白车在等渡轮。
新年没有旅行的人,可是我们急着要回到自己的房子里去。
关了一年的家,野草齐膝,灰尘满室,对着那片荒凉,竟是焦急心痛,顾不得新年不新年,两人马上动手清扫起来。
不过静了两个多月的家居生活,那日上午在院中给花洒水,送电报的朋友在木栅门外喊着:“Echo,一封给荷西的电报呢!”
我匆匆跑过去,心里扑扑的乱跳起来,不要是马德里的家人出了什么事吧!电报总使人心慌意乱。
“乱撕什么嘛!先给签个字。”朋友在摩托车上说。我胡乱签了个名,一面回身喊车房内的荷西。
“你先不要怕嘛!给我看。”荷西一把抢了过去。
原来是新工作来了,要他火速去拉芭玛岛报到。只不过几小时的光景,我从机场一个人回来,荷西走了。
离岛不算远,螺旋桨飞机过去也得四十五分钟,那儿正在建新机场,新港口。只因没有什么人去那最外的荒寂之岛,大的渡轮也就不去那边了。
虽然知道荷西能够照顾自己的衣食起居,看他每一度提着小箱子离家,仍然使我不舍而辛酸。
家里失了荷西便失了生命,再好也是枉然。
过了一星期漫长的等待,那边电报来了。
“租不到房子,你先来,我们住旅馆。”
刚刚整理的家又给锁了起来,邻居们一再的对我建议:“你住家里,荷西周末回来一天半,他那边住单身宿舍,不是经济些嘛!”
我怎么能肯。匆忙去打听货船的航道,将杂物、一笼金丝雀和汽车托运过去,自己推着一只衣箱上机走了。
当飞机着陆在静静小小的荒凉机场时,又看见了重沉沉的大火山,那两座黑里带火蓝的大山。
我的喉咙突然卡住了,心里一阵郁闷,说不出的闷,压倒了重聚的欢乐和期待。
荷西一只手提着箱子,另一只手搭在我的肩上向机场外面走去。
“这个岛不对劲!”我闷闷的说。
“上次我们来玩的时候你不是很喜欢的吗。”
“不晓得,心里怪怪的,看见它,一阵想哭似的感觉。”我的手拉住他皮带上的绊扣不放。
“不要乱想,风景好的地方太多了,刚刚赶上看杏花呢!”
他轻轻摸了一下我的头发又安慰似的亲了我一下。
只有两万人居住的小城里租不到房子。我们搬进了一房一厅连一小厨房的公寓旅馆。收入的一大半付给了这份固执相守。
安置好新家的第三日,家中已经开始请客了,婚后几年来,荷西第一回做了小组长,水里另外四个同事没有带家眷,有两个还依然单身。我们的家,伙食总比外边的好些,为着荷西爱朋友的真心,为着他热切期望将他温馨的家让朋友分享,我晓得,在他内心深处,亦是因为有了我而骄傲,这份感激当然是全心全意的在家事上回报了他。
岛上的日子岁月悠长,我们看不到外地的报纸,本岛的那份又编得有若乡情。久而久之,世外的消息对我们已不很重要,只是守着海,守着家,守着彼此。每听见荷西下工回来时那急促的脚步声上楼,我的心便是欢喜。
六年了,回家时的他,怎么仍是一样跑着来的,不能慢慢的走吗?六年一瞬,结婚好似是昨天的事情,而两人已共过了多少悲欢岁月。
小地方人情温暖,住上不久,便是深山里农家讨杯水喝,拿出来的必是自酿的葡萄酒,再送一满怀的鲜花。我们也是记恩的人,马铃薯成熟的季节,星期天的田里,总有两人的身影弯腰帮忙收获。做热了,跳进蓄水池里游个泳,趴在荷西的肩上浮沉,大喊大叫,便是不肯松手。
过去的日子,在别的岛上,我们有时发了神经病,也是争吵的。
有一回,两人讲好了静心念英文,夜间电视也约好不许开,对着一盏孤灯就在饭桌前钉住了。
讲好只念一小时,念了二十分钟,被教的人偷看了一下手表,再念了十分钟,一个音节发了二十次还是不正确,荷西又偷看了一下手腕。知道自己人是不能教自己人的,看见他的动作,手中的原子笔啪一下丢了过去,他那边的拍纸簿哗一下摔了过来,还怒喊了一声:“你这傻瓜女人!”
第一次被荷西骂重话,我呆了几分钟,也不知回骂,冲进浴室拿了剪刀便绞头发,边剪边哭,长发乱七八糟的掉了一地。
荷西追进来,看见我发疯,竟也不上来抢,只是倚门冷笑:“你也不必这种样子,我走好了。”
说完车钥匙一拿,门砰一下关上离家出走去了。
我冲到阳台上去看,凄厉的叫了一声他的名字,他哪里肯停下来,车子唰一下就不见了。
那一个长夜,是怎么熬下来的,自己都迷糊了。只念着离家的人身上没有钱,那么狂怒而去,又出不出车祸。
清晨五点多他轻轻的回来了,我趴在床上不说话,脸也哭肿了。离开父母家那么多年了,谁的委屈也能受下,只有荷西,他不能对我凶一句,在他面前,我是不设防的啊!
荷西用冰给我冰脸,又拉着我去看镜子,拿起剪刀来替我补救剪得狗啃似的短发。一刀一刀细心的给我勉强修修整齐,口中叹着:“只不过气头上骂了你一句,居然绞头发,要是一日我死了呢——”
他说出这样的话来令我大恸,反身抱住他大哭起来,两人缠了一身的碎发,就是不肯放手。
到了新的离岛上,我的头发才长到齐肩,不能梳长辫子,两人却是再也不吵了。
依山背海而筑的小城是那么的安详,只两条街的市集便是一切了。
我们从不刻意结交朋友,几个月住下来,朋友雪球似的越滚越大,他们对我们真挚友爱,三教九流,全是真心。周末必然是给朋友们占去了,爬山,下海,田里帮忙,林中采野果,不然找个老学校,深夜睡袋里半缩着讲巫术和鬼故事,一群岛上的疯子,在这世外桃源的天涯地角躲着做神仙。有时候,我快乐得总以为是与荷西一同死了,掉到这个没有时空的地方来。
那时候,我的心脏又不好了,累多了胸口的压迫来,绞痛也来。小小一袋菜场买回来的用品,竟然不能一口气提上四楼。
不敢跟荷西讲,悄悄的跑去看医生,每看回来总是正常又正常。
荷西下班是下午四点,以后全是我们的时间,那一阵不出去疯玩了。黄昏的阳台上,对着大海,半杯红酒,几碟小菜,再加一盘象棋,静静的对弈到天上的星星由海中升起。
有一晚我们走路去看恐怖片,老旧的戏院里楼上楼下数来数去只有五个人,铁椅子漆成铝灰色,冰冷冷的,然后迷雾凄凄的山城里一群群鬼飘了出来捉过路的人。
深夜散场时海潮正涨,浪花拍打到街道上来。我们被电影和影院吓得彻骨,两人牵了手在一片水雾中穿着飞奔回家,跑着跑着我格格的笑了,挣开了荷西,独自一人拚命的快跑,他鬼也似的在后面又喊又追。
还没到家,心绞痛突然发了,冲了几步,抱住电线杆不敢动。
荷西惊问我怎么了,我指指左边的胸口不能回答。那一回,是他背我上四楼的。背了回去,心不再痛了,两人握着手静静醒到天明。
然后,缠着我已经几年的噩梦又紧密的回来了,梦里总是在上车,上车要去什么令我害怕的地方,梦里是一个人,没有荷西。
多少个夜晚,冷汗透湿的从梦魅里逃出来,发觉手被荷西握着,他在身畔沉睡,我的泪便是满颊。我知道了,大概知道了那个生死的预告。
以为先走的会是我,悄悄的去公证人处写下了遗嘱。时间不多了,虽然白日里仍是一样笑嘻嘻的洗他的衣服,这份预感是不是也传染了荷西。
即使是岸上的机器坏了一个螺丝钉,只修两小时,荷西也不肯在工地等,不怕麻烦的脱掉潜水衣就往家里跑,家里的妻子不在,他便大街小巷的去找,一家一家店铺问过去:“看见Echo没有?看见Echo没有?”
找到了什么地方的我,双手环上来,也不避人的微笑痴看着妻子,然后两人一路拉着手,提着菜篮往工地走去,走到已是又要下水的时候了。
总觉相聚的因缘不长了,尤其是我,朋友们来的周末的活动,总拿身体不好挡了回去。
周五帐篷和睡袋悄悄装上车,海边无人的地方搭着临时的家,摸着黑去捉螃蟹,礁石的夹缝里两盏镑镑的黄灯扣在头上,浪潮声里只听见两人一声声狂喊来去的只是彼此的名字。那种喊法,天地也给动摇了,我们尚是不知不觉。
每天早晨,买了菜蔬水果鲜花,总也舍不得回家,邻居的脚踏车是让我骑的,网篮里放着水彩似的一片颜色便往码头跑。骑进码头,第一个看见我的岸上工人总会笑着指方向:“今天在那边,再往下骑——”
车子还没骑完偌大的工地,那边岸上助手就拉信号,等我车一停,水里的人浮了起来,我跪在堤防边向他伸手,荷西早已跳了上来。
大西洋的晴空下,就算分食一袋樱桃也是好的,靠着荷西,左边的衣袖总是湿的。
不过几分钟吧,荷西的手指轻轻按一下我的嘴唇,笑一笑,又沉回海中去了。
每见他下沉,我总是望得痴了过去。
岸上的助手有一次问我:“你们结婚几年了?”“再一个月就六年了。”我仍是在水中张望那个已经看不见了的人,心里慌慌的。
“好得这个样子,谁看了你们也是不懂!”
我听了笑笑便上车了,眼睛越骑越湿,明明上一秒还在一起的,明明好好的做着夫妻,怎么一分手竟是魂牵梦萦起来。
家居的日子没有敢浪费,扣除了房租,日子也是紧了些。有时候中午才到码头,荷西跟几个朋友站着就在等我去。“Echo,银行里还有多少钱?”荷西当着人便喊出来。“两万,怎么?”
“去拿来,有急用,拿一万二出来!”
当着朋友面前,绝对不给荷西难堪。掉头便去提钱,他说的数目一个折扣也不少,匆匆交给尚是湿湿的他,他一转手递给了朋友。
回家去我一人闷了一场,有时次数多了,也是会委屈掉眼泪的。哪里知道那是荷西在人间放的利息,才不过多久,朋友们便倾泪回报在我的身上了呢?
结婚纪念的那一天,荷西没有按时回家,我担心了,车子给他开了去,我借了脚踏车要去找人,才下楼呢,他回来了,脸上竟是有些不自在。
匆匆忙忙给他开饭——我们一日只吃一顿的正餐。坐下来向他举举杯,惊见桌上一个红绒盒子,打开一看,里面一只罗马字的老式女用手表。
“你先别生气问价钱,是加班来的外快——”他喊了起来。
我微微的笑了,没有气,痛惜他神经病,买个表还多下几小时的水。那么借朋友的钱又怎么不知去讨呢?结婚六年之后,终于有了一只手表。
“以后的一分一秒你都不能忘掉我,让它来替你数。”荷西走过来双手在我身后环住。
又是这样不祥的句子,教人心惊。
那一个晚上,荷西睡去了,海潮声里,我一直在回想少年时的他,十七岁时那个大树下痴情的女孩子,十三年后在我枕畔共着呼吸的亲人。
我一时里发了疯,推醒了他,轻轻的喊名字,他醒不全,我跟他说:“荷西,我爱你!”
“你说什么?”他全然的骇醒了,坐了起来。
“我说,我爱你!”黑暗中为什么又是有些呜咽。“等你这句话等了那么多年,你终是说了!”
“今夜告诉你了,是爱你的,爱你胜于自己的生命,荷西——”
那边不等我讲下去,孩子似的扑上来缠住我,六年的夫妻了,竟然为着这几句对话,在深夜里泪湿满颊。醒来荷西已经不见了,没有见到他吃早餐使我不安歉疚,匆匆忙忙跑去厨房看,洗净的牛奶杯里居然插着一朵清晨的鲜花。
我痴坐到快正午。这样的夜半私语,海枯石烂,为什么一日泛滥一日。是我们的缘数要到了吗?不会有的事情,只是自己太幸福了才生出的惧怕吧!
照例去工地送点心,两人见了面竟是赧然。就连对看一眼都是不敢,只拿了水果核丢来丢去的闹着。
一日我见阳光正好,不等荷西回来,独自洗了四床被单。搬家从来不肯带洗衣机,去外面洗又多一层往返和花费,不如自己动手搓洗来得方便。
天台上晾好了床单还在放夹子的时候心又闷起来了,接着熟悉的绞痛又来。我丢下了水桶便往楼下走,进门觉着左手臂麻麻的感觉,知道是不太好了,快喝一口烈酒,躺在床上动也不敢动。
荷西没见我去送点心,中午穿着潜水衣便开车回来了。“没什么,洗被单累出来了。”我恹恹的说。
“谁叫你不等我洗的——”他趴在我床边跪着。“没有病,何必急呢!医生不是查了又查了吗。来,坐过来……”
他湿湿的就在我身边一靠,若有所思的样子。
“荷西——”我说:“要是我死了,你一定答应我再娶,温柔些的女孩子好,听见没有——”
“你神经!讲这些做什么——”
“不神经,先跟你讲清楚,不再婚,我是灵魂永远都不能安息的。”
“你最近不正常,不跟你讲话。要是你死了,我一把火把家烧掉,然后上船去飘到老死——”
“放火也可以,只要你再娶——”
荷西瞪了我一眼,只见他快步走出去,头低低的,大门轻轻扣上了。
一直以为是我,一直预感的是自己,对着一分一秒都是恐惧,都是不舍,都是牵挂。而那个噩梦,一日密似一日的纠缠着上来。
平凡的夫妇和我们,想起生死,仍是一片茫茫,失去了另一个的日子,将是什么样的岁月?我不能先走,荷西失了我要痛疯掉的。
一点也不明白,只是茫然的等待着。
有时候我在阳台上坐着跟荷西看渔船打鱼,夕阳晚照,凉风徐来,我摸摸他的颈子,竟会无端落泪。
荷西不敢说什么,他只说这美丽的岛对我不合适,快快做完第一期工程,不再续约,我们回家去的好。
只有我心里明白,我没有发疯,是将有大苦难来了。那一年,我们没有过完秋天。
荷西,我回来了,几个月前一袭黑衣离去,而今穿着彩衣回来,你看了欢喜吗?
向你告别的时候,阳光正烈,寂寂的墓园里,只有蝉鸣的声音。
我坐在地上,在你永眠的身边,双手环住我们的十字架。
我的手指,一遍一又一遍轻轻划过你的名字——荷西·马利安·葛罗。
我一次又一次的爱抚着你,就似每一次轻轻摸着你的头发一般的依恋和温柔。
我在心里对你说——荷西,我爱你,我爱你,我爱你——这一句让你等了十三年的话,让我用残生的岁月悄悄的只讲给你一个人听吧!
我亲吻着你的名字,一次,一次,又一次,虽然口中一直叫着“荷西安息!荷西安息!”可是我的双臂,不肯放下你。我又对你说:“荷西,你乖乖的睡,我去一趟中国就回来陪你,不要悲伤,你只是睡了!”
结婚以前,在塞哥维亚的雪地里,已经换过了心,你带去的那颗是我的,我身上的,是你。
埋下去的,是你,也是我。走了的,是我们。
我拿出缝好的小白布口袋来,黑丝带里,系进了一握你坟上的黄土。跟我走吧,我爱的人!跟着我是否才叫真正安息呢?
我替你再度整理了一下满瓶的鲜花,血也似的深红的玫瑰。留给你,过几日也是枯残,而我,要回中国去了,荷西,这是怎么回事,一瞬间花落人亡,荷西,为什么不告诉我,这不是真的,一切只是一场噩梦。
离去的时刻到了,我几度想放开你,又几次紧紧抱住你的名字不能放手。黄土下的你寂寞,而我,也是孤伶伶,为什么不能也躺在你的身边。
父母在山下巴巴的等待着我。荷西,我现在不能做什么,只有你晓得,你妻子的心,是埋在什么地方。
苍天,你不说话,对我,天地间最大的奥秘是荷西,而你,不说什么的收了回去,只让我泪眼仰望晴空。
我最后一次亲吻了你,荷西,给我勇气,放掉你大步走开吧!
我背着你狂奔而去,跑了一大段路,忍不住停下来回首,我再度向你跑回去,扑倒在你的身上痛哭。
我爱的人,不忍留下你一个人在黑暗里,在那个地方,又到了那儿去握住你的手安睡?
我趴在地上哭着开始挖土,让我再将十指挖出鲜血,将你挖出来,再抱你一次,抱到我们一起烂成白骨吧!那时候,我被哭泣着上来的父母带走了。我不敢挣扎,只是全身发抖,泪如血涌。最后回首的那一眼,阳光下的十字架亮着新漆。你,没有一句告别的话留给我。
那个十字架,是你背,也是我背,不到再相见的日子,我知道,我们不会肯放下。
荷西,我永生的丈夫,我守着自己的诺言千山万水的回来了,不要为我悲伤,你看我,不是穿着你生前最爱看的那件锦绣彩衣来见你了吗?
下机后去镇上买鲜花,店里的人惊见是远去中国而又回来的我,握住我的双手说不出一句话来,我们相视微笑,哪里都浮上了泪。
我抱着满怀的鲜花走过小城的石板路,街上的车子停了,里面不识的人,只对我淡淡的说:“上车来吧!送你去看荷西。”下了车,我对人点头道谢,看见了去年你停灵的小屋,心便狂跳起来。在那个房间里,四支白烛,我握住你冰凉苍白的双手,静静度过了我们最后的一夜,今生今世最后一个相聚相依的夜晚。
我鼓起勇气走上了那条通向墓园的煤渣路,一步一步的经过排排安睡外人。我上石阶,又上石阶,向左转,远远看见了你躺着的那片地,我的步子零乱,我的呼吸急促,我忍不住向你狂奔而去。荷西,我回来了——我奔散了手中的花束,我只是疯了似的向你跑去。
冲到你的墓前,惊见墓木已拱,十字架旧得有若朽木,你的名字,也淡得看不出是谁了。
我丢了花,扑上去亲吻你,万箭穿心的痛穿透了身体。是我远走了,你的坟地才如此荒芜,荷西,我对不起你——不能,我不是坐下来哭你的,先给你插好了花,注满清水在瓶子里,然后就要下山去给你买油漆。
来,让我再抱你一次,就算你已成白骨,仍是春闺梦里相思又相思的亲人啊!
我走路奔着下小城,进了五金店就要淡棕色的亮光漆和小刷子,还去文具店买了黑色的粗芯签字笔。
路上有我相熟的朋友,我跟他们匆匆拥抱了一下,心神溃散,无法说什么别后的情形。
银行的行长好心要伴我再上墓园,我谢了他,只肯他的大车送到门口。
这段时光只是我们的,谁也不能在一旁,荷西,不要急,今天,明天,后天,便是在你的身畔坐到天黑,坐到我也一同睡去。
我再度走进墓园,那边传来了丁字镐的声音,那个守墓地的在挖什么人的坟?
我一步一步走进去,马诺罗看见是我,惊唤了一声,放下工具向我跑来。
“马诺罗,我回来了!”我向他伸出手去,他双手接住我,只是又用袖子去擦汗。
“天热呢!”他木讷的说。
“是,春天已经尽了。”我说。
这时,我看见一个坟已被挖开,另外一个工人在用铁条撬开棺材,远远的角落里,站着一个黑衣的女人。“你们在捡骨?”我问。
马诺罗点点头,向那边的女人望了一眼。
我慢慢的向她走去,她也迎了上来。
“五年了?”我轻轻问她,她也轻轻的点点头。“要装去那里?”
“马德里。”
那边一阵木头迸裂的声音,传来了喊声:“太太,过来看一下签字,我们才好装小箱!”
那个中年妇人的脸上一阵抽动。
我紧握了她一下双手,她却不能举步。
“不看行不行?只签字。”我忍不住代她喊了回去。“不行的,不看怎么交代,怎么向市政府去缴签字——”那边又喊了过来。
“我代你去看?”我抱住她,在她颊上亲了一下。她点点头,手绢捂上了眼睛。
我走向已经打开的棺木,那个躺着的人,看上去不是白骨,连衣服都灰灰的附在身上。
马诺罗和另外一个掘坟人将那人的大腿一拉,身上的东西灰尘似的飞散了,一天一地的飞灰,白骨,这才露了出来。我仍是骇了一跳,不觉转过头去。
“看到了?”那边问着。
“我代看了,等会儿这位太太签字。”
阳光太烈,我奔过去将那不断抽动着双肩的孤单女人扶到大树下去靠着。
我被看见的情景骇得麻了过去,只是一直发冷发抖。“一个人来的?”我问她,她点头。
我抓住她的手,“待会,装好了小箱,你回旅馆去睡一下。”她又点头,低低的说了一声谢谢!
离开了那个女人,我的步伐摇摇晃晃,只怕自己要昏倒下去。
刚刚的那一幕不能一时里便忘掉,我扶着一棵树,在短墙上靠了下来,不能恢复那场惊骇,心中如灰如死。
我慢慢的摸到水龙头那边的水槽,浸湿了双臂,再将凉水泼到自己的脸上去。
荷西的坟就在那边,竟然举步艰难。
知道你的灵魂不在那黄土下面,可是五年后,荷西,叫我怎么面对刚才看见的景象在你的身上重演?
我静坐了很久很久,一滴泪也流不出来。
再次给自己的脸拚命去浸冷水,这才拿了油漆罐子向坟地走过去。
阳光下,没有再对荷西说,签字笔一次次填过刻着的木槽缝里——荷西·马利安·葛罗。安息。你的妻子纪念你。
将那几句话涂得全新,等它们干透了,再用小刷子开始上亮光漆。
在那个炎热的午后,花叶里,一个着彩衣的女人,一遍又一遍的漆着十字架,漆着四周的木珊。没有泪,她只是在做一个妻子的事情——照顾丈夫。
不要去想五年后的情景,在我的心里,荷西,你永远是活着的,一遍又一遍的跑着在回家,跑回家来看望你的妻。我靠在树下等油漆干透,然后再要涂一次,再等它干,再涂一次,涂出一个新的十字架,我们再一起掮它吧!我渴了,倦了,也困了。荷西,那么让我靠在你身边。再没有眼泪,再没有恸哭,我只是要靠着你,一如过去的年年月月。
我慢慢的睡了过去,双手挂在你的脖子上。远方有什么人在轻轻的唱歌——
记得当时年纪小
你爱谈天
我爱笑
有一回并肩坐在桃树下风在林梢鸟儿在叫
我们不知怎样睡着了
[[托马斯·曼中篇小说四篇 - 迷失威尼斯 by 托马斯·曼|https://www.kanunu8.com/book2/10974/196085.html]]
-----
以冯 · 阿申巴赫作为他的正式名字。二十世纪的某个春天的下午,他独自一人从慕尼黑的摄政王街的府邸走出来。几个月来,欧洲大陆阴云密布,形势险恶,令人惶恐不安。多年以来,作家在工作中一直保持着谨慎小心、果敢决断、精密周到、深入细致的态度。那天一上午紧张劳累、绞尽脑汁的工作尽管使他精疲力竭,同时又使他兴奋不已,直到吃完午饭,他仍然无法抑制内心激荡的创作冲动,或者按照西塞罗的说法,当时是思如泉涌。
由于体力日渐衰退,他非常需要平静的午睡,但这种情绪令他无法安然入睡。因此,喝完茶后,他决定到外面走走,希望新鲜的空气能让他重新恢复精神和活力,这样晚上可以好好工作一会儿。
经过几星期阴冷潮湿的天气后,到了五月上旬,好像仲夏已经来临了。虽然英国花园里树木的枝叶刚刚泛绿,可是天气已像八月般的闷热,市郊一带熙熙攘攘、车水马龙。不过,奥迈斯特的一些道路比较幽静,他沿着这里的道路前行,偶尔驻足眺望一下人来人往、热闹非凡的餐厅公园的景色。公园周围停着一些出租马车和华丽的私人马车。此时,夕阳西下,落日的余晖渐渐弱下来,于是他便穿过田野,从公园外围取道回家。他感觉有点累了,而且弗林公路上空又出现了暴风雨的征兆,便等着直接回城的电车载他回城。就在等电车时,他突然发现这个车站和周围完全被废弃,荒凉无人。不论在铺过地面的——那儿,电车轨道泛着亮光孤寂地向施瓦布地区延伸过去——还是弗林公路上,都看不到一辆车子。在石匠铺子的围篱后边,没有一点儿动静。石匠铺子里陈设着各种各样待卖的十字架、神位牌、纪念碑之类,宛如另一个杳无人迹的墓场。街对面是拜占庭式结构的纪念墓园,静静地立在微弱的余晖中。
建筑物前面的墙上,装饰着希腊式十字架和浅色图案,上面镂刻着对称排列的几行圣经碑铭,内容均和来世有关;例如 “他们正在进入天父之地”,或者是 “希望圣光永远照耀他们”。候车的阿申巴赫专心默读和欣赏着这些字迹,有一段时间,让自己整个思维在这些闪光的神秘事物中徜徉。当从幻想中走出来时,他突然看到护守在阶梯口的两只圣兽附近的门廊里站着一个人。这个人的外表看上去很不平常,这让他的思路完全走向了另一个方向。
不知道这个人究竟是穿过青铜门从厅堂里出来,还是从外边悄悄地溜到这里的。阿申巴赫没有深入地考虑这个问题,只是认为更有可能是第一种情况。这个人个子不高,体态偏瘦,下巴干净无胡须,圆圆的鼻子给人留下深刻的印象。他头发发红,奶白色的皮肤,满脸雀斑。很显然,他不是巴伐利亚人:因为他的头上那顶边缘宽阔平直的草帽,让他看上去像是一个带着几分异国情调的远方来客。当然,他的肩上紧扣着一个普通的帆布背包,穿着一件淡黄色的罗登呢防水上衣,左腋下挟着一件灰色外套;他的右手里握着一根底部包有铁皮的手杖,他把手杖斜撑在地面,双腿交叉,下身紧靠在手杖上。他仰着头,突出的喉结从运动衫里露出的骨瘦如柴的脖子上赫然呈现出来;他那长着红睫毛的无光泽的眼睛凝望着远方,中间两条平直而明显的皱纹与他那个短而粗的鼻子相互映衬,显得格外滑稽古怪。也许是由于他站的位置较高,因此给人一种盛气凌人的、大胆鲁莽甚至有点目空一切的感觉,当然这也可能是因为夕阳的余晖使他的表情有点扭曲,或者是因为他的面部有些畸形,比如他的嘴唇太短,从牙龈里露出一排长长的牙齿,在两唇间发着白色的微光。
阿申巴赫用有点好奇的目光凝神研究着这个外国人显然有点欠妥,因为他突然发觉那个人用好战的目光直楞楞地回瞪着他,充满着敌意,很明显是想迫使对方退缩回去。这让阿申巴赫略感尴尬,便转身沿着围篱慢慢走开,不再去看那个人。没过几分钟,他就忘记这个人的存在了。不知是那个外国人所散发的旅行者的气息对他的想象力起作用了,还是某种肉体因素或精神因素对他产生了影响:他惊异地发现内心有一种豁然开朗的感觉,有点混乱不安,同时滋生出想到远方旅游的幼稚的渴望,这种感觉非常新奇也非常强烈,以至于他把手背在身后,目不转睛地盯着地面,一动不动地杵在那里,思索着这种情绪和它的本质与目的。
这种意愿好像早已经被磨灭而消失殆尽了。这只不过是一种渴望旅行的情结罢了,没有什么。但它确实来得那么突然,那么强烈,令人心悸,甚至达到了幻觉的程度。作为他能够想象出的对人世间多样性的所有惊奇和恐惧的尝试,他看到了一幅巨大的山水画,一片热带的沼泽在烟雾弥漫的天空之下延伸,雾气蒸腾、广袤无边。这是一片人迹罕至的原始荒野,到处都是泥泞的沼泽和死水。这块岛屿上落叶日积月累,形成了厚厚的毯子,到处都是巨大的蕨类植物,繁茂无比。在潮湿、肥沃和鲜花竞相争妍的丛林中,四处挺立着毛茸茸的棕榈树,还有一些奇怪的没有固定形状的大树,树根从树干上长出来,伸到水里面,或者露在土壤外,伸向各个方向,没有什么规律。发出恶臭的绿灰色泉水上漂着奶白色、碗状的花朵;肩膀高耸、嘴形奇特、双腿细长的怪鸟站立在浅水上,无动于衷地向旁边瞧着。透过巨大的芦苇丛,传来了咔嗒的磨擦声和呼呼声,好像士兵们正在装备武器;旁观者认为他感觉到了这块未加限制的、充满危险的荒野中温热且恶臭的气息,这种气息好像盘旋在位于创造和毁灭中间的地狱的边境。在竹林深处节节疤疤的树干中,他一度相信一只老虎正蹲伏在那里,两眼闪闪发光——他感到内心因恐惧和神秘的渴望而颤动。最终,这些幻象消失了。阿申巴赫摇摇头,又沿着石匠院落的围篱走了起来。
过去——至少从他有机会享受到遥远的乡村逗留的种种好处时起——他一直把旅行当做一种必需的养生之道,有时不得不违背心愿去享受一下。由于自我和欧洲人的责任感以及创作的重任压在身上,他忙得喘不过气来,因此几乎无法拿出点精力和时间让自己成为享受外面花花世界的忠实拥护者。他完全满足于不离开自己的圈子甚至从来不必离开欧洲就可能获得地球上的任何知识。自从他的生命力渐渐衰弱,他的艺术家无法完成事业的恐惧感渐增时,他担心自己的时光已经耗完,工作即将半途而废时,他就几乎从未离开过这栋他将其视为家的城市以及他的乡村别墅,他在山区建造了那栋别墅,在那里度过多雨的夏季。
不过,很快,年轻时代养成的理智和自制力就把刚才那种心血来潮的念头给压了下去,他的内心渐渐恢复了平静。他打算先把自己赖以寄托的作品进行到某一阶段之后再去旅行,至于要拿出几个月工作的时间去世界各地漫游,这个想法看上去太不负责任了,与他的计划相去甚远,根本不值得认真考虑。然而,他非常清楚到底是什么使他产生了这么深切的痛苦。那是对距离和新奇事物的渴望,对自由的渴求,企图摆脱重担、达到忘我境界的热盼——他不得不承认,这是企图摆脱工作和刻板、冷淡及繁重日常事务的一种渴望,是逃避现实的一种冲动。尽管他热爱这项工作,也愿意承担那种令人身心疲惫、日复一日的斗争。这是一场坚韧顽强、自豪、久经考验的意志力和与日俱增的疲惫之间的斗争,没有人能够察觉到,而他的作品中也流露不出任何灵感枯竭的征兆。但是,弓弦不能绷得太紧,也不能轻易地压抑这样强烈激发出来的愿望,而且出去旅游放松看上去充分合理。他思考着自己的工作,想到今天不得不中止的努力,就像昨天一样,即使没有煞费苦心,也没有遭到沉重的一击,你仍然不得不屈服。他又开始思考这个问题,企图打开或解开这个疙瘩,但最后还是带着厌恶的情绪停了下来。这里并没有什么不可逾越的障碍,令他精神怠殆的原因是情绪低落、踌躇犹豫,这种情绪表现为对事物永远无法满足。当然,在青年时代,这种不满足被看做是天才的特性和本质,他一直试图控制这种情感,因为他知道人们容易因为接近完美或半接近完美而沾沾自喜、心满意足。难道这种被压抑的情感现在企图通过离开他来报复他,不愿再为他的艺术生涯增砖添瓦,同时还要夺去他在表现形式及内在含义上的一切快乐与欣慰吗?倒不是他创作出了不好的作品:由于经年的经验积累,他可以随时掌握自己的创作。但即使国民都崇敬这些作品,他本人却无法引以为荣,因为在他看来,他的作品缺乏充满热情的独创性,而这种独创性是欢乐的源泉,比任何内在的价值都有意义,能够为读者带来更多的快乐。他害怕在乡间度过夏天,因为在这个小屋子里,他感到十分孤独,只有为他准备伙食的女佣和侍候他的男仆和他在一起;他也害怕看到熟悉的山峰和悬崖,它们会把他团团围住,使他透不过气来。因此,他很需要换个不同的环境,临时找个休憩的地方,呼吸一下远方的新鲜空气,汲取一些新的血液,让这个夏天过得稍微满意些,以便创作出更多的作品来。这样,进行一次旅行可能会让他感到心满意足。不必走太远,当然不必走到有老虎的地方去。在卧车里度过一个晚上,在有趣的南方的任何一个平常地方度过三四周的假期,痛痛快快地休息休息……
就在他浮想联翩时,电车叮叮当当的响声渐渐逼近翁格勒街。上车时,他决心今晚专心研究一下地图和旅行时间表。在月台上,他突然想起看看刚才那个戴草帽的游伴,他的伙伴,因为这片刻的逗留让他做出了新的决定。可是那个人已经不在他刚才的地方,也不在车厢或是下一个车站上。总之,那个人的去向成了一个谜。
古思塔夫 · 阿申巴赫出生在 L 城——西里西亚省的一个乡村小镇。
他是一个高级法官的儿子,他的祖辈都是军官、法官或是行政官员,在为国王和国家的服务中度过严谨、体面而朴素的生活。先辈当中只有一位的精神生活显得比较活跃——那是一位牧师;而诗人机灵和敏锐的特质则来自他母亲的一方。他的母亲是一位波希米亚音乐指挥的女儿,这也带给了他具有某些异国特征的相貌。官僚的朴实、责任感与热情、冲动的结合造就了这位独具一格的艺术家。他是那篇描写腓特烈大帝生活的伟大史诗的作者,这部史诗思路清晰、笔调鲜明、气势磅礴;他也是一位严谨勤勉的艺术家,精心创作了长篇小说《马亚》,这部小说形象丰富,人物命运多舛,但都紧密地归结到了一个主题思想上;他还是一位伟大的创作者,创作了伟大的叙述小说《不幸的人》,告诉应该心存感恩的年轻一代,即使达到了知识的巅峰,仍然可以保持道德上的坚定性。最后,这位作家创作了题为《艺术与智慧》的论著(他最成熟时期的代表作),这篇论著热情洋溢、激动人心、结构严谨、极富说服力,被评论家们拿来与席勒的《论素朴的诗与感伤的诗》相媲美。
阿申巴赫从最开始就一心追求名誉,因而虽不早熟,但由于写作技巧高超,笔调果敢犀利,很早就表现出了出色的天赋。还是一名学生时,他已经名声大噪。十年以后,他已学会坐在写字台面前,用优美简练、意味深长的词句处理成批的信稿,表达其善意(因为一个成功、有威望的人每天都会遇到很多要求),使自己的英名保持不衰。到四十岁时,尽管当时工作的压力与种种变迁已经使他疲惫不堪,他还不得不每天处理一批来自世界各地的信件。
由于他的才能既不同凡响又毫无怪异之处,因此赢得了大众的信赖,也同时赢得了更具识别力的阿谀奉承之人及过分苛刻之人的信赖。从青少年时代起,各个方面的人都希望他能够成就一番非凡的事业,因而,他从来就没有年轻人的闲散无聊和疏忽大意。三十五岁那年,他在维也纳病倒时,细心的观察家这样评论他:“看,阿申巴赫的生活老是这个样子,” 然后观察家握起左拳头,“但永远不可能像这个样子。” 说完,他把手张开,漫不经心地从休闲椅上垂下来。这确实是事实,他并不是天生精力旺盛,只是由于职业要求才会老是勤勤恳恳地努力工作。
遵从医嘱,这个男孩从学校回到家中,在家里接受教育。他没有同伴,只能孤独地长大成人,其实他已经认识到自己属于哪种类型的人,这种人不缺少才能,但缺少才能发挥所必需的健康体魄。也就是说,这种类型的人的才能很早就会发挥出来,但通常很难维持到晚年。不过,他最喜欢的格言是 “坚持下去”——在那本腓特烈大帝的小说里,他从这位大帝的身上看到了这一格言的典范,认为这句话集中体现了工作中美德的本质。同时,他非常希望自己能活得久一些,因为他总是认为,一位艺术家只有在人生的各个阶段都取得成功,才可以称得上是真正伟大、真正值得尊敬的人。
由于柔弱的肩膀上不得不担负起才华所赋予他的责任,而且他本人希望能够在这条路上有所建树并取得长久发展,因此,纪律对他来说显得非常重要——幸运的是,他从父亲的家族这边继承了这种素质。在其他人仍在纵情狂欢、进行着迟迟不能实现的幻想的时候,他就已经开始了严格自律的生活习惯,而在四五十岁的时候,他还仍然保持着这种习惯:每天天不亮用冷水浸湿胸部和背部,然后集中精力,在烛光中将晚上睡觉时获得的创作灵感记录下来,一写就是两三个小时。这也难怪,那些没有相关知识的局外人认为,《马亚》中的世事或者描写腓特烈大帝波澜壮阔的一生的鸿篇巨制,都是作者在某种力量的鞭策下一气呵成的结果。事实上,这些作品来自作者每天无数灵感的片段。由于作者多年来一直凭着顽强的意志,坚持不懈地辛勤努力,呕心沥血,把自己最宝贵的时间奉献给他的创作事业,因此,这些作品无论从整体或细节来说,都表现得非常完美。这些都表明了他的这种美德的过人之处。
要想使一部不失深度与持久性的智力成果也能立刻发挥影响,在创作者的生活与同时代的广大民众的一般生活必须存在着深远的联系,或者彼此间能引起共鸣。普通民众并不懂得为什么会赞赏某个艺术作品。
他们并不是真的有鉴别力,只是感觉作品中有无数的优点能证明他们对作品的喜欢是理所当然的。但他们不明白自己的这种赞扬的真正潜在的原因只是同情而已。阿申巴赫曾经在一次不太引人注目的场合中指出了这个问题,他说真正伟大的作品来自各种各样的境遇中,来自忧患和痛苦、贫困、放弃、疾病、罪恶、激情以及成千上万的障碍。这不仅仅来自观察——这来源于他生活的经验,就是他赖以生活和成名的规则,是他工作的关键。如果说这也是他的道德风貌和最值得纪念的品格特征,也并不是什么令人惊奇的事情。
在作者的作品中,总是反复出现的他喜欢的英雄类型,对此,一位目光敏锐独到的评论家曾经这样分析:这个英雄应该是 “充满智慧,有男子汉气概,宠辱不惊,危难之中巍然屹立,镇定自若”。这种说法美丽、充满才智、十分准确,但却有点过于被动和消极。因为在压力面前保持优雅远强于只是去忍受。在痛苦中保持着优雅的风范是一种积极的成就,一个确实的胜利,圣塞巴斯蒂安的形象是其中最美好的象征——即使在整个艺术中不一定是这样,但在写作艺术中肯定是这样的。让我们透视作品中的世界,可以看到:隐藏内心腐化堕落的一流的自制力,直到死亡时仍然窥探世界的衰弱的躯体;因暴躁和情欲而扭曲的丑陋依然可以将闷烧的火种点燃,化作一团纯洁的烈火甚至在美的王国中达到至高无上的境界。即使身体虚弱无力,却依然能够从心灵深处获得力量,恢复活力,这种力量足以让整个衰退的民族在他的感召下虔诚地扑倒在十字架下;在做着空洞、刻板的工作时,仍然保持着亲切优雅的举止;充满欺诈和危险的生活;令人身心疲惫的渴望和煞费心机的阴谋诡计:想一想所有这些苦难和其他更多的痛苦,人们肯定会质疑,在这种产生于脆弱当中的英雄主义之外,是否还存在着其他类型的英雄主义。什么类型的英雄主义比这种英雄主义更切实际、更符合时代的标准?古斯塔夫 · 阿申巴赫是所有那些辛勤劳作、心力交瘁、濒于崩溃边缘,但仍然坚持不懈的人们的代言人,尽管这些道德家们身材削瘦、生活窘迫,但仍然凭着顽强的意志力和自己的聪明才智,使自己的作品至少在一段时期内产生影响力。这样的人很多,他们是我们这一时代的英雄,他们在阿申巴赫的作品中看见了自己,他赞美他们,为他们唱颂歌——而他们则感激他,传扬他的名誉。
他曾经年轻幼稚,不识时务,屡次犯错,纵容自己,不论是在言语中还是著作中,经常冒犯他人,违背常理,不够审慎。但他毕竟赢得了荣誉,而荣誉是每一个天才人物的内在驱动力,有人甚至说,他的一生都是有意识地、顽强地为荣誉而不懈努力,把所有的犯忌与讥讽都抛诸脑后,只是不停地努力攀登。
市民群众感兴趣的是生动活泼而不是形式完整、结构严谨的描写,但热情奔放的青年,却只是为作者提出的问题所吸引:阿申巴赫像任何青年人一样,热衷于提出问题。他崇奉理智,在知识的土壤上辛勤耕耘,收获了种子;他摈弃神秘主义,怀疑天才,对艺术嗤之以鼻——不错,正当他的作品令信徒们沉浸其中、充满活力、推崇备至时,他,这位青年艺术家,却对艺术和艺术家们有争议的本质抱着玩世不恭的态度,这让二十岁的青年们大惊失色。
但是看起来,没有什么能够比尖锐而痛苦的体会知识能够更迅速地让一颗崇高而有能力的心灵萎缩下去。确实,比起大师们深邃而果断的决定,年轻人坚韧不拔、苦心追求的目标显然不值一提。当大师发现这些知识会使他的精神麻痹、意志削弱,或者丧失体面、一文不值时,他就会否定它、排斥它甚至完全地忽视它。那篇著名的小说《不幸的人》不就是对当代颓废心理的大肆谴责吗?小说里描述了一个栩栩如生的软弱愚昧的无赖,挥霍无度,意志薄弱,因为胆怯而将自己的妻子推到一个年轻人的怀抱中,并将这作为虚度自己后半生的借口。
作者用颇有力度的语言痛斥了受遗弃的人,对所有道德上的犹豫不决表达了深切的痛恨,对自作自受所招致的苦难绝不同情,他认为那些同情的话语毫无意义,比如说 “了解一切就是原谅一切”。这里开始的是 “重新再现公正无私的奇迹”,这在作者稍后的一次谈话中表露出来。
这真是一种奇特的思维模式。难道是由于这种 “复活”,由于新发现的高贵和严谨,才使得他对美感的发现得到绝对的提高,使他在写作形式上变得高尚纯净、简洁明澈、结构合理,并且从那以后,他的作品开始具有了明显的名家大师和古典主义的风格吗?然而,没有知识的道德果敢,没有消融或阻碍感的德行,难道不是又把世界和人们的心灵过于简单化,看成是非黑即白,从而导致了一种趋向,即只问什么是邪恶的,怎样去制止邪恶?这样,不是造成了形式上的两面性吗?难道道德和超道德不能并存吗——道德是纪律的一种表现,超道德甚至不道德则意味着对道德漠不关心,力图让德行屈服在自己的统治之下?
管它会是怎么样!发展也是一种命运,为什么公众人物应该与那些默默无闻的普通民众走相同的道路?当一种非凡的才能成熟起来,放弃放荡的过去,习惯清楚地感受智慧的尊严,接纳了充满轻率、独自承受的痛苦和斗争——这种痛苦和斗争降低了它在民众中的力量和荣誉——的孤独的道德观念时,人们就会发现这些无穷无尽的奇思怪想是多么无聊,并经常去奚落它。除此之外,在天才本身的成长过程中,有多少风险、怨恨和放纵啊!随着时间推移,古斯塔夫 · 阿申巴赫的文章逐渐抛弃了早年的大胆直言的犀利风格和微妙清新的色彩,慢慢变得有些官腔和说教意味,变得一本正经、循规蹈矩、精雕细琢、形式规整,甚至有些公式化。像众所周知的路易斯十六的传说,这位年事渐长的作家在文体方面摈弃了一切基础和普通的字句:也就是在这个时候,教育部把他的一些著作选载到教科书中。当一个刚即位的德意志君王在 “腓特烈大帝史诗” 作者的五十寿辰为他授予贵族头衔时,他认为受之无愧,并没有表现出反感。
他四处奔波了几年,寻找安居的地方,后来,选择了慕尼黑作为永久的栖身之处。在那里,市民们对知识分子表现出罕见的尊重,他一直生活在这些荣耀中。他和一位拥有良好家庭教育的家族出身的姑娘结婚,但在短暂的幸福生活之后,妻子去世了。他有一个已婚的女儿,没有儿子。
古斯塔夫 · 冯 · 阿申巴赫中等身材,黑头发,不留胡须。与纤弱的身材相比,他的脑袋显得有点大。他的头发向后梳,分开处比较稀疏,只有鬓角处的头发浓密苍白,露出了皱纹密布、疤痕累累的高额头。鹰钩鼻子上架着一副金质眼镜,显出一副贵族气派。他的嘴大而柔软,有时会突然紧闭起来;他的面颊狭窄满是皱纹,形状不错的下巴稍微有点裂开。变化多端的命运在他总是歪向一侧的额头留下了印记,不过使作家面容憔悴变形的不是繁重劳碌的生活,而是艺术。在这表情后,诞生了腓特烈大帝和伏尔泰关于战争问题的精妙的言论和巧妙的应答。透过眼镜疲惫地凝望着世界的眼睛,曾经亲眼目睹过七年战争期间医院中血淋淋的恐怖场景。即使从个人角度来讲,艺术是生活的升华,它能给人带来更大的快乐,但也能更快地消耗快乐。艺术在它的信奉者面上镌刻着幻想的和精神上的冒险经历,即使在最幽静恬淡的气氛中,它也会产生某种一丝不苟、吹毛求疵、筋疲力尽、神经过敏,即使是最汹涌的激情和快乐也无法对它产生影响。
从那次散步之后,一些日常琐事及文学事务让这位急于出门的旅行者又在慕尼黑耽误了两个星期。最后,他让人准备好乡间别墅,以便四周内回来后可以住上。这样,在五月中下旬的一天,他乘夜车去了的里雅斯特。他在那里仅逗留了二十四小时,第二天便乘船去了普拉。
他所寻求的只是新奇的、与平常不相干的事务和境界,实际上这个目的非常容易达到。因此,他在离伊斯特里拉海岸不远的亚得里亚海岛上住了下来。当地居民衣着光鲜却很俗气,说着语调怪异的外国语言。
面向着广阔大海的悬崖峭壁形态独特,引人入胜。但不幸的是,那里经常下大雨,天空沉闷,令人十分压抑,而且旅馆里都是目光狭隘、见识浅薄的奥地利人,几乎很少有机会与大海进行平静、轻松的交流,因为只有松软的沙滩才能真正让人享受这种感觉。这让他感到不快,他感到这里并不是理想中的目的地。他的内心焦躁不安,他不知道自己该去哪里。他仔细研究了客船的行进路线,四处搜寻,突然,令他吃惊和期待的目的地展现在他的面前。当一个人想去看一些无与伦比、与众不同的浪漫之地时,他应该去哪里呢?毫无疑问,他应该去那里的。可他现在在这儿干嘛呢?他最初犯了一个错误。他立刻毫不犹豫地终止了原来在岛上的计划,在这个岛上待了十天左右之后,一艘快艇在薄雾霭霭的清晨把他和他的行李带回了军港,到达这里后,他直接经过栈桥登上了一艘开往威尼斯的船甲板上。
这是一艘意大利轮船,由于使用了多年,已经陈旧过时了,显得暗淡无光、又脏又黑。一上船,阿申巴赫就被一个脏兮兮的驼背的船员热情地引到一间洞穴状的小舱内。在小舱的桌子后,坐着一个歪戴着帽子、叨着烟、长着山羊胡子的人,让阿申巴赫想起了某个老式马戏团的指挥。
他用职业性的从容自若的神态登记旅客的国籍,并为他们分发船票。
“去威尼斯!” 他重复了阿申巴赫的申请,伸出手臂,将羽毛笔伸到斜摆着的墨水瓶中蘸了蘸。“到威尼斯的头等舱!给你,先生!” 他胡乱写了一通,从一只匣子里倒出一些蓝色的沙子,撒在他写的东西上,然后把沙子倒到泥罐里,用焦黄的、瘦骨嶙峋的手指把纸折好,重新写起来。“这个地方选得好!” 他一面写,一面喋喋不休地说:“啊!威尼斯!多美的城市!对有教养的人来说,这个城市有一种不可抗拒的吸引力,因为它过去的光辉历史以及当前的魅力!” 他动作敏捷地分发船票,并且不断地说着一大堆空话,让人感觉他在招摇撞骗,好像担心那位旅客会动摇去威尼斯的决定。他迅速算好账,像赌场里的管理人一样,动作麻利地把找的钱放在污迹斑斑的台布上。“先生,旅途愉快!” 他边说边戏剧性地鞠了个躬,“很荣幸您乘坐这班轮船!…… 下一位!”
他抬起胳膊喊道,好像还有一大批旅客鱼贯地等在门口,实际上再也没有什么人需要买票办手续了。于是,阿申巴赫返回到甲板上。他把一只手臂靠在栏杆上,望着在码头上徜徉的、要目送轮船离开的闲散的人群,还有和他同船的旅客。二等舱的乘客把箱子和行李包当座位,聚集在前甲板上。头等舱的旅伴中还有一群青年,看上去像是普拉城里商业部门的伙计,他们聚在一起嬉笑,对意大利之行兴高采烈。
他们大声谈论着自己的工作,喋喋不休,并不时哄堂大笑,手舞足蹈地模仿着那些挟着公文包沿港口大街去办公事的同事们;而那些人也挥动手杖做出回应。其中有一个人穿着非常时髦的淡黄色夏衣,系着一条红领带,戴着一顶显眼的向上弯曲的巴拿马草帽;他欢呼雀跃,扯开嗓门直叫,声音比任何人都响。当阿申巴赫定神细细打量他时,才吃惊地发现他可不是一个青年人。毫无疑问,他年龄很大,嘴角和眼角布满了皱纹。
他面颊上的那层淡红色不过是化妆的结果;装饰华美的巴拿马草帽下面棕色的头发,其实是假发;脖子的皮肉松驰,露出青筋,胡子染了颜色;他笑时露出的一口黄牙,看上去是一副便宜的假货;两个食指上都戴着印章戒指,一双手完全像老年人一样。阿申巴赫瞅着这个老家伙和他的同伙,心里泛起了一阵反感。难道他们不知道或者没有注意到他已是一个老人,不应该穿着这种绚丽而俗气的衣服也不应该假扮成青年人的样子?但看上去什么也没有发生,好像他们对混在中间的这个老头儿已习以为常,把他看做是同一类人,一点儿也不反感地回应他打趣的推搡。
这是怎么回事?阿申巴赫把手放在前额上,闭上了眼睛。他的前额发热,说明觉睡得太少了。他感觉,现实正在变得不真实,像是进入了无法说明的梦境一般,可能只要他稍稍遮一会儿脸,然后再张开眼睛看,这一切似乎都会停止。但正在这时,他猛然有一种飘荡的感觉,于是十分震惊地睁开眼睛,原来,灰黑笨重的船体已慢慢离开了码头。随着引擎前后交替运动,码头与船身之间污浊的、闪闪发光的水带慢慢扩展,经过一番笨拙的操作后,汽船开始昂首驶往大海。阿申巴赫走到右舷,驼背船员已经为他准备了一把躺椅,同时,一个穿着油迹斑斑的工作服的服务员也在等候他的吩咐。
天灰蒙蒙的,风中带着潮湿的大海的气息。码头和小岛渐渐后退,陆地慢慢在视野中消失。一团团灰尘,被湿气浸透,纷纷落在了刚洗过、还没有干透的甲板上。大约一小时后,甲板上支起了帐篷,因为开始下雨了。
我们的旅行者裹上外套,把书放在膝盖上,打发着时光,时间在不知不觉中流逝。雨停了,亚麻篷布也开始卸下。天边一望无垠。在幽暗的苍穹下,四周全是空旷寂寥、无边无际的大海。可是在空旷无边的空间里,我们失去了时间的概念,在这无形的空间中也迷失了方向。奇怪的、模糊不清的身影,年老的花花公子,下甲板里那个长山羊胡子的管理员,这些形象举着模糊的手势,发出梦呓般的胡言,在他的脑海里晃来晃去。
最后,他睡着了。
中午,他被叫到一间走廊模样的餐厅里吃饭,餐厅紧靠着他的铺位。
他在一张长桌子上吃套餐,桌子另一端坐着商行的那些伙计,其中还有那个老头。他们从十点钟起,就和快乐的船长举杯痛饮,现在已经喝得很多了。这顿饭很乏味,他三口两口吃完就离开了。他想到外面去看看天空:或许此时威尼斯正在远处闪现。
他一心想见到的没有什么,只是那个一直在他心目中保持着光辉形象的美丽的城市。但是天空和大海上仍然阴云密布,灰蒙蒙的,不时还下着雾蒙蒙的雨。慢慢地,他意识到可能通过水道去威尼斯,和他以前通过陆地去那里,见到的应该完全不同吧。他站在前桅边,眺望着远方,眼巴巴地等着陆地的出现。他想起了那个忧郁敏感的诗人曾看到过这些他梦中的钟楼和圆顶屋从波浪之中缓缓升起的景象;静静地背诵起那些充满崇敬、快乐和忧愁的诗句,并被作者的这种情绪深深感动。尽管比起当时来,他现在心情沉闷,躯体疲惫,但他非常想知道是否可以再一次拥有欢天喜地和混乱迷惘的状态。
右边,略微有点坡度的海岸终于出现了,渔船令大海活跃起来,利多进入了视线,汽船从右边经过,慢慢地穿过了相同名字的海峡,然后靠近礁湖,在一排杂乱破旧的房子前停了下来,清理卫生的驳船在这里等着它。
一小时过去了,终于开来了两艘船,一艘船到达了目的地,而另一意大利威尼斯附近的一个小岛,著名的游乐地。
艘还没有过来,尽管并不赶时间,但不久,人们就感到不耐烦了。这时,嘹亮的军号声从水面上传了过来,吸引了普拉年轻人的注意,在刚喝过的阿斯蒂酒的刺激下,他们纷纷来到甲板上,向正在那里操练的步兵们欢呼雀跃。可是那个衣着太过讲究的老头和年轻人混在一起的样子实在是不和谐。他年老衰退的大脑在抑制酒精方面显然无法与年富力强的小伙子们相提并论,此时,他已经完全醉了,目光痴呆地向四周张望,瑟瑟发抖的手指中夹着一支香烟,摇摇晃晃,简直无法保持平衡,前俯后仰。
如果再走一步,恐怕都会跌个跟头,因此他一动也不敢动,但仍然表现出可悲的骄傲自大,拉住任何一个走到他身边的人,口吐脏言,时而用目光交流,时而哈哈傻笑,并伸出那只戴着戒指的干巴巴的食指去戏弄别人,显得非常愚蠢可笑,而且还经常莫名其妙地用暧昧的姿态舔着嘴角,令人一阵作呕。看到这个情形,阿申巴赫感到非常生气,又产生了一种非现实的感觉,好像周围的世界发生了小而明确的变化,变得光怪陆离、奇异可笑。正在这时,机舱的引擎砰地一声发动起来,他无法再仔细地琢磨这种感受了。轮船经过圣马利河道,返回它的航线了。
因此,他再次把注意力转到了最令人惊叹不已的码头,绚丽多彩的建筑群结构令人目眩,这是共和国为前来的船员们兴建的令人肃然起敬的景观:宫殿雄伟,叹息桥庄严,海岸附近耸立着刻有狮子和圣像的圆柱,圣马科教堂的侧翼高高耸起,绚丽动人,一眼就能看到圣马科时钟。
他环顾四周,感到从陆路搭火车到威尼斯好比穿过后门的通道进入了宫殿,只有像他现在这样乘轮船穿过大海来到这里,才能享受到这个城市难以想象的美丽全貌。
引擎停了下来,一些贡多拉划了过来,上岸的舷梯也放了下来,海关人员登上轮船,履行自己的职责。旅伴们现在可以下船了。阿申巴赫想雇一条贡多拉。他打算找个海边的房子住,得把行李运到往返威尼斯和利多的汽船码头上。他们满足了他的愿望,并把他的要求向水面上传达,水面上,船夫们正用本地方言争吵着。由于箱子需要费很大力气才能从梯子般的扶梯上拖下来,他无法下船。就在耽搁的几分钟时间里,他又遇到了那个可怕的老头的纠缠。老头儿已经喝得神志不清,非要向这位外国人道别。“祝您在这里过得愉快,希望你不要忘记我们!尊敬的先生!” 然后他夹杂着法语,喃喃地说,“再见、请原谅、早安!” 他流着口水,眨巴着眼睛,舔着嘴角,把下巴上染色的胡子弄得乱糟糟的。“请代我们问好,” 他把两个手指放到嘴边,继续嘟哝着,“请代我们向你的情人问好,向那个最可爱、最美丽的可人儿……” 说到这里,他上面的假牙突然掉到了舌头上,阿申巴赫赶紧溜之大吉。“向你的情人、最美丽的情人问好。” 当他从扶梯上下来时,背后传来了空荡荡的、有点含糊不清的声音。
当一个人第一次坐上威尼斯的贡多拉,或者长时间不坐以后再登上它,免不了感到略微不安,内心涌起一丝神秘的愤恨和颤抖,估计没有人会例外吧?这种奇怪的交通工具看上去从更善于幻想的年代流传下来后就一直没有改变过,它被漆成通常只有棺材才会有的奇怪的黑色,让人想起在深邃的夜幕中那些悄然进行的犯罪勾当;而且,它会让人想起死亡,想到灵柩,想到阴暗单调的葬礼和静寂的遗体告别仪式。这种小船的座位是漆得像棺木一样的、连垫子也是黑油油的扶手椅,你是否注意到,这原来是世界上最柔软、最奢华、最舒适的座位?当阿申巴赫把行李整整齐齐地堆在对面的船头上,在船夫脚下坐下来时,他马上意识到了这一点儿。这时,摇桨的船夫们还在吵吵闹闹地争执,声音粗哑,含糊不清,同时还做着威吓性的手势。但这座水城异乎寻常的寂静,似乎把他们的声音都吸收起来,然后散播到水面上了。港口里十分暖和。热风吹了过来,轻轻地拂在他的脸上,舒服宜人。我们的旅行者悠闲地坐在柔软的坐垫上,闭上眼睛,享受着这种不同寻常的、美好的休闲时光。
他想,这个旅行很短暂;唉,要是能一直这样多好呀!在船身轻微的颠簸中,他感到尘世的喧嚣和嘈杂似乎都离他远去了。
周围一直是那么安静啊,而且越来越安静!除了船桨拍打水的哗哗声,波浪拍打船头形成的空洞的啪啪声外,什么也听不到。船头竖立着,模糊不清像一支长矛插在水中。除此之外,还可以听到第三种声音,那是船夫发出的低沉的喃喃声——那是他在摇浆时从紧闭的齿间发出的喃喃自语。阿申巴赫抬起头,不免有点困惑,他注意到周围的水面越来越宽,船正驶向大海。看起来,他不应该过于乐观放松,实现自己的愿望可能还要花费一些工夫。
“请划到汽船码头去。” 他稍微转身说。船夫的喃喃声停了下来,他没有听到回答。
“请划到汽船码头去!” 他重复了一遍,把身子转过来,向上看了看船夫的脸。船夫正站在位置比他稍高的身后,铅灰色的天空下赫然耸立着他的身影。这个人的长相不招人喜欢甚至看上去有点凶,穿着蓝色的水手服,系着一条黄腰带,戴着一顶变了形的草帽,帽子边缘已经松散开来,斜挂在头上。从面相上极短而硬的鼻子下一抹淡黄色卷曲的胡子来看,他不太像意大利人。尽管他的身材相对纤弱,看上去并不太适合他的工作,但每次划桨时,他都使出全身力气,看上去精力非常充沛。
有时,由于用力过度,他嘴角翘向后面,露出一排雪白的牙齿。他盯着客人,皱了皱淡红色的眉毛,用坚决的、几乎粗鲁的语调冲着乘客说:“先生打算去利多。”
阿申巴赫回答说:“是的,但我只想让船把我送到圣马科广场,我想在那里乘小汽艇。”
“您不能乘小汽艇,先生。”
“为什么不能?”
“因为小汽艇不能载行李。”
他是对的,阿申巴赫想起来了,便不说话了。但这个人行为粗鲁、略显自负,对待客人一点儿也没有礼貌,这让他简直无法忍受。他接着说:
“这是我的事,或许我可以把行李寄存一下,你摇回去吧。”
船夫一声不吭。船桨仍在汨汨地划着水,波浪闷声闷气地拍打着船头。喃喃声和嘀咕声又开始了:船夫开始在齿缝里自言自语。
应该怎么办?独自一人与这个怪异叛逆、一意孤行的人在水面上,我们的旅行者不知道该如何让对方按自己的意愿行事。如果他不像现在这么执拗,他该休息得多么舒服呀。他不是希望航行能永远持续下去吗?
看来,最明智的办法莫过于顺其自然,而且,这样做显然也是最舒服的。
突然,黑色的矮座椅让他一阵麻痹,身后的那位专横的船夫摇着桨,椅子随着船桨左右摇摆,他感觉有点倦怠。这时,阿申巴赫的脑海中突然闪过一个念头,也许我落入了歹徒之手,但此时,他却无法集中精力,采取积极的防卫措施。更麻烦的可能是他的目的只是为了敲诈勒索。一种责任感,或自尊心——也可以说是尽力阻止此事的某种意念——让他振作精神,进行再一次努力。他问:“你想要多少钱?”
那个船夫从上面看了看他,回答道:“反正你会付钱的。”
很明显,对于这句话必须得有所回复。阿申巴赫干巴巴地说:“如果你把我送到我不想去的地方,我就不付钱,一个子儿也不付。”
“你想去利多。”
“但不是搭你的船去。”
“我是个好的船夫,先生。我会把你舒服地送到那儿的。”
这话倒是不错,阿申巴赫想了想,又放松下来。“你确实划得不错,即使你想要我的钱,即使你用船桨猛击我,把我杀了,你还得替我好好划船。”
但这种事情并没有发生。甚至出现了一些同伴,有一艘满载载歌载舞男男女女的船在吉它和曼陀林的伴奏下正在欢声歌唱,莽撞地向小船靠过来,本来平静的湖面立刻荡漾起歌曲,这是在向他们卖艺。阿申巴赫把钱币扔到他们伸过来的帽子里,他们静了下来,把船摇走了。这时,再一次响起了船夫的喃喃自语声。
就这样,船继续向前驶去,一艘驶向城里的汽艇经过,激起的水浪使小船颠簸起来。两个市政官员背着手,面向着礁湖,在岸边踱来踱去。
阿申巴赫在一个手里拿着抓升钩的老人的帮助下,离开小船上了岸,威尼斯的所有码头上都有这样的老人。因为手头没有足够的零钱,他到码头附近的一家旅馆里兑换一些,以便按照自己的想法付给船夫钱。他在大厅里换好钱,返回码头,发现行李已经放在码头上的一部手推车里,贡多拉和船夫已经无影无踪了。
“他已经溜走了。” 那个拿抓升钩的老头说,“他是一个坏人,没有执照,先生,他是唯一一个没有执照的船夫。其他人刚才打电话过来,他看到我们打算抓他,就逃跑了。”
阿申巴赫耸耸肩膀。
“先生免费乘坐了一次。” 老人说着,把帽子递了过去。阿申巴赫扔了一些钱币进去。他吩咐把这些行李送到旅馆里,跟着手推车穿过一条两边开满白花的林荫道,林荫道两边有很多客栈、百货店及提供膳食和住宿的地方。这一条路一直横穿小岛到达海滩。
他沿着花园的草坪从后面走进宽敞的旅馆,穿过大厅来到办公室。
由于已经预订好,因此他得到了礼貌和周到的接待。经理是一个个子矮小、说话和气、态度殷勤的人,长着黑胡须,穿着法国式的双排扣长礼服。
经理亲自陪他乘电梯到三层,把他领进房间。这是一个舒适的房间,樱桃木制成的家具,房间里装饰着桂花,香气扑鼻,高大的窗户面向着大海。
经理走后,他走到一扇窗户旁,观看着景色。这时,有人把他的行李搬了进来。此时,正值午后,窗外的沙滩上空无一人,阳光没有照射到的大海正好涨潮,连绵起伏的波浪一阵阵涌向海岸,发出有节奏的拍打声。
比起那些更合群的人来,个性孤独、沉默寡言的人在观察和感受上没有那么清晰,但却更为深刻,更加与众不同。他的想法更为真实,更加奇特,而且从来没有一丝忧伤之情。有些景象和感受,在别人那里可以一笑置之或三言两语就可轻易做出结论,而在他这里,却会一直盘踞在脑际,久久无法忘怀;而且会在沉默中变得更加意味深长,更加重要,同时成为经验、冒险精神以及情感。孤寂能产生独创精神,酝酿出敢作敢为、令人震惊的美丽的诗作。但孤寂也会促成相反的东西,会养成人们不近人情、荒唐怪僻的极端性格,也会使人萌生非法之念。因此,旅途中的种种不寻常的景象依然令这位旅行者久久无法平静——那个奇装异服、鲁莽地和他谈论情人的面目可憎的老头儿,那个没有拿到船费的船夫。尽管这些都不妨碍他的理智,却也无法给他任何真正的精神食粮,但从本质上说,这些都是些怪异的现象,这种矛盾令他内心困惑不安。
不过在这样的心绪中,他还是举目眺望大海,为这么轻易和快速地到达威尼斯,感受到这里的文化而倍感高兴。过了一会儿,他转过身,洗了洗脸,让女服务员过来帮着布置一下,以便住得更舒服,然后一个穿绿色制服的瑞士电梯工开着电梯把他送到楼下。
他在朝大海的阳台上喝着茶,然后走到下面,朝着伊克塞尔斯奥宾馆的方向散步,走了好长一段距离。当他返回来时,已经到了吃晚饭的时间。他慢条斯理、小心谨慎地换下衣服,去餐厅吃饭,到那里后才发现他仍然来得太早了,饭店里许多客人聚集在休息室里等待着吃晚饭,大家彼此互不相识,装得很冷淡,气氛有点压抑。他拿起一张报纸,在里面的一张大椅子上坐了下来,察看着周围的同伴。这些人看上去举止文雅,令人惬意,与早些时候在岛上见到的那些人迥然不同。
这里有一种令人眼界开阔的感觉,大家都压低了声音,操着不同的语言交流着。到处都是文明世界的夜礼服,使得这里不同的人形成了一个有机的整体。你可以看到拉长面孔的干巴巴的美国人,前簇后拥的俄罗斯大家庭,英国的太太们,有法国保姆陪伴的德国孩子等。宾客中大部分是斯拉夫人,他的旁边,有人在讲波兰话。
在一张小桌子旁,坐着一群由家庭女教师照看的青少年:其中三个是少女,在十五到十七岁之间,还有一个大约十四岁的男孩,头发长长的。阿申巴赫惊讶地注意到这个男孩儿长得是如此完美。他的脸色苍白,神态优雅,蜜色头发,鼻子挺拔,有一张迷人的嘴。表情纯净圣洁,非常迷人,让人想起希腊艺术鼎盛时期的雕塑。所有的一切看上去都完美无比,阿申巴赫觉得无论在自然界或造型艺术中,都从未见过这样一个吸引人的作品。还有令他吃惊的事,从孩子们的穿着和举止上来看,他们的教育方针形成了极其鲜明的对照。三个姑娘穿着朴素甚至可以说影响了她们的整体形象,其中最大的一个看上去已经成人。她们穿着统一尺寸的修女式样的制服,不太合身,翻转的白色衣领是身上唯一的亮色。
这身装束把身材上的任何曲线都给掩盖了,显得十分压抑。平滑的头发紧贴在头上,没有任何表情,让她们的脸蛋显得毫无生气。这肯定是母亲的杰作,很显然,她并没有把对三位姑娘这种学究式的严格要求,强加到男孩子身上。他肯定一出生就得到了格外的宠爱。家里人显然不愿意剪掉他引人注意的头发,像拔刺男孩的雕塑一样,他的头发蜷曲在前额上,垂到耳朵上甚至垂到了颈背上。他穿着一件英国的水手服,折起的袖子上端稍微收紧,正好包住了孩子般精致的关节和纤弱的手腕。
衣服上的丝带、网眼和刺绣,让这个娇小的身躯看上去带了几分阔气和骄纵。他坐在那里,阿申巴赫只能看到他的侧面。他的一只脚放在另一只脚前面,一只肘部靠在柳条椅的扶手上,一只手托着腮帮儿,看上去神态悠闲,完全不像那几个姐姐那样古板、拘谨。他生病了吗?因为在一头金色浓密的头发衬托下,他的皮肤像象牙一般苍白。或许他只是一个由于大人们溺爱而娇生惯养的人?阿申巴赫更倾向于后面的这种想法。几乎每个艺术家都会有一种奢华和任性的倾向,那就是承认美所引起的不公平,并对这种贵族式的偏袒心理表示敬意。
一个侍者跑来跑去提供服务,用英语通知晚饭已经准备好了。这群人慢慢散开,穿过玻璃门走进餐厅。迟到的人也纷纷从前厅或电梯里走过来,里面,大家开始用餐,但那些年轻的波兰人仍然坐在小桌子旁。
阿申巴赫本来坐在椅子里感到很舒适,更不用提周围还有赏心悦目的美景了,于是也和他们一起坐在那里等着。
面色红润、健壮结实的女家庭教师最终做出站起来的姿态。此时,一个身材高挑、穿着灰色衣服,打扮得珠光宝气的夫人走了进来。女教师扬起眉毛,把椅子向后推了推,向这位夫人鞠躬致意。这个妇人冷若冰霜,端庄稳重,略施香粉的发型和简洁大方的衣服样式,在把虔诚看成是美德的圈子里,人们往往崇尚这种风格。她可能是一位德国高级官员的妻子。但是她的外表中仍然显出某种奢华,尽管只能从她的饰物中看出来:一副耳环,一副长长的三股式项链,上面饰着樱桃般大小的、隐隐闪光的珍珠,看上去都极其昂贵奢华。
孩子们立刻站了起来,吻了吻妈妈的手。她冷淡地朝他们笑了笑,用法语跟女教师说了几句话。她的脸经过精心打扮,保养得很好,鼻子高耸,此时,面色略显疲惫。接着,她向玻璃门走去,孩子们跟在她后面,姑娘们按年龄顺序先后走着,后面是女教师,最后是那个男孩。不知什么原因,这个男孩在迈过门槛前,回头看了看。这时休息室里只剩一人,他那双独特的、暗灰色的眸子与阿申巴赫的视线相遇。阿申巴赫正端坐着,膝上摊着一张报纸,目不转睛地看着这群人离去。
从细节上看,并没有什么异常之处。在母亲来之前不入席,等着她,向她致意,按照通常的礼仪进入餐厅。但不知何故,这一切所表现出来的出色的教养、责任感和自尊心让阿申巴赫深受感动。他又等了一会儿,然后也走进餐厅,坐了下来。不过位置离波兰人一家很远,他不免有点遗憾。
尽管有点疲惫,但他的思绪仍旧很活跃。在这段沉闷的就餐时间里,他用一些抽象的甚至是超然的主题来排遣。他仔细思索了自然法则和个人之间所存在的神秘联系——人世间的美莫非就由此产生?他又从这里出发,思考形式和艺术的普遍性问题,最后,他发现自己的思考和发现只不过像睡梦中某些显然偶然得到的启示,一旦头脑清醒后,这些事情就会显得陈旧而不着边际。吃完饭后,他走进充满黄昏气息的花园,抽了抽烟,偶尔坐一下,偶尔来回漫步,后来就去睡觉了。尽管天仍然很早,他仍然睡着了,而且睡得很熟,不过,一晚上的梦境让这一夜充满了生气。
第二天,天气没有什么改善,陆地上吹来阵阵微风。阴云密布的铅灰色天空下,大海风平浪静,没精打采,好像萎缩了一般。地平线清楚地显现在眼前,海水已经差不多退尽,露出了几个巨大的沙洲。阿申巴赫开窗远眺时,闻到了礁湖发出的腐臭味。
他感到很不舒服,已经打算离开这儿了。几年以前,当他度过了两周阳光明媚的春日后,也是这种天气让他萌生离开之意。他觉着这样的天气实在影响自己的情绪,他必须得逃离威尼斯。当时那种像害热病般的低落的情绪,太阳穴上隐隐的胀痛,眼睑沉甸甸的感觉,不是又在袭击着他吗?再花一段时间换一个环境太烦人了,但如果风向不变,他也不想再待下去。考虑到这种情况,他决定不把自己的行李全部打开。九点时,他在大厅和餐厅之间专门吃早餐的房间里吃了早饭。餐厅里静寂无声,这是每个大饭店里所特有的气派。服务生静悄悄地走来走去,为客人们提供服务。除了给客人们提供茶水时茶具的碰撞的叮当声和低低的耳语声外,什么也听不到。在斜对着门、与阿申巴赫隔着两张桌子的一个角落里,他看到了那几位波兰姑娘和她们的女教师。
她们笔直地坐在那儿,穿着呆板的蓝色亚麻布上衣,白色的小衣领和小袖子,灰黄色的头发刚刚梳平,眼睛红红的,看起来睡眼惺忪。她们把果酱递来递去,早饭差不多已经吃完了。可那个男孩子还没有来。
阿申巴赫自顾自笑了起来。“这样看来,真是个小费阿克斯人!”
他想,“比起你的姊妹们来,你似乎有睡懒觉的特权!” 他突然兴致勃勃,信口背诵起一首诗来:
珠宝,
热水澡,
休息,
是生活中最紧要的事儿。
他不紧不慢地吃完饭。这时,门房摘下帽子走了进来,他从门房手中接过一些信件,打开几封信,边抽烟边读了起来。因此,他看到另一个桌子上正等着的那个睡懒觉的男孩走了进来。
这个男孩穿过玻璃门走了进来,慢慢地斜穿过静寂的餐厅走到姐姐们的桌子旁。他的步态——无论姿势、膝部的摆动,还是双脚举步的姿态——异常优雅、轻巧,显得既柔软又自豪。走进餐室时,他两次回头左顾右盼,这种稚气的羞赧又平添了几分妩媚。他笑吟吟地坐下,轻声地、用含糊不清的语言说了些什么。这时,他把全部的外形都展现在旁观者的面前,阿申巴赫可以很清楚地看到对方。这时,他再一次震惊了,对这个男孩神圣的美惊异不止。今天,这个孩子穿着一件亮色的蓝白条子的棉布上衣,胸口扎着一条红丝带,一个简单的白领子。这种衣领并不能很高雅地配上衣服的其他部分,但上面却有着无与伦比的王冠之花。
这是爱神丘比特的头颅,有帕罗斯岛大理石淡黄色的光华,有着精致而端庄的眉毛,一头鬈发浓密而柔顺地盖住了鬓角和耳际。
妙啊,妙!阿申巴赫用专家那种冷静的眼光鉴赏着,欣喜若狂,就像艺术家们有时面对着一个杰作拼命掩饰自己的喜悦的心情一样。接着,他又进一步思考:真的,要不是大海和海滩在等着我,你在这儿待多久,我就会在这儿待多久!接着,他穿过大厅,接受服务生的致意,然后沿着大露台,直接通过木板路,来到了专门为旅馆客人准备的私人海滩。
那里有一个赤脚的老头,穿着麻布短裤,水手上衣,戴着一顶草帽,他是这儿的浴室服务员。他让服务员把他带到自己的小海滩屋中,从里面拿出一把椅子和一张桌子,放在前面的木板平台上,然后把一张折叠躺椅拖到离海近一点儿的蜡黄色的沙滩上,舒服地坐在上面休息。
像平常一样,海滩的景色、大海旁如画般的轻松自在的快乐心情让他心旷神怡,他完全陶醉在大自然的怀抱里。这时,海滩上热闹起来,孩子们在涉水,有人在游泳,有人穿着花花绿绿衣服,还有一些人正双手交叉搁在脑袋下,躺在沙滩上休息,灰色平静的大海因此而变得生机盎然。还有一些人则在没有龙骨的、漆成蓝色或红色的小船上划着桨,船倾覆时发出阵阵笑声。海滩上伸展着一排排的凉屋,前面的那些平台就像小阳台一样,有的人在上面玩耍,有的人在慵懒地休息,有的人在相互拜访,有的人在聊天,有的人穿着讲究的晨装,有的人则半裸着身子,尽情享受海滨上自由自在的乐趣。在近海处潮湿而坚实的沙滩上,有些人穿着白色的浴衣或宽松艳丽的衣服,安闲地溜达着。在右边,一群孩子们搭起了一座层层叠叠、错综复杂的沙质城堡,上面插满了各个国家的彩色小旗。卖贝壳、糕饼、水果的小贩蹲在地上,把货物摊开来。在左面有一排小屋,这排小屋与另外一排小屋形成直角,那边就是海滩的终点。在这个小屋前面,有一家俄国人正在搭帐篷:男人长着胡子、露出一排阔牙,妇人美丽娇嫩,还有一位波罗的海小姐正坐在一副画架前,描绘着大海的风光,不时绝望地撕扯自己的头发。此外,还有两个长得难看但很有教养的孩子,一个缠着头布的、奴颜婢膝的老年女佣。他们在那里自得其乐,不知疲倦地喊着不守规矩、吵吵闹闹的孩子们的名字,说几句意大利话跟那个老头儿打趣儿了很长时间,有时买点糖果,有时互相亲吻着面颊,丝毫不在乎旁观者的目光。
阿申巴赫想,我还是待下去吧,哪里能比这儿好呢?他把双手交叉,放在大腿上,两眼出神地看着一望无际的大海。他的眼神渐渐散乱迷茫,变得模糊不清,眼前只有单调的、烟雾蒙蒙的虚无一片。他热爱大海的重要原因在于:艺术家勤勉繁重的工作使他渴望宁静,希望通过拥抱质朴纯净和海阔天空来摆脱各种恼人的、眼花缭乱的景象;他还热烈地向往着逍遥、超脱与永恒,向往着清净无为,这些都和他的工作背道而驰,不可能实现,正因为如此,大海对他具有很强的吸引力。一个追求完美的人渴望追求尽善尽美的安宁,但清净无为难道不是尽善尽美的一种形式吗?正在他想入非非的时候,突然从岸边掠过一个人影;当他从无边无际的远方收回视线时,才发现原来是那个俊美的少年从左面穿过沙滩向他的这个方向走来了。他光着脚,看起来像是准备涉水,裤脚一直卷到膝盖处,露出了细长的小腿。他慢慢地向前走,脚步轻盈而自豪,仿佛习惯不穿鞋子走路一样。这时,他观察了一下这些小屋。当他看到那家悠闲自在的俄国一家人时,马上脸上一片阴云,露出极度轻蔑的表情。
他的脸上阴沉沉的,嘴角向上翘起,嘴唇和面颊间像被撕开一样,扭曲变形;他的眉头紧紧地皱在一起,似乎连眼睛也陷了下去,显出邪恶忧郁、怒不可遏的模样。他转移了视线又恶狠狠地向后一瞥,然后使劲地耸了耸肩膀表示不屑一顾,就把他的冤家们扔在后面。
一种近乎羞耻或尊敬的亲切感或惶恐不安感让阿申巴赫转过头去,装作什么也没有看到的样子。因为一位严肃认真的观察者不应该把偶然看到的激情表露加以利用,并对此形成某种判断。但同时,他又高兴,又震惊:就是说,他有点兴高采烈。这种直指最仁慈生活之路的幼稚的狂热情绪,使得神圣的超然境界成为人类秩序的一部分;它成就了造物主的艺术珍品,博得所有见到的人更深的同情;同时,它为这个不同凡响的少年提供了一个历史政治背景,即便年纪尚小,仍让人们刮目相看。
这时,阿申巴赫仍然没有转过头,他听到这个男孩清脆而有点虚弱的嗓音,正招呼着正在玩堆沙堡的同伴们。伙伴们不断叫着他的名字——也可能是爱称——来回应他。阿申巴赫好奇地听着,但无法听得很清楚,只听到两个悠扬悦耳的音节,好像 “阿德吉奥”,或者更多的是“阿德吉乌”,因为最后听起来像是发“乌” 的尾音。他喜欢听这个音调,觉得这种和谐的音调十分美妙,适合它所描述的事情,于是就反复默念了几次,然后心满意足地回过神来,继续看他的信件。
他把小文具盒放在膝盖上,开始处理各种信札。但不到一刻钟,他突然觉得自己错过最值得欣赏的这番景象该有多么遗憾,于是,他把纸笔扔在一边,靠在折叠躺椅上,又把视线转向了大海。过了一会儿,正在堆沙堡的孩子们的声音吸引了他的注意力,他向右边转过头去,进一步观察来来往往、忙个不停的不同凡响的阿德吉奥。
阿申巴赫一眼就看到了他,他胸口的红丝带结让人想错过去都难。
他正和其他孩子忙着安装一块旧木板,作为沙堡的吊桥。他大声地发号施令,并摇头晃脑地强调着这些命令。和他一起玩的男孩和女孩大约有十个,有的年龄与他相仿,有的小一些,有的说波兰语,有的说法语,还有的说巴尔干半岛的语言。在他们的交谈中,最经常出现的是他的名字。很明显,他是他们所追求、仰慕的人,非常受欢迎。其中一个健壮结实的男孩,名字好像是叫 “亚斯胡”,长着一头平滑的乌发,穿着一件亚麻上衣,看上去像是他的心腹和好友。当沙堡的日常工作完成后,他们互相揽着对方的腰沿海滩溜达,那个叫“亚斯胡” 的孩子在漂亮的阿德吉奥的脸颊上吻了一下。
阿申巴赫真想伸出一根指头吓唬他一下。“我奉劝你,克里多布卢斯,”他微笑着想,“还是到外国去旅行一年吧!你至少要花这么长的时间才能恢复。”接着,他从一个小贩那里买了一些熟透的大草莓,把它们当早点吃了起来。尽管阳光无法穿透层层阴霾照射过来,但天气已经很炎热。困乏让他的思维停了下来,他的整个心情都沉醉在无垠的大海宁静的氛围中。这位认真的人煞费苦心地猜测和推敲到底哪个名字听起来有点像 “阿德吉奥”,这件事完全占据了他的心思。凭着对一些波兰文的零散记忆,他终于确定这个名字应当是“塔齐奥”,它是“塔德乌斯” 和“塔德乌兹”的简称。
塔齐奥在洗澡。有一段时间,他从阿申巴赫的视线中消失了。接着,在远处的海面上,他看到了塔齐奥的脑袋、胳膊,他的胳膊正在划水。
这时,岸边很长一段距离的水都很浅。但是,家人马上已经开始担心他了,小屋里传来了妇人的叫喊声,这个名字再一次被喊了起来,像是海滩上的一个口令一样,在沙滩上到处回荡。“塔齐乌!”“塔齐乌!”
它带着柔和的声音,尾音的 “乌” 字余音袅袅,听起来甜美而狂放。听到呼唤,他回身逆浪划游,腿部激起了一片泡沫。他向后方翘起头,以一种不太具有男子汉气概的优美而生疏的方式显现出生机勃勃的身姿。他一绺绺的鬈发湿漉漉地淌着水,像大自然怀抱中脱颖而出的年轻天神般英俊可爱:这种景象令人感受到他像远古时代神话般的内涵,他像远古时代人类起源或天神降生时的一位诗人。阿申巴赫仔细聆听着心灵深处默默地唱着的赞歌,这时,他再一次感觉到这是一个好地方,他想待在这里。
过了一会儿,塔齐奥洗完了海水澡,有点疲倦地躺在沙滩上休息。
他裹着一条白色的亚麻布浴巾,浴巾系在右肩胛下,脑袋枕在裸着的胳膊上。即使阿申巴赫在读信,不去看他时,他也念念不忘那个躺着休息的孩子,他知道只要向右稍稍转过头去,就能看到这个绝妙的形象。在他看来,自己好像正在保护这个正在休息的人;即使是在忙自己的事情,仍然一心一意地守着右边离自己不远的这个人间尤物。他的心激荡着慈父般的深情,只有像他那样竭尽全力创造美的人才会对至美的人或事物全身心地投入,并流露出感人的真情。
中午,他离开了海滩,返回旅馆,乘电梯回到了房间。在房间里,他在镜子前照了很久,端详着自己灰色的头发,疲倦硬朗的面容。这时,他想起了自己的声望,想起了那么多人因为他的准确优雅地运用词句的能力而敬仰他——他认为自己证明了他所具备的才能所给予他的所有成功,他关心甚至考虑起自己的身份和地位。接着,他走进餐厅,在小桌子旁吃了饭。当他后来进入电梯时,那些年轻人也吃完了饭,推搡着进了这个盘旋上升的小电梯,塔齐奥也在其中。他就站在阿申巴赫边上,这是第一次他们离得这么近,阿申巴赫能够近距离地看清所有细节。有人跟这个孩子说话,他面带不可思议的可爱的微笑作答,接着,他在第二层跨出了电梯,向后走了走,眼睛看着地面。美丽会使一个人害羞,阿申巴赫想,并琢磨着为什么会是这样。事实上,他注意到塔齐奥的牙齿长得并不好,有些参差不齐,颜色暗淡,缺少健康的色彩,带着贫血症患者牙齿上常见的奇怪的半透明的特征。他的躯体有点虚弱,看上去有点病态,阿申巴赫想他也许不会活太久。他根本没有注意为什么这么想时,自己会有一种愉悦的感觉。
下午,他在房间里消磨了两个小时,然后乘小汽艇穿过散发着臭味的礁湖去威尼斯。他到达了圣马科广场,在那里喝了会儿茶,然后按照在当地的日程安排,步行穿过这个城市。但是,就是这次散步使他的情绪发生突变,他完全改变了最初的决定。
街巷里感到令人压抑的闷热,空气沉闷,难闻的气味从公寓里、店铺里、餐馆里散发出来,热油味、香水味和其他更多的味道混杂在一起,烟雾腾腾,无法散逸。香烟味悬在空中,好久才能慢慢散开。狭窄小巷里熙熙攘攘、推搡着的人群使这位散步者焦躁不安,什么也引不起他的兴趣。他走得越多,越是心烦意乱,这可能是由于海风和热风以及由此而带来的激动和疲惫造成的。他浑身流着汗,感到非常难受,眼睛也不听使唤,胸口发闷,浑身发烧一样,一股热血涌上额头。他急忙逃离拥挤不堪的商业区,穿过好几座桥,到达了贫民区:乞丐们纠缠着他,河道里发出的臭气几乎让他窒息。终于,他来到了中心一个僻静的地方,这是一个被人遗忘的充满神话故事的地方。他在喷泉旁休息了一会儿,擦干额头的汗,马上意识到自己非得到另外的地方不可。
他再一次意识到,这座城市的那种气候对于他的健康来说是非常不利的,而且这种情况永远不会变化。硬要在这里坚持下去看上去并不明智,风向是否会变化也无法知晓,因此,必须马上作出决定。马上回家并不是一个好的选择,那边,不论是夏天还是冬天,都不是他适合的住处。
但不是只有威尼斯有海洋和沙滩,其他的地方也可以找到,而且没有臭气熏天的礁湖和热浪逼人的烟雾。他记起离德里雅斯特不远的地方有一个小的海滨旅游胜地,很多人都曾称赞过这个地方。为什么不去那里呢?
现在就走,仍然值得再换一个地方。他主意已定,便站了起来。在附近的码头,他乘坐贡多拉穿过曲折的河道,经过用大理石雕成的两侧刻有狮子图案的华丽阳台下面,绕过一些滑溜溜的墙角又沿着凄凉的宫殿群划过,驶向了圣马科广场。所有的这些景象都倒映在脏兮兮的水中。船夫为了从饰带和玻璃制造商那里得到小费,带着他一会儿在这里停下来,一会儿在那儿停下来,诱使他上岸观光,买些小东西。这种奇怪的威尼斯之游因为没落女王唯利是图的精神而失去了魅力,他的心马上冷了下来。
回到宾馆后,他告诉办公室职员,因为某些意想不到的事情,他必须明天一早离开。职员对此深表遗憾,把他的账目一一算清。他吃完晚饭,在后面阳台上读了读杂志,度过了温和的一晚。上床休息前,他把第二天要带的行李全部准备妥当了。
因为想到马上就要离开,他睡得并不是很好。第二天早上,当他打开窗户时,天空依旧一片阴霾,但空气似乎清新些了——就在这时,他开始有点后悔了。他匆匆宣布动身不是操之过急、有些失策吗?难道不是因为当时身体欠佳、心神恍惚所造成的后果吗?如果他能稍稍再忍耐一下,如果他能再努力尝试着适应威尼斯的气候,或者静待天气好转,那么现在就能和昨天一样,在海滩上度过这个早晨,不必为动身的事劳累忙碌、浪费时间了。但已经太晚了。现在他不得不继续渴望着他昨天曾渴望的东西。他穿好衣服,八点钟时下楼吃早饭。
走进餐厅时,里面依然没有一个人。当他坐着等饭时,零零散散地来了一些人。就在喝茶的时候,波兰女孩和她们的女教师走了进来。她们表情严肃,精神饱满,但眼皮仍然因为睡眠而发红。她们走到了角落里的桌子旁。接着,门房走了过来,手里拿着帽子,提醒他该走了。汽车等在外面,把他和其他旅客送到伊克塞尔斯奥饭店,从那里,客人可以乘汽艇穿过私人运河到达车站。时间很紧,但阿申巴赫却不以为然,离火车出发还有一个多小时。他很不喜欢旅馆过早催促客人离开的这种习惯,告诉门房他要安静地吃完早饭。那个人迟疑地退了出去,五分钟后又出现了。汽车不能再等了。阿申巴赫激动地回答,就让它走吧,不过把箱子带上。他自己可以到时乘公共汽艇过去,什么时候出发这件事让他自己来决定。服务员欠着身子离开了。阿申巴赫终于摆脱了服务员的烦人的劝告,从容不迫地吃完饭,还从侍者那里要了份报纸读了读。
时间确实太紧张了,他终于站了起来,正在这时,塔齐奥穿过玻璃门走了进来。他直接向家人坐的桌子旁走过去,正好与阿申巴赫相遇。在这位灰白头发的人面前,他垂下了眼睛,以他惯有的优雅风度抬起头来,温柔地看了看他,走了过去。“再会,塔齐奥!” 阿申巴赫想,“时间太短促了。” 他一反常态,撅起嘴唇,补充了一句:“上帝保佑你!” 接着,他起身离开,递给侍者小费,与那位穿法国式双排扣长礼服的经理告别,徒步离开饭店。他像来时一样,穿过贯穿小岛的开满白色鲜花的林荫道,来到了汽艇码头,侍者跟在他后面,拎着手提包。他到达码头,上了船,坐了下来,接下来的就是满带着遗憾的冒险旅行。
航路是他所熟悉的:穿过礁湖,路过圣马科,一直驶向大运河。阿申巴赫坐在船头的圆凳椅上,手臂倚着栏杆,用手挡在眼睛上方,以避开刺目的阳光。市政公园在他的眼前掠过,不一会儿,仪态万方的广场又展现在前面,然后渐渐远去;接着一排排宫殿式的屋宇出现在眼前,河道转向时,里亚尔多灿烂夺目的大理石桥拱就映入眼帘。阿申巴赫出神地望着,胸口感到一阵绞痛。使他迫不及待地想离开的威尼斯的空气以及海洋和沼泽隐隐散发出的腐臭气味,现在又让他依依不舍,他略带痛苦地深深地呼吸着这里的空气。难道他过去不知道也不曾体会到,自己是多么怀恋威尼斯的一切景物?今天早晨,他只是对自己的决定的正确性稍感遗憾,略作怀疑,而现在,他却是心情绝望、心痛欲裂,以致泪水涟涟。他责问自己,过去为什么没有预见到这种情况呢?显然,看上去让他耿耿于怀甚至无法忍受的是他担心再也无法见到威尼斯了,这一次可能是永别。由于他两度感到这个城市对自己的健康无益,每次都不得不匆忙离开,他就应当认为这是一个不应该住的地方,他无福消受,因此,再次返回也就没有什么意义了。他甚至觉得,如果现在离开,自尊和蔑视会让他不愿意再次看到这个城市。在这里,他已经有两次身体不支了,精神上的渴望与身体素质的差异引起了这位年长者异常激烈的思想斗争。他认为体力不济是十分丢脸的事,无论如何要置之度外,同时,他也不理解为什么昨天竟能处之泰然,没有感觉到犹豫。
这时,汽艇快到火车站了,他忧愁烦闷,不知所措,到后来甚至有点困惑混乱了。对于这位饱受煎熬的人来说,离开看上去是不可能的,但留下来也有点强人所难。在两种选择的挣扎当中,他痛苦地走进车站。
那时,已经相当晚了,如果他想搭上火车的话,一分钟也不能耽误了。
他急忙买了张票,在拥挤的候车室里寻找刚才的门房。这个人终于出现了,告诉他大箱子已经被运走了。已经运走了?是的,确实运走了,运到科摩了。运到科摩?经过一番焦急的你问我答,问的人怒气冲冲,答的人羞怯尴尬,终于弄明白这只箱子在伊克赛尔斯奥宾馆和其他箱子放在一起,被送到完全错误的方向了。
在听到这个消息后,阿申巴赫发现想要保持正常的神态很困难。实际上,他兴奋得难以置信,简直欣喜若狂,胸口一阵痉挛。门房急忙去查询,看是否能把箱子追回来,但不出所料,他空手而归。于是,阿申巴赫宣称如果没有这只箱子,他就不会离开,所以他要返回宾馆等待这件行李送到那儿。汽艇还在车站外面等着吗?门房说是的。他用流利的当地语言找售票员把买好的票退了回去,并发誓说一定要打电报去催,要不惜一切代价把箱子追回来。就这样奇怪,到达车站二十分钟后,他又再次回到返回利多的大运河了。
这是多么奇异、令人不可思议、有点尴尬而又富有戏剧性的梦一般的经历啊!他本来怀着极其沉痛的心情与这些地方永别,但命运弄人,在一个小时内,他居然又将再次看到它们!疾驰的小艇在贡多拉与汽船之间巧妙灵活地转着舵,变换着航向,像箭一样向目的地飞去,海浪在船头激起一阵阵泡沫;而此时,它的乘客表面上生气,实际上却像一个逃学的孩子,竭力掩饰内心的慌乱与激动。不时地,他仍然为自己再没有这么及时的不幸遭遇暗自失笑,确实,任何幸运儿也不会有这样的好运气。他对自己说,到时候,只要解释一下,然后勇敢地面对惊愕的表情,就万事大吉了。于是,一场意外避免了,一个严重的错误被纠正了,而他本来以为抛诸身后的一切又如他所愿再次展现在他的面前…… 难道飞快的航速欺骗了他,还是现在确实风转向了,正从海上吹过来?
海浪拍打着狭窄的运河两旁的混凝土堤岸,这条运河穿过小岛一直通到伊克塞尔斯奥宾馆。一辆公共汽车正在等着这位返回来的客人,然后通过波浪起伏的大海上面的一条路,将他送到圣莫里兹饭店。那个小胡子经理跑下台阶来迎接他。
经理对这次意外的差错低声下气地向他道歉,并称他本人和饭店管理部门对发生这样的事感到非常难过,同时还赞扬阿申巴赫,说他决定留在这里等行李送回是多么英明。当然,由于他以前的房里已有客人,所以酒店为他准备了另外一个房间,和之前的一样好。“你的运气不太好,先生。” 在他坐电梯上楼时,开电梯的瑞士人微笑着对他说。就这样,我们这位准备溜走的人又在房间里歇下来,这间房间的方位景观与家具摆设跟上次那间几乎没有什么两样。
这是一个奇怪的上午,混乱的情形让他感到精疲力竭,失去了活力,于是,他把手提包里的东西又在房间里布置好,在靠开着的窗户边上的扶手椅子上坐了下来。海面上呈现一片淡绿色,空气看起来越来越稀薄,闻起来更加清新了,在小船和小屋的点缀下,海滩上显得色彩缤纷,尽管天空看上去仍然灰沉沉的。阿申巴赫把手放在大腿上,眺望着外面的景色,为能够返回感到高兴不已,但对于自己的变化无常甚至不清楚自己的意图感到有点困惑不解。他就这样静静地坐着休息了大约一个小时,恍恍惚惚地不知想些什么。中午时,他看到了塔齐奥。他穿着那件条纹海军服,胸口扎着一个红结,从海滩那边跑过来,经过木板路返回宾馆。
阿申巴赫甚至还没有真正看清楚,就一下子认出他来了,暗自想着这样的话:“看,塔齐奥,你又在这儿了!” 但就在这一瞬间,他觉得不应该这么随便地问候,面对着内心真实的想法,他应该保持沉默——他觉着热血沸腾,内心悲喜交加,马上意识到只是因为塔齐奥,这次离别才那样费力和沉重。
他居高临下地坐在那里,沉默无语,省察自己的内心,没有人能看到他。他表情活跃起来,眉飞色舞,笑逐颜开,真切而富有生气。接着,他抬起头,举起本来垂在椅子扶手上的两只胳膊,两掌向前,做了一个慢腾腾的圆形动作,好像打开并伸展手臂一样。这是一种欣然欢迎的姿态,一种平心静气接受一切的姿态。
现在,太阳神每天驾着灼热的战车在天空中驰骋,黄色的光晕总是伴随着袭来的东风。在波浪起伏、宁静而浩瀚的海面上,闪耀着一片丝绸式的白光。沙滩变得滚烫。在闪着银白色霞光的蔚蓝苍穹下,一张张铁锈色的帆布在海滩的小屋面前伸展开,在它们提供的阴凉地里,人们度过了早上的时光。不过,晚间的风光也旖旎动人,公园的花草树木散发出阵阵清香,天上繁星点点,闪烁着光芒,夜幕笼罩着海面,海水微微激起了浪潮,发出幽幽的低语声,与人的心灵倾心交谈,令人心醉。
这样的夜晚,预示着明天准是个阳光灿烂、可以悠闲消受的好日子,在这样的日子里,肯定会有许多纵情游乐的好机会。
由于这样一个及时的意外而留在这里的这位客人清楚地知道,等待失物领回不是他不想离开的原因。在两天的时间里,他不得不忍受着随身用品短缺带来的种种不便,不得不穿着旅行装到大厅里吃饭。后来,那只丢失的箱子终于又放到了他的房间里,他把箱子里的东西都清理出来,塞进了所有的衣柜和抽屉,决定在这里待下去,至于待多少时间还没有确定。想到可以穿着丝绸衬衫在海滩上消闲,晚饭时可以穿合适的衣服在餐桌旁露面,他感到异常高兴。
这种舒适而有规律的生活深深吸引了他,这种恬静安闲而生机勃勃的生活方式使他惊异无比。事实上,在南部海滩上讲究的海滨生活与风光秀丽的城市的舒适安逸结合在一起,使这一切都那么引人入胜,待在这里真是太好了!阿申巴赫并不喜欢这种乐事。不论花费时间参加聚会或到什么休闲场合,他的内心总得不到安宁,没有多久,他就会返回写作,继续每天不可或缺的神圣事业,在他年轻时尤其如此。只有这个地方能够让他放松身心、平缓意志,让他感到快乐。
有几次,当早晨在帐篷里假寐,或者在温暖芳香的夜晚靠在柔软的贡多拉坐垫上,在繁星点点的夜空下从圣马科广场摆渡回利多,看着灿烂的灯火消逝,听着悠扬的小夜曲旋律渐渐沉寂,他总会想起他的山乡别墅,他夏季写作的住所。那里,云层在花园中穿过甚至笼罩了地面,可怕的雷鸣暴风熄灭了屋中的灯光,他喂养的乌鸦吓得跳到枞树的树梢上去。相比之下,他现在多么舒畅,仿佛置身于极乐世界,这里没有雪,没有冬天,没有暴风雨,也没有洪水,只有海洋之神俄西阿那斯送出的柔和的凉风。每天都在悠闲中自由自在地度过,不用操心,不用挣扎奋斗,只有阳光和节日。
阿申巴赫经常见到塔齐奥这个孩子。他们在狭小的天地里活动,每天生活几乎千篇一律,因此,他在白天的大部分时间里都能接近这个引人注意的孩子,即便见不到也只是很短的时间。他到处都能看到他,遇见他:在旅馆第一层的房间里,在往返于威尼斯城凉爽的船上,在圣马科广场上,如果运气好的话,还会在其他一些进进出出的场合中见到他。
不过,海滩早晨的时刻是他比较有规律能见到他的时候,在这里,他有较多机会愉快地、虔诚地欣赏和研究这个漂亮优美的形象。这种可以预见的快乐,这些每天都能反复享受到的幸运的环境让他愈发感到留在这里的可贵,在他看来,每天都是令人愉快的日子。
他起得很早,像平常急于做什么工作一样。太阳刚刚升起,光线仍然很柔和,在清晨朦胧的海面上,泛起了一片耀眼的白光,此时,他已经比其他人都早得出现在海滩上。他愉快地向看门人致意,又向为他准备小屋、安置帐篷、把家具放到露台上的赤脚老头问好,然后坐下来休息。
接下来的三四个小时属于他自己,他在那里目睹着太阳冉冉升起,发挥出可怕的能量,在这个过程中,海水的蓝色也越来越深,他可以密切地注视着塔齐奥。
他看到塔齐奥有时从左边沿海岸走过来,有时从小屋中间走出来,有时他又会吃惊地发现自己错过了看他到来的过程,因为那个孩子早已经在那里了。他穿着一件蓝白相间的游泳衣,这是他在海滩上唯一穿的一件衣服,此时,他像往常一样开始在沙滩上玩堆沙堡的游戏——这是一种甜蜜空虚、闲散不定的生活,玩耍,休息,闲逛,涉水,挖沙,捉鱼,躺卧,游泳。露台上的妇人们守望着他,不时用女高音喊着他的名字:“塔齐奥!塔齐奥!” 听到这个声音,他就会晃动着手臂向她们跑来,告诉她们自己的经历,向她们展示自己的所见所闻和收获:像是蚌类、海马、水母,还有横爬的小龙虾等。阿申巴赫一点儿也不明白他说的话,可能他说的只是一些最普通的家常话,尽管如此,在他听来仍是一窍不通、不知所云。不过,这个男孩发出的异国的音调像音乐一样悦耳动人,烈日在他身上挥洒着无尽的光辉甚至远处雄伟的海洋也成了这个男孩的背景。
不久,这位旁观者已经熟悉了这个复杂身体的每一个线条和姿态,尽管如此,每天看到这个熟悉而美丽的面容时,他总是能感受到新的欢愉,无法停止对于美的赞叹,无法停止这种柔美的感官享受。有一次,这个男孩被叫去迎接一位客人,这个客人正在小屋里和妇人们待在一起。孩子从那边跑过来,可能身上仍然滴着水,他摇了摇卷发,摊开了手,一条腿支地,另一只脚踮着脚尖儿。他看上去有点紧张,转动身子时姿态非常优美,羞涩娇媚,看上去对于自己崇高的职责非常满足。有时他躺在沙地上,浴巾围在胸前,轮廓分明的手臂支住下巴。那个叫 “亚斯胡” 的孩子蹲在他身旁,和他唧唧喳喳地说着话。没有什么比这个美少年和这个谦卑的下属和仆人说话时呈现在眼睛和嘴唇的神采飞扬的笑容更吸引人了。有时,他远离同伴或家人,独自一人站在沙滩上,这时离阿申巴赫很近。他身体笔直,两手抱着脖子,慢慢地来回摆动着脚上的足球,出神地望着蔚蓝的大海,完全不顾一些小浪花拍湿了他的双脚。他那蜜色的头发轻柔地抚摸着太阳穴和脖子,太阳照在上脊椎的汗毛上,呈现一片金黄色;细致雕刻的身形、匀称的胸部在贴身的游泳衣的映衬下,显得格外美丽;他的腋窝仍然光秃秃的,像雕像一样,膝踝光亮剔透,蓝色的静脉清晰可见,好像他的躯体是用某种透明的物质做成的。这个年轻而完美的修长形体上,体现出多么高的教养和深邃精密的思想!这背后需要多么严谨坚强的意志和纯洁的心灵,才能够把这么神圣的作品献给世人——难道艺术家不知道吗?他自己不也是这样吗?当他费尽心血、倾尽全力把灵魂深处所见到的精微形象在语言的大理石上刻画出来,然后把这种形象当成是 “智慧美” 的榜样和化身奉献给人类时,不也是这样一种力量在推动着他吗?
榜样和化身!他望着蓝色海边的高贵身影,欣喜若狂地相信他已经拥抱着美本身,这一形象是上帝构思的产物,是寓于人类心灵的纯洁完美的形象,是值得尊崇的人类形象和画像。这是一种自我陶醉、毫不迟疑甚至有点贪婪的陶醉,这位艺术家很乐于接受这种想法。他的思绪在飞,他的知识在澎湃涌动,他的记忆中甚至浮起了从接受教育的青年时代一直保持到现在但从来没有爆发出来的原始想法。书里不是说过,太阳会把我注意力从理智引向感官吗?书里说,太阳使理智和记忆混乱迷失,使人的灵魂因为纯粹的快乐和执着眷恋它所照射的最美丽的物体而忘乎所以、迷失方向:是的,它只有借助于某个物体,才有可能达到更高的境界。爱神模仿数学家,为了把抽象的概念传授给迟钝的孩子,必须借助于具体的的模型:上帝也采用这种方式,为了向我们展示其伟大,利用年轻人的形体和肤色,使概念上的东西可视化,引起人们对美的反思,使我们在看到后既满怀忧伤又燃起希望之火。
这就是这位快乐的人当时的想法,也是他的感受。置身于海浪声外的快乐的白日梦和灿烂的阳光在他的眼前逐渐成形:那是离雅典城墙不远的老悬铃树,一个神圣的地方,绿树成荫,樱桃树的香气扑鼻;为了纪念居于山林水泽的仙女和河神阿基琉斯而立起了许多神像,供奉着祭品。在枝丛茂密的大树脚下,一条清澈的小溪汩汩地从光滑的鹅卵石上流过,蟋蟀在唧唧叫着。在缓缓起伏的草地上斜靠着两个人,炽热的阳光照不到这里:一个老年人,一个年轻人;一个丑陋,一个俊美;一个智慧,一个和蔼可亲。这是苏格拉底用幽默轻松的话语,循循善诱地就德行和情欲方面的问题教导和启迪斐多。他告诉对方那个看到了永恒之美的形象的人所遭遇的煎熬;谈起了邪恶的、不敬神的人无法看到隐藏在图像后的美,也不会有崇敬的心理;他谈到了品德高尚的人看到面前完美的形象时,会产生一种诚惶诚恐的感觉,谈起他如何震惊,几乎不敢正视,谈起如果世上其他人不认为他愚蠢的话,他会如何敬仰像上帝一样美丽的人。他补充道:“因为只有美既可爱又能看得到。注意,这是我们的感官能够获得和感受到智慧的唯一方法。否则,如果神性、理智、德行和真理等都能像这样通过感官表现出来,我们又会变成什么样子呢,难道我们不会在爱情的烈焰面前活活烧死,像以前塞墨勒在宙斯面前那样?由此看来,美是感受者通向灵性的一种途径,不过这只是一个途径、一种手段而已,我的小斐多……” 接着,这个老练的求爱者谈到其中的真谛:求爱的人比被爱的人更加神圣,因为上帝站在求爱的人那儿,不站在被爱的人那儿。这也许是迄今最富于情意、最诙谐的一种想法,它是世上所有七情六欲的诙谐幽默和潜在乐趣的源泉。
思想和情感、情感和思想能够完全融为一体,这是作家的快乐。当时,这位孤寂的作家就处于冲动的思想和精确的情感中。换句话说,当心灵服服贴贴地拜倒在 “美” 的面前时,大自然也欣喜若狂。爱神喜欢闲散自在,也是为了悠闲自在被创造出来。但在这样一种状况下,这个折磨人的想法让他产生了创作的冲动,而创作的动机是什么则无关紧要。
当时,知识界正围绕着文化及其趣味的一些重大问题掀起一场争论,这位旅行者也获悉了这个消息,因而产生了创作的灵感。这个主题是他所熟悉的,他产生了一股不可抗拒的冲动,渴望用优美的文字把这个主题透彻地表达出来。他想在塔齐奥面前写,把这个男孩的体态作为模特儿,文笔也应当与这个对他来说非常神圣的少年躯体的线条保持一致。他要把他的美带入知识界,就像苍鹰一样的宙斯把牧人盖尼米德带到太空里一样。文字的快乐从来没有像现在这样温柔甜蜜,他也从来没有感觉到字里行间会像现在这样情意绵绵,闪耀着爱的光辉。就是现在,他坐在帆布帐篷下,观察着自己的偶像,开始倾心耕耘那篇小品文——这篇一页半的优美散文,言语诚恳、简洁高雅、情意绵绵,肯定在短时间内会引起许多读者赞叹,并为之倾倒。世人只知道他这篇文章写得漂亮,并不知道它是在什么情况下产生的,因为一旦了解了艺术家灵感的源泉,他们往往会大惊小怪、困惑混乱,这只会使优秀的作品失去诱人的感染力。多么奇怪的时刻啊!多么奇怪的心力交瘁的创作活动啊!多么奇怪的灵魂与肉体的交流啊!当阿申巴赫放下作品离开海滩时,他感到精疲力竭甚至觉得整个身子垮了,好像做了一件不可告人的放荡事,受到了良心的谴责。
第二天早晨,正要离开旅馆时,他看到塔齐奥已经一个人向海边走去。这时,阿申巴赫萌生了一个念头,他希望利用这个机会和他结识,和他交谈,同时自然地欣赏他的神态和回答。因为这个少年不知不觉中左右了他的情绪,成为创作灵感的源泉。这位美少年慢悠悠地溜达着,很容易就能追上,于是阿申巴赫加紧了脚步。他在小屋后面的木板路赶上了他,正想把手搭到他的脑袋或肩膀上用法语说几句话时:或许由于跑路太急,他突然觉得心脏跳到了嗓子眼儿,气喘吁吁,只能用颤抖的声音和他交谈。他迟疑了一下,尽量让自己平静下来,突然又担心自己在他身后走了太久,害怕已经引起他的注意。他又试了一次,但还是失败了,于是便放弃了打算,垂头丧气地从他身边走过。
太迟了!当时他想。太迟了!但真的太迟了吗?要不是他刚才迟疑了一下,他本来满可以到达轻松愉快和幸福快乐的彼岸,也会使头脑清醒起来,治愈他的心结。唯一的可能是,他不想清醒,深陷在想入非非的自我陶醉中了。谁能揭开艺术家的内心感受和外在表现之谜呢?谁能理解艺术家这种能够将作为基础的自律与放纵的两种秉性根深蒂固地融为一体呢?因为拒绝清醒地认识现实,就是放纵的表现。阿申巴赫并不再想作自我批判。他这个年纪的情趣和精神状态、自尊、成熟程度以及后期的单纯,都使他不愿静下来剖析自己的动机,也不愿确定究竟是什么妨碍他的行动——是良心不安呢,还是软弱,没有勇气。他惶惶不安,怕有人会注意到他的这种冲动以及后来的行动未遂,他担心遭到别人的奚落。另外,他不禁对自己滑稽而讨厌的恐惧哑然失笑。“狼狈害怕得像一只在战斗中折断翅膀的公鸡。” 他想,“这一定是神的意志,使我们一看到美色就心神涣散,把我们的渴望像这样给压下去……” 他细细玩味着自己的思想,觉得自己还是太高傲了,不愿意承认有这种恐惧情绪。
后来,他不再去在意给自己定出的休息日期甚至也没有回家的想法。
他通过写作获得了大量钱财。他唯一关心的是那家波兰人会不会离开。
一个偶然的机会,他从饭店的理发师那里打听到这家人是在阿申巴赫到这里前不久才来的。太阳把他的脸和手晒得黑黝黝的,海边含盐的空气也使他的情绪更加振奋。本来,他一向是惯于把睡眠、食物或大自然所赋予他的活力完全投入到创作活动中去,可现在呢,日光、休息和海风大大增强了他的体质,而他却把这一切都漫无节制地花在冥想和情思上面了。
他的睡眠时间很少,每天都始终如一地快乐过去,夜晚将每个白天分隔开来,不过夜间短促,他的内心既有失落也有对明天期盼的快乐。
他很早就睡,因为九点钟时,塔齐奥就会从视野中消失,对他来说一天已结束了。但在第二天黎明时分,一阵心悸会把他惊醒,他会马上想起那天的冒险,便再也没有心思躺在枕边,于是一跃而起,轻松地穿上衣服,迎着清晨袭人的寒气,坐在敞开的窗户边,静静等待太阳的升起。
那天惊心动魄的经历,装满了他的灵魂,这种投入和渴望由于睡眠而显得尤为神圣。此刻,天空、地面和海水还笼罩在黎明前玻璃般的苍白中,一颗孤独的星星还在太空中若隐若现。不过,从远处吹来一阵清风,那是厄俄斯离开丈夫起床,黎明时最初出现的一条条柔美的淡红色霞光已在天空和海面的尽头升起,这预示着创作的激情。诱骗青年的女神悄悄地走近了,她夺走了克雷多斯和西发洛斯的心,而且还全然不顾奥林匹斯山神的嫉妒,享受着英俊的奥利安的爱情。天际呈现出一片玫瑰色,焕发出无法形容的迷人的华光,一朵朵初生的云彩被霞光笼罩,有点模糊不清,看上去像是半透明的,飘浮在玫瑰色与淡蓝色的薄雾中,像一个个伫立在旁的丘比特爱神。海面上泛起一阵紫色的光,似乎在滚滚的海浪上面翻腾;金色的长矛突然飞上高空,熹微的曙光已变成耀眼的光芒,炽热的光芒升起来了,终于,太阳神驾着疾驰的骏马,在大地上冉冉升起。太阳的光芒让这个孤独坐着的人眼睛花了,他闭上眼睛,让阳光吻着他的眼睑。本来在他一丝不苟的生活中已经磨灭的内心快乐的需求,现在又奇迹般地回来了,并涌上心头——他在茫然而困惑的微笑中认出了它们。他沉思冥想,嘴唇慢吞吞地吟出一个名字;他仍然微笑着,脸朝上,双手交叠地放在膝盖上,又坐在安乐椅里睡着了。
这天一开始就热气腾腾,像节日一般,而从一整天来看,也非常欢乐,充满了神话般的色彩。黎明时不知从何处吹来了一阵清风,像神圣的耳语一般在他鬓角与耳畔抚过。一簇簇羽毛般的白云在天空飘浮着,像天神放牧的羊群。风越来越大,波塞冬的马儿正在飞驰,上帝的公牛也低垂着牛角,咆哮着、腾跃着。更远处的海滩上,波浪像山羊一样扑腾着,在峻峭的岩石间翻腾。在这位神魂颠倒的作家周围,尽是潘神的神奇动物,他的心沉浸在梦幻般的奇思妙想里。有好几次,当夕阳沉落在威尼斯后面时,他坐在公园里的一条长凳上呆呆地瞧着塔齐奥,这个少年正穿着一身白衣服,系着彩色腰带,在平整的沙砾场院中活动着。这时,他认为自己看到的不是塔齐奥,而是许亚辛瑟斯,因为两个神同时爱着他,他不得不选择死亡。不错,他体会到塞非拉斯对情敌阿波罗怀有的痛苦的嫉妒滋味,当时这位情敌忘记了神谕,忘记了弓和竖琴,终日和那位美少年一起玩乐。他看到了一个满含着痛苦的嫉妒的铁饼掷在那个可爱的头颅上,当时他也吓得面如土色,把那个打伤了的身体抱在怀里,同时又看到一朵鲜花在甜蜜的血液里绽放,悔恨不已……
当两个人只是凭眼睛相识时:他们每天甚至每小时相遇;当两个人由于道德习俗或古怪想法而表面上装作漠不关心时,没有什么比这两个人的关系更加奇怪和令人尴尬了。他们怀着过分紧张和被压抑的好奇心,想和对方交流,却又违背常理地故意控制住自己,由此产生了歇斯底里的不满足的情绪,也产生了一种紧张的敬意。因为在一个人不能对对方作出正确的判断时,他总是爱慕和尊敬这个人,这种渴望,就是彼此还缺乏了解的证明。
阿申巴赫与塔齐奥之间必然已经开始了某种关系或者友谊,因为这位长者已欣然觉察到对方对他无微不至的关注并不是完全无动于衷的。
比如说,现在这位美少年早晨来到海滩时,已不再像过去那样沿小屋后面的木板路,而是顺着前面那条路,沿沙滩缓缓地踱过来,经过阿申巴赫搭帐篷的地方——有时还不必要地挨过他的身边,几乎从他的桌子或椅子前面擦过——然后再回到自己的屋子里。究竟是什么让他这样做呢?难道有什么超然的魅力或魔力在吸引着这个天真无邪的少年吗?每天,阿申巴赫都期待着塔齐奥的出现,有时,当塔齐奥真的露面时,他却假装忙着干别的事儿,丝毫不去注意这位打身边过去的美少年。但有时,他们也会目光相接,这时,两个人总是表现得很严肃。长者违背自己的内心激动的情绪,尽量表现得有教养、有威严;但塔齐奥的眼睛却流露出一种质询,一种沉思的质问。他踌躇不前,低头瞧着地面,然后又优雅地仰起头来;经过时,他举止中的某些东西似乎在表明只是因为良好教养的羁绊,他才没有回头张望。
不过有一天晚上,情况有些异样。晚饭时,大餐厅里没有见到波兰孩子和家庭女教师的影子,阿申巴赫有点惊惶失措。晚饭后,他穿着夜礼服、戴着草帽,径直走到饭店门口的台阶下散步,一边担心着他们的行踪。突然,在弧光灯的灯光下,他看到了修女般的姐姐们和女教师,塔齐奥跟在她们身后大约四步远的地方。显然,他们刚从汽船码头过来,由于某种原因在城里吃了晚饭。水面上大概有点凉,塔齐奥穿的是有金色钮扣的深蓝色水手外套,头上戴着一顶相配的帽子。太阳和海风并没有伤害到他,他的皮肤依然像当初一样呈现出大理石般的微黄色;不过今天他比平时显得更加苍白,可能是因为天气较凉,也可能是因为灯光发出的惨白的光线照射的缘故。他两道匀称的眉毛更具特色,黑瞳瞳的眼睛炯炯有神。此时,他看上去更漂亮了,难以用语言形容这种美。这时,阿申巴赫再次感到痛苦万分:因为他只能对这种美进行赞美,却无法用恰当的语言描述出来。
他没有想到这个可贵的形象出现在眼前,来得出其不意,因而来不及使自己恢复镇定和高贵的姿态。当他的目光与失而复得的塔齐奥的目光相遇时,他的脸上流露出来快乐、惊喜和赞美之情——正好在这一瞬间,塔齐奥微微一笑:他朝着阿申巴赫微笑,笑得那么亲密、可爱,那么坦率,微笑时嘴唇微微地张开。这是那喀索斯的微笑,他在反光的水面上俯下身子,向水中映出的自己美丽的形象张开手臂,笑得那么深沉,那么迷人,那么韵味无穷。那喀索斯稍稍撅起嘴,想去吻自己水影中娇丽的嘴唇,媚态横生,好奇困惑,又有几分心神不定,似乎被完全地迷住了。
看到这个微笑,阿申巴赫像收到不幸的礼物似的匆匆转身走了。他非常激动,浑身打战,以至于不得不从台阶和前花园的灯光中溜走,急匆匆地向后面的花园中走去。他莫名其妙地动起肝火来,心底里迸出柔情脉脉的责怪声:“你怎么能够那样笑!没有人可以那样笑!”他一屁股坐在一条长凳上,惶惶然呼吸着草木花卉夜间散发出的阵阵清香,然后向后靠在凳背上,垂下双臂,全身一阵阵地战栗着。这时,他悄声默念着人们热恋和渴想时的陈词滥调——在这种场合下,这种调子是难以想象的、荒唐的、愚蠢可笑的,但即使是说 “我爱你!” 也是神圣的、庄严的。
在古斯塔夫 · 冯 · 阿申巴赫住在利多的第四个星期,他发现周围世界发生了一些令人不安的变化。首先,他觉得尽管最好的季节已经到来,但旅馆里的客人不是多了,而是少了,特别是德国人似乎从他身边销声匿迹了,因而无论在餐桌上或海滩上,最后只听到外国人的声音。有一天,在理发师那儿——现在他经常去那里——他听到一句话,不免怔了一下。
理发师谈起一家德国人只在这儿待上几天就动身回去,接着又用逢迎的口气说:“但,先生,您不会害怕瘟疫。您肯定会留在这儿吧?” 阿申巴赫直愣愣地看着他。“瘟疫?” 他重复了一句。那位多嘴多舌的人顿时一言不发,忙着干活,装作没有听到这个问题。当阿申巴赫逼着要他说时,他说他什么也不知道,然后设法把这个尴尬的话题岔开了。
这时已经是正午。午饭之后,阿申巴赫在炎炎的烈日下乘船到威尼斯去,一路风平浪静。他被迷恋驱使着跟随波兰姊弟。看到他们跟着女教师一起向汽艇码头走去,于是他也跟了上去。在圣马科广场,他没有见到自己的偶像。但当他坐在广场阴凉处的一张铁脚圆桌子旁喝茶时,他突然闻到空气中有一股特别的气味。这几天来,空气中似乎一直弥漫着这种气味,他一直没有去注意它。这是一种令人难受的香味,令人想起疾病、伤痛或者可疑的卫生状况。他嗅了又嗅,焦虑地辨别出这是什么。喝完茶后,他就离开了教堂对面的广场。在狭窄的街巷里,这种气味更加浓重。街头巷尾都贴满了告示,警告居民说,由于在此盛夏季节有某些肠胃疾病流行,不要饮用运河里的水,也不要吃牡蛎及其他贝类。
这一公告的措辞虽然委婉,但意思却很明显。一群群本地人一言不发地站在桥上、广场上,阿申巴赫在他们当中穿行,注视、聆听、思考着。他向一位倚在商店的门上的店主询问这令人难受的气味的由来,店门两旁放着珊瑚项链和人造紫水晶之类的饰物。那人先用阴沉的目光打量着他,接着就变得活跃起来。“亲爱的先生,这纯粹是一种预防性措施罢了!” 他做了一个手势说,“这是警察局的命令,我们不得不听。气候闷热,热风对健康不利。总之一句话,您知道,这也许是一种过分的防范措施……” 阿申巴赫向他表示了谢意,然后继续往前走。在返回利多的汽船上,他也察觉到了消毒剂的气味。一回到饭店,他马上在大厅里埋头翻阅起各种报纸。在外文报纸里,他看不到什么消息。在德国报纸里却刊登一些疫病的流言,还举出了统计数据,然后是官方的否认,但这种否认的动机令人怀疑。这就解释了德国人和奥地利人离开这里的理由。其他国家的人们显然对此还一无所知,对此漠不关心,依旧泰然自若。“这事应当保守秘密!” 阿申巴赫兴奋地想,把报纸扔回到桌子上。“对这件事要保密,不能声张!” 但同时他觉得很开心——为外部世界将要遭遇的各种险境而暗自高兴。因为激情像罪恶一样,与既定秩序和千篇一律、平淡而舒适的生活不能共存;它欢迎对于平庸社会结构的一切削弱瓦解以及世界上各种混乱和苦难,因为它确信能够从中获益。因此,在威尼斯肮脏的小巷里所发生的可怕事情成为他内心的秘密,阿申巴赫对于这种掩盖有一种阴郁的满足感。因为这个陷入情网的人不担心别的,只是担心塔齐奥会离开,同时还惊异地意识到,如果塔奇奥离开了他的视线,他将无法生存。
最近,他已不再满足于按照偶然或每天的固定时间来亲近和见到这位少年了。他开始尾随着他,追逐着他的脚步。例如星期天,波兰人一家从来不会出现在海滩上,他猜想他们准是到圣马科广场参观集会了,于是急急忙忙赶到那边。他从炎热的广场上一直来到暗沉沉的教堂,看到心上人正在祈祷。于是他站在后面不平坦的拼花地面上,和一些跪在那里喃喃祈祷的、画着十字的信徒们混杂在一起。教堂的结构是东方式的,富丽堂皇,让阿申巴赫眼花缭乱。前面,一个穿法衣的神甫正挥动着神器,念念有词地诵起经来。香雾四处飘散,在神坛上摇曳不定的烛光里缭绕,祭坛上浓郁的香气似乎与另一种气味微微混在一起——就是那个患病的城市散发出的气味。但透过香雾和火光,阿申巴赫看到那个优美的造物回过头来找寻他,终于也见到了他。
当人群从教堂出来,走到阳光灿烂、鸽子成群的广场里时,这个入迷的人却躲了起来。他眼看着波兰人一家离开教堂,看到姊弟们彬彬有礼地向母亲告别,之后母亲转身沿小市场回到宾馆。他也看到这位英俊的小伙子和修女般的姊妹们跟着女教师穿过钟楼,走进美彻丽雅街;他和他们保持着一定的距离,偷偷地跟在后面,穿过威尼斯各处。他们停下时,他也不得不停下来;他们转回时,他就不得不溜到小旅馆或庭院里躲避。有一次,他失去了他们的踪迹,狂热地在桥上和肮脏的死胡同里东寻西找,当他们突然在一条无法躲避的羊肠小道上相遇时,他吓得魂飞魄散,遭受了极大的痛苦。但你也不能说他在遭罪,他的精神和思维都极其兴奋,脚步像是着了魔一样,而魔鬼的癖好就是践踏人类的理智和尊严。
有时,塔齐奥和他的姊妹们在某个地方乘贡多拉。阿申巴赫就躲着,避开他们的视线,他们一上船离岸时,他便雇船跟着离开。他生硬地小声告诉船夫,如果能够小心谨慎地跟在前面刚拐弯的小船,他就会付给他一大笔小账。如果那个船夫愿意借此机会促成此事,并且唠唠叨叨地保证一定会好好为他效劳时,他就会欣喜若狂。
于是,他坐在黑色的软垫上,跟在另一条黑色驳船后面,身子随着小船左右摇摆时,他的激情也荡漾起来。有时,他失去了小船的踪迹,会感到一阵悲伤和失望。不过他的船夫经验丰富,总能够抄近路跟上它。
此时,风平浪静,空气像凝滞一样,夹杂着一股臭味,炽热的阳光透过薄雾照射下来,天空呈现着五彩斑斓的颜色。波浪拍击着木头和石块,汩汩作声;有时船夫会发出叫唤声,声音中既有警告的成分,也有问候的意味儿,一会儿,不知从什么地方传来回应声,声音在幽静曲折的水道中回荡。杏树的白色和紫色的伞形花卉从高处小花园里倾塌的墙头上低垂下来,发出杏仁的香味。摩尔式的花格窗在苍茫的暮色中若隐若现,教堂的大理石石阶伸入到水中,一个乞丐蹲在上面,拿着一顶帽子,伸向前面,像一个瞎子一样露出白眼。还有一个做古董生意的小商贩,在自己的店铺前阿谀奉迎地招徕过路客人,希望能够骗他们一下。这就是威尼斯,令人神魂颠倒,而又让人充满了猜疑——这个城市一半是神话,一半却是陷阱;在它污浊的气氛中,曾一度盛开艺术之花,而音乐家也在此获得灵感,奏出令人销魂的旋律。这位冒险家似乎喝醉了一般,好像置身于百花争艳的艺术中,好像听到了那些美妙动人的音乐。同时他也想起疫病正笼罩着这座城市,但当局为了经济利益而保守着这个秘密。他更加无拘无束地盯着在他前面缓缓行进的贡多拉。
就这样,这位头脑发昏的人什么也不想干,只是无时无刻不在追逐他热恋的偶像,对方不在时他就痴想着,像堕入情网的恋人那样甚至对着他的影子倾诉衷肠。他独自一人,又在他乡,再加上新近欣喜若狂带来的兴奋,这些都诱使他允许自己无所顾忌地去体验最荒诞不经的生活。
比如会发生这样的事情。有一天,当他晚上回到宾馆时,在饭店二层那个美少年的房间前徘徊不前,把前额靠在门上,舍不得离开,根本不顾及别人会发现自己这样疯疯癫癫的神态。
不过有时,他也会静下心反思一下。他这是走的什么样的路!他困惑地想。我竟然会选择这样的路!像每个有天赋的人那样,他以自己的家世为荣;每当取得什么成就,获得什么成功时,他就会想起自己先辈,立志不辜负他们的殷切期望,光宗耀祖。即使此时此地,他深陷在这种不适宜的生活经历中不能自拔,让奇怪的激情主宰自己,他还是想到了自己的祖先,想到他们正直诚实、严谨坚定的生活状态,想到他们光明磊落的品格和端庄的风度。看到他目前的状态,他们会说什么呢?真的,看到他的全部生活与他们大相径庭时,他们又会怎么说呢?这是一种被艺术束缚住手脚的生活,他本人年青时也曾像中产阶级的先辈们那样一度嘲笑过这种生活,然而实际上,这种生活与他们的却是如此相像!他也曾过着这种生活,恪守着准则;他也是他们中的一名战士,因为艺术是一场战斗,是一场耗尽心力的斗争,在这场战斗中,一个人只能在有限的日子内参与进来。这是一种不断征服自我、不畏艰难险阻的生活,是一种备尝艰辛、坚韧不拔而有节制的生活,他把这种生活当成合乎时代要求的英雄主义的象征。他称这种生活为凛然有男子汉气概、英勇无比的生活。在他看来,在某种程度上,主宰他的爱神尤其适合这样一种生活。难道那些最勇敢的人不值得受到高度的尊重吗?人们不是说正因为他们勇猛过人,他们的城市才繁荣起来吗?古时有许多战斗英雄听从了神的意志,甘心忍辱负重,但没有人会贬低他们。而怀有其他目的的种种胆怯行为则受到谴责:卑躬屈膝、山盟海誓、苦苦追求、低声下气。
不过,所有这些都不会使求爱者蒙受耻辱,反而会赢得赞美。
这个沉迷的人就这样聊以自慰,设法保护自己,维护着尊严。同时,他也密切关注着威尼斯城内极不明朗的危险事态的进展情况,这个城市小心地保守着秘密,就像他自己一样——外界的冒险活动和他内心的奇异经历汇合在一起,形成一股暗流,使他的激情不断得到滋养,飘散开来,形成了狂妄的希望。他在城里各家咖啡馆里仔细翻阅德国报纸,希望能够确切地获悉疫病的流行情况,因为在饭店客厅的阅览桌上,这种报纸已经消失几天了。报上一会儿承认,一会儿又否认,弄得人稀里糊涂。
病例和死亡者的数目,说法不一:二十个,四十个,一百个。但第二天,报上却又否认整个疫情,或者说疫病是从国外传染过来的,得病的人寥寥无几。不过,字里行间也作了一些警告,对当局这种危险的把戏提出抗议。当然,他也就不可能获得确凿可靠的消息。
不过,这位孤独的旅客认为自己有某种特权了解事实真相,即便离群独处,却常常向知情人提一些诱惑性的问题,后者答应对此事保持缄默,因此不得不公然说谎来应对他——从这里,他找到了一种奇妙的满足感。一天吃早饭时,那位个子矮小、说话温和的穿法国双排扣长礼服的经理先生在就餐的人们中间问候周旋,走到阿申巴赫的桌旁时,他也停下来寒暄起来。于是,他对经理也采取了这样的策略。他用一种看上去非常漫不经心的口吻问道:“看在上帝的分儿上,为什么这段时间里他们一直在威尼斯消毒?”——“这不过是警察局例行公事罢了,天气非常闷热,可能会引起危害居民健康的事儿。当局这个措施只是为了及时盯防,避免危害公共健康。”——“这倒要感谢警察局呢!” 阿申巴赫冷冷地回应道。之后,两人又交谈了几句天气方面的客套话后,经理就告辞了。
就在当天晚餐以后,在前面的花园里来了一小群来自威尼斯的街头卖唱的艺人。两男两女面向着露台,站在一个弧光灯的铁柱下面,灯光把他们的脸照得刷白。度假的人坐在露台上,一面喝着咖啡、吃着冷饮,一面欣赏着具有民间特色的歌舞。宾馆里的职工、电梯服务员、服务生和办公室管理人员都纷纷来到大厅门廊边侧耳静听。一家俄国人一向热衷于这种享受,在花园里离艺人比较近的位置摆出了藤椅,围坐成一个半圆形,全身心地享受着这种快乐。在他们身后,站着一个围着穆斯林式头巾的老奴。
这些江湖艺人奏起了曼陀林、吉他、手风琴和一只闪光的小提琴。
器乐演奏结束后,又开始了声乐演唱;年纪较轻的女人引吭高歌,和一个甜润润的假嗓子男高音表演起二重唱,演绎一首深情绵绵的情歌。但这群人中真正有才能的无疑是那个弹吉他的人。他是一个男中音,几乎不唱,但富有模仿才能,演出相当滑稽,劲头十足。他常常离开其他演员,拿着吉他,跌跌撞撞地表演,这种傻里傻气的演出,赢得人们一阵阵欢笑声。对于这种南方人的技艺,那些俄国人尤其乐不可支,不断地拍掌喝彩,鼓励他表演得更加大胆些。阿申巴赫坐在栏杆旁,不时喝一点儿石榴汁和苏打水的混合饮料,饮料在杯子里泛着红宝石般的光芒。他沉浸在吱吱呀呀的音乐和庸俗肉麻的曲调中,因为激情会削弱一个人的审美力,让他坦然接受那些在头脑清醒时不屑一顾的事物。看到那个小丑滑稽出格的行为,阿申巴赫的脸上浮现出娱乐带来的复杂和几乎受伤的表情。他松垮垮地坐在那里,可内心却因全神贯注而紧张万分——因为离他六步远的地方,塔齐奥正斜倚在石栏杆上。
他站在那里,身着一件有时在晚餐时穿的白上衣,看上去风度翩翩、气质不凡。他把左前臂搁在栏杆上,两腿交叉,右手靠着臀部。看上去,他只是为了礼貌才带着淡淡的好奇心来看这些江湖艺人的表演,脸上几乎不挂一丝微笑。他不时直起身子,动作优雅地拉开短上衣的皮带,让胸口舒坦一下。有时,那个男孩会向这位爱慕者所在的地方瞥一眼——这让阿申巴赫被一种得意、恐惧和不知所措的感觉所包围——或许是缓慢而警觉的,或许是突然和迅速的,像是有意让他吃惊。阿申巴赫不敢接触他的眼光,因为这种关注让他受到惊吓,使他不敢正视。同时也因为那些照看塔齐奥的女人也坐在露台上,他担心这种对视会引起她们的注意。事实上,在海滩上、在宾馆里以及圣马科广场上,他曾好几次注意到她们把塔齐奥从他身边唤走,让孩子远离他,当时他就像挨了一闷棍似的,受到莫大的侮辱,但他的良心却使他无法反驳。
这时,那位表演者开始在吉他的伴奏下开始了独唱,这是一曲目前风靡意大利全国的流行小调。他以戏剧性的方式演唱,抑扬顿挫、婉转动人,伙计们则用乐器伴奏,并伴唱。这人身材瘦削,面颊憔悴,破烂的毡帽挂在脖子后面,乱蓬蓬的红发从帽檐里露了出来。他站在远离同伴的沙砾地上,显得非常自信;他拨动着琴弦,向露台上送出一支诙谐而逗人的曲调,由于用尽全力表演,额头上青筋都露了出来。他不像是威尼斯人,倒像是那不勒斯的喜剧演员,有点像男妓,也有点像笑料作者,粗鲁而大胆,危险而颇有风趣。他通过脸上的丰富表情和身体摆动,挤眉弄眼,舌尖在嘴角上滴溜溜的滚转,将通常看起来无聊的歌曲演绎出了某种含糊不清的意义,不知什么原因,令人觉得很讨厌。他穿着城市运动衫,松开的领口里伸出瘦棱棱的脖子,脖子上赫然露出一个大大的喉结。他面色苍白,塌鼻子,没有胡子,这让人很难判断出他的年龄。
由于整天挤眉弄眼扮鬼脸,也由于沉湎酒色的恶习,他的脸上布满了皱纹;在两道红茸茸的眉毛中间,有两条很深的皱纹,与伶牙俐齿的嘴、露齿而笑的表情很不相称,显得目中无人、专横粗野。然而真正让我们这位孤寂的旅客对他产生关注的,却是这位可疑的人物似乎也带来了某种可疑的气氛。每当唱歌时,他都转圈手舞足蹈,每当走到阿申巴赫的旁边时,从他的衣服和身体上都散发出一股消毒剂的气味。
小曲唱完以后,他开始从俄国人那里收小费,俄国人给得很慷慨;然后他走上通向露台的楼梯。尽管在台上唱歌时他看上去厚颜无耻、大胆泼辣,但在这里,他却表现得温良谦恭。他猫着腰,踮着脚尖在桌子间穿梭,谄媚地笑着,露出一口坚实的牙齿,但红眉毛间的两条皱纹依旧显得那么咄咄逼人。人们怀着好奇——同时带几分憎恶——的眼光审视着这个收钱的外国人,把钱币扔到他的毡帽里,尽量不去碰他。只要和喜剧演员过分接触,体面的观众总会感到某种尴尬,即便演出非常受欢迎。他也觉察到这一点儿,只能低声下气地请求原谅。他走到阿申巴赫身边,带着一身药水味儿,而周围任何人似乎都没有注意到这个味道。
“听着!” 那个孤独者压低了声音,几乎机械地说,“威尼斯城一直在消毒,究竟为什么?”——这个小丑用嘶哑的声音回答:“这是警察局的主意嘛!先生,在这样大热天气,又有热风,不得不听从命令。热风让人透不过气来,对健康不利……” 他说话时的神气,似乎不明白为什么有人会提出这样的问题。然后他摊开了掌心,以便证明热风多么令人难以忍受。“那么威尼斯就没有瘟疫了吗?” 阿申巴赫轻轻地问,声音好像从牙缝里迸出似的。这时,这个小丑那张健壮的脸露出滑稽困惑的痛苦表情。“瘟疫?什么样的瘟疫呢?难道热风是瘟疫吗?或许我们的警察局是一种瘟疫?您真爱开玩笑!瘟疫?你必须明白,这纯粹是预防性措施!警察局是为了消除热风带来的影响才下达的命令!” 他又做着手势说。——“好吧。” 阿申巴赫轻声地说,然后把一枚特别大的硬币投在他的帽子里,示意叫他走开。他深深鞠了一躬,笑着走了。但他还来不及走到台阶上,两个饭店服务员就迎面向他走来,小声盘问他。
他耸耸肩膀,似乎在为自己辩护,并发誓自己什么也没有说。其中一个人看上去相信了,松开了他,于是他又回到了花园里。他跟同伴们匆忙商量了一下,又唱了最后一支曲子。
阿申巴赫这个外国人以前从来没有听过这支歌曲。这首歌曲粗旷奔放,歌词是令人无法理解的方言,有可笑的副歌,整个团队使劲地拉开嗓门儿唱着。这时,谈话和音乐伴奏都停了下来,只有一片有节奏的笑声,尤其是那位独唱者,表演得有声有色、形象逼真。由于离观众的距离远了,他又恢复了先前的厚颜无耻;刚才在露台上矫揉造作、假惺惺的笑声,似乎变成嘲讽的笑声。甚至在副歌开始前,他显然不得不控制住这种冲动,呜咽着,声音颤抖着。他用手捂住了嘴,耸起肩膀——就在这时,他突然大笑起来,笑得那么真实,那么生动,以至于观众都受到了感染,不知什么原因,也沉浸在一片欢腾之中。这使得这位歌手更加兴高采烈,他弯弯膝盖,拍拍大腿,摸摸腰部。他不再笑了,而是号叫起来,用手指指着那些愉快的人,好像没有什么比这更有趣了;最后,走廊里、花园里的人全都大笑起来,连倚在门旁的侍者、电梯服务员和仆役们也都笑起来。
阿申巴赫不再靠在椅子里,而是坐直身体,好像随时准备站起来反对或者逃离开来。但这一阵阵笑声、飘荡的医院气味和近在咫尺的美少年交织在一起,使他像着了魔一样无法离开。只有大家乱成一团、沉浸在娱乐氛围中时,他才敢壮起胆子看看塔齐奥。这时,他注意到,这位美少年回看他时表情也很严肃,好像他们的行为和表情都联系在一起,由于他的爱人正在逃避这种气氛,四周人们的欢乐情绪似乎对他并没有产生什么影响。这种孩子般的顺从让这位头发花白的长者心头一阵松快,简直无法控制自己的激动情绪,不得不把脸埋在双手中。他发现,有时塔齐奥会矫正一下身形,深呼吸一下,紧紧胸膛。“他太虚弱了,不会活很久的。” 他又客观公正地想,这时,他的痴狂和激情会奇怪地烟消云散,单纯的同情和狂妄的满足霎时充满他的内心。
这时,威尼斯艺人的演出结束了,离开了那里。一片鼓掌声欢送他们,他们的领队说着玩笑话告别,以示点缀。他打躬作揖和飞吻致意的姿态令人发笑,现在更加倍做起这些动作来。当其他人已经离开了,他又装腔作势地跑到一根灯柱下,装着依依惜别的样子回到门口。到了那里,他突然扔掉滑稽可笑的面具,站直身子,向露台上的听众们吐吐舌头,然后消失在夜色里。宾客四散开来,栏杆旁的塔齐奥也不见了踪影。但阿申巴赫仍然在那里坐了很久,独自一人喝着饮料,侍者们感到很诧异。
时光流逝,夜色渐浓。多年以前,在他父母的家中,有一个计时沙漏——现在,他突然再次看到了这个古老而重要的仪器,仿佛就在他面前一样。
他似乎看见赭红色的沙子默默地、细细地从玻璃瓶颈中流下来,由于上面的沙子已经很少了,因此形成了一个奔流的小旋涡。
第二天下午,倔强的阿申巴赫再一次尝试着探索外部世界,这一次,他获得了成功。他进入了开在圣马科广场的英国旅行社,在柜台上换了些钱后,以一个满腹猜疑的外国人的身份,和办事员谈起了这个重大问题。办事员是一个年轻的英国人,穿着斜纹软呢服,头发从中间分开,眼睛眯成一条缝,看上去老实可靠,和那种圆滑的南欧人迥然不同。
他说:“没有什么可担心的,先生。为了抵御大热天和热风带来疾病,当局经常颁布这样的命令…… 只是例行公事罢了,没有了不起的意义。”
但当他抬起蓝眼睛,看到了这个外国人困倦而有点忧郁的眼神,看到了那个外国人正带着几分轻蔑的表情盯着他的嘴唇。这个英国人的脸顿时红了。“那不过是,” 他继续说,“官方的解释,他们认为坚持这种做法才是上策。我要跟您说一说,里面还有一些隐情呢……” 接着,他老老实实地道出了真相。
“近几年来,亚细亚霍乱呈现出日益向四方蔓延的严重倾向。疫病发源于恒河三角洲闷热的沼泽地,并在杂物丛生、无法控制、没有人烟的荒地的一片恶臭环境中逐渐扩展,只有老虎蹲伏在密密麻麻的竹林里。后来瘟疫在整个印度流行,传播到中国、阿富汗和波斯,已经到达了莫斯科。正当欧洲惊恐万分,担心这个幽灵会涉足欧洲大陆时,它已经通过叙利亚商船偷偷地来了,土伦、马拉加、巴勒莫、那不勒斯甚至意大利的卡拉布里亚区和阿普利亚区也见到了它的踪迹,北方看上去还没有波及。但那年五月中旬,发现了两具骨瘦如柴、全身发黑的尸体,一具是船夫的,另一具则是女蔬菜水果商的,在他们身上都发现了可怕的弧菌。当局对这两个病例都秘而不宣。可是一星期后,在城市的各个地区,受害人逐步增多,有十个、二十个、三十个。一个奥地利人到威尼斯玩了几天,回家后就带着这种确凿无疑的症状死去了,因此在德国的报纸上,首次报道了袭击威尼斯的这种疾病。对此,威尼斯当局回应说,城市居民的健康状况极其良好,正采取必要的措施对这种疾病加以防范。
“但食物可能已经受到污染,食用肉类、蔬菜和牛奶会导致更多的死亡,尤其是运河温热的河水也会加速这种疾病的传播。看上去疫病正在加速传播,而且越来越致命,几乎很少有人康复。得病的人中有百分之八十以最可怕的方式死去,因为疫病传播得极其猖狂,同时所患的往往是最凶险的一种,人们叫它为‘干霍乱’。得这种病时,患者无法将来自血管中新陈代谢分泌的大量水分排出。几小时内,病人枯萎下去,血液变得粘稠阻塞、全身抽搐、疼痛难忍,在声嘶力竭中死去。如果疾病发作时,有人在稍感恶心和不适之后就昏迷过去,几乎不可能醒过来,那他就是幸运的了。六月初,医院的隔离病房里已经悄无声息地塞满了人,两所孤儿院也已经人满为患,而墓地圣迈克岛和城市之间的交通也繁忙起来,道路上整天熙熙攘攘、拥挤不堪。可是威尼斯当局担心这件事情泄露后会使各种利益受到损害,比如影响到不久前在市政公园里开幕的图画展览会,考虑到会威胁到旅游产业,由此带来巨大的经济损失。因此,对于老实公开真情,遵守国际协定,当局根本就不放在心上。就是这种心理支配下,当局采取保守秘密和否认事实的政策。而市民的恐惧也为这种保密提供了理由。威尼斯卫生部门的最高长官对此义愤填膺,辞职以示抗议,他的位置被一个听话的人接替。人们知道了这件事;上层的腐败及统治的不可靠,死神在城里到处游荡带来的紧急状态,使社会出现了道德败坏的现象,产生了鼓励令人厌恶的反社会的倾向,并以多种形式表现出来:放荡、干猥亵下流的勾当、犯罪的行为也增多了。与常态时不同,人们在晚上经常可以看到许多醉鬼,一些无赖在夜间闹得街上鸡犬不宁,抢劫甚至凶杀案一再发生,因为有两起案子表明:有两个人名义上染瘟疫而死,实际上却是被亲人毒死的。堕落和犯罪达到空前的规模,而这种情况通常只有在这个国家的南方和某些东方国家中才经常出现。” 最后,这个英国人说出了最重要的事情。“你最好仔细考虑一下。”
他总结道,“最好今天离开,不要等到明天了。用不了几天这里就要封锁隔离了。”
“谢谢您。” 阿申巴赫说完,离开了办事处。
广场虽没有太阳,但酷热难耐。蒙在鼓里的外国人坐在咖啡馆里或站在白鸽成群的教堂前面,看着这些鸟儿拍着翅膀飞过来,竞相啄食着递过来的玉米。阿申巴赫终于成功摸清了事实的真相,尽管嘴里有一种苦涩的味儿,心里也怀着莫名其妙的恐惧,但孤独的他在广场的石板路上踱来踱去,陷入狂热的兴奋中。他考虑到一种既体面又能免受良心责备的解决方式。今晚晚餐以后,他可以走到那位珠光宝气的贵妇人身边,对她这样说:“夫人,请允许陌生人向您提出一个忠告,可能别人为了自身的利益不会告诉您。离开吧,现在就带着塔齐奥和令嫒们一起离开吧!威尼斯正闹着疫病呢。” 然后他可以用手拍拍塔齐奥(这是善于嘲弄人的上帝的工具)的脑袋,转身逃离这个沼泽般的城市。但他马上意识到,自己并不真地想采取这一措施。这会使他走回头路,让自己的灵魂回归原位;但一个失去理智的狂乱的人,只有最后万不得已的时候才愿意再次回归自我。他想起那座铭刻着碑文的、在夕阳下闪耀着微光的白色建筑物,他曾在那里用心苦苦探索这些文字的神秘含义;然后又想起那个流浪徘徊的奇怪的人,是他激起了阿申巴赫青年时代那种想去远方漫游的渴望。他也想到回家,想到如何使自己理智、清醒、勤劳和节制,但这些想法令他产生了极为强烈的反感,以致脸上露出了厌恶而痛苦的表情。“这事不该声张!” 他急忙轻声对自己说,“我应该保持沉默!”
他因为知道自己成了威尼斯当局的共犯而极其兴奋,就像一点儿酒就会让他的大脑变得衰老疲惫一样。他的头脑中浮现出威尼斯城疫病横行后的一片荒凉景象,这让他的心中燃起了一种无法理喻、不可名状的甜蜜希望。他刚才想到的那些点滴幸福怎么能与他的这些希望相提并论呢?
对他来说,艺术和道德观念与一片混乱之下所得的好处相比,又算得了什么呢?他决定保持沉默,仍旧留在这儿。
那天晚上,他做了一个可怕的梦——如果我们可以把梦称做肉体上与精神上的一种经历的话;它虽然在沉睡时发生,完全独立,感觉真切,但自己并不亲自参加其中。梦的舞台似乎就是心灵本身,各种事件从外面闯入,冲破了他心灵深处的防线,经过后又离开他,使他生活中的优雅文明成为一片废墟。
开始时他只觉得一阵恐惧,接着恐惧、欲望以及对于未来将发生的事情的恐怖和好奇心便交织在一起。夜色深沉,他全神贯注地倾听着,因为他听到一阵骚动声和混杂的喧闹声正从远处传过来:一阵咔嗒咔嗒声、撞击声,还有被压抑住的轰隆轰隆声,接着听到举杯庆祝的尖叫声和 “呜呜” 的嚎哭声。所有的声音混合在一起,以一种可怕的方式被凄婉而缠绵的笛声掩盖,这笛声令人荡气回肠。此时,他想到了一个短语,尽管隐晦,但却预示着什么事情即将发生:“异国的神啊!”压抑的热情正在燃烧:他看到了与他夏天居住的乡间别墅周围的山脉相似的山脉。
在斑驳的光线中,从树木茂密的小山上,在巨大的树干和长满青苔的岩石中间,一阵轰隆声像一阵旋涡一样向地面涌来:那是人类、动物、蜂群、狂怒的游牧部落,他们漫山遍野而来,手执通明的火炬,在一片喧腾中翩跹乱舞。女人在腰带上悬着长长的毛皮,击打着头上的小手鼓,哀悼着,挥舞着火星四射的火炬和出鞘的短剑,拿着 “嘶嘶” 吐着舌信的蛇,或者抓挠着赤裸的胸部大喊大叫。额上长角、围着兽皮、浑身上下毛茸茸的男人,低着头,举起胳膊和小腿,拼命击打着黄铜制的锣鼓,发出震耳欲聋的响声。一群光头的孩子驱赶着山羊,紧抱住羊角,在一片欢跃的喧闹中让公羊一跳一蹦地拖着走。这些人欣喜若狂地号叫着,但叫声最后,总会发出一种柔和的 “呜呜” 的清音,既甜润又粗旷:这边听起来象牡鹿的鸣叫声,而那边回传来很多声音附和,回声在空中回荡。这些声音像是疯狂地庆祝胜利,他们在喊声下相互推挤奔逐,跳着舞,扭摆着四肢,一直不让这种声音停息。但所有的这一切都受这种深沉而悠扬的笛声控制。他憎恶地目睹了这番景象,还不顾羞耻地等待着那个酒宴,等待着不适宜的最后的献祭,难道这种笛声没有吸引他吗?
他极度憎恶和恐惧,但他的意志却是可敬的,能够抵御他所反对的异端邪说——那是冷静而高贵的思维的敌人。但喧闹声和嚎叫声震撼着山岳,并发出一阵阵的回响,使得这声音越来越大,越来越近,几乎达到令人着魔的疯狂程度。各种气味使他透不过气来,失去了判断的能力——山羊腥臭的气味,呻吟的人们发出的气息,死水散发出的臭气,还有另外一种他所熟悉的气味:那就是萦绕在四周的创伤和疾病的气味。他的心随着击鼓声而颤动膨胀,他的头脑急速运转。愤怒控制了他,盲目、已经失去的性欲,还有渴望参加祭神舞蹈的情绪控制了他,令他慌乱不知所措。一个巨大的木制生殖器被揭开:他们狂放而不加抑制地喊着口令,口角淌着白沫,用粗野的姿态和淫猥的手势相互逗引,时而大笑,时而呻吟——用带刺的棒相互戳入对方的皮肉,舔着肢体里的血。做梦者也遵从狄俄尼索斯神的意旨,加入了他们的队伍;事实上,他们就是他,“异国的神” 就是他自己。当他们杀掉动物,狼吞虎咽地吃下仍然温热的生肉时,当他们在青苔地上交媾以向他们的神致敬时,他们就是他。他的精神体验到这种放荡淫乱,他只觉得自己的灵魂在堕落。
这个不幸的人从梦中醒来时,心力交瘁、神情恍惚,像落在魔鬼手中无力挣脱一样。他不再害怕其他人警惕的眼神,他们的猜疑对他来说已经不再重要。无论如何,他们正纷纷逃离,海滩上许多小屋都空了出来,饭厅里的人也少多了,城里几乎看不到外国人了。看来,大家已经知道了事情的真相。尽管有关利益各方团结努力,仍然无法控制恐慌的情绪。
不过这位珠光宝气的妇人和她的家人仍旧留在这里,也许是因为谣言还没有传到她的耳边,也许因为她高傲无畏,对此事不屑理会。塔齐奥还住在这儿。有时,着魔的阿申巴赫想,逃离或死亡会带走周围每一个其他的人,这样他就能够和这个美少年单独留在岛上——这样,早上时,他可以用深沉的、漫不经心的目光凝视着他所追求的人;傍晚,他可以不知廉耻地在死神出没的大街小巷里尾随着他。这种荒诞不经在他看来很有可能成为现实,道德律令此时已经被抛诸脑后了。像任何求爱的人一样,他一心想博取对方的欢心,惟恐不能达到目的。他在衣服穿着的细微末节上变换花样,以便让自己看上去更加年轻有活力。他戴宝石、洒香水,每天在梳洗打扮上花费几倍的工夫,然后穿上华丽的服饰,怀着兴奋而紧张的心情走进餐厅里。看到这个把他迷住的翩翩美少年,他就讨厌憎恨自己老朽的躯体;花白的头发和尖削的面容让他自惭形秽,感到绝望。他觉着一定要千方百计打扮自己,使自己恢复青春的活力,于是他频繁地出入宾馆的理发室。他披着理发围巾,靠在椅上,让喋喋不休的理发师修剪着、梳理着。他用惆怅痛苦的目光端详着镜子里的面容。
“头发花白了。” 他歪着嘴说。
“只有一点儿,” 理发师搭着腔,“这是懒得打扮的缘故,与外貌无关,打扮对一个人来说很重要。不过不修边幅到底一点儿不值得赞扬,特别是这些人不应该对什么是真的、什么是技巧而怀有偏见。如果这类人不注意口腔卫生,也不注意化妆,他们就会给人留下烦扰的印象。归根到底,一个人老还是不老,要看他的精神与心理状态如何。头发花白准会给人们造成一个假象,染发以后就会好一些。亲爱的先生,您完全可以使头发恢复本色。您愿意让我给它恢复本来面目吗?”
“用什么方法呢?” 阿申巴赫问。
于是,这位健谈的理发师用两种溶液漂洗起主顾的头发来,一种颜色亮些,一种暗些——之后,他的发色变得像青年时代一样乌黑了。他把头发用烫钳卷成一道道的波纹,然后退后一步,仔细检查精心整修过的头发。
“现在只剩下把您脸上的皮肤稍稍修饰一下。” 理发师说。
像每个无法自制的人那样,他兴致勃勃地忙完这个,又忙那个。
阿申巴赫舒舒服服地靠在椅上,无法拒绝理发师的好意,希望能够发生一些改变,希望从镜子里看着自己的眉毛如何变得上翘,以便看上去更优雅;看着经过化妆,面颊上呈现出玫瑰红后,自己的眼睛如何变得更大,更炯炯有神;同时他苍白的嘴唇也变红了,眼角和嘴角的皱纹也消失了——他兴奋地看到,镜子里映出一个年青人的形象。最后,化妆师认为一切都很称心如意,于是他谦卑而有礼貌地感谢他的主顾,这种谦恭态度是干这行工作的人所特有的。“这只是一点儿小小的改变。” 在为阿申巴赫完成最后一下化妆时,他说,“现在,先生可以随心所欲地谈情说爱了。” 阿申巴赫满心欢喜地离开了,同时又有点恍恍惚惚、战战兢兢。他系了一条红领带,戴着一顶有彩色丝带的宽边草帽。
这时,刮起了一阵温热的小风,稀稀落落地下起小雨来,但空气依然闷热潮湿,飘荡着沉重的腐臭气味。阿申巴赫涂着脂粉的脸热得发烫,耳际只听到一片淅淅瑟瑟、哗啦哗啦的响声,仿佛凶恶的风神正在大地纵横驰骋,丑陋的海鸟正在啄食注定要毁灭的人的食物。因为闷热会使人食欲不振,很容易让人联想到食物被污染了。
有一个下午,阿申巴赫尾随着美少年,冒险深入到闹着疫病的曲折迷离的市中心。由于街巷、水道、小桥和空地彼此都很相似,因此他辨别不清方向,也不知自己究竟在什么地方。他尽力不让自己的偶像从视线中消失。他不得不采取一些不体面的行动,一会儿靠在墙上,一会儿躲在行人背后作掩护,根本没有意识到他的情绪和焦虑已经让他精疲力竭了。塔齐奥跟在家人后面,他通常让女教师和修女般的姊妹们在小巷前面走,自己独自一人走在后面。有时,他回过头来,用好奇而朦胧的眼光看看迷恋他的人是否跟在后面。塔齐奥看到了他,但并没有让他走开。他心领神会、欣喜若狂。在这一对眼睛勾引下,在一股盲目的激情驱使下,一种非分的希冀潜入他的心头——最终,他发现失去了他们的踪迹。这时波兰人一家已跨过一座拱形小桥,拱顶遮住了他的视线,当走到桥上时,他已见不到他们。他从三个方向寻找,一路往前,还有两路是朝又小又脏的码头两边方向,结果什么也没有发现。他感到焦虑万分、精疲力竭,最后不得不放弃找寻的打算。
他头脑发热,身上到处都是黏滞滞的汗,脖子瑟瑟发抖,口渴难忍,于是四下寻找有什么东西可以解渴。他买了一些水果,一些过熟的草莓,一面走一面吃。一片人迹罕至的小小空地映入眼帘,景色很吸引人,几周以前,就是在这里,他打算逃离这个城市。他在一个井边坐下,斜靠在石头上。这里很静,在铺砌石块的路面上,杂草丛生,周围都是断壁残垣。广场上有一些高低不同的废弃的房子,其中一幢尤其显眼,像是一个宫殿,有着突出的拱形窗子,小小的阳台上雕刻着狮子。另一幢屋子的底层是一家药房。一阵阵热风,不时送来了消毒剂的气味。
他坐在那里,这位大师,这位在文学界享有崇高威望的艺术家,《不幸的人》的作者。正是他采用了晶莹明澈的文体,摈弃了那种吉卜赛式浮夸的风格和晦涩暧昧的描写;正是他,对陷入深渊中的苦难人们寄予同情,而对堕落的灵魂加以谴责;正是他,承担起荣誉带给他的职责:
他的声誉已被官方认可,他的名字已加上贵族的头衔,他的文章已经成为孩子们的范本——就是他,坐在那里,紧闭着眼睛,偶尔面带嘲弄和尴尬的表情,通过化妆略有改善的嘴唇毫无声气地耷拉着,好像一个半梦半醒的大脑中形成了只言片语,产生了梦一般的奇怪逻辑。
“斐多,只有美才是神圣的,同时也是看得见的,因此,它是艺术家通向灵魂的途径。可是,我亲爱的小斐多,你是否相信一个凭感觉而获得灵性的人居然能获得智慧和人类的尊严?或者你是否认为——这留待你去抉择吧——这是一条没有结果的甜蜜而危险的道路?因为你必须知道,如果没有爱神与我们同行,成为我们的先导,我们的艺术家就无法通过美的道路。尽管我们可以成为按照自己的方式活动的英雄,但我们仍然像女人一样,因激情让我们振奋,爱情始终是我们的期望——这是我们的渴望,也是我们的羞辱。现在你难道没有看出,我们的诗人既没有智慧也没有威严了吗?我们总要迷路,偏离轨道,放纵我们的情感吗?我们的文章写得道貌岸然,其实都是虚妄与胡扯;我们的名誉不过是谎言,大众对我们的信仰也极其荒谬,因此,应该禁止用艺术来教育青年。因为当一个人在内在驱动下坠入深渊时,他怎么可能为人师表?
“我们可以拒绝坠入深渊,获得荣誉,但即便如此,它依然吸引着我们。我们还是抛弃掉最后的知识吧,因为斐多,知识是谈不上什么尊严的,也不是什么严肃的事情:它只是叫人通晓、理解、原谅,但没有态度。它对人们所陷入的深渊寄予同情,它本身就是深渊。因此我们应该毅然决然地抛弃它,全心全意地致力于寻求客观世界和外在形状的美、简洁、伟大和严谨吧。但斐多啊,外形和客观现实会使高贵的灵魂沉醉,并唤起人的情欲,同时会使他陷入可怕的情感犯罪中,把人引向深渊,而这正是美的严谨所抵御和抛弃的。我得说,它们会把诗人引到那里,因为我们无法使自己奋发向上,只能放纵欲望,导致犯罪。现在我要走了,斐多,你留在这儿吧。当你不再见到我时,你也离开吧。”
以后的几天,古斯塔夫 · 冯 · 阿申巴赫感觉不太舒服,比平时晚一点儿离开宾馆。他经常感到一阵阵的头晕,其实只有一半才是身体上的原因,除此之外,他产生了强烈的恐惧感和困惑感,还有走投无路、灰心绝望的感觉。但这到底是由于外部世界引起的还是由于个人生活引起的,并不十分清楚。在休息室里,他看到一大堆整装待发的行李,便问门房动身的是谁,对方回答出了波兰贵族的姓名,而他其实已经隐隐地感觉到了。听到这个消息后,他那憔悴的面容并不改色,只是略略仰起了头,好像这是一个不值得了解和打听的消息:“什么时候走呢?”“午饭后。” 门房答道。他点了点头,向海边走去。
那里已经没有什么人了。波浪在海岸与第一片沙滩之间冲刷着,冲向了遥远的大海。一度充满生机、五彩缤纷的海滨胜地,现在满目凄凉、无人问津、一片脏乱。一副照相机架在三脚架上,显然已被人遗弃,照相机上的一块黑布,在凉风中扑扑地飘动着。
塔齐奥在那里,跟三四个伙伴在他小屋右前边的地方玩耍着,阿申巴赫坐在大海和那排房子中间的地方,在膝盖上盖着一条毛毯,看着他。这回,女人似乎都在忙着整理行李,没有看着他们玩游戏,因此,他们玩得毫无约束、十分放肆。那个身体结实、名叫 “亚斯胡” 的小伙子忽然被掷到脸上的沙子迷了眼睛,就逼着塔齐奥跟他搏斗,结果,身体较弱的美少年很快倒了下去。但好像是因为离别时刻的到来,奴颜婢膝的亚斯胡一下子变得冷酷无情,想为自己长时间来低声下气的处境进行报复,这个胜利者把膝盖压在塔齐奥的背上,把他的头按到沙子里,以致塔齐奥差点儿窒息。他努力地想要挣脱背上的这个男孩,但无济于事,只得慢慢停了下来。惊恐万状的阿申巴赫正要跳起来去救他,那个身长力大的家伙终于把他放了。塔齐奥脸色惨白,坐了起来,一动不动地停了几分钟,眼神阴郁,头发乱蓬蓬的。后来,他站了起来,离开了。其他人叫他,开始时喊声轻快温和,后来声音变成恳求,但他没有回应。
这时,那个黑头发的男孩子似乎对自己的越轨行为感到悔恨,赶上他,想跟他和解,但他耸耸肩膀拒绝了。塔齐奥沿斜对角方向向水里边走去。
他赤着脚,穿着一件有红色胸结的亚麻布条纹游泳衣。
他在水边待了一会,低垂着头,用脚趾尖在沙滩上画着什么,然后穿过最深到膝盖的浅水,到达了沙洲上。他在那里站了一会儿,眺望着远处,然后慢慢向左边走去。那儿,有一大片水跟陆地远远隔开,他的自尊让他离群独立。他像一个独特的游魂站在海边,站在风中,面前是烟雾迷蒙的无限空间。他又一次停下来眺望。忽然,好像突然想起了什么事,他转动上半身,一只手搭在臀部,向海岸望去。阿申巴赫坐在那边看着他,就像他们目光第一次接触时那样。他的头靠在椅背上,目光随着那个漫步的孩子慢慢移动。现在,他抬起头去迎接那个男孩的目光,接着,又把头垂到胸部,好像陷入了深深的沉睡中。在他看来,那个苍白而可爱的召唤者似乎在对他微笑,向他招手;这时,那个孩子的手似乎已不再放在臀部,而是向前方伸出,似乎要在充满希望的神秘莫测的太空中翱翔。他也像往常那样,跟着他神游。
几分钟后,救援的人才过来,他已经滑向了椅子的一侧。他们把他送回房间。在夜晚来到之前,世界震惊地获悉他去世的消息。
"""
他看见推特上,附件的青年团体
要宣布免费派鸡
他们属于一个庞大的组织
这个组织有很多政治议程
但
权力是他们唯一追求的事物
冷冻鸡肉是他们的吉祥物
曾经的领袖买过一只售一元的鸡肉
”
确诊的人数像他们的功绩榜
在乱象中牟取利益
"""
命运中的热石头-[[洛朗·戈代]]
========================
命运中的热石头
[[斯科塔的太阳|https://www.20dcr.com/book/siketadetaiyang/2761508.html]] 洛朗·戈代
========================
太阳的热量仿佛要把大地烤裂。没有一丝风吹动橄榄树的树叶。一切都一动不动。山岗的清香早已消散。石头热得在呻吟。八月的天气压着加加诺高地,无疑是一种天命。在这片土地上,无法相信以前曾有一天下过雨;水也曾灌溉过农田,使橄榄树喝饱过水。无法相信任何动物或植物可能——在这片干燥的天空下——找到过滋养的东西。现在下午两点钟,大地在受火的煎熬。
一头驴子在土路上慢慢走。忍气吞声转过道路的每个拐角。什么东西都摧垮不了它的顽固。不论是它呼吸的灼热空气,还是碰坏它的蹄子的尖石子。骑在驴背上的人像受到古代诅咒的一个影子。被热气熏得麻木鲁钝,任凭坐骑把他俩怎样带到这条路的尽头。牲畜正在履行自己的职责,带着无声的意志,向白天挑战。驴子没有力气加快步子,慢慢地,一米又一米,倒也跨越了几公里。骑驴的人在牙缝里嗫嚅几句,这些话也都在热气中蒸发了。“什么都摧垮不了我……太阳可以把山岗上的壁虎都杀死,我还坚持下去。我等待得太久了……土地可以吱吱响,我的头发可以烧起来,我走在路上,一直会走到底的。”
时间就这样过去了,处在一只把万物颜色都烧得发白的大火炉里。终于转过一个弯看到了海。“我们到了世界的尽头,”那人想,“十五年来我梦想着这个时刻。”
海在那边。像一潭死水,更是衬托出太阳的威力。这条路没有穿越过一座小村庄,交叉过任何一条其他的路,总是径直地往心里钻。看到这片不动的热得发光的海面出现,可以肯定这条路是走到头了。但是驴子还在走,准备要钻到海水里去似的,要是主人要它这样做,同样会慢慢地、锲而不舍地走下去。骑驴的人不动。他感到了一阵眩晕。可能是他记错了。眼前一望无际的是联成一片的山岗与海水。“我走错了路,”他想,“我早该看到村子了。除非它往后退了。是的,它大概感到我在走近,往后退到海里去了,让我走不到。我就是跳进海浪里,也不后退。走到头。往前走。我要报仇。”
驴子登上了那座仿佛是世上最后的山头。这时候他与它看到了蒙特普西奥。那人微笑了。整个小镇呈现在眼前。白色的村庄,房屋挨得很近,坐落在一个高高凌驾于平静海面的岬角上。在这样荒凉的景色中居然有人的存在,在驴子看来好像也很滑稽,但是它没有笑出来,继续走它的路。
当那人到了小镇边沿的最初几幢房屋时,喃喃地说:“要是有个人在那里不让我过去,我就挥拳头揍他。”他仔细观察每个路角。但是很快放心了。他做出了正确的选择。下午这个时刻,村庄陷入死一般的寂静,街上阒无一人。护窗板关上。即使狗也看不见一只。这是午睡时间,即使地动山摇了,也不会有人冒险往外走。镇上流传一则传说,说有一天这个时刻,一个人从地里收工回家稍为晚了一点,穿过中心广场。就在走到房屋阴影里的那一会儿,太阳晒得他发了疯,仿佛阳光烧毁了他的脑袋。在蒙特普西奥,每个人都信这个故事。广场不大,不过这个时候试图穿越,无异于前去送死。
驴子和骑驴汉慢慢往上走。在这一八七五年,这里还是叫新街,后来才变成了加里巴尔第大道。骑驴汉显然知道他正在往哪儿去。没有人看见他。平时阴沟垃圾堆里爬满的瘦猫,他竟也没有撞见一只。他并不把他的驴子赶往阴影里走,也不想在一张凳子上坐下。他往前去。他的固执叫人提心吊胆。
“这里一切都没变,”他喃喃地说,“街道还是那么穷。房屋还是那么脏。”
这个时候,尚帕奈里神父看见了他。蒙特普西奥的本堂神父,大家都称呼他唐乔尔乔,他把自己的祈祷书忘记在挨着教堂给他当菜园的那一小块地里了。早晨他在那里工作了两小时,刚才想起肯定把书放在了工具房旁边的木椅子上了。他走出门,就像外面刮着暴风雨,卷缩身子,眯缝眼睛,叮嘱自己尽快做完,免得这身老骨头在毒日头下暴露太久。这时他看到驴子和骑驴汉经过新街。唐乔尔乔一怔,本能地画了个十字。然后他转身站到教堂沉重的木门后面躲太阳。最令人惊讶的是他没有想到发出警告或者呼唤陌生人,问他是谁,要干什么(外来的人是不多的,唐乔尔乔叫得出每个村民的名字),而是回到小室内一点也不去想它了。他躺下,打盹,夏季的午睡是连个梦也不做的。他在骑驴汉面前画十字,好像是要驱散一个幻象。唐乔尔乔没有认出吕西亚诺·马斯加尔松。他怎么会认出他来呢?那个人早已没有从前的模样了。他有四十来岁,但是他的两腮瘪得像个老头儿。
吕西亚诺·马拉加尔松在这个沉睡的古镇小路上逛。“真有些年头了,但是我还是回来了。我在这里,你们还不知道吧,既然你们睡着了。我沿着你们的房屋门前走,我在你们的窗子下经过,你们什么还都没料到。我在这里,我来收我的债。”他逛着,直到他的驴子停下,蓦地停下。这头老驴子仿佛一直知道它应该来的是这里,也是在这里它跟烈阳的斗争宣告结束。它一下子停在比斯科蒂家门前,再也不走了。那个人身手矫健地跳到地上,敲门。“我又到了这里,”他想,“十五年刚刚一晃而过了。”无尽的时间过去了。吕西亚诺正想去敲第二次,门轻轻开了。站在他面前的是一位四十来岁的妇女,穿了晨衣。她长时间盯着他看,不说什么。面孔上没有显露任何表情。不害怕,不快乐,不惊讶。她盯着他的眼睛看,好像要掂量接下来的事是什么。吕西亚诺没有动。他像在等待妇女发出信号,做手势,皱眉头。他等着,他等着,身子发僵。“她要是做出关门的表示,”他想,“她要是稍许有一点后退的动作,我就跳上去,撞开门,把她强奸了。”他的眼睛正在把她吃了,窥测任何打破这种沉默状态的动作。“她比我想象的还美。我今天死了也值的。”他揣度她在晨衣里的肉体,这使他内心滋生狂暴的欲望。她一句话不说。她让从前的事浮现到记忆的表面。她已经认出眼前的这个男人是谁了。他为什么到这里站在门槛前,这是她还没有想去弄清楚的一个谜。她只是让从前的事重新涌上她的心头。吕西亚诺·马斯加尔松,就是他没错,十五年了。她观察他,既无恨也无爱。她观察他,仿佛要在眼睛里去看出一个人的命运。她已经属于他了,不用争执,她属于他了。既然事隔十五年后他回来了,敲她的门,管他要求什么,她都给。她站在门槛上会同意的,对一切都会同意的。
为了打破围绕他们的静默与静止状态,她放开了握在手里的门把。这个简单的手势足以使吕西亚诺不用再等待。他现在从她的脸部表情看出她没有走神,她没有害怕,她会给他要什么做什么。他轻快地走进屋,仿佛不愿意让香气吹散在空气中。
一个风尘仆仆、肮脏的男人在这个壁虎做梦也要变成鱼的时刻,走进了比斯科蒂的屋子,石头也找不到反对的理由。
吕西亚诺进了比斯科蒂的家。这会要了他的命,他知道。他知道当他从这幢房子出来,街上又会全是人,生活带着它的法律和它的争斗又开始了,他必须付出代价。他知道人家会把他认出来的。人家会把他杀了。回到这个村子,走进这幢房子,这就要引来杀身之祸。这一切他都想到的。他选择了在这个暑气熏蒸,即使猫也被骄阳晒瞎眼睛的时刻进村子,是因为他知道如果街上不是阒无一人,他就是连广场也走不到。这一切他都知道,就是肯定会遭遇不幸也没有使他有过颤抖。他走进了那幢房子。
他的眼睛隔了好一会儿才习惯暗影。她是背对着他。他跟随她走进一条好像走不完的走廊。然后他们到了一个小房间。没有一点声音,墙上的凉意对他好像是轻轻的抚摸。他那时把她抱在怀里,她不说什么。他给她脱衣服。当他看到她这样一丝不挂在他面前,他禁不住喃喃地说:“菲洛美娜……”她全身颤抖。他没有注意到。他得到了满足,做了以前起誓要做的事。他经历了他想象过一千遍的这一幕。十五年监禁生活想的就是这件事。他总是相信当他脱去这个女人的衣服的时候,有一种比肉体欢乐更大的欢乐会使他激动不已——复仇的欢乐。但是他想错了。没有什么复仇。只有两只大奶子,抓在他的手心里。只有一种女人的香气,弥漫他的身子四周,持久不散,温热。他以前那么渴望这个时刻,现在他沉浸其中,迷失了,忘记了世上其余的一切,忘记了太阳、复仇和村民的乌黑眼睛。
当他在大床的新鲜床单里抱住她时,她像个处女叹口气,唇上露出微笑,表情惊奇淫猥,毫不抵抗地任人摆布。
吕西亚诺·马斯卡尔松一辈子就是被别人一边提起一边吐唾沫的“强盗”。他靠偷鸡摸狗、掠夺旅客财物为生。可能他也在加加诺的大路上杀死过几个可怜虫,但是这些事不能肯定。无法证实的故事到处流传,实在是太多了。只有一件事是有根有据的:他的生活“荒淫无度”,大家必须远远躲开这个人。
在他的光荣年代,也就是说他的无赖生涯处于巅峰时,吕西亚诺·马斯卡尔松经常上蒙特普西奥来。他不是生在村里的,他喜欢这个地方,来这里过他的好时光。在镇上他遇见了菲洛美娜·比斯科蒂。这位出身于一个普通但是光荣的家庭的少女萦绕他的心头久久不去。他知道自己受名声所累,没有希望娶她为妻,于是他就开始对她生出欲思,就像无赖对待女人一样。占有她即使只是一个夜晚也好,这种思想使他的眼睛在白昼将尽的热光下灼灼发亮。但是命运不允许他得到这种粗暴的欢乐。一个普通的早晨,五名宪兵到他歇息的旅舍候着他,不由分说把他逮走了。他被判了十五年徒刑。蒙特普西奥把他忘了,很高兴摆脱了这个斜眼贪看村里少女的孬种。
吕西亚诺·马斯卡尔松在牢里有的是时间去重新思考他的人生。他以前有过小偷小摸的行为。他做过什么吗?没有。他生活中有过什么值得他在监狱里去回忆的?没有。一个人生就是这么过去了,毫无所为也毫无风险。他没有期望什么,也没有错过什么,因为什么也没做过。他的生存只是一片无聊的海洋,逐渐地,他对菲洛美娜·比斯科蒂的欲念倒像是唯一的岛屿,也使其余一切都存在了下来。当他在街上颤着身子跟随她,他觉得自己活活要窒息过去了。这使其余一切都有了意义。那时,是的,他对自己发誓,出狱后要满足这个粗暴的欲望,他至今唯一有过的欲望。不计任何代价,占有菲洛美娜·比斯科蒂,然后死了也甘心。其余一切,一切的一切都无足轻重。
吕西亚诺·马斯卡尔松从菲洛美娜·比斯科蒂家里出来,没有跟她交换过一句话。他们并排睡了一觉,让爱的疲乏侵入身子。他睡得很沉,已经多年没有这样睡了。全身感到一种宁静的睡意。肉体极度松弛,心满意足的午睡,人毫不惊慌。
他在门前找回自己的那头驴子,驴身上还沾着一路的风尘。这一时刻他知道倒算账的齿轮啮合了。他在走向死亡。毫不犹豫。热气已下降,村庄又恢复了生命。邻近房屋的门口,几个小老太穿了黑衣,坐在摇晃的凳子上,正在低声议论这头驴子怎么怪怪地出现在这里,纷纷猜测主人可能是谁。吕西亚诺·马斯卡尔松一出现,把这些女邻居吓得噤若寒蝉。他在心里暗笑。一切跟他预想的一样。“蒙特普西奥的这些傻瓜没有改变,”他想,“他们以为怎么啦?以为我怕他们?以为我现在要设法逃出他们的手掌?我再也不怕谁了。今天他们将要把我杀了。但是这也不够叫我害怕。我要是怕也不从那么远的地方来了。我是打不着的了。他们到底懂不懂?他们要打也打不到我了。我享受过了,在这个女人的怀抱里,我享受过了。一切都到此为止还更好,因为此后的生活会平淡无奇,叫人提不起精神。”想到这里,他有了个主意,要做出最后的挑衅,迎着女邻居的窥视的目光,向她们表示自己什么都不怕,站在门槛上堂而皇之拉裤裆。然后他骑上驴背,走回头路。他听到背后老妇人群情激动。这条消息一说就飞快传了开去,惊动了每幢房子,从平台到阳台,通过这些牙齿不全的老嘴巴辗转相传。传言在他的背后愈播愈广。他又通过蒙特普西奥的中心广场。咖啡馆桌子已经摆了出来。有几个男人分散在各处谈论。他经过时大家都闭上了嘴。在他背后声音又响了起来。他是谁?从哪里出来的?有的人那时把他认了出来,谁都不敢相信,吕西亚诺·马斯卡尔松。“是的,就是我,”他经过这些惊呆的面孔前这样在想,“别花那么大的劲盯着我看。就是我。不用怀疑。你们急于要做什么就做什么吧,否则让我过去,但是别睁着野兽的眼睛瞧着我。我在你们中间穿过,慢慢地,我不想逃跑。你们是苍蝇,又肥又丑的苍蝇,我手一挥把你们都赶走。”吕西亚诺继续往前走,往新街下去。一群不声不响的人现在跟在他的后面。蒙特普西奥的男人都离开了咖啡馆露天座,女人在阳台上弯下身子,呼唤他:“吕西亚诺·马斯卡尔松?是你吗?吕西亚诺?你这个猪崽子,色胆包天还敢回这里来。”“吕西亚诺,抬起你的乌龟头,让我看看是不是你啊。”他一声不回答。始终盯着天边看,面色阴郁,不慌不忙。“女人叫喊,”他想,“男人动手。这一切我都料到了。”人群愈来愈逼近。现在有二十来人紧跟着他走。新街沿途有几个女人从她们家的阳台上,从她们家的门槛上呼唤他,同时把她们的孩子夹在大腿之间,在他经过时划十字。当他经过教堂,在几小时前遇到唐乔尔乔的地方,一个特别响亮的声音吼叫:“马斯卡尔松,今天是你的死日。”只是那时候他才朝着声音的方向转过脸来,全村的人都可看到他的嘴唇上露出可怕的挑战的笑容,叫他们大家心里发寒。这个微笑表明他知道。尽管这样他还是鄙视他们。他已经得到了他来这里寻找的东西,他带着这份欢乐直至走进自己的坟墓。有几个孩子被这个外来人的狞笑吓得哭了起来。这些妈妈异口同声,不由说出这句虔诚者的咒语:“这是个魔鬼!”
他终于走到了村子口。最后一幢房子离此仅几米远。在这以后就是这条长长种有橄榄树的石子路,伸展消失在山岗里。
有一群汉子不知从哪里钻了出来,挡住他的去路。他们带了铲子、锄头作为武器,脸绷成铁板,紧紧排成一行。吕西亚诺·马斯卡尔松勒住驴子,好久没有一点声音,没有人动一动。“我要死在这里了。在蒙特普西奥的最后一幢房子前。这些人中谁会第一个向我扑过来?”他感到驴子肋部呼噜噜喘长气,他拍拍它的肩胛骨作为回应。“这些乡巴佬把我干了以后总会想到给我的牲畜喝上水吧?”他坐正身子,盯着这群人不动。那些女人在路角也都已静了下来。没有人敢做个手势。一股呛人的味道传了过来,他嗅到的最后的味道。那是干番茄的强烈气味。所有的阳台上都放着大块木板,家庭主妇把切成四块的番茄放在上面晒干。阳光烤着它们。随着时间都蜷缩了起来,像虫子似的,发出一股恶心带酸的味道。“晒在阳台上的番茄要比我活得更长久。”
突然一块石头砸在他的脑门中央。他没有力气转过身。他勉力笔直骑在鞍子上不倒下。“就是这样的,”他还有时间想,“他们就是这样把我杀死的。就像用石头砸一个被逐出教门的人。”第二块石头打在他的太阳穴上。这次砸得很厉害,使他晃了一晃。他跌倒在尘土上,两只脚钩在马镫上。血从眼睛流下,他还听到四周的叫声。男人血性子上来了,每个人都拿了石头,个个要砸他。石头像一阵骤雨似的砸落在他的身上。他感到当地的热石头正在杀害他。这些石头还沾着发烫的阳光,把山岗的干爆气息散播在他的四周。稠而热的血洒在他的衬衣上。“我倒在了地上,我不反抗。砸吧,砸吧。我心中杀死不了的东西你们还是杀死不了的。砸吧。我没有力量了,血流了出来。谁会扔最后一块石头?”奇怪的是最后一块石头就是没有扔过来。他有一瞬间想这些男人出于残忍的本性,是要延长他的临终时刻,但不是这么回事。本堂神父刚刚赶到。他夹立在男人和他们的猎物之间。他指责他们是恶鬼,制止他们的行动。吕西亚诺感觉到他立即跪倒在自己的身边。神父的呼吸钻进了他的耳朵:“我在这里,我的孩子,我在这里。挺住。唐乔尔乔来照顾你。”石头雨没有再下下来。吕西亚诺·马斯卡尔松宁可推开神父,让蒙特普西奥人完成他们开始做的事,但是他没有力气了。神父的干预毫无作用。它只是延长他的弥留时间。让他们愤怒野蛮地用石头砸他吧。让他们用脚把他踩死吧。这也是他愿意给唐乔尔乔的回答,但是他的咽喉里一个声音也发不出。
假若蒙特普西奥的神父没有在群众与他们的受害者之间插身进来,吕西亚诺·马斯卡尔松会死得很幸福。嘴含微笑,就像渴望胜利、战死疆场的征服者。但是他拖得还是太久了一点。他的生命离开躯体还是太慢了,还有时间去听到他永远不该知道的事情。
村民已经团团围住这具躯体,既然不能完成他们的杀戮,就用嘴巴辱骂他。吕西亚诺还听得到他们的声音,仿佛这是世界上最后的呼唤。“这下子你不会再想回来了吧。”“吕西亚诺,跟你说过这是你的死日。”然后最后这句禁令使他身子底下的土地都震动了:“伊玛科拉塔之后,你再也强奸不了别的女人啦,你这个猪仔子。”吕西亚诺的毫无力气的身体从头到脚颤抖着。他的精神在他紧闭的眼皮后面摇晃不定。伊玛科拉塔?他们为什么说伊玛科拉塔?这个女人是谁?他是跟菲洛梅娜做的爱啊。过去的事涌现在他眼前。伊玛科拉塔,菲洛美娜,从前的形象跟周围人群嗜血的笑声混杂一起。他又看到了一切。他明白了。当他周围的男人继续鬼哭狼嚎时,他在想:
“我只差一点点就可以幸福地死去……才差几秒钟。多了这几秒钟……我感到热石头对我身体的反响……是的……我是这样想事情的。血在流,生命在失去。我的微笑至死也是为了嘲弄他们……就差了这么一点,我就失去了这种满足感。人生最后还要暗算我一次……我听到他们在我周围发笑,蒙特普西奥的男人在发笑,吸收我的鲜血的土地在发笑。驴子和狗也在发笑。瞧这个吕西亚诺·马斯卡尔松,他以为搂着的是菲洛美娜,干的却是她的妹妹。瞧这个吕西亚诺·马斯卡尔松,他以为在凯旋中死亡,而今躺在那堆尘土里,脸上还露出胡闹的鬼脸……命运作弄了我,狠狠地作弄了我。太阳对我的错误发笑……我糟蹋了自己的生命。我糟蹋了自己的死亡……我是吕西亚诺·马斯卡尔松,我对着嘲弄人的命运吐唾沫。”
跟吕西亚诺·马斯卡尔松做爱的确实是伊玛科拉塔。菲洛美娜·比斯科蒂在马斯卡尔松逮捕后不久就患肺动脉栓塞去世了。她的妹妹伊玛科拉塔是比斯科蒂一家最后的幸存者,住在老屋里。星移斗转,十五年的狱中生活过去了。伊玛科拉塔徐徐地长得愈来愈像姐姐。菲洛美娜若能假以时日让年华逝去的话,长的必然是她的这张脸。伊玛科拉塔一直未嫁。人生好像对她不感兴趣,她的生活中除了四季更替以外也没遇到过其他意外的事。这些沉闷的岁月,有时会使她回想起孩子时那个向姐姐献殷勤的男人,这总会引起一种欢悦的颤抖。他叫人害怕。他的无赖的笑容在她脑海里萦绕不去。她想起就感到兴奋与陶醉。
十五年后,当她打开门,看到这个人笔直站在她面前,什么话都没问,她觉得这显然是冥冥命运的力量,她必须俯首屈从。这个无赖在这里,面对着她。在她还从没发生过什么事。她伸手就可得到使自己陶醉的东西。过了一会儿,当他进了房在她赤裸的身子前喃喃说的是姐姐的名字,她的脸色苍白了。她立即明白他把她当成那个人了。她犹豫了一会儿。应不应该把他推开?向她说出他弄错了?她一点不想这样做。他在这里,她的面前。如果把她当作姐姐能给他带来更大的快乐,她准备把这份奢望贡献给他。这里面不存在谎言。她同意他要做的一切,如此而已,成为一个男人的女人,何况她的一生也仅有一次。
唐乔尔乔已经开始给垂死的人做终傅仪式。但是吕西亚诺不愿意了,他愤怒地扭动身子。
“我是吕西亚诺·马斯卡尔松,我正在受人嘲笑中死去。我的整个人生都落得个身败名裂。可是,这改变不了什么。菲洛美娜或伊玛科拉塔。无关紧要。我得到了满足。这个谁能理解呢?……我对这个女人相思了十五年。十五年梦见的是她给我这样的拥抱与宣泄。我刚出狱,做了我该做的事,我走进了这幢房子,跟里面的女人做爱。我很在乎这件事,十五年想的就是这件事。命运决定跟我开个玩笑,谁能强过它呢?我没有权力让河水倒流,使星光熄灭……我是一个男人。我很在乎一个男人能做到的事情。走到这里,敲这扇门,跟给我开门的女人做爱……我只是一个男人。除此以外,让命运嘲笑我吧,而我无能为力……我是吕西亚诺·马斯卡尔松,我陷入死亡愈是深,愈是可以不再听到这个戏弄我的世界的谣言了……”
在乡村神父还没有结束祈祷以前他就断了气。他若在死亡以前知道这一天以后发生的事,他就会笑起来。
伊玛科拉塔·比斯科蒂怀了孕。这个可怜的女人后来生了个儿子。这样给马斯卡尔松一系传宗接代,出自一个错误,出自一桩误会。一个是无赖父亲,交欢两小时后遭人杀害,一个是老处女,第一次委身于一个男人。这样诞生了马斯卡尔松家族。男人误认了人,女人接受这个谎言,因为欲望使她屈服。
在那阳光灼人的白天诞生了一个家族,因为命运有意作弄人,就像猫有时也是这样,用爪子去作弄受伤的鸟。
起风了。压得干草都倒在地上,让石头发出尖叫。一股热风,驱散村庄的噪声和海边的腥味。我老了,身板嘎吱嘎吱响,就像风中的树枝。我疲劳,手脚不方便。起风了,我靠着您才不至摇晃。您温柔地把手臂伸给我。您是个年轻力壮的汉子。我从您强壮镇定的身体感觉出来的,我们将会一直走到底。我挽着您再也不会累倒。风在我们耳边呼啸,吹走了我说的有些话。我说的话您听不清楚,别感到不安,我宁可这样。让风吹走一些我说的话,这对我更方便。我不习惯说话,我是斯科塔家的女人,我的哥哥与我是聋哑女的孩子,蒙特普西奥的人都叫我们是“不声不响的人”。
您听到我说话会奇怪吧。这是我那么多年来第一次说话。您在蒙特普西奥有二十年了,或许还不止,您看到我是如何变得沉默的。您以前像蒙特普西奥的人那样认为,我滑进老年的冰水中再也不会浮上来了。然后那天早晨,我来找您,要求跟您面谈,您颤抖了一下。仿佛是一条狗或一幢房子的门面开始说话了。您以前认为这是不可能的。由于这个原因您同意见面的。您要知道老卡尔梅拉要说些什么。您要知道我为什么要您黑夜来这里。您把手臂伸给我,我挽了您走上这条小土路。我们到了教堂前往右走,把村子抛在背后,这更增加了您的好奇。我感谢您的好奇,唐萨尔瓦托尔。这有助于我没有放弃。
我来对您说我为什么又开口说话了。这是因为我昨天开始昏了头。请不要笑。您为什么笑?您认为一个人不可能神志那么清醒,真正昏了头的时候会说自己昏了头。您错了。我的父亲临终在床上说:“我要死了”,接着他就死了。我昏了头,这是昨天开始的。从那以后我是过一天是一天了。昨天我回顾我的一生,我是经常这样做的。有一个我很熟悉的人的名字我就是想不起来。六十年来我差不多天天想他。昨天,他的名字溜走了。有几秒钟时间,我的记忆成了一大片空白,我什么也抓不住。这没有持续多长,名字又浮现上来了。科尔尼。这个人是这样叫的。科尔尼。我又找到了,但是要是我会把他的名字忘记,即使是片刻,这也是我的精神投降了,一切都会渐渐流失的。这事我知道。今天早晨我来找您就是为了这件事。我应该趁一切还未遗忘以前说出来,我给您带来这件礼物也是为了这件事,这件东西我愿意归您保存,这我会对您说的。我对您说起它的历史,我要您把它挂在教堂正殿,在还愿物中间。这件东西跟科尔尼有关,很适合挂在教堂的墙上。我再也不能把它留在家里了。我只怕有一天早晨醒来再也记不起它的历史,以及我要给的那个人。我愿意您把它保存在教堂里,然后当我的孙女安娜到了年龄,您再把它传给她。我已不在人间了,或者老朽了。您来做吧,就像是我通过那些岁月在跟她说话。请看,就是这件东西。这是一块小木板,是我请人锯的,磨光上漆。中间我放上了这张那不勒斯—纽约的旧船票,在船票下面是一枚铜徽章,上面刻着:“科尔尼惠存,他曾在纽约街头给我们做向导。”我把它托付给您啦。不要忘记,这是给安娜的。
我要说了,唐萨尔瓦托尔。但是我还有最后一件事要做。我给您带来几支香烟,让您在我身边吸。我喜欢闻烟草的味道。吸吧,我求您了。风会把烟圈吹到坟墓上。我家的死者喜欢闻香烟的味道。吸吧,唐萨尔瓦托尔。这对我们两人都有好处。给斯科塔家敬上一支烟。
我怕说。天气温和,天空也弯下腰好听我们说话。我要把一切都说出来。风会吹走我的话。让我想一想,我是为风说的,您几乎听不着我说的话。
木塔里甫的割礼- 刘亮程
========================
木塔里甫的割礼- [[刘亮程]]
-----
木塔里甫是我在库车认识的第一个维吾尔族朋友,在县电视台工作,汉语讲得很好。一起混熟了,有时喝点酒不免谈到男人女人,谈生活的快乐与满足,也谈到死亡,只是随口说几句。我和木塔里甫都年轻,有一大堆无聊时光需要那些无聊却轻松的话题去打发。男女是这种场合永谈不厌的主题,而且谈着谈着,总会落到具体的某个地方。
一次我问木塔里甫,割过礼的男人跟没割礼的男人是不是真的不一样。以前我听说男人割礼后那东西会长得长而壮实。我在乌鲁木齐大澡堂洗澡时,经常遇到割过礼的维吾尔族和回族男子,有意偷看几眼,那地方,除了毛多一些,也看不出有多长多壮实。木塔里甫却认为绝对不一样。没割礼前,木塔里甫说,那地方静悄悄的,好像一直在睡觉。割礼后没几天,就有动静了,活了,像只小兔子一样往前蹿了。我被木塔里甫的讲述吸引了,执意让他说说自己割礼时的情景。
是个秋天,木塔里甫说,门口的大桑树已经落掉一半叶子,早晨一醒来我就感觉到家里要有大事情了。院子里有洒水的声音,接着是父亲的说话声和他用那把大芨芨扫帚扫地的声音。昨晚上也许刮风了,桑叶、葡萄叶又落了金黄的一地。母亲推门进来,穿着一身过节才穿的漂亮衣服,她给我也换了一身新衣服,帮我洗净脸,戴上小花帽,然后拍着我的脸蛋说,孩子,你已经七岁了,该给你割礼了。
这之前我也知道一点关于割礼的事,老师讲没讲过记不清了。在班上经常有男同学请假,说是“割礼”了。我们似懂非懂的。因为割礼一般在五至八岁期间,有的同学早割了,有的会晚一些。待割礼的同学回来,我们总要想办法让他掏出来看看,到底割成啥样了。问他疼不疼,怎么割的。从那时我就知道自己迟早也会有这一天。
家里逐渐来了许多人,连几十里外的乡下亲戚也来了。父亲宰了一只羊,正忙着煮肉做抓饭,母亲进进出出招呼客人。还请了三个唱木卡姆的艺人,在葡萄架下的大炕上放声弹唱。他们的歌声把葡萄叶子都震落了。架上垂挂的几大串葡萄分外引人注目。后来我才知道,那是母亲为给我过割礼,特意留的几串又大又红的葡萄。一般在这个季节,葡萄早摘完该下秧了。
过了一会儿,母亲把我领到里屋,炕上坐着几个老年人,都笑眯眯地望着我。有一个长胡子阿訇,端坐在中间,母亲把我带到他面前,行过礼。阿訇摸摸我的头,很轻松地说笑两句,让我脱掉裤子。我有点害羞,忸怩几下,还是脱了。阿訇一手托起我的小东西,捋了几下,浇水清洗了一番,嘴里念着我听不懂的经文,其他人都静悄悄的。阿訇从口袋里掏出一枚磨得发亮的小铜钱,把捋得细长的包皮从铜钱中间的方孔穿过去,又捏住捻和捋,那地方木木的,都快没感觉了。这时有人从外面提进一只坎土曼,上面是烧得发烫的干净细沙。父亲蹲在旁边剥一只煮熟的鸡蛋。母亲不知到哪去了,我转过头找母亲,见房子里只剩下男人。我紧张地盯着阿訇的手,腿也有点颤。就听阿訇说,小东西还没长熟,今天不割了。我心里一轻松,阿訇又说,快看,天上飞过一只老鹰。我一仰头,只觉下身一阵生疼,低头看时,铜钱已落在地上,我的小东西上全是血,我哇的一声,嘴刚张大,还没哭出声,父亲的熟鸡蛋已塞到我嘴里。阿訇往我的伤口处敷棉花灰,然后撒上烧烫的细沙,血渐渐就不流了,我嘴里的熟鸡蛋也嚼咽下去了一半。这时外面的弹唱突然高亢起来,他们已在院子里跳起买西来甫。
我看着阿訇把割下来的一圈包皮套在一根木棍儿头上,让我父亲拿出去插在墙上。阿訇让我到远远的地方去撒尿,我不知道啥意思,还是去了,一直走到库车河边,对着河水撒了一泡尿。回来时抓饭和煮羊肉都已端上桌子。木卡姆弹唱还在继续,我知道吃喝过后,人们还会跳更加疯狂的买西来甫。这都是因为我,我割掉一小块包皮,给人们带来这么多快乐。
以后一段时间,我天天看着插在墙上的那根木棍。套在上面的一小圈包皮渐渐变了颜色,终于有一天,那一小圈包皮不见了,或许让鸟吃了,或许被风吹走了。只有木棍插在那里,我经过时还会抬头看一眼那根插在墙上的木棍。
后来我才知道,那时消炎措施落后,割礼后最怕龟头发炎。所以割下来的包皮不能扔到肮脏处,连撒尿也要到远远的没有人的地方去。这是讲究。还有,割礼时母亲不能看见,不然以后儿媳妇会经常和婆婆吵架。木塔里甫说。
那个秋天的早晨之后,木塔里甫跟我就不一样了。他被割了一下,就像板在僵土中的一棵幼芽,被人松了一下土。按他的说法,那长势就跟“兔子一样往前蹿”了,但我仍旧不清楚不一样到什么程度。他以后的生活,又是怎样一种我无法体验的快乐与幸福。真想和木塔里甫比一比,却又说不出口。要是小时候就认识,肯定会掏出来比一比的。我小的时候——木塔里甫割礼的那个秋天我在干什么呢,我一样长大了。没被“松土”也一样长长长壮实了。可是,我和木塔里甫的区别究竟在哪儿呢。
木塔里甫与我同龄,四十岁的样子,正是享受人生快乐的大好时期。我也是。我们的快乐与幸福应该是一样的吧,我想,不会因为我少“割”了一下就会少一些快乐吧。等到六十岁或七十岁时,我再跟木塔里甫好好地谈谈人生,男人、女人,当然,最重要的是谈谈死亡。那时我们俩都离死亡不远了。死后我入坟墓,他进麻扎,必定埋不到一块地方,但必定埋在同一片大地上。我们的子孙还会在埋葬我们的土地上面对我们曾经面对的一切。无论他们怎样生活,我和木塔里甫的区别,会在最后时刻显得绝对而彻底。事实就这样简单,那个遥远秋天的早晨一过,我们的生和死,都完全的不一样了。
南柯一梦-[[星新一]]
-----
“恭喜!恭喜!!”
许多人在我的身边蜂拥而至,七嘴八舌地喊叫。
事情是这样发生的。在我胡乱刨地时,意外地刨出个坛子,打开一看,啊!满坛子金币,金光闪闪,耀人眼目。
我开始摆弄着金币玩。时而一枚一枚地摆起,时而把它抛起,倾听那美妙的响声。不一会儿,人们从四面八方涌来,并喊道:“恭喜呀,发财!”
这些人不停地向我点头哈腰,满脸堆笑,阿谀奉承。此种作态,笑脸,真令人生厌。有个家伙,竟想趁机偷一枚。不巧,被旁人瞧见,只好把手抽了回去、教而,在场的人似乎都在觊觎着这块金币。
我觉得太无趣。
其间,还来了几位年轻姑娘。她们都偎依在我的身旁,悄悄地说“您太了不起!”。真是个美男子呀!”云云。
看到达番情景的男人们,不禁赞道“身边环绕着如此美貌的女人,真叫人羡慕!”“但愿今生能有如此艳遇”等等。
我抛出一把金币,并用手示意他们走开,那些家伙弯腰拾起,连连点头道谢,就走开了。这才稍微清静了些。
周围的女人,唧唧喳喳地也扰人不安。又都赖着不走。对女人,我毫无兴趣。塞给金币后,总算打发走了二、三个。可是片刻,她们又蜇了回来。
她们端来了丰盛佳肴,一个偌大的银盘子里,盛满了鱼、肉,还有酒。可我毫无兴趣,我吃了一片面包,喝了口水。她们见我不肯动筷,便说:“让我们品尝品尝吧!”其姿态看上去,为彬彬有礼,但却吃起来没够,贪馋极了。
尔后,来了一个男人说:“我想请您去公司当经理。全体职员都很敬佩您。因此,不叫您为烦杂事务操心,只是想实现敬佩您的这份心愿。”
我一点头,就被请到台上,数百人队伍整齐,向我低头致敬,并振臂高呼:“万岁!万岁!”我觉得这还有那么点意思。给他们当头头,倒也不坏。
“您的勋章已从国外运到了。”一个提着箱子的人这样说道。打开箱子一看,只见镶嵌着金光宝石的勋章上,缀有一条长长的绶带,虽然把它挂在了脖子上,但半点意思都没有。
“这是您的专车。”
面前停着两辆车。一辆是赛车,另一辆是涂黑的大型车。我仍然觉得没趣,哪辆车我也不肯坐。
然而,不管怎么讨厌,也不行。女人们一边尖声欢叫着,一边前簇后拥地把我推进了大客车。虽不情愿坐进这种车里,但又不便拂逆。车轮前飞,一加大油门,顿时觉得头晕目眩,太扫兴了。
不一会儿,车子开到海滨。一艘扬起白帆的游艇停在那儿。我被领到艇上,女人们穿着游泳衣,露出白皙的肌肤,在弹着琴,唱着歌儿。苍空、白云、海鸥、波浪……
“您必须在这儿……”
她们不让我进舱,可我什么都无心欣赏,只想躲入舱内,但好象这也不允。真没趣。
游艇冲向大海,自然,船儿开始颠簸。我感到厌烦。一旦落水,岂不……想到此,惶惶不安,猛然间一股苦涩味儿涌上胸口。我慌忙抓住栏杆,紧闭双目,强忍着。
此时,别无所求,只求“快停船吧”!
一场荒诞离奇的梦,终于结束了。我睁开眼睛,发现自己被放到桌子上。头上安着小型金属装置。周围人正在议论。
“我们研制出了使人做梦的这一装置。用它,人们就可以做理想的梦。刚才试验的录像磁带,是面向成年男子的初梦用的。但是,如对人有害,就不妥了。因此,首先用猴子做试验,看它是否有害。”
因为我是猴子,不通人语。然而,真是无聊、令人厌倦的初梦一收场,我觉得轻松了。难道人类喜欢做这样的梦吗?
我想舒舒服服地睡上一觉,并且喜欢做个梦,在那静寂的大森林里,饱餐一顿香蕉。如果再梦上成为猴王,那更是妙哉,妙哉……
人们仍然在我的身边讨论。
“这只猴子似乎有些疲倦了。看来有一定的害处。但总有一天会改进的。真盼着早一天应用。使用这种产品已经为期不远了。科学在进步,恭喜……”
4
难逃劫数-余华
========================
难逃劫数-[[余华]]
------
一
东山在那个绵绵阴雨之晨走入这条小巷时,他不知道已经走入了那个老中医的视线。因此在此后的一段日子里,他也就无法看到命运所暗示的不幸。
那个时候,他的目光正漫不经心地在街两旁陈列的马桶上飘过去,两旁屋檐上的雨水滴下来,出现了无数微小的爆炸。尽管雨水已经穿越了衣服开始入侵他的皮肤,可四周滴滴答答的声音,始终使他恍若置身于一家钟表店的柜台前。他显然没有意识到自己正行走在一条小巷之中。由于对待自己偷工减料,东山在这天早晨出门的那一刻,他就不对自己负责了。
后来,就像是事先安排好似的,在一个像口腔一样敞开的窗口,东山看到了一条肥大的内裤。内裤由一根纤细的竹竿挑出,在风雨里飘扬着百年风骚。展现在东山视野中的这条内裤,有着龙飞凤舞的线条和深入浅出的红色。于是在那一刻里,东山横扫了以往依附在他身上的萎靡不振,他的脸上出现了从未有过的汹涌激情。就这样,东山走上了命运为他指定的灾难之路。
直到很久以后,沙子依然能够清晰地回忆起那天上午东山敲开他房门时的情景。东山当初的形象使躺在被窝里的沙子大吃一惊。那是因为沙子透过东山红彤彤的神采看到了一种灰暗的灾难。他隐约看到东山的形象被摧毁后的凄惨。但是沙子当初没有告诉他这些,沙子没有告诉东山可以用忘记来解释。
听完了东山的叙述,一个肥大的女人形象在沙子眼前摇晃了一下。沙子准确地说出了这个女人的名字:
“露珠。”
沙子又说:
“她的名字倒是小巧玲珑。”
然后沙子向东山献上了并不下流的微微一笑,但是东山不可能体会到这笑中所隐藏的嘲弄。
东山走后,沙子精确地想象出了东山在看到那条肥大内裤以后的情景——
东山热血沸腾地扑到了窗口上,一个丑陋无比并且异常肥大的女人进入了他的眼睛,经过一段热泪盈眶的窒息,东山用那种森林大火似的激情对她说:
“我爱你!”
沙子也想象出了露珠在那一刻里的神态。他知道这个肥大的女人一定是像一只跳蚤一样惊慌失措了。
二
呈现在老中医眼中的这条小巷永远是一条灰色的裤带形状,两旁的房屋如同衣裤的皱纹,死去一般固定在那里。东山就是在这上面出现的。那个时候,露珠以一只邮筒的姿态端坐在窗口,而她的父亲,这个脸上长满霉点的老中医却站在她的头顶。他们之间只有一板之隔。老中医此刻的动作是撩开拉拢的窗帘一角,窥视着这条小巷。这动作二十年前他就掌握了,二十年的操练已经具有了炉火纯青的结果,那就是这窗帘的一角已经微微翘起。二十年来,在他所能看到的对面的窗户和斜对面的窗户上,窗帘的图案和色彩经历了不停的更换。从那些窗口上时隐时现的脸色里,他看到了包罗万象的内容。在这条小巷里所出现的所有人的行为和声音,他都替他们保存起来了。那都是一些交头接耳、头破血流之类的东西。自然也有那种亲热的表达,然而这些亲热在他看来十分虚伪。二十年来他一直沉浸在别人暴露而自己隐蔽的无比喜悦里,这种喜悦把他送入了长长的失眠。
东山最初出现在老中医视线中时,不过是一个索然无味的长方形。他在雨的空荡里走来。然而当东山突然站住时,老中医才预感到将会发生些什么了。在此后一段日子,老中医因为未能更早地预感,他无情地谴责了自己的迟钝。那时候在东山微微仰起的脸上,他开始看到一股激情在汹涌奔泻,于是他感到自己的预感得到了证实。不久之后东山的身影一闪消失了,他知道东山已经扑到了露珠的窗口,接着他便听到一声如同早晨雄鸡啼叫一般的声音。
面对东山的出现,露珠以无可非议的惊慌开始了她的浑身颤抖。这种出现显然是她无时无刻不在期待之中的,然而使她措手不及的是东山的形象过于完美。她便由此而颤抖起来。因为身体的颤抖,她的目光就混乱不堪,所以东山的脸也就杂乱无章地扭动起来。露珠隐约看到了东山的嘴唇如同一只启动了的马达,扭曲畸形的声音就从那里发出。她知道这声音里所包含的全部意义,尽管她一点也无法听清。
这个时候,她听到了几只麻雀撞在窗玻璃上的声音,这种声音来到时将东山的滔滔不绝彻底粉碎。她知道那是父亲的声音,父亲正在窃窃而笑。他的笑声令她感到如同一个肺病患者的咳嗽。她知道他已经离开了窗口,确实如此,老中医此刻正趴在地板上,那里有一个小孔,他用一只眼睛窥视露珠已经很久了。
在此后的时间里,东山像一只麻雀一样不停地来到露珠的窗口,喳喳叫个不止。然而在这坚强的喳喳声里,露珠始终以忧心忡忡的眼色凄凉地望着东山。东山俊美的形象使她忧心忡忡。在东山最初出现的脸上,她以全部的智慧看到了朝三暮四。而在东山追求的间隙里,她的目光则透过窗外的绵绵阴雨,开始看到她与东山的婚礼。与此同时她也看到了自己被抛弃后的情景,她的目光长久地停留在这情景上面。
每逢这时,她都将听到父亲那种咳嗽般的笑声。父亲的笑声表明他已经看出了露珠心中的不安。于是在第二天的夜晚来到以后,他悄然地走到了露珠的身后,递过去一小瓶液体。
正在沉思默想的露珠在接过那个小瓶时,并没有忘记问一声:
“这是什么?”
“你的嫁妆。”
老中医回答,然后他又咳嗽般地咯咯笑了起来。在父亲尖利的笑声里,露珠显然得到了一点启示。但她此刻需要更为肯定的回答。于是她又问:
“这是什么?”
“硝酸。”
父亲这次回答使她领悟了这小瓶里所装的深刻含义,她将小瓶拿在手中看了很久,但她没看到那倾斜的液体是什么颜色。她所看到的是东山的形象支离破碎后,在液体里一块一块地浮出,那情形惨不忍睹,然而正是这情形,使盘旋在露珠头顶的不安开始烟消云散。露珠开始意识到手中的小瓶正是自己今后幸福的保障。可是她在瓶中只看到了东山的不幸,却无法看到自己的灾难。
于是露珠对东山爱情的抵制持续了两天以后,在这一刻里夭折了。事实上露珠在最初见到东山时,她在内心已经扮演了追求的角色,所谓抵制不过是一本书的封面。
当翌日清晨东山再次以不屈的形象出现在露珠窗口时,呈现在他眼前的露珠无疑使他大吃一惊。
正如后来他对沙子所说的:
“她简直像是要从窗里扑过来似的。”
在那十分迅速的惊愕过去以后,东山马上明白他们的位置已经做了调整。眼下是他被露珠狂热的追求压倒了。他立刻知道结婚已经是一件迫在眉睫的事情。那时候两天前开始的这场雨还在绵绵不绝地下着,因为是在雨中认识,在雨停之前相爱,所以东山感到他们的爱情有点潮湿。但是由于东山的眼睛被一层网状的雾障所挡住,他也就没法看到他们的爱情上已经爬满了蜒蚰。
三
所有的朋友都来了,他们像一堆垃圾一样聚集在东山的婚礼上。那时候森林以沉默的姿态坐在那里,不久以后他坐在拘留所冰凉的水泥地上时,也是这个姿态。他妻子就坐在他的对面,他身旁的一个男人正用目光剥去他妻子的上衣。他妻子的眼睛像是月光下的树影一样阴沉。很久以后,森林再度回想起这双眼睛时,他妻子在东山婚礼最后时刻的突然爆发也就在预料之中了。
森林的沉默使他得以用眼睛将东山婚礼的全部过程予以概括。在那个晚上没人能像森林一样看到所有的情景。森林以一个旁观者锐利的目光成功地做到了这一点。不仅如此,他还完成了几个准确的预料。所以当广佛一走进门来时,森林就知道他将和东山的表妹彩蝶合作干些什么了。那个时候他们为他提供的材料仅仅只是四目相视而已,但这已经足够了。因为森林在他们两人目光的交接处看到了危险的火花。后来的事实证明了森林是正确的。那时候东山的婚礼已经进入了高潮。森林的眼睛注视着一伙正在窃窃私语的人的影子,这些人的影子贴在斑驳的墙上。他们的嘴像是水中的鱼嘴一样吧嗒着。墙上的影子如同一片乌云,而那一片嗡嗡声则让他感到正被一群苍蝇围困。彩蝶的低声呻吟就是穿破这片嗡嗡声来到森林耳中的,她的呻吟如同猫叫。于是头靠在桌面上浑身颤抖不已的彩蝶进入了他的眼睛。而坐在她身旁的广佛却是大汗淋漓,他的双手入侵了彩蝶,仿佛像是揉制咸菜一样揉着彩蝶。一个男孩正在他们身后踮脚看着他们。森林在这个男孩脸上看到了死亡的美丽红晕。
尽管后来事过境迁,然而森林还是清晰地回想出露珠当初像涂满猪血一样红得发黑的脸色,和坐在她身旁东山躁动不安的神态。他甚至还记起曾有一串灰尘从屋顶掉落下来,灰尘掉入了东山的酒杯。
他始终听到东山像一个肺气肿患者那样结结巴巴的呼吸声,他觉得自己听到的是一种强烈的欲望在呼吸。因此当东山莫名其妙地猛地站起,又莫名其妙地猛地坐下时,他感到东山已经无法忍受欲望的煎熬了。他看到东山坐下以后用肩膀急躁地撞了撞他的新娘。当新娘转过头去看他时,他向她使出了诡计多端的眼色。而她显然无法领会,因为她的头又转了回去。可是她随即就大叫一声,这一声使那些窃窃私语者惊慌失措。显然东山在她身上最肥沃处拧了一把,她于是又将眼睛交给了东山,东山这一次使出来的眼色已经肆无忌惮了。森林感到东山的眼色与对面那扇门有关,那扇门半掩着,他看到一张床的一只角。
沙子是在这个时候进来的,他进来以后并没有利用一把空着的椅子,他背靠着门站在了那里。于是森林仿佛看到在一条空荡的街道拐弯处,在一只路灯空虚的光线里,站着一个瘦长的人影。他发现沙子的目光始终逗留在某一个梳着辫子的姑娘头上。那个时候他从沙子神秘的微笑上似乎领悟到了什么。他的这种先兆在不久之后得到了证实。因此在几天以后,森林带着广佛的骨灰敲开沙子的屋门后,他向沙子揭穿了这个阴谋。尽管沙子在那一刻里装着若无其事,但他还是一眼看出了沙子心中的不安。
在沙子进来之前,森林发现妻子的眼睛已经不仅仅是阴沉了,里面开始动荡起愤怒的痛苦。可是森林那能够看出沙子诡计的锐利目光一旦投射到妻子身上时,却变得格外迟钝。即便是在那个时候,他仍然没有准备到妻子的突然爆发。
那时候东山依然在使着眼色,可他的新娘因为无法理解而脸上布满了愚蠢。于是东山便凑过去咬牙切齿地说了一句什么,总算明白过来的新娘脸上出现了幽默的微笑。随即东山和他的新娘一起站了起来。东山站起来时十分粗鲁,他踢倒了椅子。正如森林事先预料的一样,他们走进了那个房间。但是他们没有将门关上,所以森林仍然看到那张床的一只角,不过没有看到他们两人,他们在床的另一端。然后那扇门关上了。
不久之后,那间屋子里升起了一种混合的声音,声音从门缝里挤出来时近似刷牙声。在这混合的声音里最嘹亮的是床在嘎吱嘎吱响着。森林微微一笑,他想:
“一张破床。”
这一时刻那一片嗡嗡声蓦然终止,那些窃窃私语者都抬起了梦游症患者一样的脸来。森林注意到广佛开始腾出手来擦汗了,于是彩蝶靠在桌面上的头也总算仰起,在她仰起的脸上,森林看到了一种疲倦的紫色。那个男孩也不再踮着脚,他开始朝那扇门奇怪地张望。
森林是在这时看到沙子实现了他的诡计。他看到沙子微笑地走到那个正在凝神细听的姑娘身后,沙子从口袋里拿出了一把剪刀,剪刀在灯光下一闪之后,那姑娘便失去了一根辫子。于是森林看到姑娘的头颅像是失去重心一样摇摆了过去。沙子往后退去时仍然在微笑,他一直退到门旁。可是不一会森林发现沙子已经坐在妻子的身旁,沙子从门旁到那里的过程,森林没有看到。
这时候那扇门似乎在微微抖动了,里面的声音像风一样打在门上。森林感到那声音像是从油锅里煎出来似的热气腾腾。随后森林听到这混合在一起的声音开始运动。那声音在屋内抱成一团,并且翻滚起来。仿佛从床上掉落在地,滚到了墙角,又从墙角滚到了床底下。于是森林清晰地分辨出了两种声音。他听到了柳枝抽打玻璃的尖利声和巨石从山坡上滚下时的沉重喘息。他体会到这两种声音所形成的对抗。然而对抗是暂时的,不久之后它们便趋向了和解。它们从狭路相逢进入剑拔弩张的高潮后,又立刻跌了下来,这两种声音开始同舟共济了,并且正在快速地远去。此后一片平静呈现了,如同呈现了一片没有波浪的湖面。
然后屋内响起了比口哨还要欢畅的脚步声,接着那扇门打开了。东山首先走出来,他脸上的笑容像是一只烂掉的苹果,但他总算像一个新郎了,他的新娘紧随其后,新娘的脸色像一只二十瓦的灯泡一样闪闪发光。他们从容不迫地在刚才的位置上坐了下来,他们的神态强词夺理地在说明他们没有离开过。
广佛和彩蝶开始面面相觑,透过面面相觑,森林得意地看到了他们心中正羞愧不已。但是森林没有料到的是他们两人突然果断地站了起来,接着以同样的果断朝门口走去。门被打开后又被关上。然后他们已经不再存在于屋内,他们已经属于守候在屋外的夜晚。接着那门又被打开又被关上,森林看到那个男孩也出去了。在男孩出门的一瞬间,森林看到男孩的后脑勺上出现了一点可怕的光亮。
然而这个时候,森林妻子将忍耐多时的悲哀像一桶冷水一样朝他倒来。他妻子在那一刻突然哇哇大哭起来,如一只汽车喇叭突然摁响一样。妻子的哭声像硝烟一样在屋内弥漫开来,她用食指凶狠地指着森林:
“你从来没为我买过一条漂亮裤子。”
那时候森林眼前出现了一片空荡,而一块绝望的黑纱在空荡里飘来了。正是在这一刻,森林心中燃起了仇恨之火,正如他后来对沙子所说的:
“我仇恨所有漂亮的裤子。”
四
广佛和彩蝶经过漫长的面面相觑以后,他们毅然地来到了屋外。他们十分干脆地体现了命运的意志。他们出门以后绕过了几棵从房屋的阴影里挺身而出的树木,但他们没有注意树梢在月光里显得冰冷而没有生气,显然这是不幸的预兆。那个时候广佛的智慧已被情欲湮没。直到多日以后,广佛的人生之旅行将终止时,他的智慧才恢复了洞察一切的能力。然而那时候他的智慧只能表现为一种徒有其表的夸夸其谈了。
广佛在临终的时刻回想起那一幕时,他才理解了当初他和彩蝶沙沙的脚步声里为何会有一种咝咝的噪音。这噪音就是那男孩的脚步。那时候男孩就在他们身后五米远的地方。但是当广佛发现他时已是几分钟以后的事了,那时候男孩的手电光线照在了他的眼睛上。男孩干涉了广佛的情欲,广佛的愤怒便油然而生,接着广佛的灾难也就翩翩来到了。
那天晚上他们并没有走远,他们出门以后只走了十多米,然后就在一片阴险闪烁的草地上如跌倒一样地滚了下去。于是情欲的洪水立刻把他们冲入了一条虚幻的河流,他们沉下去之后便陷进了一片污泥之中。以至那个男孩走到他们身旁时,他们谁也没有觉察。
首先映入男孩眼帘的是一团黑黑的东西,似乎是两头小猪被装进一只大麻袋时的情景。然而当男孩打亮手电照过去时,才知道情况并不是那样,眼前的情景显然更为生动。所以他就在他们四周走了一圈。他这样做似乎是在挑选最理想的视觉位置,可他随即便十分马虎地在他们右侧席地而坐。他手电的光线穿越了两米多的空间后,投射在他们脸上,于是孩子看到了两张畸形的脸。与此同时那四只眼珠里迎着光线射过来的目光使孩子不寒而栗。所以他立刻将光线移开,移到了一条高高跷起的腿上,这条腿像是一棵冬天里的树干,裤管微微有些耷拉下来,像是树皮一样剥落下来。最上面是一只漂亮的红皮鞋,那么看去仿佛是一抹朝霞。腿在那里瑟瑟摇晃。不久之后那条腿像是断了似的猝然弯曲下来,接着消失了。然而另一条腿却随即挺起,这另一条腿的尖端没有了那只朝霞一样的红皮鞋,也没有裤管在微微耷拉下来,什么都没有,有的只是一条腿,这条腿很纯粹。孩子的手电光照在那上面,如同照在一块大理石上,孩子看到自己的手电光在这条腿上嘹亮地奔泻。然后他将光线移到了另一端,因此孩子看到的是一只张开的手掌,手掌仿佛生长在一颗黑黑的头颅上。他将光线的焦点打在那只手掌上,四周的光线便从张开的指缝里流了过去。随后手掌突然插入了那黑黑的头颅,于是一撮一撮黑发直立了起来,如同一丛一丛的野草。接着黑发又垂落下去,黑发垂落时手掌消失了。孩子便重新将光线照到他们脸上,他看到那四只眼睛都闭上了,而他们的嘴则无力地张着,像是垂死的鱼的嘴。他又将光线移到刚才出现大腿的地方,光线穿过了那里以后照在一棵树上。刚才的情景已经一去不返了,如今呈现在手电光下的不过是一堆索然无味的身体。于是他熄灭了手电。
广佛从地上爬起来时,孩子还坐在那里。他回头看了看彩蝶,彩蝶正在爬起来。于是他就向孩子走去,孩子的眼睛一直在看着他,那双眼睛像是两只萤火虫。孩子坐在那里一动不动,月光照在他身上仿佛他身上披满水珠。广佛走到他跟前,站了片刻,他在思忖着从孩子身上哪个部位下手。最后他看中了孩子的下巴,孩子尖尖的下巴此刻显得白森森的。广佛朝后退了半步,然后提起右脚猛地踢向孩子的下巴,他看到孩子的身体轻盈地翻了过去,接着斜躺在地上了。广佛在旁边走了几步,这次他看中了孩子的腰。他看到月光从孩子的肩头顺流而下,到了腰部后又鱼跃而上来到了臀部。他看中了孩子的腰,他提起右脚朝那里狠狠踢去。孩子的身体沉重地翻了过去,趴在了地上。现在广佛觉得有必要让孩子翻过身来,因为广佛喜欢仰躺的姿态。于是他将脚从孩子的腹部伸进去轻轻一挑,孩子一翻身形成了仰躺。广佛看到孩子的眼睛睁得很大,但不再像萤火虫了。那双眼睛像是两颗大衣纽扣。血从孩子的嘴角欢畅流出,血在月光下的颜色如同泥浆。广佛朝孩子的胸部打量了片刻,他觉得能够听听肋骨断裂的声音倒也不错。这样想着的时候,他的脚踩向了孩子的胸肋。接下去他又朝孩子的腹部踩去一脚。然后他才转过头去看了看彩蝶,彩蝶一直站在旁边观瞧,他对彩蝶说:
“走吧。”
当广佛和彩蝶重新走入东山的婚礼时,森林的妻子还在号啕大哭。所以谁也没有注意到他们推门而入,因此他们若无其事的神态显得很真实。在所有人中间,只有森林意识到他们两人刚才开门而出,但是森林此刻正在被仇恨折磨,他无暇顾及他们的回来。于是彩蝶便逃离众目睽睽,她可以神态自若地坐回到自己的位置上。然后她又以同样的神态自若,看着广佛怎样走到那伙窃窃私语者身旁,她看到广佛朝喜气洋洋的东山微微一笑,随后俯下身对一个男人说了一句话,她知道广佛是在说:
“我把你儿子杀了。”
在那个男人仰起的脸上,彩蝶看到一种睡梦般的颜色。接着广佛离开了那伙人,当广佛重新在彩蝶身旁坐下时,彩蝶立刻嗅到了广佛身上开始散发出来的腐烂味,于是她就比广佛自己更早地预感到了他的死亡。与此同时,她的目光投射到了露珠的脸上,她从露珠脸上新奇地看到了广佛刚才朝那伙人走去时所拥有的神色。因此当翌日傍晚她听到有关东山的不幸时,她丝毫也惊讶不起来,对她来说这已是一个十分古老的不幸了。
五
聚集在东山婚礼上的那群人像是被狂风吹散似的走了。沙子是第一个出门的,他出去时晃晃悠悠像一片败叶,而紧随其后森林那僵硬的走姿无疑是一根枯枝的形象。他们就这样全都走了。东山感到婚礼已经结束,所以他也摇晃地站起来,朝那扇半掩的门走去。他走去时的模样很像一条挂在风中的裤子。那个时候东山的内心已被无所事事所充塞,这种无所事事来自于刚才情欲的满足和几瓶没有商标的啤酒。因此当东山站起来朝里屋走去时,他似乎忘掉了露珠的存在,他只是依稀感到身旁有一块贴在墙上的黑影。于是他也就不可能知道此刻对露珠来说婚礼并没有结束。如果他发现这一点的话,并且在此后的每时每刻都警惕露珠的存在,那么他也就成功地躲避了强加在他头上的灾难。然而这一切在他作出选择之前就已经命中注定了。东山一躺到那张床上就立刻呼呼睡去,命运十分慷慨地为露珠腾出了机会。
在此之前,露珠清晰地听到那张床发出的嘎吱嘎吱的响声,如同一条船在河流里摇过去的橹声,而且声音似乎在渐渐地远去。这使露珠感到很宁静。随后东山的鼾声出现了,东山的鼾声让露珠觉得内心踏实了。所以她就站起来,她听到自己身体摆动时肥大的声响。那个时候屋外的月光使窗玻璃白森森地晃动起来,这景象显然正是她此刻的心情。她十分仔细地绕过聚集在她前面的椅子,她觉得自己正在绕过东山所有的朋友,他们一个一个都不再对她有威胁了。现在她已经站在了那间屋子的门口,她看到了东山侧身躺着的形象。她生平第一次站在旁边的角度看到一个男人的睡态,因而她内心响起了一种阴沟里的流水声。可是流水声转瞬即逝,因为她那时十分明白流水声继续响下去的危险,她已经意识到这声音其实是命运设置的障碍。像绕过刚才的椅子那样,这次她绕过了流水声。她已经站在了梳妆台前,她的目光停留在那个小瓶上,她发现从镜子里反映出来的小瓶要比实际大得多。那个时候她摇摇晃晃地听到了两种声音:
“这是什么?”
那是她问父亲的声音和东山问她的声音,两种声音像是两张纸一样叠在了一起。
她当初的回答是沿用了父亲的回答:
“我的嫁妆。”
于是她看到东山脸上洋溢出了天真无邪,从那时她就知道自己要干的这桩事远比想象的要简单。那时候她看到了东山其实是手无寸铁,东山的智慧出现了缺陷,东山的智慧正在被情欲用肥皂洗去。所以她拿起小瓶时丝毫没有慌乱,但是那一刻里她的左眼皮突然剧烈地跳动了几下。由于被行动的欲望所驱使,她没有对这个征兆给予足够的重视,她错误地把这种征兆理解为疲倦,所以日后的毁灭便不受任何阻挠地来到了。
她已经走到了床边,东山因为朝右侧身睡着,所以他左侧的脸在灯光下红光闪闪,那是啤酒在红光闪闪。她用手指在那上面触摸了一下,恍若触摸在削下的水果皮上。然后她拧开了瓶盖,将小瓶移到东山的脸上,她看着小瓶慢慢倾斜过去。一滴液体像屋檐水一样滴落下去,滴在东山脸上。她听到了嗤的一声,那是将一张白纸撕断时的美妙声音。那个时候东山猛地将右侧的脸转了出来,在他尚未睁开眼睛时,露珠将那一小瓶液体全部往东山脸上泼去。于是她听到了一盆水泼向一堆火苗时的那种一片嗤嗤声。东山的身体从床上猛烈地弹起,接着响起了一种极为恐怖的哇哇大叫,如同狂风将屋顶的瓦片纷纷刮落在地破碎后的声音。东山张大的嘴里显得空洞无物,他的眼睛却是凶狠无比。他的眼睛使露珠不寒而栗。那时候露珠才开始隐约意识到了一点什么,但她随即又忽视了。东山在床上手舞足蹈地乱跳,接着跌落在地翻滚起来,他的双手在脸上乱抓。露珠看到那些灼焦的皮肉像是泥土一样被东山从脸上搓去。与此同时,露珠似乎听到了父亲咳嗽般的笑声,笑声像是屋顶上掉下来的灰尘一样出现了。于是她迷迷糊糊地发现了自己的处境,她的思想摇曳地感到自己似乎是父亲手枪里的一颗子弹。
六
几天以后,广佛站在被告席上重温了他那一天里的全部经历。他的声音在大厅里空洞地响着,那声音正卖力地在揭示某一个真理。他在说到中午起床拉开窗帘后看到阳光如何灿烂时,他的神态说明他重又进入了那一天。然后有几只麻雀从半空里飞下来,一阵喳喳声也从半空里飞了下来。于是他发现再在屋内待下去是愚蠢的,因此他就来到了屋外。走到屋外时一个素不相识的陌生人朝他微微一笑,这个微笑使他走到大街上时仍然难以忘怀。这个时候他碰到了东山,东山充满激情地告诉他晚上的婚礼,那时候他表现出来的激情绝不逊色于东山。随后他们两人就各走东西。广佛朝东走去时蓦然感到东山刚才脸上的激情有些吓人。但他却没有因此想到自己刚才表现的激情是否也吓人。他就这样走进了一家点心店,一客小笼包子端上来时热气腾腾,他的早餐便开始了。尽管他在某一只包子里咬出了一颗小石子,可是并没有影响他的情绪。在他走出点心店时,他下午的经历开始了。他首先是走到邮局报栏前看了所有陈列出来的报纸的夹缝,他在夹缝里看到了三条杀人的新闻。那个时候命运第一次向他暗示了,可是得到的结果却与后来的暗示一样,命运在对牛弹琴。随后他离开报栏朝西走去,在走到那座桥上时,他得到了命运的第二次暗示,那时候他看到有一条披麻戴孝的小船哭哭啼啼地从桥下摇了过去,但他同样无动于衷。他在桥上站了一会,他这样做只是为了看着正在波动的水,水的颜色使他想起了一条柏油马路。这个联想出现后,他开始感到索然无味。于是他走下了桥,他望到了自己房间的窗口,那个窗口有点阴阳怪气。这时候他才发现自己走了一圈的结局是回家。于是他就从刚才走下来时的楼梯走了上去,那个下午以后的时间他消磨在房间里。他半躺在床上,用一只眼睛看着窗外的一片树叶,他记得那片树叶的颜色是黄的。他在望着树叶时不停地吹口哨,口哨表明他的心情一直很愉快。那片树叶在口哨声里摇摇晃晃,显得很危险。后来在他从床上跳起来准备去参加东山婚礼时,那片树叶终于掉落下来,那掉下来的姿态慢慢吞吞。显然这是命运的第三次暗示,他自然又忽视了。接下去他通过那个弥漫着灰尘的楼梯,又来到了屋外。那个时候太阳掉下去了,一片晚霞挂在马路上面,他十分愉快地走在晚霞和马路中间。他记得当时什么也没有发生,连一片树叶也没有掉下来。他就这样走到了东山家的小巷口,他的身体扭动一下后就走进了小巷。当时他朝那里的一家卫生院望了一下,透过卫生院的窗玻璃他看到了一只正在挨针扎的屁股,但尚未分辨一下这只屁股的性别,他就走过去了。然后他就出现在了东山的婚礼上,在东山婚礼上他首先看到的是那个男孩,那时男孩正用一双透明的黑眼睛望着他,男孩的眼睛使他心里涌上了一股奇怪的情绪,他想杀死他。那个时候命运的第四次暗示出现了。但他随即被娇媚的彩蝶招引了过去,他坐到了她的身旁,他用眼睛望着她的脖子,他的情欲之火就是这样点燃的。不久之后他的左腿上出现了爬动的感觉,彩蝶用脚趾开始了勾引。于是他的双手便开始传达他的情欲之火。尽管他竭尽全力,可他还是感到自己的情欲舒展不开。后来是东山的果断行为激励了他,他就和彩蝶双双走到了屋外,在一片布满水珠的草地上翻滚下去。那男孩的手电光也就接踵而至,手电光使他的情欲发泄时出现了愤怒的成分。愤怒的结果使他杀死了男孩。他就这样连续错过了命运的四次暗示,但是命运的暗示是虚假的,命运只有在断定他无法看到的前提下才会发出暗示。他现在透过审判大厅的窗玻璃,看到了命运挂在嘴角的虚伪微笑。他用右手向窗外的天空一指,窗外的天空蓝得虚无。他说这种虚伪微笑不是任何眼睛都能看到的,只有临终的眼睛才能看到。当他此刻重新回顾那一天的经历时,他才知道彩蝶和男孩其实是命运为他安排的两个阴谋,他还知道自己只要避开其中一个,那他也就避开了两个。可是由于他缺乏对以后的预见,所以他迟早也将在劫难逃,而他和彩蝶则是命运为男孩安排的两个阴谋,现在男孩已经死了,他也将殊途同归。唯有彩蝶幸存下来,命运在那一天为彩蝶安排的只是一个道具。现在他看到彩蝶的神色里有一种更为可怕的东西,因此他意识到命运对彩蝶的陷害将会更为残酷。他明确地告诉彩蝶,命运正在引诱她自杀。如果彩蝶重视他的临终忠告,那么她也许还能化险为夷。但是他十分遗憾地感到彩蝶对他的忠告显然漫不经心,所以他认为彩蝶也在劫难逃了。如今他行将就木,他并不感到委屈,他只是忏悔对那个男孩的残杀,他感到自己杀死的似乎不是那个男孩,而是自己的童年。所以当他扼杀了自己的童年以后,再在此刻回顾自己的人生之旅,他的眼睛凄凉地看到了一堆废墟。现在他已经别无所求,他只希望沙子能够将他的骨灰撒在一片蔚蓝色的海面上,他将在波浪里万念俱灭,日出会将他的人生抹掉,就像他现在抹掉嘴角的唾沫一样。
彩蝶十分无聊地听着广佛冗长的夸夸其谈,那时候她站在证人席上,她的眼睛远远地注视着沙子,沙子像一片树叶似的在那里悄无声息地飘来飘去。沙子从一个空座位不停地向另一个空座位转移,沙子每次坐下时,她都要通过某一位时髦女子的头发才能继续看到沙子,她看到的是沙子灰暗的前额,但是沙子的前额比广佛的声音要明亮多了。广佛的声音让她仿佛看到一个男人在黑暗里咬牙切齿。所以她警惕地感到那声音不怀好意。因此当广佛对她进行忠告时,她无可非议地将这种忠告理解为诅咒。广佛对她结局的预言在她听来如同麻雀的叫唤。那时她在心里想着自己的美容,她已经没有机会让广佛知道她已经和一位眼科医生取得了联系,这个联系在一个月以前就开始了。那位眼科医生会使她更为楚楚动人,医生只需在她的眼皮上轻轻划上两刀,她就会拥有生动的双眼皮,这个不久来到的事实会轻而易举地粉碎广佛的预言。尽管广佛就站在她近旁,但她没情绪去看他,看着鬼鬼祟祟的沙子使她觉得更为有趣。但是不久之后她就发现那人其实不是沙子,而是森林。森林与沙子的神态如此接近,她还是第一次发现。那个时候她已经走到大厅的门口了,她看到沙子就在前面走着,所以她就叫了一声,然后她才发现那人其实是森林。接着她从森林喜气洋洋的脸上感到,森林似乎十分乐意被错认成沙子。与此同时她看到前面有几个穿着紧身裤的时髦女子,彩蝶之所以注意她们是因为她们的臀部如同被刀割过一样裂开了,裂开的模样很挑逗,因为里面的内裤色彩斑斓。
七
这天晚上,森林用小拇指敲开了沙子的屋门,这个举动为他的这次拜访涂上了一层神秘的色彩。他进屋以后就在沙子的床上坐了下来,床摇摆了几下。然后他用一种诡秘的微笑注视着沙子。沙子显然已经意识到森林的这次拜访不同以往,所以他十分警惕地与他保持两米的距离。然而森林开口的第一句话却是告诉沙子有关广佛的消息。他告诉沙子只用一颗子弹就将广佛断送了。那颗子弹很小,因为弹壳被一个孩子捡去了,所以森林现在只能向沙子伸出小拇指。
“就这么小。”
接着森林传达了广佛的遗言。广佛临终时的重托显然使沙子感到有些棘手,但他还是十分认真地询问了广佛的骨灰现在何处。森林便拍了拍两只胀鼓鼓的上衣口袋。沙子才知道他把广佛带来了。于是沙子将一张十多年前的报纸在桌上铺开,森林就走过去把两只口袋翻出来将骨灰倒在报纸上,倒完以后森林用劲拍了拍口袋,剩余的骨灰弥漫开来,广佛的一部分就这样永久地占有了沙子的房屋。那个时候他们两人同时嗅到了广佛身上的汗酸味。
森林重新坐到沙子的床上,刚才那种诡秘的微笑又在他的嘴角出现。森林告诉沙子,彩蝶上午把他错认的经过。但是沙子却只是轻描淡写地微微一笑。因此森林便提醒他,彩蝶的错认有力地暗示了他们的接近。然而沙子立刻予以否定,因为他一点也没看出这种所谓的接近。森林便不得不揭穿了沙子在东山婚礼上的行为,随后他充满歉意地说:
“我不是有意的。”
这无疑使沙子大吃一惊,但他立刻用满不在乎的一笑掩盖了自己的吃惊。然而他并不准备去否认,他迟疑了片刻后对森林说:
“那不是我的代表作。”
“这我知道。”
森林挥了挥手,他告诉沙子他今夜来访的目的并不是要贬低沙子的天才,而是……他请沙子把剪刀拿出来。
但是沙子以沉默拒绝了,于是森林就从裤袋里拿出了一把小刀,他将锋利的刀口对准沙子,问:
“看到了吗?”
确定了沙子的点头以后,他便告诉沙子,这把小刀已经割破了二十个时髦女子的时髦裤子。他这样做是因为他仇恨所有漂亮的裤子。然后他坚信沙子也有同样的心理,并且认为当他割裤子听到咔嚓声时所得到的快感,与沙子听到剪刀咔嚓声时的快感毫无二致。他再次请求沙子把剪刀拿出来。
沙子现在完全理解了森林妻子在东山婚礼上的号啕大哭。他微微一笑后从口袋里拿出了剪刀,他也问:
“看到了吗?”
“看到了。”
森林回答。接着他说虽然小刀和剪刀的形状与大小都不一样,但是:
“它们一样有力。”
沙子听完以后并不立刻回答,他蹲下身从床底拖出了两只大木箱。他打开木箱以后让森林看到了两箱排列得十分整齐的辫子。他告诉森林它们中间每一根都代表着两根辫子,因为他从来都只是剪一根辫子的,而另一根:
“她们会替我剪去的。”
这个情景使森林感到羞愧,于是他十分坦率地承认自己远远落后了。
“问题并不在这里。”
沙子这样说。但是森林表示他一下子还不能正确地理解这句话,所以沙子就只好明确地指出:森林不过是一个复仇者,而他却是一个艺术家。
“我们的不同就在这里。”
沙子仔细分析了森林割裤子和自己剪辫子的原始动机。他告诉森林他并不像他仇恨漂亮裤子那样仇恨辫子,他是因为看到辫子时有一种本能冲动,这冲动要求他剪下辫子。所以他这样做是为了表现自我,因此:
“我是一个艺术家。”
接着他对自己的这种冲动作了一个比喻:
“近似东山看到露珠时的那种冲动,但又完全不一样。因为他是生理的,而我则是艺术的。”
提到东山的名字以后,两人都沉默了片刻,表示对东山被毁坏的面容的悼念。
现在森林感到无话可说了,他看到了自己的失败,他不得不承认沙子说得有理。
沙子看出了这种对自己有利的处境后,他就提议到外面去走一走,说话的时候他将广佛的骨灰包了起来。然后他们就来到了屋外,在走出那条小巷时,沙子告诉森林尽管他们本质不同,可表现形式还是有共同之处的,鉴于这一点,沙子感到他们的友谊朝前跨出了很大一大步。
沙子的话使森林深受感动,因为这正是他今晚的目的所在。他来向沙子指出他们的接近,无非是为了证明他们的友谊朝前跨出了一大步。现在他感到心满意足,他十分愉快地跟着沙子往前走。他们走去的方向有一条小河。那个时候他们谁也不知道命运已在河边为他们其中的一人设置了圈套。
来到河边以后,森林重提了彩蝶上午把他错认的经过,他这样做无非是证明他们的友谊朝前跨出一大步的另一种说法。森林说话的时候,沙子将报纸里的广佛扔进了那条正在闪烁流动的小河。广佛无声地掉落在水面上,由于报纸依旧包着,它漂浮了一小会,然后在桥的阴影里消失。这个举动使森林大吃一惊,但是沙子指着小河十分平静地告诉森林:
“它会流入大海的。”
于是森林就开始想象这条小河如何七转八弯流入了另一条河,这另一条河不久之后又归入别的河流,如此下去无数河流出现了。再穿过无数田野竹林和无数小小的城镇后被运河吞没,运河北上以后进入了长江,长江浩荡东去,流入了大海。在森林想象的最后时刻,那一片蔚蓝色的海面果然出现了。
这时有几个民警出现在他们面前,民警证实了谁是森林以后,就把森林带走了。这个过程十分利索,双方都心照不宣。森林在临走时委托沙子常去看望他的妻子。森林在嘱托的时候发现沙子脸上正流淌着得意的神采。于是他就对沙子说:
“我不会出卖你的。”
这其实是森林的一个阴谋,后来的事实证明森林的阴谋很成功。那几个民警显然重视了森林这句话,所以此后连续三次盘问森林,但森林每次都是坚定地回答:
“我不会出卖沙子的。”
尽管除此以外森林什么也没有说,但他却是十分出色地将沙子展览了出来。
八
沙子是在翌日傍晚去完成森林的委托的,他的这个行动说明他并没有意识到自己已被森林出卖了。那个时候展现在沙子眼中的是一个蓬头散发的女人,那女人半躺在床上,阴沉地告诉了沙子她刚才干了些什么。
她指着床头柜上的半碗水对沙子说:
“我吞下了一碗老鼠药。”
这话使沙子颇为惊讶,于是他就打听她平时的饭量。
“也就那么一碗。”
森林妻子的回答使沙子感到她必死无疑,因此他就立刻向她揭示了这个真理。她脸上出现了一只鸟飞过时闪一下的阴影。
接着沙子又告诉她森林不久之后就会回来的,这句话显然加深了她内心的痛苦。她说:
“我要惩罚他。”
“但那时你已经死了。”
沙子郑重其事地提醒她。
沙子的提醒使她有些不知所措,但她随即释然了,她颇为得意地说:
“我已经惩罚他了。”
沙子思考了一下以后,表示同意她这句话。这时候他已经看穿了她的心计,因此他便向她描述了森林回来后的详细情景。他从森林出狱后的激动心情说起,那时候森林有一种想立刻拥抱妻子的强烈愿望,所以他就一路小跑地回家,可是他推门而入时却大吃一惊。因为那时她已经腐烂了,腐烂时臭气冲天。这种久别重逢的情景显然出乎森林的预料,因此他就号啕大哭起来。森林足足哭了一整天,他的哭声使邻居毛骨悚然,夜晚来临时他的哭声才算终止,于是他在床沿上悲痛欲绝地坐到深夜。森林是在这个时候毅然决定紧步妻子后尘的,他便站起来寻找老鼠药,可是老鼠药让他妻子一人独吞了。这个事实并没有打消森林心中的决定,森林坚定地走到阳台上。沙子说到这里停顿了一下,接着他十分详细地描述了森林跳楼自杀的每一个细节,就是最后鲜血怎样在马路上洋溢开来他都足足说了五分钟。
沙子的描述使森林妻子十分满意,她告诉沙子:
“你和我想的完全一样。”
同时她又指出了沙子描述里的不真实处,那就是她并没有腐烂,即便腐烂也不会是臭气冲天。随即她轻轻叫了一声,这叫声使沙子感到是一只老鼠在叫唤。他看到她双手捂住了胃部,她的身体十分有趣地扭曲起来,有一丝鲜血从她嘴角慢慢溢出。森林妻子这时候开始哇哇乱叫了,沙子耳中响起了一家工厂的所有声音,这声音使他不堪忍受。于是他就对她说如果难受的话,就把胃里的老鼠药吐出来。她像是得到启示一样哇哇地呕吐了起来,吐得肆无忌惮。在她慢慢伸开的身体上,沙子看到呕吐出来的东西像一条毯子似的盖在她身上。在这色彩丰富的呕吐物上,沙子可以想象出她的最后一餐是如何丰盛。同时他惊讶她居然有这么大的一个胃。呕吐物散发出来的气味使沙子眼花缭乱,于是他就决定撤退了。
沙子逃离了森林妻子的呕吐后,落入了彩蝶的手中。那个时候他已经来到了街上,正走在梧桐树叶制造的阴影上,彩蝶像是等待已久似的站在他前面。那时候彩蝶使他感到长着四只眼睛,那是因为彩蝶的眼皮上出现了两块小小的纱布,被胶布固定在那里,彩蝶眉飞色舞地告诉了他美容手术的经过,沙子站得两腿发酸时她仍在喋喋不休。最后彩蝶邀请沙子在四天过去后的第五天傍晚来她家,参加她的揭纱布仪式。她得意洋洋地预言她的揭纱布仪式将会非常隆重,将会使东山的婚礼黯然失色。她指着纱布告诉沙子,那时候他就会发现:
“这里面隐藏着惊人的美丽。”
九
四天过去以后的第五天夜晚,销声匿迹了一段日子的东山,无声地推开了沙子的屋门。那个时候沙子刚刚从彩蝶的揭纱布仪式上出来,而他的心情还没有完全出来,所以他的脸上有一种正在听相声的神色。
直到很久以后,沙子依然能够清晰地回想起彩蝶当初坐在梳妆台前准备大吃一惊的神态,这个神态使沙子日后坐在拘留所灰暗的小屋内时,成功地排遣了一部分的寂寞。当他那时再度回想时,居然没有隔世之感,那情景栩栩如生如同就在眼前。
他那无聊的思绪一旦逗留在当初彩蝶纱布揭开的情景上时,仅仅用兴高采烈来表示显然是不够的。当纱布揭开时,也就是那个应该是激动人心的场面来到时,却是一片沉默出现了,如同出现了一片阴沉的天空。这个沉默所表达的含义,在场的每个人都能够心领神会。这个沉默持续了很久以后,才被一个声音打破,那个声音从沙子斜对面干燥地滑过来,那个声音显然是不由自主,声音说:
“两道刀疤。”
这话有力地概括了彩蝶美容手术的失败,所以沙子记住了这个声音拥有者的形象。当多日以后,沙子从拘留所出来时,也是这个声音向沙子描述了彩蝶最后几个情形中的一个。这个声音过去以后,很多人发出了赞同的喳喳声。在那一片喳喳声里,沙子满意地看到了自己开始欢畅起来的心情。
那个时候彩蝶确实是大吃一惊了,正如她所准备的那样,只是期待的结果恰恰相反。所以她的沉默所持续的时间长了一点。在彩蝶的沉默里,沙子幸灾乐祸地体会到了可怕的绝望。
后来彩蝶重新将纱布贴到了眼皮上,尽管她努力装着若无其事,但在场所有的人都发现了她的两条手臂像什么,像是狂风里瑟瑟摇晃的枯树枝。接着她站了起来,她站起来以后装腔作势地微微一笑。随后她以同样的装腔作势说:
“还算不错。”
但她的声音正在枯萎。
沙子在听到她的声音时,恍若看到一片秋天里的枯叶从半空里凄凉地飘落下来。因此在那一刻里,沙子隐约地看到了彩蝶近在眉睫的毁灭。当彩蝶将身体转过来时,所有人都吃惊地看到那张像白纸一样没有生命的脸。沙子从这张脸上坚定了自己刚才的预感。那时候彩蝶又说:
“你们可以走了。”
于是他们一个一个十分坚定地朝门口走去,他们的脚步声让彩蝶感到他们不会再来,所以彩蝶的眼睛开始叙述起凄凉。沙子是最后一个出去的,他在出去前对彩蝶说了一句话,以此报答彩蝶对他的邀请,彩蝶听后苍白地一笑。沙子出门以后随手将门关上,他用这个举动说明他也不会再来了。然后他发现所有人都聚在走道上,他立刻理解了他们的举止,因此他就在门口站住了脚。不一会他们共同听到屋内响起了极为恐怖的一声,这一声让他们感到仿佛有一把匕首刺入了彩蝶的心脏。第二声接踵而至,第二声让他们觉得是匕首插入了她的肺中,因为这一声有些拖拉,在拖拉里他们听到了一阵短促的咳嗽。然后第三声来了,第三声使他们一下子尚不能分辨是刺入胃中还是刺入肾里,这一声有些含糊。第四声却是十分清晰,他们马上想象到匕首插进肝脏,他仿佛听到了肝脏破裂后鲜血咝咝流动的声音。紧接着第五声出现了,第五声让他们觉得是刺中了子宫,这一声很像正在分娩的孕妇在喊叫。接下去里面的声音铺天盖地而来了。他们感到匕首杂乱无章地在她身上乱扎了。他们决定走了,他们觉得有价值的器官都被刺过了,剩下的不过是些皮肉和骨骼。
现在基于这个前提,沙子重新回顾那个色彩丰富的揭纱布仪式时,觉得那里面塞满了幽默。尽管后来沙子不承认那个仪式的隆重,但他却愿意认为这个仪式别开生面。当他跨入这个仪式时,展现在他眼中的是五十来个美男子的各种声音和姿态,这个仪式上作为女人的只有彩蝶。这个仪式因为没有辫子使沙子很久以后仍然有所失望。沙子难以忘怀的是彩蝶当初如何优美地迎了上来,又如何神采飞扬地告诉他,她把全城的美男子都请来了。随后彩蝶居高临下地让沙子明白,她之所以请他是看在往日的友谊上。沙子当然明白这是彩蝶的恩赐,他同时也理解彩蝶的恩赐其实是对他丑陋的嘲弄。因此当沙子离开那个房间时,他报复了彩蝶,他告诉她:
“这就是我来的目的。”
十
沙子回到家中不久,东山推开了他的屋门。因为沙子没有料到东山的来访,所以当东山出现时他不由失声惊叫。沙子的惊叫使东山再一次深刻地体会到了自己面容的破烂。
那时候呈现在沙子眼中的东山这张脸,如同一张被揉皱后又马虎拉开的纸,他看到昏暗的灯光在东山脸上起伏。虽然这张脸的深夜来访使沙子惊慌失措,但他随即就知道了是东山站在他的对面。当他平静下来以后,他开始感到这张脸似曾相识,于是东山在那个早晨敲开他房门时的情景便栩栩如生了。那个时候东山也像现在这样站在他对面,沙子在那时就透过东山红彤彤的神色看到了灰暗的灾难。现在这灾难不再抽象,而是十分具体地摆在沙子的视线中。然而沙子却无法透过这破碎的形象回归到昔日红彤彤的神采。他在这张脸上看到的依旧是灰暗的灾难,因此沙子隐约感到东山大难之后仍然劫数未尽。
东山并没有如沙子想象的那样在床上坐下来,他的神态说明他似乎要站到离开为止。尽管他的脸经历了毁灭,表情已经荡然无存,但是他的眼睛却强烈地表达了他此刻的心情。沙子似乎是通过两个小孔才看到他的眼睛,所以东山的眼睛并不让他感到近在咫尺,于是他也就无法体会到东山此刻心中的痛苦。这个痛苦现在由东山用嘴传达了。
他告诉沙子他已被露珠抛弃。
为了向沙子做出证明,东山从口袋里拿出了两张扑克牌。沙子接过来所看到的是红桃Q和黑桃Q,他显然无法领会其中的含义。于是东山就要求他看一下反面。沙子翻过扑克牌以后,两个裸体美女的媚笑迎面而来。但是沙子没有兴趣,他脸上露出了遗憾的微笑,他对东山说:
“可惜她们没有辫子。”
“这并不重要。”
东山伸出一个手指说,东山自然无法像森林那样能够理解沙子对辫子的激情。他现在需要沙子证实一下她们是谁。
沙子仔细看了以后的回答使东山大失所望,沙子说:
“有点像彩蝶。”
于是东山告诉沙子,他之所以展示这两张扑克是因为它们与露珠有关。那个时候沙子看到东山毁坏的脸上出现了一把匕首的阴影,这个先兆使他不寒而栗。但是他随即便释然地发现这个阴影并没有针对他,因为东山已经直截了当地告诉他:
“她们就是露珠。”
东山明确地指出以后,沙子便不再吭声。虽然他把所有的想象力全都鼓动出来,但他还是无法找出露珠与这两个裸女有一丝形象上的近似。沙子没有把这种想法告诉东山,他这样做是因为他十分明白即便说了也是没有作用。沙子感到露珠不仅毁坏了东山的面容,而且还毁坏了东山的眼睛。他感到此刻悬挂在东山脸上的匕首般阴影,似乎在预告着露珠将自食其果,同时他又证实了刚才的预兆,那就是东山大难之后仍然劫数未尽。
十一
可以说当露珠把那一小瓶硝酸朝东山脸上泼去时,她没法料到自己的灾难也开始了。十天以后,东山从医院回到自己家中,他的脸仍被纱布围困着。露珠以当初东山扑到她窗口的激情迎了上去,她笨重的身体扑过去时竟然像一只麻雀一样灵巧。那个时候呈现在东山眼中的露珠光彩夺目,她扑过来的叫声使他感到热气腾腾。然而所有这一切都转瞬即逝,东山的热情还没有完全燃烧就已经熄灭。迎接露珠的是两道悲哀的目光。正是在这一刻,东山最初预感到了抛弃,就像当初露珠在他脸上所看到的朝三暮四,他现在在露珠脸上看到了。
在此后的日子里,东山的心里长出了一口阴暗的枯井,他感到自己像是逃避光亮一样坐入了井中。他在那里反复思考,这思考带来的全部后果便是露珠正在远去。那时候他的视野被一片荒漠所占有,他看着露珠在荒漠之中如何消失。那肥大的屁股像一辆马车一样摇摇晃晃,消失时东山仿佛看到他记忆里飘扬的鲜艳内裤猝然倒下。倒下后便什么也没有了,就是一丝灰尘也没有扬起。东山的思考来到这里之后并没有终止,而是继续前行。那时候他的目光则朝另一个方向飘去,他的目光穿越了所有过来的日子,停留在他们的婚礼上。然后又从婚礼上移开进入了那间屋子,是从那扇半掩的门上滑进去的。于是他看到露珠在床上翩翩起舞,露珠在那一刻挥舞出来的动作再一次重现了。东山在露珠的动作里看到了一种训练有素的姿态。这个发现使东山终于明白了他们婚姻的实质。东山感到露珠对他的抛弃已经由来已久,在尚未得到她时,他已经被她抛弃。因此东山领悟到了那些日子来晃动在他眼前的露珠其实只是一个躯壳,露珠的灵魂从来就没有进门过一次。那躯壳也不过是在他床上寄存一下,现在就是这躯壳也要被取回了。东山对这个即将来到的事实无力阻止,因为他明确地知道露珠已经付清了躯壳的寄存费,那就是他每一次在这躯壳上所得到的美妙乐趣。
命运在让东山的眼睛变形之后,并没有对露珠丢开不管,它使露珠的眼睛里始终出现了一层网状的雾障。这雾障曾经遮挡了东山的眼睛很久,因此露珠无法看到笼罩在东山头顶的灰暗。东山终日坐在墙角的孤独神态使她错误地理解为是对昔日面容的追怀。由于她歪曲了东山心中快速生长的嫉恨,所以她命中注定的灾难也就与日渐近。那个时候露珠显然心安理得,她已经毁灭了被东山抛弃的可能。她现在开始调动起全部的智慧,这些智慧的用处是今后生活的乐趣。今后的生活她将和东山共同承担,而换来的乐趣两人将平分秋色。露珠是在这种心情下解开了围困着东山面容的纱布,当东山支离破碎的面容解放出来时,露珠不由心满意足,因为东山此刻的面容正是她想象中的。然而东山从镜中看到自己的形象时,他立刻明白了露珠为何要取走她的躯壳,答案就在这张毁坏的脸上。如果这张脸如过去一样完好无损,东山感到露珠也许不会匆忙取走她的躯壳,也许会永久地寄存在他这里。现在该发生的已经无法避免。
东山在取下纱布的这天夜晚来到了屋外,他是在一种盲目的欲念驱使下走到屋外来的。他自然无法知道这盲目的欲念其实代表了命运的意志。命运在他做出选择之前就已经为他安排好了一切,他只能在命运指定的轨道里行走。不久之后他已经站在了广佛家的门前,虽然房屋里一片漆黑,他还是举起手来敲门。他并不感到自己敲门的动作强烈,但门框上的灰尘纷纷扬扬弥漫开来。那个时候旁边裂开了一条缝,一个孩子的脑袋探了出来,于是他和孩子之间就发生了一段简单的对话,对话的结果让他知道广佛已经死了。广佛已经死去的消息使他产生了隔世之感,当他转身走下楼去时,他听到自己的脚步声十分陌生。他就这样离开了广佛家。但是命运安排他出来并不只是让他得知这个消息,广佛不过是命运安排的一个转折,同时也是一个暗示。接下去出现的那个人才是命运的目的所在。东山现在已经走到了这里。那个时候一个陌生人拦住了东山的去路,那人从口袋里掏出了两张裸体扑克牌向东山展示。借着路灯的光线,东山看到了裸体的露珠。这两张扑克正是此后向沙子出示的那两张。
十二
森林从拘留所出来以后,发现沙子仍然逍遥法外,他不禁有些失望。这个失望使他明显地看到他们之间的距离依然存在。他在这天早晨再次用小拇指敲开了沙子的屋门。尽管他敲门时很执著,但他更希望沙子不在里面,而在拘留所的某一间小屋内。同样,森林的出来也使沙子感到不那么愉快,他以为森林在里面应该待得更久一些。然而森林仿佛看穿了沙子的心思,他颇为得意地说:
“我前天就出来了。”
森林在沙子床上坐下以后,他用手颇为神秘地指着放在他脚旁的黑色旅行包。他预言沙子无法猜出其中的含义,他说:
“虽然你很聪明。”
但是沙子提醒他:
“我从来不把自己的智慧消耗在一些无聊的小事上。”
“这我知道。”
森林挥了挥手。他告诉沙子在这点上他们有着共同之处,可是沙子却说:
“我看不出来。”
于是森林拉开了那个黑色旅行包,他从里面取出了一个很大的镜框。一段充满感激的文字歪歪斜斜地呈现在沙子眼中,仿佛每个字都喝醉了。当证实沙子已经看清后,森林才将镜框重新放回旅行包中。沙子这时说:
“这种镜框可以在好几家商店买到。”
“问题不在这里。”
森林又挥了挥手,他用那种沙子的腔调说。然后他十分严肃地告诉沙子他妻子服老鼠药自杀的过程。沙子听后马上让森林明白,那个过程他更清楚。森林却并不惊讶,他告诉沙子:
“但是她没死。”
这个消息显然是沙子没法料到的。森林一眼看出了沙子此刻的迷惑。他不禁微微一笑。随后他向沙子指明,这个镜框就是送给生产那包老鼠药的厂家。他说:
“世界上难道还有更优秀的制药厂吗?”
以至他妻子吃下整整一碗后居然还活着,所以:
“仅仅写封感谢信是不够的。”
这就是他为何不远千里专程送镜框去的原因所在。
沙子听完之后同意这不是一桩无聊的小事,沙子的同意无疑使森林十分喜悦。但是沙子随后尖锐地指出他现在已经从复仇者堕落为感恩者了。
森林听后轻轻一笑,然后他从口袋里拿出了一把小刀。他告诉沙子尽管这已不是上次出示的那把小刀,但它们一样锋利。接着他得意地让沙子明白,这把小刀不再像他的剪刀一样留恋于城内,这把小刀将杀向城外一千里的地方,因此不久之后沙子就会羞愧地发现自己的剪刀已经黯然失色。那时候他会来告诉沙子,这把小刀已经比他的剪刀:
“更为有力了。”
沙子却是轻蔑一笑,他指出森林的夸夸其谈是多么苍白无力后,他告诉森林,他的剪刀在剪完城里所有的辫子后自然会走向城外。但在此之前,他的剪刀决不会像森林的小刀一样好大喜功。森林的小刀不过割破了二十条裤子,二十这个数字太简单了,他提醒森林:
“就是婴儿也能说出更复杂一点的数字。”
沙子的回答无疑给了森林以重重一击,使森林看到了自己的羞愧。森林悲伤地低下了头,悄悄地将那把小刀收起。沙子在看到自己的胜利之后,并不打算乘胜追击。相反他十分大度地肯定了森林准备杀向城外的想法是可取的。他认为森林的这个想法,又一次使他感到他们的友谊朝前跨出了一大步。说完他向森林伸出了友谊之手。
两个人长久而有力地握手之后,来到了屋外,如同上次一样来到了屋外。不同的是现在是早晨,而上次是夜晚,现在他们去的地方是火车站,上次则是那条小河。但是心情是一样的。同样,不幸也正在前面等待着他们其中的一人。
那个早晨他们没有遇到东山,在他们走入车站候车室时,东山刚刚通过检票的进口走向一列绿颜色的列车。如果他们早一分钟到,他们就会遇到东山。他们走入候车室后,在东山刚才坐过的地方坐了下来。但是他们遇到了彩蝶,他们是在那条大街的转弯处遇到彩蝶的。那个时候彩蝶的眼皮上仍然有着两块小小的纱布,她嘴角挂着迷人的微笑向他们走来,然后她却如同没有看到一样与他们擦身而过。在彩蝶异样的神色里,森林似乎看到了什么,可他一时又回想不起来。所以森林开始愁眉苦脸,森林的愁眉苦脸一直继续到车站的候车室。那时候他的脸才豁然开朗,他告诉沙子他刚才在彩蝶脸上看到了什么,他说:
“广佛临终时的神色。”
这时候有几个民警出现在他们面前,民警在证实了谁是沙子后,就把沙子带走了。时隔多日以后,沙子回想起在自己被带走的那一刻,森林脸上怎样流淌出得意的神采时,他才领悟到自己是在什么时候被森林出卖的。对于森林来说,沙子的倒霉使他远行的路途踏实了,他终于能够亲眼看到沙子也难逃劫数。
十三
那天晚上东山离开以后,沙子并没有立刻睡去。那时候有一条狗从他窗下经过,狗经过时汪汪叫了两声。狗叫声和月光一起穿过窗玻璃来到了他床上,那种叫声在沙子听来如同一个女人的惨叫。在此后的一片寂静里,沙子准确地预感到露珠大难临头了。
那时候东山来到街上时,街上已经寂静无人,几只路灯的灯光晃晃悠悠。这种景象显然很合东山当初的心情。他听着自己的脚步声沙沙地在街上响着,这声响使他的愤怒得到延伸。这延伸将他带到了自己家门口。
他将钥匙插入锁孔转动后出现了咔嚓一声,他进屋后猛地关上门,门发出了砰的一声巨响。这两种声音显然代表了他当初的心情。尽管他还没法知道自己接下去会干些什么,但在意识深处他仿佛觉得这两种声响来自于露珠的躯壳,于是他激动地战栗了一下。
那个时候他在漆黑中听到了露珠的鼾声,这充满情欲的声音此刻已经失去魅力。那鼾声就像一道光亮一样,指引着东山的嫉恨来到这间小屋。那时东山听到露珠翻身时床嘎吱嘎吱响了一阵。床的响声和刚才那两声一样硬朗,东山在听到这强硬的声响时,又激动地战栗了一下。
他在漆黑里站了片刻,然后他伸手拉开了装在门框上的电灯开关,随着“啪”的一声一片光亮突然展现。他看到露珠侧身睡在床上,露珠的模样像是一件巨大的瓷器。灯光呈现时,卷在露珠身上的被子发出闪闪绿光。东山走了过去。那个时候露珠睡眼蒙眬醒来了,她发现东山时显示了无比的喜悦,这种喜悦她用目光来传达。可是东山所看到的却是那种只有荡妇才具有的野兽般目光。正是这喜悦的目光把露珠送进了灾难的手中。在那一刻里,东山开始明确了自己该干些什么。他十分粗暴地掀开了盖在露珠身上的被子。这个动作无可非议地暗示了灾难即将来到,可是露珠的眼睛却没有看到,就像她一直没有看清东山近日来的内心一样。所以当东山掀开被子时,她把这种粗暴理解为激情正在洋溢,那种激情她曾在婚礼上尽情享受过。于是她不由重温了婚礼上的那个美妙插曲,她的脸上开始出现斑斑红点。
此刻那两张裸体扑克在东山脑中清晰地显示出来,它们就放在右侧的口袋里。但东山觉得没必要拿出来重复一下,因为更生动的形象就在床上。这个时候他听到一个声音从自己嘴里奔出,那是他进屋后听到的第四次强硬的声音,那是一种比匕首还要锋利的声音,他要露珠去掉此刻盘踞在她身上的胸罩和短裤。露珠又一次错误地理解了东山,她以现在的错误去证实刚才的错误,所以她确信无疑地认为,东山的激情已经到了无法压制即将奔泻的时候了。因此她十分麻利地脱下了胸罩和短裤,她感到自己赤裸的躯体魅力无穷,她以为东山就要肆无忌惮了。可是东山的目光一下子变得令她莫名其妙。刚才那种锋利的声音又响了起来。她按照声音指示来到了床下,她现在站在东山面前了。她感到胸部很沉重,这沉重使她得意洋洋,然而东山却往后退去,一直退到门旁,东山的神态又一次使她莫名其妙。但她随即便认为自己正在被一种情欲观赏,而那种情欲从观赏到进入将会瞬间来到。这时候她听到东山要求她把双手叉在腰间的声音,于是她就将双手叉了上去。但是她感到这样的姿态似乎呆板,所以就自作主张地微微曲起右腿。这无疑是她所犯的所有错误里最为严重的。右腿微微曲起后,刚好符合了东山口袋里黑桃Q反面所展示的姿态。不久之后她又听到东山要求她把双手放到脑后去的声音,她再次照办了。那个时候她的双腿不由自主地并拢到一起。这一次的姿态符合了红桃Q反面所展示的。到这时露珠显然已经看到东山眼中可怕的目光,可是她忽视了。她不仅忽视而且还卖弄风骚地扭动了一下。于是东山那张破烂的脸像是要燃烧似的扭曲了。这时露珠似乎听到了一种奇怪的声音,她看到东山朝自己走了过来,于是那声音也就越来越清晰。当她看到东山随手拿起一只烟缸时,她终于听清了那是父亲咳嗽般的笑声,这笑声的突然来到使她大吃一惊,这时那个烟缸已经奔她前额而来了,她看到烟缸如闪电一样划出了一道白光,她还没失声惊叫,前额就已经遭到了猛烈一击。她双腿一软倒了下去,脑袋后仰靠在了床沿上。
东山随手操起烟缸向露珠头顶砸去时,他没有听到烟缸打在她脑壳上的声音,那时露珠的失声惊叫掩盖了这种声音。露珠的惊叫让东山感到是一条经过附近的狗的随便叫声。随后露珠的身体像一条卷着的被子一样掉落在地。那个时候东山才发现烟缸已经破碎,碎片掉在地上时纷纷响起刚才关门时那种“砰”的声响,但是东山对这种过于轻微的声音十分不满。他现在心中的嫉恨需要更为强烈的声响来平息。于是他操起近旁的一把凳子,猛地朝露珠头上砸去,凳子的两条腿断了,刚才床的“嘎吱”声短暂地重现。他听到露珠窒息般地呻吟了一下,同时他看到露珠脑袋歪过去时眼皮微微跳动了一下。这情形使东山对自己极为恼火。于是他又操起了另一把凳子,可是他马上觉得它太轻而扔在了一旁。接着他的眼睛在屋内寻找,不一会他看中了那个衣架,但是当他提起衣架时又觉得它太长而挥舞不开。然后他看到了放在墙角的台扇,台扇的风叶已经取掉。他走过去提起台扇时马上感到它正合适。他就用台扇的底座朝露珠的脑袋劈去,他听到了十分沉重的“咔嚓”一声,这正是他进屋时钥匙转动的声音,但现在的咔嚓声已经扩张了几十倍。这时露珠的脑袋像是一个被切开的西瓜一样裂开了。东山看着里面的脑浆和鲜血怎样从裂口溢出,它们混合在一起如同一股脓血。灯光从裂口照进去时,东山看到了一撮头发像是茅草一样生长在里面。
十四
东山拂晓时走入了这条小巷,东山的出现,完成了老中医多日前的预测。那时早晨已经挂在了巷口的天上,东山从那里走了进来,走入了老中医的视线。东山是这一天第一个走入他视线的人,在此之前有一只怀孕的猫在巷口蹒跚地踱过。尽管东山的面容已被硝酸全盘否定,但是老中医还是一眼认出了他,在那个绵绵阴雨之晨第一次走来的年轻人。因此此刻看着东山走来时,他的心脏和两个肺叶喜悦地碰撞了一下。东山摇摇晃晃地走到窗下时站住了脚,然后微微仰起了脸。老中医深刻领会了这个回首往事的姿态。接着东山的身影在下面一闪后便消失,老中医听到楼下那扇门“呀”地一声,随即是门框上的灰尘掉落下去掉落下去的声音,然后是几下轻重不一的脚步。从脚步的声响里,老中医精确地计算出东山进屋以后跨出了几步,和每一步的距离。当他离开窗口准备趴到地板上那个小孔去时,他感到东山就在下面。
东山是看着露珠体内的鲜血从头顶溢尽后才离开的,那时候他的嫉恨也流尽了。于是他感到内心空空荡荡。他在城里的街道上转悠了很久后,才决定来这里的。那时拂晓已经开始,他显然看到了那一片最初出现的朝霞,朝霞使他重温了露珠的鲜血在地板上流淌的情形。现在他已经站在了老中医的左眼珠下面,昏暗的四壁使他感到口干舌燥。这时他听到了从上面像灰尘一样掉落下来的声音:
“你来了。”
这声音使东山感到老中医已经等待很久了。
东山告诉他:
“我把露珠杀了,她抛弃了我……”
他听到自己的声音有气无力地在屋内嗡嗡地响着。随后他听到头顶上有一张旧报纸在旧报纸在掉下来,他听到老中医说:
“你把头仰起来。”
东山把头仰了起来,他看到楼板上布满了蜘蛛网,但他没看到那个小孔。
“我看不清你的脸。”
老中医说。他的声音因为隔着一层楼板而显得遥远和缥缈。随后他指示东山:
“你向右走两步……伸出右手……摸到电灯开关上……打亮电灯吧。”
东山打亮电灯以后,老中医又指示他:
“你可以回到刚才的地方了。”
东山便回到刚才的地方。
“把头仰起来。”
东山仰起头以后,电灯的光线直奔他的眼睛而来,同时一种咳嗽般的笑声也直奔他的眼睛而来。
“露珠干得不错。”
老中医在看清了东山破烂的脸以后,显然感到心满意足,他告诉东山:
“你的脸像一条布满补丁的灰短裤。”
然后东山听到老中医像是移动椅子似的脚步声,接着楼上响起了一丝金属碰撞玻璃的声音,那声音里还包含着滴水声。不久之后他听到楼梯上那扇门伤心地“呀”了一声,门开了。然后好像是一只玻璃瓶搁在楼梯上的迟钝响声,接着门又“呀”的一声关上了。他听到老中医在说:
“你用舌头舔嘴唇,说明你需要水。去拿吧,就在楼梯上。”
于是东山就沿着灰暗的楼梯走上去,那楼梯像是要塌了似的摇晃起来。在楼梯的最后一阶上,东山看到了一只形状古怪的玻璃杯。他走上去拿起了这只玻璃杯,里面水的晃动声使东山十分感动。他没有观察一下里面水的颜色,就一口喝干了,喝干以后他觉得那水的味道和玻璃杯的形状一样,十分古怪。然后他一步一步地走下了楼梯。在他走下楼梯的时候,他听到了老中医不容争辩的声音,开始习惯了刚才那种缥缈的声音的东山,对这坚定的声音有些不知所措。老中医说:
“你可以离开了。你走到巷口以后往右拐弯,走二十分钟后你就走到了那个十字路口,这一次你应该向左走。然后你一直往前,在路上不要和任何人说话,这样也就无人能够认出你。你会顺利地走进火车站,然后会同样顺利地买到一张车票。向南也好,向北也好,只要你能逃离这里一千里,你就可以重新生活了。年轻人,现在你可以走了。”
十五
那天晚上,彩蝶在经历了漫长的绝望之后,终于对自己的翌日做出了选择。那时候她听到对面人家的一台老式挂钟敲了三下。钟声悠扬地平息了她心中的痛苦。在钟声里,一座已经拆除脚手架但尚未交付使用的建筑栩栩如生地出现了。她在这座虚幻的建筑里平静地睡去了。
当她早晨起床后,她奇怪地发现自己竟然心情很好。那时候她已经坐在梳妆台前,屋外的阳光透过窗玻璃照到了镜子上。所以她在镜中凝视着自己的脸时,感到这张脸闪闪发亮。但她同时又似乎感到自己正被一双陌生的眼睛凝视。然后她离开了梳妆台,走到窗前打开窗户,屋外潮湿的空气进来时,使窗帘轻轻地摇晃了一下。然而这个索然无味的情形却使她不禁微微一笑。于是她又一次对自己的心情感到奇怪。但是她的奇怪并没有得到发展,当她关上门走到屋外时,那种奇怪便被她锁在了屋内。因此广佛在临终时的预告将不受阻挠地成为现实了。
彩蝶走在那条小巷之中时,她不可能知道这种心情其实是命运的阴险安排。所以当她明知自己在走向毁灭时,却丝毫没有胆怯之感。相反她感到心满意足。她觉得一切忧伤都在远去,她在走向永久的宁静。命运在这天早晨为她制造了这样的心情,于是也就清扫了彩蝶走向毁灭路中的所有障碍。
彩蝶在走出小巷时,她看到了生命的最后印象。她那时看到一辆破自行车斜靠在一根水泥电线杆上,阳光照在车轮上。她看到两个车轮锈迹斑斑,于是在那一刻里她感到阳光也锈迹斑斑。这个生命的最后印象,在此后的一个小时里始终伴随着彩蝶。
彩蝶嘴角挂着迷人的微笑走出了小巷,然后她向右拐弯了,拐弯以后她行走在人行道上。阳光为梧桐树叶在道上制造了很多阴影,那些阴影无疑再次使彩蝶感到锈迹斑斑。那个时候她感到身旁的马路像是一条河流,她行走在河边。她恍若感到有几个人的目光在自己身上闪闪烁烁,她感到他们的目光也是锈迹斑斑。她就这样走过了银行、杂货商店、影剧院、牙防所、美发店……如同看一下饭店里的菜单一样,她走了过去。然后她来到了昨晚随着钟声出现的那座建筑前。她一转身就进去了,那时候挂在她嘴角的微笑仍然很迷人。她的脚开始沿着楼梯上升,她一直走到楼梯的消失。一座大厅空空荡荡地出现在眼前。她在大厅的窗玻璃上看到了斑斑油漆,因此她在那条巷口得到的锈迹斑斑的印象,此刻被这些窗玻璃生动地发展了。她用笔直的角度走到了一扇敞开的窗前。她站在窗口居高临下地看了几眼这座小城。展现在她视野中的是高低起伏的房屋,像蚯蚓一样的街道,以及寄生在里面的树木。所有这一切最后一次让她感到了锈迹斑斑,于是她感到整个世界都是锈迹斑斑。后来她就爬到了窗沿上,那个时候广佛在审判庭里夸夸其谈的声音也锈迹斑斑地出现了。
时隔几日以后,沙子坐在拘留所冰凉的水泥地上,以无法排遣的寂寞开始回想起他那天在路上遇到彩蝶的情景。那时候他的眼睛注视着那个名叫窗口的小洞,彩蝶迷人的微笑便在那里出现了。尽管那时还没有人告诉他彩蝶的死讯,但他已经预感到了,所以他脸上出现了心满意足的微笑。
直到很久以后,那一天里看到过彩蝶的人在此后回想起当初的情景时,都激动不已。那时候沙子已经从拘留所里出来了。一个十六岁的少年眼泪汪汪地告诉沙子:
“她漂亮极了。”
曾经在彩蝶揭纱布仪式上指出“两条刀疤”的那个男人,是在那家杂货商店门口看到彩蝶走来的。他后来是这样对沙子说的:
“她简直灿烂无比。”
但是沙子的祖母,一个八十岁的老人却并不那样看。她说是在米行那个地方看到彩蝶的。事实上她是在影剧院前看到彩蝶,那个地方作为米行是四十多年前的事。自然她没有说看到彩蝶,她说是看到了一个妖精,并且非常坚决地断定那是一个跳楼自杀的女人。直到后来她重温那一幕时仍然战战兢兢,她告诉沙子:
“她眼睛里放射着绿光。”
沙子肯定他祖母在影剧院前看到的那个年轻女子就是彩蝶,并不是武断的猜想。因为与此同时他的一个远房表妹也在那地方看到过彩蝶。他表妹在回忆那天的情景时没有别人那么激动,她显得十分冷漠,她对沙子说:
“他们是在虚张声势。”
沙子的表妹在那天里同样走了彩蝶走的那条路,因为其间她在美发店前看了一会广告,所以当她走到那座建筑前时,刚好目睹了彩蝶跳楼时的情景。
她告诉沙子彩蝶是头朝下跳下来的,像是一只破麻袋一样掉了下来。彩蝶的头部首先是撞在一根水泥电线杆的顶端,那时候她听到了一种鸡蛋敲破般的声音。然后彩蝶的身体掉在了五根电线上,那身体便左右摇晃起来,一直摇晃了很久。所以彩蝶头上的鲜血一滴一滴掉下来时也是摇摇晃晃的。
十六
在很多日子过去以后,一个偶然的机会使东山看到了森林。东山在那个早晨按照老中医的指示走进了一列北上的列车,他在列车上昏睡了两天一夜,当他走下列车时感到自己被虚汗浸透了。然后又经历了欲生不能的三天,此后他的体质才慢慢恢复过来。当他大病初愈般地重新回想起那个早晨的情景时,他才深刻地领悟到那个老中医让他喝下的是什么,因为从此以后他永久地阳痿了。即便他尚能苟且活下去,他也不能以一个男人自居了。
森林出现的时候,东山正坐在一千里以外的某座小城的某一条街道旁,他重新的生活是从饥寒交迫开始的。森林从他面前走过去,森林没有看到他。他看着森林背着一只黑色旅行包走入了车站。他并不知道森林出来的事,但现在他知道森林是要回去了。
一九八八年一月十八日
难以觉察的树荫移动-[[阿摩司·奥兹]]
========================
难以觉察的树荫移动
故事开始了:文学随笔集 阿摩司·奥兹
## 谈特奥多尔·冯塔纳[1]的《艾菲·布里斯特》的开头
-----
特奥多尔·冯塔纳的长篇小说《艾菲·布里斯特》1894年出版;我所读的尼莉·米尔斯基[2]的希伯来文译本1981年问世。《艾菲·布里斯特》讲述了一位年轻的普鲁士女人的故事,她是一个受人尊敬的殷实家族的女儿,她父母把她嫁给了冯·殷士台顿男爵,一个上了年纪的男人,一位军官。在故事开始多年前,这位男爵和艾菲的母亲有过一段未果情缘。两个体面的家族的这次结亲是称心如意的,但男女双方却并不般配:艾菲是个天性自然,感情丰富的性情中人,而她丈夫殷士台顿则是个不苟言笑、讲求逻辑、举止得体、考虑周全的男人,他以他自己那谨慎的方式呵护他年轻的妻子。他和托尔斯泰的《安娜·卡列尼娜》中的阿列克谢·亚历山德罗维奇·卡列宁[3]不无相似之处(尽管这位普鲁士贵族不像那位俄罗斯高官那么僵化,他的耳朵很显然比卡列宁小得多)。普鲁士上层社会那严格的价值观在小说中起着核心作用。这些价值观讲究责任、荣誉、服从和纪律、严格的按部就班和对情感的压抑。
在殷士台顿外出旅行的时候,艾菲和克拉姆巴斯上校发生了恋情。克拉姆巴斯是个长着络腮胡子的色鬼和赌徒,一个聪明的唐璜,“一个很有女人缘的男人”。当男爵得知了这段风流韵事,他当然向这位情夫提出决斗,决斗中,这位丈夫获胜,杀死了他的情敌。
艾菲从家里被驱逐出去,起先被赶到一座孤零零的寓所。为了惩罚她的通奸罪,也为了避免她的女儿受到不道德的母亲的影响,她被迫和她唯一的女儿安妮分开。年幼的安妮和她的男爵父亲一起生活,他按照名誉和传统的价值观对她进行教育。艾菲·布里斯特的形象应是安娜·卡列尼娜以及爱玛·包法利[4]两个文学形象的远亲,和阿格农的《在她风华正茂之年》中的提尔察也有一两点共同之处。到了故事的结尾,艾菲回到了她父母的家,她在那里找到了一份宁静,这份宁静源自一种深深的被接纳的感觉。不久之后她死去,死在她生于斯、长于斯的房子里,在小说的一开始,作者对这座房子的外表作了一番描写。如果是匆匆地浏览小说的开头,就只会看到一个宁静的、无人的世界。更精确地说,一个几乎没有生命的世界。甚至再精确一点说:静物营造了宁静的氛围。
冯·布里斯特在霍恩——克莱门的宅院的前面——他们家族的宅院自选帝侯格奥尔格·威廉[5]统治时期就已经存在——那条乡村街道沐浴在正午的骄阳之下,而靠近公园及花园有一座厢房,与正厅构成曲尺形,把宽阔的阴影先是投到一条白绿相间的石板村道上,继而又投到外面一座巨大的圆形花坛上,花坛中央有一个日晷,绕着花坛边缘种着美人蕉和大黄。再往前走十几码,恰好和厢房对称,是一堵教堂的墙壁,整个墙壁上爬满了小叶的常春藤,一扇漆成白色的小铁门像是把这堵墙戳开了一个洞;墙外,高耸着霍恩——克莱门塔,塔顶盖着木板瓦,塔上那个最近才重新镀了金的风信鸡在阳光下熠熠生辉。
正厅、厢房和教堂的墙壁围成了一个马蹄形地带,正好把一座作装饰用的小花园围拢起来,开口的那一边是一个小湖和一个码头,一只小船停泊在码头,附近是一个秋千,两条绳索拴住木座的两头;支撑木头秋千架的柱子已经有点儿歪斜。然而,在湖和圆形花坛之间,长着几棵巨大的老悬铃树,把那秋千遮掩了。
这难道不是一张游客的图画明信片吗?难道不是那种甜得发腻的风景画,过去摆放在客厅里的钢琴上面,以便和扶手椅及水晶枝形吊灯相搭配,给房间营造一种殷实、典雅和舒适的氛围?这无论如何都是一种非常缓慢而宁静的描写,这种描写在当代作品中再难以找到,而当代读者对这种描写或许已没有欣赏力或耐性了;假如一个读者刚刚读完雷蒙德·卡佛[6]的作品,直接来读这部作品的话,他或许会不耐烦地耸耸肩。哪位读者如果要寻找曲折的情节,在这里是找不到的。《艾菲·布里斯特》是近乎平静的水面上的一朵莲花。在各种叙事性文体中,小说最适宜诠释那些细微的轨迹和那种种偏差,偏差导致整个一生缓缓地偏离航线,走入歧途,最后以失望告终。
如果细细阅读,就会发现:开头部分的宁静是紧张的,景物里的和谐氛围遭到了威胁:村子的街道在宅院前延伸,两者都包裹在宁静中,沐浴在阳光下。和街道不同,公园和花园在阴影下,但这个阴影是动的,而不是静的:厢房的阴影先是落在石板小径上,从那里又向圆形的花园移了过去。花坛后面矗立着教堂的墙壁,而墙壁和街道一样,也延伸了出去。
不仅是阴影的线条,从小径到花坛,而是几乎这里的一切都被设计成生硬的几何形状:厢房和正厅呈直角;小径由绿色和白色的石板铺就;花坛是圆形的,正中央插着一个日晷,花坛周围是装饰性的花边;教堂的墙壁和厢房平行。在所有这一切的外面,一座塔高高耸起。几座建筑和墙壁把花园围成了“马蹄形”。作者甚至告诉我们,那个秋千的座用木头做成,和从木头架子上垂落下来的两根绳子相垂直,木头架子由两根柱子支撑,而柱子却不是直的。因此,整个画面都呈几何形状,几乎是立体主义的。
视野延伸的感觉,时光的缓缓流逝,在这里都通过阴影移动的暗示表现了出来。阴影的移动照常理是持续不断的,从铺了石板的小径移到圆形的花坛:乍看似乎感觉不到阴影的爬动,由此我们明白了,对这些建筑和花园的观察是个持续进行的活动,观察者是静止不动的,他的视角是不变的。这也暗示了其他运动的存在,而这些运动被阻滞或者是被冻结了:秋千、池塘、拴在码头的小船。
在这里,对教堂墙壁的描写是和厢房“恰好对称”:然而这一对称变得幽闭而压抑。作者告诉我们,墙上有一个开口,只有一个开口;接着我们就了解到,这不是一扇门,而是一个白色的铁门,而且是“很小”的门。所以立即就滋生出一种监禁的感觉,营造出一种幽闭的气氛,即便我们还没有理解到,被监禁的是一个“作装饰用的小花园”,三个了无生机的笨重的物体把花园围了起来:庞大的宅院,直角的厢房和教堂的墙壁,墙上只有一个小门。在这个马蹄形的开口处,虽然有一个小湖,湖面上有一只小船,但小船被拴在了码头上。最后我们发现,开口的那一边尽管能够使视线从花坛移到湖面上,但实际上也被封死了:在湖和圆形花坛之间矗立着几棵巨大的老悬铃树,几乎把秋千遮挡了起来。
这样子,我们就有了一个年轻女人,艾菲·布里斯特,和她的世界,在她周围封闭着;女主人公还没有出场,还没有交代社会背景、时代背景、各种禁忌和失败的冲破的企图,这里就描写了她所处的世界。
塔顶上的风信鸡并不是新的。或许,这个风信鸡和冯·布里斯特家族的宅院一样,自格奥尔格·威廉时代就矗立在那里了。只有它那金色的叶片是新的,闪闪发光。整个画面表现出的是力量和稳定,许多代人积累起来的权势、严格的秩序、权威和严苛。然而这个城堡却从内部受到了威胁:那倾斜的秋千支柱,那围起来的花园,尤其是那窒息的气氛。秋千那细腻的画面里有一种压抑的东西:一个木头横梁架在支柱上,两根绳子从横梁上垂落下来,一动不动。
事实上,没有运动,连一丝轻风都没有掠过这整个画面:不管是墙壁上的门还是任何一扇门都没有开着。没有人进去,也没有人出来。没有犬吠,没有鸟飞,树叶不动,一切都鸦雀无声,一切都了无生气,凝滞不动。整个段落里听不到一点点声音。没有一声呢喃,没有最轻柔的微风吹拂公园、花园、花草、风信鸡、湖面、拴着的小船、凝滞的秋千和那些老悬铃树的树梢。一个死气沉沉的世界。正如我们注意到的,在整个描写中,唯一动着的,是阴影那难以觉察的推移。这种推移进展缓慢:刚开始落在石板小径上,从那里又朝花坛爬行过去,最终来到离花坛有二十步远的教堂墙壁上,墙上覆盖着常春藤的小叶子。房子的内部还一直遮掩着,要再看好几页之后才显露出来。这就是艾菲·布里斯特的世界:那建筑物的压抑、呆板的花园、凝滞的湖水。只有那悄悄移动的阴影没有被墙壁阻挡。
这开头一段要求读者订立哪一种合同,作为进入这座宅院和这部长篇小说的前提条件呢?一种对从容细致的阅读的郑重要求:倘若没有延伸的视野,就看不到阴影的移动。如果不耐心倾听,就听不出那全然的静寂和凝滞。除非读者进入了细节内部,否则的话,这开头一段就只不过是一张赏心悦目的带画的明信片而已:一座气势恢宏的贵族宅院,建在湖边,四周是一个公园,整个笼罩在宁静之中。过分心急的读者可能会轻易得出推论——有钱人是幸福的,并匆匆往后阅读。冯塔纳小说开头的合同条款要求我们要蹑手蹑脚地进入这部小说,或者差不多是蹑手蹑脚地进入。即便我们还没有认识艾菲·布里斯特本人,我们也要从容咀嚼展示给我们的东西,静听那越来越浓重的静寂。
【注释】
[1] 特奥多尔·冯塔纳(1819——1898),德国小说家,诗人。被认为是19世纪最重要的德语现实主义作家。《艾菲·布里斯特》是他的代表作。该书曾于1974年由西德搬上银幕。
[2] 尼莉·米尔斯基(1945——),以色列著名的文学翻译家,2008年获得以色列文学翻译奖。
[3] 阿列克谢·亚历山德维奇·卡列宁:安娜·卡列尼娜的丈夫,是典型的保守男人的形象。
[4] 爱玛·包法利:法国作家福楼拜的名著《包法利夫人》的女主人公。
[5] 格奥尔格·威廉(1595——1640),勃兰登堡选帝侯,1619——1640年在位。
[6] 雷蒙德·卡佛(1938——1988),美国当代著名短篇小说家、诗人,美国“极简主义”代表作家,并被誉为“新小说”创始者。
内心之死-余华
========================
内心之死-[[余华]]
-----
我想在这里先谈谈欧内斯特·海明威和罗伯-格里耶的两部作品,这是在我个人极其有限阅读里的两次难忘的经历,我指的是《白象似的群山》和《嫉妒》。与阅读其他作品不一样,这两部作品带给我的乐趣是忘记它们的对话、场景和比喻,然后去记住从巴塞罗那开往马德里快车上的“声音”,和百叶窗后面的“眼睛”。
我指的似乎是叙述的方式,或者说是风格。对很多作家来说,能够贯穿其一生写作的只能是语言的方式和叙述的风格,在不同的题材和不同的人物场景里反复出现,有时是散漫的,有时是暗示,也有的时候会突出和明朗起来。不管作家怎样写作,总会在某一天或者某一个时期,其叙述风格会在某一部作品里突然凝聚起来。《白象似的群山》和《嫉妒》对海明威和罗伯-格里耶正是如此。就像参加集会的人流从大街小巷汇聚到广场一样,《白象似的群山》和《嫉妒》展现了几乎是无限的文学之中的两个广场,或者说是某些文学风格里的中心。
我感兴趣的是这两部作品的一个共同之处,海明威和罗伯-格里耶的叙述其实都是对某个心理过程的揭示。
《白象似的群山》有资格成为对海明威“冰山理论”的一段赞美之词。西班牙境内行驶的快车上,男人和姑娘交谈着,然后呢?仍然是交谈,这就是故事的全部。显然,这是一部由“声音”组装起来的作品,男人的声音和姑娘的声音,对话简短发音清晰,似乎是来自广播的专业的声音,当然他们不是在朗读,而是交谈──“天气热得很”“我们喝杯啤酒吧”。从啤酒到西班牙的茴香酒,两个人喝着,同时说着。他们使用的是那种不怕被偷听的语言,一种公共领域的语言,也就是在行驶的列车上应该说的那种话。然而那些话语里所暗示的却是强烈的和不安的隐私,他们似乎正处于生活的某一个尴尬时期,他们的话语里隐藏着冲突、抱怨和烦恼,然后通过车窗外白象似的群山和手中的茴香酒借题发挥。
加西亚·马尔克斯曾经用钟表匠的语气谈论欧内斯特·海明威,他说:“他把螺丝钉完全暴露在外,就像装在货车上那样。”《白象似的群山》可以说是一览无余,这正是海明威最为迷人之处。很少有作家像海明威那样毫无保留地敞开自己的结构和语言,使它们像河流一样清晰可见。与此同时,海明威也削弱了读者分析作品的权利,他只让他们去感受、猜测和想象。《白象似的群山》是这方面的专家,在那些如同列车、啤酒和窗外的群山一样明确单纯的语言下,海明威展示的却是一个复杂的和百感交集的心理过程。在驶往马德里的快车上,男人和姑娘的交谈似乎有了一个理由──堕胎,然而围绕着这个理由延伸出去的话语又缺少了起码的明确性,就像他们不详的姓名一样,他们的交谈也无法被确定下来。
欧内斯特·海明威明白内心意味着什么,正如他著名的“冰山理论”所认为的那样,人们所能看到的和所能计算的体积,只是露出海面的冰山一角。隐藏在海水深处的才真正是冰山的全部,而这部分只能通过感受、猜测和想象才得以看到。于是海明威无法用意义来确定他们的交谈,就像无法确认男人和姑娘的姓名。没有了姓名的男人和姑娘同时又拥有了无数姓名的可能,没有被指定的交谈也同时表达了更多的可能中的心理经历。
与《白象似的群山》相比,罗伯-格里耶在《嫉妒》里所叙述的内心压力似乎更为漫长,不仅仅是篇幅的原因,海明威的叙述像晴空一样明朗,有着奏鸣曲般跳跃的节奏,而罗伯-格里耶则要暗淡得多,如同昼夜之交的黄昏,他的叙述像阳光下的阴影一样缓慢地移动着。
“嫉妒”一词在法语里同时又是“百叶窗”,显然,罗伯-格里耶在选择这个词语的时候,也选择了耐心。百叶窗为注视中的眼睛提供了焦距,对目光的限制就像在花盆里施肥,让其无法流失,于是内心的嫉妒在可以计算的等待里茁壮成长。
光线、墙壁、走廊、门窗、地砖、桌椅、A和她的邻居以轮回的方式出现和消失,然后继续出现和继续消失。场景和人物在叙述里的不断重复,如同书写在复写纸上,不仅仅是词序的类似,似乎连字迹都是一致,其细微的差异只是在浓淡之间隐约可见。
长时间的注视几乎令人窒息,“眼睛”似乎被永久地固定住了,如同一件被遗忘的衬衣挂在百叶窗的后面。这一双因为凝视已久已经布满了灰尘的“眼睛”,在叙述里找到了最好的藏身之处,获得了嫉妒和百叶窗的双重掩护。罗伯-格里耶只是在第三把椅子、第三只杯子、第三副餐具这类第三者的暗示里,才让自己的叙述做出披露的姿态,一个吝啬鬼的姿态。
即便如此,阅读者仍然很难觉察这位深不可测的嫉妒者,或者说是百叶窗造就出来的窥视者。就像他的妻子A和那位有可能勾引A的邻居一样很难觉察到他的存在。窥视者的内心是如此难以把握,他似乎处于切身利益和旁观者的交界之处,同时他又没有泄露一丝的倾向。罗伯-格里耶让自己的叙述变成了纯粹的物质般的记录,他让眼睛的注视淹没了嫉妒的情感,整个叙述无声无息,被精确的距离和时间中生长的光线笼罩了。显然,A和那位邻居身体的移动和简短的对话是叙述里最为活跃的部分,然而他们之间的暧昧始终含糊不清,他们的言行总是适可而止。事实上,罗伯-格里耶什么都没有写,他仅仅是获得了叙述而已,他和海明威一样了解叙述的过程其实就是一个独裁的过程,当A和她的邻居进入这个暧昧的叙述时,已经没有清白可言了,叙述强行规定了他们之间的暧昧关系。
在这里,罗伯-格里耶向我们展示了一个不可思议的内心,一个几乎被省略的人物的内心,他微弱的存在不是依靠自己的表达,而是得益于没有他出现的叙述的存在,他成为了《嫉妒》叙述时唯一的理由,成为了词语的来源,成为了罗伯-格里耶写作时寻找方向的坐标。于是,那位不幸的丈夫只能自己去折磨自己了,而且谁也无法了解他自我折磨的方式。与此同时,罗伯-格里耶也让阅读者开始了自我折磨,让他们到自己的经历中去寻找回忆,寻找嫉妒和百叶窗,寻找另一个A和另一个邻居。
回忆、猜测和想象使众多的阅读者百感交集,他们的内心不由自主地去经历往事的痛苦、焦虑和愤怒,同时还有着恶作剧般的期待和不知所措的好奇心。他们重新经历的心理过程汇集到了一起,如同涓涓细流汇入江河,然后又汇入大海一样,汇集到了罗伯-格里耶的《嫉妒》之中。一切的描叙都显示了罗伯-格里耶对眼睛的忠诚,他让叙述关闭了内心和情感之门,仅仅是看到而已,此外什么都没有,仿佛是一架摄影机在工作,而且还没有“咝咝”的机器声。正因为如此,罗伯-格里耶的《嫉妒》才有可能成为嫉妒之海。
欧内斯特·海明威和罗伯-格里耶的写作其实回答了一个由来已久的难题──什么是心理描写?这个存在于教科书、文学辞典以及各类写作和评论中的专业术语,其实是一个错误的路标,只会将叙述者引向没有尽头的和不知所措的远方。让叙述者远离内心,而不是接近。
威廉·福克纳在其短篇小说《沃许》里,以同样的方式回答了这个问题。这个故事和福克纳的其他故事一样粗犷有力,充满了汗水与尘土的气息。两个白人──塞德潘和沃许,前者因为富裕成为了主人,而贫穷的沃许,他虽然在黑人那里时常会得到来自肤色的优越感,可他仍然是一个奴隶,一个塞德潘家中的白奴。当这个和他一样年过六十的老爷使他只有十五岁的外孙女怀孕以后,沃许没有感到愤怒,甚至连不安都没有。于是故事开始了,沃许的外孙女弥丽躺在草垫上,身边是她刚刚出生的女儿,也就是塞德潘的女儿。塞德潘这一天起床很早,不是为了弥丽的生产,而是他家中名叫格利赛达的母马产下了马驹。塞德潘站在弥丽的草垫旁,看着弥丽和她身边的孩子,他说:“真可惜,你不是匹母马。不然的话,我就能分给你一间挺像样的马棚了。”
塞德潘为格利赛达早晨产下的小公马得意洋洋,他说:“公的。呱呱叫的小驹子。”然后他用鞭子指指自己的女儿:“这个呢?”“是个母的,我觉得。”
叙述从一开始就暗示了一个暴力的结束。福克纳让叙述在女人和母马的比较中前行,塞德潘似乎成为了那匹母马的丈夫,格利赛达产下的小驹子让塞德潘表达出了某些父亲的骄傲。而沃许的外孙女弥丽对他来说只是一个奴隶,她身边的孩子虽然也是他的孩子,可在他眼中不过是另一个奴隶。福克纳的叙述为沃许提供了坚不可摧的理由,当沃许举起大镰刀砍死这个丧失了人性的塞德潘,就像屠宰一匹马一样能够为人所接受。
然后,叙述的困难开始了,或者说是有关心理描写的绝望开始了。如果沃许刚才只是喝了一杯威士忌,那么展示他的内心并不困难,任何简单的叙述都能够胜任,让他告诉自己:“我刚才喝了一杯威士忌。”或者再加上“味道不错”“我很久没喝了”之类的描叙。
描叙的欲望如果继续膨胀,那么就可以将内心放入到无所事事的状态之中,像马塞尔·普鲁斯特在《追忆似水年华》里经常做的工作──“我心中有数,我当时把自己置于最为不利的境地,最终会从我的长辈们那里得到最为严厉的处罚,其严厉程度,外人实际上是估计不到的。他们或许以为……”普鲁斯特善于让他笔下的人物在清闲的时候打发时光,让人物的内心在对往事的追忆中越拉越长,最后做出对自己十分有利的总结。
如果沃许刚才举起的不是镰刀,而是酒杯,喝到了上好的威士忌的沃许·琼斯很可能会躺到树荫里,这个穷光蛋就会像斯万那样去寻找记忆和想象,寻找所有喝过的和没有喝过的威士忌,要是时间允许,他也会总结自己,说上一些警句和格言。然而现实让沃许选择了镰刀,而且砍死了塞德潘。一个刚刚杀了人的内心,如何去描写?威廉·福克纳这样写道:
他再进屋的时候,外孙女在草垫上动了一下,恼怒地叫了一声他的名字。“什么事呀?”她问。
“什么什么事呀?亲爱的?”
“外边那儿吵吵闹闹的。”
“什么事也没有。”他轻轻地说……
沃许·琼斯显示了出奇的平静,他帮助外孙女喝了水,然后又对她的眼泪进行了安慰。不过他的动作是“笨拙”的,他站在那里的姿态是“硬挺挺”的,而且阴沉。他得到了一个想法,一个与砍死塞德潘毫无关系的想法:“女人……她们要孩子,可得了孩子,又要为这哭……哪个男人也明白不了。”然后他坐在了窗口。威廉·福克纳继续写道:
整个上午,悠长、明亮、充满阳光,他都坐在窗口,在等着。时不时地,他站起来,踮起脚尖走到草垫那边去。他的外孙女现在睡着了,脸色阴沉、平静、疲倦,婴儿躺在她的臂弯里。之后,他回到椅子那儿再坐下,他等着,心里纳闷为什么他们耽误了这么久,后来他才想起这天是星期天。上午过了一半,他正坐着,一个半大不小的白人男孩拐过屋角,碰上了死尸,抽了口冷气地喊了一声,他抬头看见了窗口的沃许,霎时间好像被催眠了似的,之后便转身逃开了。于是,沃许起身,又踮着脚来到草垫床前。
沃许砍死塞德潘之后,威廉·福克纳的叙述似乎进入了某种休息中的状态,节奏逐渐缓慢下来,如同远处的流水声轻微和单纯地响着。叙述和沃许共同经历了前期的紧张之后,随着那把镰刀果断地砍下去,两者又共同进入了不可思议的安静之中。当沃许几乎耗尽了毕生的勇气和力量,终于完成了自己的工作,他似乎像他的外孙女一样疲倦了。于是他坐在了窗口,开始其漫长的等待,同时也开始了劳累之后的休息。此刻的叙述展示了一劳永逸似的放松,威廉·福克纳让叙述给予沃许的不是压迫,而是酬谢。沃许·琼斯理应得到这样的慰劳。
显而易见,福克纳在描写沃许内心承受的压力时,不是让叙述中沃许的心脏停止跳动,而是让沃许的眼睛睁开,让他去看;同时也让他的嘴巴张开,让他去说。可怜的沃许却只能说出一生中最为贫乏的语言,也只能看到最为单调的情形。他被叙述推向了极端,同时也被自己的内心推向了极端,于是他失去掌握自己命运的能力,而叙述也同样失去了描写他内心的语言。
就像海明威和罗伯-格里耶所从事的那样,威廉·福克纳对沃许心理的描写其实就是没有心理描写。不同的是,福克纳更愿意在某些叙述的片段而不是全部,来展示自己这方面出众的才华和高超的技巧,而且满足于此;海明威和罗伯-格里耶则是一直在发展这样的叙述,最后他们在《白象似的群山》和《嫉妒》里获得了统一的和完美的风格。
另外一个例子是陀思妥耶夫斯基的《罪与罚》,拉斯柯尔尼科夫与沃许·琼斯一样有着杀人的经历。不同的是,福克纳只是让沃许举起镰刀,陀思妥耶夫斯基让拉斯柯尔尼科夫举起的是一把更为吓人的斧头。福克纳省略了杀人的过程,他只是暗示地写道:“他手里握着那把镰刀,那是三个月以前跟塞德潘借的,塞德潘再也用不着它了。”而陀思妥耶夫斯基则是让拉斯柯尔尼科夫“把斧头拿了出来,用双手高高举起,几乎不由自主地、不费吹灰之力地、几乎机械地用斧背向她的头上直砍下去”。
紧接着,陀思妥耶夫斯基令人吃惊地描叙起那位放高利贷老太婆的头部,“老太婆和往常一样没有扎头巾。她那带几根银丝的、稀疏的、浅色的头发照常用发油搽得油光光的,编成了一条鼠尾似的辫子,并用一把破牛角梳子盘成了一个发髻。这把梳子突出在后脑勺上”。
陀思妥耶夫斯基以中断的方式延长了暴力的过程,当斧头直砍下去时,他还让我们仔细观察了这个即将遭受致命一击的头部,从而使砍下的斧头增加了惊恐的力量。随后他让拉斯柯尔尼科夫再砍两下,“血如泉涌,像从打翻了的玻璃杯里倒出来一样,她仰面倒下了……两眼突出,仿佛要跳出来似的……”
陀思妥耶夫斯基噩梦般的叙述几乎都是由近景和特写组成,他不放过任何一个细节,而且以不可思议的笨拙去挤压它们,他能够拧干一条毛巾里所有的水分,似乎还能拧断毛巾。没有一个作家能够像陀思妥耶夫斯基那样,让叙述的高潮遍布在600页以上的书中,几乎每一行的叙述都是倾尽全力,而且没有轻重之隔,也没有浓淡之分。
谋财害命的拉斯柯尔尼科夫显然没有沃许·琼斯的平静,或者说陀思妥耶夫斯基的叙述里没有平静,虽然他的叙述在粗犷方面与威廉·福克纳颇有近似之处,然而威廉·福克纳更愿意从容不迫地去讲述自己的故事,陀思妥耶夫斯基则像是在梦中似的无法控制自己,并且将梦变成了梦魇。
有一点他们是相同的,那就是当书中的人物被推向某些疯狂和近似于疯狂的境地时,他们都会立刻放弃心理描写的尝试。福克纳让沃许坐到了窗前,给予了沃许麻木和不知所措之后的平静;而陀思妥耶夫斯基则让拉斯柯尔尼科夫继续疯狂下去,当高利贷老太婆“两眼突出,仿佛要跳出来似的”以后,陀思妥耶夫斯基给了拉斯柯尔尼科夫分散在两个章节里的近二十页篇幅,来展示这个杀人犯所有的行为,一连串的热锅上的蚂蚁似的动作,而不是心理描写。
拉斯柯尔尼科夫在清醒和神志不清之间,在恐惧和勇气之间,一句话就是在梦和梦魇之间,开始了他杀人的真正目的──寻找高利贷老太婆的钱财。陀斯妥耶夫斯基这时候的叙述,比斧头砍向头颅更为疯狂,其快速跳跃的节奏令人难以呼吸。
他把斧头放在死人身边的地板上,立刻去摸她的口袋,极力不让自己沾上涌出来的鲜血──她上次就是从右边的口袋里掏出钥匙的。
显然,此刻的拉斯柯尔尼科夫是镇静的。镇静使他摸到了钥匙并且掏出了钥匙,可是紧接着他又立刻惊慌失措──
他刚拿钥匙去开五斗橱,一听见钥匙的哗啦一声,仿佛浑身起了一阵痉挛。他又想扔下一切东西逃跑。
陀思妥耶夫斯基让叙述在人物状态迅速转换中前行。惊弓之鸟般的拉斯柯尔尼科夫怎么都无法打开五斗橱,所有的钥匙在他手中都插不进锁孔。随即他又清醒似的将手上的鲜血擦在红锦缎上,并且认为鲜血擦在红锦缎上不显眼……
没有一个作家会像陀思妥耶夫斯基那样,如此折磨自己笔下的人物。拉斯柯尔尼科夫如同进入了地狱似的,他将应该是一生中逐渐拥有的所有感觉和判断,在顷刻之间全部反应出来。并且让它们混杂在一起,不断出现和不断消失,互相抵抗同时也互相拯救。
显然,陀思妥耶夫斯基并不满足拉斯柯尔尼科夫的自我折磨,他不时地让楼道里传来某些声响,一次次地去惊吓拉斯柯尔尼科夫,并且让老太婆同父异母的妹妹丽扎韦塔突然出现在屋子里,逼迫他第二次杀人。就是那个已经死去的高利贷老太婆,陀思妥耶夫斯基也让她阴魂不散──
他忽然觉得好像老太婆还活着,还会苏醒过来。他就撇下钥匙和五斗橱,跑回到尸体跟前,拿起斧头,又向着老太婆举起来……
拉斯柯尔尼科夫在掠夺钱财的欲望和自我惩罚的惊恐里度日如年,十多页漫长的叙述终于过去了,他总算回到了自己的屋子。此刻叙述也从第一章过渡到了第二章──
他这样躺了很久。有时他仿佛睡醒了,于是发觉夜早已来临,但他并不想起床。末了他发觉,天已经明亮起来。
叙述似乎进入了片刻的宁静,可是陀思妥耶夫斯基对拉斯柯尔尼科夫的折磨还在继续。首先让他发烧了,让他打着可怕的寒战,“连牙齿都格格打战,浑身哆嗦”,然后让他发现昨天回家时没有扣住门闩,睡觉也没有脱衣服,而且还戴着帽子。拉斯柯尔尼科夫重新进入了疯狂,“他向窗前扑去”──他把自己的衣服反复检查了三次,确定没有留下任何痕迹,他才放心地躺下来,一躺下就说起了梦话,可是不到五分钟,他立刻醒过来,“发狂似的向自己那件夏季外套扑过去”──他想起了一个重要的罪证还没有消除。随后他又获得了暂时的安宁,没多久他又疯狂地跳起来,他想到口袋里可能有血迹……
在第二章开始的整整两页叙述里,陀思妥耶夫斯基继续着前面十多页的工作,让拉斯柯尔尼科夫的身体继续动荡不安,让他的内心继续兵荒马乱,而且这才只是刚刚开始,接下去还有五百多页更为漫长的痛苦生涯,拉斯柯尔尼科夫受尽折磨,直到尾声的来临。
与陀思妥耶夫斯基相比,威廉·福克纳对沃许·琼斯杀人后的所有描叙就显得十分温和了。这样的比较甚至会使人忘记福克纳叙述上粗犷的风格,在陀思妥耶夫斯基面前,威廉·福克纳竟然像起了一位温文尔雅的绅士,不再是那个桀骜不驯的乡巴佬。
谁都无法在叙述的疯狂上与陀思妥耶夫斯基相提并论,不仅仅是威廉·福克纳。当拉斯柯尔尼科夫杀人后,陀思妥耶夫斯基有力量拿出二十页的篇幅来表达他当时惊心动魄的状态。陀思妥耶夫斯基的叙述是如此直截了当,毫不回避地去精心刻画有可能出现的所有个人行为和所有环境反应。其他作家在这种时候都会去借助技巧之力,寻求间接的方式表达出来。陀思妥耶夫斯基却放弃了对技巧的选择,他的叙述像是一头义无反顾的黑熊那样笨拙地勇往直前。
最后一个例子应该属于司汤达。这位比陀思妥耶夫斯基年长38岁的作家倒是一位绅士,而且是法语培养出来的绅士。可以这么说,在19世纪浩若烟海的文学里,与陀思妥耶夫斯基最为接近的作家可能是司汤达,尽管两人之间的风格相去甚远,就像宫殿和监狱一样,然而欧洲的历史经常将宫殿和监狱安置在同一幢建筑之中,陀思妥耶夫斯基和司汤达也被欧洲的文学安置到了一起,形成古怪的对称。
我指的是阅读带来的反应,陀思妥耶夫斯基和司汤达的叙述似乎总是被叙述中某个人物的内心所笼罩,而且笼罩了叙述中的全部篇幅。拉斯柯尔尼科夫笼罩了《罪与罚》,于连·索黑尔笼罩了《红与黑》。如果不是仔细地去考察他们叙述中所使用的零件,以及这些零件组合起来的方式,仅仅凭借阅读的印象,我们或许会以为《罪与罚》和《红与黑》都是巨幅的心理描写。确实,陀思妥耶夫斯基和司汤达都无与伦比地表达出了拉斯柯尔尼科夫和于连·索黑尔内心的全部历史,然而他们叙述的方式恰恰不是心理描写。
司汤达的叙述里没有疯狂,但是他拥有了长时间的激动。司汤达具有与陀思妥耶夫斯基类似的能力,当他把一个人物推到某个激动无比的位置时,他能够让人物稳稳坐住,将激动的状态不断延长,而且始终饱满。
第二天当他看见德·瑞那夫人的时候,他的目光奇怪得很,他望着她,仿佛她是个仇敌,他正要上前和她决斗交锋。
正是在这样的描叙里,于连·索黑尔和德·瑞那夫人令人不安的浪漫史拉开了帷幕。在此之前,于连·索黑尔已经向德·瑞那夫人连连发出了情书,于连·索黑尔的情书其实就是折磨,以一个仆人谦卑的姿态去折磨高贵的德·瑞那夫人,让她焦虑万分。当德·瑞那夫人瞒着自己的丈夫,鼓起勇气送给于连·索黑尔几个金路易,并且明确告诉他:“用不着把这件事告诉我的丈夫。”面对德·瑞那夫人艰难地表现出来的友好,于连·索黑尔回答她的是傲慢和愤懑:“夫人,我出身低微,可是我绝不卑鄙。”他以不同凡响的正直告诉夫人,他不应该向德·瑞那先生隐瞒任何薪金方面的事情。从而使夫人“面色惨白,周身发抖”,毫无疑问,这是于连·索黑尔所有情书中最为出色的一封。
因此当那个乡村一夜来临时,这个才华横溢的阴谋家发动了突然袭击。他选择了晚上十点钟,对时间深思熟虑的选择是他对自己勇气的考验,并且让另一位贵族夫人德薇在场,这是他对自己勇气的确认。他的手在桌下伸了过去,抓住了德·瑞那夫人的手。
司汤达有事可做了,他的叙述将两个人推向了极端,一个蓄谋已久,一个猝不及防。只有德薇夫人置身事外,这个在书中微不足道的人物,在此刻却成为了叙述的关键。这时候,司汤达显示出了比陀思妥耶夫斯基更多的对技巧的关注,他对于德薇夫人的现场安排,使叙述之弦最大限度地绷紧了,让叙述在火山爆发般的激情和充满力量的掩盖所联结的脆弱里前进。如果没有德薇夫人的在场,那么于连·索黑尔和德·瑞那夫人紧握的手就不会如此不安了。司汤达如同描写一场战争似的描写男女之爱,德薇夫人又给这场战争涂上了惊恐的颜色。
在德·瑞那夫人努力缩回自己的手的抵抗结束之后,于连·索黑尔承受住了可能会失败的打击,他终于得到了那只“冷得像冰霜一样”的手。
他的心浸润在幸福里。并不是他爱着德·瑞那夫人,而是一个可怕的苦难结束了。
司汤达像所有伟大的作家那样,这时候关心的不是人物的心理,而是人物的全部。他让于连·索黑尔强迫自己说话,为了不让德薇夫人觉察,于连·索黑尔强迫自己声音洪亮有力;而德·瑞那夫人的声音,“恰恰相反,泄露出来情感的激动,忸怩不安”,使德薇夫人以为她病了,提议回到屋子里去,并且再次提议。德·瑞那夫人只好起身,可是于连·索黑尔“把这只手握得更紧了”,德·瑞那夫人只好重新坐下,声音“半死不活”地说园中新鲜的空气对她有益。
这一句话巩固了于连的幸福……他高谈阔论,忘记了装假做作。
司汤达的叙述仍然继续着,于连·索黑尔开始害怕德薇夫人会离开,因为接下去他没有准备如何与德·瑞那夫人单独相处。“至于德·瑞那夫人,她的手搁在于连手里,她什么也没有想,她听天由命,就这样活下去。”
我想,我举例的任务应该结束了。老实说,我没有想到我的写作会出现这样的长度,几乎是我准备写下的两倍。我知道原因在什么地方,我在重温威廉·福克纳、陀思妥耶夫斯基和司汤达的某些篇章时,他们叙述上无与伦比的丰富紧紧抓住了我,让我时常忘记自己正在进行中的使命,因为我的使命仅仅是为了指出他们叙述里的某一方面,而他们给予我的远比我想要得到的多。他们就像于连·索黑尔有力的手,而我的写作则是德·瑞那夫人被控制的手,只能“听天由命”。这就是叙述的力量,无论是表达一个感受,还是说出一个思考,写作者都是在被选择,而不是选择。
在这里,我想表达的是一个在我心中盘踞了十二年之久的认识,那就是心理描写的不可靠。尤其是当人物面临突如其来的幸福和意想不到的困境时,对人物的任何心理分析都会局限人物真实的内心,因为内心在丰富的时候是无法表达的。当心理描写不能在内心最为丰富的时候出来滔滔不绝地发言,它在内心清闲时的言论其实已经不重要了。
这似乎是叙述史上最大的难题,我个人的写作曾经被它困扰了很久,是威廉·福克纳解放了我,当人物最需要内心表达的时候,我学会了如何让人物的心脏停止跳动,同时让他们的眼睛睁开,让他们的耳朵矗起,让他们的身体活跃起来,我知道了这时候人物的状态比什么都重要,因为只有它才真正具有了表达丰富内心的能力。
这是十二年前的事了,后来我又在欧内斯特·海明威和罗伯-格里耶那里看到了这样的风格如何完整起来。有一段时间,我曾经以为这是20世纪文学特有的品质。可是陀思妥耶夫斯基和司汤达,这两个与内心最为亲密的作家破坏了我这样的想法。现在我相信这应该是我们无限文学中共有的品质。
其实,早在五百多年前,蒙田就已经警告我们,他说:“……探测内心深处,检查是哪些弹簧引起的反弹;但这是一件高深莫测的工作,我希望尝试的人愈少愈好。”
一九九八年八月二十六日
宁静悠长的下午时光- 李娟
========================
宁静悠长的下午时光- [[李娟]]
------
斯马胡力放羊去了。但到了下午,羊全都回来了,他还没回来。扎克拜妈妈说:“斯马胡力在大石头上睡觉呢!”说着趴到花毡上,蜷着身子,做出睡得香甜的模样,嘴里还呼呼有声。
我一想,也是。斯马胡力这家伙走哪儿都能睡着,下雨刮风统统不是问题。更何况今天这样难得的温暖天气。
至于回来的羊,很诧异自己为什么没人管。它们三三两两聚在门口山坡下,有的舔空盐槽,有的咩咩唤宝宝。
过了一会儿,小羊群从北边的山头渐渐出现。两支羊群遥遥打过照面后,哄然奔跑起来,在北面山谷里惊喜急切地撞合在一起。
我们站在毡房后面看了一会儿这幕情景,回到房间里开始喝当天的第四遍茶。
要是上午或中午时分,大小羊是不被允许见面的,把它们重新分开非常麻烦。若不分开吧,剩下大半天足够它们拖家带口、无牵无挂地走好远好远,直到走丢为止。
在满山谷回荡的咩叫声中,我们掰开坚硬的干馕泡进茶水里,食物的香气低低地弥漫在碗边。天窗盖住了一半,室内光线很暗,阳光从毡房顶的破洞里投进来八个明亮的大星星。当羊群安静下来时,布谷鸟的声音重新回荡在森林中。
茶还没喝到一半,大家都昏昏欲睡了。我草草收拾了餐具,转身一看,妈妈和卡西已经东倒西歪躺在花毡上了。外面又开始刮风,森林急切地呼啸着。我们躺在毡房中,毡房像是在大海的风浪中孤独航行的小船。
每一天都有一场缓慢无边的下午时光,于是这样的每一天都漫长得似乎经历了好几个白天,这样的一天里似乎能做完好几天的事情。
每一天,一过了中午,连时间也恍恍惚惚地迟钝下来了,连时间也同我们一起躺倒进入睡眠之中。一过了中午,时间哗地大大敞开,时间内部的精确刻度拉伸、变形。时间不清晰了,我们的意识也不清晰了。我们倒在花毡上,梦见紧贴着脸庞的那朵绣花,梦见很久之前它是怎样在一双手的抚摸下,一针一线缓慢绽放……在梦中随着那针脚无边无际走了很远很远。
睡啊睡啊,甚至感觉睡了很多很多年。但终于醒来时,看到毡房里的八个大星星的位置较之睡前只偏移了一点点。于是困意的潮水又漫过头顶,翻个身继续睡。
每一天的下午时光都容纳了一场漫长的睡眠,因此每一天的下午时光都如洪水泛滥,四面漫延。
夏牧场真好。牛羊每天都能吃得饱饱的,心满意足。羊羔长得飞快,嗖嗖嗖几下就大了。原先入栏后,还空着大半个羊圈,现在整个羊圈都挤得满满当当。在挤得最紧的角落里,羊羔们想转个身都很难。
羊羔进了圈,安静下来,一起扭头转向你,定定地看你。它们每张面孔都极为相似,那情景颇为震撼。大约是牙痒痒了,羊圈里总有一些小朋友喜欢啃旁边小朋友脑袋上尖尖细细的小角,啃得津津有味。很多羊羔开始长羊角了。
骆驼的驼峰也纷纷耸了起来,神气活现。然而还是有几峰骆驼不争气,吃到肚皮滚圆,看上去快撑爆了,驼峰仍瘪瘪软软,东倒西歪。
牛的产奶量也大增,每天煮完牛奶后,妈妈都会给我们一人匀半碗喝。
有一头牛失踪了两天,大家谁有空了,就出去找一找,却都不是很担心的样子。果然,第三天牛自己回来了,还带回来一个小宝宝。原来,它的时间到了,独自生产去了。
初生的牛宝宝瘦骨嶙峋,笨不啦唧的,瞪着大眼睛什么也搞不明白。晚上天冷,我们把它牵进毡房过夜,谁知它一进来就开始尿。尿啊尿啊,像漏水的大水箱一样,一直尿了好几分钟才打住。我们又赶紧把它赶出去。
总之,一年之中最丰盈从容的季节来临了。
我们每天下午睡醒后,会在毡房里八个明亮的大星星中间翻翻照片,互相摆弄头发,唱唱歌,提起许多往事。没有客人,山谷中的小路深深地静止着。牛羊还在几座山外欣喜地吃草。马儿好几天没回家了,它们越走越远,却又惦记着家里鲜美的盐粒,此刻正犹豫着要不要回一趟家。上午脱脂的牛奶中午就分离出干酪素颗粒,装满湿干酪素的布口袋挂在草地中央的木架子上。在它完全沥干水分形成结结实实的一整块之前,我们都无事可做。
卡西掏出一张纸给我。接来一看,上面写满汉文,像是从某本杂志上撕下来的一页。我顿感亲切,觉得已经很久都没见过汉字了。上面印的是一篇学生作文,标题格局相当广阔:“回首过去,展望未来”。细细读来,果然内容空泛,措辞激烈而毫无用处。尽管如此,我还是认真地读了一遍又一遍。再看作者,名叫玛依努儿·阿依恒,是青格里中学的一名高一学生。青格里在阿勒泰地区最东边,是个更为遥远的地方。
这一页纸我保存了很久很久,一想起来就会掏出来读一读。每次都渴望能读出什么新花样来。早起若碰到雨天,生炉子非常困难,但无论如何都舍不得拿这张纸引火。
这个叫玛依努儿的孩子陪伴我度过了多少寂寞漫长的下午时光啊。那些由汉字排列成的句子,原先的用意已经全面退潮,只剩得贝壳一样的字眼干干净净搁浅在沙滩上,笔画漂亮匀称。一句一句读下来,竟能滋生异样的希望似的。看着看着,翻个身就睡过去了。
一些独自睡醒的时刻,我悄悄起身推门出去,坐在门口面对整个空荡荡的山谷。很久以后,一个骑白马的女人抱着穿红衣的孩子,从南面河谷走来。等她完全走过后,好像山谷里的一切都被她带走了。
门口草丛寂静。但蹲在那儿看久了,会发现寂静的草丛其实是热闹的森林。小虫子们你来我往,忙忙碌碌,彼此间连打个招呼的工夫都没有。
有一只长腿长脚、长了翅膀的大蚂蚁,逮了一条粗粗大大的肉虫子,比它自己的身子还要胖好几倍呢。这么大,如何运输?若一般的小蚂蚁的话,会赶紧回家呼朋唤友,然后团结起来,合力咬住往回拖。可这只蚂蚁很聪明,它把肉虫子翻来覆去研究了一会儿,最后骑在虫子上,把虫子抱在怀里,用两条前腿紧紧搂住,用剩下四条长长的后腿大踏步前进。腿多了就是方便啊。
我蹲在那儿瞅了半天。看着它在空地上翻山涉水,迂回辗转,兜了一圈又一圈,绕了足足七八米的弯路,才总算将虫子拖进一米外自己的洞口里。看来个子太矮就没法做到高瞻远瞩,再聪明也没办法。
看着看着,又有些迷糊了。一屁股坐在草地上躺了下去,本来只想在阳光下晒一晒肚子的,谁知一躺倒,睡意就像满满一盆水当头泼了下来,浑身透湿。于是眼睛一闭,顺势舒舒服服陷进睡眠的大沙发里了。在草地上睡着了,也不知挡住了多少小虫子回家的路,不知有多少迷路的小家伙在我身体上四处流浪。
还有些睡醒后的时光,我忍不住一个人走进东面那个狭窄的溪谷。一路上会分别经过幽密的落叶松林,明亮耀眼的白桦林,然后是尽头的杨树林。杨树光洁的树干上睁满了大大的美丽的眼睛。
林木深深,林间小径沿着溪流缓缓向高处延伸,并不时地左右倾斜。路面上满是牲畜打滑的蹄印。这是一条暮归的牲畜走出的路,一路上只有牛羊欣赏四面美景。
有一株掌状叶片的植物,簇拥在水边潮湿的沼泽里,叶子又大又美,色泽浅淡娇嫩,团团裹围着中间抽出的一支箭秆。然而寒温带的北方山地森林植被里多是细碎深绿的叶片,因此当这种妖娆温柔的巨叶植物突然出现在眼前时,感觉说不出的古怪,像是因我的突然出现而躲闪不及的精灵就地幻化的形象。穿过整条溪谷,却只看到这么一株,再也没有第二株了。不知当初是怎样的一粒神奇种子被遗忘到了这里。
一路上还有七八个巨大的蚂蚁窝,像神秘的坟墓静静耸立在林间阴影中。最大的有一米多高,直径两三米,上面布满成千上万个洞口,壮观极了。蚂蚁们进进出出,忙得一塌糊涂。蚂蚁窝附近交叉遍布着蚂蚁的道路,路面不到一指宽,被蚂蚁们走得光滑干净,细晰地分布在铺满针叶和林间苔藓的空地上,蛛网一般密织交错。走在路上的蚂蚁匆忙沉默,像走在黑夜之中。
溪谷中潮湿阴暗,沼泽遍布。唯一的那一小片桦树林却干爽明亮,林间空地上堆积着又厚又软的陈年落叶,纯然一色,锦光灿灿。与周遭广阔的蓝绿色深暗丛林相比,桦树林是轻盈温暖的。
杨树林则整齐青翠,像一群孪生少女骄傲地站在一起。杨树林也不大,但林间没有一棵杂树,地上也铺满厚厚的落叶,不生一株杂草,使得这方天地从整个世界中干干净净剥裂开来,连外面世界的一丝微风也没法吹进来似的。
有一次途中走着走着,面前突然晃过一个极微小的绿点。本不太在意,正想径直走过去的,不知怎么的心里一动,停下了脚步。定睛一看,才发现竟是一根长长的蛛丝悬住了一条小小的青色肉虫!蛛丝细若无物,从上方高高的树梢一直悬到眼前。凑近细看,这条虫子还挺漂亮的,晶莹剔透,像一颗薄荷味的水晶糖柱被吮得细细小小,一触即折。再仔细观察,发现它和其他肉虫子还长得不一样,并非浑身长满了脚,只有头部和腰部后侧长着四对足。此时它的身子美妙地弓起,左右缓慢扭动,像是脱身不得,又像是兀自享受着这一小团寂静世界中的宽和与自在。我便小心地绕过它走了。
山谷虽然幽密,却并不深远,没一会儿就走到头了。尽头的溪水边横着一大块平平坦坦的石头。石头后是一小段急陡的上坡路。爬到高处,便陡然进入了另一个世界,面前一大片宽敞明亮的坡地。在天气晴暖的日子里,我每次走到此处都会躺在石头上小睡一觉。当然也没法睡深,只是静静躺在那里,闭着眼睛倾听远远近近的各种声响,然后渐渐有所遗忘地进入恍惚破碎的梦境之中。然而哪怕已经进入了梦中,仍能感觉到自己正躺在那块山谷尽头的石头上。那时巨大沉重的风正从高处经过森林,它仔细地辨认着森林里的每一棵树和树上的每一只鸟巢。
总是想象着斯马胡力独自在外放羊的情景……他赶着羊群翻过一座座大山,重重美景让人疲惫,寂寞也让人心生倦意。于是他系了马,在森林边的大石头上躺倒睡过去了。羊越走越远,他的睡眠却越陷越深。哎,睡吧。心里还有什么挂碍呢?什么样的力量都无法像“寂静”那样,轻易地就能让人完全停止下来。斯马胡力睡着的时候,山野的另一个角落,我们的家,我们的毡房,也承载着我们沉重的睡眠,在归来羊群的环绕下,稳稳当当搁放在群山之间,像扎了根的种子一般坚定。而在毡房中沉入梦境的我们呢,却左飘右荡,随着孤舟漂流在无边无际的海面。
女人、金钱和美
作者:[[星新一]]
-----
“我爱你。”
青年悄声地说。然而姑娘却支吾地答道:
“别、别开这样的玩笑!”
“不,不是开玩笑。我真爱你,从心里爱你。”
“可是我们才只见过五次面呀。”
“难道有谁规定了必须在见过几次面之后才能倾吐爱情吗?从第一次取到你的那天起,我就深深地爱上了你。只是不容易挨到了第五次见面的今天,我实在忍耐不住了。”
“我一点也不相信。”
“那,怎样才能使你相信呢?”
青年的语气是那么火热。随后他们随便闲聊了起来。
青年二十八岁左右。可以称作男人气概和潇洒风姿揉和十分匀称的美男子,而且衣冠楚楚。姑娘的年龄在二十五左右,然而……
如果说她也算作美人儿,那么她早就上电视了。然而并非如此,无论怎样放宽美人的定义来做善意的描画,她都难以称得上是美人儿。
姑娘长得很胖,从前胸到腰部,几乎是一般粗。不仅如此,那双脚也很肥大。又长着一对金鱼眼,塌塌鼻,厚嘴唇,两唇间还排列着参差不齐的龋齿。衣着也不引人注目不论穿上何等样式的服装,也毫不出色。
姑娘对此深有自知之明。所以对青年的甜言蜜语不肯轻易接受,不是没有道理的。
“适可而止吧!这类话最好还是说给别的姑娘听吧。”
“我只喜欢你,现在说起其它的姑娘,我一点都不动心。”
“喂,想笑别人,也要有个分寸,我可要生气了。”姑娘真的表现出一副就要生气的样子。她不生气时,眼神就够丑陋的了,若是一瞪眼,就更够人一瞧的。青年避开她那目光,继续说道:“随你发火好了!这样,你就会更理解我的诚意。我是真心地爱着你呀。”
“讨厌,请您不要再说了。你的话叫人悲伤。”
姑娘的声音突然变得呜咽,并且低下了头,而青年却乘机向她靠得更近了些。
“请不要悲伤!你一哭,我还怎么向您求婚呢?”
“什么?”
一听到结婚二字,姑娘不由地打了个寒噤,顿时面露难色、茫然不知所措。青年又接着说;
“请您一定跟我结婚!”
“可是,漂亮的姑娘多得很,和象我这样的女子……”
“您文静、腼腆,正是这种性格吸引了我。而其它的女人,个个都自命不凡、清高孤傲。”
他不停地、反复地说着,他每重复一句,姑娘那人为地设起的防线便被冲垮一道。她终于有些相信了。
“能得到家您这样的男子的求婚,真好象在梦境里似的。”
“别怀疑了,您不是在做梦,不信,我掐你一下。”
青年越来越亲昵,姑娘笑了。
“哎呀,别掐,痛死我了。”
“您答应了?”
姑娘答应了,谈话又前进了一步。
“如果可能,我们应当有一套自己的房子,哪怕是小一点的。我从不乱花钱,一直在积蓄。现在我有一笔相当可观的款子,够买到一所房子的吧!”
“我也攒了些钱。如果不够,请用我的。不要见外。”
“这样的话,我们就可以买到一套更好的房子了。买到了用你的名字登记。”
“随您便好了。”
“那么,我就取出存款来计算一下,也让您看看,我没撒谎。”
俩人的谈话又有所进展,谈得也更具体了。他们约定好了下次见面的日子之后,便分手了。
青年即非出于好奇,亦非神经不正常,而是非常郑重其事。这就是他的事业。干事业不郑重其事是不行的。简而言之,骗婚,成了他的恶习。
社会上干这种事的并非绝无仅有。但是,多数人都将骗婚得来的钱财大手大脚地挥霍掉。而这位青年却采取积蓄的办法,把骗到手的钱全都存进了银行。
不言而喻,资本愈多,成功率愈高。把钞票往眼前一摞,就不愁接触不到女人……如果进一步说:“要是钱再多些嘛……”姑娘就会打消疑虑,完全信任地把钱全部拿出来。这样一来,“营业成绩”的确可观。钱一到手,就远走高飞。再把钱存进银行,存款额直线上升,这便是他的生活的乐趣。
尽管如此,意位青隼可也不是一个守财权。正日为做梦一般向往看有朝一日用这笔款,他才热衷于这一行道。他的最终目的就是要同一个漂亮的女子结婚。
多次的失恋,使青年深深地体务到:漂亮的女子通常是不愿跟没钱的男人结婚的。其它一切都很顺利,而每当他坦率地说出自己没钱时,对方便和地分手。面对如此冷酷的现实地灵机一动,便开始热衷干存款,其实,这本也无可厚非。
但是,他并没有什么特殊的才能,仅有的“王牌”就是那张标致英俊的脸,他便充分地利用了这个优点。他之所以向这位似乎有钱、可又长了一副可怕面孔的姑娘求爱,就因为是盼着将来达到上述目标。而且一旦热衷于“营业”,便在对方的脸上挂一副漂亮的模样,他似乎在和一位漂亮姑娘在谈话。因此,他才表演得十分逼真。
三天后,按约定时间,青年来到了姑娘的住所。这是一间没有装饰的、朴素的房屋,也没有少女闺房所特有的那神华丽。青年暗暗地思付:她是对婚姻绝望了、一心在存款吧!然而禁止同情,他又开始营业了。他打开背包,把成叠的钞票摞在桌子上。
“瞧,这就是我费尽心机积攒下来的钱。”
姑娘也准备好了钞票,虽然比青年的少些。但要比他所想的多。她似乎有些不好意思,把钱摞在一起。
“我也把钱取出来了。哦,这样把钱摞在一起,就分不开了。”
“难道这不好吗?反正都是我们的钱。”
青年为事态一如即往进行得顺利而感到满意。看来姑娘真的相信了。现在更需要镇静,等把钱归整一下就可以溜了。这样做,姑娘受损,不免可怜。可是我呢,由于没钱就不能跟漂亮的姑娘结婚,不也同样可怜吗?
这时,姑娘似乎突然想起了什么,天真地说道;“这钱有多高,量一量好吗?”
“好的,量量吧!”
“尺子放到哪里去了?本是放在你身后那儿,也许放到杂志下面了?”
“在哪儿?在哪儿?”
青年不慌不忙地寻找。因为他知道垂成之际,更需要沉着和冷静。兴奋、不安是失败之母。然而当他找到尺子、抬起头时,眼前竟然发生了意想不到的事情。
桌子上的钱没了,姑娘也不见了。他试探着叫道:“你藏到哪儿去了?别开玩笑了,快出来吧!尺子找到了。”
没有人回答。他又连叫几声,仍然没有回音。他强压着心中的怒火,打开壁橱一看,什么也没有,更别说姑娘了。他又翻开了放在房间角落里的旧便衣箱,同样空空如也。
这样找来找去,不仅什么也没找到,反倒耽误了时间。当他慌忙跑到外面时,哪里还有姑娘的影子。
他向公寓管理人一打听,才知道姑娘已办完搬迁手续走了。虽然留下了移迁处的地址,也肯定是假的。然而青年还是抱着一线希望去找了一下,却根本就没有那么个街名。
“残酷、太残酷了。”
青年的悲伤如何是可想而知的。为了将来的幸福,忍辱负重积攒下来的钱全都被拿走了。他怎能不伤心呢?
此后,他神情沮丧,天天都在混日子。而且,再也没有重整旗鼓“营业”的劲头了。要说他现在的工作嘛,只是整日耽于酒杯之中了。
但是,这种状态并没有持续多久。一个月后,他又结识了一位漂亮的姑娘。细高挑儿,炯炯有神的大眼睛,樱桃小口,皓齿生辉,真是一位他理想中的女子,象他梦境里的一样。而且这女子还特别主动、亲切地和他搭话。可是他却十分干脆地答道:“我是不配同你交往的,因为我没有钱。”
“哎哟,男子汉还说这样的话,太可笑了。最宝贵的不是钱,而是纯真的爱情!”
如此温柔、亲昵的话语,深深触动了青年,使他多少改变了以往的人生观。看来,美人儿之中也有心地善良的人啊!然而他还是固执地说:“可是没有钱就不能使你幸福。”
“不要再提钱了吧……”
那以后又经过了几番波折,俩人终于结合在一起了。他们的婚礼虽然谈不上豪华,但却是俩人幸福生活的开端。青年找到了一个正式而平凡的工作。现在梦幻已经成为现实,他再也没有必要去从事那种不体面的“营业”了。
然而,他无论如何也想象不出他的人生会发生今天这样的变化。所以,他不由地向妻子问道:
“你为什么要跟我结婚呢?”
“因为我爱你,你是个好人!”
他的妻子只是这样回答道,便不再做声。难道会是她拿了桌子上的钱、隐身而去,不借任何代价地做了最高级的整容?
-----
译自《新潮文库》1983年版星新一著《陌国》——
女身-翁菀君
========================
女身-[[翁菀君]]
【第十五届花踪文学奖马华散文组评审奖】女身(文 / 翁菀君) - 副刊 | 文艺春秋 | 星洲网 Sin Chew Daily
-----
别人说好事不成双,自从你来过以后,我就信了。
那个草木始发的春天,我在前往中国昆明的路上,意外探见内裤一朵鲜红血迹。以为是月经早到,没想却是你来了。然而盼了多年的事,那么突如其来又怎能轻易想起?于是我在这樱花与雨水交忽飘落的四月天照常上路。这时节离我生日仍有数周,却也是祭拜祖坟的清明,仿佛一个生死交会的临界。而你选择了在这样的时候第一次住到我的身体里。
经过无数次人工受孕的失败,我又如何能猜测你竟在我丢掉所有助孕药物后,突然来给我惊喜。
血来一天就停了。我半信半疑,猜想也许是你,但重复的失败教我不要轻易期待。我不敢相信这具熟悉的女身原来也有自然孕育的能力。纵使医学报告显示它健康无碍,理应早就能哺育一个孩子。但十年光阴转眼逝去,我的子宫仍然是一片原始的荒芜。
我依然记得那一次又一次的痛,从身体延伸至脑袋,再漫延至我的心脏。那样的感觉,有别于记忆中对痛的认知。同为细针刺入皮肤,高中生物课用以验血型的针尖再可怕,也不过片刻恐惧。人工受孕的过程中,我一针一针地注射身体,如斯痛感带着期待和希望,因此能隐忍、能承受。肚皮上留下的触觉与瘀伤,经由一连串的医学程序慢慢催化,既孵出了希望的体积。在长期吃药、注射、取卵、置入胚胎和居家等消息的过程中,“希望” 这颗种子日益壮大,让我以为只要承受过痛,必能等到一个生命在体内成长。但命运的本质是不相等,也从不顺应人心。于是,每当医生宣告失败,那痛的感觉才从肚皮迅速窜升成一枚无限延长的尾音,漫延直到我头皮发麻、眼泪直流。
我一边经历失败,一边断定此身某些机能必定早已故障,我注定是个无法怀孕的女人。所以,你在我毫无预警之下来临,实在让人措手不及。我曾听说,父母是孩子到这世界来的桥樑,他们的诞生是一种选择,选择通过你的身体来成就自己的生命。而你既选择了我,我便有责任保护你。但是,在我确认了你的那一个晚上,我做了个梦。梦中老人惋惜地说:“你为何不要这个孩子?”
醒来,下腹隐隐作痛,未几仿佛有人以重拳捶入腹中,你就变成了血块流出我的身体,染了一床殷红。
那是第一次。你匆匆到来又匆匆离去。但我并不特别伤心,只是有点惋惜。至少我开始相信,我的子宫是健全的温床且拥有孕育生命的可能。但身体所承受的痛会让人清醒,我因此开始思索,能否自然怀孕于一个女人而言是否那么重要?
自从科技发达重组了自然定律,只需要一颗精子、一粒卵子和一根试管,就能化被动为主动,让生命的繁衍摆脱顺应天意的困境。然而,作为一个活生生的人,我始终无法抑制那种与生俱来的,对自然伦理的顺从与崇拜。当我发现我的身体拥有承载另一个生命的可能,我于是充满喜悦。精子与卵子在我体内自然结合,最终虽未能幻化成鲜活的血肉之躯,却让女孩一夜成了母亲。奇妙的心理变化仿佛不断演进的生物科学,在我体内开出一朵温润的花,不为人知地修改了我尖锐的棱角,使我以更为圆融的形式去感受生命、体会他人,进而遏制我在人与人的相待之间变成一只魔鬼。
记得某个农历新年期间,她们在我入门前已迫切追问:有消息吗?抑或在新年聚会大伙儿面前,不知是故意还是随口,说谁又梦见亡故的祖辈来探问你们何时为人父母?他们问我,我问谁?我敏感而记仇,这恨已记在心头。后来决心避年,数年不让自己落入困窘的境地,才渐渐自怨恨中抽离。然而,同为女人,她们一生受困于传统束缚却懵然不知,也是一种可悲。但我既然会生气,说明我多少也和她们一样在意我子宫的破败,在意我迟迟未能当上母亲的憾恨。
直到你第二次到来,我开始明白,只有宽恕与原谅才能让人走出阴翳,去寻找辽阔的天空。
你再次来临,已是两年后的春天。同样是新旧交替的时节,我在中国的旅程中绕着西湖骑脚踏车。经过上次的教训,两年来我不敢停药,怕万一你再次回到我的子宫,我必须以完备之身来迎接你。依然是在生日之前,我看过内裤那朵红花,确定果然是你如约而至。于是,安胎针、黄体素、叶酸、抗多囊卵巢症的药一份不少,我尽我所能养着你。我在扫瞄荧幕中看你从一个黑影一天天长成一个小人儿,仔细指认那是你的手、你的脚,你高挺的鼻子、额头。你是我女儿。
在你长大到四个月的时候,你却还是走了。那么出奇不意地离开,仿佛一种报复。
我曾怀疑到底是过去我负过你,抑或我今生欠过别人,才必须经历生出死胎的痛楚。你既以我为通道,两次却都来了又走,这是要渡化我,还是惩罚我?
阵痛十八小时,羊水破开。我张开双腿、用力鼓腹,让医生用他的手指深深进入,要把你和胎盘拉扯出来。身心俱痛原来能让恐惧凌驾悲伤和羞耻。我看着自己挣扎的身体和紧握床杆的拳头,几乎觉得此身不再属于我。我的身体变得陌生、诡异,痛的同时却又仿佛事不关己。
多年来不断经历人工受孕,每一次都让我离自己的身体远一些,让怀孕这件事离爱远一些。这个过程把一个人简化成一具纯粹的肉体,把爱简化为医学程序。就像我用力想把你挤出我的子宫,彼时就忘了流泪、忘了体会我对你的不舍和爱,我只想赶快回到寻常生活的正轨,重新夺回身体的主权。
直到我的子宫彻底干净了,我才觉察一阵虚空。我抚摸平坦的腹部,胯下留着你离开时的记忆触觉,犹如突然记起了什么而不由自主地抽搐起来。这一哭,就整整哭了一个小月子。
眼泪止不住,只好去走路疗伤。买了到台湾的机票,我住在同学永和的公寓,每天步行越过永福桥、汀州路,以为那样不断向前迈步就能找到旧时的自己。年轻时倔强鲁莽,却因未曾发现命运残酷而无知地快乐着。我抬腿就走,每一步如宣泄也如赌气。用身体受的伤,就用身体来疗愈吧。我竭尽所能地走,只为用双脚的印记替代悲伤和身体的记忆,想借此重拾勇敢与纯粹。
我白天走路,晚上等同学下班回来,四个女生就窝在客厅聊至夜深。
若你有机会到这世上来,这几个女生必定是你学习的榜样。她们是我见过最宽厚温柔的人,她们善待他人,更懂得善待自己。她们之中,贤和月也是情侣。记得初到台大上课,某天贤毫无避讳地和我说起她的女朋友。她说,我觉得你能接受。然而她诚实地面对自己并认清所爱,那是她生而为人的权力,又怎么需要他人来接受?但就像她们包容我人生中一些异于常人的决定一样,我们从来都站在平等的位置交往,并以多个盘膝讨论的夜晚参与彼此的经历。
人与人之间的宽待与生命的辽阔,也许大多源于自己受过的伤。因为隐忍过痛与屈辱,在伤口慢慢结痂并长出新肉之后,才学会看清事情的本质,尝试理解这人生中任何的决定皆有理由。我和这三个女生相识十年,我每每受了伤便到台北去找她们。每一次,甫踏入那所公寓的大门,未及开口,眼泪已夺眶而出。流泪不是因为伤心,而是知道自己的困顿将被看见、被理解。在我们的交谈之中,从来谁都不轻易把自己的价值观硬硬套在别人身上。
我一直想要个孩子,让你如挚友姐妹般与我为伴,并成为我逃离世事的借口,让我可以理直气壮地做个胸无大志的人。然而,贤和月的处境却让我明白,孩子的到来并非为了成就一名母亲,而是成就他自己。我看着她们为了自我确认而不断与家人沟通,进而纠结、冲突,甚至怨恨,我突然明白作为一名孩子或父母原来都不简单。从青春走至成熟,我这对女性朋友必定也经历过挣扎与自我认同的艰辛过程,然后才找到一种合适的姿态,以小数生存于这个属于众数的世界。
印象中,月从来不穿裙子,听说她大学时曾以布裹胸,以为这样就能抑制乳房继续胀大,阻止自己长成一个名副其实的女人。在接受自己的爱恋之前,要接受的原来是与生俱来的身体。这时我仿佛有所领会,你两次都来不成,或许因为我始终未能真正接受自己。在我想给予你一副身躯之前,漫长的受孕过程却使我混淆了何谓身又何谓心?抑或,到底何谓爱?
倘若生命的形成被简化为一次体外受精的程序,这让我开始思索精子和卵子来自谁又有何关系?在人工受孕机械化的过程中,伦理和爱已渐渐变得支离破碎。为了拥有爱的结晶,爱被切割成冰冷的步骤与数字。初时是凌晨爬起床计算身体的基础温度,接着遵照医生的嘱咐在排卵期交配,后来关心注射后能排出几颗成熟卵子而又将得到几个健康的胚胎?人工受孕在乎的是身体的配合,至于人心的感受,那对成功毫无帮助。也许世事必有舍才有得,要解决身体的问题又岂能兼顾心理的变化?正如我看过的医生们,专业却总是冷漠。
有时我不禁怀疑,在我遇过的医生眼中,病人是否拥有名字?抑或那些各别的女性身躯所展现的不过是一个又一个的受孕契机,甚或不过是一次金钱的交易?这些年来,我从深信我的医生有办法使我成为母亲到每次会诊皆心存质疑、微微愤懑,我不知道能否再千方百计地把你带来这世上。我想你知道,我已身心俱累。
于是在那最后一次的怀孕中,当我刚刚知悉你的性别,你便无了心跳,我想或许我该放过我的身体并与自己和解。
为了慎重地与你告别,我带着我的身体展开了一段步行之旅。我用双脚走过山川河畔,仿佛渴望用身体的行动来释放受困的灵魂。旅途中,我若遇见小女孩也总会想起你,我屈指数算你要是活着,如今也快满两岁。我后来决定给你取个名字。光如──倒过来念则宛若光照,曾映亮我部分的生命。你虽然没有具体的血肉之躯,却始终存在于我心,并让我里里外外地照见自己,重新思索我这副女性的身躯及其命运。
欧洲山上一次意外的身体经验,冥冥中似乎给了我答案。
记得我独自走入那个男女共用的水疗空间,仿佛不慎进入天体浴场,每个人一丝不挂、彻底坦露。我挣扎许久,始终过不了自己那关而穿上了运动内衣裤,在一群赤裸的身躯中当一个异类。当我在水疗池中因找不到开关而径自窘急时,一名中年妇女光着身子前来帮忙。她丰满而松弛的乳房在我眼前微微摇晃,身上的皮肤隐然嵌着年华的皱折。我红着脸望向她的眼睛道谢,只感觉到一种与情色无关的善意,仿佛盘古开天以来世界万物本该如此坦荡无色。
妇女离开后,白雾渐渐散开,我遥望远方露出的明晰山景,像获得了谁的允许般径自退下衣物。我赤裸着身体,犹如退下了此身所依附的意识形态与文化重袱、悲伤与怨恨,顷刻我只感到轻盈。我站在池水中央,任池面上身体的倒影于波光中重复地被撕碎又拼贴起来,我仿佛是碎片,也是完整。
1、[[艾丽丝·门罗]](Alice Munro) ,加拿大短篇女王。获2009年布克国际奖。
2、[[裘帕·拉希莉]](Jhumpa Lahiri),印裔美女。曾凭短篇小说集《疾病解说者》获2000年普利策小说奖。
3、[[约翰·契弗]](John Cheever),美国小说家。号称“美国郊外契诃夫”,《约翰·弗短篇小说集》获得了1978年全国图书奖和普利策小说奖
4、[[理查德·耶茨]](Richard Yates),美国小说家。《十一种孤独》被誉为“纽约的《都柏林人》”
5、[[维·苏·奈保尔]](Vidiadhar Surajprasad Naipaul)。英国移民作家。2001年获诺贝尔奖,短篇有《米格尔街》
6、[[内丁·戈迪默]](Nadine Gordimer),南非女作家。短篇和长篇都有不凡建树。91年诺贝奖得主。
7、[[弗兰纳里·奥康纳]](Mary Flannery O'Connor ),美国南方女作家的代表。擅长短篇。有短篇小说集《好人难寻》。
8、[[伊塔洛·卡尔维诺]](Italo Calvino),意大利小说家。王小波的偶像之一。有《宇宙奇趣》和《意大利童话集》
9、[[赫塔·穆勒]](Herta Müller),德国女作家。09年诺奖得主,有短篇集《低地》
10、[[胡利奥·科塔萨尔]](Julio Cortázar),阿根廷作家。短篇有《万火归一》、《南方高速公路》等
11、[[杰罗姆·大卫·塞林格]](Jerome David Salinger)。美国作家,不用介绍了,《九故事》
12、[[伯纳德·马拉默德]](Bernard Malamud)。美国作家,短篇小说集有《魔桶》和《头等白痴》等
13、[[胡安·鲁尔福]](Juan Rulfo),墨西哥作家。拉美文学爆炸超新星,短篇集《燃烧的原野》
14、[[阿摩斯·奥兹]](Amos Oz),以色列作家。短篇集好像是《胡狼嗥叫的地方》
15、[[雷蒙德·卡佛(]]RAMOND CARVER) ,美国作家。近年来很火,村上的偶像。个人不太感冒。《当我们谈论爱情时我们在谈论什么》、《大教堂》等
16、[[阿尔贝托·莫拉维亚]](Alberto Moravia),意大利作家。好像没什么翻译。《罗马故事》、《瘟疫集》
17、[[莉迪亚·戴维斯]](Lydia Davis),美国人,2013年布克国际奖得主,此后开始受人关注。作品基本都是短篇,最短可以一句话,最长也不超过三五页。去年国内出版了她的前半部小说集《几乎没有记忆》,今年后半部《困扰种种》刚刚出炉,两本加在一起共计近200个短篇,都很精彩。
18、[[塞林格]]:九故事——技术流最高级别了
卡波蒂:乖戾又敏感。是有天赋的作家。新版好像译文一般,我都是读的旧版《在蒂法尼进早餐》《卡波特小说集》
马拉默德:我很喜欢马拉默德的长篇《店员》,那种小细节,温吞下的激情。他的短篇也不错,看过他的自选集以及魔桶,大陆出译林版。
辛格:再来一个美国犹太文学代表,这些人都是写小说的高手,但是犹太文学有着相似的基调,就是那种悲悯,文化的疏离。
冯内古特:黑色幽默的代表,科幻的和非科幻的
舍伍德·安德森:《畸人志》or《小城畸人》
很热的但是不是特别喜欢的:卡弗、弗兰纳里·奥康纳
ps:安·贝蒂,库佛,凯瑟琳·安·波特...
茨威格:这个不用多说了
布鲁诺·舒尔茨:鳄鱼街
迪诺·布扎蒂:意大利的,他的书还挺多的。意大利文学有很多可爱的短篇小说家,还有一位短篇女作家马莱尔巴,我也喜欢。
克莱尔·吉根:爱尔兰的女作家,《南极》
威廉•福克纳(William Faulkner),公认是意识流集大成者。现代派小说家代表人物。虽然以长篇小说闻名于世,但其短篇小说写的非常精彩!尤其是《献给艾米莉的玫瑰》(A Rose for Emily),个人最爱。
爱尔兰作家科尔姆 托宾,短篇小说集有《空荡荡的家》和《母与子》
达芙妮·杜穆里埃。《蝴蝶梦》《浮生梦》作者。短篇小说集《此刻不要回头》
泡茶馆-汪曾祺
========================
泡茶馆-[[汪曾祺]]
-------
“泡茶馆”是联大学生特有的语言。本地原来似无此说法,本地人只说“坐茶馆”。“泡”是北京话。其含义很难准确地解释清楚。勉强解释,只能说是持续长久地沉浸其中,像泡泡菜似的泡在里面。“泡磨菇”、“穷泡”,都有长久的意思。北京的学生把北京的“泡”字带到了昆明,和现实生活结合起来,便创造出一个新的语汇。“泡茶馆”,即长时间地在茶馆里坐着。本地的“坐茶馆”也含有时间较长的意思。到茶馆里去,首先是坐,其次才是喝茶(云南叫吃茶)。不过联大的学生在茶馆里坐的时间往往比本地人长,长得多,故谓之“泡”。
有一个姓陆的同学,是一怪人,曾经骑自行车旅行半个中国。这人真是一个泡茶馆的冠军。他有一个时期,整天在一家熟识的茶馆里泡着。他的盥洗用具就放在这家茶馆里。一起来就到茶馆里去洗脸刷牙,然后坐下来,泡一碗茶,吃两个烧饼,看书。一直到中午,起身出去吃午饭。吃了饭,又是一碗茶,直到吃晚饭。晚饭后,又是一碗,直到街上灯火阑珊,才挟着一本很厚的书回宿舍睡觉。
昆明的茶馆共分几类,我不知道。大别起来,只能分为两类,一类是大茶馆,一类是小茶馆。
正义路原先有一家很大的茶馆,楼上楼下,有几十张桌子。都是荸荠紫漆的八仙桌,很鲜亮。因为在热闹地区,坐客常满,人声嘈杂。所有的柱子上都贴着一张很醒目的字条:“莫谈国事”。时常进来一个看相的术士,一手捧一个六寸来高的硬纸片,上书该术士的大名(只能叫做大名,因为往往不带姓,不能叫“姓名”;又不能叫“法名”、“艺名”,因为他并未出家,也不唱戏),一只手捏着一根纸媒子,在茶桌间绕来绕去,嘴里念说着“送看手相不要钱!”“送看手相不要钱”——他手里这根媒子即是看手相时用来指示手纹的。
这种大茶馆有时唱围鼓。围鼓即由演员或票友清唱。我很喜欢“围鼓”这个词。唱围鼓的演员、票友好像是不取报酬的。只是一群有同好的闲人聚拢来唱着玩。但茶馆却可借来招揽顾客,所以茶馆里便于闹市张贴告条:“某月日围鼓”。到这样的茶馆里来一边听围鼓,一边吃茶,也就叫做“吃围鼓茶”。“围鼓”这个词大概是从四川来的,但昆明的围鼓似多唱滇剧。我在昆明七年,对滇剧始终没有入门。只记得不知什么戏里有一句唱词“孤王头上长青苔”。孤王的头上如何会长青苔呢?这个设想实在是奇绝,因此一听就永不能忘。
我要说的不是那种“大茶馆”。这类大茶馆我很少涉足,而且有些大茶馆,包括正义路那家兴隆鼎盛的大茶馆,后来大都陆续停闭了。我所说的是联大附近的茶馆。
从西南联大新校舍出来,有两条街,凤翥街和文林街,都不长。这两条街上至少有不下十家茶馆。
从联大新校舍,往东,折向南,进一座砖砌的小牌楼式的街门,便是凤翥街。街夹右手第一家便是一家茶馆。这是一家小茶馆,只有三张茶桌,而且大小不等,形状不一的茶具也是比较粗糙的,随意画了几笔蓝花的盖碗。除了卖茶,檐下挂着大串大串的草鞋和地瓜(即湖南人所谓的凉薯),这也是卖的。张罗茶座的是一个女人。这女人长得很强壮,皮色也颇白净。她生了好些孩子。身边常有两个孩子围着她转,手里还抱着一个。她经常敞着怀,一边奶着那个早该断奶的孩子,一边为客人冲茶。她的丈夫,比她大得多,状如猿猴,而目光锐利如鹰。他什么事情也不管,但是每天下午却捧了一个大碗喝牛奶。这个男人是一头种畜。这情况使我们颇为不解。这个白皙强壮的妇人,只凭一天卖几碗茶,卖一点草鞋、地瓜,怎么能喂饱了这么多张嘴,还能供应一个懒惰的丈夫每天喝牛奶呢?怪事!中国的妇女似乎有一种天授的惊人的耐力,多大的负担也压不垮。
由这家往前走几步,斜对面,曾经开过一家专门招徕大学生的新式茶馆。这家茶馆的桌椅都是新打的,涂了黑漆。堂倌系着白围裙。卖茶用细白瓷壶,不用盖碗(昆明茶馆卖茶一般都用盖碗)。除了清茶,还卖沱茶、香片、龙井。本地茶客从门外过,伸头看看这茶馆的局面,再看看里面坐得满满的大学生,就会挪步另走一家了。这家茶馆没有什么值得一记的事,而且开了不久就关了。联大学生至今还记得这家茶馆是因为隔壁有一家卖花生米的。这家似乎没有男人,站柜卖货是姑嫂两人,都还年轻,成天涂脂抹粉。尤其是那个小姑子,见人走过,辄作媚笑。联大学生叫她花生西施。这西施卖花生米是看人行事的。好看的来买,就给得多。难看的给得少。因此我们每次买花生米都推选一个挺拔英俊的“小生”去。
再往前几步,路东,是一个绍兴人开的茶馆。这位绍兴老板不知怎么会跑到昆明来,又不知为什么在这条小小的凤翥街上来开一爿茶馆。他至今乡音未改。大概他有一种独在异乡为异客的情绪,所以对待从外地来的联大学生异常亲热。他这茶馆里除了卖清茶,还卖一点芙蓉糕、萨其玛、月饼、桃酥,都装在一个玻璃匣子里。我们有时觉得肚子里有点缺空而又不到吃饭的时候,便到他这里一边喝茶一边吃两块点心。有一个善于吹口琴的姓王的同学经常在绍兴人茶馆喝茶。他喝茶,可以欠帐。不但喝茶可以欠帐,我们有时想看电影而没有钱,就由这位口琴专家出面向绍兴老板借一点。绍兴老板每次都是欣然地打开钱柜,拿出我们需要的数目。我们于是欢欣鼓舞,兴高采烈,迈开大步,直奔南屏电影院。
再往前,走过十来家店铺,便是凤翥街口,路东路西各有一家茶馆。
路东一家较小,很干净,茶桌不多。掌柜的是个瘦瘦的男人,有几个孩子。掌柜的事情多,为客人冲茶续水,大都由一个十三四岁的大儿子担任,我们称他这个儿子为“主任儿子”。街西那家又脏又乱,地面坑洼不平,一地的烟头、火柴棍、瓜子皮。茶桌也是七大八小,摇摇晃晃,但是生意却特别好。从早到晚,人坐得满满的。也许是因为风水好。这家茶馆正在凤翥街和龙翔街交接处,门面一边对着凤翥街,一边对着龙翔街,坐在茶馆两条街上的热闹都看得见。到这家吃茶的全部是本地人,本街的闲人、赶马的“马锅头”、卖柴的、卖菜的。他们都抽叶子烟。要了茶以后,便从怀里掏出一个烟盒——圆形,皮制的,外面涂着一层黑漆,打开来,揭开覆盖着的菜叶,拿出剪好的金堂叶子,一枝一枝地卷起来。茶馆的墙壁上张贴、涂抹得乱七八糟。但我却于西墙上发现了一首诗,一首真正的诗:
```
记得旧时好,
跟随爹爹去吃茶。
门前磨螺壳,
巷口弄泥沙。
```
是用墨笔题写在墙上的。这使我大为惊异了。这是什么人写的呢?
每天下午,有一个盲人到这家茶馆来说唱。他打着扬琴,说唱着。照现在的说法,这应是一种曲艺,但这种曲艺该叫什么名称,我一直没有打听着。我问过“主任儿子”,他说是“唱扬琴的”,我想不是。他唱的是什么?我有一次特意站下来听了一会,是:
```
…………
良田美地卖了,
高楼大厦拆了,
娇妻美妾跑了,
狐皮袍子当了……
```
我想了想,哦,这是一首劝戒鸦片的歌,他这唱的是鸦片烟之为害。这是什么时候传下来的呢?说不定是林则徐时代某一忧国之士的作品。但是这个盲人只管唱他的,茶客们似乎都没有在听,他们仍然在说话,各人想自己的心事。到了天黑,这个盲人背着扬琴,点着马杆,踽踽地走回家去。我常常想:他今天能吃饱么?
进大西门,是文林街,挨着城门口就是一家茶馆。这是一家最无趣味的茶馆。茶馆墙上的镜框里装的是美国电影明星的照片,蓓蒂·黛维丝、奥丽薇·德·哈茀兰、克拉克·盖博、泰伦宝华……除了卖茶,还卖咖啡、可可。这家的特点是:进进出出的除了穿西服和麂皮夹克的比较有钱的男同学外,还有把头发卷成一根一根香肠似的女同学。有时到了星期六,还开舞会。茶馆的门关了,从里面传出《蓝色的多瑙河》和《风流寡妇》舞曲,里面正在“嘣嚓嚓”。
和这家斜对着的一家,跟这家截然不同。这家茶馆除卖茶,还卖煎血肠。这种血肠是牦牛肠子灌的,煎起来一街都闻见一种极其强烈的气味,说不清是异香还是奇臭。这种西藏食品,那些把头发卷成香肠一样的女同学是绝对不敢问津的。
由这两家茶馆,往东,不远几步,面南,便可折向钱局街。街上有一家老式的茶馆,楼上楼下,茶座不少。说这家茶馆是“老式”的,是因为茶馆备有烟筒,可以租用。一段青竹,旁安一个粗如小指半尺长的竹管,一头装一个带爪的莲蓬嘴,这便是“烟筒”。在莲蓬嘴里装了烟丝,点以纸媒,把整个嘴埋在筒口内,尽力猛吸,筒内的水咚咚作响,浓烟便直灌肺腑,顿时觉得浑身通泰。吸烟筒要有点功夫,不会吸的吸不出烟来。茶馆的烟筒比家用的粗得多,高齐桌面,吸完就靠在桌腿边,吸时尤需底气充足。这家茶馆门前,有一个小摊,卖酸角(不知什么树上结的,形状有点像皂荚,极酸,入口使人攒眉)、拐枣(也是树上结的,应该算是果子,状如鸡爪,一疙瘩一疙瘩的,有的地方即叫做鸡脚爪,味道很怪,像红糖,又有点像甘草)和泡梨(糖梨泡在盐水里,梨味本是酸甜的,昆明人却偏于盐水内泡而食之。泡梨仍有梨香,而梨肉极脆嫩)。过了春节则有人于门前卖葛根。葛根是药,我过去只在中药铺见过,切成四方的棋子块儿,是已经经过加工的了。原物是什么样子,我是在昆明才见到的。这种东西可以当零食来吃,我也是在昆明才知道。一截葛根,粗如手臂,横放在一块板上,外包一块湿布。给很少的钱,卖葛根的便操起有点像北京切涮羊肉的肉片用的那种薄刃长刀,切下薄薄的几片给你。雪白的。嚼起来有点像干瓤的生白薯片,而有极重的药味。据说葛根能清火。联大的同学大概很少人吃过葛根。我是什么奇奇怪怪的东西都要买一点尝一尝的。
大学二年级那一年,我和两个外文系的同学经常一早就坐到这家茶馆靠窗的一张桌边,各自看自己的书,有时整整坐一上午,彼此不交语。我这时才开始写作,我的最初几篇小说,即是在这家茶馆里写的。茶馆离翠湖很近,从翠湖吹来的风里,时时带有水浮莲的气味。
回到文林街。文林街中,正对府甬道,后来新开了一家茶馆。这家茶馆的特点一是卖茶用玻璃杯,不用盖碗,也不用壶。不卖清茶,卖绿茶和红茶。红茶色如玫瑰,绿茶苦如猪胆。第二是茶桌较少,且覆有玻璃桌面。在这样桌子上打桥牌实在是再适合不过了,因此到这家茶馆来喝茶的,大都是来打桥牌的,这茶馆实在是一个桥牌俱乐部。联大打桥牌之风很盛。有一个姓马的同学每天到这里打桥牌。解放后,我才知道他是老地下党员,昆明学生运动的领导人之一。学生运动搞得那样热火朝天,他每天都只是很闲在,很热衷地在打桥牌,谁也看不出他和学生运动有什么关系。
文林街的东头,有一家茶馆,是一个广东人开的,字号就叫“广发茶社”——昆明的茶馆我记得字号的只有这一家,原因之一,是我后来住在民强巷,离广发很近,经常到这家去。原因之二是——经常聚在这家茶馆里的,有几个助教、研究生和高年级的学生。这些人多多少少有一点玩世不恭。那时联大同学常组织什么学会,我们对这些俨乎其然的学会微存嘲讽之意。有一天,广发的茶友之一说:“咱们这也是一个学会,——广发学会!”这本是一句茶余的笑话。不料广发的茶友之一,解放后,在一次运动中被整得不可开交,胡乱交待问题,说他曾参加过“广发学会”。这就惹下了麻烦。几次有人,专程到北京来外调“广发学会”问题。被调查的人心里想笑,又笑不出来,因为来外调的政工人员态度非常严肃。广发茶馆代卖广东点心。所谓广东点心,其实只是包了不同味道的甜馅的小小的酥饼,面上却一律贴了几片香菜叶子,这大概是这一家饼师的特有的手艺。我在别处吃过广东点心,就没有见过面上贴有香菜叶子的——至少不是每一块都贴。
或问:泡茶馆对联大学生有些什么影响?答曰:第一,可以养其浩然之气。联大的学生自然也是贤愚不等,但多数是比较正派的。那是一个污浊而混乱的时代,学生生活又穷困得近乎潦倒,但是很多人却能自许清高,鄙视庸俗,并能保持绿意葱茏的幽默感,用来对付恶浊和穷困,并不颓丧灰心,这跟泡茶馆是有些关系的。第二,茶馆出人才。联大学生上茶馆,并不是穷泡,除了瞎聊,大部分时间都是用来读书的。联大图书馆座位不多,宿舍里没有桌凳,看书多半在茶馆里。联大同学上茶馆很少不挟着一本乃至几本书的。不少人的论文、读书报告,都是在茶馆写的。有一年一位姓石的讲师的《哲学概论》期终考试,我就是把考卷拿到茶馆里去答好了再交上去的。联大八年,出了很多人才。研究联大校史,搞“人才学”,不能不了解了解联大附近的茶馆。第三,泡茶馆可以接触社会。我对各种各样的人、各种各样的生活都发生兴趣,都想了解了解,跟泡茶馆有一定关系。如果我现在还算一个写小说的人,那么我这个小说家是在昆明的茶馆里泡出来的。
一九八四年五月十三日
在这个土地
坑洼的路面才是正常
市政府才不会过来开罚单
他曾向市政府的推特投诉
谎称有小孩要越过马路而需设置路墩
或要求交警逮捕违法改造单车的路障
出示医院的精神衰弱的诊断书
若不是市政府开罚单的效率如此神速
他还以为他留言的是假账号,背后的管理员不是狗便是只是出现在报章上叮咛你多喝温水的搞笑艺人
七重外壳-王晋康
========================
七重外壳-[[王晋康]]
-----
光怪陆离的高科技世界为我们套上了一层又一层的外壳,最终人类会不会迷失自我?
1999年8月23日,小甘和姐夫乘坐中航波音747客机到达旧金山。姐夫斯托恩·吴,中文名字吴中,买的是单程机票,给甘又明买的是往返机票。小甘打算在7天后返回北京,去上他的大学三年级课程。
在旧金山他们没出机场,直接坐上联合航空公司去休斯敦的麦道飞机。抵达这个航天城时已是万家灯火了。高速公路上的车灯组成流动跳荡、十分明亮的光网,城市的灯光照彻夜空,把这座新兴城市映成一个透明的巨大星团。飞机开始下降,耳朵里嗡嗡作响,那个巨大的亮星团开始分解出异彩纷呈的霓虹灯光。直到这时,甘又明才相信自己真的到了美国。
下了飞机,他们乘坐地下有轨电车来到一个停车场,吴中找到自己那辆银灰色的汽车,用遥控打开车门。10分钟后他们已来到高速公路上。吴中扳动一个开关后便松开方向盘,从随身皮包里取出一个小巧的办公机,开始同基地联络。
“我在为你办理进基地的手续。”他简短地说。
甘又明惊讶地看着这辆无人驾驶的汽车在高速公路上疾驶。路上,除了对面的汽车刷刷地掠过去之外,百里路面见不到一个行人和警察。在这道机械洪流中,甘又明真正体会到为什么“汽车人”在美国的动画片中大行其道。他们的汽车对前边汽车追尾太紧时,甘又明免不了心中忐忑,斯托恩·吴猜到他的心思,从办公机上抬起头,平淡地说:
“放心,它有最先进的防撞功能。”
甘问:“它是卫星导航?我见资料上介绍过,说这种自动驾驶方式是下个世纪的技术。”
姐夫微微一笑:“国内的资料比国外的现状常常有5~10年的滞后期,我带你去的B基地又是美国国内最超前的。你在那儿可以看到许多科幻性的技术,它可以说是21世纪科技社会的一个预展。比如这辆汽车,你知道它是什么动力吗?”
不是姐夫问,他还真没想这个问题。他看看汽车,外形和汽油车没什么区别,车速表上的指针已超过了150英里,汽车行驶得异常平稳。他猜道:
“从外形看当然不是太阳能汽车,是高能电池的电动汽车?氢氧电池的电动汽车?高容量储氢金属的氢动力汽车?在我的印象中,这些都是公元2000年以后的未来汽车。”
吴中摇摇头:“都不是。这辆汽车是惯性能驱动,它装备有12个像普通汽车汽缸大小的飞轮,秒速30万转。所以储能量很大,充电一次可以行驶1000公里。飞轮悬浮在一个超导体形成的巨大磁场里,基本没有摩擦损失,使惯性能在受控状态下逐步转化为电能。这是代替汽油车的多种方案之一,但不一定是最好的方案。”
甘又明半是哂笑地说:“也许,B基地里还有能给植物授粉的微型昆虫机器?有克隆人?有光孤立子通信?有激光驱动的宇宙飞船?”
斯托恩·吴扭头看他一眼,平静地说:“没错,除了‘克隆人’囿于伦理问题没有付诸实施外,其他的都已投入实用或小规模试用。”
之后他就不再说话,在他的办公机上专心致志地办公。甘又明不由得暗暗打量他的侧影。他的相貌平常,身体比较单薄,大脑门,有如女性般的纤纤十指在电脑键盘上翻飞自如,时而停下来在屏幕上迅速浏览一下从基地发来的数据。
如鱼得水。甘又明脑子里老是重复这四个字。这个文弱青年在科技社会里真是如鱼得水,无怪乎姐姐是那样爱他、崇拜他。这种人正是21世纪的弄潮儿,在女性心目中,他们已代替了那些筋腱突出的西部牛仔英雄。
7天前,34岁的斯托恩·吴突然飞回国内,第3天就同31岁的星子姑娘举行了婚礼。婚礼上,新娘满脸的幸福,新郎却像机器人一样冷静。刚从老家返校的甘又明借着三分酒气,讥讽地对姐夫说:
“谢天谢地,我姐姐苦苦等了8年,你总算从电脑网络里走出来了。你知道吗?很长时间我认为你已经非物质化了,或者只剩下一个脑袋泡在美国某个实验室的营养液中。”
斯托恩·吴平静宽厚地笑笑,同小舅哥碰碰杯,一饮而尽。甘又明对他一直非常不满,甚至可以说是抱有敌意。8年来,至少是从他考进清华大学计算机系的3年来,他极少在姐姐那儿听到吴先生的消息,最多不过是在电脑网络中发来几句问候。甘又明曾刻薄地对姐姐说:
“你的未婚夫究竟是吴先生,还是一个ZHW@07.BX.US的网络地址?别傻了,那个人如果不是早已变心,就是变成了没有性程序的机器人。”
姐姐总是笑笑说:“他太忙,现在是美国B基地虚拟实验室的负责人。”不过弟弟的话并非没有一点影响。那天晚上,她发了一封电子邮件,委婉地说想要一张他的近影。第二天一张表情漠然的照片传回来了——仍是在电脑网络中!为此,甘又明一口咬定这张照片是虚拟的:“美国的警务科学家早把面孔合成软件发展得尽善尽美,你想叫这张照片变胖变瘦,是哭是笑,或者想从10岁的照片变化出34岁的模样,都只用半秒钟的时间!你想,他为什么不寄一张普通相片呢,这里面一定有鬼!”
即使婚礼过后,甘又明仍然敌意难消。客人走后,他悻悻地对姐姐说:
“他为什么不接你去美国?这位上了世界名人录、名列美国20位最杰出青年科学家的吴先生养不活你吗?姐姐,我担心他在那边有了十七八个情人,甚至已成了家。我知道你是个高智商的学者,但高智商的女人在对待爱情上常常低能。用不用我再提醒一次?那个国度既是高科技的伊甸园,又是一个世界末日般的罪恶渊薮。”
星子已听惯了弟弟的刻薄话,她笑着说:“你不是说他是没有性别的机器人吗?这种机器人是不需要情人的。”
“那他为什么不接你去美国?”
“他说这儿有他的根,有他童年的根,人生的根。他说,当他在光怪陆离的科技社会里迷失本性时,需要回来寻找信仰的支撑点,就像希腊神话英雄安泰需要地母的滋养。”
她在复述这些话时,脸上洋溢着圣洁的光辉。甘又明喊起来:
“姐姐呀,你真是天下最痴情又最愚蠢的女人!这都是言情小说中的道白,你怎么也能当真!”他看看表,9点40分,是中央7台的科技影视长廊节目时间,这个时间他是雷打不动的。他打开电视,嘟囔道:
“反正我把该说的都说了,到时你莫怪我。”
那晚的科技影视节目是“电脑鱼缸”——正是它促成了他的美国之行。“电脑鱼缸”是一种微型仿真系统,电脑中储存了几百种鱼类的基因,你只要任意挑选几种,按下确认钮,它们就开始在屏幕上从容遨游。每秒48帧画面,比电影快一倍,所以画面上看上去甚至比真鱼还逼真。不仅如此,这些鱼还会生长,会弱肉强食,会求婚决斗,会因鱼食的多寡而变肥变瘦。雌雄配对的机会完全是随机的,一旦某对夫妻结合,它们的后代就兼具父母的基因,因而兼具父母特有的形态习性。它们会根据环境条件产生变异。一句话,这个鱼缸完完全全是一个鱼类社会的缩影——但只是虚拟状态。
新婚夫妇来到客厅时,甘又明正在击节低赞:
“太奇妙了,太奇妙了!”每次看到类似的节目,他常有“浮一大白”的快感。这会儿他完全忘却了对姐夫的敌意,兴致勃勃地对姐夫说:
“很巧妙的构思。如果把节奏加快——这对于电脑来说是再容易不过了——是否可以在几分钟内预演鱼类几千万年的进化?还可以把主角换成人,来模拟人类社会的进化。比如说模拟第三次世界大战的进程?把所有的社会矛盾、各国军力、民族情绪、宗教冲突、各国领导人的心理素质等输进一个超级虚拟系统,推演出二三十种战争进程,我想它对军事统帅的决策一定大有裨益。”
斯托恩·吴看了他一眼,他发现这个清华大三学生的思路比较活跃,不免对这位小舅子产生了兴趣。他坐到甘的面前,简捷地说:
“你说得不错,这正是虚拟技术诸多用途之一。不过这个电脑鱼缸太小儿科了,我们早已超过它,远远超过它。”
甘又明好奇地问:“发展到什么程度?能否给我讲讲,如果不涉及贵国……”他有意把这两个字念重,“利益的话。”
吴中笑笑,接过妻子递过来的两杯咖啡,递给小舅子一杯。他略为思考后说:
“我想你已知道,在虚拟技术中,人可以‘进入’虚拟世界。”
“对,通过目镜和棘刺手套,人可以进入电脑鱼缸和鱼儿嬉戏。”
吴中摇摇头:“那都是20年前的旧古董了。我们现在使用的是一种被称为‘外壳’(SHELL)的中介物。通过它,人可以完全真实地融入虚拟世界。我们的技术甚至已发展到这种程度:某人进入虚拟系统之后,如果没有系统外的帮助就无法辨别出所处环境的真假。正像一个密闭飞船里的乘员,若没有系统外参照物就无法确认自己是否在运动。”
甘笑嘻嘻地说:“那个‘某人’是否服用了迷幻药?科克(Coke)?快克(Crack)?哈希什(Hashish)?”
斯托恩·吴看看他,心平气和地说:“没有。”
甘又明大笑起来:“那你就有点吹牛了!我想,一个神经健全、头脑清醒的人,肯定能从虚拟环境中找出破绽来!要不,是美国人普遍智力低下?也难怪,在美国,全民性的吸毒泛滥至少已延续了100年,难免引起智力退化。”
吴中冷冷地说:“说几句俏皮话是很容易的,不过献身科学的人一般已经摈弃了这种爱好。甘先生,你想试试向我的虚拟技术挑战?”
甘又明两眼发光,跃跃欲试地说:
“这可挠到我的痒处了!我天生喜欢这样的智力体操,从小至今,乐此不疲。不过,我恐怕暂时去不了美国吧。”
吴中笑笑,对妻子说:“我给他安排一次为期7天的短期访问,不耽误他回校上课。”
甘又明很快领教了姐夫的地位和能量。3天后,吴中告别新婚妻子匆匆返回美国时,甘又明也怀揣着一张往返机票、一份特别签证和1000元美金坐在特等舱里,享受着空姐的微笑和茶几上的新鲜水果。
一条公路沿着海滩穿行,再往前是广阔的滩涂地。这儿人烟稀少,雪亮的灯光刺破夜色,展现出一个茂密安静的绿色世界,自然的蛮荒和嵌入其中的现代化建筑相映成趣。天光甫亮,他们赶到一个营地。营地占地不大,在做工粗糙的铁栅栏中散布着十几座平房。虽然途中已经联系过,但警卫室声称没有收到对甘又明放行的命令。斯托恩·吴面色不豫,拿起内线电话,节奏很快地说了一通。甘又明的英语水平基本可以听懂他们的谈话。
吴说,我与贵国政府签了合同,我自然会恪守它,包括其中的保密条款。实际上,只要这次我回国7天而未泄密,你就不必担心了。从这几句话中,甘又明听出了他的傲气。
他又说,实际上这位中国青年是作为临时雇员来基地的。你知道我们一直在招募挑选那些最有天资的美国青年,让他们去寻找虚拟世界的漏洞,以求改进设计。成功者还要发给一万美元的奖金。这位甘先生也是一个很合适的人选,他思维灵活,天生是个怀疑派,而且是在一个完全不同的文化背景中长大。我们的技术只有经过不同文化背景的人士的检验,才是万无一失的。当然,甘先生没有经过例行的安全甄别,但我的话是否可以作为担保呢。
对方显然犹豫片刻,然后交谈了几句。吴中笑道:“谢谢,我记住你的这次人情。”
他把话筒递给警卫,警卫听完后殷勤地说:“头头说,对两位先生免除一切检查。我送你们过去。”
现在,在他们面前是一个巨大的圆形管道。吴中按动一个电钮,管道上一座密封门缓缓打开。他们走进一个圆筒状的车厢,车厢内相当豪华,摆着四部真皮转角沙发。吴中同仅有的两名乘客打了招呼,安顿甘又明坐下,打开酒柜门,问:
“喝点什么?威士忌、橙汁还是咖啡?”
“橙汁吧。”
吴中倒橙汁时,车厢非常平稳地启动了。甘又明只是在看到橙汁液面向后倾斜时,才察觉到车厢在加速。他从窗户向外望去,看到飞速后掠的绿树旷野。一群海鸟在窗外掠过,立即出现在后边的窗户中。但他敏锐地发现,所谓窗户只是一张液晶屏幕上的仿真画面。他笑着用手敲敲假窗户:
“也是虚拟的?”
吴中微笑着说:“你的观察力很敏锐。对,这种管道是全封闭的,是饱和蒸汽管道。车厢行进时,前方蒸汽迅速凝为水滴,车厢经过后又迅速气化,所以几乎没有空气阻力。车辆可以达到两马赫的高速;使用磁斥悬浮和驱动。相信在下一个世纪中叶,它将在很大程度上代替火车。”他笑道,“当然啦,因为是封闭环境,旅客容易感到压抑郁闷,所以我们搞了这些仿真窗户。”
磁悬浮车辆已达到最高速,正保持着这个速度无声地疾驶,窗外景物的后掠也越来越快。按方位和地图推算,这时头顶已经是浅海了。吴中严肃地说:
“还有10分钟时间。我想简单地介绍一下我们的虚拟技术,希望你不要过于轻敌。像你这样的青年志愿者我们已接待过上千人次,只有六个人挣到了自己的一万美元。此后我们堵住了所有的漏洞,再没人能挣到这笔奖金了。我很希望你能成为第七个成功者,但首先你要彻底清除你的轻敌思想。”
他略为沉吟,平缓地说:
“你要知道,一个智慧生物若处于封闭系统中,很难对自身所处环境作出客观的判断。比如当宇宙飞船达到光速时,时间速率就会降为零,但光速飞船内的乘员感觉不到这个变化,他们仍然认为自己是在正常地吃饭、谈话、睡眠、衰老。再比如,我们说宇宙在膨胀,也能用光线的红移来测出膨胀速率。但这种膨胀只是天体距离的膨胀,天体本身并未膨胀。如果所有天体连同观察者本身也在同步地膨胀,我们能拿什么不变的尺度来确认宇宙的膨胀?绝无可能。”
甘又明笑道:“我信服你的理论,但进入虚拟环境中的人并未完全封闭,至少他们的思维是在虚拟系统之外形成的,自然带着它的惯性。我完全能以这种惯性作为参照物来判断环境的真实性,就像刚才用水面的倾斜来判断车辆是否加速。”
斯托恩·吴凝眸看着他,良久才笑道:
“我没有看错你,你的思维确实非常明快,一下子抓到了关键。但请你相信,我们也不是笨蛋。我们已能把被试者的思维取出来,并即时性地反馈到虚拟环境中去。比如说,尽管我们的虚拟系统与全球信息网络相通,可以随时汲取几乎无限的信息,但它肯定不能囊括你的个人记忆:你母亲20年前的容貌啦,你孩提时住的房舍啦,童年时的游戏啦,你对某位女同学的隐秘爱情啦,等等。但是,”他强调道,“凡是你在自己的记忆库中能提取到的东西,立即会天衣无缝地织进虚拟环境中,所以你仍然没有一个可供辨别的基准。”
甘又明微笑不言,对自己的智力仍然充满信心。吴中也不再赘言,简捷地说:
“我的话已经完了,你记着,我们将让你在虚拟世界中跳进跳出,反复进行。何时你确认自己已回到真实世界中,就向我发一个信号。如果你的判断是正确的,你就会怀揣一万美元回国。”他又加了一句,“不要轻敌,小伙子。呶,已经到站了,下车吧。”
他们在地下甬道里走了一段路,碰到的工作人员都尊敬地向吴中致意,这使甘又明又一次掂出了姐夫在这儿的分量。他们来到一座空旷的大厅,四周是天蓝色的墙壁和屋顶,浑然一体,大厅中央有两把测试椅。这幢大厅不算豪华,但建筑做工十分精致,每一处墙角,每一寸地板,都像象牙雕刻一样光滑严密,毫无瑕疵。吴中拿上一个遥控器,带甘又明来到大厅中间,说:
“先让你对虚拟世界有一个感性认识。让你看看哪种环境呢?”他略为思考,说,“你先看看我们的电脑鱼缸吧。”
他按动电键,大厅中瞬时间充满清澈的海水,波光潋滟,珊瑚礁壁立千尺,有的成伞状,有的成蘑菇状。一只1米长的蛤蜊垂直嵌在珊瑚里,半露的身体犹如彩色的丝绒。还有彩色的螯虾、五条手臂的星鱼、漂亮的石斑鱼。突然前边冒出一只巨大的八足章鱼,它的小眼睛阴森地盯着前边,行动诡秘地缓缓爬过来。甘又明本能地蜷起身子,但章鱼熟视无睹,缓缓从他的身体中穿过,消失在幽蓝的深海中。甘又明喘口气,笑问:
“激光全息仿真技术?确实可以乱真。”
吴中点点头,按一下快进,眼前又立刻变成深海海底景色。火山口冒着浓烟,就像地狱中的烟囱。两米长的蠕虫在海水里轻轻摇动着,管端血红色的羽状触手缓慢地开合。熔岩上铺着一层细菌,犹如白色的地毯。一只奇形怪状的细菌蟹贪婪地一路吃过去,有时还去啃食蠕虫的肉质触手。这是加拉帕戈斯群岛海底依靠硫化氢为生的太古生物群。甘又明看呆了,虽然他明知这是个虚拟世界,但似乎能感受到那深海海水的阴冷和重压。
忽然幻觉消失了,在一刹那间消失得干干净净。甘又明一时跳不出视觉的惯性,呆愣愣地立在那儿。斯托恩·吴淡淡地说:
“这只是虚拟技术的开场锣鼓。下面我要为你套上所谓的外壳,使你与虚拟环境融为一体。跟我走。”
他们走进大厅旁的一间屋子。甘又明第一眼就看到一个光脑袋的女性人体模型,几个工作人员正在它周围忙着。看见他们进来,那个人体模型竟然扭过头来——原来是一个真人!
甘又明傻望着这个脑门锃亮的裸体姑娘,解嘲地说:
“我已经进了虚拟世界?这种景象我只在青年的绮梦中见过。现在这个一丝不挂又毫不羞涩的漂亮姑娘到底是真是假?”
斯托恩·吴微笑着没有接腔,别人听不懂他的中国话独白。几个工作人员开始小心翼翼地为那个姑娘套上“外壳”,那是一件色泽纯白、很薄很柔的连体服。她把双腿蹬上后,工作人员小心地展平外壳,使上面的神经传感乳头与她的身体完全贴合。吴中低声解释,这些乳头将把虚拟信号传到相应的感觉神经,比如你“踩”上火炭时,脚底神经就送去烧灼感的信号。外壳已套到肩部,只有头盔还未戴上,它比较笨重,与黑色的目镜相连。姑娘在套上头盔前微笑道:
“我叫琼,琼·比斯特。很高兴做你的向导。”
甘又明疑问地看看吴,吴中点点头:
“对,这是你在虚拟世界里的向导,心理学和逻辑学博士,会三国语言,包括汉语。需要了解什么信息尽管问她。但她是完全超脱的,绝不会帮助你做出判断。现在请你脱光衣服,剃光头发。”
一个自动理发机无声地移过来,几秒钟内把他变成脑门锃亮的和尚,同时把发茬吸走。工作人员为他穿上那件洁白的衣服。这件衣服又薄又柔,弹性极好,穿在身上几乎变成了自己的皮肤。两人来到大厅,对面坐在两把椅子上。听见送话器中斯托恩·吴用英语说:
“虚拟系统即将启动,请你瞪大眼睛寻找它的漏洞吧。你想从哪儿开始?是海洋,太空,还是台风眼中?我们都可以为你办到。”
甘又明稍稍想一会儿,说:“还是从海水中开始吧,既然这一切都是由那个电脑鱼缸所引发。而且,我没有告诉你,我是北京高校百米自由泳纪录保持者。”
斯托恩·吴在屏幕中笑笑:“在虚拟世界里不会游泳并不是一个问题,电脑很容易为主人公加上令人信服的校正。不过,就按你的意见办吧。现在我要按下电钮了。”
甘又明在一刹那间被抛入水中。他看见自己和那位琼姑娘都穿着潜水衣,身后背着两个小小的黄色氧气瓶。他用力浮上水面,透过面罩远眺,海面十分广阔,只有后方隐约可见一线海岸。海浪轻轻地推揉着他,透过潜水服,能感到海水的浮力和温暖。他在水中作了几个滚翻,他的前庭器官感觉纤毛依旧精确地给出重力变化的方向。他知道这些都是假象,他身上穿的是白色的“SHELL”而不是黑色的潜水服,他是坐在空旷的大厅里而不是在水中。但由那件“外壳”传给他的视觉、听觉和触觉效果太逼真了,实在太逼真了,使你没办法不相信。
他取下头盔——他真的感觉到把头盔取下了,能呼吸到海面上略带咸味的空气,感到清凉的微风。琼从他旁边冒出来,甩着水珠,他喊道:
“琼!这儿是什么地方?”他笑着有意强调,“或者说,这是模拟的什么地方?”
琼也取下头盔,抖抖长发。长发如瀑布般散落,发出耀眼的金黄,这和他记忆中的光脑袋姑娘形成强烈的反差。他随口问道:
“这是你的真实形象么?”
琼奇怪地问:“你说什么?”
“你在剃光脑袋进入虚拟世界之前,就是这个模样吗?”
琼笑笑,只回答了他的第一个问题:
“我想这儿就在我们基地上方。这儿是阿查法拉亚湾附近海面,离墨西哥不远。近年来这儿贩毒活动很猖獗。”
不远处海面上有一艘快艇,上面没有人——按照虚拟系统的逻辑,这当然是他们带来的。他忽然看见南边海面上出现一个三角形的背鳍,划破水面迅速逼近,他惊慌地喊道:
“鲨鱼!”
琼挺直身子看看,笑道:“不要慌,这是海豚。”
他们戴上面罩潜入水中,果然看到十几只海豚。它们的皮肤是鸽灰色的,十分光滑,嘴里有整齐的白牙,呼哧呼哧地喘息着,喷水孔一张一合。它们排着队向西北方向游去,很快掠过两人的身边。他们甚至能感到海豚所搅起的湍流。甘又明兴致勃勃地追过去,一边笑道:
“琼,如果是在虚拟世界里被鲨鱼吃掉,会是什么后果?”
“你当然不会真的死去,但系统会‘死机’,只能重新进行冷启动。另外,你会真的感到鲨鱼利齿切断身体的痛苦。所以劝你不要尝试。”
在那群海豚之后,甘又明忽然又发现两只。它们的体形相当大,在飞速游动中严格保持着相对方位。当海豚靠近时,甘又明发现它们身上套着挽具,身后拖着一个流线型的容器,他大声喊:
“看哪,海豚邮递员!”
琼在水下通话器中听到了他的喊声,也看到了那对海豚,它们像是受过严格训练的军马,目不旁骛,以极快的速度掠过他们的身边。琼饶有趣味地说:
“我看过一些资料,说军方在着力培训海豚蛙人,让它们咬断敌方通信电缆,或者给深海作业的潜水员递送工具。海湾战争中就征调了海豚部队去排除鱼雷。噢,对了,听说贩毒集团也开始利用海豚和信鸽越境贩毒,这是最廉价又最难发现的方法。”
甘又明似笑非笑地看着她,他想琼这几句话一定是预定情节中的台词。他嬉笑道:
“要不,咱们追过去?”
“好的。”
他们迅速爬上快艇,瞅准那片背鳍追过去。海豚的速度很快,甘又明看看速度表,已超过每小时10海里。它们有时也潜入水中,好在海豚必须浮上水面换气,所以他们一直保持着追踪。马上就到岸边了,前边有一个狭长的海岛,海岸警备队的快艇远远向他们驶来。那两只海豚忽然昂起头——甘本能地感觉到它们是在作一次深呼吸——便潜入水中,倏然不见。琼急急地说:
“恐怕它们不会再浮出水面了,下水追踪吧。”
两人迅即下水,听见海岸警备队快艇上在大声喊叫着,似乎是在命令他们待在船上听候检查,但两人没理会。海豚的速度很快,一会儿就失去踪影了。两人在岸边的红树林中和乱石中徒劳地寻找十几分钟,终于失望了。琼懊丧地说:
“找不到了,回航吧。”
就在这时,甘忽然发现前边有一个狭窄的洞口。那两只海豚正一前一后从洞口钻出来,径直向大海游回去。它们身上已没有挽具和那个流线型的物体。但甘分明觉得它们就是原来那两只。从它们从容不迫的神情看,似乎已经完成了邮递任务。甘又明拉着琼游近观察,洞穴非常幽深。他问琼:“进洞看看?”
琼犹豫着,甘又明又鼓动道:
“不会有危险的。既然海豚能游进去又能游出来,何况咱们还带着氧气瓶。”他笑着补充,“何况只是虚拟世界。”
“好吧。”
两人把面罩戴上,费力地钻进洞穴。进口相当狭小,但里面越来越宽,也越来越暗,几乎成了漆黑一团。他们继续前行,大约两公里后,前边出现了暗蓝色的微光。再往前游一会儿,海水逐渐变成清澈的天蓝色,浮光摇曳,色彩斑斓的各种鱼儿在蓝光中遨游。琼惊喜地说:
“太美啦,我在这儿当向导已经五年,一直没发现这个神奇的蓝洞。”
蓝光逐渐变淡,两人同时钻出水面,摘下面罩,好奇地打量着。这儿很像一个天井,水面离岸有几米高,头顶上方仍然是岩顶,岩洞四周卧着两三幢小房子。忽然有人高喊:
“水下有人!”
立即响起凄厉的警报声,十几个人一下子冒出来,从岸边探下身,端着枪向他们瞄准。两人知道这儿不是说理的地方,迅速戴上头盔,一个鱼跃,急速向水下潜去。后边如开锅一样,无数子弹搅着海水。琼在通话器中气喘吁吁地说:
“一定是贩毒分子!否则不会不问情由就开枪的,我们快返回!”
他们尽力向来路游回去。眼看快到洞口了,忽然刷拉一声,一个秘密栅栏门从洞壁上伸出来,把洞口封得严严实实。甘又明用力摇撼,粗如人臂的铁栅栏纹丝不动。琼惊惶地喊:
“后边!他们追来了!”
十几个蛙人已经悄无声息地逼过来,他们手中的长矛和水下步枪闪闪发亮,有如鲨鱼口中的利齿。他们透过面罩阴森森地盯着两人,慢慢把包围圈缩小。在这生死关头,甘又明忽然长笑一声,大声喊道:
“暂停!吴先生,场上队员要求暂停!”
眼前的景象呼啦一下子消失了,两人仍坐在椅子上。甘又明抬起胳膊想去掉头盔,两名工作人员急忙过来帮助他。头盔取下后,面前仍是那所空旷的大厅,两人仍穿着那件白色的外壳。他大笑着站起身:
“太奇妙了,太逼真了!我虽然明知道它是假的,却看不出一丝破绽。我能感受到海水的波动、子弹的尖啸和死亡的恐惧。那个蓝汪汪的洞穴实在美极了,还有那两个勤奋尽职的海豚邮递员!吴先生,真难为你编出这么生动的情节。”
琼也取下头盔,笑问:“你在哪儿看出了破绽?”
甘又明微笑道:“你不要拿我的智力开玩笑。这是个非常逼真的故事,可惜没有开头——我们是突然跌入海水中的。稍有逻辑判断力的大脑,自然能做出正确的结论。”
从控制室出来的斯托恩·吴一直没有说话,笑着看他。这时才问一句:“什么蓝洞?”
甘又明惊奇地说:“你是开玩笑吧,你们构思的情节,你能不知道?”
斯托恩·吴微微一笑:
“你太小觑我的系统了。告诉你,系统的信息来源是完全真实的,也几乎是无限的。但究竟把哪点信息用于这一次的虚拟环境——比如你在海水里看到的是海豚还是噬人鲨——却是完全随机的。电脑根据这些信息随机地进行构思,所以系统内的情节绝不会重复。”他开玩笑地说,“我说过,我一直不忍心把这套技术公开,我怕它砸了所有小说家、剧作家的饭碗。”
“那么,我们在虚拟世界里游逛时,你并不知道我们的经历?”
“当然可以知道,不过我们一般懒得监视,你的进入只是千百个普通实验中的一个。”
这话使甘又明的自尊心颇受打击。他简要讲了当时的情形,吴中似乎对海豚和蓝洞的情节很感兴趣,盯着问了几个问题。然后他说:
“今天到这儿结束。让琼陪你去逛逛美国吧,你已经只剩下6天了。”
甘又明点点头,从身上慢慢剥下那件白色的外壳,穿上他自己的衣服。从外壳的禁锢中解脱出来,顿时觉得十分轻松。
尽管在电影中、电视中对美国的夜生活已是耳熟能详,但只有亲身置于夜总会的环境中,才真的感受到那种末世气氛。大厅里光线幽暗,烟雾腾腾,紫色、蓝色、血红色的光柱一波波扫过人群。高高的屋顶上垂下一个秋千,一个近乎裸体的艳色女郎嘎嘎笑着,一下下擦着头顶荡过人群。大厅正中是一个高台,一对身穿白色紧身衣的男女疯狂地扭动着,做出种种猥亵的动作。他们的紧身衣颇似B基地里的外壳,甘又明不由得想起裸体的琼套着外壳时的情形。他扭头端详琼,她今晚的打扮也很性感,裸露的肩头和脊背十分润泽,穿着短裙,大腿修长白皙。两人找到位置坐下,甘又明问:
“喝点什么?”
“来杯威士忌。”
甘又明为自己要了三瓶矿泉水,一杯杯地往肚里灌。他解嘲地说:“早就渴坏了。”
琼呷了几口威士忌,问:“跳舞吗?我在等你邀请呢。”
甘说:“我去一趟洗手间。”他在挨肩擦背的人群中费力地挤过去。洗手间是男女合用的,便池各自独立,两名女子正对镜整妆。他拉开一间便池的门,忽然吃惊地后退一步,一个40岁左右的黑人男子侧卧在便池上,眼睛像死鱼一样翻着,胳膊上的静脉血管插着一支注射器。
不用说,这是过量吸毒引起的猝死。那两名女子出门时也看到了尸体,但她们只漠然地扫一眼,若无其事地走了。甘又明厌恶地看着这名吸毒者。他一直生活在中国,对席卷全球的吸毒狂潮只有三个字的感受:不理解。他不理解竟然有数千万人屈服于这种魔鬼的诱惑,莫非末日审判的钟声已经敲响了么?
他回到柜台前,向侍应生问清了报警电话,把电话要通。警察局的值班人员说:
“谢谢,我们将在10分钟内赶到。请问你的名字?我们在哪儿可以找到你?”
“我叫甘又明,10分钟内不会离开这家夜总会,你到第七号餐桌前找我。”
回到桌旁,他看见座位已空,琼正同一个陌生男子跳舞,狂热地扭动着臀部和肩部。她的眼光仍留意着这边,见甘返回,向他做一个抱歉的手势。甘又明向她摆摆手,坐到原位。
两个中年人忽然出现在他的面前,他们身着便衣,一个身材矮胖,手上长满金色的软毛;另一个是瘦长个子,耳朵很大。矮个子彬彬有礼地问:
“你是中国来的甘又明先生?”
甘又明狐疑地看着两人,嘲讽地说:
“二位来得太快了吧,这不像是真实世界的速度。”他有意把这两个字咬得特别重,“我报案才1分钟。再说,我在电话中并没说我是从中国来的呀。”
这下轮到那两人纳闷了:“你说什么报案?”
“你们不是警察?”
“我们是联邦警察,”两人出示了证件,“我们是联邦调查局派驻B基地的警官汤姆和戈华德。但你说什么报案?”
甘又明讲了刚才的见闻。听了甘的解释,大耳朵的戈华德警官匆匆去洗手间处理那桩凶杀案。汤姆笑道:
“一场误会,我们是为另一件事来的,要占用你一点时间。你不会介意吧。”
“我不会介意,但我首先要确认自己是不是在梦中。”他笑着问,“请二位向我解释一下,你们是如何在一个远离B基地的繁华小镇一下子就找到我,一个刚来美国的外国人?”
“很容易。我们知道琼经常来这儿玩,又在停车场发现她的汽车。”
甘又明噢一声,觉得自己是多疑了。他说:“那么请讲吧,什么事情我可以效劳?”
汤姆开门见山地说:“听说你和琼无意中发现一条贩毒通道?”
甘又明哑然失笑:“先生,你是B基地常驻警官,难道对他们的虚拟技术一点也不了解?对,我们是发现了一条通道,还差点丧了命。但那只是一个虚拟的故事。”
汤姆微笑着说:
“恐怕正是你本人还不了解虚拟技术。你是否知道,虚拟环境中所涉及的信息都是真实的,是从间谍卫星、水下拾音器、水下摄像机输到电脑中的。海岸警备队在南部海岸线确实设了许多秘密摄像机,以便监督无孔不入的贩毒分子。所拍摄的数千英里的胶片都经过电脑的处理,把有用的资料甄别出来,送到联邦缉毒署长的办公桌上。但是,电脑不是万无一失的,它也有可能漏掉很重要的一段,又偶然被组织进那次的虚拟环境中去。我们尚未在浩如烟海的背景资料中查到这一部分,为了稳妥,请你帮我们复查一下。这也是吴先生的意见。”
“现在就去?”
“越快越好。”
“好吧,”他把最后半瓶矿泉水灌进肚里,“需要琼一块儿去吗?”
“当然。”
他把琼从舞池中唤回来,戈华德正好也返回了。他说:“本巡区的警官已经去了洗手间。我们走吧。”
琼迷惑地问:“到哪儿?”
“上车再说吧,走。”
警用快艇上已经备好四套轻便潜水服和水下照明灯。甘又明很有把握地说:“我想我会很快找到的。当时我仔细记下岸上的特征和水下岩石的特征。”
果然,不到1小时,他已在黝黑的水底找到那个洞口,洞口看不见栅栏。甘低声说:
“就是这儿,不会错的。余下的工作由你们去做吧,我可不想再被关进这个捕鼠笼子里被人捅死。”
戈华德游近洞口察看,怀疑地低声说:
“是这儿吗?洞口处没有安装栅栏的痕迹呀。甘先生,琼小姐,请你们再辨认一下。”
甘又明不相信自己会弄错,他和琼游过去,一眼就看到栅栏缩回的两排小圆洞。他猛然惊醒,但不等他做出反应,两名警官忽然用力把他们向洞里推去,同时按下一个按钮。铁门刷拉一声合拢了,把两人关在里面。琼惊呼道:
“上当了!他们一定和毒贩有勾结!”
两名警官在外面狞笑着:“聪明的姑娘,可惜你醒悟得晚了点儿。回头看看吧。”
后边刷地射来一道强光,两人本能地捂住双眼。等眼睛稍微适应光亮,看到五六个蛙人正迅速逼近,手中的水手刀和水下步枪像鲨鱼的利齿。琼失声惊叫着,甘又明迅速把她拖到身后。
但他知道这是徒劳的。蛙人正慢慢逼近,身后是坚固的栅栏,即使栅栏外面也是虎视眈眈的敌人。甘又明用身体把琼压在栅栏上,忽然厉声喝道:
“汤姆警官,临死前我有一个要求!”
汤姆游近栅栏,戏弄地说:“请讲吧,我乐意做一个仁慈的行刑者。”
甘又明忽然笑起来,油头滑脑地说:“我想撒泡尿。”
汤姆愣一下,恶狠狠地说:“我佩服你死到临头还有心情幽默,动手吧!”
几把长矛正要捅过来,甘又明急忙高喊:“暂停!吴哥,我要求暂停!”
两人突然跌回现实中,仍坐在那两张椅子上,甘又明的双手还保持着篮球比赛的暂停动作。琼取下头盔,看着他的滑稽样子,扑哧一声笑了。吴中从控制室走出来,微笑着问:
“你真是个机灵鬼,从哪儿看出破绽?”
甘又明也取下头盔,笑嘻嘻地说:“我是否可以不回答?我不想削弱自己取胜的机会。”
但一分钟后他就忍不住了,笑道:
“很简单,我在夜总会有意猛灌几杯水,可是1小时后还不觉得膀胱憋胀。这可不符合我的习惯──我从小就是个有名的尿漏子。所以我理所当然地得出结论:那几杯水并没有真正灌进我的肚里,也就是说,我仍是在虚拟世界里。”
斯托恩·吴忍不住大笑起来,琼和几名工作者也笑个不停。吴中忍住笑说:
“你很聪明,用一泡尿戏弄了超级电脑。不过我要给你一个忠告,实际上电脑里有尽善尽美的程序,可以根据你的进食或饮水等情况,及时发出饱胀感或憋尿感信号。这只是一次丢脸的疏忽,我再也不会让它出这样的纰漏了。现在你可以脱下外壳,让琼真的领你去看看美国社会。”
甘又明忽然想到一件事:
“顺便问一句,在这次的虚拟场景中,汤姆警官说的是真实情况吗?那个蓝洞真的有可能存在吗?”
“他说得不错。我的确在10分钟前向汤姆警官通报过这件事。”他笑着说,“而且,这两位警官也确实是你在虚拟环境中见过的尊容。既然身边有现成的模特儿,我何必舍近求远或凭空臆造呢。”
工作人员小心地脱下“外壳”。这种由银丝和碳纳米管混织而成的白色连体服是世界上最昂贵的衣服,甚至超过每件价值3000万美元的太空服。甘又明斜睨着裸体的琼,咕哝道:
“我一定还没跳出虚拟世界。在真实世界里,我绝不敢这样坦然地看一个姑娘的裸体。”
琼慢慢地穿着衣服,一直在斜睨着他,她的脑袋泛着青光。甘受不了她目光的烧灼,尴尬地说:
“你为什么一直盯着我?想和我比一比谁的脑袋更亮吗?”
琼含笑不语,突然说:“谢谢,甘,谢谢你。”
“为什么?”
“谢谢你在危急关头总是把我掩到身后。纵然只是在虚拟世界里,也能看出你的骑士风度。”停停她又加了一句,“我希望能有机会让我给予回报。”
甘又明笑嘻嘻地说:“你上当了,那时我已经判断出是在虚拟环境中,乐得充一阵空壳子好汉。”
琼摇摇头说:“你何必装得比实际上坏呢?”
甘又明有点尴尬,忽然笑道:“你愿意回报吗?现在就可以。”
琼误解了他的意思,吃惊地说:“现在?在这儿?”
甘又明把赤裸的左臂伸过去:“喂,咬上一口,狠狠咬上一口。这就是你的回报。”
琼迷惑地笑道:“你怎么啦?”
“老实说,我对这种虚拟世界已经心怀畏惧。在刚才那层虚拟中,我分明感到我已经脱下外壳,可是实际上它仍然紧紧地箍着我。现在我又把它脱了,谁知这回是真是假?你咬我一口,看我知道疼不。用力咬!”
琼笑着,真的用力咬一口。甘又明疼得大叫一声,低头看看,胳膊上四个深深的牙印,略有沁血。甘又明笑道:
“好,好,这下子我真的脱下那层外壳了。你说对吗,琼?”
琼含笑不言。甘又明苦笑道:
“我知道你只能做一个超然的向导,不会帮我作出判断。我也知道自己是自我安慰。即使这会儿外壳仍套在身上,也同样能造出这样逼真的痛觉和视觉效果。”他把琼的手臂拉过来,用手摩挲着。姑娘的皮肤光滑柔软,滑腻如酥,有一种麻麻的电击感。他苦笑道:“真希望我现在触摸到的是真正的你,而不是那种比真实还要真实的虚拟效果。”
琼被他话中蕴涵的情意所感动,轻轻握住他的手。突然甘又明的目光变冷了,他紧盯着琼的臂弯,那儿白皙的皮肤上有两个黑色的针孔。那分明是静脉注射毒品的痕迹。他没再说话,默然穿上衣服走出大厅。
琼自然感觉到了他突然的冷淡,走出大厅后她说:“愿意逛逛夜总会吗?”
甘又明客气地说:“不,谢谢。我今天累了,想早点休息。”
琼犹豫好久,抬起头说:“请到我的公寓里坐一会儿,好吗?我住在基地外的一所公寓里,离这儿不远。”
甘又明犹豫着,不忍心断然拒绝琼的邀请,他知道琼是想对他作一番解释。他迟疑地说:“好吧。”
琼驾着汽车在隧道中开了半小时,她说隧道下面就是你们来基地时走的蒸汽管道。出了隧道又开了大约15分钟,前边又出现辉煌的灯火。琼放慢车速,缓缓开进这个小镇。她告诉甘又明:
“这儿是红灯区。基地的男人们在周末常常到这里寻欢作乐。”
街道很窄,勉强可以容两辆车交错行驶。琼耐心地在人群中穿行。左边一个白人男子在大声吆喝着,对过往车辆做着手势。他头上的霓虹女郎慢慢地脱着最后一件衣服。琼告诉他,这里面是表演脱衣舞的地方,老板和演员都是法国人。甘又明瞥见几个年轻人聚在街角叽叽咕咕,有黑人也有白人,他们的头发大都染成火红色,梳成爆炸式的发型。琼告诉他,这是吸毒者和毒品小贩在做生意,对这些零星的贩毒,警方是管不及的。忽然一个人头出现在他们的车窗上,这是一个眉清目秀的白人青年男子,戴着耳环,嘴唇涂着淡色唇膏,对着车内一个劲儿搔首弄姿。甘又明知道这是一个同性恋者,厌恶地扭过头。
汽车终于穿过红灯区,似乎又掉头开一会儿,停在一个整洁的公寓外。几个小孩儿在绿草坪上骑自行车,暮色苍茫中听见他们在兴奋地尖叫。琼掏出磁卡打开院门,停好汽车,又用磁卡打开公寓门。
公寓很大,也很静,只有洗衣房里有一个女佣在洗衣。琼把他安顿到客厅,告诉他,公寓里的客厅、洗衣房、健身房是公用的。这里住客很少,几个护士又常上夜班,所以今晚只剩下她一个人。
她端来两杯咖啡,坐在他对面的沙发上,笑问:“今天我有意绕一段路,领你去看看红灯区。有什么观感吗?”
甘又明沉吟一会儿说:“浮光掠影地看一眼,说不上什么观感。我对美国的感情是很矛盾的,一方面,我非常敬慕美国的科技,羡慕美国人在思想上永葆青春的活力。我常常觉得美国的精英社会已经提前跨入21世纪。另一方面,我又非常厌恶美国社会中道德的沦丧、人性的沦丧:吸毒、纵欲、群交、同性恋、妇女拒绝繁衍后代……简直是世界末日的景象。我最担心的是,这种堕落是否是高科技的必然后果?因为科学无情地粉碎了人类对自然的敬畏,对生命的敬畏。如果美国的今天就是其他国家的明天,那就太令人灰心了!”
琼沉默很久,冷淡地说:
“不必那么偏激吧。我知道中国南北朝时,士大夫就嗜好一种毒品——金石散;明清的士大夫盛行养孪童。中国人比西方人摩登得更早呢。”
甘又明冷笑着,尖厉地说:
“我很为那些不争气的祖先脸红!甚堪告慰的是,我们已把它们抛弃了。美国呢,据统计,全国服用过一次以上毒品的有6600万人!对了,你刚才还忘了提中国清末的嗜食鸦片呢,那是满口仁义道德的西方人一手造成的。现在他们的子孙吸毒成癖,是不是冥冥中的报应!”
琼久久不说话,一种敌意在屋内弥漫。很久之后,琼走过来坐在甘又明旁边,握住他的手说:
“请原谅,我并不想冒犯你。坦率地讲,从一见面我就很喜欢你,你的清新质朴是我不多见的。我不瞒你,我确实偶尔服用毒品,这在美国是很普遍的事。在西班牙等国家,吸毒甚至已经合法化。不过,我知道你是在坚持传统道德的国度中长大的,对此一定很反感。如果……我答应你从此戒掉毒品。”
甘又明听出她话中的情意,很感动,但他最终用玩笑来应付:
“那首先要确定我自己是否仍在虚拟环境中。谁知道呢,也许你是假的,我也是假的,你身上的针孔连同这会儿说的话都是假的。怎么样?能不能在这上面偷偷帮我一点忙?”
琼笑了:“我不能违犯自己的职业道德。”
甘又明笑着站起身:“时间很晚了,恐怕我该告辞了。”琼没有起身,微笑道:“你可以不走的。”她补充道,“你可以睡沙发,或者为你另开一间。”
“不,我还是走吧,我怕抵挡不住某种诱惑。”
两人都笑了。甘又明说:“你不必送我,我可以叫一辆出租。”
“不,还是我送你吧。”
两人刚打开房门,正好两个警察用力挤进来,把两人挤靠在墙上,他们出示了证件:
“警察!请退回你的房间!”警察把两人逼回客厅,甘又明立即认出这正是在虚拟世界里见过的汤姆和戈华德。汤姆冷冷地说:“琼小姐,据线人说你屋里藏了大量的毒品,我们奉命搜查。”
琼和甘又明吃惊得面面相觑,琼说:“不,我从来没有藏过大宗毒品!”
汤姆用力扳过她的胳臂,厌恶地说:“那么,这些针孔是怎么回事?”他不再理会琼,径自进卧室去搜查。十分钟后,他提着两袋白色药品走出来,怒气冲冲地说:
“是高纯度的快克,足有两公斤!”
琼非常震惊,瞪大眼睛盯着他手中的药品,忽然愤怒地嚷道:
“这是栽赃!这两袋毒品一定是你刚放进去的!”汤姆走过来,狠狠抽了她一耳光。鲜血从她嘴角沁出来。她转身对甘又明说:“请你相信我,他们一定是栽赃,一定是为了那个蓝洞报复我!”
戈华德奇怪地问:“什么蓝洞?”
甘蓦然惊觉,他急忙问戈华德:“你不知道蓝洞吗?就是贩毒集团的秘密通道。是我们无意中发现的,斯托恩·吴先生说他已通知了汤姆警官。”
戈华德警觉地回头看看汤姆,但晚了一步。后者已从腋下拔出一支旋着消音器的手枪,一声轻微的枪响,戈华德警官的额头上钻了一个洞,鲜血猛烈喷射,他沉重地倒在地上。琼惊叫一声,第二颗子弹已击中她的胸膛,立时她的T恤衫一片鲜红。甘又明猛扑过去,把她掩在身下,抬起头绝望地面对枪口。汤姆狞笑着说:
“谁知道蓝洞的秘密,谁就得死!你那位斯托恩·吴也活不过今天晚上。”他把枪口抵在甘又明的嘴里,枪身伴着冰冷的死亡感。甘恐惧地盯着他慢慢按下扳机,忽然口齿不清地喊:
“暂停!斯托恩·吴先生,暂停!”
工作人员为两人取下头盔,两人都面色苍白,惊魂未定。琼下意识地用手按着胸部,甘又明也提心吊胆地紧盯着那儿。不过,当白色的外壳慢慢脱下后,那儿仍然白皙光滑,并没有一丝伤痕。
斯托恩·吴已经站在他们身后,笑问:“小甘,你这个鬼灵精,这次又在哪儿看出了破绽?”
甘又明喘息一会儿,才苦笑道:
“不,我只是侥幸。我并没有完全确定自己是在虚拟环境中。我只是想,如果戈华德先生是一个循规蹈矩的警官,他就不会到不是自己值勤区域的地方去办案;汤姆如果想杀我们灭口,又何必拉着并非同伙的戈华德同去。不过,这段推理并不严密,很容易找到其他解释。”
琼的灵魂仍未归窍,甘又明勉强打起精神问:“琼,你是虚拟世界的向导,你怎么也会相信它呢?”
琼苦笑道:“有时我也难辨真假。”
甘又明分明觉得,他所经历的虚拟环境中的阴暗气息正逐渐渗入他的心田。他压着怒气冷嘲道:“吴先生,虚拟世界是从好莱坞请的导演吗?我看这里怎么净是好莱坞的暴力、血腥、毒品和性感女郎。”
斯托恩·吴摇摇头:“不,我们不必请什么导演,我说过,虚拟技术很快能抢掉他们的饭碗。该系统的超级电脑有很强的学习能力,我们只需把近20年来美国每年的十大畅销片输进去,它就能学会他们的导演手法,并远远超过他们。”
甘刻薄地说:“怪不得这些情节十分眼熟呢。”那层无影无形的SHELL似乎一直在裹着他,箍得他无法喘息,他疲倦阴郁地说:
“我要休息了,想睡个好觉再干下去。我的住处在哪儿?”
“就在对面的白领人员公寓里,103号。”
“你也在那儿吗?”
“对,118号,我们离得不远。琼,今天的工作就到这儿结束吧,谢谢。”
琼简单地同甘又明告别,披上外衣走出大厅。她还要赶回自己的公寓。
晚上,甘又明在床上辗转难眠。倒不是因为下午“身历”的血腥场面,而是因为他不敢确认自己身上那件“外壳”是否真的已经去掉。他对姐夫的虚拟技术已有了深深的畏惧,就像害怕一个摆脱不掉的幽灵。
比如说,这会儿斯托恩·吴没有邀请他去屋里做客,就不符合真实世界的常理,毕竟小舅子是万里之外来的客人呀。
不过,也许这是西方世界的习俗?也许是吴先生的屋里还藏着一个情人?也许……还有别的秘密?
他一跃而起,他要去姐夫的屋里看一看才放心。尽管知道自己的决定有点神经质,他还是来到118号房间。按响门铃后很久,姐夫才打开房门:
“是你?还没有睡吗?”
姐夫穿着睡衣,脸上是冷淡的客气,分明不欢迎他进屋。他佯装糊涂,径自闯进去。没有等他的侦察工作开始,卧室中就传来嗲声嗲气的声音:
“亲爱的吴,快进来吧。”
一个浓妆艳抹的裸体男人扭着腰肢从浴室里走出来,两只硕大的耳环在耳垂下游荡。正是在红灯区拉客的那只兔子!甘又明痛心疾首地扭头瞪着姐夫。他十分痛心姐夫的堕落,但最使他痛心的甚至不是这件事情本身,而是姐夫那种冷静的厌烦的神情,他肯定是讨厌这位多事的小舅子。甘又明狂怒地喊道:
“我知道这不是真的!暂停!”
工作人员为他取下头盔,吴中微笑着走过来,没等他开口说话,甘又明已经愤懑地喊:
“我退出这个游戏!我要回家去!”
吴中和刚取下头盔的琼都吃惊地看着他,想要劝阻,但甘又明厉声喝道:“不要说了,我要回国!”
看来吴中很不乐意,他冷淡地说:“这是你的最后决定吗?那好,我让秘书安排明天的机票。”
第二天琼陪着他坐上了中国民航的波音747班机。甘又明曾冷淡地执意不让琼陪同,琼小心地解释:
“甘先生,这是我做向导的职责,只有在你确定自己回到真实世界的时刻,我才能离开你。”
18个小时的航行中,甘又明一直紧闭双眼,不吃也不喝。直到出租车把他送到北京方古园公寓,他才睁开眼。他急急地敲响姐姐的房门。姐姐惊喜地喊:
“小明,你这么快就回来了?这一位是……”
甘又明不回答,在屋里神经质地走来走去,目光疑虑地仔细打量着屋内的摆设。琼只好向女主人作了自我介绍,两人用英语和汉语亲切地交谈着。甘又明在博古架前停住,突兀地问:
“姐姐,我送的花瓶呢?”
姐姐迷惑地问:“什么花瓶?”
“你们结婚那天我送的花瓶!”
“没有啊,那天你是从老家下火车直接到我这儿,只带了一些家乡的土产。”
甘又明烦躁地说:“我送了,我肯定送了!”在他脑海中,对几天前的回忆似乎隔着一层薄雾。他清楚地记得自己送过一只精致的花瓶,那是件晶莹剔透的玻璃工艺品,但他又怕这只是虚拟的记忆,是逼真的虚假。这种无能为力的感觉使他狂躁郁怒。他忽然冷笑道:
“姐姐,非常遗憾,那位斯托恩·吴先生不是什么好东西……不不,我和他没什么实际接触,这几天实际我一直是在虚拟世界里和他打交道。但仅凭虚拟环境中的阴暗情节,我也可以断定创作者的人品。”
姐姐沉默很久才委婉地说:“小明,你怎么能这样说姐夫呢,你和他在一块儿相处满共不过五天。五天能了解一个人吗?再说,虚拟世界是超级电脑根据美国高科技社会的现状为蓝本构筑的,他即使是首席科学家也无能为力。”
甘又明立即胜利地喊道:“这不是你的话,是吴中的话!我仍是在虚拟世界里,暂停!”
工作人员为两人取下头盔,甘又明一直紧闭双眼,不断地重复着:
“我要回国,回我的家乡。”
吴中和琼看着心理崩溃的小甘,担心地交换着目光,说:
“好吧,我们马上送你回国。”
破旧的大客车在碎石路上颠簸着。车里大多是皮肤粗糙的农民,他们一直好奇地盯着那位漂亮的白人金发姑娘。她身旁是一个脑袋锃光的中国小伙子,一直闭着双眼,似乎是一个病人。姑娘小心地照护着他。
直到下了车,视野中出现一个山脚下的小村庄时,甘又明才睁开眼,他指点着:
“看,前边那株弯腰枣树下就是我家。”
他们进了村,小孩们好奇地围观着。琼饶有兴趣地打量着这个农家院落,大门上贴的春联已经褪色,茂盛的枣树遮蔽着半个院子。墙角堆着农具,墙上挂着苞米穗子,院里还有一口手压井。甘又明比她更仔细地端详着院子,目光中是病态的疑虑和狂热。
他妈妈从后院喂完猪回来,看见他们,惊喜地喊:
“明娃,你咋回来啦?哟,你咋成了个光瓢和尚?”她欢天喜地把两人让进屋,不错眼珠地盯着那个洋妞。停一会儿,她冲了两碗鸡蛋茶端出来,瞅空偷偷问儿子:
“明娃,这个美国妞是谁?”
在这之前,甘又明一直表情复杂地看着妈妈,既有亲切,更有疑虑。听见这句问话,他立即睁大眼睛,劈头盖脸地问:
“你怎么知道她是美国人?谁告诉你的?”
妈妈让这一连串的质问弄蒙了,怯生生地问:“我说错话了吗?打眼一瞅,任谁也知道她不是中国妞哇。”
甘又明不禁哑然失笑,知道自己多疑了。他忘了妈妈的习惯:凡不是中国人的,她都叫他们美国人。他和解地笑道:
“没错,妈,你没说错。这位姑娘的确是美国人,她叫琼。你问我们回来干什么?琼想听你讲讲我小时候的事儿,一定讲那些我自己也忘记了的事儿,好吗?”
妈妈笑嘻嘻地看着儿子,他们巴巴地从北京赶回来就是为了这事儿?不用说,这个美国妞是儿子的对象,是他的心尖儿宝贝,哼一声也是圣旨。她笑着说:
“好,我就讲讲你小时候的英雄事儿,只要你不怕丢面子。姑娘能听懂中国话吗?”
“她能听懂中国话,听不懂的地方我给她翻译。”
“你八岁那年,在洄水潭差点丢了命……”
“这事我知道,讲别的,讲我不知道的!”
妈妈想了半天,嘴角透出笑意:“行,就讲一个你不知道的,我从来没告诉过你。初中一年级时,有一天你在梦中喊李苏李苏!我知道李苏是你的同班同学,模样儿很标致,对不?”
甘又明如遭雷殛,他一下子想起来了。李苏是个性情爽朗的姑娘,常笑出一口白牙。那时他对李苏的友情中一定掺杂着特别的成分,但他把这种感情紧紧关闭在12岁小男子汉的心灵中,从未向任何人泄露过。他一直不知道自己在梦中喊过李苏的名字,也不知道大大咧咧的妈妈竟然能把这件事记上十几年。
李苏没有上大学,她在初二就患血癌去世了。同学们到医院去和她告别时,她的神志还清醒,那双深陷的大眼睛里透着深深的绝望。甘又明一直躲在同学们后边,隐藏着自己又红又肿的眼睛,也从此埋葬了那些称不上初恋的情感。
妈妈看见儿子表情痛楚,两滴泪珠慢慢溢出来。她想一定是自己的话勾起儿子的伤心,忙陪笑道:“明娃,你咋啦?都怪妈,不该提那个可怜的姑娘。”
甘又明伏到妈妈怀里,哽声道:“妈,现在我才相信你真的是我妈。”
妈妈又是好气又是好笑又是担心:“你发魔怔了?我不是你妈谁是你妈!”
甘又明没有辩解,他回头对琼说:“琼,现在我可以确认了,我已经跳出虚拟环境。”
琼笑着掏出一张支票:“祝贺你,你终于用思维的惯性证实了这一点。吴先生说,如果你能确认,让我把一万元奖金交给你。”
从这一刻起,两人都如释重负。妈妈开始做午饭,她在厨房里大声问:“明娃,你能在家住几天?”
甘又明问琼:“我娘问咱们能住几天,看你的意见吧。你是否愿意多住几天,领略一下异国情调。”
“当然乐意。我还在认真考虑,是否把根扎在这儿呢。”
甘又明当然听出她的话意。自打摆脱“外壳”的禁锢,他觉得心情异常轻松,几天来对琼的好感也复活了。他笑着把琼拥入怀中。妈妈端着菜盘进屋,瞅见那个美国丫头偎在儿子怀里,翘着嘴唇等着那一吻,她偷偷笑笑,赶紧退回去。
甘又明把手指插在琼金黄色的长发里,扳过她的脑袋,在她嘴唇上用力印上一吻。琼低声说:“你把我的头发揪疼了。”
在这一刹那,她觉得甘的身体忽然僵硬了。他不易觉察然而又是坚决地把怀中的姑娘慢慢推出去,他的身体明显地又套上一层冰冷的外壳。琼奇怪地问:“你怎么了?”
甘又明勉强地说:“没什么。”停一会儿,他把目光转向别处,低声用英语问:“琼,请告诉我,你吸毒吗?”
琼看看他的侧影,平静地说:“我不想瞒你,几年前我曾服用过大麻,现在已经戒了。这在美国青年中是很普遍的。不过我从来没有静脉注射过快克。呶,你看我的肘弯。”
她白皙的肘弯处的确没有什么针孔。甘又明仅冷漠地扫了一眼,又问:“斯托恩·吴……真的是一个同性恋者?当然,我所见到的只是虚拟世界里的情节。请你如实告诉我。”
琼摇摇头:“我不知道。我不是瞒你,我真的不知道。在B基地,除了工作上的交往,我和他没什么接触。同性恋在美国是普遍的社会现象,有公开的同性恋组织和定期的公开集会,某些州法律已经承认同性恋为合法。但华人中尤其是高层次的华人中,有此癖好的极少。吴先生大概不会吧。”
甘又明阴郁地沉默了很久,突兀地问:“你的头发不是假发?在进入虚拟世界之前,在套上那件‘SHELL’之前,我看见你剃光了头发。”
琼迟疑着回答:“这是一个复杂的技术问题……”甘又明烦躁地摆摆手,不想听她说下去,不想听一个“逼真”的解释。他清楚地记得,光脑壳的琼是他在进入虚拟环境之前看到的,也就是说,这件事情是真实的。那么,他就不该在这会儿的真实世界里看到一个满头金发的姑娘。他苦涩地自语:
“我已经剥掉了六层SHELL,谁知道还有没有第七层?也许我得剁掉一个手指头才能证实。”
琼吃惊地喊:“你千万不要胡来!我告诉你,你真的已跳出虚拟世界,真的!”
甘又明冷淡地说:“对,按照电脑的逻辑规则,一个堕入情网的女向导是会这样说的。”
琼唯有苦笑。她知道两人之间刚刚萌生的爱情之芽已经夭折了。午饭后她很客气地同伯母告别。甘又明的妈妈极力挽留很久,但姑娘的去意很坚决。儿子冷着脸,丝毫不作挽留,似乎是一个局外人。她十分纳闷,不知道这一对年轻人为什么无缘无故地翻了脸。
2小时后,琼已经坐上到北京去的特快列车,并在车站邮局向北京机场预订了第二天早上去旧金山的班机。她还给斯托恩·吴先生打了一个越洋电话,说甘已经赢得一万元奖金。对甘又明在赢得奖金之后的反复,她未置片语。她听见吴先生简单地说一句:“知道了。”就挂上了电话。
祈祷之圈-艾丽丝·门罗
========================
祈祷之圈-[[艾丽丝·门罗]]
-----
"""
特鲁迪把壶朝房间那头扔去。它没撞到对面的墙。没砸中任何人。甚至都没摔破。
这是一个没有把手的壶—灰泥色,上有棕色横条,摸上去砂纸般粗糙—是丹那年冬天参加陶瓷班做的。他做了六个小小的无把杯子配它。壶和杯子本是喝清酒用的,但是当地酒店不售清酒。一次,他们旅行时买了一些回家,不过不怎么喜欢。因此丹做的壶一直搁在厨房的开放式架子上的最高一层,里面搁着几样有点价值的稀奇玩意儿。特鲁迪的结婚戒指和订婚戒指,罗宾八年级获得的全优生奖牌,一条长长的双层黑玉珠链,原是丹的妈妈的,遗嘱留给了罗宾。特鲁迪现在还不让她戴。
特鲁迪下班回家时刚过午夜。她摸黑进屋。只有小小的炉灯开着—她和罗宾总给对方留着这灯。特鲁迪等不及开别的灯,甚至包都没放下,就爬上一把椅子,取下壶,在里面摸了一圈。
没了。当然。她早知道它没了。
她穿过黑暗的屋子,走向罗宾的房间,拎包仍挽在胳膊上,手里抓着那壶。她打开顶灯。罗宾呻吟着翻个身,把枕头扯到脑袋上。装吧。
“你奶奶的项链,”特鲁迪说,“你为什么要那样做?你疯了吗?”
罗宾假装发出一声半梦半醒的呻吟。看起来,好像她所有的衣服,旧的新的,干净的脏的,全都散落在地板、椅子、桌子和梳妆台上,甚至床上也有。墙上贴了张画着河马的大海报,下书“我怎么如此天生丽质?”。还有一张特里·福克斯[1]跑过雨中公路的海报,身后汽车如林。脏杯子,脏酸奶盒,学校笔记,一盒没拆封的卫生棉条,罗宾学龄前玩的布蛇和布老虎,一大摞两年前被轧死的猫“腊肠”的照片,罗宾跳远、赛跑或投篮得的红蓝色缎带。
“你给我说话!”特鲁迪说,“给我说说你为什么这么干!”
她丢出酒壶。但它比她想象的重,或者也可能扔出的那一瞬她手软了,总之它没撞上墙,掉在梳妆台边的地毯上,在地上滚了一会儿,完好无损。
那会儿你冲我扔了只壶呢。你差点砸死我。
不是冲你的。我没冲着你扔。
你差点砸死我。
罗宾在装睡的证据:她惊恐地坐起,却毫无突然惊醒时的困惑茫然。她好像很害怕,但孩子气的惊恐表情下,藏着另一种表情—死不悔改、察言观色、轻蔑不屑。
“它多好看啊。而且很值钱。它是你奶奶的东西。”
“我觉得它属于我。”罗宾说。
“那女孩甚至都算不上是你朋友。天哪,你今天早上对她可没说什么好话。”
“你哪知道谁是我朋友!”罗宾的脸涨成发亮的粉红色,眼里盈满泪水,不过轻蔑的、死不悔改的表情依然如旧。“我了解她。跟她聊过天。所以滚出去!”
特鲁迪在成人精神障碍中心工作。很少有人这么叫它。镇上老一点的人仍称它为“威尔姐妹之家”,其他许多人,包括罗宾—以及估计大多数她的同龄人—都叫它智障中心。
这房子现在修了一条轮椅坡道,因为有些智障人士在身体上也有残疾。后院有个游泳池,用纳税人的钱造它的时候,颇引起了一番议论。除了这些,房子看起来和从前几乎没什么不同—白木墙,带墨绿纹饰的山墙,斜屋顶,装深色纱窗的边廊,前方低洼的草坪周围环绕着软枫木。
这个月特鲁迪是下午四点到午夜的班。昨天下午,她把车停在房前,沿车道步行上去,想着这房子多美啊,就像威尔姐妹时期一样宁静,那对姐妹想必总是给人奉上冰茶,从图书馆借书看,或者还打槌球,就像那时候的其他人一样。
一旦你进门,总能听到几则新闻、一阵争吵或者激动的嚷嚷。有人来修游泳池,但没完工。他们又走啦。还没修好。
“我们反正拿它也没什么用,夏天很快就要过去了。”约瑟芬说。
“还不到六月中呢,你却说夏天马上就要过去了。”凯尔文说,“说话不经过大脑啊。你听说了那个在乡下死掉的女孩子吗?”他问特鲁迪。
特鲁迪搅拌着两份冰冻柠檬水,一份是粉红色的,一份是原色的。听了他这话,她把勺子往冰块上猛的一捣,溅出几滴柠檬水。
“怎么回事,凯尔文?”
她担心听到女孩被拖下某条乡间公路,在树林里被奸污,勒脖,毒打,弃尸。罗宾总是穿着白短裤和T恤,飞扬的头发上勒条发带,在乡间公路跑步。她的头发是金色的。腿和胳膊也是金色的。她的脸颊和四肢并非闪闪发亮,而是覆着层绒毛—要是她跑步经过,身后留下一阵花粉之雾,你也不会奇怪。汽车冲她鸣喇叭,她不为所动。有人冲她嚷嚷下流的威胁,她就不甘示弱地骂回去。
“因为开卡车。”凯尔文说。
特鲁迪心里的一块石头落了地。罗宾还不知道怎么开车呢。
“十四岁,她不会开车,”凯尔文说,“她溜进卡车,立马撞上一棵树。她父母在哪儿?我想知道的是这个。他们没看好她。她还不知道怎么开车,就溜进卡车,撞上树。十四岁。太年轻啦。”
凯尔文是独自进城的。他能打听到所有新闻。他五十二岁,仍旧瘦瘦的,像个男孩子,胡须刮得干干净净,一头柔软、干干净净的深色头发剪得短短的。他每天都去理发店,因为不大会自己刮胡子。癫痫症,然后是手术,某处骨移植受到感染,又做了更多手术,脚部和手指永久性轻微障碍,轻微的脑部障碍。这毛病并不会让他混淆事实,只会让他搞不清原因。或许他根本不该待在中心,不过又能去哪呢?再说他喜欢这里。他说过他喜欢这里。他告诉别人,他们不该抱怨。应该更守规矩,应该管好自己。他在前院捡起人们扔下的软饮料罐和啤酒瓶—尽管这不是他的分内事。
珍妮特午夜之前准时过来接替特鲁迪,也说了同样的新闻。
“我猜你听说过那个十五岁女孩的事了吧?”
珍妮特跟你说起这类事,总是用“我猜你听说过”开头。我猜你听说过威尔玛和特德分手了吧,她说。我猜你听说过埃尔文·斯蒂德心脏病发作的事了吧。
“凯尔文告诉我了,”特鲁迪说,“只是他说她十四岁。”
“十五岁,”珍妮特说,“她肯定和罗宾同班。她不会开车,甚至都没开出小巷。”
“她喝醉了吗?”特鲁迪问。罗宾对酒、麻醉药、香烟,甚至咖啡都点滴不沾,她对于纳入体内的东西极其在意。
“我想不是吧。或许是吓呆了。那是傍晚的时候。她和姐姐在家。她们的爸妈出门了,她姐姐的男朋友来了—就是他的卡车。要么是他把卡车钥匙给了她,要么是她自己拿了。反正说法不一。有人说他们打发她去做件什么事,想甩开她。有人说她拿了钥匙就走了。反正,她在小巷里一头撞到树上。”
“天哪。”特鲁迪说。
“我知道。这太蠢了。这让人一想到自己正在长大的孩子就难过。所有人都吃药了吗?凯尔文在看什么?”
凯尔文还没睡,坐在起居室看电视。
“某人的访谈。他写了一本关于精神分裂的书。”特鲁迪告诉珍妮特。
任何关于精神病的东西,凯尔文都会看看,或者试着阅读。
“我想他会沮丧吧,这类东西看得越多的话。”珍妮特说,“你知道吗,我今天发现,我不得不为了侄女劳拉的婚礼,用粉色餐巾纸做五百朵玫瑰!用来装饰车的。她说我答应过帮忙做婚车上的玫瑰。嗯,我没有啊。我可不记得答应过什么事。你愿意过来帮忙吗?”
“当然。”特鲁迪说。
“我猜想我希望他不要再看精神分裂节目的真正原因,是因为我想看老《达拉斯》[2]了。”珍妮特说。她和特鲁迪对此意见不同。特鲁迪没法忍受重播的老《达拉斯》,也不想看演员们带着昔日年轻丰满的脸庞,经历着他们和观众都早已忘记的那些磨难和错综复杂的情感关系。那才是最好玩的地方嘛,珍妮特认为。简直不可思议,所以太奇妙啦。这一切都发生过,而他们竟然已经忘得一干二净,过起自己的日子。不过特鲁迪觉得,没什么不可思议的—角色们总是从这事忙到那事,随时把往事抛诸脑后,永远兴致勃勃,拾掇得漂漂亮亮,频频换衣服。令她无法忍受的,就在于它并非真的那么不可思议。
第二天早上,罗宾评论道:“哦,没准吧。跟她玩的人全都酗酒。他们永远在聚会。他们自己不学好。全怪她自己。就算她姐姐叫她走开,她也不用真走开呀。不用这么犯蠢嘛。”
“她叫什么?”特鲁迪问。
“特雷西·李。”罗宾厌恶地说。她踩下垃圾箱踏板,举起而不是放低刚喝完的酸奶盒,往下一丢。她穿着比基尼内裤和T恤,上书“要是想听屁眼的声音,我会放屁”。
“我还是不喜欢那件T恤,”特鲁迪说,“有些东西挺恶心但挺好玩,有些东西光恶心不好玩。”
“有什么问题吗?”罗宾说,“反正我一个人睡觉。”
特鲁迪坐在屋外,裹着宽松睡衣喝咖啡,等天慢慢变热。边门外有一小片地铺着砖,她和丹总管它叫院子。她现在就坐在这里。这是一幢太阳能加热的房子,南面的斜屋顶上装着巨大的玻璃板—是镇上模样最古怪的房子。内部也很古怪,厨房装的是开放式架子而不是柜子,要爬上几级台阶才能进入俯瞰屋后原野的起居室。她和丹开玩笑地给房子各个部分取了最传统、最富郊区风味的名字—院子、化妆室、主卧室。丹总忍不住拿他的生活方式来取乐。他亲手造了这幢房子—特鲁迪揽下了不少油漆活儿以及乱涂乱抹的活儿—结果大获成功。镶板处没有漏雨,太阳能确实给房子提供了部分热量。大多数有丹的想法或理想的人都不够实际,不会修东西或做东西,不懂接电线或木匠活儿,或者任何需要懂的东西。丹却样样在行—园艺,砍木头,造房子。他尤其擅长修马达,过去经常作为汽车修理师和小马达修理工四处揽活儿。就是因为这个,他才到此地安家。他为玛莱娜而来,找到一份修理工的活儿,成了一家汽车修理店的技术合伙人,然后不知不觉地—娶了特鲁迪而不是玛莱娜—变成一个小镇商人,亲情俱乐部成员。他自始至终不曾剃掉那把1960年代的大胡子,也懒得理发。镇子太小,而丹又太聪明,无须为这些费神。
现在丹跟一个叫作吉纳维芙的女孩住在列治文山一幢市区住宅里。她在读法律。她很小就结婚了,有三个年幼的孩子。丹三年前遇到她,当时她的帐篷车在镇外几英里处抛锚。晚上他跟特鲁迪讲了她的事。租的帐篷车,三个几乎还是婴儿的小孩,非常年轻的离婚妈妈,头发梳成辫子。她的勇敢,她的贫困,她读法律学校的计划。若不是帐篷车很容易就修好了,他本打算邀请她和孩子们来家过夜。她正准备去特金巴厘尔她父母的避暑屋。
“那她就不可能真那么穷。”特鲁迪说。
“父母有钱,你也可以很穷啊。”丹说。
“不,不可能。”
去年夏天,罗宾到列治文山住了一个月。她提前返回了,说那里简直是所疯人院。最大的孩子要上特殊阅读治疗所,第二大的孩子尿床。吉纳维芙的所有时间都在法律图书馆学习。不是才怪。丹负责买食品、烧饭、照料孩子、种菜,星期六和星期天开出租车。他想在车库开个摩托车修理店,但没被允许。邻居们反对。
他告诉罗宾他很开心。从没这么快乐,他说。罗宾回家后完全成了个大人—严厉、好挖苦、说一不二。她多了几丝前所未有的、淡淡的、根深蒂固的怨恨之情。特鲁迪没法哄她说出来,逗她也没用。那些手段能生效的阶段已经过去。
罗宾中午回家,换了衣服。她穿上一件浅色印花棉布衬衫,熨平一条浅蓝色棉裙。她说,班上有些女孩或许下课后会去殡仪馆。
“我忘了你还有那条裙子。”特鲁迪说。要是她以为能借此展开一点交谈,那可错了。
与丹初次邂逅时,特鲁迪喝得醉醺醺的。她十九岁,高个儿,瘦瘦的(现在依然如此),一头狂野的黑色卷发(现在剪短了,像通常的黑头发一样已有几缕灰色)。她晒得很黑,穿牛仔裤和扎染T恤。没穿胸衣,也没那必要。那是八月,在穆苏科卡[3]一家有乐队的旅馆酒吧里。她正与一些女朋友宿营。他和未婚妻玛莱娜也在那里。他带玛莱娜回家见他妈,后者在穆苏科卡湖的一个岛上,住在空无一人的旅馆里。特鲁迪十九岁,他二十八岁。她在他和玛莱娜的桌前独舞,头昏眼花,醉醺醺的。玛莱娜是个模样挺温顺的金发女郎,粉色胸部巨大挺拔,挂满小小的人造珍珠做的链子。特鲁迪在他面前执着地跳舞,直到他站起来加入她。跳完后他问她的名字,带她回桌子,介绍给玛莱娜。
“这位是茱迪。”他说。特鲁迪笑瘫在玛莱娜旁边的椅子上。丹带玛莱娜去跳舞了。她喝掉玛莱娜的啤酒,去找自己的朋友们。
“你们好啊,”她对她们说,“我叫茱迪!”
他在酒吧门口追上她。看到特鲁迪要离开,他就和玛莱娜分手了。一个能够飞速改变计划,看出各种可能性,燃烧起全新热情的男人。他事后告诉别人,他还不知道特鲁迪真名就已经爱上了她。不过他对特鲁迪坦言,和玛莱娜分手时他哭了。
“我也有感情,”他说,“不怕流露出来。”
特鲁迪对玛莱娜则毫无感情。玛莱娜已经过了三十岁—还能指望什么?玛莱娜现在还住在镇上,在水电公司工作,没结婚。一次,特鲁迪和丹讨论着吉纳维芙,特鲁迪说:“玛莱娜一定会想,我真是罪有应得啊。”
丹说,他听说玛莱娜加入了圣经基督教会。里面的女人禁止化妆,星期天去教堂必须戴一种无边帽。
“她的脑子里不会有别的想法,只有宽恕。”丹说。
特鲁迪说:“我相信。”
关于殡仪馆的事,特鲁迪从凯尔文和珍妮特处都听到了同样的版本。
特雷西·李班上的女生放学后全去了。她们正赶上所谓的探问期,特雷西·李的家人都守在敞开的棺木边接待亲友。她爸妈都在,已婚的哥哥和老婆,姐姐,甚至卡车的主人,姐姐的男朋友也在。他们站成一排,人们列队走过,说几句安慰话。来了很多人。这种时候总是如此。特雷西·李的祖母排最后,坐在一把锦缎椅子上。她没法长时间站着。
殡仪馆的所有椅子都裹着这种白色金色锦缎。窗帘也是同样的布料,墙纸与之相配,可谓尽善尽美。墙上装着小支架灯,镶着厚厚的粉色玻璃。特鲁迪去过几次,知道那里是什么样。但是罗宾和大多数女孩从没去过,里面的样子让她们始料未及。她们有几个几乎一进门就抽泣起来。
窗帘关着。播放着轻柔的音乐—并不是真的教堂音乐,不过听起来很像。特雷西·李的棺木白底金边,与锦缎和墙纸相配,里面衬着打褶的粉色缎子,垫一个粉色缎枕。特雷西·李的脸上毫无伤痕。她并不像平时那样化妆,因为这回是葬礼承办人帮她化的。不过她戴着心爱的耳环,绿松石色的三角形和黄色新月形,每只耳朵戴两个。(有人觉得这品位很差劲。)棺木里自她腰部以下都盖着,上面摆了个粉色玫瑰组成的巨大心形枕头。
女孩们列队上前跟死者的家人说话,和他们握手,说“你痛失挚爱我很难过”,就像所有其他人做的一样。做完这个,等她们所有人都让老祖母用温暖、肿胀、布满雀斑的手握了握自己冰凉的小手之后,她们又三三两两排起队,从棺木前走过。她们中很多人已经哭起来,浑身颤抖。你还能指望什么呢?小姑娘们嘛。
不过她们一边走,一边唱起歌。开始有点拘谨害羞,渐而悲哀、甜蜜的声音变得自信起来,她们唱道:
现在啊,当鲜花仍旧长在藤上,
我要品尝你的草莓,我要痛饮你的蜜酒……
当然,她们事先计划了一切。她们从一张唱片里挑出这歌,相信它是一首古老的赞美诗。
她们就这么列队走过,唱着歌,低头看着特雷西·李。人们注意到她们往棺材里丢起东西。从手指上、胳膊上抹下戒指和手镯,从耳朵上摘下耳环。解开项链,弯腰从头上扯下链子和长珠串。每个人都丢进点什么。所有这些闪闪发亮的首饰都滑落到死去的女孩身上,和她一起躺在棺木里。一个女孩从头发上扯下亮闪闪的梳子,也丢了进去。
没人站出来制止。谁会那么煞风景呢?这简直像一场宗教仪式。女孩们好像听人讲解过该怎么做似的,好像这是个寻常的惯例。她们唱歌,抽泣,丢下珠宝。仪式感令她们每个人都显得很优雅。
这家人也没阻止她们。他们觉得很美。
“就像在教堂里啊。”特雷西·李的妈妈感叹道。祖母则说:“这些可爱的小姑娘都爱特雷西·李。要是她们想献出首饰,表明她们的爱,这是她们自己的事儿。这个不关别人的事儿。我觉得这很美。”
特雷西·李的姐姐瘫倒在地,失声痛哭,这是她首次这么做。
丹说:“这是对爱的考验。”
他指的是特鲁迪的爱。特鲁迪开始唱歌:“请放开我吧,放开我哟……”
她一只手按住胸口,唱着歌,满屋子飞舞。丹又像要哭,又像要笑。他没法控制自己。他上前抱住她,两人一起踉踉跄跄跳起舞。他们都醉得可以。整个六月(那是两年前),他们在一轮一轮爆发的间歇以及其间都在喝杜松子酒。喝酒、哭泣、争论、解释,特鲁迪不得不频频冲到酒店。不过她不记得真喝得烂醉,或者酒后头疼。只记得始终那么累,好像脚踝上拴着铅块。
她不断插科打诨,管吉纳维芙叫“吉纳傻乎乎”。
“这和打算放弃生意去做个制陶工是一回事。”她说,“没准你真该那么做的。我并不是真的反对。你自己放弃了。还有你想去秘鲁那次。我们现在还可以那么做。”
“那都是陈年旧事了。”丹说。
“我早该知道的,从你开始在电视上看《检察官》的时候。”特鲁迪说,“那是法律片,对吗?你以前对那类事从没那么感兴趣过。”
“你也可以打开生活之门嘛。”丹说,“你不必仅仅是我的老婆。”
“当然。我想我会去做个脑科专家。”
“你非常聪明。你是一个出色的女人,很勇敢。”
“你确定不是在说吉纳傻乎乎?”
“不,是你。是你啊,特鲁迪。我仍旧爱你。你没法理解我仍然爱着你。”
多年来他都不再如此强调多么爱她。他爱她瘦瘦的身材,她的鬈发,她变得粗糙的皮肤,她大踏步进屋,震得窗子嗡嗡响的样子,她的调侃,她的滑稽举止,她直率的说话方式。他爱她的思想和灵魂。他永远爱。不过他的生命和她相连的阶段已经过去。
“这纯粹是胡扯。尽是些蠢话!”特鲁迪说,“罗宾,回床上去!”因为罗宾正穿着很少的睡衣站在楼梯顶。
“我听到你们又喊又叫的。”罗宾说。
“我们没有又喊又叫,”特鲁迪说,“只是在讨论一些私人问题。”
“是什么?”
“我说过了,是私人问题。”
罗宾闷闷不乐地回到床上,丹说:“我想我们该告诉她了。孩子们最好知道这些。吉纳维芙就从不瞒着她的孩子们什么。乔西才五岁,一天下午她走进卧室……”
特鲁迪真的号叫起来,撕扯着一个垫子。“给我住嘴,别跟我提你那个甜蜜的狗屁吉纳维芙和她甜蜜的狗屁卧室和她那些狗崽子们……给我住嘴,别再讲了!你就是一个没脑袋的大漏嘴。爱干吗干吗去,给我住嘴就行了!”
丹走了。他拎个手提箱,去了列治文山。五天之后他回来了。进镇之前,他停下车给特鲁迪摘了一大抱野花。他告诉她他彻底回来了。那事结束啦。
“你确定?”特鲁迪说。
不过她把花插到水里。沾着尘土的粉色乳草花,闻起来像香粉,乌眼金光菊,野香豌豆花,还有橙色百合花,想必是从古老遗弃的花园里蔓延出来的。
“这么说,你搞不定她了?”她说。
“就知道你不会给我什么好脸色,”丹说,“不那样就不是你了。而我回来就是为了你。”
她去了酒店,不过这回是去买香槟。整整一个月—夏天尚未过去—他们恢复了过去的快乐。她从没真正搞清在吉纳维芙家发生了什么。丹说他只是经历了一场中年危机,如此而已。他恢复理智了。这里才是他的生活,她和罗宾才是。
“你说话真像个婚姻问题专家。”特鲁迪说。
“够啦,忘掉这整件事吧。”
“我们最好如此。”她说。她可以想象那堆孩子,那种混乱,那些朋友们—没准还有她从前的男朋友们—都令他措手不及。他听不懂的笑话和意见。那个很有可能。他喜欢的音乐,他说话的方式—甚至他的发型和胡子—或许都已经过时了。
他们继续全家开车出游、野餐,晚上躺在屋后草地上看星星。星星现在是丹的新兴趣所在。他弄了一张地图。他们频频拥抱、接吻,做爱时尝试一些新鲜做法—或是已经很久没尝试的做法。
此刻,房前的路在铺路面。他们的房子造在镇边山坡上,比别的房子位置远,不过卡车现在经常绕开大路,打这里走,所以镇上来铺路了。特鲁迪习惯了这些噪声和震动,她说即使夜里万籁俱寂,她也觉得自己在晃动。早上七点就开工了。他们醒来时总是深陷一片噪声的汪洋大海。丹不得不勉强起床,没法享受他最喜欢的那一个小时睡眠。空气中一股柴油味。
一天晚上,她醒来后发现他不在床上。她听听厨房或浴室里是不是有动静。没有。她起床在家里找了一圈。灯都没开。她发现他坐在房外,就在门口,没在喝酒或牛奶或咖啡,只是背对大街坐着。
特鲁迪打量一番掀开的地面和巨大的机器。“这么安静,多可爱啊。”她说。
他一言不发。
唉,唉。
她意识到自己发现了他那侧的床空着,家里任何地方都听不到他的声音时她的想法。不是他离开了她,而是干了更糟的事。他了结了自己。在所有他们那些快乐、拥抱、接吻、星星和野餐之后,她居然还会这么想。
“你忘不掉她,”她说,“你爱她。”
“我不知道该怎么办。”
听到他开口了,她很高兴。她说:“你得再去试一次。”
“我没法保证能留下,”他说,“我不能要求你支持我。”
“不,”特鲁迪说,“你去,那就行了。”
“我去,那就行了。”
他好像呆若木鸡。她觉得他没准会一直这么坐着,重复她的话,既没法行动,也不会自己说话。
“既然你这么觉得,那就够了。”她说,“你不需要选择。你已经不在这里啦。”
这话生了效。他僵硬地站起身,上前抱住她,拍拍她的背。
“回床上去吧,”他说,“我们还有点时间休息一下。”
“不。你得在罗宾起床前就走。要是我们回到床上,这一切又要从头开始了。”
她给他备了一暖壶咖啡。他收拾了上次带去的箱子。特鲁迪的每个举动都显得灵巧完美,大不同于平时。她感觉心如止水。她觉得仿佛他们是对老夫老妻,琴瑟和鸣,无须言爱,超越了伤害,超越了宽恕。他们的告别几乎波澜不兴。她陪他走到门外,那是在四点半到五点之间。天空开始发白,鸟儿醒了,一切浸润着露水,巨大无害的机器卡在路上的车辙当中。
“幸好这不是在昨晚—那会儿你可走不了。”她说。她的意思是,路那会儿还不能通行。恰好在昨天,他们才修出一条窄窄的路面供当地车辆使用。
“幸好。”他说。
再见。
“我只想问问你为什么这样做。就是为了出风头吗?就像你爸—为了出风头?其实不完全是项链的问题。不过它很好看—我喜欢墨玉珠子。这是我们唯一的一件你奶奶的东西了。这是你的权利,可你无权那样瞒过我。我有权要求一个解释。我一直喜欢墨玉珠子的。究竟为什么?”
“我觉得要怪那家人。”珍妮特说,“他们该阻止这事的。有些首饰是塑料的—廉价耳环啊,手镯啊—但是罗宾丢进去的那个,那简直就是犯罪啊。而且她不是唯一一个。有人丢进了生日石戒指和金链子。还有人说丢进了碎钻戒指呢,不过我不能肯定那是不是真的。他们说那女孩是通过继承得到它的,就像罗宾一样。你从来没拿它估过价吧,有吗?”
“估计墨玉不值钱吧。”特鲁迪说。
她们坐在珍妮特家的前厅,用粉色餐巾纸做玫瑰。
“真够蠢的。”特鲁迪说。
“嗯。你可以做一件事来着,”珍妮特说,“我不知道该怎么说。”
“什么?”
“祈祷。”
根据珍妮特的语调,特鲁迪还以为她要说一件严肃、令人不快的事,某件关于她本人—特鲁迪—的事,它影响着她的生活,所有人都知道,只有她自己除外。白紧张一场,她忍不住想笑,不知如何接茬。
“你不祈祷的,对吗?”珍妮特问。
“我不反感,”特鲁迪说,“只是从小就没被灌输过宗教。”
“那并不是严格意义上的宗教,”珍妮特说,“我的意思是,它和任何教会都没有关系。只是我们一些人自己祈祷。我一个名字也不能告诉你,不过他们大多数你都认识。这是要保密的。它叫作祈祷之圈。”
“就像高中时一样,”特鲁迪说,“高中也有些秘密社团,里面成员的名字都要保密。不过我没参加过。”
“我好像啥事都有份。”珍妮特叹了口气,“实际上这个是比较严肃的。尽管我想里面有些人不够认真。有些人哪,他们祈祷只为了找到个停车位,或者假日能有个好天气。其实它不是为这种事而设的。不过那些只是个人的祈祷罢了。祈祷之圈是这么回事,你给里面随便什么人打个电话,告诉他们你为什么而担心或不安,请他们为你祈祷。他们就会这样做。他们会给圈子里的人打电话,一个通知一个,让所有人都知道。然后我们会为这个人祈祷,全体一起。”
特鲁迪丢下一朵玫瑰。“这朵做坏了。全都是女人吗?”
“并没规定非得这样。不过确实是的。男人不好意思做这个。我一开始也有点不好意思。只有你打电话过去的第一个人知道你的名字,知道祈祷是为了谁,不过在这样一个小镇上,几乎谁都能猜出来。不过,要是我们开始八卦,互相泄密,就没效果了。所有人都明白这个,所以我们不会。而它确实有效。”
“如何有效?”特鲁迪问。
“嗯,一个女孩撞了车,损失了八百元,情况很棘手,她不确定保险是否能赔偿,她老公也不知道—他气疯了—不过我们做了祈祷,结果保险赔偿了,一点问题没有。这只是其中一个例子罢了。”
“项链在棺材里,葬礼今天早上举行,为了弄回它而祈祷,估计没啥用啦。”特鲁迪说。
“可轮不到你说这个。你哪知道什么可能,什么不可能?你只需要说出心愿就够了。因为圣经里是这样说的:‘你们祈求,就给你们。’要是不提出心愿,你怎么得到帮助呢?那样肯定是不行的。丹离开的时候,要是—要是你那时就祈祷了,会怎样?我那会儿还不在这个圈子里,不然我会跟你建议的。哪怕我知道你会拒绝,我还是会劝你。很多人都抗拒这个。现在,哪怕—虽说听起来对那女孩不大恭敬,不过你哪里知道呢?没准现在也会有效呢?或许还不算太晚。”
“好吧,”特鲁迪用机械的愉快声调说,“好吧。”她从膝盖上推开那堆软绵绵的花。“我现在就跪下,祈祷我能让丹回来。我要祈祷让项链和丹都回来。我干吗就祈祷这么点?我可以祈祷特雷西·李根本没死。我要祈祷让她起死回生。她妈怎么从没想到过这个?”
好消息。游泳池修好了。明天就可以给它灌水。不过凯尔文不开心。今天下午早些时候—部分是为了防止影响在游泳池里忙活的人—他带玛丽和约瑟芬进了城。他给她们买冰激凌蛋筒,告诉她们注意点,赶紧吃,因为太阳很热,冰激凌会化。可她们过一会儿才舔一下蛋筒,好像有一整天时间吃它似的。很快冰激凌就滴到她们的下巴和胳膊上。凯尔文抓了一把餐巾纸,但来不及帮她们擦掉。弄得一团糟。真是一场好戏啊。她们还满不在乎。凯尔文告诉她们,弄成这样,她们就不好看了。
“有人不管怎样都不喜欢我们的样子,”他说,“有人甚至觉得不该允许我们进城。人们刚刚才习惯看到我们,不再像盯着疯子一样盯着我们瞧,你俩就惹出麻烦,把事情又搞糟啦。”
她们笑话他。要是只有玛丽一个人,他还可以吓唬吓唬她,但她和约瑟芬在一起时就没用了。凯尔文认为,确实该给约瑟芬来一点传统的教训了。凯尔文去过一些地方,在那里谁要是犯了她们刚才的错,可没那么容易逃脱。他不赞同体罚。他看到过好多这种事,但是他不赞同,哪怕打手心也不行。不过像约瑟芬这样的家伙,真该被锁在她的房间里。罚她坐角落,只给她面包和水,那对她大有好处。对于玛丽,只用好好跟她谈一谈就行—她很容易被说服。但约瑟芬简直就是个恶魔。
“我来跟她俩谈谈,”特鲁迪说,“我要让她俩都道歉。”
“我希望她们意识到自己做错了,”凯尔文说,“才不要她们口头上说说。我再也不带她们出去了。”
后来,所有其他人都上床后,特鲁迪让他坐下来,在装纱窗的走廊上和她打牌。他们玩的是找对子。凯尔文说他今晚只能玩这个。他脑袋晕乎乎的。
在城里,有个男人问他:“嗨,这里面哪个是你女朋友啊?”
“蠢蛋,”特鲁迪说,“他是个愚蠢的笨蛋。”
那人身边的另一个人说:“你打算娶哪个啊?”
“他们不认识你,凯尔文。他们只是两个傻瓜罢了。”
但是他们认识他。一个是李格·胡波,另一个是巴德·德莱斯。巴德·德莱斯是个卖房子的。他俩都认识他。他们在理发店跟他说过话。他们叫他凯尔文。“嗨,凯尔文,你打算娶哪个啊?”
“白痴。”特鲁迪说,“罗宾肯定会这么叫他们。”
“你以为他们是你朋友,可他们不是,”凯尔文说,“这种事我见多了。”
特鲁迪去厨房煮咖啡。她想等珍妮特来的时候,让她喝上新鲜咖啡。今天早上她道了歉。珍妮特说,没事,我知道你心情不好。真的没事。有时你觉得是朋友的,确实是朋友。
她看看挂在钩子上的各种杯子。她和珍妮特从四处搜集来的。每个杯子上都有一个人的名字。玛丽、约瑟芬、阿瑟、凯尔文、谢莉、乔治、多林达。你会以为多林达是最难找的一个,其实是谢莉。甚至不识字的人也学会通过颜色和形状认出自己的杯子。
一天,两个新杯子出现了,都是凯尔文买来的。一个写着特鲁迪,另一个写着珍妮特。
“看到自己的名字被归入这一堆,我可不会欣喜若狂。”珍妮特说,“不过哪怕给我一百万,我也不想伤他的感情。”
蜜月里,丹带特鲁迪去他妈妈开旅馆的小岛。旅馆已经停业,不过他妈仍住在里面。他爸爸去世了,她独自生活。她开一艘装便携马达的小船,出岛购买食品。她有时会弄混,管特鲁迪叫玛莱娜。
旅馆没多大,就是位于海边一片平地上的一个白色木头盒子。几个小小的舱房盒子堆在它后头。丹和特鲁迪住在这些舱房中的一间。每间舱房都有一个烧柴的火炉子。丹晚上会点火驱赶寒气。不过早上他和特鲁迪醒来时,毯子依旧总是又湿又重。
丹会抓鱼,煮着吃。他和特鲁迪会爬到舱房后头的大岩石上摘蓝莓。他问她会不会做馅饼皮,她不会。他便教她,擀面团用的是威士忌酒瓶。
早上,湖上总是一团雾,就像你在电影或者画上看到的一样。
一天下午,丹在外面钓鱼,回来比平时晚。特鲁迪在厨房忙了一阵,擦灰尘,洗罐子。这是她见过的最古旧、最阴暗的厨房,用几个木架晾干晚餐碟。她走出门,独自爬上岩石,想摘蓝莓。不过树下已经黑乎乎的,常青藤遮天蔽日,她怕遇到野兽。她坐在岩石上,看着下方的旅馆屋顶、古老的枯叶和开裂的屋瓦。她听到钢琴声。她从岩石上笨拙地爬下,循声而去,走到旅馆前部。她沿前廊走着,在一扇窗前停下,瞥进曾是客厅的房间。屋里有发黑的石头壁炉、笨重的皮椅子和可怕的鱼标本。
丹的妈妈在里面弹琴。一个高个儿、背挺得笔直的老太太,灰黑色头发盘成那样小的一个发髻。她坐在那儿弹琴,没开灯,在昏暗、空荡荡的房间里。
丹说过他妈生在有钱人家,上过钢琴和舞蹈课,年轻时周游过世界。她有一张骑骆驼的照片。不过她弹的不是一首你以为她学过的古典曲子。她弹的是《清晨三点》。弹完一遍,又从头弹起。或许是她特别喜欢的一首曲子,昔日曾经伴着它跳过舞?也可能她弹得不满意,想弹好一点。
特鲁迪为什么对这个时刻念念不忘?她看到年轻的自己瞥进窗子,看着老太太弹琴。昏暗的房间,比例过大的横梁和壁炉,孤独的皮椅子。顿挫迟疑而又绵延不断的钢琴声。一切历历在目,仿佛她就站在自己身边,身体正因为痛苦难耐的爱之欢乐而疼痛。她旁观自己的欢乐,心头泛着悲哀之潮。丹离开的那个早上,情况正好相反。那时,她旁观自己的痛苦,心头却涌动着一股貌似不该有的柔情。不过,但凡你能置身事外,差别就不大了。那些刻骨铭心的时刻,那些记忆犹新的人生片段,它们到底算什么呢?—它们和你的生命有何关联?它们甚至连允诺都不是。喘息的空间。仅仅如此吗?
她走进前厅,听听楼上有没有动静。
到处静悄悄的。都服过药了。
电话就在她耳边响起。
“你还在吗?”罗宾问,“还没走吗?”
“我还在。”
“我跑过来坐你的车一道回家行吗?我今天跑得有点迟了,天太热啦。”
你砸了那酒壶。你差点砸死我。
是的。
凯尔文坐在灯下,在牌桌边等着,看起来苍白老迈。灯光把他的棕色头发照成白色。他发着呆,面颊凹陷。他显得苍老萎靡,一脸困顿,几乎没认出她。
“凯尔文,你祈祷吗?”特鲁迪问。话一出口,她自己都吃了一惊。“我是说,这不关我的事。不过,会不会为了什么特别的事祈祷呢?”
他的回答相当出乎她的意料。他的脸色明朗起来,仿佛感觉到了能拉他出水的力量。
“要是我足够聪明,知道该为什么祈祷的话,”他说,“不过那样我也就不用祈祷啦。”
他冲她微笑,说着这个不够地道的笑话,带点推心置腹的意味。并非特别作为一种安慰而说,可是却暖人心扉—他说的话,他说话的神情,甚至仅仅是他又清醒过来这个事实本身—就像你精疲力竭时,一些糊涂念头莫名其妙就会温暖人心,光芒四射。在她还年轻亢奋的时候,也是这样的。某人,或者某个时刻,突然之间便会显得完美而亲切,宛如一朵漂浮在雾霭之河上的睡莲。
[1] 1958—1981,加拿大人道主义者、运动员。1980年在一条腿截肢之后,跑步横穿加拿大,为癌症研究组织筹款。
[2] 始于1978年的美国肥皂剧,一直播放到1991年。
[3] 加拿大湖区,著名蜜月胜地。
"""
契诃夫的等待-余华
========================
契诃夫的等待-[[余华]]
------
安·巴·[[契诃夫]]在本世纪初创作了剧本《三姐妹》,娥尔加、玛莎和衣丽娜。她们的父亲是一位死去的将军,她们哥哥的理想是成为一名大学教授,她们活着,没有理想,只有梦想,那就是去莫斯科。莫斯科是她们童年美好时光的证词,也是她们成年以后唯一的向往。她们日复一日,年复一年地等待着,岁月流逝,她们依然坐在各自的椅子里,莫斯科依然存在于向往之中,而“去”的行为则始终作为一个象征,被娥尔加、玛莎和衣丽娜不断透支着。
这个故事开始于一座远离莫斯科的省城,也在那里结束。这似乎是一切以等待为主题的故事的命运,周而复始,叙述所渴望到达的目标,最终却落在了开始处。
半个世纪以后,萨缪尔·贝克特写下了《等待戈多》,爱斯特拉冈和弗拉季米尔,这两个流浪汉进行着重复的等待,等待那个永远不会来到的名叫戈多的人。最后,剧本的结尾还原了它的开始。
这是两个风格相去甚远的剧作,它们风格之间的距离与所处的两个时代一样遥远,或者说它们首先是代表了两个不同的时代,其次才代表了两个不同的作家。又是半个世纪以后,林兆华的戏剧工作室将《三姐妹》和《等待戈多》变成了《三姐妹·等待戈多》,于是另一个时代介入了进去。
有趣的是,这三个时代在时间距离上有着平衡后的和谐,这似乎是命运的有意选择,果真如此的话,这高高在上的命运似乎还具有着审美的嗜好。促使林兆华将这样两个戏剧合二为一的原因其实十分简单,用他自己的话说,就是“等待”。“因为‘等待’,俄罗斯的‘三姐妹’与巴黎的‘流浪汉’在此刻的北京相遇。”
可以这么说,正是契诃夫与贝克特的某些神合之处,让林兆华抓到了把柄,使他相信了他们自己的话:“一部戏剧应该是舞台艺术家以极致的风格去冲刺的结果。”这段既像宣言又像广告一样的句子,其实只是为了获取合法化的自我辩护。什么是极致的风格?1901年的《三姐妹》和1951年的《等待戈多》可能是极致的风格,而在1998年,契诃夫和贝克特已经无须以此为生了。或者说,极致的风格只能借用时代的目光才能看到,在历史眼中,契诃夫和贝克特的叛逆显得微不足道,重要的是他们展示了情感的延续和思想的发展。林兆华的《三姐妹· 等待戈多》在今天可能是极致的风格,当然也只能在今天。事实上,真正的意义只存在于舞台之上,台下的辩护或者溢美之词无法烘云托月。
将契诃夫忧郁的优美与贝克特悲哀的粗俗安置在同一个舞台和同一个时间里,令人惊讶,又使人欣喜。林兆华模糊了两个剧本连接时的台词,同时仍然突出了它们各自的语言风格。舞台首先围起了一摊水,然后让水围起了没有墙壁的房屋,上面是夜空般宁静的玻璃,背景时而响起没有歌词的歌唱。三姐妹被水围困着,她们的等待从一开始就被强化成不可实现的纯粹的等待。而爱斯特拉冈和弗拉季米尔只有被驱赶到前台时才得以保留自己的身份,后退意味着衰老五十年,意味着身份的改变,成为了中校和男爵。这两个人在时间的长河里游手好闲,一会儿去和玛莎和衣丽娜谈情说爱,一会儿又跑回来等待戈多。
这时候更能体会契诃夫散文般的优美和贝克特诗化的粗俗,舞台的风格犹如秀才遇到了兵,古怪的统一因为风格的对抗产生了和谐。贝克特的台词生机勃勃,充满了北京街头的气息,契诃夫的台词更像是从记忆深处发出,遥远的像是命运在朗诵。
林兆华希望观众能够聆听,“听听大师的声音”,他认为这样就足够了。聆听的结果使我们发现在外表反差的后面,更多的是一致。似乎舞台上正在进行着一场同性的婚姻,结合的理由不是相异,而是相同。
《三姐妹》似乎是契诃夫内心深处的叙述,如同那部超凡脱俗的《草原》,沉着冷静,优美动人,而不是《一个官员的死》这类聪明之作。契诃夫的等待犹如不断延伸的道路,可是它的方向并不是远方,而是越来越深的内心。娥尔加在等待中慢慢衰老起来;衣丽娜的等待使自己失去了现实对她的爱──男爵,这位单相思的典范最终死于决斗;玛莎是三姐妹中唯一的已婚者,她似乎证实了这样的话:有婚姻就有外遇。玛莎突然爱上了中校,而中校只是她们向往中的莫斯科的一个阴影,被错误地投射到这座沉闷的省城,阳光移动以后,中校就被扔到了别处。
跟随将军的父亲来到这座城市的三姐妹和她们的哥哥安得列,在父亲死后就失去了自己的命运,他们的命运与其掌握者──父亲,一起长眠于这座城市之中。
安得列说:“因为我们的父亲,我和姐妹们才学会了法语、德语和英语,衣丽娜还学会了意大利语。可是学这些真是不值得啊!”
玛莎认为:“在这城市里会三国文字真是无用的奢侈品。甚至连奢侈品都说不上,而是像第六个手指头,是无用的附属品。”
安得列不是“第六个手指”,他娶了一位不懂得美的女子为妻,当他的妻子与地方自治会主席波波夫私通后,他的默许使他成为了地方自治会的委员,安得列成功地将自己的内心与自己的现实分离开来。这样一来,契诃夫就顺理成章地将这个悲剧人物转化成喜剧的角色。
娥尔加、玛莎和衣丽娜,她们似乎是契诃夫的恋人,或者说是契诃夫的“向往中的莫斯科”。像其他的男人希望自己的恋人洁身自好一样,契诃夫内心深处的某些涌动的理想,创造了三姐妹的命运。他维护了她们的自尊,同时也维护了她们的奢侈和无用,最后使她们成为了“第六个手指”。
于是,命中注定了她们在等待中不会改变自我,等待向前延伸着,她们的生活却是在后退,除了那些桦树依然美好,一切都在变得今不如昔。这城市里的文化阶层是一支军队,只有军人可以和她们说一些能够领会的话,现在军队也要走了。
衣丽娜站在舞台上,她烦躁不安,因为她突然忘记了意大利语里“窗户”的单词。
安·巴·契诃夫的天才需要仔细品味。岁月流逝,青春消退,当等待变得无边无际之后,三姐妹也在忍受着不断扩大的寂寞、悲哀和消沉。这时候契诃夫的叙述极其轻巧,让衣丽娜不为自己的命运悲哀,只让她为忘记了“窗户”的意大利语单词而伤感。如同他的同胞柴可夫斯基的《悲怆》,一段抒情小调的出现,是为了结束巨大的和绝望的管弦乐。契诃夫不需要绝望的前奏,因为三姐妹已经习惯了自己的悲哀,习惯了的悲哀比刚刚承受到的更加沉重和深远,如同挡住航道的冰山,它们不会融化,只是在某些时候出现裂缝。当裂缝出现时,衣丽娜就会记不起意大利语的“窗户”。
萨缪尔·贝克特似乎更愿意发出一个时代的声音,当永远不会来到的戈多总是不来时,爱斯特拉冈说:“我都呼吸得腻烦啦!”
弗拉季米尔为了身体的健康,同时也是为了消磨时间,提议做一些深呼吸,而结果却是对呼吸的腻烦。让爱斯特拉冈讨厌自己的呼吸,还有什么会比讨厌这东西更要命了?贝克特让诅咒变成了隐喻,他让那个他所不喜欢的时代自己咒骂自己,用的是最恶毒的方式,然而又没有说粗话。
与契诃夫一样,贝克特的等待也从一开始就画地为牢,或者说他的等待更为空洞,于是也就更为纯粹。
三姐妹的莫斯科是真实存在的,虽然在契诃夫的叙述里,莫斯科始终存在于娥尔加、玛莎和衣丽娜的等待之中,也就是说存在于契诃夫的隐喻里,然而莫斯科自身具有的现实性,使三姐妹的台词始终拥有了切实可信的方向。
爱斯特拉冈和弗拉季米尔的戈多则十分可疑,在高度诗化之后变得抽象的叙述里,戈多这个人物就是作为象征都有点靠不住。可以这么说,戈多似乎是贝克特的某一个秘而不宣的借口;或者,贝克特自己对戈多也是一无所知。因此爱斯特拉冈和弗拉季米尔的等待也变得随心所欲和可有可无,他们的台词犹如一盘散沙,就像他们拼凑起来的生活,没有目标,也没有意义,他们仅仅是为了想说话才站在那里滔滔不绝,就像田野里耸立的两支烟囱要冒烟一样,可是他们生机勃勃。
贝克特的有趣之处在于:如果将爱斯特拉冈和弗拉季米尔的任何一句台词抽离出来,我们会感到贝克特给了我们活生生的现实,可是将它们放回到原有的叙述之中,我们发现贝克特其实给了我们一盘超现实的杂烩。
大约十年前,我读到过一位女士的话。在这段话之前,我觉得有必要提醒一下,这位女士一生只挚爱一位男子,也就是她的丈夫。现在,我们可以来听听她是怎么说的,她说:当我完全彻底拥有一位男人时,我才能感到自己拥有了所有的男人。
这就是她的爱情,明智的、洞察秋毫的和丰富宽广的爱情。当她完全彻底拥有了一位男人,又无微不至地品味后,她就有理由相信普天之下的男人其实只有一个。
同样的想法也在一些作家那里出现,博尔赫斯说:“许多年间,我一直认为几近无限的文学集中在一个人身上。”接下去他这样举例:“这个人曾经是卡莱尔、约翰尼斯·贝希尔、拉法埃尔·坎西诺斯-阿森斯和狄更斯。”
虽然博尔赫斯缺乏那位女士忠贞不渝的品质,他在变换文学恋人时显得毫无顾虑,然而他们一样精通此道。对他们来说,文学的数量和生活的数量可能是徒劳无益的,真正有趣的是方式,欣赏文学和品尝生活的方式。马赛尔·普鲁斯特可能是他们一致欣赏的人,这位与哮喘为伴的作家有一次下榻在旅途的客栈里,他躺在床上,看着涂成海洋颜色的墙壁,然后他感到空气里带有盐味。普鲁斯特在远离海洋的时候,依然真实地感受着海洋的气息,欣赏它和享受它。这确实是生活的乐趣,同时也是文学的乐趣。
在《卡夫卡及其先驱者》一文里,博学多才的博尔赫斯为卡夫卡找到了几位先驱者,“我觉得在不同国家、不同时代的文学作品中辨出了他的声音,或者说,他的习惯”。精明的博尔赫斯这样做并不是打算刁难卡夫卡,他其实想揭示出存在于漫长文学之中的“继续”的特性,在鲜明的举例和合理的逻辑之后,博尔赫斯告诉我们:“事实是每一位作家创造了他自己的先驱者。”
在这个结论的后面,我们发现一些来自于文学或者艺术的原始的特性,某些古老的品质,被以现代艺术的方式保存了下来,从而使艺术中“继续”的特性得以不断实现。比如说等待。
马赛尔·普鲁斯特在其绵延不绝的[[《追忆似水年华》]]里,让等待变成了品味自己生命时的自我诉说,我们经常可以读到他在床上醒来时某些甜蜜的无所事事,“醒来时他本能地从中寻问,须臾间便能得知他在地球上占据了什么地点,醒来前流逝了多长时间”。或者他注视着窗户,阳光从百叶窗里照射进来,使他感到百叶窗上插满了羽毛。
只有在没有目标的时候,又在等待自己的某个决定来到时,才会有这样的心情和眼睛。等待的过程总是有些无所事事,这恰恰是体会生命存在的美好时光。而普鲁斯特与众不同的是,他在入睡前就已经开始了──“我情意绵绵地把腮帮贴在枕头的鼓溜溜的面颊上,它像我们童年的脸庞,那么饱满、娇嫩、清新。”
等待的主题也在但丁的漫长的诗句里反复吟唱,《神曲·炼狱篇》第四歌中,但丁看到他的朋友,佛罗伦萨的乐器商贝拉加在走上救恩之路前犹豫不决,问他你为什么坐在这里?你在等待什么?随后,但丁试图结束他的等待,“现在你赶快往前行吧……”
你看太阳已经碰到了子午线,
黑夜已从恒河边跨到了摩洛哥。
普鲁斯特的等待和但丁的等待是叙述里流动的时间,如同河水抚摸岸边的某一块石头一样,普鲁斯特和但丁让自己的叙述之水抚摸了岸边所有等待的石头,他们的等待就这样不断消失和不断来到。因此,《神曲》和《追忆似水年华》里的等待总是短暂的,然而它们却是饱满的,就像“蝴蝶虽小,同样也把一生经历”。
与《三姐妹》和《等待戈多》更为接近的等待,是巴西作家若昂·吉马朗埃斯·罗萨的《河的第三条岸》,这部只有六千字的短篇小说,印证了契诃夫的话,契诃夫说:“我能把一个长长的主题简短地表达出来。”
“父亲是一个尽职、本分、坦白的人。”故事的叙述就是这样朴素地开始,并且以同样的朴素结束。这个“并不比谁更愉快或更烦恼”的人,有一天订购了一条小船,从此开始了他在河上漂浮的岁月,而且永不上岸。他的行为给他的家人带去了耻辱,只有叙述者,也就是他的儿子出于某些难以言传的本能,开始了在岸边漫长的等待。后来叙述者的母亲、哥哥和姐姐都离开了,搬到了城里去居住,只有叙述者依然等待着父亲,他从一个孩子开始等待,一直到白发苍苍。
“终于,他在远处出现了,那儿,就在那儿,一个模糊的身影坐在船的后部。我朝他喊了好几次。我庄重地指天发誓,尽可能大声喊出我急切想说的话:
“‘爸爸,你在河上浮游得太久了,你老了……回来吧,我会代替你。就在现在,如果你愿意的话。无论何时,我会踏上你的船,顶上你的位置。’
“……”
“他听见了,站了起来,挥动船桨向我划过来……我突然浑身战栗起来。因为他举起他的手臂向我挥舞──这么多年来这是第一次。我不能……我害怕极了,毛发直竖,发疯地跑开了,逃掉了……从此以后,没有人再看见过他,听说过他……”
罗萨的才华使他的故事超越了现实,就像他的标题所暗示的那样,河的第三条岸其实是存在的,就像莫斯科存在于三姐妹的向往中,戈多存在于弗拉季米尔和爱斯特拉冈的无聊里。这个故事和契诃夫、贝克特剧作的共同之处在于:等待的全部意义就是等待的失败,无论它的代价是失去某些短暂的时刻,还是耗去毕生的幸福。
我们可以在几乎所有的文学作品中辨认出等待的模样,虽然它不时地改变自己的形象,有时它是某个激动人心的主题,另外的时候它又是一段叙述、一个动作或者一个心理的过程,也可以是一个细节和一行诗句,它在我们的文学里生生不息,无处不在。所以,契诃夫的等待并不是等待的开始,林兆华的等待也不会因此结束。
基于这样的理由,我们可以相信博尔赫斯的话:几近无限的文学有时候会集中在一个人身上,同时也可以相信那位女士的话:所有的男人其实只有一个。事实上,博尔赫斯或者那位女士在表达自己精通了某个过程的时候,也在表达各自的野心,骨子里他们是想拥有无限扩大的权力。在这一点上,艺术家或者女人的爱,其实与暴君是一路货色。
一九九八年五月十日
[[浅忆黑色幽默小说|https://zhuanlan.zhihu.com/p/47273918]]
```
黑色幽默是20世纪,60,70年代流行于美国的文学流派。它深受存在主义的影响,对现实的荒诞有一种深沉的痛苦和恼怒,它以表面上的轻松语调叙述故事,从而产生滑稽可笑的喜剧效果。二十世纪六十年代,美国出现了一个特殊群体的小说家——黑色幽默小说家,他们写出了许多传世经典之作。当然,这些作品是在一定的时代背景下产生的。此外,在黑色幽默小说研究过程中,了解其与其它文学现象、文学流派的联系还是很有必要的。
```
"""
关键词: 黑色幽默小说 时代背景 联系 区别
1.时代背景
[[黑色幽默]],是一种哭笑不得的幽默,20世纪60年代美国重要的文学流派。继而出现了一批专门写此类型小说的作家——黑色幽默小说家,他们创作了一批优秀的黑色幽默小说,开创了黑色幽默小说。黑色幽默在于两种叙述声音所体现的观念是如何巧妙地产生蛆晤和碰撞。越是高级的黑色幽默,就越少依赖于语言和细节的“抖包袱”般的“突转”。
黑色幽默派作家对现实极度不满,认为美国的社会现实既荒唐又丑恶。他们不象五十年代许多作家那样回避现实,而敢于大胆暴露社会、政府和军队的阴暗面。但是,他们又对前途极度悲观,认为人的理智和善心无法扭转荒唐局面,改变丑恶的现实。因此,在愤怒之余,只能采取玩世不恭的态度,一笑了之。黑色幽默善于表现人的绝望境地,以轻松愉快的口气描写毛骨悚然的事件,在两者的不协调中创造幽默。因此,黑色幽默又被称之为“荒诞的幽默、变态的幽默、病态的幽默”。它是一种“把痛苦与欢笑、异想天开的事实与平静得不相称的反应、残忍与柔情并列在一起的喜剧”,往往能达到令人啼笑皆非的悲喜剧效果。黑色幽默派作家都希望以小说对现存的各种弊病进行高倍放大,促使人们对现实社会获得足够清醒的认识。
[[传统英雄主义]]的颠覆是黑色幽默小说产生的主要背景。
英雄形象作为激发读者斗志的本能要素,在西方文学作品悠久的发展史中占据着重要的 地位,无论是古希腊、古罗马神话和史诗中被神化的[[阿喀琉斯]]、[[埃涅阿斯]]的坚定意志和领袖 风范,还是文艺复兴之后产生的悲剧英雄[[哈姆雷特]]、于连对现实的不屈和反抗精神,个人英 雄主义的情结始终能够激起读者的强烈共鸣。但是随着西方国家社会意识形态和文化背景的 发展与变迁,文学作品中的英雄主义情结也在发生着相应的变化,古典作品中完美的神话英 雄形象逐渐变得有血有肉,从文艺复兴到十九世纪末的这段时间里则转变为与现实顽强斗争 ,却往往以失败告终的人性英雄,尽管此时个人英雄主义仍然是文学作品的重要组成部分, 但是传统英雄主义随着历史发展逐渐消亡的趋势已经初现端倪。
单化戏剧性的外在的黑色幽默,而成为目前书写得相当成功的高级的黑色幽默小说作品。诚然,一些出版商和评论家对“黑色幽默”作家及其作品大肆吹捧,过分宣染,或是一味贬低,这都是可能也是难免的。美国社会中追求新颖时髦的风尚被人利用,对黑色幽默的堀起起了推波助澜的作用。但,这决不是与黑色幽默得以产生“大有关系”的唯一原因。黑色幽默之所以能在六十年代堀起并以它的奇光异彩照亮美国文坛,其根源只能从美国文学传统的发展进程中寻根究底,在美国当代的社会习俗和时代精神的背景下考查发现。
下面两段文字,引自美国早期浪漫主义作家的作品。
早期西部幽默的重要作家沃德写过这样一个故事:俄亥俄州有一天要处死一个犯人;当绞索还未套上他的脖子时,警长问他还有没有话要说。这时一个当地有名的演说家迫不及待地推开众人挤上绞台,说:“倘若这位不幸的同胞不想说话,而又并不急赶他的路的话,我倒想利用这个机会讲讲为什么我们需要新的保护关税。”这里,作者本意是要讽刺那些利用一切机会向公众兜售口材的演说家。在执行死刑这样可怖的时刻,用幽默把风马牛不相及的事绞在一起,虽然有点残忍,但却痛快淋漓地揭露了那些好卖弄口舌的家伙,还能有比这更好的手法么?
再如,霍桑在短篇小说[[《恩地科与红十字》]]中,这样写道:“……那个女人的舌头上夹了个劈开的枝条,原来她是因为搬弄她那个难以控制的器官,反对教会的长老,才得了这份应有的报应。……有的人耳朵割去一块,象小狗的耳朵似的,有的人在脸上被烙上他本人所犯罪行的打头字母;有个人鼻孔被切开了,而且灸焦了;还有个人颈上套了一根僵绳,他本人永远不得解下,也不得拿衣服挡住。依我看,他一阵心酸起来,必定情不自禁地想过,要把套索的那一头系到一根近便的房梁或树枝上去。”本来是描写那些受到清教徒偏执的宗教狂热迫害的人们痛苦和不幸的情景,可是霍桑采用了幽默的手法表现那些人们的苦衷,多么令人震惊!
2.联系
伴随着文本颠覆性的叙述,荒诞成为黑色幽默小说家早期文学作品最突出的写作母题。下面就以余华为例谈谈。
这种荒诞更多地具有怪诞的成分,小说人物不是疯子就是虐待狂与被虐狂,这种怪诞情景中没有多少幽默成分可言,过于反常的文本情景难以让幽默“突转”而出。所以,余华早期的小说文本因为过于直接地设定一个与传统文学诸常规迥然不同的怪异景象,常常使其某些黑色幽默的因子被许多恐怖叙事所埋没。余华早期小说中暴力动作的叠加,窒息了他的小说中潜在的黑色幽默叙事语境的展开。
[[《许三观卖血记》]]是[[余华]]目前黑色幽默发挥得最淋漓尽致的一部长篇。卖血是苦难的事实,但这一残酷的事实在小市民平庸而艰难的生活中竟然获得某种快意,卖血能挣钱,卖血使“身子骨结实”,卖完一次血的感觉就好象“从女人身上下来”,卖完血还能名正言顺地慰劳自己—吃爆炒猪肝喝黄酒。卖血这一严酷的事实不断被淡化了。另外,江南小镇里男男女女的恩恩怨怨,琐碎、平庸的众生相,构成了的这篇小说的极富日常情趣的生活背景,买血的事实常常在小镇温情以及家庭成员的打趣中得以消解。《许三观卖血记》中面对苦难和死亡的威胁,善良(也不乏小滑头小堕落)的小市民屡屡无师自通找到回避的途径,并且忍痛做趣。这种程度不等的黑色幽默,不仅在《许三观卖血记》各个叙述片段中俯拾即是,而且成了贯彻整个卖血事故的基本叙事基调.这个故事带有悲剧性,但悲剧故事是由一个接一个的喜剧场景组成。
许三观善于在苦难中依靠虚构和想象对抗病痛和饥饿的煎熬,在突如其来的灾难面前常常能出人意料地按照另一种逻辑超越具体的实际的痛苦,但这种超越最终是无力的,是无法彻底地消解现实的苦痛,所以,在忍痛做趣之后,许三观往往就进入了“自我受难”阶段—一次又一次地卖血,而再次“受难”之时,许三观当然不会忘记再次用他拿手的小市民趣味缓解苦痛。所以,我们就看到的,是一个“受难”和“忍痛做趣”的循环。这些悲剧性的喜剧场景,不乏以沫相濡的无奈。对黑色幽默有一种说法:“黑色幽默是一种把痛苦与欢笑、荒谬的事实与平静得不相称的反应、残忍与柔情并列在一起的喜剧,黑色幽默作家对待意外、倒行逆施和暴行,能象丑角那样一耸肩膀,一笑了之.”
美国当代著名小说家[[库尔特·冯尼古特]]在他的第五本小说[[《上帝保佑你,罗斯瓦特先生》]]的一开头就风趣地告诉读者:“在这个关于人的故事里,主要情节是一笔钱;这和在关于蜜蜂的故事里,主要角色按理总是一摊蜂蜜是一样的。”这笔大款项是美国第十四个大家族罗斯瓦特的“罗斯瓦特基金会”的八千七百万美元,外加日利一万美元。这笔钱免交所得税,利息基金会可以任意使用。与基金会并列的是“罗斯瓦特公司”,它可以任意投资经营,牟取大量利润。这两个组织相互独立,互不制约。根据罗斯瓦特的家规,罗斯瓦特的家族成员,除精神病患者外,都可以在基金会任职。野心勃勃的年轻律师姆沙利费尽心机想证明罗斯瓦特基金会主席埃利奥特患有精神病而让另一罗斯瓦特的家族成员——傻瓜费雷德接任该会主席,以便在金钱转手之际从中渔利至少一半金额。小说的主要情节便以围绕姆沙利挑拨两家罗斯瓦特的矛盾而展开。
人类不断寻求摆脱苦难,而苦难又如影随形般地纠缠着人类,这是一个西西弗斯般的难局.这就构成了某种荒诞:这个世界看似有意义,看似按照正义、秩序和理性组织起来,可实际上,人在这个由人赋予意义的世界里并不可能与这个世界和谐一致,而是有可能处在苦难之中,处在进退两难的困境中.人无法与这困境正面对峙,又无法对这个世界的秩序发出金刚怒目的质疑,而且,还要活出某种乐趣来,所以,忍痛作趣的黑色幽默便成了绝好的精神药方和生活常态。
3.区别
但是,黑色幽默小说并不等同于荒诞派,二者虽然存在着莫大的联系,但是二者也有区别。
就作品反映的色彩而论,黑色幽默小说是最具时代特征的。它与同时期出现于英、法的荒诞派戏剧一样,用一种非常规的方法揭示生活的本质,对现实生活的描写也具有一定的艺术魅力,这也是黑色幽默小说之所以能够在美国文坛上造成重大影响的原因之一。
。“黑色”指的是人们当时所处的可怕而又荒诞、滑稽的生存现实,而“幽默”则是人们面对那样一种现实所作出的“荒唐、滑稽,又令人痛苦、绝望的、大难临头的幽默”。
黑色幽默小说以其鲜明的艺术特色被誉为当代美国文坛的奇观。黑色幽默小说的内容是复杂的,其形式更是多样的,但从叙事角度来看,黑色幽默小说的叙事手法却具有非常相似的特征。
而[[荒诞派文学]],是西方二十世纪的后现代主义文学重要的流派之一,主要是指戏剧创作。它采用荒诞的手法,表现了世界与人类生存的荒诞性。在西方文学的脉络里,“荒诞”是一种古已有之的文学手段。不过,在形成于20世纪40年代二次世界大战的劫难后的西方荒诞派文学运动中,“荒诞”有着其特定内涵。按照存在主义的观点,“荒诞”是上帝“死”后现代人的基本处境。在萨特那里,表现为人的生存的无意义,在加缪那里,表现在西西福斯式的悲剧,在卡夫卡那里,表现为异化、孤独、徒劳和负罪等等。
在一部荒诞性作品中,象征情境与故事情境必须是严格对应的,绝对不能为象征主人公随便安排一个背景环境。在对荒诞派文学的理解上,有一点是容易被人忽视的(尤其容易被中国作家忽视),就是在其令人战栗的绝望背后的价值关怀。
[[荒诞文学运动]]是一场抗议运动,一场不合作运动,而其运动宗旨却如加缪所说:“荒诞运动,反叛运动,凡此种种……其目的是同情……即是说,归根到底,是爱。所以,我们在荒诞作品一团漆黑的世界背后,总能看到一个反抗绝望的英雄,或者一个痛苦挣扎的灵魂。荒诞的图景愈是荒诞绝伦愈是蕴含着一种理想主义的痛心疾首,一种天真而锐利的失望。
总的来说,二者之间既有联系又有区别,要辩证的看待二者之间的关系。
"""
强劲的想象产生事实- 余华
========================
强劲的想象产生事实- [[余华]]
-----
一
蒙田有一篇《论想象的力量》的随笔,开始的第一句话就引用了当时的学者们所认为的“强劲的想象产生事实”。
蒙田生活的那个时代距离今天有四五百年了,他说:“我是很容易感受想象威力的人。每个人都受它打击,许多人还被它推倒。我的策略是避开它,而不是和它对抗。”
在这里,蒙田对想象表现出了多少有些暧昧的态度,他只是承认想象的力量,而不去对此多加议论。想象在蒙田面前时常是这样的:“只要看到别人受苦,我便觉得肉体上也在受苦,我自己的感觉往往僭夺第三者的感觉。一个人在我面前不停地咳嗽,连我的咽喉和肺腑也发痒。”
强劲的想象产生了事实,一个本来是健康的人通过对疾病不可逃避的想象,使自己也成为了病人。有些疾病所具有的传染的特性,似乎就是想象。这二者有一些相同的特点,比如说接触,首先是两者间的接触,这是给想象,也可以说是给传染建立了基础。想象和传染一样,都试图说明局外者是不存在的,一切和自己无关的事物,因为有了想象,就和自己有关了,“而且把它保留在我身上”。
与蒙田同一个时代的一位英国诗人约翰·堂恩,给想象注入了同情和怜悯之心,他的《祈祷文集》第十七篇这样写道:
谁都不是一座岛屿,自成一体;每个人都是那广袤大陆的一部分。如果海浪冲刷掉一个土块,欧洲就少了一点;如果一个海角,如果你朋友或你自己的庄园被冲掉,也是如此。任何人的死亡都使我受到损失,因为我包孕在人类之中。所以别去打听丧钟为谁而鸣,它为你敲响。
二
《庄子·齐物论》:“昔者庄周梦为蝴蝶,栩栩然蝴蝶也……不知周之梦为蝴蝶与?蝴蝶之梦为周与?”
《庄子·秋水》:“庄子与惠子游于濠梁之上。庄子曰:‘鯈鱼出游从容,是鱼乐也。’惠子曰:‘子非鱼,安知鱼之乐?’庄子曰:‘子非我,安知我不知鱼之乐?’”
比蒙田和约翰·堂恩要年长几个世纪的庄周,常常在想象里迷失自我,从而在梦中成了一只蝴蝶,而且还是“栩栩然”。最后他又迷惑不已,从梦中醒来以后,开始怀疑自己的一生很可能是某一只蝴蝶所做的某一个梦而已。
想象混淆了是非,或者说想象正在重新判断,像一个出门远行的人那样,想象走在路上了,要去的地方会发生一些什么,它一下子还不能知道,这时候的想象和冒险合二为一了。
蒙田说:“我以为写过去的事不如写目前的事那么冒险,为的是作者只要报告一个借来的真理……与药汤不同,一个古代的故事无论是这样或那样,并没有什么危险。”
庄子与惠子关于鱼是不是真的很快乐的对话,都是用否定想象的方式进行的,首先是庄子想象到鱼在水中嬉戏时的快乐,当他说鱼很快乐时,鱼的快乐也成为了他的快乐,而惠子立刻否定了,他对庄子说:“你又不是鱼,你怎么知道鱼很快乐?”
在这里,惠子否定的不是鱼的快乐与否,而是庄子的想象。惠子会不会这样认为:现在快乐的是庄子,而不是鱼,庄子所说的鱼的快乐只不过是借题发挥。
庄子也立刻否定了惠子的想象,他以其人之道还治其人之身:你又不是我,你怎么知道我不知道鱼的快乐?
两个人的分歧在什么地方已经不重要了,庄子是因为自己快乐,才觉得鱼也快乐,庄子的快乐是一个事实,鱼的快乐是庄子的一个想象,或者恰恰反过来,鱼的快乐才是一个事实,庄子的快乐只是延伸出来的想象。
“人自乐于陆,鱼自乐于水。”两者都很快乐以后,想象与事实也就难分你我了。
与蒙田几乎是一个时代的王船山先生,是一位抱道隐居,萧然物外之人,他所作《庄子解》里,对庄周与蝴蝶之间暧昧不清的关系进行诠释时,着重在“此之为物化”上,“物化,谓化之在物者。”船山先生的弟子王增注:鲲化鹏、蜣螂化蜩、鹰化鸠……大者化大,小者化小。至于庄周化蝴蝶,蝴蝶化庄周,则无不可化矣。
如果用想象这个词来代替物化,在同样包含了变化的同时,还可以免去来自体积上的麻烦。庄周与蝴蝶,一大一小,两者相去甚远,不管是庄周变成蝴蝶,还是蝴蝶变成庄周,都会让人瞠目结舌,可是想象就不一样了,想象是自由的,是不受限制的,没有人会去计较想象中出现的差异,而且在关键时刻“强劲的想象”会“产生事实”。
卡夫卡在其小说《变形记》的一开始,就这样写道:“一天早晨,格里高尔·萨姆沙从不安的睡梦中醒来,发现自己躺在床上变成了一只巨大的甲虫。”
很多读者都注意到了甲虫的体积已经大大超过了变化前的格里高尔·萨姆沙,可是这中间有多少人对此表示过疑问?
三
那么,想象和事实之间究竟有多少距离?卡夫卡小说《变形记》的阅读者们在面对人变成甲虫时,会不会觉得这样是不真实的,经过长达八十年的阅读检验,是否真实的问题已经不存在了,《变形记》就像《精卫填海》,或者希腊神话中的传说那样,成为人们生活中的一部分事实,也就是人们常说的经典,经典这个词是对强劲的想象所产生的事实的最高评语,也是最有力的保护。
格里高尔·萨姆沙变成了一只巨大的甲虫,所有的阅读者都知道了这个事实,然后他们都变得心情沉重起来,因为他们预感到自己正在了解着一个悲惨的命运。
如果格里高尔·萨姆沙在那天早晨醒来时,发现自己变成了一朵鲜花,并且在花瓣上布满了露珠,露珠上还折射着太阳的光芒,这样阅读者的心情就会完全不一样。
对于格里高尔·萨姆沙,甲虫和鲜花没有什么两样,他都失去了自己的身体,失去了伸出去的手和手上皮肤的弹性,也失去了带领他走街串巷的两条腿。总之他失去了原来的一切,而这一切自他出生起就和他朝夕相处了。
变成甲虫以后的悲惨和变成鲜花以后的美好,都只是阅读者的心理变化,与格里高尔·萨姆沙自己关系不大。甲虫和鲜花,本来没有什么悲惨和美好之分,只不过是在人们阅读《变形记》之前,在卡夫卡写作《变形记》之前,强劲的想象已经使甲虫和鲜花产生了另外的事实,于是前者让人讨厌,后者却让人喜爱。
蒙田说:“如果我请人做向导,我的脚步也许跟不上他。”
四
蒙田在《论想象的力量》一文里,讲述了这样一些事,一个犯人被送上断头台,接着又给他松绑,在对他宣读赦词时,这个犯人竟被自己的想象所击倒,僵死在断头台上了。一个生来就是哑巴的人,有一天热情使他开口说话。还有一个老头,他的邻居都能证明他在二十二岁的时候还是一个女子,只是有一次他跳的时候多用了一些力气,他的阳物就一下子伸了出来。
类似的故事在距离蒙田四百多年以后的中国也有,蒙田那时候的女子中间流行过一首歌,少女们唱着互相警戒步子不要跨得太大,以免突然变成了男子。而在中国的少女中间,曾经流传过这样的说法,就是有阴阳人的存在,有貌似女子实质却是男子的人,到了夜晚睡觉的时候,阳物就会伸出来。这样的说法是提醒少女们在和女子同床共枕时也得留心,以免过早失去贞操。
我小的时候也经常听说关于哑巴突然开口说话和一个人被自己给吓死之类的事,讲述者都能具体到那位当事人的容貌、身材和家庭成员,以及当事人所居住的村庄,这些辅助材料使事件显得十分逼真。
这些日子我开始认真地阅读莎士比亚。从今天的标准来看,莎士比亚戏剧中经常出现一些幼稚的想法,我说这样的话时没有一点自负的意思,一个伟人虽然衣着破旧,也不应该受到嘲笑。我真正要说的是,莎士比亚让我了解到什么是我们共同的利益,它们不会受到时间和距离的干扰,在那个时代就已经激动人心的事物,为何到了今天仍然闪闪发亮?其永葆青春的秘诀何在?
记得几年前,有一天史铁生对我说:现在人们更愿意去关注事物的那些变化,可是还有不变的。
莎士比亚戏剧中那些不变的,或者说是永恒的力量,在时移境迁中越磨越亮,现在我阅读它们时,感到世界很小,时间也很短,仿佛莎士比亚与我生活在同一个时代,同一座城市里。
五
《论想象的力量》里有这样一个段落,“西门·汤马士当时是名医。我记得有一天,在一个患肺病的年老的富翁家里遇到他,谈起治疗这病的方法。他对富翁说其中一个良方时便不要我在场,因为如果那富人把他的视线集中在我光泽的面孔上,把他的注意力集中在我活泼欢欣的青春上,而且把我当时那种蓬勃的气象摄入他的五官,他的健康便可以大有起色。可是他忘记了说我的健康却会因而受到损伤。”
我在鲁迅文学院学习时,有一位同学出于一种我们不知道也不感兴趣的原因,经常去和一些老人打交道,等到快毕业时,他告诉我,他觉得自己一下子老了很多,胃口变坏了,嘴里经常发苦,睡眠也越来越糟。他认为原因就是和老人在一起的时间太多了。
另外有一个事实大家都能够注意到,一些常和年轻人在一起的老人,其身体状况和精神状况常常比他们的实际年龄要小上十多和二十多岁。
这就是想象的力量,“它的影响深入我的内心。我的策略是避开它,而不是和它对抗。”
想象可以使本来不存在的事物凸现出来,一个患有严重失眠症的人,对安眠药的需要更多是精神上的,药物则是第二位。当别人随便给他几粒什么药片,只要不是毒药,告诉他这就是安眠药,而他也相信了,吞服了下去,他吃的不是安眠药,也会睡得像婴儿一样。
想象就这样产生了事实,我们还听到过另外一些事,一些除了离奇以外不会让我们想到别的什么,这似乎也是想象,可是它们产生不了事实,产生不了事实的,我想就不应该是想象,这大概是虚幻。
加西亚·马尔克斯在《番石榴飘香》里对他的朋友说:“记得有一次,我兴致勃勃地写了一本童话,取名“虚度年华的海洋”,我把清样寄给了你。你像过去一样,坦率地告诉我你不喜欢这本书。你认为,虚幻至少对你来说,真是不知所云。你的话使我幡然醒悟,因为孩子们也不喜欢虚幻,他们喜欢想象的东西。虚幻和想象之间的区别,就跟口技演员手里操纵的木偶和真人一样。”
几年前,我刚开始阅读蒙田的随笔时,对蒙田所处的时代十分羡慕,他生活在一个充满想象的现实里,而不是西红柿多少钱一斤的现实,我觉得他内心的生活和大街上的世俗生活没有格格不入,他从这两者里都能获得灵感,他的精神就像田野一样伸展出去,散发着自由的气息。
这样的羡慕在阅读加西亚·马尔克斯的作品时也同样产生过,他的《百年孤独》出版后,“我认识一些普普通通的老百姓,他们兴致勃勃、仔细认真地读了《百年孤独》,但是阅读之余并不大惊小怪,因为说实在的,我没有讲述任何一件跟他们的现实生活大相径庭的事情。”
而且,“巴兰基利亚有一个青年说他确实长了一条猪尾巴。”马尔克斯说:“只要打开报纸,就会了解我们周围每天都会发生奇特的事情。”
一个充满想象的作家,如果面对很多也是充满想象的读者,尤其可贵的是这里面有许多人只是普普通通的老百姓,那么这个作家也会像加西亚·马尔克斯一样,得意与喜悦之情溢于言表。
当然,这个作家的作品里必须具有真正意义上的想象,而不是虚幻和离奇,想象应该有着现实的依据,或者说想象应该产生事实,否则就只是臆造和谎言。《百年孤独》里俏姑娘雷梅苔丝飞上天空以前,加西亚·马尔克斯曾经坐立不安。
“她怎么也上不了天。我当时实在想不出办法打发她飞上天空,心中很着急。有一天,我一面苦苦思索,一面走进我们家的院子里去。当时风很大。一个来我们家洗衣服的高大而漂亮的黑女人在绳子上晾床单,她怎么也晾不成,床单让风给刮跑了。当时,我茅塞顿开,受到了启发。‘有了。’我想到,俏姑娘雷梅苔丝有了床单就可以飞上天空了……当我坐到打字机前的时候,俏姑娘雷梅苔丝就一个劲儿地飞呀,飞呀,连上帝也拦她不住了。”
六
我回到那间半截房顶的房子里,里面睡着那女人。我对她说:
“我就睡在这里,在我自己的角落里,反正床和地板一样硬。要是发生什么事,请告诉我。”
她对我说:
“多尼斯不会回来了,从他的眼神中我已发觉了。他一直在等着有人来,他好走掉。现在你要负责照料我。怎么?你不愿照料我?快上这里来跟我睡吧。”
“我在这里很好。”
“你还是到床上来的好,在地板上耗子会把你吃掉的。”
于是我就去和她睡在一起了。
这是胡安·鲁尔弗那部著名的小说《佩德罗·巴拉莫》中的一段,两个事实上已经死去的人就这样睡到了一起,一个是男人,还有一个是女人。
我第一次阅读这部小说时,被里面弥漫出来的若即若离,时隐时现的气氛所深深吸引,尤其是这一段关于两个死去的人如何实现他们的做爱,让我吃惊。
现在,我重新找到这一段,再次阅读以后又是吃了一惊,我发现胡安·鲁尔弗的描述极其单纯,而我最初阅读时,在心里产生过极其丰富的事实。当然,将这一段抽出来阅读,与放在全文中阅读是不一样的。
从叙述上来看,单纯的笔触常常是最有魅力的,它不仅能有效地集中叙述者的注意力,也使阅读者不会因为描述太多而迷失方向,就像一张白纸,它要向人们展现上面的黑点时,最好的办法是点上一点黑色,而不是去涂上很多黑点。
另一方面,胡安·鲁尔弗让一个死去的男人与一个死去的女人睡到一起时,抽干了他们的情欲,这是叙述中的关键所在,他们睡到一起,并且做爱,可是这两个人都没有一丝情欲,他们的做爱便显得空空荡荡。
那么,他们又是出于什么样的欲望、什么样的目的睡到了一起?其实他们没有任何欲望和任何目的,他们只是睡到了一起,此外一无所有,就像他们没有具体的做爱动作一样。
在“于是我就去和她睡在一起了”的下面,是两行空白,空白之后,胡安·鲁尔弗接着写道:
我热得在半夜十二点醒了过来,到处都是汗水。那女人的身体像是用泥制成的,像是包在泥壳子里,仿佛融化在烂泥里一样化掉了。我感到好像全身都泡在从她身上冒出的汗水里,我感到缺乏呼吸所必需的空气……
一九九五年一月二十四日
**大长标题**
本文完整标题有点长【"巧用 Obsidin 把 “思维导图” 软件 mindmanager 变成类 RoamResearch" 一样的“双项链思维导图”】因为标题字数限制所以浓缩了一下。
**可读性与链接性的互补**
现在双向链软件内部图谱整体**可读性**差,比如 RoamResearch 的大纲,Obsidian 的【## 小标题】构成的文章结构,以及 RoamResearch、Obsidian 的关系图谱,可读性都是较差的。
思维导图软件因为没有很好的双向链功能,做成的脑图基本也会变成一个个知识孤岛,复用性和连接性都极差。
如果制作的是大型脑图,只在单脑图内部使用脑图功能的线段进行节点与节点链接的话,是相当不方便的是 “灾难现场”,当然思维导图软件 mindmanager 还可以使用 url 建立单向 / 双向链,但使用起来几乎没有可读性操作也较为麻烦。不同脑图间双向链接功能和双向链可视化的图谱也是没有的,思维导图软件双向链接功能是很不易用的,所以这时就得使用 Ob 进行互补。
我们完全可以把脑图软件和思维导图软件混用形成强大的功能互补。
**双向链接就是块引用**
很多脑图用户,第一次接触 "块引用" 这个词的朋友对它会比较陌生,所谓 "块引用" 就是一个内容被借用到别处展现出来,这个内容可以是一个标题、一个段落、一句话、一个表格等。其实和复制粘贴是一个道理,你复制了这个内容不管多寡都可以把它形象的看作一个 "块"。
这个块出现在两个不同的位置(内容)里,这两个位置也就形成了一个链接,这两个位置可以互相跳转成为双向互通的一个链接,这就是**双向链接就是块引用**。
[脑图软件鼠标拖拽建立知识结构威廉的视频 · 253 播放](https://www.zhihu.com/zvideo/1301898235007971328)
**快速的建立结构**
还有就是双向链软件建立知识结构的效率是远远弱于思维导图软件的,因为思维导图软件可以通过鼠标拖拽就快速建立好笔记结构,如上边视频示范。更多详细内容可以阅读[威廉:【Marginnote 在 PC、IPAD、MAC 上的替代方案与不氪金订阅也能 OCR 文字识别的方法!](https://zhuanlan.zhihu.com/p/103010115) 】
**文本或大纲后的大网(大网 = 双向链)**
从【 [威廉:Obsidian 和 Roam Research 的核心差异和相通的地方及一些相通的用法](https://zhuanlan.zhihu.com/p/243515148) 】可以了解到,目前的双向链软件无非就是把线性文本或树状大纲(**缩略的思维导图**)背后加了一它们之间相互连接(双向链)的大网。笔者认为大纲实际就是缩略的思维导图
现在的思维导图软件缺乏的就是后边这张大网,**这张大网也就是无数个文本笔记或大纲双向链接**(也叫反向链)、互相连接的的一个体现,所以(大网 = 双向链)。
**用最简单的时间戳的方法实现双向链**

看过我系列 Obisidna 文章的朋友应该都知道时间戳这个概念,简单说就是把一个不变的 14 位时间标记,如 20201027233308, 标记在不同的地方,这样几个不同的地方都就有了一个相同永久不变唯一的标记(如上图)。

当我们在不同软件间(或同软件不同文件)使用**搜索功能**搜索这个雷同的时间标记时就相当于在不同的软件(或同软件不同文件)找到通用的内容(时间标记),把不同的地方自然链接了起来(如上图)。
值得注意的是 Everything 或 FileLocator 是两款强悍的搜索工具,Everything 可以秒速搜索你的所有文件名进行 “定位和跳转”,FileLocator 可以搜索你非常多软件内的文本内容进行 “定位和跳转”,定位和跳转如果灵活看待其实也相当于双向链功能了,意味着你可以在不同文件名、不同内容间建立双向链,并不仅仅局限于脑图软件或者双向链笔记。
因为借助自动化便捷辅助工具来进行时间戳的输入,建立时间戳货跳转的这个过程也是很简单的。更多相关内容可参考:【 [威廉:怎么用 obsidian 超越 marginnote,怎么做到万物皆为 obsidian 的数据库!](https://zhuanlan.zhihu.com/p/231559461) 】【 [威廉:Obsidian 的 Quicker 辅助已迁移至 AutoHotkey!Obsidian 威廉助手!](https://zhuanlan.zhihu.com/p/261183846) 】
**借助 Obsidian 呈现大网**
按时间戳的办法会有个缺点,就是时间戳的链接间没有显示出一张大网来(也可叫:关系图谱),这时我们可以借助 Obsidian 把大网呈现出来,**这种使用场景下 Obsidian 就成为了一个建立大网的工具**(当然 Obsidian 还有别的功能和用法互相不冲突)。
[Obsidian 块引用威廉的视频 · 87 播放](https://www.zhihu.com/zvideo/1304581958324977664)
我们只要把同样的节点名和内容在 Obsidian 中也建立起来,并进行引用动作即可呈现出网图来。(如上边视频)
这样我们就借助 Obsidian 的功能弥补了思维导图软件没有双项链网图的缺陷,和 Obsidian 无法快速建立结构的缺陷也用脑图进行了补充,当然这个方法使用起来就是脑图为主 Obsidian 为辅助,Obsidian 更多就是一个观察双向链的工具。
**借助工具快速调整让两个软件融为一体**
[思维导图软件和 Obsidian 混用威廉的视频 · 76 播放](https://www.zhihu.com/zvideo/1304584777782169600)
通过以上的方法,可能你会觉得脑图和 Obsidian 好像两边都是孤立的建立了一套系统一样,但只要借助双向链的思维,它们之间其实都有一个不变的 14 位时间戳在联系,我们再通过快捷的辅助程序,依靠时间戳两边进行快捷的跳转(或者你手动复制粘贴也行),Obsidian 就好像是脑图软件的一个辅助插件一样,两个软件间就自然互相配合起来了(如上边视频)。

**补充**

你可以给思维导图 A 或 B 的文件都加一个时间戳后缀,把这个加后缀的文件名备注到 Obsidian 的笔记内,这样在 Obsidian 或别的地方只要用威廉助手(如上图)就通过这个文件名和时间戳后缀,就可以快速通过 Everything 打开某个脑图文件,举一反三来使用的话其实通用于一切文件的快速定位跳转打开。
也可以在某个地方框选时间戳利用威廉助手的 "搜索 / 跳转 -- 用 Obsidian 搜索 / 跳转" 快速跳转到 Obsidian 内相关位置。
**结语**
**本文实际是对双向链这种方法的拓展实践,是一种不拘泥于笔记软件的双向链用法,把双向链这种方式通过时间戳做媒介发散到软件与软件间的活用方法**,本文的方法并不是把使用复杂化,而是用最简单最快的方式解决了脑图软件和双向链笔记软件互相的一些痛点。
读者也可以举一反三活学活用,比如把它用在你的 Word、TXT 文件、PPT、电子表格等等地方都是可以的,这样我们就在任何可能的材料上都用上了双向链功能,而不受制于各种软件极其缓慢的开发进度,据笔者所知目前 20201028 还没有一家思维导图软件或类似微软 Office 的软件商在做双向链接功能,而双向链功能恰恰又是非常实用的功能,对个人的思维启发、知识利用等都会有很大的帮助,**这个方法应该是最快让你在现有基础上用上双向链块引用的方法**。
因为方法是灵活的同样也可以使用**思源笔记**来完成,不拘泥于 Obsidian,思源笔记的图谱也是不错的。
这个方法也像是把 mindmanager 用成 Roam Research 的一种方式,这点可参考【 [威廉:Obsidian 和 Roam Research 的核心差异和相通的地方及一些相通的用法](https://zhuanlan.zhihu.com/p/243515148) 】。
刚开始实际运用起来这种方法也许你会觉得有点麻烦,就像刚学打字一样,但几天过后就会变成自然而然的工作流。
这个方法还有很多细节可以补充,并不是一个死方法,读者也可以自己举一反三进行灵活使用。
Obsidian 拓展阅读:
[威廉:威廉 Obsidian 使用心得系列文章总汇(干货满满)](https://zhuanlan.zhihu.com/p/336860525)
[威廉:用 obsidian 必备的三个 Markdown 浏览器插件拓展你的知识库!](https://zhuanlan.zhihu.com/p/239831856)
[威廉:obsidian 的关系图谱要怎么用](https://zhuanlan.zhihu.com/p/237351391)
[威廉:怎么用 obsidian 超越 marginnote,怎么做到万物皆为 obsidian 的数据库!](https://zhuanlan.zhihu.com/p/231559461)
[威廉:Obsidian 手机平板使用之二 1Writer 和 IA writer 及一定要注意的图片和笔记问题!](https://zhuanlan.zhihu.com/p/220081353)
[威廉:obsidian 手机平板上使用之一 logseq](https://zhuanlan.zhihu.com/p/207096030)
[威廉:用 obsidna 做你的《最强超级自定义字典》!](https://zhuanlan.zhihu.com/p/240258201)
[威廉:Obsidian 和 Roam Research 的核心差异和相通的地方及一些相通的用法](https://zhuanlan.zhihu.com/p/243515148)
[威廉:Obsidian 和 Anki 如何真正的联用!](https://zhuanlan.zhihu.com/p/245218259/)
[威廉:用 Obsidian 和 PotPlayer 做视频联动,让你的学习如虎添翼!辅助你的视频创作!](https://zhuanlan.zhihu.com/p/249245984)
[威廉:Obsidan 的不完美群体协作 -- 云盘 / 文件共享](https://zhuanlan.zhihu.com/p/257195856)
[威廉:重磅!Obsidian 块引用的使用方法!!](https://zhuanlan.zhihu.com/p/266909890)
[威廉:Obsidian 的 Quicker 辅助已迁移至 AutoHotkey!Obsidian 威廉助手!](https://zhuanlan.zhihu.com/p/261183846)
[威廉:用 Obsidian 一定要注意的图片和笔记问题!](https://zhuanlan.zhihu.com/p/268309654)
[威廉:双向链笔记综合体验威廉排名榜](https://zhuanlan.zhihu.com/p/267451435)
[威廉:巧用 Obsidin 解决思维导图软件的双向链块引用的痛点](https://zhuanlan.zhihu.com/p/269279110)
Obsidianbi 笔者的相关回答:
[你是怎样使用 obsidian 做笔记的?](https://www.zhihu.com/question/412868038/answer/1474149515)
[你是怎么使用 Roam Research 或 Obsidian 的?](https://www.zhihu.com/question/401073799/answer/1484457191)
[如何使用 Obsidian 软件?](https://www.zhihu.com/question/401972085/answer/1483478773)
**笔者编写的 quicker 动作集**

欢迎下载笔者编写的其它 quicker 动作集使用(不断更新维护中 ···)
笔者的动作库链接: [User - Quicker](https://link.zhihu.com/?target=https%3A//getquicker.net/User/208928/%2523ABC)

如果你觉得 Quicker 过于麻烦,笔者现已把部分内容转移到 AutoHotkey 的可执行 exe 档,只要下载一个 exe 文件开启后即可使用!相关内容请看:[威廉:Obsidian 的 Quicker 辅助迁移至 AutoHotkey!](https://zhuanlan.zhihu.com/p/261183846)

欢迎加入 Obsidian 知乎讨论群 1026788769,本群无任何收费内容,无官方人员,可畅所欲言交流软件使用心得。
琴瑟- 葛亮
========================
琴瑟- [[葛亮]]
-----
外公外婆金婚的时候,父亲请相熟的书法家题了一幅字,“琴瑟龢同”。
对外公外婆的身世,父母从来缄口。后来,不知道从哪里听来一鳞半爪。外婆的父亲大约是个豪绅,据说是颇能干涉些地方事务的那种,抗战时,又给政府捐过飞机的。
后来各种运动中,自然都落不下好。可是前几年修地方志,又成了当地最早的革命民主人士,彪炳史册了,甚至还印了些挂历来纪念。所以胡先生说得没有错。历史是随人打扮的小姑娘。所谓历史人物,更落到了陪房丫头的结局。
外婆是家里正出的小女儿,成人时正值家中的多事之秋。结婚那天,父亲溘然长逝。
外婆至今仍有些耿耿于怀,好好一个大家的小姐,婚结得那样潦草。外婆说到这些,就会去抚摸那张硬木的八仙桌。这桌子是她的嫁妆。本该是一堂红木家具,硬是给一个坏心地的庶出兄弟给换掉了。不过雕工和漆艺倒还很精细,所谓减料却未偷工。新婚燕尔之际,外婆竟没察觉。几年以后,外公不留神说了出来。事隔多时,外婆还是禁不住羞恼,埋怨外公不早些说。外公就笑道:那时说,怕你心里会难受。细细想想,外婆就有些感激,外公的确是宅心仁厚的。
外公是个外来的女婿。早些年和叔父南下做生意,成家之前,大半个中国,居然也都走遍。外公又是极聪明,直到现在,还讲得出一口地道的上海话、宁波话。学起马三立,天津话几可乱真。广东话也听得出子丑寅卯,我在南方待了几年,亲戚们玩笑着怂恿我说些粤语,外公听罢仍能指出不道地之处,让我汗颜。
外公的母亲,姓孟,是外公的养母。母亲说太奶奶是孟子的N代嫡亲孙女,存有家谱流传。我见过照片,老太太极严厉的模样,据说在世时就很有家长的气魄,说话做事斩钉截铁。外婆虽有些脾气,对这个婆婆也是言听计从。太奶奶对孙辈却十二万分的和善,尤其对母亲这个长孙女,更是视若珍宝,毫无弄璋弄瓦之别。母亲现在忆起,仍语带哽咽。说老奶奶卧床数年,有天突然神思不清,气若游丝却久不肯瞑目。直到母亲放学归来,她大叫一声孙女的乳名,用力握住母亲的手,这才走了。老奶奶身体冷了下来,手却握得越发紧。大人们想把祖孙俩的手分开,竟没有办法。母亲说,让我陪陪奶奶吧。两只手握了一夜。第二天清早,外公说,妈,桢儿要去上学了,太奶奶的手竟就松开了。太奶奶说过,桢儿是要做女状元的。就为了这一句话,母亲在最难的时候,上山下乡,也没放弃过读书。恢复高考后,硬是凭着往日的底子考上大学。这在老三届里是极稀有的。
外公外婆一共生了三女一儿,除了母亲稍稍抓住了些繁华的尾巴,舅舅姨妈们却都是跟着家庭经受过不少苦处的。熟识的都说,张老师这辈子值了,四个儿女,有钱的有钱,有学问的有学问。外婆当面笑着应付,背地却总有些忿忿,说要不是这运动那运动,我们家里还要好呢。外公就说,太太,知足常乐,知足常乐。
对于外公外婆年轻时的种种,我所知甚少。不过对他们的性情,我却很熟悉。我们表兄弟四个都是在外公家长大。堂屋里那张很大的春凳,也是外婆的陪嫁之一,夏天睡过四个胖小子,赤条条一字排开,着实让人眼热。孙辈皆为男丁,也是外人羡慕的指标。外婆却又不以为然,说人家没见识,哪里就有孙女贴心。
外婆笃信血统论,高兴不高兴起来都叫我小蛮子。父亲也是个外来的女婿,真正书香世家出身,可惜早年失怙,如父长兄又被错划成了右派。大学毕业后,父亲从南方省城分到苏北工作,在当时是有些被发配的意思。又过去了几年。其时母亲尚待字闺中,在个人问题上却犯了才女的通病,一览众山小,听凭韶华蹉跎,视追求者若无物。外公外婆却知婚姻大事任性不得,终于落了媒妁的俗套。有人就说文化馆有个南方的小伙子,省城大学毕业的,人又很厚道。
父亲不通世故,空着两手到了外公家。谈起话来,外公却觉出这年轻人谦和有礼,不似时下青年志大才疏,心里就有些欢喜。父亲走后,外婆就说,蛮子就是蛮子,又是满口学生腔。母亲喃喃道,要不是个蛮子就好了。说完想起不妥,脸红了一下,全家就有些懂得母亲的意思了。
父亲成了外公家的常客,唯有外婆对他淡淡的,他也不觉。周末大家闲坐,外公养的猫从暗影里走出来,在阳光底下伸了个懒腰。父亲掏出钢笔,信手在香烟壳上勾了几笔,一只小兽跃然纸上。外婆看后禁不住笑了,说这倒是很有趣。父亲就受到鼓舞,把平日所作都拿给外婆看。依父亲的性情,想来这样倒不是为了讨好丈母娘,却更似他乡遇知己,所以美芹十献。外婆翻看着,问父亲一张粉彩的小画是什么。父亲就答是西斯廷圣母,他九岁时临摹下来,现在留作纪念。外婆顿时觉出了这青年的不凡,这才想起细细问起父亲的家世渊源。父亲就一五一十地作答。外婆越发惊异了,想这孩子如此的出身,比自家是只强不弱的。再一转念,看父亲现在孤身一人,落到如此境地。心中就生出些悲悯,叹了口气。父亲为人单纯,以为外婆是对画作有了批评,忙问:不好么?外婆也赶忙答道:好,好。
以后,外婆对父亲的慈爱竟胜过对其他儿女。她偶尔也教父亲当地的方言,也笑着学几句父亲的蛮话,暗暗地就为母亲备下了嫁妆。
我出生时七斤六两,是个真正胖大的孩子。父亲的朋友就说是南北血液混合的优良品种。父亲调回省城,母亲随着去进修。外婆就把我揽在怀里,有些慷慨地说,这孩子我给你们带。带我并不容易,那时外公外婆尚未退休,好在家里有个小姨,却没有带孩子的经验。我吃得很多,早上要消耗两瓶牛奶。外公天擦亮就去很远的地方取奶,热奶的时候,自己先打起瞌睡。外婆授课的学校在离家不远的地方,常常上完一节课,就跑回家里给我喂奶,再小跑着赶回去上下一节课。
我四岁半的时候出水痘,外公外婆都慌了神。外公骑着自行车到黄河故道的边上转悠,到处找刚刚生芽的柳树枝。找到了,就求人给打下来。嫩柳枝煮鸡蛋,是个偏方,我吃了后,水痘果然就退了。
现在想来,五岁的时候,外婆就开始把我当神童培养。在某种程度上,我算是辜负了老人家的期望。外婆培养我,用的是私塾的办法。每天要描红大字小字若干页,每天背唐诗若干首。我记性不错,却是个不求甚解的。直到考小学,还以为“篱落疏疏一径深”是关于某个叔叔的逸事。不过当时出口成诗,已经让主考的老师大跌眼镜,小出了一回风头,这都是后话。
外公外婆后来都退休了。
外公又被一个纺织品公司聘了做经理。其实是个闲差,因为外公德高望重,坐在位上用来服众的。公司有时请外公给员工做些思想教育工作。外公又是认真,有次带了个年轻人回家来谈话,这个青年据说是私拿了些公家的财物。虽然外公动之以情,晓之以理,那青年却不领受,话不投机,突然说了一句:外国有个加拿大,中国有个大家拿。一向温文尔雅的外公就有些动了气,说如果大家都来拿你家的东西怎么办云云。年轻人离去的时候,状态上是悻悻的。外公还在自说自话,说有些事情是原则问题。外婆就有些怪外公,说老了老了,跟小孩子一般见识。都退下来了,在人家嘴里还落不下好了。外公就长叹一声,不说话了。
外婆退下来那年,政府搞土地开发。外公家的独院子被划进了征地范围。全家就开了个会,舅舅是坚决反对搬迁的。其实谁也是老大不情愿。尤其是我们表弟兄四个,都在这院子里长大的。虽说离开了,这院子还是我们的百草园,这一搬一拆,将来朝花夕拾就没了地方。外公想了一夜,对全家说,还是响应政府号召吧。谁都知道其实心里最痛的就是外公,光是东厢房门口的那棵养了几十年的大月季树,当年上过地方电视的,就够让人舍不得。
终于还是搬了。院子拆了,后来我去凭吊过一番。原地建起了一座星级酒店,设计得不见得好,和政府的理想应该有些出入。
老街的居民被政府一锅端到了新建的住宅小区。小区离市中心远了,却是滨湖的。环境还不错,适合老年人颐养天年。外公就有些自得,对外婆说,老伴你看,焉知非福,焉知非福。外婆却很不习惯,以前在市里的时候,几十年的老友,都是知心的,现在却断了交际。再一层,由于是整街搬迁,所以引车卖浆者流,吆喝煎饼果子卷大葱的,都在楼里抬头不见低头见了。大家都对外婆客气得很。外婆却觉出这热热闹闹里,她是顶孤立的一个。有一天,外婆买菜回来,在楼下小卖部门前看见一伙老太太叉麻将。外婆打了个招呼,却又慢下脚步,多看了几眼。就有个老太太站起身来,说,张老师,来打一圈吧。外婆忙摆手说自己不会。老太太却有些热情似火地把她拉到跟前坐下,说好学得很。麻将本不难学,加上外婆聪明,几圈下来已经很上手。老太太们开始还让着,有些扶上马送一程的意思。及到后面,发现外婆已经后来居上了,又是特别擅摆清一色,常常有出人意表的创举。彼此融洽了,老太太们就经常敲家里的门,有时是叫外婆打麻将,有时就送来些自己做的家常吃食。外公发现家里不如之前清静了,可是看到外婆的脸色一天好似一天,心里也暗暗欣喜。后来外婆耳里传过些话来,说有个老太打麻将打得昏天黑地,有些过分了,就被儿子骂。她就回嘴,说楼上张老师能打,我怎么不能打,人家还是某某的闺女呢。外婆知道了有些委屈,觉得自己被利用。外公就劝她。再后来老太太们觉得打卫生麻将不过瘾,就要来些彩头,外婆顺势退出了。就又有人暗暗议论,张老师那样的家底,还疼这几个钱。外婆也不和他们计较,说人和人到底是不同的,有些是个原则问题。外公听出了自己的口气,心里就笑。可是觉出外婆其实又有些寂寞了。
外公就想着带外婆去旅游,趁腿脚灵活,带外婆把年轻时没走过的地方走一走。就去了庐山,知道三峡快要被淹了,又赶着去了三峡。这样赶了一程子,外婆觉出腿脚狠狠地酸痛起来。外公想想,大约是途中奔波,伤筋动骨了,就带外婆回了家里。将息了几日,却总不见缓过劲来,外婆越发觉得脚心刺痛。人也有些焦躁,不停地喝水,嘴里边嘀咕着说自己这回是得了大毛病了。外公也怕了,就打电话给自己做医生的朋友。那朋友细细了解了一回,问外公说,嫂嫂家族里是不是有糖尿病的遗传。外婆猛醒,她的姐姐们,就是我去世的两个姨婆,生前都是得过这病的。老两口赶紧去了医院,这回确诊了,血糖还高得很,三个加号。
都知道糖尿病是个顽症,外婆没有过什么生病的经验,情绪一下子就落到了低谷,开始投入到做病人的角色。以前早上天擦亮就和外公去湖边锻炼的,现在早上醒过来也是在床边坐着,魂不守舍的。外公心里也慌张着,嘴里只管说些安慰的话,说太太你别老是对自己作消极的心理暗示,有病治病,你也知道现在医学多发达的。外婆就很丧气地说,再发达,也没见艾滋病给攻克了。外公就不言语了。虽是这样说,外婆也还是循规蹈矩地吃医生给配的药。过了几日,药吃了一个疗程。她自己却说毫不见起色,情绪越发放任了,说是小城出庸医,都是些催命的。有个老街坊就上门了。她也曾是外婆的麻友之一,自认为是情同姐妹。这老太太端着一碗卖相不甚好看的面饽饽,却迎着外婆的一张冷脸。她也还是赔着笑说,张老师,你这病要忌口。这是个偏方子,吃些糠饽饽,是有好处的。外婆听着脸色就变了,语气也很黯淡:我们家里有的是好药,不要这种东西。那人就讪讪地走了。外公就喃喃地劝道,人家也是好心,这又是何必。外婆就把头偏过去不理他,眼睛却潮湿了。
母亲知道外婆生病的消息,一夜没合眼,第二天大早跟学校请了假就往老家赶。外婆看到母亲,像是抓住了救命稻草,情绪高昂地说,你看看你们几个,哪里就有一个有你们大姐孝顺。大家都知道这话是言过其实,可阿姨舅舅们都怕扫外婆兴似的,争先恐后地说,就是就是。唯有小表弟趁出来的时候拉一下母亲的衣角,说大姨,外婆这些天越来越像个老太后了。小姨妈就狠狠地瞋了儿子一眼。母亲就知道,这恐怕也代表着家里的舆论了。
母亲抄了外婆的化验报告,回到省城,就去些大医院找专家咨询。在网上看到哪里有关于糖尿病的专题讲座,也风尘仆仆地赶过去听。这样多日下来,她就舒了口气,有些自信地说,我现在也算是半个医了。有了这半个医,外婆自己心里好像也有了底,遵这半个医的嘱配合着吃各种半个医寄过来的进口特效药,生活态度也积极起来。
病情真的就控制住了,外婆有些喜不自胜,好像迎来了生活的第二春。可是她又起了些念头,把那些甜得似是而非的木糖醇、甜味素抛在脑后,开始琢磨着吃些让自己恢复味觉的东西。无奈外公早就对外婆的毅力不信任,未雨绸缪地把一些禁食品都藏了起来。外婆就打了孙辈的主意,看到小表弟吃水果,就问,宝宝你爱不爱外婆。宝宝不知道这是个圈套,当然痛快淋漓地说爱。然后外婆就有些着急地把圈套收拢了,说你爱外婆就把桃让外婆吃一口。宝宝警惕地握紧了手中的桃,大声疾呼道,外公……外婆又是嗜辣的,以前顿顿饭是无辣不欢。病情厉害时忘了这口儿,现在回忆起来了。外公当然是极谨慎的,外婆就沉住了气,观察了几日。无奈外公步步留心,没有留下破绽。外婆最后把疑点落到实处,趁外公不在旁边,在冰箱里翻动起来,翻得太心急火燎,发出很大的响动。外公悄声走到她身后,待她黯然地关上冰箱,就适时对她进行些思想教育。
有天一觉醒过来,外婆就有些看不清,觉着眼前老漂浮着些东西。母亲听了就有些着急,对外公说,这可能是高血糖引起的并发症,视网膜病变了。外公一听心就凉了。退休以后,少了交际,外婆越发手不释卷。得了病后,不大出门,每天更是要读书看报,将大半时间打发过去。现在怎么是好,因为这个情绪上再有了反复,对外婆的病是有百害无一利的。外公就拐弯抹角地把事情跟外婆说了。刚要想着说些安抚的话,外婆却开口了,老头子,你和孩子们的心意我都懂,其实哪里就有个人定胜天啊。这么说着,很有些认命的意思。做儿女的听了更不安了,以前听外婆把一些狠话说到身上,大家心里难受着,却是踏实的。因为说明外婆心下还是不甘,是想要和这病抗争着的。现在的情形,倒好像自己先要放弃了。外婆却安慰道,你们别瞎琢磨,我是真想开了,咱们家这么多年,兴兴头头地过,比谁不强。我也知足,老头子,你不是也说知足常乐么。话虽如此,大家的心还是没有放下来。
外婆倒是真的心平气和的,每天还是按时吃药。眼睛却是一天天地坏下去,终于书报是没办法看了,电视也只能看到一个模模糊糊的影。外婆不埋怨,自己找着些乐子,听到些电视里的人声,就对小表弟说,是不是倪萍阿姨出来了,宝宝你看外婆说得对不对呀。小表弟却是个直肠子,说不对,是周涛。外婆的眼神就黯淡下去。小姨妈就对儿子使了眼色,说小宝这就是倪萍啊。小宝却是个拉不回头的驴,说明明就是周涛,我认识的。小姨妈就急了,起身作势要打他。外婆喝住了,说你这个妈怎么当的,教小孩子说假话。再说,这两个人本来就长得很像,不是么。说完自己就沉默下去。
外婆脚里长着骨刺,行动就不灵便了。家里终于给她配了轮椅,又请了个家庭护士。这是个和善的年轻姑娘,和外婆很谈得来的。每每说些可人心的话,说外婆到底是读过书的老人家,心态这样好。可偏偏做起事来,这姑娘是粗枝大叶,经常让外婆的脚磕着碰着。外婆咬着牙不说什么,外公更是把攥着心。这样几番下来,外公终于请她走了,自己担负起照顾外婆的重任。外婆退休后,身形比以前胖了。现在一举一动却都需要扶持。儿女不在的时候,外公帮着她如厕。外公是个瘦小的人,每次扶外婆回到轮椅上,自己先是大汗淋漓了。外婆帮他擦着汗,总是说些心疼的话。外公就装出不以为然的样子,说太太,这也是体育锻炼,比去湖滨散步有效得多。闲些的时候,外公就戴起老花镜,帮外婆剪脚指甲。这是他的专职,自从有次舅舅弄疼了外婆,他就禁止别人插手了。这项工程是要用去外公个把小时的,细细地剪,剪好了再一个个用锉子磨光滑了,然后又寻着甲上的倒刺除掉。那样细致地,仿佛在做工艺了。这时候,外婆的病情其实是比以往又严重了些。每每到了夜半,就被腿脚的疼痛折磨得合不了眼。她又强忍着不让自己翻来覆去的,怕的是把外公闹腾醒了。其实外公和她连着心,哪里就真睡着了,就把手悄悄伸过去给她攥住。外婆就回过头来,说,老头子,我真是疼啊。一边就哽咽了。外公就说,太太你心里别老惦记着,想些可乐的事情,把注意力转移过去就不疼了。外婆试了一下,还是疼。外公就说那你听好,我给你来一段,嘴里来了个过门儿,就压低了嗓子给外婆唱起《三家店》。我起身上厕所,看见外公房里还亮着灯,推门进去的时候,外公正唱到“娘想儿来泪双流。眼见得红日坠落在西山后……”外婆迷迷糊糊睡过去了,手还紧紧地攥着外公的手。外公的手是换过了,另一只手背上还看得见粉粉的指甲印子。这时候天已经发白了,外婆终于睡着了。外公还坐着,抬起头来看着我,眼睛是浑浊的灰,眼角有些清亮的水迹。
这样又过去了好多的日子。在外公的悉心照料下,外婆的病虽无太大好转,但也没有严重下去。外公越发老了,还是健康着,乐观着。最小的外孙也成人了,小宝气力很大,可以背起外婆去外面和别的老太太拉家常了。儿女们掐指算了,两个老人家,结婚快满五十周年了。
外公外婆的金婚,办得颇有些反响。儿女,朋友,排场都还在其次。最重要的是,外婆退休前是市里的特级教师,一生桃李无数,这时到了种豆得瓜的时候。大到省市级的干部,远至移民欧美的游子,都闻讯赶来。还有些学生,自己也是孙辈绕膝的人了,就有些小孩子遵着嘱咐给太爷爷太奶奶磕头。外公外婆都带着十二分的喜色,和身上定制的唐装相映生辉。外婆的脸上施着淡淡的妆,眉目间依稀还看得见年轻时的影子。外婆当年是极为漂亮的。
热闹了一回,父亲展开了一幅字——琴瑟龢同。众人啧啧称赞,说是从笔力到意境都是极好的。外公仔细看了,说好啊,我这把老琴,不知道下辈子有没有运气碰上这样的好瑟了。转过头去,又对外婆唱道,我这张旧船票,能否登上你的客船?众人就笑,外婆也笑,笑着笑着,她忽然一回首,是泪流下来了。
禽兽-周晓枫
========================
禽兽-[[周晓枫]]
------
复杂的珠宝镶嵌
造蜥蜴是件麻烦事儿,上帝一定比创造别的动物花费了更多的时间、心思和精力。
蜥蜴的鳞片碎细,又不像鱼鳞那样有种流水线加工的痕迹,蜥蜴的每颗鳞粒都由纯手工制造,有独特的颜色、光感、硬度和方向,几乎需要动用最古老和最复杂的珠宝镶嵌工艺。它慢慢抬升……洛可可派镶满碎钻的脸、多褶的彩色喉囊以及脊椎骨上夸张的锯齿形旗帜。它的眼神沉着、倨傲、冷冽,气宇不凡。很难有蜥蜴这样的动物,同时结合极端的美与极端的丑,混乱交错的审美呈现,让人瞠目结舌。
蜥蜴里最有名的当属变色龙:擅长色彩的绘画大师,伟大的魔术家。
厚实、涂满眼影的眼帘,总让人感觉它睡意惺忪;但有时看到那甲亢患者般鼓胀着、半突出来的眼球——咦?它有360度的双眼皮。环形眼帘,盔状头饰,鹦鹉螺一样盘卷的尾巴,浓墨重彩的变色龙从着装到表情,戏剧感都很强。它像舞台上的贪吃鬼、阴谋家,或者国王身边的弄臣。变色龙的样子,有时看起来就像微雕的恐龙,神秘而古老。
人们认为变色是为了用拟态隐藏自己的想法,不过燕雀之志、小人之心。如果现实中观察,通过变色,它甚至更为夺目。变色龙是动物界的珠宝,在光线的照耀下展现惊人效果。无论搭配多少种颜色,也万般精妙。珠宝镶嵌在黑丝绒上,而明亮夸张的变色龙,有本事把自己镶嵌在珠宝般色彩丰富的植物里,并成为其间最耀眼之物。在某种光线、温度和情绪下,变色龙都要对此表达与众不同又随时更新的独特态度。
据动物学家的最新研究,变色可实现同类之间的信息传递。若属实,无论是人类的表音还是表意的文字,和变色龙相比都相形见绌。比彩虹还丰富的图案是它的语言,瞬息万变……这是巫师的天书,神灵的魔咒。
鉴于不能第二次踏入同一条河流的真理,我们也不认识任何一只变色龙。因为,很快,它就不再是它,身上的斑斓图案就像流走的河水。
不断地,使自己的下一秒钟不像上一秒钟——这是持续的背叛,变色龙像逃开债务一样逃开自己。有意思的是,变色龙的学名是避役,就是避开劳役的意思。变色龙很少四处奔波,总是原地不动地施用诡计,守株待兔,迹近不劳而获。舌头折叠在宽阔而略显傲慢的嘴里,深藏不露。它不必考虑与猎物的亲近的距离,变色龙是个远程射手,能够岿然不动地完成猎杀。无需支付体力,变色龙只需闪电般伸出原本折叠着、两倍于体长、满是黏液的长舌头,就可以轻易得到它的正餐——不过相当于用稍长些的筷子去夹取盘中餐罢了。
热衷变化,厌恶缺乏奇迹——变色龙不仅把这种生活原则贯彻在图案设计上,甚至体现在食谱上。多数变色龙会对单一食物产生厌倦,甚至绝望……坚决抗拒单调,松开它有如爱情般既鲜艳又缠卷的尾巴,变色龙选择死。
漂亮的混血儿
我在北方乡村见过一头威风凛凛的骡子,庄严的美貌几乎令人起敬。它垂下的眼睫,具有新月的弧度;等它抬头凝视……我觉得,只有骡马的眼睛,蕴蓄万重山水,配得上“会说话”的形容。其他物种,或如兔子呆萌,或如狐狸狡狯,相对来说,动物的眼神内容单一,禁不起两种以上的解读。而这只骡子,全身细节禁得起逐一推敲:高踵小蹄,短鬃蓬尾,筋腱强韧,隐现于精干的四肢里,连耳朵都是古朴优雅的土陶色,廓尖渐成窑变后的釉黑。高大威猛的骡子,走起来简直像健美运动员的肌肉展示,臀部曲线,格外饱满生动,堪称性感。
就像人类中漂亮的混血儿,美貌来自基因的重组;骡子的血统,来自更为大胆的跨界,它是两种动物之间的乱伦,迸射出的激情产物。骡子分为两种:公驴和母马的基因容易结合,骡子多是以此杂交而成,称为“马骡”;公马和母驴的结合概率极小,称为“驴骡”,所占比例甚微。
骡子从小就体现出能力和品性上的优越。骡驹合群,胆大聪明,活泼好奇,机警勇敢。作为马和驴的后代,成年骡子的个头却不是两者的平均值,它的体型更为高大。不仅如此,骡子的力量强劲而持久,既有驴的负重能力和抵抗能力,又有马的灵活性和奔跑能力,耕挽之用胜于父母;食量一般,能粗饲;脾气温顺,耐劳;更长寿,抗病力的适应性强。人类役用骡子拉车、耕地、驮东西,即便背负沉重的挽具和物品,它依然脚步稳健,路途陡峭也不会滑倒。骡子,再好不过的血肉工具,再好不过的肌骨器械。从审美功能到实用功能,骡子,都是完美的。
哎呀,的确是受人欢迎的役畜——它干得多,吃得少,甚至不需要私人生活的空间。骡子有雌雄之分,可惜几近装饰:由于染色体的先天性差异,骡子难以繁衍。无论怎样的高大、温顺、有力,它的情欲,技止此耳。
我不了解骡子的生殖,不了解它的爱情以何种形式达到峰值。是一清至骨,毫无杂念;还是情欲荡漾,却毫无作为?是否纵欲后无需承担生育的责任,反而可以享有终生的快意,无牵动、无挂碍?抑或,这是僧侣一样的骡子,它是最克制的动物,由此节省了所有的血脉、情感、家庭和未来?
人类肉食,少有听说吃骡子肉的,就习性而言,有若处子的骡子难道不相当于动物界的童男童女吗?也许这是出自对圣徒的禁忌。不仅因其罕有,比骡子珍稀的物种多了,不是还没有躲过筷子的夹击?不吃,因由,也许近于不吃唐僧肉的尊重或慈悲。
骡子这种动物本来在自然界是没有的,是人类祖先在两三千前,采用杂交手法培育出来的。对役畜来说,人成为造物之神,他可以创造无有之物。而骡子存在的意义,似乎仅仅因为人类需要它的劳动力。骡子无后,这是一种对驴马乱伦的惩戒吗?是对非法的性关系给予的严厉的种族制止吗?其实骡子无辜,它替逾越界限的父辈受过。人类社会亦如此,一代人的灾难未必在当时呈现,恶果往往在其后代那里得到放大倍数的彰显。
最好的种子得不到繁衍。骡子,作为进化杰出的代表,继承了完美基因,似乎已无通过繁殖来更新和提升的必要。然而,隐藏其中,是一种残酷的淘优机制。这和上帝拆毁建到高处的巴别塔,本质上是一个道理。我们缄默,因为,看清神明对骄傲的刑罚、对优秀的惩戒。
小灵魂
草叶上的蜻蜓,像枚盛夏的胸针——用如此轻盈的金属,精湛得,像天使才能打造的首饰。它们漫天飞舞,不像现实主义的昆虫,更像幻境中的精灵,镀满梦想、诗意与唯美的虚幻之光。没有什么不是优雅的,甚至空中交尾,有若飞舞中的性爱芭蕾;蜻蜓点水,即使作为产妇的时候,它们也丝毫没有破坏自己的芭蕾体形。躯干纤细,翅膀却是挥霍铺张的,在重与轻之间,凝练与夸张之间,一只蜻蜓拥有绝对的完美。所以动画片里的小仙女,常以蜻蜓为蓝本,因为它非人间的气息……极轻,相当于具体而微细的小灵魂的体重。
近看,我觉得蜻蜓是几乎没有肉体的生物——用纤细的金属丝、极薄至通透的塑料薄膜组装,充满后工业时代的现代感、几何般简捷的设计美学。只剩经过烘干处理的枯燥的金属涂层,蜻蜓被压尽所有水分,干而暖,偶尔错觉它像夏天的钨丝一样发烫。同样是钨丝般的细腿,无序挣扎,碰得我的指端痒痒的。鞭节状的腹腔,细得随时断掉,中间有道狭窄而齐整的裂缝,随着呼吸,缝隙在极细的尺度里产生微弱的变化,像刀刃深切进去又抽拔出来的感觉。蜻蜓,顶着节庆日里大头娃娃那样的颅具,一副本意美化却是效果丑化的儿童样貌——两腮鼓胀,下巴方硬,眼睛大得几乎吓人。发达有力的口器,让蜻蜓的确拥有强悍无比的大下巴,我喂草叶的时候,它的嘴角很快涌出咀嚼后的绿色泡沫。它的复眼,是由赛璐珞制成的两个大泡泡,在凸透镜的效果里,我从中看到无数密集的黑点,令人晕眩……蜻蜓,来自古老的生物,亿万斯年它从未改变样貌,从未改变它有如上帝般密若繁星的万能的复眼,仿佛能够收拢每缕闪耀的光线,每张沦陷到黑暗里的面孔。
蜻蜓一直是我最钟爱的昆虫形象,我由此遭到女友刻薄的讽刺:“我没看出蜻蜓和蚊子有什么本质区别,好比,同样是肌肉男的拳击手,只是重量级别不同罢了。”我反驳:“蜻蜓与蚊子,就像神仙与鬼怪都是非人之物,蜻蜓是消灭蚊子的,所以它是更大的神。”
正是因为做过这样的比喻和辩护,所以我记住了那个平凡的画面,记住了那只死去的蜻蜓。蚂蚁集中包围它的头部,数量很多,几近完全覆盖,使这只蜻蜓看起来有些恐怖,像满头蛇发的美杜莎。死蜻蜓看起来毫无肉质可言的精瘦躯干上也爬了一些蚂蚁,不如头颅上面多,保持着透明琥珀色的拱形翅膀却完美无损,上面没有任何入侵者。这头栽倒蚁窝旁边的蜻蜓,就像一架失事的飞机,正遭到残忍的围掠。经过蚁噬的密集痛楚,这小小的圣像般的十字架倒塌了……而那些蚂蚁最初来临的时候,很像朝圣者。
草叶上的蜻蜓,像枚盛夏的胸针——用如此轻盈的金属,精湛得,像天使才能打造的首饰。它们漫天飞舞,不像现实主义的昆虫,更像幻境中的精灵,镀满梦想、诗意与唯美的虚幻之光。
从罐子里倒蜜
春日盛宴。花瓣的餐桌,已铺好带卷边的桌布。
邀请的客人来了。蜜蜂先是停在半空,翅膀像小团正在蒸发的雾,然后它落下来。摄影机的慢动作下,蜜蜂很快离开一片尚在颤动的花瓣,这位小访客在弹簧椅上只短暂地坐了一下。因为它太忙啦,还有很多约请,一只蜜蜂每天要造访几千朵花。蜜蜂体重大约40毫克,但它们每次可以携带重量相当于自身一半的花蜜返巢,像昆虫里的候鸟,每天的路线都在包裹花粉的蕊柱与六角形的巢孔之间往返。尽管劳动量很大,但蜜蜂一点不像蜻蜓那么羸弱,它把微微发福的身体勉强塞进横条纹连体衣里。阳光下,蜜蜂的身体有种珐琅质和钢琴漆的效果,并且结实,看起来像个橄榄球运动员。
事实上,蜜蜂格外脆弱。我们知道,蜜蜂的愤怒和它的勤劳一样有名,并且令人恐惧。当它刺入尾针,后果比自行截肢严重得多,内脏由此被带出体外,失去螯针的蜜蜂将很快死去。情绪易于失控,不惜以惨死来表达,有人说蜜蜂的表现几近烈妇。
巧合的是,大多数蜂群中平均90%都是女性。并且,蜂群的统治者也是女性,它曾经杀死所有竞争者甚至包括自己的母亲才得以成为君主。谁说女人不适合当总统?蜂后的管理井然有序,科学化、社会化的程度都相当高。蜂后就是绝对的宗教,蜜蜂集体膜拜它们本性凶残的女王,鞠躬尽瘁,牺牲是它们的终身原则。微小的打扰有时会被误解而招致复仇,而蜜蜂的女性尊严是不容挑衅的。
我曾在公路上见到麇集的大量蜂群,是蜂农用卡车来转运蜂箱以抵达蜜源地。但一个冒失鬼为好奇心付出了代价。被蜂群追杀的瞬间,他奔跑,事后他形容那是他唯一的飞起来的体验。然而于事无补,他肿胀得异常恐怖的胎儿脸,薄得透亮,像个吹弹即破的脓疱。放蜂人逐花而居,光阴芬芳——我曾幻想这是最具诗意的职业,我的小情小调也因此遭受重创,原来,放蜂人时刻与几百万个坏脾气的动不动以死相拼的佩剑武士为伴。诗人会把爱情的伤害比作蜜蜂的蜇痛,证明他们不够实事求是,蜜蜂比爱情暴烈多了。
我小时候可以看见像钟乳石一样悬垂的蜂巢。六角形蜂巢,小小的巢洞像夕阳映照下的教堂玻璃,有着通透而神性的色泽。那里的确贮藏着神话一样的食物:蜂蜜。平均一只蜜蜂终生只能酿造一勺半左右的蜜浆。没有哪个小孩子能拒绝糖的诱惑,我曾经模仿蜜蜂用稻草的空管吸吮蜜茶花蕊上像蜜样的东西,味道清淡,甚至是寡淡。不知蜜蜂用了什么配方,让花蜜变得那么好喝。当工蜂把盛蜜的格子用蜜蜡封好,就像给罐头扣上盖子——这时,养蜂人就知道可以采集了。美味的蜂蜜,让人们充满感恩……我喜欢那些完美的弧线:从蜜蜂劳作时的悬舞,到嗜甜的熊胸前耀眼的弦月标记,再到猎人的孩子因尝到蜂蜜而上翘的嘴角。
蜜蜂总是让我浮想联翩。流星飞过,我猜想那是一只离巢还是归巢的工蜂;或者,夜空本身就是一朵巨大的花,低垂金色的葵盘;有时我又觉得星空像嗡嗡作响的迷路蜂群,它们慌张振翅,却被我们称为天籁。
蜂蜜与宗教有着渊源的关系,它曾被视作来自天堂之物。蜂蜜以甜和养分喂养人类,同时密集蜂刺也能带来致命的恐惧,如同宗教对众生的仁慈哺育与可怕威胁。我在欧洲旅行时,看到一座离教堂不远的丛林里有许多蜂箱。乌云翻滚,酝酿雷电,我依然看到许多只徘徊的蜜蜂。工蜂寿命很短,六周的一生里,它们殚精竭虑地寻找蜜源,多是疲劳至死。此时的舞蹈,是否将成为它们的遗言?还是说,蜜蜂必须在迷途中听从教堂的钟声才能最终返回家园,它们所经历的享乐和挫折才能结晶,才能被酿造和储藏?谁掌控着那引而不发的力量——上帝,是一个隐喻中最伟大的放蜂人吗?六月的倾城之雨,整个世界接受着盛大的洗礼……我不知道那几只蜜蜂的最后归宿。
有首著名的《野蜂飞舞》被改编为大提琴独奏曲,节奏很快,营造出蜂群的缭乱与莽撞,适合高手炫技非凡的指法。我个人并不喜欢,我愿意以大提琴来传达感伤和期待。世界上没有什么力量能让蜂蜜从倾斜的罐子里加速流动,蜂蜜沉着,就像一块以极其缓慢的速度融化的琥珀……低缓,如泣如诉,我以为大提琴的音色,就像,从罐子里倒蜜。
它被自己施了魔法……
总觉得,“长角的东西”多为童话里的怪物……可现实中的鹿,如此美丽。鹿仿佛自带武器,而且武器本身的形制这么漂亮。成年鹿是一种既优雅又能自我捍卫的动物,它体形庞大,满怀素食者的道德和大动物极尽的柔情。
各种各样的鹿,我都喜欢,它们有令人怦然心动的美感。
我在加拿大的贾斯珀国家公园看到大角鹿,它顶着盛大而奢华的烛台,雍容地在公路旁边进食,无视那些停泊的车辆和驻足观赏的人类,甚至无视于他们凝视着自己线条性感的臀股以及铃铛般垂坠下来雪白而耀眼的睾丸。
我在朋友的养殖园接触他的宠物:一只梅花鹿。我吃了一半的桃子掉在地上,这只鹿敏捷地捡拾起来。它开始似乎尝试,艰难地剥离桃核外面厚而紧实的果肉。我看不清果核是否露出木质壳,只看到整齐的鹿牙和厚实的舌头——鹿就像人吃到烫食一样运动着口腔,歪了两次脑袋,试图把桃核从一侧倒到另一侧。很快,桃核破裂的声音传来。我有些惊讶,因为桃核坚硬非凡,拿锤子砸都难以破损。我一直以为,鹿这样纤美的食草动物并无锐利齿锋,不会有如此令人意外的强劲咬力,不输于食肉动物的凶猛。我心一软,甚至担心果核碎裂后的渣子,能否对鹿的消化道构成某种伤害。我忽然又有童话的想象:桃核不会死,明年鹿角新生之季,这只鹿将与众不同,因为它被自己施了魔法……角叉不仅枝条茂盛,而且,挂着数颗丰盈果实。
几年前,我到过根河,那里被称为“中国的冷极之地”,极端最低温度只有零下52.6摄氏度。就在这极寒之中,鄂温克民族守护着他们神兽般的驯鹿,在漫无际涯的冰雪和风暴中漫游。在猎户点袅袅的蚊烟旁,我看到休息的鹿群。只有严冬时节,驯鹿才会披覆浓厚而柔顺的被毛;我去的时候是夏天,驯鹿正值褪毛期,除了那些初萌的幼鹿,成年驯鹿看起来一点也不俊逸,皮毛粗糙斑驳,如牛马般有种强烈的牲畜感。不过,这才是家人式的相守吧,无论驯鹿的皮毛是神仙般高贵,还是牲畜样残破,鄂温克民族给予它们同样的呵护与照料。他们和驯鹿一起享受密林里的清凉,也一起面对灾难的考验,包括承受着和驯鹿母亲般的伤痛——当年新生的幼鹿中,近一半都被熊吃掉。
有的驯鹿还顶着硕大的角叉,有的已被割去鹿茸,我用新鲜苔藓喂驯鹿,我的掌心感觉到驯鹿浊重而温暖的鼻吸。幼鹿则漂亮得惊人,身体灵巧,眼神纯净。有一只鹿角刚刚发育,只有食指的高度,上面毛茸茸的,闪动着针刺样的晶芒,像最干净的霜。小鹿羞怯,警惕,又保持着倔强的好奇,它并不尝试我递送的食物,只是长久凝视着我,既不靠前也不退后,既向往又畏惧地与我对峙……直到我告别之前的最后一分钟,它才靠近,犹豫地给予我谨慎的友情。
当晚,我夜宿呼伦贝尔。广袤草原在风的吹拂下,如皮毛滑顺的巨鹿;而分支丰富的河流正是它最美的角叉。宛如倒影,在那蒲公英般密布星团的夜空,正升起巍峨而令人震撼的鹿角星座。
扑克牌上掉下的“J”
海马,类似鳄鱼、蜻蜓、变色龙这种古老到失真的种类,像是存在于想象之中的动物,它们全身充满拼贴感。海马的口鼻仿佛食蚁兽的嘴,它有变色龙的眼睛和马的头——马头琴上所雕,与海马低头的弧度极为相似;此外,海马还有虾的躯干、卷尾猴的尾巴、龙的风仪。海马的形体,让我想起3或7的阿拉伯数字,或者是反S形,有点奇异的拉丁感,抑或,是从扑克牌上掉下的“J”?总之,它具有一种难以概括的异域风情。
有时候,谎言比真理更像真理,真理比谎言更像谎言——比如,海马属于鱼纲。海马的样子看起来最不像鱼,比不是鱼却像鱼的鲸不像多了,像个被放错分类的标本。的确,海马全身布满骨环,更像是什么动物干透了的骷髅,比如就像变色龙残剩的骨架。有些品种的海马,生前和死后的样子几乎不变。
是的,海马活在自己由骨环形成的甲胄里,尾部像螺壳上的古老轴线那样优美地向内蜷曲,它从身体结构上就不可能向谁摇尾乞怜。和陆地上游牧的马不同,海马用尾巴把自己拴牢在珊瑚枝叶或藻草的桩子上,以使自己不致漂流。当鱼群追逐洋流,海马努力保持着身姿的直立,以及,看似宁静里所包含的抗拒。
缓慢、笨拙、固执——很难相信海马富有激情,然而,它们看似的刻板里根植着某种专注。海马不像生物,它近于加工出来的工业零件,让人无法分辨,它是警醒还是睡眠,兴奋还是沮丧,缱绻还是决绝,缅怀还是遗忘,谦逊还是傲慢。无肉、无表情、无动作……经过自我压抑乃至自我剥夺,海马达至老僧入定般的岿然不动,在暗流不断的涌动之中。
不仅样貌,海马的习性也与众不同,在动物界是个异数。雌海马把卵产在雄海马的腹囊里,由雄性孵化育儿袋的小海马。育儿习惯,仿若钙化的身体具有雕像般的沉默,以及中年男人庄重的腹部弧度,使雄海马彰显颇具责任感的充沛父性。
有意思的是,在人体左右半脑,各藏有一只秘密的海马——它们担当记忆和空间定位的功能,因其部位的弯曲形状近似海马得名。海马属于脑演化进程中最为古老的部分。天地之间,每个人唯有依靠隐匿的这对小小海马,依靠它们尾部脆弱的小小卷勾,才能记忆且自我定位,得以不致卷入辽阔到虚无的黑暗汪洋。
它们占据了所有方向
用浓重的墨液画出眼线,脸颊上生有一对不怀好意的黑痣。这只海鸥简直像戴着黑臂章,有时感觉是在巡航,有时感觉是在服丧。海鸥飞在自己的倒影之上,我看到它剪形对称的尾翼,如无声滑动的桨板。
海鸥的翅膀,由锐利、坚硬的内骨架支撑,组成一具弓弩,或者近于倾斜的锚。翅膀上初级飞羽和次级飞羽严格排列,精湛覆盖,洇开或深或淡的水墨色。它可以失重般滑翔,也可以失重地一头坠入海里,它同时拥有驾驭和犯错的自由。当然不会被淹死。海鸥橡皮玩具一样浮动水面,尾部上斜,呈30度锐角。飞起时它抬起沥水的鲜艳的红脚蹼,打开透光的尾羽,那时,它能够和教堂玻璃上的鸽子以假乱真。
多数情况下,我们看到的是集体行动的海鸥。密集恐惧症患者难以面对,因为不仅种群庞大,海鸥快节奏的飞行,产生慌张而缭乱的效果,加之悬停和陡转的炫技,观者看到的数量是海鸥和它们刚才尚在眼底停留的影像所合成的复数。到处是亮得发黑的眼睛和白得耀目的翅膀。
每年冬天,大量海鸥麇集在昆明。我怀疑游弋海鸥的湖里已无小鱼,侵略者因为具有被普世认可的美貌,坦然劫掠了财富。我在翠湖旁边饮茶,视线里布满稠密而颤动的白色。就在我头顶的矮亭上,也落满了休憩的海鸥,像无叶的大玉兰正在开花,满枝都是拥挤的繁盛。奇怪的是,无论长时栖息还是刚刚飞落,那么多只脚,却毫无声息。不走动,也不叫,消失了脚步和声线,它们变成幽灵的存在。但我始终知道,它们在那儿——在头顶的石灰或金属板层上,有许多翅膀、利喙以及从泄殖腔里排出的粪便。
我多次近距离观察海鸥。无论是追逐捕捞船以期渔获的海鸥,还是码头餐厅在一堆锈色的内脏中打斗抢食的海鸥,我都能感觉隐藏其中的一种凄厉的野蛮。正常情况下,海鸥仪态平和,那是饱食者才能产生的雍容。然而,就在这个饮茶的清晨,我曾有过不同的际遇。
清晨六七点钟,岸堤的游人稀少。我是最早的喂食者,准备为饿了一夜的海鸥提供早餐。当我撕扯面包,抛向空中,召唤那些空中的精灵……
翅膀和它们扇动的幻影瞬间遮挡了我的视线。眼前、耳侧和头顶,到处是猩红色、锐器般的嘴。像被磁石吸引的铁屑,那些尖凿子从四面八方袭来。冻疮色的脚蹼,黑得吸收了所有光线却拒绝反射的深眼睛,勺型的头颅。翻飞的,团团羽雾中隐藏的无数锥器,近在咫尺,它们占据了所有方向。这是由无数羽毛构成的幕布,翅膀后面还是翅膀,利喙后面还是利喙。更多的海鸥正从更远的湖面上赶赴而来,加入对我的威胁。半块面包被紧张的手指捏得变形……我退后,我希望能够保持自尊地远离这扇形的灾难。
没有遇到想象中的温馨,对比海鸥庞大的复数,我体验着作为孤独异类的恐慌。我的脚,退到盲道的条形砖后面。虽然恐惧使我终止了自己的慈善,争抢食物的惯性使它们继续空中偶尔的打斗——此起彼伏,它们发出灾难般的叫声。翻飞,窥伺,尖叫。有些海鸥干脆停落到间隔一米出现的桥柱上,它们从畏怯到警惕,继而是凝视食物时渐近的咄咄逼人。我从那种集体对峙里体会到了一种显著的挑衅和蔑视……那些排列着的黑得像罪恶的眼睛。
它们一直被认作天使。是的,不过那是几个小时以后才会开始的扮演。
蔚为壮观的云霞
从名称上,具有传说感。火烈鸟的生存区域遥远,对我来说,它飞翔在神秘里。没见过火烈鸟之前,它诱惑着我的想象。纸包不住火,可火烈鸟,就是一团肉体包裹的火焰,燃烧着内在而不熄的光源……近于,浴火凤凰的现实版。
是在动物园仿造自然的区域,我第一次见到真正的火烈鸟。从近处看,它并无传说中的美感。羽毛,绝非燎烈的火红,倒像一团洗脱的洇色,有种失真的化学染料效果。除了橘红,还有些是白癜风般的失血体貌和仿若脱毛外露的肉粉色,混搭着……活像遭受工业污染的劫后余生者。更为奇怪的是,这些皮肤病患者集合在一起,仿佛就摆脱了职业病的形象阴影—远望,它们是天使的受宠之物,大理石粉调制成的膏白中晕染一抹含蓄优雅的暖色。
童年的火烈鸟灰扑扑的,看起来也和黑白相间的幼鹤大同小异。红色并非它自身的羽色,是通过食用藻类和浮游生物而获得的。每种生命都被自己所摄取的食物所影响,但火烈鸟,将之渗透到外貌结构中。即将进入求偶期的火烈鸟,甚至把局部的器官红扩散到整个身体,仿佛被激情灼伤。即使野外的火烈鸟,体表通常也不是严格的红,更多情况是一种肉粉或者橘色——由于色块分布不均,状若玛瑙。
火烈鸟的喙,形状就像人类夸张的弯钩鼻,末端黑色,又使它像沾了墨汁的巨笔。也许因为这沉重的喙,火烈鸟给人感觉是在谦逊低头。它像天鹅一样有着长脖子,甚至是更长的绳状,但不具备同样的优雅——火烈鸟更像个微微的驼背人。就像造物的上帝画孔雀时用工笔,画火烈鸟,大概用的是略带狂草的写意。
它们的瞳孔很小,只是居中一个斑点,有如保险箱的锁孔。正因瞳孔之微,它的眼神可以用目中无人来形容。我们从这样的眼神里找不到任何确定的情感。有若盲视的眼睛,却充满科幻魔鬼般的血红或蜡黄。
火烈鸟属鹳类,拥有儿童到少年之间的身高。腿细长,吊脚楼式地支撑着。长腿鸟总是让我略感造作,站立如同飞翔一样轻盈,像自己架起一个被抬升的舞台,为的是在高度上展现身姿;不过,这的确使它们更具造型感。如同许多涉水禽类一样,火烈鸟的腿看起来没有肌肉和脂肪,更像螺纹钢或树脂之类的工业制品。从力学角度,难以想象这样的腿可以韧力地支撑整个体重——就像它们的翅膀,只有细而空的轴管、轻而虚的羽团,却将沉重的肉身带入天空。这是抽象的功能,这是哲学的意义,这是一个陷足泥沼和展翼云端的生命所携带的真理。火烈鸟是群栖动物,能够集结万只之众,看似散漫,却可以忽然像皇家卫队那样齐整而抖擞地列队。水滨、沼泽、泻湖,到处丛生裸长的腿;飞起来的时候,形成蔚为壮观的云霞。复数的鸟群,将它们的真理复述了千百万次。
火烈鸟的分类曾让学者们困惑。因为它似乎既具有鹳形目的特点,比如肋骨和骨盆的构造;又具有雁形目的特点,比如脚蹼和羽毛的防水性,乃至鸣叫都是相似的……作为折衷的方案,分类学家单立了火烈鸟目。而分子生物学家通过DNA杂交实验,发现与之最为接近的,却是小型鸟类的鸻鸟目。
……它就那样弯垂着头,难以判断是谦逊还是傲慢,是冷漠还是羞怯。它就那样,拥有零度的丰富。
依然,是个奇迹
充满几何曲线的形体,停留在窗纱,腹部紧贴在它自己制造的小小阴影上,像趴在滑板上的冲浪者。背腹扁平,像被踩过一脚后正在恢复身体的体积和弹性……半瘪半饱的水囊,内脏被挤压出去了一部分似的。这只壁虎的体表虽然色泽陈旧,但薄软、绸滑,初洗如婴,吹弹即破。
壁虎抬起前肢,格外谨慎,分外犹豫,末端膨起的星状趾足徐徐落下;接下来,抬起另一侧的裂掌……它扭动向前,动作经过绝对放慢的处理,像在半空锈住了,细心的观察者会发现它微幅的喘息和摆颤。行动迟缓,还有略带棱角、像被挤压过的脑袋,以及沉赘而鼓凸的下腹部,更加重笨拙者的形象——然而,这是一个闪电杀手。壁虎以蚊蝇蛾之类的昆虫为食,出鞘的舌头,不仅如剑锋令猎物瞬间致命,闲暇时,还可以用来拭去眼睛上的灰尘。
奇迹不止于此。尽管这奇迹由于日常而显出平庸的气息,依然,是个奇迹。我总觉得它会掉下来,无论看过多少次壁虎克服重力的倒置杂技。趾垫密布叉状弯勾,可以黏附于极其微小的不规则处,因此壁虎能够攀爬玻璃,甚至悬行于天花板上。我们视线里光滑如镜的天花板,在它这个攀岩高手看来,被涂料颗粒粗糙地覆盖着,到处是高低起伏的突起和裂隙。海星状的脚蹼上,那肉眼不可辨识的钩刺,让它无论到哪里,都像锚一般沉着,壁虎在危险的高度上自由地倒行逆施……当然不会掉下来,壁虎就像渗开的污迹与它所附着的平面那样融合在一起。
壁虎与蜥蜴的区别之一,是后者喉部有褶皱,而壁虎包裹喉结的外皮相对光滑——但是,壁虎,却是唯一能够鸣叫的爬行动物。爬行动物本来就古老而神秘,已生存了亿万斯年,见识过这个星球的沧海桑田,远胜于人类的短暂而粗浅的认知;壁虎作为其中唯一具有言说能力的物种,更添魅惑。
通常匿身于阴影的壁虎,被传说,具有诡异莫测的通灵能力。它也确有神异之处,来支撑这种看似玄虚的论点。比如,许多医生认为,发烧是一种复杂的防御机制,因为更高的体温能抑制入侵者的繁殖。壁虎仿佛知晓这一原理,它们被感染的情况下会爬到一个混浊区域,让体温升高2度。更为可怕的是,壁虎还懂得给自己做外科手术——断尾求生。断肠,断魂。断流,断路。断语,断章。断念,断舍离。断弦,断送。断根,断命。世间的断,都是诀别;唯壁虎之断,妙在新生……它从哪里继承了这样出神入化的技艺?
与蝙蝠、蜥蜴同样,壁虎拥有奇怪的样貌,像是魔鬼藏进口袋里的宠物。它有一条可以装卸的尾巴,像自身的假肢,又像,来自魔界招幌的旗杆。
美如幻觉
参观完偃松林,离开不久,我突然行驶在一条撒满蝴蝶的路上。很少看到如此漫天飞舞的蝴蝶,几乎难以置信,有如动漫世界的极致美景。旁边有条废弃的铁轨,盘旋其上的蝴蝶更多。蝴蝶死生短暂,不能遥远,在通往远方和彼岸的铁路上,它们舞动无尽的翅膀。蝴蝶是动物里的樱花,也许这是它们化蛹为蝶的兴奋,也许这是它们集体婚礼的狂欢。
最初,我惊喜于这瞬间的奇迹,我还不知道,这幕场景会变成随后持续几个小时的震惊。不止几公里!沿着早年用于运材的道路,这天下午,我走了绵延达100公里的蝴蝶路。
从天上到地下,到处是无辜的颤抖。蝴蝶不间歇地撞击着玻璃,小而温柔的钝响,或者根本就毫无声息。翅膀绒毛般的鳞粉和花粉,体腔内几乎可以称之为干燥的有限汁液,一点点,或醒目或微小地,留下印迹。无数精湛的属于夏天的翅膀,它们几乎用一生来酝酿,但现在,飞蛾扑火般,稠密而来,忘我地扑向它们的水晶棺……如此汹涌而壮烈的自杀。
我坐在汽车的前座,当一只蝴蝶从远处的一个点瞬间放大到眼前的一个圆,那种笔直而生硬的撞击,让我几次下意识地闪躲——我的背部紧了一下,蝴蝶的决绝好像要垂直地撞上我的脸似的。有时,蝴蝶撞击的声音会突然放大,令人心疼:噼里啪啦,像场更大的、更密集的砸在棚子上的雨。蝴蝶体内并无太多油脂和黏液,它们有着素食者的肠胃,但无数脆弱的胸膜、柔软的腔肠,无数破碎的头颅和体液,让原本清透的玻璃处于频繁的雾团之中。
蝴蝶直接撞进死神的怀抱,只有极少数借助汽车靠近时玻璃上方升起的气流而侥幸逃生。蝴蝶们,用死,用不规则的符号,写就一篇关于死亡与美的遗言。那些密布的撞击痕迹。像羽扇。像帆影。像墨滴。像金字塔。像果断的叹号。像海豚。像乌贼。像鸟翼。像水母。像燕子。像风筝。像甲虫。像彗星。像泪痕。它们具体的死,留下抽象的符,像老电影胶片上的划痕。很多蝴蝶碰到玻璃就被弹到一边,留下的印迹比书上的顿号还小。即使微如沙粒的斑点,每一粒都是一起真实的死亡事件。
品种多是白色,有着清晰的黑色翅脉,双翅叠合起来,像个微型三角板,只是斜线稍具弧度。在白底子上勒出一道道黑色的网丝,蝴蝶仿佛由破裂粘合而成,或者,这对自由翅膀似乎天生被交错的细铁丝所捆绑。也许,这里展现的是掐丝工艺,白蝴蝶像景泰蓝的素坯。
蝶群中夹杂着极少的黄翅膀,汹涌的雾团中偶尔一点金色;更稀少的,是一种落叶色的蝴蝶,也在飘零之中。彩色蝴蝶多的时候,我就像看到一场由远及近、绽放在眼前的烟花。由远处的一小团颤动斑影,忽然放大,让人看清蝶翼上清晰的翅脉。体腔,像炭笔画出来的黑灰色线条;两侧,是浓雾一样的对称翅膀。
我之所以观察得如此清楚,因为开始行车,就有一只蝴蝶笔直地撞在雨刮器上,内脏被击碎了,从腔内破裂而出的体液把它的尸体长时间粘在上面。这枚雨刮器上的标本,让我看到蝴蝶精美的遗容。还有一只尾部渗出黏液,它的身体完全倒置,靠着一滴眼泪般流下的残存汁液,它缓慢地、一毫米一毫米地下降,完全不像在疾速的车上,倒像在慢镜头的告别中。
不仅止前挡风玻璃,大巴车两侧的长玻璃外面,蝴蝶弥漫。无畏生死的蝴蝶,会让人产生一瞬的不安,仿佛那是满天的冥钱,不知为谁哀悼。美到极致,无不产生致死的虚幻。各个方向,目力所及,到处是神经质般颤动的频率。视觉上的多,既是因为蝴蝶的数量,也是因为蝴蝶的颤抖使数目翻倍。
烈日下,太多热烈或疲倦的蝴蝶,忠诚地飞在一朵花或一棵树的高度上,竭尽一生,最后死于花木高度的祭台。翅膀有如小小的合页,生死的闸门一开一合。一开一合,在花瓣、在葱茏绿意、在同伴的尸堆上起舞。这些赴难的蝴蝶中,有情侣,有兄弟,有萍水相逢的陌生客……它们死在同样时刻,就像迁徙的鸟群那样,前往致命的告别。汽车颠簸起路上的灰尘,但它们那么傻,那么绝望——阳光灼裂,蝴蝶就舞在无限的透明里;灰尘浓重,蝴蝶就舞在蒸腾的烟尘里。不能感知临近的杀伐,蝴蝶忘我地展现着美,满怀笨拙的单纯。
是的,美如幻觉。蝴蝶孪生的翅膀,让我觉得它们死于绝对的简单、绝对的对称、绝对的致命完美。
密林更能提供安全的保障,为什么蝴蝶要集中在危险的公路上?我想,因为公路上开阔,不受花木阻挡的直射阳光亮度很强。蝴蝶不喜欢暗影,童年曾躲藏在叶子的背面和自闭的蛹衣里,现在它们涌现到最强烈的光线里,在能够飞翔的倒计时里,以命作赌,追逐着高纬度的珍贵的光亮。只有当树木像钢琴键投下阴影,蝴蝶的音乐才能像休止符一样短暂地安静下来。
公路上还有个特点,汽车反复倾轧,使部分路面形成坑陷,有助积储雨水。有的凹坑较深。蝴蝶麇集其中,正好躲过滚动的车轮,像防空洞里避难的人群。有时地面上汪着半片月亮大小的污水,它们紧紧簇拥其上,如临水照花,或者拼命地啜饮着……每只蝴蝶占有的面积极为有限,每对翅膀都紧紧闭合,翅膀挨着翅膀,鳞粉摩擦着鳞粉,所以在极小面积上可以汇聚蝴蝶的丛林。这些精巧的天使啜饮着泥色的水,场景让人心疼,而一啸而过的车辆,使它们倒毙在镜薄的水里,小翅膀像脏抹布般浸透了浊浆。
在激流河的一座石桥上,我下车拍照。当我尝试近距拍摄蝴蝶,我的镜头几乎碰触到它们的翅膀,但蝴蝶不受惊扰。我才知道,原来它们对缓慢和迅疾之物,都同样毫无抵抗,就像所有美物那样缺乏对侵犯的抵抗。
我曾以为,蝴蝶不过是在原地盘旋,看起来它们向着车头飞扑而来的集体自杀应该是相对运动产生的视觉误差——在火车站台常有这样的情况,以为是自己的列车启动,其实只是侧面的火车移动造成的错觉。等我下车,发现不是,我走到车头前方三十米的地方,大量蝴蝶落在那里,当它们起飞,并非上下起舞,而是向着我刚才来的方向飞去。我在后面追逐着……我不是牧羊人,但看起来,我正放牧着蝴蝶。
而且趁着下车的时候,我在离开公路几米的背静地方,用矿泉水写了一个字。我希望能把想要饮水的蝴蝶吸引过来,就此让它们远离危险。我想,蝴蝶会用它们叠合的翅膀让这个字成为浮雕。用蝶翼重新书写的字,是我悄然的秘密。那个地点离激流河很近——激流河上并无激流,水位低浅,水势平缓,我感觉着桥上低低的水声,以及蝴蝶凋谢时的宁静。
短暂的休憩过后,车辆继续前行。频繁来往的车辆,宽大的车体和玻璃变成了蝴蝶的集体公墓。大货车的粗犷而沾满油泥的格栅里,嵌满蝴蝶的翅膀,像装饰着一个巨大的花盘。看起来大大咧咧的司机频繁打方向,一路小心绕行,他并不是佛教徒,只是如此大规模的倔强的无视生死,总是让人心生不安。他尽力躲避蝴蝶麇集的水槽,躲避那些由翅膀构成的小小灌木丛,偶尔开到蝴蝶数量减少的路段时,司机会如释重负地舒口气。
而来不及转身和闪避的蝴蝶,被撞击,被轮胎辗压……成为细小而精湛的碎片。无以计数被碾死的蝴蝶,不断来往的车辆把它们压实在地面,这条路镶满了斑斑驳驳的蝴蝶,就像硬币的图案一样无法从金属面上抠取下来。大自然中,诞生这么多专门用于死的生命。比如花籽、鱼卵和星辰。死变得如此平凡,甚至超越了生的日常性。
同行者忧虑如此庞大的蝴蝶数目,是否为明年的病虫害埋下隐患。也许。但在化学的毒杀作用下,我们几乎难得目睹这种绝美的自然灾害了。想起美国黄石公园几乎是毁灭性的大火,但重生的树木却更为高大繁茂。灾难般的美,将如何发生与结束?我祈祷,这场与蝴蝶的意外相逢,既是轻盈且沉重的回忆,也存在着美好的转折可能。
倾城-三毛
========================
倾城-[[三毛]]
------
一九六九年我住西柏林。住的是“自由大学”学生宿舍村里面的一个独立房间。所谓学生村,是由十数幢三层的小楼房,错落的建筑在一个近湖的小树林中。
是以马德里大学文哲学院的结业证书申请进入西柏林自由大学哲学系就读的。在与学校当局面谈之后,一切都似可通过了,只有语文一项的条件是零。学校要求我快速的去进“歌德语文学院”,如果在一年内能够层层考上去,拿到高级德文班毕业证明书,便可进入自由大学开始念哲学。而宿舍,是先分配给我了。
“歌德学院”在德国境外的世界各地都有分校,那种性质,大半以文化交流为主,当然也可学习德文。在德国境内的“歌德”,不但学费极为昂贵,同时教学也采取密集快速方法,每日上课五六小时之外,回家的功课与背诵,在别的同学要花多少时间并不晓得,起码我个人大约得钉在书桌前十小时。一天上课加夜读的时间大约在十六、七个钟点以上。当然,是极为用功的那种。别的同学念语文目的不及我来得沉重,而我是依靠父亲伏案工作来读书的孩子。在这种压力之下,心里急着一个交代,而且,内心也是好强的人,不肯在班上拿第二。每一堂课和作业一定要得满分,才能叫自己的歉疚感少一些。
苦读三个月之后,学校老师将我叫去录音,留下了一份学校的光荣纪录;一个三个月前连德语早安都不会讲的青年,在三个月的教道训练之后,请听听语调、文法和发音的精华。那一次,我的老师非常欣慰,初级班成绩结业单上写的是——最优生。
拿着那张成绩单,飞奔去邮局挂号寄给父母。茫茫大雪的天气里,寄完了那封信。我快乐得流下了眼泪,就是想大哭的那种说不出来的成就感。当然这里又包含了自己几乎没有一点欢乐,没有一点点物质享受,也没有一点时间去过一个年轻女孩该过的日子,而感到的无可奈何与辛酸。那三个月,大半吃饼干过日的,不然是黑面包泡汤。
也不是完全没有男朋友,当时,我的男友是位德国学生,他在苦写论文,一心将来要进外交部。而今他已是一位大使了,去年变的,这是后话,在此不说了。
在德国,我的朋友自律很严,连睡眠时枕下都放着小录音机,播放白日念过的书籍。他说,虽然肉体是睡了,潜意识中听着书本去睡,也是会有帮助的。他不肯将任何一分钟分给爱情的花前月下,我们见面,也是一同念书。有时我已经将一日的功课完全弄通会背,而且每一个音节和语调都正确,朋友就拿经济政治类的报纸栏来叫我看。总而言之,约会也是念书,不许讲一句闲话更不可以笑的。
约会也不是每天都可以的,虽然同住一个学生村,要等朋友将他的台灯移到窗口,便是信号——你可以过来一同读书。而他的台灯是夹在书桌上的那种,根本很少移到窗口打讯号。在那种张望又张望的夜里,埋头苦读,窗外总也大雪纷飞,连一点声音都听不见。我没有亲人,那种心情,除了凄苦孤单之外,还加上了学业无继,经济拮据的压力。总是想到父亲日日伏案工作的身影,那一块块面包吃下去,等于是喝父亲的心血,如何舍得再去吃肉买衣?总是什么物质的欲望都减到只是维持生存而已了。
因为初级班通过的同学只有四个,而其他十一个同学都不许升班,老师便问我想不想休息三个月。他也看见我过度的透支和努力,说休息一阵,消化一下硬学的语文,然后再继续念中级班是比较合理的。
听见老师叫我休息,我的眼泪马上冲出来了。哪里不想停呢?可是生活费有限,不念书,也得开销,对自己的良知如何交代?对父母又如何去说?于是我不肯休息,立即进了中级德文班。
中级班除了课本之外,一般性的阅读加重了许多,老师给的作业中还有回家看电视和阅报,上课时用闭路电视放无声电影,角色由同学自选,映象一出来,我们配音的人就得立即照着剧情讲德文配音——这个我最拿手。
“听写”就难了,不是书上的,不能预习,在一次一千多字有关社论的报纸文字听写考试中,一口气给拼错四十四个字。成绩发下来,年轻的我,好比世界末日一般,放学便很悲伤,一奔到男朋友的宿舍,进门摔下考卷便大哭起来。那一阵,压力太大了。
我的朋友一看成绩,发现不该错的小地方都拼错了,便责备了我一顿。他也是求好心切,说到成绩,居然加了一句——将来你是要做外交官太太的,你这样的德文,够派什么用场?连字都不会写。
听了这句话,我抱起书本,掉头就走出了那个房间。心里冷笑的想——你走你的阳关道,我过我的独木桥,没有人要嫁给你呀!回到自己空虚的房间,长裤被雪湿到膝,赶快脱下来放在暖气管上去烤。想到要写家信,提起笔来,写的当然是那场考坏了的听写,说对不起父母,写到自己对于前途的茫茫然和不知,我停下了笔将头埋在双臂里,不知再写什么,窗外冬日的枯树上,每夜都停着一只猫头鹰,我一打开窗帘,它就怪嗥。此生对于这种鸟的联想有着太多寂寞的回忆,想起来便不喜欢。
每天晚上,修补鞋子是天快亮时必然的工作。鞋底脱了不算,还有一个大洞。上学时,为着踏雪,总是在两双毛袜的里面包住塑胶袋,出门去等公车时,再在鞋子外面包上另一个袋子。怕滑,又用橡皮筋在鞋底鞋面绑紧。等到进了城内,在学校转弯处,快碰到同学时,弯腰把外层的塑胶袋取下来。为了好面子,那脱了底的鞋总当心的用一条同色的咖啡色橡皮筋扎着,走起路来,别人看不出,可是那个洞,多少总渗进了雪水。进了教室立即找暖气管的位置坐下来,去烤脚,虽然如此,仍是长了冻疮。
同学们笑我为了爱美,零下十九度都不肯穿靴子。哪知我的脚尺寸太小,在柏林买不到现成的靴,去问定做价格,也不是一个学生所花费得起的。自然,绝对不向父母去讨这种费用,家信中也不会讲的。
那天考坏了,被朋友数落了一顿,都没有使我真正灰心,写家信也没有,做功课也照常,只是,当我上床之前,又去数橡皮筋预备明天上学时再用时,才趴在床沿,放开胸怀的痛哭起来。
很清楚的记得,那是十二月二日,一九六九年的冬天。
那时候,学校说二十二日以后因为圣诞节,要放几天的假,我跟一位同宿舍的男生约好,合出汽油钱,他开一半,我开一程,要由西柏林穿过东德境内,到西德汉诺瓦才分手,然后他一路玩玩停停去法国,车子由我开到西德南部一个德国家庭中去度节。我们讲好是二十三日下午动身。那时,由西柏林要返回东德去与家人团聚的车辆很多,边境上的关口必然大排长龙,别人是德国人,放行方便。我是中国的人,那本护照万一临时在关卡不给通过,就穿不过东德境内,而坐飞机去,又是不肯花机票钱的。
为了这事,那位与我同搭车的法国朋友心里有些不情愿,怕有了临时的麻烦,拖累到他。那位朋友叫米夏埃。他坚持在旅行之前,我应该先跑到东柏林城那边的东德政府外交部去拿过境签证。如果不给,就别去了。说来说去,就是为了省那张飞机票钱才弄出这么多麻烦的。
米夏埃不常见到我,总在门上留条子,说如果再不去办,就不肯一同开车去了。我看了条子也是想哭,心里急得不得了,可是课业那么重,哪有时间去东柏林。课缺一堂都不成的,如果缺了一天,要急死的,实在没有时间,连睡觉都没有时间,如何去办手续?
心里很怕一个人留在宿舍过节,怕那种已经太冷清的心情。“中国同学会”不是没有,可是因为我由西班牙去的,又交的是德国男朋友,加上时间不够,总也不太接近,又有一种不被认同的自卑心里,便很少来往了。
那天,十二月二日,终于大哭特哭了一场。不过才是一个大孩子,担负的压力和孤寂都已是那个年龄的极限。坐得太久,那以后一生苦痛我的坐骨神经痛也是当时死钉在桌前弄出来的。而自己为什么苦读——虽然语文是我心挚爱的东西,仍然没有答案。
第二天,十二月三日,也许因为哭累了,睡过了头,发觉桌上的小钟指着十点,又急得要哭。抓了书本就往车站跑,跑的时候,鞋子一开一合的,才知忘了扎橡皮筋。而左腿,也因为坐骨的痛压到神经,变成一拐一拐的了。
知道第一堂课是完了,赶不上。想,想自己如此苦苦的折磨所为何来,想成了呆子。站在车站牌下,眼看着一次又一次的班车走过,都没有上车。
逃课好了,冻死也没什么大不了,死好了,死好了。
没有再转车,摸摸身上的护照和二十块美金的月底生活费,将书在树丛雪堆里一埋,上了去东柏林围墙边,可以申请进去的那条地下火车。
柏林本来是一个大城,英美法苏在二次大战后瓜分了它。属于苏俄的那一半,是被封了,一个城变为天涯海角,不过一墙相隔便是双城了。
我下车的那个车站,在一九六九年是一个关卡,如果提出申请,限定当日来回,是可以过去的。而东柏林的居民却不可以过来。
那个车站是在东柏林,接受申请表格的就是东德的文职军人了。
我们的护照和表格在排了很久的队之后,才被收去。收了便叫人坐在一排排的椅子上等,等播音机内喊到了名字,又得到一个小房间内去问,问什么我不明白。总之面露喜色的人出来,大半是准进东柏林去了。
等了很久,我坐着会痛,又不敢乱走,怕听不见喊人的名字,那儿,有一个办公室是玻璃大窗的,无论我如何在一拐一拐的绕圈子,总觉得有一双眼睛,由窗内的办公桌上直射出来,背上有如芒刺般的给钉着。
有人在专注的看我,而我不敢也看回去。
播音机叫出我的名字来时,已是下午一点左右了。我快步跑进小房间,密封的那一间,没有窗,里面坐着一位不笑的军官。请坐,他说。我在他对面坐了下来。军官衣着很整齐,脸色不好,我一坐定,他便将那本护照向桌上轻轻一丢,说:“你知道这本护照的意义吗?”我说我知道。他听了便说:“那你为何仍来申请?我们不承认你的,不但不承认,而且你们的政策跟南韩一样。现在我正式拒绝你的申请。”我看了他一眼,站起来,取回了护照,对他笑了一笑,说谢谢。那时的我,是一个美丽的女人,我知道,我笑,便如春花,必能感动人的——任他是谁。
已经走出了门,那位军官是心动了,他很急的叫住了我,说:“你可以去西柏林付十五块美金,参加有导游带的旅行团,我给你一个条子,这种护照也可以过去的。”
我说,我是要去你们东德的外交部,导游会放人单独行动吗?再说,十五块美金太贵了,我有,可是舍不得。说完我没有再对那个人笑,就出来了。
决定逃学,决定死也可以,那么不给过去东柏林也不是什么大事,不去也就不去好了。时间,突然出现了一大段空档,回宿舍,不甘愿,去逛街,只看不买不如不去,于是哪儿也没有去,就在那个车站里晃来晃去看人的脸。
那面大玻璃窗里仍然有一种好比是放射光线一样的感应,由一个人的眼里不断的放射在我身上,好一会儿了,他还在看我。
等我绕到投币拍快照片的小亭子边时,那种感应更强了。一回身,发觉背后站着一位就如电影“雷恩的女儿”里那么英俊迫人的一位青年军官——当然是东德的。
“哦!你来了,终于。”我说。他的脸,一下子浮上了一丝很复杂的表情,但是温柔。“晃来晃去,为什么不回西柏林去。”我指了一下那个密封的审人室,说:“他们不给我进东柏林。”我们又说了一些话,说的是想先进去拿过境签证的事。一直看他肩上的星,感觉这个军官的职位和知识都比里面那个审人的要高,而且他不但俊美,也有一副感人而燃烧的眼睛,这个人那里见过的?
事情很快解决了,台湾护照东德不承认,给发了一张对折的临时证。上面要写明身高、眼色、发色、特征等等——在填写特征时,我写:牙齿不整齐。那叫它通行证的东西是白色的。说要拍张快照,我身上没有零钱,那位军官很快掏出了钱。一下子拍出来三张,公事用了两张,另外一张眼看他放入贴心内袋,我没说一个字,心里受到了小小的震动,将眼光垂了下来。
排队的人很长,一个一个放,慢慢的。那位帮我的军官不避嫌的站在我的身边,一步一步的移。我们没有再说话,时光很慢,却舍不得那个队伍快快的动。好似两个人都是同样的心情,可是我们不再说话了。
等到我过关卡时,军官也跟了过来。一瞬间,已站在东柏林这一边了。凄凉的街上,残雪仍在,路上的人,就如换了一个时光,衣着和步伐跟西柏林全不一样了。“好,我走了。”我说。那个军官很深的看了我一眼,慢慢说了一句英文,他说:“你真美!”听了这句话,突然有些伤感,笑着向他点点头,伸出手来,说:“五点钟,我就回来。可以再见的。”他说:“不,你进入东柏林是由这里进,出来时是由城的另外一边关口出去。问问路人,他们会告诉你的。外交部不远,可以走去。我们是在这一边上班的人,你五点回来时,不在我这里了。”
“那,那么我也走了。”我说。
我们没有再握手,只互看了一眼,我微微的笑着。他,很深的眼睛,不知为什么那么深,叫人一下子有落水的无力和悲伤。
就那么走到外交部去,一面走一面问人,路上有围着白围巾的青年,一路跟着要换西柏林马克或美金,随便多少都可以。我不敢睬他,只是拒绝得难过。
都快下班了,才问到签证的柜台,也不存希望给或不给,孤零零的心,只留在那个离别时叫人落水的眼睛里。
是东德,在东柏林的外交部,是一种梦境,很朦胧的倦和说不出的轻愁。那本护照——台湾的,就如此缴了上去。
看护照的中年胖子一拿到,翻了三两下,就向身后的同事叫嚷,说:“喂!来看这本护照呀!蒋介石那边来的。”人都围上来了,看我。我的心,仍在那双眼睛里。随便人们如何看我,都很漠然。“蒋——介——石——嗯。”那位中年人叹了口气。
也是那日不想活了,也是多日不想活了,当他说到这句话,我就自杀似的冲出了一句:“蒋介石,我还是他女儿呢!”“真的?!”对方大叫起来。
他呆呆的看住我的名字,一念再念——陈、陈、陈……。“你说老实话哦!”他说。我不说话,只是笑了笑。那双眼睛,今朝才见便离了的眼睛,他说我真美丽,他用英文说,说成了他和我的秘密还有终生的暗号。
“你姓陈,他姓蒋,怎么会?”又问。
我反问他:“请问给不给经过东德的签证嘛?”他说:“给、给、给……。”急着哗一下盖了章,就成了事。
隔着柜台,我竖起了脚尖,在那中年胖子的脸上亲了一下,说:“你真美,谢谢你。”然后,走了。
东柏林在展越南战争的照片,进去看了一下。那张,美军提着越共的头,踩在无头尸体上,有若非洲猎象猎兽的成就感,在那个大兵的脸上开着花。没有再看下去,觉得自己是一个亚细亚的孤儿。
去饭店吃了一顿鱼排,付帐时,茶房暗示我——很卑微的那种笑,使我付出了不是过境时换的当地钱。有二十块美金,给了十块,每月生活费的十分之一。没有等找钱,向那位老茶房笑笑,便走了。
经过一家书店,看见齐白石的画,我一急,进去了,要人窗内拿下来,发现是印制的,不是原墨,就谢了走开。
街上行人稀少,有女人穿着靴子,那是我唯一羡慕的东西。
又走了很多路,累了,也渴,天在下午四点时已经暗了。可是这边的城没有太多灯光。问到了出关回西柏林的地方,关口很严也牢,是九曲桥似的用曲折墙建出来的,我猜是怕东边的人用车子来闯关而设计的。
他们不给我回去,一直审问,问我那张白色的通行证如何得来的?为什么会身上又有一本台湾的护照藏着。又问来时身上报了二十美金,怎么换了五块美金的当地东德马克仍在,而那另十五元美金只剩下了五块一张。我说吃饭时付错了。问是哪一家饭店,我答谁记得路。
他们不给我走。我急了,急得又不想活了,说:“你们自己发的通行证,去问放我过来的那个关卡。去问!打电话去问呀!好讨厌的,也不去解决。”
不知过了有多久,我弯弯曲曲的走过了一道又一道关,门口站着来接的,是中午那个以为已经死别了的人。他在抽烟,看见我出来,烟一丢,跨了一步,才停。
“来!我带你,这边上车,坐到第五站,进入地下,再出来,你就回西柏林了。”他拉住我的手臂,轻轻扶住我,而我只是不停的抖,眼前经过的军人,都向我们敬礼——是在向他,我分不清他肩上的星。
在车站了,不知什么时刻,我没有表,也不问他,站上没有挂钟,也许有,我看不见。我看不见,我看不见一辆又一辆飞驰而过的车厢,我只看见那口井,那口深井的里面,闪烁的是天空所没有见过的一种恒星。
天很冷,很深的黑。不再下雪了,那更冷。我有大衣,他没有,是呢绒草绿军装。我在拚命发抖,他也在抖,车站是空的了,风吹来,吹成一种调子,夹着一去不返的车声。没有上车,他也不肯离去。就这么对着、僵着、抖着,站到看不清他的脸,除了那双眼睛。风吹过来,反面吹过来,吹翻了我的长发,他伸手轻拂了一下,将盖住的眼光再度与他交缠。反正是不想活了,不想活了不想活了,不想活了……。“最后一班,你上!”他说。我张口要说,要说什么并不知道,我被他推了一把,我哽咽着还想说,他又推我。这才狂叫了起来——“你跟我走——”“不可能,我有父母,快上!”“我留一天留一天!请你请你,我要留一天。”我伸手拉住他的袖子,呀!死好了,反正什么也没有,西柏林对我又有什么意义。
怎么上车的不记得了。风很大,也急,我吊在车子踩脚板外急速的被带离,那双眼睛里面,是一种不能解不能说不知前生是什么关系的一个谜和痛。直到火车转了弯,那份疼和空,仍像一把弯刀,一直割、一直割个不停。
那一夜,我回到宿舍,病倒下来,被送进医院已是高烧三日之后才被发现的。烧的时间头痛,心里在喊,在喊一个没有名字的人。
住了半个月的三等病房,在耳鼻喉科。医生只有早晨巡视的时候带了一群实习医生来,探病的人一周可以进来一次。我的朋友念书忙,总是打电话给护理室,叫小姐来传话问好,但人不来。
医院的天井里有几棵大枯树,雪天里一群一群的乌鸦呱呱的在树枝和地上叫。病房很冷,我包住自己,总是将头抵在窗口不说什么。同住一房的一位老太太,想逗我说话,走上来,指着窗外对我说:“你看,那边再过去,红砖公寓的再过去,就是围墙,东柏林,在墙的后面,你去过那个城吗?”
请你带我走-[[《邦查女孩》]]免费在线阅读_稻草人书屋
========================
[https://www.20dcr.com/book/bangchanvhai/2627853.html](https://www.20dcr.com/book/bangchanvhai/2627853.html)
# 请你带我走
[* 邦查女孩](/book/bangchanvhai/)
* [[甘耀明]]
* 2019-03-05 16:01:03
-----
那场夏日战争很有名,有三百一十五人参战,全被“杀刀王”帕吉鲁的右手摆平了。“杀刀”不过是游戏,将一手伸出来当长刀,一手藏在后腰,用手刀砍到对方的头或膝盖以下便赢了。人马分两队较劲,被砍死的关在电线杆下,等队友来救。这种游戏有时会擦出火药味,成了地域或校区之分的小规模战斗,最后混入了小流氓,变成城市大战。
那场大战怎样开始的没有人说得明白,最后却被所有人记得,因为变成爆粗口与大规模的拳脚,不少人攻击对方头部时,以扇巴掌的合法方式打哭弱者,三百多个男孩聚在路口叫嚣,拉人助阵,演变成两派的大冲突,有人拿出扁钻与小刀示威,很快就要见血了。
这时候,帕吉鲁出现了,往三百多位男孩的战场中央站去。他把牵来的双杠脚踏车的脚架竖起来,双手拍出吓人的响声,左手藏在后腰,右手伸出来,比出了邀架手势。他口气很大,把手挽一圈,向全场的人下战帖,最后把手尖对准一位拿小刀的小流氓,先让对方的刀子往前刺了半尺后,才拍掉刀子,更用上半个令人传诵的说不清楚黑影,就点赢了额头。然后,帕吉鲁再度比手势,要全场的人通通打过来。整个过程被形容是李小龙在《精武门》中用迷踪拳跟上海虹口道场的日本人挑战。
帕吉鲁是独行侠,很少进城,一来就轰动,跟火车从中央山脉运来的大尸块一样轰动。他戴白色探险帽、牵铁马、载宝刀盒的形象,冬天又多披一件红披风,向来是一九七〇年代的花莲市传奇。最传奇的是他车后座载宝刀盒,来找老师傅修武器。宝盒又大又长,棱角处裹铜片,里头装着大型的古怪兵器,有的像是座头鲸下颚的屠龙刀,有的像锯齿鲨的利锯齿,还有可以当飞镖丢的大斧头。他是哑巴,嘴总是叼着草,更显露了孤独的调性。
帕吉鲁赢了小流氓,没有人敢上前挑战,因为他是花莲市最厉害的高手,才被封“杀刀王”。三百人簇拥上去绝对能把他拍成肉酱,却不懂帕吉鲁为谁而战,为何而战,他很像来闹场的。没人想挑战。最后,他的右手四指往内勾几下,对着某个方向邀战,拍拍口袋,示意有钱。那个方向的人墙裂开缺口,露出后头的三位“叭噗①老伯”。帕吉鲁要跟他们过招。
叭──噗──
场子边卖冰的叭噗老伯压着车龙头上挂的小皮球,令簧片发声,“夭寿!莫打了,人生海海,吃叭噗比较 high。”他们说完,把烟吐掉,抬头露出邪恶的微笑,牵着脚踏车来到场子上,要跟帕吉鲁来场会外赛了。
叭噗老伯是令人又爱又恨的程咬金,车上挂着铝壳掉漆的大冰桶。大家在哪玩,他们去哪卖冰,有时站在战场中央抽烟,猛按叭噗,故意大声讲色情故事,要大家吃冰消火。大部分的孩子穷得没钱吃冰,连寒冬想到冰都会流口水。
叭──噗──
会外赛是丢飞镖盘游戏。飞镖盘放在脚踏车后座,软木圆盘,以铁丝隔出放射状的冰品区块。丢飞镖游戏不利玩家,付了钱,多是丢中比花钱买还要小份的冰淇淋。要是丢中特别奖的“天霸王”,不用付钱外,还得到双份的冰,这几率是孩子们形容的“往后下腰能看见自己的屁股”。这种赌博性游戏很吸引人,顾客被快转的盘子催眠似朝它丢镖,像钱丢到河里,只听见水声般的喜悦。
叭──噗──,老伯发出神秘的微笑,转动飞镖盘。
帕吉鲁伸出右手捻镖子,左手缩在后腰,第一次出手,镖子没扎到盘子,弹到地上。他付钱再玩,出手后射中“再来一次”的格子。他抽起镖子再丢,转盘停了,意外地中了特别奖。
“赞!天霸王。”凡是中这格,叭噗老伯得大喊吸引人,拉开冰桶盖,压两下冰勺发出机械声响,往冰雾弥漫的圆桶里挖两大勺。他动作有些不甘愿,微笑也很职业。
帕吉鲁拿下双份的冰淇淋,示意敌对双方的主帅来拿。他没讲话,用眼神与手部的肢体动作示意。接着,他拿起镖子,扶了扶自己的墨镜,往第二摊的转盘射去。
“媠②!天霸王。”第二摊的叭噗老伯大惊。
帕吉鲁挑战第三摊,镖子落下,叭噗老伯最后喊:“恭喜喔!天霸王。”帕吉鲁拿起双份的冰淇淋,要男孩们共享。战况解除,大家聚在摊贩边,舔上一口冰,可是仇恨还在。
接下来,帕吉鲁示意要再玩一次转盘,而且一次丢三盘。三百多位男孩围着看赌局,后头几圈只能事后听闻。他们有的站上围墙,有的爬上路树,四周的电杆从上到下也夹了一串小孩。他们看到帕吉鲁左手拿冰,右手捏拳暖手,三支镖子衔在嘴上。
冰淇淋大战开始了。诈就诈在这,叭噗老伯会先用针把天霸王那块插上百回而变得松烂,或在底下偷垫坚硬的芭乐木,射中的镖子容易被快转的盘子甩出来。阳光下,巷口安静极了,风从每个街道灌来,花莲市的每种味道聚在这,男孩们也是。
古阿霞也混在人群中,穿工作雨鞋,手拿苍蝇拍,身上永远沾染了虾仁炒饭的油烟味。她只不过是路过去买包糖回家,指甲缝还残留偷吃的糖粒,却受到鼓噪声吸引。她勉强挤入人群,看到了帕吉鲁。
这不是古阿霞第一次看见帕吉鲁,曾经在某杂货店遇到,她排在后头。帕吉鲁买汽水,付出的小钞又从老板手中转到古阿霞手中。古阿霞有随手闻钞票的习惯,她闻过各式的钱钞,有油墨味、鱼腥味、霉味、海洋味,会猜它们曾在哪些人流转。那张钞票有香味,不是老女人的明星花露水的艳甜味。确切点说,那张钞票好像是木匠刨下来的薄木片,有好闻味道。
现在,帕吉鲁手中握着十几张卷成筒状的钞票,比手画脚。可是叭噗老伯不懂这哑巴的手语。古阿霞懂了,帕吉鲁要以手中的钞票赌上那几桶冰淇淋,如果全中了天霸王,冰都属于他的,输的话,钱归三位叭噗老伯均分。那些钱,买六辆车的冰淇淋也够。
“他要赌三台车的输赢,一次拼三个镖盘。”古阿霞在人群中喊。
没有错,这是帕吉鲁的意思,他瞧去,在人海里是谁那么懂他的心思,只有一堆摇晃的黑发。他回过头,对三位叭噗老伯点头,把钱放在车座。
叭噗老伯彼此看一眼,认为这是公平的赌局,不是赚翻,就是赔倒,而且不会有人再运气好到能三次全中。他们把镖子拔出来递给帕吉鲁,更使劲地猛转盘子,强大的离心力会使镖子扎下去后很容易脱落。
出手了,帕吉鲁下镖子,朝三个盘子射去。
啵!啵!啵!三声,非常清脆,是刺穿天霸王格子底下一种俗称“鲈鳗”的垫木声响。他重温声音,感受到这种树皮长出类似鲈鳗斑而得名的乌心石,长在东坡,海拔100公尺③余,可能来自附近的美仑山。此树坚硬无比,常是砧板的首选。还有,这三个转盘出自同一位师傅制作。帕吉鲁转身离开,慢慢走出人群之后,步伐加快,赶在欢呼的人潮围死他之前离开花莲市。
所有的人在原地等结果呢!尤其是三位紧张的叭噗老伯,忘了照例以手掌碰触盘缘的铁皮煞停,而是让它们慢慢地停下来。阳光下,飞镖盘越转越慢,最后静止不动。
三位叭噗老伯怒喊:“干你娘咧!”
男孩们和解地欢呼尖叫,边吃冰边回头去找人。
帕吉鲁弭平三百多人的大战,且不见了,再添一则花莲市的传奇。
在中华路后头的小巷里,阳光在十点左右照进来。古阿霞坐在小板凳,两腿间放了装水的脸盆,忙着洗菜。她是优秀的洗菜工。菠菜的蒂头很会塞泥土,高丽菜不要洗碎,还有花椰菜的蕊缝最容易藏着菜虫。要是炒完菜的锅底汤汁带黑渣,会归咎古阿霞,所以她得掌握诀窍,洗得又快又好,连最难搞的挑菜剥丝也难不倒她。
越到中午,杂活越紧,古阿霞却爱偷懒,忙里偷闲总有难忘的美景。因为这时候的阳光来到小巷,水光反射,流动着幽幽淡淡的剪影,好多影子啵滋啵滋地发芽成长。小猫从屋底出来晒太阳,蜗牛的干渍爬痕是最美的胶水抽象画,光亮中的尘埃模仿了星云流动。她闭上眼,面对太阳光,光芒从瞳孔流进体内,肺叶在行光合作用。
她知道今天帕吉鲁会来,就像这阳光,从她眼睛接收后,顺着血液流动到全身,连头发也会发热。不过,她认为帕吉鲁会来的念头,每天都有,持续六个月了,往往扑个空。这无所谓,有机会就出去跑跑,她不想下一个五年她还是关在这间餐厅与梯间卧房。
那个星期二,下午三点,小巷又恢复暗冷,却是处处流动着重复且清脆的单音,如水龙头滴水、铁皮在风中撞击、脚踏车链条响。古阿霞坐在板凳上,趁空闲看着闲书,她喜欢看书,不懂的字翻字典。可是这时候越看心越烦,情节卡在视神经上,读不进心里,字典也搁在合拢的膝盖没动。
“兰姨,你的烟快没了,我帮你跑腿。”古阿霞说,她想去找帕吉鲁。
兰姨坐在门槛上,头倚着墙,吃着花生米,听着收音机播放闽南语版的《相逢有乐町》,等到古阿霞讲到第三回,她才说:“没有,我烟抽得省。阿霞,你要是闲,去打苍蝇。”
古阿霞打完苍蝇,又问:“兰姨,你真的不缺槟榔?”
“我很久没吃槟榔了,阿霞,要出门就出去吧!”兰姨知道这女孩难得想出门却牵拖一堆理由,出去记得回来就好。
古阿霞马上头也不回地冲出去。兰姨探出身子要她带包卫生棉回来,却不见影,她失望之际,古阿霞从遥远的巷底探出头,说:“兰姨,听到了。”兰姨这才笑得很长,勾起好多回忆,她心里想,这个小女孩才十八岁,可是像她上辈子的女儿一样机灵。
兰姨这样想时,古阿霞又跑出50公尺外。她在路上随手摘了人家院子里探出篱笆外的山樱花,插在背后。复瓣樱花好大一丛,又挤又热闹,随着她的奔跑而落下点点。她沿着中山路,冲刺在冰冷柏油路。这条路在日治时期以铺上黑色柏油而博得“黑金通”之称,是花莲第一大道。她冲出第三条巷子,把常在积水厨房穿的雨鞋拎在手上跑。到了第六条街,她抱怨不该听兰姨的,用稀释的醋泡软脚上的厚茧好用刀削掉,不然她就跑到第十条街了。在第十二条街的长老教会,她真想把微隆的胸部压下,汗水会让乳头露馅。跑到第十八条街,她一身酸痛,却没抱怨了,还对上帝发出最深切的赞美,她看到帕吉鲁了。
帕吉鲁在吃煎蛋,坐在巷口的矮桌,身边围着一圈圈的小孩。煎蛋由萝卜丝与九层塔混搭,挤上美乃滋,撒上大量柴鱼片,卷薄的柴鱼片在热气烘托下像印度弄蛇不断地摆动。帕吉鲁点了十份,要那些跟他玩杀刀斗输的人一起吃。巷口都坐满了孩子,他们先抓柴鱼片吃,抠完美乃滋,才一小块一小块地捏起煎蛋吃,觉得这是最完美的阶下囚享受。
“平安!”古阿霞先用上基督教的问候,然后说,“帕吉鲁先生,我们来决斗吧!”
大伙愣住了,帕吉鲁抬头看。古阿霞又黑又瘦,头发很卷,哪来的晒过头的茄子跟花椰菜,可是她眼睛很亮,只有高山的巨嘴鸦的紫蓝翅膀才会有那样的光膜。这女孩找他干吗?帕吉鲁狐疑,全世界对他有兴趣的只有他妈妈,还有他养的黄狗。
“我们现在来决斗吧!我把东西带来。”她展示背后的樱花,凡是斗输的人得赠上任何东西,要是赢的人──这几率微乎到抠鼻屎时发现了钻石──可以提出要求。古阿霞必须赢,彻底发挥一小时洗六大篮蔬菜与掏九只鸡肚内脏的功夫,甚至十分钟打昏六十八只苍蝇的力道。她要赢,然后要求这个男人带她离开花莲市,不管去哪里都行。
“你很烦咧!不要吵,没看到我们在吃东西?”一个带头的孩子站起来,要古阿霞闪开。
“我时间不多,我待会还要回去洗菜,也得买卫生用品回去。”
“我等一下要去买米酒,要买盐,还要去菜园浇水,回家要帮弟弟洗澡,我功课还没写。你看,我时间更不够。”某个孩子站起来,对大家喊,“谁的时间最多的?”
“火车站的时钟。”几个孩子大喊。
古阿霞很坚持,摆出决斗的姿势,“拜托,我等一下还要回去工作,不能等太久。”
帕吉鲁想起来了,这道声音曾在冰淇淋大战中帮过他。他决定在半招内把这女孩打败,好谢谢她。
他站起来,却看到恐怖的一幕。有个愤怒的粗汉冲他来,推开围观的男孩,把古阿霞挤歪,大喊:“好胆勿走。”他手上拿的菜刀不是玩假的,往帕吉鲁砍来。
帕吉鲁机灵闪开,刀子在油渍的木桌迸刨出一条垢。接着,粗汉用刀指着自己没穿鞋的赤脚,骂了脏话,说:“上次我儿子拿我的皮鞋跟你赌,那双皮鞋一双一百元,害我没鞋只能穿拖鞋出门。你这个人,怎么能教坏小孩赌博?”说完话,把儿子从人堆拉出来。他的儿子穿卡其服,打赤脚,耳根子红辣辣的,头揿得低,只能见到三分平头顶的发旋子。
这是杀刀的规则,赢者可以向输者拿取某项东西。帕吉鲁从来不主动跟输的人拿东西,是输的孩子主动献上物品,一件衣服、单只鞋子、棒棒糖或现场拔下带有血丝的松动乳牙,只有搞不清楚的人才会拿皮鞋。
粗汉挥几下刀,马上制伏了帕吉鲁。在场的人都知道,帕吉鲁不好惹,有一双虾子腿,弹来跳去,碰不着他,这是他向来是赢家的原因。可是帕吉鲁闪几下后,故意跌个跤,给粗汉骑上来。他的如意算盘是让这男人多骂几句后,一切就可以淡化,别让挥来挥去的刀子无意间砍伤了旁人。
这粗汉有前科记录,附近的人不敢惹。他怒气甚强,跨骑在帕吉鲁胸口,两脚夹住他的手,用刀抵住他的腮帮子,希望他的嘴巴发挥功能,说出如何赔偿天价。帕吉鲁是个哑巴,只能惊讶地张大嘴,惹得粗汉就要下刀了。
“快赔我一百元皮鞋的钱,要不然,我砍死你的头。”粗汉大吼。
谁都知道,一双一百元皮鞋是天价,鞋子不是镶金,就是剥了天皇老子的皮制成的。可是刀子抵住喉咙,这双天价的鞋算便宜的。
这时候,古阿霞尖叫。那种叫声极为悠长,而且猖狂,还掺着惊喜。她这功夫是在一九六八年练成,那时红叶少棒打赢日本和歌山队,她过于喜悦而瞬间练就喉功。场子上的人回过头看,没有人知道古阿霞要干吗,不过,有两位年纪约八岁的小孩,被突如其来的叫声吓湿了裤裆。
古阿霞的声音非常长,逼到高八度的喉尖后,瞬间收音,用手刀作势划了自己的脖子,说:“砍下去。”
大家都糊涂了,不知道这什么把戏,都觉得脖子痒。
“你说什么?”粗汉被古阿霞吸引,抬头大喊。
“快杀了他。”古阿霞强调。
大家莫不想阻止杀戮,古阿霞却唱反调。
粗汉也是,刀在他手中,杀人是他的活,干什么听一位女孩的,怒气使得他脑袋红得像是通电的钨丝灯泡。
“拜托,快点杀他。我时间不多,看你杀死人后,得绕路去买东西。你早点杀死他,我早点回去工作。唉哟!不要在那发呆浪费时间了,来,我教你怎么杀人,”这是古阿霞折磨自己脑袋所想到的办法,“你不要割他的喉咙,要往脖子边割动脉,血往外喷才不会弄脏你。血流光,你再砍下他的头。然后,让警察很快抓到你,你赶快吃牢饭三十年,差不多就是你手上这把刀烂光光的时候,你就出狱了。不过,你得习惯一件事,你老婆早就跟别人跑了,你儿子会把你这个老废物踢出门。你握着烂刀柄去讨饭,绝对有饭吃。”
“谁说我要杀死他,我只要砍他的手。”粗汉有点紧张地说。
古阿霞见机会来了,说:“砍手也会死,他的手断了,拿不住筷子,会饿死的。”
“我砍他左手就好。”
“你知道他是左撇子还是右撇子?算了,干脆随便砍一只手,你早点砍,我早点回去工作。但是,我跟你讲,砍手有技巧,要砍关节那个地方,刀子不会卡住。砍下去,只要吃十年公家饭,不过,你在牢里要想办法弄个假释,不然老婆跟人跑。”
“谁说我要砍手,我只要挑断他的脚筋。”
“砍脚筋,啊,这我最懂。你快点砍呀,我待会也要回去砍猪脚筋。我告诉你怎么砍,抓住这家伙的五根脚趾头往上扳,这样脚筋紧了就好砍,绝对不会砍下去,让刀子倒弹,还会被他踹的问题。”
“就这样,砍完呢?”
“当然快跑,沿中山路跑到火车站,跑到海边,跑过琉球村,从白灯塔堤防那里跳上渔船,顺台湾绕个几十圈吧。趁大家忘了你之后,你才能偷偷上岸爬回家。”
“我为什么听你的话?”
“你不是要砍他,你砍完,我早点走呀!你看,警察来了,你现在砍还来得及,也许能剁下他的一根手指。”其实古阿霞没看到警察,她只是兜个谎,得夸张点才能继续演下去,她跳起来,大喊,“警察杯杯④,不要来,我们这边什么事都没发生。”
“干,你这破麻仔⑤。”粗汉说完,跑走了。
古阿霞拉起地上的帕吉鲁,很快离开现场,就怕粗汉随时回来。帕吉鲁惊魂甫定,额头冒冷汗,得靠古阿霞在后头推脚踏车。接近傍晚的花莲市区,人流多了些,不少是观光人潮。古阿霞提高嗓子喊:“让路,让路。”她生怕车后头横放的大木箱打着人,却忙得看来像是急着运棺材、趁尸体还热时放进去的殡葬业。急归急,但没有漏眼,古阿霞很快回到了那条巷子。
餐厅的人正在干活,洗菜的洗菜,炒菜的炒菜,着急的穷着急,大家在油烟乱窜的厨房忙得碰运气才不会掉进锅里。发怒的兰姨终于等到古阿霞回来,拿着铲子出门,要她上工,别给大家添麻烦。
“我得走了。”
“去哪?”
“离开花莲市,我现在要跟他走了。”古阿霞紧握着帕吉鲁那只急着挣开的手。
兰姨焦虑起来,她要古阿霞买卫生棉,却带回灾难。她的大脑需要尼古丁来厘清问题,可是嘴角只有烟渍。她摸了放烟的左胸衣袋,除了急升的心跳之外没有东西。这时连烟都没了,何况一个女孩。她潇洒地说:“跑吧!阿霞,我要是年轻也想找个男人跑了,趁老板还没回来,快走吧!”
随即,厨房发出了婆婆妈妈们的欢呼,冲出去对帕吉鲁问东问西,使出一群丈母娘看女婿的功夫。
这正是古阿霞要的。她冲进屋内,钻近楼梯下的小房间收拾细软。那里约1坪⑥大,除了木床,摆满了沙拉油桶、酱油桶与味精盒,硬邦邦的棉被有各种调味酱味道,她的衣服缝线永远塞了面粉。她喜欢文字,墙上糊着遮丑用的《更生日报》,墙角有几堆看得卷边破页的杂书,甚至背下味精盒标签上写的主要成分是麸胺酸钠⑦。要不是从天花板挂下一盏20瓦灯泡,带给她看书的光明,才不会让自己沦为老鼠与蟑螂的屠夫。
她把几件衣服与书本塞袋子,从床底抽出钞票,再看看还要拿什么,这时她的额头不经意碰到了灯泡。灯摇动,影子晃动让人以为摆设也跟着晃起来,晃呀晃的,她心头沾了惆怅,泪眼蒙眬。她真不敢相信自己在这待了五年,走与不走都消耗勇气,但机会一瞬间,她现在终于抓到。
球球外传:一个时代和一只小狗的际遇-野夫
========================
球球外传:一个时代和一只小狗的际遇-[[野夫]]
------
一
好久以来,和它相对枯坐在苍山下的茶隐村舍时,看着它那双忧郁的眼睛,我都不免要想——也许今生,该要我为你树碑立传,而不是你为我去守坟了。因为按自然规律,人的命再贱,不出意外的话,总要比一条狗命长。
尽管村舍里来来往往的过客,都因出于对这个小杂种的喜爱,而动员我写写它;但我总是乐观地设想,还早着呢,它才三岁。比照人类的生命周期,它正是青春岁月。也许我们还要相依为命熬出更多的故事,才轮到我为它哭泣,为这个世界讲述一只狗的颠沛流离。
然而人事尚不可测,况乎畜牲道。无妄也罢,意外也罢,一切可以降临到人类的灾难,本质上狗类也不能幸免。似乎2009年注定是一个残忍的年份,大年初三,侯哥来电幽幽地说——球球走失了,年前就已失踪,世存兄怕你伤心,没敢告诉你。
在电话里,我只能达观地说——狗也有狗的命数。在恶的人世间,它不能指望终生都能遭遇善意。大限到了,一切都在劫难逃。再说比起它的同胞兄弟姊妹,它的奇特际遇已经可谓前世的福报。更何况,一去不归的它,也许原本如世存兄引用的龚自珍的诗,它是“空山徙绮倦游身”;念念此去,或者入的竟是锦衣玉食的门户,而无须追陪几个潦倒江湖的书生,再过这种朝秦暮楚的无根生涯了。
往好处想,只为聊宽老怀。失踪的故事于我的真切隐痛,原不陌生。世间何处无刀俎?你我谁谓非鱼肉?人犹如此,狗何以堪?这样说来,悲声便可压抑。但是许下的愿——为球球传——却是我这开年的创伤之夜,必须要偿还的孽债了。既是为它,也为它那几位自我流放在祖国的卑微父亲。
二
球球的身世血缘,是我断续听来的。流浪在丽江一带的许多落魄书生音乐人,偶尔在大理邂逅它,会认出它是诗人L的养子。
球球的生母大抵原是丽江的一只流浪狗。四年前当L被都市驱赶而流落到这个古城时,也许同病相怜一见钟情,遂收留了这只相貌平平且血缘混杂的小母狗。那时,他再婚的妻子——一个原本贤淑漂亮的女人,实在不堪他那种动荡不安的生活,终于挥泪告别了他。于是衣衫落拓的他只好漂到边地,在一条游踪罕至的深巷尽头,一个唤作三十八号院的纳西木楼中,暂时赁居小驻了。
因为他的存在,三十八号院在今日的丽江古城,几乎已经成为一道江湖背包客的人文景观。谁要在滇西北一带厮混,肯定都曾去朝拜过这个码头。也许因为寂寞,或者出于生计,他把这个死气沉沉荒草萋萋的小院,异想天开地办成了一个音乐酒吧。
说他异想天开,是因为这个小院,实在太像《聊斋志异》中的某个鬼狐出没的背景了。院子古老且久无人居,燕泥蛛丝覆满空梁,窗外就是荒草颓墙别家的废墟,常有鼠蛇游离。他廉价租来后,只是在泛灰的墙上,找人胡乱涂鸦了一些非仙非道的图案,歪七竖八地扯了几条风马旗,挂了几条哈达,垃圾堆废品站去扒拉回来几张缺胳臂短腿的桌椅,然后就开张了。
没有字号招牌,没有工商注册,没有霓虹灯饰,没有像样的酒具,甚至没有红酒洋酒,只卖啤酒青梅酒和烈性的青稞酒——这也就只有他,才敢在这个国际性旅游胜地,开这样一个奇特的酒吧了。即便是我这样的老客,今天要去那阴森歪曲的寂寞深巷,不问路是仍然难以探出门径的。可想对一般的游客,那是绝无可能成为他的座上宾的。
问题是即便如此简陋,他那里依然门庭若市。乃因他那一管双截棍似的箫,每夜像一个埋名江湖之高手的暗器,总能洞穿那个喧嚣小城背后的枯寂,以至洞穿无数偶然过往的畸零者的心灵。于是许多人去过还转顾,坐下即沉醉——到了后半夜,常常满屋乌烟瘴气,地板上随处躺着的都是醉客。本来屋里就只点了一个五瓦的普通电灯,晚来的客稍不留神,就会踩踏上一些红男绿女的肚皮。因此,打架斗殴也就成了他那里长年的保留节目。
L原本有匪相,天生有叛骨,江湖有名头;虽然店里雇不起丘二伙计,但时相过从的丽江老炮,多数便成了他的兄弟。偶尔有新客闯来,不识风色,那就很容易被抬起,直接从二楼扔到墙外的荒草中去。派出所先还来问问,见摔得多了,也没出人命,只要听说是三十八号的事,便再也不肯来叨扰了。周边居民听惯了这里的鬼哭狼嚎,只当是鬼屋闹鬼,也懒得去投诉了。
那一年的L,夜里是长箫当哭,白天是和球球的生母牛衣相对,就物质层面上说,也就算是一最低级别的醉生梦死了。当他终于邂逅并留住一位今天还在陪护他的女人时,球球的生母也到了发情期,开始背着他翻墙越脊去寻找艳遇了。当这个小母狗的肚皮日渐紧绷之时,L才开始意识到要做养父的责任,以及还要重新做人的责任。
三
球球的生父是谁,似乎大家皆不甚了然。有的说是一只沙皮,有的说是京叭,总之肯定也是一个贱种流浪汉。球球一胎堕地的大约有四姐弟,也许因为血统驳杂身份卑微,个个皆无福相。要放在富贵之家,母狗临盆也是一喜;可是狗命如人,投胎到L的三十八号,几乎注定先天带着悲剧符号。只因酒吧原非餐馆,尤其是L的吧,多的是酒,缺的是骨头。当L自己都是有一顿没一顿的时候,可想而知,这一窝狗崽岂能好过。
小狗如庄稼,撒在地里即便不追肥,自个儿也会悄然长大。但哪怕就算孪生姐弟,各自的命数也因落地的时辰微异而天壤有别。在成长的过程中,一只先夭折,一只被抱养,一只迷失在古城八卦阵一般的巷陌中,可能率先上了哪家的餐桌。唯有球球,抑或先天便憨厚,长相也无足称道,竟然在三十八号的混乱生活中,像猪一样活得安然自足。因为它的胖,憨憨的模样神似L,过往的熟客便即兴唤作球球,于是这一名字就这样进入了历史。
三十八号的地下音乐在丽江日渐成名,各地的浪人也多慕名而往,使这个原本萧然的小院慢慢有了人气。尤其是那些背着吉他漫游在大地上的天下客,更把这个二十平米的小楼当成了问鼎中原的大舞台。经常看见的场景是,一些被酒色摧得嘶哑的歌手,跳到桌子上放歌,满地的男女醉鬼一起合唱——当我已老到不能做爱,你还爱我吗?就是这些即兴音乐,常常也能触动离人幽怀,现场勾出无数涕泗。
老板兼酒保还兼乐手的L,生计不愁之时,文事却日趋荒芜。女友也厌倦了这种天天打打杀杀的日子,北归读书去了。L看着硕果仅存的球球,忽然便有了觉醒——决定回耕砚田。眼看望五的他,如果以酒业终老,那确实辜负了那几年深牢大狱。于是他决定带着球球南下大理,把酒吧转给了另一个流浪乐手阿泰。因为他要是不离开丽江,天天缠着喝酒的弟兄太多,实在也无法闭门耕耘。正应了那句名言——出来混,早晚是要还的。于是他毅然背着球球——这几乎是他唯一的情感羁绊了,为着内心中不离不弃的承诺,向苍山洱海唇齿相依地飘来。
客车原是不许人畜同行的,司机死活要他丢下球球。可怜原本暴怒慷慨的L,在那一刻竟然为了怀中的一只杂种小狗,而不得不委婉乞怜,坐在车门边耍赖求情。一车人看他们情同父子,抑或也被球球那天生忧郁的眼神打动,终于说服司机,就这样移民到了南诏古城。
四
这是公元2006年的夏天,我因毁家之变,也因厌倦了京城的碌碌生计,放弃一切,只身来到大理。正可谓人生何处不相逢,我赁居的小院就在大理城墙外的南村,而L则正好寄身在我旁边不出一里的一塔寺下的一个客栈。
他牵着球球来为我接风,开篇也就是一碗味道极好的羊肉面而已。他因是长包的农家客栈的一间房,每月四百五十元,除开床铺和书桌,基本也就家徒四壁。卖文维生,自然捉襟见肘,不可能天天上餐馆解决伙食。他只好买了个电炉,再买一些杂粮,每天闭门写作,靠熬粥勉强度日。可怜球球一个天性的肉食者,也只好和他开始奉行素食主义。
狗乃忠臣义仆,即便生计拮据,胃口枯淡,还是每天摇头摆尾地看着L写文章,渐渐也有了几分儒者气。L自己也被所谓的八宝粥喝得馋虫涌动之时,便会牵着球球晃晃悠悠上街,拿牛杂肥肉解气一场。那时的球球多会在大快朵颐之后,见到小母狗就四爪抓地,和L强项对峙。
有母狗的主人乃美妇,看见这大小俩雄性胖子在当街较劲,生怕自个儿也遭遇非礼,柳眉倒竖抱着爱犬急逃。球球的被歧视连带L的人品都受到怀疑,他老脸上不免泛出尴尬。其实,L自己都没有夜生活,多少也能感同身受地理解球球的诉求。偶尔便也松开缰绳,让球球去扬鞭江湖寻找艳遇。
但是球球每次兴尽而归,都满身煤灰,黑乎乎地像一个疲惫的矿工,L就有些起疑。一次L跟踪查访,发现原来路口有一个做煤球的人户,养着一只更加邋遢的小母狗,痴情的球球原来每天就是在这里守候厮混,彼此追逐得风尘满面的。户主也是贫寒之家,经常是锁着那个素面荆钗的;看见球球来围着不怀好意地转悠,便有些厌烦。看见L就求情——不同种,搞不得,搞不得。L又是自尊心很强的人,看见球球恨不得背一把吉他去人家窗下求爱,还被人家主人干预,便生气地骂球球——你再不济,好歹也是一个诗人的狗,你连煤厂的母狗也去搞,一点品位都“莫得”(即“没有”),你把老子的脸都丢了。
球球何尝懂得人世间的炎凉,挨骂的时候倒是知道低眉顺眼,伪装出一脸的无辜。但一旦逮着机会,仍旧会一溜烟地跑向人间去寻欢作乐。结果不幸染上了狗瘟,茶饭不思,看着就像《红楼梦》里的瑞大爷,被风月宝鉴弄得即将精断气绝。那会儿我时常看见L用一个背篓天天背着它去兽医站打针,神情焦虑,来去累得牛喘吁吁,我当时还真的难以想象一个养父的钟情,竟也会如斯揪心。
球球也算是命硬之狗,在L的精心侍候下,渐渐还阳。大病初愈,狗也需要进补。L便经常牵着它,来我的小院乞食。我因租的是农家院落,有厨房庭院,自己又是个绝不茹素的饕餮之徒,伙食便接近干部水平。球球在我这里生活改善,每来必吃得脑满肠肥,但是L一出门,它便会忘记一饭之恩,立马追随而去。
L也是出于爱意,便委婉对我说,怕球球出去再染上瘟疫,我的院落长期是柴门深锁,要把球球寄养在我处。他甚至还诱惑我,说只要牵着球球上街,绝对有很多美女喜欢而来逗它,你也可以顺便搭腔接个飞碗。我原本是反对养宠物的人,对狗还有些偏见,虽然不相信他编造的爱狗及乌的露水情缘,但是看在多年的情分上,便只好应允。甚至我还威胁说,要是跑丢了,我可不负责任。可是谁承想,我这个义父一当,就再也难得释手,球球竟成了我相依相随的至亲玩伴了。
五
球球是戴着项链来的。L吃罢出门,便把它锁在我的窗下。球球初不解L的意图,看着不再牵它随行,急得呜呜欲哭,拖着铁链像拔河拉纤一般,想要追随而去。但真正一声门响之后,它似乎立马像被拐卖的孩子,顿时变得老实懂事起来,惶恐地打量着我,眼角开始润湿,匍匐在地上一副任人宰割的样子煞是可怜。
许多年前,我编过一部《狗的秘密生活》的书,对狗有点泛泛了解。本质上我是反对养宠物的,因为我一直主张与其爱动物,不如先爱人类。我曾经对一些朋友说,如果你未曾资助穷人,那你养宠物就应该感到可耻。基于这样的观念,最初的我,对球球的到来实在无所谓欣喜,多少还有些为L减负的意思。
球球属于那种长不大的杂种,毛发土黄,身体滚圆,体重大约十几斤。消瘦的时候呈尖脸,稍微猛吃几顿就变圆,且额头上胖出几道有趣的皱纹;再搭上那双忧郁的眼睛,就活脱一个苦闷的思想家形象了。它性格温良得几乎胆怯,很少有龇牙咧嘴的时候。由于习惯了沉默,凡事不愠不火的,倒显出几分大智若愚的神态。事实上,这个家伙也确实不傻,它老实巴交的外貌下,也暗藏着一些狡黠和滑稽。也许正是这种小奸小坏的性格,逐渐迎合了我的处世趣味,使我慢慢开始喜欢上它来。
我一直并未视其为宠物,还是当村狗在饲养。最初是锁着的,它的活动舞台也就链子长度的一平米左右。每天两餐,我吃什么它就吃什么。常常被我的麻辣风格弄得伸舌头打喷嚏,它也只能忍受。L偶尔带着一捆火腿肠来探亲,它就屁股摇得快闪腰了,抱着他的胡茬脸猛舔。看着它对L的亲热,我多少有些嫉妒,心想这家伙大肉吃腻了,还想喝粥吗。
我每天是要懒觉的人,大早就听见它在窗下呜呜低鸣,抓耳挠腮急火攻心的样子。我一吼它,它便改成乞怜的神态。等我牵起链子,它便往门外拖,一出大门就在野地里跷起后腿遗矢,然后双脚扒灰迅即掩盖。原来它是不肯排泄在我廊下,才这样强憋着自己的。我也不知道它从哪里获得的这种教养和习惯,为了不影响我的睡眠,我开始为它解开绳套。这样它就可以随时在花园出恭了,但它仍坚持在最角落的地方方便,不给主人添麻烦。
它平时就在院子里散步发呆打瞌睡,静如处子;但偶尔发现有松鼠或者耗子翻墙过来,它却能动如脱兔,射箭般迎击过去,并发出恐吓的号叫。一般我是不许它进屋的,到了饭点如果我还在写作,它便会从帘下探头探脑提醒它的饥饿,但脚却不敢越雷池一步。我以为它已经养成不敢进屋的习惯,有时出去忘记锁门,等我回来才发现被子上印满梅花,它似乎报复般地在我床上过瘾宣泄。我拎着拖鞋找它上课,它似乎知道犯错惹祸,远远地窥视着我的行动,不尴不尬地故作轻松。一旦我追到它,它立刻卧倒等着挨揍,既不逃跑也不嘶喊,更不会反咬一口。我的手才举到半空,它的眼睛就吓得乱眨,缩着脖子皱着眉头,一副听天由命死猪不怕开水烫的无赖相。
相处久了,感情日增,我以为它乐不思蜀了,就放松了警惕。哪知某天来客,大门刚开,它便趁机窜了出去。我追赶着叫它,它也停步看我,但我一向前冲,它就撒开丫子狂奔。我岂能跑得过它,只能看着它远去。到下午,L抱着它回来,说它跑去客栈他的门口守候着。对于这样恋旧的家伙,我还真没法惩处了。譬之于人,这正是知道感恩和毫无势利的表现,我何能苛求于这个畜生。
六
L就要回四川了,他想带着球球还乡去陪他的母亲,这时我才开始意识到依依难舍了。禅和子曾说:桑下不三宿。意味对一棵树也会生情,有情就难以破执,不破执岂能参透情关,顿悟成佛。对树犹需戒惕,况乎球球这样一个充满灵性的坏种。既然已经上了贼船,我还是决定把这个义父之责承担到底。L见我如此,遂将球球留给了我。
可是球球仍当L只是寻常的小别,逮着空子便逃亡出去找他。那时正好我也出游,平时交给邻居的房东在代养。房东十分着急,来电道歉,我让他们去L住过的段家园看看。晚上房东告我,果然在那里找到了守候着的球球。等我半月后回去,球球听我足音初到门前,便在院里惊喜撒欢,急不可待,似乎已看见一架排骨朝它走来。原来邻居房东也圈养着一只狼狗,每天只喂一餐,就只给玉米面糊。球球不能特殊化,口中已然淡出鸟来,看见我回,自然有种未被遗弃而重见天日的欣喜。
球球的天性原很纯良,且十分好客。每有客来,它比我还亲热激动。扑上去摇尾乞怜,舔手示爱,屁股扭出花来。即便十分眼馋,肉食摆在院里的矮桌上,它也只是围着转悠,从来不敢贸然上桌偷食。大家扔给它骨头,小的就迅速吞下,大的则立刻含着出屋。如果有人看它,就装作若无其事地漫步,一旦发现没人,立即找个隐蔽处刨坑,把骨头埋存进去。我常常笑话它,像一个省吃俭用的富农,对未来似乎充满了忧患意识。诗人梁乐却说,只怕它以为把骨头种进地里,来年就会长出卤肉来——一只狗也在耕耘着它的日子,偷偷期盼着意外的丰年。
很长时间以来,它给我的孤独写作确实带来了乐趣。写累了,到院子里和它说说话,恶作剧地捉弄它一下;它尽管经常上当受骗,但依然每次听到召唤,还是畏怯地来到脚边,狐疑地等待我的新招。夜里,我就在廊下为它准备了一个纸盒做窝,但它更喜欢在躺椅上睡觉。半夜醒来,听见它在屋外鼾声如雷,仿佛院里住着两个醉汉,自然就少了寂寞。尽管这样的小犬,原无防卫和攻击能力,但是稍有异响,它还是会本能地勇敢扑出嗷嗷警告。在萧索村居生活里,人便多了许多安全感。
闲来无事时,我也会牵着它去古城游逛。一路走来它都要沿途撒尿,留下求爱的信息。但凡见着别家的狗,它都想上去亲热。有的大狗很凶,常常要追咬它,我也只能牵着它跑开以免受伤。看着它像一个情场上的劳模,孜孜不倦地奔波于途却求偶不成的沮丧模样,也不免联想到人世间的种种离合因缘,无端生出许多感慨。
有个女邻居苏苏抱着一只小母狗常来串门,把她那妖精穿得花枝招展,视同千金宝贝。蓬头垢面的球球,像一个波希米亚式的嬉皮去觊觎一个布尔乔亚的小姐,又不敢直接去生扑。连我都几乎想放下老脸,去帮它求苏苏把她的小母狗放到地下来,以成全它们一段交情。大家都笑话球球对情欲的执着,我只能惭愧地撇清责任说——这点,主要还是像它的养父L。大家嘿然。痴于情,而终老于山林,球球也许和这一代人真有默契之处。
七
就在2007年的冬天,我和余世存在北京又聚在了一起。世存是我的老乡兼故交,也是一个非常纯良的男人。他是80年代末的北大中文系毕业生,本来分在国土资源部工作——对许多人来说,这恐怕正是攀附权贵的良机。但他却最后选择了辞职,去做了90年代影响中国甚多的《战略与管理》的主编,后来成了自由撰稿人。
我知道世存是嗜书之人,原本无意江湖纵横,我便撺掇他也去大理读书,私心也想多个可以寒夜过访的酒友。他原也去过敝院,颇多同慨,当下就决定徙居大理。很快我们就在南村,寻到了另一农家院落,相去我的寒舍,也就几百米。我们就算随时可以“隔篱呼取尽余杯”了。
最重要的是,我又为球球找来了一位绝佳的教父。这小畜生似有灵感,看见前赴后继的父亲接踵而至,心下窃喜,初见世存便屁颠屁颠地巴结不已,仿佛它从此也有了社保一样。
世存为人谦和恭谨,处世却贫贱不移威武不屈,属于那种温良之中傲骨铮铮的另类知识分子。相比起我的顽劣和粗糙,球球似乎更喜欢和他相处——他几乎从来不厉声训诫这个沉默的小友。
人与人相交,讲究的是情味相投;其实人与动物之间,也有一个气味相投的缘分问题。球球对寒舍的过客,绝大多数都一见如故,也有对一些来访者充满戒备的时候。两三岁的它,几乎像阅人无数的长亭老树,用它的鼻子即能判断人间的敌友和善恶。通常它远远地打量来人,用它那暗藏智慧的忧郁目光表示不屑于亲近的态度时,往往也能契合我内心的情感。
世存和球球相看两不厌,当下定交成了朋友。他的房东原本也给他留下了一只小狗,但他左看右看就是没有感觉,还是退给了原主,却要求和我一起分享对球球的抚养权。反正这小家伙儿又不是老婆,弟兄们要分享自然可以同乐。于是球球便得以东家吃西家住地两边享福,我们反倒像它的大房二房了。
我一般对球球实行的是圈禁政策,也就是院门长闭只许在院落里活动,而且不许进客厅卧室。要带它出去,也是要戴上项圈链条的——有点像个严父,怕孩子混社会受到伤害。有几次它暗度陈仓出去撒野,我和梁乐满村子寻找,在苍山下呼喊,但凡有母狗之家便去小心哀告;那种凄惶和担忧,确实如孩子走失的老人。
但是世存对它却一开始就采取的放养制度。他的院子略大,为了节省和吃放心菜,他们小两口竟然在那薄土上开荒种菜,真正过起耕读生活来。球球在他的院子出入自由,活得像一个散仙,就开始变得野性起来。经常一出去就是整天,也不知到哪里鬼混,到半夜才回去敲门。等轮到在我的院子小住时,它一旦偷跑了,半夜却总找回世存那里。如果那里敲不开了,才会到我的门边守候。
有一次它走了两天,我和世存都开始担忧它被拐卖,内心感到揪疼之时,它又疲惫归来了,我们都无法想象它经历了怎样的逃亡和历险。我喜欢呵斥它,而世存则习惯对它轻言细语,因此它便更愿往世存家跑,更喜欢世存这样温润如玉的慈父。我知道它的善良和弱小,也了解这个社会的险恶,因此总是担心它还没有自我保护的能力,容易在流亡的路上遭遇伤害。村民们流传乡下有专门套狗的人,即便是凶狠的狼狗,他们都能用一种秘方默默引走。像球球这样从不攻击他人且长得像一锅肥肉的家伙,岂不是人狗皆能看中的下饭菜!
果然未久,它的第一次险情便出现了。
八
春末,我把球球全托给世存,自己则去了四川灾区搞社会调查。孟夏我回大理小憩,世存吆喝着球球回来,它一见久别的我,仍旧激动非常,拥抱狂吻真正如劫后重逢的恋人。饭罢世存回去,有意让它留下陪我盘桓几天,它却自以为是地要跟着世存,像一个撵脚的孩子。我想它是对我这种飘萍无据的生活感到害怕了,才更想有一个稳定的依靠。
世存走后,它一会儿探头进来呜呜唤我,一会儿又去拍院门,看着它那丧魂落魄的样子,我虽有些失落感,但也感到些许不忍。我不能把我的爱强加给它,它在世存那里爱上了自由,连人体会到自由之后都不甘被奴役,况乎一只天性自由的畜生。于是次日大早,我便为它打开了锁链,它则立刻飞沙扬尘地逃向了苍山田野。
我只要院门开着,它也会经常回来看我,经常晃悠一圈又扬长而去。一天,世存告我,球球受伤了,走路蹒跚且再不愿出门,神情有些畏怯甚至恐惧,召唤也不爱搭理了。我急忙过去探视,发现它毛上有血痕,屁股上有伤口,右后腿在奔跑的时候要悬着了。显然它受到了侵犯,眼神中满含落寞和委屈。
我和世存都不是养宠物的贵族,也不知道如何为它疗伤复仇。它和我们一样命贱地苟活于此恶世,内心的伤痛都只能依靠自己和时间去疗治。我们唯一能做的,只是和它同甘共苦,一起寒泉配食,箪食瓢饮;也许其他的人畜皆不堪其苦,然而“回也不改其乐”。除此之外,本质上我们都活在各自的命途中,谁也不能彻底拯救谁。
球球尚未痊愈时,我又去了灾区。后来听说它伤口愈合,快乐恢复,只是不得不踮着一只脚去追寻它的爱情了。再后来到了年前,它一去不归了。世存像往日一样信任它还会倦游还家,总在寒夜倾听它可能的跫音和剥啄叩门,但是这次它真的销声匿迹了,幻影一般迷失在逃向自由的路上。
一只狗来到人间,遭遇了三个并不足以带给它娇生惯养生活的父亲,悲剧似乎就是命定的。它不能选择它的运数,就像我们无法选择自己的祖国。我们生于斯长于斯,默默地忍受着生活,平静地面对着伤害,安详地等待着结局;像球球一样,在乱离的岁月中随处颠沛,时而戴着锁链,时而自我圈禁,但时而也在品味着挣脱逃亡的自由欢愉。加缪曾经说——我是我自己的囚徒,时刻流放在自己的祖国。偶尔想起球球和这个世界的许多朋辈,仿佛正是对这个时代的某种注解。
寒冬将尽,此刻是京都初七的黎明前夕,酒阑灯灺的夜空显得更加暗黑而迷离。沉沉大野啊,一只狗,你将走向哪里?我唯在这些薄醉的余生里,和我的弟兄一起分担这种伤悼,以纪念它那些日子的守护和偎依。
!去告诉她们-[[柳文扬]]
-----
孩子的出现总能缓和一下气氛,不管他是个好孩子还是捣蛋鬼,我早就发现这一点了。本来,我和木克(同伴们习惯叫他“老木”)都呆坐在沙发上,膝盖紧紧并在一起,手捧茶杯,双眼直盯着墙上的画。那孩子从内室门里钻出来,拯救了我们。
他对我还有点印象呢,他说:“去年圣诞节我见过你!大叔。在你们航天局的联欢会开完了的时候,你扮的圣诞老人往我袜子里放了糖果。其实我想要一只小青蛙……”
“我可没做过什么圣诞老人,”我说,“你见到的八成是真的。”
小孩坐在茶几上说:“我都六岁了。你别想骗我,没有真的圣诞老人!”
老木翻起大白眼珠谴责地看着我,我只好承认了,并且说:“老木扮的驯鹿。”
“我没有。”他闷声闷气地说。
“你必须承认,在营地里你的外号就叫‘驯鹿’。”
“我的外号是‘牡鹿’。”
小孩子靠在老木腿上,不知为什么老木总是受到儿童的欢迎。小孩说:“是我爸爸让你们来看我的吧?”我们互相望了一眼,老木脸红了,我吭哧了几声,说:“可以这么说,你爸爸委托我们来看你……”“你有五毛钱吗?”小孩抬起蓝幽幽的大眼睛看着老木。老木从衣袋里掏出一个硬币给他,手有点发颤。
这时,孩子的妈妈进来了。她仿佛已经意识到发生了什么事,脸色苍白,双手揪着衣角。
“你出去玩一会儿好吗?我们要跟你妈妈说点事。”木克对孩子说。
小孩从他腿上跳下去,同意了,但他讲条件道:“呆会儿我们要玩游戏,要玩‘骑牡鹿’,好不好?我去准备牡鹿的饲料。”
等到孩子跑出门去,气氛又变得紧张起来,我们俩又开始研究墙上的画。那位母亲呆了片刻,问:“格林怎么了?他为什么没回家?”
“夫人……”我说,看了看老木,他的脚在地板上来回蹭着,我真想捶他一拳。我接着说:“出了点事……”
“我知道一定是出事了。”她盯着我们,“格林返家的日子一直拖延下来,一个月、两个月……我打电话到你们局里,他们什么也不告诉我!到今天,你们突然来了……”
“第二班工作人员出了点岔子,一直没能上路。”老木笨拙地解释,“我们这班人就只能留在工地上等着。我们俩,也是刚回来不久。”
女人望着我们,那眼神令人无法忘记。
我难受地点点头:“是的。他……”
格林夫人哭了起来,我和老木手足无措。
进来之前,我俩本是商量过对策的,我们预料到肯定会看见眼泪。老木说:“我们就让她哭个够吧,女人哭一场,心里就好过些。她是咱们一个好伙计的老婆,咱们应该忍,我是说,她不对咱们哭,又能对谁哭呢?”
可是,真正面对一个伤心哭泣的女人,我们俩全身如同被针扎着一样,我们都没有对付女人的经验。过了一会儿,她抬起头,说:“行了,我总算知道他出了什么事儿。局里为什么不发通知给我?”
我的脸发热了,我说:“这是我们俩要求的,我们要上门来告诉您。一个大活人,我的意思是,像那样一个人,不能用一张通知书和一个电话就交代了呀。格林是咱们的弟兄呀。”
格林太太又流了泪,老木偷偷地瞪了我一眼。
我把通知书、遗物和抚恤金交给她,遗物不多——到那个鬼地方去干活也没法带更多的东西,只有一块表,一只微型录音机,侥幸没被压烂。格林太太神情木然地接过东西。
她忽然问:“他是怎么死的?”
我们都非常难受,仿佛这是一句责难:“格林死了,你们倒活得好好的。为什么?”虽然她没有那个意思,但我们还是非常难受。
我说:“他心脏病突发,没有几分钟就……”
“我从来不知道他有心脏病。”
“谁又知道呢?”我说,“有隐疾的人是不能上太空的,格林自己都没想到。不过这也好,他从发病到……到……只有五分钟,根本没受什么罪。大夫说是‘二尖瓣分流’什么的。”
“‘二尖瓣回流’。”老木更正道。
“他有什么话给我吗?”女人缓慢地问。
我说:“夫人,格林发病后,就一直处在昏迷状态,他什么也没说。不过,平常他总是说很想念你和孩子,盼着假期回家跟你们好好地团聚。”
又一串眼泪。格林太太说:“谢谢你们了,他死得很安心,我也觉得好受点儿。”
“您跟孩子要好好过……”我嘟囔着。
走出房子,我们长长地舒了口气。我说:“幸亏咱们把谎话提前编好了。”
老木说:“谁敢跟她说真事儿呀?她会当场昏倒的。”
实际上,格林死得相当惨,人是不该像他那么死的:被沿着缆索高速滑来的板块砸成了肉酱。
太空中的物体是没有重量的,但它的质量还在,这一点连小学生都懂。那板块在太空里仍是包含一吨金属物质的物体,它运动到缆索末端时,速度可达每秒十五米。一百二十根数公里长的缆索像脚踏车辐条一样成放射状排列,它们的头端都系在一颗直径一千五百米的小行星上,末端则系着我们制造出来的金属建筑板块,伸进太空。格林就是在这样一根缆索上被砸死的。每个新制造出来的板块都自动顺着缆索滑向末端,对接在已经建筑好的部分上。整个缆索系统以小行星为轴每四分钟旋转一周,在缆索末端的建筑里面就可以形成类似地球上的模拟重力。所以,一个板块滑到那里时,其动量足以把钢筋铁骨的汉子砸扁。一吨重的金属块砸死格林后,偏离了轨道,又把缆索末端联结的那架小型空天飞机撞得龙骨断裂。
格林爬到缆索上,应该说是严重违反施工条例的,他想到那架空天飞机上去。至于为什么要到那儿去,就不好说了。你别问我,也别问老木,你最好去问问局里的那些官儿们:八个血气方刚的男人,在离开地球几亿公里的空间,在狗窝一样的小舱房里,最久应该呆几个月。
我们俩沿着格林家门外那条清静笔直的小街走了一会儿,树荫下走路别提多舒服了。老木叹了口气:“我巴望着地球老是这样,老是这么干净,这么多的树。到我孙子那时候也要这样……如果我能有孙子的话。”
的确,地球真是我们亲爱的小小家园,在小行星工地上呆过的人,这种感受特别深。外太空建起了那么些庞大的能源站、采矿场、工厂和食品基地,飞船在火星、金星、小行星带之间忙碌地穿梭,但地球仍然像个宁静、简朴的乡村小镇。想到这点儿,让我们这些伙计们心里热呼呼的,尽管我不太好意思承认这个。
走上大街,老木忽然停住了脚步,我顺着他的目光看去:街拐角立着一个巨大的宣传画架子,画面上,轮环状的太空城市悬挂在蓝色地球上空。这就是我们要建造的城市。
老木又叹了口气。
这幅画太漂亮了,漂亮得足以牢牢吸引人们的目光和思想,使他们不去考虑这座太空城背后那些不太漂亮的事儿。
“你猜,”老木说,“它建成了之后要作什么用?”
“当豪华旅馆呗,让人们到那里去度蜜月。”我说。
一辆出租车停在我俩面前,我们坐进去,让司机开到这次旅行的下一站。
在相邻那座小城的街上,我和老木考虑着下一步怎么办。老木说:“我想,还是等一会儿再去吧。现在正是中午,咱们如果这时候去,倒好像是去赶午饭似的。”
我们在一家小饭馆吃了点东西,我提醒老木别喝太多啤酒,但他还是喝了不少。吃完饭,老木让我看看他的脸红不红。我说:“比猴屁股还红。”他哀求道:“再等一会儿,等一会儿再去吧,让我恢复正常了再说。”我没有反对。
下午三点,我们再也没法拖延了,想不出借口了。按照以前的记忆,两个人朝史耐德老先生家走去。
房子的门没锁,但里面没有人。屋内的陈设简单朴素,午后的阳光从干净的小窗射进来,房子里温暖而明亮。
邻居说,史耐德老夫妇去小河边钓鱼了,他们天天如此。
我们在绿树掩映下走向缓缓流淌的小河。二十分钟后,我从前面的矮灌木丛里分辨出两个白发苍苍的头。他们静静地坐在河边,沉浸在下午的宁静之中。
老木像待宰的牛一样抬起眼睛看着我。我明白他的心情,可这事儿必须干好。其实,谁愿意在这样一个晴朗的下午,把一对老夫妇从半梦幻一般的休憩中惊醒呢?
脚步声让老头儿和老太太回过头来,钓鱼的人耳朵总是很灵。他们认出了我俩,史耐德先生费力地站起来。
老木碰碰我的腿,我张开了嘴,但没说出话,呆了几秒钟。
老太太也站起来了,她睁大眼睛看着我们,似乎想说什么。
“贝克?”老先生低声问。
我抓抓衣服,说:“贝克,他……他不能回来了!”
老头点了点头,很严肃地说:“咱们到家里去谈谈吧。”但他突然一阵摇晃,两只手伸出去,好像要在空中抓什么东西。我跑上去扶他,他已经恢复正常,摆摆手道:“没事,只是一时头昏,老毛病。”
老太太抽泣了一下,声音很小,但却仿佛把这个安静的下午都震动了。她伸手扶着丈夫,两人一起爬上河岸。我们走在后面,望着这对老头老太太相互扶持的背影,心想他们以后可怎么过呀。
进了家门,史耐德老头温和地说:“特蕾茜,去厨房给这两个孩子倒点茶来。”老太太弓着背走进里面去了。
我从衣服里面取出东西:“史……史耐德先生,这是贝克的殉职通知书,还有抚恤金和他的遗物。”
“殉职?”老头儿严肃地说,“这么说他死得很光荣,我很高兴。”
我把东西交给他,他没有忙着看,而是让我们坐下,说:“你们在营地过得好吗?”
“过得比狗好不了多少。”我心想,但嘴里说,“很好。吃的虽然没法跟家里比,但是很有营养,每天有充足的休息。”我们知道,问题完全不在于吃饭和休息……
史耐德先生根本没有问返家日期为什么拖延了这么久。
老太太端了茶出来,眼睛红红的。她在厨房里一定哭了一场。
我们喝着茶,好一会儿没说话。
史耐德先生对太太说:“贝克是殉职,我们的好儿子。”
“嗯,贝克是殉职。”老太太很温顺地重复着,她又问我,“他是怎么……怎么死的?”
我按照早已背熟了的那篇话说:“您知道,在我们的营地上,食品是每隔三个月换班时才有新的补给,空气和水都是循环使用的。”这话倒完全没错,我们喝的每一滴水都已经在所有队员的肾脏里循环过一百次了,“这次,因为第二班队员没能按时来换班,食品就得省着吃,倒也不成问题。就是空气循环器出了点毛病。贝克是个好工程师……”
史耐德先生用心地听着,不时点点头,完全是一派军人风度。
我说:“他去把机器修好了。可是,有一处电线漏了电……贝克被高压电击中了,半秒钟都不到……”
老头严肃地问:“他还是把机器修好了?”
“是的。”我说。老木连连点头:“先生,可以说贝克救了我们一队人的命!您知道空气循环器是多么重要……”
史耐德的脸有些苍白,但他说:“贝克是个好小伙子,他从小就很有责任感,很有责任感。”
“您真太好了。”我说。
“能为地球做点事,贝克死得也值了。”他僵硬地说。
我们俩在这间小屋里简直呆不下去,如坐针毡。老先生压制自己心中强烈的感情,力求尽主人的本份,更让我们难受。他问了太空城市的一些事儿,还想留我们吃晚饭。最后老木都快喊叫起来了,我们几乎是哀求着告辞出来。老夫妇挽着胳膊走回门内,木门慢慢地关上了。
老木提议又去酒馆喝几杯,我点了头,并且说,今晚要一醉方休。
灌得差不多的时候,老木趴在桌子上苦恼地说:“我不行了,高,再让我干这么一次,我非崩溃不可。高,你自己去吧。”
我安慰他说:“你崩溃不了,你自己清楚:你比榆木疙瘩还结实。上次贝克和你打得那么凶,你头上开了两个口子,还不是没几天就好了。”
“别提贝克了好吗?”他绝望地看着我,“在营地里打架是家常便饭呀,你让咱们拿什么消遣?贝克是好人,只要看见他爸爸就看见他了,又古板又认真,热心肠啊。老头还以为儿子是触电死的。”
“就让他们这么以为吧。”我说,“你能跟他们说:‘贝克飞出了营地,因为氧气用光被慢慢地憋死’吗?”
“李唐也跟他一起……”老木说,“这死法真难受,我一想起来就心里发堵。”他又灌下去一杯。贝克是跟队长去追格林和其他逃跑的人时,被甩到太空中去的,还在格林被砸扁之前。他倒真是殉职,我们没有骗史耐德先生。
我们喝了好多,我觉得自己从来没有喝过那么多。老木低声嘀嘀咕咕,还唱歌。后来,两个壮实的年轻侍者把我们抬到后面的一间小屋里,我昏沉沉地睡了。
第二天上午很晚的时候,我结清帐,把老木喊起来,因为事情还没办完。一辆出租车把我俩拉到城外的小机场,一架冲压式飞机送我们到了英格兰。
我俩对兰德都没什么好感。老木不喜欢他,仅仅因为他是英国人;我不喜欢他是因为他和我的朋友关系不好。在狭小的舱房里,八个男人要和睦相处是多么困难哪。
但我们仍然要尽到对兰德的责任。
兰德的妻子跟她父亲一起住在乡间一所冷清的大房子里。我们坐在客厅的沙发上时,看到了兰德妻子悲伤的脸和他岳父那双满是敌意的眼睛。
“抚恤金!你们难道不给抚恤金吗?”他盯着我说。
我把通知书、遗物和抚恤金都交给他。
“这东西有什么用?”他翻弄着那些手表、笔和音乐匣,“只能让我女儿更难过!我告诉你,她和兰德的关系早就冷淡了!这桩婚姻不成功。”
“爸爸,”他女儿说,“别说那些啦,人家不是来听这个的呀。”
“他们在我这儿什么也拿不走。”老头说,灰眼睛上下打量着我们。
我说:“我们不想从您这儿拿走任何东西,先生。兰德是你女儿的丈夫,您一点也不关心他是怎么死的么?”
“你们为什么要亲自来告诉我们这件事?”他不放心地问,“我知道惯例的,发一份通知书,打个电话就是了。你们何必跑这么远呢?”
“兰德是我们的同事。”老木只说了一句。
“你们送了通知就走,不再来了?”
“爸爸,”女儿哭起来,“您还不明白他们的心思!求你别说了。”她望着老木,“兰德什么时候死的?他受了什么苦没有?”
老木慌了神,求助地看看我,我说:“他得了重病。小行星的岩石内部有一种被冻结的病毒,我们把岩石样品拿了几块到舱里,兰德喜欢研究那些东西。病毒在室温下又活跃起来,这是一种不知名的病,发高烧,严重共济失调……我们轮流照顾兰德,局里的专家也通过电话提建议。但病毒太凶猛了,兰德昏迷了二十多个小时就死去了。我们已经尽力而为,他死前有一会儿清醒过来,说自己感到很轻松,仿佛要上天堂了。他还说,他心里其实非常爱你。”
兰德太太边听边点头,她爸爸却说:“人要死的时候会说特别动听的话,其实是为了让别人同情他!”
他女儿刚刚想说什么,他又盯着我问:“这就是返家延期的原因,嗯?兰德是个牺牲品?怕把病毒带到地球来,所以不许你们回来。是不是?”
我对这老家伙说:“兰德生病是在返家延期之后,这两件事根本没关系!”
“谁知道!上边不许你们透露消息,我懂。”他点着头。
兰德太太不理会她父亲,问我:“您刚才说,同事们轮流照看兰德?”
“对,我们在他身边尽量照顾他,能做的都做了。”
“谁愿意冒被传染的危险照顾他呢?”老头冷冷地说。
我说:“先生,您没去过我们那个营地。在那种地方,人和人之间像亲兄弟一样。必须这样,我们才能生存,才能完成任务。在那儿即便是陌生人也会很快变成好朋友。”我慷慨激昂地说着,心里清楚自己在撒谎:在那个地方,即便是生死之交的密友也能为了一点小事就火冒三丈,打得头破血流。
兰德太太说:“你们太好啦。我知道兰德性子不好,他一向跟人搞不好关系。你们要忍受他多少坏脾气呀……”
的确,我们在营地里都受过他不少恶气。兰德自己的死也有一半是为了这个,在逃跑途中,他竟想拔断同路的浩男的氧气管。我刚才说过,我讨厌兰德主要是因为他跟我的朋友关系极坏,浩男是我最好的朋友之一。
在为了抢一张女明星泳装照片打了一架之后,兰德和浩男一直互相横眉立目。打架本是寻常小事,谁能料到兰德会在逃跑时趁机泄愤呢?结果,他的面罩反而被浩男一拳捅破了。
谁都听说过人在真空中活不了,但有谁见过被真空夺去生命的人?兰德按照练习过多次的自救法,把肺里的空气都呼出来,闭紧眼睛,但他的一双眼珠还是夺眶而出,血跟着从各个孔窍里喷出来。浩男要帮他都来不及。
我偷偷看一眼老木,他呆呆地盯着地板,肯定也在想兰德的事。
因为已经吃过了午饭,喝茶的时间又没到,兰德太太不知怎么和我们再聊下去,她父亲实在也不是一个好主人。我们告辞了。
在乡村的草场上走着,老木说:“我今天不能再干了!咱们明天去朝鲜吧?”
我们找个旅馆住下了。
当夜,我睡得不好。梦见浩男站在几尺之外,把那张烧坏了的脸朝向我,眼睛仿佛是两颗炽热的炭火。“好热呀!”他呻吟着,“让我快点死吧!”
后来,他又直勾勾地盯住我说:“我觉得冷,这儿太冷了。你们把我一个人扔在这个地方……”
我醒来时,看见窗帘被阳光映得发白。出了一身的汗,心里有一种感激之情。我还活着,活在有窗帘、有床铺、能看见太阳的地方。
当飞机在大田机场降落后,我心中又踌躇起来。浩男是我的好朋友,我为他难过,但从道理上说,他是罪有应得。他杀了兰德,贝克和李唐也可以说是因他而死。
老木拿出地址,塞进路边的问讯亭里,机器给出通往浩男家的最近的路线。我们乘坐慢悠悠的公共电车上路,因为大田这里出租车很少。
亚细亚的和风、黑眼睛和古典的建筑让我伤感,我使劲儿捏着老木的肩膀。他没理会。我们很快到了。
浩男的妻子和一位年轻男人正在家里闲聊呢,因为茶几上有酒杯和几个碟子,一堆小豆蔻壳儿。那年轻人看见我们有点惊慌。
老木瞧瞧小伙子,脸慢慢地红起来。我拉住他,坐在沙发上。
浩男太太,名叫粉姬的,神色很镇定,她也没倒茶,只是淡淡地问:“浩男让你们俩来的?他呢?”“他死了。”老木粗声粗气地说。
粉姬吃了一惊,抬起眼睛,她的目光在半分钟里变化了几次。那个小伙子轻轻地拉她的手,而她却始终没有看他一眼。
“你走吧。”她简单地说。年轻人愣了一会儿,起身就走了。
我把东西都拿给她。她摸着那些洗干净的袜子、小本子,若有所思,最后微弱地叹息了一声。
老木说:“浩男一直很努力工作,他是营地里最卖力气的一个。”他这么说的时候,那语气似乎是在责备粉姬。
粉姬给自己倒了杯酒,仰头喝下去。也不让让我们俩,她就这样又连喝了两杯。我们注视着她,她是个怨妇、公主和坏女孩的混合体。
“抚恤金和预付的薪金可以让你过得很好。”我低声说,毕竟她是浩男的妻子。
她点点头,终于抽泣起来,用手帕掩住了脸。老木的眼神和蔼了一些。
“他有什么话给我吗?”她问。
我说:“他最后留下了话。他说他对你很抱歉,以后再也不能照顾你了,要你再找一个可靠的好人。”
粉姬轻轻摇着头,把腿蜷到了沙发里面,脸搁在膝盖上。
“后来,他要我们抬着他到外面去,他想看看星星。我们把他抬出去了,因为谁都知道,这是他最后的要求。”我慢慢地回忆着,“小行星旋转着,我们用靴子底下的电磁钩挂在岩石表面安装好的轨道上。浩男说:‘我找不到地球,可是星星多好看呀。’这是他最后一句话。”
粉姬又哭了。她喃喃自语:“星星多好看呀……”
这并不是浩男的最后一句话。这次骚乱的幸存者都记得很清楚,一辈子也不会忘——他最后的话是:“日你娘!还没完哪?”
这句话是和着血沫子一起喷出来的。当时高压电有点故障,队长连着两次都没把浩男电死。第二次,他左边肩膀都被烧焦了,冒出烟来。他醒过来之后,又哭又喊,说了那句话。谁也不敢再去看他那张脸,队长最后用枪打死了他。
我还要说,浩男是罪有应得。他杀了兰德还可以说是正当防卫,但当贝克追上去抓住他的时候,他不应该那么狠,不应该把贝克从缆索上推出去,更不应该在贝克伸手向他求救时,冷酷地置之不理。
何况这里还牵扯到李唐的死。
好,起码最为难的时刻已经过去了。粉姬认可了浩男的死讯,接下来必须告诉她详细些的情况。
“他想你,”我简单地说,“他有时候要放弃营地里的轮休,到外面去看星星。他希望能找到地球。”粉姬望着我,开始认真地听。
我继续讲:“一颗流星打中了他。这种机会非常非常小,大概只有千万分之一。但是它确实打在浩男的头上,头盔裂开了,浩男受的伤很重。”
“他流了很多血?”粉姬沙哑着嗓子说。
“血倒没流多少,可是内伤很重。他可能会感觉到一点头痛、眩晕,但多半时候是在昏迷当中。我们围着他,他的样子就像睡着了一样。他没受什么罪。”
“可是他不在了,”粉姬说,“再也不回来了。”
我们都说不出话来。
从浩男家里出来,我想尽快办完这次差事,急匆匆地往街上走。老木对我说:“那年轻人肯定是她的情人,这女人!”
我心里替浩男难受,嘴上却激烈地说:“你让她怎么办?一年里有六个月见不到自己的男人。何况那个青头儿萝卜也许是她的表弟,也许是个邻居,也可能是修水管的,被她留下聊聊天而已!她是个女人哪。”
“你什么时候把女人弄懂了?”老木闷声说。
我们乘车来到浅水湾,正好赶上当天下午那班高速列车。
车厢里安静而明亮,很难想像列车正以每小时八百公里的速度穿过海底隧道。服务小姐送来了饮料。我们像乡巴佬一样每样都尝了些。
“这就是生活!”老木突然像哲学家似的感慨了一句。
“你说什么?什么就是生活?”
老木说:“我是说,现在这样,坐在舒舒服服的车厢里,喝美女送上来的饮料,这也是生活;像咱们那样,在狗窝一样的舱里一窝三个月,那也是生活。”
我没说话。
还没来得及打个盹儿,车已经停了。
外面就是我的老家:山东蓬莱,这个曾经在传说中是人间仙境的地方。
我带着老木出了车站,在街上买家乡的烤大虾请他吃。他老老实实地称赞了一番,称赞大虾,不是我。
其实,我离开这里才八个月,却觉得仿佛阔别多年了一样。身边晃过的鲜活的面孔和厚重的语音令我有恍如隔世的感慨。
坐上由高大的司机开着的电车,我们往李唐家赶去。
车窗外面的景色渐渐变得开阔清新,路旁有了一群群的牛。老木出神地瞧着,我敢说他这辈子也没见过这么多牛。他是个典型的空间技工。
下了车,往那条两旁夹着参天白杨的乡间石子路里一拐,过一座木桥,七只大白鹅气昂昂地叫着示威般从我们脚边摆过去。再向右拐……我嘴里念叨着。老木没出声,一直跟在我屁股后头。
“恐怕这儿就是,我也说不太准。”我指着前面木栏围起的大农庄说。
我们推开栅栏门,踌躇地走进去。阳光照着大片草地,远处有一排矮房子。
“有人吗?”我喊着。
这儿静得使人感到不可思议。微风拂面,我听着树叶哗哗地轻响。
老木有时候也要说点挺有学问的话,这时他揪了根草嚼着,叹息说:“要是这儿就是李唐的家,那他何苦去那鬼地方卖命呢?”
“年轻人的热情……”我说,“咱们不是也受过宣传海报的吸引吗?”
我们转过那排矮房子。房子背后堆着很多原木,有个三十多岁的男人坐在木料堆上,捧着本书在看。他看得那么起劲儿,直到我大声咳嗽了两声,他的眼睛才从书上移开,望着我们的脸。
“有事儿?想买什么,伙计?”他说。我喜欢在种族大混合的时代还能听到纯粹的老家方言。
我说:“我们找李唐的家属,伙计。”
汉子笑了,嘴唇里面露出的白牙齿让人觉得阳光灿烂。
“我是他姐夫,他姐姐在屋里呢。来吧。”
但我们没有进屋。李唐的姐姐出来了,不会认错,她的眉眼和李唐简直一模一样。她衣着简单,盘着头发。
我看看老木,他又低头踢着土块。我就对李大姐说:“我们是李唐的同事。”
“快进屋喝水。”她说,“我隔窗子看见,还以为是谈生意的。你怎么不叫人进屋呀?”她小声责备丈夫,“姐夫”笑笑。
“不,不进去了……”我说。
“客气什么!”
但姐夫有点明白过来,他拉住妻子的手,对我们问道:“小李子出事儿了?”
我点点头。
李大姐低叫一声,用手捂住脸。
“别哭,我的人儿。”姐夫镇定地说了一句,又转向我,“怎么了?他在哪儿呢?”
我取出通知书。
李大姐把哭声埋进男人怀里。我们只得把她弄到屋子里面,坐下了。
在堂屋的木椅子上,她开始自言自语:“说是去了有出息,有出息!……才几个月呀,弄回个‘通知书’来了……这叫什么事儿!”
“别嚷啊,叫人家说完。”男人仿佛是下命令般劝着,眼睛看着我。大概因为老木是个蓝眼珠,他不太喜欢。
我把李唐留下的笔记本交给他,李唐平时没事就爱写日记,还有抚恤金。姐夫接过去时“嘿”了一声,说:“人都没了,要钱干什么!小李子哟。”
“出什么事死的?”李大姐抬起头来问。
“救人,李唐是救人死的。”
她哭了:“他从小就喜欢帮人!两肋插刀的孩子。”
我说:“我们这个同事……”指指老木,“他干活儿的时候,机器的摇杆突然往下打。李唐把他推开了,摇杆打在他自己头上……”老木看我一眼,因为原来商量谎话的时候,这个角色本是我的,可我宁愿把被李唐从死亡边缘拯救出来的幸运让给老木。
“铁杆子呀,打在头上……”她喃喃道。
“一下子就过去了。”我说,“基本上没感觉。没什么感觉……”
“就像东边马家小儿子那次被树砸了一样。”她丈夫帮着我给她解释,“人一下就昏了,疼都不疼。嗯!”
但女人想了想,还是流眼泪,流个不停。
姐夫看了我们一眼,点点头,扶着李大姐进了里间。我们俩在堂屋坐着,膝盖并紧。我听见头顶有几声稚嫩的鸣叫,抬眼一看,屋顶的木檩子上结了一个泥巢,两只乳燕探出头来。
老木长长地叹了口气。
过一会儿,李大姐跟丈夫一起出来了。她已经好了些,手上捏着一叠纸,一看就知道是由营地发回来的信。
她把信拿给我们一起看,因为信息通过量的限制,每封信都不能超过一百个字。
我展开一张纸,上面是传真过来的,李唐亲笔写的字体:
“姐,我过得挺好,别挂念。吃得好,睡得香,一百四十斤,一斤没少!营地里的同事对我可好了,都拿我当亲弟弟看……”我一边读,一边想起了李唐刚到营地上时,那副笑眯眯的、跟谁都想亲热的样子。他瘦得很快,因为在那儿患了消化不良。
“姐,我升职了,采矿小组长。我的头盔外面有个红圈圈,别人一看就知道我是组长。我年纪小,可他们都挺服我……”
他们不服,兰德起码跟他打过四架。开始,李唐不肯真打,后来他就动真格的了。两人都打得眼里冒火,队长用枪才能把他们压住。
“我想家了,想吃你做的酱汁鱼。家里的那片树林子可多好看哪,那个水塘不能填,留着我还要钓鱼呢,你跟姐夫说说。你没见过我们营地这儿的风景,全是星星!不停地转!因为我们扎营的这个小行星老在转,你在这儿看一会儿天,就能把头看晕了……”
星星不停地转。
李唐是看着旋转的星空死去的。他为了抓住飞向空中的贝克,自己也给带出去了,都是因为浩男……氧气一时半会儿用不完。他会看见营地渐渐远了,而自己却坠入无底深渊般的太空。没人能救他,唯一的一架空天飞机已被撞坏。他的同伴是贝克,但只是暂时的同伴。他俩会相隔越来越远,越来越远。他们也许会通过对话来减轻恐惧感,发泄悲忿,直到氧气用光。
我在宇航服头盔里的对讲器中,没听见李唐的喊叫。他是个沉着勇敢的小伙子。
我从信纸上抬起头,又对李大姐说:“他没受什么苦,只一下子就过去了……”仿佛这句话能够补偿什么似的。
“他没受什么苦。”姐夫帮着我说。
“人不能回来了,骨灰总要拿点儿回来吧?”她说,“有点儿骨灰,也比什么都没留下强……”“规定不许带回来……”我低着头说。
李大姐盯着老木看,我认为,老木准被她看得心里发毛。她的眼神很奇怪,显得又伤心,又温柔。她准是把老木看作自己的弟弟了,既然老木是被李唐救的,那么老木现在就是在替李唐活着,那么老木就是她弟弟。她是个女人,她不管老木是黑眼珠、蓝眼珠。
我们后来在她的堂屋里吃了饭,桌上有李唐最爱吃的酱汁鱼和铁锅烤蛋。老木吃了好多,把盘子里剩的汤都喝了。他的脸通红。
坐在北去的列车上,我们低声唱起了在营地里常唱的几首歌。老木像喝醉了一样,他说:“李唐是个好小伙儿,他跟着他们跑太傻啦。死得可惜……”
我想,到底谁更傻?逃跑的那四个人,还是留在营地上、后来又去追捕逃亡者的我们?也许,他们的心里更有人味儿一些。本来在那地方闷三个月就要发疯了,何况命令突然下来:你们必须再坚持三个月。
他们只想乘那架小型飞机飞到火星。在那里,人要多些,热闹些,每个月有两班飞船往地球发货。他们根本没有顾及必将落在他们身上的惩罚。
我又听见了浩男的声音,这声音曾在我头盔的对讲器中响起:“让我走吧!贝克,别过来!别过来!”
老木的话惊醒了我:“这是最后一个了,总算快熬到头了。”他说。
这是最后一个,这也是最难办的一个。
队长,他的家在北京。据我所知,他只有一个妻子。这也是我们对他的仅有的一点认识,因为他是个沉默寡言、严峻得近乎冷酷的家伙。他能像机器一样执行自己的使命,在任何情况下都毫不畏缩。
即便是让他对一个朝夕相处的部下执行死刑。
他抓回了浩男,我们觉得他做得对。他处死了浩男,没有人表示异议。那时,他手下只有我和老木两个了,他仍然带着我们坚持到第二班人马赶到。
队长肖汉的家,在北京西郊一条林荫道的尽头。绿树掩映的小白房子里只住了两个女人,肖太太和保姆。我知道肖太太名字叫“小琳”,这是格林以一只眼睛乌青半个月为代价,从队长写的信上偷窥到的机密。据他青着眼眶子跟我们透露,那封信极其肉麻。
小琳是个能在早晨的树林里飘动起来的清秀女子,我们俩并排挤在沙发中间看着她,对她十分仰慕。我很明白队长为什么要写那样肉麻的信。
她听到消息后,没有表示出多么大的震惊。她只是沉默了一会儿,说:“他早就告诉我,有这个可能……”她用目光鼓励我们,“告诉我他是怎么去的,你们要说真话。我能听下去。”
老木的脸红了又白,我想自己也好不到哪儿去。我手忙脚乱地把通知书和一切东西给她,有一件东西是肖汉特别嘱咐过的。
我把那半朵银质的玫瑰花递过去:“他告诉我,必须把这个给你。”
她接了过去,捧在手里看着,突然对我们说:“跟我到这边来吧。”
我俩跟她走进旁边的一间小书房。我的心颤了一下:这里全是队长的东西,有他的照片,他们两人的合影,有队长得的奖牌,他的旧制服……小琳走到书柜前,拉开柜门,拿出一个水晶盒子,打开。
里面是半朵银玫瑰,同我拿给她的那半朵一样。
她把两个半朵花对在一起,严丝合缝,成了完整的一朵玫瑰花。她久久地抚摸着它……
我们俩站在她身后看着。
老木喘了两口气,说:“夫……夫人,您今后如果有什么麻烦的话,只要给我打个电话,只要一个电话!不管我在哪儿……”
小琳回过头来,轻轻一笑,说:“我谢谢你们两个。”她又看着我,“你还没告诉我呢,肖汉是怎么去的?”我注意到她两次都是用的“去”字,她不说“死”。
我说:“血液感染。我们有个队员患了病毒-射线败血症,营地没有趁手的药物和器械,只有用原始办法给他换血。队长是O型血……”
她默默地点头。
“换血的时候,没有注意回流……”我说,“那个队员没救活,队长也染上了病。这种病是发展极快的,几小时内就能致命。我们想尽了办法,我说的是真话,半点不掺假。我们能用的法子都用了,队长很坚强,他边接受治疗边给我们鼓劲,但是他很快就昏过去……”
我讲着,脑海里响起队长对浩男说的话:“我心里是想你活的,浩男。”
浩男的声音:“我该死,你下手吧。我服气。”
“后来他又醒过几次,喊你的名字。他说,小琳,我们还能见面吗?”我说得自己也动了感情,鼻子酸起来,“队长平时挺严肃,可大家都知道他是非常重感情的,他对我们也很好……”
“这是队里的纪律,浩男。”当时队长说,“不执行的话,我就对不起死了的贝克和李唐。”
我真傻,看到队长脸上的表情,居然没有意识到,他的心智已经不在正常的轨道上了……
“他死的时候,大家都哭啦。”我说,“他不止救了我们一次两次,没有他的经验,我们队不能坚持这么久。”
我听见了电流烧灼浩男肉体的声音,听见了呻吟和哭喊,听见了最后的枪声……
为什么没想到?队长的眼睛里当时就有那种疯狂的目光了。
“他还说了什么吗?”小琳问。
“对啦,他小声唱歌,唱‘伤心的小玛丽’。”我说。这首歌,我偷偷听见他唱过两三次。
小琳转身快步走出去,老木低声说:“你干嘛说那个?你肯定把她弄哭啦。傻瓜!”
“咱俩谁傻?”我说,“你觉得,她这么镇定正常吗?她该哭一场才舒服。”
老木无法反驳,也走了出去。
我们坐在客厅里等了好一会儿,小琳出来了。她换了件衣服,说:“对不起,我刚才觉得有点儿凉。”
一切都说完了,我看看窗外,对她说我们还有事,应该早点走了。
我不知道她的心里在说什么,她的眼睛那么深……
老木一路把地上的树叶踢得满天飞舞。我说:“幸亏局里同意全部按殉职处理。”
“他们也该有点人情味儿。”老木说。
我也踢起了树叶:“恐怕是不愿意这件事张扬出去吧。什么人情味儿!”
但我必须承认,有些人的感情,不是我们这样的人能看透的。就像队长,他平时那么冷酷,像一尊石像,像一个法规的化身。
但他在交了班、乘着空天飞机飞往地球的路上,却做了那件事。在叮嘱我一定把银玫瑰交给妻子之后,他突然用那把枪打穿了自己的头。
回忆一下他那时的目光吧,处死浩男时,他也露出了那种目光。我明白,就在执行死刑的时候,作为有生命的人的肖汉已经不存在了。他的另一半意义,今后将保存在那朵银质玫瑰花里,直到海枯石烂。
风,吹起了满地树叶。我们裹紧衣服,虽然天气一点都不冷。一队小学生抬着一个木匣走过来,手里举着小旗子。
“捐点儿钱吧!叔叔。”他们喊着,“太空城市的建设费呢!我们这个月要收足一万元!”
我们俩每人投了十块钱进去。孩子们叽叽喳喳地叫着跑了,跑得越来越远,越来越远。
全世界的人都知道我丢了-李娟
========================
全世界的人都知道我丢了-[[李娟]]
------
我三岁那年,一天傍晚妈妈从地里干完活回家,发现我不在了。她屋前屋后四处寻找,敲遍了所有邻居家的门,都没找到我。后来邻居也帮着一起找,翻遍了连队(我们当时生活在兵团)的角角落落。后来有人怀疑:莫不是我独自一人进了野地?又有人严肃地叹息,提到最近闹狼灾,某团某连一夜之间被咬死了多少多少牲畜……我妈慌乱恐惧,哭喊着去找领导。她捶胸顿足,哭天抢地,引起了连长和指导员的高度重视。于是连队的大喇叭开始反复广播,说李辉的女儿不见了,有知情者速来办公室报告云云。还发动大家一起去找。几乎连里的每一个人听到广播后都放下碗筷,拿起手电筒出了家门。夜色里到处灯影晃动。连队还派出了两辆拖拉机,各拉了十来个人朝着茫茫戈壁滩的两个方向开去。呼唤我的声音传遍了荒野。
半夜里,大家疲惫地各自回家。没有人能安慰得了我妈,她痛苦又绝望。妇女们扶着她回到家里,劝她休息,并帮她拉开床上的被子。这时,所有眼睛猛然看到了我。我正蜷在被子下睡得香甜又踏实。
我二十岁时,去乌鲁木齐打工。一次外出办事,忘了带传呼机,碰巧那天我妈来乌市提货,呼了我二十多遍都没回音。她不禁胡思乱想,心慌意乱地守着招待所的公用电话。这时有人煽风点火,说现在出门打工的女孩子最容易被拐卖了,比小孩还容易上当受骗。我妈更是心乱如麻,并想到了报警。幸亏给招待所的服务员劝住了。大家建议说再等一等,并纷纷帮她出主意,更是令她坐立不安。又不停地打电话给所有亲戚,发动大家联系乌市的熟人,看有没有人了解我最近的动向。然后又想法子查到我的一些朋友的电话,向他们哭诉,请求大家若是联系到我的话一定通知她。于是乎,我的所有亲戚和朋友一时间都知道这件事了,并帮忙进一步扩散,议论得沸沸扬扬。说我莫名消失,不理我妈,要么出事了,要么另有隐情……
我妈一整天哭个不停,在招待所里逢人就形容我的模样。告诉他们我叫什么,我是干什么的,来乌市多久了,现在肯定出了意外,如果大家以后能遇到这个女孩,一定想办法帮助她……大家一边安慰她,一边暗自庆幸自家女儿懂事听话,从来没有发生过跑丢了这样的事情。
除了没完没了地打电话和向人哭诉外,我妈还跑到附近的打印店,想做几百份寻人启事。幸亏一时没有我的照片,只好作罢。否则的话我就更出名了。
而这些事,统统发生在一天之中。很快我办完事回家,看到二十多条留言时吓了一大跳,赶紧打的跑去那家招待所。一进大院,一眼看到她茫然失措地站在客房大门前,空虚又无助。我叫了一声“妈”,她猛一抬头,号啕大哭起来,一边快步向我走来,一边指着我,想骂什么,又骂不出来。但哭得更凶了,好像心里有无限的委屈。
直到很多年后,我有事再去那家招待所(那相当于我们县的办事处),里面的工作人员还能记得住我,还会对我说:“那一年,你妈找不到你了,可急坏了……”并掉头对旁边的人津津有味地详诉始末。
这些年,我差不多一直独自在外。虽然和我妈联系得不算密切,但只要有一次联系得不通畅,她会生很大的气,不停地问:“刚才为什么不接电话?为什么关机?”而我不接电话或关机肯定不是故意的,老被这么质问的话,我也会生气。然而,有时给她打电话,若遇到她不接电话,她关机的时候,也会不由自主地着急。并在电话打通的时候也会生气地连连质问为什么、为什么、为什么。
联系不到她时,我也会胡思乱想。但永远不会像她那样兴师动众,绝倒一大片。这些年来,她坚决不肯改变,仍然是只要一时半会儿联系不到我,就翻了锅似的骚扰我的朋友们。向他们寻求帮助,并神经质地向他们反复展诉自己的推理及最坏的可能性。大家放下电话总会叹息:“李娟怎么老这样?”于是乎,我就落下个神出鬼没、绝情寡义的好名声。
而我妈则练就了一个查电话号码的好本领。无论是谁,只要知道了其工作单位和姓名,茫茫人海里,没有她逮不出来的。
如今我已三十岁,早就不是小孩子或小姑娘了,但还是没能摆脱这样的命运。
这段时间妈妈在乌市照顾生病的继父,我独自一人在家。一天睡午觉,把手机调成了静音。于是那天她一连拨了三遍我都不知道。于是她老人家又习惯性地六神无主,立刻拨打邻居一位阿姨的电话,请她帮忙看一看我在不在家。那位阿姨正在地里干农活,于是飞快地跑到我家查看端倪。由于怕我家的狗,只是远远看了一下,见我家大门没有挂锁,就去向我妈报告说我应该在家,因为门没关。
可我妈把“门没关”误会成了大门敞开了,立时大惧。心想:我独自在家时一般都反扣着院门的,怎么会大打而开呢?于是乎,又一轮动员大会在我的左邻右舍间火热展开了。她不停地给这个打电话,给那个打电话,哀求大家四处去找我。说肯定有坏人进我家了,要不然大门为啥没关呢?还说就我一个人在家,住的地方又偏又荒,多可怕啊。又说打了三遍电话都没接,肯定有问题……很快,一传十,十传百,全村的人都知道我一个人在家出事了。
小地方的人都是好心人,于是村民们扛着铁锨(怕我家狗)一个接一个陆续往我家赶。大力敲门,大呼小叫。把我叫出门后,又异口同声责问我为什么不接我妈的电话,为什么整天敞着门不关……于是这一天里,我家的狗叫个不停,我也不停地跑进跑出,无数遍地对来人解释为什么为什么,并无数遍地道歉和致谢。唉,午觉也没睡成。
可是,她老人家怎么忘了咱家还有座机?既然手机打不通,为啥不试试座机呢?再说,我家养的狗这么凶,谁敢乱闯我家?……
有这样一个没有安全感的母亲,被她的神经质撼摇了一辈子心意。我觉得自己多多少少肯定也受了些影响。说不定早在不知不觉间,也成了一个同样没有安全感的偏执型人格障碍病患。真倒霉……弄得丁点大的小意外都忍不住浮想联翩,绵延千里,直到形成重大事故为止。太可怕了。
她没有安全感,随时都在担心我的安危,是不是其实一直在为失去我而作准备?她知道总有一天会失去我的。她一生都心怀这样的恐惧而活着。并且这悲伤和痛苦不停地积累,日渐沉重。每当她承受不了时,便借由一点点偶然的际遇而全面爆发出来。她发泄似的面向全世界的人跺脚哭诉,让全世界的人都知道我丢了。因为她的痛苦和不安如此强烈巨大,非得全世界的人一起来分担不可。她是最任性的母亲,又是最无奈的母亲。
2010年
本章将继续讲述人物,在上一篇章里面我们得到了一个相对简单的,能用的人物。但是这在于真正的文学创作之中是完全不够的,好的人物应该更复杂也更有趣。(我们暂时只讨论现实主义流派的创作)所以,人物怎么样才能变得更加的有趣和更加的复杂,并让读者产生移情作用呢?本章讲述:
"人物的复杂化:人物真相,人物需求和人物维。"
人物的复杂化,需求我们丰满人物,让人物立体。我们在已经知道了人物内心的冲突和外部冲突之后,我们就需要考虑到人物进一步复杂化过程了。
我是写过一篇论文,论述人物的复杂化过程,但是那确实很无聊,所以我们尽量选择简平快的方式来搞定这个内容。人物的复杂化我们包含:内部复杂化和外部复杂化。
!! 内部复杂化
人物内部的复杂化,我们就需要考虑到人物真相的问题了。人物真相在[[罗伯特 · 麦基]]的《故事》之中指的是人物的的本质是什么样的人。而其实在人物塑造之中,人物的动力往往来自于其最真实的欲望。在这里我们要注明一点,人物欲望不一定是卑劣的,但一定是强烈的。那说到欲望,大家脑海里闪现的第一个一定是性欲。(对我要开始污了,鼓掌)
很多时候我们在面对人物的性欲的时候,会显得有些慌张,要么写的扭扭捏捏,要么写的不伦不类。其实原因很简单,这是因为作者没有给人物的真实欲望定性,和有目的的、准确的刻画这一点。在讲到刻画之前,我们提出另一个延伸部分——性欲也可以是爱情的延伸和基础。(如果你都不想睡她,你凭什么说爱她,我好想 cue 杨德昌一下)
我们就用一个简单的例子来讲述一下人物的欲望是如何做的,对,我们就是用性欲的例子。
!!!单纯的性欲
单纯的性欲,以性欲作为人物行动的动力和需求。面对这样的人物塑造上,我们需要坦诚的接受他是为了性欲而活着的,他需求性,很强烈的需求。在这种情况下,作者特别容易给人物添加上特别多的借口和掩饰,而往往作者还真的相信了这些借口和掩饰,如果是这样,这个人物就会坍塌,缺乏力度。
人物如果是继续需求性欲的,那么我们就让他得不到性欲,或者为性欲付出代价。这个还涉及到情节,暂且不提。让我们塑造一匹让人不讨厌的种马,而且是单纯的为了性欲活着的种马,不是小网文里的那种种马。
```
A 今年 24 岁,年轻,健康,他有一个傲人的阳具,这是他极度骄傲的本钱。他长得并不帅,但是还蛮有幽默感,而且身材很不错。他喜欢和女人睡觉,而且女人往往也喜欢和他睡觉。从 14 岁开始,他认真学习岛国动作片,起初他只是为了满足性欲,而慢慢的他真的开始学习各种姿势和动作。他相信这也算是一个技术,做一个有一技傍身的男人总是好的。但是他不懂的什么叫谈恋爱,可是女人们总是想要跟他谈恋爱,他不知道什么是爱情,他只知道怎么做爱。这让他像是一个鸭,其实也真的有富婆想要包他,可是他拒绝了。他需要性爱的快感,他对性爱永远抱着崇高的敬意,他不希望去做一个男优或者其他以此盈利的行当,甚至对他而言,做爱是一门艺术。但是很多女人总不能让他得到性欲的满足,那些女人让他十分的厌烦,他讨厌自己被当成一个满足别人性欲的工具,他要去寻找自己的性高潮。
```
这个才是种马,他真的是被性欲控制的,他并不把性欲当做一个不堪的事情(本来就是让人愉快的事,对不对!),反而进一步研究和发展,将做爱当做技术,甚至他可以从生理反应上研究性生活。你看,活脱脱的一个性学家的样子。种马不一定需要天天做爱的,他甚至不经常做爱,甚至表现出来像是性冷淡,是因为常人的性快感已经不能满足他了。所以他才特别,他才不一样,他才有趣。
那么这个性欲实际上可以换成其他的玩意,变成食欲,变成对食物的挑剔,变成对某一件事的追求,其实都可以的。那么是什么支撑着这样的人物塑造呢?出了基本的作者对于人物欲望,人物需求的认知和相信。还需要一个十分重要的组成部分——极致化。人物的需求需要极致化之后才好看,如果人物的需求和欲望平平,那么这个人物就缺乏张力。(你们等待着我某一章打自己的脸哟)人物缺乏极致化的时候,他的动作不够激烈,他的心理支撑不足以让他做出足够激烈的动作。至少对于大部分人来说,塑造人物的时候极致化他欲望是一个很好用的方式和办法。
其实反过来做人物的极致化也是 OK 的,人物的极致化可以从多个方面,方向来处理。
```
A 今年 24 岁,年轻,健康,性欲旺盛。他就像一匹种马一样,时时刻刻都想要发泄自己的性欲,而更让他尴尬的是他难以抑制自己的性欲,甚至无法抑制自己的勃起。他为此十分羞耻,这让他觉得自己随时随地感觉自己像是一只发情的公狗。而实际上这也直接影响了他的社交和生活,他 24 岁依旧是一名处男,他为自己不能控制的硕大阳具感到难堪。他发泄性欲的方式主要依靠左右手。他去找过一个不太靠谱的医生,而这个医生却建议他捐精。逐渐的,他选择将自己关在房间里,他羞于见人,他依靠捐精生活。他从来不曾得到真正的满足,他恐惧于面对自己的性欲。
```
然后我们来看欲望的延伸和转变可以带来什么样子人物塑造,其实这也是作者找借口和掩饰的过程,但是和我上面说到的找借口有什么不同呢?我们是让人物寻找借口,而不是我们寻找借口,意思是人物会因为社会性原因寻找自我安慰甚至是自我麻醉。
```
A 今年 24 岁,年轻,健康,他一直觉得自己对于爱情有着纯粹的向往。他很会谈恋爱,可是他却是别人所说的渣男。倒不是因为他做了什么伤天害理的事情,他只是从来没有找到他想要的爱情。他实际上只是对上床感兴趣而已,而他却自以为是对爱情的向往。他总是觉得自己是在追求爱情的,他会营造浪漫,也知道如何追求女人。他试过在酒吧撩姑娘,也试过钓学生妹,他尝试过所谓的一见钟情,也尝试过慢斯条理的谈恋爱。但是这一切都没有让他得到真正的满足,他开始怀疑自己是不是被上天诅咒无法得到爱情,却从考虑过自己只是性欲需求,却又马上否认了,他太会谈恋爱了,但是他也开始找不到爱情了。
```
喏,一只种马 +“渣男” 的形象出来了。对于这种借口和掩饰是人物给自己的,而作为作者的我们则需要清晰的知道这个人物真正的需求和欲望是什么。千万不能我们来麻醉自己,如果我们都不能把握一个人物的话,那么我们的创作之中人物就会崩塌,他的行为会变得很奇怪、甚至不符合逻辑。
其实基础欲望可以引发很多活动,千万不要程式化和被禁锢。其实性欲的引发不一定真的反映到做爱和爱情之类上,它还可以有诸多延伸行为。欲望只是人物本能的需求而已,我们不可以拒绝对人物欲望的刻画,单也不要太禁锢于欲望刻画之中。在人物的塑造之中,欲望可以成为人物直接行动力的因素,也有可能成为人物发展的阻碍因素。
!! 外部复杂化
其实外部复杂化是由人物性格本身引起的,这一点一定要放在前面。所谓的外部复杂化实际上应该是内部矛盾的外化表现。在人物性格的影响下,人物真相的确立下,如何将这些外化到我们所建立的人物身上呢?
人物性格的来自于人人物真相,人物性格确立人物需求。可是在实际的创作过程中我们的人物依旧不够复杂不够好玩。这是因为我们给予了人物足够的内心支撑,却没有做好外化成动作、行为的原因。
人物外化我们需要遵从几个很重要的方面。
# 符合逻辑
# 符合人物性格
# 具有冲突性
我们可以一条一条的看。首先符合逻辑这一条,看起来容易做起来难,实际上很多人写东西是没有逻辑的。(我们所说的逻辑不仅仅是生活逻辑)我们可以让人物有反差,有冲突,对人物的意志做出挑战,对人物的需求创造阻碍。这些都没有问题,但是咱一定要符合逻辑。我们先来看一个没有逻辑的例子。
```
A 是个爱学习的好娃娃,他生活在南京,他有鼻炎,每到一年的四五月份就会因为法国梧桐而犯鼻炎。他每天上学,放学,特别安稳,他有一个同班的小女友,两个人感情很好,准备一起奋斗同一所大学,他语文好,他的女友英文好,两个人互相补习,成绩逐步上升。双方家长是同事,关系不错,甚至还觉得如果俩孩子真的可以走到一起结个亲家也是好事,从不干涉二人。然后 A 因为觉得谈恋爱影响学习分手了,然后 A 学业有成,从此出任 CEO, 迎娶白富美,走向人生巅峰。
```
这就叫做没有逻辑,这样是有些夸张的,但是很多时候,特别在写比较长的文章的时候。真的莫名其妙就能看到类似的状况,这是因为掌握不住人物变化和情节发展,导致的逻辑缺失。而往往会发展成这样:
```
等到 A 年迈之后,他又想起了曾经的小女友。他回去寻找他最初的爱情,这些年虽然看上去过的风风火火,事业有成,但是他的内心并不开心。他觉得为了事业而放弃的爱情,远远比他现在得到的一切要重要的多。等他看到他曾经的小女友之后,发现了自己依旧爱她。(或者只剩个墓碑,和一封陈年的信。)
```
看上去,好像挺好的呀。但是问题还是一样的,这是没有逻辑,很想当然的写法,可是挂上这样的情感展示就会变得特别的无逻辑。因为他的行为和他的反思实际上并不对位,如果他在大学毕业之后,有一个富婆非要包养他,他可以平步青云而放弃了小女友的话就是 OK 的。或者他们因为什么天灾人祸的外力冲突而被迫分手不得相见也是 OK 的。再或者因为两家反目而引起的男孩对其家庭的恨意延伸导致的分手也可以。
我们不是不能这么写,但是我们这么写的时候是抱着一种讽刺的心情,写的讽刺喜剧或者荒诞喜剧,并不是看上去的这样的心灵救赎。
这是基本的逻辑问题,而很多时候人物逻辑问题更加细节化,我很难具体的分门别类的列清楚。但是符合逻辑,我们需要符合:
# 生活逻辑
# 人物逻辑(性格逻辑,行动逻辑)
这个地方我们会在情节、事件部分继续展开,暂且就到这里。
2,符合人物性格
符合人物性格这个不必多说,人物如果不符合人物性格是很奇怪的。如果一个懦弱、胆小的人,没有任何理由就跳起来反抗歹徒是不符合人物性格的。也是上面说到的不符合人物性格逻辑。
而在符合人物性格的前提下如何让人物外部复杂化呢?我们往往会选择让他的性格和需求与情境或者社会、现实情况造成冲突。人物性格被压抑,人物表现在外部的抗争性或者顺从性都是在人物外部复杂化的手法。
然后我们需要再次提出上一次提过的重要的三个字
''具体化''
(对!加大,加粗)
具体化,细节化,把人物的多个角度多个方面都做出来,他可能会很顺从,被压抑,但是他也会在某些场合表现出抗争的行为。
拿经典的 “救猫咪” 为例子,一个看上去的恶棍,却在一个下雨天救了一只流浪猫。这种桥段,就是展现人物的手法。
同样我们也可以使用反差塑造的手法,一个越是自卑的人就越是喜欢炫耀,一个越是懦弱的人就越是喜欢逞强。这是一种很常见的手法,或许有人会觉得这很 LOW,但是用好也不容易,更何况很多高级的玩意是建立在反差手法之上的。我们后面再说。
3,具有冲突性
具有冲突性是非常重要的一点,冲突生发于矛盾,人物的内部矛盾,人物和社会和现实的矛盾,人物关系上的矛盾。这些在外部的呈现上都是十分有效而快捷的。
而这一切一样扎根于人物性格,我们具有独特的准确的人物性格之后,在按照人物性格给他添加实际的,明确的冲突性的外化行为、动作或者前史。这是让人变得好玩的方式,你总不想看一个一马平川的玩意的。
4,直接性的特征和前史加入
在复杂化人物外部形象的时候实际上可以遵从典型性原则,给人物增加习惯性动作,语言,行为。这一样应当符合人物性格,也一样可以用反差手法。或者也可以给人物添加足够细节化的形象,在高级一点给人物添加象征性作用。这些都是相对有效的办法,我们也可以让一个人物的气质和某一些细节产生戏剧性的效果。
我们可以让一个抠脚糙汉熟读四书五经,平时像个傻逼喊着 niconiconi,但是当某一个时刻在让他展现出自己的文化修养。
举个最近很火而且我觉得做的很好的例子《欢乐颂》里面的魏渭这个人物,给了他一个前史,他在经济崩盘时期抛了合作伙伴,独善其身。这个人物实际上是有些猥琐,但是被他的儒雅气质压住,透过一点点细节偶尔的展示出其内心,这个也同样是很有效的一种人物塑造方式。
三,人物维
罗伯特 · 麦基在《故事》中提出 “人物维” 指的是塑造多维度的人物,让人物形成一种类似图形 “球形” 的丰满的人物。多维度的人物来自于多个方面的细化塑造,以及各个方面之间的冲突和矛盾建立。并且在 “人物维” 的概念之中还包括人物发展的部分,然而人物发展我们下一次再说。
我们这一次主要针对多方面,多维度这一块来讲述。
我们可以先设计三个维度给一个人物,
# 社会属性的维度,被社会性要求的部分。
# 人物真相需求,人物的本质性格。
# 人物的情感及其他人物关系影响部分。
这三个维度塑造的人物一定比 “小偷,妓女,抢劫犯” 好看,同样刻画的维度,方面越多人物越立体也越复杂。在每个方面里面都应当有冲突有矛盾,有人物独特的地方。
我们可以举个例子
```
一个男人,四十多岁,已婚,警察,住在北戴河。他是个性欲极其旺盛爱吃海鲜的世俗男人。他的妻子是个痴呆,他遇到一个想要自杀的妓女,他一边要救妓女一边操她。
——朱文《海鲜》里的一个男人
```
当然实际上那个男人比这个好玩的多,具体还是希望可以自己去看看这个人物。人物维的建立和使用时十分有效的复杂化一个人物的手法。
! 人物的建立和基本属性的塑造方式
无论是《论戏剧性》还是《戏剧技巧》或者《剧作法》都在讲述人物的重要性,甚至相当的篇幅讲述人物的可能是戏剧的核心,但是我也相信人物也是任何包含叙事意图的文学作品的核心。同样我也说明,这只关系到每个人个人的创作思维和创作认知,并不关系到优劣。
优秀的、独特的人物是让读者产生移情作用和兴趣的基本和核心,我们这里指兴趣,而不是好奇、更不是猎奇。那么什么样的人物是独特的人物呢,是好的人物呢?不妨让我们从一个例子开始。
```
一个曾经辉煌过的天才,然后因为什么原因废掉了,却发现只是一个开挂的前期续费。他善良,他有担当,长得不一定很帅但是很有魅力。(不要猜我用的谁)
一个20多岁的年轻人,他的祖父是个很有本事的人,有田产经营下了许多的家业,却被他的儿子一个酒鬼给硬生生的败光。这个年轻人只能和他的母亲躲在家里,他的母亲用童话来麻痹他,让他不至于忍受他父亲的不堪。而这个年轻人长到20多岁的时候却变成了一个只知道吹牛的家伙。他精力旺盛,喜欢打闹,他去抢过别人的老婆却又抛弃了她,他被追杀,逃到山里睡了三个牧牛女,他又睡了山妖的女儿,他变成一个只为自己而活的人。母亲死后他逃到国外,当过资本家、先知、科学家还进过疯人院。他总说他秉承着真正的自己,最终却发现自我已然丢失。(培尔·金特)
```
我们看这两个人物,培尔金特是一个让人能够记得住的人物,说起培尔金特,就是培尔金特,通过我的描述,读过的人都知道这是培尔金特。但是前者,我们似乎在很多地方都能看到他的影子,似乎挂在什么地方都OK的。这是独特性的问题,而我不想现在就提到独特性,我希望在写完人物的最后,大家能够自然的知道独特性是什么。
那么言归正传,从无到有,人物应该如何建立呢?一般情况下,我们的人物需要具有基本的属性,社会属性。基础如下:
```
1,基础部分
年龄,性别,性向,身高,体重,相貌,受教育水平等
2,事业部分
职业,收入组成,兴趣,能力,能上的缺陷。
3,个人部分
家庭组成,癖好,爱情观,生理缺陷,心理阻碍。
```
在这样的基础部分之下,我们可以组织出一个简单的人物。但是人物实际上是十分单薄的,我们的人物应该丰富和有趣。那么我们可以根据上面的部分进行延伸,这是一个十分重要的事情。
!! 事业部分
* 职业,他做这个职业的原因,他是否适合这个职业,他是否喜欢自己的职业,他在职业生活中是否得心应手,原因是什么?
* 收入组成,这个跟职业的有关,并且收入组成也包含其所在社会阶级和自我的消费情况,并且这也关系他他的社交圈子和他的经济压力,在这样的经济状况下他的经济观念又是什么呢?
* 兴趣,他的兴趣决定他性格的一个展现,他的兴趣什么,是否和职业相关,这也影响他的品味和受教育程度。
* 能力及能力缺陷,能力的倾向如何,体力、思维逻辑能力、他能力的累计于何处?他是否在能力上有所缺陷,缺陷的原因来自于什么,他是否自我认知到能力的缺陷。缺陷是否会给他带来危机。
!!个人部分
* 家庭组成,大家族、三口之家、单亲或者孤儿直接可以影响人物性格,以及他在家庭组成中的位置是如何的也是有效作用力。
* 癖好,癖好不等同于兴趣,癖好更加私人也更加具有展现力。癖好不一定是不好的部分,但是应当是狂热的,这是一个直接呈现人物性格的地方。
* 爱情观,是乐观还是悲观,对于爱情的愿景如何,并且为何产生这样的爱情观。
* 生理缺陷和心理阻碍,生理缺陷一般指的是其生理上的问题,缺胳膊断腿什么的,当然也可能是脱发严重之类的,但是他生理缺陷的原因是什么?心理阻碍指的是人物内心的阻碍,他对于某些事情的抗拒或者是缺失,其形成原因是什么。
这些问题进行一些回答之后,大概我们可以做出一个简单的人物小传。人物具有心理支撑,开始呈现相对有效的性格,但是还是具有雷同化问题。那么我们则需要寻找人物的矛盾,人物自身的内部矛盾。我们这是增强人物张力的一个十分有效的手段,人物自身的问题也是其在之后的发展中需要克服的部分。
那么人物的内部矛盾应该如何建立,如何生成一个相对好玩一些的人物呢?人物的内部矛盾,应该从各个角度入手,但是不应当所有的部分都变成矛盾点,他可能对于职业有不满,内心的需求与职业不符合,也可能是家庭引起的童年变故或者童年压力造成的心理阻碍。他的外部与内部产生矛盾和冲突的时候,这个人物大概会有些意思。那么我们来试着完成一个人物。
```
赵可,20多岁的年轻男人,刚刚大学毕业,学的是文学。家境曾经十分殷实但是在其读大学时破产,他原本因为兴趣学的文学难以让他生存,他原本的自尊在他被迫做家教的时候被彻底击碎。他在看着一个乞丐吃馒头而自己只能咽口水的时候发生了改变。他成功熬成到了毕业,当了一个小学老师,他虽然希望写点东西出来,但是却只能当一个小学老师,甚至逐渐放弃了写作这件事。他受着班里领导孩子的折磨,只能在午休的时候坐在教学楼的石头下吹口琴。他在一天终归还是被年级主任的侄子顶替,从学校里面被赶了出来,揣着自己仅有的积蓄准备回到老家去。(这是我一个剧本的人物)
```
赵可这个人物其实比这样写出来的部分要复杂的多,但是再复杂的部分今天并不适合拿出来,因为他还关系着更多的原因和一些技术之外的东西。但是就先看一个简单一些的赵可,他有梦想和职业上的矛盾,有家境变化之后经济上的矛盾,有尊严和现实的矛盾。这些事在他本身内部和外部上的矛盾。(我也不介意稍微的复杂一点,原本的赵可实际上是没有写作才能的,家境的变化也更加复杂。)
我们其实按照基础部分,事业部分,个人部分组成人物,然后用矛盾的方式来复杂化一些人物,其实是很容易创作出一个人物来的。然而就目前来看,其实这个人物也并没有多么的有趣,但是也确实够简单的使用了。那么希望人物更加有趣的话应该怎么办呢?怎么让人物更加有趣呢?
''具体化!(这个很重要) ''
人物需要具体化,人物越具体就越独特也就越有趣。至于进一步的人物的戏剧性需求,人物真相,人物维这些东西我希望在之后的文章之中再提及,他们应该属于人物塑造和人物复杂化的部分。现在我希望讲述的是人物从无到有的部分。
人物从无到有我讲述了一个方法,但是还有一个很重的事情我放在了后面来说。它很重要,如果不包含这个的话,人物是不具备价值的,他刻画出来之后也会显得格格不入。
!!人物含义
人物需要同主题统一,人物如果与创作者的主题不同,那么人物的价值在哪里呢?人物不能够有效的表达作者的意图又有什么用呢?其实主题每个人都不同,但是实际上人物是为了表达主题的,但是我们并不提倡“主题先行”的概念,这种概念已经被淘汰了。但是我们也要相信,主题其实在某些时候开始居寓人物性格,人物命运之中。我们或许不需要知道明确的“主题”是什么,但是我们要从人物的身上看到人物的含义和对人物的发展过程之中逐渐的清晰我们作为一个创作者到底在说什么,到底在表达什么。实际上,这是一个相对简单的创作方式,它很通俗,真正的严肃文学的创作上会更加的复杂,我自认为没有能力讲述严肃文学的具体写作方法。
在人物的创作过程之中我们可以逐渐找到我们希望叙述的东西,我并不认为创作者需要有一个明确的,需要表达的“主题”。我相信一个优秀的创作者可以从在他的创作之中找出他所需要表达的东西,甚至创作者并不十分清楚自己想要表达的一切。但是我也要说,这是一种相对高级的东西,因为如果是真正靠谱的东西很有可能其作品的张力已经扩大到创作者意图之外,一个作品的张力很有可能在创作中迸现出来,而不是提前想好的。这来自于一个创作者的直觉和天赋。
我也要提前说明一点,这个世界上具有这种天赋的人少之又少,请不要莫名的把自己当做这种天赋的拥有者。很多的时候会发现,自己其实是掌控不住。请千万别把自己当做一个天才,我不是,我猜大部分人也不是。所以请不要以此为借口来掩饰自己能力的不足,因为创作者不应该夸张自己的能力,这种东西在有了足够的阅读量和对于文学作品艺术作品的鉴赏能力之后是可以有感知的。而最好的办法是把它给别人评价,除非你可以自省,自己清醒的判断自己。
所以,在创作人物的时候要具体化,也要逐渐明确他的含义,他可能身上并不具有意象作用。但是我们要知道为什么要创作这个人物,哪怕只是一个模糊的概念,可以从有趣逐渐散发出其内部的含义才是比较重要的。
在我们具有了基础的人物之后,我会在下一篇聊聊人物复杂化,和具有目的的人物处理。所以在初始阶段,我们可以尽量多的给人物添加东西,人物属性是可以十分细化的,人物属性的矛盾也是可以不断添加的。甚至在初始阶段,建立人物的时候可以不考虑很多限制,不断地丰富,不断的添加内容。在之后在进行有目的性的删改和复杂化,也是完全可以的。
**人物的发展:人物弧光、人物揭示**
-------------------
人物的发展,我们主要就是说人物在基本建立之后的人物塑造部分。这一部分很重要,跟情境直接挂钩,跟结构直接挂钩,很重要哟。一个人物完成了基本的立体之后,如何让他更加吸引人,更加有趣,就靠这个了!
**1,人物弧光**
人物弧光是《故事》(麦基著)里的一个概念,其定义为人物发展的弧线,在情节中人物需要发展,无论是变好还是变坏。简单来说,就是一个 “弧线模型” 为主的人物发展轨迹,但是 “弧光” 二字,应该还包括人物的辐射和张力。
那么人物弧光到底是个什么鬼?其实也不复杂,就是人物从初始状态 A 到终止状态 B 的发展轨迹。比如:
> * **A 在开始的时候,是一个很好的,优秀的教师。(起点)
> **
> * **到最终的时候,A 变成了一个十足十的在逃变态杀人犯。(终点)**
>
你看 A 的起点和终点存在了,那么人物中间的部分是什么呢?就是 “人物弧光” 人物的发展轨迹。这一部分应该如何处理,《故事》还是相对于给有写作基础和经验的人们看到,所以没有十分细致的讲解这个部分。其实想要自己的故事没有那么无聊,我们需要让这个过程曲折,让人物的的变化成为一种逐步的,在逻辑内的处理方式。
在这里我们要先拎出一个点,就是 “**人物真相**”(不知道的小伙伴们请去看上一章节)。“人物真相” 支撑着人物的动机和目的,也影响着最终人物结果。区别很明显,比如上面的 A,其实最大的区别就是在于 A 到底是被迫,还是自愿。可能会有小伙伴问:
他不可以,先被迫再自愿吗!
当然可以,但是人物真相还是:自愿。而被迫只能成为一个 A 呈现自我真相的一个诱因和渠道而已。那么我们确定了 “人物真相” 之后,再如何让人物的发展过程更有趣,更好玩呢?其实也不复杂。人物分变化是一个过程,我们要把握过程,而过程在故事之中是什么呢?我们一般叫做“情节点”。小说和戏剧有很大区别,戏剧比较考虑“骤变”,而小说则更加考虑“持续”,这来自二者的表达语言不通。但是在人物变化之中二者却是很相似的,我不建议各位玩“瞬间的变化”,我们需要给人物“**动机,诱因,刺激,抗拒,(动摇),接受**” 这样的一个过程。看起来好像还蛮复杂的样子,其实落实到文本中之后还蛮简单的。
> A:讨厌做老师,甚至讨厌小孩子,家庭也有许多的问题(动机)。有一个小孩子 B 特别特别的讨人厌,还是 A 领导的亲戚,小孩子 B 有一天冒犯了 A 的底线(诱因)。但是 A 忍住了,但是在处理完需要修改的作业回家的路上,A 看到 B 被一群混混抢劫,然后 B 被一板砖拍倒在地(刺激)。A 在纠结于要不要救 B,特别在看到 B 的挣扎之后,但是 A 却觉着 B 罪有应得(抗拒)。B 看到 A,没有哀求,反而威胁 A,告诉 A 如果 A 不救自己,自己就会告诉别人是 A 动的手(第二次刺激)。A 补刀,B 死了,但是 A 逃离了之后,发现自己的内心恐惧(第二次抗拒)。逃到另一个城市 A 过着像乞丐一样的生活,但是他在乞讨的同时看到了对孩子下毒手的群体,却慢慢的发现了一种莫名的刺激。A 却一直担心着自己的案件,结果,他却发现这件事根本没有联系到他身上,他通过新闻发现那几名混混顶了缸(动摇)。A 再次离开了这个城市,去了一个陌生的地方,通过阅读大量的 “心理学”、“案件资料 “等等文献,变成了一个变态杀人狂,而且以孩子为主要下手目标(接受)。
好的一个阴暗的小故事的人物发展线出来了。但是你发现,这个人物发展现好狗血哦,而且过不了审唉,太不正能量了,怎么办?A 是个日本人!你看,完美解决。
但是从人性的角度上来说,还是不太好的,从技术的角度上来说还是很单薄的。怎么办?我们先填补人性的坑。我们众所周知,在当今状态下,我们要让恶人有个理由变成恶人,除了上面的直接诱因之外,我们需要给他一个根本原因,一般情况下我们会回溯人物童年做前史。这个就不展开了,聪明的你们可以 get 的。(实际上也蛮狗血的)
然后我们来填技术层面的坑,我们一般有两种选择。
* 1,延续弧线发展——“救赎”,“放逐”
* 2,修改情节点,玩弄 “现象学” 在文学作品中的表现。
* (3,暴力解决法,适合有相当写作能力的玩家,直接、暴力的让人物呈现,物化人物形象,叙事手段上相对冷漠,讽刺。这个还是个比较高级的玩法的,不建议新手尝试。)
我们逐条来看,优劣和手段。
延续弧线发展的方式,实际上就是让人物的发展线回归的上升曲线,得到自我救赎,或者自我放逐。这个事不复杂:就是顿悟嘛,就是很不幸伤害到自己的身边的人嘛,或者再次受到其他的刺激来反馈到人物身上嘛...... 这个跟上面的部分实际是很相似的,可以从前史入手,也可以从事件入手。
修改情节点,玩弄 “现象学”。首先建议各位先搞明白“现象学” 的概念,至少去读读《时间与存在》。然后我们说说这个玩意到文学作品之中应该怎么做。表达到文学作品之中,我们以在极致化一种人物行为,一种情景,一种心理支撑。极致化,A 的行为要相对极致化,但是行为需要一个心理支撑来作为依靠。简单一点就是给予人物一个心理支撑,并且将其心理支撑的外化行为做“狠”。但是请不要让 A 具有反社会性人格,还告诉大家你们看“他有反社会性人格哦”,这样做很傻,我们在这个部分不坐解释,只做展现。
**2,人物揭示**
阿契尔对于人物变化的理解为 “人物解释” 即指 “人物的变化是指对于人物真相的不断揭示。” 意思是:我们只是在不停的揭露一个人物的本质而已,并不是给予人物实质上的变化。
这个是就好理解多了,我们在写作一个人物的时候,已经知道了给人物诸多的假面,我们需要的是不停的撕下这些假面,让人物的本质呈现在我们的面前。这是一样也是一个逐步的过程,我们有一个写作理论,也是电影理论叫做——“照明理论”。意思就是:人物处于一种黑暗之中,我们每次打开一个灯照亮人物身上的一部分,知道将所有的灯都打开,让人物完全呈现在我们的面前。
就是指,人物是逐渐呈现出本来面目的,不要一上来就给人物下一个定义,除非你认为你有能力掌控住这样的写作方式,并且通过事件和结构安排一样让人物的形象变化有趣。而实际上,往往我们在一开始给予人物的定义都是虚假的人物定义,人物在故事的发展中还是在逐渐的揭露自己的本质的过程。这需要我们对人物有一个比较准确和深刻的理解。而这一切需要建立在一个很重要的事情之上:
**人物开掘**
开掘人物,不停的明确人物,并且让人物具有一种具体的,独特的形象。然后人物也具有其自带的人格魅力和作者的主题意图。人物本身是表现主题,而不是用人物来图解主题。那么对于人物的开掘上,我们更多的要着力于人物的独特性和人物真相上。甚至在某些情况,一个作者对于人物的开掘可以得到一个真正的 “主题” 而不是一个概念化的“主题”
而人物揭示我们需要的就是把人物身上开掘出来的部分逐渐的展示给读者或者观众。那么如何做到有效的,合理的,好看的人物揭示呢?这依旧需要依托于事件,更准确的说是依托于人物的动作、行为。每一盏灯,都是在故事发展中的事件、冲突、选择。甚至在一些细节的动作之中也是揭示人物的一个手段,这还牵扯人物潜意识的部分,推荐大家阅读《精神分析引论》(我将之称为——《台词写作技巧》)。
当然也还有更为高级的玩法,暂时不说,毕竟我们讨论那些基本上都是和差不多会写的人玩的,这些还涉及结构和叙事手段之类的东西。甚至我们一个概念说出会有许多种的解决方法提出,只要说一下就能了解如何处理。当然更高级的玩法也我自己也只能了解各大概,让我跟大家讨论,就比较难了。
——————————————————————————————————————————
你们看,本宝宝又写字了。最近手上事情比较多,还抽出时间来写没有钱赚的专栏,宝宝多么认真,多么刻苦,多么敬业。这一次是人物暂时的最后一部分。后面我可能会写点别的,暂不进入结构,发现许多人在意自己的文笔状况、语言运用的问题,下次我可能随便写点这个,之后再进入结构。
是不是我写的略长,就让大家看不下去呀。
每次都纠结自己要不要继续写下去呢。
哼。
人物的描写-老舍
========================
人物的描写-[[老舍]]
-----
按照旧说法,创作的中心是人物。凭空给世界增加了几个不朽的人物,如武松、黛玉等,才叫作创造。因此,小说的成败,是以人物为准,不仗着事实。世事万千,都转眼即逝,一时新颖,不久即归陈腐,只有人物足垂不朽。此所以十续《施公案》,反不如一个武松的价值也。
可是近代文艺受了两个无可避免的影响——科学与社会自觉。受着科学的影响,不要说文艺作品中的事实须精确详细了,就是人物也须合乎生理学心理学等等的原则。于是佳人才子与英雄巨人全渐次失去地盘,人物个性的表现成了人物个性的分析。这一方面使人物更真实更复杂,另一方面使创造受了些损失,因为分析不就是创造。至于社会自觉,因为文艺想多尽些社会的责任,简直的就顾不得人物的创造,而力求罗列事实以揭发社会的黑暗与指导大家对改进社会的责任。社会是整个的,复杂的,从其中要整理出一件事的系统,找出此事的意义,并提出改革的意见,已属不易;作者当然顾不得注意人物,而且觉得个人的志愿与命运似乎太轻微,远不及社会革命的重大了。报告式的揭发可以算作文艺;努力于人物的创造反被视为个人主义的余孽了。说到将来呢,人类显然的是朝着普遍的平均的发展走去;英雄主义在此刻已到了末一站,将来的历史中恐怕不是为英雄们预备的了。人类这样发展下去,必会有那么一天,各人有各人的工作,谁也不比谁高,谁也不比谁低,大家只是各尽所长,为全体的生存努力。到了这一天,志愿是没了用;人与人的冲突改为全人类对自然界的冲突。没争斗没戏剧,文艺大概就灭绝了。人物失去趣味,事情也用不着文艺来报告——电话电报电影等等不定发展到多么方便与巧妙呢。
我们既不能以过去的办法为金科玉律,而对将来的推测又如上述,那么对于小说中的人物似乎只好等着受淘汰,没有什么可说的了。这却又不尽然。第一,从现在到文艺灭绝的时期一定还有好多好多日子,我们似乎不必因此而马上搁笔。第二,现在的文艺虽然重事实而轻人物,但把人物的创造多留点意也并非是吃亏的事,假若我们现在对荷马与莎士比亚等的人物还感觉趣味,那也就足以证明人物的感诉力确是比事实还厚大一些。说真的,假若不是为荷马与莎士比亚等那些人物,谁肯还去读那些野蛮荒唐的事儿呢?第三,文艺是具体的表现。真想不出怎样可以没有人物而能具体的表现出!文艺所要揭发的事实必须是人的事实,《封神榜》虽很热闹,无论如何也比不上好汉被迫上梁山的亲切有味。再说呢,文艺去揭发事实,无非是为提醒我们,指导我们;我们是人,所以文艺也得用人来感动我们。单有葬花,而无黛玉;或有黛玉而她是“世运”的得奖的女运动员,都似乎不能感人。赞谀个人的伟大与成功,于今似觉落伍;但茫茫一片事实,而寂无人在,似乎也差点劲儿。
那么,老话当作新话来说,对人物的描写还可以说上几句。
描写人物最难的地方是使人物能立得起来。我们都知道利用职业,阶级,民族等特色,帮助形成个特有的人格;可是,这些个东西并不一定能使人物活跃。反之,有的时候反因详细的介绍,而使人物更死板。我们应记住,要描写一个人必须知道此人的一切,但不要作相面式的全写在一处;我们须随时的用动作表现出他来。每一个动作中清楚的有力的表现出他一点来,他便越来越活泼,越实在。我们虽然详知他所代表的职业与地方等特色,可是我们仿佛更注意到他是个活人,并不专为代表一点什么而存在。这样,人物的感诉力才能深厚广大。比如说吧,对于一本俄国的名著,一个明白俄国情形的读者当然比一个还不晓得俄国在哪里的更能亲切的领略与欣赏。但是这本作品的伟大,并不在乎只供少数明白俄国情形的人欣赏,而是在乎它能使不明白俄国事的人也明白了俄国人也是人。再看《圣经》中那些出色的故事,和莎士比亚所借用的人物,差不多都不大管人物的背景,而也足以使千百年后的全人类受感动。反之,我们看Anne DouglasSedgwick(安妮。道格拉斯。塞奇威克)的The Little French Girl(《法国小姑娘》)的描写法国女子与英国女子之不同;或“Elizabeth”(伊丽莎白)的Caravaners(《队商》)之以德人比较英人;或MargaretKennedy(马格雷特·肯尼迪)的TheConstantNymph《恒久的宁芙》之描写艺术家与普通人的差别;都是注意在揭发人物的某种特质。这些书都有相当的趣味与成功,但都够不上伟大。主旨既在表现人物的特色,于是人物便受他所要代表的那点东西的管辖。这样,人物与事实似乎由生命的中心移到生命的表面上去。这是揭发人的不同处,不是表现人类共同具有的欲望与理想;这是关于人的一些知识,不是人生中的根本问题。这种写法是想从枝节上了解人生,而忘了人类的可以共同奋斗的根源。这种写法假若对所描写的人没有深刻的了解,便很容易从社会上习俗上抓取一点特有的色彩去敷衍,而根本把人生忘掉。近年来西洋有许多描写中国人的小说,十之八九是要凭借一点知识来比较东西民族的不同;结果,中国人成为一种奇怪好笑的动物,好象不大是人似的。设若一个西洋写家忠诚的以描写人生的态度来描写中国人,即使背景上有些错误也不至于完全失败吧。
与此相反的,是不管风土人情,而写出一种超空间与时间的故事,只注意艺术的情调,不管现实的生活。这样的作品,在一个过着梦的生活的天才手里,的确也另有风味。可是它无论怎好,也缺乏着伟大真挚的感动力。至于才力不够,而专赖小小一些技巧,创制此等小玩艺,就更无可观了。在浪漫派与唯美派的小说里,分明的是以散文侵入诗的领域。但是我们须认清,小说在近代之所以战胜了诗艺,不仅是在它能以散文表现诗境,而是在它根本足以补充诗的短处——小说能写诗所不能与不方便写的。SirWalterRale(i)gh(沃尔特。雷利爵士)说过:“一个大小说家根本须是个幽默家,正如一个大罗曼司家根本必须是诗人。”这里所谓的幽默家,倒不必一定是写幽默文字的人,而是说他必洞悉世情,能捉住现实,成为文章。这里所谓的诗人,就是有幻想的,能于平凡的人世中建造起浪漫的空想的一个小世界。我们所应注意的是“大小说家”必须能捉住现实。
人物的职业阶级等之外,相貌自然是要描写的,这需要充分的观察,且须精妙的道出,如某人的下巴光如脚踵,或某人的脖子如一根鸡腿……这种形容是一句便够,马上使人物从纸上跳出,而永存于读者记忆中。反之,若拖泥带水的形容一大片,而所以形容的可以应用到许多人身上去,则费力不讨好。人物的外表要处,足以烘托出一个单独的人格,不可泛泛的由帽子一直形容到鞋底;没有用的东西往往是人物的累赘:读者每因某项叙述而希冀一定的发展,设若只贪形容得周到,而一切并无用处,便使读者失望。我们不必一口气把一个人形容净尽,先有个大概,而后逐渐补充,使读者越来越知道得多些,如交友然,由生疏而亲密,倒觉有趣。也不必每逢介绍一人,力求有声有色,以便发生戏剧的效果,如大喝一声,闪出一员虎将……此等形容,虽刺激力大,可是在艺术上不如用一种浅淡的颜色,在此不十分明显的颜色中却包蕴着些能次第发展的人格与生命。
以言语,面貌,举动来烘托出人格,也不要过火的利用一点,如迭更司的次要人物全有一种固定的习惯与口头语——Bleak House(《阴暗的房子》)里的Bagnet (巴格内特)永远用军队中的言语说话,而且脊背永远挺得笔直,即许多例子中的一个。这容易流于浮浅,有时候还显着讨厌。这在迭更司手中还可原谅,因为他是幽默的写家,翻来覆去的利用一语或一动作都足以招笑;设若我们不是要得幽默的效果,便不宜用这个方法。只凭一两句口头语或一二习惯作人物描写的主力,我们的人物便都有成为疯子的危险。我们应把此法扩大,使人物的一切都与职业的家庭的等等习惯相合;不过,这可就非有极深刻的了解与极细密的观察不可了。这个教训是要紧的:不冒险去写我们所不深知的人物!
还有个方法,与此不同,可也是偷手,似应避免:形容一男或一女,不指出固定的容貌来,而含糊其词的使读者去猜,比如描写一个女郎,便说:正在青春,健康的脸色,金黄的发丝,带出金发女子所有的活泼与热烈……这种写法和没写一样:到底她是什么样子呢?谁知道!
在短篇小说中,须用简净的手段,给人物一个精妥的固定不移的面貌体格。在长篇里宜先有个轮廓,而后顺手的以种种行动来使外貌活动起来;此种活动适足以揭显人格,随手点染,使个性充实。譬如已形容过二人的口是一大一小,一厚一薄,及至述说二人同桌吃饭,便宜利用此机会写出二人口的动作之不同。这样,二人的相貌再现于读者眼前,而且是活动的再现,能于此动作中表现出二人个性的不同。每个小的动作都能显露出个性的一部分,这是应该注意的。
景物,事实,动作,都须与人打成一片。无论形容什么,总把人放在里面,才能显出火炽。形容二人谈话,应顺手提到二人喝茶,及出汗——假若是在夏天。如此,则谈话而外,又用吃茶补充了二人的举动不同,且极自然的把天气写在里面。此种写法是十二分的用力,而恰好不露出用力的痕迹。
最足以帮忙揭显个性的恐怕是对话了。一个人有一个说话方法,一个人的话是随着他的思路而道出的。我们切不可因为有一段精彩的议论而整篇的放在人物口中,小说不是留声机片。我们须使人物自己说话。他的思路决不会象讲演稿子那么清楚有条理;我们须依着他心中的变动去写他的话语。
言谈不但应合他的身分,且应合乎他当时的心态与环境。
以上的种种都是应用来以彰显人物的个性。有了个性,我们应随时给他机会与事实接触。人与事相遇,他才有用武之地。我们说一个人怎好或怎坏,不如给他一件事作作看。在应付事情的时节,我们不但能揭露他的个性,而且足以反映出人类的普遍性。每人都有一点特性,但在普遍的人情上大家是差不多的。当看一出悲剧的时候,大概大家都要受些感动,不过有的落泪,有的不落泪。那不落泪的未必不比别人受的感动更深。落泪与否是个性使然,而必受感动乃人之常情;怪人与傻子除外;自然我们不愿把人物都写成怪人与傻子。我们不要太着急,想一口气把人物作成顶合自己理想的;为我们的理想而牺牲了人情,是大不上算的事。比如说革命吧,青年们只要有点知识,有点血气,哪个甘于落后?可是,把一位革命青年写成一举一动全为革命,没有丝毫弱点,为革命而来,为革命而去,象一座雕像那么完美;好是好了,怎奈天下并没有这么完全的!艺术的描写容许夸大,但把一个人写成天使一般,一点都看不出他是由猴子变来的,便过于骗人了。我们必须首先把个性建树起来,使人物立得牢稳;而后再设法使之在普遍人情中立得住。个性引起对此人的趣味,普遍性引起普遍的同情。哭有多种,笑也不同,应依个人的特性与情形而定如何哭,如何笑;但此特有的哭笑须在人类的哭笑圈内。用张王李赵去代表几个抽象的观念是写寓言的方法,小说则首应注意把他们写活了,每个人都有他自己的思想与感情,不是一些完全听人家调动的傀儡。
人造美人-[[星新一]]
-----
这是一个制作得极其巧妙的机器人女郎。可以说,无论多么妩媚动人的美女都比不上这位人工制造的摩登女郎。由于广泛地吸收了所有的美女的长处,所以这位机器人女郎简直成了十全十美的仙女。不过,她老是爱摆架子,常常对别人爱理不理的。可是,这也是合情合理的。要知道,有许多漂亮的姑娘都是眼睛朝上,非常骄傲的呢。
一般的人都不愿意去制作这种好看而不实用的机器人。很多人认为,费尽心机去制造那种工作效率和人相同的机器人是得不偿失的蠢事。如果有这笔经费的话,完全可以购买各种高效率的机器,至于操作机器的工人则更不用担心了到处都是失业者,要多少就可以雇到多少。
在激烈的商业竞争中,有一家酒吧间濒临于破产倒闭的边缘。老板为了招徕顾客,特地花钱制作了这个富有魅力的机器人女郎。对于酒吧间的老板来说,酒只不过是一种做买卖的工具,无论是在家里还是在店里,人们都没有兴趣一个人独斟独饮。自从有了这个机器人女郎以后,这家酒吧间的生意日益兴隆,喝得醉熏熏的顾客们满不在乎地掏出了大把大把的金钱。老板乐得眉开眼笑,心花怒放。
由于这个机器人女郎决定着酒吧间的命运,因此老板颇费了一番苦心,把她制作得十分美丽动人。她那洁白如玉的肌肤绝不比任何一个少女逊色,完全能以假乱真。不知内情的人看到了,一定会认为这是自己所见到过的女人中皮肤最为娇嫩的一位。
可是,她的头脑里却空空的,几乎一无所有。因为老板光顾了在她的外表上下工夫,没有注意到智力这一方面。这位漂亮的机器人女郎只会回答一些简单的问题和端起酒杯来喝酒。不过,只要能做这些事也就足够了。
老板刚一制作出这个机器人女郎,立刻就把她安放到了酒吧间里。虽说店堂里还有不少餐桌空着座位,但老板还是把她放在柜台里面,万一出了纰漏可就糟糕了。
顾客们看到酒吧间里新来了一位年轻貌美的女郎,都争先恐后地向她打招呼搭话。当对方询问名字和年龄的时候,她还能从容不迫地微笑回答,但再往下问的话就答不上来了。虽说如此,可谁也没有觉察到她是一个机器人。
你叫什么名字?
布克。
今年多大啦?
还很年轻呢。
到底是多大呀?
还很年轻呢。
就是说
还很年轻呢。
由于到这家酒吧来喝酒的顾客大都比较讲究文明礼貌,所以也就不再追问下去了,以免对方难堪。
这衣服真漂亮啊!"
这衣服是很漂亮。
你喜欢什么呢?
我喜欢什么呢?
能够开怀畅饮吗?
开怀畅饮吧。
她神情坦然地举起酒杯喝了一杯又一杯,但是却毫无醉意。
有一位年轻美貌的女郎,自命清高,爱摆架子,答话时总是冷冰冰的。消息一传开,顾客们不约而同地纷纷来到这家酒吧间里。大家都饶有兴趣地喝着酒和布克小姐交谈,并且还请她喝酒。
在这些客人中间你最喜欢哪一位呢?
我喜欢谁呢?
你不喜欢我吗?
我喜欢你呀。
下次我们一起去看电影好吗?
去看电影吧。
什么时候去呢?
一旦答不上来的时候,布克小姐就会通过无线电电波发出紧急信号。于是,老板就匆匆忙忙地赶来解围。
各位先生,玩笑可别开得太过分了。
当然,大多数的顾客都是通情达理的,大家略带几分尴尬地笑着停止了嬉戏。
老板站在柜台里面,不时地蹲下来,从布克小姐脚下的那根塑料管子里把酒回收来,再公平合理地卖给顾客们喝。
可是,顾客们并没有发现这个秘密。这位姑娘年纪轻轻的,酒量可真不小,可想而知身体一定是非常健康的了。她也不会卖弄风骚地拖住客人纠缠不休;客人请她喝酒,她总是一饮而尽,却又全无醉意。没过多久,这位与众不同的美女就变得闻名遐迩了。顾客们闻讯而来,日益增多。
在这些顾客中间有一个年轻人,他对美丽的布克小姐一见钟情,着了迷。每天都要到这家酒吧间里来喝酒。当然,不管他怎样陪着笑脸向布克小姐献殷勤,都是对牛弹琴,枉费心机。可是,他却不死心,相反的,对布克小姐追求得更加起劲了。为此,他孤注一掷地把自己的积蓄花得一干二净。
最后,由于付不起酒钱,不得不硬着头皮把家里的钱也拿出来用。他父亲对此大为恼火,怒力冲冲地斥责道:以后不许再到那个鬼地方去了!喏,把这笔钱拿去付了。记住:这是最后一次!
这个年轻人拿着这笔钱来到了酒吧间。他伤心地想着,今天晚上是最后一次了。他闷闷不乐地喝着酒,为了表示告别,他频频举杯,请布克小姐也喝了很多酒。
唉,今后再也不能到这里来了。
再也不能来了吗?
你感到悲伤吗?
悲伤呀。
也许这并不是你的真心话吧。
这并不是真心话。
没有比你更冷酷无情的人了。
比我更冷酷无情的人是没有的。
我恨不得把你杀死!
请把我杀死吧。
这个年轻人悄悄地从口袋里掏出一小包毒药,撒在酒杯里,然后斟满一杯酒送到了布克小姐的面前。
请再喝一杯吧。
喝一杯吧。
他眼睁睁地看着布克小姐仰起头来,一饮而尽。
这个年轻人解恨似地说道:神不知鬼不觉地死掉才好呢。
布克小姐也微微地点着头说道:神不知鬼不觉地死掉吧。
这个年轻人心满意足地回过头来,朝布克小姐背后看了最后一眼,把酒钱付给老板之后就出门去了。外面一片漆黑,夜已经深了。
这个青年出门以后,老板就向剩下来的那些顾客们大声地招呼着:从现在开始,我请大家喝酒。诸位只管开怀畅饮吧!
虽说是请客,但老板也不会吃亏。因为在夜深人静的时候,已经不会有什么顾客再来了;再说,老板给大家喝的也不过是从布克小姐脚下的塑料管里回收的酒,用不着花什么本钱。
哈哈
好啊!好啊!
顾客们和店里的服务员都兴高采烈地大声喧闹着,互相干杯,开怀畅饮。
就连老板也受了这种气氛的感染,在柜台里举起酒杯来,慢慢地喝了一杯。
这天晚上,酒吧间里灯火辉煌、通宵达旦。然而,奇怪的是,明明没有什么人回去,但酒吧间里却像死一般的寂静,听不到任何人的说话声或喊叫声。只有一台收音机在不停地播送着轻快的乐曲。
过了一会儿,收音机里传出了诸位晚安,再见的声音,然后就无声无息了。于是,布克小姐也自言自语地说了一声诸位晚安,再见,接着便以十分冷淡的表情等待着下面该轮到谁来和她打招呼了呢?
(全文完)
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [www.99csw.com](https://www.99csw.com/article/9877.htm)
### 一
也许——我没仔细思考过这个问题——虚拟程序固然荒谬,但是否也得算是文学在新的时代里的存在方式呢?
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
阳光从西边斜射过来,给街区抹上一层金黄色的糖浆。
哪两种?
树叶在晚风里纷纷下坠,已经初秋了。
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
我一愣,反问:你呢?
现实世界真是太落后了,与其费那么大劲儿吃顿晚饭,倒不如去网上做一次虚拟约会呢。她说。
他在阳光里偏过头,细细打量了阵儿,说:不像。
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
拉开抽屉,所有的烟盒都空了,好像 FORMAT 后的软盘。
这期间,父亲久久地注视着我。最后他低下头,喃喃地说:要是觉得太累就放弃吧。网络虚拟也好,脉冲震颤器也好,都是我们自己创造出来的,我们是在和自己斗争,所以你永远找不到抵抗的神圣感。你我都只是一块礁石,而不是堤坝。
庆祝酒会上,JACK 使劲儿跟我套近乎。他拉着我把我介绍给几个和他一样的杂种,并亲热地说:这是我们自己人。我瞅着这几张一模一样的脸,他们的五官都消失了,只剩下几套西服空壳般支在那儿。厌恶感在我心中长成一株大树,我将杯里的马提尼一饮而尽,对 JACK 说:你愿意和一个傻瓜做自己人吗?他茫然地摇摇头。我拍拍他的肩:我也不愿意。
海滩上,我和小卷手拉手散步。湿软的沙子温柔地舔着我的脚趾缝,海风拥抱我的皮肤。小卷的笑声清脆如浪花轻拍岸边的礁石,我们惬意地嬉戏着,我再次有了种飘飘欲仙的感觉……
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
那么,你是电脑工程师喽?
我按下电钮,不一会儿,S-3 型服务机器人轱辘辘地滚进来,托着一杯速溶咖啡。这是为我设置的专门程序,整个设计部就我一个人喝咖啡,同事们都使用脉冲震颤器,这种小玩意儿能促使大脑产生多巴胺。自它出现后,毒品贩子都跳楼自杀了,烟草、咖啡的产量也连年下降。
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
我依靠着脉冲震颤器撑过了第四天,完成全部的工作后,我忽然不经意地看到一则网络新闻:领航者公司的第二代智能电脑终于问世。它具有强大的想像衍生功能,可根据一个程序联想衍生出系列程序,它的诞生将可能导致大批程序设计员的失业。
我的眼眶突然像沼泽地一样潮湿起来。
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
### 四
喝完咖啡,疲劳稍稍得到安抚,但远未被镇压下去。我急切地渴望一支香烟,渴望把自己淹没在袅袅的烟雾里,于是我到主管办公室去请假。
阳光从西边斜射过来,给街区抹上一层金黄色的糖浆。
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
我按下电钮,不一会儿,S-3 型服务机器人轱辘辘地滚进来,托着一杯速溶咖啡。这是为我设置的专门程序,整个设计部就我一个人喝咖啡,同事们都使用脉冲震颤器,这种小玩意儿能促使大脑产生多巴胺。自它出现后,毒品贩子都跳楼自杀了,烟草、咖啡的产量也连年下降。
40 个小时没睡觉了,全靠咖啡和烟撑着。没法子,公司催得紧,这批活儿得在三天内完成,否则就落在别的公司后面了。
多多少少。
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
公司又下达一项任务,设计部忙得不可开交。为了保住 4%的市场占有率,勉强养活自己,所有的人都必须拼尽全力。你只要看看 JACK 几天未换的西服和凌乱的头发,就能明白什么叫竞争。
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
于是我不由自主地朝迎面而来的每一个人微笑,他们或者报以同样的微笑,更多的人都面无表情地躲开去。我知道我那时的样子和一个从精神病医院翻墙出来的人是多么相似,尽管电脑装有视觉护屏,但连续 40 小时的目不转睛仍使我眼眶下陷,双眼赤红,满脸洋溢着回光返照似的神采。
JACK 往椅背上一靠,嘴角朝左边斜了两厘米,微龇着牙,露出一种很 “优雅” 的笑。
我一下来了兴趣:随便说说吧,瞎说也成。
这杂种今天穿着一件藏青色西服,衬衫松开顶上一颗纽扣,松松地系着一条蓝白相间的纱制围巾——今年最流行的白领装束。当他听说我请假的理由是出去买烟时,脸上惊讶的表情像是看到一只苍蝇在跳华尔兹。
你看呢?
多多少少。
我面无表情地看完新闻,关机,走出大楼。
譬如,你走过商店橱窗时会仔细打量自己。一般来说,只有两种人喜欢观察镜像里的自我。
这个傻蛋,我知道他在想什么。他早就清楚我从不使用震颤器,可他总是一有机会就在这个问题上找我的茬儿,用一种看乡巴佬的眼色看我。我拼命克制,才没有在他白净的脸蛋上造出几块青色的小丘来。长时间的饱和工作使我的愤怒盎然。
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
我把一张电子货币卡塞进他手里,里面还有 1500 单位电子货币,大约是我一周的薪水。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
于是我默不作声地听她的抱怨,陪她吃晚饭,送她回家。回家的路上,她默默地说:我们就此分手吧。
像你这样的人不多了。老板说。
不喜欢。
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
是软件制造和销售,虚拟软件。
是软件制造和销售,虚拟软件。
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
有道理。我把烟摁灭。说来不怕你笑话,我曾经想做诗人来着,在大学里。我父母都是作家,从小受他们影响太大,以至于现在还改不过来。可是,你知道,时代变了,电脑虚拟一诞生,文学就完了。
JACK 往椅背上一靠,嘴角朝左边斜了两厘米,微龇着牙,露出一种很 “优雅” 的笑。
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
阳光从西边斜射过来,给街区抹上一层金黄色的糖浆。
你这样认为?
这个傻蛋,我知道他在想什么。他早就清楚我从不使用震颤器,可他总是一有机会就在这个问题上找我的茬儿,用一种看乡巴佬的眼色看我。我拼命克制,才没有在他白净的脸蛋上造出几块青色的小丘来。长时间的饱和工作使我的愤怒盎然。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
他在阳光里偏过头,细细打量了阵儿,说:不像。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
也许——我没仔细思考过这个问题——虚拟程序固然荒谬,但是否也得算是文学在新的时代里的存在方式呢?
JACK 往椅背上一靠,嘴角朝左边斜了两厘米,微龇着牙,露出一种很 “优雅” 的笑。
看在我已连续干了 40 个小时的份儿上,他以施舍者的姿态准了我两个小时假。
街面儿很敞亮,暮春的阳光使整座城市看起来像姑娘的身体,富有弹性。满街的玉兰花都开了,花粉在空气中连续而轻微地爆炸,随着风迎面扑来。我站在铺着暗红色方砖的人行道上,贪婪地吸吮,感觉自己的肺被新鲜空气胀得无限大。眼睛因为无法适应刺眼的阳光而眯缝着。
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
这期间,父亲久久地注视着我。最后他低下头,喃喃地说:要是觉得太累就放弃吧。网络虚拟也好,脉冲震颤器也好,都是我们自己创造出来的,我们是在和自己斗争,所以你永远找不到抵抗的神圣感。你我都只是一块礁石,而不是堤坝。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
我苦笑。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
JACK 往椅背上一靠,嘴角朝左边斜了两厘米,微龇着牙,露出一种很 “优雅” 的笑。
### 二
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
公司又下达一项任务,设计部忙得不可开交。为了保住 4%的市场占有率,勉强养活自己,所有的人都必须拼尽全力。你只要看看 JACK 几天未换的西服和凌乱的头发,就能明白什么叫竞争。
以后的几天里,我始终精神恍惚。我已失去了对这个决定对错的判断力。像一头受伤的小野兽,我只顾躲在洞穴里舔着自己的伤口。我无力救赎他人,甚至也无力救赎自己,因为我根本不知道我的抵抗是不是徒劳。
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
我把一张电子货币卡塞进他手里,里面还有 1500 单位电子货币,大约是我一周的薪水。
街面儿很敞亮,暮春的阳光使整座城市看起来像姑娘的身体,富有弹性。满街的玉兰花都开了,花粉在空气中连续而轻微地爆炸,随着风迎面扑来。我站在铺着暗红色方砖的人行道上,贪婪地吸吮,感觉自己的肺被新鲜空气胀得无限大。眼睛因为无法适应刺眼的阳光而眯缝着。
这个傻蛋,我知道他在想什么。他早就清楚我从不使用震颤器,可他总是一有机会就在这个问题上找我的茬儿,用一种看乡巴佬的眼色看我。我拼命克制,才没有在他白净的脸蛋上造出几块青色的小丘来。长时间的饱和工作使我的愤怒盎然。
### 一
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
我一下来了兴趣:随便说说吧,瞎说也成。
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
那么,你是电脑工程师喽?
咖啡端上来,杯子的颜色很典雅。老板坐到我的对面,递过来一整条圣罗兰。这也是我的习惯,我总在他这里买烟。
诗人和哲学家。
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
环顾四壁层垒的旧式书籍,童年时的梦想又涌上我的舌尖。那翻动书页的哗哗声是如此真切,我似乎回到了那些消耗在书本间的下午时光。也许正是这种感觉太悠长,才使我用尽全力企图抵挡时代的冲刷。
于是我不由自主地朝迎面而来的每一个人微笑,他们或者报以同样的微笑,更多的人都面无表情地躲开去。我知道我那时的样子和一个从精神病医院翻墙出来的人是多么相似,尽管电脑装有视觉护屏,但连续 40 小时的目不转睛仍使我眼眶下陷,双眼赤红,满脸洋溢着回光返照似的神采。
我苦笑。
是软件制造和销售,虚拟软件。
上个周一,本来下班后约好一起吃饭,小卷却出人意料地迟到了。我站在街边,看车来车往看了二十分钟,小卷才心不在焉地出现在我面前。不等我问她迟到的原因,她便开始向我抱怨路上塞车是多么厉害。
于是我默不作声地听她的抱怨,陪她吃晚饭,送她回家。回家的路上,她默默地说:我们就此分手吧。
公司又下达一项任务,设计部忙得不可开交。为了保住 4%的市场占有率,勉强养活自己,所有的人都必须拼尽全力。你只要看看 JACK 几天未换的西服和凌乱的头发,就能明白什么叫竞争。
咖啡馆在街角,一座老公寓的底楼。临街的窗开得很低,里面没多少人。推门进去时我看了一眼墙上的店徽——交叉的吉他和步枪,上面落满了灰尘,在阳光里无精打采。
多多少少。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
是软件制造和销售,虚拟软件。
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
街面儿很敞亮,暮春的阳光使整座城市看起来像姑娘的身体,富有弹性。满街的玉兰花都开了,花粉在空气中连续而轻微地爆炸,随着风迎面扑来。我站在铺着暗红色方砖的人行道上,贪婪地吸吮,感觉自己的肺被新鲜空气胀得无限大。眼睛因为无法适应刺眼的阳光而眯缝着。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
咖啡端上来,杯子的颜色很典雅。老板坐到我的对面,递过来一整条圣罗兰。这也是我的习惯,我总在他这里买烟。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
哪两种?
回到家里,我蒙头睡了两天,其间只吃了一顿饭,活似一只冬眠的熊。
我笑着点头,这是我每次来必喝的,我习惯于每天下班后到这里来喝一杯,听上一会儿音乐,把浮躁的心情慢慢沉淀下来。这是一个落伍的习惯,现在的时尚是去网上虚拟狂欢。
街面儿很敞亮,暮春的阳光使整座城市看起来像姑娘的身体,富有弹性。满街的玉兰花都开了,花粉在空气中连续而轻微地爆炸,随着风迎面扑来。我站在铺着暗红色方砖的人行道上,贪婪地吸吮,感觉自己的肺被新鲜空气胀得无限大。眼睛因为无法适应刺眼的阳光而眯缝着。
多多少少。
环顾四壁层垒的旧式书籍,童年时的梦想又涌上我的舌尖。那翻动书页的哗哗声是如此真切,我似乎回到了那些消耗在书本间的下午时光。也许正是这种感觉太悠长,才使我用尽全力企图抵挡时代的冲刷。
像你这样的人不多了。老板说。
不喜欢。
我在最角落的窗前坐下来,阳光透过玻璃落在黄白格子的桌布上。歌声还在荡漾:带我去看你的房间吧,像挪威的森林一样漂亮……
我面无表情地看完新闻,关机,走出大楼。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
拉开抽屉,所有的烟盒都空了,好像 FORMAT 后的软盘。
### 一
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
咖啡端上来,杯子的颜色很典雅。老板坐到我的对面,递过来一整条圣罗兰。这也是我的习惯,我总在他这里买烟。
像你这样的人不多了。老板说。
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
终于,我把手伸向虚拟程序的插口。
不喜欢。
我的眼眶突然像沼泽地一样潮湿起来。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
多多少少。
唱片到头了。老板歉意地笑笑,站起来去换 CD。
我抵挡不住了。
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
像你这样的人不多了。老板说。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
为什么?
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
指吸烟和喝咖啡吗?
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
唱片到头了。老板歉意地笑笑,站起来去换 CD。
### 三
是软件制造和销售,虚拟软件。
我的眼眶突然像沼泽地一样潮湿起来。
还有听古旧的音乐。
是软件制造和销售,虚拟软件。
小卷红着脸点点头:有过几次,我觉得和真的差不多。
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
你看呢?
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
不喜欢。
他一笑,年轻的脸上竟显出苍老来。问:你熬夜了吧,工作很忙?
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
### 二
我一下来了兴趣:随便说说吧,瞎说也成。
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
40 个小时没睡觉了,全靠咖啡和烟撑着。没法子,公司催得紧,这批活儿得在三天内完成,否则就落在别的公司后面了。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
他一笑,年轻的脸上竟显出苍老来。问:你熬夜了吧,工作很忙?
日落了,却再没人会写诗。我对自己说。
是网络公司吧,那么抢时间。
是网络公司吧,那么抢时间。
我在最角落的窗前坐下来,阳光透过玻璃落在黄白格子的桌布上。歌声还在荡漾:带我去看你的房间吧,像挪威的森林一样漂亮……
我一愣,反问:你呢?
街面儿很敞亮,暮春的阳光使整座城市看起来像姑娘的身体,富有弹性。满街的玉兰花都开了,花粉在空气中连续而轻微地爆炸,随着风迎面扑来。我站在铺着暗红色方砖的人行道上,贪婪地吸吮,感觉自己的肺被新鲜空气胀得无限大。眼睛因为无法适应刺眼的阳光而眯缝着。
日落了,却再没人会写诗。我对自己说。
是软件制造和销售,虚拟软件。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
### 一
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
天气开始热起来,到处是蝉儿嘶哑的鸣叫。觉得像是为我和小卷的爱情吟唱的挽歌。
那么,你是电脑工程师喽?
我的眼眶突然像沼泽地一样潮湿起来。
上个周一,本来下班后约好一起吃饭,小卷却出人意料地迟到了。我站在街边,看车来车往看了二十分钟,小卷才心不在焉地出现在我面前。不等我问她迟到的原因,她便开始向我抱怨路上塞车是多么厉害。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
我已经三天三夜没有睡过觉了。咖啡喝得我反胃,感觉自己就像一只掉进石油污染里的水鸟,满身油污,寸步难行。
是网络公司吧,那么抢时间。
你看呢?
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
环顾四壁层垒的旧式书籍,童年时的梦想又涌上我的舌尖。那翻动书页的哗哗声是如此真切,我似乎回到了那些消耗在书本间的下午时光。也许正是这种感觉太悠长,才使我用尽全力企图抵挡时代的冲刷。
他在阳光里偏过头,细细打量了阵儿,说:不像。
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
是网络公司吧,那么抢时间。
喝完咖啡,疲劳稍稍得到安抚,但远未被镇压下去。我急切地渴望一支香烟,渴望把自己淹没在袅袅的烟雾里,于是我到主管办公室去请假。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
天气开始热起来,到处是蝉儿嘶哑的鸣叫。觉得像是为我和小卷的爱情吟唱的挽歌。
为什么?
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
树叶在晚风里纷纷下坠,已经初秋了。
JACK 往椅背上一靠,嘴角朝左边斜了两厘米,微龇着牙,露出一种很 “优雅” 的笑。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
我一愣,反问:你呢?
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
木立良久,我转身走开去。身后,落满了灰尘的吉他和步枪黑乎乎的没有一点儿生气。
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
等养足精神,我便把那笔奖金全部提出,买了两张去夏威夷的机票,带上女友小卷度假去了。
诗人和哲学家。
以后的几天里,我始终精神恍惚。我已失去了对这个决定对错的判断力。像一头受伤的小野兽,我只顾躲在洞穴里舔着自己的伤口。我无力救赎他人,甚至也无力救赎自己,因为我根本不知道我的抵抗是不是徒劳。
我一下来了兴趣:随便说说吧,瞎说也成。
这期间,父亲久久地注视着我。最后他低下头,喃喃地说:要是觉得太累就放弃吧。网络虚拟也好,脉冲震颤器也好,都是我们自己创造出来的,我们是在和自己斗争,所以你永远找不到抵抗的神圣感。你我都只是一块礁石,而不是堤坝。
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
指吸烟和喝咖啡吗?
### 二
譬如,你走过商店橱窗时会仔细打量自己。一般来说,只有两种人喜欢观察镜像里的自我。
譬如,你走过商店橱窗时会仔细打量自己。一般来说,只有两种人喜欢观察镜像里的自我。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
回到家里,我蒙头睡了两天,其间只吃了一顿饭,活似一只冬眠的熊。
哪两种?
街面儿很敞亮,暮春的阳光使整座城市看起来像姑娘的身体,富有弹性。满街的玉兰花都开了,花粉在空气中连续而轻微地爆炸,随着风迎面扑来。我站在铺着暗红色方砖的人行道上,贪婪地吸吮,感觉自己的肺被新鲜空气胀得无限大。眼睛因为无法适应刺眼的阳光而眯缝着。
喝完咖啡,疲劳稍稍得到安抚,但远未被镇压下去。我急切地渴望一支香烟,渴望把自己淹没在袅袅的烟雾里,于是我到主管办公室去请假。
我一下来了兴趣:随便说说吧,瞎说也成。
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
诗人和哲学家。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
你看呢?
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
### 五
我笑着点头,这是我每次来必喝的,我习惯于每天下班后到这里来喝一杯,听上一会儿音乐,把浮躁的心情慢慢沉淀下来。这是一个落伍的习惯,现在的时尚是去网上虚拟狂欢。
有道理。我把烟摁灭。说来不怕你笑话,我曾经想做诗人来着,在大学里。我父母都是作家,从小受他们影响太大,以至于现在还改不过来。可是,你知道,时代变了,电脑虚拟一诞生,文学就完了。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
看在我已连续干了 40 个小时的份儿上,他以施舍者的姿态准了我两个小时假。
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
那么,你是电脑工程师喽?
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
你这样认为?
我依靠着脉冲震颤器撑过了第四天,完成全部的工作后,我忽然不经意地看到一则网络新闻:领航者公司的第二代智能电脑终于问世。它具有强大的想像衍生功能,可根据一个程序联想衍生出系列程序,它的诞生将可能导致大批程序设计员的失业。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
像你这样的人不多了。老板说。
我抵挡不住了。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
我在最角落的窗前坐下来,阳光透过玻璃落在黄白格子的桌布上。歌声还在荡漾:带我去看你的房间吧,像挪威的森林一样漂亮……
我苦笑。
咖啡端上来,杯子的颜色很典雅。老板坐到我的对面,递过来一整条圣罗兰。这也是我的习惯,我总在他这里买烟。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
多多少少。
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
### 一
### 五
为什么?
庆祝酒会上,JACK 使劲儿跟我套近乎。他拉着我把我介绍给几个和他一样的杂种,并亲热地说:这是我们自己人。我瞅着这几张一模一样的脸,他们的五官都消失了,只剩下几套西服空壳般支在那儿。厌恶感在我心中长成一株大树,我将杯里的马提尼一饮而尽,对 JACK 说:你愿意和一个傻瓜做自己人吗?他茫然地摇摇头。我拍拍他的肩:我也不愿意。
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
既然是哥们儿,就更得帮你,你的景况也不好。
譬如,你走过商店橱窗时会仔细打量自己。一般来说,只有两种人喜欢观察镜像里的自我。
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
### 四
以后的几天里,我始终精神恍惚。我已失去了对这个决定对错的判断力。像一头受伤的小野兽,我只顾躲在洞穴里舔着自己的伤口。我无力救赎他人,甚至也无力救赎自己,因为我根本不知道我的抵抗是不是徒劳。
也许——我没仔细思考过这个问题——虚拟程序固然荒谬,但是否也得算是文学在新的时代里的存在方式呢?
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
我抵挡不住了。
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
我一下来了兴趣:随便说说吧,瞎说也成。
咖啡端上来,杯子的颜色很典雅。老板坐到我的对面,递过来一整条圣罗兰。这也是我的习惯,我总在他这里买烟。
我苦笑。
我依靠着脉冲震颤器撑过了第四天,完成全部的工作后,我忽然不经意地看到一则网络新闻:领航者公司的第二代智能电脑终于问世。它具有强大的想像衍生功能,可根据一个程序联想衍生出系列程序,它的诞生将可能导致大批程序设计员的失业。
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
咖啡馆在街角,一座老公寓的底楼。临街的窗开得很低,里面没多少人。推门进去时我看了一眼墙上的店徽——交叉的吉他和步枪,上面落满了灰尘,在阳光里无精打采。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
我也曾这么想过,但那不过是自欺欺人罢了。你听说过有哪一头猪愿意以香肠的方式存在呢?
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
我抵挡不住了。
我的眼眶突然像沼泽地一样潮湿起来。
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
像你这样的人不多了。老板说。
唱片到头了。老板歉意地笑笑,站起来去换 CD。
这杂种今天穿着一件藏青色西服,衬衫松开顶上一颗纽扣,松松地系着一条蓝白相间的纱制围巾——今年最流行的白领装束。当他听说我请假的理由是出去买烟时,脸上惊讶的表情像是看到一只苍蝇在跳华尔兹。
终于,我把手伸向虚拟程序的插口。
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
哪两种?
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
树叶在晚风里纷纷下坠,已经初秋了。
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
喝完咖啡,疲劳稍稍得到安抚,但远未被镇压下去。我急切地渴望一支香烟,渴望把自己淹没在袅袅的烟雾里,于是我到主管办公室去请假。
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
### 五
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
日落了,却再没人会写诗。我对自己说。
我的眼眶突然像沼泽地一样潮湿起来。
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
回到家里,我蒙头睡了两天,其间只吃了一顿饭,活似一只冬眠的熊。
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
### 五
回到家里,我蒙头睡了两天,其间只吃了一顿饭,活似一只冬眠的熊。
既然是哥们儿,就更得帮你,你的景况也不好。
拉开抽屉,所有的烟盒都空了,好像 FORMAT 后的软盘。
### 三
树叶在晚风里纷纷下坠,已经初秋了。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
指吸烟和喝咖啡吗?
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
木立良久,我转身走开去。身后,落满了灰尘的吉他和步枪黑乎乎的没有一点儿生气。
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
这期间,父亲久久地注视着我。最后他低下头,喃喃地说:要是觉得太累就放弃吧。网络虚拟也好,脉冲震颤器也好,都是我们自己创造出来的,我们是在和自己斗争,所以你永远找不到抵抗的神圣感。你我都只是一块礁石,而不是堤坝。
我苦笑。
我把一张电子货币卡塞进他手里,里面还有 1500 单位电子货币,大约是我一周的薪水。
还有听古旧的音乐。
我已经三天三夜没有睡过觉了。咖啡喝得我反胃,感觉自己就像一只掉进石油污染里的水鸟,满身油污,寸步难行。
还有听古旧的音乐。
### 四
像你这样的人不多了。老板说。
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
回到家里,我蒙头睡了两天,其间只吃了一顿饭,活似一只冬眠的熊。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
老板看见我,很热情地打个招呼,不等我开口,便问:蓝山咖啡?
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
### 三
### 四
是软件制造和销售,虚拟软件。
拉开抽屉,所有的烟盒都空了,好像 FORMAT 后的软盘。
这杂种今天穿着一件藏青色西服,衬衫松开顶上一颗纽扣,松松地系着一条蓝白相间的纱制围巾——今年最流行的白领装束。当他听说我请假的理由是出去买烟时,脸上惊讶的表情像是看到一只苍蝇在跳华尔兹。
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
多多少少。
多多少少。
是软件制造和销售,虚拟软件。
他一笑,年轻的脸上竟显出苍老来。问:你熬夜了吧,工作很忙?
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
还有听古旧的音乐。
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
小卷红着脸点点头:有过几次,我觉得和真的差不多。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
庆祝酒会上,JACK 使劲儿跟我套近乎。他拉着我把我介绍给几个和他一样的杂种,并亲热地说:这是我们自己人。我瞅着这几张一模一样的脸,他们的五官都消失了,只剩下几套西服空壳般支在那儿。厌恶感在我心中长成一株大树,我将杯里的马提尼一饮而尽,对 JACK 说:你愿意和一个傻瓜做自己人吗?他茫然地摇摇头。我拍拍他的肩:我也不愿意。
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
我把一张电子货币卡塞进他手里,里面还有 1500 单位电子货币,大约是我一周的薪水。
那么,你是电脑工程师喽?
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
回到家里,我蒙头睡了两天,其间只吃了一顿饭,活似一只冬眠的熊。
我苦笑。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
我的眼眶突然像沼泽地一样潮湿起来。
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
等养足精神,我便把那笔奖金全部提出,买了两张去夏威夷的机票,带上女友小卷度假去了。
### 二
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
也许——我没仔细思考过这个问题——虚拟程序固然荒谬,但是否也得算是文学在新的时代里的存在方式呢?
### 五
庆祝酒会上,JACK 使劲儿跟我套近乎。他拉着我把我介绍给几个和他一样的杂种,并亲热地说:这是我们自己人。我瞅着这几张一模一样的脸,他们的五官都消失了,只剩下几套西服空壳般支在那儿。厌恶感在我心中长成一株大树,我将杯里的马提尼一饮而尽,对 JACK 说:你愿意和一个傻瓜做自己人吗?他茫然地摇摇头。我拍拍他的肩:我也不愿意。
环顾四壁层垒的旧式书籍,童年时的梦想又涌上我的舌尖。那翻动书页的哗哗声是如此真切,我似乎回到了那些消耗在书本间的下午时光。也许正是这种感觉太悠长,才使我用尽全力企图抵挡时代的冲刷。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
指吸烟和喝咖啡吗?
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
我抵挡不住了。
海滩上,我和小卷手拉手散步。湿软的沙子温柔地舔着我的脚趾缝,海风拥抱我的皮肤。小卷的笑声清脆如浪花轻拍岸边的礁石,我们惬意地嬉戏着,我再次有了种飘飘欲仙的感觉……
我把一张电子货币卡塞进他手里,里面还有 1500 单位电子货币,大约是我一周的薪水。
我一愣,反问:你呢?
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
### 二
上个周一,本来下班后约好一起吃饭,小卷却出人意料地迟到了。我站在街边,看车来车往看了二十分钟,小卷才心不在焉地出现在我面前。不等我问她迟到的原因,她便开始向我抱怨路上塞车是多么厉害。
环顾四壁层垒的旧式书籍,童年时的梦想又涌上我的舌尖。那翻动书页的哗哗声是如此真切,我似乎回到了那些消耗在书本间的下午时光。也许正是这种感觉太悠长,才使我用尽全力企图抵挡时代的冲刷。
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
小卷红着脸点点头:有过几次,我觉得和真的差不多。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
我端起杯子时,发现咖啡早已喝光了。一时间疲劳揭竿而起,迅速淹没了我。眼里仿佛被人塞进青橄榄一样生涩,电脑屏幕开始模糊,满屏的汉字像一群发酵的小馒头在跳舞。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
哪两种?
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
上个周一,本来下班后约好一起吃饭,小卷却出人意料地迟到了。我站在街边,看车来车往看了二十分钟,小卷才心不在焉地出现在我面前。不等我问她迟到的原因,她便开始向我抱怨路上塞车是多么厉害。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
是软件制造和销售,虚拟软件。
小卷红着脸点点头:有过几次,我觉得和真的差不多。
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
我觉得自己像是沉溺海水中,无力挣扎,快被窒息死了……
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
于是我不由自主地朝迎面而来的每一个人微笑,他们或者报以同样的微笑,更多的人都面无表情地躲开去。我知道我那时的样子和一个从精神病医院翻墙出来的人是多么相似,尽管电脑装有视觉护屏,但连续 40 小时的目不转睛仍使我眼眶下陷,双眼赤红,满脸洋溢着回光返照似的神采。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
我也曾这么想过,但那不过是自欺欺人罢了。你听说过有哪一头猪愿意以香肠的方式存在呢?
是网络公司吧,那么抢时间。
### 四
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
多多少少。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
我面无表情地看完新闻,关机,走出大楼。
天气开始热起来,到处是蝉儿嘶哑的鸣叫。觉得像是为我和小卷的爱情吟唱的挽歌。
我把一张电子货币卡塞进他手里,里面还有 1500 单位电子货币,大约是我一周的薪水。
终于,我把手伸向虚拟程序的插口。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
### 一
上个周一,本来下班后约好一起吃饭,小卷却出人意料地迟到了。我站在街边,看车来车往看了二十分钟,小卷才心不在焉地出现在我面前。不等我问她迟到的原因,她便开始向我抱怨路上塞车是多么厉害。
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
现实世界真是太落后了,与其费那么大劲儿吃顿晚饭,倒不如去网上做一次虚拟约会呢。她说。
小卷红着脸点点头:有过几次,我觉得和真的差不多。
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
我笑着点头,这是我每次来必喝的,我习惯于每天下班后到这里来喝一杯,听上一会儿音乐,把浮躁的心情慢慢沉淀下来。这是一个落伍的习惯,现在的时尚是去网上虚拟狂欢。
现实世界真是太落后了,与其费那么大劲儿吃顿晚饭,倒不如去网上做一次虚拟约会呢。她说。
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
诗人和哲学家。
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
这个傻蛋,我知道他在想什么。他早就清楚我从不使用震颤器,可他总是一有机会就在这个问题上找我的茬儿,用一种看乡巴佬的眼色看我。我拼命克制,才没有在他白净的脸蛋上造出几块青色的小丘来。长时间的饱和工作使我的愤怒盎然。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
我依靠着脉冲震颤器撑过了第四天,完成全部的工作后,我忽然不经意地看到一则网络新闻:领航者公司的第二代智能电脑终于问世。它具有强大的想像衍生功能,可根据一个程序联想衍生出系列程序,它的诞生将可能导致大批程序设计员的失业。
### 五
我沿着大街慢慢地走,一种无来由的快感使我有如失重,每一根神经都肿胀起来。使用了震颤器后是不是这种感觉,我不知道,但这和我时常坐在办公室里幻想自己抄一块板儿砖把 JACK 砸得血花怒放时的感觉很相似。
我在最角落的窗前坐下来,阳光透过玻璃落在黄白格子的桌布上。歌声还在荡漾:带我去看你的房间吧,像挪威的森林一样漂亮……
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
海滩上,我和小卷手拉手散步。湿软的沙子温柔地舔着我的脚趾缝,海风拥抱我的皮肤。小卷的笑声清脆如浪花轻拍岸边的礁石,我们惬意地嬉戏着,我再次有了种飘飘欲仙的感觉……
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
这个傻蛋,我知道他在想什么。他早就清楚我从不使用震颤器,可他总是一有机会就在这个问题上找我的茬儿,用一种看乡巴佬的眼色看我。我拼命克制,才没有在他白净的脸蛋上造出几块青色的小丘来。长时间的饱和工作使我的愤怒盎然。
于是我默不作声地听她的抱怨,陪她吃晚饭,送她回家。回家的路上,她默默地说:我们就此分手吧。
是网络公司吧,那么抢时间。
既然是哥们儿,就更得帮你,你的景况也不好。
公司又下达一项任务,设计部忙得不可开交。为了保住 4%的市场占有率,勉强养活自己,所有的人都必须拼尽全力。你只要看看 JACK 几天未换的西服和凌乱的头发,就能明白什么叫竞争。
你这样认为?
终于,我把手伸向虚拟程序的插口。
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
有道理。我把烟摁灭。说来不怕你笑话,我曾经想做诗人来着,在大学里。我父母都是作家,从小受他们影响太大,以至于现在还改不过来。可是,你知道,时代变了,电脑虚拟一诞生,文学就完了。
我的眼眶突然像沼泽地一样潮湿起来。
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
有道理。我把烟摁灭。说来不怕你笑话,我曾经想做诗人来着,在大学里。我父母都是作家,从小受他们影响太大,以至于现在还改不过来。可是,你知道,时代变了,电脑虚拟一诞生,文学就完了。
以后的几天里,我始终精神恍惚。我已失去了对这个决定对错的判断力。像一头受伤的小野兽,我只顾躲在洞穴里舔着自己的伤口。我无力救赎他人,甚至也无力救赎自己,因为我根本不知道我的抵抗是不是徒劳。
在喝了几乎一百加仑的咖啡后,终于把任务完成了。
也许——我没仔细思考过这个问题——虚拟程序固然荒谬,但是否也得算是文学在新的时代里的存在方式呢?
JACK 往椅背上一靠,嘴角朝左边斜了两厘米,微龇着牙,露出一种很 “优雅” 的笑。
看在我已连续干了 40 个小时的份儿上,他以施舍者的姿态准了我两个小时假。
为什么?
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
这杂种今天穿着一件藏青色西服,衬衫松开顶上一颗纽扣,松松地系着一条蓝白相间的纱制围巾——今年最流行的白领装束。当他听说我请假的理由是出去买烟时,脸上惊讶的表情像是看到一只苍蝇在跳华尔兹。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
我也曾这么想过,但那不过是自欺欺人罢了。你听说过有哪一头猪愿意以香肠的方式存在呢?
咖啡馆在街角,一座老公寓的底楼。临街的窗开得很低,里面没多少人。推门进去时我看了一眼墙上的店徽——交叉的吉他和步枪,上面落满了灰尘,在阳光里无精打采。
环顾四壁层垒的旧式书籍,童年时的梦想又涌上我的舌尖。那翻动书页的哗哗声是如此真切,我似乎回到了那些消耗在书本间的下午时光。也许正是这种感觉太悠长,才使我用尽全力企图抵挡时代的冲刷。
海滩上,我和小卷手拉手散步。湿软的沙子温柔地舔着我的脚趾缝,海风拥抱我的皮肤。小卷的笑声清脆如浪花轻拍岸边的礁石,我们惬意地嬉戏着,我再次有了种飘飘欲仙的感觉……
### 四
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
### 四
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
这期间,父亲久久地注视着我。最后他低下头,喃喃地说:要是觉得太累就放弃吧。网络虚拟也好,脉冲震颤器也好,都是我们自己创造出来的,我们是在和自己斗争,所以你永远找不到抵抗的神圣感。你我都只是一块礁石,而不是堤坝。
终于,我把手伸向虚拟程序的插口。
看到许许多多的音节从她红润的嘴唇里蹦出来,我忽然觉得周围的一切都离我远去,所有的车声、人声像隔着一层毛玻璃般听不真切。她的脸在真实的阳光里无比生动,但我分明感觉到了一种陌生。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
老音响唱着 BEATLES 的歌,是[《挪威的森林》](https://www.99csw.com/book/2539/index.htm),正和店名一样。这儿总是放一些几十年前的老歌,爵士或摇滚,最多的就是这首[《挪威的森林》](https://www.99csw.com/book/2539/index.htm)。
于是我默不作声地听她的抱怨,陪她吃晚饭,送她回家。回家的路上,她默默地说:我们就此分手吧。
### 五
像你这样的人不多了。老板说。
哪两种?
喝完咖啡,疲劳稍稍得到安抚,但远未被镇压下去。我急切地渴望一支香烟,渴望把自己淹没在袅袅的烟雾里,于是我到主管办公室去请假。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
公司又下达一项任务,设计部忙得不可开交。为了保住 4%的市场占有率,勉强养活自己,所有的人都必须拼尽全力。你只要看看 JACK 几天未换的西服和凌乱的头发,就能明白什么叫竞争。
我按下电钮,不一会儿,S-3 型服务机器人轱辘辘地滚进来,托着一杯速溶咖啡。这是为我设置的专门程序,整个设计部就我一个人喝咖啡,同事们都使用脉冲震颤器,这种小玩意儿能促使大脑产生多巴胺。自它出现后,毒品贩子都跳楼自杀了,烟草、咖啡的产量也连年下降。
多多少少。
回到家里吃完饭,母亲收拾盘碟,我和父亲则端着酒走进书房。
拉开抽屉,所有的烟盒都空了,好像 FORMAT 后的软盘。
多多少少。
我已经三天三夜没有睡过觉了。咖啡喝得我反胃,感觉自己就像一只掉进石油污染里的水鸟,满身油污,寸步难行。
记不请谁说的了,读书就是在别人的故事里旅行。但那是在书籍时代,而虚拟程序可以让你成为任何人,在任何地方旅行。你可以刚参加完二战,接着就和性感女星约会,沉溺在温柔乡里。谁还需要读小说?谁还需要写作?当然还剩下网上聊天,如果聊天也能称之为写作的话。你明白我的意思?
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
上个周一,本来下班后约好一起吃饭,小卷却出人意料地迟到了。我站在街边,看车来车往看了二十分钟,小卷才心不在焉地出现在我面前。不等我问她迟到的原因,她便开始向我抱怨路上塞车是多么厉害。
急不可待地拆开,抽出一支点上,深深吸一口。烟很清凉,咖啡很浓,一切都很好。
我抵挡不住了。
小卷红着脸点点头:有过几次,我觉得和真的差不多。
公司抢先一步把这批软件推向市场,销售业绩极佳。为此,我得到一笔数目不小的奖金,还被提升为副主管。
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
他一笑,年轻的脸上竟显出苍老来。问:你熬夜了吧,工作很忙?
终于,我把手伸向虚拟程序的插口。
有道理。我把烟摁灭。说来不怕你笑话,我曾经想做诗人来着,在大学里。我父母都是作家,从小受他们影响太大,以至于现在还改不过来。可是,你知道,时代变了,电脑虚拟一诞生,文学就完了。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
随后她仰起头来,冷冰冰地望着我。在她平静的目光里,我听到世界坍塌的声音。
### 五
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
海滩上,我和小卷手拉手散步。湿软的沙子温柔地舔着我的脚趾缝,海风拥抱我的皮肤。小卷的笑声清脆如浪花轻拍岸边的礁石,我们惬意地嬉戏着,我再次有了种飘飘欲仙的感觉……
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
天气开始热起来,到处是蝉儿嘶哑的鸣叫。觉得像是为我和小卷的爱情吟唱的挽歌。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
我也曾这么想过,但那不过是自欺欺人罢了。你听说过有哪一头猪愿意以香肠的方式存在呢?
在夏威夷临海的旅馆房间里,在斜阳余晖的阳台上,在正午海滩的遮阳伞下,我们疯狂地玩乐。我不知道为什么要这样做,我只是觉察到一种绝望正在腐蚀我,我只能通过这种方式来抵抗、挽留和拯救。
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
这个傻蛋,我知道他在想什么。他早就清楚我从不使用震颤器,可他总是一有机会就在这个问题上找我的茬儿,用一种看乡巴佬的眼色看我。我拼命克制,才没有在他白净的脸蛋上造出几块青色的小丘来。长时间的饱和工作使我的愤怒盎然。
你这样认为?
一天晚上,我们正坐在清凉的露天咖啡座里看月亮。小卷突然问我:你有没有尝试过在虚拟程式里和人做爱?
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
### 三
临走时我们互相拍了拍肩膀。我也不知道这代表或包含了什么,大概是两个跟不上趟的人在互相安慰吧。
我点点头,又点上一支烟。现在我是个掘墓工人,正在为埋葬文学贡献力量。这 40 个小时里,我在做莎士比亚系列,就是把老莎的剧本分解,序幕、高潮、结局都编成若干模块,用户可以任意组合,只要你愿意,你可以让朱丽叶死而复活,结婚生子,就是这么一回事。这就是我的工作,我把各式各样的文学拆散,写成软件工程师能轻易看懂的语句,然后由他们编程。我就像解牛的庖丁一样,把动物尸体剔骨去肉,肢解成块,交给机器制成香肠。
当我黑着脸,骂骂咧咧冲进电梯时,里面所有的人都露出一种看见吃人生番的表情。
于是我不由自主地朝迎面而来的每一个人微笑,他们或者报以同样的微笑,更多的人都面无表情地躲开去。我知道我那时的样子和一个从精神病医院翻墙出来的人是多么相似,尽管电脑装有视觉护屏,但连续 40 小时的目不转睛仍使我眼眶下陷,双眼赤红,满脸洋溢着回光返照似的神采。
我依靠着脉冲震颤器撑过了第四天,完成全部的工作后,我忽然不经意地看到一则网络新闻:领航者公司的第二代智能电脑终于问世。它具有强大的想像衍生功能,可根据一个程序联想衍生出系列程序,它的诞生将可能导致大批程序设计员的失业。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
### 四
突然间,我抑制不住地想像着小卷在虚拟环境里的所作所为。尽管我知道那是假的,可是嫉妒以及随之而来的愤怒伸出尖利的牙齿撕咬我:该死的网络!连我们仅存的这一点最后的真实也要夺走。
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
那么,你是电脑工程师喽?
我面无表情地看完新闻,关机,走出大楼。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
公司又下达一项任务,设计部忙得不可开交。为了保住 4%的市场占有率,勉强养活自己,所有的人都必须拼尽全力。你只要看看 JACK 几天未换的西服和凌乱的头发,就能明白什么叫竞争。
我需要一种真实让我安心,没办法,我是一个落伍的人,容忍不了虚拟。
木立良久,我转身走开去。身后,落满了灰尘的吉他和步枪黑乎乎的没有一点儿生气。
我已经三天三夜没有睡过觉了。咖啡喝得我反胃,感觉自己就像一只掉进石油污染里的水鸟,满身油污,寸步难行。
树叶在晚风里纷纷下坠,已经初秋了。
喝完咖啡,疲劳稍稍得到安抚,但远未被镇压下去。我急切地渴望一支香烟,渴望把自己淹没在袅袅的烟雾里,于是我到主管办公室去请假。
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
### 一
我憋足浑身的劲儿伸了一个悠长的懒腰。烟头躺在厚厚的灰堆上,像雪地里杂陈的尸体。如果能像死尸那样不分地点、不计时间的长眠该是一件多么甜美的事,我开始胡思乱想。
有一个比我强大无数倍的东西轻而易举地把她从我身边夺走了。它使她迷恋,使她沉溺,她已站在另一边,不愿再和我一起抵抗。
我沿街走到咖啡馆门前。门紧闭着,一张 “此房出租” 的招贴被风掀起一角,哗啦啦地响。
也许——我没仔细思考过这个问题——虚拟程序固然荒谬,但是否也得算是文学在新的时代里的存在方式呢?
### 三
这时我环顾四周,只有两个戴着眼镜的中年人在读旧式的书本。他们多像我父亲哪!忽然间我想不起我父亲的样子了,只觉得他和那两个中年人有着同样的脸——一本落满了灰尘的书,书名是[《荒原》](https://www.99csw.com/book/680/index.htm)。
为什么不用 SMALL BIRD(脉冲震颤器的昵称)?对,汉语里夹杂英文也是这类人的癖好。
项目主管是一个 “草瓶”0 这是我字典里的一个专用词,与“花瓶” 对应,专指那些永远西服革履、头发一丝不乱的小白脸儿。在网络界这类人我见得多了,他们目空一切,总以高级白领、社会精英自居。这种人阶层观念很强,对自己人永远笑脸相迎,如果他认定你是异类,那么你就只配看到他的屁股。
木立良久,我转身走开去。身后,落满了灰尘的吉他和步枪黑乎乎的没有一点儿生气。
歌声重又响起来,但咖啡已经凉了。我站起来要付帐,老板连忙说:烟和咖啡,今天算我请客。你,是哥们儿。
有道理。我把烟摁灭。说来不怕你笑话,我曾经想做诗人来着,在大学里。我父母都是作家,从小受他们影响太大,以至于现在还改不过来。可是,你知道,时代变了,电脑虚拟一诞生,文学就完了。
哪两种?
连接在我头上的脉冲器放射出一阵阵强烈的电波,我沉溺在头脑的幻像中,这景象是如此真实,以至于我的每一根神经都为之畅快地悸动。
天气开始热起来,到处是蝉儿嘶哑的鸣叫。觉得像是为我和小卷的爱情吟唱的挽歌。
阳光从西边斜射过来,给街区抹上一层金黄色的糖浆。
不喜欢。
多多少少。
听到我的话,他的神色有些黯然:自从有了电子脉冲震颤器,这儿就变成了这副模样。这条街上的咖啡和酒吧只剩下我这一家了。
是网络公司吧,那么抢时间。
可退出程序后,我却感到了落入深渊般的空虚,分外强烈。
日落了,却再没人会写诗。我对自己说。
既然是哥们儿,就更得帮你,你的景况也不好。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
那么,你是电脑工程师喽?
唱片到头了。老板歉意地笑笑,站起来去换 CD。
你的牛仔裤和 T 恤都旧了,你头发很乱,戴银制项链,那帮高级职员是不会这么打扮的。另外你身上还有一些东西,很隐秘,我说不好。
如果我在即将坠机的航班上睡着了-孔亚雷
========================
如果我在即将坠机的航班上睡着了-[[孔亚雷]]
-----
二十九岁那年,我决定去死。
我没有太多时间做准备。首先是请假。去死还要请假?你一定觉得奇怪——毕竟是去死,不是去度假。但我有我的理由:我希望让一切看起来像个意外。辞职太麻烦,擅自离职又太惹人注目。于是我对空乘主管——我是名空姐——说最近身体很不舒服,需要休年休假。然后去银行取出所有存款——总共九万多一点,全都匿名捐给了“流浪小动物保护协会”。房租已经付到年底。房间里真正属于我的东西并不多。没有电脑没有电视机。只有衣橱里的几件衣服,简易书架上的书、CD、日记本和相册,墙上挂的一幅宜家买的黑白摄影作品,以及一些琐碎的日常用品。第二天我花了一天时间,一边听巴赫的钢琴曲,一边整理这些私人物品。衣服都整整齐齐地塞入纸箱扔掉,昂贵的香水、口红和化妆品也一并丢进垃圾桶。除了一本《小王子》,其余的书和CD都捐给社区的公共图书馆。日记本和相册从头到尾细细看了一遍,然后烧掉。接着大扫除。卫生搞完后,整个房间变得洁净而明亮:空空荡荡,几乎没什么家具,地板擦得一尘不染,新换上的白色亚麻床单散发出好闻的太阳的味道。我冲了淋浴,泡了绿茶,光脚在地板上侧身躺下。躺下后世界好像变得跟站立时有所不同。地板似乎在向四周伸展,而我在慢慢缩小。闭上眼睛,能听见公寓楼里其他住户发出的各种声响:炒菜声,电视声,不断重复的钢琴练习曲,婴儿的啼哭声。那些声音微弱而清晰,仿佛来自遥远的另一个世界。空气里荡漾着初秋傍晚所特有的凉爽而微妙的气息。我深深地吸了一口气。
好了,我在心里对自己说,接下来要做的,就是静静等待那一刻的来临。
我又看了一遍《小王子》。百看不厌。事实上,我大概已经看了二千遍。我第一次看它是在十三岁那年。那年五月。我之所以记得这么清楚是因为就在那时我来了初潮。血量多得惊人。我一边读《小王子》一边不停地流血。血像自来水一样源源不断地从我体内流出来。并不太痛,只是血停不下来——就好像流的是别人的血。我无法想象自己小小的身体里会有那么多血可流。这样流下去,我不禁想,我大概活不到六一儿童节。
这让我很难过。六一儿童节是一年中我最开心的日子,因为那天父亲会让我在书店里随便买自己喜欢的书。于是,好像光流血还不够,我又开始流泪。为自己活不到六一儿童节,也为书中消失的小王子。我觉得我就是小王子,不,也许应该叫小公主。跟小王子一样,我也来自遥远的另一个星球。否则为什么我会流这么多血,为什么我会看见别人看不见的东西?找不到比这更好的解释。和小王子一样,我来自另外一个世界。我不属于这里。
我不属于这里。
每次发作之后,我就会涌起这样的念头。“发作”这个词或许不太恰当,但那确实像一种病。就像羊颠疯。毫无征兆,突如其来,你完全无法控制。你无法不看见那些画面,哪怕使劲闭上眼睛也不行。而且,跟发病一样,它伴随着各种生理上的不适:头痛得像要裂成几瓣,浑身发冷,瑟瑟发抖,恶心,想吐又吐不出来,内衣被汗水湿透,人虚脱得仿佛马上就要昏死过去。
我不属于这里,我在心里说。
可是——那么——我又属于哪里呢?
我不知道。我不知道我属于哪里。我不知道为什么会这样。从记事起,我的脑海中便不时闪现出各种灾难图像,而且不久之后,那些图像就会变成现实。一开始我以为那很正常,我以为每个人都能看见我看见的东西——既然我们记得过去发生的事,我们自然也记得将来发生的事,不是吗?(在五六岁的我看来,过去和将来是一回事。)我唯一不能理解的是,为什么将来让我们记住的统统都是坏事?但有一天我突然意识到:别人看不见那些东西!只有我能看见。从震惊到恐惧到不知所措,最后那渐渐变成一种日常的折磨。我找不到任何人可以一起分担我的秘密。没人会相信我,我知道。他们会把我当成怪物,当成女巫,说不定他们还会把我吊起来烧死(我在一本书上看到过)。我也想过去医院。但我该对医生怎么说呢?说我能预知未来?(哦,不过仅限于灾难。)说我能看见未来将要发生的灾难?我恐怕会直接被送进精神病院。去医院只会自讨苦吃。没人会相信我。没人。
上大学时特意去最大的国家图书馆查过资料。这方面的书不多。大都是一些奇闻逸事,天知道是真是假。比如据说中世纪有个叫拉姆斯丹的预言家写了本预言诗集,预言了包括1929年经济大萧条和二战在内的许多世界大事。还有本书上说20世纪60年代有个美国人自称是来自未来——2015年——的时间旅行者,他不仅准确地预言了很多重大历史事件(比如肯尼迪将被刺杀),还在股票市场上大赚了一笔,而后神秘失踪。但我显然既不是预言家也不是时间旅行者。我说过,我的预言仅限于灾难。灾难。从某人跌断腿到某幢大楼起火,从车祸到地震到火车脱轨,各种各样形形色色大大小小的灾难。仅限于灾难。既不能提前预知考试题目,也猜不中彩票号码。准确地说,那甚至都算不上是预言。因为我完全是被动的。就像我脑袋里有一台类似电视机那样的接收器,会随机接收到一些发自未来的特定频率的电波。
灾难接收器。
我在图书馆找到的唯一有意思一点的东西是关于泰坦尼克号的预言。据说在泰坦尼克号失事前,有许多人以各种形式预言了灾难的发生。最多的是通过做梦(一名富商因为接连几天梦见沉船而放弃了好不容易托关系才买到的首航船票,从而逃过一劫);而一个名叫麦克唐纳的工程师则因为有一种将会发生什么的“非常强烈的感觉”(这是书上的原话),三次拒绝到泰坦尼克号第二工程师的岗位签到,最后公司只好找人接替他(当然,那个接替者被淹死了)。但在所有这些预言中最有名的是一本小说。这本叫《徒劳》的小说出版于1898年——泰坦尼克号失事前的十四年,写的是一艘超级豪华邮轮因为撞上冰山而沉没的故事,从船只规模到航行路线到失事原因,小说里描绘的情况几乎跟后来的泰坦尼克号如出一辙,连船名也几乎一样(小说中的船叫泰坦号),因此这部本来无人问津的小说一时成为人们争相购买的超级预言小说,但奇怪的是,小说的作者摩根·罗伯逊却在这之后不久自杀身亡。是因为他为自己虚构的灾难成真而有负罪感,或者他真的有某种预言能力(就像我一样)?
没人知道。
我合上书页,闭上眼睛,轻轻叹息一声。
没人知道。虽然说法很多(说法很多意味着没有一个说法站得住脚)。有人认为是时间折射(就像光线折射一样,未来发生的场景被折射到现在),有人说是特异功能,也有人说摩根·罗伯逊是外星人。难道我真的是外星人?
就算我真的是外星人,我也不知道自己来自哪里——他们没有联系我。
当然,也可能是联系不上。
我睁开眼睛。图书馆里很安静。安静得仿佛能听见窗口洒进的阳光光束里尘埃飘舞的声音。我看着那些尘埃。我能闻到图书馆所特有的气味。我很熟悉那种气味。那是许多许多许多书待在一起的气味。我从小就喜欢图书馆。图书馆是这个世界上为数不多的让我觉得有安全感的地方。我喜欢被层层叠叠的书本包围着的感觉,就像藏进了一座坚实的城堡。
我一直喜欢看书。从小到大,我的图书馆借书卡总是填得满满的。面对脑子里时不时发作的灾难接收器,书是我唯一的安慰,也是我最好的朋友。我一有空就看书。但基本上只看厚墩墩的砖头似的19世纪外国古典小说。狄更斯。雨果。艾略特。托尔斯泰。这些书里散发着某种令人欣慰的平衡感,那里面有另一个世界,另一个实实在在的世界,那个世界甚至比这个所谓的现实世界更坚固(至少对我来说是这样)。那个世界部分地抵消了我在这个世界的不安、恐惧和焦虑。那个世界就像我的避难所。书成了我的必备药。我的包里——从书包到挎包到带滑轮拖杆的空姐行李包——总是放着两本书:一本是看了一半的大部头外国小说,一本是《小王子》。
不知幸还是不幸,十三岁那年我没有死于失血过多。一周后血戛然而止,就像谁随手关掉了水龙头。我顺利活到了六一儿童节,并在书店买了一本新的《小王子》(我最初看的那本是从图书馆借的)。我从此迷上了圣埃克絮佩里。我四处搜集有关圣埃克絮佩里的一切。因为圣埃克絮佩里,我也爱上了飞行。我不顾家人反对考上了航空学院(他们希望我学经济),大学毕业后本来想去考飞行员,但那时不招收女飞行员,所以只好做了空姐(无论如何我都想做跟飞行有关的工作)。无论是中学、大学,还是工作以后,我都几乎没有朋友——不,更确切地说,是没有真正的朋友,事实上,我走到哪里人缘都很好,原因很简单:我不跟任何人抢任何东西,我总是面带微笑,不张扬,很少交际,就像个淡淡的安静的影子。业余时间大多躲在房间里看书。不看电视,也从不上网(我讨厌任何带荧幕的东西)。房间里我待得最多的地方是阳台窗下的沙发。一有空我就蜷在沙发里看书。书怎么看都看不腻。《战争与和平》看了两遍,《悲惨世界》看了三遍,《米德尔·马契》看了五遍。除了圣埃克絮佩里,我几乎不看其他20世纪作家的小说。我曾经试过,但无法忍受,在我看来,那些现代作品就像只有三条腿的椅子,根本没法让人安心踏实地坐下去。但圣埃克絮佩里不一样,他会带你去飞翔。自由自在地飞翔,脱离地球的控制,从高空中观察小小的可笑的人类。他甚至死于飞翔。1944年7月31日,他在驾机外出执行任务时失踪。没有尸体,没有飞机残骸,没有通话记录。什么都没有。没人知道为什么,没人知道发生了什么事,那成了一个不解之谜。他和飞机一起悄悄地消失了——就像小王子那样。
电话响了。我过了一会儿才意识到那是电话。我合上书本。也许是外星人打来的,我想,他们要求我继续留在地球,而我将坚决拒绝。当然——不是。来电显示是他——我前男友——的号码。我犹豫了一会儿要不要接。我想静静地度过最后一个夜晚。电话还在响。不屈不挠,就像某种贴着墙壁飞快生长的藤蔓植物。我眼前浮现出他那孩子气的笑容。我按下通话键。但就在我按下的同时他挂断了。我愣了一下,随即松了口气。我实在不知道该说些什么。这样也好,我放下电话,这样更好。
我跟两个男人上过床。一个是飞行员,一个是他。飞行员是我同事,比我大十五岁,长得有点像加里·库珀,是个有妇之夫。我们的第一次——同时也是我的第一次——发生在波音747的驾驶舱里。那是冬天,停机坪的地面上铺着一层薄薄的积雪,雪在夜晚灯光的照射下闪闪发亮。空无一人的机舱感觉非常奇妙,让人想到整洁的废墟。我们走进驾驶舱,他打开所有的仪表灯。我们在绿色的荧光里静静地做爱。我们平均每个月见一两次。听古典音乐会,去各种风味餐厅吃饭,在高级宾馆开房间。他颇有情趣,是个美食家,喜欢玩点浪漫,而且,正如许多有经验的男人那样,他很有耐心——无论是在床上还是在别的什么地方。我们相处得很愉快。我从未想过要和他结婚。那与其说是恋爱,不如说更像某种配合默契的搭档。我们像那样交往了大概有两年。之后他被调去了另一个城市(不知为什么,对此我们俩似乎都松了口气)。最后一次见面时我们在一家有名的法国餐厅吃了饭,点了菜单上最贵的葡萄酒。
“我说——你是不是有什么事瞒着我们?”吃到一半时他说。他晃了晃杯中的葡萄酒,浅浅地喝了一口。
我没有回答。
他放下酒杯,微笑着摇了摇头,“没什么,只是一种感觉。总觉得你不太像这个年纪的女孩。怎么说呢,你好像——好像对什么都提不起热情,对什么都无所谓。”
我们沉默了一会儿。他似乎还想说什么,但最终没说。
是的,我的确有事瞒着你们,我在心里说。有几次我差点开口告诉他我那噩梦般的能力(如果那也算能力的话),但每次话到嘴边就消失了,就变成了嘴角的微笑,变成了无声的叹息,变成了冬天呼出的一团白气。那些话无法凝固成形。从小就这样。我有无数次想把脑子里看到的事情告诉父母,告诉同桌的小伙伴。但我始终没说。那类似于某种本能。这种事最好谁也别说,有个声音对我说。时间一长,渐渐地,别的事情我也懒得说了。我的倾诉欲望不知不觉中消失了,就像退化的味蕾。无论什么感受——快乐,痛苦,紧张,向往,无论什么——我都不会表露出来,事实上,也无法表露(即使有时想表露)。
所以他会觉得我对什么都无所谓。所以大家都觉得我脾气好,温柔。所以我看上去总是那么平静,那么自足。所以甚至有人开玩笑说我像佛。
也许那只是因为我对这个世界厌倦了。是的,厌倦。我觉得很累。我对什么都提不起兴趣。对我来说,这个世界的灾难太多了。对于大多数人,那些灾难只存在于报纸和电视里。但对于我,它们却像闪电一样接连不断地打进我的身体。而且,更要命的是,我虽然知道灾难即将发生,但却完全无能为力。我什么都做不了。既不能告诉别人,也不能动手阻止——根本阻止不了。只能眼睁睁地看着灾难发生。
你无法理解那种感觉。有时候那甚至会让我有一种罪恶感,就好像那些灾难是因为我而发生的。我完全理解为什么摩根·罗伯逊要自杀。
电话铃又响了。
一。二。三。四。五。响到第六声时我拔掉插头。他——我的前男友——大概又喝多了。他一喝多就会不停给我打电话。我们是在一个同事的生日聚会上认识的。他一看就是那种营养和教养都过于良好的富家子弟,开宝马Z4,穿范思哲,娃娃脸,皮肤白皙,很喜欢笑,笑起来像孩子一样灿烂,看到他的笑你就会明白在这世界上他没有任何事情可以烦恼。事实上也的确没有。即使有也很少很少,少到让他觉得珍贵——比如说我。我也许是他在这座星球上唯一的烦恼。他父亲是哪个大集团的总裁,家里钱多得吓人。据我所知,公司里几乎所有的单身空姐都想做他的女朋友。除了我。但他却偏偏选了我。
“你到底喜欢我什么?”有次我问他。
他歪头想了半天。“镇定。”他说。
镇定?
“噢。”我摸摸他的头。镇定。
我们第四次约会时睡了觉。在我住的地方。让我吃惊的是,他居然是第一次。
“这方面家教很严。”他说,“从小就教育,说容易被人骗家产。”
“那不怕被我骗?”
“不怕——”他脱口而出,“你好像什么都不想要。”
“所以你就放心了。”
听我这么一说,他的脸刷地红了,“不是,其实……”
我笑起来。“没关系,”我亲亲他的额头,“是也没关系。”
我喜欢他脸红的样子,喜欢他笑的样子。但我并不怎么喜欢他的跑车和钱。实际上当初我答应跟他约会的原因之一就是为了避免尴尬。我实在受不了他每天开着银闪闪的跑车和一大捧玫瑰在公司门口等我。我对他说要想见我就先换辆车。
“没问题。”他说,“什么车都有。陆虎还是法拉利?”
“不不,越普通越好。”
第二天他开来一辆大众高尔夫。那是他家保姆买菜的车。“我逼她跟我换了一辆。”他笑嘻嘻地说。
就是这么一个人。温柔,善良,孩子气,整天乐呵呵的,不知忧愁为何物。你很难不喜欢他。说实话,我没见过比他更纯真的人。纯真得简直有点可笑。他就像活在童话世界。一个是童话王国的纯真王子,一个是受过诅咒、会预知灾难的邪恶公主,不错的组合,不是吗?就像格林童话,经过重重奇遇和历险,公主被解除了诅咒,“最终王子和公主结婚了,他们从此过上了幸福的生活”。
但那有可能吗?像个正常人那样,结婚,生孩子,做家务,照顾家人,度过平凡而又充实的每一天,什么都不用多想,什么都不会看到——无论什么时候有什么灾难在什么地方发生。那有可能吗?我——至少曾经——抱着一丝希望。不是有一种说法吗,女人的很多毛病会在生完孩子后不治而愈。说不定我的那种“能力”也会因为分娩而消失。说不定拥有一个自己的孩子会或多或少地改变我的人生:至少,我会找到一个可以全心全意去爱的人,一个愿意为他(或她)付出一切的人,一个完全是因为我而来到这个世界的人——这会让我觉得,我也是因为他(或她)而来到这个世界的。
说不定,我可以重新开始。
所以,当我确认自己怀孕的时候,我并没有惊慌。那是我们认识之后六个月。在去看电影的路上,我轻描淡写地跟他说了。
“真的?”
“真的。”
他愣在那里。连宝马Z4也愣住了(大众高尔夫早就被保姆要回去了)。红灯变绿后好半天,后边车不停地按喇叭,他才反应过来。
“你不用担心,”我说,“我们对你的家产不感兴趣。你不一定非要娶我,我一个人也能养孩子。”我停顿一下,然后又补充一句,“不管怎样我都要把他生下来。”
不出所料,他脸又红了。“胡说!”他笑着看了我一眼,“我高兴都来不及——我昨天还在想该怎么向你求婚呢。太好了!”他拍了拍方向盘,又看看我的肚子,“太好了!”
电影院里他从头到尾都紧紧握着我的手。
第二天他就带了一颗硕大——足有小鸟蛋那么大——的钻石戒指来向我求婚。他父母比我想象的要开明,我们一起吃了顿饭(之前我已经在他家的家族聚会上见过他们几次),他们对这门婚事毫无异议,而且似乎很高兴(至少看上去很高兴)。我们拟定了大致的婚礼日期(一个月后)。我们飞去巴黎拍了婚纱照。我们决定在他家的海边度假别墅举行一个户外的派对式婚礼。我们甚至开始想孩子的名字。
但我的妊娠反应很强烈。如果把强烈程度分成十级的话,那我就是九点九级。几乎吃不下任何东西,一吃就吐。睡眠不好,常常被噩梦惊醒。更糟糕的是,我脑袋里的灾难接收器似乎因为强烈的妊娠反应而变得更灵敏了,几乎每天都要“发作”。越发作妊娠反应就越厉害;妊娠反应越厉害就越容易发作。恶性循环。那些可怕血腥的灾难画面像电脑程序自动输入一样源源不断地输入我的视网膜。
也许等把孩子生下来就好了,我安慰自己,或者干脆说,我骗自己。
我请了假,搬到他家城郊的别墅静养,由一个阿姨专门照顾我。他们全家都很忙,他刚刚接手一个家族企业,经常好几天才见上一面。我成天一个人待在空荡荡的大房子里,散步,看书,发作,呕吐。
不管怎样我都要把他(或者她)生下来。我下定决心。不管怎样。这是我唯一的机会。
但很显然,上帝——或者外星人,或者不管是谁——不想给我这个机会。
婚礼前两天,我去医院做孕期三个月的例行检查。检查结束后护士说请我去一下医生的办公室,医生要见我。医生要见我?我的心突然狂跳起来。我有种不祥的预感。我本来就已经很虚弱,我闭上眼睛,感觉自己马上就要昏过去。我站在那里,一只手扶住桌角,另一只手放在肚子上,才三个月,肚子几乎还看不出来,但我已经能感觉到他(或者她)的存在。我轻轻托住肚子,担心他(或者她)会被我剧烈的心跳震出来。
不要紧吧?护士搀扶住我。
我睁开眼睛,微笑着朝她摇摇头。她也笑了笑,笑得比哭还难看。
我在医生对面坐下。我的心跳得不再那么厉害了,事实上,我感觉它已经不跳了,它就像个被击毙在跑道上的短跑运动员。
他放下手里的B超片。“最近情绪怎么样?”他问。
我没有回答,我只是看着他。
“有没有什么剧烈的情绪起伏,或者见过什么特别可怕的场面?”
我没有回答。
他又开始低头看手里的片子。“发生这种情况的原因很多。”他对着片子说,“先天的基因缺失。剧烈的情绪震荡。精神打击。都有可能。”
我什么都没说。我只是看着他。
他沉默了一会儿,然后艰难地抬起头,接住我的目光。“你没有选择。”他说,“胎儿畸形。越早处理越好。可以马上安排手术。”
我什么都没说。
“手术后好好休养,”他开始移动鼠标,在电脑上开单子,“不要太难过,你还年轻,还有机会。”打印机开始咯吱咯吱地工作。
一切都安排好之后,他问我还有没有什么要求。
“我想看看那张片子。”我说。
当然,我没有好好休养。我不想好好休养。根本没必要好好休养。不,我心里很清楚,我已经没有机会了。我回到别墅,整理好东西,留了封短信,然后离开。我没有告诉男友——未婚夫——真正的原因。我只说我打掉了孩子。我能怎么说呢?说我怀了个怪胎?说那是因为我能预言灾难?我回到自己的小公寓,拔掉电话插头,睡了一天一夜,第二天起床上班——我急切地想回到天上去。
我又看了好几遍《小王子》。一个字一个字地看。
之后一天晚上我接到他的电话。他喝多了,我静静地听着
他在电话里冲我大吼。是你杀了他!他叫道,你杀了自己的孩子!你也杀了我!你谁也不爱!你不是人!你是个魔鬼!
我挂了电话。
你没有选择。他说。
我没有选择。
是的,我谁也不爱。
因为我没法爱。
我根本不知道什么叫爱。
爱?
不错,我喜欢他,也喜欢飞行员,但那只是喜欢,就跟喜欢喝冰镇啤酒和喜欢吃芒果一样的喜欢。那不是爱。
爱。
到底什么是爱呢?《小王子》里的那只狐狸把那叫作“驯养”。“对我而言,你只不过是个小男孩,”狐狸对小王子说,“就像其他千万个小男孩一样。我不需要你,你也同样用不着我。对你来说,我也不过是只狐狸,就跟其他千万只狐狸一样。然而,如果你驯养我,我们将会彼此需要,对我而言,你将是宇宙间唯一的,而我对你来说,也是世界上唯一的。”
彼此需要。可我不觉得自己需要谁。我什么都不想要。这不正常。这与这个时代背道而驰。但这不能怪我——我也不想这样。我没有选择。
我也感觉不到在这个世界上有谁真正需要我。谁会认为对他来说我是宇宙间唯一的呢?没有。飞行员有他的家庭。英俊的富家公子有成打的候选女朋友。爸妈有弟弟。我不怪他们偏心,换成我我也会更喜欢弟弟,他从小就聪明伶俐,人见人爱。(谁会喜欢一个整天板着脸戴着厚眼镜,沉默寡言只顾埋头看书的小女孩呢?)所以,即使我从这个世界消失了,他们至少还有一个各方面都比我更出色的儿子——他去年刚从英国留学回来,在北京一家外资银行做投资顾问。
不,不对,我好像遗漏了什么。什么小而重要的东西。
是黑皮。
黑皮是一只小狗。我是一次半夜回家时——我刚飞完蒙特利尔的国际航班,那时我才跟男友分手不久——在小区外的路口捡到它的。它靠着路灯柱缩成一团,身体不停地颤抖,我蹲下来抚摸它的时候,它抬起头用晶亮的眼神看着我,用湿湿的舌头舔我的手指。我把它带回家。是只黑色短毛杂种狗,大概只有三四个月大,右边的后腿有点瘸,不知道是摔的还是被人打的。我给它洗澡,喂它牛奶,给它吃冰箱里剩下的面包——它一边吃一边摇尾巴。我给它起名叫黑皮,英语Happy——高兴的意思——的谐音,因为它有身黑亮的皮毛,也因为它总是一副愁眉苦脸的表情,好像在思考什么重要的哲学难题。
我们一起度过了一段快乐的时光。我们一起散步,做游戏,聊天——当然,主要是我在说(它偶尔会叫两声)。我对它说自己飞去的城市,说最近在看的小说,我甚至给它朗读《小王子》。我这辈子其他时候说的话加起来大概也没那几个月说得多。我们总是坐在窗下的棉布沙发上。我一边说话一边抚摸它。不管我说什么,它都会一动不动地把小脑袋搁在我的大腿上,若有所思地听着,偶尔还翻起眼睛看我一眼。我打赌它听得懂。它什么都听得懂(而且只会比人类懂得更多)。我对它说自己脑中的灾难接收器,对它说那是如何的折磨,如何的痛苦,如何的绝望。能说出来让我觉得轻松了许多(就好像胸口有个硬块在慢慢融化),更何况我知道它——只有它——完全地百分百地相信我,理解我。好几次发作时我把它紧紧搂在怀里。
我想我“驯养”了它。就像小王子驯养了狐狸那样。当然,它同样也“驯养”了我。我们彼此需要。那是我第一次感觉到自己真真正正地被什么东西所需要。那大概就是爱——我猜。对黑皮来说,我是世界上唯一的人类;而对我来说,黑皮是宇宙间唯一的小狗。一下班我就急着往家赶,因为我知道黑皮在等我。而刚走到楼下(我住在四楼),就能听到它叫唤着扑打门的声音——简直像心灵感应——真是神奇,每次我都感叹,那么远,它怎么会知道是我呢?
如果黑皮还在,我大概不会做出今天这样的决定。至少我会犹豫不决。我死了黑皮怎么办?它会不会饿死?它会不会又变成街头的流浪狗?会不会有人欺负它?为了它我大概会继续活下去。只要它活着,我也就要活着。
但是它死了。
是被小区放的强力鼠药毒死的。晚上出去散步时误食了。之后一周我不知如何是好。我主动要求加班,替人顶班,飞最长最苦的国际航线。我觉得胸口空荡荡的,仿佛心脏被人掏走了,我经常有一种感觉:我已经死了。不,比死还糟,死意味着解脱,意味着失去一切,一切——无论好坏。而我呢,我不死不
活,我失去了一切好的,留下了一切坏的。
我看了看时间。晚上十点。该睡觉了,明天还要早起。我不想睡眠不足昏头昏脑地去死。这将是我在地球上的最后一夜。最后一夜。听上去甚至有点浪漫,不是吗?或许我们应该稍稍庆祝一下?我似乎又看见黑皮晶亮的眼睛和摇晃的尾巴。我想起厨房柜子里还有一瓶干邑白兰地(飞行员从外地寄来的生日礼物)。我给自己倒了一杯,和那本《小王子》一起放到床头柜上。跟往常一样,我想在睡前读会儿书。
我一边喝白兰地一边看《小王子》的最后几页。
“我会像是死去的样子,但那不是真的……”小王子说,“你明白,路很远。我不能带着这副身躯走。它太重了。……但是,这就好像剥落的旧树皮一样。旧树皮,并没有什么可悲的。”
我停下来喝了口白兰地。我感觉着酒液经过舌头,滑下喉咙,进入我体内。是的,并没有什么可悲的。不过是旧树皮而已。明天晚上我会在哪里呢?像小王子那样,回到真正属于自己的星球?或者从此消失,再也没有所谓的我?也许我会在天堂(或者地狱)遇见黑皮。不过,这些都不重要,重要的是先要离开这里。离开这个充满血腥和灾难(尤其是对于我)的星球。以后的事以后再说——当然,如果还有以后的话。当务之急是离开。这里已经没有任何让我留恋的东西。我已经看完了所有的托尔斯泰。我品尝过性和美食。我去过世界各地。我谁也不爱。因为我无法爱——除了死掉的黑皮。
我没有选择。
我合上《小王子》,放松身体,坐在床上静静地发了会儿呆。我既不恐惧,也不悲伤。为什么?也许是因为多年来我一直想着自杀。几乎每次发作后我都会涌起自杀的念头。我并不怕死。我甚至对死有一种强烈的向往。那是从上大学时开始的(大概就在看了摩根·罗伯逊的故事之后)。有一天我突然意识到自己可以去死。就像摩根·罗伯逊那样。我似乎在一瞬间长大了。我突然意识到,即使我什么都做不了,但至少我还可以去死。我仿佛突然发现了一件秘密武器。死。死将战胜一切。这让我感到一丝安慰和自信。这甚至让我觉得有了继续在这个世界活下去的理由,因为我随时可以去死。听起来很荒谬,但的确可以说,死给了我活下去的力量。你甚至可以说,死给了我们活下去的力量。想想看,如果没有死,如果连死也不行,我们的生活必将更加绝望,更加难以忍受。我不理解为什么有许多宗教禁止自杀。在我看来,自杀是上天赐予人类的一件礼物。自杀赋予生命一种尊严,一种力量,一种自由。不是吗?小王子就是自杀的(他主动让毒蛇咬他的脚)。而且我几乎可以断定——尤其是现在,这一刻——圣埃克絮佩里也是自杀的。他故意把飞机开到一个偏僻的山谷(或海域),一头撞向高耸的山峰(或无边的海面)。我几乎能切身感受到他那一刻的幸福。死于飞翔的幸福。我想象不出还有比那更好的死法。
所以死不是问题,问题是怎样去死。我设想过各种各样的死法。像电影里那样对着太阳穴来一枪?我没有枪,也不知道到哪儿能搞到枪(有我也不会用)。割脉?太慢,而且很可能流了半天血还没死成。上吊太难看。卧轨或者跳楼?我不想叫别人去收集自己四分五裂血肉模糊的肢体。总之,一想到自己的尸体会被人发现,我就觉得无法忍受。另外,还有一点,如果我突然自杀的话,那些认识我的人——同事,朋友——以及家人和亲戚会怎么想呢?肯定会觉得难以接受(为什么这样一个性格温婉的女孩竟然会自杀呢?),有人会伤心,有人会好奇,有人会胡乱猜测,有人会散布谣言,结果势必弄得纷纷扰扰不得安宁。你甚至指望不了一个正常的葬礼。不,我不愿那样。我宁愿活着也不愿那样。
所以我一直活到今天。
但明天一切都将结束。或者说开始。一回事。明天。我把杯里的酒喝光,不再多想。我下床漱口,用冷水洗脸。然后调好闹钟,关灯睡觉。
但睡不着。脑袋很清醒。我静静地躺在黑暗中。清空所有往事,就像拔掉塞子放光水槽里的水。不知道过了多久。我觉得我从未这么清醒。一切都如此清晰,我似乎可以看到宇宙的尽头。我看到地球不过是亿万颗闪烁的光点中的一个。我想起以前在图书馆看到的在阳光中飘浮的尘埃。我感到一种平静的喜悦。听起来可能有点奇怪:我甚至觉得一切都充满了希望——因为明天我就要死了。
*
我醒来。我在床上又躺了一会儿。我意识到这将是我最后一次醒来。我意识到接下来自己所做的一切都将是最后一次。最后一次穿衣。最后一次刷牙。最后一次淋浴。最后一杯咖啡。最后一顿早餐。最后一次洗碗。最后一次拉开窗帘。最后一次晨光。
我专注地,不慌不忙地做着这一切。我用心体味每一点细微的感受。一切都散发出一种奇异的美感。
我最后一次确认要带的东西。Xanax。一种超强效安眠药。可以让你睡得人事不省。墨镜。大大的、能遮住大半个脸的墨镜。虽然国内航班的空乘我都不太认识,但还是要以防万一。我不想遇见熟人。机票。上午十一点起飞。零钱。要打的去坐机场大巴。《小王子》。
是《小王子》给了我灵感。
几天前我又发作了一次。我看见一架飞机坠毁。画面很清晰。浓烟。尖叫。灯光明灭。剧烈的震动。爆炸。那是我们公司的航班。在某个瞬间我看见了机舱内电子显示屏上的航班号。我做了五年的空乘,我不会看错。那个号码像刀一样刻在我脑海里。我去查了一下,是三天后的一个国内航班。
但我又能怎么样呢?难道跑去跟领导说,“求求你相信我,某某航班将要坠毁!”那样只会有两种下场:要么被当成神经病,要么被当成恐怖分子。
我什么都做不了。一如往常。
我只能眼睁睁地看着他们去死。
我想到了《小王子》。想到了写《小王子》的圣埃克絮佩里。我突然觉得很羡慕他们。至少他们可以像圣埃克絮佩里一样去死。他们将死于飞翔。
然后我有了那个主意。我也许不能救他们,但我可以跟他们一起去死。像圣埃克絮佩里那样去死。像小王子那样去死。死于飞翔。一瞬间,灰飞烟灭。没人会知道我是自杀。所有人都会以为那只是个意外。
如果我在即将坠机的航班上睡着了。
我最后一个登机。我想尽量少看见他们——我的那些同行者。但我对每一个遇见的人微笑。的士司机。机场巴士上邻座的小女孩。登机口的检票员。空姐。机舱过道上擦肩而过的年轻男人。坐在我旁边的和蔼老头。我调整好座位。我系好安全带。我摘下墨镜。我吞下两粒Xanax。飞机开始滑行。飞机离开地面。飞机开始上升。我戴上耳机,调到古典音乐频道。莫扎特。莫扎特,不坏。我闭上眼睛。我听了一会儿莫扎特。飞机继续上升。但我觉得自己正在往哪里下降——就像一只被推倒的花瓶。
[写作技术][[如何避免写作中的用力过猛 附:拼接段落二 - 知乎|https://zhuanlan.zhihu.com/p/26275973]]
-----
[写作技术] 如何避免写作中的用力过猛 | 附:拼接段落二
写作中我见到太多的用力过猛的问题,这样或许会带来很不错的戏剧性效果,但实际上这是个蛮大的问题。
用力过猛往往出现于短篇写作之中,往往越短越容易用力过猛。虚构写作中问题比非虚构写作大。
用力过猛的原因有很多,大多来自于对于戏剧性的过度追求。用力过猛的问题常常出现在高潮,次高潮,结尾和开场部分。
那么让我们快速的解决一下高潮,次高潮,结尾和开场部分的用力过猛问题。
高潮,次高潮的用力过猛问题
本身高潮和次高潮就是激烈事件,问题的解决和爆发,本身就是有很强的渲染力度的。而作者很容易被其感染,然后为了更加激动人心,更加具有力量而进一步挤压戏剧性动作和事件让整个高潮无比激动。原本这不是什么问题,但是之前 “过猛” 的时候,就会出现人物和发展部分无法承载过强的戏剧性,从而人物脱离故事,开始强行激动,开始强行激烈...... 这件事情就比较可怕了。
但是这不是更可怕的,更可怕的是,当作者写完这个高潮之后,回头一看,“我操,脱节,但是高潮好好看啊,我修改一下前面吧。” 这个确实是一个解决方式,并且在很多时候是一个优化方式。但是从我个人经验而言,这样带来了巨大的工作量,并且整个故事可能会大变脸。
好在如果是一个相对成熟的作者,可以仅仅加强发展部推动力,修正一部分人物,同时对于不适合的高潮进行删减修改。这是一个完整的优化方式。
但是,如果作者没有那么成熟,往往容易被激烈而 “好看” 的高潮所迷惑,为了完成这个 “灵光一闪的完美高潮” 而不择手段,这件事就很麻烦了。这种状况下作品往往不会走向到一个相对舒服的结果上面,为了完成高潮的情境,人物往往会更激化,并且为了完成高潮而激化。发展部事件不一定会按照逻辑发展,带着一定的强行动力而出现。结构上必然出现发展部过长的问题(简单来说,不成熟的作者喜欢为了完成高潮而加戏)。节奏上,必然呈现过于紧张且混乱的状态。
你们一定想想不到更可怕的状况,更可怕的状况是这个高潮实际上,没有那么好。
处理方式上很简单,写作一步一步地来实际上可以避免很多问题。现在大纲上做好修改会打败 50% 的用力过猛问题。还有 50% 来自于写作过程中的自我修正和一时冲动,这种冲动有时好有时坏。
面对高潮部分的用力过猛最重要的是能够分清好坏优劣,这属于雕琢的功夫,选择好的留下,并对前场戏进行修改,坏的部分请直接删掉。
然后做一个补充:往往出现这种状况,是因为事件的吸引力盖过了人物的吸引力。
开场和结尾部分的用力过猛。
开场部分往往是为了能够瞬间吸引读者,这件事本身没什么不对,但是塞上太多的戏剧性不一定好。而更严重的是,写的过多反而让读者和观众对于这本书失去兴趣。
其实解决这个不难,最简单的方法是抓住 “人物和核心主线”。读者对于人物的命运更加关心,所以开场的悬念和戏剧性一定是放在这两点上的,不要过多的描述当时的情景有多么的紧张,各方的心里如何如何纠结,这件事情有多么突如其来,意义不大。想想《百年孤独》是怎么写的开场。
结尾部分,往往是因为作者过于希望读者意犹未尽,或者强行升华。其实就是对于韵味的要求过于严重,简单一点,提前一点结束文章可以让这个问题得到很好的解决。
然后我们需要的是谈的重点来了,这个问题是包括我在内的半成熟作者的问题。以下部分不一定能够提供到帮助,同样写作新手们也不一定能够遇到这个问题。
在发展部分的用力过猛以及在主题,核心问题上的用力过猛
发展部分的用力过猛,来自于戏剧性的持续要求,但是往往容易失去文章的细腻度。因为实际上戏剧性是会剥夺掉一定的文章细腻度的,戏剧性的激烈度会让读者更多的关注到事件的发展上,人物的命运上。所以很多的时候细腻的部分需要用事件来做融合,简单来说是选择更为优秀的事件和更为凌冽的处理方式。但是在发展部分的推进中戏剧性过强带来的效果是读者对于核心事件的过度关心,而少了对于人物的内心细节的体会。(但是如果在发展部可以一样做到戏剧性强烈并且吸引人,那么我想应该会是一个很不错的通俗作品,特别如果是悬疑作品的话。)
在发展过程中的用力过猛还有一种反向的可能,就是过于注重 “质感” 和细腻度,细微状态的表述,而对主线的忽略。这个问题比上面大的多,主线的薄弱最直白的问题就是“拖沓”... 但是和水不一样的是,这些东西是有效的,是符合逻辑内的,甚至一些人写的这些东西也一样十分吸引人。可是如果冷静下来想,主线如果薄弱,那么必然带来的问题就是丢失掉一部分的事件的推动力,和事件吸引力。当然进一步引发的就是,事件对于主题表述的力度也被削减了。
为什么说这是半成熟作者的问题呢?是因为他们不容易暴露出来,简单地说如果是一个写作新手,这么写,一眼就能看出问题。而一个相对成熟的作者,这么玩的时候... 会让读者一样可以看下去,并且有一些还变成了作者的 “个人风格”。而且相对成熟的作者是可以做出调整和修改的,往往可以相对的修正一些这种问题,更重要的是可以让整个作品具有统一度,这也是读者觉得这只是“个人风格” 的原因。
总的来说,这样的作品依然不错,但是对于能否更进一步就不好说了。(当然是指创作之路上。)相对更进一步的状态,我个人认为是比重合理而且舒服的。但是真正的好作品是文字的质感和主线的叙事以及其中人物,主题核心的融合度极高,这也是进行删减时真正要做的工作。原本要用两件事情分别表述事件的紧张发展和人物细腻的心理状态,融合成一件事,进而对这件事件进行优化才能呈现好的效果。
对于主题,核心问题上的用力过猛
这件事很简单,就是对于自己要表述的主题过于执着,这往往会导致各部分的紧张,而更进一步的问题是,对于主题本身要求过于执着,也就是常说的 “对于深度的要求过高”。容易呈现出来的状态是很整体的——“讨论性过强,表属性过强,目的性过强,多方面紧张,并且还没有讲清楚。” 但是往往这种作品会呈现一种十分强的实验性... 从而也掩盖掉其问题。
对此我只能说 “take it easy,please.”。
好了可能要说解决方法了。
这发展部分及主题核心的用力过猛就是我现在的问题,我哪有什么解决办法。XD
-----------------------------------------------------------------------------------------
拼接部分二
朋友见到臭流氓张三的时候,往往以为他是个文人,直到张三开口,朋友才能确定他确实是个文人。
朋友李四也是个妙人,除了极度喜爱喝酒吃肉以外,几乎没有什么缺点。
有那么一天,张三正站在河边,朝河里撒尿。阳光如此明媚,飘着小柳絮,姜黄色的液体融入墨绿色的液体涌现出来的复古感,让张三无比的舒适。李四就在这个时候不合时宜的出现了,李四伸手拍了拍正在哆嗦的张三,却让张三脚下不稳掉入了复古感极强的河中。
李四把张三拉上来,湿哒哒的张三看着戴着红袖箍的李四。李四搔搔脑袋,终于还是开了口,“随地大小便,罚款 200。”。只是张三直勾勾的双眼看着他,让李四的这句话的声音越来越小,特别是张三的头发还是湿哒哒的时候。
李四又想到如果张三的手机进水了,自己是不是还要补偿一下他的手机。如果张三回去感冒了会不会找到自己要求自己补偿误工费,医疗费甚至精神损失费。从而进一步,李四看到这河里墨绿色的水,如果让张三不幸患上什么胃癌,肺癌,甚至如果上一个撒尿的人如果有艾滋病,而很不幸张三有脚气正发作,他还不幸染上了艾滋病,自己会不会算是过失杀人。
“算了,看你也是初犯,就不扣钱了。” 李四强作镇定地说着,“下不为例啊!”
“那么随地游泳不扣钱吧?” 张三如是说道。
李四就是通过这句话,知道了张三是个文人,他从张三的话里读出了许多内容,有存在主义的偏离感,又荒诞派的无意义,还有断裂运动之后的陌生感,以及魔幻现实主义的色彩。李四也想当个文人,他想,面前的这个人一定是一个很厉害的文人。
“看你湿漉漉的,来换身衣服吧。”
李四将张三带到自己小小的看守亭,并拿出自己的一套衣服递给张三。
张三接过衣服,脱了个精光,消瘦的身体,肋骨嶙峋,身体上还粘黏着河水。转过身去,看着李四,“你有毛巾吗?”
李四看着张三的身体入了迷,心想,“天呐,这就是文人的身体,消瘦而病态。他一定很痛苦,饱受着生活的痛,这些痛都在他的身上留下了足够的痕迹。这就是文人创作的源泉啊,人生的痛每个人都有,但是只有文人能够感触的如此之深。”
“你有毛巾吗?”
李四终于反应过来,“没有。”
“哦,好吧。”
张三只能又湿漉漉的穿上了干的衣服。
李四对张三说:“你,是个文人吗?”
“文人不罚款吗?”
“罚。”
“那我不是。”
这一次是李四直勾勾的看着张三,可是张三不为所动。
“我可以走了吗?”
李四看着张三身上的衣服,那是自己的睡衣,虽然不昂贵,但是很舒服,自己已经穿了几年了,有些感情。
“等一等。” 李四,“那个衣服。”
“你不知道借扇子吗?有借有还,说不好我们还能成为朋友。” 张三如是说道,顺便抱起了自己的湿衣服。
李四想到那么多的佳话,都是从借扇子借伞开始的,更加确定了张三是个文人,如果他不是文人,他怎么会知道这个。李四点点头,并送张三离开。
李四喜欢喝着酒吃着肉,想着自己还有一个文人朋友,会把自己的睡衣送回来。
张三再也没有回来过,因为他掏了掏睡衣的口袋,一个钢镚也没有找到。
只是可惜,张三不知道:如果他送睡衣回去的话,他以后就可以经常喝酒吃肉了。
——————————————————————————————————————————
卖萌时间
最近忙,且状态不好很久没有更新。估计大家都习惯了...
你们一定以为拼接的段落我就直接弃坑了,生命处处有惊喜。
唉,最近状态好差,心情也好差,所以下次更新就等我心情好了的时候再更新吧。
哦对了,上面的主体部分,就是讲用力过猛的部分,是我瞎编的。
——————————————————————————————————————————
给看到最后的朋友一个自省练习方式。
遗书练习,常常写遗书,可以回顾自己很多的问题,可以达到自省的效果。比日记好用。
(从神秘学的角度来说,这是跟死亡做游戏,有可能倒霉,慎重使用)
全文完
本文由 简悦 SimpRead 优化,用以提升阅读体验
使用了 全新的简悦词法分析引擎 beta,点击查看详细说明
!痛点: 笔记存在的问题
我们先来简单列举一下记笔记过程中存在的问题,如果您也存在或多或少的类似问题,那么看完本视频后,一定会大有收获。
首先,笔记没有为写作奠定基础。回想一下无论是大学里写论文,还是工作中写文档等等,是不是感觉痛苦万分?因为一切都是“从零开始”:选定课题之后,制定一个写作计划,然后头脑风暴或者开始上网找资料,平时摘录的上千条笔记似乎并没有什么用,甚至干脆都不记得曾经做过哪些相关的笔记了,还不如上网搜索来的简单痛快呢。之后开始一句一句地挤文档。
其次,笔记做完之后不再去看了。这或者是因为笔记记得太详细了,简直跟抄书一样,看笔记还不如去看原版书呢,又或者是因为笔记记得太散乱,要点不清,时间一长,根本不记得自己写得啥了。
最后,找不到笔记在哪里。要想笔记有用,首先得记得我们有笔记才行。如果只是在书上高亮,过一段时间后,还记得曾经高亮过哪些书吗?回顾自己的阅读习惯,很多时候做笔记其实就是在感兴趣的语句下写写画画,而这些批注大部分不会再瞅一眼。当我们开始记笔记时,我们并不知道什么时候会把他们用在哪里,因此需要有一种方法记住他们在哪里以及如何找到他们。
而这种方法,就是来自于20世纪德国社会学家[[Niklas Luhmann 尼克拉斯.卢曼]] (1927.12.8–1998.11.6)的卡片盒笔记法。原名称是德语:[[Zettelkasten]] ,英文:Slipbox,中文:卡片盒。卢曼借助于他独特的卡片盒笔记法,撰写了70多本书,发表了近400篇学术文章。之后阿伦斯Sönke Ahrens把对这套卡片盒笔记系统的研究成果,写成了一本书。书名很长,叫做:《如何聪明地记笔记》 — 献给学生、学者和非小说类作家用于提高写作、学习和思考能力的一套简单技巧
!笔记的类型:书中将笔记分为四种类型:
{{Fleeting Notes 临时笔记}}
{{Literature Notes 文献笔记}}
{{Permanent Notes 永久笔记}}
{{Project Notes 项目笔记}}
!核心要点及原理:
以上就是卡片笔记法得四种笔记类型,看起来似乎没有什么大不了的地方。但是他的思想却体现了我们的大脑学习和记忆的奥妙。他的核心要点有三个:
# 笔记之间建立链接。通过笔记的链接,我们可以知道这条笔记引用了哪些笔记; 通过笔记的反向链接,我们可以知道都有哪些笔记引用了这条笔记,从而我们可以将我们的知识形成一个网状结构,这和我们的大脑得思考过程是类似的。所以[[史蒂文·平克]]说过 “写作之难,在于把网状的思考,用树状的语法结构,转换成线性字符串。”
# 使用自己得话重述。而不是直接抄写。这是最困难得部分,但也恰恰是重点所在。因为重述会帮助我们组织和消化信息,从而将信息转化为我们内嵌的知识。正是因为重述做起来要比直接抄写摘录更困难,他才会给我们留下更深刻得记忆。这体现了一个叫做[[必要难度]]得理论。必要难度最早是由心理学家罗伯特·比约克推出的概念,简单来说就是,你如果记忆的过程越容易,那么你忘的就越快,反之如果记起来很辛苦,也不会轻易忘掉。所以说,在课堂上边听老师讲边记笔记并不是一个好的的学习方式。因为他太容易了,老师刚讲完还热乎着呢,顺手记下来并不需要费太大得精力,还有一种情况就是看书时做各种花式高亮标记,把一段话高亮之后,你的大脑就会以为记住了这段话。其实这些都只是给人一种自己正在学习得幻象而已,很快就会都忘掉。相反,课后梳理时依靠会议再作学习笔记会更好一些。这也是为什么在另外一种更流行得笔记方法[[康奈尔笔记系统]]中,课后的Summary很重要的原因。
# 不分类,只使用标签。所有的笔记都存放在一个卡片盒中,不通过文件夹来进行分类管理。因为分类代表着预先确定笔记结构,而且笔记不可以从属于多个类别,这都会损失笔记得灵活性。同时,固化的结构会难以产生跨学科的灵感。因为他会将我们约束在狭隘得直线思维当中。
作者使用集装箱来类比卡片笔记。许多人使用便捷得方式记录笔记:如果他们读了一个有趣的句子,则在其下划线。如果要发表评论,则将其写在空白处。如果他们有想法,就将其写到笔记本上,如果一篇文章似乎很重要,他们会努力并撰写摘录。这会在很多地方存有各式各样得笔记。就像很多的货物散落在各处一样。而写文章,就像是要符合某种特定需求得所有相关货物运输到某个指定地点一样。在散乱的货物中分拣,整理,装车,将是一个痛苦得过程。而卡片笔记法,则相当于把货物集中在一个地方,并持续对这些货物进行整理,不断地打包到一个一个集装箱里。当需要写文章时,只需选择合适的集装箱运输即可,标准化的集装箱极大地提高了货物运输的效率。即便要做一定得调整,也不会大动干戈。
这样,就把写作的过程,从一个自顶向下的过程,变成了一个搭积木的过程。随着我们得积累越来越多,积木也就越来越多,能搭出的东西也就越多越复杂。写作,也就不再是一个痛苦的,从零开始的历程。这也是为什么著名作家,纳博科夫说他写作的时候,“并不从开头写起,一章接一章地写到结尾。我只是对画面上的空白进行填充,完成我脑海中相当清晰的拼图玩具,这儿取出一块,那儿取出一块,拼出一角天空,再拼出山水景物”。
如何评价《[[一颗像里茨饭店那么大的钻石-菲茨杰拉德]]》?
-----
```
论《一颗像里茨饭店那么大的钻石》中的美国梦的破灭
论《一颗像里茨饭店那么大的钻石》中的美国梦的破灭
作者: 徐剑莹
摘 要:F ・司各特・菲茨杰拉德的大多数作品都和美国梦紧密相关,它赋予传统的美国梦以爵士时代的节奏和内容。本文就其短篇小说《一颗像里茨饭店那么大的钻石》中对美国梦的描写,分析美国梦发展历程,揭示其破灭的必然性。
关键词:菲茨杰拉德;美国梦;破灭
中图分类号:I3074 文献标识码:A 文章编号:1673-2596(2014)01-0200-02
菲茨杰拉德是 20 世纪美国文坛的代表人物,虽然创作生涯充其量不过二十年,但却留下了四篇长篇小说和一百六十多篇短篇小说。作为美国爵士时代的 “桂冠诗人” 和“编年史家”,他栩栩如生地重现了那个时代的社会风貌、生活气息和感情节奏。更重要的是,在沉湎其中的同时,他又能冷眼旁观,体味 “灯火阑珊,酒醒人散” 的怅惘,用严峻的道德标准衡量一切,用凄婉的笔调书写了战后 “迷惘的一代” 对于美国梦幻灭的悲哀。虽然菲茨杰拉德最出名的作品是他的长篇小说,他的短篇小说也取得了很高的艺术成就。在他众多的作品中虽有平庸之作,但其中的上品绝对是美国短篇小说宝库中不可多得的瑰宝。创作于 1922 年的《一颗像里茨饭店那么大的钻石》(以下称《钻石》)就是一个极好的例子。
小说的主人公约翰・昂格尔出生在中西部城镇的小商人家庭,家族生意的收入勉强能让他去读富家子弟的预科学校,在校期间结识了富有却很神秘的同学珀西・华盛顿。当约翰接受了珀西的邀请,去他家度暑假时,一次踏上 “黄金国” 的奇幻之旅开始了。起初,约翰还以为自己掉进了一个豪奢的梦境里。纯金的墙壁、钻石天花板、象牙回廊,更不可思议的是,一整座山都是钻石,一块完整的、毫无瑕疵的大钻石。约翰享受了无尽奢华,连爱情都不期而至,但很快他就觉察到了危险。华盛顿家对外人从来只许进不许出,因为钻石矿的消息一旦泄露,事情就不可收拾。约翰一定会被杀死,就像那个五金批发商的女儿一样。只是因为偶然的运气――逃跑的意大利人带来攻击机队,把整个钻石山炸毁,他才逃出生天。表面上看来这只是个童话般的奇幻故事,但隐藏在其背后的正是菲茨杰拉德惯用的主题――美国梦的破灭。
一、美国梦的内涵和演变
所谓的美国梦,有广义和狭义之分。广义上指美国的自由、平等、民主,渊源可追溯到早期欧洲移民到北美新大陆开辟新生活的时期。他们当中许多人认为,新大陆代表了人类最后的希望。纵观美国早期历史和相关文化作品,我们可以认识到早期美国梦是对一个基于平等、正义和自由国度的向往。而狭义上的美国梦是一种相信在美国经过不懈努力便能获得更好生活的理想,亦即人们必须通过自己的勤奋工作、勇气、创意和决心迈向繁荣,而非依赖特定的社会阶级和他人的援助。通常这代表了经济上或是物质上的成功。美国梦的首个提倡和体现者就是本杰明・富兰克林,同时也可以说是美国梦的完美诠释者。他编写的《穷人理查年鉴》是美国历史上最早宣扬通过个人奋斗取得成功的美国梦精神的畅销书,他的自传更是一本具体教诲如何实现美国梦的教科书。而后来的马克・吐温,无数的政治家,社会活动家都使用过这个字眼。在舆论界的大力宣传下,美国梦成了无数普通民众深信不疑、执着追求的理想,同时更是推动资本主义经济发展的、维护社会制度的重要精神力量。
到了 20 世纪 20 年代,美国梦更是大行其道。第一次世界大战结束后,元气未伤的美国进入了一个空前繁荣的阶段。整个社会物欲横流,人们对货币的准宗教狂热丝毫不亚于现在中东的原教旨主义者。好莱坞的电影,《花花公子》的裸体女郎,街头广告牌的煽动口号使得无数民众醉心于追逐财富和享乐。尤其是年轻人,醉心于在这个全新的世界憧憬无限的机遇,憧憬一个完美得令人窒息的伊甸园,然后坐着硕大的肥皂泡飘然飞越大峡谷,在某个睁开眼睛的早晨抵达满是黄金的海岸。可以说这时的美国已经彻底抛弃了富兰克林所提倡的勤俭奋斗的道德标准,取而代之的是冷酷的机会主义和对金钱、享乐的崇拜。菲茨杰拉德在这种时代背景下创作的《钻石》,不仅重现了这一社会现实,而且预言了这场盛大梦境的结束和随之而来的迷茫和苦涩。
二、约翰・昂格尔的美国梦
主人公约翰来自于一个偏远小镇海地斯,当地流行的那种纯朴的虔诚,是以真诚崇拜财富和尊敬财富为第一信条的。这种信念很早就在他身上打下了烙印。当他背负着父母的期望去外地求学时,他的发愤图强的寻梦之旅也就开始了。他本能地艳羡那些家境富有的同学,努力与他们打成一片。即使同学的父亲拿他的故乡打趣,他也能强迫自己应声附和。他直言不讳地表达:“一个人越是有钱,我就越喜欢他。” 所以当他在珀西家见识了无尽奢华之后,他对财富的敬仰就完全流露出来了。他开始享受这种由金钱带来的难以言述的、梦境般的奢华生活,并视之为人生追求的终极目标。
菲茨杰拉德笔下的美国梦不仅仅包含了对财富的极力追求,还有另一方面即对爱情的追求。约翰也不例外,在遇到同学的妹妹吉斯米之后,约翰很快坠入了爱河。他不是没有注意到吉斯米的缺点,“珀西和吉斯米似乎从他们的父亲那里继承了他那种盛气凌人的傲慢态度。他们每一转念,象一个模式似地都贯穿着彻头彻尾的自私。”但是吉斯米的美貌和她所代表的财富,使得约翰选择对此忽略不计。在他看来,珀西的家就是 “人间天堂”,身边又有美女相伴,他所追求的的梦想似乎在此刻达到了顶点。这正是他一直以来所向往的未来,他终于可以实现父母对他的殷切期望了。“年轻人不仅由于他们的不足,而且也由于他们的幸福,他们要求生活必须符合他们所憧憬的美好未来,否则他们就不能在现实中生活,而这美好的未来――鲜花和黄金,少女和命运,这些不过是不可比拟、不可企及的青春美梦的先兆和预示而已。” 约翰沉浸在这美好的梦境中不能自拔,却没想到梦境终究是虚幻的,是无法持久的,再美好的梦终究有醒来的一刻。
三、梦想的破灭及其根源
当约翰发现有许多闯入者被华盛顿先生关在高尔夫球场下面,当吉斯米不经意间告诉他所有受邀的客人都会被毒死,当他意识到这座富丽堂皇的人间宫殿其实充满了血腥和暴力时,他才幡然领悟到财富的拥有者对穷人的鄙视和排挤,富人关心的永远是他们的财富和他们自己。当那些黑人奴隶被炸死时,平时显得天真无邪、不谙世事的吉斯米丝毫没有同情和怜悯,相反,她痛惜是财富的损失:“价值五万元的奴隶全完了,这还是按战前的价格计算。尊重产业的美国人可真少。” 财富使得他们丧失了人性和灵魂,只剩下彻头彻尾的自私、冷漠。约翰的梦想在钻石山被炸为灰烬那一刻,也随之破灭了。他只能感叹:“那是一场梦。每个人的青春都是一场梦,一种化学的发疯形式。”
随着约翰财富梦的破灭,他的爱情梦也走向了终点。秘密泄露前,约翰对吉斯米是爱得如痴如狂,觉得她简直是十全十美的美女化身。得知真相后,吉斯米在他心中的地位是一落千丈。要不是还要靠吉斯米逃命,他就会立刻和她一刀两断。即使在逃离城堡前,他也不忘提醒吉斯米带上她所有的珠宝首饰。当他发现吉斯米错带了不值钱的水晶石时,他毫不掩饰他的失望、沮丧,而且暗示他不再珍视彼此间的爱情,“让我们权且相爱吧,你和我,相爱一年或者两年吧。这是人人都可以一试的一种神圣的喝醉了酒的形式。”
20 世纪 20 年代的年轻人把对物质的追求等同于精神追求,将财富作为人生成败的准则,却没有意识到对财富的崇拜正是他们的祸根,最终只会导致他们精神颓废,道德败坏,梦想破灭。这是资产阶级精神文明破灭的结果,也是美国梦破灭的根源。约翰最终意识到了这一点,菲茨杰拉德借他的口感叹:“整个世界有的是钻石,钻石以及或者说是幻想破灭的寒伧的礼物。这种钻石我到底有了,而我对平常的那种钻石也就无所谓了。”
四、结束语
《钻石》这篇短篇小说通过主人公约翰的奇幻经历描述了爵士时代下的美国社会中隐藏的深刻危机和人们道德价值观的沦丧,揭示了那个时代背景下美国人对世界、对人生的迷茫,以及对理想破灭的无能为力。菲茨杰拉德作为 “迷惘的一代” 的代言人,敏锐地觉察到了爵士时代虚假繁荣背后涌动的危险的暗流,以冷静的旁观者身份加以记录和描写,揭示了美国梦的虚幻性和破灭的本质,为世人留下了无尽的反思和回味。
参考文献:
〔1〕吴建国. 菲茨杰拉德研究 [M]. 上海:上海外语教育出版社,2002.
〔2〕常耀信. 美国文学教程 [M]. 天津:南开大学出版社,2005.
〔3〕王长荣. 现代美国小说史 [M]. 上海:上海外语教育出版社,2002.
〔4〕巫宁坤. 菲茨杰拉德小说选 [M]. 上海:上海译文出版社,1983.
〔5〕史志康. 美国文学背景概观 [M]. 上海:上海外语教育出版社,2004.
(责任编辑 徐阳)
转载注明来源: https://www.xzbu.com/9/view-5679531.htm
```
如何阅读世界文学-赫尔曼·黑塞
========================
如何阅读世界文学-[[赫尔曼·黑塞]]
-----
## 第一章
真正的教养并非是为某些目的而努力以赴的教养,它与一切以完美为目标的奋斗一样,本身即具有意义。为增强体力、灵敏与美所下的工夫,并不见得可以使我们富裕、成名或强壮。但它提高了我们的生活情趣与自信,让我们觉得更快乐、更幸福,并赐予我们心灵的平和与健康,因此,单单它本身即已有所得。“教养”,亦即以精神上之圆满为目标的努力,并不是通往某些有限目标的崎岖道路,但却能激励我们,愉悦我们,扩大我们的意识范围,增加我们生活与幸福的可能性。
所以,真正的教养一如真正的体育,是实践,也是刺激,从任何方向出发都可达到目的,但任何地方也都不能停憩。真正的教养存在于无限世界中任一旅途上,与宇宙一起呼吸振动,在超越时间的世界中摇荡,它的目标不是为了提高人们的能力与成就,真正的教养会帮助我们赋予生活意义,解释过去,更以无畏的心面对未来。
在臻及此一教养的各类途径中,最重要的途径之一就是研究世界文学。研究世界文学可以让我们慢慢地亲近许多民族的诗人与思想家,他们在著作中遗留下极其丰富的宝藏——思想、经验、象征、空想与理想。这条路是没有止境的,任何人都无法走到终点。仅仅是一种伟大文化民族的文学,就没有人能完全研究并精通它的全部宝藏,更何况全人类的整个文学。
但了解、体会优异思想家或诗人的著作,本身就是一种完成,也是幸福的体验——不是对死知识,而是对鲜活意识与理解的体验。尽量求多读多识,而更重要的是自由地,依个人意志选择我们空闲时能沉溺其中的杰作,以了悟人类所思、所求之广阔与丰盈;对整个人类的生命与振动产生多彩的共鸣,这就是一切生活的意义,生活绝不仅仅只是为了满足实用的需求而已。
可是,读书绝非只是为了使我们“心情愉快”,而是应该集中心神来读。读书不是要打发无聊的生活,以外在的慰藉来麻痹自己,而是帮助我们逐渐提升并充实自己的生活。
接近世界文学时的选择,大抵因人而异,不只视读者为此高尚欲求所花费的时间与金钱而定,也受到其他种种因素的影响:对某人来说,也许柏拉图是他最敬仰的哲人,而荷马是他最喜爱的诗人,柏拉图与荷马是一切文学的重心,他可以由他们来整理、批判其他一切事物;可是,对另一位读者而言,他选择的文学重心可能是另外的名字。有些人有能力体会高尚诗体的作品,同时也能领悟才华洋溢的空想游戏及生动语言构成的音乐;另一些人也许会执著于较严肃的知性作品。有些人特别重视自己母语的著作,甚至不看任何其他国家的作品;也有些人特别偏爱法国、希腊或俄国的作家。
此外,还有一些因素应该加以考虑,即使最博学的人,充其量也只懂得几国语言,其他时代与民族所有的重要作品,未必会全译成德语,何况许多文学作品根本不能翻译。真正的抒情诗,不单有结构轻快的诗句与美丽丰富的内容,甚至语言和诗句本身都有意义,创造性语言的音乐也就是世界与生命现象跃动的象征。这样的抒情诗,其用语往往是不能替代的,与诗人的母语相连结,而且和他特有的诗人语言有密切关系,因此,无法翻译。
最高尚、尊贵的文学作品——想想普罗旺斯1吟游诗人的诗吧——往往只有少数人能得到,能懂得。因为这些文学作品所用的语言已随其文化而衰亡,只有依赖充满爱心的学术研究,才能使之重现。我们德国人很幸运,能够自由阅读很多从外国语与死语翻译过来的美妙而丰富的宝藏。
读者阅读世界文学,最重要的就是能够先认识自己,进而认识对自己有特别作用的作品。无需依循任何模式或纲要,我们读书必须走爱之路,而非义务之路,如果只因某书非常著名,不认识它是一种羞耻,而勉强自己去读,实在是大错特错,所有的人都应该从最适合自己的地方开始阅读、认知,并且愉悦自己。
有些人在学生时代初期,已发现自己特别偏爱美丽的诗句;也有人偏好历史或乡土传奇;有人喜欢民谣;另一些人精密研究自身的情感,并借优异的知性加以解释,他们一定都会觉得读书是富有魅力而令人欣悦的事。
阅读之路有数不清的方向,可以从学校课本、日历出发,而终结于莎士比亚、歌德或孔子。他人推荐我们的作品、想读但又引不起兴趣的作品、与己意相反而无法融入其中的作品,我们都应该放弃,不必勉强、忍耐地去读。所以,不要过分鼓励孩子或太年轻的人专门去读某一范围内的书。否则,年轻人会终身厌恶精美的作品,甚至厌恶读书。每个人都可随心所欲去读任一文学作品、诗歌、报道或考察,也可以从此不断地去寻求类似的作品。
以上述种种为前提,我们可以开始阅读了。世界文学可敬可爱的庙堂,对每个努力的人开放,量是不成问题的,我们无需惊讶于其中宝藏的丰富。有人一生中只读过12本书,仍是真正的读书人。也有人走马观花般浏览许多作品,对任何事物都能头头是道地表示意见,但这些人的努力是白费了,因为所谓教养必须以一些可被教养的事物为前提,性格与人格即属之。如果没有这些,如果教养没有实体,只在虚空中进行,那么,也许可以获得知识,但绝不能产生爱与生命。没有爱的阅读、没有尊重的知识、没有心的教养是戕伤精神的最大罪恶之一。
谈到这个问题,我并无学理的依据,也不希望能提出圆满无憾的答案。我只凭个人生活以及作为一个读书人的经验,陈述一下世界文学理想的小文库。但在谈书之前,必须先注意一些实际的事项。
走完这条路的第一阶段之后,与书籍的不朽世界有过若干接触,对书的内容与书本本身都会发生新的关系。不仅是读书,还必须买书。对经验丰富的爱书者,或已经拥有不少藏书的人,我可以凭个人经验断言:买书不单对书店与作者有益,而且可以获得特别的喜悦与独有的道德观。
譬如,在阮囊最羞涩的时期,仔细研究各种图书目录,克服一切困难,灵敏、坚忍、缓慢但圆满地,利用最廉价的普及本,创出小而精美的藏书库,这就是一种喜悦,一种有魅力的竞赛。反之,对有教养又有钱的人来说,寻求心爱书籍最精美的版本,搜集最稀贵的古本,替书施以自己充满爱意的装裱,也是一种无上的喜悦。从逐步存款、仔细选书到最奢侈的投资,其间有多种不同的方式,也有许多的喜悦。
开始藏书的人都会注意搜求好版本。所谓“好”版本(善本),并不一定是高价的版本,而是指那些以敬业之心加以处理,校对周详,适合高尚作品的版本。有些版本虽然价格昂贵、皮面烫金,又有插图,但编者处理时却冰冷无情,这样的版本为数颇多。而廉价普及本中,却有很多是经由编者诚心诚意编订而成。有些版本只是从全集中抽出的最粗俗选本,编者却大言不惭地以“全集”名义刊登广告,这种恶习几乎已屡见不鲜,不同的编者会从不同的角度来精选一位作家的作品。
一个人怀抱深密的敬意与爱慕,从多年来不断阅读的作家中,编出选集,这与一位接受委托的文学家,以冷淡轻率的职业态度编成的选集,两者之间实不可同日而语。
因此,每出一新版,都必须小心谨慎,再三检对全文。一位畅销作家的作品,印刷厂大多不参照原版,只一意翻印其他印刷厂所出的版本,因此,书中错误连篇,歪曲之处所在多有,种种缺点不胜枚举,有许多惊人实例,可供举证。但很遗憾,我无法针对这点为读者开药方,也无法指出某一出版商及其版本绝对可靠,或某一出版商及其版本绝不可靠。
几乎所有出版德国古典作品的公司,都出过一些好版本,也都出过一些不太妥善的版本。我们曾在一家出版社发现全文监修最完善的海涅2,但在其他地方也发现编选并不成功的雷瑙3与施蒂弗特4。幸而,这种情况已不断改进,在古典作家的作品中,一家著名的出版社,数十年来,对诗人诺瓦利斯一向极为忽略,最近却出版了诺瓦利斯的新版本,可以满足所有严格要求的新版。可是,出版商往往关心纸质与装订,更甚于关心内容,这是买书人要注意的一点。同时,还要注意,别为了形式的整齐,而将所有“古典作家”的作品,都购买同一版本,对每位喜爱的作家,都应该尽量去搜寻最好的版本。5
大多数读书者都应具备分辨的能力,自己决定哪些作家应买完备的全集,哪些作家只需购置选集即可。至于,数位作家的合集,目前还没有令人满意的本子。全集本,这几年,甚至可说几十年来,始终在不断刊行,但似乎永远没有出齐的日子。在这种情况下,只好求助于旧书店,以寻取旧版,或即以目前出版的本子为满足了。
就多数德国作家而言,有的固然已出了三四种优秀的版本,但有的作家却往往只有一种本子,甚至一种好版本也没有。目前,不仅缺乏完整的尚·保罗6,也缺乏令人满意的布伦达诺7。而弗列特利希·许雷格8极其重要的青年期作品,连许雷格自己也未列入其著作集中,数十年前,曾经一度出过非常完善的版本,但已绝版多时,此后也未见有足以取代的其他本子。有些作家,如海因塞9、贺德龄10、德洛丝特·修尔斯霍夫11虽被漠视了几十年,但现在已出了非常完备的版本。在廉价的普及本中,可以发现各民族不同时代的作品,其中,以雷克拉姆(Reclam)社出版的世界文库最醒目。只要是我所喜爱的作家,无论是他多么短小,不为人知的作品,我都拥有两种,甚至三种版本,这些版本中具有其他任何版本中所缺乏的成分。
上面谈的只是我们自己的宝藏——最优秀的德国作家的作品。如果再扩及其他国家翻译成德语的作品,那情况就更复杂了。真正古典的翻译为数并不多,马丁路德的德语《圣经》、许雷格与狄克合译的莎士比亚,是最著名的。这些名译,常使德国人将他国的杰作视为自己的宝物——虽然持续了一段很长的时间,但并不是永远!这“很长的一段时间”,也有终结的一天。例如路德的《圣经》,今天大部分德国国民都已看不懂,必须不断以现代语言加以修订,以适应新时代。
最近,德语《圣经》一再出现全新的版本。《圣经》译本是由马丁·布伯12监修,与我们幼年时所读的《圣经》完全不同,形式上改变得很厉害。事实上,路德《圣经》所用的德语已接近我们白话著作所能适用的年龄极限,15世纪的德语,对今日的德国人民而言,早已如同陌路。
唯一的例外是:拥有但丁的意大利人,今天许多意大利人仍能背诵但丁大部分的诗篇。今日欧洲,如果没有激烈的变形与翻译,没有一个作家能像但丁这样广为流传。对我们德国人来说,读但丁究竟哪种译本最好?根本上这是无法解决的问题,任何译本都只不过是近似而已。某译本如有某些地方引人入胜,我们才会热心地想读原文,尽力从内心去感受、理解用古意大利语写成的可敬诗句。
现在让我们进入正题:创立小而优美的世界文库。首先我们要重新体谅一切精神史的一个原则:凡是最古老的作品,因为其古老,所以数量最少。今天流行的畅销书,也许到明天就会被淘汰;今天新奇有趣的事物,后天也许就成了明日黄花。几世纪来,始终维持其生命,至今仍未被遗忘、湮灭的作品,其评价,在我们活着的时候,也许仍然不会有太大的变化。
先从人类精神中最古老、最神圣的佐证——宗教与神话的书籍谈起吧!除了众所周知的《圣经》以外,我想以《奥义书》选粹的形式,从古印度哲学中,把吠檀多——即吠陀结尾的部分,置于我们的文库之首。佛陀传法的选粹也列于其中。源自巴比伦的《吉尔嘉梅西》13,是歌咏伟大英雄壮志与死神搏斗的豪雄诗歌,其优秀杰出不下于吠檀多。从古代中国可选孔子的《论语》、老子的《道德经》,以及庄子美丽的寓言(《庄子》)。这样,我们已拨出全人类文学的基本和音。
我们在此几乎可以同时认知并感受到《旧约》与孔子典范教言的先见,对规范与法则的努力,印度人与《新约》所显示的预感,以拯救世人之不满为目标的探索,超越复杂焦虑之现象界的永恒和谐的神秘知识,以诸神形象显现的自然力与灵力崇拜;并且还可以认知并感受到诸神只是象征,人已掌握着力量与懦弱、生活的欢愉与苦恼。抽象思考的一切冥思、文学的一切游戏,有关人生无常的痛苦,对痛苦的慰藉与幽默,都已表现在以上少数书籍中。中国古典抒情诗的选粹,也可归入其中。
关于东方较后期的作品,《一千零一夜》必须放入我们的文库,这部书是无穷快乐的源泉、世界最丰富的画本、最庞大的童话故事。世界上各民族都有美丽无比的童话故事,不过,在我们的藏书中,仅此一本古典魔法书也就够了。如果想再加以补充的话,可添入格林兄弟搜集的《德国民族童话》。从波斯抒情诗选辑的美丽《诗选》,也清新可喜,可惜,还没有完整的德译本,只译出哈菲斯14与奥玛·开俨15两人的作品。
现在转向欧洲文学,从古代文学丰富壮丽的世界中,我们一定要选荷马的两部伟大叙事诗,这两部杰作可以让我们完全浸入古希腊的空气与氛围中。此外,再选希腊三大悲剧作家艾斯奇勒斯、索福克利斯与尤利匹底斯。抒情诗人的古典诗集《诗选》16也应加入。面对希腊的智慧世界,我们不能不感到非常遗憾,因为最具感化力,或许也是最重要的希腊哲人苏格拉底,我们只能从其他哲人,尤其是柏拉图与色诺芬的著作中,获得片断的印象。如果能有条理地收集有关苏格拉底生活与学说方面,最可信的证言,辑成一书,那是多么可贵,不过,这的确是一件艰难的工作,语言学家们也不愿意从事。我不想将真正道地的哲学家列入我们的文库。反17之,亚里斯多芬则必须列入。
他的喜剧确实是欧洲幽默文学伟大系列的先驱。此外,巨匠普鲁塔克的《英雄传》,至少也要选出一两卷。讽刺寓言大家鲁奇阿诺斯18的作品也不能遗漏。
还有一些重要作品,是不可或缺的,那就是叙述希腊诸神与英雄故事的书。关于神话的书并不多,所以我想可以采用许瓦普19的《古代传说集》来补充,这本书虽然挖掘得不怎么深,却能以极难得的文笔叙述许多美丽神话。晚近,许瓦普有了一个真正的继承者,阿尔普列希特·薛佛20开始撰写希腊传说,第一部已经问世,使读者对他的期待更为殷切。
在罗马方面,我喜爱史家甚于文学家。虽然如此,仍有一些作家,不能不选入,像贺拉士21、维吉尔22、奥维德23。与他们并列的,除了泰西塔斯24外,还有苏埃登25与彼特罗尼斯26的《塞第利孔》,这是尼罗时代颇富机智的风俗小说,再加上阿普利斯的《金驴》。从后面这两部作品中,我们可看到罗马帝制时期内部的颓废。在罗马衰亡期社交界人士的游戏之作旁边,我要放置一部伟大而肃穆的作品,这就是《圣奥古斯丁忏悔录》,全书用拉丁文撰写,但却源出另一个世界——早期基督教世界。古罗马气氛冷漠冰凉的作品,遭遇到中世纪初期热情洋溢之作,其冰凉感已逐渐变弱。27
一般常以“黑暗”称之的中世纪,在我们父亲甚至祖父辈时代已被忽视,以致关于中世纪的拉丁文学,几乎没有现代的版本与译本。值得称赞的例外就是保罗·凡·温特菲尔特的优秀杰作《拉丁中世纪的德意志诗人》,这是我们文库必须收入的书。表现雄伟的中世精神之极致,而在文学史上28长久保持鲜活生命的巨著,应推但丁的《神曲》,虽然除了意大利人与学者阶层外,只有少数人认真读过《神曲》,但它仍不断放射出深密的感化力,而成为人类所拥有少数几本具有永恒性的书籍之一。
古意大利文学中,时代仅次于但丁的作品,可选薄伽丘的《十日谈》。这部著名的小说集,因为描写露骨,颇为清高人士所菲薄。但《十日谈》确是欧洲小说艺术成就最高的第一部杰作,全书以灵妙多姿的古意大利语撰写,几乎世界所有语言都有译本。由于劣本甚多,购存时应多加注意。在现代德译本中,各位最好选择茵塞尔书店的版本。三个世纪中,薄伽丘的后继者写出了许多著名的小说,但没有一人比得上薄伽丘,不过,这些模仿者的选集(例如保罗·艾伦斯特29所刊行者),在我们书单中仍不应漏失。文艺复兴时代,意大利的叙事诗人,首先不能忘记《疯狂的奥尔兰》的作者亚里奥斯特30。这部作品可说是魅人的浪漫式迷宫,充满奇妙的比喻与卓越的构思,是许多后继者模仿的范本。仿作者中最后也最优秀的是我们的魏兰德31、彼特拉嘉32的十四行诗,足可与之并列。还有,不要忘了米开朗基罗的诗,这本真挚的小书,在那时代是孤独而高贵的。充分表现文艺复兴时期的节奏与生活情调之代表作,应推齐里尼33的《自传》。其后的意大利文学,选择起来,已没有问题,哥尔德尼34的两三出喜剧,哥吉35的浪漫童话剧,此外,还有19世纪的雷欧帕尔迪36与嘉尔多奇37。
中世纪时期才开始孕生的最美丽作品是法国、英国、德国的基督教英雄传说,尤其是亚瑟王的圆桌武士故事。这些遍及全欧的传说,部分保存于[[《德国民间传说故事集》]](Deutsche Volksbücher)中,因此这也是一本应优先列入我们藏书目录的作品。最好的现代版本是由李夏特·贝恩慈编辑的,这本书可与[[《尼布龙根之歌》]] [[《古德伦之歌》]]并列。虽然它不是原形的作品,而经过后世的改写,有各种语言的译本。普罗旺斯吟游诗人的作品,前文已述,华尔特·凡·德尔·佛格伟德38、哥特福利特·凡·许特拉斯保39、华尔福兰·凡·艾森巴哈40是普罗旺斯吟游诗人的弟子。我们怀着感谢的心情将他们的作品(如华尔特的《诗集》、哥特福利特的《托利斯坦》、华尔福兰的《巴尔姬佛》)收入文库。此外,骑士的《恋爱歌人(Minnesänger)之歌》,也应自选集中择其佳者,加以购存。
现在,我们已走到中世纪的终点,随基督教拉丁文学与传说源泉之衰退,全欧在生活、文学方面已孕生了新事物,欧洲各国的语言已逐渐取代了拉丁语。僧侣与佚名文学过去了,继之而起的是都市与个人文学(在意大利以薄伽丘为起点)。
## 第二章
在法国,当时放纵孤独的诗人法兰沙·威扬41开出了奇异之花。他那粗犷、可怖的诗是无与伦比的。再深入法国文学的内部,我们会发现许多不可缺少的作品。至少要拥有一卷蒙田的《论文集》,幽默嘲讽巨匠拉伯雷42的《嘉甘狄亚》与《庞塔格留埃》、孤独的信仰者与禁欲的思想家巴斯卡之《沉思录》和《与外省人书简集》。还有,柯耐耶43的《勒·希德》与《贺拉士》也不可缺少,再加上拉辛44的《费德尔》《阿塔利》《贝雷尼斯》,我国就拥有了法国戏剧之父的古典作家。
然后,应该数到喜剧作家莫里哀,作为第三颗明星。这位嘲讽大师,《塔尔提夫》的作者,是大家都很熟悉的,至45少应该备有一卷他的杰出戏剧选集。拉·封丹46的《寓言故事集》与费诺龙47的《特勒马克》虽然很有吸引力,却很少有人将他们列入书单,我们不可漏掉这两人的作品。至于伏尔泰48,我想他的戏剧和诗都可省略,但不能错过他那闪电式的散文,尤其是《戆第德》与《沙地克》。这两部作品所流露的嘲弄与兴奋,当时曾被目为法国精神的典范。
不过,法国有多种不同的面,其中之一即为革命的法国。伏尔泰之外,波马尔谢49的《菲嘉洛》与卢梭的《忏悔录》都应该收藏。还有,我差点忘了勒·萨哲50精致的恶徒小说《吉尔·布拉斯》,以及阿贝·布列佛51动人的恋爱故事《马侬·列斯科》。现在已经到了法国浪漫派及其后一系列伟大小说家的时代——在此几乎可以举出数百本书名!不过,我们只集中心力于那些真正独特、不可替代的杰作!
首先要提到[[司汤达]](本名安利·贝尔)的小说《红与黑》和《巴玛修道院》,由热烈灵魂与猜疑心重、优秀圆融的知性战斗中,产生了全新的文学。波特莱尔的《恶之花》也不下于司汤达,而且深富独创性。与这两位大师相比,缪塞52笔下的可爱人物,以及小说家哥提耶53和缪杰尔54颇具魅力的浪漫小说,不免要相形见绌了。接踵而来的是[[巴尔扎克]]55,他的小说,我们至少应该拥有《高老头》《欧也妮·葛朗台》《表皮》与《三十岁的女人》。在这些激情洋溢、素材丰富、为生命而挣扎的书籍中,还应添入名家梅里美56高贵的短篇小说。然后是最灵妙出色的法国散文家福楼拜的巨构《包法利夫人》与《情感教育》。左拉57虽略逊一筹,也应给予一席之地,因为他创作了《酒店》与《神父之罪》。同样,莫泊桑58若干病态美的短篇小说,也值得传世不朽。由这里我们可以迈入近代领域,但在还未越过这领域之前,仍有一些高贵作品值得列举。最重要的是不可遗忘保罗·魏尔仑59,他的诗是法国最具深邃灵魂,同时也最纤细的作品。
英国文学可从乔叟的[[《坎特伯雷故事集》]]谈起。这部杰作部分源于薄伽丘,但在节奏上却是全新的。乔叟是第一位道地的英国诗人,莎士比亚的作品可以与之并列,但不能以选集,应以全集。我们的师长辈常以最崇高的敬意谈起弥尔顿的《失乐园》。但我们大可不必将弥尔顿列入书单来勉强读他。《失乐园》可以割爱,虽然这似乎有点不大妥当。柴斯特菲尔德60写给儿子的《书简》,不是道德训言,可以列入。天才爱尔兰人、《格列佛游记》作者斯威夫特的作品,只要能够得到,即应列入。他那广阔心灵、痛切滴血的幽默以及孤独的独创性,足可弥补他那怪人气质的一切过错。笛福61的诸多作品中,《鲁滨逊漂流记》与《摩尔·福兰达斯的故事》都是很重要的杰作,由它们开启了英国古典小说的辉煌系列。费尔汀的《汤姆·琼斯》与史莫雷特62的《普雷格林·彼克尔》当然也应列入。还有,史特恩的《特雷斯特安·薛迪》与《一个感伤的旅程》绝不可忽略,这两本书代表典型的英国心态,并从感伤跃向惊险的幽默。
至于想认识浪漫的吟游诗人欧西安63,只要读歌德的《维特》就足够了。雪莱和济慈的诗,不能错过。现存的抒情诗中,应推他们二人的诗最美。反之,拜伦只要读他一首长诗就够了。这首长诗《柴尔德·哈勒德》(Child Harold’s Piligrimage)也许是他最好的作品,我对拜伦笔下浪漫式的超人非常欣赏。司各特的历史小说,也可选取一部,例如《艾凡赫》(Ivanhoe)。至于不幸的德·昆西64可选《鸦片吸食者的忏悔》,虽然这是一本极为病态的书。麦考莱65的《论文集》不能忽略。辛辣的卡莱尔66除《英雄论》外,可以选极富英国式机智的《衣裳哲学》。
接着,长篇小说的伟大明星来了。这就是《名利场》与《斯诺普之书》的作者萨克雷67和令人流泪但不失善心与景仰之情的英国小说家之王狄更斯。狄更斯的作品,至少应拥有《匹克威克故事》与《块肉余生录》。在狄更斯的后继者中,梅雷狄斯68对我们似乎比较重要,尤其是《自我主义者》,如果可能的话,梅雷狄斯的《李察·费瓦雷尔》也应列入。史云朋69美丽的诗也不能缺少,不过,难译得很。再加上奥斯卡·王尔德70的一两卷,最好是选《道林·格雷的画像》及若干篇故文。
美国文学可以焦虑与恐怖的诗人爱伦坡之短篇小说集,以及惠特曼激情大胆的诗为代表。
西班牙方面,首先应选[[塞万提斯]]的《唐·吉诃德》。这是超越时空最雄伟、魅人的书籍之一。叙述一位对幻想中的恶徒作战的徬徨骑士,以及他的胖随从者桑丘,这两位不朽人物的故事。此外,塞万提斯的短篇小说也不应放弃,这些短篇是杰出小说艺术的真正珠玉,也是精美的《吉尔·布拉斯》的先驱。著名的西班牙恶徒小说也该拥有一本,要从中择取一部实在不容易,但我决定选格贝德71的《大恶徒巴布洛·塞歌维亚》。这是一部充满激烈冒险,洋溢奇特机智的作品。西班牙剧作家中,也有精美高贵的人物。我们可选巴洛克的伟大诗人、半世俗华丽、半宗教训示的舞台魔术家卡尔德隆72为代表。
此外还有应该遍历的各种文学,例如荷兰与福兰德73的文学。其中可选德·科斯特尔74的《狄尔·乌伦斯贝格》与穆尔塔特利75的《马库斯·哈威拉尔》。科斯特尔的小说可说是《唐·吉诃德》的后代兄弟,福兰德民族的叙事诗。《哈威拉尔》是殉教者穆尔塔特利的主要著作,数十年来,他为被压迫的马来人争取权利而战,终于牺牲了生命。
散布各地的犹太人,在世界许多地方,以各种不同的语言,留下他们的作品。其中有一些是不能忽视的。西班牙的犹太诗人耶夫达·哈雷威76用希伯来文写的诗与赞歌应列入我们的文库。卡西丁(Chassidim)派犹太人最美的传说也应选入,现有马丁·布伯的古典译本。在布伯的《巴尔仙》与《伟大的马奇德》中都含有这些传说。
北方世界有格林兄弟所译的《旧爱达之歌》、冰岛人的萨嘉(Saga传说)如《斯嘉顿·爱吉尔的故事》,以及波努斯的《冰岛人之书》,这些选集或改写的作品都可列入文库。近代斯堪的那维亚文学,可选安徒生童话、雅可普森77的故事、易卜生的主要戏剧、史特林保78的一些著作。不过,易卜生与史特林保在今天似乎已不十分重要。
19世纪的俄国文学特别丰富。俄语的伟大古典作家普希金79是无法翻译的,所以我们从果戈里80谈起。果戈里的《死魂灵》与短篇小说可列入我们的文库,屠格涅夫81的一些杰作今天已被遗忘,我们选择他的《父与子》,再加上冈察洛夫82的《奥布洛莫夫》。托尔斯泰伟大的艺术家精神,因其说教与改革意图,曾被冷落一时,但至少他的长篇小说《战争与和平》(或许可称为俄国最美的长篇小说)和《安娜·卡列尼娜》应该选入。他的《民间传说集》也不能遗漏。至于陀思妥耶夫斯基的《卡拉马佐夫兄弟》《罪与罚》以及他最撼人心魂的作品《白痴》都不可不读。
我们已从中国到俄国,从远古到现代,遍搜了许多民族的文学,认识了许多值得感叹、值得喜爱的作品。现在只留下我们最大的宝藏,我们自己的德意志文学还未探查。前文只提到《尼布龙根之歌》以及中世纪后期的两三篇作品,现在我们要以特殊的感情来观察1500年以后的德国文学。我们只选取最可爱、真正属于我们的作品。
关于马丁路德,他的主要著作《德译圣经》,前文已经提过,不过,我们也应该一读他的短论,例如两三部最平民化的《小册子》或《餐桌语录》等选集,甚至1871年出版的所谓《德国文豪路德》都可以。
反宗教改革运动期间,布雷斯劳出现了一位奇特的诗人,他只留下一册薄薄的诗集,和我们有密切关系——但,它却是德意志信仰精神与文学最崇高的精华之一,这本诗集就是安格尔斯·希雷修斯83的《天使般的旅人》。至于歌德以前的抒情诗,只要有我编的《德国诗人之歌》这类选集就够了。在路德时期,纽伦堡的民众诗人汉斯·萨克斯84,一般都认为应该列入文库,他可与格林梅尔斯豪森85的《冒险家辛普利吉斯穆斯》并列。在这期间,三十年战争,正如火如荼地进行,但这部杰作由于其新鲜感及辉煌的独创性,并未在战火中佚失。幽默作家洛依特86强有力的杰作《谢尔穆夫斯基》,虽较前书略逊一筹,但仍值得我们珍惜,可与《辛普利吉斯穆斯》并列。在上述这些作品旁边,可置放18世纪的《慕西豪森男爵冒险记》87,然后我们便来到近代德意志文学伟大时代的入口处。
怀着欢愉之情先开列几卷莱辛88,不用全集亦可,但必须包含一些他的书简。至于克洛普斯托克89,他最华美的赞歌,已见于我们的诗集中,仅此即足够。困难的是赫尔德90,他几乎已被完全遗忘,但仍值得一读——常常翻阅他的作品,可以获得很大的享受。虽然他的长篇,就整体来说,很难从头到尾读完,不过,雷克拉姆社已出版了三卷很好的选集。即使没有魏兰德的全集也不要紧,可是,千万不可缺少《奥贝龙》,可能的话,《阿普特勒市民的故事》也该购存。魏兰德容易亲近,富于机智,擅写游戏文章,并借古代人与法国人历练自己,倾向启蒙主义,但颇富空想性,他是一个在我们历史中很独特,而又被完全遗忘的人物。91
关于歌德,如果财力许可,我们的文库应该拥有他最精美、完整的版本。可以没有即兴戏剧、论文、批评中的某些部分,但他道地的文学作品,包括抒情诗在内,都该收存。在本文库所有的全集中,歌德震撼心灵的作品已发出轰然巨响,他多数的杰作都表现得很明确,而且具有决定性。从《少年维特之烦恼》到《诺威雷》,从初期诗作到《浮士德》的第二部,是多么遥远而又美丽的道路!除了作品之外,关于歌德的最重要传记文献也必须具备。爱克曼92的《对话》及一些往返书简——特别是给席勒与史坦因夫人的书简——都非常重要。歌德年轻时的朋友中,也产生了许多引人注目的作品,其中最精美的大概应推云格·许提林93的《海因利希·许提林的青春时期》,我们要把这本可爱的书置于歌德旁边。同样的,我们还需要一卷芳贝克的使者克劳狄斯94的著作。
至于席勒,我不敢多说,他大部分著作,我几乎都没有。但他整个人,以及其精神与生活当然是非常伟大的,而且极富吸引力,没有人会相信,这耀目的星座会消逝。我们可选他的散文作品(非历史的,而是美学的),以及1800年前后的伟大诗篇,此外再加上彼得生95的《席勒对话录》。和席勒同时代的作家,我们的文库可以加入穆索依斯、希培尔、丁梅尔、莫里兹、索衣美等人的作品——不过,不能受感情的影响,必须严加选择。本文库中既然连缪塞与雨果都未选入,当然无法容纳可爱但并非大作家的全部作品。否则,在德国精神史上最丰盈的时代——1800年前后,还应列入许多第一流的作家。其中有部分作家,已因时代潮流与观念极其褊狭的文学史而被遗忘,甚至被轻视到难以置信的程度。例如德国最伟大的人物之一尚·保罗,在今天数以千计的学子用作教科书的通俗文学史中,对他只有笼统而不关痛痒的批评。对诗人的风貌更无一语提及。为了报复这种不公平的待遇,我们要排出能够发现的,最完整的尚·保罗全集。也许有人会认为这样未免过于极端,那么,我想至少应该拥有《年少气盛》《希本卡斯》《巨人》等主要著作。古典轶事作家赫伯尔96的《珠宝盒》也不能忘记。
最近出了一些贺德龄的好版本,我们应满怀谢意拥有其中的一种,而且常常请出这高贵的灵魂,倾听他那富有魔力的声音。贺德龄的一边放置诺瓦利斯的作品,另一边则放克雷门斯·布伦达诺的著作。可惜布伦达诺还没有真正完美的版本。他的故事与童话已被大多数人遗忘,但他诗歌中所含具的深邃音乐性,已逐渐被发现。布伦达诺和他的妹妹贝狄娜共同的杰作就是《克雷门斯·布伦达诺的春之花环》。他与阿尔宁97合编的德国民谣集《少年的魔笛》,是最美丽独特的德国书籍之一,一定要列入我们的文库。关于阿尔宁,我们要收存一卷编选俱佳的短篇小说集,像《长子继承者》《埃及的伊莎贝拉》这样的佳作,是不可缺少的。其次是狄克98写的一些故事,尤其是《金发的艾克伯特》《生命的过剩》《塞温的叛变》,以及德国浪漫派最富幽默感的作品《穿长靴的雄猫》。遗憾的是歌雷斯99至今没有好的版本。许雷格100《梅林故事》之类的隽永作品,几十年来竟然始终未曾再版!至于胡格101,只有美丽的《温婷》对我们有益。
海因利希·凡·克莱斯特102的作品,包括戏剧、小说、逸闻在内,我们应该全部收存,他是后来逐渐由德国国民发现的作家。至于夏密梭103,只需备一部《彼特·许雷密尔》就足足有余了。这本小册子应置于高位。艾亨多尔夫104尽可能采取完整的版本,除了诗(最德国式的诗)和畅销的《饭桶生涯》之外,其他小说都应全部拥有。反之,戏剧与理论的著作即使没有也无妨。浪漫派中最练达的小说家霍夫曼105也该拥有他的若干作品,不仅有人喜欢他的短篇小说,即使长篇如《魔鬼的药酒》也有爱读者。豪夫106的《童话》与乌兰特107的《诗集》不能错过。更重要的是雷瑙的《诗集》与德洛丝特·修尔斯霍夫的《诗集》。他们都是擅用独特语言的音乐家。赫伯尔108的一两部戏剧以及他的《日记》(至少应备选本),海涅作品中不太无聊的好版本(散文亦然)都不可或缺。此外,莫里克美丽丰盈的版本,尤其是诗集和《旅游布拉格的莫扎特》《老公公》都应收存,可能的话,《画家诺尔登》也不可缺。赫伯尔之后即为德国散文最后的古典作家施蒂弗特,他的杰作有《晚夏》《习作》与《五彩缤纷的石头》。109
前一世纪中,有三位值得注意的瑞士小说家加入德国文学的行列。一位是贝伦农民阶级出身的伟大叙事文学家哥特赫尔夫110,另外两位是苏黎士人格勒111与迈耶112。哥特赫尔夫可选两部《乌利》小说;格勒可选《绿色的海因利希》《塞尔特威拉的人们》与《警语诗》;迈耶可选《于格·耶纳契》。格勒与迈耶都有优异的诗作,可列入近代抒情诗佳作选。这类好诗为数甚多,诗人之名,难以一一列举,如果有兴趣的话,还可以加上薛佛尔113的《艾克哈德》。对威尔黑姆·拉伯114,我想先赞一辞,他的《阿布·特尔芳》与《运尸车》,不容错过。
就此打住吧——当然,这并非无视于当代浩瀚的书籍世界,我们还需在脑海与文库中留有余地。不过,这已与我们的主题无关,哪一本书能超越若干世代长存下去,是无法由当代的人来评断的。
立于我们探寻的终点,回顾已完成的工作,难免会发觉破绽百出,无法面面俱到。在文库中列入《慕西豪森男爵冒险记》,而省略了印度的《圣薄伽梵歌》,这样做是正确的吗?如果我很公平,怎能省掉古西班牙的杰出喜剧作家、塞尔比亚人的民谣、爱尔兰的童话,以及其他种种作品?一卷格勒的短篇小说真能与塔西陀相称吗?《画家诺尔登》能与印度的《五编书》(Pañcatantra)或中国预言书《易经》相当吗?不,当然不能!
因此,很容易就可以看出来我的世界文学选集是极其主观而无准则的。可是,如要代之以极公平、客观的选择,不仅困难,简直可说是不可能的,除非采纳从少年时代起在文学史中提及的所有作家与作品。所谓文学史,其实就是作家与作品内容反复的解说,而且互相抄袭。要真正读完所有的作品,人寿何堪?坦白地说,德国诗人美好的诗句,我们可以体味其旋律至最深的境界,有时甚至超过梵文文学最高贵的作品,这是因为,对于梵文文学,我们只能借粗糙无味的译本去接近。
此外,作家及其作品的知识与评价,经常受变化多端的命运所支配。今天,我们已很尊重20年前文学史上未曾提及的作家。(突然想起我犯了重大的过错,我竟然忘记了《佛采克》《但顿之死》《雷昂斯与雷娜》的作者毕西纳115。当然,他是不可遗漏的!)
对生于今日的我们而言,古典时期德国文学中,我们认为最重要且最富生命力的作品,一定与25年前文学研究者称之为不朽的作品,大不相同。当德国国民读《塞金根之喇叭手》,学者们将特奥多顿·乔尔纳列为古典作家时,毕西纳即被忽略,布伦达诺则完全被遗忘,尚·保罗被目为放荡无行的天才而列入黑名单中!同样的,我们后代子孙,也许会认为我们今天的解释与评价极其落伍。即使学术方面,也很难保证不会如此。
评价上此种永恒变易,某些人被遗忘,数十年后又被发现、赞赏的现象,决非基于人性的弱点与游移,而是依从我们无法明言,却能感觉到的法则。换言之,一度超越某一时期继续发挥作用,以显示其真正价值的精神瑰宝,都是属于全人类的既存宝藏,而且会随不同时代之潮流与精神要求而再度被提出、检讨,并使之复活。我们的祖父辈论及歌德时,不仅与我们的观念完全不同,而且遗忘了布伦达诺,高估狄德格、雷德维治或其他时尚作家——甚至完全不知道人类重要书籍之一——老子的《道德经》。因为古老中国及其智慧的发现,是今日世界与时代的事件,而非祖父辈所能想象。当然,我们今天一定也会失去一些祖父辈相当了解的精神界伟大精美之处,而我们的子孙一定会再度予以发现。
## 第三章
在组构我们的理想小文库时,的确有点草率,遗漏了不少珠玉之作,也完全忽略了一些有力的文化圈。譬如埃及,那数千年持续不断的崇高文化。那辉耀的诸王朝、强有力的组织与可怕的死亡崇拜之宗教——这一切难道都毫无价值?都不值得保留在我们文库中吗?当然不是。对我而言,埃及的历史属于考察时可完全省略的书——亦即画本之类的书。诸如有关埃及人的艺术、含有美丽图画的册子、许坦因多尔夫与费西海摩等人的著作均属之。我经常看这类著作,因此对埃及亦有所知。但我不知道哪些书可以让我们真正亲近埃及文学。
很久以前,我曾热心阅读有关埃及宗教的著作,也能侃侃而谈埃及的原典、法律、墓志铭、赞歌与祈祷文。就内容而言,它们大都能引起我强烈的兴趣,可是,大部分都很难长记心中。这些都是真挚良好的书籍,但却不是古典之作。因此文库中没有埃及。我对自己不可解的健忘与怠慢相当自觉,不过,仔细回想起来,我对埃及的观念,绝非只源于那些画册与宗教史的著作,而是因为我读过绝不下于这些书籍、而且私心非常偏爱的希腊著作家希罗多德116的书。希罗多德醉心于埃及人,甚至尊重埃及人更甚于伊奥尼亚的同胞。我几乎忘了这位希罗多德,现在必须加以修正,他应居于希腊作家中的上席。
反复检视我所提出的理想文库书目,似乎极不完整,也有许多缺陷。不过,对于我们的文库,我最关心的并非体裁上的缺陷。这主观而无学者风味,但确实是根据不少知识与经验收集起来的文库,越是整体来看,越不容易看出犯了主观与偶然的毛病。而且刚好相反,我们的小理想文库,尽管有缺陷,但根本上,是太理想、太整齐、太像珠宝盒了。虽然遗漏了不少佳作,但各时代的文学中,最美丽的珠玉已完全具备,就质与客观价值而论,不可能有超越此一文库的书目了。
可是,站在精心制成的文库之前,不禁自问,拥有这文库的到底是些什么样的人?它不属于眼眶深陷、彻夜工作、禁欲的老学究,也不属于富丽堂皇时髦住宅中的社交名流,更不属于医生、牧师、上流贵妇。我们的文库,看起来非常整洁、理想,但无个性。这张目录,大部分爱读书的人,原则上都能同样列举出来。
如果以现实眼光来看我们的文库,我会认为,这文库不仅充满了值得信赖的作品,而且是真正佳美的文库——不过,这些书籍的拥有者中,难道没有追逐时尚的人吗?难道他们没有偏好或热情?难道除了两三部文学史外胸中空无一物?譬如说,他拥有狄更斯与巴尔扎克的小说各两部,这可能是因为听人劝告才购存的,如果他顺自己的个性主动加以选择,他也许会因为喜爱这两位作家,尽可能去搜集他们所有的作品,或者喜欢其中一位胜过另一位,也许喜欢美丽可爱而有魅力的狄更斯更甚于有野兽味道的巴尔扎克,或者喜爱巴尔扎克,希望拥有他的全集,却剔除太甜美、太诚实、太平民化的狄更斯。我属意的文库应该具有这种富有个性的特色。
为了提示如何扰乱那似乎太整齐、太中立的目录,而与书籍作有个性而生动热情的交往,我只有把自己作为一个读书人的热情完全倾吐出来。打从很早以前开始,我就过着一种与书为伍的生活,正确选读世界文学的努力,对我而言是相当熟悉的。广泛涉猎之后,我有义务去认知自己熟悉的种种事物。
可是这种读书方法以及为追求教养而公平学习外国文学的态度,是不合我性情的。我不断在书籍世界内部为某些特殊的挚爱所吸引,被特殊的新发现所魅惑,唤起新的热情。这类热情不断交替出现,其中有些热情经过一段时期后又再度回归,但另一些热情却仅展现一次就消灭了。因此,我自己的文库几乎包含了上述所有的书籍,但排列次序却不同。我的书散满各处,其中一部分只为了义务而收存,另一部分却像娇宠的爱儿一样,流露出特别被珍爱的样子。
这些获得特殊珍爱而被重视的书籍,在我的文库中为数不少,在此无法一一细述。我只想约略谈谈世界文学如何反映在个人身上?如何从各方面吸引读者?如何感化、形成个人的性格?如何由个人加以处理?
我自己很早就开始了对书籍的爱好与读书的欲望。少年时期,我所知道而能加以运用的唯一藏书就是我祖父的藏书。这包含几千册书的大收藏,大部分都引不起我的兴趣。这些书籍如何累积成如此庞大的数量,我完全不明白。好多册的历史与地理年鉴、英语与法语的神学书、金边的英国少年读物与宗教书、学术性杂志(有的用厚纸装裱整齐,有的按年份排列捆在一起)堆满了书架。这一切在当时的我看来,都是完全无聊,任其尘封,不值得保存的。
可是,这批藏书中也有些其他部门的作品,是后来我逐渐发现的。首先是几册单行本引起了兴趣,我开始逐一搜寻这批看来毫不引人入胜的藏书,终于发现了自己觉得有趣的东西。
其中有令格兰威尔看得入迷、有插图的《鲁滨逊漂流记》,也有18世纪30年代沉重四开本、有插画的德文版《一千零一夜》。这两本书有如尘封书海中的两粒珍珠,从此,我不停地搜寻客厅中高大书架的每一角落,经常在高梯上一坐数小时,有时更俯卧在堆满书本的地板上。
在这种神秘尘封的图书室中,我第一次发现了有价值的文学作品——18世纪的德国文学!
这批奇妙藏书中,居然具备了完整的18世纪德国文学,有《少年维特之烦恼》,有克洛普斯托克的《救世主》,有哥德维兹奇插有铜版画的数册年鉴,以及其他当时我还不十分明白的宝藏——九卷哈曼117的全集、云格·许提林与莱辛的全集、怀依塞与拉贝纳·格拉特118的诗集、《从梅美尔到萨克森的索菲之旅》六卷、一些文学新闻、若干卷尚·保罗的作品。
此外,我也是在那个时候才看到巴尔扎克的名字。那是他生前出版16开本蓝厚纸封面的几册德译本巴尔扎克。虽然第一次知道了这位作家,但我记得读了其中一卷时,完全不懂。主人翁的财务状况竟然描述得如此详尽,从他的财产每月可获益多少、母亲的遗产有多少、其他遗产预计有多少、借款为数若干等等,都一一写出。我非常失望,我所期待的是通往热情、诱惑、野蛮国度之旅,美丽的失恋体验,或者,对一个年轻人腰包中究竟有多少钱也极感兴趣!我厌恶地把这本蓝色小书又放回原处,从此以后,有一段很长的时间,我完全不碰巴尔扎克的作品。
直到很久以后,才逐渐改变过来,重新发现了他,这次才认真地读了下去。
因此,我对祖父藏书的体验主要是18世纪的德国文学。从中我认知了怪异、被遗忘的人物与作品——波德摩119的《诺亚的子孙》,格斯纳120的《牧歌》,格奥克·佛尔斯特121的《游记》,马提斯·克劳狄斯的全集,宫廷顾问官凡·艾嘉尔兹豪森的《彭嘉尔之虎》《修院故事》,希培尔的《各国漫游记》及其他。在这些古书中当然有许多无益的作品、被正当遗忘与排斥的书。但也有克洛普斯托克美妙的《赞歌》、格斯纳与魏兰德纯朴典雅的散文、哈曼奇妙动人心弦的精神之光。即使读了无聊作品,我也丝毫不后悔,因为真正从多方面认知历史上的时代,自有其益处在。
总之,我以博学专家也有所不及的完整性学习了一个世纪的德国文学。从旧式偏颇的书籍中传来了我亲爱祖国语言的气息,这世纪又正是古典主义开花结果的孕育期。我借这些藏书、年鉴、布满灰尘的小说与英雄叙事诗学习德文。此后,当我逐步认知了歌德与近代德国文学的全部精华后,我的耳朵与语言良知越来越尖锐,而且接受了足够的训练。我熟知而且精通歌德与德国古典文学所孕生的精神特性。至今,我仍然特别喜爱18世纪的文学。那许多被遗忘的文学作品仍然保存在我的藏书中。
若干年后——在这期间我累积了许多体验与读书经验——精神史另外的领域,亦即古印度开始吸引了我,不过,并非直线式的。我因朋友的介绍,认识了当时被称为接神术与神秘智慧记述的著作。这些著作有的非常厚,有的则只是片段陈旧的小册子。但都是令人毫无感觉的东西,读来很不愉快,充满教训语,而且有点卖弄小聪明。不过,虽有叫我厌恶的贫血与说教倾向,也有不能不让人发生共鸣的某种理性与超俗性。它们吸引了我一段相当长的时期。不久之后,我发现了它们魅人的秘密。隐秘不见的精神指导者向这些教派典籍作者细语陈述的所有奥义,展示了共同的出处,那源头就是印度,以此为出发点,我继续地探求下去。
不久后,我有了第一次的发现,心情激动地阅读[[《圣薄伽梵歌》]],这是一部可怕的译本。到今天为止,我读过好几种译本,但并未发现真正美的译本。可是,我已找到了开始探求时所预感的黄金穗粒,在印度式形体中发现了贯通亚洲的思想。
从那时起,我开始读有关“业”与轮回的矫饰著作,不再为其狭隘性及不重要的说教而气愤。我尽力想把原典中所能获得的东西当作我自己所有,于是,我认识了奥登保122与德逸森123的著作,以及他们从梵文翻译过来的德译本,还有雷奥波尔特·许雷德尔的著作《印度的文学与文化》和若干印度文学的旧译本。当时,古印度的智慧与思想和叔本华的思维世界一样,强烈地影响了我的思想与生活,达数年之久。虽然如此,不满与失望依然残留。首先,我所收集的印度原典译本,几乎都有数不清的缺点。只有德逸森的《六十奥义书》与诺曼124的《佛陀说法集》,让我纯粹而完整地体会并享受到印度哲学的境界。但这一切不应归罪于翻译,我在印度世界中所要追求的是一种欧洲无法发现的东西,也就是说一种智慧。我不仅预感到这种智慧的存在与可能性,甚至预感到它必然存在。可是,无论在什么地方都无法发现这种智慧已借语言的传达而实现。
可是,几年后,新书籍的体验终于带给我实现——如果可用“实现”这两个字来表现的话。在这之前,由于父亲的指示,我借格里尔的翻译认知了老子。其后,中国丛书陆续出版,以迄于今。我认为这是德国精神生活中最重要的事件之一,李希特·威尔黑姆125着手翻译中国文豪的作品。人类文化发展最高贵、崇高的精华,以往一直受到德国人冷淡的珍品,现在已成为我们的所有物。这稀贵的珍宝并不是经由拉丁或英文的迂回路线才到达我们眼前,也没有辗转经过第三者、第四者的手,而是直接由一个德国人的翻译赐给我们的。这个德国人,他半辈子都消磨在中国,对中国精神面的事物精通得吓人。他不仅精通中文,也精通德文,并且亲身体验到中国精神对今日欧洲的意义。这套丛书的第一本是孔子的《论语》,由耶纳的狄德利克斯书店刊行。我永远忘不了我是如何惊异、神驰地接受这本书!书中的一切对我是如何的生疏、如何的精确、如何符合我的预感,又如何的优美!
这套丛书陆续出版,堂皇有致,《孔子》之后接着是德译本的《老子》《庄子》《孟子》,吕不韦(《吕氏春秋》)、中国民间童话。同时,还有好几位翻译者,致力于翻译中国的抒情诗,与中国的通俗文学,获得了更伟大的成就。在这些方面,马丁·布伯、H.卢德斯保格、保罗·邱耐尔、雷奥·格莱纳等人,完成了值得赞美的工作,圆满地补充了李希特·威尔黑姆创始的事业。
15年间,对这些中国典籍,我的喜悦有增无已,大部分时间,我床边总放有其中的一册。印度人所欠缺的,在中国典籍中都非常丰富,其中充满对实际生活的接近、向最高道德迈进的高贵精神与感觉,日常生活中游戏和魅力之调和——崇高精神与纯真生活之乐的交流。如果说印度在禁欲与僧侣式的扬弃现世中,已臻及极高之境,那么,古代中国精神性的训练,所达到的优美境域,绝不下于印度。古代中国人认为,自然与精神、宗教与日常生活并不是敌对的,而是友好的对立,双方都有正当的权利,这就是古代中国精神性的训练。印度的禁欲式智慧,就其要求之彻底而论,可说是清教徒式的,中国的智慧则是累积经验以臻贤明之域,这种智慧不会因经验而幻灭,也不会流于浅薄,却可习得幽默。
德国最优秀的分子,在最近二十年间已接触到这使人获益匪浅的思潮。与性急喧闹、迅起迅落的许多精神运动并列而观,李希特·威尔黑姆的中国著作集虽然极其沉静,却不断增加其重要性与感化力。
对德国18世纪的偏爱、印度宗教的探求、中国学说与文学的日益亲近,使我的藏书内容迅速变化,也更加丰富。同样,其他种种体验与精神上的倾向,也改变、增加了我的藏书。有一段时期,我拥有庞德罗126、马斯提奥127、巴吉雷128、波吉欧等意大利杰出短篇小说家的原本。又有一段时期,我收集了一些其他民族的童话与传说,仍觉意犹未足,不过,这些兴趣很快就消失了。但有些方面的兴趣却长期留存,非但未随岁月流逝而减少,而且与日俱增。例如我对曾经铭感五内的人物回忆录、书简与传记的兴趣,即属此类。129
少年时期,有好几年时间,我尽量收集有关歌德其人及其生活的作品。对莫扎特的喜爱,也促使我披阅有关他的一切著述及绝大部分的书简。此外,我对萧邦、撰写《肯道尔》的法国诗人格兰、威尼斯画家吉奥尔吉昂,以及达·芬奇,都怀有同样的挚爱。关于这些人物,我所读到的未必是非常重要而有价值的书,但因心中怀有敬爱之情,故所得亦多。
今日社会似乎颇有轻视书籍的倾向。年轻人往往认为舍朝气蓬勃的生活而沉湎书本,是可笑而且没有价值的事,这类的年轻人为数甚多。他们认为人生太短暂,太可贵,因此不能耗费在书本上。他们往往一星期六次泡在咖啡馆的音乐或舞会中,浪费了许多光阴。现实世界的大学、工作场所、交易所与娱乐场所,也许极为灵动而富有生气,可是,终日停留在这些地方,难道比每日为古圣先贤、文士诗人留下一两小时,更接近真实的人生吗?的确,过分耽读有害无益。书本有时也会与生活做不纯的竞争,但我仍然劝告人们应献身于书籍。
该说、该谈的实在很多,在前文所述我个人读书的乐趣中,应该再附加一项,那就是对基督教中世纪神秘生活的探求。我对中世纪政治史的细微末节,没有丝毫兴趣,我认为只有两大势力——教会与帝国之间的紧张才重要。更吸引我的是僧侣的生活。这并不是因为僧侣的禁欲生活,而是我在僧侣的艺术与文学中发现了美轮美奂的宝藏,同时因为教团与修院成为虔诚、静观生活之避难所,实在值得钦慕,就文化与教养方面而言,教团与修院可说是最美妙、理想的场所。徜徉于僧侣式的中世纪,我并未将这类著作收入我们的文库,但却发现了许多我非常喜欢的书,以及值得列入我们书目的作品,例如陶乐130的《说教集》、索依塞131的生活、艾克哈特132的《说教集》等,均属之。
今天,我认为是世界文学精髓的作品,在我的父亲与祖父看来,也许不值一顾。同样,他年,我的孩子们,也许更不满意,认为我的看法太偏颇。这是难以避免的必然命运,可是,千万不要以为我们比父亲辈聪明。以客观与公正为目标,不断努力,是极其美丽的,但不可忘记,这往往只是难以实现的理想。读我们美丽的世界文库,不要存着当学者的念头,更不要想做世界的审判者。只是通过一道最容易进入的门,踏进精神的广场。让我们每个人都从自己能够了解、喜爱的作品开始吧!从报纸或眼前所见的现代文学中,我们无法学习崇高范畴定义下的“阅读”,只有靠读真正的杰作才能达成。大多数杰作都不像流行读物那样甜美,那样富于刺激性。杰作需要人们认真地接受与猎取。接受动作鲜明的舞蹈,比接受拉辛戏剧钢铁般严肃而富弹力的修辞要容易得多,也比接受史特恩与尚·保罗等人节奏微妙、丰富有韵致的幽默容易得多。
在我们证明杰作的真正价值之前,我们先要靠杰作来证明自己真正的价值。
## 后记
《世界文学文库》以新版问世,并非出于我自己的意愿,而是顺应多数读友的要求。虽然我认为极需加以新的修正,但又无法着手,人生短暂,日常工作的负荷是非常沉重的。这本小册子完成于我生命中一个令人思念的时代。以浩瀚书海中的第一座路标而言,也许仍有助于众多的探求者,直到他们能独立行走为止。
赫尔曼·黑塞
1948年12月,于利马河畔的巴登
三岛由纪夫的写作与生活-余华
========================
三岛由纪夫的写作与生活-[[余华]]
------
三岛由纪夫自杀之后,他的母亲倭文重说:“我儿做步人后尘的事,这是头一回。”作为母亲说这样的话,显然隐含了一种骄傲,这种骄傲是双重的,首先是对儿子一生的肯定,她的儿子只是在选择如何死去时,才第一次步人后尘;其次是对儿子自杀本身的肯定,在这句貌似遗憾,实质上仍然是赞扬的话里,这位母亲暗示了三岛由纪夫的自杀是与众不同的。
因为在三岛由纪夫这里,自杀不再是悄悄的、独自的行为,他将传统意义上属于隐秘的行为公开化了。新闻媒体的介入,使他的自杀不再是个人行为,而成为了社会行为。三岛由纪夫之死,可以说是触目惊心,就像是一部杰出作品的高潮部分。在这部最后的作品中,三岛由纪夫混淆了写作与生活,于是他死在了自己的笔下。
写作与生活,对于一位作家来说,应该是双重的。生活是规范的,是受到限制的;而写作则是随心所欲,是没有任何限制的。任何一个人都无法将他的全部欲望在现实中表达出来,法律和生活的常识不允许这样,因此人的无数欲望都像流星划过夜空一样,在内心里转瞬即逝。然而写作伸张了人的欲望,在现实中无法表达的欲望可以在作品中得到实现,当三岛由纪夫“我想杀人,想得发疯,想看到鲜血”时,他的作品中就充满了死亡和鲜血。
从这一点来说,三岛由纪夫的写作有助于他作为一个人的完善,使个人的双重性得到了互相补充,就像他自己所说的:“既当死刑囚,又当刽子手。”另一方面,写作使他的个人欲望无限扩张,使他的现实生活却是越来越狭窄。对于其他作家来说,写作仅仅只是写作,仅仅只是表达隐秘的想法和欲望,他们的欲望永远停留在内心里面,不会侵入到生活之中,在生活中他们始终是理性的和体面的。可是三岛由纪夫不是这样,他过于放纵自己的写作,让自己的欲望勇往直前,到头来他的写作覆盖了他的生活。
就像他作品中美和恶的奇妙结合一样,这种天衣无缝的结合让人们无法区分开来。他说:“如果世上的人是通过生活与行动来体味恶的话,我则尽可能深深地潜沉在精神界的恶里。”这句话其实是对恶的取消,人们通常只是以生活和行动的准则来判断什么是恶,什么是善。当恶一旦成为精神里的一部分,往往就不知所云了。
三岛由纪夫一再声称他对死、对恶、对鲜血淋淋的迷恋,在他的作品中,人们也经常读到这些,谁都知道这是事实。然而,三岛由纪夫与人们的分歧是如何对待这些,也就是站在什么样的立场上,通过什么样的角度来对待死亡、对待恶、对待鲜血。对于三岛由纪夫来说,这一切都是极为美好的,他的叙述其实就是他的颂歌,他歌颂死亡,歌颂丑恶,歌颂鲜血。这就是为什么他的叙述是如此美丽,同时他的美又使人战栗。
所以说,三岛由纪夫混淆了全部的价值体系,他混淆了美与丑,混淆了善与恶,混淆了生与死,最后他混淆了写作与生活的界限,他将写作与生活重叠到了一起,连自己都无法分清。
在三岛由纪夫作品中,《忧国》这部短篇的重要性,一定程度上来自于他后来自杀所产生的影响力,作品里武山中尉自杀的动机和自杀时的壮烈,与六年后三岛由纪夫在市谷自卫队总监室切腹自戕时几乎一致。他驱车前往自卫队时这样说:“六年前我写了《忧国》,现在又写了《丰饶之海》,没想到今天自己要实际表演了。真想象不出再过三小时我们就要死的样子是怎么样的。”
他说这番话时的轻松令人吃惊,他对待自己的死与对待作品中虚构人物的死没有什么两样,他既置身其间,又像局外人似的欣赏自己的自戕。他在自杀前所做的全部准备,就像是在构思一部新作一样,情节如何发展,细节和对话如何进行,他都成竹在胸。他开车赴死之时,车子还经过他长女纪子的学校门前,他开玩笑地说:“在这种时候,如果是电影,就会配上一段感伤的音乐了。”
他自杀的过程,由于《忧国》这部作品的对照,就成为了另一部作品。在《忧国》中,三岛由纪夫给了武山中尉充分的时间,他的叙述从容不迫,在武山和新婚之妻丽子经过肉体的狂欢以后,三岛由纪夫才让他盘腿坐下,解开军服,露出胸脯和腹部后,还让他用左手不停地搓揉着小腹,让他将刀刃从腿上轻轻划过,来试探军刀是否锋利……然而后来的现实,却没有给予三岛由纪夫足够的时间,他对自卫队队员的煽动失败后,他理想重振军国主义的《檄文》遭到嘲笑后,他嘟囔着“他们好像没怎么听我讲话”,马上解开了衣扣……与武山中尉相比,三岛由纪夫的切腹自戕就显得匆忙和局促了。
这里面存在着这样一个问题,武山中尉的切腹自戕是来自于三岛由纪夫的叙述,而三岛由纪夫自己的自戕只能依靠别人的叙述了。在《忧国》里,三岛由纪夫对武山自戕的描叙充满了热情和欢乐,在这狂欢似的描叙里,三岛由纪夫迷失了自己,到最后已经不再是三岛由纪夫在叙述《忧国》,而是《忧国》在叙述三岛由纪夫了。因此,六年以后当他身体力行时,来自别人的叙述是不可靠的,这种新闻式的记叙掩盖了三岛由纪夫自杀时的真正感受。好在六年前,三岛由纪夫在《忧国》里已经对自己的切腹自戕做出了全面的预告。事实上,三岛由纪夫自杀时唯一可靠的叙述就是“关孙六”,这把17世纪精美的短刀。当他用“关孙六”切开腹部时,随着鲜血的喷涌,他的叙述也就开始了。这时候,三岛由纪夫与他六年前虚构的武山中尉合二为一,于是人们也应该明白《忧国》中的武山中尉究竟是谁了。
三岛由纪夫在自杀前,有两件事不能完全放心,一件是《丰饶之海》英译本在美国出版的事宜,另一件就是担心自己的死会被掩盖起来。他对自杀所引起社会反应的关心,与关心一部作品问世后的反应是一样的,或者说他对后者显得更为忧心忡忡,因为他最后的作品并不是《丰饶之海》,而是切腹自戕。在生命的最后时刻,三岛由纪夫作品中所迷恋的死亡和鲜血,终于站了出来,死亡和鲜血叙述了三岛由纪夫。
一九九五年九月十八日
! 进行中
//待完成的任务清单//
<<list-tagged-draggable tag:"散文" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"你没有待处理的任务">>
! 已结束
//(已完成的任务清单)//
<$list filter="[!has[draft.of]tag[散文]tag[done]sort[created]]">
<div>
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
</div>
</$list>
的地平线上残留着一抹血红,夕阳西沉,绽射出几束长长的余晖,和大地告别。
考古学家米哈伊尔·葛利戈里耶维奇站在巨大无比的两座雕像脚边,他环顾四周的沙丘,隐隐地感到:这儿有什么东西发生了变化。究竟是什么呢?他却无法确定。惶恐不安的感觉占据了他的心头。米哈伊尔那稍稍绷紧的瘦削身材比起被风吹得粗糙的褐色面庞来,要显得年轻些。脸上有一双疲倦的过于安详的眼睛。但这双眼睛一盯住两座雕像,立即变得神采奕奕、炯炯发光。米哈伊尔端详着巍巍耸峙的雕像,竭力回忆当时的情景5年前,正在准备学位论文答辩的米哈伊尔有机会参加沙漠考察队,实地考察将对他的论文有很大帮助。在前往沙漠古城遗址的途中,米哈伊尔和另外两名考察队员因掉队而在沙漠中迷了路。就在这时候,他们偶然在沙丘之间发现了这两座雕像。那男人雕像的身材比女人雕像略微高些。米哈伊尔清楚地记得,那两座雕像的脸是用粗线条雕刻出来的,几乎分辨不出鼻子,也看不清耳朵,宽阔的嘴巴只是一个窟窿。
一对轮廓分明的眼睛在整个脸上显得异常突出,极不协调,菱形的瞳仁、虹膜上的青筋,以及直愣愣的梳状睫毛十分醒目。
雕像的身材很不匀称,甚至令人感到诧异:躯干和胳膊很长,两条腿却又短又细。考察队员们争论不休,却终究不能确定这两座雕像属于哪一种文化、哪一个时代。
米哈伊尔无论如何也忘不了自己乍一看见雕像的眼睛时的感受。他呼吸急促,呆若木鸡,无法把视线从这对眼睛上移开。他受着某种莫名其妙的外力的驱使,伸开双臂,像梦游似地向雕像走去,直至他的胸口撞到一座雕像的腿才停祝他感觉到他的大腿被什么东西灼了一下。他将一只手伸进口袋,不禁“哎呀”一声惊叫起来,他的黄铜烟盒滚烫滚烫的,仿佛在火上烤过一样。
米哈伊尔定了定神,朝四周扫了一眼。历史学教授两眼瞪得像铜铃,臂膀紧贴着身子,纹丝不动地愣在那里,看上去比雕像更像雕像。就连一向对任何事物都不以为然的费多罗夫也承认,他在这儿“感到有点不太自在”。费多罗夫还偷偷干了一件考古工作最忌讳的事情。他从女人雕像的脚上敲下了一小块标本,打算带回实验室进行研究,以确定这些雕像取材于什么物质。这种物质显然不同寻常——它有着某种涡形的纹路,表面还蒙着一层天蓝色的液滴。
几天之后,一架飞机发现了迷路的考察队员。在飞往列宁纳巴德时,米哈伊尔他们立下了早日重返沙漠研究这些雕像的夙愿。
可是不久,伟大的卫国战争爆发了。米哈伊尔上了前线。
历史学教授在彼得堡被围困期间与世长辞了。费多罗夫也在一次实验室爆炸事故中罹难。爆炸正是在他研究那块雕像物质时发生的。一位实验室的助手断定,肇事的祸根就是那一小块物质。他说,那东西犹如一种活性极强的酶,能加速一些反应,延缓另一些反应。正由于这个原因,引起易燃物质猝然起火、爆炸。
战争结束后,米哈伊尔又恢复了以往的生活,他打算重新开始那些原先没有完成的研究,当然首先是要去探究那两座雕像的奥秘。米哈伊尔得知,在这之前曾有一支小型考察队到发现雕像的沙漠里去过,但没有找到雕像,也许它们被流沙覆盖了。
米哈伊尔很快组织了一支新的考察队,从列宁纳巴德启程向沙漠进军。
米哈伊尔头脑中有一个不太肯定的设想:也许某个时候曾有一艘宇宙飞船在沙漠中着陆,也许是飞船中有理性的生物留下了这些雕像,作为到过地球的标志。这种假设对雕像的奇怪模样、对构成雕像的神奇物质,以及对其他许多问题都能作出解释,但也并非无懈可击。
考察队的一架飞机终于在沙漠上空发现了寻觅已久的雕像。现在米哈伊尔正站在雕像面前。
落日尚未全部从地平线上隐去。天地尽头,沙砾似乎正在熔化,形成一条奔腾的火龙。一阵风吹过,沙子簌簌作响。
只有雕像仍旧纹丝不动地站在那里,仿佛比这沙漠更缺乏生气。整整五年,它们就这样一动不动地矗立着,狂风泄怒于这些高大的障碍,从四面八方侵蚀它们。时光像沙子一样从它们身边流逝,带走人间的欢乐和痛苦但米哈伊尔总感觉这儿发生了某些变化,却又说不出变化在哪里。为此,他既感到生气,又有些惶惑。他从口袋里掏出钱夹,取出一张照片,那是五年前他在雕像前的留影。这是怎么回事啊?这不可能!不可能!
米哈伊尔把目光从照片移向雕像,然后重又移回照片。照相机是不可能出差错的,莫非是他的眼睛看花了不成。他走近一些,又退后几步。不,眼睛并没有看花。照片上,那座女雕像笔直地站着,两手下垂;而眼前,她已改变了姿势:两膝微屈,一只手伸向脚边,伸向被敲掉一块的那个地方。而那座男雕像则向前跨了一步,朝那女雕像侧过半边身子,仿佛在庇护她,右手伸向前方,握着一件武器一样的东西。
这一切意味着什么呢?对于米哈伊尔来说,周围的一切都已荡然无存。他的脑海里除了雕像,再没有其他任何事物。
他两眼闪闪发光,被太阳晒成褐色的脸上泛平淡淡的红晕。他所学过的知识在他记忆的屏幕上一一闪过。大象可以生存几十年,而某些种类的昆虫却只能活若干小时。但是,如果对某只大象和某只昆虫一生的动作分别进行统计,结果表明,它们的数量几乎是相等的。新陈代谢和生命持续的时间并不固定,它们因物种而异,差异幅度极大。例如葶苈属植物的全部生长过程在五六周内即可结束,但红杉属植物却能生长几千年。
一个中心思想已经越来越清晰,越来越明确。即使就地球上的生物而论,其生命的基本过程所持续的时间也相去极远,以致一种生物与另一种生物相比,差异就像一天与十年或一百年相比那样悬殊。老鼠把食物全部消化掉,至多不过需要一至一个半小时,而蛇却要几个星期。某些细菌的细胞每隔一两个小时就发生分裂,而许多高级组织的细胞却要好几天才能分裂一次。每种生物都有自己的时间、自己的空间和自己的生命期限。对于动作迅速的蚂蚁来说,软体动物简直就是化石。
两座雕像仍旧纹丝不动地矗立在那儿,但米哈伊尔已经领悟到这种静止不动只是一种假象,这根本就不是什么雕像,而是来自其他行星,来自另一个世界的生物,他们由另一种材料构成,他们有自己的时间。我们这儿的一百年,对于他们来说,只不过是一瞬间。显然,他们那儿非生物界的运动过程,也是按照另外一种节律,一种较慢的节律进行的。这个女人感到脚上疼痛,并开始对此作出反应,这竟用了五年时间;那个男人则用了五年时间才向前跨了一步。
在这五年时间里,米哈伊尔经历了漫长的生活历程,他结识了一些朋友,也失去了一些同志,他对自己有了正确的认识,并在战火中体验到了爱和恨。他经受了千辛万苦,尝到了痛楚、绝望、欢乐、悲伤和幸福的滋味。而这些生物的神经脉冲却缓慢地沿着他们的神经系统向前传送,向那女人发出疼痛的信号,向男人发出危险的信息。这些年来,那妇女一直在把手伸向感到疼痛的地方,那男人则在抬腿,以迎着危险再跨前一步。这似乎令人难以置信,但米哈伊尔却非常清楚,自然界一切都有可能发生,它千姿百态,变幻无穷。
米哈伊尔的脑海里一下子涌现出许多问题。那男人拿的是什么样的武器?它的杀伤力强吗?要过多少年那男人才射击呢?但他很快认为这些问题是多么无足轻重,地球上的居民要对付这些天外来客是轻而易举的,他们可以击落那男人手中的武器,也可以用钢缆把这些生物捆绑起来。谁的时间推移得快,谁就能取得胜利。
米哈伊尔考虑的是怎样去和这些天外来客交往?怎样去了解他们的故乡,并向他们介绍地球?要知道,今天向他们提出问题,要过几十年才能为他们所理解;等他们对此作出答复,那又要过去几十年、几百年。何况,地球居民和天外来客要取得哪怕是最起码的相互了解,也必须提出许多问题,这样就需要几千年时间。而这些由祖先提出的问题,对后人得失去任何意义,他们又将提出自己感兴趣的问题,这样又要几千年时间米哈伊尔不敢去考虑自己的生命期限。它是多么微乎其微,转瞬即逝,如同沧海一粟,而他却把它看得如同整整一个时代。他知道他的时光并未虚度,他将留下他的事业,他打开了新的历史篇章,他领悟了从前不能想象的事情,他识破了雕像的奥秘。
米哈伊尔思潮澎湃,他知道他的忧虑是多余的。地球居民一定能找到与天外来客交往的办法。那些今天还办不到的事情,明天一定能够成为现实。而他的生命则和所有人的生命一样,不会受任何期限的制约,而是由各人自己来决定的。
有的人生活得毫无价值,庸庸碌碌,另一些人却生活得高尚伟大,多姿多彩。“瞬间”这个概念是非常相对的。人生的一秒钟并不是钟表的“滴答”一声这么简单,而是指人在这一秒钟内所做的事情。这一秒钟可以是无所作为,也可以具有划时代的意义。一秒钟之内,地球运行一定路程,风儿掠过一定距离,蚂蚁爬过一段小路。人可以根本不介意一秒钟时间,也可以用一秒钟按动电钮,将火箭送入太空;可以无聊地打个呵欠,也可以发现一条新的自然规律。时间是自然界的万物之主,而人则是自己时间的主人。
沙漠尽头火红的地平线正渐渐暗淡下去,一堵墙垣似的火烧云已隐没在沙丘后面,唯有一长束橘红色的余晖告诉人们,太阳是在这儿被不可抗拒的时间送走的。
沙田山居-余光中
========================
沙田山居-[[余光中]]
-----
书斋外面是阳台,阳台外面是海,是山,海是碧湛湛的一弯,山是青郁郁的连环。山外有山,最远的翠微淡成一袅青烟,忽焉似有,再顾若无,那便是,大陆的莽莽苍苍了。日月闲闲,有的是时间与空间。一览不尽的青山绿水,马远夏圭的长幅横披,任风吹,任鹰飞,任渺渺之目舒展来回,而我在其中俯仰天地,呼吸晨昏,竟已有十八个月了。十八个月,也就是说,重九的陶菊已经两开,中秋的苏月已经圆过两次了。
海天相对,中间是山,即使是秋晴的日子,透明的蓝光里,也还有一层轻轻的海气,疑幻疑真,像开着一面玄奥的迷镜,照镜的不是人,是神。海与山绸缪在一起,分不出,是海侵入了山间,还是山诱俘了海水,只见海把山围成了一角角的半岛,山呢,把海围成了一汪汪的海湾。山色如环,困不住浩渺的南海,毕竟在东北方缺了一口,放樯桅出去,风帆进来。最是晴艳的下午,八仙岭下,一艘白色渡轮,迎着酣美的斜阳悠悠向大埔驶去,整个吐露港平铺着千顷的碧蓝,就为了反衬那一影耀眼的洁白。起风的日子,海吹成了千亩蓝田,无数的百合此开彼落。到了夜深,所有的山影黑沉沉都睡去,远远近近,零零落落的灯全睡去,只留下一阵阵的潮声起伏,永恒的鼾息,撼人的节奏撼我的心血来潮。有时十几盏渔火赫然,浮现在阒黑的海面,排成一弯弧形,把渔网愈收愈小,围成一丛灿灿的金莲。
海围着山,山围着我。沙田山居,峰回路转,我的朝朝暮暮,日起日落,月望月朔,全在此中度过,我成了山人。问余何事栖碧山,笑而不答,山已经代我答了。其实山并未回答,是鸟代山答了,是虫,是松风代山答了。山是禅机深藏的高僧,轻易不开口的。人在楼上倚栏杆,山列坐在四面如十八尊罗汉叠罗汉,相看两不厌。早晨,我攀上佛头去看日出,黄昏,从联合书院的文学院一路走回来,家,在半山腰上等我,那地势,比佛肩要低,却比佛肚子要高些。这时,山什么也不说,只是争噪的鸟雀泄露了他愉悦的心境。等到众鸟栖定,山影茫然,天籁便低沉下去,若断若续,树间的歌者才歇下,草间的吟哦又四起。至于山坳下面那小小的幽谷,形式和地位都相当于佛的肚脐,深凹之中别有一番谐趣。山谷是一个爱音乐的村女,最喜欢学舌拟声,可惜太害羞,技巧不很高明。无论是鸟鸣犬吠,或是火车在谷口扬笛路过,她都要学叫一声,落后半拍,应人的尾音。
从我的楼上望出去,马鞍山奇拔而峭峻,屏于东方,使朝曦姗姗其来迟。鹿山巍然而逼近,魁梧的肩膂遮去了半壁西天,催黄昏早半小时来临,一个分神,夕阳便落进他的僧袖里去了。一炉晚霞,黄铜烧成赤金又化作紫灰与青烟,壮哉崦嵫的神话,太阳的葬礼。阳台上,坐看晚景变幻成夜色,似乎很缓慢,又似乎非常敏捷,才觉霞光烘颊,余曛在树,忽然变生咫尺,眈眈的黑影已伸及你的肘腋,夜,早从你背后袭来。那过程,是一种绝妙的障眼法,非眼睫所能守望的。等到夜色四合,黑暗已成定局,四围的山影,重甸甸阴森森的,令人肃然而恐。尤其是西屏的鹿山,白天还如佛如僧,蔼然可亲,这时竟收起法相,庞然而踞,黑毛茸蒙如一尊暗中伺人的怪兽,隐然,有一种潜伏的不安。
千山磅礴的来势如压,谁敢相撼?但是云烟一起,庄重的山态便改了。雾来的日子,山变成一座座的列屿,在白烟的横波回澜里,载浮载沉。八仙岭果真化作了过海的八仙,时在波上,时在弥漫的云间。有一天早晨,举目一望,八仙和马鞍和远远近近的大小众峰,全不见了,偶尔云开一线,当头的鹿山似从天隙中隐隐相窥,去大埔的车辆出没在半空。我的阳台脱离了一切,下临无地,在汹涌的白涛上自由来去。谷中的鸡犬从云下传来,从敻远的人间。我走去更高处的联合书院上课,满地白云,师生衣袂飘然,都成了神仙。我登上讲坛说道,烟云都穿窗探首来旁听。
起风的日子,一切云云雾雾的朦胧氤氲全被拭净,水光山色,纤毫悉在镜里。原来对岸的八仙岭下,历历可数,有这许多山村野店,水浒人家。半岛的天气一日数变,风骤然而来,从海口长驱直入,脚下的山谷顿成风箱,抽不尽满壑的咆哮翻腾。蹂躏着罗汉松与芦草,掀翻海水,吐着白浪,风是一群透明的猛兽,奔踹而来,呼啸而去。
海潮与风声,即使撼天震地,也不过为无边的静加注荒情与野趣罢了。最令人心动而神往的,却是人为的骚音。从清早到午夜,一天四十多班,在山和海之间,敲轨而来,鸣笛而去的,是九广铁路的客车、货车、猪车。曳着黑烟的飘发,蟠蜿着十三节车厢的修长之躯,这些工业时代的元老级交通工具,仍有旧世界迷人的情调,非协和的超声速飞机所能比拟。山下的铁轨向北延伸,延伸着我的心弦。我的中枢神经,一日四十多次,任南下又北上的千只铁轮轮番敲打,用钢铁火花的壮烈节奏,提醒我,藏在谷底的并不是洞里桃源,住在山上,我亦非桓景,即使王粲,也不能不下楼去:
栏杆三面压人眉睫是青山
碧螺黛迤逦的边愁欲连环
叠嶂之后是重峦,一层淡似一层
湘云之后是楚烟,山长水远
五千载与八万万,全在那里面……
山鲁佐德的故事-余华
========================
山鲁佐德的故事-[[余华]]
-----
《一千零一夜》第351夜,山鲁佐德的冒险之旅刚刚走过三分之一,虽然她还没有改变山鲁亚尔来源于嫉妒的残暴,不过她用故事编织起来的陷阱已经趋向了完美,她的国王显然听从了那些故事的召唤,在痴迷之中将脚踩进了她的陷阱。于是,这位本来只有一夜命运的宰相之女,成功地延长了她的王后之夜。这一夜,这位将美丽和智慧凝聚一身的阿拉伯女子故伎重演,讲述的是一个破产的人一梦醒来又恢复财富的故事:
一个古代巴格达的富翁,因为拥有了无数的财产,所以构成了他挥金如土和坐吃山空的生活,最后就是一贫如洗。从荣华富贵跌入到贫穷落寞,这个人的内心自然忧郁苦恼,他终日闷闷不乐。有一天,他在睡梦里见到有人走过来对他说:“你的衣食在埃及,上那儿去寻找吧。”
他相信了梦中所见,翌日就走上了背井离乡之路。在漫漫长途的奔波跋涉和心怀美梦的希望里,巴格达人来到了埃及。他进城时已是夜深人静,很难找到住宿,就投宿在一座礼拜堂中。当天夜里,礼拜堂隔壁的人家被盗,一群窃贼从礼拜堂内越墙去偷窃。主人梦中惊醒,呼喊捉贼,巡警闻声赶来,窃贼早已逃之夭夭,只有这个来自巴格达的穷光蛋还在堂中熟睡,于是他被当成窃贼扔进了监狱,饱尝一顿使其差点丧命的毒打。巴格达人度过了三天比贫困更加糟糕的牢狱生活后,省长亲自提审了他,问他来自何处。他回答来自巴格达;省长又问他为何来到埃及。他就想起那个曾经使他想入非非如今已让他伤心欲绝的美梦来,他告诉省长梦中有人说他的衣食在埃及,可是他在埃及得到的衣食却是一顿鞭子和牢狱的生活。
省长听后哈哈大笑,他认为自己见到了世上最愚蠢的人,他告诉巴格达人,他曾经三次梦见有人对他说:“巴格达城中某地有所房子,周围有个花园,园中的喷水池下面埋着许多金银。”省长并不相信这些,认为这些不过是胡思乱梦,而这巴格达人却不辞跋涉来到埃及,巴格达人的愚蠢给省长带去了快乐,省长给了他一个银币,让他拿去做路费,对他说:“赶快回去做个本分人吧。”
巴格达人收下省长的施舍,迅速起程,奔回巴格达。在省长有关梦境中那所巴格达房子的详尽描述里,他听出来正是自己的住宿。他一回家就开始了挖掘,地下的宝藏由此显露了出来──
与山鲁佐德讲述的其他故事一样,这个故事在现实和神秘之间如履薄冰,似乎随时都会冰破落水,然而山鲁佐德的讲述身轻如燕,使叙述中的险情一掠而过。山鲁佐德让梦中见闻与现实境遇既分又合,也就是说当故事的叙述必须穿越两者相连的边境时,山鲁佐德的故事就会无视边境的存在,仿佛行走在同样的国土上,而当故事离开边境之后,现实的国度和神秘的国度又会立刻以各自独立的方式呈现出来。这几乎是《一千零一夜》中所有故事叙述时的准则,它们的高超技巧其实来自于一个简单的行为:当障碍在叙述中出现时,解决它们的最好方式就是对它们视而不见。
显然,组成这个故事的基础是不断出现的暗示。我所说的暗示带有某些迷信的特征,就像巴格达人得到梦的启示一样,他此后风餐露宿的艰难经历只是为了证明梦中的见闻,而在叙述中以梦的形式出现的暗示其实十分脆弱和可疑。即使是阅读者,在它刚出现时对待它的态度也大多会和省长一致,很少会和巴格达人一致。仿佛是让行走者在一条道路上看到了很多方向,暗示的不可确定性不仅使人物的命运扑朔迷离,而且让故事也变得宿命了。这时候只有将迷信的激情注入到命运的暗示之中,方向才会逐渐清晰起来,然而前景仍然难以预测。山鲁佐德这个故事的迷人之处,在我看来,是让后面出现的暗示对前面暗示的证实。当巴格达人向省长讲述自己为何来到埃及后,省长讲述了自己的梦中见闻,故事的叙述出现了奇妙的汇合,巴格达人之梦和省长之梦在审讯里相逢。省长之梦是故事里第二个出现的暗示,这时候第一个暗示成为了它的梯子,使它似乎接近了宝藏。于是巴格达人选择了第二个梦境所指出的方向,与第一个梦境完全相反的方向,他回到了家中。让一个暗示去证实另一个暗示,从而使这个第351夜的故事始终沉浸在叙述的梦游里,一切都显得模棱两可和似是而非,直到巴格达人挖出了地下的宝藏,故事才如梦方醒。至于故事中有关宝藏的主题,在这里仅仅是叙述的借口,使故事前行时有一个理由,而且这样的理由随时都可以更换。因此,一个与宝藏无关的主题同样可以完成这个巴格达人的故事。正如人们常说的金钱是身外之物,对故事来说更是如此。
《一千零一夜》将民间世俗的理想、圆滑的人情世故、神秘主义的梦幻、现实主义的批判性,以及命运的因果报应和道德上的惩恶扬善熔于一炉,其漫长和庞杂的故事犹如连成一片后绵延不绝的山峰。然而重要的是──只要仔细阅读全书就会发现,叙述中合理的依据在其浩瀚的篇幅里随处可见,或者说正是这些来自于现实的可信的依据将故事里的每一个转折衔接得天衣无缝。
在其开篇《国王山鲁亚尔及其兄弟的故事》里,山鲁亚尔和沙宰曼兄弟在被他们各自的王后背叛之后,他们不再相信女人的诺言,开始信任某一位诗人的话──女人的喜怒哀乐,总是和她们的身体紧密相关。这位诗人接着说:“她们的爱情是虚伪的爱情,衣服里包藏的全是阴险。”然后诗人警告道:“莫非你不知道老祖宗亚当的结局,就是因为她们才被撵出乐园。”于是山鲁亚尔在此后对女人的残暴获得了逻辑的源泉,然后《一千零一夜》的讲述者山鲁佐德应运而生了。
山鲁佐德来到宫中,这位一夜王后延长她命运的法宝就是不断地去讲述那些令人着迷的故事。因此在这漫长叙述里的第一个重要的衔接出现了,那就是山鲁佐德如何开始向山鲁亚尔讲述她的故事?《一千零一夜》中遍布这样的转折,这些貌似平常的段落其实隐藏着叙述里最大的风险,因为它们直接影响了此后的叙述,在那些后来的展开部分和高潮部分里,叙述的基础是否坚实可信往往取决于前面转折时的衔接。山鲁佐德为自己的讲述寻找到了合理的依据,她让自己的妹妹在这一夜来到宫中,并且让妹妹提出让她讲述故事的请求。山鲁佐德向国王申请再见一面妹妹的理由是“作最后的话别”,国王自然同意。于是姐妹两人在宫中拥抱了,然后一起坐到床脚下,妹妹向山鲁佐德请求讲述一个故事,为的是让这个死亡之夜尽量快活。山鲁佐德顺水推舟:“只要德高望重的国王许可,我自己是非常愿意讲的。”国王山鲁亚尔并不知道这是陷阱的开始,他欣然允诺,使自己也成为一名听众,而且将自己听众的身份持续了一千零一夜。
《一千零一夜》的叙述者没有让山鲁佐德以直接的方式对国王说──让我讲一个故事,而是以转折的方式让她的妹妹敦亚佐德来到宫中,使讲述故事这一行为获得了最大限度的合理性。这似乎就是叙述之谜,有时候用直接的方式去衔接恰恰会中断叙述的流动,而转折的方式恰恰是继续和助长了这样的流动。叙述中的转折犹如河流延伸时出现的拐弯,对河流来说,真实可信的存在方式是因为它曲折的形象,而不是笔直的形象。
在《洗染匠和理发师的故事》里,我们读到了两个相反的形象,奸诈和懒惰的艾彼· 勾尔与善良和勤快的艾彼·绥尔。正如人们相信人世间经常存在着不公正,故事开始时好吃懒做和造谣撞骗的洗染匠与辛勤工作和心地单纯的理发师得到的是同样的命运──都是贫穷,于是两个绝然不同的人携手外出,他们希望能在异国他乡获得成功和财富。艾彼·勾尔是个天生的骗子,他的花言巧语使艾彼·绥尔毫无怨言地以自己的勤劳去养活他。以吃和睡来填充流浪中漫长旅途的艾彼·勾尔,在艾彼·绥尔病倒后偷走了他全部的钱财,然后远走高飞。山鲁佐德告诉我们:骗子同样有飞黄腾达的时候。当艾彼·勾尔来到某一城中,发现这里的洗染匠只会染出蓝色时,他去觐见了国王,声称他可以洗染出各种颜色的布料,国王就给了他金钱和建立一座染坊所需的一切。艾彼·勾尔一夜致富,而且深得国王的信任。然后故事开始青睐倒霉的艾彼·绥尔了,这位善良的理发师从病中康复后,终于知道了他的伙伴是一个什么人。可是当一贫如洗的他来到同样的城市时,他立刻忘记了艾彼·勾尔对他的背叛,他为艾彼·勾尔的成功满心欢喜,并且满腔热情地来到艾彼·勾尔高高的柜台前。接下去的情节是故事中顺理成章的叙述,艾彼·勾尔对艾彼·绥尔的迎接是指称他为窃贼,让手下的奴仆在他背上打了一百棍,又将他翻过来在胸前打了一百棍。以后就该轮到好人飞黄腾达了,这不仅仅是《一千零一夜》的愿望,差不多是所有民间故事叙述时的前途。山鲁佐德让伤心和痛苦的艾彼·绥尔发现城中没有澡堂,于是他也去觐见了国王,仁慈和慷慨的国王给了他多于艾彼·勾尔的金钱,也给了他建造一座澡堂的一切。于是艾彼·绥尔获得了超过艾彼·勾尔的成功,他的善良使他不去计较金钱,让顾客以自己收入的多少来付账,而且无论是王公贵族还是平民百姓,他都以同样的殷勤去招待。在山鲁佐德的故事里,坏蛋总是坏得十分彻底,他们损人往往不是为了利己,而是为了纯粹的损人。出于同样的理由,艾彼·勾尔设计陷害了艾彼·绥尔,让国王错误地以为艾彼·绥尔企图谋害他,国王决定处死善良的艾彼·绥尔。于是好人有好报的故事法则开始生效了,死刑的执法者是一位去过艾彼·绥尔的澡堂并且受到其殷勤侍候的船长,他相信艾彼·绥尔的为人,释放了他。后来艾彼·绥尔重新赢得了国王的信任,而艾彼·勾尔则是恶有恶报,最后轮到他被处死。处死他的方法曾经是处死艾彼·绥尔的方法,那就是将他放入一个大麻袋中,又将石灰灌满麻袋后扔进大海,这是一个充满了想象力的刑罚。艾彼·绥尔化险为夷,躲过此劫;艾彼·勾尔则不可能在《一千零一夜》里获得同样的好运,他被扔进了大海。他在被海水淹死的同时,也被石灰活活地烧死。
离奇曲折和跌宕起伏几乎是《一千零一夜》中所有故事的品质,也是山鲁佐德能够在山鲁亚尔屠刀下苟且偷生的法宝。在故事中,艾彼·绥尔重新获得国王的信任就是出于离奇和跌宕的理由。在好心的船长手里捡回生命的艾彼·绥尔,开始了渔夫的生涯。如同其他故事共有的叙述,落难之后往往会获得重新崛起的机遇,艾彼·绥尔在打上来的某一条鱼的肚子里看到了一枚宝石戒指,这枚神奇的戒指戴在手指上以后,只要举手致意,那么眼前的人就会人头落地。这是国王的宝石戒指,他之所以能够统辖三军,是因为人们慑于这枚戒指的威力。山鲁佐德紧凑地讲述着她的故事,她让国王失落权力的戒指与艾彼·绥尔的命运紧密相连,因此国王宝石戒指的失而复得也必然是艾彼· 绥尔重获荣华富贵的开始。当船长释放艾彼·绥尔之后,他将一块大石头放入麻袋中以假乱真。船长划着小船来到宫殿附近,此刻的国王坐在临海的宫窗前,船长问国王是不是可以将艾彼·绥尔抛入海中,国王说抛吧,国王说话的时候举起戴着宝石戒指的右手一挥,一道闪光从他的手指上划到了海面,戒指掉入了大海。然后,戒指来到了艾彼·绥尔的手上。那个处死艾彼·绥尔的挥手,不久之后就转换成了他的幸运。艾彼·绥尔决定将戒指还给国王,以此来表示他的忠诚。于是,艾彼·绥尔的命运就像是一只暴跌后见底的股票,开始了强劲无比的反弹。
我欣赏的正是国王挥手间戒指掉入大海的描述,在离奇和跌宕不止的情节间的推动和转换里,山鲁佐德的讲述之所以能够深深地吸引着山鲁亚尔,有一点就是人物动作和言行的逼真描写,山鲁佐德说得丝丝入扣。她的故事就是在细节的真实和情节的荒诞之间,同时建立了神秘的国度和现实的国度,而且让阅读者无法找到两者间边境的存在。正是这样的讲述,使山鲁亚尔这个暴君在听到这些离奇故事的同时,内心里得到的却是合情合理的故事。这也是《一千零一夜》为什么会吸引我们的秘密所在。清晰明确和简洁朴素的叙述──这几乎是它一成不变的讲述故事的风格,然而当它的故事呈现出来时却是出神入化和变幻莫测。
可以这么说,《一千零一夜》是故事的广场,它差不多云集了故事中的典范。它告诉了我们:在故事里什么才是最为重要的。就像国王处死艾彼·绥尔的挥手,这个挥手是如此的平常和随便,然而正是在这个会让人疏忽和视而不见的动作里,孕育了此后情节的异军突起。在此之前,国王的挥手与好运卷土重来的艾彼·绥尔之间似乎有着漫长的旅途,犹如生死之隔。可是当两者相连之后,阅读者才会意识到山鲁佐德的讲述仿佛是一段弥留之际的经历,生死之隔被取消了,两者间曾经十分遥远的距离顷刻成为了没有距离的重叠。第351夜的故事也同样如此,当省长的梦和巴格达人的梦在埃及相遇之时,阅读者期待中的最后结局也开始生根发芽了。《一千零一夜》告诉我们的就是这些:什么才是故事?什么才是故事前行时铺展出去的道路?我们总是沉醉在叙述中那些最为辉煌的段落之中,那些出人意料和惊心动魄的段落,那些使人想入非非和心醉神迷的段落;山鲁佐德的故事指出了这些华彩的篇章,这些高潮的篇章和最终结束的篇章其实来自于一个微小的和不动声色的细节,来自于类似国王挥手这样的描述,就像是那些粗壮的参天大树其实来自于细小的根须一样。
在我看来,这不仅仅是《一千零一夜》的叙述道路,也是其他故事成长时的座右铭,比如莎士比亚讲述的故事和蒙田经常引用的故事。毫无疑问,在夏洛克和安东尼奥签订契约时,莎士比亚就是要让这位狡诈的犹太商人忘记了一个事实的存在:如果割下安东尼奥身上一磅肉的话,同时会有安东尼奥的血。于是,夏洛克的这个疏忽造就了《威尼斯商人》里情节的跌宕和叙述的紧张;造就了想象的扩张和情感的动荡;造就了胜利和失败、同情和怜悯、正义和邪恶、生存和死亡;一句话,就是这个小小的细节造就了《威尼斯商人》的经久不衰。同样的道理,蒙田在《殊途同归》一文里,向我们讲述了日耳曼皇帝康拉德三世的故事,这位公元10世纪时期以强悍著名的皇帝,在他率部下包围了他的仇敌巴伐利亚公爵后,对巴伐利亚公爵提出的诱人条件和卑劣赔罪不屑一顾,他决心要置他的仇敌于死地。然而10世纪流行的胜利者的风度使康拉德三世丧失了这样的机会,他为了让同巴伐利亚公爵一起被围困的妇女保全体面,允许她们徒步出城,而且做出了一个微不足道和顺理成章的决定,允许这些妇女将能够带走的都带走。正是这个小小的让人几乎无法产生想象力的决定,使康拉德三世对巴伐利亚公爵的包围失去了意义。当这些被释放的妇女走出城来时,康拉德三世看到了一个辉煌和动人的场景,所有的妇女都肩背着她们的丈夫和孩子,他的仇敌巴伐利亚公爵也在其妻子的肩膀上。故事的结局是这些心灵高尚的妇女让康拉德三世感动得掉下了眼泪,使他对巴伐利亚公爵的刻骨仇恨顷刻间烟消云散。
斯蒂芬·茨威格一度迷恋于传奇作品的写作,这些介于历史和文学之间的叙述,带有明显的斯蒂芬·茨威格的个人倾向。我的意思是说,这位奥地利作家试图像一个历史学家那样去书写真实的历史事件,同时小说家的身份又使他发现了历史中的细小之处。对他来说,正是这些细小之处决定了那些重大的事件,决定了人的命运和历史的方向,他的任务就是强调这些细小之处,让它们在历史叙述中突现出来。用他自己的比喻就是有时候避雷针的尖端会聚集太空里所有的电,他相信一个影响深远的决定其实来自于一个日期、一个小时,甚至是来自于一分钟。为此在他的笔下,拜占庭的陷落,或者说是君士坦丁堡的陷落并不是因为奥斯曼土耳其人的强大攻势,而是因为那个名叫凯卡波尔塔的小门。奥斯曼土耳其人,这些安拉的奴仆,在他们的苏丹率领下包围和进攻这座希腊旧城,而罗马人在他们的皇帝指挥下,一次次将攻城的云梯推下墙头,眼看着拜占庭就要得救了,眼看着巨大的苦难就要战胜野蛮的进攻之时,一个悲剧性的意外发生了。这个意外就是凯卡波尔塔小门,它是和平时期大门紧闭时供行人出入所用,正是因为它不具有军事意义,罗马人忘记了它的存在。凯卡波尔塔小门敞开着,而且无人把守,土耳其人发现了它,然后攻入了城中。就这样,强盛了一千多年的东罗马帝国被凯卡波尔塔小门葬送了。出于同样的理由,斯蒂芬·茨威格认为滑铁卢之役是由格鲁希思考中的一秒钟所决定的。当拿破仑被威灵顿包围之后,格鲁希率领着另一支大军正沿着战前布置的道路前进,他们听到了炮声,炮声距离他们只有三个多小时的路程,格鲁希的副司令热拉尔激烈地要求向着炮火的方向前进,其他军官也都站到了热拉尔一边,然而习惯于服从的格鲁希拒绝了热拉尔的要求,因为他没有接到拿破仑的命令,他说只有皇帝本人有权变更命令。激动的热拉尔提出最后的请求,他想率领自己的师和骑兵奔赴战场,并且保证按时赶到约定的地点。格鲁希考虑了一秒钟,再次拒绝热拉尔的请求。就是这一秒钟决定了威灵顿的胜利,决定了拿破仑彻底的失败,也决定了格鲁希自己的命运。斯蒂芬·茨威格认为格鲁希的这一秒钟改变了整个欧洲的命运。
同样的道理,很多人在获得成功或者品尝了失败之后,再回首往事,常常会发现过去生活中的某一个平常的选择,甚至是毫无意义的举动,都会带来命运的动荡。在这一点上,人生的道路和历史的道路极其相似,然后就会诞生故事的道路。山鲁佐德的故事或者其他人的故事,为什么都会让一个不经意的细节去掌握故事中高潮的命运?我相信这是因为人生的体验和历史的体验决定着故事的体验。当我们体验着人生或者体验着历史之时,这样的体验是在分别进行之中;当我们获得故事的体验时,我想这三者已经重叠到了一起。这时候我们就会重新判断故事中各段落的价值,有时候一个不经意的细节和故事中情节的高潮,这两者间的关系很像是贺拉斯描述中的丽西尼的头发和堆满财宝的宫殿,贺拉斯说:“阿拉伯金碧辉煌堆满财宝的宫殿,在你眼里怎抵丽西尼的一根头发?”
一九九九年十月二十五日
闪光的生命--[[柳文扬]]
-----
一
刘洋最近一直在埋怨:干嘛不让我早一点碰到雷冰?大学五年里有的是机会嘛。偏偏是在毕业设计最紧张的时候,偏偏那一天去计算机中心,偏偏雷冰坐在机房里──她那么好看!连她的眼镜都好看!还有头发,还有衣服,还有她安安静静坐着的样子。
如果不是毕业设计,刘洋想,那我就天天泡在机房里陪她。可是现在,我只能窝在小实验室造苹果。
他在屋里慢慢地转圈,在他脚步所划的大圆圈里,有一张沙发椅,一个实验台,一台奇型怪状的仪器──叫做复制槽,摆成个三角形。实验台上放着一只又红又大的苹果,完美无缺,现在它是刘洋单相思病的唯一见证了。复制槽那边咝咝作响,正在对苹果进行全息扫描。这就是他的毕业设计课题。
刘洋眼瞪着苹果,脚下绕着圈子,心想:今儿晚上去看她,找什么借口呢?他在事先总爱一个人演习一番──但基本上不能用于实战。
我应该用含蓄的语言赞美她,同时,深情地凝望(但不可过于肉麻)。他自言自语:我就说,又漂亮、又聪明、又有个性的女孩子真是太少啦,最近我倒发现一个。她要问,那是谁?──等一下,她也许不问呢?我看她肯定不问。那我不是自讨没趣吗。我这么说,你歇一会儿,我讲个故事?不行,她不会听,就是想听也装作不爱听。那我就硬讲,把她逗笑为止。我马上夸她:你笑容好动人!她万一不笑呢?我就是说,你板着脸的样子好动人!──是否贱了一点?
正自个儿瞎念叨,蜂鸣器响了。刘洋走到复制槽边,拉开盖子,里面有一个大红苹果:它是照原样复制的,从外到里,连滋味都是一模一样。
刘洋笑了,是那种心怀叵测的笑。他有主意了!
在温柔的夜晚,一位美少年,面带微笑(穿着最亮的皮鞋),手捧苹果,送到姑娘窗下。这是多么浪漫动人的情景!虽然雷冰的窗子在九层楼。
浪漫是要有代价的。从实验大楼到计算机楼很远,而且,计算机楼的电梯和往常一样,就是说又坏了。刘洋爬上九层,呼哧带喘。定了定神,走到那个机房门口,轻轻地推门进去。
里面当然只有雷冰一个人。
“大家好!我又来了。”刘洋装模做样地说。
雷冰心里笑了:这个人!每一次来,屋里明明只我一个,他总说“大家好”,好象所有的机器,连桌椅和地毯里的微生物,都是他朋友。雷冰聪明剔透,她知道这个男孩子,不敢面对她一个人问好,,因为他心有所求,所以怕露痕迹呢。她两眼望着屏幕,也不扭头,说:“又跑来捣乱,今天不许在机子上玩游戏。”
刘洋找一把椅子坐好,问:“你的课题怎么样?”
雷冰说:“你没看见吗,乱七八糟,我头都大了。你一来,我头更大了。”
刘洋跑到她背后,说:“我会叫它小下去的。”双手虚空作发功状,念到:“小,小,小……”
雷冰吃吃地笑了,然后又正正经经地问:“你呢?你那边怎么样?”
刘洋从衣兜里掏出两个苹果,说:“你看!”
雷冰把苹果接下来,摆在桌上,仔细端详,出神地说:“真棒!一模一样!”说完懊丧地摇摇头:“你都快完成任务了,我这儿还没有摸着边儿呢。”
刘洋安慰说:“差得远呢,还没能复制动物,而且,复制的东西都不够稳定,只能存在半个小时。”
“是吗?”雷冰看着苹果,“那,过一会儿就会有一个苹果消失么?”
刘洋笑道:“对!现在你挑一个,看看是真是假?挑着哪个吃哪个啊。”
雷冰摇头笑道:“我不。”
刘洋说:“挑一个嘛,试试你的手气。”
雷冰闭眼拿了一个。
刘洋说:“现在可以吃啦,在半个小时以内,都是真苹果。”
“我不,我要看它怎样分解掉。”雷冰握着苹果说。
“那好,你拿那个,我拿这个,咱们一起等着。”
过了好一会儿,刘洋手上的苹果忽然无声无息地消失了。
雷冰笑道:“我选对啦。我有第六感!”她用修长的手指握住水果刀,把它切成两半,说:“你吃大的一半。”
她很大方,刘洋拿着半个苹果,倒有点儿不知所措了。
雷冰看看他,问:“你干嘛呢?”
刘洋笑道:“我奇怪。以前,我看女孩子吃苹果,都是先用香皂洗一遍手,然后用洗涤剂洗苹果,再用洗涤剂洗水果刀,再用香皂洗手,才削皮,最后用牙齿啄着吃。可不象你这样。”
雷冰笑说:“我从小就是这么吃,习惯了。”
他们俩一起吃完苹果。雷冰说:“如果复制的东西只能存在半小时,那又有什么用?”
刘洋说:“有用啊,特别是对你们女孩子大有用处。”
雷冰问:“为什么?”
刘洋笑说:“你爱吃什么?”
“不告诉你。”
“好吧,假设你爱吃肥肉……”
雷冰抗议说:“我根本不爱吃!”
刘洋说:“行,行,假设你爱吃巧克力,可又怕胖。那好办,你买一块来,我给你复制一大堆。你可以不停嘴地吃,吃到肚子里就消失了,又不用节食,又保持苗条身材!”
雷冰笑道:“就你能想出来,你以为人家都象你一样好吃。”她看看屏幕,又说:“你帮我处理一下这些数据好不好?我手指头都发酸了。”
刘洋说:“行。”他坐在桌边,一边敲键,一边说:“千里迢迢,披星带月来送苹果,不许玩游戏,还得干活……”
“瞎唠叨……”她责备人也总是这么淡淡地。
刘洋说:“你的导师是陈教授吧?他怎么总不来。”
雷冰慢条斯理地说:“他可千万别来,他一来只有一句话:‘雷冰,进度为什么这样慢哪?’我就得特别乖地在这儿熬夜。”
刘洋笑道:“我们王教授还不如他呢!把课题留给我,自己去火星考察了。”
雷冰说:“你一说上火星━━咱们学校旁边的航天实验场,总是抢我们学校的电用。有时候夜里停电,机房里的警铃就响,我最怕那种声音了。”
刘洋笑道:“我还没见过你害怕是什么样……”
雷冰在后面说:“数据都错啦!你就会捣乱……”
二
苹果换成小白鼠,是一个月以后了。实验很有进展,但是刘洋的爱情冒险迟迟没有开端。他总是演习,总是临阵退缩。
这一回他又绕着小白鼠转圈子,自己描绘一幅与雷冰对话的情景:
首先我要把话题引到容貌方面,说一个人的相貌可以显示她的个性。然后我说:“我猜猜你的个性,好不好?”
雷冰说:“好吧。”
(万一她说“不好”呢?她多半会说“不好”━━她很严肃。那么,我就硬要说。她会无可奈何,然后转过脸去,假装不听。)
我就在她背后说道:“后脑形状也能显示个性,只不过你头发太长,盖住了。”(她的头发很顺滑。)
雷冰会自顾自地敲键盘,装作旁边根本没有我这个人似的。
我说:“先从眼睛说起吧,你的眼睛非常好看(我真敢这么说吗?),很明澈,说明有内在的生命力。你的目光喜欢低垂,说明你怕羞,但又很骄傲(我好大胆!)。鼻子高,有一点儿尖,表示自信、矜持。嘴唇薄,有个性,可是笑起来就很柔和。额头广,说明你聪明、灵透。脸型是瓜子型,柔和、秀气,表明性格文静、温和。头发柔顺光滑,是直的长发,唔……表示朴素,不随潮流,又有一点浪漫。”
雷冰这时很斯文地、慢悠悠地说:“你净瞎说。”哎呀,我真是喜欢她这种柔和的责备口气。
这时候,雷冰不说话,显然已经被触动了。(嘻嘻。)
我抓紧机会,说(一定要很自然地,不经意地):“对啦,我很喜欢你低头的这个样子(我敢说“喜欢”吗?)。还喜欢你掠头发的样子(豁出去了。就是喜欢,谁怕谁?)。还喜欢你笑,你生气,喜欢你这样,喜欢你那样……”
雷冰回过头来,然后……
刚刚演习到“然后”,正在臭美之际,屋里的灯突然熄灭,警铃也响起来。停电了。
刘洋赶忙把所有电闸都拉开,关掉警铃。
忽然想起:雷冰还在机房!别看她有时候凶巴巴的,其实胆量极小,一个人在那里会吓死的。刘洋摸黑找出一盏手提灯。
雷冰正安安静静地坐在桌边,桌上有一盏应急灯。看到刘洋进来,她笑道:“你来啦。”
刘洋说:“来看看你害怕是什么样子。我很失望啊。”
雷冰说:“你就是来看这个的吗?”
刘洋笑道:“对。”帮她去拉电闸。
雷冰坐在那儿,说:“那你走吧,不用你帮忙。”
刘洋一惊,回头看时,她寒着脸,正生气。
刘洋想说:你生气的样子真好看。但毕竟不敢,就坐在一边,有趣地看她。
雷冰又转了个身,没理他。刘洋就绕着她走圈子。
雷冰一笑,道:“你有病啊!”
刘洋笑说:“好了!我逗你一句,你骂我一句,咱们打个平手。”
雷冰说:“突然停电,我一慌就关机了,可能丢了好多数据。”
刘洋哄她说:“没关系,以后慢慢来。陈教授还能不让你毕业吗?反正停电干不成了,我送你回宿舍吧。”不等雷冰说话,又笑道:“快走!慢了就关门!”说完就往门口跑。
雷冰却是一点儿也不起劲,叹了口气,慢慢地站起来,走到门口,笑说:“我知道你不会锁的!”
路上,雷冰说:“刘洋,你应该去搞文艺。”
刘洋问:“为什么?”
“你性子活,而且,你爱幻想。”
刘洋奇怪地问道:“你怎么知道?”
雷冰笑说:“我比你大嘛,能看透你。记着:幻想有时候好,有时候不好。到宿舍啦,再见!”
刘洋自己穷嘀咕:一层窗户纸,轻轻一捅就破,我怎么就不敢呢?刚才雷冰生气,是因为我没说真话。其实,她那么聪明,不用我说她也懂的。可是,据说女孩子喜欢听到表白……
又想:准备好的那些话,一句也没说呀。根本就没机会说,等下次……
三
离毕业答辩的时间越来越近,现在只有一个月了。小白鼠已经换成大黄狗,刘洋还是刘洋:演习大师。
实验已至收尾阶段,需要作的,只是延长复制体的寿命。刘洋抱着大黄狗,想着雷冰,把狗放在实验台上,按上电钮开始扫描。他已经不愿再绕圈走了,就懒懒地坐在沙发上。时间过得真快呀。他想,还有一个月,大家就要毕业了。那时候各奔东西,不知道还能否见面。他懊悔自己为什么总不敢主动一些,坦白一些。
总是想自自然然地开口,以免尴尬,可是,设想好的场面从来就没有出现。现在怎么办呢,只有一个月了。
不过,一个月还够长,三十天,七百二十个小时呢。这么多个小时里面,难道就没有一个机会?
“没有机会!”
刘洋听到一个声音说。
他吓了一跳!这声音多熟啊。
蜂鸣器响了。复制槽的盖子竟然自己掀开,跳出一个人来!而且,居然就是刘洋自己的样子!
这个人一边跳出来,一边大声说:“你等不来机会,而且你的时间也不多。”
刘洋惊呆了,片刻,他才说:“复制大黄狗,怎么会跳出一个我来?”
那人说:“你心不在焉,把狗放在沙发上,自己坐在实验台上了。”
刘洋一看,可不是,狗正趴在沙发上睡觉。然后,他又吃惊地看着复制人说:“你刚出生,就会说话!”
复制人熟练地整理着实验仪器,平静地说:“当然了,复制么,你整个都被复制了,连衣服、手表,还有所有记忆、性格。我知道你从小到大的所有事,我还知道,我只能存在半小时。”
刘洋兴奋地搓着手,说:“太奇怪了!太奇怪了!我问你几个问题行吗?”
复制人说:“快问,我时间宝贵。”
刘洋一笑,说:“我左腿的疤怎么来的?”
复制人说:“左腿,小时候爬树摔的。那一次真疼,疼哭了。”
刘洋又惊又喜,想了想,说:“刚一出生,就有二十年真切的记忆,是什么感觉?”
复制人说:“非常奇妙,无法言说,好象大梦初醒。”
刘洋问:“你是和我一样的人,知道人世的快乐。你又知道自己只能感受半小时的生命,不觉得不公平?”
复制人淡淡一笑道:“不短了,因为是命里注定。我本不应该出世的,有这半小时,总比没有好。其实,你就算能活一百年,难道就很长么?”他转过身,说:“我要走了,时间宝贵。”
刘洋惊问:“你去哪儿?你不能出去!”
复制人已跑出实验室,把大门从外面反锁了。
刘洋捶门叫道:“你回来!你干什么?”
复制人在门外低声说:“谢谢你!你让我出生,又让我有自己的心!”
跑出实验大楼,门外月光朗照,夜色清明。复制人深深呼吸了一口气,对自己说:“真幸运!我出生在这么美丽的晚上。”看一看手表:还有二十分钟!
他定定神就往学校的后花园跑去,那儿有他要的东西。
一园子的玫瑰,在晚上都静静地睡着。他翻进花园,喘息着伸手──在花圃中立着一面木牌,上写八个字:生命短暂,请爱惜我!
他呆了一呆,一跺脚!
还有希望,学校外面有一个鲜花店,只需翻过院墙就行。
没有灯光。商店锁了门。
他又翻了回来,冲进花园,轻声说:“对不起!对不起!”
那是对玫瑰花说的。他伸手折枝,花枝上的刺扎进肉里,无暇去管,就让血流吧。
折下几枝最繁盛的,抬手看表:还有一刻钟!
他跑!向计算机楼跑,一面跑,一面用手指把花枝上的刺都掰下来。没有时间可以耽误了,一秒钟也不行,只希望电梯是好的。
电梯坏了。
还剩下十分钟!
他冲上楼梯,一阵风似的向上刮去,直到九层。
到九层,双腿都软了。他靠在墙上,喘着,使心跳平静,掏出手绢来擦了擦汗,又用手绢包好流血的手。他要最完美地去见雷冰,不让她看见一点匆忙狼狈的样子。
看表,还有七分钟!
雷冰坐在桌边,心想:刘洋又该来了。
刚刚想到他,门被推开,雷冰不用回头就知道是谁。
“你好吗?”来人说。
雷冰吓一跳──第一次没说“大家好”!她回头一看,那分明是刘洋,和往常一样,笑嘻嘻的,两只手还装模作样的背在身后。只不过,眼睛好亮,坚决地看着她,看得她有点儿心慌意乱……
“时间过得太快啦。”刘洋说话了。
雷冰抬起眼睛,问:“你的课题做不完了吗?”
刘洋说:“不是,我是说生命短暂。”他坐在对面,温柔地注视雷冰,使她又一次低下了头。
刘洋又说:“这一生,我没有时间选择,只来得及做一件事。是我最想做、最重要的一件,就是──爱你。”
雷冰的脸忽地红了。她转过身去,脸色变得仓白,一颗心怦怦乱跳!
刘洋沉默了一会儿,看她那一头长发不再颤抖了,他说:“我不代表别人,只代表我自己说:我爱你。”
雷冰忍不住一笑,小声说:“这种时候,你……你还开玩笑……”
刘洋伸出双手,扳着她的肩膀,让她转过身来,看着她的眼睛。
雷冰脸蛋红红的,她把目光低垂下去,看自己的衣服。忽然又抬起眼睛,和他的目光交汇,她的睫毛湿润而黑密。
这是超越时间之外的一瞬。
刘洋低声说:“我一生下来就喜欢你。你信吗?”
雷冰抿着嘴一笑,说:“口恩,信。”
刘洋看着她眼睛,微微笑道:“你知道小海龟吗?它们一出壳就会往大海里爬。我也是!我从有感觉的一刻起,就在跑,在往你这儿跑。”
雷冰小声说:“你是说缘份。”
刘洋说:“口恩,缘份吧。一辈子这么短,可是能遇到你,真好。”他从背后拿出一束花来,递给雷冰。
那是一束含苞欲放的玫瑰。雷冰双手接过来,抚摩着花枝,看着刘洋用白手绢缠着的手──
她握着他一只手,贴在自己脸上,轻轻叹了口气。
刘洋抚摩着她的头发,说:“我应该给你更多一些。带你去外面看月亮,带你去美丽的地方玩儿,去吃你喜欢的巧克力,应该给你种很多很多花,修一个花园……应该让你一生都快乐,让你一生安宁。可是,我不知道──”
雷冰闭着眼睛,低声道:“我们以后有很多时间啊……”
刘洋叹息一声,微微一笑,问:“你高兴吗?”
雷冰睁开眼睛,笑说:“口恩。”
“我也是。”刘洋忽然紧紧握着她的手,说:“你再把眼睛闭上,好么?”
雷冰把眼睛阖起,睫毛微微颤抖。
刘洋慢慢凑近去,用嘴唇在她的唇上轻轻一碰。
雷冰没有动。刘洋闭了眼,笑道:“轮到你啦。”雷冰伏在他肩上,翘唇一吻。
刘洋叹息说:“真好!我一生都快活,可是这一秒钟最好。”他猛然微微一惊,看一下手表:“要走啦!”
雷冰惊问:“你去哪儿?”
刘洋离开她几步,回过身来,对她微笑着,柔声说:“你别怕!”
然后,他就无声无息地消失在空气里。
最后的声音,似乎还留在空屋中,慢慢,慢慢地消融。
四
“如果我只有半小时生命,我也会象他那样。”刘洋说,“其实……他说的,就是我想说的话。我们是同一个人啊。”
雷冰说:“不是!他不是替你来说话的,他也不是你的复制品。他就是他自己!”
刘洋抱着头,低声说:“本来,我才是真的!他根本不应该来!他什么也不是──没有名字,没有生命,没有心……他是我偶然造出来的!”
雷冰说:“他有生命!他是活着的!他不属于你……”她呆了一会儿,又自言自语似地说:“虽然只有半个小时……”
刘洋黯然道:“你以后的日子还长,可是他已经消失了,什么也没留下。”
雷冰道:“玫瑰花还在……”她忽然热泪盈眶!看见玫瑰花,她想到:那个人消失了,永远。他从生到死只有三十分钟,他就用这三十分钟,用他整整一生,让我快乐………
刘洋转头看去。在花瓶里,昨夜的玫瑰花沐浴着阳光,已经盛开。
他心里在想:“一百年真的很长吗?”
「[[陌生化]]」又称「反常化」或「奇异化」,它是由[[什克洛夫斯基]]首先提出的,是[[俄国形式主义]]的核心概念。陌生化理论认为,文学的功能就是使人们已经习惯化、自动化了的感知力恢复到新奇状态。怎样才能做到这一点呢?那就是:使对象陌生,使形式变得困难,增加感觉的难度和时间的长度。
在「陌生化」理论看来,所有的艺术都是「陌生化」艺术,艺术表达什么内容并不重要,重要的是表达的形式。比如:「春天来了,江南岸边的草又绿了」。——这是日常的表达方式,表达的对象是「春天来了,青草绿」。但是「春风又绿江南岸」。——这里表达的对象依然是「春天来了,青草绿了」,但是这里却成为了「文学」,由此可见,文学与非文学的区别不在于表达的内容,而在于表达的方式。
再次强调,「陌生化」的重点在于「使人们已经习惯化、自动化了的感知力恢复到新奇状态」。举例来说,茅盾《子夜》中有一段吴老太爷进城的描写,通过第一次到上海的吴老太爷的眼光,都市景观就显得分外光怪陆离、摄人心魄:汽车成了「小箱子」「长蛇阵似的」怪物,突然,「怪物们」「静静地一动也不动」,横在前面的却像河水一样流淌,男男女女则仿佛被鬼追着似的飞跑。
都市的生活本来对于城市中的人是习以为常的事情,而在这里,茅盾就是用了「陌生化」的手法将读者习以为常的事物重新回归到新奇的状态。
嗯哼,其实科幻小说就是典型的「陌生化」艺术。
要说“陌生化”理论,我们得先知道俄国形式主义,因为“陌生化”理论是俄国形式主义的核心。
## 形式主义
[[形式主义]]盛行于20世纪初的俄国,最早出现在对文学作品的探讨中。1914年,[[什克洛夫斯基]]发表《词的复活》(The Resurrection of the Word)一文,通常认为这标志着形式主义开始进入人们的视野。
形式主义的形成受到多种理论的影响,例如[[索绪尔]]的语言学和[[胡塞尔]]的[[现象学]],而对其影响较为深刻的是当时俄国的三个文学理论——[[学院派理论]]、[[俄国象征主义]]和[[未来主义]]。
- 学院派理论界定了文学与其他学科的界限且高度关注文学作品的形式,什克洛夫斯基将其视为对形式主义的一种启蒙与鼓励,说形式主义发端于此也许并不过分。
- 俄国象征主义对形式主义的影响主要在于对文学作品的研究方式上,俄国象征主义在研究诗歌时,花费大量精力研究诗歌的韵律、节奏以及选词(说起来这和中国诗歌很像,象征主义和中国诗歌有着千丝万缕斩不断理还乱的关系,由于没有深入研究过,无法细谈,见谅),形式主义继承了象征主义这样的研究方式,对文学作品作者的选词、遣词造句、描写角度等都相当重视。未来主义则做得更加彻底,他们认为文学作品的词就是语言的本质所在,这一观点在形式主义中被发展为对文学文本的的重视,形式主义研究文学作品时将文本当做研究的主要对象,甚至说唯一对象也不为过。
当时俄国的主流文学理论深受马克思主义影响,导致主流文学分析多立足于作品的历史性、社会性和政治性,像形式主义这样关注作品文学性的理论在当时可谓独树一帜。前期的形式主义主要运用在文学作品的分析上,后期逐渐发展到对所有艺术作品的分析中。什克洛夫斯基在《作为手法的艺术》(Art as Technique)中是这样定义艺术的:艺术是体验对象的艺术构成的一种方式;而对象本身并不重要。(art is a way of experiencing the artfulness of an object: the object is not important)。当这一观点用于分析文学作品时,文学作品所描述的事件、场景、物品本身便不再是分析的重点,作者选用何种视角、哪个词语、如何描写才是分析的重点所在。也就是说,如果什克洛夫斯基来出一份阅读考试题,绝对不会有作者的中心思想是什么这样的问题,而是要问“你是磨人的小妖精”和“你这磨人的小妖精”有什么区别。23333
陌生化
说完形式主义,我们就可以来谈谈“陌生化”了。与其说“陌生化”是一种理论,不如说它是一种手段,一种打破“自动化”的手段。
“陌生化”的提出,与什克洛夫斯基对艺术的理解密不可分。他认为艺术的存在是为了使人们恢复对生活的感知,“使石头成为石头”。艺术的目的是向人们传达被感知的事物而不是人们所知的事物。(Art exists that one may recover the sensation of life; it exists to make one feel things, to make the stone stony. The purpose of art is to impart the sensation of things as they are perceived and not as they are known. )什克洛夫斯基认为,当人们重复某个动作许多遍后,这个动作便成了习惯,在重复了无数次之后,这个动作就变成了无意识的“自动化”行为,做这个动作是无意识,也无记忆的。如果人的每一个行为都是这样无意识的“自动化”行为,那相当于不曾活过。(你现在试着回想一个普通的工作日,是否能记起自己做过些什么?如果不能,你的那一天算有过还是没过?)为了不让生活沦落于此,艺术出现了。艺术通过一些手段使对象陌生,使形式变得困难,增加感觉的难度和时间长度,来达到审美目的,来恢复人们对生活的感知,这些手段即“陌生化”。
这有一点费解,我们可以举个栗子。你家里有一把藤椅,你知道你家里有一把藤椅,你每天坐在它上面吃早餐晚餐(午餐在公司里吃)。有一天你同事问你,你家餐桌旁的椅子是什么样的,因为他之前来过你家,觉得那椅子很舒服也想买一把。听到他的问题,你拼命回忆家里的椅子什么模样,然而却一点也想不起来。此时的你已落入“自动化”的陷阱,藤椅在你的生活里存在了太久,久到你无视它的存在,你无数次重复坐在上面的感觉,重复到你遗忘了第一次坐在它上面的惊艳的舒适感。晚上,你回到家里,已经忘了中午在公司和同事的对话。这时,儿子把在学校里被老师表扬的作文拿给你看,题目是《爸爸的藤椅》,儿子写到“爸爸的藤椅是一只小怪兽,有四条笔直的长腿,总是一动不动,斜斜的站立在餐桌旁,好像沾染了爸爸的威严。”你心里一震,从来不知道自己每天坐的藤椅在儿子心里是这样的形象。你从沙发里抽出身体,走到餐桌旁坐在熟悉无比的藤椅上,心里有一丝陌生感。买藤椅时,臀部第一次接触到藤椅粗糙却略带韧性的舒适感,靠背的支撑角度完全契合你的脊柱,你再次感受到了藤椅粗犷的纹理和舒服的设计。而你又不自觉地坐直了身板,因为儿子的作文里提到的威严感。此时,藤椅已不只是你所知的事物,而是你所感知的事物。你对藤椅的“自动化”已被打破,明天如果你的同事再次问你,藤椅的形象将鲜活地出现在你的脑海中。从你对藤椅无知无觉到直起身板坐在上面,你儿子的作文扮演着一个唤醒“陌生感”的角色,这一角色也是什克洛夫斯基所理解的艺术的目的——唤起人们对生活的感知。如果有一天你的画家妻子画了一幅藤椅的肖像画,画中的藤椅四角大开,粗糙的表面被画成了竖立的汗毛,血脉贲张,姿势撩人,那又是你妻子对藤椅的不同认识,也会唤起你对藤椅的不同感知。(或者还有别的?哈哈)同一把藤椅,你儿子的作文,你妻子的画,都给你带来不同的感受。这便是艺术在做的事,对象是不重要的,表达的形式才是艺术的本质所在,不同的形式传达对对象的不同感知,而这些感知唤起人们对对象(即生活)鲜活的认识,才使人们真正地活着。
为了打破“自动化”,唤起人们对生活的感知,艺术采取了各种手段,这些手段就是“陌生化”。
说到这里,“陌生化”是什么已经很清楚了,下面属于进阶知识。
如何实现“陌生化”
如前文所说,一切艺术手段都可以称为“陌生化”,以下归纳的是什克洛夫斯基在《作为手法的艺术》(Art as Technique)中提到的写作中运用的“陌生化”手法。
手法一:使用不平常的词语或运用修辞
所谓不平常的词语,并不一定是艰涩难懂的词,让我们举个栗子。
好,我的栗子举完了。
纳尼??是的,机智如你应该已经发现,刚刚的“举个栗子”本身就是一个例子,此处的“栗子”就是一个不平常的词。它利用谐音,把原本比较枯燥的“例子”变得可爱,甚至可视,反正每次我看到“举个栗子”脑子里就浮现冰河世纪里那只松鼠高举着和自己体型一样大的栗子XD。这就是“陌生化”。
至于运用修辞,比喻、拟人、夸张这些都是,我们见得很多。不赘述。
手法二:改变写作视角
改变写作视角中最受什克洛夫斯基欣赏的一种方式是——“初见的视角”。所谓“初见的视角”就是用第一次看到一件事物的眼光来描写事物,而不用人们已经用滥的名称去称呼它们。让我们举个栗子。
她递给温斯顿的第一个纸包给他一种奇怪而有点熟悉的感觉。里面是种沉甸甸的细沙一样的东西,你一捏,它就陷了进去。(The first packet that she passed to Winston had a strange and yet vaguely familiar feeling. It was filled with some kind of heavy, sand-like stuff which yielded wherever you touched it.)
这是乔治·奥威尔的小说《1984》里的一个描写。此处描写的是糖。一方面,糖在读者的日常生活中是再常见不过的调味品,另一方面,糖在极权主义的大洋国却是十分奢侈的东西,作为一名普通党员,温斯顿轻易不可能接触到。当这样一个对主人公来说稀有而珍贵,对读者来说却稀疏平常的的东西出现时,如何让读者感受到稀有而珍贵?“初见的视角”描写就派上了用场。奥威尔没有直接说明这是糖,而是用温斯顿的视角描写——“沉甸甸的细沙一样的东西,你一捏,它就陷了进去”。一种陌生又有点熟悉的感觉,读者也回忆起手里捏着一包糖的感觉——“你一捏,它就陷了进去”。就这样,读者对生活的感知被“初见视角”的描写唤醒,艺术达成。
这样的描写方式备受什克洛夫斯基推崇,也的确是一种非常好的写作手法。
手法三:区别文学语言与日常语言
什克洛夫斯基认为,文学语言大大区别于日常语言。文学语言是新且鲜的,所以也更困难(The form of literary language is new and fresh, so it is more difficult (Shklovsky, 1917))。所谓困难,我的理解是,需要思考才能读懂。答主陈柏龄举的「春风又绿江南岸」就是一枚好栗子。
「春天来了,江南岸边的草又绿了」。——这是日常的表达方式,表达的对象是「春天来了,青草绿」。但是「春风又绿江南岸」。——这里表达的对象依然是「春天来了,青草绿了」,但是这里却成为了「文学」,
由此可见,文学与非文学的区别不在于表达的内容,而在于表达的方式。
但文学语言不会永远是文学语言,日常语言也不见得不能成为文学语言。当一种文学语言被广泛地使用于生活时,它也渐渐地落入“自动化”,就会被文学创造者所抛弃,而当文学语言落入过度精巧艰涩的怪圈时,朴素的口头语言可能反而是一种“陌生化”,比如方言在马克·吐温小说中的应用。
个人见解,如有错漏,欢迎指正。
Reference
Viktor Shlklovsky, 1914, The Resurrection of the Word.
Viktor Shklovsky, 1917, Art as Technique.
乔治·奥威尔,2009,《一九八四》,董乐山译,上海译文出版社。
Cai Guanghua[蔡光华],2011,论《一九八四》的“陌生化”,《上海师范大学》硕士论文。
Cheng Zhengmin[程正民],2013,历史地看待俄国形式主义,《俄罗斯文艺》1:26-34。
Li Yanli[李艳丽],2012,“陌生化”的审美实现探析,《河南工业大学学报》3:116-119。
生活又开始了- 李娟
========================
生活又开始了- [[李娟]]
------
在我的个人经验里,搬一次家非得伤筋动骨一百天不可。整理东西啦,熟悉新环境啦,诸多不便。但是来到冬库尔的第三天,我们的生活就完全步入了正轨。羊也认圈了,牛也知道回家的路了,晾奶疙瘩的架子也搭起来了。日子开始顺顺当当。
大家各就各位。扎克拜妈妈绣花毡、煮牛奶、做胡尔图。斯马胡力放羊、拾掇骆驼,并联合附近的小伙子们做些钉马掌、给奶牛配种之类的活计。卡西挤奶、赶牛、背柴、找羊。我呢,除了以前那些活儿,又多了一个任务——摇牛奶分离机。牛奶分离机是牧业办公室特意送上门的。一进夏牧场,牛的产奶量剧增。此时正是一年中大量生产奶制品的时节。
同时,也到了加工羊毛制品的时节了。斯马胡力每天都会逮两三只大羊剪毛。羊毛片洗净晾干后,妈妈把它们撕开,用借来的柳条棍反复抽打,边抽边对我说,再等一个月,到了下一个牧场就开始剪羊羔毛了。又说,羊羔毛比大羊毛更好。同时,羊羔们也将陆续出栏,编入大羊的队伍。繁殖与收获的季节即将到来。
但是就在第三天,大羊们突然有些犯迷糊,一上午就回来了两次,差点儿和羊羔会面。大家分头追赶,好半天才把它们逐回正道。然后回家喝了一道茶,休息片刻,卡西和斯马胡力兄妹俩开始在家门口的草地上打木桩,很快搭起了一个蒙着塑料布的小棚。
我问:“干什么用?”
卡西说:“给斯马胡力住!”
我说:“太好了,他的脚太臭了!”
卡西大笑:“对!对!”
妈妈却说:“给李娟和卡西住!”她总是埋怨我俩话多,整晚说个不停,打扰大家休息。
后来才知是用来放置我和妈妈的马鞍(而卡西和斯马胡力的马鞍比较漂亮、昂贵,它们几乎被当作装饰品放在毡房里的醒目位置)、牛皮、毡片之类一时用不上的杂物的。之前它们一直被码在室外空地上,盖着一大块毡子。因为春牧场干燥,很少下雨嘛。可进入潮湿多雨的夏牧场后,就不好再露天放了。
斯马胡力真能干。为了栽稳木桩,用尖头铁锨掏了四个又深又窄的洞。窄洞非常难掏,要是我的话,掏多深的洞就必须得挖开多宽的洞口。但埋木桩的话,那种喇叭状的洞远不如直上直下的窄洞结实。木桩栽进坑里后,四面缝隙填满泥土。斯马胡力扶着木桩,卡西跪在地上用斧头把子将埋住木桩根部的松土捣得结结实实。
而扎克拜妈妈在山坡另一头烧了一大锅水慢慢洗衣服,由着兄妹俩自个儿倒腾,既不插手,也不表态。等小棚搭好,不说好,也不说不好。她绕着走了一圈,铲了几锨土压住垂在小棚墙根处的塑料布边角,开始往里面挪杂物。
这时,又开始下雨。整整一天不见蓝天了。
进入夏牧场,时间如同倒退了几个月。这边雪仍没化完,气温也比春牧场低多了。而且每天一到下午就会刮大风。若不是满目葱翠,这样的冷真令人灰心。
是的,较之戈壁滩的荒凉,夏牧场绿意汹涌。就算是阴天,也没有一点儿阴天应有的沉郁之气,虽冷而不寂,万物升腾,生命迹象沸沸扬扬。尤其是我们驻扎的这个坡顶,出门一望,草地绿得跟假的一样,绿得跟塑料做的似的。
雨时停时下。大家坐到一起重新喝茶,一时无言,一起望向门外。新的塑料棚收容着各种杂物,它拥抱着它们,在雨中簌簌作响。这时,羊的咩叫声远远响起。怎么羊又回来了?看来没人跟着就是不行。
于是决定今天早早地分羊入栏。加上牛也回来得格外早,我们都很高兴。赶完羊,挤完奶,总算能够早点儿休息了。连着两三天紧张地收拾驻地、修建牛羊圈,大家都疲惫了。
就在分羊的时候,妈妈突然想起了什么,忍不住自个儿笑了起来。接下来越笑越刹不住了,边笑边赶羊。大家都莫名其妙,问怎么了,她也顾不上回答。直到小羊全部入栏后,她干脆一头扑到草地上,脸埋在青草里尽情大笑起来。好半天我们才搞清怎么回事。
原来她想起我们刚到冬库尔第一天的情景。当时也是在赶羊,但斯马胡力打架去了,就我们三个女的,困难重重。因为是第一次在冬库尔赶羊入栏,羊羔不熟悉新圈栏。加之当时天色暗了,它们看不清周围形势,一个个紧紧盯着自己的妈妈不放,死活不肯进栏。好不容易赶进去了几只,孤零零待在暗处,一瞅到机会又不顾一切冲出去,死活要和大部队一搭儿。我们紧张极了,要知道天色越暗,越难入栏。不入栏的话,第二天天不亮大羊就带着小羊跑完了。
卡西尤其焦躁,不停冲我瞎指挥,用汉语大喊:“赶!李娟!不!不赶!李娟!这边的赶!不!不这边的赶!赶!不的赶!……”弄得我一头雾水。
结果我还没生气,她倒气得不得了,越发凶巴巴地冲我乱七八糟地囔囔。实在令人恼火,又深感挫败。
那晚好不容易才把一部分羊羔入了栏。当时大家一心惦记着还在外面打架的斯马胡力,顾不上想别的。
直到今天,等全部整理工作都结束了,大家完全放松下来,妈妈才想起了这事。晚饭的时候,她津津有味地给斯马胡力模仿道:“李娟!这边!李娟!那边!李娟!赶!李娟!不的赶!……”大家一直笑到吃过晚饭钻进被窝了还停不下来。
第二天一大早,卡西就向我请教汉语的“前”“后”“左”“右”该怎么说。
生活一安定下来,时间也慢了下来。我和卡西又开始互相学习语言。之前这种学习中止了十来天。在塔门尔图春牧场住的时间短,一副随时准备出发的情形。临时的生活让人多少有些定不下心来。到了冬库尔没几天,我们各自的本子都记满了四五页新内容,并时不时互相提问。
我的圆珠笔是“爱好”牌的。卡西知道“爱”是什么意思,也知道“好”是什么意思,但两个字放在一起就不能明白了。我绞尽脑汁解释了半天,又举了一堆例子:我的爱好是写字,妈妈的爱好是唱歌,斯马胡力的爱好是放羊,卡西的爱好是睡觉……她开始还听得高高兴兴,听到最后一句时顿时大怒,扑上来打我,硬要我改成:卡西的爱好是做饭。
我问卡西:ber-sigun是“后天”的意思吗?她一边揉面粉一边回答“是”。看她心不在焉的样子,我又故意问:baoer-sake也是“后天”的意思吗?她面不改色,仍说“是”……豁切!baoer-sake明明是油饼!太不负责了!顿时想到之前请教时,也不知被骗了多少次……欺负人!然而再想想,自己也不是没骗过她,便恨恨地扯平了。
在一年四季的不同牧场上,最热闹的地方怕是只有冬库尔了。较近的邻居就有四家。沿着河谷往深处去,两翼延伸的每一条山沟里都扎有毡房。而且一天天过去,搬来的人家越来越多。妈妈一闲下来,就会包点糖果,拎上纺锤出去串门。如果哪一天她突然换上好一些的那件长外套和干净裙子,我就知道她要去拜访远一些的邻居了。果然,她打开上了锁的箱子,翻出一块闪闪发光的布料,展开看了又看,找出剪刀毫不犹豫地咔嚓咔嚓剪下一大截,裹些糖果、馕块叠起来放进肩包里,挎着出门了。我看着她下了山,沿着溪水往上游走去。远处的岔路口处,莎里帕罕妈妈正等待着,肩上也挎了一个大包……看着看着,顿感寂寞。
其实我们三个和妈妈一样,一到闲下来的时分,又没有客人的话,就一个接一个出门去也。
如果家里的人都走空了,最后一个离家的人会把门“锁”上——用一截绳子把门轻轻挽一下。与其说是锁门,不如说只是为了告诉来者:主人不在。
不止我们天天串门,我们的客人也多了起来,每天至少来一拨。大多是附近的姑娘小伙儿,来了无非喝茶、听歌、聊天。聊着聊着,渐渐无语。时间还早,外面的牛羊还没吃饱。于是大家推开茶碗向后一倒——睡觉。
和邻居们相比,我们的毡房小多了,而且随意多了。花毡下什么也没垫,睡觉总是很硌。有一天晚上硌得实在辗转难眠,早起掀起毡子一看,在我腰背下的位置上正好抵着一块大石头。试着踹两脚,纹丝不动,看来只是冰山一角,挪不得。真倒霉啊!怨怪之余,又掀开旁边的毡子,发现妈妈和卡西身下的石头更多……
而且毡房已经很旧了,一下雨,好几个地方都在漏。每到雨天,花毡潮潮的,地面泥泞。太阳出来时,除了天窗,破漏处也洒下点点光斑。当云朵在大风中飞快地移动时,毡房内的光线便忽明忽暗,满地的光斑也闪烁不停,如置身星空之中。
由于昼长夜短,早上四点多大家就得起来挤奶、赶羊。于是每到下午,劳动告一段落,大家都会和衣午休一场。但总是那么冷,总是阴沉沉的,再瞌睡也睡不踏实。醒来时总是晕乎乎的,脚都快冻掉了,肩背更是又酸又疼。
无论如何,夏牧场的日子还算惬意。尤其在刮大风的天气里,我用铁锨把火种从室外的火坑挪进毡房里的铁皮炉。呼啸风声中,火焰异常激动,热气腾腾。茶水刚刚结束,困意就席卷而来。而室外一阵风一阵雨的,有时是漫天的雾气,然后渐渐地,这雾气中直接下起了雨,接着是冰雹……睡醒后,风停雨住,天空中满是灿烂耀眼的崭新白云,云和云之间的天空破碎而湛蓝。这一切似乎出自我们睡眠的力量。
在夏牧场上,妈妈绣的新花毡也加快了生长速度,花毡上枝枝叶叶四面蔓延。黑色小牛不见了的消息令妈妈忧虑。那时,她绣出的一只羊角状花纹稍稍偏斜了一分。
卡西大部分时候心情愉快,总是唱着歌来去。她一直期盼着不久后的几场拖依(宴会),早早地开始准备那天要穿的衣服。偶尔,这姑娘也会因为劳动的辛苦而烦躁,不经意间流露出寂寞冷淡的神色。如果新借的磁带绞带了,并且被她越修越糟的时候,千万不能上前帮忙,甚至不能提任何建议。直到她扔了磁带出去赶牛的时候,我才赶紧捡起来修。等她再回来看到恢复原状的磁带,会惊异地叫出声来,再甜蜜地抱着我:“我爱你,李娟!”和半小时前那个家伙判若两人。
斯马胡力总是最辛苦的一个,总是冒着雨出去赶羊、找骆驼。但是,他又是全家人里睡觉时间最长的一个,因此得不到任何同情。不过斯马胡力从不对家人发脾气,总是笑眯眯的样子,讨人喜欢。
我呢,整天捂着羽绒衣缩着脖子干活、散步、睡觉。
班班总在毡房向阳的墙根处,在饥饿之中深深地睡着。
山坡下,南面草地上,大羊和羊羔总是试图在那里会合。一有苗头,大家就扔了碗冲下山坡,打着呼哨,扔着石头,围追堵截老半天。但总有那么一两次,大家站在家门口,不为所动地看着它们撞合成一群。真奇怪,那时候明明才中午。
总之,生活又开始了,不明白的事情还是有那么多……
```
失焦 萧丽芬
“哎,你可以下来了。”美丽的验光师第三次回头,发现我还坐在仪器上。
“真没问题?”我一再问。
“真的!没有!”验光师的耐心受到考验,但依然美丽,可见是真的美。3
“那好吧。”戴上眼镜,我其实无法说出到底有什么不对劲,世界并没有改变,至少大家都那么认为,只有我觉得好像有“什么”不一样了,所以毫无疑问是我的问题。
可是一旦真要准确说出什么不同,我就是掏空了脑髓,也说不出个所以然。
“是不是你视线太集中了?”这是我听到过最贴心的说法,而且好像如果不在意的话就一点问题都没有也是有可能的。6
但我不知道怎样才算不那么集中。
我在书店找了许多有关眼疾的书,视网膜脱落、绿内障、飞蚊症……,但没有我这种状况。最后买了新版的汉巫对照词典,北京的西西自从听说半呆(pandai)即本领就决心要学马来文。
绕到猫食部门,看了一下新来的猫玩具,想象那群长着人脸的猫专家,不断设计研制符合猫思维的玩具,除却利益因素,还是值得为这样的博爱喝彩。9
我养了两只猫,说养也不完全正确。
那天,我正啃着一粒小的出奇的苹果,上面标明来自加拿大;我不知道这中间谁撒了谎。
扯远了,猫。是的,那天,我正在啃一粒小苹果的时候,它从后面的铁门探了探头,瞅我半响没反对,就跨进来了。我记得它当时的表情好像在说:不好意思,我进来了。12
后面跟着一只稍小的猫,看体型早该独立的年纪,但因为长期在母亲的保护下,表情还非常天真安心,仿佛既然妈妈都认可了,所以我一定不会是坏人地挨到我脚下。
就这样,猫和我共用着不算大的房子。
大猫不太喜欢我踩它的地毯,不过如果坚持的话,它也不会说什么,基本算是性情不错的猫。15
我买了猫饼干,一起看电视的时候不好意思只有自己有零嘴。
邻近的商场正举办马日童画交流展览,我被门口一幅自画像版画勾引进去。作画的孩子有的很老,有的年轻;有些机心很重,有的不。
出来的时候,天暗了,我看见我的车卡在两棵大树中间。我知道事实并非如此,但眼睛看到的确实是这样的画面。18
我低头往车子走去,尽管车子几乎淹没在树丫里,我还是轻易上了车。树回复原来的状态--远远地立在马路边上。
情况比想象迅速--我的人生正逐渐失焦。
开始仅仅视觉和现实突然像断线风筝那样渐行渐远,而今似乎一切已知或既定的事实也逐渐无法确定起来,而这种不确定性是否仅存在于我而已。不得而知。21
猫在门口睡着了,未尝不可以想成因为等累了而睡着。书橱上的纸箱掉了下来,给0818准备的冬瓜凉茶,散落一地。至于为什么会变成0818我也不清楚,只是突然有人的名字噗通沉入水底,努力捞起的时候就只剩下类似生日日期的浅薄记忆。
在另一个小盒子里,还养了尾鲸鱼。
那天,在还能感觉幸福的时候,走了好多地方,看了城里所有男性专卖柜--PLAY BOY、ADDIDAS、POLO……,负责这些专柜的女孩大都特别温柔,诚心分享幸福。因为专程跑到这些价值不菲的专柜选购礼物绝对是满怀幸福的女人,至少当时如此。24
最后决定鲸鱼,宝蓝色的暗花领带,沉实稳重,希望0818即便出差或发表会都能想起我。
那时是真的这么想的。在我还能感觉幸福的时候。
我把冬瓜凉茶放进锅里,加10碗水,20分钟后满室溢香。这原来打算寄给一到夏天就爱感冒的0818,还有那尾鲸鱼。我能听见它在抽屉里不耐翻腾。它讨厌现在的尴尬状况--既不能大方地作为礼物送出,又无法被谁欣然接受;更不能原谅被冷落。27
晚上,我做了个梦。梦见我骑在鲸鱼背上,0818在一个小岛上使劲招手,我和鲸鱼头也不回地呼啸而过。
醒来,特别特别遗憾,终究是毫无缘分。
不过没关系,我的人生正无可挽回地陷入失焦状态,0818明天可能只剩下818了。30
这个梦过分亢奋,再无法入睡,扭开电视,正上映80年代的中国电影。
对于那个年代,我总格外用心,恨不得能猛吸几口那会儿的空气,在灰蓝的光与影中竭力寻找,寻找我永远无法体会0818曾经的生活。虽是一代人,但彼此的成长背景除了太阳和月亮,便没有任何交集。
每次电视画面一暗,搁在窗口水晶即巧妙地接住月光,那是仪从英国给寄来分别代表健康、幸运、财富、快乐、工作和爱情的六颗水晶。在月光下显得苍白,像白发。33
我的头发已放弃长长,仅仅变白、变白。那是从0818说最迟这个冬天或是夏天一定来看我的时候开始留的。
冬天还是夏天?36
夏天……
问题讨论:
1. 角色:你认为作品中的主角是一个怎么样的人?谁是主要角色(主角)?谁是次要角色(配角)?谁又是若隐若现的角色?
2. 情节:哪些段落是开端、发展、高潮、结局?哪一条是主线?哪几条是副线?
3. 环境:哪些是现实的环境?哪些是想象或是超现实的环境?
4. 象征/意象:哪些事情、现象和器物是另有所指/别有寓意的象征?
```
十八岁出门远行-余华
========================
十八岁出门远行-[[余华]]
-----
柏油马路起伏不止,马路像是贴在海浪上。我走在这条山区公路上,我像一条船。这年我十八岁,我下巴上那几根黄色的胡须迎风飘飘,那是第一批来这里定居的胡须,所以我格外珍重它们。我在这条路上走了整整一天,已经看了很多山和很多云。所有的山所有的云,都让我联想起了熟悉的人。我就朝着它们呼唤他们的绰号。所以尽管走了一天,可我一点也不累。我就这样从早晨里穿过,现在走进下午的尾声,而且还看到了黄昏的头发。但是我还没走进一家旅店。
我在路上遇到不少人,可他们都不知道前面是何处,前面是否有旅店。他们都这样告诉我:“你走过去看吧。”我觉得他们说得太好了,我确实是在走过去看。可是我还没走进一家旅店。我觉得自己应该为旅店操心。
我奇怪自己走了一天竟只遇到一辆汽车。那时是中午,那时我刚刚想搭车,但那时仅仅只是想搭车,那时我还没为旅店操心,那时我只是觉得搭一下车非常了不起。我站在路旁朝那辆汽车挥手,我努力挥得很潇洒。可那个司机看也没看我,汽车和司机一样,也是看也没看,在我眼前一闪就他妈的过去了。我就在汽车后面拼命地追了一阵,我这样做只是为了高兴,因为那时我还没有为旅店操心。我一直追到汽车消失之后,然后我对着自己哈哈大笑,但是我马上发现笑得太厉害会影响呼吸,于是我立刻不笑。接着我就兴致勃勃地继续走路,但心里却开始后悔起来,后悔刚才没在潇洒地挥着的手里放一块石子。
现在我真想搭车,因为黄昏就要来了,可旅店还在它妈肚子里。但是整个下午竟没再看到一辆汽车。要是现在再拦车,我想我准能拦住。我会躺到公路中央去,我敢肯定所有的汽车都会在我耳边来个急刹车。然而现在连汽车的马达声都听不到。现在我只能走过去看了。这话不错,走过去看。
公路高低起伏,那高处总在诱惑我,诱惑我没命地奔上去看旅店,可每次都只看到另一个高处,中间是一个叫人沮丧的弧度。尽管这样我还是一次一次地往高处奔,次次都是没命地奔。眼下我又往高处奔去。这一次我看到了,看到的不是旅店而是汽车。汽车是朝我这个方向停着的,停在公路的低处。我看到那个司机高高翘起的屁股,屁股上有晚霞。司机的脑袋我看不见,他的脑袋正塞在车头里。那车头的盖子斜斜翘起,像是翻起的嘴唇。车厢里高高堆着箩筐,我想箩筐里装的肯定是水果。当然最好是香蕉。我想他的驾驶室里应该也有,那么我一坐进去就可以拿起来吃了。虽然汽车将要朝我走来的方向开去,但我已经不在乎方向。我现在需要旅店,旅店没有就需要汽车,汽车就在眼前。
我兴致勃勃地跑了过去,向司机打招呼:“老乡,你好。”
司机好像没有听到,仍在拨弄着什么。
“老乡,抽烟。”
这时他才使了使劲,将头从里面拔出来,并伸过来一只黑乎乎的手,夹住我递过去的烟。我赶紧给他点火,他将烟叼在嘴上吸了几口后,又把头塞了进去。
于是我心安理得了,他只要接过我的烟,他就得让我坐他的车。我就绕着汽车转悠起来,转悠是为了侦察箩筐的内容。可是我看不清,便用鼻子闻,闻到了苹果味。苹果也不错,我这样想。
不一会他修好了车,就盖上车盖跳了下来。我赶紧走上去说:“老乡,我想搭车。”不料他用黑乎乎的手推了我一把,粗暴地说:“滚开。”
我气得无话可说,他却慢慢悠悠打开车门钻了进去,然后发动机响了起来。我知道要是错过这次机会,将不再有机会。我知道现在应该豁出去了。于是我跑到另一侧,也拉开车门钻了进去。我准备与他在驾驶室里大打一场。我进去时首先是冲着他吼了一声:“你嘴里还叼着我的烟。”这时汽车已经活动了。
然而他却笑嘻嘻地十分友好地看起我来,这让我大惑不解。他问:“你上哪?”
我说:“随便上哪。”
他又亲切地问:“想吃苹果吗?”他仍然看着我。
“那还用问。”
“到后面去拿吧。”
他把汽车开得那么快,我敢爬出驾驶室爬到后面去吗?于是我就说:“算了吧。”
他说:“去拿吧。”他的眼睛还在看着我。
我说:“别看了,我脸上没公路。”
他这才扭过头去看公路了。
汽车朝我来时的方向驰着,我舒服地坐在座椅上,看着窗外,和司机聊着天。现在我和他已经成为朋友了。我已经知道他是搞个体贩运的。这汽车是他自己的,苹果也是他的。我还听到了他口袋里面钱儿叮当响。我问他:“你到什么地方去?”
他说:“开过去看吧。”
这话简直像是我兄弟说的,这话可真亲切。我觉得自己与他更亲近了。车窗外的一切应该是我熟悉的,那些山那些云都让我联想起另一帮熟悉的人来了,于是我又叫唤起另一批绰号来了。
现在我根本不在乎什么旅店,这汽车这司机这座椅让我心安而理得。我不知道汽车要到什么地方去,他也不知道。反正前面是什么地方对我们来说无关紧要,我们只要汽车在驰着,那就驰过去看吧。
可是这汽车抛锚了。那个时候我们已经是好得不能再好的朋友了。我把手搭在他肩上,他把手搭在我肩上。他正在把他的恋爱说给我听,正要说第一次拥抱女性的感觉时,这汽车抛锚了。汽车是在上坡时抛锚的,那个时候汽车突然不叫唤了,像死猪那样突然不动了。于是他又爬到车头上去了,又把那上嘴唇翻了起来,脑袋又塞了进去。我坐在驾驶室里,我知道他的屁股此刻肯定又高高翘起,但上嘴唇挡住了我的视线,我看不到他的屁股。可我听得到他修车的声音。
过了一会他把脑袋拔了出来,把车盖盖上。他那时的手更黑了,他的脏手在衣服上擦了又擦,然后跳到地上走了过来。
“修好了?”我问。
“完了,没法修了。”他说。
我想完了,“那怎么办呢?”我问。
“等着瞧吧。”他漫不经心地说。
我仍在汽车里坐着,不知该怎么办。眼下我又想起什么旅店来了。那个时候太阳要落山了,晚霞则像蒸气似的在升腾。旅店就这样重又来到了我脑中,并且逐渐膨胀,不一会便把我的脑袋塞满了。那时我的脑袋没有了,脑袋的地方长出了一个旅店。
司机这时在公路中央做起了广播操,他从第一节做到最后一节,做得很认真。做完又绕着汽车小跑起来。司机也许是在驾驶室里待得太久,现在他需要锻炼身体了。看着他在外面活动,我在里面也坐不住,于是打开车门也跳了下去。但我没做广播操也没小跑。我在想着旅店。
这个时候我看到坡上有五个人骑着自行车下来,每辆自行车后座上都用一根扁担绑着两只很大的箩筐,我想他们大概是附近的农民,大概是卖菜回来。看到有人下来,我心里十分高兴,便迎上去喊道:“老乡,你们好。”
那五个人骑到我跟前时跳下了车。我很高兴地迎了上去,问:“附近有旅店吗?”
他们没有回答,而是问我:“车上装的是什么?”
我说:“是苹果。”
他们五人推着自行车走到汽车旁,有两个人爬到了汽车上,接着就翻下来十筐苹果,下面三个人把筐盖掀开往他们自己的筐里倒。我一时间还不知道发生了什么,那情景让我目瞪口呆。我明白过来就冲了上去,责问:“你们要干什么?”
他们谁也没理睬我,继续倒苹果。我上去抓住其中一个人的手喊道:“有人抢苹果啦!”这时有一只拳头朝我鼻子上狠狠地揍来了,我被打出几米远。爬起来用手一摸,鼻子软塌塌的像是挂在脸上,鲜血像是伤心的眼泪一样流。可当我看清打我的那个身强力壮的大汉时,他们五人已经跨上自行车骑走了。
司机此刻正在慢慢地散步,嘴唇翻着大口大口喘气,他刚才大概跑累了。他好像一点也不知道刚才的事。我朝他喊:“你的苹果被抢走了!”可他根本没注意我在喊什么,仍在慢慢地散步。我真想上去揍他一拳,也让他的鼻子挂起来。我跑过去对着他的耳朵大喊:“你的苹果被抢走了。”他这才转身看起我来,我发现他的表情越来越高兴,我发现他是在看我的鼻子。
这时候,坡上又有很多人骑着自行车下来了,每辆车后面都有两只大筐,骑车的人里面有一些孩子。他们蜂拥而来,又立刻将汽车包围。好些人跳到汽车上面,于是装苹果的箩筐纷纷而下,苹果从一些摔破的筐中像我的鼻血一样流了出来。他们都发疯般往自己筐中装苹果。才一瞬间工夫,车上的苹果全到了地上。那时有几辆手扶拖拉机从坡上隆隆而下,拖拉机也停在汽车旁,跳下一帮大汉开始往拖拉机上装苹果,那些空了的箩筐一只一只被扔了出去。那时的苹果已经满地滚了,所有人都像蛤蟆似的蹲着捡苹果。
我是在这个时候奋不顾身扑上去的,我大声骂着:“强盗!”扑了上去。于是有无数拳脚前来迎接,我全身每个地方几乎同时挨了揍。我支撑着从地上爬起来时,几个孩子朝我击来苹果,苹果撞在脑袋上碎了,但脑袋没碎。我正要扑过去揍那些孩子,有一只脚狠狠地踢在我腰部。我想叫唤一声,可嘴巴一张却没有声音。我跌坐在地上,我再也爬不起来了,只能看着他们乱抢苹果。我开始用眼睛去寻找那司机,这家伙此时正站在远处朝我哈哈大笑,我便知道现在自己的模样一定比刚才的鼻子更精彩了。
那个时候我连愤怒的力气都没有了。我只能用眼睛看着这使我愤怒至极的一切。我最愤怒的是那个司机。
坡上又下来了一些手扶拖拉机和自行车,他们也投入到这场抢劫中去。我看到地上的苹果越来越少,看着一些人离去和一些人到来。来迟的人开始在汽车上动手,我看着他们将车窗玻璃卸了下来,将轮胎卸了下来,又将木板撬了下来。轮胎被卸去后的汽车显得特别垂头丧气,它趴在地上。一些孩子则去捡那些刚才被扔出去的箩筐。我看着地上越来越干净,人也越来越少。可我那时只能看着了,因为我连愤怒的力气都没有了。我坐在地上爬不起来,我只能让目光走来走去。
现在四周空荡荡了,只有一辆手扶拖拉机还停在趴着的汽车旁。有几个人在汽车旁东瞧西望,是在看看还有什么东西可以拿走。看了一阵后才一个一个爬到拖拉机上,于是拖拉机开动了。
这时我看到那个司机也跳到拖拉机上去了,他在车斗里坐下来后还在朝我哈哈大笑。我看到他手里抱着的是我那个红色的背包。他把我的背包抢走了。背包里有我的衣服和我的钱,还有食品和书。可他把我的背包抢走了。
我看着拖拉机爬上了坡,然后就消失了,但仍能听到它的声音,可不一会连声音都没有了。四周一下子寂静下来,天也开始黑下来。我仍在地上坐着,我这时又饥又冷,可我现在什么都没有了。
我在那里坐了很久,然后才慢慢爬起来。我爬起来时很艰难,因为每动一下全身就剧烈地疼痛,但我还是爬了起来。我一拐一拐地走到汽车旁边。那汽车的模样真是惨极了,它遍体鳞伤地趴在那里,我知道自己也是遍体鳞伤了。
天色完全黑了,四周什么都没有,只有遍体鳞伤的汽车和遍体鳞伤的我。我无限悲伤地看着汽车,汽车也无限悲伤地看着我。我伸出手去抚摸它。它浑身冰凉。那时候开始起风了,风很大,山上树叶摇动时的声音像是海涛的声音,这声音使我恐惧,使我也像汽车一样浑身冰凉。
我打开车门钻了进去,座椅没被他们撬去,这让我心里稍稍有了安慰。我就在驾驶室里躺了下来。我闻到了一股漏出来的汽油味,那气味像是我身内流出的血液的气味。外面风越来越大,但我躺在座椅上开始感到暖和一点了。我感到这汽车虽然遍体鳞伤,可它心窝还是健全的,还是暖和的。我知道自己的心窝也是暖和的。我一直在寻找旅店,没想到旅店你竟在这里。
我躺在汽车的心窝里,想起了那么一个晴朗温和的中午,那时的阳光非常美丽。我记得自己在外面高高兴兴地玩了半天,然后我回家了,在窗外看到父亲正在屋内整理一个红色的背包,我扑在窗口问:“爸爸,你要出门?”
父亲转过身来温和地说:“不,是让你出门。”
“让我出门?”
“是的,你已经十八了,你应该去认识一下外面的世界了。”
后来我就背起了那个漂亮的红背包,父亲在我脑后拍了一下,就像在马屁股上拍了一下,于是我欢快地冲出了家门,像一匹兴高采烈的马一样欢快地奔跑了起来。
-----
一九八六年十一月十六日 北京
史蒂文·米尔豪瑟 著
孙仲旭 译
-----
普鲁士人包围了我们(注:本篇的背景为1870—1871年的普法战争,此场战争以法国战败而结束),我们无路出去,所以我急急忙忙升空,一只手抓着摇摇晃晃、到我腰部那么高的柳条篮子边,另一只手抓着一根绳子,绳子一头绑在篮子上,一头绑在上方的一个环上。我往下看,看到了仰起的脸孔、朝上伸着的胳膊、挥动的帽子,我听到“法兰西万岁!”“共和国万岁”的呼喊。在有风的蓝色的十月天空中,我的领航员瓦拉德穿着他那件裹得紧紧的大衣站在我旁边,冷静得好像他在往一家猪肉铺的窗户里看。我的任务简单:飞过普鲁士人的包围圈,降落在未被占领的法国,在外省组织抵抗,迟一点我会和图尔的甘比大会合。危险来自多方面,目的地与风向不确定,但是这时在快到中午的光线下,当我升起在巴黎的屋顶上方,下方的壮观景象还是让我吃了一惊:荣军院闪着光的镀金圆顶,圣叙尔皮斯教堂不一样高的塔,杜伊勒里花园的一排排大轮子铜炮,市内广场上一群群绵羊,在一座被炸毁的桥旁边塞纳河里洗澡的士兵,看!凯旋门顶上的旗语站,那条河像一轮绿色的新月一样弯弯地穿过这座城市,房顶上的人眺望要塞和小山。每条街上都颤动着光和颜色,戴着红色军帽、穿着蓝色长外套、红裤子的国民卫队,女士们黄色、紫罗兰色和绿色的阳伞,来复枪枪头长刺刀的闪光,还有一个轻步兵的红色头巾,那边突然有铜制品(一位骑兵军官戴的上面有马鬃的头盔)闪了一下光,当时我们在东南风中飘往西北方向的城墙。
——
环绕着巴黎的雉碟式厚城墙有30英尺高,有94座棱堡,城墙上有无数射击孔,并且配备了重型大炮。国民卫队、正规军和外省的动员军夜以继日在城墙上守卫。巴黎,光明的城市,有着两万间咖啡馆的城市,已经变成一座中世纪的堡垒。墙外是条十英尺宽的护城河,护城河外面是把这个城市围了一圈的16座要塞,每座要塞有50到70门重炮。那圈要塞之外的小山那边是毛奇的军队的包围线。有没有哪个城市被保卫得如此之好?巴黎固若金汤,我们决不投降。
——
在我们下方,我看到城墙上的士兵在抬头看,他们挥着军帽,枪托朝上举枪致敬。就在西边的城墙外面,在布洛涅森林那边的蒙马特高地上,我看到橙色火光一闪,烟好像是从烟囱里冒出来的,向一旁飘去。那团烟雾悬在空中,就好像墙上的雪。我能认出炮手帽子上的红色。四轮两座大马车和双排座活顶四轮马车离那尊大炮很近,穿拖地长裙的女人站在那里观看,因为看开炮已经成为巴黎人的一种娱乐。
——
在我上方是鼓鼓的巨大的黄色气球,是用涂了清漆的棉布做的,里面充满煤气。它有五十英尺宽——给普鲁士军队的针发枪当靶子挺好,一颗子弹打穿布,就能把天空变成一个致命的火球,但是眼前的危险——当我们在北部和西部的城堡中飘过时——是来自气球本身无法预测的运动。瓦拉德可以通过扔掉沙袋而让它上升,通过拉阀门绳放掉气体来下降,但是就连他也控制不了风向突然改变、篮子的摇晃和倾斜、空气的温度——那会让气体膨胀或收缩。瓦拉德仔细看从上面的圆圈吊下来的航海用指南针,读在指南针旁边吊着的气压计。我们两人都很清楚气球是难以操纵的。发明家提出过用帆、螺旋桨和直接来自神话中的一群鸟。这个篮子的边再高一点就好了!秋天时变成黄褐色的小山里,藏着普鲁士人的炮兵阵地。在清冽的空气中,我听到不知道从哪里的农家院里,传来一只公鸡突然打鸣的声音。
——
我抓紧一根绳子,让自己靠着低低的篮边站稳,往下看田地和杂树林、散开的农场和一个有一座教堂的村庄。瓦拉德告诉我我们离地面有一千英尺。这时在清新的十月空气中,几乎会让人感觉平和。小山是红色、褐色的,有一块块黄色,还有我们的气球投下的起伏的影子。在这里,在天空这里,宁静的蓝色天空这里,当我们飘过秋天的树林、阳光照耀下平和的田野时,你也许几乎会忘了树林中的普鲁士军营、卢浮宫窗户那里的沙袋、以马肉为食、从沙蒂永战役开小差躲到蒙帕纳斯高地的士兵的脸庞、在法兰西喜剧院的演员休息室为伤兵放置的床。
——
突然,从一片树丛中出来一个骑着黑马的枪骑兵,他那顶带羽饰的闪闪发光的头盔就像一座外国教堂的圆顶。我能看到他挂在腿边的马刀,白色绶带挂在胸前。他抬头看我们的气球时,那片杂树林中又出来一个枪骑兵,抬头盯着我们看,一只手里端着一根比他的马还要高的长矛,矛尖上飘扬着一面三角旗。这时他们开始追赶我们、喊叫。我看到了第三、第四个枪骑兵,我听到一声响亮的来复枪声。一群乌鸦从树林里尖叫着飞起来。瓦拉德割断篮子边上系着一个沙包的绳子,又割断了系着第二、第三个沙包的绳子;我们急速上升,篮子危险地摇晃着,有什么让我的手感到刺痛;一道血;那几个枪骑兵在下方很远的地方,有八个,十个;我把被子弹擦伤的手包起来。我们晃晃悠悠地朝着上方天空中寒冷的区域飞去时,那些变得越来越小的枪骑兵骑马追赶我们。
——
我们已经上升至一万英尺的高度,在明亮而寒冷的天空中,我已经认不出低头看到的世界:不规则的一块块绿色和紫罗兰色—褐色,就是乱画出来的一条条黑线,像是漂浮的雪的一块块云。这里,在这个高度,人是看不清的,只有大自然,你会有所触动,感到不安。我想到了大自然的辽阔与人类的渺小,但我的想法是不准确的,未能表达出像一团黑暗在我内心活动着的感情。就好像我心里有了道缝,一个裂口,一个伤口,对,不是子弹擦的那一下,而是内心有地方裂开了;在那种黑暗中,一切都毫无意义,不管我去努力还是睡觉,打呵欠还是流血,完成我的任务或者飘向月亮;在那种丑陋的黑暗中,巴黎和柏林没有区别,巴黎和撒尿没有区别。可恶的高度!这里只有梦的死去、长着地狱之火翅膀的堕落和天使黑色的笑声。一种可怕的淡漠感掠过我心里,深深触动了我。总是有个微小的声音在悄声说话,悄声说:有什么关系呢,这样还是那样……我看着我紧抓着篮子边缘的冷冷的手。手指,我说,手指,手指,但是我不理解那个词。人们有手,手有手指,一只手五根手指,两只手有十根手指。法兰西是个国家,英格兰是铺主的国家,法兰克国王克洛维在苏瓦松打败了罗马军团,盖乌斯•尤利乌斯•凯撒于公元前44年被刺。我看到瓦拉德的胡子上有冰碴。
——
当瓦拉德拉阀门绳,我们开始从危险区域下降时,那种感觉就像一阵眩晕、疯狂一样过去了。我看着瓦拉德这个少言寡语的人,他不易激动,保持不变。他二十六岁,肩膀宽阔,来自鲁昂附近的一个村子,父母是农民。他让我放心,外省会起来消灭侵略者。瓦拉德讲了一个农民的故事,这个农民遇到一个普鲁士巡逻兵时,将其扑倒,咬开了他的喉咙。我问他是在哪儿学会为气球导航的,“奥尔良码头。”他用他那种言简意赅的方式说。我的脑海里马上浮现出奥尔良码头那间巨大的候客厅,还有长长的工作台,一排排裁缝坐在那里,在煤气灯下把大片的白棉布缝起来,水手编绳子,编织能包住气球的网,穿着蓝衬衫的工人编柳条篮子。在那个大房间的地板上,在废弃的铁路轨道旁边,充了一半气的气球——巨大的,松松垮垮的——歪放在那里,它们极长的弧线越过工人们的上方,到了墙壁的一半高度那里。在高高的头顶上,在玻璃加铁结构屋顶的下方,从站内的大梁那里用绳子吊着几个篮子。瓦拉德就在其中一个篮子里为我们这次飞行做准备,当时他低头看着长长的工作台、墙上的一排排煤气灯、女人们正在缝东西的手、放在路轨上的大气球的阀门。
——
往哪儿看呢?不是往下,因为我看到的,仍是个看不到人的世界,一个无意义的世界。就像撕裂了一条韧带,那道裂缝开始打开,里面的伤口开始流血。不是往上看,因为往上我看到一个黄色怪物的底部,这个怪物在用爪子抓着我,把我带向地狱般的天上。那就直直往前看?不,因为在我前面是一道道宽阔的神秘蓝色——不祥的蓝色——令人极度不快的蓝色。我不害怕死亡,我已经准备好为法兰西而死。但我害怕这种蓝色的虚无,这个细细的声音在悄声说,悄声说:噢,有什么关系呢,巴黎还是普鲁士,呼吸的暖意或者尸体的冰冷。我感到一阵厌恶,厌恶上面这个天空世界中的一切,这个有着小小的黑色秘密的嘲笑的蓝色天空。对这一切感到恶心至极,我死死盯着这个寒碜的篮子,盯着由粗糙的手编出来的一条条柳条,盯着吊在篮子旁边的六爪锚,盯着装有政府急件和一万封私人信件的皮袋子,盯着一袋袋压载物、那卷绳子、让外省人把消息传回巴黎的一篮鸽子。柳条篮,皮革,铁器,绳子。现在我平静了。
——
毛奇的围城部队分散在一道无法防御的周长为50英里的包围圈上。他们希望把我们饿得投降,但我们绝对不会投降。今天我们吃马肉,把黄色的马油涂在面包上。明天呢?明天我们会吃铺路的石头!但是我们必须有所行动。想到我们无所事事,就让我怒火中烧。日尔曼人的第一、第二集团军被拖在洛林地区,在麦茨的城墙前,但是如果麦茨失陷呢?那又该怎么办?那两个集团军就会被放出来,来加强对巴黎的包围,要么去跟南方甘必大的军队交战。我们必须进攻!双线进击不可能失败:同时从巴黎各城门突围,同时从日尔曼人战线后方发起攻击。在图尔跃跃欲试的甘必大急于夺回奥尔良,和卢瓦尔河一带的军队一起往北向巴黎进军。我跟那种人一样,相信明智得多的,是卢瓦尔河一带的军队和北方的军队在鲁昂会师,然后一起沿着塞纳河谷进军巴黎。但是有一件事毫无疑问,那就是我们必须有所行动。我们的外省军队的任何动作,都会迫使毛奇从他拉得太开的包围圈那里调走部队。他会被削弱,感到迷惑。我们必须马上进攻,必须消灭侵略者,必须为色当灾难雪耻。在共和国的荣耀中,帝国的耻辱会得到洗刷。
——
我往下看着有着树林的乡间。这里那里会有一片林间空地、一幢小屋,小屋烟囱直直地冒出一柱烟,烟柱的顶端有点摇晃,看上去像是散开的绳子。一只鹰高高地飞过树林上空,我们不知道这是哪里的森林。指南针的指针疯了似的乱转。树林里有等着像欢迎英雄一样欢迎我们的法国人吗?要么有普鲁士的炮兵阵地的军营,端着针发枪的士兵已经在往上看、瞄准?瓦拉德相信降落是不安全的,到处都有普鲁士巡逻兵。我们在不知其名的森林上空飘得更高。
——
昨天我走出城墙到了布洛涅森林那里。因为把大树砍了当燃料、设路障,留下了令人不安的新景观:能看到远处圣克劳德的白色教堂、从闷烧的房子那里升起的颜色发蓝的烟雾。长着矮灌木、树桩处处的田野延展开去,到处能看到灰色帆布搭的帐篷和用冷杉树枝搭的棚屋、搭在绳子上晾干的衬衫。路上一直有四匹马拉的大轮子铜炮发出的轰隆声;拉军火的马车;然后还有观光者的私人马车轻一点的隆隆声。在你的耳朵、皮肤和脚底里,总能感受到瓦莱里安高地要塞那边传来的大炮轰鸣声。
——
一片有起伏的平原,黄色的蛇麻子地和燕麦地,被犁过的褐色农田,一条运河的黑色线条,有影子的干草堆,一丛丛树。我看到一座扇页在转动的风车,旁边有转动的影子。远处,小山带点紫色和褐色。尽管我特别留意树林里有没有动静,这样却是平和的,在蓝天中一直飘着。我心里悄然有了种难以捉摸的欲望:待在高处,生活在空中,永远悬浮在大地与天空之间。那种欲望让我感到不安,在其最深处,我感觉到有种秘密的弱点:这种突然出现、难以解释的欲望,这难道不是标志着意志薄弱、内心有未愈合的伤口?停留在上面,往下看,随风飘荡,放弃,做梦……这难道不是用漠不关心来选择立场,让内心的裂缝裂得更开?所以——单纯是逻辑,让我不得不得出这样的结论——这难道不是秘密地助了普鲁士人的事业一臂之力?天空是危险的,我必须保持警惕。
——
我定睛看下方已经在过渡成为树林的田野,强迫自己去考虑战争。大炮的问题让我睡不安稳。在斯皮歇壬、弗罗埃斯克维莱、圣普里瓦、色当打过仗的士兵的说法令人不安,不过有可能夸大其辞了。在战争时期的混乱状态下,还有可能了解事实吗?然而后膛装弹的铜管克虏伯大炮似乎比我们前膛装弹的铜管大炮的射程要远得多。这有可能吗?装了雷管的克虏伯炮弹只是在受到撞击时才爆炸,而我们装有定时引信的炸弹多数在空中就爆炸了。据说如果毛奇发令,普鲁士的炮手可以从夏迪龙高地(九月时失陷)把炮弹打到巴黎的街道上。为什么,为什么,为什么我们要坐以待毙?我们的储备还能撑多久?我们想拿巴黎换面包皮吗?我们必须进攻。巴黎已经准备好了,渴望一战。我们的战士装备了极好的后膛装弹的夏塞波式来复枪,能够瞄准1600码以外的目标。想想看吧!拿破仑一世的士兵——耶拿的征服者——装备的是前膛装弹的滑膛火枪,射程简直还不到50码!我们的来复枪甚至比普鲁士人的针发枪要好得多,而他们的针发枪已让奥地利屈服。我们干吗要坐着什么也不做?在树林里,我看到突然有什么动静,似乎是一头动物,也许是一头鹿。
——
难以摆脱那种百无聊赖的感觉。蓝色的天空,我们气球的影子起伏着掠过树木。那种欲望又出现了,不是欲望,而是种倾向,不是倾向,而更应该说是一种心中的意象,无聊时的想象,寂静与蓝色天空所产生的。我受过这么重的伤吗?我一定不能放弃。然而生活在空中,一个飘来飘去的人,一个天空中的公民……这当然可以做到。时不时下去一下,在一块土豆地或者李子园,气球的篮子悬浮在锚上方,然后爬一段绳子,爬进我在空中的家,进入别人到不了的地方。很容易就可以把这个篮子弄得更文明一点,有睡觉地方,有遮挡雨雪的屋顶,书,食物储备,写东西的材料,一杆来复枪,一架望远镜,养在笼子里用来做伴的鹦鹉——一个漂浮的岛屿,可移动的窝;在变化的景象之上游遍世界:有着白色浪头的大海和猴子叫的丛林,北方闪闪发光的冰山。我的床漂浮在天空的蓝色湖泊中,永远不再回来;童年时的梦。
——
我可以把瓦拉德从篮边推下去,一个快速的动作就够了。他会很快掉下去,翻转一周又一周。一件不幸之事。突然变轻的气球迅速上升,但是我冷静地拉动阀门绳。一个人,飘过天空,离开一切。这是可以做到的。
——
有过这样的想法——我已经不再是我自己了吗?被天空变得没人性了吗?被天上变疯了!这时——突然的感情变化——这个篮子里让我感到恶心;绳子,锚,我的手像是个冰冷的爪子一样抓着篮子边;我无法忍受这个地方;这次飞行;在这里悬浮;无人性的天空;往下,往下看;我的皮肤感到刺痛,我想:跳下去,感受头发里的风,冲进一股疾风中,感觉自己撞到一棵树上骨折;甜蜜的疼痛;刺进我喉咙的刺刀;鲜血涌出;重重地砸在地上;反正不是像现在这样。
——
突然,我们进入有涡流的浓雾中,在我半步之外的瓦拉德变得像是鬼魂。在我上方,那个气球已经消失。吊着篮子的绳子上升到烟雾中,就像粉笔画的线条一样被抹掉了。云变厚,我的手消失了,我看不到自己。除了寒冷、潮湿、凄凉、空虚的灰色和我手抓紧篮边时感到的刺痛,这个世界上什么都没有。我们已经死了,我和瓦拉德,我们已经进入一个没有影子的区域,一个被抹掉和缺少东西的世界,一个瓦解了的王国。一团团云雾像烟一样进入我嘴里。这里,在另一岸,在世界的尽头,让我能看到、摸到东西吧:一只手的形状,下巴的曲线,一块石头的重量,尘世之物的重量。让我看到边缘!边缘!
——
最后,在那里,在云的汤里有一个形状,我们飘近时,下面,在雾的漩涡被割出来的,对!树梢——一棵松树的?
——
我们冲破云层,云好像在我们上方像蒸汽的长条旗一样急冲,看到下方有道山谷,又宽又深,被阳光乱砍——绿得耀眼,有几处黄色和猩红色——像烟一样的一片片薄雾。阳光之剑从云中刺去。我们飘到一座陡峭的小山上,山上长着直直的松树。我们下方有一群鸟,黑蓝色,在它们拖在后面的影子上空飞。我看着瓦拉德,他跟我凝视的眼光接触。我们之间心领神会。他也感觉到了吗?是时候了。他拉那根阀门绳,我们开始下降。黑色湖泊般的影子落在秋天的树林和田野上。一条铜褐色的溪流或者河,闪着鱼鳞般的阳光。远处那座小山上,有一座石板屋顶的很小的农舍。是友是敌?我们已经升空4个半钟头又35分钟,是时候了。我们的指南针疯掉了,没有用,但是风变得如此频繁,什么指南针都不管用。我们真的安全飞过了日尔曼人的包围圈吗?我们到了北边吗?西边?这是哪里?我们被吹到布列塔尼半岛那么远了吗?是否有可能我们往东飘,越过边界,进入了比利时?我们不知道。就这样吧!我们下降时,我仔细看那片森林,看有没有帐篷、马、迷路的巡逻队。我只看到云影在田野和森林那里变幻、那幢寂静的农舍、一片残留着农作物茬的田地、松树林。我们的气球胖胖的影子在下方滑过,后面拖着小得让人不放心的我们篮子的影子。这时出现了开阔的草地,在树木中间是棕褐色、黄色的。紫红色的影子。杂树林,田野,灰色石头露出地表的岩层。我们斜斜地降落时,地面上升来迎接我们,变得更大,分裂成细节。我开始辨认出禾杆色的高高的草、一块有坡度的田野上紫色、白色的野花。我抬头往天上看,看蓝色的天空和飘荡的云,上面那里宽阔的空间就像斧刃一样劈开了精神。我跟低语着而且太高的天空道了别,然后眼睛往下看,看着升起来的大地,看着坚实的地方、人类的骚动。
**使用 TiddlyWiki 进行个人知识管理**
近一段时间在研究个人知识管理,期望能够找到一个好用并且能够长期使用的「非线性笔记」软件来进行管理。近期比较火的 Roam Research 与 Notion 都尝试过,但可惜的是两者都有些地方我不是特别满意。最后我选择了 TiddlyWiki 来进行知识管理。
无法满足需求
------
理论上 [[Roam Research]] 是最符合我的需求的,但问题在于后续的收费价格过高(15 刀每月),并且手机上不管是看还是写都不是特别的友好。
而[[Notion]] 多端的支持很不错,但是有一些小的点用起来还是特别难受。例如,笔记间相互链接不够方便(利用 database Relation 不好用,行内关键词无法直接链接到对应的笔记);加载速度太慢,稍微大一点的 database 都需要转蛮久的菊花。
而且以上两者都或多或少的依赖网络,完全离线的状态下是不可用的。最后也是最重要的一点是,使用这些服务时数据需要储存在云端,太过脆弱。
我的需求
----
因此,对于个人知识管理软件我的需求有以下几点:
* 成本低(毕竟是要长期使用的)
* 网状组织结构,能够方便的在笔记间相互链接
* 能够离线使用,如果能够公开分享更好
通过了一番搜寻,发现了曾经嫌弃太丑的 [[TiddlyWiki]] 完全的符合需求,而且并不是印象中的那么丑。更棒的是 TiddlyWiki 完全免费!
{{https://ahonn-me.oss-cn-beijing.aliyuncs.com/images/LMq7hQ.png?x-oss-process=image/format,jpg/quality,q_100/resize,w_650/interlace,1}}我的 TiddlyWiki
TiddlyWiki 特点
-------------
### 单 HTML 文件
单 HTML 文件,没有什么其他的东西,软件与数据本身都在其中,每次保存的使用会生成新的 HTML 文件。部署及其方便,如果需要公开笔记给其他人看只要将这个 HTML 文件丢到服务器上就可以了。
### 丰富插件与主题
作为一款十几年历史的软件,相关的插件非常的多,能够实现大多数想要的功能。而且还可以通过主题来解决长得丑的问题,再不济可以写些 CSS 样式来改造它。
### 强大的编辑能力
通过标签与条目间的互相引用可以非常灵活的进行整理,并且提供了一些非常强大的宏来实现一些复杂的功能(例如,列出某个标签下面按时间排序的最近 15 条日志条目)。
另外,通过 {{CodeMirror}} 插件还可以对编辑器进行增强,可以使用 emacs 或者是 vim 之类的 keymap,或者是添加代码高亮支持(BTW,Roam Research 对这方面的支持几乎为 0)
如何使用
----
由于 TiddlyWiki 是单 HTML 文件,所以一开始非常简单,只需要在官网上[下载空白](https://tiddlywiki.com/#GettingStarted)的文件,拖进浏览器中就可以使用了。但这样在保存的时候会比较麻烦,需要把生成的 HTML 文件(内容保存后的文件)保存下来或者是覆盖原来的 HTML 文件。
为了简化数据保存的步骤,TiddlyWiki 提供了[一些方案](https://tiddlywiki.com/#GettingStarted),大概分成几种:通过服务端部署的方式自动进行保存、基于浏览器插件自动处理、使用专门的 Desktop 软件。
这里我使用的是 [TiddlyDesktop](https://tiddlywiki.com/#TiddlyDesktop) 软件的方式。我将 TiddlyWiki HTML 文件放到 iCloud 中,然后通过 TiddlyDesktop 进行编辑与保存。TiddlyDesktop 会在保存的时候将自动备份原文件,然后把修改后文件覆盖原文件,从而实现了数据保存。
由于放置在 iCloud (你可以选择你喜欢的同步方式) 中,因此在不同的设备上都可以进行编辑、保存和同步,我唯一需要做的就是安装 TiddlyDesktop。
### 插件与主题
前面提到了 TiddlyWiki 上可以安装 CodeMirror 插件来增强编辑器,除此之外,TiddlyWiki 还有非常都的插件与主题可以使用。可以通过 [TiddlyWiki toolmap](https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM) 来找到需要的插件与主题,如果现有的插件不满足需求,我们还可以[通过 JavaScript 来编写自己的插件](http://tw5-zh.tiddlyspot.com/#Using%20ES2016%20for%20Writing%20Plugins)
我使用的一些插件
### 双向链接
Roam Research 最大的特点以及用的最舒服的功能就是双向链接了。因为在 TiddlyWiki 中也希望能够有类似的功能。幸运的是,社区已经有人做了,并且它可以通过插件的形式集成到现有的 TiddlyWiki 中。它就是 [Stroll](https://giffmex.org/stroll/stroll.html#Welcome%20to%20Stroll)(前身是 [TiddlyBlink](https://giffmex.org/gifts/tiddlyblink.html)),通过 TiddlyWiki 强大的宏来实现双向链接。
Stroll 实现的双向链接
### 使用控件与宏进行定制
除了使用插件来进行拓展之外,还使用内置的[控件](http://tw5-zh.tiddlyspot.com/#Widgets)或[宏](http://tw5-zh.tiddlyspot.com/#Core%20Macros)来进行定制。
通过控件,我们可以使用 `transclude` 控件来在条目里面动态的嵌入其他条目的内容;或者使用 `diff-text`控件展示两个条目直接的差异。通过使用 `tabs` 宏来把一些条目放到同一个条目中的标签里;使用 `copy-to-clipboard`宏来显示一个复制到剪贴版的按钮。
写在后面
----
目前来说,TiddlyWiki 基本满足我的需求,使用体验上来说与 Roam Research 类似,但又提供了更多的功能可以做更多的事情。当前我的使用模式是每天写日志,将看到的、学到的东西统统记录到里面,充当日记的角色,也充当 Wiki 的角色。
至于使用 TiddlyWiki 不足的地方可能还需要用多几个月后来回来补充。如果你有什么看法或者想法,欢迎留言交流~
相关链接
----
* [号外:知识管理工具 - Λ-Reading](https://rizime.substack.com/p/d28)
* [使用 TiddlyWiki 打造轻便个人 Wiki 知识库 - 钉子の次元](http://blog.dimpurr.com/tiddly-wiki/)
* [TiddlyWiki 舞 — 基礎文件正體中文版](http://tw5-zh.tiddlyspot.com/)
* [TiddlyWiki toolmap - Dynalist](https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM)
世界文明的河源-胡兰成
========================
世界文明的河源-[[胡兰成]]
-----
欧洲的地下考古,及摩尔甘调查易洛魁蛮族的报告,作成今人关于古代社会的知识。但自第一次世界大战末期至第二次大战前夕,又发掘俄属土耳其斯坦的阿瑙,伊朗高原的古都市苏撒,毗邻亚述的古墟及印度全境,出现了全新的证据,它不只是异类的,而且有为今史学家所不知的文明,以致他们无法处理,因为人是要自己亦是美人,陌上拾得旧花钿,才能知昨天有美人在此经过的。但阿瑙及苏撒的出土物迄今虽还只是专家手里的材料,而像地上桂枝,已够喜鹊衔来搭成桥,走到古代世界的银河了。
太古印澳非之间的大陆渐陷为海洋时,曾在此居住过悠久岁月的人类一支深入澳非内地,一支迁至中央亚细亚。及旧石器末期,此中亚盆地又渐成沙漠,漠北白种人愈北去深入于森林沼泽,停滞在渔猎。漠东黄种人亦陆续更东徙,先行的至满州一带,尚只知渔猎,后去的至蒙古一带,始进于游牧。而漠南黄种人及漠西南白种人则移入阿瑙苏撒地方,发展为定居的农牧,建起新石器时代的始生文明。
阿瑙石器估计起自公元前九千年,石器铜器并用起自公元前六千年,铜器起自公元前五千二百年,苏撒亦相仿。
阿瑙苏撒新石器时代,已有石制的锄犁锹镰斧锯,及耕牛骆驼骡马,能建屋造船,发明了滑车杠杆,应用轮盘于辘轳,且会立石柱测日影,制定历法。陶器的形状及绘画多是几何学的,亦有自然作风的写生绘,明朗而无图腾。有阳光与音乐。有数学。
火的发明是在前,但至新石器人始知以火烧除森林草莱,开辟出广大的耕地,本格的农业遂成立。农业作成定居,定居又把渔猎及游牧变成畜牧。火又引出铜铁来,前此旧石器时代不知经过多少万年,而新石器时代则在短短几千年中,即进入石铜并用及铜器时代了。
中国有女娲氏炼五色石补天,烧芦灰填地的古说,那石即新石器,五色是有铜铁在内了,而烧芦灰则是焚森林开辟出耕地,为前此旧石器人只用石斧砍伐所必不能的。当初看见土壤露出来真是件喜事,遂对于大地有了新的感觉,而且天为鲜洁明静的泥土所映,亦成了昭明的天,补天填地是有了新的日月山河了。印度人对这件事的记忆有传灯古佛,波斯人且拜石拜火,但皆不及女娲的故事平实。而希腊人说火是普洛美修斯从天上偷来,那是因希腊人的祖先不曾参加过发明火,后来才从埃及巴比仑人那里窃得的。
女娲之前,有盘古,盘古开天地,用的一把斧是旧石器时代的,只是自然形状的锋利石片的摹制品。而新石器时代的斧,则更磨光装柄,且轮廓线条变出花样来,斧才不只是工具,而亦呈生命的姿态,自己会得生长,演绎出滑车及杠杆了。
恩格斯说人与动物的分界是人能制造工具,但他不知制造尚有摹制与创造的分别,摹制仍是凭借外物,而创造则是人的流露,新石器的斧比旧石器的不只在程度上更复杂,而是还开了一个新境界,人才在天地间有着他自己的东西了。罗素亦惟知摹制,他以地图为喻,说地图非事实物,但亦非虚幻,它是摹仿地面的,而可以准确到与地面相符。但是地图到底于人不亲。
再说滑车及杠杆的发明。现代的机器亦不过是工作机与传递机与动力机的组合,而新石器时代已有滑车则是第一次出现传递机,故又诱发畜力风力水力的利用,把动力机亦渐渐催生,而且对工作机生起更复杂精密的要求,渐渐离开石器,应用铜铁了。
这传递机的巧妙全在轮盘。中国《周礼•考工记》里说轮人如何造轮,竟是把来作为礼,印度亦佛经里有转轮圣王,又说世界为风轮所持,而且这轮竟是法,“三转法轮于大千”,我们的祖先当初发明了轮盘原来有这样的高兴。西洋人则没有这种记忆。
H. G. Wells的《世界史纲》里称阿瑙苏撒时代是日石文化,V.G.Childe著New Light On the most Ancient East里称旧石器人为绘画的民族,新石器人为音乐的民族,而且已有氏族社会。日本关于这方面的介绍,有中原与茂久郎的《西南亚细亚文化史》,杉勇的《西南亚细亚文化之源泉》。而我现在,则以一个中国人来说明这件大事。
旧石器时代的洞穴壁画亦如他们的石斧,只是外界自然物的摹仿,著的颜色没有光,多是灰色似的,其有用浓烈的颜色的,亦惊恐刺激混浊,是人的沉重的存在。而新石器时代的音乐,则是生于喜气。
轮盘及杠杆滑车辘轳是流丽的节奏的源泉。但音乐虽成于节奏,而不止于节奏,新石器时代是更因正式出现了产业,并且有了好性情,劳动不再只是手段,器物不再只是工具,而亦是赏心乐事,人乃从需要与应用的小范围里解放出来了。前此旧石器人的脸都是凶恶的,要到新石器人才会得喜笑,故能有音乐,而且主言语亦活泼发达了。
后世有悲哀的音乐,但《乐记》“乐者乐也”,音乐是快乐。而且八音皆与产业及人事相连,是故乐在中国乃是礼乐的乐。印度虽有天之伎乐,希腊亦有日神爱坡罗手执金琴,但皆与产业及人事相失,对新石器的音乐传统隔膜了。至于今之史学家,说音乐的起源是为了劳动的协力,及吹管象百兽之声以诱百兽,且有巫咒的作用,这种一是需要,二是摹仿,三是巫魇,皆惟从蛮族人及现代西洋人的祖先考查得来,阿瑙苏撒新石器时代的却并不如此。
彼时言语的发达,亦非只因物类增多,劳动复杂,言语在应用上的需要扩大了,而是更因文明开拓了无用之用的领域,让言语可以逍遥,摇曳有姿,如中国人的看书是说看闲书,说话是说闲话,国家兴亡大事亦是渔樵闲话。而《诗经》里的“爰居爰处,爰笑爰语”,还比印度的“佛以一音演说法”更有人世的热闹活泼,此即是言语的有风光。中国语不但音韵发达,而且言语自身即是个意思无限,远非惟为需要及应用的西洋语所能及。西洋人虽有舞,而其日常动作皆是直线的;虽有音乐,而其言语则只是工具,故其舞乐亦不过是手段,为了艺术的需要。
阿瑙苏撒时代亦有了人的天下世界的风姿熠熠,故有音乐,有笑语晏晏,有可喜乐的太阳。前此旧石器时代亦有太阳,但照在洪荒草昧的自然界,连太阳亦是迷惘不安的;新石器时代则照在妙相的人间,故太阳乃亦是音乐的妙相的了。连原有的绘画至此亦成为妙色,而与音乐生在一起的舞亦成为妙舞,当时乃是这样一个有妙相妙色妙舞妙音声的阳光世界。
佛经,“尔时光明过百世界,遍照东方千世界,南西北方四维上下,亦复如是,尔时世界在光明中微动,空中雨宝摩尼云、宝幢云、衣裳云,尔时光明中出妙音声,颂扬如来现相”。而中国人说的则更即是历史,《尚书》里有寅宾出日,寅饯纳日,以及光被四表,百姓昭明。西洋人可是远远望过去惟见神的头上有一圈光明,小得很,而且必与黑暗对立。今之史学家又说古人惟为农业的需要而发明历日。此皆是他们没有阳光世界的胸襟。
中国人对于岁时节气的亲切,并非因其农业社会,西洋在农业社会时代亦没有过对于岁时节气的这亲切。亦惟中国人记得音乐是出生在新石器时代,说女娲始作笙簧,而且知道音乐与天文数学是生在一起的,统归于律历。《汉书•律历志》,“度者所以度长短也,本起黄钟之长”,黄钟之长是九十黍,惟因黍有大小,不能尽准,故又埋律吕之管于地,取验于节气。
数学始生于新石器时代。新石器时代的人不只是动物身,却还可以是如来身,天不再是洪荒草昧的自然界,而是昭明的天。这天人之境便是荡荡乾坤,清平世界,有光阴迢迢,风景无边,而这亦即是数学的0无有内外,点惟有位置而无面积,线惟有长而无幅与厚的由来。是故数学与其说是理,毋宁说是妙相,印度的数论师是相宗,而中国亦以数学通于天人之际。
西洋人不知文明是这样虚虚实实的存在。故罗素说0是一个群或团或类,殊不知0时尚未有一,如何能有这一群一团一类的一?而且数学是演绎的,归纳但是演绎行程中的段落,他以归纳法作成的群或团或类乃是科学的,而非数学的。以归纳法作成的0,即有内外,有非0的部分,有限而不精密,又如何能是数学的0?
0亦即是点,是点之初,从0生一,此时0遂是点了。又从点生线,从一生二。是一路演绎的过程,《隋书•律历志》有“传曰,物生而后有象,象而后有滋,滋而后有数”,这“传曰”真来得辽远,乃是从新石器人传下来的。
旧石器时代亦有物生,但渔猎人对之不注意,是新石器人有了农牧与手工业,才看着并且晓得种的秧苗,养的小羊小马,一天天在生长;又因耕地纺织,才晓得工作的进度,不像渔猎人的只有得,或失,而没有已做了多少,还要做多少的认明。而且是在这种工程里,人才觉得了日影在移动,注意到它的一寸寸。
人世的诸般妙好,皆是一个生命的演绎,而在劳动中有着人与物的亲情,好比女孩子刺绣,看着绣的花从自己手里一朵朵生出来,有欢喜。因是一物的生长,故秧苗及小羊小马及纺织物的一节节发育进展,与日影的一寸寸换地方,皆不过是位置的移动。且因新石器人已有轮盘滑车及杠杆等,这种移动皆在手工业里压缩,变成更显明活泼的可被觉察,可被计算了。
数学从点有线,最短的线是二点,即是二黍。而数字从一到无论若干,皆只是点的线的演绎,故数从度,大小多少皆惟是长短。
从点线又有自理,如连结自理,两点之间恒可作一直线,亦只可作一直线,此即因是数学的点线才可能,若点有面积,线有阔厚,则或许可能作一直线,或许可作许多直线,亦不能有那样的自理了。自理又演绎而有定理,如欧氏几何学定理,自理从来只有这几条,而定理则可以多至数百条。数学在西洋,定理是希腊时才日益完备,但那自理则埃及时早有,而且远在阿瑙苏撒新石器时代已早有着的了。
点演绎为线是一生二,点线又演绎为自理是二生三,自理又演为定理是三生万物,这是四个顺位。但这四个顺位不单是数学的,亦要是人事的,才算得文明的遍在。如在中国,仁的演绎为义,即好比点的演绎为线。仁义亦即忠恕,忠己恕人,人是己的推广。但一人是人,二人则是朋友或夫妇了,这朋友或夫妻对于二人乃是新的东西。义又行于亲疏尊卑之别,而有五常,五常是人事自理,又从五常推广而为治国平天下,如洪范九畴,则是人事定理了。仁一义二,五常是三,治国平天下是三生万物。
可是这四个顺位在阿瑙苏撒的始生文明尚未具备。彼时在数学上,是定理未备,亦即万物未备,而止于三顺位。在人事上更连这三亦尚未建立,新石器后期虽出现父系社会,渐有五伦,可能有了一常二常,但未备五常,至于治国平天下的理,当然是更尚未演绎得到。彼时但有人的妙好,这在后来惟印度人保持原状,如西域壁绘里有一群菩萨在路上走过,那眉目清扬,完全是平人陌路相逢的桃笑李妍,但是未能以这份潇湘行于君臣有义,父子有亲,兄弟有序,夫妇有别,朋友有信。
文明的四个顺位,乃至亦遍在于人事,是后来到了中国才达成,故惟中国人能如此清楚,说一生二,二生三,三生万物。阿瑙苏撒的始生文明,则惟止于三,且连这三亦不遍不备,故后世印度沿承,转为佛法僧三宝,西洋更歪曲为圣父圣子圣灵三位一体,及辩证法的正反合三个阶段。
西洋是从巴比仑埃及时起,已因奴隶社会而损害甚至丧失了这份平人的潇湘,他们在最健康时亦惟有平等的权利义务关系,那平等不过是对等,当然更没有五常。西洋是虽有五伦,而无五常,有社会而无人世,有时间而无光阴,有空间而无位置,有地球与国际而无天下世界,是故数学成了独立,而在人事上则连文明的点线亦已迷失,不知可以有虚虚实实的存在,连他们的人亦是高等动物,高等而已,仍旧是动物。他们的哲学追求本体,是唯心的,或唯物的,要用气力来唯,故有了客观的逻辑,必还要有主观的辩证法。
本体之外有认识与实践,那本体即不是一切,不能自行。西洋人连对于数学的0及点线亦一说便成曲解,哲学更从二点的矛盾关系开始,线是二点之间的关系,其点线皆是有面积而位置可疑的。至于逻辑,它宁是后天的。逻辑只是轨迹,数学的演绎才是白马金轮,而哲学却以法求法海,以逻辑求点线。故又要实践,因那样的点线不可以演绎,若可演绎,它必是自行的。
倒是印度人晓得本体是文明的虚虚实实的存在,说“法不实不虚,非有非无”。法不是理,故非辩证的,亦非逻辑的;辩证有作,而法不可作,法只有自行的。逻辑无相,而法则亦是相,其演绎是点线的相好妙严。印度人很晓得法是演绎的,故不说从二点开始,而说从一开始,“法不二”。且又说“法不二亦不一”,则是点之初的0了。0是万法之海,而演绎则从0之为一而开始,故曰“佛以一音演说法”。但印度亦五常未备,即文明的四顺位在人事方面三尚未备,且以为三即是万物,佛经里说一说二,而随即跳到“万法唯识”的万法。五常未备,即不可能演绎出齐家治国平天下的万法,如数学的自理未备则不能有定理,若有定理,若有万法,那亦是造作的靠不住的,故说万法皆幻,是有为法,难免劫毁。连释迦至此,亦演绎不去,行不去了,故退回到点线,甚至只要一之初,他的涅槃是尚未成为点时的0。
但印度到底还有文明,这文明在印度不过是生长停滞了,而在西洋则已全然不见。西洋语的文明与文化,一是物质的,一是精神的,或一是基层,一是升华或反映,但说物质的或精神的,乃是色相两不具足,升华亦还要看是毒菌不是,反映更不过是个影子,而下层上层的决定与被决定关系则根本没有个自在。中国说天地人,而西洋说人类,人不过是一类,只有他们的神是无可比类。西洋人是未得人身,即一半是兽,一半是神,像希腊神话里的半马人。
我在这里,是用《易经》里“天下文明”的文明,对佛经里的“无明”一语而说的。无明亦可有文化,但不是文明。文化或可以有西洋的东洋的,文明只是这一个,没有东西二洋之别。
文明是有人的位置,物的位置,不只是空间,却还有人世,不只是地球与国际,却还有天下世界;文明的演绎必是吉祥嘉庆的,而实从阿瑙苏撒新石器时代开始,故我称那个时代的为始生文明。
却说新石器时代的女娲又是新的女人的出现,而前此的盘古则是男人。旧石器时代只有渔猎,以男人为主,女人惟保管及分配。至新石器时代有农牧,财富增大,保管及分配变得重要起来,又且是女人领导生产,男人在开始一段仍惟渔猎,农牧多在女人手里,故女人的地位提高。而以女人为主,乃有氏族社会,不像前此的只是群。这在后世人的记忆里,尚有埃及巴比仑的伊什斯,印度的观音,日本的天照大神,以及希伯来人的夏娃,皆是女身。《旧约》里的夏娃吃无花果,从此开始了人类的劳动,与西洋神话里潘特拉的开了知识之箱。地母的驾龙耕种,皆是有来历的。但仍以女娲的故事为最本色。
女娲却并非女酋长,而阿瑙苏撒的亦并非母权社会,因为权的开始出现是物权,又强化于战斗,但这两个因素彼时皆没有。
今时落后蛮族及西洋人的祖先,皆有女权社会。他们是未发生私有制之前早已发生了物权。他们的原始共产社会乃部落的私有,共同的私有权,部落与部落之间有争物权的斗争。此外他们的人亦仍像旧石器人那样的,见了生人就要斗,只因对外界充满恐怖。他们的母系社会因此亦必定要是母权社会,行于征服与被征服,女酋长连带亦征服了男人。可是其后男人来了反征服,女人乃被判决了是犯罪的、不洁的,这而且成为一切宗教的共同之点。
阿瑙苏撒新石器时代则因有人的位分,物的位分,故可以不发生物权与统治权。彼时是人与物皆有了新的秩序,但与统治权无关,而只如同数学的顺位,如同花叶枝柯的条理,乃至可以渐渐有了政治而仍不发生政权,渐渐出现了私有制亦仍不是物权。而因此亦没斗争。前此旧石器人的为抢食物,及因对外界的恐怖单是见了生人就要斗,至此是没有了。好斗的是漠北白种蛮人及漠东黄种半蛮人,但他们早已分头远徙,而此地阿瑙苏撒一带则部落与部落之间并不发生贫富不等,亦且惟有氏族,而未成部落,因部落是临外敌或迁徙时才形成的,而彼时却只是平衍的聚居,故不发生部落对部落的物权与斗争。
彼时是有过这样和平的,故中国人及印度人皆说太古极好,乃至西洋亦有世界最初是黄金时代的古说。但西洋人说黄金时代过去了,后来的是银时代、铜时代、铁时代,越变越坏了,中国则不薄今人爱古人,孔子称尧舜,而他亦说周朝好。这些暂且不表。
这里单说阿瑙苏撒新石器时代女人的地位虽高,而且是他们开了文明,但后来男人亦渐渐来与女人一道农牧,女人便在若干工作部门让了出来,这都是好商量的,因为没有权的问题。而且此后虽是男人多做生产事业,但把生产的结果变成衣食器皿室家之美则仍是女人,故女人是文明的始启者,而其后亦一直生于文明;男人的地位,虽提高了,女人的地位仍不因之降低,而母系社会乃自然解消,变为父系社会。
这历史的传统后来是惟在中国不坠,中国人即从来不说男权女权,故对于女人特有一种平正。今史学家说的女酋长与母权社会,实在很难听,幸得那是说江南甄家,而我们自是金陵贾家,两家并不通谱。早先阿瑙苏撒时代由母系到父系,不过是夫妇定位,父母定位,其出土品所以没有一点经过争斗或革命的痕迹。而中国的传统,起先盘古,后来女娲,再后来黄帝与嫘祖,黄帝与嫘祖夫妇的出现这样自然,这即是历史的清洁。
阿瑙及苏撒真的好像星宿海,后来四天下的千山竞秀万壑争流,皆是从这里发源的,彼时的人,因为有人新的物与可喜乐的阳光世界,便生出一种没有名目的大志,只是兴兴头头的想要在日月山川里行走,有的竟乘槎远出大海大洋之外,几乎世界的沿海各地都到了,所以新石器的传播这样普遍,连墨西哥的印伽文明亦是这因缘。他们比后来希腊人的寻求金羊毛,比欧洲人产业革命后天涯地角的长征,还更气魄宏大,而且心地明朗。
及至公元前约四千年顷,阿瑙苏撒已入石器铜器并用时代,更来了几次大迁徙,但不是因为发生了灾变。若因灾变,如过去印澳非之间大陆的渐陷为海洋,或如中亚细亚盆地的渐为沙漠,乃是大家都搬了,而阿瑙苏撒一带的人却是去者自去,留者仍留。亦不是人口粮食发生了问题,因为没有过互相吞噬的迹象。他们是一队人往西南走,前面来到了尼罗河流域,一队人往西走,前面来到了幼发拉斯及底格勒斯两河流域,又一队人往南,前面来到了恒河流域,又一队人往东,前面来到了黄河流域,恰如张骞的只管去只管前面有路,连他自己亦没有想着的竟到了天上的银河。
如此乃建起了埃及巴比仑印度及中国的文明,其早期彼此有许多地方相似,即因出于同源。
但现在世界各地的落后蛮族,则惟从过去阿瑙苏撒人乘槎飘洋过海那一段远征时,才接触了所谓日石文化,而且其后还学会了石器铜器并用,但他们的根底仍是旧石器人的,故有图腾,迷惘于怪力乱神。而现代西洋人的祖先,则是漠北白种人,曾久久停滞在渔猎,其后渐从阿瑙苏撒间接学得了用新石器与铜器,散居到欧洲,至今留下许多遗迹,他们一样的仍是旧石器人的根底,一样的有图腾。又其后,他们中途闯入巴比仑埃及,翻造出希腊及罗马帝国等,又再破坏再翻造,种种多有隔膜。他们没有参加过当初创造文明下来沿路的风景与亲情。
文明在西方,是埃及巴比仑时,已为邪气所乘,再无数次辗转过手到了现代西洋人,更有似梦寐。文明在印度,还比较发展得好,但亦起了问题。文明的成长是惟在中国。现在虽全世界在走向毁灭中,可是有了个文明在那里,它就有着在那里了,中国的事仍像瑶池蟠桃二千年开花,三千年结实。
文明原是自证的,历史的大信亦惟生于现前,中国的事即使没有阿瑙及苏撒的地下考古,亦不拿巴比仑埃及乃至现代西洋的来比,亦并不生疑,对比了亦没有什么更得意,不过一个民族要显身扬名,亦是为了对世人皆有亲情,或者如姊妹们刺绣,彼此把手中鲜亮的针线比并比并,亦有一份喜气,又或者如“看剑引杯长”,是与壮士共看剑,则更有些雄心了。
世事如烟- 余华
========================
世事如烟- [[余华]]
------
第 一 节
一
窗外滴着春天最初的眼泪,7卧床不起已经几日了。他是在儿子五岁生日时病倒的,起先还能走着去看中医,此后就只能由妻子搀扶,再此后便终日卧床。眼看着7一天比一天憔悴下去,作为妻子的心中出现了一张像白纸一样的脸,和五根像白色粉笔一样的手指。算命先生的形象坐落在几条贯穿起来后出现的街道的一隅,在那充满阴影的屋子里,算命先生的头发散发着绿色的荧荧之光。在这一刻里,她第一次感到应该将丈夫从那几个精神饱满的中医手中取回,然后去交给苍白的算命先生。她望着窗玻璃上呈爆炸状流动的水珠,水珠的形态令她感到窗玻璃正在四分五裂。这不吉的景物似乎是在暗示着7的命运结局。所以儿子站在窗下的头颅在她眼中恍若一片乌云。
在病倒的那天晚上,7清晰地听到了隔壁4的梦语。4是一个十六岁的女孩,她的梦语如一阵阵从江面上吹过的风。随着7病情的日趋严重,4的梦语也日趋强烈起来。因此黑夜降临后4的梦语,使7的内心感到十分温暖。然而六十多岁的3却使7躁动不安。7一病不起以后,无眠之夜来临了。他在聆听4如风吹皱水面般的梦语的同时,他无法拒绝3与她孙儿同床共卧的古怪之声。3的孙儿已是一个十九岁的粗壮男子了,可依旧与他祖母同床。他可以想象出祖孙二人在床上的睡态,那便是他和妻子的睡态。这个想象来源于那一系列的古怪之声。
有一只鸟在雨的远处飞来,7听到了鸟的鸣叫。鸟鸣使7感到十分空洞。然后鸟又飞走了。一条湿漉漉的街道出现在7虚幻的目光里,恍若五岁的儿子留在袖管上一道亮晶晶的鼻涕痕迹。一个瞎子坐在一块大石头上,他清秀的脸上有着点点雀斑。他知道很多已经发生和正在发生的事,所以他的沉默是异常丰富的。算命先生的儿子在这条街上走过,他像一根竹竿一样走过了瞎子的身旁。一个灰衣女人的身影局部地出现在某一扇玻璃窗上,司机驾驶着一辆蓝颜色的卡车从那里疾驰而过,溅起的泥浆扑向那扇玻璃窗和里面的灰衣女人。6迈着跳蚤似的脚步出现在一个胡同口,他赶着一群少女就像赶着一群鸭子。2嘴里叼着烟走来,他不小心滑了一下,但是没有摔倒。一个少女死了,她的尸体躺在泥土之上。一个少女疯了,她的身体变得飘忽了。算命先生始终坐在那间昏暗的屋子里,好像所有一切都在他意料之中。一条狭窄的江在烟雾里流淌着刷刷的声音,岸边的一株桃树正在盛开着鲜艳的粉红色。7坐在一条小舟之中,在江面上像一片枯叶似的漂浮,他听到江水里有弦乐之声。
这时候7的妻子听到接生婆和4的父亲的对话,对话中间有着滴滴答答的水声。她转过身来注视着7,发现他的两只眼睛如同灌满泥浆,没有一丝光泽。然而他的两只耳朵却精神抖擞地耸在那里,她看到7的耳朵十分隐蔽地跳动着。
怕是鬼魂附身了。接生婆说。
我也这么担心。4的父亲对女儿的梦语表现得忧心忡忡。
去找找算命先生吧。接生婆建议。
二
司机在这天早晨醒来时十分疲倦,这种疲倦使他感到浑身潮湿。深夜在他枕边产生的那个梦,现在笼罩着他的情绪。他躺在床上听着母亲和4的父亲的对话,他们的声音往来于雨中,所以在司机听来那声音拖着一串串滴滴答答的响声。他们是在谈论着算命先生,已年近九十的算命先生为何长寿。算命先生的五个子女已经死去四个,子女的早殁,做父亲的必会长寿。他们的对话使司机觉得心里有一块泥土。司机眼前仿佛出现了算命先生第五个儿子的形象,那个五十多岁仍然独身的瘦长男子,心事重重地走在街道上,他拖着一条像竹竿一样的影子。母亲走进屋来了,她走到儿子卧室的门口,朝他看了一下。作为接生婆的母亲有时也能释梦。但司机并没有立即将这个梦告诉她。他是在起床以后,而且又吃了早餐,然后才郑重其事地将梦向母亲叙述。
那时候母亲十分安详地坐在远离窗户的一把椅子里,因此她的身上没有那类夸张的光亮。儿子向她走来时,她脸上出现了会意的微笑。
你有什么事要告诉我?她这样说。
我梦见了一个灰衣女人。他开始了他的叙述。我那时正将卡车驰到一条盘山公路上,我看到了那个灰衣女人,她没有躲让,我也没有刹车,然后卡车就从她身上过去了。
接生婆感到这个梦过于复杂,她告诉儿子:
如果你梦见了狗,我会告诉你要失财了;如果你梦见了火,我会告诉你要进财了;如果你梦见了棺材,我会告诉你要升官了。
但是这个梦使接生婆感到为难,因为在这个梦里缺乏她所需要的那种有明确暗示的景与物。尽管她再三希望儿子能够提供这些东西。可是司机告诉她除了他已经说过的,别的什么也没有。所以接生婆只好坦率地承认自己无力破释此梦。但她还是明显地感到了这个梦里有一种先兆。她对儿子说:
去问问算命先生吧。
三
司机随母亲走出了家门,两把黑伞在雨中舒展开来。瘦小的母亲走在前面,使儿子心里涌上一股怜悯之意。这时候4出现在门口,她似乎已经知道自己每晚梦语不止,而且还知道这梦语给院中所有人家都笼罩上了什么,所以她脸上的神色与她那黑色长裤一样阴沉,然而她却背着一只鲜艳的红色书包。司机觉得她异常美丽。但是3的孙儿的目光破坏了司机对她的注视,尽管司机知道他的目光并不意味着什么,可是司机无法忍受他的目光对自己的搜查。司机想起了他与他祖母那一层神秘的关系。司机的目光从4脸上匆忙移开以后,又从7的窗户上飘过,他隐约看到7的妻子坐在床沿上的一团黑影。然后司机走到了院外。他听到4在身后的脚步声,在那清脆的声音里,司机感到走在前面的母亲的脚步就显得迟钝了。
瞎子坐在那条湿漉漉的街道上,绵绵阴雨使他和那条街道一样湿漉漉。二十多年前,他被遗弃在一个名叫半路的地方,二十多年后,他坐在了这里。就在近旁有一所中学,瞎子坐到这里来是因为能够听到那些女中学生动人的声音,她们的声音使他感到心中有一股泉水在流淌。瞎子住在城南的一所养老院里,他和一个傻子一个酒鬼住在一起,酒鬼将年轻时的放荡经历全部告诉了瞎子,他告诉他手触摸女人肌肤上的感觉,就像手放在面粉上的感觉一样。后来,瞎子就坐到这里来了。但起先瞎子并不是每日都来这里,只是有一日他听了4的声音以后,他才日日坐到这里。那似乎已是很久以前的事了,那时候有好几个女学生的声音从他身旁经过,他在那里面第一次听到4的声音。4只是十分平常地说了一句很短的话,但是她的声音却像一股风一样吹入了瞎子的内心,那声音像水果一样甘美,向瞎子飘来时仿佛滴下了几颗水珠。4的突出的声音在瞎子的心上留下了一道很难消失的瘢痕。瞎子便日日坐到这里来了,瞎子每次听到4的声音时都将颤抖不已。可是最近一些日子瞎子不再听到4的声音了。司机和接生婆从他身旁经过时,他听到了雨鞋踩进水中水珠四溅的声音,根据雨鞋的声响,他准确地判断出他们走去的方向。可是4紧接着从他身旁走过时,他却并不知道在这个人的嗓子里有着他日夜期待的声音。
司机是第一次来到算命先生的住所,他收起雨伞,像母亲那样搁在地上。然后他们通过长长的走道,走入了算命先生的小屋。首先进入司机视线的是五只凶狠的公鸡,然后司机看到了一个灰衣女人的背影。那女人现在站起来并且转身朝他走来,这使司机不由一怔。灰衣女人迅速从他身旁经过,深夜的那个梦此刻清晰地再现了。他奇怪母亲竟然对刚才这一幕毫不在意。他听到母亲将那个梦告诉了算命先生。算命先生并不立即作出回答,他向接生婆要了司机的生辰八字,经过一番喃喃低语后,算命先生告诉接生婆:
你儿子现在一只脚还在生处,另一只脚踩进死里了。
司机听到母亲问:
怎样才能抽出那只脚?
无法抽回了。算命先生回答。但是可以防止另一只脚也踩进死里。
算命先生说:在路上凡遇上穿灰衣的女人,都要立刻将卡车停下来。
司机看到母亲的右手插入了口袋,然后取出一元钱递了过去,放在算命先生的手里。他看到算命先生的手像肌肉皮肤消失以后剩下的白骨。
四
司机梦境中的灰衣女人,在算命先生住所出现的两日后再次出现。
那时候司机驾驶着蓝颜色的卡车在盘山公路上,是临近黄昏的时候。他通过敞开的车窗玻璃,居高临下地看着这座小城。小城如同一堆破碎的砖瓦堆在那里。
灰衣女人是在这个时候出现的,她沿着公路往下走去,山上的风使她的衣服改变了原有的形状。
因为阴天的缘故,司机没有一下子辨认出她身上衣服的颜色。虽然很远他就发现了她,但是那件衣服仿佛是藏青色的,所以他没有引起警惕。直到卡车接近灰衣女人时,司机才蓦然醒悟,当他踩住刹车时,卡车已经超过了灰衣女人。
然而当司机跳下卡车时,灰衣女人从卡车的右侧飘然出现,司机感到一切都没有发生。同时他一眼认出眼前这个灰衣女人,正是两日前在算命先生处所遇到的。尽管风将她的头发吹得很乱,但却没有吹散她脸上阴沉的神色,她朝司机迎面走来,使司机感到自己似乎正置身于算命先生的小屋之中。
司机伸出双手拦住她,他告诉她,他愿意出二十元钱买下她身上的灰色上衣。
司机的举动使她感到奇怪,所以她怔怔地看了他很久。然而当司机递过二十元钱时,她还是脱下了最多只值五元的灰色上衣。灰衣女人脱下上衣以后,里面一件黑色的毛衣就暴露无遗了。
司机接过衣服时感到衣服十分冰冷,恍若是从死人身上刚刚剥下的。这个感觉使他的某种预兆得以证实。他将衣服铺在卡车右侧的前轮下面,然后上车发动了汽车,他看了一眼此刻站在路旁的女人,她正疑惑地望着他。卡车车轮就从衣服上面碾了过去。女人一闪消失了。但司机又立刻在反光镜中找到了她,她在反光镜中的形象显得很肥胖,她的形象越来越小,最后没有了。然而直到卡车驰入小城时,司机仍然没能在脑中摆脱她——她穿着那件灰色上衣在公路上有点飘动似的走着。但是司机已经心安理得,那件灰色上衣已经替他承受了灾难。
第 二 节
一
6在那个阴雨之晨,依然像往常那样起床很早,他要去江边钓鱼。还在他第一个女儿出生时,他就有了这个习惯。他妻子为他生下第七个女儿后便魂归西天。他很难忘记妻子在临死前脸上的神色,那神色里有着明显的嫉妒。多年之后,他的七个女儿已经不再成为累赘,已经变为财富。这时候他再回想妻子临死时的神态时,似乎有所领悟了。他以每个三千元的代价将前面六个女儿卖到了天南海北。卖出去的女儿中只有三女儿曾来过一封信,那是一封诉说苦难和怀念以往的信,信的末尾她这样写道:
看来我不会活得太久了。
6十分吃力地读完这封信,然后就十分随便地将信往桌子上一扔。后来这封信就消失了。6也没有去寻找,他在读完信的同时,就将此信彻底遗忘。事实上那封信一直被6的第七个女儿收藏着。
在6起床的时候,他女儿也醒了。这个才十六岁的少女近来噩梦缠身,一个身穿羊皮夹克的男子屡屡在她梦中出现。那个男子总是张牙舞爪地向她走来,当他抓住她的手时,她感到无力反抗。这个身穿羊皮夹克的男子,她在现实里见到过六次,每次他离开时,她便有一个姐姐从此消失。如今他屡屡出现在她的梦中,一种不祥的预兆便笼罩了她。显然她从三姐的信中看到了自己的以后,而且这个以后正一日近似一日地来到她身旁。在那以后的岁月里,她看到自己被那个羊皮夹克拖着行走在一片茫茫之中。
她听到父亲起床时踢倒了一只凳子,然后父亲拖着拖鞋吧嗒吧嗒地走出了卧室,她知道他正走向那扇门,门角落里放着他的鱼竿。他咳嗽着走出了家门,那声音像是一场阵雨。咳嗽声在渐渐远去,然而咳嗽声远去以后并没有在她耳边消失。
6来到户外时,天色依旧漆黑一片,街上只有几只昏暗的路灯,蒙蒙细雨从浅青色的灯光里潇潇飘落,仿佛是很多萤火虫在倾泻下来。他来到江边时,江水在黑色里流动,泛出了点点光亮,蒙蒙细雨使他感到四周都在一片烟雾笼罩下。借着街道那边隐约飘来的亮光,他发现江岸上已经坐着两个垂钓的人。那两人紧挨在一起,看去如同是连接在一起。他心里感到很奇怪,竟然还有人比他更早来这里。然后他就在往常坐的那块石头上坐了下来,这时候他感到身上正在一阵阵发冷,仿佛从那两个人身上正升起一股冰冷的风向他吹来。他将鱼钩甩入江中以后,就侧过脸去打量那两个人。他发现他们总是不一会工夫就同时从江水里钓上来两条鱼,而且竟然是无声无息,没有鱼的挣扎声也没有江水的破裂声。接下去他发现他们又总是同时将钓上来的鱼吃下去。他看到他们的手伸出去抓住了鱼,然后放到了嘴边。鱼的鳞片在黑暗里闪烁着微弱的亮光,他看着他们怎样迅速地把那些亮光吃下去。同样也是无声无息。这情形一直持续了很久。后来天色微微亮起来,于是他看清了那两人手中的鱼竿没有鱼钩和鱼浮,也没有线,不过是两根长长的类似竹竿的东西。接着他又看清了那两个人没有腿,所以他们并不是坐在江岸上,而是站在那里。他们的脸上无法看清,他似乎感到他们的脸的正面与反面并无多大区别。这个时候他听到了远处有一只公鸡啼叫的声音,声音来到时,6看到那两人一齐跳入了江中,江水四溅开来,却没有多大声响。此后一切如同以往。
二
灰衣女人这天一早去见算命先生,是因为她女儿婚后五年仍不怀孕。于是她怀疑女儿的生辰八字是否与女婿的有所冲突。这种想法在她心里已经埋藏很久了,直到这一日她才决定去请教算命先生。所以天一亮她就出门了。她在胡同口遇到6,那时6从江边回来。她从6的眼睛里恍恍惚惚地看到了一种粉红色。6从她的身边走过时,她感到自己的衣服微微掀动了一下。她不由回头看了他一眼,6的背影使她心里产生了沉重之感。这种感觉在她行走时似乎加重了。阴沉的雨天使她的呼吸像是屋檐的滴水一样缓慢。不久之后,瞎子出现在她面前,瞎子是坐在算命先生居住处的街口。那时候有一群上学的女孩子从这里经过,她们像一群麻雀一样喳喳叫着,她们的声音在这雨天里显得鲜艳无比。灰衣女人看到瞎子此刻的脸上有一种不可思议的紧张。在她的记忆深处,瞎子已经坐在了这里,但她无法判断瞎子端坐在此已有多少时日,只是依稀感到已经很久远。
在走入算命先生住所时,一个瘦长的男子迎面而来,她不用侧身,此人便顺利地通过了狭窄的门。她一眼认出这个五十来岁的男子正是算命先生最小的儿子。她又回头望去,那男子瘦长的身体在街上行走时似乎更像是一个影子。
然后她才来到了算命先生的小屋,年近九十的算命先生似乎已经知道了她的来意,他那张惨白的脸上露出的笑意使她感到了这一点。这时那五只公鸡突然凶狠地啼叫了起来,公鸡的啼叫声十分尖利。公鸡和刚才门口所遇的瘦子联系起来以后,使灰衣女人想起了很多有关算命先生的传说。
灰衣女人将自己的来意如实告诉了算命先生,她听到自己的声音在小屋里回响时十分沉闷。
算命先生在掌握灰衣女人的女儿与女婿的生辰八字以后,明确告诉她,他们是天生的一对,在命上不存在任何冲突。
可是已经五年了。灰衣女人提醒他。
算命先生对此表示爱莫能助,但他还是指点了灰衣女人,让她将此事去拜托城外那座寺庙里的送子观音,他说也许观音会托梦给她的,让她得知其中因由。
灰衣女人是在这时起身的,那时司机和他的母亲刚刚来到,她没有注意他们,所以也就无法知道自己已被司机深深地注意上了。
按照算命先生的指点,灰衣女人在离开以后没有回家,直接去了城外那座在山腰上的寺庙。她在那里磕拜了庞大的金光闪闪的送子观音,又烧了几炷香,然后才回到家中。整个一天她都心神不定,总算等到了天黑,于是她上床睡去。翌日凌晨醒来时,果然记忆起一梦,那梦很模糊,仿佛发生在那座寺庙里。送子观音在梦中的模样不是金光闪闪,似乎很灰暗,那座寺庙让她感到很空洞,送子观音那悬挂笑容的嘴没有动,但她听到一个宽阔的声音在飘落下来:能否生育要问街上人。灰衣女人是在这个时候醒来的,她完整地回想出了这个梦,所以她立刻起床,没有梳妆就来到了胡同外的街上。
那时候天还没有明亮,只是东方有一片红色正逗留在某一个山顶上,很像是嘴唇,街上已经有隐隐约约的脚步声了,但她没有看到人。很久以后,三个挑担的男子在模糊中朝她走来,她便迎了上去。因为担子的沉重,还在远处她就听到了扁担嘎吱嘎吱的声响。她走到近前,看到第一个担子是苹果,第二个担子是香蕉,第三个担子却是橘子。她觉得只有橘子才会有籽,因此就走到了第三个男子面前,那是一个三十来岁的壮实汉子,在他宽阔的脸上有汗珠在滚动。然后他们之间发生了一次对话。
灰衣女人问:卖不卖?
男子回答:卖。
是有籽的吧?她问。
无籽。男子说。
这个回答使灰衣女人蓦然一怔,良久之后,她才在心中对自己说,看来是天绝女儿了。于是灰衣女人算是明白了女儿婚后五年不孕的因由所在。
三
灰衣女人在得到无籽蜜橘的暗示以后,经历了两个白天一个夜晚的深深失望。然而当第二个夜晚来临前,她心里又死灰复燃。因此她再次去了城外的那座寺庙,她在离开寺庙走在下山的公路上时,她遇到了司机。司机的古怪行为使她疑惑不解。尽管如此,她还是脱下外衣给了他。然而在接过那二十元钱时,她手上产生了虚假的感觉。但是通过眼睛的判断,她就对这二十元钱确信无疑了。然后她看着司机弯下腰将她的衣服垫在车轮下,又看着他上车开动汽车。那时司机望了她一眼,司机的目光很刺人。汽车发出一阵沉闷的声响以后就驰走了。卡车没有扬起什么灰尘,卡车驰走时显得很干净。然后她才低下头去看自己的外衣,外衣趴在地上,上面有车轮碾过的痕迹。外衣的模样很可怜,仿佛已经死去。她走上几步捡起了它,仍然是先前的那件外衣。似乎刚才的一切都没有发生,似乎是她刚从床上坐起来,从旁边的凳子上拿过外衣。她就这样又重新穿在了身上,接着往前走。那时卡车已经驰下盘山公路了,就要进入小城。她在山上看着卡车,觉得它很像一只昨天爬在她腿上的褐色小虫。
不久之后她也走入了小城,那时候街上行人寥寥,她的内心也冷冷清清。在走入第一条街道时,她看到那些低矮的房屋上的烟囱大多飘起了缕缕炊烟,她感到自己的身体有点像烟一样缥缈。虽然雨从昨天就停了,可阴沉的天色,让她觉得随时都会有一场雨再次到来。
她在回到家中之前,最后一次看到的人是6的女儿。那时候她已经走入了通往家中的胡同,她是在经过6的窗下时看到的。6的女儿就站在窗前,正望着窗外胡同的墙壁发怔,在墙壁上有几株从砖缝里生长出来的小草在摇晃。灰衣女人透过窗玻璃看到这位少女时,心里不由哆嗦了一下。她无端地感到这个少女的脸上有一种死亡般的气息在蔓延。这个感觉使灰衣女人蓦然惊愕,因为她马上发现这其实是诅咒。对于刚刚求过观音的人来说,诅咒显然很危险,诅咒将意味着她刚才的努力不过是空空一场。这时灰衣女人已经走到自己家门口了,她听到屋内女儿在咬甘蔗,声音很脆也很甜。
四
6那天凌晨的奇怪经历,在此后的两个凌晨里继续出现。但是他并没有当回事,他依旧坐在自己往常坐的地方,与那两个无脚的人只有一箭之隔,他好几次试图和他们说话,可是他们的沉默使他不知所措。他们的动作与他第一次见到时没有两样,而且从那天以后他再也没有能从江水里钓上来一条鱼。在这天凌晨,他试着走过去,可还没有挨近他们,他们便双双跃入江中。正当他十分奇怪地四下张望时,他发现他们坐在另一处了,与他仍然是一箭之隔。于是他就回到原处坐。不一会他开始感到十分困乏,慢慢地眼前一片全是江水流动时泛出的点点光亮,接着他就感到身体倾斜了,然后似乎倒了下去。接下去他就一无所知。
也是在这个早晨,天还没有亮的时候,6那躺在床上的女儿听到有人在叫她的名字。声音十分轻微,恍若是从门缝里钻进来的风声。她便从床上爬起来,穿上衣服走到门前,那时候声音没有了。她打开门以后,发现父亲正躺在门外,四周没有人影。从鼾声上,她知道父亲并没有死去,只是睡着了。于是她就把他拉进屋内,还没把他扶上床时,他就醒了。
6醒来时对自己的处境感到十分惊讶,因为他清晰地记起自己是到江边去了,可是居然会在家中。他询问女儿,女儿的回答证实他去了江边。而女儿对刚才所发生的一切的叙述,使他心里觉得蹊跷。所以在天完全明亮以后,他就来到了算命先生的住所。
算命先生还没有完全听完,他的脸色就发生了急剧的变化。这一点6也感觉到了。当6看到算命先生苍白的脸上出现蓝幽幽的颜色时,他开始预感到了什么。
算命先生再次要6证实那两个人没有腿以后,便用手在那张布满灰尘的桌子上涂出了一个字,随后立刻擦去。
虽然这只是一瞬间,但6清晰地认出了这个字。他不由大惊失色。
算命先生警告他,以后不要在天黑的时候去江边。
6胆战心惊地回到家中以后,发现女儿正站在窗前,他没法看到女儿脸上的神色,他只是看到一个柔弱的背影。但是这个背影没法让他感觉到刚才在这里发生了什么,所以他也就不会知道那个穿羊皮夹克的人来过了。身穿羊皮夹克的人敲门时显然用了好几个手指,敲门声传到6的女儿的耳中时显得很复杂。当6的女儿打开房门时,她看到了自己的灾难。羊皮夹克的目光注视着她时,她感到自己的眼睛就要被他的目光挖去。她告诉他6没在家后就将门向他摔去,门关上时发出一声巨响。但是巨响并没有掩盖掉她心里的恐惧,她知道他不一会又将出现。
很久以后,在那个身穿羊皮夹克的人与父亲在一间房内窃窃私语结束以后,她听到了灰衣女人的死讯。那时候羊皮夹克已经走了,父亲又回到了那房屋。
灰衣女人在死前没有一点迹象,只是昨天傍晚回到家中时,她似乎很疲倦,晚饭时只喝了一点鱼汤,别的什么也没吃,然后很早就上床睡了。整个夜晚,她的子女并没有听到异常的声响,只是感到她不停地翻身。往常灰衣女人起床很早,这天上午却迟迟不起,到八点钟时,她的女儿走到她床前,发现她嘴巴张着,里面显得很空洞。起先她女儿没在意,可半小时以后第二次去看她时,发现仍是刚才的模样,于是才注意到那张着的嘴里没有一丝气息。灰衣女人的死得到了证实。后来她的子女拿起那件搁在凳子上的灰色上衣时,发现上面有一道粗粗的车轮痕迹。他们便猜测母亲是否被某一辆汽车从身上轧过。如果真是这样,那么灰衣女人事后再安然无恙地回到家中的情形就显得不可思议了。
第 三 节
一
灰衣女人的突然死去,使她儿子的婚事提前了两个月举办。为了以喜冲丧,她儿子沿用了赶尸做亲的习俗。
灰衣女人的遗体放在她床上,只是房中原有的一些鲜艳的东西都已撤去。床单已经换成一块白布,灰衣女人身穿一套黑色的棉衣棉裤躺在那里,上面覆盖的也是一块白布。死者脚边放了一只没有图案花纹的碗,碗中的煤油通过一根灯芯在燃烧,这是长明灯。说是去阴间的路途黑暗又寒冷,所以死者才穿上棉衣棉裤,才有长明灯照耀。灵堂就设在这里,屋内灵幡飘飘。死者的遗像是用一寸的底片放大的,所以死者的脸如同一堵旧墙一样斑斑驳驳。
灰衣女人以同样的姿态躺了两天两夜以后,便在这一日清晨被她的儿子送去火化场。然后她为数不多的亲属也在这天清晨去了那里。3被请去做哭丧婆。因此在这日上午,3那尖厉的哭声像烟雾一样缭绕了这座小城。
灰衣女人在早晨八点钟的时候,被放进了骨灰盒。然后送葬开始了。送葬的行列在这个没有雨也没有太阳的上午,沿着几条狭窄的街道慢慢行走。
瞎子那个时候已经坐在街上了。4的声音消失了多日以后,这一日翩翩出现了。那时候那所中学发出了好几种整齐的声音,那几种声音此起彼伏,仿佛是排成几队朝瞎子走来。瞎子知道那里面有4的声音,但他却无法从中找到它。不久之后那几种整齐的声音接连垂落下去,响起了几个成年人穿插的说话声。然后瞎子听到了4的声音,4显然正站起来在念一段课文。4的声音像一股风一样吹在了他的脸上,他从那声音里闻到了一股芳草的清香。但是4的声音时隐时现,那几个成年人的说话声干扰了4的声音,使4的声音传到瞎子耳中时经过了一个曲折的历程。然而一个短暂的宁静出现了,在这个宁静里4的声音单独地来到了瞎子的耳中,那声音仿佛水珠一样滴入了他的听觉。4的声音一旦单独出现,使瞎子体会到了其间的忧伤,恍若在一片茫茫荒野之中,4的声音显得孤苦伶仃。此后又出现了几种整齐的声音,4的声音被淹没了,就像是一阵狂风淹没了一个少女坐在荒野孤坟旁的低语。随后3的哭声耀武扬威地来到了,那时他和送葬的行列还相隔着两条街道。3的哭声从无数房屋的间隙穿过,来到瞎子耳中时像是一头发情的猫在叫唤。这哭声越来越接近时,瞎子才从中体会到了无数杂乱的声响,3的哭声似乎包括了所有令人毛骨悚然的声响。那里面有一个孩子从楼上掉下来的惊恐叫声,有很多窗玻璃同时破裂的粉碎声,有深夜狂风突然吹开屋门的巨响,有人临终时喘息般的呻吟。
灰衣女人的骨灰在城内几条主要街道转了一周,使某几个熟悉她的人仿佛看到她最后一次在城内走过。然后送葬的行列回到了她的家门。一入家门,她的女儿与亲属立刻换去丧服,穿上了新衣。丧礼在上午结束,而婚礼还要到傍晚才能开始。
二
司机也去参加了这个婚礼,他在走进这个家时没有嗅到上午遗留下来的丧事气息,新娘的红色长裙已经掩盖了上午的一切。
司机一直看着新娘,因为灯光的缘故,他发现坐在另一端的新娘,一半很鲜艳,一半却很阴沉。因此像是胭脂一样涂在新娘脸上的笑容,一半使他心醉心迷,另一半却使他不寒而栗。因为始终注视着新娘,所以他毫不察觉四周正在发生些什么。四周的声响只是让他偶尔感到自己正置身于拥挤的街道上,他感到自己独自一人,谁也不曾相识。有时他将目光从新娘脸上移开,环顾四周时,各种人的各种表情瞬息万变,但那汇聚起来的声音就让他觉得是来自别处。然而他却真实地发现整个婚礼都掺和着鲜艳和阴沉。而这鲜艳和阴沉正在这屋子里运动。那时候他发现一只酒瓶倒在了桌上,里面流出的紫红色液体在灯光下也是半明半暗。坐在司机身旁的2站了起来,2站起来时一大块阴沉从那液体上消失了,鲜艳瞬间扩张开来,但是靠近司机胸前的那块阴沉依然存在,暗暗地闪烁着。2站起来是去寻找抹布,他找到了一件旧衣服。于是司机看到一件旧衣服盖住了紫红色液体,衣服开始移动,衣服上有2的一只手,2的手也是半明半暗。然后司机看出了那是一件灰色上衣,而且还隐约看到了车轮的痕迹。
司机这天没有出车,但他还是在往常起床的时候醒了。那时他母亲正在洗脸。他觉得水就像是一张没有丝毫皱纹的白纸,母亲正将这张白纸揉成一团。然后他听到了母亲的脚步声在走出去,接着一盆水倒在了院子里。水与泥土碰撞后散成一片,它们向四周流去,使司机想起了公路延伸时的情景。隔壁的3这时也在院中出现,她将一口清水含在嘴里咕噜了很久,随后才刷地一声喷了出去。司机听到母亲在说话了,她的声音在询问3的举动。
洗洗喉咙。3回答。
谁家在服丧了?母亲问。
那时3嘴里又灌满了水,所以她的回答在司机听来像是一阵车轮的转动声。司机没法听清,但他知道是某一个人死了,3将被请去哭丧。3被水洗过的喉咙似乎比刚才通畅多了,于是司机听到母亲对3嗓子的赞叹,3回答说体力不如从前了。
司机在床上躺了很久以后才起床,他走到院里时,看到7正坐在门前一把竹椅里,7用灰暗的目光望着他,7的呼吸让司机感到仿佛空气已经不多了。7五岁的儿子正蹲在地上玩泥土,他大脑袋上黄黄的头发显得很稀少。这时有人送来了一份请柬,他打开请柬一看,是很多年前相识的某一位姑娘的结婚请柬。这份请柬的出现很突然,使司机勾起了许多混乱的回忆。
三
婚礼的高潮在司机和2之间开始。那时候厨师已经离开厨房很久了,厨师也已经吃饱喝足。几个醉汉摇摇晃晃地走到了楼梯口,还没下楼就趴在楼梯上睡着了。2高声叫着要新娘给他们洗脸,于是所有的人都围了上去。司机并没有意识到什么将会发生,他此刻的眼睛里有一件灰色上衣时隐时现。然而新娘端着一盆水走来时,那件灰色上衣便蓦然消失。这时候他才感到将会发生什么了,而且显然与自己有关,因为此刻坐着的只有他和2。新娘将洗脸盆端到桌子上时,两只红色的袖管美妙地撤退了,他看到两条纤细的手臂,手臂的肤色在灯光下闪烁着细腻滑润的色泽。然后十个细长的手指绞起了毛巾。司机的眼睛里没有毛巾,他只看到十个手指正在完成一系列迷人的舞蹈,水在漂亮地往下滴,水是这个舞蹈的一部分。
先给他擦。司机听到2这样说。他抬起眼睛,看到2正用食指指着他,2的手指在灯光下显得很锐利。
新娘的毛巾迎面而来,抹去了2的手指。在毛巾尚未贴到脸上时,司机先感觉到新娘的一只手轻轻按住了他的后脑,他体会到了五个手指的迷人入侵。接着他整个脸被毛巾遮住,毛巾在他的脸上揉动起来。但是司机并没有感觉到毛巾的揉动,他感到的是很多手指在他脸上进行着温柔的抚摸,这抚摸使他觉得自己正在昏迷过去。可是这一切转瞬即逝,2的形象又出现在他眼中,他看到2正微笑地注视着自己。于是司机从口袋里摸出二十元钱给新娘,新娘接过去放入了口袋。司机没有触到新娘的手指。
然后司机看着新娘给2擦脸,他感到不可思议的是新娘给2擦脸的动作为何也如此温柔。擦完之后,他看到2拿出四十元钱放入新娘手中。接着2说:给他擦。
这句话开始让司机感到面临的现实,因此当他再次看着新娘绞毛巾的手指时,刚才的美景没有重现。新娘的毛巾在他脸上移动时,也没有刚才令他激动的感受。擦完以后,他拿出了四十元。那时候他知道自己口袋里已经一片空空。他想也许2不会再逼他了,但他实在没有什么把握。
2这次给了八十元。2没有就此完结。他要新娘再为司机擦脸。司机这时才注意到四周聚满了人,这些人此刻都在为2欢呼。新娘的毛巾又在他脸上移动了,这时他悄悄从手腕上取下了手表。擦完以后,他将手表递给了新娘。他听到一片哄笑声,但是2没有笑,2对他说:算你的表值一百元吧。2说完拿出二百元放在桌上。新娘为他擦完之后,他就拿起二百元放入新娘长裙的口袋里,同时还在新娘屁股上拍了一下。接着2指着司机对新娘说:再擦一次。
新娘这次的毛巾贴在司机脸上时,使他感到疼痛难忍,仿佛是用很硬的刷子在刷他的脸。而按住他的脑后的五个手指像是生锈的铁钉。但是毛巾和手指消失之后,司机开始痛苦不堪。他清晰地感到了自己狼狈的处境,他听到四周响起一片乱糟糟的声音,那声音真像是一场战争的出现。他看到坐在对面的2脸上倾泻着得意的神采,2的脸一半鲜艳,一半阴沉。2拿出了一叠钱,对司机说:这四百元买你此刻身上的短裤。
司机听到了一阵狂风在呼啸,他在呼啸声中坐了很久,然后才站起来离开座位朝厨房走去。走入厨房后他十分认真地将门关上,他感到那狂风的声音减轻了很多,因此他十分满意这间厨房。厨房里的炉子还没有完全熄灭,在惨白的煤球丛里还有几丝红色的火光。几只锅子堆在一起显得很疲倦,而一叠碗在水槽里高高隆起。接着他看到一把菜刀,他将菜刀拿在手中,试试刀锋,似乎很锋利。然后他走到窗前,他看到窗外的灯光斑斑驳驳,又看到了一条阴沟一样的街道,街上一个人在走去。随后他往对面一座平房望去,透过一扇窗户他看到了一个少女的形象。少女似乎穿着一件黑色上衣,少女正在洗碗,少女在洗碗时微微扭动身体,她的嘴似乎也在扭动。他于是明白了她正在唱歌,虽然他听不到她的歌声,但他觉得她的歌声一定很优美。
四
2在司机走入厨房以后也投入了那一片狂风般的笑声中,笑声持续了很久,然后才像一场雨一样小了下去。2感到应该去厨房看看司机正在干些什么,于是他站起来朝厨房走去。他走去时感到所有人的目光在与他一同前往,他知道他们都想看看此刻司机的模样。他走到门前时,发现从门缝里正在流出来几条暗色的水流,他对这个发现产生了兴趣,所以他蹲下身去,那水流开始泛出一些红色来,他觉得还是没有看清,于是就伸出手指在水流里蘸了一下,再将手指伸回到眼前,这次他确信自己看到了什么。他站起来后感到自己不知所措,然后他转回身准备离开这里,可他发现他们正奇怪地望着他,他犹豫了。此后只好又转回身去,他有点紧张地去推厨房的门,他看到自己的手伸过去时像是风中的一根树枝。他只将门打开一条缝,根本没有看到司机就立刻将门关上。他再次转身去,他想朝他们笑一下,可他的脸仿佛已经僵死过去没法动。他听到有人在问他:在干什么?他不知道自己该如何回答,他感到自己正在走过去。他又听到有人在问:是不是在脱短裤?他不由点点头,于是他听到了一片像是飞机俯冲过来的笑声。他走到自己的椅子旁稍微站了一会,随后就朝楼梯走去。他听到有人在问他什么,但他没有听清。他已经走到楼梯口了,几个醉汉此刻横躺在楼梯上打呼噜。他小心翼翼地绕过他们,一步一步走下了楼梯,然后来到了街上。
那时候街寂静无人,只有路灯灰色的光线在地上漂浮,一股冷风吹来仿佛穿过了他的身体。这时他听到身后有轻微的脚步声,那声音像一颗颗小石子节奏分明地掉入某一口深井,显得阴森空洞,同时中间还有一段“咝”的声响。他知道是司机在追出来了。他不敢回头,只是尽量往亮处走。他感到自己每当走到路灯下时,身后的脚步声便会立刻消失,而一来到阴暗处时,那声音又在身后出现了,所以他一来到路灯下时便稍微站了一会,那时候他觉得身上的灯光很温暖。随即他又拼命地跑过一段阴暗,到另一盏路灯下。他在跑动时明显地感到身后的声音也加快了。他觉得他们之间始终保持着一段距离,没有拉长也没有缩短。
后来他看到自己的家了,那幢房屋看去如同一个很大的阴影,屋顶在目光里流淌着阴森可怖的光线。他走到近前,一扇门和几扇窗户清晰地出现在眼前,这时身后的声音蓦然消失。他不由微微舒了口气,可这时他眼前出现了一片闪闪烁烁的水,那条通往屋门的路消失了,被一片水代替。他知道司机就在这一片闪烁的水里。他双腿一软,跪在了地上。他听到自己的声音在说:饶了我吧。那声音在空气里颤抖不已。他那么跪了很久,可眼前的一片闪烁并没有消失。于是他再次说:饶了我吧。随即便呜呜地哭了起来。他说:我不是有意要害你。但是那一片闪烁仍然存在。他便向这一片闪烁拼命地磕头,他对司机说:你在阴间有什么事,尽管托梦给我,我会尽力的。他磕了一阵头再抬起眼睛时,看到了那条通往屋门的小路。
第 四 节
一
在司机死后一个星期,接生婆在一个没有风但是月光灿烂的夜晚,睡在自己那张宽大的红木床上时,见到了自己的儿子。仿佛是天还没有亮的时候,儿子心事重重地站在她的床前,她看到儿子右侧颈部有一道长长的创口,血在创口里流动却并不溢出。儿子告诉她他想娶媳妇了。她问他看准了没有。他摇摇头说没有。她说是不是要我替你看一个。他点点头说正是这样。
接生婆是在这个时候听到外面叫门的声音的,她醒了过来。她听到门外有人在叫着她的名字,屋外的月光通过窗玻璃倾泻进来,她看到窗户上的月光里有一个人的影子在晃动。她觉得那叫门的声音有些古怪,那声音似乎十分遥远,可那个人却分明站在窗前。她从床上爬起来,穿上衣服后走过去打开房门,一个她从未见过的人站在她面前,她感到这个人的脸很模糊,似乎有点看不清眼睛、鼻子和嘴巴。她问他:你是谁?
那人回答:我住在城西,我的邻居要生了,你快去吧。
她家的男人呢?接生婆问。一个女人要生孩子了,却是一个邻居来报信,她感到有些奇怪。
她家没有男人。那人说。
接生婆再次感到眼前这个人的说话声很遥远。但她没怎么在意,她答应一声后回到房内拿了一把剪刀,然后就跟着他走了。
在路上时接生婆又一次感到很奇怪,她感到走在身旁这人的脚步声与众不同,那声音很飘忽。她不由朝他的脚看了一眼,可她没有看到。他好像没有腿,他的身体仿佛是凌空在走着。但是她觉得自己也许是眼花了。
不久之后,很多幢低矮的房屋在眼前出现了,房屋中间种满了松柏。接生婆走到近前时不知为何跌了一跤,但是她没感到自己爬起来,跌下去时仿佛又在走了。她跟着这人在房屋与松柏之间绕来绕去地走了一阵后,来到一幢房门敞开的屋子前,她看到一个女人躺在一张没有颜色的床上。她走进去后发现这个女人全身赤裸,女人的皮肤像是刮去鳞片后的鱼的皮。她感到这个女人与站在旁边的男人有惊人的相似之处。她的脸也很模糊,而且同样也很难看到她的双腿。但是接生婆的手伸过去时仿佛摸到了她的腿。接生婆开始工作了,这是她有生以来最困难的一次接生。但是那个女人竟然一声不吭,她十分平静地躺在那里。接生婆的手在触摸到女人的皮肤时,没有通常那种感觉,而似乎是触摸到了水。那女人在接生婆手上的感觉恍若是一团水。接生婆感到自己的汗水从全身各处溢出时冰冷无比。很久之后,婴儿才被接生出来。奇怪的是整个过程竟然没让接生婆看到一滴血的出现。刚刚出生的婴儿没有啼哭,它像母亲一样平静。婴儿的皮肤也与它母亲一样,像是被刮去鳞片后的鱼的皮。而且接生婆捧在手里时,也仿佛是捧着一团水。她拿着剪刀去剪脐带,似乎什么也没剪到,但她看到脐带被剪断了。这时那个男人端上来一碗面条,上面浮着两个鸡蛋。接生婆确实饿了,她就将面条吃了下去,她感到面条鲜美无比。然后那个男人将她送出屋门,说声要回去照顾就转身进屋了。于是接生婆按照刚才走过的路,又绕来绕去地走了出去。她觉得出去的路比进来时长了很多。在这条路上,她遇到了算命先生的儿子。她看到他那细长的身体像一株树一样站在两幢房屋中间,他好像是在东张西望,接生婆走上去问他这么晚了怎么还在这里,他回答说他是才来这里的。她感到他的声音也有些遥远。她问他在找什么,他说在找他住的那间屋子。然后他像是找到了似的往右边走去了。接生婆也就继续往前走,走到刚才跌跤的地方时,她又跌了一跤,但她同样没感到自己爬起来,她只感到自己在往前走。
二
接生婆回到家中后感到了从未有过的疲倦,所以一躺在床上,她就觉得自己像是死去一般昏睡了过去。待她醒来时已是接近中午的时候了。她听到院里传来说话的声音,她就从床上爬起来,当她向门口走去时,感到自己的两条腿像棉花一样软绵绵。
7那时候坐在自己家门口的一把竹椅里,他的妻子站在一旁。7的妻子正和4的父亲在说着关于4夜晚梦呓的事。7似乎是在听着他们说话,他那张灰暗的脸毫无表情,他的眼睛一直看着他的儿子,他儿子正兴冲冲地在院内走来走去,那大脑袋摇摇晃晃显得有些沉重。接生婆站在了门口。此刻4推开院门进来了,4的出现,使她父亲和7的妻子的对话戛然而止。4走进来时脸色十分阴沉,但她身上的红色书包却格外鲜艳。4低着头从父亲身旁走过,走入了敞开的屋门。3的孙儿这时也从屋内出来了,他似乎是听到了4进来时的声响,他站在院子里小心翼翼地望着4走入的屋门,接生婆问7是不是感到好一点了。她听到自己的声音在空中显得很迟钝。7听到了她的问话,就抬起混浊的眼睛看了她一眼,随即又低下头去。他没有回答她,但他的妻子回答了。他妻子说还是老样子。接生婆便建议7去看看算命先生。她说没准在命上遇到了什么麻烦事。7的妻子早就有此打算,听了接生婆的话后,她不由朝丈夫看了看。7仿佛没有听到她们的话,他的脑袋耷拉着像是快要断了。倒是4的父亲点了点头,他说是应该去看看算命先生。他想起了自己每夜梦语不止的女儿。接生婆点了点头。她听到有人在问她昨夜谁在叫唤,她才发现3也站在院子里来了。3的脸上近来出现了像蜡一样的黄色。她在询问接生婆之后,立刻从嘴里发出了一阵令人恶心的空呕声,随后她眼泪汪汪地直起腰杆来。
接生婆告诉3:是城西一户人家的女人生孩子。
哪户人家?3问。
接生婆微微一怔。她没法做出准确的回答,她只能将昨夜所遇的一男一女,以及那幢房屋告诉3。
3听后半晌没有说话,她想了好一阵才说城西好像没有那么一户人家。她问接生婆:在城西什么地方?
接生婆努力回想起来,依稀记得是走过那破旧的城墙门洞以后,才看到那无数低矮的房屋。
3十分惊愕,她告诉接生婆那里根本没有什么房屋,而是一片空地。
3的话使接生婆猛然惊醒过来,她才意识到自己昨夜去过的是什么地方。她发现7的妻子正吃惊地望着她。7却依旧垂着脑袋,4的父亲刚才进去了。7的妻子的目光使她很不自在。接生婆觉得自己站在这里已经不合适,她想走回屋内,可是昨夜所遇使她无法能在屋中安静下来。因此她站了一会以后就朝院门外走去了。
接生婆走在街上时,昨夜那个男人与她一起行走的情景复又出现。那模糊的脸和没有双腿的脚步声。于是接生婆已经预料到她一旦走过那破旧的城墙门洞以后,她将会看到什么。
此后的事实果然证实了接生婆的预料。当她走到昨夜看到的无数房屋的地方时,她看到了一片坟墓,坟墓中间种满了松柏。接生婆听到自己心里发出了几声像是青蛙叫唤的声响。她呆呆地站了一会,然后就像夜里绕来绕去一样,走入坟墓之中。有些坟墓已经杂草丛生,而另一些却十分整齐。后来她在一座新坟前站住了脚,她觉得昨夜就是在这里走入那座房屋的。呈现在她眼前的这座坟墓上没有一棵杂草,土是新加的。坟墓旁有一堆乱麻和几个麻团。坟顶上插着一块木牌,她俯下身去看到了一个她听说过的名字,这是一个女人的名字,接生婆想起了在一个月以前,这个带着身孕的女人死了。
接生婆在走出坟场时,回想出了昨夜与算命先生儿子相遇的情景,她感到心里有一种想见到他的迫切愿望,所以她就向算命先生的家走去。在离算命先生的家越来越近时,昨夜的情景也就越来越生动了。她看到了瞎子。那时候近旁中学的操场上传来一片嘈杂响亮的声音,瞎子正十分仔细地将这一片声音分成几百块,试图从中找出属于4的那一块声音。瞎子脸上的神色让接生婆体会到了某种不安,这不安在她站到算命先生家门口时变成了现实。
算命先生的屋门敞开着,她看到里面蔓延着丧事气息。屋门的门框上垂下来两条白布,正随风微微掀动。她知道是算命先生的儿子死了,而不会是算命先生。
听到门口有响声,算命先生拄着一根拐杖出现了。他告诉接生婆这段日子他不接待来客。望着算命先生转身进屋的背影,接生婆发现他苍老到离死不远了。同时她想起了多种有关他的传闻,她想他的五个子女都替他死光了,眼下再没人替他而死,所以要轮到他自己了。算命先生刚才说话时的声音,回想起来也让接生婆感到有些遥远,那沙哑的声音仿佛被撕断似的一截一截掉落下来。
接生婆回到家中以后,再次回想起自己昨夜的经历时,那一碗面条和面条上的两个鸡蛋出现了。这使她感到恶心难忍,接着就没命地呕吐起来,两侧腰部像是被人用手爪一把把挖去一般的疼痛。吐完以后,她眼泪汪汪地看到地上有一堆乱麻和两个麻团。
三
已年近九十的算命先生,一共曾有五个子女,前四个在前二十年里相继而死,只留下第五个儿子。前四个子女的相继死去,算命先生从中发现了生存的奥秘,他也找到了自己将会长生下去的因由。那四个子女与算命先生的生辰八字都有相克之处,但最终还是做父亲的命强些,他已将四个子女克去了阴间。因此那四个子女没有福分享受的年岁,都将增到算命先生的寿上。因此尽管年近九十,可算命先生这二十年来从未体察到身体里有苍老的迹象。这一点在算命先生采阴补阳时得到了充分的证实。采阴补阳是他的养生之道,那就是年老的男人能在年幼的女孩的体内吮吸生命之泉。而他屋中的那五只公鸡,则是他防死之法。倘若阴间的小鬼前来索命,五只公鸡凶狠的啼叫会使它们惊慌失措。
每月十五是算命先生的养生之日,这一日他便会走出家门,在某一条胡同里他会看到一个十一二岁的女孩正无所事事地站在那里,他就将她带回家中。对付那些小女孩十分方便,只要给一些好吃的和好玩的。他找的都是一些很瘦的女孩,他不喜欢女孩赤裸以后躺在床上的形象是一堆肥肉。
算命先生的儿子是在这月十五的深夜,这一日即将过去时猝然死去的。但还是傍晚儿子回到家中,算命先生就从他脸上看到了奇怪的眼神。在此前一小时,一个十一岁的女孩刚刚离去。
那是一个奇瘦无比的女孩,女孩赤裸以后躺在床上时还往嘴里送着奶糖。那两条瘦腿弯曲着,弯曲的形态十分迷人。女孩用眼睛看了看他,因为身体的瘦小,那双眼睛便显得很大。他的手触到她的皮肤时有一种隔世之感。每月十五的这个时候,坐在离此不远的街口的瞎子,便要听到从这里发出的一阵撕裂般的哭叫声,现在这种叫声再次出现了。那声音传到瞎子耳中时,已经变得断断续续十分轻微,尽管这样,瞎子还是分辨出了这不是自己正在寻找的那个声音。
女孩子离去以后,算命先生便坐入一把竹椅之中。他为自己煮了一碗黄酒糖鸡蛋,坐在椅中喝得很慢。他感到自己仿佛是刚从澡堂出来,有些疲倦,但全身此刻都放松了,所以他十分舒畅。他喝着的时候,觉得有一股热流在体内回旋,然后又慢慢溢出体外。
儿子回到家中时,算命先生正闭目养神,他是睁开眼睛后才发现儿子奇怪的眼神的,在前四个子女临终前,他也曾看到过类似的眼神。
儿子吃过晚饭后又出去了,回来时已是深夜。那时算命先生已经躺在床上了。他听着儿子从楼梯走上来的脚步声,脚步很沉重。然后借着月光他看到儿子瘦长的影子在脱衣服,接着那影子孤零零地躺了下去。
第五个儿子的死,使算命先生往日的修养开始面临着崩溃。他感到前四个子女增在他寿上的年岁已经用完,现在他是在用第五个儿子的年岁了,而此后便是寿终的时刻。他觉得第五个儿子只能让他活几年,因为这个儿子也活得够长久了,竟然活到了五十六岁。算命先生明显地感到自己的身体正在枯萎下去。这一日他发现那五只公鸡的啼叫,也不似从前那么凶狠。这个发现使他意识到公鸡也衰老了。
四
半个月以后的一个夜晚,开始有些恢复过来的算命先生,听到了敲门的声音。这声音使算命先生一时惊慌失措。随后他听到了有人在叫他的名字,听声音像是一个女人。能从声音里分辨出敲门者的性别,使算命先生略略有些心定。于是他小心翼翼地走到门旁,然后无声地蹲了下去,将右眼睛贴到一条门缝上,通过外面路灯的帮助,使他看到了两条粗腿。腿的出现使他确定敲门者是人,而不是他所担心的无腿之鬼。因此他打开了屋门。
3出现在他眼前,他认识3。3的深夜来访,使算命先生感到不同寻常。
3在一把椅子里坐下以后,朝算命先生颇为羞涩地一笑,然后告诉他她怀孕了。
面对这个六十多岁的女人怀孕的事实,算命先生并不表现出吃惊,他只是带着明显的好奇询问播种者是谁。
于是3脸上出现了尴尬的红色,3尽管犹豫,可还是如实告诉算命先生,是她孙儿播下的种。
算命先生仍然没有吃惊,3却急切地向他表白她实在不愿意干那种事,她说她是没有办法,因为她不忍心看着孙儿失望的模样。
3的夜晚来访,是要算命先生算算腹中婴儿是否该生下来。
算命先生告诉她:要生下来。
但是3为婴儿生下以后,是她的儿女还是她的重孙而苦恼。
算命先生说这无关紧要,因为他愿意抚养这个孩子,所以她的担忧也就不存在了。
第 五 节
一
算命先生儿子的死去,尽管瞎子没法知道,但是连续一月瞎子不再感到这个瘦长的人从他身旁走过了。这个人走过时,他会感到一股仿佛是门缝里吹来的风。这人与别的人明显不同,所以瞎子记住了他。这人的消失使瞎子的内心更加感到孤单。
4的声音也已经很久没有出现,尽管附近那所中学依旧时刻发出先前那种声音,那种无数少男少女汇集起来的声音,那种有时十分整齐有时又混乱不堪的声音。但是他始终无法从中找出4的声音。在上学和放学的时候,瞎子听着那些声音三三两两从他身旁经过,他曾在那时候听到过4的笑声,可已是很久以前的事了。4的笑声使瞎子黑暗的视野亮起了一串微微闪烁的光环,他看着那串光环的出现与消失,这些都发生在瞬间。4的声音最初出现时仿佛滴着水珠,而最后出现时却孤苦伶仃,这中间似乎有一段漫长的历程,然而瞎子却感到这些都发生在瞬间。
这时候4正朝瞎子走来,她的父亲走在旁边。瞎子听到了有两个人走来的脚步声,一个粗鲁,一个却十分细腻,但是瞎子并不知道是4在走来。4走到瞎子近旁时,发现瞎子枯萎的眼眶里有潮湿的亮光,这情景使她对即将走到的地方产生了迷惑之感,她与父亲从瞎子身旁走过,不久就走入了算命先生总是敞开的屋门。
然后几辆板车从瞎子面前滚动了过去,一辆汽车驰过时瞎子耳边出现一阵混浊的响声。他听到街上有走动的声音和说话的声音,刚才汽车驰过时扬起的一片灰尘此刻纷纷扬扬地罩住了他。街上说话的是几个男子的声音,那声音使瞎子感到如同手中捏着一块坚硬粗糙的石头。有一个女人正在叫着另一个女人的名字,另一个女人说话时带着笑声,她们的声音都很光滑,让瞎子想到自己捧碗时的感觉。4的声音是在此后再度出现的。
二
4出现在算命先生的眼前时,刚好站在一扇天窗下面,从天窗玻璃上倾泻下来的光线沐浴了她的全身,她用一双很深的眼睛木然地看着算命先生。
听完4的父亲的叙述,算命先生闭上眼睛喃喃低语起来,他的声音在小屋内回旋,犹如风吹在一张挂在墙上的旧纸沙沙作响。4的父亲感到他脸上的神色出现了某种运动。然后算命先生睁开了眼睛,他的眼睛令人感到没有目光。他告诉4的父亲:每夜梦语不止,是因为鬼已入了她的阴穴。
算命先生的话使4的父亲吃了一惊,他望着算命先生莫测深浅的眼睛,问他有何救女儿的法术。
算命先生微微一笑,他的笑容使4的父亲感到是一把刀子割出来似的。他说有是有,但不知是否同意。
4听着他们的对话,4所听到的只是声音,而没有语言,算命先生的形象恍若是一具穿着衣服的白骨,而这间小屋则使她感到潮湿难忍。她看到有五只很大的公鸡在小屋之中显得耀武扬威。
在确认4的父亲没有什么不答应的事以后,算命先生告诉他:从阴穴里把鬼挖出来。
4的父亲惊骇无比,但不久后他就默许了。
4在这突如其来的现实面前感到不知所措。她只能用惊恐的眼睛求助于她的父亲。但是父亲没有看她,父亲的身体移到了她的身后,她听到父亲说了一句什么话,她还未听清那句话,她的身体便被父亲的双手有力地掌握了,这使她感到一切都无力逃脱。
算命先生俯下身撩开了4的衣角,他看到了一根天蓝色的皮带,皮带很窄,皮带使算命先生体内有一股热流在疲倦地涌起来。皮带下面是平坦的腹部。算命先生用手解了4的皮带,他感到自己的手指有些麻木。他的手指然后感受到了4的体温,4的体温像雾一样洋溢开来,使算命先生麻木的手指上出现了潮湿的感觉。算命先生的手剥开几层障碍后,便接触到了4的皮肤,皮肤很烫,但算命先生并没有立刻感觉到。然后他的手往下一扯,4的身体便暴露无遗了。可是展现在算命先生眼中时,是一团抖动不已的棉花。
4的挣扎开始了,但是她的挣扎徒劳无益。她感到了自己身体暴露在两个男人目光中的无比羞耻。
三
那个时候瞎子听到了4的第一次叫声,那叫声似乎是冲破4的胸膛发出来的,里面似乎夹杂着裂开似的声响。叫声尖利无比,可一来到屋外空气里后就四分五裂。声音四分五裂以后才来到瞎子耳边。因此瞎子听到的不是声音的全部,只是某一碎片。4的声音的突然出现,使瞎子因为过久的期待而开始平静的内心顷刻一片混乱。与此同时,4的叫声再度传来。此时4的叫声已不能分辨出其中的间隔了,已经连成一片。传到瞎子耳中时,仿佛是无数灰尘纷纷扬扬掉入在瞎子的耳中。声音持续地出现,并不消去。这使瞎子感到自己走入了4的声音,就像走入自己那间小屋。但是瞎子开始听出这声音的异常之处,这声音不知为何让瞎子感到恐惧。在他黑暗的视野里,仿佛出现了这声音过来时的情景,声音并不是平静而来,也不是兴高采烈而来,声音过来时似乎正在忍受着被抽打的折磨。
瞎子站了起来,他迎着这使他害怕的声音,摸索着走了过去。他似乎感到了这迎面而来的声音如一场阵雨的雨点,扑打在他的脸上,使他的脸隐隐作痛。声音在他走去的时候越来越响亮,于是他慢慢感到这声音不仅仅只是阵雨的雨点。他感到它似乎十分尖利,正刺入他的身体。随后他又感到一幢房屋开始倒塌了,无数砖瓦朝他砸来。他听出了中间短促的喘息声,这喘息声夹在其中显得温柔无比,仿佛在抚摸瞎子的耳朵,瞎子不由潸然泪下。
瞎子走到算命先生家门口时,那声音骤然降落下去。不再像刚才那样激烈,降落为一片轻微的呜呜声,这声音持续了很久,仿佛是一阵风在慢慢远去的声音。然后4的声音消失了。瞎子在那里站了很久,接着才听到从前面那扇门里响出来两个人的脚步,一个粗鲁,一个却显得十分沉重。
四
在4回到家中的第二天,7由他妻子搀扶着去了算命先生的家,他们是第一次来到算命先生的小屋,但是他们并不感到陌生。在此之前,一间类似的小屋已经在他们脑中出现过几次了。
7在算命先生对面的椅子坐下后,算命先生那令人感到不安的形象却使7觉得内心十分踏实。灰白的7在苍白的算命先生面前,得到了某种安慰——
7的妻子站在他们之间,她明显地感受到了自己的健康。但是这种感受让她产生了分离之感。
算命先生在得知他们来意以后,立刻找到了7的病因。他告诉7的妻子:7与他儿子命里相克。
算命先生是在他们的生肖里找到7的病因的,他向她解释:因为7是属羊的,而他儿子属虎。眼下的情景是羊入虎口。
7已经在劫难逃,他的灵魂正走在西去的路途上。
算命先生的话使7和他妻子一时语塞。7不再望着算命先生,他低下了头,他的眼中出现了一块潮湿的泥地,他感到自己的虚弱就在这块泥地的上面。7的妻子这时问算命先生:有何解救的办法?
算命先生告诉她,唯一的解救办法就是除掉她的儿子。
她听后没有说话,算命先生的模样在她的视线里开始模糊起来,最后在她对面的似乎不再是一个人,而是一块石头。她听到丈夫在身旁呼吸的声音,7的呼吸声让她觉得自己的呼吸也曲折起来。
算命先生说所谓除掉并非除命,只要她将五岁的儿子送给他人,从此断了亲属血缘,7的病情就会不治自好。
算命先生的模样此刻开始清晰起来,但她将目光从他身上移开,看着低垂着头的7,然后又抬头看看从天窗上泄漏下来的光线,她的眼睛微微眯了起来。
算命先生表示如果她将儿子交给别人不放心,可交他抚养。
算命先生收养7的儿子,他觉得是一桩两全其美的好事。7可以康复,而他膝下有子便可延年益寿。虽然不是他亲生,但总比膝下无子强些。尽管7的儿子在命里与他也是相克,但算命先生感到自己阳火正旺,不会走上此刻7正走着的那条西去的路。
他指着那五只正在走来走去的公鸡,对7的妻子说:如果不反对,你可从中挑选一只抱回家去,只要公鸡日日啼叫,7的病情就会好转。
五
4在那天回到家中以后,从此闭门不出。多日之后,4的父亲在一个傍晚站在院中时,蓦然感到难言的冷清。司机死后不久,接生婆也在某一日销声匿迹,没再出现。她家屋檐上的灰尘已在长长地挂落下来,望着垂落灰尘的梁条,他内心慢慢滋生了倒塌之感。3的离去也有多日,她临走时只是说一声去外地亲戚家,没有说归期。她的孙儿时时无精打采地坐在自己家门槛上,丧魂落魄地看着4的屋门。7由他妻子搀扶着去过了算命先生的家。他没有向他们打听去算命先生那里的经过,就像他们也不打听4一样。他只是发现在那一日以后,再也不见那脑袋很大的孩子在院里走来走去,取而代之的是一只公鸡,一只老态龙钟在院中走来走去的公鸡。
7的病情似乎有些好转了,7有时会倚在门框上站一会,7看着公鸡的眼神有时让4的父亲感到吃惊,7的目光似乎混乱不堪。尽管7原先的病有些好转,可他感到有一种新的病正爬上7的身体,而且这种病他在7妻子身上同样也隐约看到。后来他在自己女儿身上也有类似的发现。女儿此后虽然夜晚不再梦语,但她白天的神态却是恍恍惚惚。她屡屡自言自语,脸上时时出现若即若离的笑容,这种笑不是鲜花盛开般的笑,而是鲜花凋谢似的笑。
院中以往的景象已经一去不返,死一般的寂静在这里偷偷生长。从接生婆屋檐上垂落下来的灰尘,他似乎看到了这院子日后的状况。不知从哪一日开始,他感到这院里隐藏着一股腐烂的气息。几日以后,气息趋向明显。又过几日,他才能确定这气息飘来的方向,接生婆那门窗紧闭的屋子在这个方向正中。
也是这几天里,他听到了一个少女死去的消息。他是在街上听到的,那少女死在江边一株桃树下面。她身上没有伤痕,衣服也是干的。对于她的死,街上议论纷纷。那少女是他女儿的同学,他认识少女的父亲6,6常去江边钓鱼。他记得她曾到他家来过,有一次她进来时显得羞羞答答,她在院子里站了一会,就在他现在站着的这个地方。
第 六 节
一
接生婆在那天呕吐出了一堆乱麻和两个麻团以后,感到自己的身体开始变得飘忽了。她向那张床走去时,竟然感受不到自己的身体,她的身体很像是一件大衣。而且当她在床上躺下来时,觉得自己的身体像件扔到床上的衣服似的瘪了下去。然后她看到了一条江,江水凝固似的没有翻滚,江面上漂浮着一些人和一些车辆。她还看到了一条街,街道在流动,几条船在街道上行驶,船上扬起的风帆像是破烂的羽毛插在那里。
司机经常在接生婆的梦中出现,但是那天晚上没有来到她的梦里。在夕阳西下炊烟四起时,接生婆的视野里出现了一片永久的黑暗。接生婆的死去,堵塞了司机回家的路。
但是那天晚上,2的梦里走来了司机。那时候2正站在那条小路上,就是曾经被一片闪烁掩盖过的小路。2看到司机心事重重地朝他走来。司机的手正插在口袋里,似乎在寻找什么,或者只是插插而已。
司机走到他面前,愁眉苦脸地告诉他:我想娶个媳妇。
2发现司机右边的脖子上有一道长长的创口,血在里面流动却并不溢出。
2问他,是不是缺钱没法娶?
司机摇摇头,司机的头摇动时,2看到那创口里的血在荡来荡去。
司机告诉他:还没找到合适的人。
2问司机:是不是需要帮助?
司机点点头说:正是这样。
此后每日深夜来临,2便要和司机在这条小路上发生一次类似的对话。司机的屡屡出现,破坏了2原来的生活,使2在白天的时候眼前总有一只虚幻的蜘蛛在爬动。这种情形持续了多日,直到这一日2听说6的女儿死在江边的消息时,他才找到一条逃出司机围困的路。
二
回想起来,6的女儿的死似乎在事前有过一些先兆。那个身穿羊皮夹克的人再次路过这里以后,6开始发现女儿终日坐在墙角了,女儿坐在那里恍若是一团暗影。但是6却没有把这些放进心里,因为6一直没看出她身上正在暗暗滋长的那些东西,这些东西在她前面六个姐姐身上显然没有。事到如今,6才感到他和那个身穿羊皮夹克的谈话,女儿可能偷听了。他想起那天送羊皮夹克出门时,他看到女儿怔怔地站在房门外。
本来当初羊皮夹克就要带走他女儿,只是因为他节外生枝才没有。他告诉羊皮夹克他的这个女儿远远胜过前面六个,所以他对按照惯例支付的三千元钱很难接受,他提出增加一千。羊皮夹克的坚持没有进行很久,在短暂的讨价还价之后,他便作出了让步。但他提出先把女孩带走,先付上三千,另一千随后通过邮局寄来。6当然拒绝了,除非现交四千元,他才答应将他的女儿带走。羊皮夹克说身上的钱不够了,虽然四千还是可以拿出来,但在路途上还要花一笔钱,所以只好一个月以后再来。
在约定的日子临近时,6的女儿躺到了江边的一株桃树下面。那时候6正坐在城南的一座茶馆里,自从那次在江边的奇异经历以后,6不去江边钓鱼,而是每日坐到茶馆里来了。有关他女儿的消息,是他的一个邻居告诉他的。那个邻居去江边看死人后,在回家的路上从茶馆敞开的门里看到了6,他告诉6他正到处找他。这个消息使6顿时眼前一片昏暗,然后羊皮夹克的形象在他脑中支离破碎地出现了。邻座的茶客对6听到如此重大的消息以后仍然坐着不动感到惊讶,他们催促他赶快去江边。但是6没有听到他们在说话,他的眼睛望着门外的一根水泥电线杆,他看到那电线杆上贴着一张纸条,那是一张关于治疗阳痿的广告。6没法看清上面的字,但是羊皮夹克的形象此刻总算拼凑完整了,尽管那形象有无数杂乱的裂缝。可6明确地想起了这人再过两天就要来到,6仿佛看到他右面的衣服口袋显得肿胀的情景。这时他才深深意识到当初不让羊皮夹克带走女儿是一个很大的错误。他对自己说:这是报应。
尽管那条江已使6感到毛骨悚然,但既然女儿躺在那里,他也只得去了。他在走去的时候,仿佛感到女儿死在江边是有所目的的。这个想法在他接近江边时变得真切起来。当他在远处看到一堆人围在一株桃树四周的时候,他已经猜测到了女儿躺在那里的模样。
不久之后他已经挤入了人堆,那时候一个法医正在验尸。他看到女儿仰躺在地上,她的脸一半被头发遮住了。她的外衣纽扣已经被解开,里面鲜红的毛衣显得很挑逗。他才发现女儿的腰竟然那么纤细,如果用双手卡住她的腰,就如同卡住一个人的脖子。然后他注意到了女儿的脚,那是一双孩子的脚,赤裸的脚趾微微向上跷着。
这时候一个警察拍了拍他的肩,他转过头去看到了一张满是胡子的脸。
警察问他:她是不是你的女儿?
他疲倦地点点头。
警察告诉他:你女儿死因要过些日子才能明确答复你。
他对这句话不感兴趣,他觉得他不需要他们的答复,他觉得自己应该离开一会,这地方使他站着有点不知所措。于是他转身往外挤。那时候警察又拍了他一下,这次警察对他说:待会儿有几个问题要问你。
6挤出去以后,立刻感到身后有几个人的脚步声音。但他没在意,他走到堆满木材的地方时,身后有一个人来到了他的面前,那人用眼睛暗示了一下他女儿躺着的地方,然后低声说:我买了。
6微微一怔,但他随后就明白了那意思。他以同样低的声音问:出多少?
那人将右手的五个手指全部伸开。
五千?6问。
但是6明白这人只是出五百,他摇摇头,表示不卖。那人还想讨价还价,可第二人已经赶上来了。第二个人伸出一个手指偷偷放入6的右手手掌。6知道这个愿意出一千,但他还是摇摇头。
第三个人走到他面前时,他将两个手指主动插入那人的手掌,告诉他要出两千才卖。那人迟疑了一会,伸出手指暗示愿出一千五百,可6立刻就摆摆手,转过身去了。
2是在这个时候赶来的,当6伸出两个手指时,他丝毫没有犹豫,他一把捏住6的两个手指,然后抖动了几下。
于是6心安理得地在那堆木材上坐了下来,2朝着那一堆围着的人看了看,也在木材上坐下。他们现在都在等着这一堆人散去。
三
接生婆的死被发现,还是在2为6的女儿送葬以后。6的女儿死去的消息在城内纷纷扬扬,对她死因的猜测一日生出一种。但是为她送葬的事却几乎无人知道。为他送葬的只有2一个人。当2将她的骨灰盒捧到家中以后,他接下去要做的便是去司机的家,他需要得到司机的骨灰。然后2发现司机的母亲已经死去了。
其实那院子里的其他几个人早就有此疑心,因为那股腐烂气息越来越浓烈,那气息由风伴随着在他们房中进进出出,而且从多日前看着接生婆走入家中以后,他们再没见到她出来,但是他们中间谁也没把这话说出口。虽然他们在腐烂的气息里生活得十分恶心。
2在走入这个院子时,这股气息使他惊诧不已。当他走到司机家门前时,他感到另外三个门口都站了人,他们都看着他。2那时候已经发现这股令人痛苦的气息就来自眼前这个房间。他敲了敲门,里面也响起了敲门的声音,但是除此之外什么动静也没有。于是他就推了一下,门发出了一声使他战栗的吱呀声,门没有上锁。从那裂开的一条门缝里,一股凶狠的腐烂气息朝他扑打过来,使他一阵头晕。但他还是继续将门推开,并且走了进去。里面一片昏暗,满屋子翻滚的腐烂味使他眼泪直流。他走进去以后看到了躺在床上的接生婆。接生婆脸上的五官已经模糊不清。那脸上有水样的东西在流淌,所以她的脸显得亮晶晶的。2看了一眼后立刻将目光移开。接着他走入了另一间屋子,他在这间屋子里找到了司机的骨灰盒。骨灰盒放在一张桌子上,那是一张用来打牌打麻将的桌子。2捧着司机的骨灰盒出来以后,通过泪汪汪的眼睛,他看到那几个站在自己房门口的人都是水淋淋的,他告诉他们:已经烂掉了。
2回到家中以后,将司机的骨灰盒和6的女儿的骨灰盒并排放在一起。然后请来四位纸匠,用白纸做了一套组合式家具,以及冰箱彩电之类的家用电器。四位纸匠昼夜而作,三日后便全部完成。接着2请了一位唢呐吹手和几个拉板车的,把纸匠们的作品放在板车上,第一辆板车上还放着司机与6的女儿的骨灰盒。唢呐吹手和2走在最前列,在尖利的喜调声里,司机和6的女儿的婚礼在街上开始了。
他们走在城内几条主要街道上,街上的风将那套组合家具吹得歪歪斜斜,如同一个孩子手下的画。这情景吸引了街上所有的人,他们像几片水一样围了上去。2心想总算对得起司机了。他回答了他们的询问,高声告诉他们是谁与谁的喜事。他看到街两旁几乎所有的窗口都有脑袋挂在那里,有一家窗口挂着好几个脑袋。他们也经过了瞎子端坐的那条街。从尖利的唢呐声里,瞎子知道正在走来一个婚礼。
婚礼的行走经过了那破旧的城墙门洞以后,来到了城西坟场上。一个新坟已经掘好。2将司机和6的女儿的骨灰盒放入坟中。然后盖土,土盖下去时有几块石子击在骨灰盒上,发出几声清脆的响声,那响声透出了隐藏的喜悦。接着纸匠们的作品被堆在坟墓四周,2点燃了火。一群火像是一群马一样奔腾而起,一片黑烟在红色的火中缭绕不绝。顷刻之后,火势便跌落下来,于是失去了保护的黑烟也立刻四散而去。那烧透以后变得漆黑的纸灰将坟墓完整地盖住。可是一阵风将纸吹得七零八落,冉冉飘起以后便晃晃悠悠如烟般消散了。
此后,司机不再来到2的梦里。
四
在司机与6的女儿的婚礼行走过去以后,4出现在大街上。她的嘴里哼着一支缓慢的曲子,在街道的右侧迟缓走来。在这个没有雨也没有阳光的上午,4的形象显得很灰暗。她那张若有所思的脸,仿佛在暗示对往事的回首。4走在灰白的水泥路上,很像是一种过去在走来。
4在走来的时候,她的右手正在解开上衣的纽扣,她的动作小心翼翼显得十分优美。纽扣解开以后,她的身体出现了一根树枝似的倾斜,她开始从身上一点一点推开了那件上衣,然后右手抓住衣角,衣服便垂落在地了。她那么走了一会才松开右手,衣服就在街道上迅速地躺了下去,无声无息。接着她剥开藏青的毛衣,她依旧显得很美。藏青的毛衣掉落在地以后的模样,很像是一个人正在平静地死去。随后她开始解白色衬衣的纽扣,纽扣解开以后恰好一股微风吹来,使她的衬衣出现了调皮的飘动。衬衣掉下去时显得缓慢多了,似乎是一张白纸在掉落了下去。
4走到一棵梧桐树旁,她伸出手抚摸了梧桐树野蛮的树干。然后她将身体靠了上去,她继续哼着那支曲子。她似乎看到前面有很多人都站着没有动,于是她模糊地记忆起很久以前甩了甩钢笔,墨水留在地上的斑点。
4在那个时候解开了皮带,那条黑色长裤便沿着她白晃晃的大腿滑落下去,滑下去时似乎产生了一丝痒的感觉,她不禁微微一笑。她那条粉红色的短裤也随即滑落下去。然后她小心翼翼地从裤子包围中伸出了右脚,脚上没有袜子,接着她同样小心地伸出了左脚,左脚也没穿袜子。她赤裸的脚踩在了粗糙的水泥地上,她继续往前走去。
4赤裸的身体在这个阴沉的上午白得好像在生病。一股微风吹到她稚嫩的皮肤上,仿佛要吹皱她的皮肤了。她一直哼着那支曲子,她的声音很微小,她的声音很像她瘦弱的裸体。她走到了瞎子的身旁,她略略站了一会,然后朝瞎子微微一笑后就走开了。
瞎子在此之前就已经听到4的歌声了,只是那时候瞎子还不敢确定,那时候4的歌声让他感到是虚幻中的声音,他怀疑这声音是否已经真实地出现了。但是不久之后,4的声音像是一股清澈的水一样流来了。这水流到他身旁以后并没有立刻远去,似乎绕着他的身体流了一周,然后才流向别处。于是瞎子站了起来,他跟在4的声音后面走向一个他从未去过的地方。
4一直走到江边,此后她才站住脚,望着眼前这条迷茫流动的江,她听到从江水里正飘上来一种悠扬的弦乐之声。于是她就朝江里走去。冰冷的江水从她脚踝慢慢升起,一直掩盖到她的脖子,使她感到正在穿上一件新衣服。随后江水将她的头颅也掩盖了。
瞎子听到几颗水珠跳动的声音以后,他不再听到4的歌声了。于是他蹲了下去,手摸到了温暖潮湿的泥土,他在江边坐了下来。瞎子在江边坐了三日。这三日里他时时听到从江水里传来4流动般的歌声,在第四日上午,瞎子站了起来,朝4的声音走去。他的脚最初伸入江水时,一股冰冷立刻袭上心头。他感到那是4的歌声,4的歌声在江水慢慢淹没瞎子的时候显得越来越真切。当瞎子被彻底淹没时,他再次听到了几颗水珠的跳动,那似乎是4微笑时发出的声音。
瞎子消失在江水之中,江水依旧在迷茫地流动,有几片树叶从瞎子淹没的地方漂了过去,此后江面上出现了几条船。
三日以后,在一个没有雨没有阳光的上午,4与瞎子的尸首双双浮出了江面。那时候岸边的一株桃树正在盛开着鲜艳的粉红色。
一九八八年五月五日
这夜里将会很宁静,将会如子宫般,令人觉得安详。虽然门外聚居的人群有些吵闹,但也只是图一时新鲜,过几日便会遗忘。电单车的咒骂声也一样,过几日便也将和引擎声一齐消声觅迹。届时,他将有一个空间,属于自己的宁静和安详。
似水流年-王小波
========================
似水流年-[[王小波]]
-----
王二年表:
一九五〇年出生。
一九六六至一九六八年,“文化革命”。住在矿院,是一名中学生,目睹了贺先生跳楼自杀和李先生龟头血肿。
一九六八年,和许由在地下室造炸药玩,出了事故,大倒其霉。先被专政,后被捕,挨了很多揍。
一九六九至一九七二年,被释放。到云南插队。认识陈清扬。
一九七二至一九七七年,在京郊插队。与小转铃交好。与刘先生结识。刘老先生死。后来上调回城,在街道厂当工人。
一九七七至一九八一年,上大学。
一九八一至一九八四年,毕业,三十而立。与二妞子结婚。
一九八五至一九九〇年,与旧情人线条重逢,很惊讶地发现她已嫁了李先生。出国读学位。丧父。离婚。回国。
一九九〇年,四十岁。
-----
### 一
岁月如流,如今已到了不惑之年。我现在离了婚,和我母亲住在一起。小转铃有时来看我,有时怄了气,十几天都不露面。如今我基本上算是一个单身汉。
我住的是我父亲的房子,而我父亲已经不在了。我终于调进矿院来,在我父亲生前任教的学校教书。住在我家对面的是我的顶头上司李先生。李先生的夫人,是我的老同学,当年叫线条。线条在“文化革命”里很疯,很早就跑出来,和男孩子玩。现在提这些事不大应该,但是我想,线条不会见我的怪。因为她就是和我玩的。也可以说,我们俩是老情人。
至于李先生,更不会见怪,因为他不在乎这些事。除此之外,他和我的交情非常好。他从海外回大陆,第一个能叫上名字的人就是我。他还是个不善交际的人,直到现在,除了夫人之外,也就是和我能聊聊。我不知他在国外的情况,反正在中国,能说说心事的,也就是一个线条,一个王二。这实在不算多。用李先生的话说,别人和他没有缘。我也把李先生当个朋友。我向来不怕得罪朋友,因为既是朋友。就不怕得罪,不能得罪的就不是朋友,这是我的一贯作风。由这一点你也可猜出,我的朋友为什么这么少。
我现在没有几个朋友了。许由找了个出国劳务的活,到中东去修公路。陈清扬见不着。小转铃说,我对线条旧情不断,还说我是癞蛤蟆想吃天鹅肉。她简直是个醋葫芦。我爱上了李先生的老婆。李先生不知道,还说我和他有缘。该着做朋友。
李先生说,和我有缘,这种缘分起源于二十三年前一个冬日的早上。那时我是十七岁一个中学生,个子像现在一样高,比今天瘦很多,像竹竿一样。头上戴狗皮帽,身穿蓝制服罩棉袄,脚下穿大头皮鞋,这身打扮在当时很一般。我身上的衣服不大干净,这在当时也很一般。我那顶帽子是朋友送的,而他也不是好来的,不是偷来就是抢来的,这在当时也很一般。当年的中学生,只要不是身体单薄性情懦弱,有谁没干过几件坏事,抢几顶帽子实在一般——我就这个样子走到矿院的大操场上去看大字报。在六七年大字报已没有了轰动效应,但是还有不少东西可看。某先生早年留学日本时去嫖妓,想赖嫖资;某教授三年困难下矿山,吃招待饭时偷了馒头藏在怀里;某书记当年贪污了党的经费,给自己打了一个银烟盒等,颇为有趣。看这种东西很容易入迷,不知不觉自己也变成了坏蛋。假如再有“文化大革命”,这种东西我绝不看了。在当年我有一个习惯,就是每天要把全院的大字报看一遍。矿院很大,大字报很多,所以不能全看完。有些我只看看标题,有些览其大略,有些有趣的我仔细看。就是这样,还得起早贪黑。一大早我就到了大操场上,而大操场早被席棚隔成了九宫八卦之型。我在八卦之中走动,起得早了,没碰见人。转了几个圈后遇上了第一个人,他躺在地上像条死鱼。这就是李先生。
把时间推到二十三年前,李先生刚从香港回内地,过冬的衣服都是临时置办的。他身穿一件蓝色带风帽的棉大衣,北京人叫棉猴的那种东西,又小又旧,也不知是谁给他的。李先生个子小,那棉猴比他还小。可见是小孩子穿过的东西。棉猴下是粗呢裤管,这是他从海外带回来的东西。粗呢裤下是一双又肥又大的塑料底棉鞋,这是他在北京买的。李先生胡子拉碴,戴一副瓶子底也似的眼镜。我见时他就是这副样子倒在地上,半闭着眼睛,不见黑眼珠,浑身打着哆嗦,很像前几天跳楼的贺先生刚着地时的样子。但是仔细看时颇有不同,贺先生的脑子当时是洒出来的,而李先生的脑子还在脑壳里面,这是最主要的不同之点。贺先生从楼上跳下来时,我不在现场,是后来得到消息赶去的。虽然去得很快,也错过了不少场面。据说贺先生刚落地时,还在满地打滚,这场面我就没看见。据说贺先生的手还抓了两把,我也没看见。贺先生死时的景象,我几乎都没看见,只看见他最后抽抽了两下。这使我很没有面子。所以看见李先生倒在地下,我大为兴奋。虽然我拿不准他死了没有。
假如我知道李先生没死,只不过是晕了过去,那么我肯定会去救他。虽然我当时很瘦,但是“文革”前的孩子重视体育,所以都有一把力气,李先生又不重,我把他扛走没什么问题。但是当时我以为他有可能已经没救了,在这种情况下,就该保护现场,等待警察。既然我拿不准他死没死,还有第三种办法:我去喊几个人来,看看他死没死。这个办法我最不乐意。设想李先生已死,我又离开了现场,别人再撞上了,那时我再说我是第一个到达现场之人,谁还肯信?就算信了,对我更不好,他们会说,王二叫死人吓跑了。如今到了不惑之年,我不怕人家说我胆小了。经过了插队,当工人,数十年的时间,所到之处人都说我胆子非常大,胆大心黑,色胆包天,胆大妄为等等。偶尔有人说一句王二胆小,我也不觉得有什么。可是在当时,我就怕人说我这个。因此我采取了第四个办法,站在当地不动,看李先生是越抽越厉害还是越抽越硬邦。假如是后者,我就嚷嚷起来。假如是前者,我就过去扛他。谁知他很快就睁开了眼睛,坐起身来,这叫我大失所望。我转过身去,准备走了。
在李先生看来,那天早上的事就没这么轻松。当时他从香港赶来参加“文化革命”(后来他说,这是他这辈子犯的最大的错误),头天晚上刚到矿院,早上就来贴大字报。谁知和别人起了争执,遭人一脚踢成了重伤,晕倒在地。醒来一看,大出意料:原来没躺在医院里,也没人围着他。踢他的人也不见了。只有一个半桩孩子在一边看着,而且那孩子有姗姗离去之势。所以他急忙叫我回去搀他一把。李先生说,当时他伤处极疼,没人架一把一步也走不动。而我却摇头晃脑,好半天才走过去,可把他急坏了。所以等他能够上,就一把搂住了我的脖子,再也不敢放,生怕我也跑了。结果到了医院,我脖子上被箍出了一溜紫印。在这种情况下,我当然不肯再搀他回去,抽个冷子就跑掉了。这下又苦了李先生,他根本不认识回去的路,花了几倍的工夫才回到了矿院。
对于这件事我还有些补充。当时我不认识李先生,不知他是矿院的人。假如认识,抢救的态度会积极一点。我也不知他是被人摆平的,还以为他是在抽羊角风。假如知道,抢救的态度也会积极一点。做了这两点辩护之后我也承认,当时我对死人特别有兴趣,对活人不感兴趣。李先生说,他对我当时的心情能够理解。有件事他不能理解,就是那一脚踢得委实厉害。只要再踢重一点,他就会变成我感兴趣的人。
李先生挨那一脚的事是这样的:六七年大家都想写些大字报贴出去,然后看见别人在自己写的东西面前交头接耳,议论纷纷,这和我今天想发表作品的心情是一样的。顶叫人愤怒的是,自己辛辛苦苦写了一夜,才贴出去就被人盖掉。所以都在大字报上写着:保留五日,保留十日,无奈根本没人给你保留。那年头为这种事吵嘴、动手的事也不知有多少。李先生的大字报正贴在司机班一伙冒失鬼好不容易诌出的大字报上,而且被本主当场逮到。叉住了脖子和他理论,和他又理论不清。因此照他裆下踢了一脚,人家怎么也想不到他会让人踢个正着。当时我们院谁不知道司机班那伙人?只有李先生不知道。所以连挨揍的准备都没有。这一脚踢出麻烦来了,眼见得李先生脸色也变了,眼珠子也翻了,软软地挂在人家手上。人家也怕吃人命官司,赶紧把他放在地上跑掉了。谁又能想到他还有救呢?假如送他上医院,万一他又没救了呢?
现在我们院的人都在背后叫李先生龟头血肿,包括那些没结婚的小姑娘。她们说,李先生原是日本人,姓龟头,名血肿。这是不对的。李先生从未到过日本。他叫这个名字,是因为他挨了一脚后,十分气愤,就把医院的诊断书抄出来寻求公道,那诊断中有这样的字句:“阴囊挫伤,龟头血肿。”他寻到的公道就是从此被叫做龟头血肿,一肿二十三年,至今还没消。
-----
### 二
十几年后,我到当年李先生拿博士的学校里读书。李先生毕业后还在这儿任了两年教,所以不少人还记着他。人家对他的评价是:性情火暴,顽固到底,才华横溢。乍一听只觉得自己的英文出了问题:李先生性情火暴?他是最不火暴的呀!
李先生的才华横溢我倒是见过,那是在他被人龟头血肿了之后。他连篇累牍地写出了长篇大字报,论证龟头血肿的问题。第一篇大字报开头是这样的:李某不幸,惨遭小人毒手,业已将经过及医院诊断,披露于大字报。怎知未获矿院君子同情,反遭物议;兄弟不得不再将龟头血肿之事,告白于诸君子云云。
这篇大字报的背景是这样的:他把医院的诊断书画成大字报贴出来,就有些道学的人在上面批:这种东西也贴出来,下流!无耻!至于他怎么挨了人踢,却没人理会。所以李先生在大字报里强调:李某人的龟头,并非先天血肿,而是被人踢的。
李先生在大字报里说,他绝不是因为吃了亏,想要对方怎样赔罪才写大字报。他要说的是:龟头血肿很不好,龟头血肿很疼。龟头血肿应该否定,绝不要再有人龟头血肿。他这些话都被人看成了奇谈怪论。到这时,他回来有段日子了,大家也都认识他。在食堂里大师傅劝他:小李呀,拉倒吧。瞧瞧你被人踢的那个地方,不好张扬。李先生果然顽固,高声说:师傅,这话不对。人家踢我,可不是我伸出龟头让他踢的!踢到这里就拉倒,以后都往这里踢!
虽然没有人同意李先生的意见,但是李先生的大字报可有人看。他就一论龟头血肿,二论龟头血肿,三论四论地往外贴。在三论里他谈到以下问题:
近来我们讨论了龟头血肿,很多人不了解问题的严重,不肯认真对待,反而一味嗤笑。须知但凡男人都生有龟头,这是不争的事实。龟头挨踢,就会血肿,而且很疼,这也是不争的事实。不争的事实,何可笑之有?不争的事实,又岂可不认真对待之?他这么论来论去,直把别人的肚子都要笑破。依我看,这龟头血肿之名,纯粹是他自己挣出来的。
李先生论来论去,终于有人贴出一张大字报讨论龟头血肿问题,算是有了回应。那大字报的题目却是:龟头血肿可以休矣。其论点是:龟头血肿本是小事一件,犯不上这么喋喋不休。在伟大的“文化革命”里,大道理管小道理,大问题管小问题。小小一个龟头,它血肿也好,不血肿也罢,能有什么重要性?不要被它干扰了运动的大方向。一百个龟头之肿,也比不上揭批查。这篇大字报贴出来,也叫人批得麻麻扎扎:说作者纯属无聊。既知揭批查之重要,你何不去揭批査,来掺和这龟头血肿干吗。照批者的意见,这李先生是无聊之辈,你何必理他?既然理他,你也是无聊之辈。但是李先生对这大字报倒是认真答辩了。他认为大道理管小道理,其实是不讲理。大问题管小问题,实则混淆命题。就算揭批查重要,也不能叫人龟头血肿呀?只论大小重要不重要,不论是非真伪,是混蛋逻辑。他只顾论着高兴,却不知这大小之说大有来头。所以就有人找上门,把他教训了一顿。总算念他是国外回来的左派,不知不罪,没大难为他。要不办起大不敬罪来,总比龟头血肿还难受。李先生也知道利害,从此不再言语。这龟头血肿之事,就算告一段落。
流年似水,转眼就到了不惑之年。好多事情起了变化。如今司机班的凤师傅绝不敢再朝李先生裤裆里飞起一脚弹踢,可是当年,他连我们都敢打。院里的哥们儿,不少人吃过他的亏。弟兄们合计过好几回,打算等他一个人出来时,大家蜂拥而上,先请他吃几十斤煤块,然后再动拳脚。听说他会武功,我们倒想知道挨一顿煤雨后,他的武功还剩多少。为了收拾这姓凤的,我们还成立了一个“杀鸡”战斗队,本人就是该战斗队的头。我曾经三次带人在黑夹道里埋伏短他,都没短到。凤师傅干过侦察兵,相当机警,看见黑地里有人影就不过来。第四次我们用弹弓把他家的玻璃打坏了几块,黑更半夜的他也没敢追出来。经过此事,司机班的人再不敢揍矿院的孩子。
关于龟头血肿,我们矿院的孩子也讨论过,得到的结论是,李先生所论,完全不对。我们的看法是:世界上的人分两种,龟头血肿之人和龟头不肿之人。你要龟头不肿的人理解血肿之痛,那是完全不可能的。惟一的办法是照他裆下猛踢一脚,让他也肿起来。
有关李先生龟头血肿的事还可以补充如下:那些日子里北京上空充满了阴霾,像一口冻结了的粘痰,终日不散。矿院死了好几个人,除贺先生跳楼,还有上吊的,服毒的,拿剪子把自己扎死的,叫人目不暇接。李先生的事,只是好笑而已,算不了大事情。
-----
### 三
流年似水,有的事情一下子过去了,有的事情很久也过不去。除了李先生龟头血肿,还有贺先生跳楼而死的事。其实贺先生是贺先生,和我毫无关系。但是他死掉的事嵌在我脑子里,不把这事情搞个明白,我的生活也理不出个头绪。
贺先生死之前,被关在实验楼里。据我爸爸说,贺先生虽然不显老,却是个前辈。就是在我爸的老师面前,也是个前辈。到“文化革命”前,他虽还没退休,却已不管事了。用他自己的话来说就是:“我一辈子的事都已做完,剩下的事就是再活几年。”我爸爸还说,贺先生虽然是前辈,却一点不显老,尤其是他的脑子。偶尔问他点事,说得头头是道,而且说完了就是说完了,一句多余的话也没有。据此我爸爸曾预言他能活到很多当时五十岁的人后面。他被捉进去,是因为当过很大的官。然后他就从五楼上跳下来了。
贺先生从楼上跳下时,许由正好从楼下经过。贺先生还和许由说了几句话,所以他不是一下就跳下来的。后来我盘问了许由不下十次,问贺先生说了什么,怎么说的等等。许由这笨蛋只记得贺先生说了:“小孩,走开!”
“然后呢?”
“然后就是砰的一下,好像摔了个西瓜!”
再问十遍,也是小孩走开和摔了西瓜,我真想揍他一顿。
在我年轻时,死亡是我思考的主题。贺先生是我见过的第一个死人。我想在他身上了解什么是死亡,就如后来想在陈清扬身上了解什么是女人一样。不幸的是,这两个目标选得都不那么好。就以贺先生来说,在他死掉之前,我就没和他说过话。而许由这家伙又被吓坏了,什么都忘记了。你怎能相信,一个存心要死的人,给世界留下最后的话仅仅是“小孩走开”呢?
贺先生后来的事我都看见了。他脑袋撞在水泥地上,脑浆子洒了一世界,以他头颅着地点为轴,五米半径内到处是一堆堆一撮撮活像新鲜猪肺的物质。不但地上有,还有一些溅到了墙上和一楼的窗上。这种死法强烈无比,所以我不信他除小孩走开之外没说别的。
贺先生死后好久,他坠楼的地方还留下了一摊摊的污迹。原来人脑中有大量的油脂。贺先生是个算无遗策的人(我和他下过棋,对此深有体会),他一定料到了死后会出这样的事。一个人宁可叫自己思想的器官混入别人鞋底的微尘,这种气魄实出我想象之外。
虽然贺先生死时还蒙有不白之冤,但在他生前死后,我从没对他有过不敬之心。相反,我对他无限崇拜,无限热爱。不管别人怎么说他(反动学术权威、国民党官僚等等),都不能动摇我的敬爱之心。在我心中,他永远是那个造成了万人空巷争睹围观的伟大场面的人。
-----
### 四
前面提到李先生说过,取道香港来参加革命工作是个错误,这可不是因为后来龟头血肿起了后悔。起码他没对我说过不革命的话。他说的是不该走香港。在港时他遇上了一伙托派,在一起混了一些时,后来还通信。到了后来清理阶级队伍,把他揭了出来。
李先生的托派嘴脸暴露后,我和线条在小礼堂见过他挨打。那一回人家把他的头发剃光,在他头上举行了打大包的比赛,打到兴浓时还说,龟头血肿这回可叫名副其实。线条就在那回爱上了他。二十三年前,线条是个黄毛丫头,连睫毛都发黄,身材很单薄,腰细得几乎可以一把抓,两个小小的乳房,就如花蕾,在胸前时隐时现。现在基本还是这样,所不同的是显得憔悴疲惫。她是我所认识的最疯最胆大的女人,尽管如此,我也没料到她会嫁龟头血肿。
现在应该说到李先生挨打的情形。那个小礼堂可容四五百人,摆满了板条钉成的椅子,我们数十名旁观者,都趴在椅子上看。李先生和参赛选手数人在舞台上,还有人把大灯打开了,说是要造造气氛。李先生刮了个大秃瓢,才显出他的头型古怪:顶上有尖,脑后有反骨,反骨下那条沟相当之深。这种头剃头师傅也不一定能剃好,何况在场的没有一个是剃头出身,所以也就是剃个大概,到处是青黑的头发茬。我在乡下,有一回和几个知青偷宰一口猪,最后就是弄成了这个样子。我和线条赶到时,他头上的包已经不少了,有的青,有的紫,有的破了皮,流出少许血来。但是还没赛出头绪,因为他们不是赛谁打的包大,而是赛谁打出的包圆。李先生头上的包有些是条状,有些是阿米巴状,最好也是椭圆,离决出胜负还差得远。李先生伸着脖子,皱着眉,脸上的表情半似哭,半似笑,半闭着眼,就如老僧入定。好几个人上去试过,他都似浑然不觉。直到那位曾令他龟头血肿的凤师傅出场,他才睁开眼来。只见凤师傅屈右手中指如凤眼状,照他的秃头上就凿,剥剥剥,若干又圆又亮的疙瘩应声而起。李先生不禁朗声赞道:还是这个拳厉害!
线条后来对我说:那回李先生在台上挨打,那副无可奈何的样子真可爱!对此我倒不意外。李先生那样子,和E.T.差不多。既然有人说E.T.可爱,龟头血肿可爱也不足怪。线条还说,有一种感觉钻进心里来,几乎令她疯狂。她很想奔上前去,把他抱在怀里,用纤纤小手把那些大包抚平。这我也不意外,她经常是疯狂的。真正使人意外的是她居然真的嫁给了龟头血肿。
我也爱过李先生。在我看来,一个人任凭老大栗凿在头上剥剥地敲,脸不变色眉不皱,乃是英雄行为。何况在此之前,他曾不顾恶名,愤起为自己的龟头论战。虽然想法有点迂,倒也不失为一条好汉。所以当他被关在小黑屋里时,我曾飞檐走壁给他送去了馒头。线条说,要给李先生以鼓励,我也不反对。她给他的条子,都是我送去的。那上面写着:龟头血肿,坚持住!我爱你!我想,哥们儿,你活着不容易。让我婆子爱爱你也无所谓。谁知到后来弄假成真。线条真成了龟头夫人!
-----
### 五
那年贺先生从楼上跳下来,在地上抽了几下就不动了。然后不久,警察来验尸,把贺先生就地剥光。那时我站在人群的前列,脚下如穿了钉鞋,结结实实扎下了根,谁也挤不动。因此我就近目睹了验尸的全过程。等把贺先生验完,他已经硬了,因此剥下的衣服也穿不回去。警察同志们把裤子草草给他套到屁股上,把衣服盖在他身上,就把他搭上了车运走了。验尸中也没发现什么,只发现他屁股上有一片紫印。有位年轻的警察顺嘴说:他死!当时我觉得简直废话。“他”当然死了,你没看见他脑浆都出来了吗?然后马上想到这可能是术语。回去一査辞书,果然是的。那位小警察也没什么证据说是他死,只不过那么多人瞪着眼看着,屁股上那么一大片淤伤,又黑又紫,不说点啥不好。最后结论当然是自杀。其实打在屁股上,不伤筋骨不害命,还是相当人道的。后来和贺先生关在一起的刘老先生出来,别人问他是谁打的,他也说不太清楚,因为谁想起来都去打两下,只单单把凤师傅点了出来,倒不说他打得狠,只说他戴黑皮手套,拎根橡皮管子,一边打一边摸,弄得人怪不好意思。
后来家属据此要告凤师傅,但是刘老先生已经中风死掉了,死无对证。贺先生死的情形就是这样,对此我有一个结论,觉得犯不上和凤师傅为难,因为不管怎么说,他也不是个大坏蛋。闹了一回红卫兵,他干这点坏事,不算多。闹纳粹时,德国人杀得犹太人几乎灭了种。要照这么算,凤师傅只打屁股,还该得颗人道主义的奖章。问题不在这里。问题也不在贺家大多数人身上。贺老妈妈七十多,又是小脚,只想到告状,不能怪她缺少想象力。贺家大公子五十多岁,也不能怪他没想象力。贺家小公子,和我同年,叫做贺旗。原来在院里生龙活虎,也是一条好汉。我真不知他是怎么了。
-----
### 六
下乡时,线条没跟我去云南插队。她跟父母下了干校,其实是瞄着李先生而去。当然他们的情形不一样,下干校时,线条是家属,爱干不干,十分轻松。而李先生是托派分子,什么活都得干。后来不说他是托派了,干校是工人师傅主事,又觉得这龟头血肿不顺眼,继续修理。当地农村之活计有所谓四大累之说,乃是:
打井,脱坯,拔麦子,操屄。
除了最后一项,他哪一样都干过。再加上挑屎挑尿,开挖土方,泥瓦匠,木匠小工;初春挖河,盛夏看青。晚上守夜,被偷东西的老农民揍得不善。幸亏是吃牛肉长大的,身体底子好,加之年龄尚轻,不到三十岁;要不线条准是望门寡。
现在系里的人说起李先生,对他下干校时的表现都十分佩服。说他一个海外长大的知识分子,能受得了这些真不容易。更难得的是任劳任怨,对国家,对党毫无怨言,真是好同志,应该发展他入党。但是李先生说,他背着龟头血肿的恶名,恐怕给党抹黑——还是等等吧。
线条说,李先生那时的表现真是有趣极了。叫他干啥就干啥,脸上还老带着被人打包时的傻笑。她觉得龟头血肿这大E.T.简直是好玩死了。要不是干校里耳目众多,她早就和他搞起来了。
后来李先生自己对我说,老弟,我们是校友,同行,又是同事,当年你还给我送过馒头,这关系非比寻常。所以,告诉你实话不妨。在干校的时候,我正在发懵懂,觉得自己着了别人的道儿。像我这样学科学方法的人,也有这种念头,实在叫人难以置信。但是想到我在大陆遇到的这些事,又是血肿,又是托派,又是满头大包,实在比迷信还古怪。还有一件更古怪的事:每天下工以后,床上必有一张纸条。所以我宁愿相信自己是得罪了人,正在受捉弄。第一个可疑分子就是我大学时同宿舍的印度师兄。有一回我嫌他在房间里点神香,就钻到厕所里弄点声音给他听,一连扳了七八下抽水马桶。这下把他得罪了,他就叫我做起噩梦来,一梦三年不得醒转。既然碰上了这样的非自然力,还是乖乖屈服为好,免得吃更大的苦头。李先生在干校里的事就是这样。
李先生在下干校时,我在云南插队,认识了陈清扬,不再把线条放在心上,但是有时还想到贺先生的事。我想出了贺先生为什么临死时要叫小孩走开,这是因为在他死时,不喜欢有人看。
“文化革命”前,矿院有个俱乐部,夏天的晚上,从八点到十一点,一直亮着灯,备有扑克象棋等等。那里有吊扇,沙发上还铺了花边,既凉快,又宽敞。每天晚上我都到那里去下棋。有一天人家告诉贺先生说,王二的棋非常厉害。贺先生头发油黑(是染的),指甲修过,声音浑厚,非常体面。他的棋也好,却下不过我。但是他常来找我下棋,输了也不以为羞。
贺先生死时,头发半截黑半截白,非常难看。两只手别在后面,脖子窝着,姿势不自然。总的来说,他死时像个土拨鼠。贺先生肯定预见到自己死后的样子不好,所以不想让人看见。
贺先生的尸体被收走后,脑子还在地下。警察对矿院的人说,这些东西你们自己来处理。矿院的人想了想说:那就让家属来处理好啦。留下几个人看尸体,别人一哄而散。等到天色昏暗,家属还不来,那几个人就发了火,说道:爱来不来,咱们也走,留下这些东西喂乌鸦。天将黑时起了风,冷得很。
在云南时,我又想起了贺先生的另一件事。验尸时看见,贺先生那杆大枪又粗又长,完全竖起来了。假如在做爱前想起这件事,就会欲念全消,一点不想干。
-----
### 七
我在美国时,常见到李先生的印度师兄。他是我的系主任,又是我的导师。所以严格地讲,他既是我师父,李先生就是我师叔,线条就是我师婶。我和李先生称兄道弟,已是乱了辈分,何况我还对李先生说:线条原该是我老婆。不过在美国可不讲究这个。我早把导师的名字忘了,而且从来就没记住。他的名字着实难念,第一次去见他,我在他办公室外看了半天牌子,然后进去说:老师,您的名字我会拼了,能教教我怎么念吗?每回去见他,都要请他教我念名字,到现在也不会念。好在我根本不认他是我师父——这样线条也不是我的师婶。
我不认这位印度师父,还因为他实在古怪,和你说着话,忽然就会人定,叫也叫不醒。上课时讲科学,下了课聚一帮老美念喇嘛教的经,还老让别人摸他的脑袋,因为达赖喇嘛给他摩过项。虽然这么胡闹,学校还是拿他当宝贝。这是因为人家出过有名的书。照我看他书出得越多,就越可疑。李先生疑他和龟头血肿有关系,不是没有道理。
李先生告诉我说,他在大陆的遭遇,最叫人大惑不解的是在干校挨老农民的打。当时人家叫他去守夜,特别关照说,附近的农民老来偷粪,如果遇上了,一定要扭住,看看谁在干这不屙而获的事。李先生坚决执行,结果在腰上挨了一扁担,几乎打瘫痪了。事后想起来,这件事好不古怪。堂堂一个doctor,居然会为了争东西和人打起来,而这些东西居然是些屎,shit!回到大陆来,保卫东,保卫西,最后保卫大粪。“如果这不是做噩梦,那我一定是屎壳郎转世了!”
-----
### 八
后来我离开了云南,到京郊插队,这时还是经常想起贺先生。他刚死的时候,我们一帮孩子在食堂背后煤堆上聚了几回,讨论贺先生直了的事。有人认为,贺先生是直了以后跳下来的。有人认为,他是在半空中直的。还有人认为,他是脑袋撞地撞直了的。我持第二种意见。
我以为贺先生在半空中,一定感到自己像一颗飞机上落下来的炸弹。耳畔风声呼呼,地面逐渐接近,心脏狂跳不止,那落地的“砰”的一声,已经在心里响过了。贺先生既然要死,那么他一定把一切都想过了。他一定能体会到死亡的惨烈,也一定能体会死去时那种空前绝后的快感。
我在京郊插队时,我们家从干校回来过一次。和贺先生关过一个小屋的刘老先生也从干校回来,住在我家隔壁。我问刘老先生,贺先生有何遗言。刘老先生说,贺先生死时我不在呀,上厕所去了。要是在,还不拉住他?到了贺先生跳下去以后,脑子都撞了出来,当然也不可能有任何遗言。故而贺先生死前在想些什么后来就无法考证,也就没法知道,他为什么直了。
贺先生死那天晚上,半夜两点钟,我又从床上起来,到贺先生死掉的地方去。我知道我们院里有很多野猫,常在夏夜里叫春,老松树上还常落着些乌鸦,常在黄昏时哇哇地叫;所以我想,这时肯定有些动物在享用贺先生的脑子。想到这些事我就睡不着,睡不着就要手淫,手淫伤身体。所以我走了出去。转过了一个楼角,到了那个地方,看到一幅景象几乎把我的苦胆吓破。只见地上星星点点,点了几十支蜡烛。蜡烛光摇摇晃晃,照着几十个粉笔圈,粉笔圈里是那些脑子,也摇摇晃晃的,好像要跑出来。在烛光一侧,蹲着一个巨大的身影,这整个场面好像是有人在行巫术,要把贺先生救活,后来别人说王二胆子大,都是二三十岁以后的事。十七岁时胆力未坚,遭这一吓,差点转身就跑。
我之所以没有跑掉,是因为听见有人说:小同学,你要过路吗?过来吧。小心一点,别踩了。我仔细一看,蜡烛光摇晃,是风吹的;对面的人影大,是烛光从底下照的。粉笔圈是白天警察照相画的。贺先生的脑子一点也没动。因此我胆子也大了,慢慢走过去。对面的人有四十多岁,是贺先生的大儿子。他不住院里,有点面生,但是认识。他披了一件棉大衣,脚下放了一只手提包,敞着拉锁。包里全是蜡烛。我问他:白天怎么没看见你?他不说话,掏出烟来吸。手哆里哆嗦,点不着火。我接过火柴,给他点上了烟。然后在他身边蹲下,说:我和贺先生下过棋。他还是不说话。后来我说:已经验过尸啦。他忽然说道:小同学,你不知道。根本没验过。根本没仔细验过。说着说着忽然噎住。然后他说:小同学,你走吧。
我慢慢走回家去,那天夜里没有月亮,但有星光。对于我这样在那些年里走惯夜路的人来说,这点亮足够了。我在想,贺先生家里的人到底想怎样?反正贺先生死了,再也活不了。但是想到贺先生家里那些人,我就觉得很伤心。
贺先生的儿女们在寒风里看守着那些脑浆,没有人答理他们,那些脑浆逐渐干瘪下去。到后来收拾的时候,有一些已经板结了。所以后来贺先生的脑子有很大一部分永久地附着在水泥地上了。告诉我贺先生遗言的刘老先生也死了。在刘老先生生前,我对他没有一点好印象。这老头子在棋盘上老悔棋,明明下不过,却死不认输。我不乐意说死人坏话,但我不说出来,别人怎能知道呢?他嘴极臭,正对着人说话时,谁也受不了。
有关贺先生直了的事,我还有一点补充。不管他是在什么时候直了的,都只说明一件事:在贺先生身上,还有很多的生命力。别的什么都不说明。
-----
### 九
流年似水,转眼到了不惑之年。我和大家一样,对周围的事逐渐司空见惯。过去的事过去了,未过去的事也不能叫我惊讶。只有李先生龟头血肿和贺先生的事,至今不能忘。
那一年冬天,北京没一个好天,看不见太阳。那时候矿院是个一公里见方的大院子,其中三分之二的地方是松树林。那时候有好多人(革命师生、革命职工)从四面八方来到矿院,吃了窝窝头找不到厕所,在松林里屙野屎,屙出的屎橛子粗得吓死人。那时候,矿院的墙上大字报层层板结,贴到一尺厚,然后轰地一声巨响,塌下一层来。许由的奶奶活了七十八岁,碰上脑后塌大字报,被这种声音吓死啦。那时矿院里有好多高音喇机,日日夜夜响个不停。后来我们的同龄人都学不好英文:耳朵不好,听不见清辅音。那时候烂纸特多,有很多捡烂纸的孩子,驾着自制的小车,在马路上做优美之滑行。那时有很多疯子被放出来,并且受到崇拜。那时我刚过了有志之年,瞪大了眼睛,把一切都看在眼里。
如果我要把这一切写出来,就要用史笔。我现在还没有这种笔。所以我叙述我的似水流年,就只能谈谈龟头血肿和贺先生跳楼,这两件事都没在我身上发生(真是万幸),但也和我大有关系。
在结束这个话题之前,谈一点别的事情。我和许由造炸药,落到了保卫组手里,当时我身上有一篇小说的手稿,是我和我们院里的小秀才鸡头合著。王二署名不执笔,执笔的是鸡头。他犯了大错误,写小说用了真名,里面谈到了矿院诸好汉的名次,还提到了我们的各种丰功伟绩,飞檐走壁,抛砖打瓦之类。最不该的是把我砸凤师傅窗子的事都写上了,而后来我正是落到了凤师傅的手里,他把我的腰都打坏了。这件事情告诉我们:写小说不可以用真名,尤其是小说里的正面人物。所以在本书里,没有一个名字是真的。小转铃可能不是小转铃,她是永乐大钟。王二不是王二,他是李麻子。矿院不是矿院,它是中山医学院。线条也不是线条,她是大麻包。李先生后来去的地方,也可能不是安阳,而是中国的另一个地方。人名不真,地点不真,惟一真实的是我写到的事。不管是龟头血肿还是贺先生跳楼,都是真的,我编这种事干什么?
-----
### 十
七二年底李先生被发到河南安阳小煤窑当会计。河南的冬天漫天的风沙,水沟里流着黑色的水,水边结着白色的冰。往沟里看时,会发现沟底灰色的沙砾中混有黑色的小方块。这些小方块就是煤。水是从地下流出来的,地下有煤,所以带出了这种东西。一阵狂风过去之后,背风的地方积下了尘埃。在尘埃的面上,罩着黑色的细粉。这件事也合乎道理,因为风从铁路边上煤场吹过来,就会把粉煤吹起来。早上他从宿舍到会计室去,路上见到了这些,觉得一切井然有序,不像在梦里。
李先生那个时候对一切都持将信将疑的态度。
李先生到会计室上班时,头上总戴一顶软塌塌的毡帽。这种帽子的帽边可以放下来,罩住整个面部,使头部完全暖和起来。这种感觉是好的。李先生喜欢,乐意,并且渴望一天到晚用毡帽罩住头部。因为河南冬天太冷,煤矿又在山上。虽然有煤烧,但是房子盖得不好,漏风,所以屋里也冷。但是科长看见他在屋里戴着毡帽,就会勃然大怒:你别弄这个鬼样子吓我好不好?说着就会把他头上的帽子一把揪下来。这件事完全不合道理。
李先生去上班,身上穿蓝色大衣。这衣服非常大,不花钱就拿到了。这件事非常之好,虽然不合道理。给他这件大衣的是矿上的劳资科长,一个广东人。李先生见了他备感亲切,这是因为李先生所会的三种语言中,广东话仅次于英语。他就想和他讲粤语。劳资科长说:你这个“同机”不要和我讲广东话啦,别人会以为我们在骂他啦。这非常合理,在美国也是这样子的。不能在老美面前讲中国话。广东科长给了他这件大衣,说是劳保。李先生问,何谓劳保?广东科长说:劳保就系国家对你的关怀啦。这个话不大明白,李先生也不深问。劳保里还有些怪东西,橡胶雨衣,半胶手套,防尘口罩等等。李先生问了一句:我不下井,发我这些干什么?旁边有个人就猛翻白眼说:想下井?容易!李先生赶紧不言语了。在干校学习了两年,到底学会了一点东西。
李先生上班时也穿着这件大衣不脱。科长苦着脸看他,直到李先生被看毛了才说:很冷吗,你这么捂着?真的很冷?遇到这种情形,李先生也不答话,只是走到窗前,仔细看看温度表。看完后心里有了底,就走回来坐下来。科长也跟着走过去,看看温度表,说道:十五度。我还以为咱们屋是冷库呢!
李先生知道,放蔬菜的冷库就是十五度,谁说不冷?但是他不说。在噩梦里,说什么就有什么。假如把这话说了出来,周围马上变成冷库,自己马上变成一棵洋葱也不一定。在干校里已经学会了很多,比如上厕所捏着鼻子,下午一定会被派挑屎,臭到半死。科长说十五度不冷,李先生已有十分的把握——假如一时不察,顺嘴说出不满的话,大祸必随之而至。李先生暗想:“这肯定是我的印度师兄想把我变成洋葱!”
在一九七三年,李先生对他的印度师兄的把戏已谙然于胸,那就是说什么来什么,灵验无比。这个游戏的基本规则就是人家叫你干啥,不要拒绝;遇上不舒服不好受的事应该忍受,不要抱怨。只要严守这两条,师兄也莫奈他何。
李先生上班时脚上穿双大毛窝。他不适应北方气候,年年长冻疮。以前在美国,天也有冷的时候,那时不长冻疮。毫无疑问,这必是印度师兄搞的鬼。李先生认为,印度师兄这一手不漂亮。别的事印度人搞得很漂亮。比方说,龟头血肿,一个极可笑的恶作剧。满头起大包也想得好。有些地方师兄的想象力叫人叹为观止,包括叫他流落到河南安阳,中国肯定没有这么个地方。但是地名想得好:安阳。多像中国的地名啊!我要是个印度人,准想不出这么个地名来。但是长冻疮不好,一点不像真的。将来见了我也不好解释。别的事都是开玩笑,出于幽默感,冻疮里没有幽默感,只有恶意。
李先生并不是死心塌地地相信眼前是一个噩梦或是印度人的骗局。那天早上到会计室上班,顶着很大的风。风里夹着沙粒,带来粗粝的感觉。说印度人能想出这样的感觉,实在叫人难以置信。风从电线、树枝、草丛上刮过,发出不同的声音。如果说,这声音是印度人想出的,也叫人不敢信。人类在一个时间只能想一件事,不可能同时造出好几种声音。如果说,这一切都是印度人的安排,那么也是借助了自然的力量。这就是说,眼前的一切,既有真实的成分,也有虚构的成分。困难的是如何辨认,哪一些是虚构,哪一些是真实。
那天早上李先生到会计室上班,科长不在,他有如释重负之感。那个科长非常古板,一天到晚的找麻烦。李先生不会打算盘,要算时总是心算。他的心算速度非常之快,而且从不出错。但是科长不但强迫他把算盘放在桌上,而且强迫他在算账时不停地拨算盘珠。所以他见到科长不在,就赶快把算盘收起来,他一见到这东西就要发疯。
如果算盘放在他面前,李先生就忍不住琢磨,这个东西到底有什么用处。在他看来,那东西好像是佛珠一类的东西,算账时要不停地捻动,以示郑重。但是这佛珠的样子,真是太他妈的复杂了,简直不是人想出来的。然后他把脚跷在桌上,舒舒服服地坐着,把今天早上的所见仔细盘算一番。他觉得只要科长不在,别的人也不在,只有他一个人的时候,一切都比较贴近于自然。而当他们出现时,一切都好像出于印度师兄的安排。这种安排只有一个目的,就是要把他逼疯。其实他也没干什么坏事,不过是多扳了几下抽水马桶而已。为了这点小事把他灭掉,这印度人也太黑了!
李先生后来说,他觉得那时候自己快发疯了。一方面,他不脱科学方法论的积习,努力辨认眼前的事,前因如何,后果如何,如何发生,如何结束,尽量给出一个与印度师兄无关的解释。另一方面,不管他怎么努力,最后总要想到印度人身上去。到了这时,就觉得要发疯;想想看,我们俩同窗数年,感情不错,他竟如此害我!惟一能防止他疯掉的,是他经常在心里长叹一声说:唉!姑妄听之吧。然后就什么也不想了。
那天早上有人到会计室来,告诉李先生,山下有人找。李先生锁上门,往山下走,老远看见矿机关那片白房子。当时他精神比较好,又恢复了格物致知的老毛病,想到:
这片房子在山的阳面,气候较好。比较干燥,冬天也暖和。而且是在山下,从外面回来不必爬山。把全矿的党、政、工、团放在那里,十分适宜。而全矿的大部分房子都在上面一条山沟里,又黑又潮,这也合乎道理,因为坑口在山沟里。你总不能让工人爬四百级台阶上来上班,这样到了工作现场(掌子面),累得上气不接下气,就不能干活了。所以这一个矿分了两个地方,是合乎情理的,并不可疑。
山下的房子雪白的墙面,灰色的瓦面,很好看,这也合乎道理。因为那是全矿的门面嘛。但是走近了一看,就不是那么好。雪白的只是面上的一层灰。灰面剥落之处,裸露出墙的本体,是黄泥的大块(土坯——王二注)。仰头一看,屋檐下的椽子都没上漆,因为风化之故,木头发黑。窗上玻璃有些是两片乃至三片拼出来的,门窗上涂的漆很薄,连木纹都遮不住。这也不难解释,矿上的经济状况不是太好。
有关矿上的经济情况,矿长知道的应该是最多。他说:同志们,要注意勤俭节约。我们是地方国营嘛。地方国营是什么,相当难猜,但也不是毫无头绪。在一些香烟和火柴盒上,常见这字样。凡有了这四个字的,质量就不好,价格也不贵。在美国也是这样,大的有名的公司,商品品质好,卖的也贵。小的没名的公司,东西便宜,货也不好。在超级市场里有些货是白牌,大概也是地方国营。可以想见地方国营的煤矿,经济上不会宽裕,办公的房子也就很平常。
就是不知道地方国营是什么意思,李先生也能猜出矿的经济状况。井下还是打钎子放炮,有两辆电瓶车,三天两头坏。坏时李先生就不当会计,去帮着修电瓶车。李先生说,我可不会修电瓶。可是人家说:管你会不会,反正你是矿院下来的,没吃过猪肉,总见过猪跑吧。在一边蹲着,出出主意。这是因为电瓶车坏了,井下的煤就得用人力推出来。要是大电机坏了,连医务室的大夫也得到一边蹲着去。她百无聊赖,就给大家听听肺。试想一个矿,雇不起工程师,把会计和医生拉去修电机,这是何等的困境。矿里还有三台汽车,有一台肯定在美国的工业博物馆里见过。这件事想不得,一想就想到印度师兄身上去。
李先生走到矿上会议室门前时,精神相当稳定,这是因为早上格物致知大获成功。像这样下去,他的心理很快就会正常,不再是傻头傻脑的样子。假如是这样,线条见他不像E.T.,也许就不会喜欢他。不喜欢就不会嫁,这样现在我可能还有机会娶她为妻。然而岁月如流,一切都已发生过了。发生过的事再也没有改变的余地。
-----
### 十一
李先生走进会议室,这是一间大房子,里面有好大一个方桌。桌边上坐着两个人。一位是副矿长。另一位是个女孩子,穿件军大衣,敞着衣扣;里面穿着蓝制服,领口露出一截鲜红的毛衣。她的皮肤很白,桃形脸,眼睛水汪汪;嘴巴很小,嘴唇很红,长得很漂亮。这件事不难理解:矿上来了个漂亮女孩子,说是来找人,副矿长出来陪着坐坐,有什么不合理的?但是她来找我干吗?仔细一看,这姑娘是认识的。在矿院,在干校都见过。但是不知她叫什么名字。那女孩抬头看见李先生,就清脆地叫了一声:舅舅!李先生就犯起晕来:怎么?我是她舅舅?我没有姐妹,甥从何来?副矿长说:你们舅甥见面,我就不打搅了。李先生心想:你也说我是她舅舅?线条(这女孩就是线条。这两人以舅娶甥,真禽兽也!——王二注)说:叔叔再见。等他出了门,李先生就问:我真是你舅舅?线条出手如电,在他臂上狠拧了一把,说:我操你妈!你充什么大辈呀你!我是线条呀!李先生想:外甥女操舅舅的妈,岂不是要冒犯外祖母吗?姑妄听之吧。
然而线条这个名字却不陌生。在干校时,每天收工回来,枕头下面都有一张署名线条的纸条子。这是线条趁大家出工时溜进去塞的,以表示她对李先生的爱慕之心。有的写得很一般:
龟头血肿,我爱称!——线条。
有的写得很正规:
亲爱的龟头血肿:你好!
我爱你。
此致
无产阶级文化大革命的敬礼!
线条
有的写得很缠绵:
我亲爱的大龟头:我很想你。你也想我吗?——线条。
有的写得极简约,几乎不可解:
龟,血:爱。条。
李先生见了这些条子,更觉得自己在做梦。
对于线条的为人,除了前面的叙述,还有一点补充。此人什么话都敢说,“文化革命”里,除了操,还常说一个字,与逼迫的逼字同音不同形。当了教授太太后,脏字没有了,也只是不说中文脏字。现在在我院英语教研室工作。有一回给部里办的出国速成班上课,管学生(其实是个挺大的官)叫silly cunt。那一回院里给她记了一过。还叫她写检查。她检讨道:我是怕他出国后吃亏,故此先教他记着。该同志出国后,准有人叫他silly cunt,因为他的确是个silly cunt!院长看了这份检查,也没说什么。大概也是想:姑妄听之吧。
线条说,在干校时她已爱上了李先生,但是没有机会和他接近。后来李先生被分配到了河南,她就尾随而去。当然,这么做并不容易,但正如她自己所说,有志者事竟成。她靠她爸爸的老关系到安阳当了护士,然后打听到龟头血肿的所在地,然后把自己送上门去。这一切她都做了周密的计划,包括管李先生叫舅舅。最后他们俩终于到了一个没人的地方,这是在矿山的小山沟里。这也是计划中的事。她突然对准龟头血肿说:我要和你好!这是计划中关键的一步。说完了她抬起头来,看李先生的脸。这时她发现李先生的表现完全在意料之外,他把眼闭上了。这时她开始忐忑不安:龟头血肿这家伙,他不至于不要我吧?
李先生说,他琢磨了好半天,觉得此事是个圈套。这十之八九是印度师兄的安排。怎么忽然跳出个漂亮女孩子来,说她要跟我好?他琢磨了好半天,决定还是问问明白。于是他睁开眼睛,说道:什么意思?问得线条很不好意思,很难受。她发了半天的窘才说:什么意思?做你老婆呗。
不少人听说我会写小说,就找上门来,述说自己的爱情故事。在他们看来,自己的爱情可以写人小说,甚至载入史册。对此我是来者不拒。不过当我把这些故事写人小说时,全是用男性第一人称。一方面驾轻就熟,另一方面我也过过干瘾。但是写李先生的爱情故事我不用第一人称,因为它是我的伤心之事。线条原该是我老婆的,可她成了龟头血肿夫人!
线条说了“做你老婆呗”,心里忽然一动。说实在的,以前她可没想过要做龟头血肿夫人。她想的不过是要和李先生玩一玩,甚至是要耍耍李先生。可是李先生说你可要慎重时,她就动了火,说:就是要做你老婆!你以为我不敢吗!因此悲剧就发生了。李先生又说:这事可不是开玩笑。线条就说:我真想抽你一嘴巴。李先生就想:姑且由之吧。
后来李先生说,在我这一方面,当然不会发生问题。别的没有说。线条则凶巴巴地说,我这一方面更不会发生问题。忽然她惊叫起来:不得了,十一点半了。我得去赶汽车。原来从安阳来的就是这一班车。早上开过去,中午十二点开回来。如果误了,等两天才有下一班。她赶紧告诉李先生怎么去找她,还告诉他去时别忘了说,他是她舅舅。说完了这些话,就跑步去赶车。为了跑得快一点,还把大衣脱下来,叫李先生拿着。线条就这么跑掉了。如果不是这件大衣,什么事都不会发生。因为李先生觉得忽然跳出一个大姑娘要做他老婆,恐怕是个白日梦。他对世界上是否存在线条都有怀疑。在这种情况下,他不敢冒险跑到安阳去。假如坐了三个多钟头的长途车到了安阳,结果发现是印度师兄的恶作剧,他就难免要撒癔症。有了这大衣就有了某种保证,使他敢到安阳去。找到线条固然好,找不到线条也不坏,可以把大衣据为己有。
李先生说到当日的情形时指出,那个自称要做他老婆的小姑娘,和他说了没几句,就忽然不见了。等他跑出山沟,只见一个人影正以极快的速度向公路绝尘而去,而远处的公路上一辆客车正在开来。过了一秒钟,就起了一阵风沙,什么都看不见(李先生高度近视,戴两个瓶子底——王二注);再过一秒钟,风沙散去,连人带车什么都没了。这些事活脱脱像白日见鬼。那时他不知道线条是四八百、一千五的好手,而且她还有骤然开始飞奔的暴走症。关于前一点,不但有她过去历年在中学生运动会上的成绩为证,而且可以从体形上看出来。她的体形不像黄人,也不像白人,甚至不像黑人,只像电视里体育节目中奔在长跑跑道前面的那种人。假如晚生二十年,人家绝不会容她跑到河南去胡闹,而是把她撵到运动场上去,让她拿金牌升国旗一这些事比龟头血肿重要。
关于后一点,虽然暴走症是我杜撰的,但线条的确因为在我们院里滥用轻功,引起了很大议论。现在她已经是四十岁的女人,正是老来俏的时候,她却不穿高跟鞋。夏天她穿不住运动鞋,就穿软底的凉鞋。头发剪得不能再短,不戴任何首饰(首饰不但影响速度,而且容易跑丢了,造成损失一王二注);在学校的草坪上和人聊天,忽然发现上课的时间已到,于是她把绸上衣的下襟系在腰间,把西装裙反卷上来,露出黑色真丝三角裤,还有又细又长肌肉坚实决不似半老徐娘所有的两条腿,开始狂奔。中国教员见了这幅景象,个个脸色苍白。那些西装革履手提皮箱的外籍教员见了,却高叫道:李太太——!fucking——good!一个个把领带往后一掉,好像要上吊似的,就跟在后面跑出来。
在这一节里,我们说到了线条对李先生初吐情愫的情形,谈到了她把大衣放在李先生手里,跑步去追汽车。由此又谈到线条有暴走的毛病。夏天她暴走之时,两条玉腿完全出笼。这还不能完全说明问题,最能说明问题的是我俩一块去游泳。在这里要做些说明。她从水池里爬上来——在池沿上用双臂支撑——然后爬上岸。真正说明问题的是支撑那一瞬间。那一瞬间我看见的是由上到下流畅的线条,这些线条从十七岁以来就没有变。如果仔细分辨,可以看出乳房大了一点。但这也是往好里变。线条那两个乳房,原来不够大。考虑到她是属于苗条快速的类型,还是嫌小;现在则无可挑剔了。我不能相信像她这样的女人会一辈子忠于龟头血肿,而且我们俩从十七岁就相爱,居然没做过爱,这事实在不对。所以我就说:假如你想红杏出墙的话,可别忘了我呀。
-----
### 十二
线条听了这话,愣了一下才说:假如你的话只是称赞我美,那我很高兴,一定要请你吃一顿。到了四十还能得到这样的赞美,真是过瘾。假如还有别的意思的话,我要抽你一个嘴巴。当然,假如你不在意的话。要是你在意就不抽。二十多年的老友,可别为一个嘴巴翻脸。你到底是哪种意思?我当然不想挨耳光,就说:当然是头一种意思啰。不过我也想知道这是为什么。她说不为什么,只不过是因为早就下了决心,除龟头血肿,一辈子不和别的男人睡觉。
线条这家伙就是这样,干的事又疯又傻。她自己也知道自己的所作所为是发疯,但是依然要发疯。这是因为她觉得疯一点过瘾。这种借酒撒疯的事别人也描写过,比如老萧(萧伯纳——王二注)就写过这么一出,参见《卖花女》(又名《匹克梅梁》——王二注);卖花女伊丽莎白去找息金斯教授,求他收她为学生一场。在场人物除上述二人,还有一个老妈子别斯太太,一个辟克林上校。别斯太太心里明白,一个大学教授,收个没文化的卖花女当学生是发疯,而且是借酒撒疯。因为那姑娘虽然很脏,洗干净了准相当水灵。所以她对上校说:
先生,您别唆着我们东家借酒撒疯!
息金斯听了说道:人生是做吗?!可不就是借酒撒疯嘛。想撒疯还撒不起来哪!借酒撒疯,别斯太太,你可真哏!
编辑先生会觉得这段话里错字特多。其实不然,那息金斯的特长是会讲各路乡谈,一高兴就讲起了天津话。题外的话说得太远了。我说的是线条的事,她一辈子都在借酒撒疯。
以下的事主要是线条告诉我的。她从煤矿回来,只过了两天,龟头血肿就跟踪而至,送还大衣。那天线条的同宿舍的舍友也在。不但在,而且那女孩还歇班。外面刮着极大的黄风,天地之间好似煮沸了的一锅小米粥一样。这种天气不好打发别人出去。何况已经说了,龟头血肿是她舅舅,来了舅舅就撵人出去,没这个道理。线条只好装成个甜甜的外甥女,给龟头血肿削苹果。然后带他去吃饭,到处对人介绍说:我舅舅!别人说:不像。线条就说:我也不像我妈。别人说:太年轻。线条说:这是我小舅舅。别人又说:你怎么对舅舅一点不尊重?线条说:我小舅在我家长大,小时候一块玩的。到了没人的地方就对李先生瞪眼,说:你刚才臭美什么?你以为我真是你外甥女?
到了下午李先生回矿,线条送他出来时才有机会单独说话。线条叫他下礼拜天黑以后来,那一天同屋的上夜班。来的时候千万别叫人看见。然后她就回去等下星期天。李先生着实犹豫去不去,因为要想在晚上到安阳,只能坐火车,下车九点了。鬼才知道线条留不留他住。没有出差证明,住不上旅馆,在候车室蹲一夜可就糟了。李先生南国所生,最怕挨冻,要他在没生火的房子里待一夜,他宁可在盛暑时分挑一天大粪,而且他对这件事还是将信将疑。但是李先生还是来了。线条说起这件事,就扁扁她那张小嘴:我们龟头对人可好啦。
线条说,李先生和她好之前,保持了完全的童贞。男人的这种话,他一说你就一听,反正没有处女膜那回事。但是线条对此深信不疑。据李先生自己说,在和线条好之前,只和高一年的一位女同学date了几次,而且始终是规规矩矩的。这件事我在美国调查过,完全属实。我的这位师姑和我的老师不是本科的同学,也不是硕士班的同学。当时是七十年代以前,试想一个美国女孩,假如不是长得没法看,怎么当上了理科的博士生?她又矮又肥,两人并肩坐时,还会放出肥人的屁来,可以结结实实臭死人。李先生说:我也嫌她难看。但我怎么也不忍伤了一个女孩子的心,所以不能拒绝她。
其实李先生是个情种,他对线条的忠诚是实,我不便加以诋毁。但是别的女人要是做出可怜的样子来勾引他,他就靠不住了。我知道他教的研究生班里,有个女孩子漂亮得出奇,也笨得出奇。考试不及格时哭得如雨打梨花。等到补考时,李先生对我说,你给她辅导一下。然后假装不经意,把题全告诉了我。我自己把它们做了出来,把答案给了那女孩,说:背下来。假如再不及格,你就死吧。她就这样考了六十分。根据这个事实可以推导出,假如有个女人对李先生说,你不和我性交我就死!他一定把持不住。
李先生成为革命者也是因为他心软,不但见不得女人的眼泪,而且见不得别人的苦难。他老念格瓦拉的一句话:我怎能在别人的苦难面前转过脸去?他就这样上了师姑的钩。后来该师姑又哭着说,你就是个黑人,我也不跟你吹。怎奈黄的和白的配出来,真是太难看!其实黄白混血,只是很小时不好看。大了以后,个顶个的好看,就如皮光缩肚的西瓜,个个黑籽红瓤。师姑的说法以偏概全,强词夺理,李先生居然就信了,白闻了不少臭屁。现在该师姑在母校任教,嫁了个血统极杂的拉美人。生了一些孩子,全都奇形怪状。
现在要谈到线条与李先生幽会的事。为了保持故事的完整,本节的余下部分将完全是第三人称,没有任何插话。
李先生第二次到线条那里的日子,不但是星期天,而且是12月31日。那天刮起了大风。风把天吹黄了,屋里的灯光蓝荧荧。线条住的房子是一座石板顶的二层洋楼,原来相当体面,现在住得乱七八糟,有七八家人,还有女单身宿舍,所以就把房子改造了一下,除原有的大门外,又开了一个门,直通线条一楼住的房间,那房子相当大,窑洞式的窗子,在大风的冲击下,玻璃乒乓响。和她同屋的人上夜班,黄昏时分走了。
如前所述,线条住的房子很大,有三米来宽,八九米长。这大概是原来房主打台球的地方。整个安阳大概也只有这么一座够体面的洋房,但是原来的房主早就不在了。后来的房主也不知到了哪里。但是这间房子里堆着他们的东西,箱子柜子穿衣镜等等,占去了三分之二以上的地方,要不偌大的房子不会只住两个姑娘。屋子正中挂了一盏水银灯,就是城市里用来做路灯的那种东西,一般很少安在家里。这种灯太费电,而且太耀眼。但是在这里没有这些问题。因为这里是单身宿舍,烧的是公家的电;这里住了两个未婚姑娘,电工肯给她们安任何灯;丫头片子不怕晃眼,除了这些东西,就是两张铁管单人床。
傍晚时分线条就活跃起来。她打了两桶水放在角落里,又把床上的干净床单收起来,铺上一张待洗的床单。这是因为上次李先生来,在雪白的床单上一坐,就是一幅水墨荷叶。线条倒不在乎洗被单,主要的是,不能让人看出这房里来过人。故此她不但换了被单,而且换了枕巾。别人的床上也盖了一张脏被头。除此之外,她还换了一件脏上衣。这样布置,堪称万全。做完了这些事,她就坐下等待。天光刚刚完全消失(这间房子朝西,看得很清楚),大概是晚上八点。现在李先生刚下火车,正顶着大风朝这里行进。这段路平常要走四十分,今天要一小时以上。线条站起来,走到窗前往外看。什么也看不见。她把窗帘仔细拉上了,线条又回来,坐在床上等李先生。听着窗外的风声,她想到,李先生来一趟太不容易了。下回我到矿上去找他。但是这一回也不能让她安心。于是她在床下待洗的衣服堆里拣了一件脏衬衣,走到穿衣镜面前,透过上面的积尘,久久地看着自己。她拣了一块布,把镜子擦了擦,就在镜前脱起衣服来。在把那件脏衬衣穿上之前,她看着镜子说了一句话:这么好的身体交给龟头血肿去玩,我是不是发了疯?
晚上李先生走到线条门前时,他比她预见的要黑得多。这是因为李先生到火车站去,经过了煤场。当时正好有一阵旋风在那里肆虐。走过去以后,李先生的模样就和从井下刚出来时差不多了。然后他又从火车上下来,走了很远的路,几乎被冷风把耳朵割去。虽然人皆有好色之心,但是被冷风一吹,李先生的这种心就没了。他想的只是:我要是不去,那女孩子会伤心。
李先生当时不但黑,而且困得要死。时近年底,矿上挖出的煤却不多,还不到任务的三分之一。所以矿上组织了会战,把所有的人都撵下井去,一定要在新年到来之前多挖些煤出来。开头是八小时一班,后来变了十二小时一班,然后变成十六小时一班,最后没班没点,都不放上井来,饭在下面吃,困极了就在下面打个盹。如此熬了三十六小时(本来想熬到新年的,那样可以打破会战纪录)之后,因为工人太累,精力不集中,出了事故,死了一个人。矿领导有点泄气,把人都放上来。李先生推了三十小时的矿车,刚上来洗了澡,天就到了下午。他在火车上打了一会盹,完全不够。所以他站在线条门前时,睡眼惺忪。
晚上李先生到来之前,线条坐在床上想:龟头血肿虽然好玩,这一回可别玩得太过分。虽然她说过,要做龟头血肿的老婆,但是要是能不做当然好啦。这种心理和任何女人逛商店时的心理是一样的:又想少花钱,又想多买东西。更好的比方是说,像那些天生丽质的少女:又想体会恋爱的快乐,又不想结婚。然而她的心理和上述两种女人心理都不完全一样,龟头血肿之于线条,既不是商店里的商品,也不是可供体会快乐的恋人,而是介乎两者之间的东西。
李先生进了线条的门,迷迷糊糊说了声:你这里真暖和。然后他打了个大呵欠,又说:你好,线条。圣诞快乐,新年快乐,上帝保佑你。他实在是困糊涂了,说话全不经过大脑。假如经过了大脑,就会想到:我们这里是无产阶级革命派的天地。假如有上帝,他老人家也不管这一方的事,正如他老人家管不了霍梅尼。
-----
### 十三
晚上李先生到来之后,线条让他洗了脸,又叫他刷牙。李先生带着姑且由之的态度,照做了。此时她看着李先生那张毛扎扎的嘴,心里想:万一他要和我接吻,我就拒绝好啦。不必叫他刷牙。后来听见外面风响,又想到他今天来是多么的不容易。所以他要接吻也不好拒绝的,让他刷刷吧。现在李先生连牙缝里都是煤,被他亲上几下就成了蜡染布啦。
线条的这些想法,都以“够意思”为准则。“文化革命”里我们都以“够意思”为准则,这话就如美国人常说的“be reasonable”,但是意思稍有区别。美国人说的是:要像一位诚实的商人一样,而我们说的是:要像一个好样的土匪。具体到线条这个例子,就是她要像一位好样的女土匪对男土匪那样对待李先生。
对于线条的够意思,还有如下补充。六八年夏天,正兴换纪念章(纪念章三个字怪得很。当时还没死嘛,何来纪念?——王二注),海淀一带,有几处人群聚集,好像跳蚤市场。线条常到那些地方去。除了换纪念章,那儿也是拍婆子的地方。有人对线条有了拍拖之心,就上前纠缠。线条嫣然一笑,展开手中的折扇。扇面上有极好的两个隶字(我写的——王二注),“有主”!那时是二十二年前,线条是个清丽脱俗的小姑娘,笑起来很好看。
假如对方继续纠缠,线条就变了脸,娇斥一声:“王二,打丫的!”王二立刻跳出来,揪住对方就打。假如对方有伙伴,王二也有伙伴,那就是许由。许由一出场,就是流血事件。他是海淀有名的凶神。然后我们送打伤的人上医院,如果伤得厉害,以后还要请吃饭。这就是够意思了。
李先生刷牙时,线条正在想,自己要够意思。但是她也想到了,够意思也要有止境。这个止境是个含混的概念。假如他想动手动脚,一般是不答应。但是也有答应的可能,所以线条做了这种准备。假如李先生想要她的贞节,那就决无可能。他敢在这事上多废话,就打丫的。当时线条决定和男人玩,但要做一辈子处女。她以为这样最为过瘾。
李先生洗漱完了,他们到床上坐下。原来线条坐着自己的床,李先生坐别人的床,后来她叫李先生过来,坐在她身边。这是因为她看出李先生很疲惫。那被头只能垫住李先生的屁股,万一他往后一倒,就全完了。然后她就研究起李先生来。第一个研究成果是:李先生是招风耳。第二个研究成果是:李先生的毛孔里都是煤。她正要告诉李先生这些事,李先生却说:我想躺下睡一会儿。说着他就朝一边歪去,还没躺倒就睡着了。线条后来说:“当时我真想宰了他(谋杀亲夫!——王二注)!”
李先生倒下后,打起呼噜来。线条简直想哭。可是她马上就镇定下来:妈的,你睡吧。老娘先来玩玩你!她给他脱了鞋,把他平放在床上,解开他胸前的衣扣和腰带,把手伸了进去,摸着了一大堆破布片(单身汉的衬衣——王二注)。后来她这样形容自己初次爱抚情人的感觉道:把龟头血肿捆在一根木棍上,就是一个墩布。
然而龟头血肿不完全是墩布。把手伸得更深,就摸到了李先生的胸膛。那一瞬间线条几乎叫出来,当然,摸久了也稀松平常,但是第一次摸感觉不一样。李先生的胸上有疏疏落落的毛,又粗又硬,顺胸骨往下,好像摸猪脊梁。这还得是中国猪,外国猪的鬃毛不够硬,不能做刷子。不管李先生的胸毛能不能做刷子,反正线条摸着心花怒放。她一路摸下去,最后摸到了一样东西,好像个大海参。这一下她停下来,想了好半天,终于想到李先生的外号上去。于是她咬着自己的手指说:乖乖,这哪里是器官,分明是杀人的凶器。
一摸到这个地方,李先生就醒了。刚才他在做梦,梦见在矿上,从矿井里出来去洗澡,澡堂里一锅黑泥汤。好多工人光着屁股跳到泥塘里去,其实他梦的全是真实所见的事,只是他当时不敢相信自己的眼睛,到现在还不敢相信自己的眼睛。怎么能在一个房顶下,看见了那么多男性生殖器。所以他怀疑自己在做梦,而且怀疑自己是同性恋者。只有满足上述两个条件,才会看见这种东西。
李先生说,他从睡梦中醒来,感到线条在摸他,倒吓了一跳。那时他看到线条小脸通红,脸上笑盈盈。他刚从梦中醒来,所以觉得,眼前的事不是梦,而且他也不希望是梦。这是他的似水流年,不是我的。岁月如流,就如月在当空,照着我们每一个人,但是每个人的生活都不一样。
后来线条叫李先生做了庄严保证:保证不做进一步的非分之想,保证在线条叫他停的时候停下来等等,线条就准许他的手从衣襟底下伸进去。这已经是第二次幽会时的事,和上次隔了一星期。线条说,李先生的手极粗。好像有鳞甲一样。但是透过他的手,还是感到自己的腰很细,乳房很圆,肚皮很平坦。她对这些深为满意。除此之外,感觉也很舒服(但是有些惊恐),这比在班上聊大天好玩多了。
与此同时,我在云南偷农场的菠萝。半夜三更一声不响地摸进去,砍下一个,先放到鼻子下闻闻香不香。要是香的,就放到身后麻袋里;不香就扔掉。我们俩如出一辙,都不走正路。走正路的人在那年月里,连做梦都想着天下三分之二的受苦人。可是我说:这些受苦人我认得他们是谁吗?再说了,他们受苦,我不受苦?那晚上我一脚踩进了蚂蚁窝,而且我两只脚都得了水田脚气,趾缝里烂得没了皮。那些蚂蚁一齐咬我,像乱箭穿心一样疼。
我们三人里,李先生感觉最好,可是他却想入非非,觉得眼前的感觉不可靠。人要是长了这个心眼,就有点不可救药。当他的手掌从线条乳房上掠过时,感到乳头有点凉冰冰,于是他又动了格物致知的心思:这东西是凉的,对头吗?
李先生迷迷糊糊,手往下边伸去。线条动作奇快,一下子挣脱出来,还推了李先生一把,说道:你好大胆!李先生说:对不起对不起!我不是这个意思。线条却说:管你什么意思,反正人家(同宿舍的河南小姑娘)快下班了,你该走了。
-----
### 十四
“文化革命”来到之时,有些人高兴,有些人不高兴。刘老先生对我说过,一开头他就想自杀。因为他见那势头,总觉得躲不过去。但是他想到在峨嵋酒家还能吃到东坡肘子,又觉得死了太亏。他属于不高兴者,线条属于高兴者,因为那一年我们上初三,她各科全不及格。她爸爸说:考不上高中,你给我到南口林场挖坑去。当时就是这么安置考不上高中者。妈妈则说:这院里全是书香门第,还没人去挖坑呢。她叫老头到附中讲讲去。老头则说,我是党委书记,怎能干这种事?那年头天下三分之二的受苦人和党性原则都和真的似的。老妈妈实在怕丢人,就找我给线条补功课。实在补不动,差得太远。我王二不但是坏蛋,而且有怜香惜玉之心,所以订下计划,要点如下:
一、线条要考的高中,不是外面的学校,只是本校高中;因此只须参加毕业考,及格就能上。
二、毕业考试上厕所的次数不限。
三、男厕和女厕之间,我已打了一个小洞。
虽然有此万全安排,线条仍然吓到要死。到临考前一星期,她告诉我,已经把月经吓了回去。到临考前三天又告诉我,开始掉头发。但是临考前一天,她把我从床上叫起,口唱革命战歌。原来根据革命需要,中学停课不考试了。
我怎么也想不到线条后来不但考上了大学,而且上了研究生。我们学校要是来了有大学问的洋人做讲座,翻译非她不成。那些老外开头只以为她不过是个漂亮女人罢了,聊起来才发现,不管是集合论,递归论,控制论,相对论,新三论老三论,线条无不精通。不但精通,而且著作等身(和李先生联名发表)。那些洋人只好摇头说道:我们国家像李太太这样有才的女人也有,但是长得都不像女人。
现在我们院里的人都说:这有什么奇怪?她是龟头血肿夫人嘛。好像在李先生的精液里,含有无数智力因素,灌溉了线条的智力之花,此说是不对的。有三天前她和小转铃的话为证,地点是在我家的客厅里:
线:铃子,你们还有吗?
铃:什么东西?
线:什么东西?老公干老婆用的东西嘛。橡皮的condom!我的妈,得了失语症了!(这是英文好的人才得的毛病,不是谁想要得就得得了的。——王二注)
铃:(不好意思)有是有,全是特号的。
线:那才好哪。我们龟头那玩意可大了!肯定不比你们王二小。
铃:他不是“我们”。他对我不好!
线:那你治治他,买小号的,两次他就老实了。
由上述对话可知,他们是用避孕套的,智力传染之说可以休矣。我讲这事的目的是要说明,线条原是个性早熟、智力晚熟的家伙,嫁给龟头血肿之前的线条,和以后的线条不一样。
撵走了李先生,线条还有很多事要干。首先是要把床上的脏床单换下来。然后是刷洗李先生喝水的杯子,藏起李先生用过的牙刷和毛巾,因为上面都有煤。然后从隐秘的地方拿出一块很大的白毛巾。她把所有的衣服全脱光。站到镜子前面去。镜子里站着一位白皙、纤细的少女(有关这个概念,我和线条有过争论。我说她当时已经二十一岁,不算少女。她却说,当时她看起来完全是少女。如果不承认这一点,她毋宁死。我只好这样写了——王二注)。该少女眼睛水汪汪,皮肤洁白,双腿又直又长。腰非常细,保证玛丽莲·梦露看了都要羡慕。在小腹上,有很小一撮阴毛。虽然面积很小,但是很黑很亮。线条对此非常自豪。她说这一点非常重要,假如没有的话,就不好看,太多太乱,也是不好。她后来和李先生出国时,租了很多录像带,在录像机上定格比较,发现很多大名鼎鼎的脱星,在这一点上还不如她远甚。只有一位克瑞斯透,在十九岁拍的片子里,曾有过如此美丽的腹部(我没看见,不能为她作证——王二注)。
线条还说,在这个美丽的躯体上,有极美的装饰,就是一道道黑色。这位美丽的少女,有绝美的黑色嘴唇,乳房上有黑色的斑纹,小腹上有几条细的条。初看似信手拈来,细看才发现那种惊人的美。要问此美从何而来?这是龟头血肿涂上的煤黑。线条用毛巾蘸了凉水,把黑印一一拭去。然后她洗了脸,漱了口,刷了牙,穿上衣服,出了门,要把脏水倒掉。这个走道黑糊糊的,线条又不像王二那么胆大。所以当她听见呼呼的声音时,着实吓得够呛。
线条说,那个走廊里没有灯,可是也没什么地方可以藏人。听见这声音可把她吓坏了。于是她放下了水桶,悄悄溜了回去,拿了一个大电筒出来。这东西不但可以照亮,还可用来打架,她拿这个东西循声而去。结果找到一段楼梯下,有一块小得不得了的空间。在那块空间里,李先生正以娘胎里的姿势睡觉呢。他那件劳保大衣放在外面,没带进去,这是因为里边塞不下了。线条一看,登时勃然大怒,想道:龟头血肿!不是叫他找大车店睡觉去吗?她想立时把李先生叫起来暴打一顿,然后叫他滚蛋,再也别来。假如这样做了,不但大快人心,而且我现在还有机会。
但是线条没有这么做。她做了另外的决定,所以现在她的户口本上户主一栏上写着李先生的名字。线条那一栏里写着:李某某之妻。这十足肉麻。做了这个决定之后,她就完全堕落了。
在似水流年里线条做了这样的决定,要做龟头血肿之妻,永不反悔。对此我完全不能理解。但是,只要李先生不死,这事不会改变。虽然岁月如流,什么都会过去,但总有些东西发生了就不能抹煞。
-----
### 十五
李先生听见线条说:你对我干什么都行,他就想起我那位胖师姑来,师姑过去老和他说这话,他只是不懂。到吹了以后,师姑告诉他,那话的意思就是:make love to me!后来他想,幸亏没听懂。听懂了还能不答应?答应了还能不兑现?每回一想到兑现,就会眼前发黑,要晕死过去。
因为有过上述经历,那天李先生听了这话,马上就反应过来了。他直言不讳地说:咱们做爱吧。线条一听,小脸挣得通红,厉声说:你倒真不傻!然后想了想,又说:那就做吧。
李先生和线条后来约定了在煤矿附近山上的庙里做爱。时间就定在春天停暖气的那一天。
李先生决定相信线条,把自己理智的命运押在她身上。七三年的三月十五日中午十二时,他就到那破庙里去。为了验证一切,他非常仔细地记下了所有的细节。他受的是英式教育,故此像英国人那样一丝不苟,像英国人一样长于分析,像英国人一样难交往,交上以后像英国人一样,是生死朋友。
李先生说:那个破庙在山顶上,只有十平米的正殿。围墙里的草有齐腰深,房顶上的草像瀑布一样泻下来。庙里的门框、窗框、供桌等等一切可搬可卸的木头,都被人搬走了。正殿里有一小堆碎砖瓦,还有一个砖砌的供台,神像早没了。他想过,这会是个什么庙。照道理,山顶上的应该是玉皇庙,这是因为山离天较近,虽然是近乎其微的一点。作为中国人,他在海外读过有关民间风俗的书。但是在这座庙里,得不到一点迹象来验证这是玉皇庙的说法。而且也得不到一点验证它不是玉皇庙的说法。在这里,什么验证都得不到。因为没有神像,没有字迹,什么都没有。正因为如此,李先生对这庙的存在才坚信不移。
李先生还说:那个庙里的墙该是白的,但是当时很多地方是黑的。房顶露洞的地方,下面就是一片黑。这是因为年复一年漏进来的雨水,把墙上的白灰都冲走了。墙皮剥落的地方也是一片黑。墙上有的地方长起了青苔,有的地方发了霉。地上是很厚的泥。泥从房顶上塌下来,堆在地上。在房顶露洞的地方,椽子龇牙咧嘴地露出来。那些椽子朽烂得像腐尸的肢体一样,要不也会被人拆光。地上的泥里还混有石子,石子的周围,长着小草,小草也是黑色的。院子里长着去年的蒿子,它们是黄色的。房上泻下的草也是黄色的。风从门口吹进来,从房顶的窟窿吹出去,所有的草都在摇,映在房子里的光也在摇。但是线条没有来。李先生爬到香台上往外看,透过原来是窗子的洞,穿过墙上的窟窿,可以看到很多地方,但是看不见线条。他又退回院子里,从门口往外看,只看见光秃秃的石山和疏疏落落的枯草,还是见不到线条。但是线条一定在这里,李先生刚决定要找一找,线条就像奇迹一样出现了。她从庙后走出来,把大衣拿在手里,小脸上毫无血色,身上甚至有点发抖,怯生生地说:龟头,你不会整死我吧?
线条则说:当时确实害怕了。虽然从来不知什么叫害怕,以后也不知什么叫害怕。当时害怕的滋味现在也说不出来,只觉得心里很慌,这感觉有点像六七年我带她爬实验楼,从五楼的一个窗口爬出来,脚踏半尺宽的水泥棱,爬到另一个窗口去。但是爬窗口比这回的感觉好多了。
李先生说:线条把大衣铺在平台上,自己坐上去,说道:你什么话也别说,也别动我,一切让我自己来。好吗?说完了这些话,就坐在那里,半天没有动。
线条说:李先生果然什么都没说。
李先生说:后来线条抬起头来,想朝他做个鬼脸,但是鬼脸僵死在脸上了,好像要哭的样子。她哆嗦着解开制服的扣子,然后把红毛衣从头顶上拽下去。那一刻弄乱了头发,就用手指抚了好半天。她穿了一件格子布衬衣,肩头开了线。然后她就像吃橄榄一样,一个一个地把扣子解开。那时的时间好像会随时停止一样。然后她又把乳罩解下来。那东西是细白布做的,边上缀着花边。然后她把裤子(包括罩裤、毛裤和线裤)一下都脱下来,钻到大衣里,坐在供台上发呆。
线条说:那一回好像我把自己宰了。
线条说:李先生露出那杆大枪来,真是吓死人。
线条还说:最可怕的是第一次,只觉得小肚子上一热,就被他把下身弄得很脏。后来知道,所谓的做爱,原来还没有完。然后只好像要生孩子一样,拼命用手把腿分开。经过了这些事以后,就再也不想爱别人。
-----
### 十六
在似水流年里,有件事叫我日夜不安。在此之前首先要解释一下什么叫似水流年。普鲁斯特写了一本书,谈到自己身上发生过的事。这些事看起来就如一个人中了邪躺在河底,眼看潺潺流水,粼粼流光,落叶,浮木,空玻璃瓶,一样一样从身上流过去。这个书名怎么译,翻译家大费周章。最近的译法是追忆似水年华。听上去普鲁斯特写书时已经死了多时,又诈了尸。而且这也不好念。
照我看普鲁斯特的书,译作《似水流年》就对了。这是个好名字。现在这名字没主,我先要了,将来普鲁斯特来要,我再还给他,我尊敬死掉的老前辈。
似水流年是一个人所有的一切,只有这个东西,才真正归你所有。其余的一切,都是片刻的欢娱和不幸,转眼间就已跑到那似水流年里去了。我所认识的人,都不珍视自己的似水流年。他们甚至不知道,自己还有这么一件东西,所以一个个像丢了魂一样。
现在该谈谈刘老先生的事。要说这事,还有很多背景要谈,首先要谈刘老先生的模样。当时,他还没死,住在我家隔壁。那时他一头白发,红扑扑的脸,满脸傻笑。手持一根藤拐棍,奔走如飞,但是脚下没根,脚腕子是软的,所以有点连滚带爬的意思,如果不在我家吃饭,就上熟人家打秋风,吃到了好菜回来还要吹。他还是一个废话篓子,说起来没完,晚上总要和我爸爸下棋到十二点。照我看是臭棋,要不一晚怎能摆二十盘。
刘老先生内急时,就向厕所狂奔,一边跑一边疯狂地解裤腰带。有一次,一位中年妇女刚从女厕出来,误以为刘老先生是奔她去的,就尖叫了一声,晕了过去。
其次要谈谈地点——矿院。当然,它也可能不是矿院。那时矿院迁到了四川山沟里接着办(毛主席说了,大学还要办),可是矿院的人说,那山沟里有克山病,得了以后心室肥大。主事的军宣队说,你们有思想病,所以心室肥大;我没有思想病,所以不肥大。刚说完这话,他也肥大了。于是大家拔腿跑回了北京,原来的校舍被人占了,大家挤在后面平房里,热热闹闹。我爸我妈也跑回来,我正在京郊插队,也跑了回来,带着小转铃。一家人聚在一起,共享天伦之乐。
谁知乐极生悲,上面派来了一批不肥大的军宣队。通知留守处,所有回京人员,必须回四川上班,不回者停发工资。只有肥大到三期或者老迈无能者例外。后来又来了一条规定,三期和老迈者只发将够糊口的工资,省得你们借钱给没病的人。出这主意的那位首长,后来生了个孩子没屁眼,是我妈动手术给孩子做了个人工肛门。这个故事告诉我们,随着医学的发展,干点缺德事不要紧,生孩子没屁眼可以做人工肛门,怕什么?
然后就该谈时间,那是在不肥大的军宣队来了之后,矿院的人逐渐回到四川去。我爹我娘也回去了。我爸我妈走后两天,刘老先生就死了。在他死之前,矿院后面的小平房里只剩下三个人,其中包括我、小转铃、刘老先生。这对我没什么不好,因为我爸爸妈妈在时不自由,他们不准我和小转铃睡一个床。
-----
### 十七
我始终记着矿院那片平房。那儿原不是住人的地方。一片大楼遮在前面,平房里终日不见阳光。盖那片平房时就没想让里面有阳光,因为它原来是放化学药品的库房。那里没有水,水要到老远的地方去打;也没有电,电也是从很远的地方接来;也没有厕所,拉屎撒尿要去很远的地方,这个地方就是远处的一个公共厕所。曾经有一个时候,矿院的几百号人,就靠一个厕所生活。就因为这个原因,这个厕所非常之脏,完全由屎和尿组成,没有人打扫,因为打扫不过来。
库房里的情况也很坏。这房子隔成了很多间,所有房间的门全朝里,换言之,有一条走廊通向每一个房间。这房子完全不通风。夏天住在里面的人全都顾不上体面。所以,我整天都看见下垂的乳房和大肚皮,走了形的大腿,肿泡眼。当然,库房里也有人身上长得好看点的东西,可是都藏着不让人看见。
除此之外,还有走廊里晾的东西!全是女人的小衣服。这种东西不好晾到外面,只好晾在走廊里自家附近,好像要开展览会。我倒乐意看见年轻姑娘的乳罩裤衩,怎奈不是这种东西。走廊里有床单布的大筒子,还有几条带子连起来的面口袋。假如要猜那是什么东西,十足令人恶心,可又禁不住要猜。最难看的是一种毡鞋垫式的东西,上面还有屎嘎巴似的痕迹。所以我认为一次性的月经棉是很伟大的发明,有时它可以救男人的命。中年妇女在中国是一种自然灾害,这倒不是因为她们不好看(我去过外国,中国的中年妇女比外国中年妇女长得好看一王二注),而是因为她们故意要恶心人!
我听说有人做了个研究,发现大杂院里的孩子学习成绩差,容易学坏,都是因为看见了这些东西,对生活失去了信心。我没有因此学坏,这是因为我已经很坏,我只是因此不太想活了。
在我看来,与其在这种环境里活着,还不如光荣地死去。像贺先生那样跳楼,造成万众瞩目的场面,或者在大家围观中从容就义。每天晚上睡觉之前我都给自己安排一种死法,每种死法都充满了诗意。想到这些死法,我的小和尚就直挺挺。
临刑前的示众场面,血迹斑斑酷烈无比的执行,白马银车的送葬行列,都能引起我的性冲动。在酷刑中勃起,在屠刀下性交,在临终时咒骂和射精,就是我从小盼望的事。这可能是因为小时候,这样的电影看多了(电影里没有性,只有意识形态,性是自己长出来的——王二注)。我爸爸早就发现我有种寻死倾向,他对我很有意见。照他的说法就是:你自己要寻死我不管,可不要连累全家。照我看,这是十足恶心的说法。要是他怕连累,就来谋杀我好啦。
我爸我妈对小转铃没有意见。首先,她是书香门第的女孩子(我爸有门第观念)。其次,她长得很好看。最后,她嘴甜,爸爸妈妈叫个不停。弄得我妈老说:我们真不争气,没生出个好点的孩子给你做女婿(这是挑拨离间一王二注)。小转铃就说:爸爸妈妈,够好的啦。这话像儿媳对婆婆说的吗?可是你见过婆婆非要和媳妇睡一个房间的吗?我爸和我睡在一起,他打呼噜。我提出过这样的意见:你们两位都不老,人说三十如狼四十如虎,五十赛过金钱豹。现在妈是虎,爸爸是金钱豹,你们俩不敦伦,光盯着我们怎么成。最好换换,你们睡一间,我们睡一间。我妈听了笑,我爸要揍我。不管怎么说,他们只管盯死了我们,不让我们干婚前性交的坏事。直到他们回四川,还把我们交给刘老先生看管。
-----
### 十八
刘老先生我早就认识,早到他和贺先生关在一个屋里时,我就见过他。那时我和线条谈恋爱,专拣没人的地方钻,一钻钻上了实验楼的天花板,在顶棚和天花板的空里看见他在下面,和贺先生面对面坐着。贺先生黑着脸坐着,而刘老先生一脸痴笑,侧着脸,口水从另一边滚落下去,他也浑然不知,有时举起手来,用男童声清脆地说:报告!我要上厕所!人家要打他,他就脱下裤子,露出雪白的屁股,爬上桌子,高高地撅起来。刘老先生就是这么个人,似乎不值得认真对待。我爸爸和刘老先生攀交情,我很怀疑是为了借钱。
我爸爸走时已是冬天,别人都回四川去了。他们不仅是因为没有钱,还因为留守处的同志天天来动员。但是谁也不敢到我家里来动员,因为他们都怕我。这班家伙都和我有私仇,我既然还活着,他们就得小心点。我爸爸能坚持到最后,都是因为我的关系。但是我们也有山穷水尽的时候,不但把一切都吃光当净,还卖掉了手表和大衣,甚至卖光了报纸。能借钱的全搬走了,不能搬走的全没有钱。库房里空空荡荡,到了好住的时候,可是我们二老没福消受了!
我爸爸虽然一直看不起我,但是那时多少有点舐犊之情:到了那般年纪,眼看又没什么机会搞事业了(后来他觉得可以搞事业,就重新看不起我甚至嫉妒我——王二注),看见眼前有个一米九的儿子,一个漂亮儿媳——双璧人,有点舍不得离开,这可以理解。但我心里有点犯嘀咕:
你们这么吃光当净,连刘老头的钱也借得净光净,走了以后叫我们怎么过嘛。当然,这话我也没说出来。
我爸爸临走时,要我管刘老先生叫刘爷爷。操他妈,我可折了辈了。他还朝刘老头作揖说:刘老,我儿子交给你,请多多管教。这畜生不学好不要紧,不要把小转铃带坏,人家可是好女孩。刘老先生满口答应。我爸还对小转铃说:铃子,把刘爷爷照顾好。小转铃也满口答应(我爸爸向刘老先生借过不少钱,有拿我们俩抵债的意思)。临了对我说:小子,注意一点,可别再进(监狱——王二注)去。说完这些话他们就走了。矿院派了一辆大卡车,把他们拉到火车站,不让人去送。我的二老一走我就对刘老先生说:老头,你真要管我?老先生说:哪能呢,咱们骗他们的。王二呀,咱们下盘棋,听贺先生说,你下一手好棋!
刘老先生要和我摆棋,我心里好不腻歪。你替我想想看:我和小转铃有好几个月没亲热了。好不容易我爸走了,我妈也走了,你再走出去,我一插门,就是我的天下。虽然大白天里她不会答应干脱裤子的事,起码摸一把是可以的吧。可恨刘老头没这眼力见,我也不好明说,恨死我啦。
我恨刘老先生,不光是因为他延误了我的好事,而且因为他是贪生怕死之辈。他经常找我量血压,一面看着水银柱上下,一面问:高压多少?
没多少,一百八。
可怕可怕。铃子,给我拿药。高压一百八!低压多少?
没多少,一百六。
低压高!不行我得去睡觉。醒了以后再量。
拿到一纸动脉硬化的诊断,就如接到死刑通知书一样。听说吃酸的软化血管,就像孕妇忌口一样。买杏都挑青的。吃酸把胃吃坏了,要不嘴不会臭得像粪缸一样。其实死是那么可怕吗?古今中外的名著中,对死都有达观的论述:
吕布匹夫!死则死矣,何惧也?——《三国演义》,张辽。
死是什么?不就是去和拿破仑、恺撒等大人物共聚一堂吗?——大伟人江奈江·魏尔德。
弟兄们,我认为我死得很痛快。砍死了七个,用长矛刺穿了九个。马蹄踩死了很多人,我也记不清用枪弹打死了多少人。——果戈理·塔拉斯·布尔巴。
(以上引自果氏在该书中描写哥萨克与波兰人交战一场。所有的哥萨克临死都有此壮语,所以波兰人之壮语当为:我被七个人砍死,被九个人刺穿,也不知多少人用枪弹打死了我,否则波兰人不敷分配也!——王二注)
怕死?怕死就不革命!怕死?怕死还叫什么共产党员!——样板戏,英雄人物。
死啦死啦的有!——样板戏,反面人物。
像这类的话过去我抄了两大本。还有好多人在死之前喊出了时代的最强音。“文革”中形式主义流行,只重最后一声,活着喊万岁的太一般,都不算。我在云南住医院,邻床是一个肺癌。他老婆早就关照上啦:他爹,要觉得不行,就喊一声,对我对孩子都好哇。结果那人像抽了风,整夜不停地喊:毛主席万岁!闹得大家都没法睡。直到把院长喊来了,当面说:你已经死了,刚才那一声就算!他才咽了气。想想这些人对死亡的态度,刘老先生真是怕死鬼!
我和刘老先生摆起棋来,说实在的,我看他不起,走了个后手大列手炮局。看来刘老先生打过谱,认得,说一声,呀!你跟我走这样的棋!我轻声说:走走看,你赢了再说不迟。听我这么说,他就慌了。大列手炮就得动硬的,软一点都不成。他一怯,登时稀里哗啦,二十合就被杀死了。他赞一声,好厉害!再摆,摆出来又是大列手。一下午五个大列手,把刘老先生的脑门子都杀紫了!
刘老先生吃了很多大列手炮局。打过谱的都知道,这是杀屎棋的着法。到晚上他又来和我下,真可恨。我早想睡啦,但也不好明说。我当然走列手炮!他一看我又走列手炮,就说:王二,你还会不会别的?我说:什么别的?他说:比方说,屏风马。我说:好说,什么都会。不过你先赢我这列手炮再说。他说:你老走这个棋不好。我说:怪,你还管我走什么棋?刘老先生委委屈屈地走下去,不到十五回合又输了。老头长叹一声道:看来我得拜你为师了。我说:我哪敢教您老人家。刘老先生气跑了。
时隔二十年后,我也到了不惑之年。对刘老先生的棋力我有这样的看法:他的棋并不坏。和我爸下,一晚能下二十盘,那是因为我爸的棋太臭。而和我下时,假如我告诉他:他输棋是因为走了怯着,他可以多支持些时候。我当时能知道这些道理,但是我一心要和小转铃做爱,所以想快点打发他走。假如我能知道他第二天就要死了,真该把做爱的事缓缓,在棋盘上给他点机会。
刘老先生经常拄着拐棍坐在椅子上打瞌睡,口水流在前襟上。
-----
### 十九
我所认识的人里,就数刘老先生馋。当时他和我们搭伙,我们俩也很馋。像这种问题很容易解决(可以多买些肉来煮),但是我们没有钱,刘老先生也只领四十块钱生活费,除了吃还有其他花费,所以这问题也就不好解决了。如前所述,我爸爸他们没走时,就把一切吃光当净,连废报纸都卖了,所以我们除了白菜,也就是一点广东香肠。小转铃想,王二一米九的个子,在性生活里又会有些支出,和我吃的一样多恐怕不够。所以她尽量少吃。但是头天晚上,刘老先生到了餐桌上状如疯魔,运筷如飞,把香肠全夹走了。虽然我从小没受礼教的影响,但是和老头抢东西吃的事还干不出来。所以我只好瘪着半截肚子和小转铃做爱,对刘老先生深为不满。
我现在知道了,刘老先生当时已到了非肉不饱之年,而且他前半生都在吃牛排。清水煮白菜吃下去完全不消化,机米饭吃下去也毫无用处,这样的饭菜是对他肠胃的欺骗。在他生命的最后时刻,他无时无刻不在饥饿中。从另一方面看,刘老先生打了一辈子光棍,也未昉说他有任何风流韵事。到了那个年头,他也不搞什么学问了,一切一切都在嘴上。但当时我对此尚不能体会。我觉得糟老头贪吃简直该死。
现在我还知道刘老先生晚饭吃了一顿熬白菜,到口不到肚,后半夜生生饿醒了。他在家里翻箱倒柜,只找到一块榨菜,就坐在那里以榨菜磨牙,直到天明。天一亮他就奔到菜市场买菜:我们的菜金全在他手里,他买菜我们做,就是这么分工。
那晚上刘老先生走了后,我隔着墙叫小转铃过来,她不肯。我就说:我生气了,我不理你了,我不跟你好了。说到最后一句,她过来了。我和她亲热了一番,她就要走。我让她别走。她说:你妈再三嘱咐,叫我别跟你睡。我都答应了。我知道小转铃答应人的事死也要坚持,但是还是不死心。劝说了一番,她居然同意不走,和我做爱。那时我好不得意:连小转铃都为我破了诺言,可见我的魅力!心里一美,小和尚挺得像铁一样,可是过一会就不美了。小转铃坚持要给我套避孕套,还说:这是你妈嘱咐的!原来我妈让小转铃答应了不和我睡还不放心。她说:少男少女的事我还不知道吗?现在答应,未必能坚持住。记住,一定要套套子,别的措施全靠不住!王二粗心,这事你来做。你可一定要答应我!小转铃最后答应的是给我套套子,不是不和我睡。她要是答应了不和我睡,那晚上只好手淫了。
这件事使我对我的爹娘怀恨在心。什么都管,管到了套套子!我最恨我爸爸,因为肯定是他的主意。我也恨小转铃,因为她不听我的,听我妈的。所以我最后没跟她结婚。
我现在明白了我爸我妈为什么对我的性生活这么操心。当时我是二十三岁,小转铃还未成年。万一走了火,她怀了孕要做人流,还得开介绍信。别的地方开不出来,只有我们公社能开。你替我想想吧,假如发生这样的事,我会怎样。我爸爸妈妈死命看住我,心还不够狠,心狠就该把我阉掉。我现在明白小转铃最爱我,想和她结婚,她却不干了。
那晚上的事我还有些补充,干之前,我编了个小故事,说到我将拉砍头。窗外正给我搭断头台,刽子手在门外磨刀,我脖子上已被面上了红线,脑后的头发已经剃光了。人们把小转铃叫来,给她一个筐,让她在里面垫上干草:“别把脸磕坏了,这可是你的未婚夫!”准备接我的脑袋。而她终于说动了狱卒,让我们在临刑前半小时呆在一起。小转铃哭起来:那你就快点干吧,套子套好了。每听到一种新死法,她就哭起来。当我用到第二个避孕套时(说我将被绞死——王二注),就听见隔壁刘老先生闹,一直闹到第四个避孕套(那回是我被开膛挖心——王二注)。第六个避孕套时他出去了,当时已经天明。那夜一共就是六个,因为刘老先生骚扰,所以那一夜不是很开心。
第二天早上他从外面跑回来敲我的门时,我们俩还没起床。当时我正以极大的兴趣抚摸小转铃的乳房。而小转铃的乳房乃是我一生所见乳房里最好的一对:形状是最完备的半球形,皮肤最洁白,乳头又小又好看。假如世界上有乳房大赛,她绝对有参赛的资格,小转铃对性生活的其他方面毫无兴趣,只对此事有兴趣。通过胸前的爱抚达到高潮,是她享受性乐趣的惟一途径。这种事情不容易搞成,可遇不可求的,那天她兴趣极大(戒欲两个月,贞女如小转铃都会有变化),头枕双臂,双眼紧闭,脸色潮红,马上就要来了。就在这时刘老先生来砸门,乓乓乓,所以去开门时我说了:这老鸡巴头子真该死啦。
打开门以后的第一观感是:这老头像喝了子母河的水,怀孕了。他的肚子上圆下尖,秃顶周围的白毛全竖了起来,脸上露出了蒙娜·丽莎似的微笑。然后他就像分娩一样艰难地从肚皮下拉出一只填鸭来。看到他这样做作,我也不禁惊喜道:这是你偷的吗?他听了大惊道:偷?怎么能偷?偷东西是要判刑的嘛,是买的。我也顾不上向他解释知青的理论“偷吃的不是偷”,也顾不上问他为什么要把鸭子藏在衣服底下,这些都顾不上问。我只问他花了多少钱。他说很便宜,五块钱。我说混账,像你这么花,下半月只好吃屎啦。他听了这话,也觉得不好意思。这时小转铃跑出来说:王二,怎能对刘爷爷这样?快道歉。其实我也不是在乎这五块钱,我只嫌刘老头没出息。你猜他为什么把鸭子藏在怀里?最怕留守处那几个把大门的说他贪嘴。他是回城治病的,怕人家说他没病,一天吃一只大肥鸭。说到底,是“文化革命”里挨了几下打,把胆子打破了。
如果说到挨打,刘老先生简直不能和我相提并论,虽然当时我是那样年轻,而他已经老了。他一生所挨的打,也就是实验楼里那几下,数都能数出来。而我挨的打,绝不可能数清楚。我被专政时,凤师傅把我叫到地下室,屋顶亮着灯,四周站了很多人。他说道:你看好了,我们不打你。工宣队都进校了,我们不打人。然后灯就黑了。等灯再亮时,我从地下爬起来,满头都是血。凤师傅笑着说:我们没打你,对吧。你能说出谁打你了吗?当然我说不出。我说的是:操你妈!然后灯又黑了,在黑暗里挨打,数都没法数。打我的就是留守处那班家伙,和打刘老先生的相同。可是我一点也不怕他们,连姓凤的都管我叫爷爷,我还怕谁?
现在到了不惑之年,我明白了,我挨的打,的确不能和刘老先生相提并论。因为我是那样的人,所以挨的揍里面,有很大自找的成分。刘老先生挨的打,没有一点自找的成分。我还年轻,还有机会讨回账来,可是刘老先生已经到了垂暮之年,再不能翻本,每一下都是白挨。因此刘老先生当然怕得厉害。
刘老先生给自行车打气,对不准气嘴,打不进气,就气急败坏,把自行车推倒。
-----
### 二十
早上刘老先生对我说:昨晚上一宿没睡,就想两件事。一是要吃一只鸭,二是要向王二学棋,搞清楚为什么他的大列手炮我就是下不过。我告诉他说:这路列手炮,乃是一路新变化。公元一九六六年,天下著名的中国象棋名手,包括广东杨官麟、上海何顺安、湖北柳大华、黑龙江王嘉良等等十五人,齐集杭州城。大家说:上海胡荣华太厉害,一连得了好几届冠军,可恶!咱们得算计他一回。都说大列手是臭棋,就从这里编出变化来,让他一辈子也想不到,要他的命!于是想了七七四十九天,编出叶五着来,邪门得厉害!刘老先生听得眉飞色舞,嘴里啧啧咂出声来。小转铃就笑,说,您别听王二臭编。刘老先生说:铃子,你不懂棋,别打岔有这么回事!接着说,后来怎么了?我说:当时大伙约定,一人记一路变化。这路变化只有对胡荣华才能用,自己人之间不能用——铃子,你法收拾鸭子,你听不懂——但是后来谁也没用。胡荣华还是冠军!刘老你懂棋,猜猜为什么?
刘老先生想了半天,才迟迟疑疑地说:刚才你说,何顺安?
我说:着哇!到底是老前辈!那厮是胡荣华同乡,专做奸细(要开是刘老先生一提,我还编不下去了呢——王二注)!比赛头一天,参加杭州棋会的每个棋手,都收到一封信,就写了一句话:车八平五。下署:知名不具!刘老,再猜猜,怎么回事?他拍案叫道:好个胡荣华!真真厉害!何顺安只会一变,其他十四种变化肯定记不全。老胡见不能取胜,就把大列手第一步写下,给人家寄去,人家一看,你知道我们要走列手炮就不敢走了。这是死诸葛惊走活仲达之计!你一定会这十五路变化,难怪下不过你。这大列手好大的来历,教给我吧。我说,教也可,一路一块钱。他说,便宜!
人老了就像小孩一样,此话不虚,刘老先生搬来棋盘,裁好了纸削好了铅笔准备记谱,圆睁怪眼,上下打量我。我心里痒痒,真想在他妥上打一下。才走了一步,刘老先生就高声唱道:车八平——五!举手就记谱。把我笑得打跌,连棋盘都打翻了。
后来我告诉他,没有这路变化,是我编着骗他的,他很不高兴。窮眼之间又高兴了,因为想起了鸭子。人老了就这么天真,事事都在别人意料中。刘老先生对着那可怜的鸭子,出了很多主意要把它分成几部分。一部分香酥,一部分清蒸,一部分煮汤,一部分干炸,那鸭子假如死而有灵,定然要问刘老先生这是为什么。假如我死了,有人拿我的四分之一火葬,四分之一土葬,四分之一天葬,四分之一做木乃伊,我也有此疑问。但是我们的厨房里只有酱油膏,所以只能红烧。刘老先生说,红烧鸭要烧到稀烂才好吃,要烧到天黑。刘老先生把菜金花了个精光,只买了一只鸭。所以中午只好挨饿了。刘老先生说,好饭不怕晚。但是他老去揭那炖鸭子的锅,说是看了也解馋;他那副馋相叫人不敢看。炖鸭的香味飘到屋里,刘老先生坐不住,走来走去,状如疯魔。到晚上还有一白天,他血压又高,肯定挨不过。所以小转铃把我叫出去,给了我一点钱,叫我带他去吃午饭。她还说,她不饿。于是我对刘老先生说:老头,陪我去逛逛。我骑一辆男车,他骑一辆女车,出了矿院的门。然后我对刘老先生说:我还有一点钱,够咱俩去新街口吃一顿羊肉泡馍。只听“夸”的一声,刘老先生连人带车倒在地上。我连忙停车回头,只见刘老先生从地上爬起来,口角流涎,说道:羊——肉泡馍!
我请刘老先生吃了泡馍。因为早上我骂了他,有点内疚。后来他就死掉了。他到底没吃到那只鸭。当天晚上我吃那只鸭,第一口就吐了,小转铃也吃不下,最后倒掉了。鸭子的肉又粘又滑,吃时的感觉实在可怕,我到现在也不爱吃鸭子。
和刘老先生吃泡馍时,我和他谈起了贺先生。老头的脸色登时大变,说道:吃饭,吃饭,别谈这些事,怪害怕的。我说:谈谈何妨,老头,你怕什么?他说:别提死人。我说,真笑话,你这么一大把年纪,还怕死吗?老头很天真地说:谁不怕?我说:怕就能不死吗?老头,你看看你吃的东西,乃是羊杂碎。全是胆固醇。吃下去动脉硬化,离死就不远了。那老头的样子真好看,手都抖起来了。
后来刘老先生大起胆子(他说,回家喝点醋,能解——王二注),告诉我贺先生死之前的事,都不大有趣。贺先生跳楼前只说,告诉我家里人,别太伤心了。没有说过像二十年后又是一条好汉之类的话,甚至也没说:让我儿子给我报仇。那时我想,像刘老先生这种没劲的人,说出的事都没劲。
吃完饭,我叫刘老先生回家,自己在外面遛到天黑方回。我活得很没劲,好像一个没用的人。人到了这步田地,反而会满脑子伟大的想法。
那时我想:假如发生了战争就好了。
活得没劲的人希望发生战争,那是很自然的想法。我们那一代人,都是在对战争的期待中长大的。以我为例,虽然一不怕疼,二不怕死,但是在和平年月里只能挖挖坑,而中国并不缺少挖坑的人。
在和平年月里,生活只是挖坑种粮的竞争。虽然生得人高马大,我却比不过别人。这是因为第一,我不是从小干惯了这种活计;第二,我有腰疼病,干农活没有腰不成。所以我盼望另一种竞争。在战场上,我的英勇会超过一切人。假如做了俘虏,我会偷偷捡块玻璃,把肚子划破,掏出肠子挂到敌人脖子上去。像我这样的兵员一定大为有用。但是不发生战争,我就像刘老先生一样没用。
到现在我明白了,掏出肠子挂到别人脖子上,那是很糟糕的想法。自己活得不痛快,就想和别人打仗。假如大家都这么想,谁也别想过好日子了。而且我也明白,刘老先生怕死,那是再自然也没有的事,他在世上什么都没有了,只有最后的日子。
刘老先生在厕所里撒尿,经常尿到自己裤子上。
-----
### 二十一
刘老先生死了以后我常想,我老了以后,可能和刘老先生一样。
刘老先生活着时,我老在背后说,没骨气的人就是活得长。贺先生和刘老先生比,一个在天上,一个在地下,贺先生大义凛然,从楼上跳下去,刘老先生挨了两下打就把胆子吓破了,但他死时我还是着了急。我从外面回来时,小转铃对我说:去看看刘老先生怎么了,躺在那里打呼噜,叫也不答应。我到他房里一看,他流了很多哈喇子,翻开眼皮一看,眼珠子不动。我转过身来就打小转铃一凿栗:你是死人吗?快找车,送老头上医院!
据小转铃说,刘老先生回来时,骑车骑得飞快,头上见了汗。回来就看鸭子,看到鸭子已经炖烂,摩拳擦掌,口水直流。后来说,感到不舒服,要回去睡,告诉王二,回来给我量血压。王二回来,不量血压,先打小转铃一凿栗:老头都这样了,还等我回来吗?
小转铃也不是省油的灯。我蹬平板三轮送刘老先生上医院,她坐在后面胡搅蛮缠:好哇,你敢打我!我非打回来不可。我说:刘老先生中风了。以后好了,也是歪嘴耷拉眼,你看看他嘴歪了没有。我这么说是要分散她的注意力。到了医院里,把刘老先生推进急诊室。过了一会儿就遮着白布推出来。有个大夫对我说:老先生已经逝世了。我说:你别逗了。我们送来那会儿,刚才还打呼噜呢,你跟别人说去。
可是那大夫说:请您节哀,总共就送进去一个。我登时瞪起眼来,说:胡扯!刚送进去,你还没给他看!他就说:令尊来的时候,呼吸已经停止了。你别揪我领子好不好!快来人!救命哪!
这时来了一群白大褂,可是我只对那个急诊大夫紧追不舍。后来出来一个穿制服的,喝道:不准乱闹!你是哪单位的?我找你们领导!我说:你们他妈的找去!老子是知青!那人一听又缩了回去,知道全是亡命之徒,谁也不敢惹。
刘老先生的事是这么结束的:最后医院的院长出来,请我和小转铃到办公室坐。他说:人总是要死的,这是不可避免的现象。所以有些危重病人,我们救不活。既然对我们的抢救措施有怀疑,做个尸检好吗?我们不但要对病人负责,也要对我们的大夫负责。那时我已经清醒了,说道:我和这死人没关系,你等矿院留守处来找你们吧。说完就和小转铃回家了,路上我和小转铃说,他是叫鸭子馋死的。
当晚我和小转铃在一起,谈到刘老先生的好多事,均属鸡毛蒜皮。比方说:走廊里黑,又堆了很多东西。刘老先生走进来时看不见,就拿藤棍乱打,打得那棍像狗咬过一样。刘老先生贪嘴,拿香肠在煤炉上烤着吃,叫我们碰上啦。他怕我们说他,老脸臊得通红,圆睁怪眼立在那里说:你们谁敢说我一句,我就自杀!不活了!他怎么忽然死了呢?这事真逗哇。我们应该干一回纪念他。
我们想起刘老先生好多事,都很逗,除了一件。有一回我爸爸告诉我:刘老先生并不笨,矿院的老人都知道,此人绝顶的聪明。他是故意装出一副傻样,久而久之弄假成真。所以我就去问他:老头,干吗不要脸面?他马上回答:顾不上了!
后来我下了床,走到窗口去,看见外面黑夜漫漫,星海茫茫。一切和昨夜一样,只是少了一个刘老先生。忽然之间我想到,虽然刘老先生很讨厌,嘴也很臭,但是我一点也不希望他死,我希望他能继续活在世界上。
流年似水,日月如梭。很多事情已经过去了。在七三年元旦回首六七年底,很多事情已经发生,还有一些事将要发生。无论未发生和已发生的事,我都没有说得很清楚。这是因为,在前面的叙述中,略去一条重要线索。这就是在我身上发生了很多变化。有些变化已经完成,有些变化正在发生。前面说过,刘老先生告诉我贺先生的遗言,我听了当时很不以为然。但那天夜里我和小转铃干到一半停下来,走到窗前,想起这话来,觉得很惨。看到外面的星光,想起他脑子前面的烛火,也觉得很惨。刘老先生死了,也很惨。对这些很惨的事,我一点办法也没有,所以觉得很惨。和小转铃说起这些事,她哭了,我也想哭。这是因为,在横死面前无动于衷,不是我的本性。
我说过,在似水流年里,有一些事叫我日夜不安。就是这些事:贺先生死了,死时直挺挺。刘老先生死了,死前想吃一只鸭。我在美国时,我爸爸也死了,死在了书桌上,当时他在写一封信,要和我讨论相对论。虽然死法各异,但每个人身上都有足以让他们再活下去的能量。我真希望他们得到延长生命的机会,继续活下去。我自己也再不想掏出肠子挂在别人脖子上。
-----
### 二十二
流年似水,转眼到了不惑之年。我觉得心情烦闷,因为没碰上顺心的事。而且在我看来,所有的人都在和我装丫挺的。
线条在装丫挺的,每天早上上班之前,必然要在楼道里大呼小叫:
“龟头,别把房子点着!按时吃药!”
回来时又在楼下大叫:“大龟头!快下来接我,看我拿了多少东西!”
李先生也装丫挺的,推开门轰隆轰隆冲下去。这简直是做戏给人看。要不是和他们是朋友,我准推门出去,给他们一个大难堪:李教授、李夫人:你们两口子加起来够九十岁了,还在楼道里过家家,肉麻不肉麻?
我和线条,交情极为深厚。上初二时,到了夏天,我常和线条到玉渊潭去游泳。那时她诧异道:王二,你怎么了?裤衩里藏着擀面杖,不硌吗?
我说:你不懂,因为你不读书。我有本好书,叫《十日谈》,回去借给你看看。重要地方我都夹了条子。你只看“送魔鬼下地狱”和“装马尾巴”两篇就够了。
她说,这些话越听越不明白,最好找个没人的地方脱下来给我看看。于是找到了没人的地方,脱了给她看。线条见了惊道:
王二,你病啦!小鸡鸡肿到这个样子,快上医院看看吧!
当然,我没去医院。晚上把书借给她。线条还书时,满面通红地说:王二,你该不是现在就要把那魔鬼送给我吧?
怎么?你反对?
不是反对。我是说,就是要把它送给我,也得等我大一大。现在硬要送给我,我可能就会死掉啦!
自从我把小和尚给她看过之后,线条的成绩就一落千丈,中英文数理化没一门及格的。因为给别的女孩讲过马尾巴,被老师知道了,操行评语也是极差。要不是我给她打小抄,她早就完蛋了。这线条原是绝顶聪明一个女孩,小学的老师曾预言她要当居里夫人的。他们可没想到,该居里夫人险些连高中也考不上。
线条自己说,上初二初三时,她被一个噩梦魇住了,所以连音乐都考不及格。那时候她觉得除了嫁给王二别无出路,可王二那杆大枪……噩梦醒了以后,嗓子眼都痒痒。
如今我与线条话旧,提起这件事,她就不高兴。说道:王二,你也老大不小的啦,还老提这件事!不怕你不高兴,你那杆枪和我老公的比,只好算个秫秸秆啦。
我马上想到,女人家就是不能做朋友,不说小时候我给她打过多少小抄,考试时作过多少弊,只说后来我在京郊插队,忽然收到一封电报:“需要钱线条”,我就把我的奥米伽手表卖了,换了二百块钱,给她寄去了。
我自己会修表,知道手表的价值。那块奥米伽样子虽老,却是正装货。所有的机件都镀了金,透过镜子一看,满目黄澄澄。全部钻石都是天然的,无一粒人造的。后来到美国,邻居是个修表的老头,懂得机械表,我对他说有过一块这样的表,他就说:你要真有,就给我拿来,五百一千好商量。要是没有,就别胡扯吊我胃口。我血压高,受不了刺激。那块表除了是机械工艺的结晶和收藏的上品,还是我爸爸给我的纪念品。我妈认识联合国救济署的人,所以家里不缺吃的。这块表是我爹拿一袋洋面换的。要是寻常年景,他也买不起这样的表。只为线条一句话,我就把这表卖了,二十年来未曾后悔过,直到她说我是秫秸杆才后悔了!
我对线条说,这辈子再也不交朋友,免得伤心。线条就说:至于的吗?好吧好吧,秫秸秆的话收回了。可是你也太腻歪了。我老公和你是何等的交情,我和小转铃又是好朋友。你迫我干吗?小转铃不是挺好的吗?李先生和我交情好,我也不想甩了小转铃,这些我全知道。怎奈我就是想抱她一抱,难道她不该让我抱一抱?所以我说她装丫挺的。
小转铃也和我装丫挺。每次我要和她做爱,她就拿个中号避孕套给我套上。我的小和尚因此口眼歪斜,面目全非,好像电影上脸套丝裤去行劫的强盗。于是我就应了那些野药的招贴:“(专治)举而不坚、坚而不久!”这也很容易理解。假如一位一米九的宇航员,被套入一米六的宇航服,他也会很快瘫软下去。为此我向小转铃交涉:
“铃子,这套子太小了。”
“没办法。全城药房只有这一种号。”
这医药公司也装丫挺的。我们这个年龄的人都会背这两句诗:“太平世界,环球同此凉热。”可也没听说环球同此长短的。我知道计生委发放避孕药具,各种尺寸全有。小转铃说:
“王二,咱们将就一点吧。你知道不知道,我已经离了婚,是个单身女人?”
其实真去要,也能要来。可是小转铃说:她单位正要评职称。假如人家知道她在和一个尺寸三十七毫米的家伙睡觉,会影响她升副编审。为了副编审,就给男人套中号,是不是装丫挺的?
其实我自己也可以去要,我们单位也在评职称,而且我也是个离了婚的单身男人。我去要三十七毫米的套子,势必影响到我升副教授。所以我也得装丫挺的。
连我妈也在装丫挺的。我让她去搞一些特号,她说:王二呀,我丧了偶,也是单身女人!
我说:妈,您快七十岁了,谁会疑到您。再说,你教授已经到手了,还怕什么,不好意思说是给儿子要,就说要了回家当气球吹。
“呸!实话跟你说,能要来,就是不去要。你还欠我个孙子呢!”我的生活就是这样,到了四十岁,还得装丫挺的。我就像我的小和尚,被装进了中号,头也伸不直。小的时候,我头发有三个旋(三旋打架不要命——王二注),现在只剩了一个,其他的两个歇掉了。往日的勇气,和那两个旋儿一道歇光。反正去日无多,我就和别人一样,凑合着过吧。我现在给本科生上数学分析课。早几年用不了一秒钟的积分题,现在要五分钟才能反应上来,上课时我常常犯木,前言不搭后语,我也知道有学生在背后笑我。有个狂妄的研究生当面对我说:
听说您是软件机器,我看您不像嘛。
我答道:机器?机器头顶上有掉毛的吗?
还有个更狂的研究生说我:
老师,我觉得您讲话老犯重复。
我说:是吗?一张唱片用的时候久了,也会跑针的。
还有一个女研究生对我说:老师,听说您是有名的王铁嘴,真是名不虚传。
这话我倒是爱听。但她在背地里说:这家伙老了以后一定嘚啵嘚啵嘚,讨厌得要命。
我妈跟我说的却是:人就是四十岁时最难过。那时候脑子很清楚,可以发现自己在变老。以后就糊里糊涂,不知老之将至。
叔本华说:人在四十岁之前,过得很慢,过了四十岁,过得就快了。
咱们孔夫子说的是:四十而不惑,五十知天命,六十耳顺,七十从心所欲不逾矩。好像越活越有劲,真美妙呀!可不逾矩以后又是什么?所以我恐怕他是傻高兴了一场。
除了别人说我和说四十岁的话,我还发现自己找不着东西;刚看过一本书,击节赞赏,并推荐给别人看,可是过了几天,忽然发现内容一个字也记不起来了。而过去我是出了名的一目十行、过目不忘。这对我倒是一件好事:以前只恨书不够读,现在倒有无穷阅读的快乐。因为以上种种,在这不惑之年,我却惶惶不可终日,对什么都失去了兴趣,成天想的是要和线条搞婚外恋。更具体地说,是想和她干,当然,也不想干太多。我的身体状况是这样的:一周一次有余,二次勉强。所以干一两次就够了。
我和线条谈这件事,是在矿院学生办的咖啡馆里,说着说着情绪激动,嚷嚷了两次。一次是因为说到秫秸秆,还有一次是谈到李先生和小转铃。我说,他们知道了又有什么呢?小转铃爱我,李先生爱你,一定会原谅我们。现在一想到你,我就会直。所以有一件事可以肯定:假如现在不干,到直不起来时一定会后悔。有海涅的悲歌为证:
在我的记忆之中,
有一朵紫罗兰熠熠生辉。
这轻狂的姑娘!我竟未染指!
妈的,我好不后悔!
我读过的诗里,以此节为最惨。线条说:这儿有我的学生,就站在吧台后面。你要是一定要嚷嚷,咱们到外面去。
我和线条出了咖啡馆,在外面漫步。外面漫天星斗。我马上想起了二十三年前,也是仲夏时节,我和线条半夜里爬到实验楼顶上,看到漫天星斗,不禁口出狂言:假如有一百个王二和一百个线条联手,一定可以震惊世界!
时至今日,我仍不以为这是狂言。两百个一模一样的怪东西聚在一起,在热力学上就是奇迹,震惊世界不足为奇,不震惊世界反而不对头。比方说,二百名歌星联袂义演,一定会震惊世界。一百个左独眼和一百个右独眼一齐出现,也会震惊世界。一百个十七岁的王二和一百个十七岁的线条联手,那就是二百名男女亡命徒,世界安得不惊也?
那天晚上在实验楼顶,除了口出狂言,我还干了点别的事,对女人的内衣有了初步的了解。我的手从她上衣下伸了进去,解开了背后乳罩的挂钩,然后那东西就如护胸甲,松松散散挂在外衣和皮肤之间,以后探手到她胸前,就如轻骑人阵,十分方便。我发觉女人的乳房比其他部分温度要低,摸起来就如两个小苹果一样。除此之外,还说了些疯话:我们生在这亡命的时代,作为两个亡命之徒,是何等的幸福!真应该联手做一番事业!
那天夜里我说道:在这世界上要想成一番事业,非亡命徒不可。比如布鲁诺这厮,在宗教法庭肆虐之时提倡日心说,就是十足的不想活了。他被烧死了。作为一个男人,被烧死不足为奇,但他还熬了无数的酷刑,实在可钦可佩。教廷说,只要你承认曾受魔鬼之诱惑,可以免遭刑罚。砍头、上吊、喝毒药,可随便你挑。临死前还可玩个妓女,嫖资教廷报销。但他选择了一条光荣的荆棘之路,被吊上拷问架去。两根绳子,一根捆手,一根捆脚,咯咯一叫劲,把他活活地拉长,原本一米六〇的身高,放下来时被拉到三米七八。火刑处死之时,刽子手用杈子把他挑到柴堆上,盘成一堆(像蛇一样——王二注),放火烧掉。布鲁诺真好汉也!还有圣女贞德,被捕后,只消承认与魔鬼同谋,就可先吊死再烧。但她不认,选择了被活着烧。年轻姑娘的皮嫩,烧起来最难煞。根据史籍记载,那一天贞德身着亵衣,腰束草绳,被引到火刑柱旁,铁链拦腰束定。这时她发现,柴堆上面还铺了一层油松松针。这种搞法缺德得很。贞德见此,只微微皱眉,对刽子手说:愿上帝宽恕你。这贞德真是个好样的娘们!一点火时,松针上火苗猛蹿上去,把头发眉毛亵衣一燎而光,还烧了一身燎浆大泡!把个挺漂亮的姑娘烧得像癞蛤蟆,还要忍受慢火的烘烤。人家在她对面放了镜子,让她看着自己发泡。只见那泡泡一个个烤到迸裂,浆水飞溅,而贞德在火焰中,双手合十,口中只诵圣母之名,直到烤成北京烤鸭的模样,一句脏话也没骂。烤成烤鸭的模样,她就熟啦,圣母之名也念不出来了。在我看来,贞德比布鲁诺伟大。因为王二可以做布鲁诺,做不了贞德。我要被烤急了,一定要骂操你妈。圣女要是骂出这话,一切就都完了。
我对线条说:老天爷会垂青我们,给咱们安排一场酷刑,到那时你我可要挺住,像个好样的爷们和好样的娘们!
而线条则说:她希望酷刑之前给五分钟上厕所。见到血淋淋的场面她就尿频。
二十三年之后,线条对我说:现在机会到了!我们正可以联手做一番事业。摆在我们面前的正是一场酷刑。我会秃顶,性欲减退,老花眼,胃疼,前列腺肿大尿不出尿来,腿痛,折磨了我一辈子的腰痛变成截瘫,驼背,体重减轻,头脑昏聩,然后死去。而她会乳房下垂,月经停止,因阴道萎缩而受欲火的煎熬。皱纹满脸,头发脱落,成为丑八怪,逐渐死于衰竭。这是老天爷安排的衰老之刑,这也是你一生惟一的机会,挺起腰杆来,证明你是个好样的!
线条所建议的是:在衰老到来之时,做一件值得一做的事,正如布鲁诺提倡日心说,贞德桿卫奥尔良一样。我们要在未来的痛苦面前,毫不畏缩,坚持到神志丧失的时刻:正如布鲁诺被拉成面条之前还在坚持日心说,贞德被烤熟之前口诵圣母之名一样。我们做这件事不是为了别的,只是为了证明自己是好样的!
线条建议的事情相当值得一做。起码我还没想出有什么事比这还值得做。她还说,挑选我来做这件事,不是因为我有做成这事的能力和资格,只是因为少年时期我们是同伴,曾经发誓要联手证明自己是英雄(雌)好汉(娘们)!
线条说,王二年轻时虽像一条好汉,但是到了四十岁,却只想苟安偷欢,不似一条好汉。况且他还没经过任何考验,不能证明他是好汉。而王二则说:他出过斗争差,被人打背了过去。和刘二师傅偷过泔水(偷泔水比偷汽车更需要勇气——王二注),怎么还不算条好汉?如果王二不是条好汉,线条又有什么事情能够证明她是个好汉(娘们)?
线条说道:她爱上了龟头血肿。只此一条就能证明她是个好娘们。如果需要细节的话,那就是:她曾在河南安阳某地的一个破庙里,在寒冷和恐惧中,赤裸裸躺在砖砌的供台上,尽全力分开双腿,把贞操献给了李先生而不要任何保证。她还决定要在一生中倾全力去爱龟头血肿,其实李先生就像任何男人一样毫无可爱之处。只此一条她就可算通过了考验。
线条的这些鬼话,不过是强词夺理罢了,不值得深论。但是这些说法倒可以说明,她为什么到河南去跟了李先生。她说,她是按自己的方式,在光荣的荆棘路上走到如今(参见安徒生《光荣的荆棘路》——王二注)。现在她还提供机会,让我们联手去博取光荣。这个光荣就是把我们的似水流年记叙下来,传诸后世,不论它有多么悲惨,不论这会得罪什么人。
我一直在干这件事,可是线条说,我写的小说中只有好的事,回避了坏的事,不是似水流年的全貌,算不得直笔。如果真的去写似水流年,就必须把一切事都写出来,包括乍看不可置信的事,不敢写出这样的事情,就是媚俗。比如不敢写这样的事,就是媚俗。
现在矿院门口正在建房子,有些地方盖起半截来,有些地方正在挖地基。结果挖出几方黑土来。别的地方是黄土,就那几块是黑的。年轻的工人不能辨认,有人说是煤,有人说是沥青,有人说是窖藏炭化的粮食。为了考据到底是什么,有人还撅了一块,放在嘴里尝尝,到底也没尝出个味道来。这件事情我们就知道:既非煤,也非粮食,是人屙的屎。
在我们的似水流年里见过这样的事:我八岁那年,正逢大跃进,人们打算在一亩地里种出十万斤粮食,这就要用很多的肥料。新鲜的粪便不是肥料,而是毒药,会把庄稼活活烧死,所以他们就在操场上挖了很多极深的坑,一个个像井一样,把新鲜大輿倒了进去。因为土壤里有甲烷菌存在,那些粪就发起酵来,嘟嘟地冒泡。我小的时候,曾立在坑旁,划着火柴扔进去,粪面上就泛起了蓝幽幽的火光。
在我小时,觉得这蓝幽幽的火十分神秘。在漫漫黑夜里,几乎对之顶礼膜拜,完全忘记了它是从大便中冒出来的。
不幸的是,这挖坑倒粪的事难以为继,因为当粪发酵之后,人们才发现很难把它弄出来:舀之太稠,挖之太稀,从坑边去掏又难以下手,完全不似倒下去时那么容易。何况那些坑深不可测,万一失足掉下去,很少有生还的机会。所以那些坑,连同宝贵的屎,就一齐被放弃。
过了一些时候,坑面上罩上了浮土,长起了青草,与地面齐,就成了极可怕的陷阱。我的一个同伴踩了上去,惨遭灭顶之灾。这就是似水流年中的一件事。
线条说,此事还不算稀奇,下干校时听说过另一件事。在同一个时期,当地的干部认为,挖坑发酵太慢了。为了让大異快速成熟,他们让家家户户在开饭前,先用自家的锅煮一锅屎(参见北京大学社会学系沈关宝博士论文——王二注)。一边煮,一边用勺子搅匀,和煮肉的做法是一样的。还要把柴灰撒进锅里,好像加入作料一样。煮到后来,厨房里完全是这种味儿。有些人被熏糊涂了,以为这种东西可以吃,就把它盛进碗里,吃了下去。
这个故事是线条讲的,我听出前面是实(有沈博士论文为证一王二注),后面两句是胡扯,这种浪漫主义要不得。但是煮屎的事则绝不可少,因为它是似水流年中的一条线索。它说明有过一个时候,所有的人都要当傻×(线条所谓silly cunt一王二注),除此之外,别无选择。当时我们还小,未到能做出选择的年纪。
而当我们长大之时,就有了两种选择:当傻×或是当亡命之徒。我们的选择是不当傻×,要做亡命之徒。
要记做亡命之徒的事,那就太多了。我们的很多同伴死了。死得连个屁都不值。比方说,在云南时,有些朋友想着要解救天下三分之二的受苦人,越境去当游击队,结果被人打死了。这种死法真叫惨不忍睹。想想吧:
一、天下三分之二的受苦人,你知道他们是谁吗?
二、天下三分之二的受苦人,你知道他们受的什么苦吗?
三、正如毛主席所说,世上没有无缘无故的爱,也没有无缘无故的恨。你什么都不知道就为他们而死,不觉得有点肉麻吗?
死掉的人里有我的朋友。他们的本意是要做亡命徒,结果做成了傻×。这样的故事太悲惨了,我不忍心写出来。假如要求直笔来写似水流年,我就已经犯了矫饰之罪。
我还知道很多更悲惨的事——在我看来,人生最大的悲哀,在于受愚弄。这些悲惨的故事还写得完吗?
线条说:就凭你这平凡、没长性、已经歇顶的脑袋瓜,还想在其他方面给人类提供一点什么智慧吗?假如你写了矿院的黑土之来历,别人就会知道它是屎,不会吃进嘴里,这不是一点切实的贡献吗?难道你不该感谢上帝赐给了你一点语言才能,使你能够写出一点真实,而不完全是傻×话吗?
如果决定这样去写似水流年,倒不患没得写,只怕写不过来。这需要一支博大精深的史笔,或者很多支笔。我上哪儿找这么一支笔?上哪儿去找这么多人?就算找到了很多同伴,我也必须全身心投人,在衰老之下死亡之前不停地写。这样我就有机会在上天所赐的衰老之刑面前,挺起腰杆,证明我是个好样的,但要作这个决定,我还需要一点时间。
-----
1992年3月由香港繁荣出版社出版的王小波小说集《王二风流史》收本篇作品。——编者
[[事件选择与信息扣押 - 知乎|https://zhuanlan.zhihu.com/p/22241283]]
==============
-----
该文章在上一篇中说要稍微提及一下关于结构的技巧,其实实际上牵扯的也就是在结构之中的一些选择问题,即情节选择及排布。并且在其中的一种常用技巧便是“信息扣押”,也就合在一起来讨论一下。
## 事件选择
其实所谓事件选择,不过就是在我们已有的故事之中选择出要写的部分,在要写的部分中选择出着重的场次。其实这也就是在结构之中最麻烦的地方,我们往往会觉得这里不错,那里也不错,就很难寻找到真正的合适的场次。
其实就算是说合适的场次或者说事件,在写作的初期,我建议选择相对激烈的场次作为主要的写作点。这种方式我们往往更容易写的吸引人,当激烈的场次不断出现,读者或者观众的注意力也自然就会被其吸引。这也就是常见的架构剧选择方式,而实际上当创作到达一定的程度之后,我们往往会选择更能够表现人物或者表现主题的场次来进行描写。可能这些场次既不激烈也不“好玩”,但是这样的场次却具有极佳的戏剧张力。
我们不妨举一个简单的例子。
A决定抢劫一家银行,他想到了绝佳的手段和方式。**
- 我们可以选择他抢劫银行的过程来写,这样一个惊心动魄的过程往往可以很好的吸引读者的注意力,并且只要具有一定的写作技术就可以将其写的十分的精彩。**
- 但是我们也可以换一种方式。我如果选择将A放置到一个咖啡馆之中,旁边坐着两个大谈特谈银行劫案的记者。A只是喝咖啡,并且静静的听记者们讲述自己的故事,拿出连号的崭新的钞票付款。
- 甚至还可以再换一种方式。这个银行劫案已经成为了一个历史事件,而A也已经成为一个潦倒的老头,在一个破破烂烂的小酒吧里面,A开始大谈特谈自己曾经的劫案过程,而只能引起其他人的哄笑。
这都是对于这样一个劫案的叙述方式,甚至还可以串联起来,无非是至于我们到底要写哪一段而已。当然实际上这都是比较平凡而且简单的写作方式,也是比较好用的方式。当然我还可以延伸出更多的方式。
A决定抢劫一家银行,约了一个朋友私下里讨论方案,并且决定去做,可是他们并没有,他们讨论的内容也乱七八糟,并且问一个过路人方案是不是可行,过路人甚至也加入其中进行讨论。最终没有结果,就约好第二天继续,可是第二天一如第一天。*
这是一种偏荒诞的写法,要够准确也要够无趣,总的来说不好写,而且需要写的足够吸引人。
那么其实这都是对于叙事角度不同的区别,而且任何一种也都可以完成一个故事。优劣之分不仅仅局限在这些选择之中,还会包括内部的事件选择,和基本的写作技巧。我们以第一种为例,如果我们决定走激烈的场面为主的叙事方式,在具体的事件选择之中我们应该更多的选择劫案过程中临近危险,并且A成功克服的部分,而不是事前的策划或者事后的销赃。我们应该着重选择A在实施抢劫中的狡猾和智慧。这样的过程是吸引人也是相对更符合需求的。
如果我们选择第二种的话,我们则需要选择更为表现A冷静的智慧,也要表现A的骄傲。而不是在过程中的行动。A可能故意给自己制造麻烦,并且以此为乐趣。这一个部分应该以人物为重点的展现。
第三种,我们则应该表现人物自身的颓败,过往智慧于时间的无力感。这样我们则应该更多的选择人物于时代的不和谐的部分,要抓住人物希望在时间长河中试图遗留下些许印记的行动和事件。要将人物压制住,静静看人物的反抗,他只要一抬头就给他一巴掌。
最后一种,我们选择是荒诞,在内部事件里面我们需要更多的展示出人物行动的无意义,无趣和荒诞性。荒诞性实际上往往呈现出间离化的效果。准确的说荒诞性诞生于德国布莱希特的间离化理论之后。要注意叙事的无意义呈现和对于幻觉的讽刺。
这里说这么多实际上是希望表述一件事——事件的选择要符合我们的写作需求,符合故事的选择角度。而内部的具体事件选择和建立从某种角度上来说应该顺应“自然承载”的要求,即“必然或可然”发生的,而不是“机械”的,要求发生的。**
我看到之前也有人问及如何避免写作之中的“偶然和巧合”。实际上我们完全不需要去避免“偶然和巧合”更重要的是如何合理的使用它们。这里需要提及的就是“必然和可然”,我们需要让所谓的“巧合”都成为“可然”的部分,而不是“机械”的部分。“巧合”应该是具有严密的、逻辑上的可能性的,甚至许多的“巧合”实际上是必然的。其内部是应该具有统一的逻辑的,是严密的自然而然会发生的。
同时当我们让所有的“偶然和巧合”具有产生足够的作用的时候,这种“偶然和巧合”不仅仅是不堪入目的、僵硬的技巧了。就如一个人若是出门偶然踩了一泡狗屎,就应该借着这个“巧合”产生足够作用,而不是仅仅因为“臭”遭遇一些小问题甚至马上就解决了。我们将这种巧合合理化一下看看能产生什么效果:
**A出门走着,一个花盆掉下来,A为了躲花盆,一下子踩到了狗屎上。而花盆则是因为B在跟男友C吵架的时候扔下来的,听到A的破口大骂,而让B跑下来,两个人见到了面。A虽然没有受伤,但是别因为要去面试,狗屎也让他很尴尬。B为了赔偿A希望男友C借给A一双鞋,但是因为吵架的缘故,C拒绝了。于是B为了道歉塞了一些钱给A,让A去买一双鞋子作为赔偿。而这又引起了C的不满,于是B和C继续争吵。A离开,却没有去买鞋,留下了钱,因为时间不足回家换鞋,就找了一个水龙头冲洗鞋子。稍晚到达面试现场的A被排到了后面,面试时却依旧被面试官嗅出了臭味,并且问及了A很刁钻的问题,A幽默的告诉考官,自己踩了狗屎运,冲走了狗屎留下了运。面试完之后的A走在回去的路上,发现了B。A跟B打招呼,表示自己感谢B,并在预备把钱还给B的时候,发现B的宠物狗在老地方又拉了一泡狗屎。
(好吧,这一段只是想解释一下“偶然”,所以写的超烂,没有矛盾引发什么的,而且反复利用“臭”来做事件,本来打算改来着,但是懒癌发作,大家自己get一下好了)
要好好的把“狗屎”用足,让偶然引出必然,让必然成就偶然。
## 信息扣押
其实信息扣押这个事情也不复杂,从字面意思来理解,把信息扣押住隐藏起来,并且以此来引发悬念的效果**。这是一个常用的技巧,不过我可以稍微解释一下,信息扣押很多人用不好的原因是不知道该扣押什么,以及该怎么扣押。这涉及“发现和突转”这个后面再说。
信息扣押我们需要搞清楚一个很重的问题!**扣押谁的信息**!
我们可以把信息扣押分开来分成一下三种:
- **人物知道,但是观众不知道的。
**
- **观众知道,但是人物不知道的。
**
- **观众和人物都不知道的。****
这是常见的信息扣押区别,这三种方式的使用方式还是很有区别的。
第一种,人物知道但是观众不知道的。这种方式就是最简单的悬念营造,没什么特别的。观众不知道某件事情的隐情,到了后半部分突然揭示,让观众恍然大悟一些事件的手法。网剧《毛骗》中大部分就是这种手法,常用而且好用。但是想要用的高明和巧妙也并不容易。
第二种,观众知道但是人物不知道的。这种方式其实目的是营造紧张感,观众会因为期待某些事情的发生而紧张。常见的方式就是遗落物品,但是人物并不清楚,可是这个物品后面必然会引起一些问题。或者观众知道了B是坏人,但是B却装作是好人的样子接近主角,陷害主角,会引起观众的紧张。
第三种,观众和人物都不知道的。这种方式其实就是营造误会,矛盾的常见方式,大家都不知道的事情被隐藏了,观众和人物一起逐渐揭开这个被隐藏的信息。实际上是可以做到一种引导作用的,用的好的还可以引导观众的情绪。这也是一种可以直接作用到结构上的信息扣押方式。这种信息的揭开往往居于结构中的关节点甚至是高潮部分,比如突然解释两个人的血缘关系,比如解释一个宝藏的负面意义等等。但是这种扣押下的信息是需要人物行动的,如果人物的行动不刺激这个被扣押的信息,就自然的揭开说明使用十分不成功。
然后我们要提及一下信息扣押的内容**。
可以信息扣押的内容很多,比如一个小道具,比如一段历史往事,比如一个阴谋的细节或者真正目的,又或者一段人物关系之类。但是到了具体的内容之中如何扣押,如何排布也是个问题。实际上这个论题也比较大,值得写一篇论文,但是你们都知道我怎么可能写论文呢。所以就大概说一下常见原则。
- 扣押关键信息,所有扣押下的信息都应该是关键的,可以推动事件发展的,并且有积极作用力且能引发矛盾或者误会的。
- 扣押的关键信息可以是不起眼的,不经意的,但是一定是有作用的,有意义的。
- 扣押人物关系,扣押的人物关系都应该是十分重要的,并且可能是持续引发矛盾的,而且当被扣押的人物关系被揭开的时候必然会引起一次突转。
- 不要将不重要的信息扣押,应该直接删掉。
- 扣押下的信息必须要得到揭示,并且揭示的场面应该是紧张的,无论是场面的激烈还是人物内心或者关系上的紧张。且揭示的时候必然要引发事件,要作用的主要人物身上。
- 在某些情况下,可以扣押虚假信息,但是这需要不停地加强夸张作用和幻觉感,或者加强荒诞感来促使人物为虚假信息行动。(比较少见,而且比较难处理)往往这种方式应当让观众知道扣押的信息是虚假的,如果观众也不知道的情况下,那么“揭示信息”的意义需要比“信息”的意义要重要。
诺兰拍的第一部电影《尾随》,可以观摩学习信息扣押的技术。
总的来说,无论事件选择或者其中的技巧都是有路可寻的,后面我会回到结构正题部分。
以上。
——————————————————————————————————————————
事实的运用-老舍
========================
事实的运用-[[老舍]]
-----
小说中的人与事是相互为用的。人物领导着事实前进是偏重人格与心理的描写,事实操纵着人物是注重故事的惊奇与趣味。因灵感而设计,重人或重事,必先决定,以免忽此忽彼。中心既定,若以人物为主,须知人物之所思所作均由个人身世而决定;反之,以事实为主,须注意人心在事实下如何反应。前者使事实由人心辐射出,后者使事实压迫着个人。若是,故事才会是心灵与事实的循环运动。事实是死的,没有人在里面不会有生气。最怕事实层出不穷,而全无联络,没有中心。一些零乱的事实不能成为小说。
大概我们平常看事,总以为它们是平面的,看过去就算了,此乃读新闻纸的习惯与态度。欲作个小说家,须把事实看成有宽广厚的东西,如律师之辩护,要把犯人在作案时的一切情感与刺激都引为免罪或减罪的证据。一点风一点雨也是与人物有关系的,即使此风此雨不足帮助事实的发展,亦至少对人物的心感有关。事实无所谓好坏,我们应拿它作人格的试金石。没有事情,人格不能显明;说一人勇敢,须在放炸弹时试试他。抓住人物与事实相关的那点趣味与意义,即见人生的哲理。在平凡的事中看出意义,是最要紧的。把事实只当作事实看,那么见了妓女便只见了争风吃醋,或虚情假义,如蝴蝶鸳鸯派作品中所报告者。由妓女的虚情假义而看到社会的罪恶,便深进了一层;妓女的狡猾应由整个社会负责任,这便有了些意义。事实的新奇要在其次,第一须看出个中的深义。
我们若能这样看事实并找事实,就不怕事实不集中,因为我们已捉到事实的真义,自然会去合适的裁剪或补充。我们也不怕事实虚空了,因为这些事实有人在其中。不集中与空虚是两大弊病,必须避免。
小说,我们要记住了,是感情的纪录,不是事实的重述。我们应先看出事实中的真意义,这是我们所要传达的思想;而后,把在此意义下的人与事都赋与一些感情,使事实成为爱,恶,仇恨,等等的结果或引导物;小说中的思想是要带着感情说出的。“快乐”,巴尔扎克说,“是没有历史的,‘他们很快乐’一语是爱情小说的收结。”
在古代与中古的故事里,对于感情的表现是比较微弱的,设若HenryJames(亨利·詹姆斯)的作品而放在古人们手里,也许只用“过了十年”一语便都包括了;他的作品总是在特别的一点感情下看一些小事实,不厌其细琐与平凡,只要写出由某件事所激起的感情如何。康拉德的小说中有许多新奇的事实,但是他决不为新奇而表现它们,他是要述说由事实所引起的感情,所以那些事实不止新奇,也使人感到亲切有趣。小说,十之八九,是到了后半便松懈了。为什么?多半是因为事实已不能再是感情的刺激与产物。一旦失去这个,故事便失去活跃的力量,而露出勉强堆砌的痕迹来。一下笔时不十分用力,以便有余力贯彻全体,不过是消极的办法;设若始终拿事实为感情起落的刺激物,便不怕有松懈的毛病了。康拉德之所以能忽前忽后的述说,就是因为他先决定好了所要传达的感情为何,故事的秩序虽颠倒杂陈亦不显着混乱了。
所谓事实发展的关键,逗宕与顶点者,便是感情的冲突、波浪与结束。这是个自然的步骤。假若我们没有深厚的感情,而空泛的逗宕,适足以惹人讨厌,如八股文之起承转合然。ArloBates(阿洛·贝茨)说:“我不相信小说构成的死规则。工作的方法必随个人的性情而异。我自己的办法据我看是最逻辑的,可是我知道这是每一写家自决的问题。以我自己说,我以为小说的大体有定好的必要,而且在未动手之前就知道结局是更要紧的。”
这段话使我们放胆去运用事实。实事是事实,是死的,怎样运用它是我们自己的事。Arnold Bennett(阿诺尔特·贝内特)在巴黎的一个饭馆里,看见一老妇,她的举止非常的可笑。他就设想她曾经有过美好的青春,由少艾而肥老,其间经过许多细小的不停的变化。于是他便决定写那《老妇们的故事》。但这本书当开始动笔的时候,主角可已不是那个老妇,因为她太老了,不足以惹起同情。杜思妥益夫斯基的《罪与罚》是根据他自己的经验,但把故事放在都市里,因为都市生活的不安与犯罪空气的浓厚,更适宜于此题旨的表现。这样看,我们得到事实是随时的事,我们用什么事实是判断了许多事实之后的结果。真人真事不过是个起点,是个跳板。我们不仗着事实本身的好坏,而是仗着我们怎样去判断事实。这就是说,小说一开首的某件事实,已经是我们判断过的;在小说中,大家所见到的是事实的逐渐的发展,其实在作者心中,小说中的第一件事与第末一件事同样是预先决定好了的。自然,谁也不会把一部小说的每一段都预先想好,只等动笔一写,象填表格似的,不会。写出来才是作品,想得怎样高明不算一回事。但是,我们确能在写第一件事的时候,已经预备好末一件事,而且并不很难,因为即使我们不准知道那件是什么事,我们总会知道那是件什么样的事——我们所要传达的与激起的情绪是什么便替我们决定,替我们判断,所需要的是什么事。明乎此,在下笔的时候便能准确;我们要的是“怒”,便不会上手就去打哈哈。及至写完了,想改正,我们也知道了怎去改正——加强我们所要激起的感情,删削那阻碍或破坏此种情绪的激发的。
由事实中求得意义,予以解释,而后把此意义与解释在情绪的激动下写出来;这样,我们才敢以事实为生材料,不论是极平凡的,还是极惊奇的,都有经过锻炼的必要。我们最怕教事实给管束住:看见或听见一件奇事,我们想这必是好材料,而愿把它写出来。这有两个危险,第一是写了一堆东西,而毫无意义;第二是只顾了写事而忘记了去创造人。反之,我们知道材料是需要我们去锻炼炮制的,我们才敢大胆的自由的去运用它们,使它们成为我们手中的东西。小说中的事实所以能使人感到艺术的味道就是因为每一事实所给的效果与感力都是整个作品所要给的效果与感力的一部分,仿佛每一件事都是完全由作者调动好了的,什么事在他手下都能活动起来。硬插入一段事实,不管它本身是多么有趣,必定妨碍全体的整美。平匀是最不易作到的。要平匀,我们必须依着所要激动的情绪制造出一种空气,把一切材料都包围起来。我们所要的是“怒”,那么便可以利用声音、光线、味道,种种去包围那些材料,使它们都在这种声音、光线、味道中有了活力,有了作用,有了感力。这样,我们才能使作品各部分平匀的供给刺激,全体象一气呵成的,在最后达到“怒”的高潮。所谓小说中的逗宕便是在物质上为逻辑的排列,在精神上是情绪的盘旋回荡。小说是些图画,都用感情联串起来。图画的鲜明或暗淡,或一明一暗,都凭所要激起的情感而决定。千峰万壑,色彩各异,有明有暗,有远有近,有高有低,但是在秋天,它们便都有秋的景色,连花草也是秋花秋草。小说的事实如千峰万壑,其中主要的感情便是季节的景色。
但是,我们千万莫取巧,去用小巧的手段引起虚浮的感情。电影片中每每用雷声闪光引起恐怖,可是我们并不受多少感动,而有时反觉得可笑可厌。暗示是个好方法,它能调剂写法,使不至处处都是强烈的描画,通体只有色而无影。它也能使描写显着细腻,比直接述说还更有力。一个小孩,当故意恐吓人的时候,也会想到一种比直陈事实更有力的方法——不说出什么事,而给一点暗示。他不说屋中有鬼,而说有两只红眼睛。小说中的暗示,给人一些希冀,使人动心。说屋中有些血迹,比直说那里杀了人更多些声势;说某人的衣服上有油污,比直说他不干净强。暗示既使人希冀,又使人与作者共同去猜想,分担了些故事发展的预测。但是这不可用得过火了,虚张声势而使读者受骗是不应该的。
双帽先生-艾丽丝·门罗
========================
!双帽先生-[[艾丽丝·门罗]]
-----
“外面那是你弟弟吗?”戴维森问,“他要干吗?”
科林走到窗口,看看罗斯在做什么。很正常嘛。罗斯在用长柄剪刀修剪人行道边的草地,人行道一直通到学校大门口。他干得不紧不慢,看样子还挺投入的。
“他在干吗?”戴维森问。
罗斯戴了两顶帽子。一顶是去年夏天从饲料库找来的绿白相间的尖顶帽,上面叠着另一顶,是他们的妈妈在花园干活时戴的粉色旧草帽。
“我真不知道。”科林说。戴维森一准会以为他是在装聋作哑吧。
“你是问他干吗戴两顶帽子?我也不知道啊。我真不知道。没准他自己忘了吧。”
这是在学校前部的办公室里,正值星期五下午的上课时间,秘书们都俯在桌子上,耳朵却都支棱着。科林在上体操课—他刚进办公室,想看看半小时前请病假的一个男孩怎么样了—没料到撞上在这里溜达的戴维森。要他为罗斯的事做解释,这真叫他猝不及防。
“他是个健忘的人吗?”校长问。
“也不算特别健忘吧。”
“或许是为了搞笑。”
科林没回答。
“我不是不懂幽默,可你不能在孩子们面前搞笑啊。你知道他们是怎么回事。就算不给他们什么理由,他们也找得到足够的东西来寻开心的。任何一件小事,他们都能用作分散注意力的理由,然后你就晓得厉害了。”
“你想要我出去跟他谈谈吗?”科林问。
“暂时不要。没准已经有两教室人在盯着他了,那只会让他们更兴奋。非得有谁去跟他说说的话,可以让伯克斯先生去。实际上,伯克斯先生已经跟我提过他了。”
库尼·伯克斯是学校的看门人,他雇用了罗斯来清理春季草坪。
“哦,都说了什么?”科林问。
“他说你弟弟在时间上有点自作主张。”
“他完成自己的工作了吗?”
“并不是说他没有。”戴维森冲科林做出一个抿紧嘴唇、打发人的微笑,这笑被人们争相模仿过。“只是说他有点倾向于自行其是。”
科林和罗斯模样很像,跟他们的爸爸一样是高个子,金发白肤则来自他们的妈妈。科林是运动员的体态,表情害羞而严肃。罗斯尽管比他小,腰部却已发福,整个人看起来松垮多了。他的眼神偷偷摸摸,却又天真无邪。
罗斯并不迟钝,他一直和同龄人一起上学。他妈妈说他是个机械天才,不过没别人会如此抬举他。
“怎么说?罗斯习惯早上起床了吗?他有闹钟吗?”科林问他妈。
“能雇到他是他们的运气呢。”西尔维娅说。
科林之前并不知道能否在家里碰到她。她在医院做三班倒的护士助理,不上班时经常会出门。她有很多朋友和事情要应付。
“而你在家碰到我,也够运气的,”她说,“我这周和下周都上早班,不过下班后通常要去埃迪家,帮他做点清洁。”
埃迪是西尔维娅的男朋友,一个衣冠楚楚的七十岁老头,做过两次鳏夫了,膝下无子,很有钱。他是个退休的修车厂老板和汽车交易商,本该出得起钱雇个打扫房子的人才对。再说,西尔维娅对于清洁活儿又懂得多少呢?整个去年夏天,她都任由冬天的塑料护板继续钉在前窗上,省得回头还要再钉上。科林的老婆格伦娜说,这感觉就像戴着副模糊的眼镜—她可受不了这个。而房子本身—西尔维娅、罗斯和科林一直住着的这幢覆盖着沥青的房子—塞满了家具和破烂,有的房间已沦为走道。大多数地方都覆满杂志,报纸,塑料袋和纸袋,宣传目录,推销传单,关于一度有过又早已结束的打折活动的宣传单子,其中一些单子宣传的公司已经倒闭了,产品已退出市场。在任何一个烟灰缸或者装饰碟里,你都有可能发现一两枚扣子,几把钥匙,剪下来的可以便宜十分钱的优惠券,一个耳环,一个仍裹在塑料包里的感冒胶囊,一片碎成粉末的维生素药片,一个睫毛刷,一个破晾衣夹。西尔维娅的碗橱里塞满各种清洁液和上光剂—并非商店里通常能买到的那些,而是些据称有奇效的产品,都是在各种活动上签字认购的。化妆品、盆盆罐罐、烤箱用具、各种塑料碗—为了给签字认购的所有这些东西买单,她总是处在破产状态。她喜欢举办和参加这类活动,新娘送礼会和欢迎新生儿派对,还有给离开医院的同事举办的告别聚会。在这儿,这些混乱不堪的房间里,她仅凭一己之力东拼西凑,兴致勃勃地散发出了许多好客之情。
她把水壶里的水倒进杯中的咖啡粉,杯子只是在水槽里稍微冲了冲。
“水开了吗?”
“差不多啦。”
她从塑料袋里抖出一些粉色白色的软糖饼干。
“我告诉埃迪我下午要休息。他好像觉得我差不多属于他了似的。”
“真受不了,”科林说。
关于她的男朋友们,他通常采用一种淡淡的批评口吻。
西尔维娅是一个矮个子、大脑袋的女人—脑袋因为毛茸茸的灰白头发,显得尤其硕大—臀部和肩膀都很宽阔。她的一个男朋友过去常说她看起来像一头小象,她视之为一种爱怜之语—在开头那阵子。科林觉得她的体型,她那又柔又软的粉色肌肤,她宽阔的脸,那几近于无的眉毛下面清澈湛蓝的双眼,她那急切的没心没肺的微笑,都显得既笨拙又讨喜。不过也有点让人受不了。
罗斯是少有的几个能让她脸色变得凝重的话题之一。再有,就是她男朋友们的索求和古怪之处了,一旦他们开始失去她的欢心。
埃迪也快失去她的欢心了吗?
西尔维娅说:“我一直在跟他说,他的占有欲太他妈的强了。”然后她给科林讲了一个医院里流传的笑话,关于一个黑人和一个白人在小便池前的故事。
“要是你上早班,”科林说,“你怎么知道罗斯几点起床呢?”
“有人告罗斯的状了,是吗?”
“嗯,他们只是说他在时间上有点自作主张。”
“他们会明白的。要是他们有什么机械或者电器坏掉的话,他们会很庆幸有罗斯在的。罗斯的脑袋像你的一样够用,只是它使力的方向不同。”
“这个我没意见,”科林说,“不过他的工作是对付地面。”
格伦娜说过,西尔维娅之所以宣称罗斯是个天才—除了他确实挺擅长对付机器之外—是因为他具有天才的缺陷。他心不在焉,邋里邋遢。他总是引人关注。他有点怪异,那正是天才该有的样子。不过单凭这个,格伦娜说,并不怎么让人信服呐。
她总是补充道:“不过,我喜欢罗斯。你没办法不喜欢他。我喜欢他和你妈。我也很喜欢你妈妈的。”科林相信她确实喜欢罗斯。至于她是不是喜欢他妈,他不能肯定。
“我只有得到邀请才会去你家,科林,”他妈说过,“那是你家,但也是格伦娜的家。不管怎样,罗斯在那里受到欢迎,我也很高兴了。”
“我今天去办公室了,”科林说,“戴维森在那里往窗外看来着。”他不知道自己会不会跟他妈妈提帽子的事。和平时一样,他想让她对罗斯有点紧张,但又不要过于紧张。罗斯独自一人在学校的草地上,用电动剪刀干活,一顶粉色阔檐草帽压在那顶尖顶帽上,这对科林而言是某种新情况,某种新烦恼。他以前见过罗斯奇装异服的样子—有一次是在超市里戴着西尔维娅的金色假发。比起今天的装束,那次似乎经过了更精心的策划,比较像一个针对明确的目标观众开的玩笑。今天也一样,罗斯有可能针对的是窗后的所有孩子们,还有老师、打字员、戴维森和任何开车路过的人。不过又不全是为了他们。罗斯今天的表现中,有什么东西表明,他的目标观众扩展了,同时也隐退了—它囊括了整个镇,整个世界,而罗斯对它几乎已经漠然了。这是个迹象,科林想。他说不准是关于什么的—只是一个迹象,表明罗斯已经在罗斯的道路上愈行愈远。
西尔维娅似乎对此并不在意。她很紧张,但不是因为这个。
“我的帽子啊。他肯定会弄丢它的。我真要给他点厉害瞧瞧。我要好好教训他一通。那顶帽子看起来或许没什么,可我真的很在乎它啊。”
罗斯对格伦娜说的第一句话是:“你知道你唯一的问题在哪里吗?”
“什么?”格伦娜警觉地问。她是个高挑、瘦弱的女孩,深色卷发,白皮肤,非常浅的蓝眼睛,经常习惯性地咬住下唇,这让她显得惆怅、忧心忡忡。她是那类经常穿淡蓝色衣服(她现在正穿着件淡蓝色的毛茸茸的毛衣),脖子上挂条细链,上面有一个十字架、心形或者名字坠儿的女孩。(格伦娜戴的坠儿是她自己的名字,因为人们经常拼错它。)
“你唯一的问题,”罗斯一边咀嚼,一边点着头说,“就在于没让我先找到你!”
悬着的心落下了。他们全都乐了。这是格伦娜头一回到西尔维娅家吃晚饭。西尔维娅、科林和格伦娜吃外卖中餐,西尔维娅在硬纸盒边摆了一叠盘子、刀叉,甚至还有纸餐巾。而罗斯吃的是一个比萨,西尔维娅专门给他订的,他不喜欢中餐。
格伦娜提议罗斯晚上跟他们开车兜风去,他接受了。他们三个坐在科林的车顶喝啤酒,格伦娜坐中间。
这变成了一则家族笑话。要是格伦娜先遇到罗斯,会发生什么?
那就根本不关科林什么事啦。
最后,科林忍不住问她:“要是你先遇到他会怎样?你会跟他约会吗?”
“罗斯很可爱啊,”格伦娜回答说。
“但你会跟他约会吗?”
她有点窘,这实际上已经给出了科林想知道的所有答案。
“罗斯不是那类你会与之约会的人嘛。”
西尔维娅说:“罗斯,总有一天你会找到一个好女孩的。”
但是罗斯好像已经放弃了寻找。他不再给女孩们打电话,冲着电话听筒学公鸡叫了。不再沿街慢慢开车,跟着她们,像发莫尔斯电码一样按喇叭了。一个星期六晚上,在科林和格伦娜家里,他宣布对女人断了念想。找一个像样的女人实在太难啦,再说他也忘不掉威尔玛·巴里。
“威尔玛·巴里,那是谁?”格伦娜问,“你恋爱过吗,罗斯?什么时候?”
“九年级。”
“威尔玛·巴里!她漂亮吗?她知道你对她的感觉吗?”
“是的,是的。是的吧,我想。”
科林说:“天哪,整个学校都知道!”
“她这会儿在哪里呢,罗斯?”格伦娜问。
“消失啦。结婚了。”
“她也喜欢过你吗?”
“她受不了我。”罗斯自鸣得意地说。
科林回忆起对威尔玛·巴里的迫害—罗斯如何溜进空荡荡的教室,在黑板上用彩色粉笔画的点子或小小的心形图案拼成她的名字。他如何跑去看她参加的女孩篮球赛,每次她靠近球或篮筐,他都像疯子一样欢呼。她退出了球队。她躲在洗手间里,派出侦查员,帮她侦查道路是否通畅。罗斯知道这个,他躲在扫帚柜里,以便突然跳出,冲她吹悲伤的口哨。她干脆彻底辍学了,十七岁就嫁了人。罗斯让她崩溃了。
“多可惜啊!”格伦娜说。
“我确实爱过那个威尔玛,”罗斯说道,摇了摇头,“科林,告诉格伦娜我和那片饼的事!”
科林便讲了那则轶事。上高中那会儿,它曾被全校人津津乐道。科林和罗斯向来带午饭上学,因为妈妈要上班,而餐厅太贵了。他们带的总是香肠番茄酱三明治和店售馅饼。一天,不知何故,他们中午全都被留在学校,九年级和十年级都是,因此罗斯和科林待在同一间教室里。罗斯桌肚里有午饭,就在他们听的不知什么训话正进行得起劲的时候,他摸出一大片苹果馅饼啃起来。“你到底在干什么?”老师咆哮道。罗斯毫不犹豫,将饼塞到身子下,一屁股坐在上面,无辜地拍拍黏答答的双手。
“我不是为了搞笑!”罗斯对格伦娜解释,“我只是不知道该怎么处理那饼,除了塞到屁股下面!”
“我能想象你那样子!”格伦娜笑着说,“哦,罗斯,我能想象你那样子!就像电视里的什么角色一样!”
“我们以前没告诉过你这事吗?”罗斯说,“怎么会从没告诉过你呢?”
“我以为我们说过呢。”科林说。
格伦娜说:“你说过,但是再听一遍还是很好笑啊。”
“好啦,科林,告诉她那次你开枪射死我的事!”
“那个你也给我讲过了,我可不想再听一遍。”格伦娜说。
“为什么不?”罗斯失望地问。
“因为太可怕了。”
科林知道,他从西尔维娅家里回到自己家,罗斯会在那里,修着汽车。他猜对了。快到五月底了,罗斯一等雪化,就在科林的院子里干起拆车拼车的行当。西尔维娅家里嫌小。
而这里地方够大。科林和格伦娜买下了一幢远离大街、位于一座果园遗址上的破败小房子,正对它进行修整。他们过去住在洗衣店楼上,格伦娜怀上了丽奈特而不得不辞职—她也是老师,是个小学教育专家—之后,干起了管理洗衣店的工作,这样就不用交房租了,可以省点钱。他们会谈起搬家—说走就走,搬到一个偏僻的、听起来充满冒险气氛的地方,比如拉布拉多、穆索尼或者黄刀镇[1]。他们谈论着去欧洲,给加拿大军人的孩子们当老师。突然间,这幢房子开始出售了,碰巧它是格伦娜用童车或小推车推着丽奈特散步时,经常兴趣十足地打量的一幢房子。她在全国各地的空军基地长大,喜欢看老房子。
现在,格伦娜说,这地方有这么多修整工作要做,似乎他们已经知道自己该待在哪里,该干什么了,这辈子都是。
罗斯要拆开两辆车,拼成一辆。1958年的雪佛兰出过事故。挡风板碎了,散热片和风扇都被压到发动机上。电线烧坏了。罗斯说不准引擎能不能发动,直到他把风扇、散热片和碾碎的金属通通清除掉。他给水箱灌满水,用电线短路法发动引擎,成功了。罗斯说早知道它能行,所以他才买下这车来着。车身已经毁坏,没什么用处了。他用的车身来自一辆1971年的科迈罗。他用剥离剂处理车身,车顶油漆成片剥落,不过现在得用水管和砂纸对付剩余的油漆。他要用铁锤敲平车顶的凹坑,切除地板上生锈的部分,换上铝板。此外还有很多别的活儿。估计要干上一个夏天。
这会儿,罗斯忙着修理轮子,格伦娜给他打下手。格伦娜负责打磨拆下的轮毂盖和中心盖板,罗斯抓着一把钢刷,俯身在轮子上方刷洗。丽奈特站在前门边的婴儿围栏里。
科林嗅着鼻子,看看有没有剥离剂的味道。罗斯没用面罩,他说在新鲜空气中不需要这个。科林知道,他应当相信格伦娜不至于让她自己和丽奈特暴露在这种气味中。但他还是嗅了嗅,一切正常,没用剥离剂。出于掩饰,他说:“闻起来是春天了嘛。”
“没必要由你来告诉我,”格伦娜说,她是花粉热患者。“我能感觉到成团花粉正在袭来。”
“你打针没有?”科林问。
“今天没去。”
“那太蠢啦。”
“我知道,”格伦娜说,她疯狂地磨着擦着,“我正准备走去医院来着。然后就开始傻乎乎地摆弄起这些,走火入魔啦。”
丽奈特抓着围栏边,颤巍巍地在围栏里走来走去,举起胳膊嚷道:“起喽,爹地。”科林对于她说“爹地”时一本正经、像模像样的口气很高兴—不像别的宝宝只会喊“爹”。
“我的打算是这样的,”罗斯说,“我要刷上一层除锈剂,那是一种软化剂,然后上一层转化涂层,然后再刷一层底漆。但是,我得把最后一点旧涂料全部清除掉,因为剥离剂有可能渗进去,那样一来,新油漆一刷,难看极了。我打算用丙烯漆。你们觉得呢?”
“什么颜色?”科林问。他正对着两个穿着牛仔裤的臀部说话。格伦娜是一条毛边短裤,露出修长、粉白色的双腿。罗斯脑袋上这会儿一顶帽子也没有。他一旦走近他的车,立马变得一本正经。
“我想过黄色。不过我又想着,红色科迈罗向来挺漂亮。”
“我们要拿油漆色表来,举到丽奈特面前让她挑,”格伦娜说,“行吗,罗斯?不管她指哪个?我们可以那样做吗?”
“行啊。”罗斯说。
“她会指红色的。她喜欢红色。”
“别紧张,”科林朝屋里走去,从丽奈特身边走过时安慰她道。她发出抱怨的声音,不过有点心不在焉。他从冰箱里取出三瓶啤酒。整个冬天他们都在室内忙活,撕下墙纸,扯掉地毯,现在他们已经让这地方的内部全都暴露出来。一片片粉色的绝缘材料安装到位,盖着塑料布。用来做新隔断的一堆堆木材四下摆放,等着干燥。厨房里铺着有弹性的木板地面。罗斯定期过来帮忙,不过自打开始摆弄汽车,他就不再提出帮忙了。
格伦娜说过:“我猜想,他意识到不会跟我们一起住在这房子里,于是就开始研究他的车了。”
科林说:“罗斯向来就爱摆弄汽车。”
不过罗斯以前没这么在乎车的外表。他在乎的只有启动速度、最高速度,以及能逼迫车子发出的各种可怕或古怪的噪音。他出过两次车祸。一次把车滚进沟里,自己毫发无伤地走出来。另一次,按他的说法,抄了条近路,穿过镇上一片空地,结果撞上了一堆垃圾,里面有个旧浴缸。科林周末从大学回家,看到罗斯的脸一半全是青紫,一只耳朵被划伤了,肋骨上打着绷带。
“我撞上了一个浴缸。”
他喝醉了?还是嗑药了?
“我想没有吧。”罗斯回答。
这一次,他好像脑袋里盘算的不只是让发动机轰鸣,飞驶过街道,在人行道上留下一道焦痕。他想要一辆真正的汽车,他读的杂志上所谓的“街车”。那有可能是为了要吸引女孩子吗?或者就为了出出风头,用一种体面的方式开车,只有在亮起绿灯、车发动的时候才偶尔表现出一点惊人的速度或强劲油门?没准这次他甚至不会装那种恶作剧的喇叭了。
“这辆车在大街上开来开去的时候可不会像个疯子一样,也不会在碎石路上开到一百码。”他说。
“很好啊,罗斯,”格伦娜说,“你也该毕业了。”
“啤酒。”科林招呼道。把它放在罗斯可以够到的地方。
“罗斯?”格伦娜说,(“谢谢。”她对科林说。)“罗斯,你必须把门上的毯子撕掉。你必须这么做。它看起来还行,其实很难闻。我能闻到那味道,在这里。”
科林让丽奈特趴在他的一个膝盖上,在台阶上坐下,他知道自己不会提什么准不准时的问题,更不用说帽子了。他不会提醒罗斯这是他一年来找到的头一份工作。刚才他是太累了不想说,现在他又太安逸了。这种安逸感有一部分要归功于格伦娜。格伦娜不会与任何彻底不可理喻的人做伴,也不会与任何毫无意义的事业为伍。而此刻她在这里,对着盖板照自己的脸,嗅着门板毯子的味道,认真地对待罗斯和他的汽车—如此认真,以至于科林一走出车门,看到她蹲在那里擦洗的时候,真想问问她是否整个夏天都会这样,她是否打算一直如此关注罗斯的汽车,以至于自个儿的家都不顾了。要是真这么说了,他现在肯定会后悔得想踢自己。如果她不喜欢罗斯,如果她不是从一开始就喜欢他、愿意与他相处的话,科林他又该怎么办呢?第一次见面时,当罗斯说了那个唯一的问题,而格伦娜报之以一个并非礼貌或者屈尊俯就的,而是发自内心的惊讶、快活的微笑时,科林不仅仅是松了口气。他的感觉是,仿佛从那时开始,罗斯不再是他心头的一个秘密负担了。他可以有另一个人来分担罗斯了。他从没算上过西尔维娅。
另一个令科林烦恼的想法,则彻头彻尾是肮脏的。罗斯绝不会的。罗斯是个对性充满抵触的人。他每次看到电影上出现性爱镜头,都瞪着眼睛,噘着厚厚的嘴唇,好像快要哭出来似的。
星期六早上,厨房台面上放了一大包鸡肉在解冻。这让科林想起,格伦娜邀请了西尔维娅和埃迪还有她的朋友—他们的朋友—南希来吃晚饭。
格伦娜推着丽奈特走路去医院打花粉热的针了。罗斯在忙活。他进屋放了一盒磁带,开着门听。《烈火战车》,是格伦娜的。罗斯通常听的都是乡村音乐和西部音乐。
科林刚从建材店回来,店里还没进到他要的吊顶板,尽管他们答应过。他出门看看上星期六种的草坪,它位于房子侧面,用绳子做成篱笆。他浇了点水,看罗斯打磨轮子。没多久,不知不觉地,他也开始磨起来。正像格伦娜说的,这让人着魔。你没法停下来。轮子彻底打磨后,要刷上底漆(轮胎部分要贴上防护胶带和防护纸,免得沾上漆),底漆干了后,要用铜片刮擦,再用油蜡清洁剂清洗。罗斯对这一切早已计划停当。
他们整个早上都在干活,然后又干了一下午。格伦娜做了汉堡包当午饭。科林告诉她没法装厨房吊顶,因为板子还没到,她回答说反正也不可能在厨房里搞装修的,因为她要做甜点。
罗斯进城买来一个补漆喷枪、一些金属木炭涂料和轮胎护理亮泡。这真是个好主意—补漆喷枪使轮胎的凹处变得容易对付多了。
午后过半,南希来了,开着她的微型雪佛兰,穿了身奇怪的新衣服—相当长而松垮的短裤,上衣有点像一个口袋,剪了几个洞用来露头和伸胳膊,整套衣服都是泥土色,用一条破破烂烂的紫色长腰带拦腰一扎。由于当局新出台的规定,南希今年刚刚被学校聘请,负责教从幼儿园到八年级的法语。她是个瘦高、苍白的平胸女孩,一头卷曲的玉米黄色头发,一张聪慧、悲伤的脸。科林觉得她可爱又让人不安。她像一个老朋友一样过来,带着自己的啤酒和音乐。她和丽奈特聊天,给她取了个编造出来的名字—维尼维尼。不过她算是谁的老朋友呢?去年九月之前,他们谁也没见过她。她三十出头,和三个男人同居过,觉得自己永无结婚之日。她头回见到西尔维娅和埃迪,就跟他们讲了这三个男人,以及她吃过的药。西尔维娅自然怂恿她多讲点。埃迪则根本不知道她在说什么,她扯到什么酸,他以为说的是电池酸液。每次你遇到她,她都会告诉你她的感受。不是头痛啊感冒啊腺体肿胀啊脚痛啊之类,而是她是否沮丧或者快乐,等等。她谈起这个镇来有一种古怪的态度。她谈论它,好像它是一个物品,一团混沌,好像里面的人全都黏成一片,好像这团混沌—对她而言—有着一些特殊的,通常都是令人沮丧的特点。
“我昨天看到你了,罗斯。”南希说。她坐在台阶上,开了罐啤酒,换上琼·艾姆特里丁[2]的磁带,《流露情绪》。她站起身,把丽奈特从围栏里抱出来:“我在学校看到你了。你真漂亮啊。”
科林说:“这里到处都是她会放到嘴里的东西,小螺丝之类的。你得盯着她。”
“我会盯着她的,”南希说,“维尼维尼。”她用腰带的流苏给丽奈特挠痒痒。
“双帽先生[3],”她说,“我让三年级的学生往窗外看、欣赏你来着。我们决定给你起这个绰号。双帽先生。戴两顶帽子的先生。”
“我们能听懂点法语。虽说这听起来有点怪。”科林说。
“不懂,”罗斯说,“我不懂她在说什么。”
“哦,罗斯,”南希说,一边挠着丽奈特,“你不是我的小熊熊吗?我的小维尼维尼?罗斯,你那会儿很漂亮呐。在无聊漫长的星期五下午,那是多棒的一个灵感啊。”
南希总会让罗斯陷入愠怒。当着她的面,或者在她背后,他常说她是个疯子。
“你是个疯子,南希。你根本没看见我。你在幻想。你幻视了哦。”
“确实,”南希说,“绝对如此,双帽先生。你是在干吗?给我讲讲。你拆起车了吗?”
“这会儿我们正在涂这些轮子,”科林说。罗斯不会开口的。
“我有回上了一种课,”南希说,“我上了一种基础机械课,好知道我的车出了什么问题,不用像个小女人一样尖叫着冲进修车厂。”她像个小女人一样尖叫起来,“哎哟,出了点奇怪的噪声,告诉我这罩子下是什么,好吗?老天爷啊,这是个引擎!嗯,好吧,我不想那样,所以去上了这种课,结果突然兴趣大增,又上了一轮,实际上都开始考虑当个修车工了。我差点就要到修车厂去干咯。但我真的太保守了。我可受不了非议。还是教法语得了。”
她把丽奈特搂到胯部,走过去看引擎。
“罗斯?你要用蒸汽清洗这个吗?”
“是啊,”罗斯说,“我得考虑租一台。”
“此外,我还和一个跟汽车打交道的人住过。你知道他干什么了吗?他非得租蒸汽机的时候,总会到处问问谁还要用,然后收他们十元。这样他租机器反而赚了钱。”
“不错嘛,”罗斯说。
“只是个建议罢了。你要换一种散热器支架脚撑,对吗?V8的散热器装在脚撑后面。”
打这之后,罗斯不再那么愠怒了—他发觉最好还是换个态度—开始介绍她看这看那的。
“来吧,科林,”南希招呼道,“格伦娜说我们还得买点发泡奶油。我们可以开我的车去。你抱着丽奈特。”
“我衬衫都没穿。”科林说。
“丽奈特不会介意的。我来进商店好了。来吧。格伦娜现在就要。”
在车里她说:“我想和你谈谈。”
“我猜也是。”
“是关于罗斯的。关于他做的事。”
“你是说他戴那些帽子到处跑的事吗?怎么了?戴维森说什么了吗?”
“我根本没想说这事。我想说的是那汽车。”
科林松了口气。“车怎么了?”
“是引擎,科林。那引擎太大了。他不能把那个引擎塞进那个车身里。”
她的声音富于戏剧性,低沉、平静。
“罗斯很懂汽车的,”科林说。
“我相信你。我绝不是说罗斯是个蠢蛋。他确实懂。但是那个引擎,要是他把它放进去,我恐怕它会扭断驱动轴—不是立即,但是迟早会。而且很有可能用不了多久。小孩子们常干这种事。他们会装个巨大强劲的引擎,好得到他们想要的加速和速度,但总有一天,你知道,说真的,它会毁掉整辆车。不夸张地讲,它真的会把车子弄翻。驱动轴会断掉的。不过,对孩子们来说,十有八九别的地方会先出点毛病,或者他们干脆就直接把车开坏了。所以他大有可能以前这么干过,却没出事。所以他以为不会出这种事呢。我不是在假装大专家,科林。我向上帝发誓我没这意思。”
“好吧,”科林说,“你没有。”
“你知道我没有吧,科林?”
“我知道你没有。”
“我只是没法亲自对罗斯说这个。他一个劲儿想弄它。这是这里人的说法,对吗?‘一个劲儿’?我没法把这种彻头彻尾的反对说出口。反正,他未必会信我的话。”
“不知道他会不会相信我,”科林说,“听着,你肯定得要命对吗?”
“别说‘要命’!”南希请求道,声调做作,但他又不得不相信那是真诚的。“我绝对、毫无疑问地肯定,不然的话,我大可不必开口的。”
“他知道他在装进一个过大的引擎。他清楚的。他想必是以为不会有问题。”
“他的想法错啦。科林。我爱罗斯。我也不想破坏他的计划。”
“你最好不要让西尔维娅听到你说这话。”
“说什么?她也不想他被害死吧?”
“说你爱罗斯。”
“我爱你们所有人啊,科林,”南希说,一边拐到麦克斯米尔克便利店的停车场上,“真的。”
“这就是我干的事,我来告诉你吧,”喝到第四杯玫瑰红,西尔维娅主要是冲着南希说道,“我给自个儿举办了一次二十五周年结婚纪念聚会。你有何感想?”
“太棒了!”南希说。西尔维娅刚跟她说了那则小便池前的黑人和白人的笑话,科林能看出她有点难以接受。
“我的意思是,在没有老公的情况下。我说的是,他不再和我一起生活了。我不再和他一起生活了。他那会儿还活着哩。在彼得伯勒。现在他已经不在啦。不过我说:‘我已经结婚二十五年啦,我仍旧是已婚。我干吗不配举行一个庆祝晚会呢?’”
南希说:“那当然。”
他们坐在后院的野餐桌边,在一棵开花的黑莓树下,距离厨房门只有几步之遥。格伦娜铺开一张白色桌布,摆上结婚用的瓷器。
“到明年,这里就会是一个露台了。”格伦娜说。
“瞧啊,”西尔维娅说,“要是你用塑料桌布的话,这会儿只要把这些拎起来,丢进垃圾桶就行了。”
埃迪给西尔维娅点了烟。他自己吃饭时烟就没停过。
南希从酥皮饼残余的顶部拿起一枚浸湿的草莓。“这里现在就很可爱呐。”她说。
“至少还没有虫子,”格伦娜说。
西尔维娅说:“不错。草莓下周就会便宜好多了,不过你们那时就不能在这里吃饭了,因为虫子也多啦。”
在南希听来这话很好笑。她笑了,埃迪也跟着笑了。因为某种不得明说的原因—就他而言,那是当然不能明说的—他仰慕南希和她所做的一切。西尔维娅的脸蛋这会儿像朵粉色软纸做的玫瑰一样,边缘部分已经揉得挺皱。她有点困惑,不过依然好脾气地问:“我看不出有什么好笑的,我说什么了吗?”
“继续呀。”罗斯说。
“继续什么?”
“继续讲你的纪念日晚会。”
“哦,罗斯,”格伦娜说。她站起身,打开装在彩色塑料灯罩里的灯,它们成串缀在房子的墙上。“我应该让科林爬上去,在樱桃树上也挂一些的。”
“好吧,科林当时十三岁,罗斯十二岁,”西尔维娅说,“哦,所有人都知道来龙去脉了,只有你不知道,南希。怎么回事,结婚二十五年了,我最大的孩子才十三岁?你可以说,问题就在这里。这么久都没孩子,我们以为再也不会有了。先是一心想要,然后失望了,然后习惯了,然后习惯了这么久,都结婚十多年了,我竟然怀孕了!那就是科林。之后过了甚至不到十二个月,就在十一个月零三天之后,又生了一个!那就是罗斯!”
“哎哟哟!”罗斯说。
“可怜的人,我猜想他从此担心他一来我就会生个宝宝下来,所以他走啦。”
“他被调走了,”科林说,“他在铁路上工作,他们取消了穿过这里的客车,他就调到彼得伯勒了。”
他对爸爸没有多少记忆。有一次,沿大街走着,爸爸给他吃了一片口香糖。这个举动有一种公事公办的表示友善的味道—他爸当时身穿制服—而不是一种父爱的亲切。科林的感觉是,西尔维娅不知怎的,没法应付两个儿子和一个老公—她搅乱了她的婚姻,尽管并非刻意为之。
“他不光在铁路上工作,”西尔维娅说,“他是个列车长。他调走后,起初经常坐大巴回来,不过他讨厌坐大巴,自己又不会开车。慢慢就不怎么来了,然后刚要退休时就死了。所以,他没准本来可以回来的,谁知道呢?”
(格伦娜的想法—又传给了科林—则是,所有这些关于自己一个人开周年纪念晚会的瞎扯都是西尔维娅的臆想,其实她请求或者要求过她老公来参加,但是他没来。)
“哼,别管他了,聚会还是开啦,”西尔维娅说,“我请了很多人。我本来说不定也会请埃迪,只是那会儿跟他还没现在这么熟。我那时候觉得他层次太高啦。”她用胳膊肘捣捣埃迪的胳膊。所有人都知道层次太高的其实是他的第二任妻子。“那是在八月,天气好极了,我们可以在户外活动,就像现在这样。我架起几张搁板桌,做了整整一洗衣盆的土豆沙拉。我做了肋排、炸鸡、甜点、馅饼和一只周年蛋糕,让糕点房的人帮忙刷了奶油。还有两种水果潘趣酒,一种带酒精,一种不带。带酒精的那种夜越深酒精越多,人们不断往里面倒伏特加、白兰地和随便什么他们手头有的酒,而我都不知道!”
罗斯说:“所有人都以为科林跌到潘趣酒里了!”
“不,他没有,”西尔维娅说,“那不是真的。”
早些时候,科林和南希一起清理餐桌,他俩单独在厨房,南希说:“你跟罗斯说了没有?”
“还没。”
“不过,你会说的吧,科林?这不是开玩笑。”
格伦娜端着一大盘鸡骨头进来,听到了这个,不过什么也没问。
科林说:“南希觉得罗斯在汽车的问题上犯了个错。”
“一个能要命的错。”南希说。科林回到外面,留下她用一种压低的、急切的声音对格伦娜说了起来。
“我们还放音乐来着,”西尔维娅说,“我们在前院周围的人行道上跳舞,后院也热闹着。我们在我的前屋放音乐,把窗户开着。夜班巡警过来了,他和我们一起跳舞!他们刚刚点亮街上的粉色街灯,我就说啦:‘瞧瞧他们为我的晚会开的灯!’你去哪儿?”她问科林,后者正站起身。
“我想给埃迪看点东西。”
埃迪站起身,绕过桌子走来,似乎很高兴。他穿着棕色和黄色格子裤,不过格子并不明显,搭了一件黄色运动衫,围着深红色领巾。“他样子难道不是很棒吗?”西尔维娅感叹道,她不是头一回这么说了。“埃迪,你真会穿衣服!科林只是不想听我说剩下的部分而已。”
“剩下的才是最好的,”罗斯说,“马上就到了!”
“我想给埃迪看个东西,再问他件事,”科林说,“私下的。”
“这部分就像你会在报上读到的那种。”西尔维娅说。
格伦娜说:“太可怕了。”
“他要给埃迪看他的宝贝草,”西尔维娅说,“而且,他真不想听我说那个。何必呢?又不是他的错。好吧,只有部分是他的错。不过这种事在别人家里发生过一遍又一遍,只是我们的结果更糟一点罢了。悲剧啊。”
“真的差点成了悲剧。”罗斯笑道。
科林领着埃迪绕到房子前院,一路上还听到罗斯的笑声。他带埃迪走过绳子栅栏和新草坪。前院里有一点点街灯光,不过不够亮。他打开前门边的灯。
“好了。你能看清罗斯的汽车吗?”科林说。
埃迪说:“我以前都看过了。”
“等等。”
科林的汽车停在旁边,可以让车灯照到想要看的位置,钥匙就在他口袋里。他钻进汽车,发动引擎,打开车灯。
“来吧,”他说:“趁我开着灯,看看那引擎。”
埃迪说:“好吧,”他走进车灯光中,站着打量那引擎。
“现在看看车身。”
“嗯,”埃迪应道,转过一点身子,但没弯腰。穿着这样的衣服,他不想凑近任何东西。
科林关掉灯,熄灭引擎,钻出了汽车。黑暗中,他听到罗斯又在笑。
“有人跟我说,这引擎太大,不适合装在这里面,”科林说,“这人还说,它会扭断万向节,主轴会断掉,造成翻车。可我不大懂车。真会那样吗?”
他不打算说那人是南希,并非因为南希是个女人,而是因为埃迪会像着魔一样对南希说的做的任何事都感到高兴,你就没法听到他说出自己的见解了。事实上,任何时候要听他发表见解都不容易。
“这是个大引擎,”埃迪说,“这是一个350的V8。是一辆雪佛兰的引擎。”
科林没说他已经知道这个。“它太大了吗?”他追问,“有危险吗?”
“是大了点。”
“你以前看到过他们把这种引擎装在这样的车身里吗?”
“嗯,是的。我知道他们啥事都干过。”
“会造成事故吗,就像这人说的?”
“难说。”
大多数人说完这话,都会接下来告诉你为什么难说。埃迪除外。
“它肯定会扭断万向节吗?”
“哦,不一定,”埃迪随和地说道,“我可不会那么说。”
“那有可能吗?”
“嗯。”
“我应该提醒罗斯吗?”
埃迪不安地笑了笑:“你每次提醒罗斯什么,西尔维娅都不大开心呐。”
科林没跌进那缸深褐色的潘趣酒里。他、罗斯还有其他六七个男孩没跑到离晚会核心那么近的地方。他们对晚会不屑一顾,只待在它的边缘地带,喝几罐听装饮料—不知谁带来放在后院台阶边的可乐和橙汁。他们吃人家带来的土豆片,但不耐烦去吃桌上要用碟子或叉子的食物。他们不关心大人们在做的事。几年前,他们或许会到处乱跑,盯着所有东西瞧,一心想着寻点乐子或者捣个乱。现在他们却根本不打算承认那个世界—晚会上或者任何其他地方的成人世界—的存在。
属于大人们的东西则是另一回事,它们仍旧是有趣的。从停在黑暗小巷边的车子里,他们找到不少东西。工具啊,铲子啊,去年冬天用的铁链啊,靴子啊,还有一些夹子。破雨衣,一条毯子,有下流图片的杂志,一把枪。
这枪躺在一辆没锁门的车的后座上。是一把狩猎用的来复枪。毫无疑问他们必须把它弄出来,打量打量,用一种无所不知的态度评价评价,用它瞄准想象中的鸟儿。
有人提醒他们小心点。
“它没装子弹。”
“你怎么知道?”
科林再也没听到那个男孩是如何知道的。他想的是不能让罗斯摸到那枪,不然,不管装没装子弹,它都会爆炸。为了防止这种事发生,科林亲自抢到了它。之后的事,他实际上根本搞不明白,或者说再也想不起来了。他不记得拿这枪瞄准过。他不可能拿它来瞄准。他也不记得扣下扳机,因为那是不可能的。他不可能扣下扳机。他不记得枪响的声音,只知道出事了—感觉就像你被一声巨响从梦中惊醒:有那么一会儿,它显得过于遥远,过于必然,你都不会去琢磨。
同时尖叫和嚷嚷在他耳边炸开。其中一声尖叫来自罗斯,它本该让科林明白过来的。(被射死的人通常会尖叫吗?)科林没看到罗斯倒下。他看到的—刻骨铭心的—是罗斯仰天躺在地上,胳膊摊开,头顶那里冒出一摊深色的东西。
不可能有那个的—是个水坑吗?
男孩们再也不厌恶大人的世界或者帮助了,其中一两个沿小巷飞奔到西尔维娅家,嚷嚷着:“罗斯中枪了!科林射中了他!罗斯!他中枪了!科林开的枪!罗斯!科林!罗斯!”
等他们让坐在后院桌边的人们明白过来—他们中有些人听到了枪声,以为是鞭炮—等到第一个人沿小巷跑来,赶到悲剧现场,罗斯已经坐起来了,伸着胳膊,带着一种耍恶作剧的羞愧表情。没跑去求救的男孩们看到他动弹起来,觉得他一定没死,只是受伤了。其实他根本没受伤。子弹挨都没挨到他。它击中了巷子远处的棚子,只有一个老头冬天会在里面磨冰刀。没人受伤。
罗斯说他是被枪声吓昏,或者吓得跌倒了。但是所有了解罗斯的人都相信或者疑心,他是一时兴起,故意那么干的。枪躺在小巷边的草地上,是科林丢下的。没有哪个男孩捡起它。没人想碰它或跟它扯上关系,尽管他们所有人都知道现在什么都瞒不了啦—他们如何没事找事,将它从车里弄出来,他们如何全都要为此受罚。
不过主要还是科林。科林才是该受罚的人。而他溜掉啦。
关于罗斯的最初骚乱平息之后,喊声四起。
“发生什么了?罗斯,你还好吗?你中枪了吗?枪在哪里?你真的没事吗?你们从哪儿弄来的枪?你为什么假装中弹?你肯定没中枪吗?谁开的枪?谁?科林!”
“科林呢?”
甚至都没人记得他往哪里跑了。没人记得看到他跑开。他们喊他,但是没回音。他们沿小巷寻找,看他有没有躲在哪里。巡警钻进警车,其他人钻进各自的汽车,在街上来回开着,甚至开了几英里到公路上,看看有没有可能找到逃跑的他。蛛丝马迹都没有。西尔维娅跑进家里,在壁橱和床底下找。人们四处搜寻,动辄互相撞上,往杂木林里照手电,喊科林的名字。
然后罗斯说他知道去哪里找。
“在提普莱蒂大桥下。”
这是一座老式铁桥,横跨提普莱蒂河。尽管上游建起了一座新的混凝土大桥,让拓宽的公路穿过镇子的这个部分,但铁桥仍然保留着。通往老桥的道路已禁止通车,当局已警告此桥不安全,但人们还会去那里游泳、钓鱼,晚上总有汽车摸索到“道路关闭”的告示牌周围去停车。路面中断了,街灯坏了,没有换。关于街灯传出一些谣言和笑话来,暗示说在这里停车的包括几位议员,所以宁可任其这么黑着。
大桥离西尔维娅家只有两个街区。男孩子们跑在前面,并不是由罗斯打头,相反他跟在后面,若有所思地迈着步子。西尔维娅紧挨着他,督促他快走。她穿着高跟鞋和一条水鸭蓝的筒裙,臀部裹得太紧,令她行动不便。
“你最好没搞错。”她说,她现在都搞不清到底对哪个儿子更恼火了。她还没来得及从罗斯没中枪这个事实中回过神来,旋即就要担忧是不是会从此失去科林。几个晚会客人喝醉了,或者是有欠考虑,竟然大声讨论起他会不会跳进了提普莱蒂河。
巡官把脑袋从车里探出,吩咐他们搬开路障。他开过去,把车灯对着大桥。
这种灯光中,看不大清楚桥顶,不过他们能看到有人坐在那里。
“科林!”
科林爬上了大桥顶梁,坐在那里。他在呢。
“科林!真不相信你会干这事!”西尔维娅冲他嚷道,“快从桥上下来!”
科林没动弹。他好像呆掉了。其实他被警车灯照得两眼昏花,就算想爬下来也做不到。
巡警对他下令,别人也对他大吼大叫着。他毫不松动。在这些吼叫和责备当中,西尔维娅突然想到,他当然不晓得罗斯没死。
“科林,你弟弟没中弹!”她对他嚷道,“科林!你弟弟活着呢,就在我身边!罗斯没死!”
科林没回答,不过她觉得好像看到他的头动了动,似乎正往下看。
“把那该死的灯光挪开!”她对巡警嚷道,后者算是她的一个男朋友。“要是你非得用它对着什么,那就对着罗斯吧。”
“我们干吗不让罗斯站到灯光里?”巡警说,“然后我们可以关掉灯,让那孩子爬下来。”
“好啦,科林,”巡警吼道,“我们让你看看罗斯就站在这里—他根本没受伤!”
西尔维娅把罗斯推到灯光中。
“张开嘴,大声喊几句,”她命令,“告诉哥哥你没死。”
科林帮格伦娜清理餐桌。他想到他妈妈说的,如果用塑料碟子和桌布,你就可以把它们一兜,丢进垃圾箱。格伦娜这么做的可能性几乎为零。他妈妈根本不懂格伦娜,对她毫不了解。
格伦娜操办了一个过于精致的晚餐聚会,除了她自己,没有别人能欣赏得来。现在她精疲力竭了。
不,这样说不对。他是欣赏的,尽管他也不理解为何非要如此。她的任何举动,但凡能让他忘掉他妈妈的混乱,他都是欣赏的。
“不知该怎么跟罗斯说啊,”他说。
“说什么?”格伦娜问。
她太累了,他想,以至于忘掉南希跟她说的话了。他不由自主地想起他们婚礼前的那个晚上。格伦娜找了五个伴娘,挑选标准不是友谊深浅,而主要是她们的身高发色。她亲自设计,动手给她们所有人做了礼服。婚纱也是她自己做的,还有所有手套和头饰。每只手套上都镶有十六枚小小的包布纽扣。她直到婚礼前夜九点半才做完。她上了楼,脸色非常苍白。科林也在房子里,他上楼查看情况,发现她在抽泣,手里还抓着一些彩色布片。他没法让她安静下来,只好打电话给她妈妈,后者说:“她就是那样的,科林。她总是用力过猛。”
格伦娜抽泣着,发了通抱怨,说她根本看不出活着有什么意义。第二天,她打扮得像天使一样美丽,一丝憔悴的痕迹也没有,祝着酒,赞美祈求着她的幸福。
这个晚宴不大可能像那些伴娘礼服一样把她累垮,不过她还是一脸拒人于千里之外的神情,苍白、严厉,好像对许多事都疑虑重重。
“他不会愿意再去找一个新引擎的,”科林说,“他哪里买得起呢?这一个还是借西尔维娅的钱买的。再说,他就想要个大引擎。想要那种动力。”
格伦娜说:“区别有那么大吗?”
“总归有区别吧,就启动和加速而言。真的。那样一个引擎,区别大了。”
随后,他发觉她或许指的不是这个。她或许并不是想说:“引擎区别有那么大吗?”也许她想说的是:“就算不是这个,也会出别的事吧。”
(她坐在草地上。她擦洗着盖板。她嗅着车门垫子的味道。她说:“让丽奈特选颜色吧。”)
也许她想说的是:“我们为什么不干脆一切都撒手?”
科林摇晃着垃圾倒进塑料袋,把口扎紧。“要是那样,我不想你和丽奈特坐他的车。”
“科林,我不会的,”格伦娜温柔、困惑地说,“你以为我会跟他一起坐进那汽车,或者让丽奈特坐他的车吗?我才不会。”
他把垃圾送出去,她扫起地来。等他回来后她说:“我刚想到件事。我想,很快我就要扫着黑白相间的瓷砖地了,我会记不起这些旧地板的样子。我们会想不起来的。我们该拍些照片,这样才会记住我们做过什么。”
然后她说:“我想南希有时会夸大其词。我是说关于我和丽奈特。不过我觉得她做过头了。”
事实上,格伦娜设想各种事情的本领令他震惊。房子,每间房间,它们装修完毕的样子。她已经摆好了他们还没买的家具,她已经根据朝北或朝南的方位、早上还是晚上的光线,搭配好了家具的颜色。格伦娜能够在脑海中秩序井然地构筑出一系列房间,一种既定的、和谐的,对她来说完全水到渠成的安排。
没有什么问题能砸到格伦娜身上,让她堕入怀疑和痛苦。各种解决方案就像一系列房间一样随时恭候。她有一种无须谈论或思考就能解决问题的本领。平日她再耐心、再甜美,这本领都不会改变,也不会被侵犯。
起初,在灯光和喊叫声中,他唯一的想法是他们都跑来谴责他了。对此他毫无兴趣。他知道自己做了什么。逃开,跑到这里,摸黑爬上大桥,并不是为了躲开他们的惩罚。他并不害怕,并没有因为受惊而瑟瑟发抖。他坐在细细的桥梁上,感到铁条是那样冰冷。尽管这是一个夏夜,他自己也浑身冰凉,不过心情依然平静,他自己的以及镇上其他人的混乱无序的生活现在全部翻转回来,就像一张照片剥离、翻转起来一样,露出了一直以来就藏在其下的东西。那就是一片空白。罗斯躺在地上,脑袋周围有一摊东西。罗斯沉默了,而他是谋杀者。仍旧一片空白。他既不高兴也不伤心。这类情感过于细弱、过于私人了,不合时宜。事后,他发现大多数人,尤其是他妈,相信他爬到那里是因为追悔莫及,正考虑跳进提普莱蒂河。其实他从没想这么干过。在某种意义上,他都忘了下面是河流。桥是一种修在河面上的建筑,以及他妈妈是一个可以命令他做这做那的人,这些他都忘记了。
不,与其说他忘了那些事,不如说意识到了它们有多蠢。他有一个名字,叫作科林,而那些人正嚷嚷着它,这有多蠢啊。在某种意义上,就连想到他射死了罗斯,也够蠢的,尽管他明知自己确实这么做了。愚蠢之处在于,得用这样一个个字眼儿来思考。科林。射死。罗斯。将它理解为一个行动,某件尖锐、独立的事情,一个事件,一种区别。
他并没想着跳进河里,或者接下来可以做什么,或者从现在开始,生活将如何继续。这样的继续看起来不仅毫无必要,也绝无可能。他的生活已经撕裂,再也不需要为之思索什么。
他们正告诉他罗斯没死。
他没死,科林。
你压根没射中他。
那是个玩笑啦。
是罗斯的一个玩笑。
罗斯的玩笑。
你压根没射中任何人,科林。那枪走火啦,但是没打到任何人。
看啊,科林。他在这里呐。
罗斯在这里呢。他没死。
“我没死啦,科林!”
“你听到没?听到他的话没有?他说他没死!”
现在你可以下来啦。
赶紧下来吧。
科林。快下来。
那就是一切重新恢复如初的时刻。他看到罗斯毫发无损,确确实实是他本人,被车灯照亮着。复活的罗斯,看起来挺开心,又有点不安,但并非真的抱歉。罗斯,哪怕一动不动站着都好像在雀跃,哪怕竭力闭紧嘴巴都好像在哈哈大笑的罗斯。
还是老样子。
科林感觉头昏目眩的,事物恢复生机的速度,这种混乱和激情,都让他眩晕。这就像滚烫的血液推进你身体冻僵的部分一样疼痛。他按照人家的吩咐爬下来。有些人开始鼓掌、欢呼。他不得不集中注意力,免得失足。他因为一直坐着,感觉腿发软、抽筋。而且他得努力不去思考,以免自己突然琢磨起刚才全凭侥幸而并未发生的事情。
他知道,从此以后,防止那样的事件发生—对罗斯,以及对他自己—将成为他毕生的使命。
[1] 均为加拿大地名。
[2] 1950年出生的英国黑人女歌手,曾获数次格莱美提名。
[3] 原文为法语。
水蛇腰-汪曾祺
========================
水蛇腰-[[汪曾祺]]
------
崔兰是个水蛇腰。腰细,长,软。走起路来扭扭的。很多人爱看她走路。路上行人,尤其是那些男教员。看过来,看过去,眼睛很馋。崔兰并不知道有人看她。她只是自自然然地走。崔兰还小,才读小学五年级;虽然发育得比较快,对于许多事还有点朦朦的,感觉并不大懂。她还不知道卖弄风情,逗引男人。
崔兰结婚早。未免过早一点,高小毕业就结婚了。在这所六年级制的小学里,也许她是结婚最早的一个。嫁的是朱家。朱家的少爷。朱家是很阔的人家,开面粉厂。这个地方把面粉叫“洋面”,这个面粉厂叫“洋面厂”。崔兰嫁的是洋面厂的小老板。崔兰怎么会嫁到朱家去的呢?
崔兰的父亲是洋面厂的账房先生,崔兰常给她父亲到洋面厂去送饭(崔兰的母亲死得早,家里许多事得她管),朱家的少爷一眼看上崔兰,托人说媒,非崔兰不娶。崔兰的父亲自然没有意见,崔兰只说了两句话:“我还小哩。……他们家太阔了!”事情就定了。
结婚三朝,正是阴历七月十五,“迎会”(赛城隍)的日子。这个地方每年七月十五“出会”。近晌午时把城隍老爷的“大驾”从庙里请出来,在主要街道上“巡”一“巡”,到“行宫”里休息,下午再“回銮”。这是一年里最隆重而热闹的日子。大锣大敲,丝竹齐奏。踩高跷、舞狮子、舞龙、舞“大头和尚”(月明和尚度柳翠)。高跷有“火烧向大人”(向大人即清末征太平天国的名将向荣)。柳枝腔“小坟”贾大老爷用一个夜壶喝酒……茶担子、花担子,倾城出动,鞭花訇鸣,各种果品,各种鲜花,填街满巷,吟叶百端……
朱家的少爷带着新娘子去“看会”,手拉手。从挡军楼(洋面厂的所在)一直走到中市口(全城最繁华处)。新婚夫妻在大街上,在那么多人面前手搀手地走,那样亲热,很多“老古板”看不惯。
他们的衣装打扮也是这城里的人没有见过的。朱家少爷穿了一件月白香云纱长衫,上面却罩了一个插了玫瑰红韭菜叶边的黑缎子的小马甲。马甲插边,还是玫瑰红的,男不男,女不女!
崔兰穿的是一件大红嵌金线乔其纱旗袍,脚下是一双麂皮软底便鞋,很显脚形,——崔兰的脚很好看,长丝袜。新烫的头发(特为到上海烫的),鬓边插一朵小小的珍珠偏凤。脸上涂了夏士莲香粉蜜,旁氏口红,描眉画眼,风姿绰约,光彩照人。
朱家少爷和崔兰坐在王万丰(这是中市口一家大酱园)楼上靠栏杆一张小方桌前的藤椅(这是特为给上宾留的特座)上看会,喝茶,嗑瓜子。楼下的往来人议论纷纷,七嘴八舌。有男的,也有女的。有荤的也有素的。有的人说出了声(小声),有的只是自己在心里想。
——崔兰这双丝袜得多少钱?
——反正你我买不起!
——她的旗袍开叉未免太高了,又坐在栏杆旁边,从下面什么都看见了!
——她穿了裤子没有?
——她晚上上床,一定很会扭,扭得很好看。
——你怎会知道?
——想当然耳,想当然耳!
——闭上你们这些男人的臭嘴!
一夜之间,崔兰从一个毛丫头变成了一个少奶奶,不知道为什么,很多人为此很不平。一句话在很多人的嘴里和心里盘桓。
“这可真是糠箩跳米箩了!”
水星播种-王晋康
========================
水星播种-[[王晋康]]
-----
几亿年前人类在水星上放养了新型生命。现在,索拉人类刚刚进入文明启蒙前的阵痛,科学与宗教角力,理性被愚昧摧残,信徒们因狂热而害死了他们的缔造者,从而背负上沉重的原罪……
再宏伟的史诗性事件也有一个普通的开端。2032年,正当万物复苏的季节。这天我和客户谈妥一笔千万元的订单,晚上在得意楼宴请了客户。回到家中已是11点,儿子早睡了,妻子田娅倚在床头等我。酒精还在血管中燃烧,赶跑了我的睡意,妻子为我泡了一杯绿茶,倚在身边陪我闲聊。我说:“田娅,我的这一生相当顺遂呀,年方34岁,有了2000万资产,生意成功,又有美妻娇子。人生如此,夫复何求!”妻子知道我醉了,抿嘴笑着没接话。
这时电话铃响了,拿起听筒,屏幕上显出一位男人,身板硬朗,一头银发一丝不乱,目光沉静,也透着几分锐利。他微笑着问:
“是陈义哲先生吗?我是何俊律师。”
“我是陈义哲,请问……”
何律师举起手指止住我的问话,笑道:“虽然我知道不会错,但我仍要核对一下。”他念出我的身份证号码,我父母的名字,我的公司名称,“这些资料都不错吧。”
“不错。”
“那么,我正式通知你,我的当事人沙午女士指定你为她的遗产继承人。沙女士是五年前去世的。”
我和妻子惊异地对看一眼:“沙午女士?我不认识——噢,对了!”我突然想起来了,小时候在爸爸的客人中有这么一位女士,论起来是我的远房姑姑。她那时的年龄在40岁左右,个子矮小,独身,没有儿女,性格似乎很清高恬淡。在我孩提的印象中,她并不怎么亲近我,但老是坐在角落里静静地观察我。后来我离开家乡,再没有听过她的消息。她怎么忽然指定我为遗产继承人呢?“我想起沙午姑姑了,对她的去世我很难过。我知道她没有子女,但她没有别的近亲吗?”
“有,但她指定你为唯一继承人。想知道为什么吗?”
“请讲。”
“还是明天吧,明天请允许我去拜访你,上午9点,可以吗?好,再见。”
屏幕暗下去,我茫然地看着妻子,这个消息太突然了。妻子抿嘴笑着:“义哲先生,你的人生的确顺遂呀。看,又是一笔天外飞来的遗产,没准它有几个亿呢。”
我摇摇头:“不会。我知道沙午姑姑是一名科学家,收入颇丰,但仍属于工薪阶层,不会有太丰饶的遗产。不过我很感动,她怎么不声不响就看中我呢?说说看,你丈夫是不是有很多优点?”
“当然啦,不然我怎么会在50亿人中间选上你呢。”
我笑着搂紧妻子,把她抱到床上。
第二天,何律师准时来到我的公司。我让秘书把房门关上,交代下属不要来打扰。何律师把黑色皮包放在膝盖上,我想,他马上会拉开皮包,取出一份遗嘱宣读了。他没有这样做,而是轻叹道:
“陈先生,恐怕这是我一生中最困难的律师业务。为什么这样说?以后你会明白的。现在,先说说我的当事人为什么指定你继承遗产吧。”
他说:“还记得你两岁时的一件事吗?那时你刚刚会说一些单音节的词。一天你父母抱着你出门玩,沙女士也陪着。你们遇到一家饭店正在宰牛,血流遍地,牛的眼睛下挂着泪珠。你们在那儿没有停留,大人们都没料到你会把这件事放到心里。回家后你一直愀然不乐,反复念叨着:刀、杀、刀、杀。你妈妈忽然明白了你的意思,说:你是说那些人用刀杀牛,牛很可怜,对不?你一下子放声大哭,哭得惊天动地,劝也劝不住。从那之后,沙女士就很注意你,说你天生有仁者之心。”
我仔细回想,终于愧然摇头,这件事在我心中已没有一丝记忆。何律师又说,另一件事则是你7岁之后了。沙女士说,那时你有超出7岁的早熟,常常皱着眉头愣神,或向大人问一些古古怪怪的问题。有一天你问沙姑姑,为什么闭上眼睛后,眼帘上并不是空的,不是绝对的黑暗,而是有无数细小的微粒、空隙或什么东西飘来飘去,但无法看清它们。你常常闭上眼睛努力想看清,总也办不到,因为当你把眼珠对准它时,它会慢慢滑出视野。你问沙姑姑,那些杂乱的东西是什么?是不是在我们看得见的世界背后,还有一个看不见的世界?
我点点头,心中发热,也有些发酸。童年时我为这个毫无意义的问题苦苦追寻过,一直没有答案。即使现在,闭上眼睛,我仍能看到眼帘上乱七八糟的麻点,它确实存在,但永远在你的视野之外。也许它只是瞳孔微结构在视网膜上的反映?或者是另一个世界(微观世界)的投影?现在,我已没有闲心去探求这个问题了,能有什么意义呢。但童年时,我确实为它苦苦寻觅过。
我没想到这件小事竟有人记得,我甚至有点凛然而惧:一个人的一生中,有多少双眼睛在默默地观察你啊。何律师盯着我眼睛深处,微笑道:
“看来你回忆起来了。沙女士说,从那时起她就发现你天生慧根,天生与科学有缘。”
我猜度着,沙姑姑的遗产大概与科学研究有关吧,可能她有某个未完成的重要课题等待我去解决。我很感动,但更多的是苦笑。少年时我确实有强烈的探索欲,无论是磁铁对铁砂的吸引,还是向日葵朝着太阳的转动,都能使我迷醉。我曾梦想做一个洞悉宇宙奥秘的科学家,但最终却走上经商之路。人的命运是不能全由自己择定的。
“谢谢沙姑姑对我的器重。但我只是一个商人,在商海中干得还不错。我没有接受过高等教育,即使我真的有慧根,这慧根也早已枯死了。”
“没关系,她对你非常信赖,她说,你一旦回头,便可立地成佛。”他强调道,“一旦回头,立地成佛,这是沙女士的原话。”
我既感动,也有些好笑,看来这位沙姑姑是赖上我啦!她就只差说“苦海无边,回头是岸”了。不过,如果继承遗产意味着放弃我成功的商业生涯,那沙姑姑恐怕要失望了。但我仍然礼貌地等客人往下说。老于世故的何律师显然洞悉我的心理,笑道:
“我已经说过,这是我最困难的一次律师业务。你是否接受这笔遗产,务请认真考虑后再定夺,你完全可以拒绝的。”他歉然说,“对不起,我现在还不能宣布遗嘱的内容。遵照我当事人的规定,请你先看看这本研究笔记,如果你对它不感兴趣,我们就不必深谈了。请你务必抽时间详细阅读,这是立遗嘱人的要求。”
他从黑提包里取出一本薄薄的笔记,郑重地递给我,然后含笑告辞。
这位狡猾的老律师成功地勾起我的好奇心,我匆匆安排了一天的工作,带上笔记本回到家中。家中没有人,我走进书房,关上门,掏出笔记本认真端详。封皮是黑色的,已有磨损,显然是几十年前的旧物。它静静地躺在我手中,就像是惯于保守秘密的沧桑老人。笔记本里究竟藏有什么秘密?
我郑重地打开它。不,没什么秘密,只是一般的研究笔记,是心得、杂记和一些实验记录。遣词用句很简练,看懂它比较困难,不过我还是认真看下去。后来,我看到一篇短文,一篇不足千字的短文,这篇短文影响了我的一生。
《生命模板》
20世纪后半期,科学家费因曼和德雷克斯勒开启了纳米科学的先河。他们说,自古以来人们制造物品的方法都是“自上而下”的,是用切削、分割、组合的方法来制造。那么,为什么我们不能“自下而上”呢?可以设想制造这样的纳米机器人,它们能大量地自我复制,然后它们去分解灰尘的原子,再把原子堆砌成肥皂和餐巾纸。这时,生命和非生命、制造和成长的界限就模糊了,互相渗透了。
这当然是一个美好的设想,可惜其中有一个重大的缺陷——当纳米机器人大量复制时,当它们把原子堆砌成肥皂和餐巾纸时,它们所需的程序指令从何而来?毫无疑问,这个指令仍是自上而下的,因此就形成宏观世界到纳米世界的信息瓶颈。这个瓶颈并非不能解决,但它会使纳米机器人大大复杂化,使自下而上的堆砌烦琐得无法进行。
有没有简便的真正自下而上的方法?有。自然界有现成的例子——生命。即使最简单的生命,如艾滋病毒、大肠杆菌、线虫、蚊子,它们的构造也是极复杂的,远远超过汽车、电视机等机器。但这些复杂体却能按DNA中暗藏的指令,自下而上地建造起来。这个过程极为高效和低廉。想想吧,如果以机械的办法造出一架功能不弱于蚊子的微型直升机,需要人们做出多么艰巨的努力!付出多少金钱!而蚊子的发育呢,只需要一颗虫卵和一池污水就行了。
由于生命体的极端复杂和精巧,人们常把它神秘化,认为它只能是上帝所创造,认为生命体的建造过程是人类永远无法破译的黑箱。实际上并非如此,只要用还原论的手术刀去剖析它,就会发现它也是一种自组织过程,仅此而已。宇宙中的一切都是由自组织形成——宇宙大爆炸形成的夸克;宇宙星云中产生的星体;地球岩石圈的形成;石膏和氯化钠的结晶;六角形雪花的凝结;等等。宇宙中的四种力:强力、弱力、电磁力和引力是万能的粘黏合剂,是它们促使复杂组织能自发地建造。
生命也是一种自组织,不过是高层面的自组织。两者的区别在于:非生命物质自组织过程是不需要模板的,或者说它也要模板,但这种模板很简单,宇宙中无处不有。所以,太阳和100亿光年外的恒星可以有相同的成长过程;巴纳德星系的行星上如果飘雪花,它也只能是六角,绝不会是五角。而生命体的自组织需要复杂的模板,它们只能产生于难得的机缘和亿万年的进化。但不管怎么说,生命体的建造本质上也是一种物理过程,是由化学键(实质上是电磁力)驱使原子自动堆砌成原子团,原子团变形、拓展、翻卷,直到生命体建造出来。
想造一台微型直升机吗?假如我们找到类似蚊卵的模板(当然不需要吸血功能),让它孵化、发育……这个工作该多么简单!
不过,以蛋白质为基础的生命体有致命的弱点:它太脆弱,不耐热,不耐冻,不耐辐射,寿命短,强度低,等等。那么,能否用硅、锡、钠、铁、铝、汞等金属原子,依照生命体的建造原理,“自下而上”地建造出高强度的纳米机器,或纳米生命呢。
经过30年的摸索,我想我已制造了硅锡钠生命的最简单的模板。
也许我确实有科学的慧根,我马上被这篇朴实的文章吸引住了。它剖析了复杂的大千世界,轻松地抽出清晰的脉络。尤其是结尾那句简短的、平淡的宣布,纵然是科学的外行也能掂出它的分量。一种硅锡钠生命的模板!一种高强度的,完全异于现有生命形式的新生命!可以断定,我将得到的遗产肯定与之有关。
我立即打电话给何律师,直截了当地问他:“何律师,那种硅锡钠生命是什么样子?现在在哪儿?”
何律师在电话中大笑道:
“沙女士的估计完全正确!她说你会打电话来的。还说如果你不打来电话,律师就可以中断工作了。她没看错你。来吧,我领你去,那种新型生命在她的私人实验室里。”
沙女士的试验室在城郊的一座小山坡上,是一幢不大的平房,屋内有两名工作人员正在安静地工作。何律师引我参观着各屋的设施,耐心解释着。他说,给沙女士当了10年律师,我已成半个纳米科学家啦。他领我到实验室的核心——所谓的生命熔炉。四周是厚厚的砖墙,打开坚固的隔热门,灼热的气浪扑面而来,里面是一个约有100平方米的大熔池,暗红色的金属液在其中缓缓地涌动。看不到加热装置,大概藏在熔池下面吧。透过熔池上方因高热而畸变的空气,能看到对面墙上有一面金属蚀刻像,表现的是一位相貌普通的中年女人,何律师说那就是沙午女士了。她默默俯视着下面灼热的熔池,目光慈爱,又透着苍凉,就像远古的女娲看着她刚用泥土抟成的小人。
何律师告诉我,这是些低熔点金属(锡、铅、钠、汞等)的混合熔液,其中散布着硅、铁、铬、锰、钼等高熔点物质,这些高熔点物质尺寸为纳米级,在熔液中保持着固体形态。我们的变形虫——沙女士说的新型生命——正是以这些纳米级固相原子团为骨架,俘获一些液相金属而组成的。熔池常年保持在490℃正负85℃的范围,这是变形虫最适宜的生存环境。“现在,看看它们的真容吧。”
他按一下按钮,侧面墙上映出图像。图像大概是用X光层析技术拍的,画面一层层透过液体金属,停在一个微小的异形体上。从色度看,它和周围的液体金属几乎难以区分,但仔细看可以看出它四周有薄膜团住。它努力蠕动着,在黏稠的金属液中缓缓地前进,形状随时变化,身后留下一道隐约可见的尾迹,不过尾迹很快就消失了。
“这就是沙女士创造的变形虫,是一种纳米机器,或纳米生命。在这个尺度的自组织活动中,机器和生命这两个概念可以合而为一了。”何律师说,“它的尺度有几百纳米,能自我复制,能通过体膜同外界进行新陈代谢。不过它吃食物只是为了提供建造身体的材料(尤其是固相元素),并不提供能量。它实际是以光为食物,体膜上有无数光电转换器,以电能驱动它体内的金属‘肌肉’进行运动。”
我紧紧盯着屏幕,喃喃地说:“不可思议,真正不可思议!”
“是啊,和地球上的生命完全不同。它的死亡和繁衍更离奇呢。一只变形虫的寿命只有12~16天,在这段时期,它们蠕动、吞吃、长大,然后蜷成一团,使外壳硬化。在硬壳内的物质发生‘爆灭’,重新组合成若干只小变形虫。至于爆灭时生命信息如何向后代传递,沙女士去世前还未及弄清。”
“它们繁殖得很快吗?”
“不快,金属液中的变形虫达到一定密度时,就会自动停止繁殖。我想其内在原因是合适的固相材料被耗尽了。看!快看!镜头正好捕捉到一只快要爆灭的变形虫!”
屏幕上,一只变形虫的外壳显然固化了,在周围缓缓涌动的金属液中,它的形状保持不变。片刻之后,壳体内爆发出一道电光,随之壳内物质剧烈翻动,又很快平静下来,分成四个小团。然后硬壳破裂,四只小变形虫扭转着身体,向四个方向缓缓游走。
我看呆了,心中有黄钟大吕在震响,那是深沉苍劲的天籁,是宇宙的律动。我记得有不少科学家论述过生命的极限环境,但谁能想到,在500℃的金属液中,会有一种金属生命,一种不依赖水和空气的生命?这种生命模板的合成是多么艰难的事,那应该是上帝10亿年的工作,沙姑姑怎么能在几十年的研究中就把它创造出来?我瞻望着她的雕像,心中充满敬畏。何律师关上隔热门,领我回办公室。他说:
“这种生命还相当粗糙,它体内光电转换器的效率还不如普通的太阳能板呢。沙女士说,经过一代代进化后,它们也会像地球生命一样精巧,不过那肯定是几亿年以后的事了。至少在我接手后的5年里,这些慢性子的家伙们没有一点儿变化。”
我问:“这是私人实验室?得不到政府的支持?”
“对,至于原因——我想你能猜到。从实用主义观点看,这种研究恐怕在几千万年内毫无价值。沙女士开始研究时,原是想创造某种能耐高温、有实用价值的纳米机器人。后来她阴差阳错地搞出了这种小变形虫,但一直没有为它找到实际用途。沙女士去世后,委托我用她的财产维持生命熔炉的运转,不过,这笔资金很快就要告罄了。”
他看看我,我看看他,我们都知道这句话的含义。沙女士留给我的,实际是一笔负资产,我一旦接下,就要向这座熔炉投入大量的资金,直到用尽家财。然后……然后该怎么办?再去寻找一个像我这样易于被感动的傻瓜?
但不管怎样,我无法拒绝。这些生命尽管粗糙,终究已脱离物质世界。它们是妙手偶得的孤品,如果生存下去,也许能复现地球生命的绚丽。我怎忍心让它们因我而死呢。童年的科学情结忽然复活了,就像是一泓春水悄悄融化着积雪。我叹口气:“何律师,宣布遗嘱吧。”
“啊,不,”何律师笑道,“遵照沙女士的规定,还有第二道程序呢。请你先看完这封信吧。”
他从皮包中掏出一件封固的信,郑重地递给我。我狐疑地接过来,撕开。信笺上用手写体简单地写着两行字,其内容是那样惊世骇俗:
致我的遗产继承人:
真正的生命是不能圈养的,太阳系中正好有合适的放养地——水星。
我呆住了。我瞠目结舌,太阳穴的血管嘭嘭跳动。那个狡猾的律师似笑非笑地看着我,他一定料到了这封信对我的震撼。是啊,与这两行字相比,此前我看到的一切还值得一提吗?
索拉星
《圣书》《创世纪》
大神沙巫创造了索拉人。沙巫神是父星之独子,住在父星第3星上,那个星球曾是蓝色的,浸在水波之中。20个4152万年前,神来到索拉星上,他见索拉星是好的,光是好的,天地是好的。神说:好的天地,焉能没有活物呢。神伸展身躯,高579亿步,从父星的熔炉里舀出热的汤液,汤液中有小的活物。他把汤液洒遍索拉星的土地。20个4152万年后,小活物长成索拉人。
沙巫神行完这件事,失去了父星的宠爱。父星发怒说:你怎么敢代我行这件事?父星用白色的光剑惩罚了蓝星,毁灭了沙巫的家。沙巫神乘神车逃离蓝星,去了父星照不到的地方。
沙巫神在索拉星上留下化身,化身沙巫睡在北极的寒冰里,躲避着父星。每隔4152万年,化身沙巫醒来,乘神车巡视索拉星。他怜悯索拉人的愚昧,把智慧吹进索拉人的眼睛和闪孔。
沙巫神告诉索拉人:
我的孩子们啊,我偏爱你们,你们有福了。我造出你们的身体比我更强壮,不怕父星的惩罚;你们以光为食,不以生命为食;你们是金属做的身子,不是泥和水做的身子;你们身上有五窍,不是九窍;你们没有雌雄之分,免去作为人的原罪。你们有福了啊。
沙巫神告诉索拉人:
我把神的灵智藏在圣书里,你们什么时候能看懂它呢。看懂圣书的人就能找到极冰中的圣府,神会醒来,带你蒙受父星大的恩宠。
水星素描
水星是离太阳最近的行星,距太阳0.387地球天文单位,即5789万公里。太阳光猛烈地倾泻到水星上,使它成了太阳系最热的行星。它的白昼温度可达450℃,在一个名叫卡路里盆地的地方,最高温度曾达到973℃。由于没有大气保温,夜晚温度可低至-173℃。这个与太阳近在咫尺的星球上竟然也有冰的存在,它们分布于水星的两极,常年保持着-60℃以下的温度。
水星质量为地球的1/25,磁场强度为地球的1/100。公转周期为87.96天,即1000地球年=4152水星年。水星自转周期为58.646天,是其公转周期的2/3,这是由于太阳引力延缓了它的自转速度,造成了一定程度的引力锁定。
水星地貌与月球相似,到处是干旱的岩石荒漠,是陨星撞击形成的寰形山(卡路里盆地就是一颗大陨星撞击而成)。地面上多见一种舌状悬崖,延伸数百公里,这种地形是由水星地核的收缩所形成。水星的高温使一些低熔点金属熔化,聚集在凹部和岩石裂缝内,形成广泛分布的金属液湖泊。由于水星缺少氧化性气体,它们一直保持金属态的存在。夜晚来临时,金属液凝结成玻璃状的晶体。当阳光伴随高温在58.6个地球日之后返回时,金属湖迅速开冻。
如此严酷的自然环境,毫无疑问是生命的禁区——可是,真是如此吗?
“疯了,”我神经质地咕哝道,“真的是疯了,只有疯子才这样异想天开。”
何律师安安静静地看着我:“可是,历史的发展常常需要一两个疯子。”
“你很崇拜沙女士?”
“也许算不上崇拜,但我佩服她。”
我干笑着:“现在我知道这笔遗产的内容了,是一笔数目惊人的负遗产。继承人要用自己的财产去维持生命熔炉的运转,维持到哪一年——天知道。不仅如此,他还要为这些金属生命寻找放生之地,一劳永逸地解决这个问题,而这么做,至少需要数百亿元资金,需要一二百年的时间。谁若甘愿接受这样的遗产,别人一定会认为他也疯了。”
何律师微笑着,简单地重复着:“世界需要几个疯子。”
“那好,现在请你忘记自己的律师身份,你,我的一个朋友,说说,我该接受这笔财产吗?”
何律师笑了:“我的态度你当然知道。”
“为什么该接受?对我有什么益处?”
“它使你得到一个万年一遇的机会,可以干一件前无古人的事。你将成为水星生命的始祖之一,它们会永远铭记你。”
我苦笑道:“要让水星生命进化到会感激我,至少得一亿年吧,这个投资回收期也太长啦。”
何律师笑而不答。
“而且,还不光是金钱的问题。要到水星上放养生命——地球人能接受吗?毕竟这对地球人毫无益处,说不定还会给地球人类增加一个竞争对手呢。”
“我相信你,相信沙女士的眼力,所有困难你都有能力、有毅力去克服。”
我像是蝎蜇似的叫起来:“我去克服?你已坐定我会接受这笔遗产?”
那个狡猾的律师拍拍我的肩:“你会的,你已经在考虑今后的工作啦。我可以宣读遗嘱了吧,或者,你和夫人再商量一次?”
6天后,我们举行了一个小小的正式仪式,我和妻子签字接受了这笔遗产。
我为这个决定熬煎了6天,心神不宁,长吁短叹。我告诉自己,只有疯子才会自愿套上这副枷锁,但海妖的歌声一直在诱惑我,即使塞上耳朵也不行。40亿年前,地球海洋中诞生了第一个能自我复制的蛋白质微胞,那是个粗糙的、微不足道的东西。如果真有上帝,恐怕他也料不到,这种小玩意儿会进化出地球生命的绚烂吧。现在,由于偶然的机缘,一种新型生命投到我的翼下。它是一位女上帝创造的,它能否在水星发扬光大,取决于我的一念之差。这个责任太重了,我不敢轻言接受,也不敢轻言放弃。即使我甘愿作这样的牺牲,还有妻儿呢?我没有权力把他们拖入终生的苦役中。妻子对此一直含笑不语,直到某天晚上,她轻描淡写地说:
“既然你割舍不下,接受它不就得了。”
她说得十分轻松,就像是决定上街买两毛钱白菜。我瞪着妻子:“接下它——你知道这意味着什么?”
“意味着咱俩一生的苦役。不过,如果不能按自己的意愿和兴趣去生活,活一辈子又有什么意义?我知道,如果你这会儿放弃它,老来你一定会后悔的,你会为此在良心上熬煎一生。行了,接受它吧。”
那会儿我望着妻子明朗的笑容,泪水潸然而下。
现在妻子仍保持着明朗的笑容,陪我接受了沙姑姑的遗产。何律师今天很严肃,目光充满苍凉。我戏谑地想,这只老狐狸步步设伏,总算把我骗入毂中,现在大概良心发现了吧。沙午实验室的两名工作人员欣喜地立在何律师身后。屋里还有一个不露面的参加人,就是沙午女士,她正待在那座生命熔炉的上方,透过因高温而颤抖的空气,透过厚厚的墙壁在看着我们,我想她的目光中一定充满欣慰。我特意请来的记者朋友马万壮则是咬牙切齿:
“疯了!全疯了!”他一直低声骂着,“一个去世的女疯子,一对年轻的疯夫妻,还有一个装疯的老律师。义哲,田娅,你们很快会后悔的!”
我宽容地笑着,没有理他。不管怎样反对,他还是遵照我的意见把这则消息捅到新闻媒体中去。我想,行这件事,既需要社会的许可,也需要社会的支持。那么,就让这个计划尽早去面对社会吧。
老马把那篇报道捅出去之后,我立即接到一位朋友的电话,他兴高采烈地说:
“我见到报道了!金属生命,水星放生,一定是愚人节的玩笑吧。”
我说:“不,不是。实际上,那篇报道原来确实打算在4月1日出台,但我忽然悟出4月1日是西方愚人节,于是通知报纸向后推迟4天。”
“正好推迟到4月5号啦,清明节,那这篇报道一定是鬼话喽!”
我苦笑道,慢慢放下话机。
此后舆论的态度慢慢认真起来,当然大多数是反对派。异想天开!地球人类的事还没办完呢,倒去放养什么水星生命!也有人宽容一些,说只要不妨碍人类的利益,人人都可干自己想干的事,只要不花纳税人的钱。
在这些争论中,我沉下心来全力投入实验室的接收工作。我以商人的精打细算,最大限度地压缩实验室的开支。算一算,我的家产能够维持它运转30年。这种生命很顽强,高温能耐到1000℃以下,低温则可耐受到绝对零度。在温度低于320℃时,它们会进入休眠。所以,即使因经费枯窘而暂时熄灭熔炉也没什么关系,只是暂时中断这种生命的进化。
不过,我不会让生命熔炉在我手里熄灭的。我不会辜负沙姑姑的厚望。
晚上,我和妻子常常来到生命熔炉,看那暗红涌动的金属液。或者把图像调出来,看那些蠕动的小生命。这是一些简单的粗糙的生命,但无论如何,它们已超越物质的范畴。1亿年之后,10亿年之后,它们进化到什么样子,谁能预料到呢?看着它们,我和妻子都找到一种感觉,即妻子腹中刚刚诞生一个小生命时的感觉。
老马很够朋友,为我促成一次电视辩论。“或者你说服社会,或者让社会说服你吧。”
我、妻子和何律师坐在演播厅内,面对中央电视台的摄像镜头,聚光灯烤得脸上沁出细汗。演播台另一边坐着七位专家,他们实际是这场道德法庭的法官,不过他们依据的不是刑法,而是生物伦理学的教义。台前是一百多名听众,多数是大学生。
主持人耿越笑着说:“节目开始前,首先我向大家致歉,这次辩论本来应放在水星上进行的,不过电视台付不起诸位到水星的旅费。再说,如果不配置空调,那儿的天气太热了一点。”
听众会心地笑了。
“‘水星放生’这件事已是妇孺皆知,我就不再介绍背景资料了。现在,请听众踊跃提问,陈义哲先生将做出回答。”
一位年轻听众抢着问:“陈先生,放养这种水星生命——这样做对人类有益处吗?”
我平静地说:“目前没有,我想在一亿年内也不一定有。”
“那我就不明白了,劳神费力去做这些对人类无益的工作——为什么?”
我看看妻子和何律师,他们都用目光鼓励我,我深吸一口气说:“我把话头扯远一点儿吧。要知道,生物的本质是自私的,每个个体要努力从有限的环境资源中争取自己的一份,以便保存自己,延续自己的基因。但是,大自然是伟大的魔术师,它从自私的个体行为中提炼出高尚。生物体在竞争中发现,在很多情况下合作更为有益。对于单细胞生命来说,各细胞彼此是敌对的。但当单细胞合为多细胞生命时,各个单细胞就化敌为友,互相协作,各有分工,从而在生存环境中处于更有利的地位。于是,多细胞生命便发展壮大。概而言之,在生物进化中,这种协作趋势是无所不在的,而且越来越强。比如,人类合作的领域就从个体推至家庭,推至部族,推至国家,推至不同的人种,乃至于人类之外的野生生物。在这些过程中,生命一步步完成对自身利益的超越,组成范围越来越大的利益共同体。我想,人类的下一步超越将是和外星生命的融合。这就是我倾尽家财培育水星生命的动机,我希望那儿进化出一种文明生物,成为人类的兄弟。否则,地球人在宇宙中太孤单了!”我说,“其实,在一个月前我还没有这些感悟,是沙女士感化了我。站在沙教授的生命熔炉前,看着暗红涌动的金属液中那些蠕动的小生命,我常常有做父母的感觉。”
一位中年男人讥讽地说:“这种感觉当然很美妙,不过你不要为了这种感觉,而培育出人类的潜在竞争者。我估计,这种高温下生存的生命,其进化过程必定很快吧,也许1000万年后它们就赶上人类啦。”
我笑了:“别忘了,地球的生命是40亿年前诞生的,如果担心地球生命竞争不过40亿年后才起步的晚辈,那你未免太不自信了吧。”
耿越说:“说得对,40亿岁的老祖父,1000万岁的小囡囡,疼爱还来不及呢,哪里有竞争?”
观众笑起来,一位女听众问:“陈义哲先生,我是你的支持者。你准备怎么完成沙女士的托付?”
我老实承认:“不知道。至少到目前为止我还不知道。我的家产能在30年内维持生命熔炉的运转,但30年后怎么办?还有,怎样才能凑出足够的资金,把这些生命放养到水星上?我心里没有一点数。不管怎样,我会尽我的力量,这一代完不成,那就留给下一代吧。”
听证会进行了近两小时,七名专家或称七名法官一直一言不发,认真地听着,不时在纸上记下一两点,从表情上看不出他们的倾向性。最后耿越走到演播台中央说:“我想质询已相当充分了,现在请各位专家发表自己的意见吧。你们对水星放生这件事,是赞成、反对还是弃权?”
七位专家迅速在小黑板上写字,同时举起黑板,上面齐刷刷全是同样的字:弃权!听众骚动起来,耿越搔着头皮说:
“如此一致呀!我很怀疑七位裁判是否有心灵感应?请张先生说说,你为什么持这个态度。”
坐在第一位的张先生简短地说:“这件事已远远超越时代,我们无法用现代的观点去评判将来的事。所以,弃权是最明智的选择。”
埋在索拉星北极冰层中的沙巫圣府快要露面了,透过厚厚的深绿色的极冰,已能隐约看到圣府中的微光。牧师胡巴巴进入了神灵附体的癫狂状态,向外发射着强烈的感情场,胸前的闪孔激烈地闪烁着,背诵着圣书旧约和新约篇的祷文。破冰机飞转着,一步一步向前拓展。胡巴巴俯伏在白色的冰屑中向化身沙巫遥拜,脑袋和尾巴重重地在地上叩击,打得冰屑四处飞扬。
科学家图拉拉立在他身后,不动声色地看着,助手奇卡卡背着两个背囊(那里有四个能量盒),站在他的身边。
这次的“圣府探查行动”是图拉拉促成的,他已经150岁了,想在“爆灭”前找到圣书中屡次提到的圣府——或者确认它不存在。他原想教会要极力反对,但他错了,教会的反应相当平和,甚至相当合作。他们同意这次考查,只是派了牧师胡巴巴作监督。图拉拉想,也许教会深信圣书的正确?圣书说,化身沙巫睡在北极的极冰中;圣书说,能看懂圣书的人就能找到极冰中的圣府,唤醒大神,蒙受大的恩宠。千百年来,无数自认读懂圣书的信徒争着到北极去朝拜,但没有一个人活着回来。现在,教会可能想借科学的力量来证明圣书的正确。
想到这儿,图拉拉不禁微微一笑。近500年来科学的力量越来越强大,几乎能与教会分庭抗礼了。比如说,眼前这位虔诚的胡巴巴牧师就受惠于科学,他的尾巴上也装着一个能量盒,科学所发明的能量盒,否则,“以光为食”的他就不可能来到无光的北极。
这次向北极行进的路上,图拉拉看到了无数的横死者,他们是一代代虔诚的教徒,按圣书的教诲,沿着从圣坛伸向北极的圣绳,来寻找沙巫神的圣府。当他们逐渐脱离父星的光照后,体内能量渐渐耗竭,终于倒在路上。对这些横死者,教会一直讳莫如深。因为,这些人死前没找到死亡配偶,没经过爆灭,灵魂不得超生,这是圣诫三罪(不得横死,不得信仰伪神,不得触摸圣坛和圣绳)中第一款大罪。但这些人又是可敬的殉教者。教会是该诅咒他们,还是褒扬他们呢?
图拉拉决定,从北极返回时,他要把这些横死者收集起来,配成死亡配偶,让他们在光照下爆灭。图拉拉倒不是相信灵魂超生,但总不能任这些人永远暴尸荒野吧。
破冰机仍在转着,现在已经能确定前面就是圣府了,因为极冰中露出40根圣绳,在此汇集到一块儿,向圣府延伸。圣府中射出白色的强光,把极冰耀得璀璨闪亮。牧师胡巴巴让工人暂停,他率领众人作最后一次朝拜,诚惶诚恐地祈祷着。人群中只有图拉拉和奇卡卡没有跪拜。牧师愠怒地瞪着他们,在心中诅咒着,你们这些不尊崇沙巫神的异教徒啊,神的惩罚马上要降临到你们身上!
奇卡卡不敢直视牧师,也不敢正视自己的导师,他的感情场抖颤着,两个闪孔轻微地闪烁,像是询问自己的导师,又像是自语:难道化身沙巫真的存在?难道圣书上说的确实是真理?因为圣书说的圣府就在眼前啊。
图拉拉看到助手的动摇,他佯作未见,苍凉地转过身去。他一向知道奇卡卡不是一个坚强的无神论者,常常在科学和宗教之间踟蹰。图拉拉本人在100年前就叛离了宗教,麾下聚集一大批激进的年轻科学家。他们坚信图拉拉在100年前提出的生物进化论,相信索拉人是由低等生物进化而来(这一点已有许多古生物遗体给出证明),坚信圣书上全是谎言。但是,在对宗教举起叛旗100年后,图拉拉本人反倒悄悄完成圣书的回归。
他不信宗教,但相信圣书(指圣书的旧约篇),因为圣书中混着很多奇怪的记载,这些记载常常被后来的科学发展所确证。比如,圣书上说:索拉星是父星的第1星,蓝星是父星的第3星。这些圣谕被人们吟哦了数千年,从不知是什么含义。直到望远镜的出现刺激了天文学的发展,科学家才知道,索拉星和蓝星都是父星的行星,而其排列顺序完全如圣书所言!
又比如,《圣书》〈旧约〉第39章中规定了索拉星的温度标定,以水的凝结为0度,水的沸腾为100度。可是,索拉星生命在几亿年的进化中从没有接触过水!只是在近代,科学家才推定在南北极有极冰存在。那么,圣书中为什么做这种规定,这种规定又是从何而来呢。
难道真有一个洞察宇宙,知过去未来的大神吗?
还有,索拉星赤道附近的20座圣坛,也一直是科学家的不解之谜。在那些圣坛上,黑色的平板永不疲倦地缓缓转动,永远朝着父星的方向。每座圣坛都有两根圣绳伸出来,一直延伸到不可见的北方。圣书上严厉地警告,索拉人绝不能去触碰它,不遵圣诫的人会被狠狠击倒,只有伏地忏悔后才能复苏。图拉拉不相信这则神话,他觉得圣坛中的黑色平板很可能是一种光电转换器,就如索拉生物的皮肤能进行光电转换一样。问题是——是谁留下这些技术高超的设备?以索拉人的科学水平,500年后也无法造出它!
正是基于这个信念,他才尽力促成了对圣府的考察。现在已经可以确认圣府的存在了,圣书上那个神秘缥缈的圣府已经明明白白地摆在眼前。如果化身沙巫真的住在这里……图拉拉迫不及待想见到他。
最后一层冰墙轰然倒塌,庄严的圣府豁然显现。这是一个冰建的大厅,厅内散射着均匀的白光,穹顶很高,厅内十分空旷,没有什么杂物,只有大厅中央放着一辆——神车!圣书上提到过它,无数传说中描绘过它,3120年前的史书中记载过它。这正是化身沙巫的坐骑呀。神车上铺着黑色的平板,与圣坛上的平板一模一样。下面是四个轮子。神车上方是透明的,模样奇特的化身沙巫斜躺在里面。
化身沙巫真的在这里!洞外的人迫不及待地拥进去。以胡巴巴为首,众人一齐俯伏在地,用脑袋和尾巴敲击着地面,所有人的闪孔都在狂热地祷告着:至上的沙巫大神,万能的化身沙巫,你的子民向你膜拜,请赐福给我们!
跪伏的人群包括他的助手,似乎奇卡卡的祷告比别人更狂热。只有图拉拉一人站立着。众人合成的感情场冲击着图拉拉,他几乎也不由想俯伏在地,但他终于抑制住自己,快步上前,仔细观看化身沙巫的尊容。
化身沙巫斜倚在神车内,模样奇特而庄严。他与索拉人既相似又不相似,他也有头,有口,有胳臂和双手,有双眼,有躯干;但他的尾巴是分叉的,分叉尾巴的下端也有指头。他身上有五处奇怪的凸起:脑袋正前方有一个长形凸起,其下有两孔;脑袋两侧两个扁形凸起,各有一孔。两条尾巴开始分岔的地方有一个柱形凸起,上面有一个孔。胸前没有闪孔,图拉拉惊讶地想,没有传递信息的闪孔,沙巫们如何互相交谈?他们都是哑人吗?不过把这个问题先放放吧。他现在要先验证圣书上最容易验证的一条记载。他仔细数了沙巫身体上的孔窍,没错,确实是九窍,而不是索拉人的五窍。
圣书又对了啊。图拉拉呆呆地立着,心中又惊又喜。
他又仔细观察神车内部。车前方放着一个金质的塑像,塑像只有半身,与沙巫神一样,头部有七窍,不过这尊塑像的头上有长毛,相貌也显然不同。这是谁?也许是沙巫神的死亡配偶?他忽然看到更令人震惊的东西,一本圣书!圣书是崭新的,但封面的字体却是古手写体,是3000年前索拉先人使用的文字。在图拉拉的一生中,为了击败教会,他曾认真研究过圣书,对圣书的渊源、版本和讹误知之甚清。他一眼看出这是第二版圣书,内容只有旧约而无新约,刊行于3120年前。这版圣书现在已极为罕见。
胡巴巴也看到了圣书,他的祈祷和跪拜也几近癫狂。等他抬起头,看见图拉拉已经打开车门,捧住圣书,胡巴巴立即从闪孔射出两道强光,灼痛了图拉拉的后背。图拉拉惊异地转过身,胡巴巴疯狂地喊道:
“不许渎神者触摸圣书!”他挤开科学家,虔诚地捧起圣书,恶狠狠地说,“现在你还敢说神不存在吗?你这个渎神者,大神一定会惩罚你的!”他不再理会图拉拉,转向众人说:“我要回去请示教皇,把沙巫神的圣体迎回去。在我回来之前,所有人必须离开圣府!”
他捧着圣书领头爬出去,众人诚惶诚恐地跟在后面。奇卡卡负疚地看看自己的老师,低下脑袋,最终也去了。胡巴巴走到洞口时,看到留在洞中的科学家,便严厉地说:
“你,要离开圣府。化身沙巫不会欢迎一个渎神者。”
图拉拉不想与他争执,他的闪孔平和地发射着信息:“你们回去吧,我不妨碍你们,但我要留在这里……向化身沙巫讨教。”
胡巴巴的闪孔中闪出两道强光:“不行!”
图拉拉讥讽地说:“胡巴巴牧师的脾气怎么大起来啦?不要忘了,你是在科学的帮助下才找到圣府的。如果你逼我回去,那就请把你尾巴上的能量盒取下来吧,那也是渎神的东西,圣书从未提到过它。”
牧师愣住了,他想图拉拉说得不错,圣书的任何章节中,甚至宗教传说中,都从未提到过这种能量盒。它是渎神者发明的,但它非常有用,在这无光的极地,没有了能量盒,他会很快脱力而死,而且是不得转世的横死。他不敢取掉能量盒,只好狂怒地转过身,气冲冲地爬走了。
那次电视辩论之后的晚上,何律师在我家吃了晚饭。席间他告诉我:“义哲,你实际已经胜利了,对这件事,法律上的‘不作为’就是默认和支持。现在没人阻挡你了,甩开膀子干吧。”
他完成了沙午姑姑的托付,心情十分痛快,那晚喝得酩酊大醉,笑嘻嘻地离开。这时电话铃响了,拿起话机,屏幕上仍是黑的,那边没有打开屏幕功能。对方问:
“你是陈义哲先生吗?我姓洪,对水星放生这件事有兴趣。”
他的声音沙哑干涩,颇不悦耳,甚至可以说,这声音引起我生理上的不快。但我礼貌地说:
“洪先生,感谢你的支持。你看了今天的电视节目?”
对方并不打算与我攀谈,冷淡地说:“明天请到寒舍一晤,上午10点。”他说了自己的住址,随即挂断电话。
妻子问我是谁来的电话?说了什么?我迟疑地说:“是一位洪先生,他说他对水星放生感兴趣,命令我明天去和他见面。没错,真的是命令,他单方面确定了明天的会晤,一点也不和我商量。”
我对这位洪先生印象不佳,短短的几句交谈就显出他的颐指气使。不仅如此,他的语调还有一种阴森森的味道。但是……明天还是去吧,毕竟这是第一个向我表示支持的陌生人。
后来我才知道,我这个勉强的决定是多么正确。
洪先生的住宅在郊外,一庄相当大的庄园。庄园历史不会太长,但建筑完全按照中国古建筑的风格,飞檐斗拱,青砖青瓦,曲径小亭。领我进去的仆人穿一身黑色衣裤,态度很恭谨,但沉默寡言,意态中透着一股寒气。我默默地打量着四周,心中的不快更加浓了。
正厅很大,光线晦暗,青砖铺的地面,其光滑不亚于水磨石地板。高大的厅堂没有什么豪华的摆设,显得空空落落。厅中央停着一辆助残车,一个50岁的矮个男人仰靠在车上。他高度残疾,驼背鸡胸,脑袋缩在脖子里。五官十分丑陋,令人不敢直视。腿脚也是先天畸形,纤细羸弱,拖在轮椅上。领我进屋的仆人悄悄退出去,我想,这位残疾人就是洪先生了。
我走过去,向主人伸出手。他看着我,没有同我握手的意思,我只好尴尬地缩回手。他说:
“很抱歉,我是个残疾人,行走不便,只好麻烦你来了。”
话说得十分客气,但语气仍十分冷硬,面如石板,没有一丝笑容。在他面前,在这个晦暗的建筑里,我有类似窒息的感觉。不过我仍热情地说:
“哪里,这是我该做的。请问洪先生,关于水星放生那件事,你还想了解什么情况?”
“不必了,”他干脆地说,“我已经全部了解。你只用告诉我,办这件事需要多少资金。”
我略为沉吟:“我请几位专家做过初步估算,大约为200亿元。当然,这是个粗略的估算。”
他平淡地说:“资金问题我来解决吧。”
我吃了一惊,心想他一定是把200亿错听为200万了。当然,即使是200万,他已是相当慷慨。为了不伤他的自尊心,我委婉地说:
“太谢谢你了!谢谢你的无比慷慨。当然,我不奢望资金问题一下子全部解决,200亿的天文数字呵,可不是200万的小数。”
他不动声色地说:“我没听错,200亿,不是200万。我的家产不太够,但我想,这些资金不必一步到位吧。如果在10年内逐步到位,那么,加上10年的增值,我的家产已经够了。”
我恍然悟到此人的身份:亿万富翁洪其炎!这是个很神秘的人物,早就听说他高度残疾,丑陋过人,所以从不在任何媒体上露面,能够见到他的只有七八个亲信。他的口碑不是太好,听说他极有商业头脑,有胆略,有魄力,把他的商业帝国经营得欣欣向荣。但手段狠辣无情,常常把对手置于死地。又说他由于相貌丑陋,年轻时没有得到女人的爱情,滋生了报复心理。几年前他曾登过征婚启事,应征女方必须夜里到他家见面,第二天早上再离开,这种奇特的规定难免会使人产生暧昧的猜想。后来,听说凡是应征过的女子都得到一笔数目不菲的赠款,这更使那些暧昧的猜想有了根据。不过这些猜想很可能是冤枉了他。应征女子中有一位年轻漂亮的女律师,大概是姓尹吧,她是倾慕洪其炎的才华而非他的财产。据说她去了后,主人与她终夜相对,不发一言,也没有身体上的侵犯。天明时交给她一笔赠款,请她回家,尹律师痛痛快快地把钱摔到他脸上。不过,这个举动倒促成了二人的友谊,虽说未成夫妻,但成了一对形迹不拘的密友。
虽说他是亿万富翁,但这种倾家相赠的慷慨也令我心生疑窦,关于他的负面传说更增加了疑虑的分量。也许他有什么个人打算?也许他因不公平的命运而迁怒于整个人类,想借水星放生实行他的报复?虽然一笔200亿的资金是万年难求的机缘,但我仍决定,先问清他有没有什么附加条件。
洪先生的锐利目光看透我的思虑——在他面前,我常常有赤身裸体的感觉,这使我十分恼火——他平淡地说:
“我的赠款有一个条件。”
我想,果然来了。便谨慎地问:“请问是什么条件?”
“我要成为放生飞船的船员。”
原来如此!原来就这么一个简单的要求!我不由看看他的腿,心中刹那间产生强烈的同情,过去对他的种种不快一扫而光。一个高度残疾者用200亿去购买飞出地球的自由,这个代价太高昂了!这也从反面说明,这具残躯对他的桎梏是多么残酷。我柔声说:
“当然可以,只要你的身体能经受住宇航旅行。”
“请放心,我这架破机器还是很耐用的。请问,实现水星放生需多长时间?”
“很快的,我已经咨询过不少专家,他们都说,水星旅行在技术上没有太大的难点,只要资金充裕,15~20年就能实现。”
他淡淡地说:“资金到位不成问题,你尽量加快进度吧,争取在15年之内实现。这艘飞船起个什么名字?”
“请你命名吧。你这样慷慨地资助这件事,你有这个权利。”
洪先生没推辞:“那就叫姑妈号吧。很俗气的一个名字,对不?”
我略为思索,明白了这个名字的深意:它说明人类只是水星生命的长辈而非父母,同时也暗含着纪念沙姑姑的意思。我说:“好!就用这个名字!”
他从助残车的袋里取出一本支票簿,填上5000万,背书后交给我:“这是第一笔启动资金,尽快成立一个基金会,开始工作吧!对了,请记住一点,飞船上为我预留一辆汽车的位置,就按加长林肯车的尺寸。我将另外找人,为我研制一个适合水星路面的汽车。”他微带凄苦地说:“没办法,我无法在水星上步行。”
我柔声说:“好的,我会办到。不过,”我迟疑着,“可以冒昧地问一句吗?我想问:你倾尽家财以放养水星生命,是为了什么?只是为了到水星一游吗?”
他平淡地说:“我认为这是件很有趣味的事,我平生只干自己感兴趣的事。”他欠欠身,表示结束谈话。
从此,洪先生的资金源源不断地送来。激情之火浇上金钱之油,产生了惊人的工作效率。当年年底,已经有15000人在为“姑妈号”飞船工作。对“水星放生”这件事,社会上在伦理意义上的反对一直没有停止,但它始终没有对我们形成阻力。
洪先生从不过问我们的工作。不过,每月我都要抽时间向他汇报工作进度,飞船方案搞好后,我也请他过目。洪先生常常一言不发地听完,简短地问:
“很好。资金上有什么要求?”
按洪先生要求,我对他的资助严格保密,只有我妻子和何律师知道资助人的姓名。当然实际上是无法保密的,姑妈号飞船需要的是数百亿元资金,能拿得出这笔资金的个人屈指可数,再加上洪先生不断拍卖其名下的产业,所以,这件事不久就成了公开的秘密。
姑妈号飞船有条不紊地建造着,到第二年,当我去洪先生家时,总是与一位漂亮的女人相遇。她有一种恬淡的美貌,就像薄雾笼罩着的一枝水仙,眉眼中带着柔情。她就是那位尹律师。她与洪先生的关系显然十分亲近,一言一行都显出两人很深的相知。不过,毫无疑问,两人之间是纯洁的友情,这从尹律师坦荡的目光可以确认。
尹律师已经结婚,有一个3岁的儿子。
在我向洪先生汇报进度时,他没有让尹律师回避。显然,尹律师有资格分享这个秘密。谈话中,尹女士常常嘴角含着微笑,静静地听着,偶尔插问一句,多是关于飞船建造的技术细节。我很快知道了这种安排的目的——是她负责建造洪先生将要乘坐的水星车。
那天尹律师单独到我办公室。这是我第一次单独与她会面。我请她坐下,喊秘书斟上咖啡,一边忖度着她的来意。尹律师细声细语地说:
“我想找你商量一下飞船建造的有关技术接口。你当然已经知道,我在领导着一项秘密研究,研制洪先生在水星上使用的生命维持系统。”
我点点头。她把水星车称作“生命维持系统”没有使我意外。要想在没有大气、温度高达450℃、又有强烈高能辐射的水星上活动,那辆车当然也可称作生命维持系统。但尹律师下面的话无疑是一声晴天霹雳,她说:
“准确地说,其主要部分是人体速冻和解冻装置。”
我从沙发上跳起来,震惊地看着她。洪先生要人体速冻装置干什么?在此之前,我一直把洪先生的计划看成一次异想天开的、挑战式的旅行,不过毫无疑问是一次短期旅行。但——人体速冻和解冻装置!
在我震骇的目光中,尹女士点点头:“对,洪先生打算永远留在水星上,看守这种生命。他准备把自己冷冻在水星的极冰中,每1000万年醒一次,每次醒一个月,乘车巡查这种生命的进化情况,一直到几亿年后水星进化出‘人类’文明。”
我们久久地用目光交换着悲凉,我喃喃地说:“你为什么不劝他?让他在水星上独居几亿年,不是太残忍吗?”
她轻轻摇头:“劝不动的,如果他能被别人劝动,他就不是洪其炎了。再说,这样的人生设计对他未尝不是好事。”
“为什么?”
尹女士叹息一声:“恐怕没有人比我更了解他了。命运对他太不公平,给了他一个无比丑陋残缺的身体,偏偏又给他一个聪明过人的大脑。畸形的身体造就了畸形的性格,他心理阴暗,对所有正常人怀着愤懑;但他的本质又是善良的,天生具有仁者之心。他是一个畸形的统一体,仁爱的茧壳箍着报复的欲望。他在商战中的砍伐,他在征婚时对应征者的戏弄,都是这种矛盾心态的反映。不过这些报复都是低度的,是被仁爱之心冲淡过的。但是,也许有一天,报复欲望会冲破仁爱的封锁,那时……他本人深知这一点,也一直怀着对自身的恐惧。”
“对自身的恐惧?”我不解地看看她。她点点头,肯定地说:“没错,他对自身阴暗一面怀着恐惧,连我都能触摸到它。他对水星放生的慷慨资助,多少是这种矛盾心态的反映。一方面,他参与创造了一种新的生命,满足了他的仁者之心;另一方面,对人类也是个小小的报复吧。想想看,当他精心呵护的水星生命进化出文明之后,水星人肯定会把洪其炎的残疾作为标准形象,而把正常地球人看成畸形。对不?”
虽然心地沉重,我还是被这种情景逗得破颜一笑。尹律师也漾出一波笑纹,接着说:
“其实,想开了,他对后半生的设计也是蛮不错的嘛——居住在太阳近邻,与天地齐寿,独自漫步在水星荒原上,放牧着奇异的生命。每次从长达1000万年的大梦中醒来,水星上的生命都会有你预想不到的变化。彻底摒弃地球上的陈规戒律、庸俗琐碎、浑浑噩噩。有时我真想抛弃一切,抛弃丈夫和孩子,陪伴他到地老天荒——可是我做不到,所以我永远是个庸人。”她自嘲地说,语气中透着凄凉。
这件事让我心头十分沉重,甚至有说不清道不明的愤懑,只是不知道愤懑该指向谁。但我知道多说无益。我回想到,洪先生是在看过那次电视辩论仅仅2小时内就作出了倾家相赠的决定。这种性格果决的人,谁能劝得动呢。我闷声说:“好吧,就成全他的心愿吧。现在咱们谈谈技术接口。”
第二天我和尹律师共同去见他,我们平静地谈着生命维持系统的细节,就像它是我们早已商定的计划。临告辞时,我忍不住说:
“洪先生,我很钦佩你。在我决定接受沙姑姑的遗产时,不少人说我是疯子。不过依我看,你比我疯得更彻底。”
洪先生难得地微微一笑:“谢谢,这是最好的夸奖。”
众人走了,圣府大厅中只留下图拉拉。没有了恼人的喧嚣,他可以静下心来同化身沙巫交谈了,心灵上的交谈。他久久地瞻望着化身沙巫奇特的面容,心中充满敬畏。圣府找到了,化身沙巫的圣体找到了。牧师及信徒们喜极欲狂。不过,他们错了。化身沙巫的确存在,他也的确是索拉生命的创造者。但他不是神,而是来自异星的一个科学家。图拉拉为之思考多年,早就得出了这个结论。在他对化身沙巫的敬畏中,含着深深的亲近感。科学家的思维总是相通的,不管他们生活在宇宙的哪个星系,都使用同样的数字语言,同样的物理定律,同样的逻辑规则。所以他觉得,在他和化身沙巫之间,有着深深的相契。
他已经捋出化身沙巫的来历及经历:他来自父星系第三星(蓝星),是20个4152万年前来的(为什么是有零有整的4152万年?他悟到,4152万个索拉星年恰恰等于1000万个蓝星年,沙巫是按母星的纪年方式换算过来)。那时他创造了一种新型的、与蓝星生命完全不同的生命——并不是创造了索拉人,而是一种微生命——将它撒播在索拉星上,然后把进化的权杖交还给大自然。为了呵护自己创造的生命,化身沙巫离开母星和母族,在索拉星的极冰中住了20个4152万年。不可思议的漫长啊。当他独自面对蛮荒时,他孤独吗?当他看着微生命缓慢地进化时,他焦急吗?当他终于看到索拉星生命进化出文明生物时,他感到欣喜吗?
从他神车中有3000年前的圣书来看,他大约在3000年前醒来过,那时他肯定发现索拉人有了二进制语言,有了文字。但那时的索拉人还很愚昧。他无法以科学来启发他们的灵智,只好把一些有用的信息藏在圣书里,以宗教的形式去传播科学。
圣书说,只要看懂圣书,就能找到圣府,那时,化身沙巫就会醒来,带索拉人去蒙受父星大的恩宠——什么“大的恩宠”?一定是一个浩瀚璀璨的科学宝库,索拉人将在一夕间跃升几万年、几十万年,与神(化身沙巫)们平起平坐。
这个前景使图拉拉非常激动,开始着手寻找化身沙巫留下的交代。化身沙巫既然在圣书中邀请索拉人前来圣府,既然答应届时醒来,那他肯定留下了唤醒他的办法。图拉拉寻找着,揣摩着,忽然发现了一个秘密的冰室。门被冰封闭着,但冰层很薄,他用尾巴打破冰门,小心地走进去。冰室里堆着数目众多的圆盘,薄薄的,有一面发着金属的光泽。这是什么?他凭直觉猜到,这一定是化身沙巫为索拉人预备的知识,但究竟如何才能取出这些知识,他不知道,绞尽脑汁也想不出来。这不奇怪,高度发展的技术常常比魔术更神秘。
但墙上的一幅画他是懂得的,这是幅相当粗糙的画,估计是化身沙巫用手画成。画的是一个索拉人,用手指着胸前的两个闪孔。画旁有一个按钮,另有一个手指指着它。图拉拉对这幅画的含意猜度了一会儿,下决心按下这个按钮。
他的猜测是正确的,墙上的闪孔立即开始闪烁,明明暗暗。图拉拉认真揣摩着,很快断定,这正是二进制的索拉人语言。闪烁的节奏滞涩生硬,而且,其编码不是索拉人现代的语言,而是3000年前的古语言,但不管怎样,图拉拉还是尽力串出它所包含的意义。
“欢迎你,索拉人,既然你能来到无光的北极并找到圣府,相信你已经超越蒙昧。那么,我们可以进行理智的交谈了。”
巨大的喜悦像日冕的爆发,席卷他的全身。他终生探求的宝库终于开启了。那边,闪孔的闪烁越来越熟练,一个10亿岁的睿智老人在同他娓娓而谈,他激动地读下去。
“我就是圣书中所说的化身沙巫,来自父星系的蓝星。20个4152年前,蓝星系的科学家创造了一种全新的生命,我把它撒到水星上,并留下来照看它们的成长。我看着它们由单胞微生物变成多胞生物,看着它们离开金属湖泊而登陆,看着它们从无性生物进化出性活动(爆灭前的配对),看着它们进化出有智慧的索拉人。这时我觉得,10亿年的孤独是值得的。”
“我的孩子们啊,索拉人类的进步要靠你们自己。所以,这些年来我基本没干涉你们的进化,只是在必要时稍加点拨。现在,你们已超越蒙昧,我可以教你们一些东西了。你们如果愿意,就请唤醒我吧。”
下面他介绍唤醒自己的方法。他的苏醒必须按照严格的程序,稍有违犯,就会造成不可逆的死亡。图拉拉这才知道,神圣的沙巫种族其实是一种极为脆弱的生命。他们须臾离不开空气,否则会憋死。他们还会热死、冻死、淹死、饿死、渴死、病死、毒死……可是,就是这么脆弱的生命,竟然延续数十亿年,并且创造出如此先进的科技!图拉拉感慨着,认真地读下去。他真想马上唤醒这位10亿岁的老人,对索拉人来说,他可以被称作神灵了。
他忽然感到一阵晕眩,知道是能量盒快耗尽了。他爬过去找自己的背囊,那里应该有四个能量盒。但是背囊是空的!图拉拉的感情场一阵战栗,恐慌向他袭来。面前这个背囊是奇卡卡的,肯定是奇卡卡把自己的背囊带走了。他当然不是有意害自己,只是,在刚才的宗教狂热中,奇卡卡失去了应有的谨慎。
该怎么办?大厅中有灯光,但光量太弱,缺少紫外光以上的高能波段,无法维持他的生命。看来,他要在沙巫的圣府里横死了。
圣书中有严厉的圣诫:索拉人在死亡前必须找到死亡配偶,用最后的能量进行爆灭,生育出两个以上新的个体。不进行爆灭的,尤其是死后又复苏的,将为万人唾弃。其实,早在圣书之前,原始索拉人就建立了这条伦理准则。这当然是对的,索拉人的躯体不能自然降解,如果都不进行爆灭,那索拉星上就没有后来者的立足之地了。
横死的索拉人很容易复生(只需让他接受光照),但图拉拉从没想过自己会干这种丑事。不过,今天他不能死!他还有重要的事去办,还要按沙巫的交代去唤醒沙巫,为索拉人赢得“大的恩宠”,他怎么能在这时死去呢。头脑中的晕眩越来越重,已经不能进行有效的思考了,他必须赶紧想出办法。
他在衰弱脑力许可的范围内,为自己找到一个办法。他拖着身躯,艰难地爬到厅内最亮的灯光之下。低能光不能维持他的生存,但大概能维持一种半生半死的状态。他无力地倒下去,但他用顽强的毅力保持着意识不致沉落。闪孔里喃喃地念诵着:
“我不能死,我还有未了之事。”
2046年6月1日,在我接受沙午姑姑遗产的第14年,“姑妈号”飞船飞临水星上空,向下喷着火焰,缓缓地落在水星的地面上。
巨大的太阳斜挂天边,向水星倾倒着强烈的光热。这儿能清楚地看到日冕,它们向外延伸至数倍于太阳的外径。在太阳两极处的日冕呈羽状,赤道处呈条状,颜色淡雅,白中透蓝,舞姿轻盈,美丽惊人。水星的天空没有大气,没有散射光,没有风和云,没有灰尘,显得透明澄澈。极目之中,到处是暗绿色的岩石,扇状悬崖延伸数百公里,就像风干杏子上的褶皱。悬崖上散布着一片片金属液湖泊,在阳光下反射着强烈的光芒。回头看,天边挂着的地球清晰可见,它蓝得晶莹,美丽如一个童话。
这个荒芜而美丽的星球将是金属变形虫们世世代代的生息之地。
我捧着沙姑姑的遗像,第一个踏上水星的土地。遗像是用白金蚀刻的,它将留在水星上,陪伴她创造的生命,直到千秋万代。舱内起重机缓缓放着绳索,把洪先生的水星车放在地面上。强烈的阳光射到暗黑色的光能板上,很快为水星车充足能量。洪先生掌着方向盘,把车辆停靠在飞船侧面。他的头发已经花白,脸色仍如往常一样冷漠,但我能看出他内心的激动。
洪其炎是飞船上的秘密乘客,起飞前他已经“因心脏病突发,抢救无效而去世,享年64岁”。我们发了讣告,举行了隆重的葬礼,社会各界都一致表示哀悼。虽然他是个怪人,虽然他支持的“水星放生”行动并没得到全人类的认可,但毕竟他的慷慨和献身令人钦服。现在,他倾力支持的“姑妈号”飞船即将起飞,而他却在这个时刻不幸去世,这是何等的悲剧!而其时,洪先生连同他的水星车已秘密运到飞船上。洪先生说:
“这样很好,让地球社会把我彻底忘却,我可以心无旁骛,留在水星上干我的事了。”
飞船船长柳明少将指挥着,两名船员抬着一个绿色的冷藏箱走下舷梯。里面是20块冷凝金属棒,那是从沙午姑姑的生命熔炉中取出的,其中藏着生命的种子。飞船降落在卡路里盆地,温度计显示,此刻舱外温度是720℃。宇航服里的太阳能空调器嗡嗡地响着,用太阳送来的光能抵抗着太阳送来的酷热。如果没有空调,别说宇航员了,连那20块金属棒也会在瞬间熔化。
5个船员都下来了,马上开始工作。我们打算在一个水星日完成所有的工作,然后留下洪先生,其余人返回地球。5个船员将在这儿建一些小型太阳能电站,通过两根细细的超导电缆送往北极。电缆是比较廉价的钇钡铜氧化物,只能在-170℃以下的低温保持超导性,不过这在水星上已足以胜任了。白天,太阳能电站转换的电量将就近储存在蓄电瓶内;晚上,当气温降到-170℃时,电源便经超导电缆送到遥远的极地。在那儿它为洪先生的速冻和解冻提供能源。至于每个复苏周期中那长达1000万年的冷藏过程,则可以由-60℃的极冰自动致冷,不必耗用能源,所以,一个小型的100千瓦发电站就足够了。不过为了绝对保险起见,我们用20个结构不同的发电站并成一个电网。要知道,洪先生的一觉将睡上1000万年。1000万年中的变化谁能预想得到呢?
我和柳船长乘上洪先生的跑车,三人共同去寻找合适的放生地。这辆生命之舟设计得十分紧凑,车身覆盖着太阳能极板,十分高效,即使在极夜微弱的阳光中,也能维持它的行驶。车后是小型食物再生装置和制氧装置,能提供足够一人用的人造食品和空气。下面是强大的蓄电瓶,能提供10万千瓦时的电量,其寿命(在不断充放电的条件下)可以达到无限长。洪先生周围是快速冷凝装置,只要一按电钮,便能在2秒钟内对他进行深度冷冻。1000万年后,该装置会自动启动,使他复苏。他身下的驾驶椅实际是两只灵巧的机械腿,可以带他离开车辆,短时间出去步行,因为,放养生命的金属湖泊常常是车辆开不到的地方。
洪先生聚精会神地开着车,在崎岖不平的荒漠上寻找着道路,我和柳船长坐在后排。为了方便工作,我们在车内也穿着宇航服。老柳以军人的姿态端坐着,默默凝视着洪先生的白发,凝望着他高高突起的驼背和鸡胸,以及瘦弱畸形的腿脚,目光中充满怜悯。我很想同洪先生多谈几句,因为,在此后的亿万年中,他不会再遇上一位可以交谈的故人了。不过在悲壮的气氛中,我难以打开话题,只是就道路情况简短地交谈几句。
洪先生扭过头:“小陈,我临‘死’前清查了我的财产,还余几百万吧。我把它留给你和小尹了,你们为这件事牺牲太多。”
“不,牺牲最多的是你。洪先生,你是有仁者之爱的伟人。”
“伟人是沙女士。她,还有你,让我的晚年有了全新的生活,谢谢。”
我低声说:“不,是我该向你表示谢意。”
车子经过一个金属湖,金属液发出白热的光芒。用光度测温计量量,这儿有620℃,对于那些小生命来说高了一些。我们继续前行,又找到一处金属湖,它半掩在悬崖之下,太阳光只能斜照它,所以温度较低。我们把车停下,洪先生操纵着机械腿迈下车,我和柳船长揣上两块金属棒跟在后边。金属湖在下方100米处,地形陡峭,虽然他的机械腿十分灵巧,但行走仍相当艰难。在迈过一道深沟时,他的身子趔趄一下,我下意识地伸手去扶,老柳摇摇手止住我。是的,老柳是对的。洪先生必须能独力生存,在此后的亿万年中,不会有人帮助他。如果他一旦失手摔下,只能以他的残腿努力站起来,否则……我鼻梁发酸,赶快抛开这个念头。
我们终于到了湖边,暗红的金属液面十分平静。我们测量出温度是423℃,溶液中含有锡、铅、钠、水银,也有部分固相的锰、钼、铬微粒,这是变形虫理想的繁殖之地。我们从怀中掏出金属棒交给洪先生,他把它们托在宇航服的手套里,等待着。斜照的阳光很快使它们融化,变成小圆球,滚落在湖中,与湖面融合在一起。少顷,洪先生把一枚探头插进金属液中,打开袖珍屏幕,上面显示着放大的图像。探头寻找到一个变形虫,它已经醒了,慵懒地扭曲着,变形着,移动着,动作十分舒曼,十分惬意,就像这是它久已住惯的老家。
三个人欣慰地相视而笑。
我们总共找到10处合适的金属湖,把20块“菌种”放进去。在这10个不相连的生命绿洲里,谁知道会发生什么事?也许它们会迅速夭折,当洪其炎从冷冻中复苏过来后,只能看到一片生命的荒漠;也许它们会活下来,并在水星的高温中迅速进化,脱离湖泊,登上陆地,最终进化出智慧生命。那时,洪先生也许会融入其中,不再孤独。
太阳缓缓地移动着,我们赶往天光暗淡的北极。那儿的工作已经做完。暗绿色的极冰中凿出一个大洞,布置了照明灯光,40根超导电缆扯进洞内,汇集在一个接头板上,再与水星车的接口相连。冰洞内堆放着足够洪先生食用30年的罐头食品,这是为了预防食物再生装置一旦失效。只是我们拿不准,放置数千万年的食物(虽然是在-60℃的低温下)还能否食用。
我们把洪先生扶出来,在冰洞中开了一次聚餐会。这是“最后一次晚餐”,以后洪先生就得独自忍受亿万年的孤独了。吃饭时洪先生仍然沉默寡言,面色很平静。几个年轻的船员用敬畏的目光看他,就像在仰望上帝。这种目光拉远了他同大伙儿的距离,所以,尽管我和老柳做了最大的努力,也没能使气氛活跃起来。
我们在悲壮的氛围中吃完饭,洪先生脱下宇航服,赤身返回车内,沙女士的金像置放在前窗玻璃处。我俯下身问:
“洪先生,你还有什么话吗?”
“请接通地球,我和尹律师说话。”
接通了。他对着车内话筒简短地说:“小尹,谢谢你,我会永远记住你陪我度过的日子。”
他的话语化作电波,离开水星,向一亿公里外的地球飞去。他不再说话,静静地等待着。10分钟后才传来回音,我们都在耳机中听到了,尹女士带着哭声喊道:
“其炎!永别了!我爱你!”
洪先生恬淡地一笑,向我们挥手告别。在这个刹那,他的笑容使丑陋的面孔变得光彩照人。他按下一个电钮,立时冷雾包围了他的裸体,凝固了他的笑容。2秒钟后他已进入深度冷冻。我们对生命维持系统作了最后一次检查,依次向他鞠躬,然后默默退出冰洞,向飞船返回。
5个地球日后,“姑妈号”飞船离开水星,开始长达1年的返程。不过,大家都觉得我们已经把自身生命的一部分留在这颗星球上了。
不知过了多长时间,图拉拉隐约感到人群回来了,圣府大厅里一片闹腾。他努力喊奇卡卡,喊胡巴巴,没人理他,也许他并没喊出声,他只是在心灵中呼喊罢了。闹腾的人群逐渐离开,大厅里的振动平息了。他悲怆地模模糊糊地想,我真的要在圣府中横死么?
能量渐渐流入体内,思维清晰了,有人给他换了能量盒。睁开眼,看见奇卡卡正怜悯地看着他。他虚弱地说道:
“谢谢。”
奇卡卡转过目光,不愿与他对视,微弱地闪道:“你一直在低声唤我的名字,你说你有未了之事。我不忍心让你横死,偷偷给你换了能量盒。现在——你好自为之吧。”
奇卡卡像躲避魔鬼一样急急跑了,不愿意和一位丑恶的“横死复生者”待在一起。图拉拉感叹着,立起身子,看见奇卡卡为他留下四个能量盒,足够他返回到有光地带了。化身沙巫呢?他急迫地四处查看。没有了,连同他的神车都没有了。他想起胡巴巴临走说:要禀报教皇,迎回化身沙巫的圣体,在父星的光辉下唤他醒来。一阵焦灼的电波把图拉拉淹没,他已知道沙巫的身体实际上是很脆弱的,那些愚昧的信徒们很可能把他害死。他可是索拉人的恩人啊。
他要赶快去制止!这时他悲伤地发现,在经历了长期的半死状态后,他身上的金属光泽已经暗淡了。这是横死者的标志,是不可豁免的天罚。如果他不赶紧爆灭,他就只能活在人们的鄙夷和仇恨中。
但此刻顾不了这些。他带上能量盒,立即赶回戛杜里盆地。那是索拉星上最热的地方,所有隆重的圣礼都在那儿举行。
他爬出无光地带,无数横死者还横亘在沿途。他歉然地想,恐怕自己已没有能力实现来时的承诺,无力收敛他们了。进入有光地带后,他看到索拉人成群结队向前赶,他们的闪孔兴奋地闪烁着:化身沙巫的复生大典马上要举行了!图拉拉想去问个详细,但人群立即发现他的耻辱印,怒气冲冲地诅咒他,用尾巴打他。图拉拉只好悲哀地远远避开。
一个索拉星日过去了,他中午时赶到戛杜里盆地的中央。眼前的景象令他瞠目,成千上万的索拉人密密麻麻地聚在圣坛旁,群聚的感情场互相激励,形成正反馈,其强度使每个人都陷于癫狂。连图拉拉也几乎被同化了,他用顽强的毅力压下自己的宗教冲动。
好在癫狂的人群不大注意他的耻辱印,他夹在人群中向圣坛近处挤去。神车停在那里,车门关闭着,化身沙巫的圣体就在其中,仍紧闭着双眼。人群向他跪拜,脑袋和尾巴猛烈地撞击地面。这种撞击原先是杂乱的,逐渐变成统一的节奏,竟使地面在一波波撞击中微微起伏。
教皇出来了,在圣坛边跪下,信徒的跪拜和祈祷又掀起一个高潮。这时,一个高级执事走上前,让大家肃静。这是奇卡卡!看来教皇对这位背叛科学投身宗教的人宠爱有加,他的地位如今已在胡巴巴之上了。奇卡卡待大家静下来,朗朗地宣布:
“我奉教皇敕令,去北极找到极冰中的圣府,迎来化身沙巫的圣体。此刻,沙巫神将在父星的光辉下醒来,赐给我们大的恩宠!教皇陛下今天亲临圣坛,跪迎沙巫大神复生!”
教皇再次叩拜后,奇卡卡拉开车门,僧侣上前,想要抬出化身沙巫的圣体。图拉拉此刻顾不得个人安危,闪孔里射出两道强光,烙在一名僧侣的背上,暂时制止住他。图拉拉发出强烈的信息:
“不能把他抬出来,那会害死他的!”他急中生智,又加了一句有威慑力的话:“是沙巫神亲口告诉我的,你们不能做渎神的事!”
人们愣住了,连教皇也一时无语。奇卡卡愤怒地转过身,大声说:“不要听他的,他是一个横死者,不许他亵渎神灵!”
人们这才发现他的耻辱印,立刻有一条尾巴甩过来,重重地击在他的背上。他眼前发黑,但仍坚持着发出下面的信息:
“不能让化身沙巫受父星的照射,你们会害死他的!”
又是狂怒的几击,他身体不支,瘫倒在地。仍有人狠狠地抽击他。奇卡卡恶狠狠地瞪图拉拉一眼,举手让众人静下来。迎圣体的仪式开始了。四个僧侣小心地把化身沙巫抬出车,众人的感情场猛烈地迸射、激励、加强,千万双闪孔同时感颂着沙巫神的大德和大能。
这种感情场是极端排外的,现场中只有图拉拉的感情是异端,他头疼欲裂,像是被千万根针刺着神经。他挣扎着立起上身,从人缝中向里看。化身沙巫的圣体已摆放在一个高高的圣台上,教皇领着奇卡卡、胡巴巴在伏地跪拜。图拉拉的神经抽紧了,他想可怕的事马上就要发生了。化身沙巫坐在圣台上,眼睛仍然紧闭着。在父星强烈的照射下,在720度的高温中,他的身躯很快开始发黑,水分从体内猛烈蒸发,向上方升腾,在他附近造成了一个畸变的透明区域。随之他的身体开始冒烟,淡淡的灰烟。然后,焦透的身体一块块迸脱,剩下一副焦黑的骨架。
教皇和信徒们都目瞪口呆,这是怎么回事?索拉人的金属身体从不怕父星的曝晒,那些未经爆灭的遗体能千万年保存下来。但化身沙巫的圣体为什么被父星毁坏?人们想到刚才图拉拉的话:“不能让他受父星的照射,你们会害死他的。”他们开始感到恐惧。千万人的恐惧场汇集在一起,缓缓加强,缓缓蓄势,寻找着泄洪的口子。
教皇和奇卡卡的恐惧也不在众人之下——谁敢承担毁坏圣体的罪名?如果有人振臂一呼,信徒们会把罪人撕碎,即使贵为教皇也不能逃脱。时间在恐惧中静止。恐惧和郁怒的感情场在继续加强……忽然奇卡卡如奉神谕,立起身来指着那副骨架宣布:
“是父星惩罚了他!他曾逃到极冰中躲避父星,但父星并没有饶恕他!”
恐惧场瞬时间无影无踪,信徒们的神经一下子放松了。是啊,圣书中确实说过,化身沙巫失去父星的宠爱,藏到极冰中逃避父星的惩罚。现在大家也亲眼看见是父星的光芒把他毁坏了。奇卡卡抓住了这个时机,恶狠狠地宣布:
“杀死他!”
他的闪孔中闪出两道杀戮强光,射向沙巫的骨架。信徒们立即仿效,无数强光聚焦在骨架上,使骨架轰然坍塌。教皇显然仍处在慌乱中,他没有在这儿多停,起身摩挲着奇卡卡的头顶表示赞赏,随后匆匆离去。
信徒们也很快散去。虽然他们用暴烈的行动驱走恐惧,但把暴力加在化身沙巫的圣体上,这事总让他们忐忑不安。片刻之后,万头攒动的场景不见了,只留下圣坛上一副破碎的骨架,一辆砸扁了的神车,一副白金雕像,还有地上一个虚弱的图拉拉。
图拉拉忍着头部的剧痛,挣扎着走到骨架边。灰黑色的骨架散落一地,头颅孤零零地滚在一旁,两只眼睛变成两个黑洞,悲愤地瞪着天边。片刻之前,他还是人人敬仰的化身沙巫,是一个丰满坚硬的圣体,转瞬之间被毁坏了,永远不可挽救了。图拉拉感到深深的自责。如果他事先能见到教皇,相信凭自己的声望,能说服他采用正确的方法唤醒沙巫——毕竟教皇也不愿圣体遭到毁坏呀。可惜晚了,来不及了,这一切都是由于缺少一个备用能量盒,是由于自己该死的疏忽。
他深深地俯伏在地,悲伤地向化身沙巫认罪。
他立起身,小心地搜集化身沙巫的骨架。为什么这样做?不知道,他没有什么目的,只是想以这种下意识的动作来驱散心中的悲伤和悔恨。只是到了2000年后,当科学家根据基因技术(在沙巫留下的大批光盘里有详细的解说)从幸存的骨架中提取了化身沙巫的基因并使他复活之后,索拉人才由衷地赞叹图拉拉的远见。
此后1000年是索拉星的黑暗时期,狂热的教徒砸碎了和科学有关的一切东西,连索拉人曾广泛使用的能量盒,也被当做渎神的奇技淫巧被全部砸坏。羽翼未丰的科学遭到迎头痛击,一蹶不振,直到1000年后才慢慢恢复元气。
沙巫教则达到极盛。他们仍信奉沙巫,但化身沙巫不再被说成沙巫大神的使者,他成了一尊伪神,一个罪神。信徒的祈祷词中加了一句:
“我奉沙巫大神为天地间唯一的至尊,
我唾弃伪神,他不是大神的化身。”
不过,沙巫教中悄悄地兴起一个小派别,叫赎罪派。据说传教者是一个横死后复生的贱民。他们仍信奉化身沙巫是大神的使臣和索拉人的创造者,他们精心保存着两件圣物,一件是焦黑的头骨,一件是白金制的塑像。赎罪派的教义中,关于沙巫之死的是非是这样说的:化身沙巫确实是沙巫的化身,原打算给索拉星带来无上的幸福。但他被索拉人错杀了,幸福也与索拉人交臂而过。
尽管新教皇奇卡卡颁布了严厉的镇压法令,但赎罪派的信徒日渐增多。因为赎罪派的教义唤醒了人们的良知,唤醒了潜藏内心深处的负罪感。对教廷的镇压,赎罪派从不做公开的反抗,他们默默地蔓延着,到处搜集与科学有关的一切东西:砸碎的能量盒,神车的碎片,残缺不全的图纸和文字等。在那位180岁的赎罪派传教者去世后,再没人能懂得这些东西,但他们仍执著地收藏着,因为——传教者说过,等化身沙巫在下一个千禧年复活时,它们就有用了。
赎罪派只尊奉圣书的旧约篇而扬弃新约篇。他们在旧约篇上加了一段祷文:
化身沙巫越权创造了索拉人,父星惩罚了他。
索拉人杀死了化身沙巫,你们得到父星的授权了吗?
索拉人啊,
你们杀死了自己的生父,你们有罪了;
你们要世世代代背负着原罪,直到化身沙巫复生。
苔藓-艾丽丝·门罗
========================
!苔藓-[[艾丽丝·门罗]]
-----
斯泰拉的爸爸在俯瞰休伦湖的白垩岩上造了这幢房子,作为夏季避暑的地方。她家人称之为“避暑小屋”。第一次看到它时,大卫很是吃惊,因为它毫无这一叫法所暗示的那种松木虬曲的风韵、遮风挡雨的温馨。他是一个被斯泰拉家人称为“来自不同背景”的城市男孩,对于夏季避暑地毫无概念。这房子过去是,现在还是一幢高大的光秃秃的木屋,涂成灰色模仿附近的旧农庄,尽管或许没有后者结实。房子前方是陡峭的岩壁—同样不怎么结实,不过毕竟延续至今—以及一条通向下方沙滩的长长的台阶小径。屋后是一个围着篱笆的小院子,还有一条短短的沙子小路和一片野黑莓灌木。斯泰拉在小院子里以相当的技术和手段种着蔬菜。
大卫将车拐上小路,正逢斯泰拉拿着一小篓黑莓,从灌木丛中走出。她是个矮胖的白发女人,穿着牛仔裤和脏兮兮的T恤。根据他的判断,这些衣服下没有穿戴任何支撑或束紧她身体的东西。
“瞧瞧斯泰拉成什么样了,”大卫气呼呼地说,“都快变成个巨魔了。”
凯瑟琳之前从未见过斯泰拉,礼貌地评论道:“是啊。她更老了。”
“比什么更老,凯瑟琳?比这幢房子更老?比休伦湖更老?比那只猫更老吗?”
菜园边的小路上躺着一只睡眼蒙眬的猫。一只老大的姜黄色雄猫,耳朵打架撕碎了,一只眼蒙着白翳。它叫大力神,自打大卫在的时候就在了。
“她是年纪更大了嘛,”凯瑟琳在抗议的冲动下反驳道。即便是在抗议,她仍旧显得很温顺。“你明白我的意思。”
大卫觉得斯泰拉是故意这样出场的。这不仅是对自然老化的逆来顺受—唉,不是的,比这糟多啦。斯泰拉总喜欢把事情搞大。不过,这不仅限于斯泰拉。就有一种女人到了这个年纪,非得从女性的外形中挣脱,炫耀起满身的肥肉或者难看的皮包骨头,长起鼓突的疙瘩和脸上的毛发,拒绝遮挡住苍白的、青筋暴突的腿部,而且对此几乎是沾沾自喜,好像这就是她一直以来的理想似的。彻头彻尾就是些憎恨男人的女人嘛。现如今,你还不能大声说出这类观点。
他停得离黑莓灌木太近了—对凯瑟琳而言太近了,她从副驾驶座挤出车门,立刻遇到了麻烦。凯瑟琳身材苗条,但她的连衣裙裙摆很长,还有长长的、波浪起伏的袖子。这是一件蛛网似的棉布做的裙子,从粉色过渡到玫瑰色,打着很多小小的不规则的褶子,形似皱纹。是一件漂亮的裙子,不过在斯泰拉的地盘上,这可不是一个好选择。黑莓灌木密密地钩住它,凯瑟琳没完没了地摘着钩子,试图脱身。
“大卫啊,天哪,你可以给她留点空当的嘛。”斯泰拉说。
凯瑟琳对自己的窘境发笑了。“我没事,我很好,真的。”
“斯泰拉,凯瑟琳。”大卫介绍着。
“吃点黑莓吧,凯瑟琳。”斯泰拉同情地说,“大卫?”
大卫摇摇头,凯瑟琳拿起两枚黑莓。“真可爱,”她评论道,“给太阳晒暖了。”
“我看它们都看得恶心啦,”斯泰拉说。
凑近看,斯泰拉稍微像样了一点—光滑的皮肤晒得黑黑的,头发像孩子一样剪得短短的,一双大大的棕色眼睛。凯瑟琳比她高出不少,高挑、瘦弱、骨感,满头金发,皮肤细嫩。她的皮肤是那样细嫩,以至于根本不能用化妆品,而且动辄由于感冒、食物或者情绪而发红。最近她试着用起蓝色眼影和黑色睫毛膏,大卫觉得这是个错误。刷黑那些稀疏的睫毛,正好突出了她水汪汪的蓝色眼睛,那颜色浅得好像都无法承受日光,也强调了眼睛下面干巴巴的皮肤。大约一年半前,大卫第一次遇到凯瑟琳,以为她只有三十出头。他觉得她保留了不少女孩气质,爱上了她的美貌、高挑和脆弱。从那时起她就开始日益老去。而且,她根本也比他以为的要老得多—已近四十了。
“但是你打算拿它们做什么?”凯瑟琳问斯泰拉,“做果酱吗?”
“我已经做了差不多有五百万罐果酱了,”斯泰拉说,“把它们灌进有那种艺术兮兮的方格棉布盖儿的小罐子,送给所有邻居。他们要么是太懒,要么是太精了,都不去摘自己的黑莓啦。有时我也不明白,我干吗不让这些大自然的慷慨赠品在藤上烂掉算了。”
“不是长在藤上,”大卫说,“是长在那些人神共愤的带刺灌木上的,它们该被清空、烧掉才对。那样就有地方停车了。”
斯泰拉对凯瑟琳说:“听听,他好像还是我丈夫似的。”
斯泰拉和大卫结婚二十一年。分居八年。
“不错,大卫,”斯泰拉大度地回答,“我应该清掉它们的。我该干而一直没着手干的事有一长串啦。进来吧,等我换件衣服。”
“我们还得去一趟卖酒的店,”大卫说,“我路上没来得及。”
每年夏天,他都要进行一次这样的拜访,时间尽可能安排在斯泰拉爸爸的生日前后。他总是带去同样的礼物—一瓶苏格兰威士忌。今年是岳父九十三岁生日。他住在几英里远的一个护理中心,斯泰拉一周可以去看他两三回。
“我得洗个澡,”斯泰拉说,“然后穿件鲜艳点的衣服。不是为了爹地,他现在完全瞎了。不过我想其他人会喜欢的,看到我穿件粉红啊蓝色啊什么的,他们会像看到个气球一样开心起来呢。你们两个还有点时间喝一小杯。对了,也可以帮我倒上一杯。”
她领着他们,一个接一个沿小路走进屋。大力神没动弹。
“懒畜生,”斯泰拉说,“他快要像爹地一样了。你觉得这房子需要油漆吗,大卫?”
“是啊。”
“爹地总说每隔七年就要刷一次。我不知道啊—我正在考虑装上外墙。我得有更好的防风设施。虽然已经装了点御寒设备,可我总感觉像住在个透风的板条箱里似的。”
斯泰拉全年住在这里。一开始,两个孩子中的这个或者那个时不时会陪她住住。但现在,保罗在俄勒冈学习森林学,迪尔德丽在巴西一所英语学校教书。
“不过,你可不可以涂上外墙那种颜色呢?”凯瑟琳说,“它多好看呀,那种可爱的风吹日晒的颜色。”
“我想用奶油色。”斯泰拉说。
独自一人在这样的环境中,在这幢房子里,斯泰拉过的是一种忙碌的,甚至可以说是混乱的生活。他们穿过后走廊和厨房走向起居室,一路上这种生活的痕迹随处可见。这里有几盆她种的盆栽植物,还有她提到的果酱—她解释说,并不曾全部送掉,留了一些等着在糕点拍卖会和秋季集市上用。这里还有她的全套制酒设备。此外,俯瞰湖面的长条形起居室里有她的打字机,周围一摞一摞都是书和纸。
“我在写回忆录,”斯泰拉说。她向凯瑟琳做了个两眼朝天的鬼脸。“给我钱我就不写。不,没事啦,大卫,我是在写一篇关于老灯塔的东西。”她把远处的灯塔指给凯瑟琳看。“你朝窗外看,看到最远那里,就可以看到它了。我在给历史学会和本地报纸写一篇文章。差不多算是崭露头角的女作家啦。”
除了历史学会,她说,她还加入了戏剧阅读小组、教堂合唱团、制酒人俱乐部,以及一个非正式团体,其成员每周举行价钱固定(便宜)的晚餐聚会,互相做伴。
“测试我们的创造力,”她说,“总是会测试点什么。”
而这些仅仅是其中多少比较有组织的那部分罢了。她的朋友可谓五花八门。退休到此的人们,在重新装修的农场房子里,或者安装了过冬设施的夏季小屋里安下家;背景各异的年轻人们,他们接手了土生土长的农夫再也不想要了的岩石嶙峋的老农场。还有一个本地的牙医及其朋友,是同性恋。
“现在我们这儿宽容得出奇啊,”斯泰拉嚷道,她走进浴室,努力压过水流的声音。“我们并不是非要男女搭配。这对我们这些被淘汰的老婆们来说挺不赖的。我们有差不多半打人呢。其中有一个会织布。”
“我找不到汤力汽水。”大卫从厨房里喊道。
“是一罐一罐的。在冰箱旁边地板上的盒子里。这女人自己养羊。我是说会织布的那个女人,她有自己的纺车。她会纺羊毛,织成布。”
“老天爷啊。”大卫若有所思地感叹道。
斯泰拉关掉龙头,啪啪地拍水。
“我以为你会喜欢那样呢,你瞧,我还没到那个地步。我只是做做果酱。”
很快,她用毛巾裹着身子走出来,问:“我的酒在哪里呢?”毛巾上方的两角掖在她一只胳膊下,下方的两角晃荡着,摇摇欲坠。她接过一杯金汤力[1]。
“我要在试衣服的时候喝。我有两套新的夏季套装,一套是火红色的,另一套是绿松石色的。可以混着搭配它们。反正不管怎么穿,看起来都挺抢眼。”
凯瑟琳从起居室走来取她的饮料,像喝水一样猛喝了两口。
“我爱这幢房子。”她带着一种柔和的热情说道,“真的。它是这样质朴、谦和。到处都亮堂堂的呢。我一直在琢磨它让我想起了什么,现在我明白了。你看过英格玛·伯格曼的那部老电影吗,讲一家人住在岛上的一幢夏季别墅里?一幢可爱的简陋的房子。那女孩疯了。我记得那会儿就思忖过,那才是避暑小屋该有的样子呢。可它们从来都不是那样的。”
“就是那部上帝变成了一架直升机的电影吗,”大卫说,“女孩和她兄弟躲在一艘小船底下鬼混。”
“我得说,我们这儿从来就没有这么有意思的事,”斯泰拉在卧室墙那边说,“我可不能说什么时候真的喜欢过伯格曼的电影。我一向觉得它们有点阴森,神经兮兮的。”
“这里的谈话到处都能听到,”大卫对凯瑟琳说,“注意到没?没有哪堵墙连到天花板的。浴室除外,感谢老天。这可真有助于家庭生活啊。”
“每次大卫和我想私下说点什么,都得把脑袋埋到被子里才成,”斯泰拉说。她从卧室走出来,穿了一条绿松石色的弹力裤和一件无袖上衣。上衣是白底绿松石色的花朵和树叶图案。她好像总算穿了件文胸。一条浅色带子若隐若现,啮进肩膀的皮肉里去。
“记得有天晚上我们上了床,”她说,“聊着是不是买辆新车,在说不晓得哪种车的油耗是多少之类的,我记不清了。好了,爹地向来迷恋汽车,他精通这些,突然间我们听到他说:‘一加仑跑二十八英里。’诸如此类的。就好像他就在床的另一边似的。当然了,他不在—他躺在自己房间的床上呢。大卫非常淡定,他只是答道:‘哦,多谢,先生。’就好像我们一直就在和爹地聊着天似的。”
大卫从村里的售酒商店走出来,斯泰拉摇下车窗,正在和一对夫妇说话,她介绍了他们:罗恩和玛丽。他们大概六十多岁了,不过晒得黑黝黝的,样子挺利索,穿着情侣格子裤和白色运动衫,戴着格子帽。
“很高兴见到你啊,”罗恩说,“这么说,你过来看到聪明人是怎么过日子的啦?”他听起来很快活,让人想到拳击中的佯攻,或者开玩笑的捶打。“你啥时退休来加入我们啊?”
这让大卫狐疑,斯泰拉有没有说过他们已经分居。
“我还没到退休呢。”
“早点退休吧!我们这儿很多人都是这么干的!我们摆脱了所有那些束缚,那种成天跌爬滚打,挣钱花钱的日子。”
“嗯,我不在其中,”大卫说,“我只是个公务员。我们用纳税人的钱,然后尽量啥事都不干。”
“那不是真的,”斯泰拉谴责道—像个妻子一样。“他在教育部工作,干得很卖力呢。他只是永远不肯承认罢了。”
“一条大蟒蛇[2]!”玛丽咯咯地笑道,“我过去在渥太华上班—那是几辈子之前的事啦—我们通常管自己叫大蟒蛇!公务蛇。公务员。”
玛丽一点也不胖,但她的下巴不知怎的像个胖女人的下巴。它软塌下去,像一系列梯田那样过渡到脖子。
“说实在的,”罗恩说,“这种生活很棒啊。你不会相信我们找到多少事来忙活。每天都嫌短啊。”
“你有很多爱好吗?”大卫问。他突然显出一脸认真相,彬彬有礼、一本正经的。
这种语调让斯泰拉警惕起来,赶紧试图分散玛丽的注意力。“你打算怎么用从摩洛哥带回来的那料子呢?”
“我拿不定主意。可以做成一条迷人的裙子,但实在不像我穿的东西。或者干脆就把它铺床上算了。”
“有那么多活动,你永远有事儿干,”罗恩说,“比如说吧,滑雪。越野的。我们二月份整整十九天都在外面。今年天气太棒了,都不用开车出门。只要沿着后门外的巷子滑出去……”
“我也尽量坚持自己的兴趣爱好来着,”大卫说,“我想那会让人年轻。”
“毫无疑问!”
大卫一只手搁在外套内袋里。他不以为然地笑着,把握在手心里的一个东西给罗恩看。
“我的兴趣之一。”他解释道。
“想知道我给罗恩看的是什么吗?”他们沿着悬崖开往护理中心的途中,大卫问。
“不,谢了。”
“希望罗恩喜欢它。”大卫快活地说。
他唱起歌。他和斯泰拉在大学里因为唱古典牧歌而相识。至少斯泰拉是这么跟人说的。他们也唱些别的,不止牧歌。“大卫是个瘦瘦的纯洁小伙子,有纯净甜美的男高音,我呢是个敦实粗野的小姑娘,有响亮深沉的女低音,”斯泰拉经常这样说,“对此他毫无选择。缘分呐。”
“哦,我的情人啊,你要去往何方?[3]”大卫唱道,直到今天仍未失去优美的男高音。
哦,我的情人啊,你要去往何方?
哦,我的情人啊,你要去往何方?
哦,不要走,再忍忍,真正的爱人就要到来,
哦,不要走,再忍忍,真正的爱人就要到来,
他会唱歌,高音低音通通擅长。
下面沙滩上,斯泰拉的宅子的两头,各有一堵长长的、低矮的岩石墙,一块块岩石由铁丝网兜着摞起来,通到湖里。它们摞在那里,是为了防止沙滩被侵蚀。凯瑟琳坐在其中一堵墙上看着水面,薄薄的裙子和长发被湖风拂动。她的姿态简直可以入画。她真像在拍广告呢,斯泰拉想—要么是为了某种非常私密的、有可能会令人厌恶的东西,要么就是某种体面的、相当盛大的东西,比如人寿保险。
“我一直想问你来着,”斯泰拉说,“她的眼睛有什么问题吗?”
“眼睛?”大卫说。
“她的视力。凑近的话,你会发现她好像不怎么能聚焦。我也不知道怎么形容。”
斯泰拉和大卫站在起居室窗口。从护理中心回来后,他俩都喝了一杯新调的提神酒。归途中他们几乎没有交谈,不过那种沉默不带敌意。他们觉得自己变温和了,变得比较融洽起来。
“据我所知,她视力没什么问题。”
斯泰拉走进厨房,端出烤盘,用蒜瓣和新鲜鼠尾草叶擦着烤猪肉。
“你知道,女人身上会发出一种气息,”大卫站在起居室门口说,“一旦知道你再也不想要她们的时候就会散发出来。一种陈腐的气息。”
斯泰拉拍打着猪肉。
“那两道堤坝要彻底换换铁丝了,”她说,“有些地方铁丝已经磨得像蜘蛛网一样了。你真该去看看。水流的力量,它能把坚硬的铁丝也磨光。我今年秋天得举行一个干活晚会啦。得做好多吃的,邀请一些人过来,确保他们当中体力好的人足够多。我们都是这么干的。”
她把烤肉放进烤箱,洗洗手。
“你去年夏天跟我说的就是凯瑟琳,是吗?她就是那个你说的,有点超凡脱俗的人。”
大卫呻吟一声。“我说了什么?”
“有点超凡脱俗,”斯泰拉一边说,一边砰砰地倒出苹果、土豆、洋葱来。
“好吧,告诉我,”大卫说,他走进厨房,凑近她。“告诉我吧,我都说过些什么?”
“就这么多,真的。我不记得别的了。”
“斯泰拉,跟我说说我都是怎么形容她的。”
“不记得了,真的。我不记得了。”
她当然记得。真真切切地记得他说“有点超凡脱俗”时的口气。他声音中的骄傲和嘲讽。在爱情的阵痛中,他总是会带着温柔的轻蔑来形容那个女人—甚至带着一种惊叹。他总说这真是发疯啦,说他自己也不明白,他明明看得出那人其实根本就不是适合他的类型嘛。然而,然而,然而啊。然而那绝非他所能掌控的,根本无法抵御。他告诉斯泰拉,凯瑟琳信占星术,是个素食者,会画一些怪异的画,比如关在塑料泡泡中的小人儿。
“烤肉,”斯泰拉突然警醒地说,“她肯吃肉吗?”
“什么?”
“凯瑟琳吃肉吗?”
“她没准什么都不会吃。她没准会迷迷糊糊的。”
“我要做个苹果洋葱炖菜。量很大。或许她会吃这个。”
去年夏天,他说:“她是一个幸存下来的嬉皮士,真的。她甚至不知道那年代已经过去了。我想她是从不看报的。她对于世界上正在发生什么可以算是一无所知,除非她能从哪个占卜者那儿听说。那就是她眼中的现实。我想她连地图也看不懂。她全凭本能做事。你知道她干了什么吗?她跑到爱尔兰去看了凯尔经[4]。她听说凯尔经在爱尔兰。她就直接从香农机场的飞机上走下来,向人打听去凯尔经的路怎么走。结果你知道吗,她真的找到了!”
斯泰拉问,这个超凡脱俗的人儿哪来的钱去爱尔兰。
“哦,她有份工作,”大卫说,“算是工作吧。教艺术课,不是全职的。天晓得她会教什么。没准是根据星座来画画吧。”
现在他说的是:“有别人了。我还没告诉凯瑟琳。你觉得她察觉到没有?我感觉是的。我想她察觉了。”
他靠着厨房台子站着,看斯泰拉削苹果。他飞快地伸手到衣服内袋,趁斯泰拉没来得及扭过头去,把一张快照塞到她的眼前。
“我的新女友,”他说。
“看起来像苔藓嘛,”斯泰拉说,削皮刀陡然停止。“再说,它太暗了。在我看来,就是岩石上的一团地衣嘛。”
“别傻了,斯泰拉。别装了。你能看到她的。瞧见她的腿了?”
斯泰拉放下削皮刀,顺从地眯起眼看向照片。地平线上远远地有一对放平的乳房。前景是叉开的双腿。双腿大大地打开—光滑、金色、盛大:一对倾倒的石柱。当中是那团她称为地衣或苔藓的黑色毛丛。不过实际上更像一只动物的深色毛皮,脑袋、尾巴和爪子都被砍掉了。某只倒霉的啮齿动物深色的,丝绒似的毛皮。
“嗯,现在我看出来啦。”她心平气和地说。
“她名叫蒂娜。蒂娜,不是蒂楠哦。她二十二岁。”
斯泰拉没法请他收起照片,哪怕只是不再举在她眼前。
“她是个坏丫头,”大卫说,“哦,她真是个坏丫头!她到修女们那里上学。一旦变野了,就再没有比修道院的女学生更坏的姑娘了!她是凯瑟琳教书的艺术学校里的一个学生。退学了。现在是个鸡尾酒会女招待。”
“在我听来,这并不算多堕落嘛。迪尔德丽读大学时,不也当过一阵鸡尾酒会的女招待。”
“蒂娜跟迪尔德丽可不一样。”
终于,举着照片的手放下了,斯泰拉拿起刀子,重新削起苹果。不过大卫还不肯收起照片。他想要收,旋即又改了主意。
“这个小巫婆,”他说,“她要索我的魂呐。”
他谈论这女孩的声音在斯泰拉听来尤其做作。不过哪里轮得到她来评价大卫怎样是做作,怎样不是呢?他这种特别的声音高亢,单调,顽固,带有一种刻意的,残忍的甜蜜。他想对谁残忍呢—斯泰拉,凯瑟琳,那个女孩,他本人?斯泰拉叹了口气,没料到比预想的更大声,更恼怒。她放下削了一半的苹果,走到起居室,朝窗外看去。
凯瑟琳正从墙上爬下。或者说正在试着爬下来。她的裙子钩在铁丝上了。
“那件漂亮的小破裙儿今天可给她添足了麻烦,”斯泰拉说,被自己糟糕的口音和不乏恶毒的语气吓了一跳。
“斯泰拉。希望你替我保管这张照片。”
“我来保管?”
“我怕我会拿给凯瑟琳看。我一直想这么做。我怕我真会这么做。”
凯瑟琳已经挣脱了,看到他们在窗子后面。她挥了挥手,斯泰拉也挥了挥手。
“我相信你还有别的,”斯泰拉说,“我是说照片。”
“不在身上。我并不是想伤害她。”
“那就不要嘛。”
“她弄得我想伤害她。她用眼泪汪汪的样子缠住我。她吃药。‘心情电梯’。她喝酒。有时候我想,最好的做法或许就是给她来个迎头痛击。致命一击嘛。致命一击,凯瑟琳。拿着吧。迎头痛击。不过我担心她的反应。”
“‘心情电梯’,”斯泰拉说,“‘心情电梯’,直上云霄!”
“我是认真的,斯泰拉。那些药丸能要命的。”
“那是你的好事嘛。”
“真有意思。”
“我其实根本没这意思。不过,每次脱口说出这类话,我都会假装是故意说的。得到的承认越多越好嘛!”
晚餐时,这三个人都感觉好多了,比他们预想的都要开心。大卫心情好多了,是因为他想起售酒商店对面有个电话亭。斯泰拉在做出一顿美餐之后,心情总会大好。凯瑟琳感觉好多了则是药物的原因。
谈话并不困难。斯泰拉讲了几则为自己的文章做调查时读到的故事,关于五大湖区的沉船事件。凯瑟琳对于沉船也知道一些。她有个男朋友—前男友—是个潜水员。大卫慷慨地宣布他妒忌这个家伙,不想听他在深水中的本领。没准他说的是真话。
晚饭后,大卫说他要散个步。凯瑟琳请他随意。“去吧,”她快活地说,“我们这里不需要你。没有你,斯泰拉和我会相处得很好呢。”
斯泰拉很好奇凯瑟琳这种新的声音是打哪儿来的,这种时髦的,相当愚蠢的,像是在调情的声音。喝点酒不至于这样。她吃下的不知什么东西并没有让她变得迟钝,相反倒让她利索起来。层层叠叠的柔弱的歉意,犹犹疑疑的谄媚、畏缩或者希冀,全都一下子被这阵轻快的化学之风刮得无影无踪。
不过,凯瑟琳站起身试图清理桌子时,很明显这种利索仅限于精神层面。凯瑟琳撞到了厨房台面的一个角上。她让斯泰拉想起被截肢的人。截除得不是太多,只是切掉手指尖,或许还有脚趾尖。斯泰拉不得不盯着她,趁碟子还没滑下地,赶紧从她手中拿开。
“你注意到那头发了吗?”凯瑟琳说。她的声音像摩天轮一样忽高忽低。它猛地下降,又陡然爆发,热情洋溢。“他染发啦!”
“大卫吗?”斯泰拉问,这回是真吃惊了。
“每次他想起这个,都会把脑袋朝后仰一点,免得你凑得太近看出来。我想他很怕你会说什么吧。他有点怕你呢。其实,头发看起来很自然。”
“我真没注意。”
“他两个月前开始这么弄的。我说:‘大卫,这有啥关系呢—我爱上你的时候,你的头发就已经开始变灰了,你以为现在我还会在意吗?’爱真是奇怪啊,它会导致奇怪的事情。大卫其实是个敏感的人—他是个容易受伤的人呐。”斯泰拉从凯瑟琳的指缝中抢救下一个正在滑落的酒杯。“它会让你变得刻薄。爱会让你刻薄。要是你觉得离不开谁了,你就会对他们刻薄。我知道大卫就是那样的。”
他们晚餐喝的是蜂蜜酒。斯泰拉这批家酿蜂蜜酒是首次开封,她这会儿回想着它有多么棒,浓稠,冒着泡泡。看着都像香槟了。她查看瓶子里还有没有剩下。大概有半杯。她给自己倒出酒,把杯子放到搅拌器后面,洗起瓶子来。
“你在这里过得不错嘛。”凯瑟琳说。
“我过得很好,确实。”
“我觉得我生活中要有变化了。我爱大卫,但我淹没在这爱中太久了。太久啦。你知道我的意思吗?我在下头的时候看着波浪,数了起来,‘他爱我,他不爱我。’我经常那么做。然后我想,嗯,波浪是没有尽头的,和雏菊花瓣可不一样。甚至和我的脚步也不同,如果我开始计算走到街区尽头的步数的话。我想着,波浪永远、永远都不会有尽头。所以我明白了,这对我来说是个信号啊。”
“别碰那些罐子,凯瑟琳。我等会儿来洗它们。”
斯泰拉为什么不说“坐下吧,我自己弄更方便”?哪怕对那些比凯瑟琳强的帮手们,她都经常这样直言不讳来着。她没这样说,是因为有点警惕。凯瑟琳的状态看起来不怎么稳定,蠢蠢欲动的。万一刺激到她,后果堪忧。
“他爱我,他不爱我,”凯瑟琳说,“就像这样。没完没了的。那就是波浪设法告诉我的。”
“只是好奇问问,”斯泰拉说,“你相信星座吗?”
“你是说我有没有让人帮我占过星座?没有,其实并没有。我知道有人这么干过。我也想过。我猜我没有信到愿意花这个钱的地步吧。我有时会看看报上的这类东西。”
“你看报纸?”
“看一部分。我订了一份,不会全读完。”
“那你吃肉吗?你晚饭时吃猪肉来着。”
凯瑟琳看起来并不介意被盘问,或者甚至都没注意到这是在盘问。
“嗯,我可以只吃沙拉过活,尤其是这样的季节。不过我时不时也会吃肉。我是个非常不坚定的素食者。真好吃啊,那烤肉。你用了大蒜吗?”
“大蒜、鼠尾草和迷迭香。”
“真好吃。”
“那就好。”
凯瑟琳突然坐下,男孩子气地叉开两条长腿,裙摆从两腿当中滑下去。晚餐期间,大力神一直在桌子另一头的第四把椅子上睡觉,现在决然地一跳,落在她的膝盖上。
凯瑟琳笑了:“疯猫。”
“要是你不喜欢,就赶它下去好了。”
现在斯泰拉不需要紧盯着凯瑟琳了,就开始忙着擦洗、摞好碟子,清洗杯子,擦桌子,抖干净桌布,擦洗台面。她感觉心满意足,兴致勃勃。她呷了一小口蜂蜜酒。一首歌谣的旋律涌上心头,她不由自主地唱了几个字,才意识到这就是大卫早些时候唱的那首,“未来如何尚无法预料!”
凯瑟琳发出轻轻一声呼噜,猛地抬起头。大力神没逃开,相反用爪子抓住她的裙子,竭力趴得更稳些。
“是我睡着了吗?”凯瑟琳问。
“你需要喝点咖啡,”斯泰拉说,“撑着点。你恐怕不该现在就睡呢。”
“我累啦。”凯瑟琳固执地说。
“我知道。可你不该现在就睡。撑着点,我们马上就给你灌点咖啡。”
斯泰拉从抽屉里取出一块手巾,浸透冷水,敷到凯瑟琳脸上。
“好啦,接着,”斯泰拉说,“拿着它,我开始弄咖啡了。我们不会让你在这里昏睡过去的,对吗?不然大卫会没完没了地抱怨这事。他会说是因为我的蜂蜜酒,或者我做的饭,或者我的陪伴,或者别的什么。撑住,凯瑟琳。”
电话亭里,大卫开始拨蒂娜的号码。旋即他想起这是长途,必须先找接线员。他拨了接线员的电话,询问电话费是多少,掏空口袋找零钱。他掏出一些二十五分硬币和角子,点出总共一元三十五分,摞在架子上备用。他又开始拨号。手指颤抖,掌心冒汗。腿、腹部和胸部都充满一种蠢蠢欲动的感觉。电话在蒂娜那间挤挤挨挨的公寓里响起第一声铃,这让他的五脏六腑都沸腾起来。真是疯了。他往里塞硬币。
“我会告诉你何时开始投币,”接线员说,“先生?我会告诉你何时开始投币。”他的二十五分硬币叮当叮当掉到退币口,他费了点劲才摸出它们。电话又响了一声,在蒂娜的梳妆台上,在那堆混乱不堪的化妆品、连裤袜、珠子和链子、长羽毛耳环、一个可笑的烟斗、一大堆发条玩具当中。他觉得它们近在眼前:绿色的青蛙、黄色的鸭子、棕色的熊—全都一样大小。青蛙和熊一般个头。此外还有一些太空怪物,都是根据电影中的角色来的。上发条后,这些玩具就会在蒂娜的地板或者桌子上摇摇晃晃,咔嗒走动,嘴里冒出火星。她喜欢让它们赛跑,或者让其中两个相撞。它们奔向未知的路途时,她会兴高采烈地嚷嚷,甚至尖叫。
“好像无人接听,先生。”
“让它再响几声。”
蒂娜的浴室在大厅对面。她和另一个女孩共用它。要是她在浴室,或者甚至在浴缸里的话,要多久才能决定要不要接电话呢?他决定数到十下铃声,从现在开始。
“还是无人接听,先生。”
再数十下。
“先生,你愿意等会儿再打吗?”
他若有所思地挂上。旋即,激动万分地,他拨了询问台。
“你要哪里,先生?”
“多伦多。”
“请讲,先生。”
他询问了一位迈克尔·里德的电话。不,他不知道街道名称。他只知道名字—她的上一任,或许还藕断丝连的男朋友的名字。
“这里没有叫迈克尔·里德的信息。”
“没关系,试试看利德。利—德。”
确实有一位M.利德,在戴文波路。不叫迈克,不过至少首字母是M。那回头再查查。有没有一位M.里德呢?里德?是的。是的,有一位M.里德,住在西姆科大街。还有另一位M.里德,里—德,住在哈伯德。她怎么不早说呢?
他凭直觉选了哈伯德的那个。那里距离蒂娜的公寓不算太远。接线员告诉他号码,他拼命记住。他没有什么用来记录的东西。他觉得不能让接线员再报一遍号码,这一点很重要。不该透露出他在一个电话亭里,手边没有铅笔和钢笔。他觉得他的询问之绝望与鬼祟是昭然若揭的,任何时刻都有可能遭拒,不允许他知道关于住在哈伯德或者西姆科或者戴文波,或者随便哪里的M.里德或者M.利德的任何进一步信息。
现在必须从头打一通了。多伦多的区号。不,要打给接线员。然后是记住的号码。要快,趁他还没失去勇气或者忘记号码。要是她接电话,他说什么好呢?但是她不大可能会接电话,哪怕她真的在那里。M.里德会接电话。然后大卫必须问蒂娜在不在。不过很有可能要换种声音。或许根本就不用男人的声音。他过去经常能在电话里装出各种声音,一度甚至能蒙过斯泰拉。
没准他可以装出一个女人的声音,尖利的那种。或者一个孩子的声音,一个小妹妹的声音。蒂娜在吗?
“请再说一遍,先生?”
“没什么。抱歉。”
“电话响了。我会告诉你何时投币。”
要是M.里德是个女人怎么办?根本就不是迈克尔·里德。是玛丽·里德。吃养老金的。职业女郎。你给我打电话干吗?性骚扰。那么,就回到信息台。试试看西姆科的M.里德。试试看戴文波的M.利德。继续试。
“很抱歉,看来无人接听。”
电话在M.里德的公寓里,或者宅邸里,或者房间里响了一遍又一遍。大卫靠在金属架子上,他的硬币就搁在上面等着。一辆车在售酒商店的停车场停下。里面的两个人正盯着他看。显然是等着用电话。不凑巧的话,没准接着就该是罗恩和玛丽开车来了。
蒂娜住在一家印度进口商店楼上。她的衣服和头发上,除了香烟、麻醉剂和性的味道(大卫觉得那是她的自然体味)之外,总有一股咖喱粉、肉豆蔻、熏香的味道。她的头发染成死沉沉的黑色。脸颊上涂了一团粗野的颜色,眼皮有时涂成砖红色。她有一次去为她认识的什么人在拍的一部电影试镜。她没得到那个角色,因为要把一只驯服的老鼠夹在大腿间,让她犯了恶心。这次失败令她倍感羞耻。
大卫浑身冒汗,不再想捉住她,而是一心只想以随便什么方式找到她,听听她沙哑的年轻的声音,它带有天然的颤音和挥之不去的猥亵感。哪怕在这个时刻,听到它即意味着她已经背叛了他。当然她已经背叛了他。她一直就在背叛他。只要她能接电话(他几乎已经忘了接电话的应该是M.里德才对),他就可以冲她吼叫、斥骂,而要是他感觉足够卑微—他肯定会感到足够卑微的—还可以哀求她。这种机会让他求之不得。任何机会都成啊。晚餐时,他兴致勃勃地与斯泰拉和凯瑟琳聊天时,手指一直在木餐桌底部描着蒂娜的名字。
人们对于这种痛苦不会有任何耐心。又怎么会有呢?受难者必须放弃同情,断绝尊严,自己对付灾难。最糟的是,人们还会煞费苦心地告诉你,这不是真正的爱情。这一波一波的欲望,依赖,膜拜和悖逆,这些心甘情愿但是可怕的转变—它们不是真正的爱情。
斯泰拉过去时常告诉他,他对于爱情并不感兴趣。“甚至也不是性。我觉得你甚至对性也不感兴趣,大卫。我觉得你感兴趣的只是当一个坏坏的大男孩。”
真正的爱情—应该是和斯泰拉继续生活下去,或者娶了凯瑟琳。所谓懂得真正的爱情的人应该是罗恩吧,罗恩和玛丽的那个罗恩。
大卫知道自己在做什么。这就是有意思的地方,他这么想,也这么说过。他知道蒂娜并非真的那样狂野、贪婪或者堕落,像他假装的那样,或者像她自己有时候假装的那样。再过十年,她也不会被她疯狂的生活毁掉,也不会变成什么迷人的婊子。她只会变成个在洗衣店里被孩子们缠着的妇人。那个老派的词“娼妓”,他用来描述她的,其实并不贴切—和她其实没多大关系,就像“嬉皮士”与凯瑟琳没多大关系一样—这会儿凯瑟琳他连想都不愿想。他知道,蒂娜的伪装一旦破裂了,就像凯瑟琳的那样,那他迟早不得不再换人。无论如何,那对他来说都是迟早的事—再换个人。
他对这一切心知肚明,冷眼旁观着自己,不过这种认知和洞察,对于他此刻腹部的震颤、急切甜蜜的腺体分泌和狂乱的祈祷都丝毫不起作用。
“先生?你想继续打下去吗?”
他们这天早些时候拜访的护理中心叫作白壳杨之家,是根据湖边大量生长的白壳杨树命的名。这是十九世纪一位百万富翁建造的一幢巨大的石头宅邸,现如今到处搭着活动坡道和救生梯,已经面目全非了。
前院草坪上那堆轮椅中间,有不少声音召唤着斯泰拉。她喊了好几个名字作答,特地绕过去握握手,送上几个吻。她这里那里来来回回,好似一只肥胖的蜂鸟。
她回到大卫身边时唱道:
我是你的小阳光,矮矮又胖胖
把我转一转,倒一倒![5]
她气喘吁吁地说:“实际上应该是茶壶啦。我想你不会觉得爹地有多大变化的,除了现在眼睛变成全瞎了。”
她领着他穿过刷了绿油漆、装了低矮的假天花板(以节省取暖费)的走廊,走廊里挂着按照数字序号填色的图画,还有消毒水味儿和其他各种味道。后门的门廊上,她爸爸独自坐着,裹着毯子,绑在轮椅上,这是为了防止他跌下来。
爸爸问:“大卫?”
声音仿佛从他体内一个深深的、阴湿的洞穴里发出,受嘴唇、下巴或舌头的阻碍而走了样,后者似乎动也没动。他的脑袋也没挪动。
斯泰拉走到椅子后,搂住他的脖子。她的动作非常轻柔。
“是的,是大卫来了,爹地。”她说,“你认得他的脚步声!”
爸爸没回答。大卫弯腰摸摸老人的手,与想象中不同,它们并不冰凉,而是温暖干燥的。他把威士忌酒瓶塞进这双手。
“小心点,他抓不住。”斯泰拉轻声说。大卫用手稳住酒瓶,斯泰拉推来一把椅子,这样他可以坐在她爸爸对面。
“还是同样的礼物,”大卫说。
岳父发出一声认可的哼哼。
“我去拿几个杯子,”斯泰拉说,“在外面喝酒是违反规定的,不过我通常可以说服他们放宽一点。我会告诉他们这是在庆祝。”
为了习惯岳父的模样,大卫尽量把他想象成一种后人类的产物,某个新物种。活下来对他不仅意味着苟延残喘,还意味着样貌的改变。散布着深蓝斑点的灰蓝色皮肤,发白的眼睛,瘦骨嶙峋的脖子,上面有脆弱的深深的凹洞,仿佛是个雾化玻璃做的瓶子。从这脖子里冒出了更多的声音,一种类似于交谈的表示。发出的是每个音节的核心,湿润的元音由前后的辅音勉强烘托出来。
“路上—挤吧?”
大卫描述了高速公路和次级公路的状况。告诉岳父他最近买了一辆车,是日本货。他讲述了一开始如何没能获得和广告里哪怕有点接近的油耗。不过他去投诉了,坚持不懈,把车退给了交易商。进行了各种调整,现在情况已经改善,油耗比较让人满意了,尽管还没达到之前允诺的水平。
这番谈话看来挺受欢迎。岳父好像听进去了。他点着头,他狭窄、瘦长、发青、后人类的脸上显现出昔日表情的遗迹。一种精明的、庄严的忧虑,对于广告、外国汽车和汽车商人的怀疑。甚至还有一丝狐疑—就像过去一样—操心大卫是否真能像样地处理这类事,以及为他确实有这能力而感到的宽慰。在岳父眼中,大卫始终是个正在学习如何成为男子汉的家伙,某个有可能永远也学不会,永远都无法达到那种坚定沉着、稳重含蓄境界的人。大卫这家伙,选择杜松子酒而不是威士忌,读小说,不懂股票,喜欢撩女人,而且起初只是个教书匠。大卫,这个老是开微型车、外国车的人。不过现在那已经没问题了。微型车不再拥有昔日它们所代表的意义了。即便在这里,在休伦湖边的悬崖上,在生命的尽头,也有一些变化得到了确认,一些改变得到了理解—被一个无法抓握也看不见东西的人。
“有什么关于—拉达的消息吗?”
幸运的是,大卫有个同事开的就是拉达车,许多次无聊的午饭和咖啡茶点时间都进行着关于这辆车的讨论,性能、缺点、购买配件的困难之类。大卫复述了这些,岳父似乎很满意。
“灰色。多尔。灰色多尔。第一辆车—有生以来。杨格大街。六十英里,六十英里。一……一小时。”
“他当然从来不曾以一小时六十英里的速度在杨格大街开过什么灰色多尔,”他们推着她爸爸和他的酒瓶回到他的房间,告了别,沿绿色走廊往回走的时候,斯泰拉说,“根本没有。谁的灰色多尔?它们在他有钱买车之前早停产了。他也从没冒险开过别人的车。这是他的幻想罢了。他已经到达了那个让人飘飘欲仙的阶段—修订过去,让所有他希望发生的事都真的发生。在想我们是否也会到达那个阶段吗?大卫,你的幻想会是什么?不,别告诉我!”
“你的会是什么?”大卫说。
“你没有离开我?你从没想要离开我?我打赌那一定就是你以为的,但我可不那么肯定!爹地看到你真高兴,大卫。对爹地来说,男人就是更重要啊。我猜,要是他想到你和我的事,他会不得不站在我这一边,不过没关系,他不用想这个。”
在护理中心的斯泰拉似乎恢复了一些从前的圆融和柔顺。她对爸爸的关注,甚至对那群坐轮椅者的关注,都让她的举止又有了几分温顺优雅,让她的声音也多了一丝娴静。大卫脑海中涌出十二年或者十五年前她的一个形象。他看到她端着一锅炖菜,在一个郊区派对上穿过草坪。她穿了一条夏裙。那些日子里,她总抱怨自己太胖了,穿不得长裤,尽管那会儿还没现在一半胖。这一幕缘何令他如此动容?斯泰拉走过草坪,一头秀发在阳光中闪耀—那会儿灰发只有几缕,头发显出一种淡金色—赤裸的肩膀晒得黝黑,她嚷嚷着跟邻居打招呼,笑着,诉说着烹饪过程中的某个意外。当然了,她带来的食物美味无比,而且她不光带来了吃的,还带来了人们所期待的邻里聚会的气氛。她用强大的社交魅力,把所有人都吸引到身边。尽管有时斯泰拉的这类天赋令大卫浑身不自在,但这一次他毫无气恼之感。她活泼的佯怒,她的夸大其词,她瞪大眼睛寻求同情的幽默恳求,都曾经让他不快过。他听过她为了讨人开心,添油加醋地描述他们生活中的各种情节—孩子们平时的小事故和不听话,送猫去看兽医,儿子的第一次醉酒,电动割草机的古怪表现,给楼上大厅贴墙纸。她是可爱的妻子,在聚会上光彩照人,她看待事物的方式是那样有趣。有时她简直太奇妙了。你妻子真是个妙人儿啊。
好吧,他原谅了她—他爱着她—在她走过草坪的时候。那一刻,他正用光脚逗弄一个住在附近的有夫之妇的冰冷、棕色、剃过毛、粗里粗糙的小腿肚子,她刚从游泳池里出来,胡乱套着件长长的掩盖一切的猩红色浴袍。一个深色头发,没有孩子,没完没了地抽烟的女人,始终保持着令人心猿意马的沉默—至少在他们关系的那个阶段。(是他的第一次—那个女人—是他和斯泰拉婚姻中的第一次。罗斯玛丽。一个甜蜜阴郁的名字,尽管到头来其实是个声音尖细的平庸女人。)
不仅如此。对本色的斯泰拉油然而生的这种欢喜感觉,这种与她和平共处的意外感受,并不仅仅来自这个—他的大脚趾的非法动作。关于他和斯泰拉的这份醒悟,其实内涵颇深—他们到底是唇齿相依的,只要还能感到这份对于她的好意和温柔,他那隐秘的个人行为就仿佛是在她的祝福底下完成的。
结果斯泰拉并不这么想。而且他们并非唇齿相依,或者说,即便密不可分,也是一种他不得不打破的关系。我们在一起这么久了,就不能设法熬到头吗?斯泰拉当时这么说过,试图开个玩笑。她不明白,或许到现在也没搞清楚,其实那正是原因之一,让事情变得不可能。这个白发苍苍、和他肩并肩穿过护理中心的女人一路拖拽着如此沉重的分量—里面不仅有他的性秘密,还有他夜半时分对上帝的思考,因为精神压力导致的胸痛,他的消化不良,他的逃跑计划—它一度是包括她的,涉及非洲或印尼。他的所有普通和非凡的生活—甚至一些她不大可能知道的事—似乎都为她所掌控着。在一个知道这么多的女人身边,永远不可能有什么轻松,不可能有什么隐秘、舒展可言。她因为洞悉一切而洋洋自得。不过,尽管如此,他还是搂住了斯泰拉。他们拥抱了,两个人都是真心诚意的。
一个年轻女孩正推着推车沿走廊走来,不知是中国还是越南姑娘,她穿着浅绿色制服的身形像孩子一样瘦小,却涂着口红和胭脂。推车上摆了一些纸杯和装了橙汁、葡萄汁的塑料瓶。
“喝果汁的时间到喽!”女孩愉快地,公事公办地吆喝道。“喝果汁喽!橙汁。葡萄汁。果汁来喽!”她没注意大卫和斯泰拉,不过他们还是赶紧分开了,继续走路。大卫感到一阵轻微的,非常轻微的不悦,因为被这样一个年轻美丽的女孩看到自己拥抱斯泰拉。这种感觉不值一提—仅仅是在他心头掠过,旋即消失—不过,他帮斯泰拉推门的时候,她说了:“别介意啊,大卫。我可以是你的姐妹嘛。你可以是在安慰你的姐妹嘛。你的老姐。”
“斯泰拉夫人,著名窥心术大师。”
真怪,他们这样交谈的态度。他们过去常说些辛辣、伤人的话,说的时候偏要假装挺开心:心平气和,甚至故作亲切。如今,这种一度是伪装的语调渗进了他们所有尖锐的情感,被吸收了,深入心底,而那份辛辣虽然还在,却显得陈腐、平庸、流于形式了。
大约一周之后,在清理起居室,为在她家举行的历史学会活动做准备时,斯泰拉找到了这张照片,一张快照。大卫到底还是把它留给她了—藏了起来,但又藏得不够深,就塞在起居室长条形窗子的一角,在窗帘后面,也就是你通常站着看灯塔的地方。
当然,因为躺在阳光中,照片有点褪色。斯泰拉一手抓着抹布,站着打量它。天气真好。窗户开着,她的房子秩序井然,赏心悦目,炉子上炖着一锅美味鱼汤。她看到照片上那团黑色毛发已经变成灰色。一种蓝灰色,或者绿灰色。她记得她第一次看到它时的评价。她说它是苔藓。不对,她说它看起来像苔藓。其实她一下子就知道是什么了。这会儿,她感觉甚至大卫刚把手伸进口袋那会儿,她就知道它是什么了。她感到自己体内那个古老的小穴正在敞开。不过她假装若无其事。她说:“像苔藓。”现在,瞧啊,她的话应验了。胸部的轮廓线已经褪掉。你再也看不出腿是腿了。黑色变成灰色,变成植物柔和、干燥的色泽,这植物神奇地从岩石上得到滋养。
这就是大卫干的好事。他把它留在这里,暴露在阳光下。
斯泰拉的话应验了。这一想法将不断地重现—在她努力延续的日日夜夜的流动中,它是一个停顿,是心跳漏掉的一拍,是一次短暂的,生硬的喘息。
[1] 一种常见的鸡尾酒。—编注
[2] “公务员”一词中的servant与大蟒蛇(serpent)发音近似。
[3] 歌谣出自莎士比亚《第十二夜》。
[4] 凯尔经,或译凯兰书卷,是一部精美的圣经福音手绘书卷,其中的插画异常精美。约完成于八世纪,被誉为爱尔兰的国宝。—编注
[5] 原歌词应为“我是你的小茶壶”。
谈[[果戈理]]《鼻子》的开头-[[阿摩司·奥兹]]
========================
谈果戈理《鼻子》的开头
故事开始了:文学随笔集 阿摩司·奥兹
## 谈果戈理《鼻子》的开头
谈果戈理《鼻子》的开头
-----
尼古拉·果戈理的《鼻子》最早于1836年问世,比冯塔纳的《艾菲·布里斯特》早六十年,比阿格农的《在她风华正茂之年》早九十年。《鼻子》讲述的是一个八品文官科瓦廖夫的鼻子的故事,科瓦廖夫是一个陆军少校,全名叫普拉东·库兹米奇·科瓦廖夫。这个鼻子弃主人而去,到城里四处游荡,它穿上用金线织就的官服,为了快活还雇了一辆四轮马车,到教堂里虔诚地鞠躬、祷告,但到了最后,当它就要凭官方颁发的护照过境去里加时,被警察逮捕了。科瓦廖夫少校本人在故事中要比他的鼻子出场晚得多。开头的一幕发生在清晨时分,地点在理发师伊凡·雅可夫列维奇和他妻子普拉斯科维娅·奥西波芙娜的家中,他们夫妻很显然没有子嗣。
三月二十五日这一天,圣彼得堡发生了一件稀奇古怪的事情。住在沃兹涅先斯基大街的理发师伊凡·雅可夫列维奇(他的姓氏给弄丢了,甚至在他的招牌上——画着脸颊上涂满肥皂的绅士,并写有“本店兼营放血”的字样——也没有任何说明)这天一大早醒来就闻到了热面包的香味。他在床上坐起来,看见他的妻子正从炉子里取出刚刚烤好的面包。她是一个挺受人尊敬的太太,很爱喝咖啡。
“普拉斯科维娅·奥西波芙娜,我今天不喝咖啡了。”伊凡·雅可夫列维奇说,“我只吃些热面包和洋葱就行了。”(在这里我得解释一下,其实,伊凡·雅可夫列维奇既想喝咖啡,又想吃面包,但他知道,要想既喝咖啡又吃面包,那是不可能的,因为普拉斯科维娅·奥西波芙娜可不会纵容他随心所欲。)“就让这个老傻瓜吃面包吧,我可是不在乎,”她心里想,“这样我就可以多喝一份咖啡了!”于是她把一个面包扔到桌上。
伊凡·雅可夫列维奇为了体面起见,在他的长睡衣外面罩上一件长衣,坐到桌子跟前,撒了点盐,削好两个洋葱,拿起餐刀,脸上摆出一副毅然决然的表情,开始切面包。
他把面包切成两半,往中间瞧了一眼,惊奇地看到那里有一个发白的东西。伊凡小心翼翼地用餐刀拨了拨,又用手指头摸了摸。“挺厚实的,”他自言自语地说,“这究竟会是什么东西呢?”
他伸进去两根手指,拽出来一看——原来是一个鼻子!
伊凡·雅可夫列维奇吓得重重地墩回到椅子上,揉了揉双眼,又在面包上摸来摸去。是的,是个鼻子,不会搞错的。而且,看上去还挺眼熟的。伊凡·雅可夫列维奇的脸上露出了惊恐的神色,但这惊恐跟他妻子的愤慨比起来就算不得什么了。
“你这畜牲,你到底把谁的鼻子割下来了?”她怒不可遏地叫喊起来,“你个恶棍!你个酒鬼!我要亲自去警察局告你,我说去就去。你这个盗贼!你倒是想想啊,我听三个主顾说过,人家来刮脸的时候,你总是把人家的鼻子揪过来揪过去的,他们的鼻子居然还没掉下来,简直是奇迹!”
可伊凡·雅可夫列维奇早已吓得半死不活。他心里清楚,这不是别人的鼻子,正是八品文官科瓦廖夫的,这人每逢星期三和星期天都要来刮脸。
“等一下,普拉斯科维娅!我用一块布把它包好,扔到那个墙角:先把它在那儿放一放,然后我再想想办法,把它扔掉就是了。”
“我不想知道!你以为我会让一个割下来的鼻子在我的屋子里搁着?……真是个猪脑袋!你就知道在皮带上磨你的那个破剃头刀,别的事儿烂掉你都不管不问。你这个不务正业的东西!你这个傻瓜!你居然指望我在警察面前替你遮掩过去!你这头臭烘烘的脏猪!傻瓜蛋!把这个鼻子从这儿弄出去,弄出去!随便你怎么处理,但是我不想让这东西在这里晃来荡去了,一分钟都不行!”
和《艾菲·布里斯特》及《在她风华正茂之年》的开头部分形成对照的是,这部作品的开头并不和谐,连表面上的和谐都没有,但是却相当有官僚气息。叙述者的语言,即果戈理在他的彼得堡故事中的语言,很是精细、正式,偶尔会闪现出走火入魔、疯疯癫癫的光芒:他一开头是一则详细的报道——包括月份、日期、城市的名称以及房子的地址——报道了“一件稀奇古怪的事情”。然而,他还没有进入正题,他的报道就离题了,滑入了一对括号里,开始追加一个漏掉的细节,而要填上这些个表格,这个细节很显然就至关重要了:这就是主人公的姓氏。主人公的姓氏和它的主人分开了,“给弄丢了”——这和那个鼻子不久就会遇到的情形一样——为了追加上姓氏,把叙述者从位于沃兹涅先斯基大街的家里拖拽到理发店,再从理发店拖拽到那个招牌上。然而最终他在那个招牌上还是找不到那个漏掉的细节。不过,作为一个很有瘾头的报告者,他还是不厌其烦地报告了一些事实:在理发店的招牌上,有一个绅士的画像,这位绅士脸上涂满肥皂泡,并且承诺“本店兼营放血”,再没有别的东西了。
讲到这里,叙述者不再追加姓氏,恰如其分地结束了括号,继续讲理发师伊凡·雅可夫列维奇的故事:“这天一大早醒来就闻到了热面包的香味。”
故事开头这几行发生的事,即寻找姓氏,在整个故事中会反复出现,寻找丢失的鼻子。在这个故事的每一片丛林后面都潜伏着无序的力量,引诱着故事偏离正道,试图把故事从那体面的、带有官僚气息的又直又窄的道路上引开,尽管这个故事照理是要坚持在这条路上走下去,但是这股无序的力量却一次又一次把它引入了林荫侧道上去。
第二次试图正式开始这则报道——在括号里面放血那一部分之后——是从一个鼻子和烤面包的香味儿写起的。这还不是科瓦廖夫少校那个狡猾、傲慢的鼻子,还不是刚刚烤好的面包卷里蹦出来的那个鼻子的故事。在这个时刻,作者通过那个姓氏已经“给弄丢了”的理发师那睡意朦胧的鼻子,闻到普拉斯科维娅·奥西波芙娜烤的面包的香味,邀请我们进入了故事。
开头这一幕,直到鼻子给割下来为止,都使人闻到一种邋遢的体面,或是不洁的尊严的味道,这股味道贯穿整个故事的始终,总是在意想不到的地方不屈不挠地表现出来:当伊凡·雅可夫列维奇在床上坐了起来,他看见他的妻子,“一位挺受人尊敬的太太”。(可是,“一位挺受人尊敬的太太”和一位仅仅是“受人尊敬的太太”之间是怎么个不同法儿呢?)后来,他“为了体面起见,在他的长睡衣外面罩上一件长衣”(穿给谁看?出于何种目的?),而且,在他切开面包之前,先摆出“一副毅然决然的表情”。从这里直到故事结束,所有的人物或多或少都是“挺受人尊敬的”;他们都会做出彬彬有礼的架势;他们都会“摆出一副毅然决然的表情”;他们每一个人都会阿谀奉承,骗人,献媚,造假——或者是反过来——妄自尊大、趾高气扬、羞辱别人。比如,科瓦廖夫少校和任何人说话,除了居高临下的喝斥或者低三下四的溜须拍马外,再不会说别的话。甚至他在教堂里遇见自己的鼻子,他自己的“血肉”,他在这个傲慢无礼的鼻子面前也巴结奉承,因为他的鼻子虽然弃他而去,他却不敢抓住它(这个鼻子比它的主人地位高,穿的制服也比他华贵)。这样,故事的调子就和故事所描写的现实吻合起来:等级森严的现实,“挺受人尊敬”,披着“一副毅然决然的表情”的外衣,沾染上官僚那愚蠢的习气以及走火入魔的繁文缛节,通过那星星点点的疯疯癫癫,这里强调一下,那里渲染一番;在这样的现实里,所有的人物看上去都同时得体、虚伪、正派、狡诈、过分矫饰;在这一现实中,每个人都深知自己在这个森严的社会等级中的确切位置;每个人都刁难比他地位低的人,巴结比他地位高的人。然而,故事前前后后都是一群无政府主义的狐狸不断啮咬所有这些社会常规,暗中撕扯社会习俗、主导秩序以及逻辑规则。
甚至在这个理发师(他后来也被描绘成一个在好几个方面受人尊敬的人)从面包里拉出来一个鼻子之前,他做了几个琐碎的动作,匆忙的读者不会在这上面逗留的,因为乍一看,这些充其量不过是对普普通通、单调乏味的早餐的平淡无奇、毫无意义的描写;他削洋葱、撒盐、切面包。然而,通过仔细观察会发现,这按部就班的程序是颠倒着来的,是从后往前做的,这样,关于那个会跑的鼻子的主要的荒诞故事甚至还没有发生,小说就染上了些许荒谬、无意义的乖张色彩。
“伊凡·雅可夫列维奇为了体面起见,在他的长睡衣外面罩上一件长衣,坐到桌子跟前,撒了点盐,削好两个洋葱,拿起餐刀……”
但是,伊凡·雅可夫列维奇还没有削洋葱头,凭什么就倒起盐来了?他还没有拿起餐刀,用什么削洋葱头呢?难道我们这位学究气和官气都十足的叙述者报道起来是细致入微,但实际上是个粗心大意的马大哈吗?或许是一个讨人嫌的酒鬼,就像这个理发师和少校,像这个故事中的大多数人物那样?
像这样不合逻辑的细节、心不在焉的小小嘲弄、令人毛骨悚然的怪诞描写,几乎每一页都有。作品的开头部分邀请我们,要我们准备好接受一种像用烤肉扦串起来的被解构了的逻辑,它是这里起作用的力量中不可分割的一部分:令人窒息的枯燥、粗鲁的残暴、道德的沦丧以及生存的绝望。比如,下面一小段凶狠的描写,把无聊、轻蔑和扭曲结合在一起。科瓦廖夫找了一天他那丢失的鼻子,无功而返,“步履踉跄”地回到家。
天已经越来越黑。询问了一天毫无结果,回到家,家里似乎极度的凄凉和压抑。一进门厅,他看见仆人伊凡躺在肮脏的皮沙发上,一个劲儿地朝天花板吐唾沫,而且几乎百发百中地吐在同一个地方。这家伙那一副吊儿郎当的样子可把他气坏了。他用帽子打了他的前额一下,说:“你这头肥猪!你难道就没有什么好事可做!”
伊凡一跃而起,飞奔过来给他脱斗篷。
但愿愚蠢之神别让我们给这个鼻子附上一定的寓意,好几个评论家已经试图这样做了:那个鼻子起床后,穿上一身外交顾问的官服,到城里四处招摇,这在沙皇时代的俄罗斯社会并不是一个寓言,并不能反映人的境况。它只不过是一个鼻子而已,一个活生生的鼻子,上面还有点粉刺。
诚然,科瓦廖夫是个拈花惹草的浪荡公子,而我们这位挺受人尊敬的女士普拉斯科维娅·奥西波芙娜却是打心眼儿里瞧不起她那位当理发匠的丈夫的生殖能力,所以,有的读者就有理由推测,那天一大早,这位丈夫从他妻子那柔软、温暖的面包深处抽出来的科瓦廖夫的鼻子,实际上是代指另一个生殖器官,想到这一层读者就乐了;或者甚至有人会注意到,在面包里发现异物被写得几乎就像是生下了一个意外的根本不想要的后代,一个怪物般的婴孩,这件事使得这位女士勃然大怒,而使她丈夫感到愧疚和恐惧。(最后,这可怜的理发匠兼“接生婆”提议,用一块布把它裹起来,扔出去算了,而那位烤面包的母亲却催促他,并声嘶力竭地责骂:“把这个鼻子从这儿弄出去,弄出去!随便你怎么处理,但是我不想让这东西在这里晃来荡去了,一分钟都不行!”)
这个故事开头的怪诞不仅表现在在面包里发现了鼻子,还突出表现在那位可怜的丈夫和用铁腕对他颐指气使的妻子之间那恐怖的关系上。每天早上,他必须在咖啡和面包之间做出选择,因为绝不允许,甚至连想都不许想“咖啡和面包都要,因为普拉斯科维娅·奥西波芙娜可不会纵容他随心所欲。”当他选择了面包,放弃咖啡的时候,普拉斯科维娅就自言自语:“就让这个老傻瓜吃面包吧……这样我就可以多喝一份咖啡了!”当那个鼻子从温暖的面包里生出来时,奥西波芙娜可不像她丈夫那样吓得目瞪口呆,她没有大吃一惊,而是看到那个白色的东西后勃然大怒。她丈夫在把那个鼻子从面包里抽出来之前,“小心翼翼地用餐刀……拨了拨,又用手指头……摸了摸”。夫妻之间礼节、尊敬和客气的那层薄薄的外壳破碎了,表现出的是恐怖的深渊和暴躁的仇恨。读者应该看一眼理发匠的妻子咒骂丈夫的那一堆恶语:禽兽、酒鬼、盗贼、傻瓜、不务正业的东西、臭烘烘的脏猪、傻瓜蛋。很容易就能看出来,这一堆骂人的话不仅仅是咒骂,也是抱怨,把这位挺受人尊敬的女士和她丈夫之间的关系表现出了一点点,别看这位丈夫在早餐前为了体面起见,在他的长睡衣外面罩上了一件长衣。其中有些骂人话不一定指的是他当理发匠活儿干得不怎么样,听起来更像是指桑骂槐,骂这位可怜的男人日渐衰退的性功能。
因此,《鼻子》开头部分的合同是破绽百出、令人怀疑的。叙述者对他的人物的思考很是老到,但是却不知道他们的姓氏。可以说,还在故事的一开头,他就从家里跑到理发店,追到店铺招牌上找那个姓氏,然后带着多余的信息满载而归,就是没有找到那丢失的姓氏。他还不厌其烦地展现出一对表面是彬彬有礼、相敬如宾的夫妻,但实际上主宰一切的是暴虐、吝啬、性生活不和谐和蔑视。
从这里开始,贯穿整个故事,这位官气十足的叙述者从一大堆恼人的细节快跑到另一大堆自以为是的细枝末节,以学究式的沉迷和狭窄的眼界加以记录,看上去是一个头脑简单的叙述者,不停地为他那些可鄙、贪婪、傲慢、献媚、嫉妒、骗人的人物辩护,而让读者自己去芜存菁。
然而,这也只不过是一个圈套而已。除了别的方面之外,果戈理的天才在这一事实中得以充分表现,即到了最后,还是他那位不诚实的、烦人的、神神道道的叙述者是对的。在这个故事中,没有也不可能有什么去芜存菁。这琐屑的细节就是核心。开头那一份破绽百出、令人生疑的合同毕竟还是公平的——因为科瓦廖夫少校的鼻子出发去探索的那个世界,本身就是破绽百出、令人生疑、具有欺骗性的。
谈加夫列尔·加西亚·马尔克斯的长篇小说-阿摩司·奥兹
========================
母牛怎么可能上到阳台呢?
故事开始了:文学随笔集 阿摩司·奥兹
## 谈加夫列尔·[[加西亚·马尔克斯]]的长篇小说
-----
《族长的秋天》[1]的开头
加夫列尔·加西亚·马尔克斯的长篇小说《族长的秋天》的开头,一群暴徒冲进了总统府。故事的叙述者就是暴徒之一,他描述了这群暴徒发现那位族长的尸体的过程,这位族长已经统治这个国家几百年,如果不是永远的话。
和《乡村医生》以及《米克达莫特》的开头一样,《族长的秋天》的开头部分理想的办法是作为一个没有隔断的长句子来读;此外,这部小说虽然分成了六个部分,每个部分都有数十页,但这部小说是不分段的——给人以一口气讲完的感觉。小说也没有一个故事主线,而是时而描写族长统治的时期,时而描写一个使时间停滞不前的暴君的死亡。开头即是结尾:暴君的死亡及其统治的衰落,并不是由于时间的流逝,而是由于时间的腐烂;时光已经分解成了“无法计数的永恒的时间”(本书以这句话结尾)。从一开始,读者就像是应邀到外层空间的一个黑洞里旅行一样,把手表拨到没有时间概念的钟点。另外,小说虽然是用过去时写的,但是我们最后发现,这个过去不仅仅是讲往事,也讲现在的事,还讲未来的事。它的发展与其说像是一把钻,往里面钻了一层又一层,倒不如说更像是拆开一副俄罗斯套娃[2]。第二部分的开头讲得很清楚,暴君的死亡及其尸体的发现并不仅仅是一时的事件,标志着一个时代的终结,而是一个事件周而复始一而再再而三地发生。
这个死亡的暴君并不是小说开头的那个死亡的暴君的子嗣或继承人。他就是那同一个人,他就是他本人(除非他们当中的一个是个酷肖他的人,而这个人不管从哪个方面讲都是暴君本人)。“我们”依旧是“我们”,尽管“我们谁都没有老到记得最早发生了什么事情”。在第三部分写道:“就这样,他们在他的垂暮之年发现了他……许多年以后,我们又这样发现了他……”;而又在第六部分的开头写道:“当时,他就在那里,仿佛本来就是这个样子,他甚至想过可能不会这样,他躺在那张宴会桌上……”
开头即是结尾:现在,即发现尸体这件事,融汇了未来和过去。此刻即是永恒。这个暴君并不是在活过了几代人之后去世的,而是时而活着,时而死去,实际上甚至不是时而活时而死:他在每一刻都既是活着的,也是死去的,他既是他本人,也不是他本人,因为每一刻都是永恒,因为在这凝固的永恒内部,只有一个东西是不断进行的:即持续不断的腐烂的过程。
这就提供了一个引人入胜的悖论:这里是一篇书面文本,它在竭力克服其基本的性质——它不再是一排文字,一个接着一个,被写下或者读出;它克服了时间那固有的线性的本质。要求读者不动而动,或者是在不动之中求动,就像是那群暴徒在那个僵死的总统府的大厅里活动一样。
听起来叙述者好像对这座总统府的掌故和前朝往事烂熟于心,每一辆锈迹斑斑的马车、每一辆破败的轻便马车都属于哪个历史的或神话的年代,他都能够对得上号。但是,比如说,他怎么知道宫廷的嫔妃们曾和士兵们待在庭院里的同一个散兵坑里的呢?这开篇合同在多大程度上要求读者相信这位叙述者呢?
开头的几页弥漫着时间、冷落和堕落,就像它们充斥着小说的其余部分一样。这群暴徒倒是真的想象过狂暴地冲进“这气势恢宏的权力的巢穴”,想象过用牛轭敲击宫墙,把大门从合页上敲下来,然而到了最后却没有狂暴的革命,只是轻轻地,几乎梦一般的穿过大门;而大门仿佛“仅仅用声音一推”就开了。冻结的时间主宰着这个故事,就像从第一句话就主宰着这座宫殿一样:“……这群劫掠成性的人闯进总统府……他们拍打着翅膀,搅动起其中凝滞的时间……”这帮入侵者感觉到,他们进入的不是一座建筑,而是几个当其轻轻地进入“另一个时代”,或者进入一种更为古老的静默时被冻结的时代。他们遇到的那个洗礼盘,超过五代人都曾在里面受洗,他们还遇到古老的马厩,和一辆“激动人心的时代”的四轮马车,一辆“瘟疫肆虐时代”的四轮运货马车,还有其他人工制品,上面蛛网密布,而每一件物品都标志着一个时代,而不是一个地点。
主宰着“这气势恢宏的权力的巢穴”的时间是腐朽的,散发着恶臭,和饲养场的臭味等量齐观,到处是动植物繁殖流出来的湿漉漉的水汽。这座宫殿向这座城市吹送着一股“温暖而柔和的微风”,这股风却是“腐朽的恢宏”。宫殿的墙壁“摇摇欲坠”。那一丛丛的玫瑰花“布满了月尘”,麻风病人曾在花丛下安眠,玫瑰的花香“和臭味儿混合在一起……还有鸡窝的臭味和屎尿的臭味……”花园里的植物“令人窒息”,衣物就挂在“敞开的散兵坑”旁边,“在阳光下日渐腐烂”。在宫殿里面,入侵者们会发现,母牛们已经把里面的厅堂据为己有,散落在家具残片间的牛粪散发着恶臭,和这帮劫掠成性的人身上散发出的腐烂的臭味混合在一起。在“一间隐藏在墙壁里的办公室里”,躺着那个暴君的尸体——这才是各种臭味的根源,这些臭味儿从宫殿里吹出来,使得整座城市都臭气熏天。
那么,读者要进入这座宫殿兼牛棚,就必须主动承担起什么样的责任,作为一种入场券呢?他必须信以为真地接受那精确的、自然主义的细节,各种臭味,那摇摇欲坠的物件,那牛粪和那一番含糊其辞的简要介绍,作为这一描写看似具有纪录片性质的证明吗?还是必须把所有这一切当作虚拟的现实?或者是当作神话呢?
和果戈理的《外套》开头部分以及卡夫卡的《城堡》的头几页一样,《族长的秋天》开头的几页也是不锁门的,是开放的。您可以把它当作一种描写,确实是一种荒诞不经的描写,用一种拉丁美洲人的怪诞手法写了出来,描述了在某个残暴腐败的香蕉共和国,人民在一个年老的统治者死后接管皇宫的故事。或者,您也不妨把它当作一份无政府主义宣言的艺术版本来阅读,这份宣言对各国政府的腐败行为都予以谴责,并以生动的色彩,描绘所有统治阶级的堕落。如果进行这样一种阅读的话,往往就会失去《族长的秋天》里那哲学的或神学的维度。我们不要忘了,那恶魔般的独裁者是不朽的。他的死并不是终结。那群暴徒一次又一次闯进他的住处,一次又一次发现那具被秃鹫啄食的尸体;他一次又一次称王称霸,他永远存在,折磨着他的臣民——或者是赏赐他们以不可思议也无法预测的恩典。
卡夫卡的城堡里的那些使者,个个都是阴险狡诈、靠不住的家伙,他们来到那个等着面谈的人面前,无情地奚落他,折磨他,但这个人就是进不了那座城堡,面见那座城堡的主人。相比之下,《族长的秋天》开篇就侵入了君王的城堡,就发现了他的死尸,但是在这里——和卡夫卡的作品一样,在某种程度上也和果戈理的作品一样——你却无法触摸权力本身,至多可以触摸到权力那破烂不堪、名声狼藉的使者,它那令人生厌的代表和那难以理喻而又荒诞不经的残酷,如此而已。至于统治者本人,“……自从黄热病流行的时期就再也没有人见到过他,然而我们都知道他就在那里,我们知道这一点是因为世界还在继续,生活还在继续,邮件还在寄送……”
这并不是尼采的“上帝死了”的理论,而是时间的瓦解;不是灾难降临的世界末日,而是事物不断分解变质的循环,这个统治者和他地位最低的臣民一样难逃这个循环:“……但即便到了那时,我们也不敢相信他死了,因为这是第二次在那个办公室发现他……他们第一次发现他时……他还在执政,就好像他知道他注定不死……”
一切都散发着臭味,一切都摇摇欲坠,但一切也都没有停止活动。这群暴徒闯进皇宫,只不过是一个堂吉诃德式的胜利而已,因为“敌人”只不过是一个演员,他的角色事先已经在剧本中设定好了,每次幕布一升起,他就重新开始表演。
然而,开篇合同邀请读者进入的既不是一个病态的绝望山谷,也不是一个阴郁的形而上的寓言。恰恰相反,这个开头是在邀请读者参加一场感官的狂欢节。加西亚·马尔克斯描绘了笼罩在快人的丑闻下的腐朽的政府大楼,其中是地狱般的恐怖景象。
……元月的一个下午,我们看见一头母牛从总统府的阳台上凝视落日的余晖,只要想象一下呀,一头母牛上了国家的阳台,是多么不成体统的事,又是一个多么令人作呕的国家,人们生出了种种猜测:母牛怎么可能上到阳台上去呢,因为大家都知道,母牛是不会爬楼梯的,更不会爬铺了地毯的楼梯,所以,我们最后也根本不知道我们是不是真的看见过这一幕,也根本不知道我们有没有在那个大广场上度过一个下午,我们一边漫步,一边梦想着我们曾在总统府阳台上看到过一头母牛,而这个阳台上过去什么也不曾看到,在以后的许多年也不会看见任何东西……
这个客观的叙述者的声音,他是这群人当中的一个,他口口声声说“我们”,是一个狂喜的声音,它因把气势恢宏的总统府的外衣扒了个精光,揭露出那不堪入目的真相而感到快乐。随着每一个令人发指的发现,随着每一个令人震惊的细节,随着每一个难以置信的有关当权者生活的揭露,这个声音就愈加顽皮的快乐。它甚至邀请读者通过闯进一座壁垒森严的“神圣中的神圣的”殿堂,参加一个亵渎神圣的飨宴,参加破坏偶像的狂欢。这种欢快气氛融合了可鄙的恐怖,那荒诞不经、不可思议的权威的土崩瓦解,以及劫掠和狂欢那戏谑的快乐。
从小说的第一句开始(“整个周末那群劫掠成性的人撩开阳台窗户上的屏风,闯进了总统府”),读者就必须接受这场游戏的规则:完全消除庄重和戏谑之间通常的界限;消除可怖和欢闹之间的界限;消除形而上探究和小报惊爆丑闻的欢乐之间的界限;消除一个香蕉共和国里神圣无比的统治者和歌剧总监之间的界限。
如果读者拿着破解密码的凿子接近这部小说,极有可能错过狂笑着走进这部小说的读者所能发现的东西,反过来也是如此。从一开始,作者就期待着读者在两条平行的轨道上通过这部小说:它是一部有关宇宙及其主宰的黑色的形而上的寓言,同时又是一场嬉闹的、残酷无情的无政府主义取乐:它像卡夫卡式的寓言,同时又像是狂欢节,这部滑稽剧似的小说试图带给我们周而复始的精神混乱的噩梦。
【注释】
[1] 国内有译本《族长的没落》,伊信译,山东文艺出版社1985年出版。原作于1975年出版,1976年被美国《时代》杂志评为当年世界十大优秀作品之一。它是一部以极其夸张的手法鞭笞拉丁美洲残暴的军人独裁统治的小说。
[2] 俄罗斯套娃:俄罗斯民间木制玩具,一般由多个绘有图案、由小到大的空心木娃娃一个套一个组成,最多可达十几个,玩时依次拆开。
谈[[卡夫卡]]《乡村医生》的开头-[[阿摩司·奥兹]]
========================
山洪中的一根木头
故事开始了:文学随笔集 阿摩司·奥兹
谈卡夫卡《乡村医生》的开头
-----
卡夫卡的短篇小说《乡村医生》(1919)是讲一个乡村医生在一个风雪交加的夜晚出诊,来到一个重症病人床前的故事。这位医生应诊了,他克服了重重古怪的障碍,赶到了病人的床前,但却救不了他。最终,他发现自己“驾着尘世的马车,赶着非尘世的马,我这老头子四处飘荡”[1]。在故事的末尾,这位医生说:“上当了!上当了!一次听信了深夜骗人的铃声——就永远无法挽回。”这结尾的一句指引读者回到故事的开头,查询这位医生具体在哪里犯了那唯一的错误,而这个错误是永远无法纠正了。从故事的表面看,结尾包含某种寓意。似乎假如那天夜里,医生早一些知道了这层寓意的话,他本来完全可以避免这一致命的错误的。
然而,事实上,这位医生,或者读者,到了故事的末尾了解到了什么?他犯的是什么错误,其寓意是什么?这“骗人的铃声”是什么?这位医生当时不能不理睬这铃声吗?他能不能从一开始就搞清楚这是骗人的铃声?(在这个故事里,或者在故事之外)有没有办法区别骗人的铃声和真正的铃声呢?最后,这位医生真的应诊了吗?或者,他是不是不情愿地让人强推上路的?
实际上,在故事的开头,并没有人求诊,根本就没有深夜铃声——没有骗人的铃声,什么铃声都没有。另一方面,故事开头有一个精确的报道,报道了确凿的事实,在此过程中,发生了一连串噩梦般曲折的事件。读者的确很难确定其中曲折具体是在何时发生的。和卡夫卡的许多作品一样,这里没有突然的情节变化,而是现实本身出现了一种难以名状的模糊,维度出现难以置信、难以理解的扭曲,出现一种变形,使得一切都渐渐弥漫着噩梦的阴影。
我的处境十分窘迫:我必须即刻出行;一位重病人在十英里开外的一个村子里等着我;猛烈的暴风雪席卷着我与他之间的广阔地带;我有一辆大轮子的轻便马车,正好适合于在我们的乡村大道上行驶;我身穿皮衣,提着手术包,已经站在院子里准备出发;但却没有马,完全没有。我自己的马在这个天寒地冻的冬天精疲力竭,昨天夜里死掉了;我的女仆正在村子里到处为我借马;可这毫无希望,我心里很明白;我茫然地站在那儿,雪花落到我身上,越积越厚,我也越来越举步维艰。女仆出现在门口,就她一个人,晃着手里的灯;当然,谁会在这种天气借出马来跑那么远的路?我又在院子里来回踱起步来;我看不到出路;我神思恍惚,痛苦地朝常年不用的猪圈的破门上踢了一脚。门开了,吱嘎吱嘎地摇来摆去。一股暖烘烘的气味扑面而来,像是马的气味。里面的一根绳子上晃动着一盏昏暗的厩灯。一个男人缩成一团,蹲在低矮的圈栏里,露出他那嵌着一双蓝眼睛的坦诚的脸。“要我套马车吗?”他问道,四肢着地爬了出来。我不知该说什么,只是弯下腰,想看看猪圈里还有什么。女仆就站在我身旁,她说道:“你永远想不到会在自己家里找到什么。”我俩笑了。“喂,老兄!喂,妹子!”马夫喊道,两匹马,两头膘肥体壮的牲口,腿紧贴着身体,像模像样的脑袋骆驼一般低垂着,完全靠马屁股扭动的力量,才先后从那个被它们的身体塞得满满的门洞里挤了出来。不过它们马上就站直了,腿很长,浑身冒着热气。“帮帮他吧!”我说道,听话的女仆赶紧跑过去帮马夫套辔具。然而,她刚一走近,马夫就一把抱住了她,把脸贴到她的脸上。她尖叫一声,逃回我身边;她的脸颊上印着两排红红的齿印。“你这个畜牲!”我怒吼道,“你是不是想挨鞭子了?”但我随即意识到,我根本不认识他,也不知道他来自何方,现在谁也不肯帮忙,他却主动雪中送炭。他似乎明白我的心思,我威胁了他他也不恼,仍然忙着套马,只有一次转向我,说道:“您上车吧!”果真:一切准备就绪。我发现这两匹马真漂亮,我还从未坐过这么好的马拉的车呢,就高高兴兴地爬了上去。“不过得我来赶马车,你不认识路。”我说。“那是当然,”他说道,“我根本就不跟你去,我要留在这儿,和罗莎在一起。”“不!”罗莎预料自己在劫难逃,尖叫了一声,跑进了房子;我听到她当啷一声套上门栓链;听见钥匙在锁里转动的声音;此外,我看见她熄灭了门厅里的灯,飞快地穿过一个又一个房间,以防被找到。“你同我一道走,”我对马夫说,“否则我就不去了,虽然这次出门非常紧急。为了出这趟门,我可不想搭上这个姑娘,把她交给你糟蹋。”“驾!”他说,拍了拍手,马车应声疾驰,宛若被冲入山洪的木头;我还听得见在马夫的凌厉攻势下,我的房门猛地被撞开,裂成碎片,接着,马车顶风冒雪风驰电掣,呼呼的响声不断猛击着我所有的感官,我什么都听不见,什么都看不见了。
小说的叙述者还一言未发,题目就把我们介绍给了这位第一人称叙述者:一个乡村医生。接着,他用一本正经的口气介绍了所有的初步情况,几乎像是一份警方的报告;仿佛他在陪审团前作证,仿佛他遭到刑事起诉,必须为自己辩护。
他的处境:十分窘迫。他的问题:紧急出诊,一位重症病人,一个十英里之外的村子,一场暴风雪,没有马,也没有希望搞到一匹马。他采取的措施:一、派一个女仆去借马,尽管借到的可能性微乎其微。二、站在院子里,站在大雪中,等着随时上路,以便一旦仆人借到马,一分钟也不会耽搁。三、又在院子里转来转去。四、甚至朝那个废弃不用的猪圈的门猛踢一脚,万一在那里能找到什么东西呢。五、当那两匹马和马夫出现时,没有浪费时间去询问他们那奇迹般的现身的含义。六、那马夫对女仆行为不轨,他并没有保持沉默,而是责骂他,但是他并没有耽搁——他首先考虑的还是赶过去看那个重病号。七、当他意识到那个马夫要猥亵罗莎时,他改变了首先要办的事,决定绝不能不管她。八、但是,当马夫让那两匹马疾驰向前时,他就控制不了了,那两匹马朝前猛冲,拉着马车,“宛若被冲入山洪的木头”。
辩护词看似滴水不漏。对这位医生在这一系列事件任何阶段的行为,任何陪审团都无法判他有罪。然而,在故事的开头,一直到结尾,对中心问题并没有给出答案。甚至都没有提出中心问题。
这位医生究竟犯了什么罪而遭到起诉?他极力辩驳的,是什么罪责,什么指控?对他的起诉来自何方?在故事结尾,是谁判他“赤身裸体,遭受着这最不幸时代的冰雪肆虐,驾着尘世的马车,非尘世的马,我这老头子四处飘荡”?他犯了什么罪?
小说用了大约三分之一的篇幅写这位医生试图对那从未提出的指控进行自我辩护,反驳一个在故事中从未出现的检察官。除了在小说的开始部分有这番符合逻辑而又严密的辩解以外,后来又出现了一份“辩护请求”,和最初那份完全不同,是哀怨的,充满着自怜。
我是本区的医生,恪尽职守,到了几乎是太过分的地步。我的报酬很低,但我对穷人慷慨解囊,乐善好施。……在这无穷无尽的冬天,我来这儿算是干吗的呀!我的马死了,村子里谁也不愿把自己的马借给我。我不得不从猪圈里拉出一套车马来;要不是猪圈里刚好有马,我就得靠母猪拉车了。就是这样。……又让我出去白跑了一趟,对此我已习以为常,全区的人都半夜三更来按门铃,使我的生活变成了折磨,这次我还得牺牲罗莎这姑娘……这要求也太过分了……
和故事的开头部分那简短的辩护词形成对照,这一段独白看起来并不是企图说服,而是要努力引起别人的同情。或许这是一段绝望至极的独白,因为叙述者在一开始就表达了要死的愿望(只要罗莎平安无事),最后他概括地讲述了他去看望病人的过程——以及他整个一生——都是无可挽回的失败。
然而,故事的开头部分至少在表面上看,还是一篇滴水不漏、无可指责的辩护词。这是一份具有戏剧性的辩护词:几乎是用一个长句子写出来的,是一个从句套从句的长句子,各部分主要用分号隔开。医生的证词是用现在时讲的,就像是直播(“她刚一走近马夫,嗐,是的,这马夫一把抓住她,把脸啪的一声撞到她脸上。这姑娘尖叫一声,逃回我身边。”[2])。有好几处这样在句子中间从过去时过渡到现在时。
医生用脚把门踢开,这一脚却从这个废弃的猪圈里踢出来一个马夫和两匹马,使他感到大为震惊。就像是果戈理小说里那个鼻子的出现一样,《乡村医生》中马夫和马匹的出现差不多被描写成了诞生:马夫“四肢着地”爬了出来;那两匹马“一前一后,腿紧贴着身体,像模像样的脑袋骆驼一般低垂着……完全靠马屁股扭动的力量,才从那个被它们的身体塞得满满的……门洞里挤了出来……它们浑身冒着热气。”咬罗莎的脸颊是马夫的第一个动作,这位医生叙述者因此骂他是“畜牲”。马夫对这姑娘的情欲和不轨行为的确是兽性的。医生能听到“在马夫的凌厉攻势下,我的房门猛地被撞开,裂成碎片”。同时,马夫扮演了民间故事中常见的魔鬼的角色,不知从何处跳将出来,提出一个奇特的交易,主动向其主顾提供他急需的东西;然而作为回报,却索要某种有意义得多的东西。这里,医生在最后一分钟放弃了交易,拒绝了(“为了出这趟门,我可不想搭上这个姑娘,把她交给你糟蹋。”)可是交易还是强加给他了:他一旦同意使用这魔鬼的马,就免不了要向魔鬼付出代价。
故事开头部分发生的事,从表面看像是努力要解决交通问题——在这风雪交加的夜晚,这位医生怎样才能赶到重症的病人床边——但后来却变成了背负着羞辱和罪恶的事:医生的马出力太多,累死了,他无法保护那个姑娘,他也没能治好病人的病。或许,这就是为什么开头部分——实际上是故事的大部分——被演绎成了一份检讨书。然而,这却是一份怪诞的、循环论证的检查书,简直像是《桶里有个洞》这首民歌:没有第二件事,第一件事就办不成,而第三件事的制约,又使第二件事办不成;缺了第四件事,第三件事也办不了;而只有办好了第一件事,第四件事才能办到。我们如果把《乡村医生》的情节作为一个审讯的程式进行图式化演绎的话,这位医生的状况的荒诞性以及他的辩护词的荒诞性就会更加明显。
如果出门已经是万事俱备,包括“一辆有大轮子的轻便马车”,你为什么不走?
因为没有马。
马呢?
昨天夜里死了。
马怎么会死的?
“在这冰天雪地的冬天里跑,累死的”。
这匹马在这冰天雪地的冬天里为什么给累死了?
因为“全区的人都半夜三更来按门铃,使我的生活变成了折磨”。
为什么这次出诊比其他时间出诊更加艰难?
这次“我还得牺牲罗莎这姑娘”。
那你为什么还不管她?你为什么让那个马夫咬她的脸?
我责骂他了。我威胁说要拿皮鞭抽他。
那你为什么没有抽他?
因为我突然想起来“我根本不认识他,也不知道他来自何方”。
你连他从哪儿来都不知道,干吗要接受一个陌生人的帮助?
因为“现在谁也不肯帮忙,他却主动雪中送炭。”
别人为什么都不肯帮忙?
“全区的人使我的生活变成了折磨。”
他砸碎门,对罗莎行为不轨,你为什么不阻止他?
我试过。我命令他和我一道走,要是不走的话,“我就不去了,虽然这次出门非常紧急。”
那你为什么不取消这次出诊呢?
因为那马夫赶马赶得那么猛,那辆马车“应声疾驰,宛若被冲入山洪的木头”。
可是,你为什么听任这么一个马夫的摆布呢?
因为一个重症病人在等我,而我又没有马。
故事又绕回来了。(实际上,这同样的模式后来又出现一次,就是在误诊那一段。医生刚开始没有注意到男孩子的伤口,就没能给他治病,矛盾的是,他没有办法给他治病。就医生这方面说,他没有玩忽职守或不当的行为。他是个做不成好事的好人。)
那么,在故事开头要读者接受的“开篇合同”又是什么呢?
起初,读者得相信这位医生叙述者,对这位正派的人心怀同情。在这风雪交加的夜晚,他要出门应诊,给一个病得很重的病人诊治;但却仅仅因为一个技术问题,给耽搁下来;读者也一定认同,为了给重症病人提供医疗救助,道义和职责使医生必须尽最大努力,如果必要,甚至以身犯险。这位医生在他“证言”的开头部分描述的情况那么急迫,读者就感觉有必要把注意力放在主要的问题上面(即,救病人),而不是在别的事情上浪费精力。昨天夜里一匹马又冻又累,死掉了,那是另外一个故事,眼下还没有时间讲,不管怎么说,讲了也救不了那匹马。马夫和那两匹漂亮的马从一个废弃不用的猪圈里突然冒了出来——啊,他们当然引起惊讶,但是在危急时刻,人是不会问那么多问题的。读者就顺理成章地认可这种紧迫感,是这种紧迫感驱使着医生顾不上问问题,就决定使用那些马。
甚至那个陌生人第一次羞辱那姑娘也不成其为耽搁的理由,医生斥责了他,读者应该对医生感到满意。
总之:直到那两匹马开始狂奔,读者都没有理由批评医生的种种考虑。然而,当形势发生逆转,超出了叙述者的控制时,读者就要自问,形势是不是一开始就在控制之下。医生的决定真的算是决定吗?描述出来的那一连串算计和决定,看似非常合情合理,但实际上只不过是一个噩梦般的幻觉:医生受骗了。夜晚使他出诊的铃声是假的,没有什么“能被挽回,根本没有”。不仅是医生被误导,这样看来,连读者似乎也上当了。
因为事实上根本没有铃声。另外,医生在最后一刻没有主动取消出诊,没有拒绝用马换姑娘的交易,是不是仅仅因为他的选择被粗暴的力量压制下去了?他毕竟没有自己动身,而是违背自己的意愿,被赶着上路了。
和在故事开头部分留下的印象完全矛盾,这一印象在故事结尾部分再次得到强调,《乡村医生》并不是一个有关罪与罚的故事,也不是关于误入歧途或者是做出错误选择的寓言故事:这位医生的悲剧根本不是他的行为和失败所致。他所做的辩解是多余的。开篇合同只不过是真正的内在冲突的对象。根据这一内在的暗伏的合同的条款,这位医生是先验地有罪的,从一开始,甚至在他出那根本就没有的急诊前,甚至在他开始一系列的道歉之前,他就被判有罪,并被判刑了,尽管他是无辜的。从一开始,这位医生就只不过是“山洪中的一根木头”而已。他有罪,是因为人的罪总在等着他。罗莎似乎道出了卡夫卡的合同的真正条款,当她说:“你永远想不到会在自己家里找到什么。”罪一直潜伏在“常年不用的猪圈的破门”后面。
【注释】
[1] 本文引文部分参考了中文版《卡夫卡中短篇小说选》的译文,韩瑞祥、仝保民选编,王炳钧译,人民文学出版社2003年1月出版,特此说明并向原译者致谢。
[2] 这部分引文和前文所引有些出入,大概是作者奥兹为突出其“现在时”而作了发挥。
谈雷蒙德·卡佛的短篇小说《没人说一句话》的开头-阿摩司·奥兹
========================
把它弄出去,趁我还没吐
故事开始了:文学随笔集 [[阿摩司·奥兹]]
-----
## 谈雷蒙德·卡佛的短篇小说[[《没人说一句话》]]的开头
雷蒙德·卡佛的短篇小说[[《没人说一句话》]]收入短篇小说集《请你安静些,好吗?》,1976年首次出版。它讲的是一个小男孩的故事,他借故不去上学,待在他那空无一人的家里看电视,去一条小溪钓鱼,遇到一个引起他性欲的女人,遇到一个长着龅牙的陌生男孩,他们一起抓到一条他们认为是大鱼的东西,两人分了,这个小男孩叙述者把那个东西带回家;他发现父母亲正在吵架,就试图把他们的注意力转移到他带给他们的礼物上,可是他们转过身,吼着让他看在基督的分儿上,把“那个该死的东西”扔到垃圾堆里去。小说的题目直到故事的结尾才完全得以彰显,原来它指的是——尽管没有明说——这个小男孩希望父母亲能对他带回来的战利品说上一句好话。他或许是想引他们高兴,好使他们不再争吵。或许他希望赢得他们的爱。他的希望终于实现了,尽管是以讽刺的方式实现的:他们看到他带回来的礼物时,的确不吵了,但只停了一会儿。他们转而合伙责骂起他来。
小说既没有写到希望,也没有写到失望;但希望和失望都在字句的空隙里了,要请读者去填满这些空隙。
开头部分除了写家里的各个成员之间互相讨厌和生气以外,不包含任何感情或情绪的表现。开头部分是用简短的写实的句子和一点点对话写出来的。
我听见他们在外面的厨房里。我听不清他们在说什么,但是他们在争吵。接着,安静下来了,她哭了起来。我用胳膊肘捅捅乔治。我原想他会醒来,对他们说上几句话,他们觉得不好意思就不再吵了。可乔治是混蛋。他开始又踢又喊。
“别捅我了,你这个杂种,”他说,“我会告诉他们的。”
“你个傻瓜蛋,”我说,“难道就不能聪明一回吗?他们在打架,妈妈都哭了。听。”
他脑袋从枕头上抬起来听了听。“我不管。”他说完,身子一扭,对着墙继续睡。乔治是个十足的混蛋。
后来我听见爸爸动身去赶公共汽车了。他“砰”的一声关上前门。她早就跟我讲过,他想把这个家撕碎了。我不想听。
过了一会儿,她来叫我们去上学。她的声音听上去很滑稽——我说不准。我说我肚子不舒服。这是十月份的第一个星期,我还没有缺过课呢,所以她能怎么说呢?她看了我一眼,但她好像在想别的心事。乔治醒着,在听。看见他在床上动来动去的,我就知道他是醒着的。他在等着看事态发展,好相机而动。
“好吧,”她摇摇头,“我还不知道。那么,就在家里待着吧。但是,不许看电视,这一点要记住。”
乔治发火了。“我也不舒服,”他对她说,“我头疼。他一个晚上又是捅我,又是踢我。我根本就没睡着。”
“够了!”她说,“乔治,你给我上学去!你不能在这儿待着,成天和你弟弟打架。快起来,穿好衣服。我不是说着玩儿的。我今早上可不想再吵一架了。”
乔治一直等到她离开了房间。然后,他从被窝里爬出来,站在床腿边。“你个杂种。”他说着,一把把我的被子全拉了下来。他躲进浴室里去了。
“我会杀了你。”我说。但是声音不大,她听不见。
直到乔治上学走了我才起床。当她准备去上班的时候,我问她能不能在沙发上给我铺铺床。我说我要学习。咖啡桌上放着我过生日时得到的礼物,埃德加·赖斯·巴勒斯[1]的书,还有我的社会科学课本。但是我不想看书。我希望她走,这样就能看电视了。
从表面看,我们这里有的只不过是纪录片一样的真实生活材料的堆积:没有地点的描述,没有背景,没有各种层次的隐含意义,没有感情,没有疑问,没有动机,没有意识流,只是一串生活琐事:母亲和父亲吵架而不欢而散,两个兄弟也恶言相向,互相骂对方是“杂种”和“傻瓜蛋”。父亲和孩子们没有接触,母亲对孩子们表现出怀疑、不耐烦和责骂;叙述者是一个骗人的、爱耍心眼儿的孩子,乔治则是个告密者、说谎者。当叙述者听他母亲说他父亲要把这个家“撕碎”时,他的反应是:“我不想听。”乔治听到母亲哭泣时,他也说:“我不管。”说完就回去睡觉了。他们一家人似乎都讨厌对方。
尽管如此,人们还是能窥见一些微妙之处:母亲对叙述者的耐性就比对他兄弟的耐性大一些,而叙述者对母亲痛苦的反应和乔治的反应又略微有所不同。当叙述者听见她哭时,他没有置之不理,而是叫醒他哥哥,策划了一个小把戏,试图让乔治说些什么话,使父母感到不好意思,这样他们就会停下来不吵架了,但是这个计谋失败了,因为乔治不愿意配合。
读者必须自己填补起信息的空白:在故事开头几行,我们没有看到“我父母亲”和“我哥哥”这些字眼,只有“我听见他们在外面的厨房里”,“她哭了起来”,“我用胳膊肘捅捅乔治”。时间是清晨,小哥俩在一张床上睡觉,连这样的事实都没有明说,而是推断出来的。读者的任务就是把第一段里的几个声音“拼”成一幅家庭的画面,从而为读者在后文要扮演的积极角色作了准备。读者要从这个孩子那一连串对事实和行为的叙述中体会到那深深的孤独、对爱的渴望,以及极力要修复那已经无法修复的父母关系的努力。虽然“孤独”、“爱”和“修复”这些字眼根本没有出现,虽然这些字眼甚至不可能出现在这个干巴巴的、平铺直叙的小说里,但是读者的任务就是要从这笼统的沉闷后面体会这些东西。
倘若匆匆地看小说,就会留下这样一个印象:这部小说只不过是按时间顺序记录了一个孩子生活中的一天里发生的事情罢了,而这种记录毫无章法可言。下面列出在开头几段之后发生的事情:
这孩子和母亲待在一起,直到母亲去上班。
他要她在长沙发上给他铺个床铺。他对她撒谎:要学习。
他关掉声音看电视。读《火星公主》。
母亲和这个孩子单独在家时,有几个温柔的时刻。接着,她去上班了。
这个孩子看电视。抽了一支母亲的烟。到他们抽屉里找避孕套。找到凡士林油,阴茎硬了起来。
之后,抓了些吃的,写了个字条,离开家。去波奇小溪。看外面的世界;秋天了,但还不冷。
搭乘一个女人开的红色汽车。“……她够时髦的……穿着一件毛衣,里面的奶子真漂亮”(不过她嘴巴周围长了些粉刺,头发上有卷发夹子)。想象她带他回家。
那个女人让他在十字路口下了车。他继续走着。想象她在他的卧室里,那玩意儿就又硬了起来。
来到小溪边。回想起和爸爸钓鱼的事。吃了随身带的食物。想抓个东西。又一次想象和红色汽车里的那个女人鬼混的情景。
抓到一条鳟鱼。努力不再想那个女人,可是一努力,那家伙又硬了起来。
他在垂钓的时候,想起来曾凭着《圣经》发誓,要少手淫。可是刚刚发完誓,就冲着那本《圣经》手淫起来。
遇到一个长着龅牙的不认识的孩子。那个孩子发现一条很大的鱼,有一条胳臂那么大,可就是抓不住。
叙述者帮他。他们一起设法抓住一条瘦长的鱼,“比我捉到的任何一条鱼都大”。傍晚了。天冷了。
他们俩用一根棍子抬着那条鱼。他们为这条鱼该怎么分而争执不下。他们妥协。叙述者拿到了鱼头。
他和那个不认识的孩子分手。回家。乔治在外面骑自行车。在厨房里,妈妈和爸爸又干起仗来。她在哭。
这孩子脱掉靴子,打算满脸笑容地走进去,用他从小溪边给父母带回的礼物给他们一个惊喜。
他听见父亲说:“孩子们懂什么?”母亲回答:“我要是那样想,我倒宁肯看到他们先死了。”
煎锅烧煳了。母亲把锅朝墙扔了过去。父亲说:“你发神经了吗?”
那孩子走进厨房,满脸堆笑。“你们不会相信我在波奇小溪逮住了什么……”
母亲喊:“拜托……把它弄出去,趁我还没吐。”父亲也尖叫道:“把那个该死的东西弄出去!”
那个孩子又往外面走去。故事结束。
这一连串事件似乎是漫不经心、没有重点的。尽管用的是第一人称,但视角却是外在的;文本几乎是行为主义的(“他在床上动来动去的,我就知道他是醒着的”)。但仔细阅读就会发现一个经过剪裁的内在的故事,一个精心构筑的文本的轮廓。叙述一开始是清晨,在家里,后来的事情发生在外面。到了晚上,我们又一次回到家里,接着又回到外面。另外,故事一开始就企图分散父母亲的注意力,不让他们争吵,可是这一企图失败了;故事结尾又有这样一个失败的企图。
这个儿童叙述者先讲一厢情愿地祈求家人和睦(尤其是一厢情愿地求他的母亲),又讲性(找避孕套、凡士林、那个陌生女人和她激发起的性幻想、手淫的种种想法),接着又讲到遇到那个不认识的孩子、两个孩子在小溪岸边的秘密经历,他们捉到一条“瘦长”的鱼。那个不认识的孩子说:“我真想把这条鱼给我爸爸看看。”而那天晚上,这个儿童叙述者真的试图给他父亲看。
这两个男孩子弄鱼的描述近乎是性试验。那条鱼“慢慢地抖了很久……我们看着它,不断地摸它。”后来:“我把鱼头摁到水下面,扒开鱼嘴。溪水灌进鱼的嘴里,从另一头流出来……”这个男孩子做完这个试验,就回家并试图通过给爸爸妈妈讲他遇到的事情,给他们看他历险的收获,使他们不再争吵。他请求父母亲的那句话也许是整个故事里他说的唯一一句带感情的话:
“你们不会相信我在波奇小溪逮住了什么。看看呀。看这儿。
“看这个。看看我逮住了什么。”
然而母亲并没有看到一条鱼。她看到一个使她害怕和恶心的东西;她厌恶地尖叫起来,似乎这孩子带回家的不是一条鱼,而是,比如说,一个用过的避孕套。
“啊,啊,我的上帝!那是什么?一条蛇!那是什么呀?拜托,把它弄出去,趁我还没吐。”
孩子转向他父亲,哀求他至少看上一眼。
“看看吧,爸爸。看看这是什么……
“当时还有一条呢,”我急忙说,“一条绿的。我发誓!是绿的。您见过绿色的吗?”
父亲不感兴趣;他和母亲的反应一样。
“把那个该死的东西弄出去!……扔到那该死的垃圾堆里去!”
可是,这孩子实际上从那条小溪里带回了什么东西?他父母看到的是什么东西呢?
这正是在卡佛的许多小说里都有的“谜点”,读到这个谜点,就要求读者回到故事的开头并作出选择:想不想相信那是一条鱼;想接受还是拒绝这个已经知道爱撒谎的儿童叙述者的报道。
到了小说的结尾,这孩子又是孤零零一个人,在外面。“是什么东西装满了鱼篓……我提着鱼篓。我提着他的那一半。”
《没人说一句话》不是一个“清教徒式的”故事;它有含蓄的表达,也有图画般清晰的对一个青春期的男孩子的性欲觉醒的描写。在以前几代人的许多文学作品中,都有一种对性描写的自以为是的审查,同时又有大量的情感叙述。在这里,性审查被情感审查所取代:这个儿童叙述者毫不费力地讲述他找父母亲用的避孕套的过程,也毫不避讳讲述他什么时间、为什么阴茎勃起,然而,他在这篇小说里没有一处说“我爱”,“我怀念”,甚至说“我被粗暴对待”,“我很伤心”之类的话。从第一段开始就要求读者透过这毫无感情描写的纱幕,不仅要想象父母亲看那半条鱼时看到了什么,而且——主要地——要想象在故事的内部发生了什么:孤独,对母亲痛苦的同情,面对家庭破裂的痛苦,想谈话却谈不成,幻想,缺少爱,还有青春期压抑的痛苦。
【注释】
[1] 埃德加·赖斯·巴勒斯(1875——1950),美国小说家,他创作的《人猿泰山》系列小说塑造了一个丛林英雄的形象,深受儿童喜爱,影响非常深远。下文提到的《火星公主》是巴勒斯的一部科幻小说。
谈[[契诃夫]]《[[罗特希尔德的小提琴]]》的开头-[[阿摩司·奥兹]]
========================
重大损失
故事开始了:文学随笔集 阿摩司·奥兹
## 谈契诃夫《罗特希尔德的小提琴》的开头
------
契诃夫的短篇小说《罗特希尔德的小提琴》于1894年首次出版,这个题目有四个方面都误导读者:故事中的罗特希尔德并不是那位大名鼎鼎的慈善家;他不是个小提琴手;那把小提琴也不是他的,直到故事快结尾才归他所有;他连故事的主人公都不是,只是一个陪衬人物,一个在婚礼上吹风笛的可怜的乐手,是个穷困的犹太人。
题目中的那把小提琴实际上属于一个名叫亚可夫·伊凡诺夫的,大家管他叫“青铜”。这位青铜,是个讨厌犹太人的老头子,粗俗猥琐而又没心没肺,以做棺材为生,有时候为了能挣上几个戈比[1],他和一群衣衫褴褛的犹太乐手在婚礼上拉小提琴。
尽管《罗特希尔德的小提琴》和《艾菲·布里斯特》同一年出版,它并没有描写一个和谐的世界,甚至没有描写一个表面和谐而实际暗藏危险的世界。然而,这个故事的开头和《乡村医生》之间还是能找到一些相似之处的:两个故事开头部分的基本前提在故事的发展过程中都被证明是错误的。开篇合同最终瓦解,回头再看,却发现一份大相径庭的合同:和《乡村医生》一样,在契诃夫的这篇小说里,读者需要再看一遍,并重估一切。
契诃夫的世界弥漫着细致的社会观察,淡淡的忧伤和悲悯的幽默,当然,与卡夫卡那噩梦般的世界相去甚远。但是,这个故事(以及契诃夫另外几篇小说)的开头部分所展示的合同却是误导人的。像《乡村医生》里的合同一样,它也是漏洞百出。
这是一个小镇,但是比村庄更悲惨,住的几乎清一色都是老头子,很少有人死,特别烦人。还有,医院和监狱也很少要棺材。一句话,生意很冷清。亚可夫·伊凡诺夫要是在某个大省城做棺材,他极有可能已经有了房子了,大家也会尊称他“伊凡诺夫老爷”。可是在这荒凉的穷乡僻壤他只是亚可夫,由于某些原因,他在外头的绰号叫青铜,他和任何一个普通农民一样,日子过得很是凄惶,住在一个单间小屋里,小屋又窄又旧,里面住着他自己、玛尔法、一个炉子、一张双人床、那些棺材、工作凳,以及所有的家什。
……当地的警察局长现在已经病了两年了,身子骨是一天不如一天。亚可夫本来是迫不及待地等他死呢,可是这个警察局长搬到本地区的大镇子上去治病,在那里一命归西了。这就算是至少十个卢布的损失了,因为这口棺材会很贵,里面衬着锦缎。尤其在夜晚,亚可夫会胡思乱想,想到这些损失就特别的心烦意乱。他把小提琴放在床上他的身边,每当他想到烦心事的时候,他就碰碰琴弦,小提琴在黑暗中就会发出铮铮的响声,于是他就感觉好受一些。
若没有冰冷地拣选细节,手术刀一般剖析人性,细心测量人物和真相之间的距离,这柔和的忧伤以及温暖宽厚的幽默就会给《罗特希尔德的小提琴》这篇小说打上伤感的印记。人物往往并没有意识到这一真相,要么就不承认它,可是读者可以从字里行间辨认出来。在这里以及其他短篇小说里,契诃夫就像是在化学家的天平上一样,在荒唐和心碎之间建立了一种精确的平衡。这份合同包含叙述者和读者之间口头上的理解,是一种不成文的默许,或是秘密的合同附件。有些东西读者往往要通过其反面才能理解。比如,第一句就是这样:本来是哀叹村子里很少死人,哀叹老年人“很少有人死,特别烦人”。这番哀叹是叙述者发出的,而不是主人公发出的,但是,读者在稍感困惑之后,就会领悟到,这番抱怨是这个棺材匠嘟囔出来的,因为他的“生意很冷清”。
青铜和玛尔法是一对没有孩子的老夫妻。叙述者历数他们那间寒酸的小屋的家什:“玛尔法、一个炉子、一张双人床、那些棺材、工作凳”,连玛尔法这个女人都算到家什清单里了——然而读者已经知道,叙述者已经把他自己的声音和那没心没肺的青铜的声音混合在一起了。
青铜极不情愿接受小孩棺材的订单,管做这种棺材叫“在这种无聊的事情上浪费时间”。这个细节在故事刚刚开始就出现了,证明了他爱贪占小便宜的心理(小棺材利薄嘛)。然而,到了故事的中间部分,读者了解到,青铜把对自己唯一的孩子的生与死的记忆从脑海中抹去了,那是他和玛尔法五十年前生的一个金发的女孩。只是在玛尔法死了以后,青铜才突然想起他的灾难,读者也才明白,这些年来,青铜硬起一副铁石心肠,为的是使自己不再痛苦。他讨厌做小孩棺材,并不仅仅表示他那愚蠢的贪婪,也暗示他那隐藏在内心深处的对儿童夭折的厌恶:夜里,从青铜的小提琴上发出的如泣如诉的旋律只不过是一首结结巴巴的农民版的《亡儿之歌》[2]罢了。
开篇合同是误导人的,因为叙述者故意采用了这位老棺材匠的视角以及他的语言和行话,这样一来,叙述者就使读者必须完成一项审慎“解读”的任务:“贪婪”也是一个代码,指代深深的孤独。他看不上打造小孩棺材的活计,是要掩盖亲人亡故的痛苦。罗特希尔德的长笛那凄厉的旋律一响,青铜的内心就产生反感,实际上是为了防止再次撕开心灵的创伤。他一方面厌恶罗特希尔德和所有的犹太佬,一方面又笨拙地、强行地努力压抑内心深处某种和受苦人本能地抱成团的感觉,这两种感情混合在了一起。至于青铜所哀叹的重大损失,在故事的发展过程中,部分地承载了对虚度的光阴和对人类境况之“虚空的虚空[3]”的哀叹。
故事的情节非常简单,甚至是极简主义的:一个乡村棺材匠的故事,他日子过得很艰难,靠在婚礼上拉小提琴挣钱补贴家用。他吝啬,脾气暴躁,喜欢吵架,一副铁石心肠,对生死都无动于衷:他所有的日子在他看来,就是成年累月地损失金钱。一天,他妻子病了,她早就盼着死,因此暗自高兴,觉得这样一死,她就再也不用过这种以泪洗面的日子了。棺材匠看见她这么高兴,开始对长期以来那么严厉地对待她感到内疚。他拉着这生病的女人去村子里的医生家,求他——还像是讨价还价——求医生的助手,那里唯一的一个人,治好她的病。可是那个狠心肠的老头子耸耸肩,很快就转向下一个病人了。老两口回到家,丈夫量了量妻子的身材,开始给她做棺材。他把这一笔“损失”也记在账簿上。在生命最后的几个小时里,他妻子试图让他想起他们曾有一个死去的女婴,可是他却想不起来了。给她办完丧事,他自己也病倒了。那个吹笛子的犹太人来找他说话,他就把一肚子的火气全撒在这个犹太人身上。他茫无目的地走到河边,街上的男孩子们冲他大喊大叫。回到家,他想起了那个女婴,回想他这一生,他觉得只是一连串的缺憾和损失而已。他把那把小提琴遗赠给了罗特希尔德。棺材匠死后,这个犹太人用这把小提琴拉出了哀伤得不可言喻的旋律。
小说题目中四个“骗人的地方”(罗特希尔德不是那位大亨;罗特希尔德不是一个小提琴手;罗特希尔德不是故事的主人公;那把小提琴也不是他的),到了故事的结尾,都出人意料地自圆其说了:罗特希尔德变成那把小提琴的主人后通过继承遗产而的确成了富翁;他不再吹风笛,而是成了一个小提琴手,继续演奏青铜的旋律。所以,读者一开始遇到在题目中隐藏着的事实,然后发现这些事实都是错的,只是到了最后一刻,又发现这四个骗人的地方都实至名归,尽管晚了一些。
在这篇短篇小说中,犹太人和音乐之间、音乐和灵魂之间,都有一种微妙的、难以捉摸的联系。乍一看,这篇小说似乎是通过青铜的眼光,运用了老掉牙的反犹太主义的套路:犹太人说话粗声大嗓,满嘴大蒜的臭味,他们剥削人,贪婪,牢骚满腹,懦弱,体格衰弱,趋炎附势。但是,故事的结局把一切都颠倒过来了:小提琴的遗赠和乐曲的传承使罗特希尔德变成了那个藏在棺材匠粗俗外观下的深情者的继承人。《罗特希尔德的小提琴》的确有些哈西德教[4]故事中的味道,而青铜本人也使人想起关于那深藏不露的正义之士的神话。
青铜喋喋不休地抱怨“损失”,读者则要把他的怨言转换两次:一次转换是喜剧性的,一次是悲剧性的。喜剧性的转换和这一事实有关,即:口齿不清的青铜总是在账本的借方不仅计入真正的损失,也计入没挣到手的收入。
那毕竟是一条河啊,不是一条小溪流。你可以去那里捕鱼,把鱼卖给生意人、职员和火车站膳食主管,然后赚的钱存进银行。你可以划船从一个地界儿到下一个地界儿,拉小提琴,各色人等都会给你钱的。你可以重新把驳船运输的生意搞起来——那可比做棺材强多了。最后,你还可以养鹅,到冬天把鹅杀了,送到莫斯科去。兴许光鹅绒这一项一年就能挣上十个卢布呢。可是他只是白白地浪费了这么多年的时光,这些事儿他哪一样也没有做。他损失掉的钱那个多啊!您要是把这些都加在一起——捕鱼、拉小提琴、开驳船、杀鹅——那他早就挣了老鼻子钱了。
而悲剧性的转换包含着契诃夫伟大的创新,这一创新在他的短篇小说和剧作里均有体现:去除了自古以来喜剧和悲剧之间的屏障;取消了这一严格的惯例,即“低等”人物,粗俗而无知的那一类人,必定属于喜剧的范畴——他们至多有时会陷入凄惨的不幸之中——而悲剧的维度只留给“高贵的”人物。只有高贵的、受过启蒙的人,才能“拿起武器,反抗那无边的苦海,”[5]才能从他们的苦难中得出有关命运、人类的境况、存在之荒谬,或者是他们自身性格缺陷的结论,由于这些东西,他们注定要失败。
亚可夫·伊凡诺夫,别名青铜,在他临死的那一刻,也上升到了悲剧意识的高度。在他自己毫无意义的人生之外,用他那笨拙的、无知的方式,他这样勾画出人类的境况:
一辈子就这么过去了,没有获利,没有快乐;一辈子就过完了,没有目标,没有目的。往前看,没有任何盼头;往后看,浪费的钱多得可怕,可怕得足以使你毛骨悚然。人为什么不能没有这一切损失和浪费,就过他一辈子呢?……他得出结论,他只有一死才能获利:这样一来,他就不用吃,不用喝,不用缴税,不用再侮辱人了。人在坟墓里一躺不只是一年,而是几百年,几千年,所以那利润就大了去了……这个结论是正确的,当然了,却不是那么好受的。在这个世界上,事情为什么安排得这样奇怪呢?你只能活一次,却没有任何东西可以向世界展示的。
这一段悲剧性的独白,不是出自一个英雄或哲学家王子之口,而是出自一个贪得无厌、心胸狭窄而无知的农民之口,这就给这篇故事的开头部分洒下了完全不同的光芒。表面上的贪婪和粗俗只不过是一层薄薄的外壳,读者必须去掉这层外壳才能取出珍珠;不仅如此,贪婪、粗俗和珍珠是合为一体的。就好像契诃夫让一个殡仪工匠扮演那位悲剧性的丹麦王子[6]。那悲剧性的苦难、悲剧意识以及对宇宙秩序的反抗,在这个故事中都恰到好处地得到深刻的反映。
最后,契诃夫是在哪里又是如何在作者和读者之间,背着主人公种下那默契的种子的?当这个棺材匠在床上孤枕难眠,他就去够他的小提琴,这时候我们从这夜晚的旋律中,大概就能听出那些默契。此时此刻,青铜既变成了一个扫罗,饱受邪灵的折磨,又变成了一个大卫[7],“碰碰琴弦,小提琴在黑暗中就会发出铮铮的响声,于是他就感觉好受一些。”
【注释】
[1] 戈比:俄罗斯货币单位,一百个戈比等于一卢布。
[2] 《亡儿之歌》:捷克著名作曲家古斯塔夫·马勒的声乐套曲,作于1902年,系为吕克特的同名诗谱曲。吕克特此诗为哀悼亡儿而作。马勒作成此曲后,1906年其爱女不幸夭折,马勒在悲痛中曾哀叹“爱女之死,实为此曲预悼之故”。
[3] 出自《圣经》传道书第一章第二节。
[4] 哈西德教:犹太教一个教派。
[5] 语出莎士比亚《哈姆雷特》第三幕第一场中哈姆雷特那段著名的独白“活下去还是不活,这是个问题”。作者以《哈姆雷特》为例,盖因该剧是典型的传统悲剧。
[6] 丹麦王子:指《哈姆雷特》的主人公丹麦王子哈姆雷特。
[7] 参见《圣经·撒母耳记上》“:主的灵离开扫罗,有恶魔从主那里来扰乱他……从神那里来的恶魔临到扫罗身上的时候,大卫就拿琴,用手而弹,扫罗便舒畅爽快,恶魔离了他。”
谈[[萨·伊兹哈尔]][1]的长篇小说《米克达莫特》的开头-阿摩司·奥兹
========================
故事开始了:文学随笔集 [[阿摩司·奥兹]]
## 谈萨·伊兹哈尔[1]的长篇小说《米克达莫特》的开头
-----
谈萨·伊兹哈尔[1]的长篇小说《米克达莫特》的开头
萨·伊兹哈尔的长篇小说《米克达莫特》[2]于1992年首次出版。该书的第一部分叫做《凝视一个地方》。谁在凝视?有人揣测——尽管没有写成文字——凝视者是一个希望回归那铭刻在他内心深处的最早经历的人。努力挖掘出最深层的记忆,努力探到最底部,这就包含了一个悖论:他必须把他有语言能力之前很久发生的事情用语言表达清楚。在作家记忆的最深处微微闪光的东西并不是语言,而是一连串的感受,其中迸射出那有意识的“我”最初记忆的闪光:“……我现在看见了,并且第一次知道了,在这里:他知道了。”或者还有:“渐渐了解到所有这些橘黄色的存在。”这种叙述的意识命令自己去回忆——就像纳博科夫的题目《说吧,记忆》那样——完全依赖于语言;但当它第一次意识到这个世界的存在时,它并没有语言。
因此,开篇合同就要求读者通过语言看到一些非语言地存在或曰只能非语言地存在的东西。
那最初的地方在哪里?就是那最初的一个?因为那最初的地方,不需任何证明,是橘黄色的。完全是橘黄色。橘黄橘黄的。很浓的橘黄色。完完全全。
光滑,像丝绸那样光滑。还有一种充溢着橘黄色的帘幕的不经意的抖动。浓重的橘黄色上涂抹着橘黄色。而且好像没有别的逻辑,这只不过是一顶巨大的帐篷的衬里;帐内充满了窸窣的浓重的橘黄色丝绸以及大河奔流般的丰饶,懒洋洋地泛着波浪,满眼的橘黄激荡起轻柔的波浪。明亮的橘黄和阴暗的橘黄,明暗不一的橘黄,许多的反应多姿多彩,一律有着丝绸的质感,在那顶大帐篷里,似乎,那或许是一顶撑在那里的军队帐篷,(英国的?土耳其的?)好像离母亲所来的那个地方不远,那个婴儿抱在她怀里(父亲在哪儿呢?),或许应邀来到那里,到那个军队驻扎的帐篷,这顶帐篷,这顶印度帐篷(为什么是印度的?不过可能就是印度帐篷了:在一个英国军营里的一顶印度帐篷?),这顶大帐篷,在那个炎热的日子里,轻轻摇荡,几乎没有一丝风,帐篷懒洋洋地一次次鼓胀起来,那似有若无的风吹拂一次,帐篷都用丝绸般柔软光滑的橘黄色悄声细语轻轻应答。这丝绸般的橘黄色是那么的光滑,那么的明亮,一泻千里进入那个观察者记忆的大海,他现在看见了,并且第一次知道,在这里,他知道了,从他内心深处知道,在这里,现在渐渐地了解到所有这橘黄色的存在,那橘黄色的丝绸鼓荡起波纹,轻轻地、柔柔地掠过那高大、细腻的帐篷,帐篷轻轻地固定在那里,满眼是辉煌壮丽的橘黄,全是辉煌壮丽的橘黄,这里略显黯淡,那里无比光亮,在一顶巨大无比的帐篷里,被似有若无的风追逐着,他至多有两岁,如果不是母亲用胳膊搂着,在她的怀抱里,他怎么会到过那个地方?在她的臂弯里,在她的怀抱中,他当时突然发现了这个东西的幻象,了解到这完美的橘黄色,这独特的、普遍的、完美的、满世界洪水泛滥一般的橘黄色闪耀着光芒,那光滑的、半透明的丝绸带来喃喃低语般的微风,能触摸到,或许甚至还能闻到它的气味,就在那同一顶印度帐篷的衬里上,好像,还有些绵软,假如,这的的确确就是那整个微微闪光的橘黄色波动的真正含义,如果这一切都是真真切切的,如果他真的就在那里,那么,就有这么个地方。而这就是那个地方,混沌初开的地方。这就是万物的初始,然后才有后来的事,开始有了天和地,有了热、日子和风,开始有了母亲把他抱在臂弯里,带着母亲的体香,这就是那最初的地方。
这整个开头部分试图出现在时间之外,很像是一幅画,而不是一个故事,像是同一个句子,像是在那顶帐篷内部空间来回反弹的一瞥,就地旋转而没有时间的推移。不过,这个长句子用节奏感很强的短语划分节拍,还包含了另外一个声音:这个声音一次又一次严厉地责问第一个声音,探究,怀疑,求证。第二个声音几乎总是在括号里响起,而且几乎总是在提问:“英国的?”“土耳其的?”“父亲在哪儿呢?”“为什么是印度的?”“在一个英国的军营里?”“至多有两岁吗?”“如果这一切都是真真切切的,如果他真的就在那里。”
第一个声音,也就是那个主要的声音,努力触摸到无遮无掩的感官:喃喃低语,光滑,触摸得到,闻得到气味,绵软,移动。而第二个声音总在限制、确认、定位、定义。第一个声音是原始的,第二个声音仿佛在试图限制第一个声音,总在审问,求证:“如果不是母亲用胳膊搂着,在她的怀抱里,他怎么会到过那个地方?”第一个声音是通感的声音,把各种不同的感官结合在一起了(“那光滑的、半透明的丝绸带来喃喃低语般的微风,能触摸到,甚至还能闻到它的气味”)。到了这一部分的结尾,似乎这两个对立的声音之间那越来越紧张的关系达成了某种谅解,第一个声音回忆“母亲把他抱在怀里,带着母亲的体香”,而第二个声音把它的怀疑主义搁置一边,只说了一句很短的话,就把那个很长的句子描绘的一切给确认了:“这就是那最初的地方。”
然而,那顶橘黄色的印度帐篷并不是那最初的地方,或许只是最初的地方的映照。那顶印度帐篷只不过是叙述者“当时突然发现了这个东西的幻象”的那第一个地方。在这一发现下面,很显然有比这更早的东西在闪着微光:母亲的子宫。“光滑,像丝绸那样光滑……充溢着橘黄色的帘幕的抖动……而这只不过是一顶巨大无比的帐篷的衬里,帐内充满了……大河奔流般的丰饶……一律有着丝绸的质感……这就是万物的初始……开始有了天和地,有了热、日子和风,开始有了母亲把他抱在臂弯里,带着母亲的体香……”
凝视那个地方的人实际上同时凝视着两个地方,而这两个地方又相互印证:子宫和帐篷,第一串的感觉和第一个识别的时刻。两个新发现一旦融合,那个“我”就开始成其为“我”。(伊曼纽尔·康德发现,无意识的感觉是“盲目的”,而无感觉的意识是“空洞的”。)
要描写那个“我”的出生,语言就其本质来说,便构成了一个障碍。语句必须一句跟在一句后面,而对橘黄色的丰富的感觉却是一层含在一层里面。所以,叙述者就试图打破语言的镣铐,用词语塑造一些本为词语力所不及的东西。为了达到这一目的,他把“所在”这个词语和它通常的含义分开了:在《米克达莫特》整个第一部分,读者都被要求用“时刻”置换“地方”:“这就是万物的初始……这就是那最初的地方。”(顺便说一下,在一些希伯来语词句中,地方的概念指的都是时间,反过来也是如此,正如在英语里:“从此(from here on in)”、“提前(beforehand)”、“整点(top of the hour)”、“正午(high noon)”。
该书的开头部分要求读者参与消除地点和时间的界限。“地方”在这一页里并不是一个地点概念,而是世界的丰富光亮促使“我”由蒙昧而发生的无限觉醒。不管怎么说,第一个声音是这样声称的。
“因为那最初的地方……是橘黄色。”
“橘黄色”在《米克达莫特》的开头一页出现了不下二十三次。此外,希伯来文版本的首句有二十二个单词,其中五个是“橘黄色”,四个是“最初的”,还有“完整”、“非常”、“完完全全”这些词语。一种预言性的行为,一种通过巫术来激发回忆的行为,蕴涵在这些重复当中:最初的橘黄色橘黄色最初的橘黄色最初的。因此,在叙述者的记忆中,太阳和橘子的颜色是这个世界的鲜明色彩,这也是《米克达莫特》这部小说大半篇幅的主色调。
和许多小说的开篇合同形成对照的是,这份开篇合同没有向读者交待事件、人物、时间和地点。没有通常意义上的“说明”,没有一个摆放在故事的主要入口、为读者的阅读之旅提供必要信息的咨询台。诚然,第二个声音一次又一次从括号里审问第一个声音——那个军营是英国的?还是土耳其的?那顶帐篷是印度的?那么他的父亲在哪里?——仿佛在要求第一个声音按顺序讲述,要求它履行其“说明的职责。”
诸如“最初的橘黄色最初的橘黄色最初的”这种预言性的祈祷,不断重复某一个语句或一个声音或一个形象,旨在变魔术一样变出记忆的洞穴,指望挖出一些深埋在遗忘的沙层之下的宝藏——所有这一切在文学中都司空见惯。许多小说描述“我”和“它”的初次相遇,描述通过对“非我”的初次认识而有的“我”的结晶过程。例如,人们会回想起乔伊斯的《一个青年艺术家的画像》开头部分那哞哞叫的奶牛,盛开的野玫瑰花,啄眼睛老鹰之歌;就这样,在睡眠和清醒以及小玛德莱娜蛋糕[3]之间的模糊区域中的细致回忆,促使普鲁斯特的记忆开始《追忆似水年华》;托马斯·沃尔夫的《天使,望故乡》开头部分那催眠的重复的咒语也起到相同的作用:“……一块石头,一片叶子,一扇没有发现的门……在哪里?在何时?”
在《米克达莫特》的开篇合同里,要求读者一路撤回到那通感的、多种感官并用的体验中去,回到众感官分离和分工之前对存在的感知:读者必须从开头第一句就毅然启航,驶入一个满是颜色的世界,这(唯一的)颜色是橘黄色,而这橘黄色宛若丝绸,光滑柔软,窸窣作响,慵懒地波动,时而明亮,时而幽暗,还能够“变换反应”,化为“橘黄色的尘埃”,而这橘黄色的尘埃“被无声地、悄悄地吹走了”,但还能闪闪发光,喃喃低语,是“半透明的,能触摸到,或许甚至还能闻到它的气味”。(无巧不成书,哈伊姆·纳赫曼·比亚利克[4]在他的好几首诗如《微风》[5]、《光辉》、《池塘》和他的短篇小说《再生》里,都有类似的尝试,伸手触摸感官分工之前的体验。)
如果一个读者不能或是不愿一同来消除各个感觉之间、各种情感之间以及感受和被感受到的东西之间的那神秘的樊篱,那么他就完全无法读懂《米克达莫特》。这样一个读者至多是紧紧抓住“第二个声音”提供的“护栏”穿过它而已;他来到文本的另一边,所得信息的皮囊宛若蛋壳一样轻薄易碎:一个故事,故事里的人啰里啰嗦地讲述他还是婴儿的时候,抱在母亲怀里,去看了一顶帐篷,或许是顶印度帐篷,在一个军营里,或许是个英国或土耳其的军营,帐篷笼罩在语言的橘黄色云雾中。
然而,这开头部分的一切并不是雾,而是看似矛盾地运用语言去达到超乎语言的东西,达到词语产生之前存在着的东西,达到和词语那局限、固定的本质相悖的东西:语言毕竟是一种工具,我们大多用它来标识、定义、澄清、分割和区别。然而,在《米克达莫特》的开头部分,语言试图使世界重新归一,回复到其原始的、泛感官的本质上去。词语,就其本质来说,必须按照顺序,一个一个地来,这样便把一种线性的时间顺序决定论强加到一切事物上。在这个开头部分,那些词语并没有按照线性顺序进行安排,也没有勾画出一条线:它们颇像涟漪一般四散开来。那些涟漪的眼,也就是在这个文本中发出一圈又一圈幽光的鹅卵石,就是“地方”、“橘黄色”、“最初的”这些词语。
一个人怎么才能够用词语达到那恰恰被词语破坏削弱的原始体验呢?
通过打破常规,比如:那顶印度帐篷在“无风”的吹息中“懒洋洋地鼓胀应答”。(我有一次听到一个匈牙利移民妇女生造了一个类似的词语,她抱怨水龙头里没有水,说:“连没水都没有。”)
或者是通过把整个开头部分写成一个连绵不断的句子,这个句子中的东西(理想情况下)没有时间上的先后。
或者,运用括号,在第一个声音和第二个声音之间营造一种赋格[6]。
或者,通过顿悟的灵光忽现:“……他当时突然发现了这个东西的幻象,了解到这完美的橘黄色,这独特的、普遍的、完美的、满世界洪水泛滥一般的……”
然而主要还是通过把语言当作音调,而不是当作标识来运用,用一串又一串的拟声词,用旋律多变的混成曲,这样,语言突然之间就不再指示,不再传达信息,而是开始歌唱,开始起舞:
最初的地方最初最初
不用任何明证的最初的地方
是橘黄色啊完完全全的橘黄色
橘黄橘黄浓重的橘黄
或者这样:
这就是万物的开始,
在后来发生的一切之前
天和地,热、日子和风
都是这样开始
【注释】
[1] 萨迈赫·伊兹哈尔(1916——2006),原名伊兹哈尔·斯米兰斯基,以色列当代著名作家,现代希伯来文学的伟大革新家。代表作有长篇小说《齐克拉格的日子》。曾获以色列文学奖。
[2] 《米克达莫特》:伊兹哈尔在文坛沉寂近三十年后于1992年出版的一部自传性很强的长篇小说,讲述了1917年至1930年之间,一个男孩在巴勒斯坦的犹太人农垦社区和特拉维夫这座年轻的城市的成长经历。这个男孩子的感官体验、他对世界最原始的萌芽状态的领悟与回顾往事的成人的意识、一种晚年向着孩童的内心深处的回归结合在一起。他的成长经历和以色列早期犹太人农耕定居点的故事相关:创造一个新的犹太民族的渴望,定居点艰苦的生存条件以及犹太人和阿拉伯人早期的冲突。伊兹哈尔描写的画面富有感官冲击力,充满着气味和色彩。《米克达莫特》的主题是一个孩子在困惑、好奇和恐惧中对他周围具体世界的发现。伊兹哈尔使他的童年在以色列的土地上复活,并借此对重建的犹太人社会进行了温和的盘点。
[3] 小玛德莱娜蛋糕:一种甜点,因《追忆似水年华》一书而闻名。在这部小说的开头,小玛德莱娜蛋糕的味道唤起了主人公对往事的回忆。
[4] 哈伊姆·纳赫曼·比亚利克(1873——1934),犹太诗人,被誉为现代希伯来语诗人的先驱。
[5] 英文版作“Zephrys”,疑为“Zephyrs”(微风)之误。
[6] 赋格:复调乐曲的一种形式。赋格中的主题和与其成对位关系的对题在不同声部中交替出现。
谈[[什·约·阿格农]]小说《在她风华正茂之年》的开头-[[阿摩司·奥兹]]
========================
谁来了?
故事开始了:文学随笔集 阿摩司·奥兹
谈什·约·阿格农小说《在她风华正茂之年》的开头
-----
《在她风华正茂之年》比《艾菲·布里斯特》的出版时间晚大约二十七年,和《艾菲·布里斯特》一样,《在她风华正茂之年》讲述的是一个年轻女人嫁给一个曾和她母亲相爱过的老男人的故事。艾菲在她那个时代同意和殷士台顿结婚,对爱情没有什么期盼,因为她接受了她所处的社会环境的价值观并深深认同,以致在她看来,“他当然是合适的男人。每个男人都是合适的。当然了,只要他出身高贵,有地位,长相好”。与之形成对照的是,《在她风华正茂之年》中的女主人公提尔察非常想嫁给阿卡维亚·马扎尔,努力按照自己的方式行事,并且根据她的心愿,或许也根据某种跨代的正义感断定,阿卡维亚就是合适的男人。和艾菲不同的是,提尔察不接受她认为的她周围的世界流行的价值观。对提尔察来说,爱情高于一切:她爱阿卡维亚·马扎尔——或许她爱的只是她母亲对他的那份不了情中反映出的他的形象。她甚至愿意得重病,用生病作为一种非常规武器,把她想得到的男人弄到手,即便他对这桩姻缘并不热心,抑或是对任何别的姻缘都不热心,总体来看,他不是那种热心人。提尔察的目的就是要纠正发生在她父辈身上的不公正。到了故事的结尾,读者可能意识到了——可以说是背着叙述者——情欲上的不公正是无法修复的。在这个故事中,有一只小狗时不时地跑来跑去。那不是一只《就在昨天》里那样的疯狗;事实上,这条狗相当友好,不过它的名字是梅乌瓦特,是扭曲、歪曲、变形的意思。
提尔察为了得到她想得到的,不惜把她的病变成武器,似乎在说:如果你不给我阿卡维亚,你怎样失去我母亲的,也就会怎样失去我。这里,爱情和疾病的关系既是微妙的,又是辩证的:提尔察的母亲生病了,所以就无法和阿卡维亚结合;而提尔察呢,通过生很重的病,却赢得了他。然而,提尔察的爱情使人想起了赫拉克利特之火:她的胜利就是她的失败。提尔察婚后的生活是冷冰冰的,要么是因为经过了这么多年,那位浪漫的偶像已经变成了一位彬彬有礼、体贴入微的中年绅士,要么是因为他一直就是这个样子,不同于母女二人浪漫的幻想。提尔察试图严格照着她母亲的形象生活,而在她看来,她的丈夫却开始像她的生身父亲了(他们如此相像,以至到了故事的末尾,她甚至把他们混淆了起来)。
提尔察和一个比她老了一辈的男人的生活恰好变成了他父母婚姻的复制品:温柔体贴,但却不是她追寻的生活。她追求的,不是世俗的生活而是母亲一直求而不得的火一般的激情。
两个人身份相同的基本模式在小说中一次又一次出现,使得整个作品充满了身份的混淆,不管是大的还是小的,琐屑的还是象征的,喜剧的还是悲剧的身份,都给混淆了。每一个人物似乎都包含着另一个人物。在故事的开头,甚至我们还没搞清楚谁爱的是谁,就在好几处出现了身份错认或身份误导。而这种身份错认或误导的意义只有到了故事的结尾部分,读者才恍然大悟。(阿格农本人有一次在另一个场合开玩笑说,一本书如果不值得读上两遍,那干脆连第一遍也不要读。)《在她风华正茂之年》的开篇合同要求,除了别的事情,读者还要在读完整部作品后回过头再看一遍开头。
我母亲在她那风华正茂的年龄就逝世了。她死时大约三十岁。她的一生短促而痛苦。她整日坐在屋子里,从不离开。她的朋友和邻居不来看她,我父亲也不请他的熟人过来。我们的屋子伫立着,像是默哀。房门几乎从来没有为陌生人打开过。我的母亲躺在床上,很少说话。而当她说话的时候,就仿佛是悲悯的双翼裹挟着我,把我带到了圣殿。我是多么热爱她的声音啊。许多次我打开房门,好让她问问是谁来了。我表现得像个小孩子。她有时候会离开床,坐在窗户边。她会身穿白色的衣服坐在窗户边。她的衣服总是白色的。有一次,我叔叔戴维到我们的城市来,看见我母亲,还以为她是个护士呢,因为她那身白色的衣服把他弄糊涂了,他不知道她就是病人。
她的病是一种心病,使她感到郁郁不乐。每年夏天,医生都把她送到温泉疗养。但几乎是刚刚到她就回来了,说是她的渴盼并没有得到缓解。她就又坐到窗前,或是躺到床上。
我父亲开始减少他的商业活动了。他甚至连德国也不怎么去了。他过去可是每年都要去德国和他的生意伙伴见面的;我父亲是个粮食商人。这一次他没有去。在那些日子里,在那一段时间,他不问世事。到了晚上他回到家,就坐在我母亲身旁。他左手托在头下面,右手放在她的手里。而她有时候会把他的手拿到唇边亲吻。
在这开头的几行,身份混淆的地方不下三处:谁来了,谁又没有来?谁是病人,谁是护士?谁是被《雅歌》[1]激起爱情的恋人?
提尔察和她母亲的关系近乎宗教仪式。从故事的开始,她就把母亲神化了,爱慕她那坐在窗边的仪式,崇拜她那身白色的衣服。后来,她为母亲的美貌所折服,沉迷于她那美妙的香气(尽管她从不搽香水)。环绕母亲的那微妙而顽强的临终仪态的那种神秘,在提尔察内心唤起一种强烈的激情,这激情最终决定了她的命运。母亲去世以后,她设法融入到母亲的形象中,以至到了自我否定的地步。她们之间那近乎宗教仪式的关系使得她们没有了母女之间的亲密关系,或许这话得反过来说:正因为缺少母女之间的亲密关系,才在提尔察的内心产生了一种对母亲崇拜的态度。母亲身陷病痛和她那渴盼的忧伤之中,她没有表现出与提尔察亲近的欲望,甚至对女儿的存在都没有表现出兴趣。对孩子吸引她的注意力的企图,她没有任何反应。
对提尔察来说,她母亲的声音宛若天使的歌声:“她说话的时候,仿佛是悲悯的双翼裹挟着我,把我带到了圣殿”,“我是多么热爱她的声音啊”。可是,提尔察的声音,几乎是她对她母亲的耳朵发出的唯一声音,却是门的响声,那扇门打开过“许多次”(在一个“房门几乎从来没有为陌生人打开过”的屋子里)。那是一个孩子气的,逗引人的声音:母亲就要死了,女儿对她玩个小恶作剧。读者直到后来才会发现,这孩子气的欺骗是多么残忍(但是并无恶意)。当读者明白了这位病入膏肓、每次都问“谁在那儿?”的女人或许还在等待她的心上人来向她道别。这位母亲一次又一次了解到,那扇门打开,只不过是她女儿孩子气的恶作剧而已,但是她不仅没有责骂孩子,还再次追问是谁来了。仿佛在说:我等待的不是你。
从故事一开始,提尔察似乎就是一个爹不亲、娘不爱的孩子。她父亲很显然整个心思都在她母亲身上;她母亲沉浸在她的爱情和告别仪式中;亲戚朋友几乎不注意提尔察。和《艾菲·布里斯特》那全知的叙述者形成对照的是,提尔察对她母亲最后那些日子的观察带有“审美的”和“情感的”意味:她对母亲那浪漫的香消玉殒,对那环绕着这位病入膏肓的女人的白色的、忧郁的光环无比地着迷。提尔察感觉到“悲悯的双翼”把她运送到“圣殿”。她是唯一的观众,在观看一个女人的独角戏。
即便是在母亲生命的最后一天,提尔察都试图捕捉到母亲的眼神,哪怕仅仅是一小会儿:“那扇门开了三次,而她没有问是谁来了,我跟她说话她也不理。”母亲临死前最后几个小时,她一直在读信件,烧信件,和她幼时的朋友明奇·戈特利布长谈,和她丈夫进行温和而坚决的告别。而对于她唯一的孩子,她没有给她片刻的时间,没有给她一句解释、关爱和告别的话,尽管那孩子尽了最大的努力,通过开门的暗示接近她。甚至连一句责骂的话也没有。“……这些话写在薄薄的纸上,一行又一行,写得有长有短。当我看到母亲阅读时,我对自己说,她永远也不会冷落那些文字。”假如提尔察能够看清那笔迹、纸张的质量和那一行行字的长度的话,那么至少有一刻,她和她母亲是站得很近的。然而,即使是那一刻,她母亲都没有对她说一句话,甚至连一点点温柔和关注的样子都没有。
正如我们已经看到的,开门的恶作剧并不是故事开头部分唯一迷惑人的地方。一位叔叔来访,他误以为病人就是护士,因为她穿着一身白衣服。在下一段,读者也被误导了,会想象母亲和父亲之间有一份由《雅歌》激发的爱情,“他的左手在我头下,他的右手将我抱住”(《雅歌》2:6)。而真实情况是,提尔察父母之间的关系虽然也是那种柔情的亲密和忧郁的厮守,但《雅歌》中却没有一句唱到它。我们眼前的情景是,他的左手没有放在她的头下,他的右手也没有拥抱她,却几乎是反过来的:“他左手托在他的头下面,右手放在她的手里。”他们没有像《圣经》里描写的那样拥抱,而只是握着手,后来,他们没有接吻,而只是吻了吻手。
母亲的衣服总是一袭白色,这就强化了那爱情和疾病的含蓄统一:母亲的连衣裙白得像婚纱,像医院的白大褂,像护士的制服,像裹尸布。把婚礼和死亡并置,毫无疑问是浪漫主义的曲目:一对恋人受着社会或家庭的禁忌的阻挠,但不管怎样,他们终于通过死亡结合在一起。(就像是埃德加·爱伦·坡在《安娜贝尔·李》[2]中描述的那样。)
《在她风华正茂之年》的开头写得就像一个精心绘制的平行四边形,连恐怖都给平衡得恰到好处。的确,故事中的那些平行关系和《圣经》式的希伯来语中的神韵都依托着一种严密的内部逻辑:母女二人都是阿卡维亚·马扎尔的学生。阿卡维亚·马扎尔是一位从维也纳来的知识分子和教师,他放弃了都市生活,来到这个小镇边上租了一间房子住下,要进行一次浪漫的“寻根”之旅。他有点儿是老师,又有点儿是启蒙时代的诗人,还有点儿是研究墓碑的历史学家。提尔察的父亲对她的希伯来语教育非常关心。那位男家庭教师塞加尔教她现代希伯来文。那位向她求婚的小伙子兰达,则用《圣经》里的古希伯来文给她写情书。
回到故事的开头几行:母亲的生命在消殒,而父亲的整个世界也要随之而去。他们两人都沉浸在自己的悲伤之中,几乎没有注意到女儿的存在。尽管如此,他们始终保持着有序而稳定的日常生活。从某种意义上,这一点使人回想起霍恩-克莱门的冯·布里斯特的宅院:一个表面上四平八稳的世界,有着固定的规矩,良好的举止和自我克制的习惯。明氏家族多年来长盛不衰,靠的是粮食贸易、犹太人的传统、周而复始的假期和礼节。家里有一个女仆,有一个——或许有一个吧——保姆,还有一个男家庭教师;定期到国外的温泉胜地疗养,到德国去谈生意。
在《艾菲·布里斯特》的开头,那一成不变的现实是通过对建筑、墙壁和花园的线条的详尽描写而形成的,而在这里,家族传统的稳定性首先是在写作风格上突显出来:一个《圣经》式的平行四边形——从故事开头的几行——就给我们展现出这样一个世界,这个世界即使在危机和悲剧发生的时刻,都牢牢稳稳地屹立在对称的支柱上:“她整日都坐在屋子里,从不离开。”(从字面讲也就是:“她整日坐在屋子里;她从不走出屋子。”)
这个句子的第二层意思里,没有一点信息不是第一层意思已经传达的。(性急的编辑可能会在页边批注:阿格农先生,这是多余的重复,应该删掉。)然而,这样一个句子的力量就是通过这样一个事实营造出来的,那就是,这个句子包含相同的两层意思。表面上稳定的平衡、均势以及坚固的结构掩盖了一个社会和家庭的实际情况,其内部的平衡越来越遭到动摇。
在《艾菲·布里斯特》里,那移动的阴影威胁着宁静、富足而凝滞的气氛,这种气氛笼罩着这座贵气的深宅大院。同样地,《在她风华正茂之年》的开头部分,那压抑的爱情和即将到来的死亡颠覆了开头几页的风格所表现的矜持而忧伤的和谐根基。那段未果情缘动摇了一场功利婚姻的支柱;那压抑的激情削弱了家庭和社会的价值;启蒙——或许只是启蒙那伤感的回音——颠覆了传统;灾难深藏在家庭的和谐之下。孪生性和可互换性恰恰威胁着人物的身份。
若不是莎士比亚已经使用了《错误的喜剧》这个题目,并且已经是久负盛名,我们倒是可以把这个题目用于《在她风华正茂之年》,故事里多的是成对出现的人物,一个关于两个女人的故事,她们母女二人,一个嫁给了一个爱她、呵护她的男人,但这个男人不是她想嫁的;另一个嫁给了她想嫁的男人,后来却发现他根本不是她想象中的男人。在这个故事里,丈夫实际上是父亲,而父亲却酷似丈夫。这还是一个婴儿的故事,这婴儿一看到父亲和他的双胞胎兄弟站在一起,就惶恐不安,绝望困惑地大哭。这也是一个年轻女人的故事,她出生于一个剥夺了女人情爱选择权的时代和社会,她奋起反抗——成为希伯来文学中最早的叛逆女性形象之一。她冲破了传统的壁垒,得到了她想得到的。然而,她发现她的胜利是空洞的,要么是由于她还没搞清楚她是何许人,那个男人是何许人,什么东西只不过是镜子里的虚影;要么是由于她成了一种“情感教育”间接辐射的受害者,这种情感教育充满着“悲悯的双翼”、“圣殿”、披着纯白色外衣的疾病和以迷人的婚礼的姿态登场的死亡。
开头几行在读者眼前设置了一个合同的圈套[3]。提尔察的声音,这位叙述者的声音,她那抑扬顿挫的《圣经》式的语言,对母亲疾病的那种挽歌式的忧郁和父亲的钟情所表现出的审美兴奋,对《雅歌》的暗指,所有这一切把读者带进了一种朦胧而感动的情绪之中。这些似乎为一个有关伤心、孤女、爱情以及感情战胜了社会桎梏和阶级樊篱的故事做好了铺垫。然而,如果再读一遍,或者是往回读的话,那么《在她风华正茂之年》透露出的却是,提尔察虽然给自己争得了她母亲当年没有争得的东西,但是她极有可能只是一个小阴谋的牺牲品,而这个小阴谋就是一个爱操控他人的家庭密友一手策划的。[4]最后,提尔察陷入了几乎和她那心碎的母亲一样的境地。因此,就要求读者,甚至是迫使读者,回到开头部分,重新审视那份合同里的蝇头小字。这样一看,读者就会确信他压根儿就没有受骗:他只是过于匆忙地相信了提尔察的声音,没有停下来质疑她和她的故事,而她的故事从一开始就到处是错误,到处是混淆的身份,比如开门的恶作剧,使得母亲一次又一次问:“谁在那儿?”
“谁在那儿?”而不是“谁在这儿?”
母亲的名字叫利亚。《圣经》中利亚[5]的故事也是一个身份混淆的故事。几乎直到提尔察的回忆的最后一页,她都在搞错身份,不管是重要还是次要的身份。
利亚那“温柔”的目光、她女儿提尔察的目光和这个故事中其他人物的目光都不断地去看“谁在那儿”。或许是因为他们几乎看不到谁在这儿。
【注释】
[1] 《雅歌》:《圣经》中的一章,其中的诗篇有人认为是爱情诗。
[2] 《安娜贝尔·李》:爱伦·坡的一首关于爱情和死亡的抒情诗。
[3] 原文注:亚伯拉罕·班德,《〈我的米海尔〉和〈在她风华正茂之年〉中靠不住的叙述者》,文见《什穆埃尔·约瑟夫·阿格农作品论文集》,希勒尔·巴泽尔编;阿姆·奥韦德出版公司,特拉维夫,1982,320-329(希伯来文版)。
[4] 原文注:尼察·本·多夫,《阿格农的间接艺术》;E.G.布里尔,莱顿,纽约,科伦,1993,107——133。
[5] 利亚:雅各的第一个妻子。她奉父命冒充妹妹拉结与雅各结婚,而雅各爱的是拉结。见《圣经·创世记》。
谈幽默-老舍
========================
谈幽默-[[老舍]]
-----
“幽默”这个字在字典上有十来个不同的定义。还是把字典放下,让咱们随便谈吧。据我看,它首要的是一种心态。我们知道,有许多人是神经过敏的,每每以过度的感情看事,而不肯容人。这样人假若是文艺作家,他的作品中必含着强烈的刺激性,或牢骚,或伤感;他老看别人不顺眼,而愿使大家都随着他自己走,或是对自己的遭遇不满,而伤感的自怜。反之,幽默的人便不这样,他既不呼号叫骂,看别人都不是东西,也不顾影自怜,看自己如一活宝贝。他是由事事中看出可笑之点,而技巧的写出来。他自己看出人间的缺欠,也愿使别人看到。不但仅是看到,他还承认人类的缺欠;于是人人有可笑之处,他自己也非例外,再往大处一想,人寿百年,而企图无限,根本矛盾可笑。于是笑里带着同情,而幽默乃通于深奥。所以Thackeray(萨克莱)说:“幽默的写家是要唤醒与指导你的爱心,怜悯,善意——你的恨恶不实在,假装,作伪——你的同情与弱者,穷者,被压迫者,不快乐者。”
Walpole(沃波尔)说:“幽默者‘看’事,悲剧家‘觉’之。”这句话更能补证上面的一段。我们细心“看”事物,总可以发现些缺欠可笑之处;及至钉着坑儿去咂摸,便要悲观了。
我们应再进一步的问,除了上面这点说明,能不能再清楚一些的认识幽默呢?好吧,我们先拿出几个与它相近,而且往往与它相关的几个字,与它比一比,或者可以稍微使我们痛楚一点。反语(irony),讽刺(satire),机智(wit),滑稽剧(farce),奇趣(whimsicality),这几个字都和幽默有相当的关系。我们先说那个最难讲的——奇趣。这个字在应用上是很松泛的,无论什么样子的打趣与奇想都可以用这个字来表示,《西游记》的奇事,《镜花缘》中的冒险,《庄子》的寓言,都可以叫作奇趣。可是,在分析文艺品类的时候,往往以奇趣与幽默放在一处,如《现代小说的研究》的著者Marble(马布尔)便把Whimsicality and humour(奇趣和幽默)作为一类。这大概是因为奇趣的范围很广,为方便起见,就把幽默也加了进去。一般地说,幻想的作品——即使是别有目的——不能不利用幽默,以便使文字生动有趣;所以这二者——奇趣与幽默——就往往成了一家人。这个,简直不但不能帮忙我们看明何为幽默,反倒使我更糊涂了。不过,有一点可是很清楚:就是文字要生动有趣,必须利用幽默。在这里,我们没弄清幽默是什么,可是明白幽默很重要的一个效用。假若干燥,晦涩,无趣,是文艺的致命伤;幽默便有了很大的重要;这就是它之所以成为文艺的因素之一的缘故吧。
至于反语,便和幽默有些不同了;虽然它俩还是可以联合在一处的东西。反语是暗示出一种冲突。这就是说,一句中有两个相反的意思,所要说的真意却不在话内,而是暗示出来的。《史记》上载着这么回事:秦始皇要修个大园子,优旃对他说:“好哇,多多搜集飞禽走兽,等敌人从东方来的时候,就叫麋鹿去挡一阵,满好!”这个话,在表面上,是顺着始皇的意思说的。可是咱们和始皇都能听出其中的真意;不管咱们怎样吧,反正始皇就没再提造园的事。优旃的话便是反语。它比幽默要轻妙冷静一些。它也能引起我们的笑,可是得明白了它的真意以后才能笑。它在文艺中,特别是小品文中,是风格轻妙,引人微笑的助成者。据会古希腊语的说:这个字原意便是“说”,以别于“意”。因此,这个字还有个较实在的用处——在文艺中描写人生的矛盾与冲突,直以此字的含意用之人生上,而不只在文字上声东击西。在悲剧中,或小说中,聪明的人每每落在自己的陷阱里,聪明反被聪明误;这个,和与此相类的矛盾,普遍被称为Sophoclcanirony(索福克里斯的反语)。不过,这与幽默是没什么关系的。
现在说讽刺。讽刺必须幽默,但它比幽默厉害。它必须用极锐利的口吻说出来,给人一种极强烈的冷嘲;它不使我们痛快的笑,而是使我们淡淡的一笑,笑完因反省而面红过耳。讽刺家故意的使我们不同情于他所描写的人或事。在它的领域里,反语的应用似乎较多于幽默,因为反语也是冷静的。讽刺家的心态好似是看透了这个世界,而去极巧妙的攻击人类的短处,如《海外轩渠录》,如《镜花缘》中的一部分,都是这种心态的表现。幽默者的心是热的,讽刺家的心是冷的;因此,讽刺多是破坏的。马克。吐温(Mark Twain)可以被人形容作:“粗壮,心宽,有天赋的用字之才,使我们一齐发笑。他以草原的野火与西方的泥土建设起他的真实的罗曼司,指示给我们,在一切重要之点上我们都是一样的。”这是个幽默者。让咱们来看看讽刺家是什么样子吧。好,看看Swirt(斯威夫特)这个家伙;当他赞美自己的作品时,他这么说:“好上帝。我写那本书的时候,我是何等的一个天才呀!”在他廿六岁的时候,他希望他的诗能够:“每一行会刺,会炸,象短刃与火。”是的,幽默与讽刺二者常常在一块儿露面,不易分划开;可是,幽默者与讽刺家的心态,大体上是有很清楚的区别的。幽默者有个热心肠儿,讽刺家则时常由婉刺而进为笑骂与嘲弄。在文艺的形式上也可以看出二者的区别来:作品可以整个的叫作讽刺,一出戏或一部小说都可以在书名下注明asatire.幽默不能这样。“幽默的”至多不过是形容作品的可笑,并不足以说明内容的含意如何。“一个讽刺”——asatire——则分明是有计划的,整本大套的讥讽或嘲骂。一本讽刺的戏剧或小说,必有个道德的目的,以笑来矫正或诛伐。幽默的作品也能有道德的目的,但不必一定如此。讽刺因道德目的而必须毒辣不留情,幽默则宽泛一些,也就宽厚一些,它可以讽刺,也可以不讽刺,一高兴还可以什么也不为而只求和大家笑一场。
机智是什么呢?它是用极聪明的,极锐利的言语,来道出象格言似的东西,使人读了心跳。中国的老子庄子都有这种聪明。讽刺已经很厉害了,可到底要设法从旁面攻击;至于机智则是劈面一刀,登时见血。“圣人不死,大盗不止!”这才够味儿。不论这个道理如何,它的说法的锐敏就够使人跳起来的了。有机智的人大概是看出一条真理,便毫不含忽的写出来;幽默的人是看出可笑的事而技巧的写出来;前者纯用理智,后者则赖想象来帮忙。Chesterlon(切斯特顿)说:“在事物中看出一贯的,是有机智的。在事物中看出不一贯的,是个幽默者。”这样,机智的应用,自然在讽刺中比在幽默中多,因为幽默者的心态较为温厚,而讽刺与机智则要显出个人思想的优越。
滑稽戏——farce——在中国的老话儿里应叫作“闹戏”,如《瞎子逛灯》之类。这种东西没有多少意思,不过是充分的作出可笑的局面,引人发笑。在影戏的短片中,什么把一套碟子都摔在头上,什么把汽车开进墙里去,就是这种东西。这是幽默发了疯;它抓住幽默的一点原理与技巧而充分的去发展,不管别的,只管逗笑,假若机智是感诉理智的,闹戏则仗着身体的摔打乱闹。喜剧批评生命,闹戏是故意招笑。假若幽默也可以分等的话,这是最下级的幽默。因为它要摔打乱闹的行动,所以在舞台上较易表现;在小说与诗中几乎没有什么地位。不过,在近代幽默短篇小说里往往只为逗笑,而忽略了——或根本缺乏——那“笑的哲人”的态度。这种作品使我们笑得肚痛,但是除了对读者的身体也许有点益处——笑为化食糖呀——而外,恐怕任什么也没有了。
有上面这一点粗略的分析,我们现在或者清楚一些了:反语是似是而非,借此说彼;幽默有时候也有弦外之音,但不必老这个样子。讽刺是文艺的一格,诗,戏剧,小说,都可以整篇的被呼为asatire;幽默在态度上没有讽刺这样厉害,在文体上也不这样严整。机智是将世事人心放在X光线下照透,幽默则不带这种超越的态度,而似乎把人都看成兄弟,大家都有短处。闹戏是幽默的一种,但不甚高明。拿几句话作例子,也许就更能清楚一些:今天贴了标语,明天中国就强起来——反语。
君子国的标语:“之乎者也”——讽刺。
标语是弱者的广告——机智。
张三把“提倡国货”的标语贴在祖坟上——滑稽;再加上些贴标语时怎样摔跟头等等招笑的行动,就成了闹戏。
张三把“打倒帝国主义走狗”贴成“走狗打倒帝国主义”——幽默;这个张三贴一天的标语也许才挣三毛小洋,贴错了当然要受罚;我们笑这种贴法,可是很可怜张三。
这几个例子摆在纸面上也许能帮助我们分别的认清它们,但在事实上是不易这样分划开的。从性质上说,机智与讽刺不易分开,讽刺也有时候要利用闹戏;至于幽默,就更难独立。从一篇文章上说,一篇幽默的文字也许利用各种方法,很难纯粹。我们简直可以把这些都包括在幽默之内,而把它们看成各种手法与情调。我们这样分析它们与其说是为从形式上分别得清楚,还不如说是为表明幽默——大概的说——有它特具的心态。
所谓幽默的心态就是一视同仁的好笑的心态。有这种心态的人虽不必是个艺术家,他还是能在行为上言语上思想上表现出这个幽默态度。这种态度是人生里很可宝贵的,因为它表现着心怀宽大。一个会笑,而且能笑自己的人,决不会为件小事而急躁怀恨。往小了说,他决不会因为自己的孩子挨了邻儿一拳,而去打邻儿的爸爸。往大了说,他决不会因为战胜政敌而去请清兵。褊狭,自是,是“四海兄弟”这个理想的大障碍;幽默专治此病。嬉皮笑脸并非幽默;和颜悦色,心宽气朗,才是幽默。一个幽默写家对于世事,如入异国观光,事事有趣。他指出世人的愚笨可怜,也指出那可爱的小古怪地点。世上最伟大的人,最有理想的人,也许正是最愚而可笑的人,吉珂德先生即一好例。幽默的写家会同情于一个满街追帽子的大胖子,也同情——因为他明白——那攻打风磨的愚人的真诚与伟大。
潭施 假死 - 副刊 文艺春秋 星洲网 Sin Chew Daily
==================================
[https://www.sinchew.com.my/content/content_2385285.html](https://www.sinchew.com.my/content/content_2385285.html)**
# 潭施/假死
文艺春秋
天气变热的后果超乎想像,绝对不是安装冷气或减少出门就可以独善其身。那年4月,空气中弥漫着一股焦躁,早晚犹如置身在蒸气房中,驱之不散的湿热充斥着鼻腔气管,让人坐立不安,让人缺氧。那个4月,大部分时间我伏案在空气不流通的小房间里赶论文——游客入住乔治市古迹酒店的意图。
说实在,我不关心乔治市的古迹酒店,以及游客入住古迹酒店的意图。我不认为事情那么复杂,是因为口耳相传还是能力所及,是酒店位置好还是房间装饰别致,听起来左右都像在鸡蛋里挑骨头。事实是,大部分古迹酒店的客房都与普通酒店没有两样,充其量房内多一张古董椅子,价位高昂些的可能就多一架泛黄的老旧浴缸,而我居然要为此撰写一篇至少100页的文章,天花乱坠地绕一圈地球回到原点。无论如何,我的个人立场不阻碍我站在老城的街头巷尾,头顶着大太阳厚着脸皮要求游客填写问卷。没有站在街头抛头露面的日子,我窝在自己的小房间,孜孜矻矻地吞咽其他论文学说,找寻可以支撑理论的论点。这通常是一整天的事,虽然谈不上废寝忘食,但察觉时间时经常也已是半夜三更。
随着论文截稿日期逼近眉睫,呼吸困难与胃胀风的老毛病卷土重来。凌晨一点半,我站在盥洗台前刷牙,像脱水的鱼大口大口深呼吸。入夜后虽然没有白天闷热,却也不凉快,外头的树如蜡像静止,仿佛有无形的罩子罩在上空,滴水不漏。我清着舌苔,捎到敏感处胃酸伴随胃气哗啦哗啦嗝出来。夜晚的社区除了大楼对面的室内巴刹还有人在打麻将,通常非常安静,连周围流连的野狗也鲜少叫吠。
漱完口,客厅的电视画影还在流动,电视机前的妹妹已经沉入梦乡。她的身躯陷在陈年的横条藤椅上,弯成一个弧,疲惫的脸上泛着浅浅油光。午夜新闻播着卡巴星车祸片断,行动党党员神色凝重——这绝对是党以至国家沉重的损失,画面上的人物说。
我将电视关掉,转身看见妹妹额头上的汗,细而密集。她头顶上的吊扇拼了命在转,已然是速度的最大极限。将灯熄掉之前,妹妹下意识举起手,在手臂上抓了两下。长指甲与肌肤摩擦发出刷刷两声,夜里显得特别响亮,随即手臂上留下了两道浅色的红。
灯熄灭后,世界只剩黑暗。
它们畏光。
人类因为没有在黑暗中看见的能力,所以没有及早发现它们。包括心思细腻的母亲,都没发现它们留下的蛛丝马迹,那些圆圆的小黑点,完好地融入周遭背景,象是岁月在床边墙角留下的痕迹,在真身揭示之前毫不显眼。
那一阵子,岛上笼罩在一片失去的悲恸氛围中,参加追思会的人来自全国各地,各族群和各年龄层。先跨过我的尸体!卡巴星对伊刑法坚定的立场让人印象深刻,那是一个无所畏惧的巨人,立成一堵高耸的坚硬的墙,将世俗国的框架稳住。许多人舍不得那敢怒敢言的真性情,在政坛上尤其难得;更多人恐惧,在没有卡巴星后,伊刑法的提案会如西伯利亚冻土底下的炭疽菌,等待时机刚好,悄然苏醒。
它的苏醒、布局与繁衍,完全在我们可能的想像范围外。当家人开始发现有异物入侵居家环境,影响日常生活时,感染程度已扩散如癌症末期,失去控制。天气的炎热让人难以忍受,蚊虫在妹妹全身上下留下张扬的咬痕,母亲则一天到晚精神不济。
“妈你是不是睡不好?”
“没有啊……”母亲伸手擦拭眼角的泪,一脸疲态,“只是眼睛不知怎的一直在流泪。”
妹妹以为自己火气大惹蚊虫叮咬,大喝罗汉果青草茶降火;母亲则认为天气热眼睛过敏,猛滴眼药水。直到一天下午,母亲罕见地大声唤我,是一种近乎毛骨悚然的求助声。
我盯着母亲床上的竹席很久。
母亲每晚都睡在竹席上,这习惯已经持续了好几年。竹席由一小块一小块3x2公分的竹板连接起来,在炎热的赤道铺在床上睡特别凉快。自从母亲睡坏了若干年前她从大陆扛回来的那张竹席后,就一直念叨着买新的。只是竹席并非必需品,镇上不容易找,好不容易找到,如获至宝。“还是最后一张”,母亲为她的战利品喜滋滋。
我蹲在床边,盯着床上的竹席。蓦地,一只黑色的只有几毫米的虫从竹块这一端爬出来,快速钻入竹块那一端。流着汗的背脊瞬间凉了,寒意延伸到耳后,冻结脑袋运转的能力。我转过头,正好对上母亲的视线,两人相觑半晌,二话不说,七手八脚将竹席卷起来,连拖带拉将竹席扛到大楼垃圾堆。丝毫不留恋。
母亲事后用消毒药水前前后后擦拭家里的每一个角落,将床被单都洗过,枕头抱枕都曝晒过。我们绝口不提虫子的事。5月下旬我提交了论文的最终版本,等待教授做最后一次反馈。长期在外的弟弟回家过生日,我们还帮他庆生。蓝卡巴星誓言捍卫他父亲的政治立场,誓死抵抗伊刑法,在补选中用狂风扫落叶的姿态大胜。妹妹身上的咬痕渐渐消退,母亲的眼泪也不流了,一切仿佛回到从前,那一个下午什么事情都不曾发生。
一个早上,妹妹惺忪着眼,抓着手上新鲜的五分一角大小红包,万念俱灰的表情说明了一切——它们还在。
万念俱灰。许多发生在我们身上的事情,当事人还来不及理解就成了定局,仿佛你只是个局外人,是第三者,无关紧要的群众。你以为自己生长在世俗国,突然一天她成了回教国;你以为土地上执行的是世俗法,突然一天她说要执行伊刑法。这些念头一直都在,它们只是隐藏起来,随着遏制条件松垮复活;就像它们携家带眷搬进来,大剌剌掠过我们的眼底,没有询问过我们,喧宾夺主。
怎么办?母亲问,哭丧着脸。
床虱二字刺痛我的神经,我弹跳起身上网爬文——“床虱是一种体型扁平椭圆,呈赭红色,吸人血为生的寄生虫。它们没有翅膀,既不能飞,也不能跳,通常潜伏在人们睡觉的区域附近……检查床铺或枕头,它们会留下黑色小点,那是它们的排泄物……”
母亲不停地抓头。她头皮发痒,那些小黑点嵌在她床头的地板上,嵌在墙角边,嵌入瞳孔里,我用指甲用力抠,非常难除去。那不是岁月的痕迹,是床虱走过必留下的大便,吃饱喝足的铁证。我们粗心至此。
“床虱进行创伤式受精,既雄虫不管雌虫的感受,用自己如利剑般的生殖器官强行插入雌虫身体。它们在隐蔽的场所交配,将卵产在墙壁、床板、家具等缝隙中。雌虫每个繁殖季节产卵二百多个,一年繁殖三代或三代以上。耐饥,吸血后即躲藏不出,成虫不得血食可耐饥一年以上,幼虫得不到血食可活30天以上……”我看着那些家具摆设,它们可潜藏的范围太广,我们战败的机率太大。
怎么办?我们是不是该考虑搬家。
我突然发现,世界上的生命组织超乎所认知的庞大与复杂,多种生物交错生存在同一个空间,不只鸟在天空飞,不只鱼在水里游,这群生物和你占用同一个空间,比如蟑螂出没厨房的频率和你出没的次数一样多,比如白蚁吃掉了房子的骨架,比如螨虫爬满了床爬上你的脸,而你对它们的认知如此匮乏,甚至对它们的存在浑然不知。这种浑然不知,正如我就站在你面前而你却不知道我爱你,是现实与想像的落差,是人与人或人与事认知上的黑洞,直到东马的邻居文莱突然宣布通过伊刑法,众人才棒头大喝。
我们丢弃了床褥,多余的家具,跑遍了镇上大小超市尝试了不同的杀虫剂。我们分工合作检查房内各个肉眼所及的缝隙,出动强力手电筒照明,细针探入罅隙中钩扰一动不动的赭红色身体,它们圆滚着肚子打禅,在缺少日照的卧室建构理想的天堂。
墙上到处是它们被压扁的尸体,血却是来自于我们。血迹是一笔一笔加上去的,像血债血还的账,要一笔一笔算清。一天一天过去,每一次喷药过后,蓝色的房门被紧紧地关起来,如潘多拉的小盒子,里头发酵着另一个咬牙切齿的世界。数小时后,我们一家总动员清算业绩,每回都有来自各生命阶段的鲜活个体曝露嘴脸,象征源源不绝的生命力。它们还在,而且非常顽强。我们甚至用批土将所有缝隙填满,缝隙无处不在,石灰与木板连接的地方、裂开的墙角、落漆的墙壁,电灯罩底下、电线管背后……雪白的墙如补破衫般糊上东一块西一块的批土,却总有我们错漏或超出我们所及的地方。我们几乎疯了。
半夜热醒,客厅仍然灯火光明,藤椅空荡荡的。妹妹趴在桌上不敢睡,她被折磨得最惨,一脸的惶恐憔悴。对街麻将声依旧,除了我们一家,没有人知道那些外生物盘踞于此,每天交配产卵繁殖后代,蓄势待发毁灭人类。世界如常运转。世界如常运转?发生那么大件事,世界怎么可以如常运转!我想起《最后十四堂星期二的课》中,最让我动容的篇幅。没有人因为你怎样了就怎样,没有谁不可以失去。除非床虱搬到你家。
人就是沧海一粟。
我看着装订好的论文,朱红色的厚皮上烫上我金色的名字,以及金色的“游客入住乔治市古迹酒店的意图”。所以呢?那时候我还不知道,后来的求职面谈中,面谈的人要问同一句话——所以呢?而我支支吾吾,答不出来。
准备论文口试那几天,除虫公司的人终于出现在家门口。他们只有一个电话的距离,承认无计可施却需要极大勇气。在这之前,我以为他们的制服至少要像抓鬼团队或化学测漏员那样,戴个氧气罩或防毒面具,将鬼怪都吸到背后的钢制长筒里。尽管外形并不惹人注目,他们的到来还是引起同楼层一两户邻居的注意,毕竟我们是户挨着户地生活着。
除虫公司来了三次,前两次相隔两天,最后一次相隔一个星期。他们三人成一队,每人一桶药水,一支喷嘴,将屋子里各房间角落家具褥垫都仔细喷上一回。开始作业前,他们戴上口罩、手套和穿上白色袜子,“以防粘上,白色袜子增加看见的机会”。每次作业结束,他们将外面的衣物除下,装到大塑料袋内封死。
我对这份工作充满好奇,他们是否有洞悉另一个微观世界的能力?就像道士驱惊,问米婆附灵。你怎么不怕被感染?我问其中一人。
什么不怕!对方反射性地脱口,却一副欲言又止,“带过一次回家……家里的地上铺的是地板,它们躲在地板下,喷药根本喷不到,搞到全家活动范围就只剩各自的床。那时每张床架四个脚都浸泡在水杯里防止床虱爬上来,床架上的床垫则用塑料袋套死,不让它们爬出来。”
后来呢?我问。
“如果不是房子刚买,应该会搬家。”他大叹一口气,“后来就掀开地板啊,花了一大笔钱。”他心有余悸,捉鬼反被鬼附身,毕生难忘。
三次治疗结束后,日子算是回到了常轨上。论文口试结束后,我们替沾血的墙重新上漆。没有人建议将凹凸不平的墙磨平,大家都担心床虱冬眠式假死的本事,一不小心又复活。
天气依旧炎热,据报上说是自1975年以来最炎热的一年,单是这个月的高温就已经破了好几次历史纪录。我们尽量少出门,同时商议是不是应该装冷气了。伊斯兰党很快在国会提呈私人法案,寻求在吉兰丹州落实伊刑法,引来各路挞伐,也为后来的民联解体埋下伏笔。
周末,弟弟如往常般打电话回家。他说起新加坡的天气和大马一样糟,而且房里突然多了好多蚊子,每天醒来都发现手臂有新咬痕,全身都在痒。
作者 : 潭施
文章来源 :
星洲日报 2020-12-04
[[托马斯·曼文集·中短篇小说选 - 特里斯坦 by 托马斯·曼|https://www.kanunu8.com/book2/10973/196096.html]]
托马斯·曼文集·中短篇小说选 特里斯坦
作者: [[托马斯·曼]]
-----
这儿就是“爱茵弗里德”疗养院!它的亘长的大厦和两侧的建筑,矗立在广阔的园子中央,颜色洁白,线条笔直。园子里,精致地布设着假山洞、林阴小径和树皮搭成的小亭。在石板瓦屋顶后面,蜿蜒着高大的山峦,直耸向天空,山上一片绿色的枞树林。
仍旧是列昂德医生主持这所疗养院。他蓄着下端两头尖的黑须,又僵硬又鬈曲,就像填塞家具用的马鬃;还戴着闪闪发光的厚眼镜,那副神气俨然科学已使他冷却、硬化,并给他灌注了沉静、开明的悲观主义。就依凭这些,他严峻冷酷、沉默寡言地管理着他的病人,而那些人呢,大都优柔寡断,既不能为自己制定一套规章制度,又不能自动遵守,便干脆让他作主,乐得去依赖他的严格管束。
至于封·奥斯特罗小姐呢,她孜孜不倦地献身于疗养院的总务工作。天啊,她多么忙碌,顺着楼梯跑上跑下,从疗养院的这一头奔到那一头!她统治着厨房和储藏室,在收藏浣洗衣物的橱里钻来钻去,指挥仆役,从经济、卫生、美观、可口的角度,安排全院的膳食,尽量做到皆大欢喜。她做事迅速周到,在那极度的精明能干中,蕴藏着对整个男性世界的经常谴责,要知道在那个世界里还没有人想到要娶她回家哩。但在她的面颊上,在两朵圆圆的朱红彩云中,燃烧着不可磨灭的希望,终有一日会成为列昂德医生夫人……
臭氧和安宁幽静的空气!……不管列昂德医生的竞争者和妒忌他的人怎么说,“爱茵弗里德”是值得向肺病患者热诚推荐的。但不仅是肺结核病患者,其他各种病人也上这儿来,男女老少都有;列昂德医生在各种疾病的领域中都显示出成绩。这儿有害胃病的,例如市参议员史巴兹夫人,她外加耳朵还有毛病;还有害心脏病的老爷太太们,和中风的、害风湿病的,以及神经有各式各样毛病的人。有一位害糖尿病的将军,在这儿消耗他的退休金,老是怨个不停。有几位先生,脸上瘦得皮包骨头,两条腿不听指挥地晃来晃去,显然不是什么好兆。还有一位五十岁的太太,郝伦劳赫牧师的妻子。她养了十九个孩子,完全失去思维的能力,但仍得不到安宁。一年以来,她在一种癫痴的烦躁驱使下,倚着她私人看护的胳膊,瞪着眼睛,哑口无言,阴森森而漫无目标地在整幢屋子里窜来窜去。
在“重病号”当中,偶尔有人死去。这些人睡在自己的房间里,从不出来吃饭,也不在客厅里露面。他们死去时,没有人知道,连隔壁屋里的人也一无所知。在寂静的深夜里,直挺挺的客人被打发出去,而“爱茵弗里德”的活动却毫无阻碍地继续进行:在装置着现代设备的各个诊疗室里,进行着按摩、电疗、注射、淋浴、盆浴、体操、发汗和气功等治疗……
是的,这儿可真热闹。疗养院正欣欣向荣哩。新客人来的时候,侧屋入口处的门房便敲响大钟。有人离去时,列昂德医生就和封·奥斯特罗小姐一起,郑重其事地陪送上车。什么样人物“爱茵弗里德”没有接待过呢!这儿甚至有一位作家。他是个乖僻的家伙,叫一个什么矿物或者宝石的名字,也在这里浪费光阴……
此外,除了列昂德医生,还有另一个医师,负责轻微或者业已绝望的病号。不过他姓缪勒,并不值得一提。
一月初,批发商科勒特扬——阿·茜·科勒特扬公司的老板——把他的夫人带到“爱茵弗里德”来了。门房敲响了钟,封·奥斯特罗小姐在底层的会客室里接待从远方来的贵宾。这间会客室里的布置,和几乎整幢豪华的古老建筑物一样,也是道地的拿破仑帝国时代的式样。列昂德医生跟着就出现,并鞠了个躬,随即开始了初次交换双方情况的谈话。
窗外的花园是一片冬日景象,花坛上铺着草席,山洞埋在雪里,小亭显得孤单。两个仆役,正把新客人的箱子从马车上搬进来;马车停在铁栅门外公路上,没有一条直达屋前的支路。
当科勒特扬先生带领他妻子经过花园时,他曾说:“慢点,迦伯列勒;takecare,我的天使,把嘴闭上。”大凡见过她的人,都不能不怀着温存和激动的心情,对这声“takecare”从心底发出共鸣。——其实,要是科勒特扬先生干脆用德语说这两个字,也不见得就会拗口些。
从车站送贵宾来疗养院的马车夫,是个无知的粗汉,不懂什么温存,可是当批发商搀他妻子下车时,他竟提心吊胆起来,不由自主地把舌头伸到牙缝当中。是呀,看起来好像连两匹在宁静的严寒中冒着水汽的棕色马儿,也直朝后面翻眼睛,紧张地注视着这令人不安的场面,对如此脆弱的娇媚和优柔的丽质充满关怀。
这位少妇患的是支气管的毛病,关于这点,科勒特扬先生从波罗的海海滨写给“爱茵弗里德”主治医师的报到信里说得明明白白。感谢上帝,毛病不在肺里!不过,如果毛病果真在肺里的话,——那么这位新病人的模样,看起来也不可能比现在更加妩媚和高贵,更加远离尘世和超凡脱俗了。她坐在健壮的丈夫身旁,娇弱疲惫地靠在直线条的白漆安乐椅上,倾听着谈话。
她美丽、苍白的手,轻放在膝上一件深色厚布裙的褶裥里,除了一只朴素的结婚戒指外,没有戴什么别的首饰。她穿一件硬高领的银灰色贴身小腰的上衣,上面镶满着凸起的阿拉伯式天鹅绒花纹。可是厚实温暖的衣服,只有使那说不出地娇柔、甜蜜和慵倦的脸蛋儿,显得更加迷人、神秘和可爱。淡褐色的头发,平平地梳向脑后,打成一个结儿,直垂到颈下;只是靠近右边的太阳穴,才有一绺松开的鬈发吊在额上。离这儿不远,在描画得显明的眉弯上面,有一根出奇的小血管,呈淡蓝色,带几分病态,在明净无疵、仿佛透明的前额上岔开。眼睛上的这根蓝色小血管,令人不安地控制着整个纤巧的椭圆形面孔。只要夫人开口说话,甚至只要笑一笑,它就明显地隆起,给脸部带来一些紧张、甚至郁闷的表情,使人感到一种不可名状的担忧。但她还是在说笑。说起话来,坦率亲切,声音略有点喑哑;用眼睛微笑,眼神显得有点疲乏,有时还会变得黯淡,纤细的鼻根两旁的眼角,笼罩在深浓的阴影里。她也用嘴笑,阔阔的美丽嘴巴是没有血色的,但好像发出光彩来,那大概是因为嘴唇的轮廓格外鲜明和清晰的缘故。她间或轻轻咳几声,用手绢揩揩嘴,然后看看手绢。
“别咳,迦伯列勒,”科勒特扬先生说。“你知道,darling,在家里的时候,辛兹彼得大夫特别嘱咐你不要咳。只要克制一下就行了,我的天使。就像我所说的那样,毛病在气管。”他重复道。“开始发作的时候,我当真以为是肺病,天知道,我多么害怕。但并不是肺病,不是的!见鬼,我们才不会让肺病缠上呢,是吧,迦伯列勒?啊,啊!”
“当然不会。”列昂德医生说,眼镜朝她闪了闪。
接着,科勒特扬先生叫了咖啡,——咖啡和奶油面包卷。他的K音是从喉咙深处发出的,奶油面包卷也读得很特别,别人听了不免要嘴馋。
他叫的东西端了上来,他和妻子的房间也分配好了,便安顿下来。
附带地说,列昂德医生亲自负责治疗,没有要缪勒医生过问病情。
新来女病人的神采轰动了整个“爱茵弗里德”。科勒特扬先生对这种现象早已司空见惯,得意洋洋地接受人们对他妻子的赞美和奉承。害糖尿病的将军第一次瞧见她时,居然在片刻间停止发牢骚;脸上瘦得只有皮包骨头的绅士走到她跟前时,便露出微笑,拚命克制自己的两条腿;市参议员史巴兹夫人立刻跟她亲昵起来,做她年长的朋友。啊,这位以科勒特扬先生的姓为头衔的女人,的确给了人们一个深刻的印象!有位在“爱茵弗里德”消磨了好几个礼拜的作家,是个性情乖僻的家伙,名字听起来就像什么宝石似的;当她在走廊里经过他身旁时,他飞红了两颊,停了下来,直到早已看不见她了,还像生根似地站着不动。
两天还没过去,全疗养院的人都已知悉了她的身世。她是不来梅人;这也可以从她说话时的某些可爱的土音中听出来。两年前,就在不来梅这个地方,她把终身交托给批发商科勒特扬先生。她跟随他到他在波罗的海海滨的故乡,在离现在大约十个月以前,在极端困难和危险的情况下,为他生了一个孩子,一个惊人地活泼和发育良好的儿子和继承人。但自从那些可怕的日子以来,她始终就没有恢复她的精力——如果她曾有过精力的话。她精疲力竭,刚从产床上起来,便咳出一点血——唔,并不多,只是无关紧要的一点点血;可是,倘若根本没发现血,就更好了。令人不安的是,这桩不祥的小事故,不久以后又重新发生了。对付它自然有办法,家庭医生辛兹彼得大夫,就采用了一些办法。他嘱咐病人要好好休息,吞食小冰块,用吗啡抑制咳嗽的刺激,尽可能使心脏平静。但病始终不能痊愈,就在小安东·科勒特扬这个出众的婴儿,用巨大的精力无情地占据和巩固他在生活中的地位时,年轻的母亲却似乎在柔和、宁静的火光中熄灭下去……就像前面所说的,毛病出在气管——这个字眼儿,从辛兹彼得大夫嘴里说出来,对大家都产生了惊人的慰藉、安心,差不多有鼓舞的效果。但尽管毛病不在肺里,医生终于表示,比较温和的气候,加上在疗养院里住一个时期,对加速痊愈的过程是迫切需要的。“爱茵弗里德”疗养院和它主持人的声誉,解决了余下的问题。
情况就是这样,科勒特扬先生亲口把这些事讲给每一个表示有兴趣的人听。他大声地、懒洋洋地、愉快地讲,俨然是一位消化系统同他钱袋的状况一样良好的绅士。他的嘴唇张得很开,就像北方海边上的人那样,语调拖得既长而又急促。有些字给他吐出来,每个音节都好比是一次小小的爆炸,这使他自己发笑,仿佛讲了什么好玩的笑话似的。
他中等身材,阔肩,健壮,短腿,圆滚滚的红脸,海蓝色的眼睛,上面蓬着金黄的睫毛,宽大的鼻孔,湿漉漉的嘴唇。他蓄着英国式的颊须,一身都是英国式的打扮;当他在“爱茵弗里德”遇到一家英国人时,便喜出望外。这家英国人,包括父亲、母亲、三个漂亮的孩子和孩子的保姆,在这儿逗留,仅仅是因为他们不知道还有什么别的地方好去。科勒特扬先生早上总跟他们一起吃英国式早餐。他这人就爱吃喝,既要多又要好,显示出自己是个道地的烹饪和酒窖的鉴赏家,津津有味地向疗养的人们描述在家乡朋友们所举行的宴会,介绍这儿无人知道的山珍海味。说话的时候,眯起眼睛,露出亲昵的表情,声音里夹杂着上腭和鼻腔的音调,喉咙里伴随着轻微的啧啧声。至于对世上别的一些乐趣,他原则上也并不抱有反感,这点有一天晚上得到证明。有一位在“爱茵弗里德”疗养的病人,职业是作家,曾看见他在走廊上相当放肆地同一位侍女调笑。这诚然是桩小事情,开开玩笑而已,那位作家却露出一副可笑的令人厌恶的表情。
至于科勒特扬夫人呢,显而易见她是钟情于她的丈夫的。她含着微笑,倾听他的谈话,注视他的举动:不是像有些病人那样,对健康人抱着高傲的宽容态度,而是像心地温良的患者,对一身舒泰的人在生活上充满自信的表现,感到亲善的愉悦和同情。
科勒特扬先生在“爱茵弗里德”没有逗留多久。他是带妻子上这儿来的;过了一个星期,他眼看她已受到很好的照顾,并且在可靠的人手中,就不肯呆下去了。同等重要的职责——他的欣欣向荣的孩子和同样欣欣向荣的事业——召唤他归去,迫使他启程,留下妻子享受最好的治疗。
那位作家叫史平奈尔,在“爱茵弗里德”已住了好几个礼拜,他的全名是德特雷夫·史平奈尔。他有着一副奇特的仪表。
我们设想一个长着深褐色头发的男子吧,他三十岁刚出头,身材魁梧,太阳穴上的头发已明显地开始花白,但那圆圆的、略有点浮肿的苍白面孔上,却连胡须的痕迹也没有。不是脸刮光了——这可以看得出来,而是像孩童一般柔嫩、细软,只不过这里那里长一两根茸毛罢了,看上去古怪得很。他的眼睛明亮,呈小鹿似的淡褐色,眼光里流露出温和的表情;鼻子粗短,略嫌臃肿。此外,史平奈尔先生还长着一个拱形多毛孔的罗马式上唇,蛀掉了的大牙齿,和一双大得出奇的脚板。有个两腿不听指挥的绅士,说话俏皮,喜欢嘲讽,在背后给他取了个绰号,叫他“败坏的婴儿”;这句话说得有些恶毒,不一定恰当。——他的衣着考究、时髦,长长的黑上装,杂色花点的背心。
他为人孤僻,跟任何人都不交往。只是偶然之间会突然激动起来,便对人和蔼可亲、热情洋溢。这每每发生在史平奈尔先生受到“美”的感染的时候;他偶尔看到什么美的景象,调和的色彩,奇丽的花瓶,夕阳回照下的一脉山峦,便情不自禁地赞叹起来,说一声:“多美呀!”一面说,一面把头歪向一边,耸起肩膀,摊开双手,皱缩鼻子和嘴唇。“天哪,您瞧,多美呀!”在这激动的一刹那,他甚至可能冲动地去拥抱最显贵的人士,不管是男的还是女的……
他的桌上,总放着自己写的那本书,每个走进他房间的人一眼就可以瞧见。那是部篇幅有限的小说,封面上画着一张使人莫名其妙的图画,印书的纸颇似滤咖啡的纸头,每个字母看上去像个哥特式的大教堂。封·奥斯特罗小姐有次在空闲的时候曾读过这部小说,发觉它很“高雅”,这是她代替“沉闷得不近人情”的一种迂回的说法。故事发生在时髦的客厅里,豪华的闺房中;那里尽是些精致的东西,五彩的壁毯,古色古香的家具,贵重的瓷器,无价的针织品,和各种各样的古玩摆设。他以最珍爱的心情描绘这些物件,阅读的时候仿佛老是会看到史平奈尔先生皱起鼻子喊:“多美呀!天哪,您瞧,多美呀!……”附带说一下,令人诧异的是,除了这本书以外,他还没有写出第二本来,虽然显而易见,他热衷于写作。他一天大部分时间都关在屋里写东西,寄出去许多信件,几乎每天都有一两封——奇怪和有趣的是,他自己却难得收到一封信……
吃饭时史平奈尔先生坐在科勒特扬夫人的贴对面。当这一对新客人第一次到侧屋底层的大餐厅里吃饭时,史平奈尔先生来得稍微迟了一些。他用柔和的声调向大家打了个招呼,坐在自己的位子上。列昂德医生不太客气地把他介绍给新来的客人。他鞠了一躬,便开始吃饭,显然有点窘;一双长得很好看的又白又大的手,从紧窄的袖管里伸出来,挥动着刀叉,动作颇不自然。吃好以后,便沉静地轮流端详科勒特扬先生和他的妻子。用膳当中,科勒特扬先生曾向他提出一些有关“爱茵弗里德”的环境和气候的问题与意见;他的太太也和蔼可亲地插进一两句,而史平奈尔先生总是有礼貌地回答。他的声音柔和,相当悦耳,但说话不大流利,吞吞吐吐,好像牙齿妨碍了舌头似的。
饭后,大家都到了客厅里,列昂德医生特地过来祝两位新客人健餐,科勒特扬夫人便打听坐在她对面的人是谁。
“那位先生姓什么?”她问,“……史平奈尼?我没听清楚他的姓名。”
“史平奈尔……不是史平奈尼,夫人。不,他不是意大利人;据我所知,他只不过出生在棱堡……”
“你说什么?一位作家?还是别的什么?”科勒特扬先生问;他两手插在舒适的英国式裤子口袋里,耳朵凑向医生,像某些人所习惯的那样,张着嘴巴听。
“嗯,我不清楚,——他在写什么……”列昂德医生回答,“好像出版过一本书,小说之类的东西,不过我的确不太清楚……”
列昂德医生一再重复“我不清楚”,乃是暗示他根本没有把这位作家放在心上,对他也不负任何责任。
“多么有趣呀!”科勒特扬夫人说。她从来还没有面对面地看到过一位作家。
“唔,是的,”列昂德医生逢迎地应道。“据说他有些名气哩……”关于这位作家的谈话就到此结束了。
可是过了一会儿,新客人出去以后,列昂德医生正打算离开客厅时,史平奈尔先生却拦住他,进行他这方面的探询。
“这对夫妇姓什么?”他问……“我当然什么也没听清楚。”
“科勒特扬。”列昂德医生答道,拔脚就走。
“丈夫叫什么?”史平奈尔先生问……
“他们姓科勒特扬!”列昂德医生说,自顾自地走了。——他根本没有把这位作家放在心上。
我们是不是已经提到科勒特扬先生回家去了?是的,他又重新居住在波罗的海的海滨,照料他的事业和孩子——就是那个冷酷无情和充满活力的小家伙,他给母亲招致了那么多痛苦和气管里的毛病。至于年轻的夫人自己,则仍然留在“爱茵弗里德”,市参议员史巴兹夫人以年长女友的身份陪伴着她。但这并不妨碍科勒特扬夫人跟别的疗养的客人建立友好关系,比如跟史平奈尔先生。他出乎大家意料之外(他过去一直没有跟任何人交往),从开头起,就异常专心和殷勤地侍奉她。而她呢,在严格的日程所空余下来的时辰,也未尝不乐意跟他聊聊。
他万分关心、极其恭敬地跟她接近,说话时总是留心压低嗓门,弄得那位耳朵有毛病的史巴兹夫人,通常连一个字也听不清。他踮起那双大脚板的脚尖,凑向科勒特扬夫人的靠椅;她微笑着,娇弱无力地靠在椅背上。他在两步开外停下来,一条腿曳在后面,向前弯下上身,用那不大流利的、吞吞吐吐的声调,恳切地轻声低语,随时准备急忙离去,只要她脸上露出一丝疲乏和厌倦的表情。但他并不使她厌烦;她请求他跟她和参议员夫人坐在一起,向他提出个什么问题,然后微笑着,好奇地倾听,因为有时他的话听起来确实又有趣又古怪,都是她从来没有听到过的。
“你到底为什么留在爱茵弗里德?”她问。“你需要什么样的治疗,史平奈尔先生?”
“治疗?……我只稍微电疗一下。不,不值得一提。就告诉你吧,尊贵的夫人,我为什么呆在这里:——是为了风格。”
“唔!”科勒特扬夫人说,下巴靠在手上,脸转向他,一副夸张的热心神情,就像小孩子要讲述什么时,大人故意装出的模样。
“是这样,夫人,爱茵弗里德是道地的拿破仑时代的建筑,有人告诉我,它以前是宫殿,一座夏宫。不错,这侧屋是后来添造的,但正中的大厦却是原来的老房子。有时候我简直少不了这古老的东西。为了保障起码的身心健康,非要它不可。显然,在软绵绵、舒适到令人淫逸的家具当中,人们的感觉是一个样子,而在这些线条笔直的桌子、椅子和帷帘当中,感觉又是另一样……这种明朗和坚实,这种冷酷的朴素和拘谨的严峻,给我力量和尊严。夫人,毫无疑问,它最终会使我得到内心的清涤和复苏,使我在品格上有所提高……”
“真有意思啊,”她说。“而且,要是我费一番心思,就会懂得的。”
他接着回答说:不值得费心思。于是他们就一块儿笑起来。连史巴兹夫人也笑了,表示怪有意思,但她并不说究竟听懂没有。
客厅宽敞,漂亮。洁白、高大的双扇门敞开着,通往贴邻的弹子房,两腿不听指挥的绅士们和另一些人在那里游戏。另一边有扇玻璃门,望出去是开阔的阳台和花园里的景致。玻璃门旁放着一架钢琴。还有一张衬绿绒的玩纸牌的台子,患糖尿病的将军和几位先生在那儿打惠斯脱。女士们在看书,或者在做针线活。一只铁火炉发出热来,但精美的壁炉里却堆着仿造的假煤块,上面贴着一条条火红的纸条,壁炉前安置着舒适的座位,供聊天之用。
“你起得可真早呀,史平奈尔先生,”科勒特扬夫人说。“有两三次我碰巧看见你早上七点半钟就出去。”
“起得早?啊,其中大有区别,夫人。老实说,我起得早,实在是因为贪睡。”
“这点你必须解释一下,史平奈尔先生!”——史巴兹夫人也要求他解释。
“嗯,……一个真正早起的人,照我看,不需要起得特别早。良心,夫人……良心真可怕!像我这样的人,一辈子都跟它扭打,费尽心机才能间或蒙骗它一次,巧妙地让它得到一点小满足。我们这号人是无用的,除了几个钟头的好时光以外,都是在创伤和病痛中挨日子,因为意识到自己毫无用场。我们憎恨那有用的,知道它粗俗、丑陋,并且捍卫这个真理,就像人们捍卫他们所不可缺少的真理一样。虽然这样,受到责备的良心却一直在啃啮我们,害得我们体无完肤。再加上我们的整个内心生活、我们的人生观、我们的工作方式……它们都具有异常不健康、腐蚀和折磨人的效果,使得情况更加恶化。幸亏还有些止痛药,否则简直不能支持下去。譬如说,一定程度的守规矩,讲究卫生的严格生活方式,对我们许多人说来,已成为一种必要了。早起床,早得出奇,洗个冷水澡,出去在风雪中散散步……这也许会使我们在一个钟头内,对自己感到稍许满意。如果依我的性子,请你相信,我会在床上一直躺到下午。所以我的早起,实质上是一种伪善。”
“不,为什么呢,史平奈尔先生!我说这是自我克制……不是吗,参议员夫人?”史巴兹夫人也说这是自我克制。
“不管是伪善也好,还是自我克制也好,夫人!随你用哪个字眼都是一样。我这人是那么令人烦恼的诚实,害得我……”
“正是这样。你一定太爱烦恼了。”
“是的,夫人,我时常烦恼。”
——天气一直晴好。附近一带的山峦、房屋和园林,都沉浸在无风的恬静和明朗的严寒中,沉浸在耀眼的光亮和淡蓝的阴影里,一切都那么雪白、坚硬和洁净。万里无云的淡蓝天空,穹顶似地笼罩着大地,成千成万闪烁的光点,发亮的晶体,在天空中飘舞嬉戏。这一向,科勒特扬夫人过得还差强人意;她不发烧,很少咳嗽,吃东西也不太勉强。她照医生的嘱咐,常在阳台上闲坐几个钟头,在寒气中晒太阳。她坐在雪地中,全身裹着毯子和毛皮,怀着希望呼吸那清新、寒冷的空气,好让她的气管痊愈。有时候,她看见史平奈尔先生在园子里散步。他也是一身温暖的衣着,还穿了一双毛皮衬里的鞋子,使那双脚板显得格外庞大。他小心翼翼地挥舞两臂,那副姿态又呆板又文雅,一步一探地在雪里走着。走近阳台时,便向她恭敬地问一声好,然后登上下面的台阶,好跟她攀谈一会儿。
“今早散步时,我看见一位美人……天哪,她多美呀!”他说,头歪向一边,摊开双手。
“真的吗,史平奈尔先生?请你把她描绘给我听吧!”
“不,那可办不到。我只会给你刻画出一个不真实的形象。我仅仅在走过去时,扫了那位夫人一眼,实质上就等于没有看见。但我所看到的模糊形影,已足够激起我的想象,给我留下一幅图画,美丽的图画……天哪,多美呀!”
她笑了起来。“你总是这样看美丽的女人吗,史平奈尔先生?”
“是的,夫人;这样看要好多啦,要是为了贪求真实,干脆盯住她们的脸看,那只会得到一个实际上含有缺陷的印象……”
“贪求真实……多么古怪的字眼!十足的文人辞令,史平奈尔先生!但说实话,它给我的印象倒挺深。它值得去玩味,而我好像也有点领会;字里似乎含有某种独立和自由的意味,它连真实都不放在眼里,尽管真实是最体面的东西,甚至就是体面的化身……它使我意识到,除了那些手可以抓住的东西以外,还存在着别的什么东西,更加微妙的东西……”
“我只知道有一副面孔,”他突然说,兴奋得声音不寻常地轻扬起来,握紧的手举在肩上,激动的微笑暴露出蛀牙……“我只知道有一副面孔,要是通过我的想象,对它珍贵的真实进行什么修改,那就是罪恶!我恨不得老是去端详它,在它上面留恋,不止是几分钟,或者几个钟头,而是我整个一生,让我完全陶醉在它里面,把人世间的一切都……”
“是的,是的,史平奈尔先生。不过,封·奥斯特罗小姐的耳朵可长哩。”
他沉默了,深深地鞠了一躬。当他重新站直时,他的眼光,带着窘迫和痛苦的神情,停留在那根奇异的小血管上;它虽现淡蓝的颜色,带有几分病态的模样,在她那仿佛透明的明净前额上岔出来。
一个怪人,一个非常特别的怪人!科勒特扬夫人有时会想起他,因为她有很多闲工夫去想。不知是换空气的效果开始失灵了呢,还是受到某种肯定有害的影响:她的健康恶化了,气管的状况一点都不理想,她感到虚弱、疲惫、食欲不振,还时常发烧。列昂德医生叮嘱她要休息、安静和当心。所以除非要躺在床上,她就在史巴兹夫人陪伴下,不声不响地静坐着,膝头上放着针线活,但不去动它,只是东想西想。
是的,他引起她思索,这位古怪的史平奈尔先生。说也奇怪,倒不一定是去想他,而是更多地去想自己。不知怎的,他在她内心里唤起一种对自己命运的罕有的好奇心,而她从来还没有过这种好奇心哩。有一天闲谈时,他曾向她表示:
“咳,女人们真是一种难解的谜……这道理虽不新奇,但你老是会为此感到诧异。喏,有位美人,一位仙子,一位如花如玉的人儿,一位神话梦境中的人物。她干的是什么呢?她去嫁给一个市集上卖艺的大力士,或者什么屠夫的徒弟她吊住他的胳膊走来,甚至还把脑袋儿倚在他肩上,恶作剧似地微笑,四下里探望,仿佛要表示:好吧,你们就为这事去伤脑筋吧!——于是我们就伤起脑筋来!”
这话引得科勒特扬夫人反复思索。
又有一天,史巴兹夫人颇为惊讶地发觉,他们两人中间进行了下面一段对话:
“请问夫人——恐怕我问得太冒昧了——你叫什么,你的名字究竟是什么?”
“我姓科勒特扬呀,史平奈尔先生!”
“嗯——那我是知道的。或者不如说,我否认这点。我的意思当然是指你自己的姓名,你的闺名。说公道话,夫人,你不得不承认,谁要叫你科勒特扬夫人,就该挨一顿鞭子。”
她打心底里笑出来,弄得那蓝色的小血管在眉弯上令人焦急地明显凸出来,给她娇嫩妩媚的脸蛋儿带来吃力和郁闷的表情,使人深为不安。
“咳!那怎么可以呢,史平奈尔先生!鞭子?难道科勒特扬这名字对你说来,是那么可怕吗?”
“是的,夫人,从我第一次听见这名字起,就从心底憎恨它。这名字不仅滑稽,而且俗气得要命。如果一定要刻板地遵守习俗,把你丈夫的姓名加在你头上,那真是又野蛮又卑鄙。”
“那么埃克霍夫呢?埃克霍夫好一些吗?我父亲叫埃克霍夫。”
“啊,你瞧呀!埃克霍夫就完全不同了!甚至有过一位杰出的演员也叫埃克霍夫。埃克霍夫还不错。——你只提到你父亲的名字,那么你母亲呢……”
“嗯,我还小的时候,母亲就去世了。”
“啊。——可以请求你再讲一些关于你自己的事给我听吗?如果你疲倦,就不必了。那么你歇一会儿,让我像上次一样,继续聊聊巴黎吧。不过,说得非常轻,是的,要是你低低地耳语,那只会使一切格外美丽……你生在不来梅吗?”他问这问题时几乎轻得没有声音,还带着意味深长的敬畏的表情,仿佛不来梅是个举世无双的城市,隐藏着无法形容的奇迹和不可告人的美妙,出生在那儿,就具有天赋的神秘高贵似的。
“可不是吗!”她不由自主地说。“我是不来梅人。”
“我有次去过那儿。”他若有所思地说道。
“天啊,你也去过那儿吗?咳,真是,史平奈尔先生,我相信,从突尼斯直到斯匹次卑尔根群岛,你一定什么地方都逛过了!”
“是的,我有次去过那儿,”他重复说。“晚上短短几个钟头。我还记得一条古老狭窄的街,在街旁的尖屋顶上空,奇异地斜挂着一轮明月。然后我进了一个地窖,里面是一股酒味和霉臭。印象真深……”
“真的吗?那在什么地方呢?——是呀,我就生在这样一幢尖屋顶的灰房子里,一幢古老的商人住宅,那儿地板发着回响,走廊漆得白白的。”
“令尊大人是商人吗?”他有点犹豫地问。
“是的。不过,实际上首先是艺术家。”
“啊!啊!什么样的艺术家?”
“他拉小提琴……但这还不能说明什么,史平奈尔先生。问题在于他拉得怎样!有些音调,我只要一听见,总是禁不住热泪盈眶,从来没有任何其他遭遇曾使我这样激动。你不会相信的……”
“我相信!啊,是多么地相信!……告诉我,夫人,你们大概是个古老的家族吧?已经有好几代人住在那尖屋顶的灰屋子里,在那儿工作和归天?”
“是的。——你为什么这样问呢?”
“因为这种情况并不罕见:一个具有讲求实际和单调刻板的资产阶级传统的家族,在接近衰亡时期,往往会再次通过艺术来放射出异彩。”
“是这样吗?——不错,拿我父亲来说,他跟一些自称艺术家并靠这种荣誉过活的人比起来,确实更像个艺术家。我只略会弹一点钢琴。现在他们不准我弹了;以前在家乡时,我却经常弹的。父亲和我,我们合奏……啊,那过去的岁月都保藏在我亲密的回忆里;特别是那座花园,我们家的花园,就在屋子的后面。花园里荒芜不堪,蔓生着野草,围着盖满苔藓的败墙颓垣;但正好是这一切才使它格外迷人。花园当中有一座喷泉,喷泉的四周像花圈似地着鸢尾花。夏天我常和女伴们一起在那儿消磨许多时辰。我们围在喷泉四周,坐在小折椅上……”
“多美呀!”史平奈尔先生说,耸起肩膀。“你们坐在那儿唱歌吗?”
“不,我们大多在打毛线。”
“可是……可是……”
“是呀,我们打毛线,聊天,我的六个女友跟我自己……”
“多美呀!天哪,听着,多美呀!”史平奈尔先生喊,脸完全扭歪了。
“这有什么使你感到特别美呢,史平奈尔先生?”
“啊,除了你还有六个姑娘,而你并不包括在这六人之内,却像一位女王那样,从她们当中崭露出来……你跟你的六位女伴是截然分开的。一顶小巧的金王冠,非常朴素,但又意味深长,戴在你的鬈发上闪闪发光……”
“咳,瞎说,哪儿有什么王冠呢……”
“有的,它隐隐地发光。我会看见它的,清清楚楚地看见它戴在你头发上,要是我在这样的时刻,曾悄悄躲在树丛里……”
“天晓得你会看见什么。不过,你并没躲在那儿,倒是有一天,我现在的丈夫,跟我父亲一起,从树丛里走出来。我们谈的话恐怕给他们偷听了不少……”
“那么就是在那儿,夫人,你认识了你的丈夫?”
“是的,我在那儿认识了他!”她愉快地高声说;微笑时,淡蓝的小血管,紧张地在眉弯上凸起。“你知道,他是来找父亲接洽业务的。第二天我们请他吃饭,再过三天,他便向我求婚。”
“真的吗!这一切发生得那么惊人地快吗?”
“是的……那是说以后进展得稍慢一些。你要知道,父亲对这事本来一点也不愿意,他提出一个条件,要我们考虑一段较长的时期。首先,他盼望我留在他身边,还有一些别的顾虑。可是……”
“可是……”
“可是我自己愿意,”她微笑着说,淡蓝的小血管,带着郁闷和病态的神情,再度主宰着整个可爱的面孔。
“啊,你自己愿意。”
“是的,而且我的态度非常坚决和庄重,就像你所看到的……”
“就像我所看到的。不错。”
“……所以我父亲最后不得不让步。”
“于是你就离开你的父亲和他的提琴,离开那幢古老的房屋,那座野草蔓生的花园、喷泉和你的六个女伴,跟随科勒特扬先生去了。”
“跟他去了……你说话真特别,史平奈尔先生!简直像《圣经》里一样!——是的,我离开了那一切,因为这是人的本性呀。”
“是的,大概是他的本性。”
“而且这关系到我终身的幸福。”
“当然。于是它就来了,幸福……”
“它是在那时候来的,史平奈尔先生,就是当他们第一次把小安东抱来的时候——我们的小安东,他鼓足那健康的小肺,用劲嘶叫起来,他可真强壮和健康呀……”
“这不是我第一次听你谈起小安东多么健康,夫人。想必他一定是格外健康吧?”
“他是的。而且他非常像我的丈夫,真滑稽呀。”
“唔!——事情的经过原来是这样啊。于是你现在不再姓埃克霍夫了,你改了姓,得到了健康的小安东,气管患了小毛病。”
“是的。——而且,你压根儿是个不可思议的人,史平奈尔先生,这点是肯定的……”
“对,我凭天起誓,你正是这样的人!”史巴兹夫人说,原来她也在场。
这次谈话,也同样使科勒特扬夫人暗自反复思索。尽管话没有什么意思,但话里包含着供她思考本身问题的有价值的内容。这是否就是她受到的有害影响呢?她愈来愈虚弱,经常发烧。温火般的寒热,给她一种轻微的振奋感觉,引起沉思、痴想、自我珍惜,和一点被损害的情绪。她不躺在床上时,史平奈尔先生便踮起那双大脚板的趾尖,小心翼翼地走过来,在离她两步远的地方站住,一条腿曳在后面,上身向前弯下去,毕恭毕敬地压低嗓子,侃侃而谈起来,仿佛他怀着胆怯的崇拜心情,把她轻轻举起,让她安卧在云彩上面,免得任何刺耳的声响,任何尘世间的干扰来触犯她……这时她就会联想起科勒特扬先生讲话的那副神情:“当心点,迦伯列勒,takecare,我的天使,把嘴巴闭起来!”那副模样,就好像他粗鲁而善意地拍了拍她的肩膀似的。她连忙抛开这段回忆,以便在虚弱和振奋中,躺在史平奈尔先生为她殷勤铺好的云彩被褥上休息。
有一天,她突然回到关于她出身和幼年的短促谈话上。
“那是真的吗,史平奈尔先生?”她问,“你当真会看见王冠吗?”
虽然从那次聊天后,已过了两个礼拜,但他一下就懂了这话指的是什么,并用激动的语句向她保证,当她和六个女伴坐在喷泉旁边的时候,他一定会看见那顶小王冠,——看见它在她头发上隐隐发光。
过了几天,有一位疗养的客人,出于礼貌,询问留在家里的小安东的健康情况。她向正在近旁的史平奈尔先生飞了一眼,然后有点不耐烦地回答:
“谢谢你;他该怎样呢?——他和我的丈夫过得很好哩。”
二月底,有个严寒的日子,比以前任何一天都更加纯净和明亮,整个“爱茵弗里德”都弥漫着一股放纵的情绪。患心脏病的先生们在交谈,双颊闪着红光;害糖尿病的将军唱着山歌,就像年轻人一样;两腿不听指挥的绅士们,也抛开了一切禁忌。是怎么一回事呢?这事非同小可,要举行一次团体旅行,一次雪橇游览,乘好几辆马车,在叮噹的铃响和噼啪的马鞭声中,到群山深处去游玩:这是列昂德医生决定的,好让他的病人散散心。
当然啰,“重病号”必须呆在家里。可怜的“重病号”!大伙儿点头示意,相互约定不要让他们知道这桩事,能够借此表示一点同情和关怀,使大家都感到舒畅些。但也有些人,虽然毫无问题可以参加郊游,却不肯跟大家一起去。至于封·奥斯特罗小姐呢,她不愿意去,自然受到大家的体谅。像她那样负有一身职责的人,压根儿就别想参加什么雪橇游览。家里绝对少不了她,一句话,她不得不留在“爱茵弗里德”。可是,当科勒特扬夫人宣称她也要留在家里时,大伙儿都感到不痛快了。列昂德医生劝她,出门呼吸点新鲜空气,会对她有好处,但也没有用;她坚持说,她没有这个兴致,头痛得厉害,全身疲倦无力,于是大家也就无可奈何了。那位说话俏皮、喜欢嘲讽的绅士,却趁机表示道:
“请注意吧,现在那败坏的婴儿也不会去啦。”
这话果然灵验,史平奈尔先生透露出来,他当天下午打算工作;——他非常喜欢用“工作”这个字眼来表示他那可疑的活动。不过,他不去,反正没有人会感到遗憾。同样,当史巴兹夫人决定留下给年轻的女友做伴时——因为乘车会使她头晕——谁也不特别惋惜。
这一天还不到十二点就开午饭,饭刚吃完,橇车就停在“爱茵弗里德”门口了。一群群兴致勃勃的客人,穿得暖暖的,又好奇又激动,从花园里穿过去。科勒特扬夫人跟史巴兹太太一起,站在通往阳台的玻璃门旁,史平奈尔先生守在自己房间的窗口,看客人们出发。他们看到在诙谐和嬉笑中,为了占取最好的座位,发生了一些小争夺;看到封·奥斯特罗小姐,脖子上围着毛皮领,从这辆车奔到那辆车,把一篮篮食物塞在座位下面;看到列昂德医生,毛皮小帽紧扣到额上,眼镜闪闪发光,最后再巡视一遍,也登上座位,发出启程的号令……马儿开始用劲拉车子,几位太太尖叫起来,向后倒去,铃儿叮噹地摇,短柄皮鞭噼啪地响,皮鞭的长绦子在橇车木架外面的雪地上拖曳。封·奥斯特罗小姐站在铁栅门旁,挥舞手帕,直到雪上滑过去的橇车在公路转角处不见了,快乐的喧嚷消逝为止。随后,她穿过花园回来,赶忙去履行她的职责。两位太太离开了玻璃门,而几乎就在同时,史平奈尔先生也从他的瞭望处走开。
“爱茵弗里德”疗养院里一片寂静。探险队不到天黑不会回来。“重病号”则躺在自己的房间里,忍受病痛。科勒特扬夫人跟她年长的女友散了一会儿步,然后各自回到房间里。史平奈尔先生也呆在自己屋里,忙他自己的事。大约四点钟,仆役给两位太太端上半公升牛奶,史平奈尔先生也得到他那杯清茶。过了片刻,科勒特扬夫人敲了敲她和史巴兹夫人屋子之间的墙说:
“我们到楼下客厅里去吧,参议员夫人?这儿我简直闷得慌。”
“立刻就来,亲爱的!”参议员夫人回答说。“允许我穿上靴子。你得知道,我刚才躺在床上哩。”
不出所料,客厅里没人。两位太太在壁炉旁边坐下。史巴兹夫人在一块十字网布上绣花,科勒特扬夫人也绣了几针,然后就把那活儿放在膝上,靠着安乐椅背,发呆地梦想起来。她终于说了什么简直不值得启齿的话。尽管这样,史巴兹太太还是问:“什么?”于是她只好耐住性子把整个句子重复一遍。“什么?”史巴兹太太又问。就在这当儿,前廊上响起了脚步声,门打开了,史平奈尔先生走了进来。
“我打扰吗?”他在门槛上就温柔地问,眼睛只瞅着科勒特扬夫人,文质彬彬地向前俯下身子……年轻的夫人回答道:
“哎,怎么会呢?首先,这屋子可以说是个自由港,史平奈尔先生;再说,你会在哪方面打扰我们呢?我觉得,我肯定使参议员夫人感到憋闷了……”
他无话以对,只好微笑着露出蛀牙,在夫人们的注视下,跨着相当拘束的步子,一直走到玻璃门口,在那儿站住,向门外探望,不大礼貌地把背对着两位太太。随后,他转过半个身子,一面继续瞧花园,一面说:
“太阳落坡了,天空不知不觉布满了云。开始黑啦。”
“可不是吗,一切都罩上了阴影,”科勒特扬夫人回答说。“看来,我们的游客还要碰一场雪哩。昨天这时候还是大白天,现在却已经昏暗了。”
“唉,”他说,“接连几个礼拜都是阳光明媚,天阴暗一下,倒使眼睛舒服些。这个太阳,不管美的还是丑的,全都照得一清二楚,现在终于稍微隐蔽起来,我倒要感激它哩。”
“你不喜欢太阳吗,史平奈尔先生?”
“我既然不是画家……没有太阳,人会变得更内倾些。——天上一片灰蒙蒙的厚云层。这也许预示着明天将是融雪的天气。顺便说一下,夫人,我劝你不要在那后边费眼神做活儿。”
“啊,别担心,我本来就没瞧它啦。但有什么事好做呢?”
他在钢琴前面的旋转椅上坐下,一只胳臂靠在钢琴盖上。
“音乐……”他说。“要是现在能听到一点音乐该多么好!只不过有时英国小孩唱几首黑人歌曲罢了。”
“昨天下午,封·奥斯特罗小姐还在百忙中弹过《修道院的钟声》哩。”科勒特扬夫人提醒道。
“可是你会弹钢琴呀,夫人,”他恳求地说,站了起来。……“过去你每天都跟令尊大人一起弹奏。”
“是的,史平奈尔先生,那是过去呀!是在喷泉时代,你知道吗……”
“今天再弹一次吧!”他恳求着。“就这次弹一两节给我们听听!要是你知道,我多么渴望……”
“我们的家庭医生,还有列昂德医生,都特别禁止我弹琴,史平奈尔先生。”
“他们不在这儿,两个都不在!我们是自由的……你是自由的,夫人!一两节可怜的和音……”
“不,史平奈尔先生,办不到。天晓得你指望我弹得多么美妙!我已经完全荒疏了,请相信我,几乎记不起什么调子。”
“啊,那么就弹那几乎记不起的吧!况且这儿乐谱多得是,就在钢琴上面。不,这没什么意思,但这儿有肖邦……”
“肖邦?”
“是的,他的夜曲。现在只需要我点燃蜡烛就……”
“你别以为我会弹,史平奈尔先生!我不能弹。如果弹了对我有害处呢?”
他沉默了。他站在钢琴上两支蜡烛的光亮下,无力地垂下双手:庞大的脚板,细长的黑上装,轮廓模糊的头上长着花白的蓬发,脸上光光地没胡子。
“我不再请求你了,”他终于低声说。“要是你怕对你有害处,夫人,那么你就让那渴望在你手指下鸣响起来的美死去和沉默吧。你过去并不老是这样理智,至少在你和美背道而驰的时候。当你遗弃喷泉、摘下那顶小小的金王冠时,你并不那么关心你的身体,态度也爽朗和坚决多了……听我说,”他过了片刻再说下去,声音更加低沉,“要是你现在坐在这儿,就像从前当你父亲还站在你身旁,他的小提琴发出使你流泪的调子时那样,弹起琴来……很可能,又会看到那顶小小的金王冠,在你头发上隐隐发光……”
“真的吗?”她问,微笑起来……碰巧,在说这话时,她的嗓子失灵了,吐出来的声音半喑半哑。她清了清喉咙,然后说:
“你那儿果真是肖邦的夜曲吗?”
“果真是。就摊开在这儿,什么都预备好啦。”
“好吧,愿上帝保佑,我就弹一支夜曲吧,”她说。“但只弹一支,你听见了吗?不用说,弹了一支以后,你就再也不要听啦。”
说了这话,她便站起来,搁下针线,走向钢琴去。她在旋转椅上坐下,椅子上面还放着几册装订起来的乐谱,摆正烛台,翻开乐谱。史平奈尔先生拖了一张椅子过来,像音乐教师似地坐在她身旁。
她弹的是肖邦的《降E大调夜曲,作品第九号之二》。倘若她现在真有些荒疏,那么当初的弹奏在艺术上一定十全十美了。这架钢琴只不过属于中等质量,但她弹了头几个音以后,就能优美地操纵自如。她对不同的音色表现出一种过敏的感受,对有节奏的旋律,流露出近乎痴迷的喜悦,指法坚实而又轻柔。在她的手指下,旋律鸣唱出它最诱人的甜蜜,装饰音羞怯、温柔地依附在指节的周围。
她穿的是到达那天所穿的衣裳:银灰色厚实的小腰身上衣,浮雕似的阿拉伯式天鹅绒花纹,这衣服把她的脸和手衬托得异常娇柔。弹的时候,脸上的表情并没改变,但嘴唇的轮廓似乎变得更加清晰,眼角的阴影好像更加深沉。弹完以后,她两手搁在膝上,继续盯着乐谱看。史平奈尔先生还是一动也不动地默默坐在那儿。
她又弹了一支夜曲,弹了第二支和第三支。然后站起来,但只是为了在琴盖上找别的乐谱。
史平奈尔先生忽然想到要去翻那旋转椅上的黑色硬面的书本。他骤然莫名其妙地喊起来,白皙的大手狂热地翻阅一本被忽略的乐谱。
“不可能!……不是真的!……”他说,“……然而我并没有弄错!……你知道是什么吗?……什么放在这儿?……我拿的是什么吗?……”
“是什么?”她问。
他默默地指着封面,脸色苍白,让书垂下去,嘴唇发抖地瞅着她。
“真的吗?怎么会在这里?那么给我吧。”她直率地说,把乐谱放在谱架上,坐下静默了片刻,开始弹第一页。
他坐在她身旁,俯下身子,两手合在膝间,垂着头。开头一部分,她悠然地弹着,慢得折磨人,音节之间出现拖长的停顿,令人感到心焦。渴慕的主题,一个在深夜里迷失的孤独声音,轻轻地诉说它那胆怯的疑问。接着是静默和等待。瞧呀,回答了:同样怯弱和孤独的调子,只是清脆些,温柔些。又是沉默。突然,伴随那被抑低的美妙加强音,好像一股被禁锢的热情,猛然振奋,狂喜地迸发出来似的,爱情的主题被引了进来。它扬起来,如醉如迷地向高处挣扎,直飞上那情谊交织的顶峰,随后又沉下去,松弛解散。接着,声调深沉的大提琴鸣响起来,一面歌颂沉重、痛苦的喜悦,一面把调子引去……
在这架可怜的乐器上,弹琴者相当成功地暗示出交响乐队的效果。达到高潮时小提琴的节奏,清脆精确地在琴音中回响。她又细腻又虔敬地弹着,忠实地守卫着每个形象,恭顺地烘托出每个独立的细节,就像神父把最神圣的十字架举在头上那样。发生了什么呢?两股力量,两个陶醉的生命,在悲痛与狂喜中,为了得到对方而挣扎;它们如痴如狂地渴望那永恒和绝对的东西,并在渴望中相互拥抱……序曲澎湃起来,然后低沉下去。她在分幕的地方停下来,默默地继续看乐谱。
这时,史巴兹夫人却已感到说不出的憋闷,当人们烦恼到这种程度时,面孔往往会变样,眼睛会鼓出来,露出僵尸般可怕的神情。况且这种音乐还影响她的胃部神经,使那消化不良的器官处在一阵阵恐怖的状况中,弄得她害怕会发一次痉挛症。
“我不得不回自己的房间去,”她软弱无力地说,“再见,我等一下再来……”
她说着就走了。这时暮色更黯淡了。屋子外面可以看见密密麻麻的雪花无声无息地飘落在阳台上。两支蜡烛投射出摇曳不定、范围有限的微光。
“第二乐章,”他悄声说;于是她翻了几页,开始弹第二乐章。
号角的鸣响在远方消失。是吗?也许是簇叶的簌簌?泉水轻柔的淙淙?这时夜的寂静早已渗透了树林和房屋,任何恳求般的警告,再也约束不住汹涌澎湃的渴慕。神圣的奥秘正在完成。火光熄灭了,死的主题,随着突然阴暗的奇异音色而降临,迫不及待的渴慕,正向那摊开双臂从黑暗中迫近的情人,挥舞它白色的面纱。
啊,只有在那永恒的尘世中结合在一起所带来的欢乐,才是无穷无尽、永不餍足的!折磨人的误会消除了,时间与空间的桎梏解脱了,“你”和“我”,“你的”和“我的”,融合为珍贵的喜悦。白昼狡猾的幻影造成他们的分离,然而它骄矜的谎言蒙骗不了黑夜中的明视,因为那一饮的魅力已赋予他们洞察一切的目光。谁曾眷恋地窥探过死亡之夜和它那甜蜜的奥秘,他在白昼的虚妄中,只会剩下一个渴望,渴望那神圣的夜,那永恒、真实、融合一切的夜……
啊,爱情之夜,降临吧,赐给他们所渴求的忘却,用你的快乐紧紧拥抱他们,让他们从充斥着虚伪和离愁的世界里解脱出来。瞧,最后的火光熄灭了!思索和烦恼沉没在神圣的黄昏中,夜色笼罩在幻觉的痛苦上,拯救着人世。就在幻影黯然失色,我的眼睛在狂悦中失去光明的时候:这时,白昼的欺骗所阻止我看到的,它在我面前所呈现和歪曲的——这一切曾给我带来不可抑止的痛苦……就在这时,啊,奥妙的灵验啊!就在这时,我就是世界了。接着,跟随勃郎加娜阴沉的警告歌唱,出现了提琴超越一切理智的翱翔。
“我不十分懂,史平奈尔先生,有许多我只能感觉到。这是什么意思:就在这时候——我就是世界了?”
他简短地解释给她听,声音很轻。
“是的,是这样。——不过,你既然理解得那么透彻,为什么却弹不出来呢?”
不知怎么,他竟无法回答这个天真的问题。他红了脸,扭着手,仿佛连同椅子一起沉了下去似的。
“这两样很少碰在一起,”他终于痛苦地说。“不,我不会弹。——还是请你继续下去吧。”
于是他们就继续漫游在那神秘爱情的醉人旋律中。爱情曾死亡过吗?特里斯坦的爱情?你的和我的伊索尔德的爱情?死亡的魔爪抓不到那永恒的爱!它所能扼杀的,只不过是那些妨碍我们的东西,那些狡猾地拆散原为一个整体的东西?爱情通过一个甜蜜的“和”字,把两人紧连在一起……除非一个人的“生”给另一个人带来了“死”,死亡怎么能拆散他们呢?神秘的二重唱,把他们结合在一种说不出的期待中,期待在爱情中死去,在夜的神秘王国里永不分离地拥抱在一起。甜蜜的夜,永恒的爱之夜!无所不包的极乐之土!曾在思念中窥探过你的人,怎么会不满怀愁苦地在那凄凉的白昼里重新醒来呢?亲爱的死亡,求你驱散这愁苦吧!求你把思恋的人们完全从觉醒的痛苦中解放出来!啊,那不可名状的暴风雨般的节奏!那玄妙的领悟所带来的急骤上升的有声有色的喜悦!他们怎样领受,怎样顺服这远隔白昼离愁的喜悦呢?啊,那是一种没有虚伪和恐惧的柔情眷恋,一种神圣的、没有痛苦的熄灭,一种在无穷无尽中令人销魂的黎明!你是伊索尔德,我是特里斯坦,但又不再是特里斯坦,不再是伊索尔德啦……
突然发生了一桩可怕的事。弹奏者骤然停下来,手罩在眼睛上,向暗处探望,史平奈尔先生也在座位上急忙转了身。在后面,通往走廊的门开了,一个阴暗的形影,倚在另一个形影的胳膊上,飘了进来。原来是“爱茵弗里德”的一位客人,她的病情也同样不允许她参加雪橇游览。她趁这夜色朦胧的时刻,在疗养院里作一次不由自主的阴惨游历。她就是那位养了十九个孩子、完全失去思维能力的病人,倚在看护胳膊上的郝伦劳赫牧师太太。她头也不抬,一步一探地茫然走去,穿过房间的后部,跨过对面的门槛,飘然离去——默默地,瞪着眼睛,梦游一般,不省人事……接着,寂然无声。
“是郝伦劳赫牧师的妻子。”他说。
“是的,是可怜的郝伦劳赫太太。”她说。然后,翻了几页,弹乐曲的结局:伊索尔德的情死。
她的嘴唇多么苍白和清澈,眼角的阴影多么深沉!在仿佛透明的眉头上,那根淡蓝的小血管愈来愈明显地凸出,紧张疲惫,令人不安。在她那灵活的手指下,乐曲发展到前所未有的高潮,突然被简直肆无忌惮的最弱音切断,仿佛一个人立脚的根基滑去了,或者沉入崇高欲望的深渊中似的。一股洋溢着解放和满足的情绪涌了进来,反复出现,发出心满意足的震耳欲聋的怒涛声,贪婪地一再重复,接着潮水般地退下去,似乎筋疲力尽了,然后再一次在它的旋律中体现出渴慕的主题,呼出最后的一脉气息,死去,消逝,飘散。深深的寂静。
他们两人都在谛听。头侧向一边,谛听着。
“是铃儿叮噹响。”她说。
“是橇车,”他说,“我走了。”
他站起来,穿过房间。他在后面的门口停住,转过身,焦躁不安地一会儿举起这条腿,一会儿举起那条腿,然后竟在离她十五步到二十步的地方,突然跪下来,默默地屈着两条腿。他那黑色的长外套摊开在地板上。双手合在嘴上,肩膀搐动着。
她坐在那儿,手搁在膝上,身子略向前弯,背对着钢琴朝他看。脸上露出一丝迟疑、窘迫的微笑,眼睛沉思、费力地向昏暗中探望,好像禁不住要闭起来似的。
在远处,铃儿叮噹,鞭子噼啪,人声嘈杂,声音越来越近……
雪橇游览是在二月二十六号举行的,旅途的见闻事后大家还谈论了好久。二十七号是个化雪的日子,那天什么都在融化、滴落、飞溅、流动,而科勒特扬夫人感到很舒适。二十八号,她吐了一点血……啊,并不要紧;但到底是血哩。就在这时,她突然衰弱了,空前地衰弱了,不得不躺在床上。
列昂德医生把她检查了一番,却丝毫不动声色。他按照科学的条文,开出处方:冰块、吗啡、严格的休息。他还由于负担过重,第二天就不再看她的病了,把她交给缪勒医生去治疗,而后者则根据他的职责范围和合同规定,极其温顺地接管了她。他是个沉默、苍白、平凡、忧郁的人,他的微不足道的谦卑职责,是看顾那些几乎没有毛病或者没有希望的病人。
他所表示的头一个意见是:科勒特扬先生伉俪间的离别已经很久了。因此迫切希望,科勒特扬先生再来“爱茵弗里德”访问一次,只要他那欣欣向荣的事业允许他抽身的话。也许可以写封信给他,或者拍封简短的电报。要是他能把小安东带来,那一定会给年轻的母亲带来快乐和力量。不用说,医生们也怀着兴趣,巴不得见识一下这位健康的小安东。
瞧呀,科勒特扬先生驾到了。他接到缪勒医生的简短电报,从波罗的海的海滨来到这里。他爬下马车,叫了咖啡和奶油面包卷,露出莫名其妙的神气。
“先生,”他说,“怎么啦?为什么唤我来看她?”
“因为你现在最好呆在尊夫人的身旁。”缪勒医生回答说。
“最好……最好……可是必要吗?我得节省呀,先生,这年头不景气,火车票又贵。这趟整天的旅行难道不能免去吗?比方说,要是肺有毛病,那我就不说什么了;可是,谢天谢地,毛病生在气管里……”
“科勒特扬先生,”缪勒医生温顺地说。“首先,气管是个重要的器官……”“首先”这词儿用得很不恰当,因为他接着根本没说“其次”。
随着科勒特扬先生同时到达“爱茵弗里德”的,还有一位打扮得红红绿绿、珠光宝气的胖女人,而就在她的胳膊上,抱着安东·科勒特扬少爷,那健康的小安东。是的,他也来了,而且任何人都不能否认,他确实十分健康。他红润、白嫩,穿着整洁清爽的衣裳,圆胖、喷香,重重地压在那满身都是花边的女人裸露的红胳膊上。他吞食大量的牛奶和碎肉,哭闹嘶喊,极为任性。
作家史平奈尔先生曾从他房间的窗口,观看小科勒特扬的来临。当小家伙从马车上被抱到屋里时,他用一种奇异的眼光,又含糊又锋利地盯着他看,然后带着同样的面部表情在窗旁呆立了许久。
从此,他就尽可能避免跟小安东·科勒特扬相遇。
史平奈尔先生坐在自己的屋子里“工作”。
这间屋子跟“爱茵弗里德”所有别的房间一样:古老、朴素、高雅。庞大的五斗橱上镶着金属的狮头,高大的壁镜,不是一片光滑的平面,而是由许多镶着铅边的小方块拼成。在发蓝的油漆地板上,清清楚楚映出家具僵直的腿影。靠近窗口摆着一张宽阔的写字台,小说家也许是为了使自己更内倾一些,挂下了黄色的窗帘。
在黄沉沉的朦胧中,他伏在案上书写——写那些数不清的信件之一;这种信他每周都寄出几封,而有趣的是,在大多数情况下,都没有回音。他面前放着又大又厚的信纸,在信纸的左上角,画着离奇古怪的风景,画下面是用十足新奇的字母印好的姓名:德特雷夫·史平奈尔。他在纸上写满细小、纤巧、工整的字体。
“先生!”信上写道,“我写给你下面这封信,是因为我非写不可,因为我所要告诉你的,梗塞了我的心头,使我痛苦和战栗,因为字句那么猛烈地朝我涌来,倘若我不通过这封信摆脱它们,就会被它们窒息……”
为了尊重事实,必须声明,史平奈尔先生所谓的“涌来”,根本就不是那么一回事。天晓得他由于什么虚荣的缘故,硬要这样说。字句压根儿就不肯“涌来”;对于他这样一个以写作为职业的人,倒可以说是写得慢得可怜。要是有谁观察过他,就一定会下一个结论:作家是这样一种人,写作对于他比对任何人都来得艰巨。
他两个指尖捏住脸上一根古怪的茸毛,揉搓个刻把钟,同时向空中出神,一行字也写不出,然后写下一两个纤巧的字,重新搁下笔。不过,另一方面也得承认,最后写成的东西,却给人一个生动、流畅的印象,尽管内容从本质上说来,颇为怪诞和可疑,有时甚至难于理解。
“有万分必要,”那封信继续写道,“让你也看到我所看到的,看到几个星期以来,像个不可磨灭的形影似的,浮现在我眼前的事物,让你通过我的眼睛,看到在同样语言的照耀下,呈现在我心目中的东西。我通常没法回避这种冲动,它迫使我用生动鲜艳、恰如其分的字句,把自己的体验向世人公开。所以请你听我说下去吧。
“我所要说的,仅仅是曾经发生和还在发生的事;只不过是讲个故事罢了,故事很短,但令人说不出地愤慨。我不作注解,不加责难,也不加评语,只用自己的语言叙述而已。这是迦伯列勒·埃克霍夫的故事,先生,那个你自称属于你的女人……而且请你注意!经历这故事的是你自己,然而实际上是我,是我的语言使你第一次把它提高到具有经历的意义。
“你还记得那座花园,先生,那幢古老的灰色房屋后面的荒芜的花园吗?败墙颓垣围着它那梦境似的荒凉,青苔茂盛地长在墙壁的裂缝中。你还记得园子中央的喷泉吗?淡紫色的百合花,俯首在它朽坏的边缘上,洁白的泉水向破裂的石上溅流,仿佛在神秘地窃窃私语似的。夏日正临近薄暮。
“七位少女围着喷泉坐成一圈。夕阳好像在其中第七位,也就是第一和唯一的一位的少女鬈发间,隐隐地织上一顶灿烂的至尊标志。她的眼睛像胆怯的幻梦,但清澈的嘴唇上仍旧浮着微笑……
“她们在唱歌。细长的脸蛋儿,举向喷泉的顶峰,那儿,喷泉娇弱无力地弯成弧形向下溅落。她们轻柔清脆的歌声,荡漾在袅娜的舞蹈周围。也许她们一面唱,一面还用细嫩的手儿抱住膝盖……
“你还记得这幅图画吗,先生?你看见了吗?你没有看见!你的眼睛不是为此生的,你的耳朵也听不见那旋律中纯洁的甜蜜。你看见了吗?——那你就应该屏住呼吸,禁止心脏跳动。你应该走开,回到生活里,回到你的生活里去,把你所看到的当作不可触犯、不容亵渎的圣物,一辈子都保存在你灵魂的深处。但你干了什么呢?
“这幅画是个终结,先生;你怎么竟甘心要破坏它,给它添上一段庸俗丑陋的痛苦续篇呢?这是个动人和宁静的终场,浸沉在没落的黄昏的回光中,一片离解和熄灭的气息。一个古老的世族,它太疲惫,太高贵,以致不能再有所作为,不能再面临生活,正接近末日。它最终的表现是艺术上的鸣响,一两声提琴的旋律,充满死亡前心明眼亮的悲哀。……这旋律曾使一对眼睛噙满泪水,你看见过这对眼睛吗?那六位女伴的灵魂也许属于苍生;但她们姐妹般的主宰灵魂,却属于美和死。
“你看见了这死之美:瞅着它,为的是贪求它。在她那动人的圣洁面前,你心里竟丝毫没有肃然起敬的感觉。单单看还不能满足你,你必须占有,使用,亵渎……你选得可不错啊!你是个爱吃山珍海味的食客,一个卑俗的食客,一个口刁的村夫。
“请你注意,我丝毫没有中伤你的意思。我所说的并不是什么责难,而是个典型的例子,一个适用于你这种文学上毫无价值的庸俗人物的简单心理公式。我要说出来,是因为有什么在逼迫着我向你说明一下你的所作所为,因为我在世上责无旁贷的职务是照实反映事物,让它们倾吐,使不为人知的事物公诸于世。世上充满我所谓无知的类型,而我忍受不了这一切无知的类型!忍受不了这一切糊涂、无意识和无知的生活和行为,受不了我周围的那种天真得令人激怒的世界!一种痛苦的不可抗拒的力量,迫使我就我力所能及,对我四周的一切加以说明,申述,使它被知觉,不管这样做起促进作用,还是起阻碍作用,带来慰藉和镇静,还是增添痛苦。
“你呀,先生,正像我说过的那样,是个爱吃山珍海味的卑俗的食客,一个口刁的村夫。实际上你体质粗鄙,还处在最低下的进化阶段。财富和安定的生活方式,使你的神经系统骤然达到一种史无前例的野蛮堕落,引起享受欲望的一种淫猥的贪精求美。很可能,当你打定主意要把迦伯列勒·埃克霍夫占为己有时,你的喉头肌肉曾抽缩起来,发出啧啧的声响,就像是面对着什么可口的鲜羹或者稀有的美食一般……
“你确实把她迷梦中的心灵引上歧途,带她离开野草蔓生的花园,走进生活和丑恶里去,给予她你那庸俗的姓名,使她成为妻子,家庭主妇,成为母亲。你使那疲惫、羞怯、在崇高的不切实际中盛开的死之美,屈从、侍奉那卑贱的日常事物,那愚痴、执拗和可耻的偶像,也就是所谓的本性。而你这伧夫俗子的良心,却丝毫也没有意识到这举动多么卑鄙。
“再重复一遍:发生了什么呢?她这位眼睛像胆怯的幻梦一样的人,为你生了一个孩子;把自己血液和活力中所拥有的一切,给予这个小生物,这个乃父的低级生命的续篇,然后死去。她在死去,先生!我所关心的是指望她不在庸俗中死亡,终于从卑鄙的深渊中脱身,在美的死吻下骄傲、幸福地逝去。而你所关心的,恐怕是怎样利用这闲工夫,在一些隐秘的走廊里,跟婢女们消磨时间。
“你的孩子,迦伯列勒·埃克霍夫的儿子,却在茁长、生活、凯旋。他大概会继承父亲的事业,成为一个经营商业、缴纳捐税、喝饱啖足的公民;也许会成为一个军人或者官吏,一个不学无术、精明能干的国家支柱;但不管怎样,他将是一个与艺术绝缘、功能正常的人物,不体贴别人,自以为是,强壮和愚蠢。
“允许我向你坦白,先生,我憎恨你,憎恨你和你的孩子,就像我憎恨你所体现的生活,那种庸俗、可笑,然而毕竟是占上风的生活,它是美的永恒对立面和死敌。我不好说我轻视你。我不能这样说。我是坦率的。你是强者。在同你的斗争中,我能拿出来应战的,只是弱者的珍贵武器和复仇工具:精神与文字。今天我使用了它。这封信不是别的——这点我也要坦率承认,先生——而是一种报复。哪怕信里只有一个字还称得上尖刻、利落、华美,足以使你感到惊愕,使你觉察到有一种陌生的力量存在,使你那健壮体魄带来的镇静和冷漠受到震撼,那我就会喜悦欢腾!
“德特雷夫·史平奈尔”
史平奈尔先生把信装进信封,贴上邮票,用纤巧的字体写上姓名地址,交给邮局。
科勒特扬先生敲打史平奈尔先生的房门;他手里拿着一张写满工整字迹的大信纸,那副模样看来像是要使用强硬的手段。邮局已经履行了职责,这封信走了它应该走的道路,完成它那奇特的旅程,从“爱茵弗里德”又回到“爱茵弗里德”,正确无误地到达收信人手中,时间是下午四点钟。
科勒特扬先生走进来时,史平奈尔先生正坐在沙发上,看自己那部封面画得离奇古怪的小说。他站起来看了看客人,眼光里含着诧异和疑问的神情,他的脸孔却明显地涨红了。
“你好,”科勒特扬先生说。“请原谅我打扰你工作。不过请问,这是你写的吗?”他说着,用左手举起布满工整字迹的大信纸,用右手背把它敲得噼啪直响。然后,右手插进舒适宽大的裤子口袋里,头歪向一边,像有些人习惯的那样,张开嘴巴听回音。
史平奈尔先生怪模怪样地微笑起来:微笑中含有一点殷勤,还带着一点不自在和近乎道歉的神情。他伸手摸了摸头,好像在思索,然后说:
“啊,不错……是这样……我冒昧……”
原来他今天对自己的性子让了步,一直睡到晌午。结果内心负疚,脑筋昏沉,神经有些紧张,斗志不昂。再加上空气中已开始有春天的气息,使他迷糊,引起一股忧伤的情绪。这一切都必须提到,才能说明他干吗在下面的一幕中,表现得那么可笑。
“唔!啊哈!很好!”科勒特扬先生说,下巴抵住胸膛,竖起眉毛,伸出两臂,还做出一系列类似的准备动作,表示他在提出例行的问题后,打算毫不留情地转到本题上来。由于他很欣赏自己的神态,因而这些准备动作未免做得有点过火;接下来所发生的,似乎跟这装腔作势的吓唬人的开场并不完全相称。史平奈尔先生的脸却已变得相当苍白了。
“非常好!”科勒特扬先生重复道。“那么让我亲口答复你吧,亲爱的,还请你注意,我认为你给一个随时都能找他谈的人,写长达数页的信,是愚蠢的……”
“好吧……愚蠢……”史平奈尔先生微笑说,含着道歉和简直谦卑的神情……
“愚蠢!”科勒特扬先生重复说了一遍,用劲晃了晃脑袋,表示对自己的论点有充分信心。“这种臭文章,本来丝毫不值得为它费口舌,坦白地说,拿它包面包我都会嫌太脏,要不是它向我解释了一些我过去还不明白的事,一些变化……不过,这跟你不相干,也不是我所要跟你谈的。我是个忙人,我有比你那些不可告人的形影更有意义的事情需要考虑……”
“我写的是不可磨灭的形影。”史平奈尔先生说,挺直了胸膛。这是他在这一幕中,唯一显出一点尊严的一次。
“不可磨灭……不告人……!”科勒特扬先生回答,看了看信稿。“你这手字写得真糟糕,亲爱的;我的写字间里才不会雇佣你哩。乍一看,倒还整齐,但再细瞧一下,那就东倒西歪,漏洞百出了。不过这是你自己的事,跟我不相干。我来是为了要告诉你,你首先是个混蛋——嗯,这点你恐怕早已知道了。此外,你还是个十足的懦夫,这大概也用不着我向你多加证明。我内人有次写信告诉我,你碰到女人,就不敢正面瞅她们,而是斜着眼瞟一下,为的是要保藏什么美感,因为你害怕真实。可惜她后来信中不再提起你了,否则我还会知道更多关于你的丑事。你就是这样的人。美是你的口头禅,而实际上你只不过是胆小、伪善和嫉妒而已,也正是因为这样,你才不要脸地提起什么隐秘的走廊,想借这话暗伤我,但结果只使我感到好笑。感到好笑!你现在明白真相了吧?我是不是对你……对你的所作所为已经说明了一下吗?你这可怜虫?尽管这并不是我不可逃避的职务,嗬,嗬!……”
“我写的是责无旁贷的职务。”史平奈尔先生说,但立刻又放弃了反抗的企图。他站在那儿不知所措,挨骂受训,就像一个大个子灰头发的可怜学童似的。
“责无旁贷……不可逃避……你是个卑鄙的懦夫,我告诉你。你每天吃饭时碰见我,你笑着向我问好,笑着递给我碗碟,笑着祝我健餐。忽然有一天,竟写来这么一封臭东西,满纸荒唐的诽谤,惹我麻烦。哈,不错,咬文嚼字你倒有勇气!倘若仅仅是这么一封荒谬的信那也罢了;但是,你在搞阴谋,在我背后中伤我,我现在可都明白了……不过你甭自以为这对你会有什么用处!要是你妄想要给我妻子灌输些怪思想,那你是白费心思,尊贵的先生,她太理智了,不会接受的。要么你竟然以为,我们这次来到时,她没有像过去那样接待我和孩子,那你更是异想天开!她没吻小孩,那是由于谨慎的缘故。因为新近有这么个假定,说她毛病可能不在气管,而在肺部。在这种情况下,就得小心点……不过毛病是否在肺里,以及你所谓的她死去,都还有待于证明,先生!你简直是头驴!”
说到这里,科勒特扬先生换了换气。他现在非常愤怒,右手的食指不住向空中指划,左手把信纸揉得不成样子。他的脸,夹在英国式的颊须当中,涨得绯红,暴起的青筋像凶狠的闪电似地交叉在那满布云翳的额头上。
“你憎恨我,”他继续说,“如果我不是强者,你还会瞧不起我,……是的,我是强者,他妈的,我是个好汉,你是胆小鬼。要是法律不禁止的话,我会把你和你的精神与文字一齐剁成肉酱,你这阴险的白痴。但这并不是说,亲爱的,我就要容忍你的辱骂,不加追究。等我回了家,就把这封写着我庸俗姓名的东西,交给我的律师,然后我们瞧你会不会吃苦头。我的名字是呱呱叫的,先生,我的信誉是靠自己的努力挣来的。凭你的名字,谁肯借你一个铜板?这问题请你自己深思一下,你这个不知从哪儿跑来的流浪汉!你应该受法律的制裁!你危害公共安全!你把人弄成神经病!……但你别自以为你这次也能得逞,你这恶毒的家伙!我才不会让你这样的人击败我。我是个好汉……”
科勒特扬先生这时确已万分激动,他大声嘶叫,一再声称自己是个好汉。
“她们在唱歌。嗯。她们根本没有唱歌!她们在打毛线。至于她们所谈的呢,据我所知,是谈一种马铃薯煎饼的烧法。如果我把关于那堕落和离婚的事告诉我岳父,他同样会依法对你起诉,这是可以肯定的!……你看见这幅图画吗,你看见了吗?当然看见啦。但我不懂,为什么我就该屏住呼吸和逃走。我从来不斜着眼睛瞟娘儿们,我好好看一阵,如果中我意,而她们也肯要我,那我就带去。我是个好汉……”
有人敲门。——房门上接连急促地敲了八九下,这阵又短又急的恐怖的咚咚声,使科勒特扬先生收住了口。接着有个惊惶失措的声音,慌张得上气不接下气,异常急迫地说:
“科勒特扬先生,科勒特扬先生,唉呀,科勒特扬先生在这儿吗?”
“不准进来,”科勒特扬先生暴躁地喊……“什么事?我在这儿有话要谈!”
“科勒特扬先生,”那颤抖的声音断断续续地说,“你非来不可……医生们都在那儿……啊,多悲惨呀……”
他一步就跨到门口,用劲打开房门。史巴兹夫人站在外面,手帕蒙在嘴上,又大又长的眼泪,成对地往手帕里滚。
“科勒特扬先生,”她一个劲儿地说……“多悲惨呀……她吐了那么多血,多得真可怕……她安静地坐在床上,轻轻哼着什么调子,突然血涌了出来,天哪,多得不得了……”
“她死了吗?”科勒特扬先生嘶喊起来,抓住参议员太太的胳膊,把她在门槛上推来推去。“没有断气吧,对不对?还没有断气,还能见到我……她又吐了一点血?从肺里吐出来,对不对?我承认,也许是从肺里出来的……迦伯列勒!”他突然叫道,眼眶里噙满泪水,可以看出好像有一股温柔、善良、诚恳而富于人性的感情从他身上爆发出来。“是的,我来啦!”他说,迈开步子,拖着参议员夫人,跨出门槛,顺着走廊奔去。从走廊的另一头,传来他那很快远去的声音:“没有断气,是不是?……从肺里出来,是吧?……”
史平奈尔先生还站在原处,注视着敞开的房门,在科勒特扬先生这场突然中断的访问期间,他就站在那儿。过了好久,他终于向前移动了几步,向远处谛听。但到处都寂静无声,于是他关上门,回到屋里。
他照了照镜子,走到写字台旁,从抽屉里拿出一个小酒瓶和酒杯,啜了一点白兰地——为此任何人都不该责备他的。然后直挺挺地躺在沙发上,闭住眼睛。
上半扇窗子开着。窗外,“爱茵弗里德”的花园里,鸟儿在鸣唱,而在它们婉转活泼的细小声音里,整个春天都微妙、充分地流露出来。史平奈尔先生低声自言自语说:“不可逃避的职务……”然后摇了摇头,透过牙齿缝深深吸了口气,好像神经一阵阵剧烈作痛似的。
安静下来集中思想是不可能的。谁受得了这样粗暴的待遇!经过一番内心的斗争——要分析它,那就未免扯得太远了——史平奈尔先生终于决定起来活动一下,到外面去散散步。他拿起帽子,离开房间。
他到了室外,就有一股温暖新鲜的空气在周围荡漾。他回过头,眼光顺着楼房慢慢溜上去,一直接触到一扇挂着帘幕的窗子为止。在这扇窗子上,他的视线严肃、专注、阴沉地胶着了片刻。然后,他两手搁在背后,沿着石子路走去,沉思地迈着步子。
花坛上还盖着草席,树枝和灌木依旧是光秃秃的,但雪已经消失了,小径上只有几处还留下潮湿的痕迹。宽阔的园子,连同它的假山洞、林阴小径和亭榭,都沉浸在午后绚丽的光亮中,深沉的阴影与充裕的金色阳光交织在一起,明亮的天空映衬着墨黑的树枝,枝节柔嫩、分明。
这正是太阳显出轮廓的时辰,由一团模糊的光源,变成一轮明显的下沉的圆盘;它的光芒也比以前浓厚和温和多了,不再那么刺眼。史平奈尔先生却看不见太阳;他这样走路,正好使太阳光遮住他的身体。他低着头走,轻轻哼着什么调子,短短的一节音乐,一段怯弱、哀诉地升扬的旋律,就是那渴慕的主题……蓦地,他怔了一下,短促而痉挛地呼了一口气,像生根似地站住。他紧皱起眉毛,张大了眼睛,露出恐怖厌恶的神情,发呆地盯着前面看……
小径转了个弯,正好通向下沉的太阳。一轮庞大的红日,围着镀金边的狭长明亮的云带,斜挂在天空中,看起来好像把树梢点燃了,并向花园里倾泻它那橘红的光辉。就在这灿烂的仙境里,头上的夕阳宛若祥光缭绕,有个穿得红红绿绿、浑身珠光宝气的丰满女人,伫立在路上。她右手撑着肥圆的髋部,左手轻轻推动一辆式样别致的童车。而在这辆童车上,坐着那个孩子,安东·科勒特扬少爷,迦伯列勒·埃克霍夫的胖儿子!
他坐在枕褥中间,穿一件白色绒短衣,戴一顶白色大帽子,两颊丰腴,漂亮,健壮。他的眼光愉快而准确地跟史平奈尔先生的视线相遇了。小说家正打算振作起来;他是个男子汉,应该有勇气从这浸沉在阳光中的尤物旁走过去,继续他的散步。但就在这时,发生了一桩恐怖的事,安东·科勒特扬竟嬉笑和欢呼起来;他不知怎么突然感到兴奋,尖声嘶喊个不停,令人听起来毛骨悚然。
天晓得是什么逗得他这样,要么是眼前那黑色的身影勾出这番放纵的欢乐,要么是他那健旺的本能发作起来,他一只手里拿着个骨制的咬圈,另一只手握着个铁皮的响筒。他欢呼着,把这两件东西在阳光中高高举起,摇晃,碰撞,好像要嘲弄地把什么人吓走似的。他眼睛喜得眯成一条缝,嘴巴张得那么大,以致整个玫瑰色的上腭都显露出来。他一面欢呼,一面还拚命摇晃脑袋。
于是史平奈尔先生来了个一百八十度急转弯,拔脚就走。他在小科勒特扬欢呼声的追随下,拘谨、斯文地挥动着直挺挺的两臂,踏着石子路,很勉强地故意放慢步子,仿佛要掩饰自己内心里正在逃跑似的。
(刘德中译)
天火-王晋康
========================
天火-[[王晋康]]
-----
在一个荒诞的暗夜中发生的荒诞故事,但暗夜中仍有不死的火种,那是爱心、天才和不屈的探索精神。
熬过五七干校的两年岁月,重回大寺中学物理教研室。血色晚霞中,墙上的标语依然墨迹淋漓,似乎是昨天书写的;门后的作息时间表却挂满了蛛网,像是前世的遗留。
我还是我吗?是那个时乖命蹇却颇以才华自负的物理教师吗?
批斗会上,一个学生向我扬起棍棒,脑海中白光一闪——我已经随那道白光跌入宇宙深处了,这儿留下的只是一副空壳。
抽屉里有一封信,已经积满灰尘,字迹柔弱而秀丽,像是女孩的笔迹。字里行间似乎带着慌乱和恐惧——这是一刹那中我的直觉。
何老师:
我叫向秀兰,五年前从你的班里毕业,你可能不记得我了……
我记得她,她是一个无论学业、性格、容貌都毫不出众的女孩,很容易被人遗忘。但“文革”期间她每次在街上遇到我,总要低下眉眼,低低地叫一声“何老师”,使我印象颇深。那时,喊老师的学生已不多了。
……可是你一定记得林天声,你最喜欢他的,快来救救他吧!……
林天声!
恐惧伴随隐痛向我袭来。我执教多年,每年都有几个禀赋特佳的天才型学生,林天声是其中最突出的,我对他寄予厚望,但也有着深深的忧虑,因为最硬的金刚石也最脆弱,常常在世俗的顽石上碰碎。
我记得林天声脑袋特大,身体却很孱弱,好像岩石下挣扎出来的一棵细豆苗。性格冷漠而孤僻,颇不讨人喜欢,与他的年龄极不相符。实际上,我很少看到他与孩子们凑群,总是一个人低头踱步,脚尖踢着石子。他的忧郁目光常使我想起一幅“殉道者”的油画——后来我知道他是一个“可教子女”(当时的常用语,即“可以教育的子女”的简称),他父亲是著名的右派,1957年自杀。于是我就释然了,他实际是用这层甲壳来维持自己的尊严。
他的学业并不十分突出,如果不是一次偶然的发现,我完全可能忽略这块璞玉。物理课堂上,我常常发现他漠然地注视窗外,意态游移,天知道在想些什么。偶尔他会翻过作业本,在背面飞快地写几行字东西,过一会儿又常常把它撕下来,揉成纸团扔掉。
一次课后,我被好奇心驱使,捡起他才扔掉的一个纸团,摊开。纸上是几行铅笔字,字迹极草,带着几分癫狂。我几乎难以相信这是他的笔迹,因为他平时的字体冷漠而拘谨,一如他的为人。我费力地读着这几行字:
“宇宙在时间和空间上是无限的(否则在初始之前和边界之外是什么?),可是在我们之前的这一‘半’无限中,宇宙早该熟透了,怎么会有这么年轻的星系,年轻的粒子,年轻的文明?
我相信震荡宇宙的假说,宇宙的初始是一个宇宙蛋,它爆炸了,飞速向四周膨胀,现在仍处于膨胀状态。亿兆年之后,它在引力作用下向中心跌落,塌缩成新的宇宙蛋。周而复始,万劫不息。
可是我绝不相信宇宙中只有一个宇宙蛋!地球中心说和太阳中心说的新版!‘无限’无中心!逻辑谬误!
这儿是几个大大的感叹号,力透纸背,我感受到他写字时的激扬。下面接着写道:
如果爆炸物质以有限的速度——天文学家所说的红移速度,它的绝对速度应该小于光速——膨胀,那么它到达无限空间的时间当然是无限的,怎么可能形成周期性的震荡?如果它到达有限的空间(即使是难以想象的巨大空间)即收缩,那它只能是无限空间中微不足道的一点,怎么能代表宇宙的形成?
下面一行字被重重涂掉了,我用尽全力辨认出来:
或许宇宙是无限个震荡小宇宙组成,无数个宇宙蛋交替孵化,似乎更合逻辑。
多么犀利的思想萌芽,尽管它很不成熟。为什么他涂掉了?是他自感没有把握,不愿贻笑他人?
纸背还有几行字,字迹显然大不相同,舒缓凝滞,字里行间充满着苍凉的气息,不像一个中学生的心境:
永远无法被‘人’认可的假说。如果它是真的,那么一‘劫’结束后,所有文明将化为乌有,甚至一点痕迹也不能留存于下一劫的新‘人’。上一劫是否有个中学生也像我一样苦苦追索过?永远不可能知道了!
读这些文字时,我的心脏狂跳不止,浑身如火焰炙烤。似乎宇宙中有天火在烧,青白色的火焰吞噬着无限,混沌中有沉重的律声。
我绝对想不到,一个孱弱的身体内能包容如此博大的思想,如此明快清晰的思维,如此苍凉深沉的感受。
我知道百十年前有一位不安分的犹太孩子,曾遐想一个人乘着光速的波峰会看到什么?……这就是爱因斯坦著名的思想实验,是广义相对论的雏形。谁敢说林天声不是爱因斯坦第二呢?
我不知道天文学家读到这些文字作何感想,至少我觉得它无懈可击!越是简捷的推理越可靠,正像一位古希腊哲人的著名论断:
“又仁慈又万能的上帝是不存在的,因为人世有罪恶。”
极简单的推理,但无人能驳倒它,因为人世有罪恶!
天声的驳难也是不能推翻的,只要承认光速是速度的极限。
我把他的纸条细心地夹到笔记本里,想起他过去不知道随手扔掉了多少有价值的思想萌芽,我实在心痛。抬起头,看见天声正默默地注视着我,我柔声道:“天声,以后有类似的手稿,由老师为你保存,好吗?”
天声感激地默然点头。从那时起,我们俩常常处于心照不宣的默契中。
可惜的是,我精心保存的手稿在“文革”抄家中丢失了。
我摇摇头,抖掉这些思绪,拿起向秀兰的信看下去:
……在河西大队下乡的同学都走了,只剩天声和我了,他又迷上了迷信(语法欠通,我在心里评点着),一门心思搞什么穿墙术。我怕极了,怕民兵把他抓走,怎么劝他都不听。何老师,天声最敬佩你,你来救救他吧!
我唯有苦笑。我自己也是刚从牛棚里解放出来,惴惴地过日子,哪有资格解救别人!
一张信纸在我手里重如千斤,纸上浸透了一个女孩的恐惧和期待。信上未写日期,邮戳也难以辨认。这封信可能是很久前寄来的,如果要发生什么早该发生了……我曾寄予厚望的学生是不会迷上什么穿墙术的,肯定是俗人的误解,也许只有我能理解他……第二天,我还是借一辆嘎嘎乱响的自行车,匆匆向河西乡赶去。
河西乡是我常带学生们大田劳动的地方,路径很熟。地面凸凹不平,常把我的思绪震飞,像流星般四射。
我的物理教学也像流星一样洒脱无羁,我不愿中国的孩子都被捏成呆憨无用的无锡大阿福泥人。课堂上我常常天马行空,尽力把智者才具有的锐利的见解,微妙的深层次感觉,在不经意中浇灌于学生。
在一次课堂上,我讲到黑洞。我说黑洞是一种被预言但尚未证实的天体,其质量或密度极大,其引力使任何接近它的物质都被吞没,连光线也不能逃逸。
学生们很新奇,七嘴八舌问了很多问题:一位不小心跌入黑洞的宇航员在跌落过程中会是什么心境?被吞没的物质到哪儿去了?物质是否可以无限压缩?既然连光线也不能逃逸,那人类是否永远无法探索黑洞内的奥秘……
我又谈到白矮星,它是另一种晚期恒星,密度可达每立方厘米一万千克。又谈到中微子,它是一种静止质量为零的不带电粒子,可以在0.04秒内轻而易举地穿过地球。
不知怎么竟谈到《聊斋》中可以叩墙而入的崂山道士,我笑道:“据说印度的瑜伽功中就有穿墙术。据载,不久前一个瑜伽术士还在一群印度科学家众目睽睽之下做了穿墙表演。关于印度的瑜伽术,中国的气功,关于人体特异功能,常常有一些离奇的传说,比如靠意念隔瓶取物,远距离遥感等。很奇怪,这些传说相当普遍,简直是世界性的——当然,这些都是胡说八道。”
在一片喧嚷中,只有林天声的目光紧紧盯着我,像是幽邃的黑洞。他站起来说:“1910年天文学家曾预言地球要和彗星相撞,于是世界一片恐慌,以为世界末日就要来临。这个预言确实应验了,巨大的彗星尾扫过地球,但地球却安然无恙。这是因为……”
我接着说:“彗星是由极稀薄的物质组成,其密度小到每立方厘米10-22克,比地球上能制造的真空还要‘空’。”
林天声目光炯炯地接口道:“但在地球穿过彗尾之前有谁知道这一点呢?”
学生们很茫然,可能他们认为这和穿墙术风马牛不相及,不知所云为何。只有我敏锐地抓到他的思维脉络,他的思维是一种大跨度的跳跃。在那一瞬间,我甚至激发出强烈的兴奋,两个思维接近的人在这么近的距离内产生共鸣,这在我是不可多遇的。我挥手让学生们静下来。
“天声是对的,”我说,“人们常以凝固的眼光看世界,把一些新概念看成不可思议。几百年前人们顽固地拒绝太阳中心说,因为他们‘明明’知道人不能倒立在天花板上,自然地球下面也不能住人。这样,他们从曾经正确的概念作了似乎正确的推论,草率地否定了新概念。现在我们笑他们固执,我们的后人会不会笑我们呢?”
我停顿了一下,环视学生。
“即使对于‘人不能穿墙’这种显而易见的事实,也不能看作天经地义的最后结论。螺旋桨飞机发明后,在飞机上装机枪几乎是不可能的,因为飞速旋转的桨叶对子弹形成不可逾越的壁障,直到发明同步装置,使每一颗子弹恰从桨叶空隙里穿过去,才穿破这道壁障。岩石对光线来说也是不可逾越的,但二氧化硅、碳酸钠、碳酸钙混合融化后,变成透明的玻璃。同样的原子,仅仅是原子排列发生了奇妙的有序变化,便使光线能够穿越。在我们的目光里,身体是不可穿透的致密体,但X光能穿透过去。所以,不要把任何概念看成绝对正确,看成天经地义不可稍改。”
学生们被我的思维震撼,鸦雀无声。我笑道:“我说这些,只想给出一种思维方法,帮助你们打破思想的壁障,并不是相信道家或瑜伽派的法术。天声你说对吗?你是否认为口念咒语就可叩墙而入?”
学生们一片哄笑,林天声微笑着没有说话。
直到后来,我才知道我犯了多么愚蠢的错误。我给出一连串清晰的思维推理,但在最后关头却突然止步,用自以为是的嘲笑淹没了新思想的第一声儿啼。
这正是我素来鄙视的庸人们的惯技。
到达河西乡已是夕阳西下。黄牛在金色的夕阳中缓步回村,牛把势们背着挽具,在地上拖出一串清脆的响声。地头三三两两的农民正忙着捡红薯干,我向一个老大娘问话,她居然在薄暮中认出我:“何老师哇,是来看那俩娃儿吗?娃儿们可怜哪!”她絮絮叨叨地说下去,“别人都走了,就剩下他俩,又不会过日子。你看,一地红薯干,不急着捡,去谈啥乱爱,赶明儿饿着肚子还有劲儿乱爱么?”
她告诉我,那俩娃儿一到傍晚就去黄河边,直到深夜才回来。呶,就在那座神像下面。我匆匆道谢后,把自行车放在村边,向河边走去。
其实,这老人就是一位了不起的哲学家,我想。她的话抓住了这一阶层芸芸众生的生存真谛——尽力塞饱肚子。
说起哲学,我又想起一件事。20世纪60年代初,日本一位物理学家阪田昌一提出物质无限可分的思想。毛主席立即作了批示,说这是第一位自觉运用辩证唯物主义指导科学研究的自然科学家,全国自然闻风响应,轰轰烈烈地学起来。
我对以政治权威判决学术问题的做法,历来颇有腹诽,这样只能产生李森科那样的学术骗子加恶棍。但在向学生讲述物质无限可分思想时,我却毫无负疚之感,因为我非常相信它。甚至在接触到它的一刹那中,我就感觉到心灵的震撼,心弦的共鸣!我能感受到一代伟人透视千古的哲人目光。
我在课堂上讲得口舌生花,学生听得如痴如醉,包括林天声。
傍晚,我发现一个大脑袋的身影在我宿舍前久久徘徊,我唤他进来,温和地问他有什么事。林天声犹豫很久,突兀地问:“何老师,你真的相信物质无限可分吗?”
我吃了一惊。纵然我自诩为思想无羁,纵然我和林天声之间有心照不宣的默契,但要在政治高压气候下说出这句话,毕竟太胆大了。我字斟句酌地回答:“我是真的相信。你呢?”
林天声又犹豫很久。
“何老师,人类关于物质世界的认识至今只有很少几个层次,总星系、星系团、星系、星体、分子、原子、核子、层子或夸克。虽然在这几个层级中物质可分的概念都是适用的,但做出最后结论似乎为时过早。”
我释然笑道:“根据数学归纳法,在第n+1步未证明之前,任何假设都不能作为定理。但如果前几步都符合某一规律,又没有足够的反证去推翻它,那么按已有规律做出推断毕竟是最可靠的。”
林天声突然说:“其实我也非常相信。我一听你讲到这一点,就好像心灵深处有一根低音大弦被猛然拨动,发出嗡嗡的共鸣。”
我们相互对视,发现我们又处于一种极和谐的耦合态。
但林天声并未就此止步。“何老师,我只是想到另外一点,还想不通。”
“是什么?”
“从已知层级的物质结构看,物质‘实体’只占该层级结构空间的一小部分,如星系中的天体、原子中的电子和原子核。而且既然中微子能在任何物质中穿越自如,说明在可预见层级中也有很大的空隙。你说这个推论对吗?”
我认真思索后回答:“我想是对的,我的直觉倾向于接受它,它与几个科学假设也是互为反证的。比如按宇宙爆炸理论,宇宙的初始是一个很小的宇宙蛋,自然膨胀后所形成的物质中都有空隙。”
林天声转了话题:“何老师,你讲过猎狗追兔子的故事,猎狗在兔子后100米,速度是它的两倍。猎狗追上这100米,兔子又跑了50米;追上这50米,兔子又跑了25米……这似乎是一个永远不能结束的过程。实际上猎狗很快就追上兔子了,因为一个无限线性递减数列趋向于零。”
我的神经猛然一抖,我已猜到他的话意。
林天声继续他的思路:“物质每一层级结构中,实体部分只占该层级空间的一部分,下一层级的实体又只占上一层级实体部分的若干分之一。所占比率虽不相同,但应该都远小于1——这是依据已知层级的结构,用同样的归纳法得出的推论。所以说,随着对物质结构的层层解剖,宇宙中物质实体的总体积是一个线性递减数列。
“如果用归纳法可以推出物质无限可分的结论,那么用同样的归纳法可以推出:物质的实体部分之总和必然趋近于零。所以,物质只是空间的一种存在形式,是多层级的被力场约束的畸变空间。老师,我的看法是不是有一点道理?”
我被他的思维真正震撼了。
心灵深处那根低音大弦又被嗡嗡拨动,我的思维乘着这缓缓抖动的波峰,向深邃的宇宙深处,聆听神秘的天籁。
见我久久不说话,天声担心地问:“老师,我的想法在哪个环节出错了?”
他急切地看着我,目光中跳荡着火花,似乎是盗取天火的普罗米修斯在跌宕前行,天火在他瞳仁里跳跃。天声这种近乎殉道者的激情使我愧悔,沉默很久,我才苦笑道;“你以为我是谁,是牛顿、马克思、爱因斯坦、霍金?都不是。我只是一个普通的中学物理教师,纵然有些灵性,也早已在世俗中枯萎了、僵死了。我无法做你的裁判。”
我们默默相对,久久无言,听门外虫声如织。我叹息道:“我很奇怪,既然你认为自己的本元不过是一团虚空,既然你认为所有的孜孜探索最终将化亡于宇宙混沌,你怎么还有这样炽烈的探索激情?”
天声笑了,简捷地说:“因为我是个看不透红尘的凡人;既知必死,还要孜孜求生。”
夜幕暗淡,一道清白色的流星撕破天幕,倏然不见,世界静息于沉缓的律动。我长叹道:“我希望你保持思想的锋芒,不要把棱角磨平,更要慎藏慎用,不要轻易折断。天声,你能记住老师的话吗?”
河边地势陡峭,那是黄土高原千万年来被冲刷的结果,是大自然的鬼斧神工。夕阳已落在塬上,晚霞烧红了西天。
老太太所说的神像实际是一尊伟人塑像。塑像的艺术性我不敢恭维,它带着文化大革命特有的呆板造作。但是,衬着这千古江流,血色黄昏,也自有一番雄视苍茫的气概。
暮色中闪出一个矮小的身影,声音抖抖地问:“谁?”
我试探地问:“是小向吗?我是何老师。”
向秀兰哇的一声扑过来,两年未见,她已是一个典型的农村女子了。她啜泣着,泪流满面,目光中是沉重的恐惧。我又立即进入为人师表的角色:“小向,不要怕,何老师不是来了嘛、我昨天才见到你的信,来晚了。天声呢?”
顺着她的手指,我看到山凹处有一个身影,静坐在夕阳中,似乎是在做吐纳功。听见人声,他匆匆做了收式。
“何老师!”他喊着,向我奔过来。他的衣服破旧,裤脚高高挽起,面庞黑瘦,只有眸子仍熠熠有光。我心中隐隐作痛,他已经跌到生活最低层,但可叹的是他的思维仍然是那样不安分。
我们良久对视。我严厉地问:“天声,你最近在搞什么名堂,让秀兰这样操心?真是在搞什么穿墙术?”
天声微笑着,扶我坐在土埂上:“何老师,说来话长,这要从这一带流传很广的一个传说说起。”
他娓娓地讲了这个故事。他说,距这儿百十里地有座天光寺,寺里有位得道老僧,据说对气功和瑜伽功修行极深。“文革”期间,他自然逃不了这一劫,红卫兵在他脖子上挂一双僧鞋,天天拉上街批斗。老僧不堪其扰,一次在批斗途中,忽然离开队伍,径直向古墓走去,押解的人一把没拉住,他已倏然不见,古墓却完好如初,没有一丝缝隙。吓呆的红卫兵把这件事暗暗传扬开来。
他讲得很简洁,却自有冰冷的诱惑力,向秀兰甚至打一个冷战。我耐着性子听完,悲伤地问:“你呢,你是否也相信这个神话?难道你的智力已降到文盲的档次了?”
天声目光锐利地看着我:“稍具科学知识的人都不会相信这个传说,只有两种人会相信:一种是无知者,他们是盲从;一种是哲人,他们能跳出经典科学的圈子。”
他接着说道:“何老师,我们曾讨论过,物质只是受力场约束的畸变空间,两道青烟和两束光线能够对穿,是因为畸变的微结构之间有足够的均匀空间。人体和墙壁之所以不能对穿,并不是它们内部没有空隙,而是因为它们内部的畸变。就像一根弯曲的铜棒穿不过弯曲的铜管,哪怕后者的直径要大得多。但是,只要我们消除了两者甚至是一方的畸变,铜棒和铜管就能对穿了。”
他的话虽然颇为雄辩,却远远说服不了我。我苦笑一声问道:“我愿意承认这个理论,可是你知道不知道,打碎一个原子核需多少电子伏特的能量?你知道不知道,科学家们用尽解数,至今还不能把夸克从强子的禁闭中释放出来?且不说更深的层级了!”
林天声怜悯地看着我,久久未言,他的目光甚至使我不敢与他对视。很久,他才缓缓说道:“何老师,用意念的力量去消除物质微结构的空间畸变,的确是难以令人信服的。我记得你讲过用意念隔瓶取物,我当时并不相信,只是觉得它既是世界性的传说,必有产生的根源。从另一方面说,人们对自身机构,对于智力活动、感情、意念、灵感,又有多少了解呢?你还讲过,实践之树常绿,理论总是灰色的。如果可能存在的事实用现有理论完全不能解释,那么最好的办法是忘掉理论,不要在它身上浪费时间,而去全力验证事实,因为这种矛盾常常预示着理论的革命。”
我没有回答,心灵突然起了一阵颤动。
“你去验证了?”我低声问。
林天声坚决地说:“我去了。我甚至赶到天光寺,设法偷来老和尚的秘籍。这中间的过程我就不说了,是长达三年的绝望的摸索。被囚禁在地狱的幽冥世界里,孤独和死寂使我几乎发疯。直到最近,我才看到一线光明。”
听他的话意,似乎已有进展,我急急问道:“难道……你已经学会穿墙术?”
我紧盯着他,向秀兰则近乎恐惧地望着他,显然她并不清楚这方面的进展。我们之间是一片沉重的静默,很久很久,天声苦笑道:“我还不敢确认,我曾经两次不经意地穿越门帘——从本质上讲,这和穿过墙壁毫无二致。但是,我是在意识混沌状态下干的,我还不知道是否确有此事。等我刻意追求这种混沌状态时,又求之不得了。”
他的脸庞突然焕发光彩:“但今晚不同,今晚我自觉得竞技状态特佳,大概可以一试吧。我想这是因为何老师在身边,两个天才的意念有了共鸣。何老师,你能帮我一把吗?”
他极恳切地看着我。我脸红了,我能算什么天才?一条僵死的冬蚕而已。旋即又感到心酸,一个三餐无着的穷光蛋,却醉心于探索宇宙的奥秘,又是用这样的原始方法,这使人欲哭无泪。我柔声问:“怎样才能帮你?你尽管说吧。”
向秀兰没有想到我是这种态度,她望着我,眼泪泉涌而出。我及时拉住她:“秀兰,不要试图阻拦他。如果他说的是疯话,那他这样试一次不会有什么损失,至多脑袋上撞个青包,”我苦笑着,“也许这样会使他清醒过来。如果他说的是事实,那么……即使他在这个过程中死亡,消失,化为一团没有畸变的均匀空间,那也是值得的,它说明人类在认识上又打破一层壁障。你记得普罗米修斯盗取天火的故事吗?”
向秀兰忍住悲声,默默退到一边,珠泪滚滚而下。
天声感激地看着我,低声说:“何老师,我就要开始了,你要离我近一些,让我有一个依靠,好吗?”
我含泪点头。他走到塑像旁,盘腿坐好,忽然回头,平静地向姑娘交代:“万一我……你把孩子生下来。”
我这才知道向秀兰已经未婚先孕了。向秀兰忍着泪,神态庄严地点头,没有丝毫羞涩。
最后一抹夕阳的余晖涂在天声身上,他很快进入无我状态,神态圣洁而宁静,就像铁柱上锁住的普罗米修斯在安然等待下一次苦刑。我遵照天声吩咐,尽力把意念放松。我乘着时间之船进入微观世界,抚摸着由力场约束的空间之壁,像是抚摸一堆堆透明的肥皂泡。在我的抚摸下,肥皂泡一个个无声地破碎,变成均匀透明的虚空。
意念恍惚中我看到天声缓缓站起来,下面的情形犹如电影慢动作一样刻在我的记忆中:天声回头,无声地粲然一笑,缓步向石座走去。在我和小向的目光睽睽中,人影逐渐没入石座,似是两个半透明的物体叠印在一起,石像外留下一个淡淡的身影。
我下意识地起身,向秀兰扑在我的怀里,指甲深深嵌入我的肌肤。不过,这些都是后来才注意到的。那时我们的神经紧张得就要绷断,两人死死盯着塑像,脑海一片空明。
突然,传来一声令我们丧魂失魄的怒喝:“什么人?”
那一声怒喝使我的神经铮然断裂,极度的绝望使我手脚打战,好半天才转过身来。
是一个持枪的民兵,一身“文革”的标准打扮,无领章的军装,敞着怀,军帽歪戴着,斜端一支旧式步枪,是一种自以为时髦的风度。他仔细打量着向秀兰,淫邪地笑道:“妈的,老马还想啃嫩草咧。妈的臭老九!”(他准确地猜出了我的身份)。
他摇摇摆摆走过来,我大喝一声:“不要过来,那里有人!”
话未落,我已经清醒过来,后悔得咬破舌头,但为时已晚了。那民兵狐疑地围着石像转了一圈,恶狠狠走过来,噼噼啪啪给我两个耳光:“老不死的,你敢玩我?”
这两巴掌使我欣喜若狂,我一叠声地认罪:“对对,我是在造谣,我去向你们认罪!”
我朝向秀兰做个眼色,主动朝村里走去。向秀兰莫名所以,神态恍惚地跟着我。民兵似乎没料到阶级敌人这样老实,狐疑地跟在后边。
这时向秀兰做了一件令她终生追悔的事。走了几步,她情不自禁地回头望了一眼,民兵顺着她的目光回头一看,立刻炸出一声惊呼!
一个人头正缓缓从石座中探出来,开始时像一团虚影,慢慢变得清晰,接着是肩膀、手臂、上半个身子。我们都惊呆了,世界也已静止。接着我斜睨到民兵惊恐地端起枪,我绝望地大吼一声,奋力向他扑去。
“啪!”
枪声响了,石像前半个身子猛一抖颤,用手捂住前胸。我疯狂地夺过步枪,在地上摔断,反身向天声扑过去。
天声胸前殷红斑斑,只是鲜血并未滴下,却如一团红色烟雾,凝聚在胸口缓缓游动。我把天声抱在怀里,喊道:“天声!天声!”
天声悠悠醒来,灿烂地一笑,嘴唇嚅动着,清楚地说道:“我成功了!”便安然闭上眼睛。
下面的事态更令人不可思议。我手中的身体逐渐变轻,变得柔和虚浮,顷刻间如轻烟四散,一颗亮晶晶的子弹砰然坠地。只有天声身体和石像底座相交处留下一个色泽稍深的椭圆形截面,但随之也渐渐淡化。
一代奇才就这样在我的怀里化为空无。我欲哭无泪,拾起那颗尚发烫的子弹,狠狠地向民兵逼过去。
民兵惊恐欲狂,盯着空无一人的石像和我手中的子弹,忽然狼嗥一般叫着回头跑了。
以后这附近多了一个疯子。他蓬头垢面,常常走几步便低头认罪,嘴里嘟嘟囔囔地说:我不是向塑像开枪,我罪该万死,等等。
除了我和向秀兰,谁也弄不清他说的是什么意思。
我从痛不欲生的癫狂中醒来,想到自己对生者应负的责任。
向秀兰一直无力地倚在地上,两眼无神地望着苍穹。我把她扶起来,低声说道:“小向……”
没有等我的劝慰话出口,秀兰猛地抬头,目光奇异地说:“何老师,我会生个男孩,像他爸爸一样的天才,你相信吗?”她遐想地说:“儿子会带我到过去未来漫游,天声一定会在天上等着我,你说对吗?”
我叹口气,知道小向已有些精神失常了,但我宁可她暂时精神失常,也不愿她丧失生活的信心。我忍泪答道:“对,孩子一定比天声还聪明,我还做他的物理老师,他一定会成为智者、哲人。现在我送你回村去,好吗?”
我们留恋地看看四周,相倚回家去。西天上,血色天火已经熄灭,世界沉于深沉的暮色中。我想天声不灭的灵魂正在幽邃的力场中穿行,去寻找不灭的火种。
听 ● 斫
“寻”、“斫”
山上的老家很静,像千百年的岁月凝结成的巨岩,唯有的是以祖宗的血肉滋养高大的树木们低语的婆裟声,从树上扔下果实给自己的脚瘙痒的声音、猴子在它们身上拨弄的声音、鸟儿穿梭其中高歌的声音,抑或是养在园子里的鸡和鸭互相协奏曲的声音,狗和猫相互交响乐的声音,以及父亲在阴房里面捣鼓着,由祖宗身化而成,被保存多年等待自然干燥木板的声音。父亲说自祖宗传下来的手艺,琴的选材首选是纹理通顺、宽度均匀、无节眼及虫蛀,存放在阴房多年自然干燥,如旧杉木,梧桐和梓木为佳。“寻”出木材后绘制图样,决定外轮廊线,计算出岳山、龙池、凤沼、雁足等位置,再按照木料的纹理及材质,判定适合琴首、琴尾、琴面、琴腹的位置。之后便是磨利斧头,劈削塑造外形,发出变化多端叩、叩、叩的“斫”声。也有的是哥哥练琴的声音,指尖撩拨琴弦,琴弦波动,令琴身震动出,静静的数步之内方可听见的,松沉而旷远的散音;清冷入仙如天籁的泛音;飘渺多变,有时细微悠长,有时如低语倾诉的按音。祖宗留下的规矩,擅弹琴的人才能成为斫琴人。
“挖”、“合”、“镶”
哥哥像一座山,祖宗反复筛选才决定世代定居的这座山,有能埋骨种下琴材宽阔之地,有流水四季韵静的心,高山流水可以轻而易举地从指尖流淌而出。他的灵魂一定是经祖宗时刻反复用尺量度,用手指感觉厚度,并敲打聆听反应后,恰到好处地“挖”过,才能如父亲手上所挖出最恰到好处的琴腹,能够随心所欲奏出沉厚而通透的实音,微细而清晰的虚音,琴清绵长,即便微弱的流离虚音都清晰绵绵。父亲在挖好琴腹后会慎重地在面板槽腹内签名,及记录斫琴年份般,也将祖宗的名字都签在哥哥的灵魂和造诣里。父亲对哥哥,就像他斫琴时,在用天然生漆混和面粉糊成的黏合剂黏合面板和底板般,要小心翼翼地分开点于底面板边沿,深怕不小心涂满反而不利于音质,后以布条“五花大绑”,在温暖及潮湿的环境下等待黏合剂自然干固,逐渐变得坚实,最后裹上以植物纤维编成的薄布(如葛布、麻布),防止琴体开裂或变形般,精心教养与呵护。哥哥也是个极好的琴材,心静如镜也坚韧不易催,极能接受各种不同程度的“斫”、“挖”、“合”、“镶”,即使再辛苦也能够紧密准确地镶上各种能配合琴发音的坚硬滑溜的配件(如岳山,承露,冠角,琴轸,护轸,轸池,雁足,齿托),如果说琴面的面板为阳,底板为阴,那哥哥便是那充分承载了祖宗们期盼的面板,在祖宗的荫泽之下,紧疏有致地黏合并五花大绑地“合”在一起。
不像我。
第一次乘坐火车的缘由,那时候我企图爬上埋着祖宗的树,想要眺望山下的村庄,却摔下来,折了条腿。山上老家交通极其不便,父亲恼怒得很,嘴上骂骂咧咧地恨我不省心,却连夜掮我到山下的村庄看医生,到半山腰时父亲已经全身湿透喘着大气,嘴里再也吐不出一句完整咒骂的话语,好不容易把医生吵醒,结果医生也拿我的腿没办法,只能打止痛针,昏昏沉沉中父亲托村里人连夜开货车,一路颠簸地把我抬到省城医院。
路途遥远,父母也鲜少来看我,直到我出院那天,父亲才带我搭了趟火车,好让我打着石膏的腿能少受点罪。风景在火车车窗外呼啸而过,从高楼大厦奔腾到原野,再从原野奔驰到大河大湖,又从大河大湖奔波到村庄。之后是父亲托的村里人开车把我送回那遥远的山上的老家。
摔断腿在省城医院的日子,变得很吵,却也解闷。医院外车辆的引擎声不曾止歇,救护车急切的进出声,医生护士忙碌巡诊的脚步声,突如其来的急诊求救,墙角处断续的的抽泣及颤动。最有趣的要数隔壁病床那爱摆弄相机的老爷子,他是一名摄影师,透过手上古老的相机,把他走过的痕迹和看到的人事物都瞬间定格封存,刊在各大报章和杂志上同世人炫耀。我看着他那具剩下单薄皮肉挂着的头颅,眼眶里的光随着岁月流逝而剥离;可当他聊着他的照片、他的回忆而有了朝气,甚至年轻生动鲜活,像把这些年来无人倾听的话语全都要说完。我出院前一夜,他似有所感,把相机送给了我。相机陪我回到了山上,看到了祖宗埋骨的树林,哥哥的勤勉,父亲斫的琴,山下孩子的游戏,山下家庭的炊烟日常,可我渴望在镜头后看到更多,于是我带着相机又爬上祖宗的树,希望能望到更远。我又摔下来了。
我的世界静了,彻底地静下来,比山上老家更加安静。救护车响声再急切也不能听见,经过一轮轮深切的检测后,医生都无法找出确切听不到的原因。父亲身体颤抖腿一软竟跌跪在我面前,垂着脑袋,我望着他逐渐稀疏的头顶,感受到脚上下着淅淅沥沥的雨,似在向祖宗谢罪,他这一代,少了一个子孙。
“灰”、“磨”
合好的琴,需要反复“灰”“磨”,父亲始终不肯承认在世代的循规中,他这一代出了我这一块难以被斫好的材料,所以他要生生的把我跟祖宗的荫泽黏合,快速地想要批上灰胎,然后磨到琴面细滑为止。但是父亲忘了,即使强行黏合镶嵌,批上一层又一层从粗到细的灰胎,然后吃力地、反复地把整张琴面的灰磨平,但没有斫好及挖妥的琴面,终究奏不出祖宗世代钻研七弦里的十三徽。打小起,当哥哥在研究琴谱时,我躲过父亲的视线,跟着蟋蟀蚱蜢蹦跳下山,跟山下的孩子弹弹珠,打陀螺,放风筝。当哥哥开始抚琴以慰劳辛苦一天的太阳后,我才恋恋不舍地由萤火虫带路回到祖宗面前迎候父亲责杖。
出院后,我留在省城,住进聋哑学院,学习一个听不见的人须懂得的一切常识。 在第一次乘坐火车时,从省城医院康复回家,一路上的火车奔驰呼啸的声音,带来的远方和风景,如今的我,离它特别近。跟我一起从树上摔下来的相机完好无事,多年以后,我也随着老爷子的步履,到处定格封存眼前的风景。妻子是聋哑学院的同学,在记事前因高烧而导致的聋哑,她没有听见的记忆及技能,只能从物体的震动中感受声音。新婚时因经济拮据,我们租住在火车轨道不远处的房子里,每次火车经过都惊得屋子发抖,听不见的妻子通过屋子的震动享受火车的声音。妻子与父亲极度不同,怀着身孕的她,拿着在聋哑学院授课微薄的薪水无条件支援我带着老爷子留给我的相机四处留下脚印,定格封存我看到的一切,渐渐地我的照片得到越来越多愿意刊登它的地方,我们的生活因此开始充裕,儿子是个听力正常的孩子,为了不让他被火车呼啸的声音所扰,我们曾一度搬到平和的社区。
这十多年,我游历了数不尽的国家和地区,通过镜头见证过一些远离着文明的古老部落,他们或仍延续着古老的农耕文化,明明贫瘠艰难,却仍在祖宗们传承给他们的土地与荫泽下自得其乐地困守不出。也通过镜头看到一幕幕的,或因战争,或因旱灾而衍生的大屠杀或大饥荒。那些因战乱而散落在路上成群成群的尸体,或死于爆炸,或死于抢杀,抑或死于砍杀。那些因旱灾而导致的大饥荒,无论成人,孩子抑或是刚出生的婴儿无一不被饥旱成仅顶着一层皮的白骨,伴随着饥荒的还有瘟疫,每天每时每刻都有新的死亡发生,快门在它们的面前显得如蜗牛般缓慢地仅来得及在所经之处留下很快便会被蒸发的汁液。这些地方如此的美丽,却发生着那么多的灾苦和承载这么多的死亡。苦难在听不见的镜头下被永恒地定格封存,镌刻这些的除了相机的镜头,洗出来的照片之外,也许也在不知不觉中浸染在相机镜头后的,我的灵魂上。渐渐的,需要迈出的步伐越来越沉重,不再期待在新的地方留下足迹,也不再想按下快门记录下那一幕幕刺耳的,地狱瞬间。然而,令我停下脚步的原因,却是妻子患上难以被治愈的肺病。她不再能胜任教职,我也因此不便再离家。为了维持生活,我接替了她在聋哑学院的职位,我们的经济拮据,致使被迫再次搬回那时常被火车惊吓得发抖的房子。铁路串起省城与老家的山,临近这座祖宗身化的树林,远远地在注视着我。
“漆”
火车飞驰震撼的声音,妻子剧烈咳嗽震动床榻的声音,我正要听见的瞬间便能感受到祖宗埋骨的深深树林在凝视。我,似乎,必须,应该听不见。孩子被火车惊扰得夜不能眠,精神出现恍惚,医生建议妻子搬离省城,能移居到深山最好,祖宗树林的影子在我脑海里摇曳,蹉跎间,从我未来到这世间便在阴暗的羊水中紧密依靠的母亲,即使与我脐带隔断,十数年来不曾见面的母亲,即便离得这么远,她的灵魂仍能关注到我的。母亲的信,经过数不清的转站姗姗来到我的面前,是她病重,渴望我举家回去探望的消息。
风景在火车车窗外呼啸而过,从高楼大厦逃亡到原野,再从原野奔波到大河大湖,又从大河大湖奔腾到村庄。和许多年前一样,还是是父亲托的村里人开车把我一家送回那遥远的山上的老家。多年不见长得清朗娟秀的哥哥,模样传承了母亲的,灵魂继承了祖宗的,手艺则是接手了父亲的,这才是祖宗的子孙,父母的儿子。母亲是强撑着一口气,似是用尽了最后一丝力气羸弱无力地握着我向她伸出的手,嘴巴蠕动,似在说“回来便好”。当夜,母亲便随着祖宗的步伐,身化成那树林里的其中一员,子孙们将来的琴材。
家族历代的葬礼,便是在祖宗的树林里寻得一处,淘一口坑,布上不适宜作为琴材的木料和斫挖出来的木屑碎片,撒一点燃油,逝者躺于之内,点火,焚化。木材燃烧飘散四周的炭味,肉体被烧焦焦灼的味道,祖宗的魂灵在摇曳中释放出树木独有的气息在努力净化,企图冲淡一丁点死亡的味道,猴子将双掌都平放在树丫上,鸟儿也如静默的乐者,祖宗们则流下一滴滴的果实,许是在为母亲引路。父亲在燃烧旁抚琴,儿子无视眼前惊骇的丧葬仪式,死盯着父亲弹奏的手,耳朵耸得高高的,聆听这家族里原本他出生之初便应该听到的声音。妻子听不见,却也好奇地紧盯着父亲的手,父亲知道妻子听不见,示意哥哥让妻子手触琴身,感受琴弦的波动和琴身的震动,此举必会影响琴槽腹与琴弦之间的共鸣,不过琴,原本就仅传声于数步之内,刚好得以给弹琴人和三五知己静听。焚毕便在其浇上泥土,种上逝者生前所属意的树。母亲生前所属意的,是漆树。
母亲身化成漆树,多年以后便能让子孙们从她身上切割表皮收取汁液,用纱布仔细过滤后,髹在打磨好灰胎的琴上。涂上漆的琴,无论是斫得好的琴,抑或是斫得坏的琴,只要涂上漆,便能历千年而不腐。漆本身是一种变化多端的美术材料,能混入不同颜料、矿物、贝壳、金属。于父亲,母亲是个与他灵魂高度契合的伴侣,父亲斫琴,母亲抚琴;父亲斫琴卖钱,母亲操持家务。于哥哥,母亲是在他深陷瓶颈或遭遇挫折而绝望时,在岸边照亮黑暗的海面的不动灯塔,引导并安抚着他,让他总能平安顺遂地迎合着祖宗和父亲的期望下前行。
于我,父亲则是认为“有毒”。
上漆的工序其实不比“灰”、“磨”轻松,最理想的做法是徒手以掌心推漆,但生漆有毒性,大多数人稍微触碰生漆,都会引发程度不同的皮肤敏感。如因皮肤敏感而无法徒手推漆,可用真丝布包成球状,蘸漆推拭,每层漆必须很薄,自然干透后再打磨至光滑平整,上漆要重复多次,直至音色和漆面效果理想为止,完成上漆步骤之后,还要进行退光工序,就是用羊皮或棉纱,蘸种子油和瓦灰打磨琴体,使漆面更显温润无痕。
对于总是逃跑下山玩乐而忘乎祖宗的我,老是爬上树给授之于父母的发肤制造伤痛的我,永远渴望远方而非祖宗遗留的琴的我,母亲会为我辩护,也常在许多个因被父亲责杖至满身伤痕而彻夜疼痛不能眠的夜晚,用羽毛轻柔地在我的伤处涂上药膏,而后拿着扇子为我的伤口扇凉,一整夜,好减轻我的疼痛,让我好眠。太阳升起,我依旧是那个我行我素,杖责加身当吃素的好汉。
嘿,慈母多败儿。
“弦”
祖宗埋骨的树林许是有了母亲的加入而比小时候少了许多的可怖的威严与压迫,山林之内,流水之中,湖泊之上,在这里世代恣意生活的古老的各式各样的渺小的物种们,犹如一把好琴遇上好的琴手与琴谱,在这片山里,共同生存,奏出和谐的,相互尊重的旋律。
搬到山上老家的妻子病情减轻不少,开始量力而行地逐渐代替母亲操持家务,家里有条不紊地,虽少了母亲的气息,但生活的气息最大的程度上被延续着。父亲颈椎老化,无法操劳,时常头晕并且四肢麻痹,父亲现在已经很少亲自斫琴,一般都是哥哥斫琴,父亲从旁点拨。儿子在山里与树木,猴子,鸟儿,虫子玩成一篇。在观赏养在园子里的鸡和鸭吵架,狗和猫相互挑衅的当儿还能向父亲学习抚琴。我从小无法从父亲哪儿获得的赞扬和欣慰的颜色,从我儿子哪里获得。那些在苦难和灾祸中骤然被迫离世的,心有渴望与不甘的,透过镜头渗透进我灵魂深处的冤魂们,似乎在祖宗树林的写意下,在父亲日日抚琴的平静里,在哥哥斫琴的忙碌里,慢慢地被洗涤,超度。脚步不再沉重,精神渐渐丰沛,曾经不惜摔断腿也要爬上高处遥望远方的孩子,如今步入中年反而能够乐在其中。被省城的吵闹而导致精神开始恍惚的儿子因父亲的琴声和哥哥的斫琴声中得到平和。为了妻子的病情,我将省城的工作辞去,省城的房子也已退租,父亲为了留住持家有道的媳妇,和像哥哥一样被祖宗眷顾灵魂的孙子,不介意赡养我一个闲人。在妻子与儿子的庇荫之下,父亲破天荒地第一次不再正视我的不务正业,任由我恣意地一事无成地遨游在山水之间,偶而下山与儿时好友叙旧。
小时候,我跟着蟋蟀蚱蜢蹦跳下山,跟山下的孩子弹弹珠,打陀螺,放风筝,入夜后才恋恋不舍地由萤火虫带路回家,哥哥从来不担心,那时候山里的老家是我唯一的归处。而今我蹦跶下山,入夜后才缓缓返山,却总会见到哥哥提着灯笼在半山腰,巡山之后携我照返山里的路,兴许哥哥不是怕我在黑暗的山路里发生意外,而是担心而今的我即使妻儿留在山上,我仍有其他去处。我听不见以前被父亲逼迫而斫的琴被摆在斫琴房最显眼的地方,远远便能看见,琴身的漆保养极优仿佛是刚刚才髹上的,并以紫檀做成的岳山,承露,冠角,琴轸,护轸,轸池,雁足,齿托镶在琴体上。那张琴被哥哥呵护着却日复一日地躺在哪儿,似等待某个应该把它斫好的人。斫琴房是儿子最爱流连的地方,我则敬斫琴房而远之,有时远远地看到哥哥在斫琴房内一边斫琴一边细细为儿子讲解,仿佛看到壮年时的父亲和年幼时的哥哥,明明应该长得像我的儿子,冥冥之中却顶替了没有婚娶、没有子嗣的哥哥,成为祖宗、父亲和哥哥眼里,下一代唯一可以传承的希翼。
岁月如琴,细微悠长,松沉而旷远的散音;清冷入仙如天籁的泛音;飘渺多变,有时细微悠长,有时如低语倾诉的按音,和谐地铺排日子,但还是有偶发意外之时。那天,在手指下自在被拨弄的琴弦,突然断裂,划破一切和谐,在心上剜了一个大缺口的破音……
一日,妻子和儿子在祖宗树林的树林里湖泊旁自在地游览,妻子听不见,因此完全没察觉儿子不慎滑入湖中的呼救。远处对声音敏感的哥哥第一时间冲过来跃入湖内把儿子托上岸,湖面如琴弦般来回荡漾,哥哥却安静得像一首沉重的按音,下降到琴腹之内。过了良久他才浮上来,宛若一具横摆在湖心的古琴。父亲将哥哥横抱在怀,小心翼翼地将他放置在祖宗埋骨的树林里那为他而淘的坑,然后再把斫琴房内,尚未完成的琴都覆盖在哥哥的身躯,随后父亲点燃了祭拜的焚香,再把剩下半截的火柴,丢进坑里。父亲在燃烧的火焰旁,抱着琴,不住地颤抖,火光映照下,他的身影显得特别黑,黑的像一团缩得越来越小的影子。风凄凄呜呜地吹过,埋着祖宗的树林滴滴答答地跌落果实;树上的猴子低着头,弓着身,看上去就像在鞠躬;鸟儿沙哑的嗓音低沉得,如敲在木鱼般。哥哥焚毕的坑上种下的是他生前属意的紫檀。紫檀是特别坚硬滑溜的木材,适合制成受力的配件(如岳山,承露,冠角,琴轸,护轸,轸池,雁足,齿托)镶在琴体上。硬木配件都要一琴一做以配合个别琴体。被祖宗寄于厚望,年纪轻轻便可独当一面的哥哥,竟然甘愿全身心地配合琴,为其作配。
“破”
妻子告诉我她希望死后能够身化成将来适合制成面板的杉树,她生前听不到声音也发不出声响,希望百年以后能够透过琴共鸣出她此生都无能听见的天籁。我对她说如果她为面板的杉木,那我便为适合作为底板的梓木,与她共振出她渴望的声音。
祖宗埋骨的树林婆娑不息,我也不得安宁。
“你留下来继承父亲的手艺吧。”妻子打着手语。
我以手语回应:“听不见的人是斫不出琴的。”
妻子停下手语不语,只是静静地凝视我,如梦里祖宗埋骨的深深树林的凝视,只是我这次不再觉得我似乎必须应该听不见。
“你是几时知道的?”
妻子温煦地微笑:“我其实一直都知道。”
这是个不能寐的夜,我摸进斫琴房,哥哥为我精心呵护并保留的琴在黑暗里的显眼之处等候着我,如在半山腰为我提着灯笼等候我的哥哥。拿起我听不见以前,在父亲逼迫下亲斫的琴,这张还没上弦的琴却一直被摆在斫琴房最显眼的位置,这次我决心不再故意无视或装作不认识它。上“弦”包括为琴轸穿上绒剅、搓绒剅、打蝇头、上弦、试音、寻找毛病。为琴张好弦,试弹一曲之后,果然手感不顺、声音欠佳,小时候哥哥会代替父亲教我弹琴,研习琴谱,这张琴在斫的时候得到哥哥明里暗里的不少帮助,哥哥总比父亲温柔包容许多,而今琴的毛病也似有哥哥的庇护,手指拨弄琴弦之间,琴声震动而出的毛病的症结清明无比。有毛病的琴,父亲和哥哥都会毫不留情地把灰漆磨走重做,很多时候甚至不惜把琴“破腹”打开,重新“斫”,“挖”,来回数次直到得到满意的琴音为止。
我在斫琴房费力地磨开表面的漆,感受不到时间的流逝,园子里养的公鸡贴心提醒,抬头看向门外蒙蒙亮的天色,才惊觉父亲站在斫琴房门外,不知是在注视我还是渴望能够通过我看到哥哥的魂魄。父亲踉跄欲跌,我冲上前扶住,是颈椎老化头晕的老毛病,不知道他到底在哪里站了多久,身体凉飕飕地,眼神却格外温煦。我扶他入内安坐后。忐忑地跪在他面前,低着头颤抖着:
“父亲……我……其实一直都听得见……”
“我知道,我们其实一直都知道……”
在医生终于判定我不再能听见的那一天。在父亲绝望地跪下,淅沥淅沥留着泪被迫接受他终究还是养出一个无法传承祖宗意志的子孙的那一天。我依稀想起母亲颤抖地抱着我,淌着泪的眼眸里所流露出的不舍,直到今天我才知道,那不舍中其实夹杂着为我感到庆幸的眼神。
“父亲,我想回家。”
童话结构的借鉴方式 - 知乎专栏
=======
童话结构的借鉴方式
童话这个东西啊我们一般指各种传说,民间故事,童话之类的,并不单单指儿童故事。从根本上说,“童话” 起源于坊间故事,民俗故事和神话传说。他们大多具有基础的叙事结构和符号化意义。如果阅读量足够会发现同时期,各个地方的童话具有十足的相似性,无论东西方,而且实际上童话本身也具有着相当的地方文化特色。譬如北欧童话就更加直白甚至稍微有些年代的童话还具有十足的性暗示特征,而相对的中欧童话则更加具有宗教和古典主义色彩,中东童话的宗教意味更浓,而东方童话的巫术色彩更为丰富。
那么,我们为什么要寻求从童话中借鉴结构呢?其实童话本身的特点注定了它的叙事更为直白,而我们从中拉出结构框架更为方便,实际上童话中很多都是我们常常提及的 “故事原型” 譬如韩剧中十分常见的 “灰姑娘” 故事原型等等。而实际上,童话的结构是十分适合初学者来整理并且学习的。
在上一篇文章之中,我提及了基础的 “三幕剧结构”,而在“开端、代入、发展、高潮、结尾” 的结构之中我们还缺乏着情节点的加入部分,这个时候,童话的结构方式就很好的可以满足我们的需求。
我们今天主要提及的部分应该——“代入及发展”部分。其实高潮并不难处理,真正的麻烦都来自于高潮之前的部分。我们就以 “灰姑娘” 为例子,照扒一下整体结构。
“灰姑娘” 的故事应该大部分人都十分熟悉,大抵讲述的就是一个可怜的女孩有一个恶毒的继母以及两个恶毒的姐姐,在一个王子的宴会前夕,灰姑娘被困在家中无法参与,一个女巫出现帮助了灰姑娘,让灰姑娘参加了王子的宴会,但是却有一个限制。灰姑娘在离开时,遗留下了一只水晶鞋,被王子捡到。(王子对着水晶鞋撸了好几天之后。)王子全城寻找灰姑娘,恶毒的姐姐因为贪心收到了惩罚,而王子最终找到了灰姑娘,过上了没羞没臊的生活。
其实把人物符号化一些我们就可以从中得到这样的一些玩意。
灰姑娘:貌美如花的主人公
继母:恶毒的敌人
姐姐们:恶毒的敌人的手下们
女巫:强而有力的助手
王子:具有吸引力的宝藏。
所以这是一个什么故事?这是一个——“主人公通过帮助获得宝藏并打败敌人” 的故事。实际上童话提供给我们的就是这样的一个故事原型,我们需要的是好好的借鉴一下故事原型之中的排布问题。
主人公 A 在一个艰难的环境之中(开端),发生了一件大事 A 要去完成这件事情(代入),遇到了敌人的阻碍,出现帮手来帮助主人公,帮助具有限制(发展),A 达到一定目的(次高潮),因为限制没有完全成功,但是因为这一次的行动而使得事态发生进一步的发展(延宕),A 再一次遇到阻碍,A 突破阻碍,A 成功并反杀敌人(高潮及结尾)。
然后我们就可以套壳子了呀,到这里就是送分的了呀。A 可以是男是女,是不男不女;这件事情可以是出现一个宝藏,可以是当年的一个秘密;敌人可以是杀父仇人,也可以是自身缺陷。这样是不是很轻松,很方便。
可是为什么?为什么看起来这么想水的厉害的小网文。
那么怎么才能让这样的结构变成一个有点意思的玩意呢?其实也不难,我们只需要结合之前人物的部分,将人物复杂化,就可以让其变得稍微像点样子了。主人公不仅仅具有自身的问题还有吸引人的特质,主人公可以就是个普通人,他的目标也不尽然需要多么伟大,我们将夸张的、过于戏剧化的部分压下来,靠近生活就可以了。
我记得我曾经拉过一个卡尔维诺《意大利童话》中的结构,做过一个仿写。那一篇好像叫做《七公主》讲的大概是一个国家的七公主天生自带不幸体质的事情,但是最终也算是圆满的结局。那么我是如何处理这个结构,做一个相对扎实有趣的仿写的呢?
首先我确定了一个时代感——八国联军侵华时期。
然后人物我将至降格为一个大户人家的姑娘,而不是什么公主以辅助时代。
给她每一次的不幸寻找到了一个客观的、具有现实化的原因——一个纨绔子弟对其的爱慕和追击。
最终也没有让七姑娘变成一个善良的姑娘,而是最终跟了侵华的外国军官。
将整个故事的叙述者编排成一个乞丐,位置在菜市口皮匠(缝脑袋的那种)旁边。
时间的极致化——这个故事的讲述在纨绔子弟被砍头的同时。(当然他被砍头的原因自然是那个外国军官的关系更硬罢了)
语言风格调整——模仿话本的写作方式,由乞丐讲述,像评书一样。
最后的深化——纨绔子弟被砍下脑袋的同时乞丐结束了讲述,对听客们讲:故事结束了,大爷大娘们,赏口粮食吧。
所以其实要深化原始结构也是一门手艺,如何深化这个事情需要每个创作者的意图也是不同的。这关系到作者母题和阅读量练习量以及自己的悟性,而我现在看当初的仿写简直是羞耻,我觉得写得真的就是一堆垃圾。特别想起当时还觉得不错的心情,瞬间觉得自己更加羞耻了。
不过我觉得还是可以给出一些方式和选择的。
第一点我们需要确认自己需求的是什么,要写的核心是什么?结构的本身是不具备内核的,我们需要通过结构、人物和叙述手段去表现我们的核心。这个核心真的是谁也帮不上忙的,就像是黄维若老师曾经研究过的 “从无到有” 的部分一样,我不懂啊。(啊啊啊,好想听黄老师几节课啊,好想啊 QAQ。)
如果我们有了戏核我们就好办多了,我们可以从几个角度入手。
人物
事件
选择
叙述风格
其实这里我也那不太准。但是大概看看吧,首先人物需要具有独特性,并且可以承载我们的内核。事件的选择和填充实际上我们需要给予事件逻辑,同时我认为选择和事件不可能分开。选择代表着人物对于事件的选择,还代表着我们对于事件在结构中的选择。(这个部分我打算下一次专门写一下在结构上的一些写作技巧)。其实我们在有了结构之后可以尽可能多的思考和罗列事件,在之后再进行选择。
关于叙述风格的问题,不同的叙述风格选择对于读者来说是有不同的感觉,对于作品的表现力而言也是有差别的。选择话本式的写法和选择意识流写法是不同的,当然这一切都间离在我们文字水平基本过关的基础上的。而实际上,从我自己的感觉来说,这些叙述风格在使用的时候往往不如自己的文字风格更加的扎实和圆润。不过我还是要提出来的,毕竟我们要从整体上来把握。
这些都不代表着真正的——“创作”二字。千万别觉得这就入了 “创作” 的大门了,在我第一个四幕话剧剧本整理完之前我从来不敢说自己是个“创作者”。
请对 “创作” 二字,对 “文学” 二字,具有一定的尊敬。
——————————————————————————————————————————
又到了宝宝的卖萌时间。
唉,最近好忙啊,烦烦烦。
还是好想听黄维若老师的课啊,可是英语太差考博绝对无望啊 QAQ。(谁门路能旁听的话请私信我。)
其实本来不想写来着,但是前两天发现可以开打赏,所以我一定要试试新功能。(虽然我知道没有人会点的)
至于再开个专栏直播开坑这件事,我还没有纠结好。
就是这样,我继续装死了。
推理小说十二按<谋杀的简约之道>-雷蒙德·钱德勒
========================
推理小说十二按<谋杀的简约之道>-[[雷蒙德·钱德勒]]
-------
1.小说的原始设定和结局的动机必须可信,必须由合理环境下合理的人做出的合理的事情组成。要记住,“合理性”在很大程度上就是一种风格。满足了这个要求,那些唬人的结局和大量所谓“闭环”的故事就不可能出现——在这些故事里,那些最不可能成为罪犯的人被迫犯了罪,简直毫无说服力可言。类似克里斯蒂的《加莱车厢谋杀案》[1]那样精巧的舞台式布局也将无处容身:犯罪情节设置全由一系列巧合组成,怎么看也不像真的。
2.谋杀手段和侦破方法从技术层面上来说都必须能够自圆其说。不能出现万能的毒药或是不合理的药物效用,比如剂量不足以致命却害死了人之类。左轮手枪不能安消音器(根本不管用),铃绳上也不可能总盘着一条蛇(《花斑带之谜》[2])。一读到这些东西,故事立刻就从根儿上毁了。如果侦探是受过训练的警察,就必须有个警察的样子,而且要有合乎工作要求的心智和体魄。倘若他是一名私家侦探或是业余侦探,至少也应该了解必备的刑侦手法,否则只会显得自己像头蠢驴。假使像夏洛克·福尔摩斯系列故事里写的那样总把警察当傻子戏弄,不仅会让侦探取得的成就大打折扣,而且还会让读者怀疑作者在这一领域的知识水平。柯南·道尔和爱伦·坡[3]是这种艺术形式的开山鼻祖,他们和最优秀的现代作家之间的关系就好比乔托[4]之于达·芬奇。但是当代侦探小说已经不能像他们那样写了,他们作品中显示出来的蒙昧无知也不再为当今社会所容忍。而且,警察文学这种艺术形式在他们那个时候仅处于萌芽状态。《一封失窃的信》[5]只能糊弄现在的警察4分钟。柯南·道尔看起来也对苏格兰警场[6]的各个组织一无所知。克里斯蒂在我们这个时代还会干同样的蠢事,但时间的推移并不意味着能把错误洗白。奥斯汀·弗里曼[7]则恰恰与之相反,在他那部有关伪造指纹的小说[8]面世10年之后,警方才意识到,小说里写的可以成为事实。
3.必须对读者诚实。这虽是老生常谈,但人们却始终不解其意。重要的事实不仅决不应该被隐瞒,也同样不应该对其虚假强调,造成曲解。无关紧要的事实则不应该将其蓄意夸大,虚张声势。(这是典型的好莱坞悬疑影片常玩的把戏,利用特效摄像机的作用和剧烈的情绪变化转移观众注意力,造成虚假的恐吓效果。)根据事实做出推论是侦探的拿手好戏,但他也应该放出足够的事实,好让读者的脑筋跟着转起来。有一种说法似乎有些道理,虽然尚无定论:凭借某种特定知识(比如桑戴克医师[9])作出的推论从某种意义上说是在耍赖皮,因为所有好的悬疑小说都会遵守一个基础理论,那就是在故事中的某个阶段要供给读者足以找出问题答案的素材,而且这个阶段不能来得太晚。如果理解事实真相需要某种特定的科学知识,那么除非读者恰好也了解这些知识,否则就无法自行解决问题。或许奥斯汀·弗里曼也有同感,因此才开创了“倒叙推理小说”这种文体,让读者一开始就知道了问题的答案,然后就可以饶有兴味地看着侦探一步步顺藤摸瓜了。
4.人物、布景和氛围都必须真实可信,像是真实世界里的真人真事。推理小说作家能写好人物的不多,但并不代表不需要这种能力——让人一读再读难以忘怀的作品和扫了几眼便抛诸脑后的作品,区别就在这里。至于瓦伦丁·威廉姆斯[10]之流,宣称“问题大于一切”,只不过是为了掩饰自己对人物塑造的无能罢了。
5.即使去掉推理相关的部分,也必须无损故事的价值。也就是说,办案经过本身也应该是值得一读的冒险经历。
6.要达到这种效果,小说必须具有某种悬念,哪怕需要花点儿脑筋。这并不是指威胁,尤其不是指侦探必须受到严重的人身安全威胁。后者简直成了一种潮流,就像所有的潮流一样,因为彼此间的过度模仿而显出一副疲态。读者并不需要总是紧张得坐立难安。故事情节安排过犹不及,震惊太多只会让人麻木。然而矛盾冲突是必要的,无论是肢体上、伦理道德上还是情感上,而且必须在字里行间始终弥漫着某种危险的元素。
7.小说必须色彩斑斓,鼓舞人心,还要适度地扣人心弦。如果风格太过沉闷,就要用大量的技术手段去弥补,然而也不是没有先例,尤其是在英国。
8.在需要的时候,小说必须能简明而又轻松把一件事情解释清楚(这也许是所有条律中最不容易遵守的一条)。最理想的结尾是:电光火石间一切真相大白于天下。而这实属难得,因为好点子太过罕见。解释过程不必求短(在银幕上除外),而且往往根本短不了,但是必须生动有趣,让读者迫不及待要看个究竟,而不能是为了摆平某个过于复杂的情节而新编一个故事,再牵扯进一堆新角色。解释过程最重要的一点就是,它并不仅仅是冗长的细枝末节的组合,因为这些东西没有任何一个普通读者能记得住。把对答案的寻找寄托在这些东西上面对读者而言是不公平的,因为这实际上又已经超越了他们对答案的控制范围。让读者记下上千个枝节,再从中选出三种具有决定性意义的,其不公平程度不啻于希望读者对化学、冶金术或是巴塔哥尼亚食蚁兽的交配习性烂熟于胸。
9.小说必须能唬得住还算有点脑子的读者。这可就出了一个大难题。有些最棒的侦探小说(比如奥斯汀·弗里曼的作品)也无法从头到尾蒙住聪明的读者,但就是让人猜不透全部的答案,也没办法自行作出逻辑论证。读者的脑筋千差万别,有些能猜出深藏不露的凶手,而有些却会被最显而易见的情节糊弄(《红发俱乐部》[11]放到今天,还能骗得过读者吗?)。不过,也没必要非得把一个推理小说的狂热爱好者愚弄到家门都不认识的地步;当然了,这也不太可能。如果推理小说就是为了坚持骗过这些人,而且对这一目的不加掩饰,那么在普通爱好者看来就会显得不知所云,连小说到底写了点儿什么都搞不清楚。但是,有些重要的故事元素又必须让最犀利的读者也无法参破。
10.答案一旦揭晓,就一定要显得是必然结果。这是一部好的推理小说中最容易被忽视的要素,但却是所有小说最重要的元素之一。光是愚弄读者、唬住读者,或是逃避读者,都是不够的。必须让读者既拍着脑袋懊悔不迭,又对“对手”心生敬意。
11.切忌贪多求全。如果这个故事是一桩谜案,氛围既冷静又理智,那它就不可能是暴力探险故事或是激情罗曼史。恐怖的氛围会摧毁逻辑思维能力——如果小说写的明显是普通人因为无法承受错综复杂的心理压力而犯下了杀人罪,那么就别再想笔锋突转到警方调查员的冷静分析上去。侦探不可能同一时间既是英雄又是祸害,杀人犯也不会既是饱受折磨的命运牺牲品,又是个五大三粗的流氓。
12.不管方式如何,罪犯必须受到惩治,虽然不一定藉由执法完成。和当下流行的(以及来自约翰斯顿办公室[12]的)观点恰恰相反,这个要求无关道德,而只是侦查逻辑的一部分。如果案件无法告破,故事悬而未决,一定会引起众怒的。
附录
1.完美的侦探小说是写不出来的。能解决完美问题的脑袋瓜子对写作这种艺术工作是无能为力的。能让达希尔·哈米特和奥斯汀·弗里曼共处一册固然好,但绝无可能。哈米特没有耐心慢条斯理,而弗里曼的叙事缺少激情。两个人捏不到一块儿去。即使是取中庸之道的多萝西·塞耶斯,如果把她的两种写法拆开来看,也根本不能和那两位作家分庭抗礼。
2.要想把一个简单的推理过程隐藏起来,最有效的方法就是把它藏在另一个推理过程中。这是文学“戏法”中的一种。你不能光靠把线索藏起来或是假造诸如“克里斯蒂”之类的人物来愚弄读者,而是要误导他去解决错误的问题。
3.有一种说法是“没人关心尸体”。一派胡言。简直就是抛弃了一个有价值的元素。这就像是说,对你而言,你的姨妈被害就跟城市里你从未去过的地方死了一个陌生人一样。
4.油滑的对白并不是机智。
5.连载推理故事并不能成就好的推理小说。因为只有当你不能立刻读到下一章的时候,小说中的“幕布”才能起作用。如果以整本书的形式呈现,这些“幕布”只会带来虚假的悬念,招人反感。杂志已经开始意识到这一点了。
6.谈情说爱几乎总是会削弱一部推理小说,因为爱情会营造一种与主题不相容的悬念,对于侦探费尽心机破解难题于事无补。出现在悬疑小说里的爱情要想行得通,就得既能给侦探找麻烦、让问题复杂化,而与此同时你又会本能地感觉到这种情感撑不到最后。真正的好侦探永远不会结婚。婚姻会让他失去超脱的气质,而这种气质正是他魅力的一部分。
7.虽然爱情元素在畅销杂志和银幕上被大加渲染已成事实,但并不能使之成为艺术。杂志小说和电影的目标受众应当是女性。杂志才不屑于把推理作品当作艺术。任何类型的写作都不会被杂志当成艺术。
8.推理小说中的主角是侦探。一切都要紧扣他的个性。如果他的个性并不鲜明,你也就写不出什么东西来,也就更不用提写出好的悬疑小说来了。这是自然而然的。
9.罪犯不能当侦探。这是老规矩了,虽然偶尔会遭到违背,但依然和以前一样颠扑不破。原因如下:根据传统和规定,侦探是真相的追寻者。如果他已经知道了事实真相,还如何追寻?对读者而言,侦探的诚实可信是一种不言而喻的保证。
10.同样的说法也适用于第一人称叙述者是罪犯的故事。对此我还要多说两句。在我看来,第一人称叙事总是显得有些不诚实,它看似坦率,而且明明白白地记录下了侦探的一言一行,但却恰好掩盖了他的心理活动。这就引出了一个更为广义的问题:在这种语境中,诚实究竟是什么?是绝对的还是相对的?我认为,诚实永远是相对的。尽管第一人称叙事看似坦率,但总有侦探心意已决却并没有跟读者吐露的时候。他总要留些念想到大结局或是跟读者解释原委的时候。他说出了实情,却不会袒露心迹。这是不是一种约定俗成可以接受的欺骗手法呢?一定是。否则讲述自己的故事的侦探就不能抢在结局到来之前解决问题。像《长眠不醒》[13]那样几乎毫无保留的小说可谓千载难逢:收尾只用了一个动作,读者和侦探同时看见,推理过程旋即跟上。小说只在马洛侦探在油井边递给卡门的枪上的是空包弹这一点上暂时有所隐瞒,但是就连这一点也对读者早有暗示,因为马洛说:“如果她打不中盒子——那是想当然的——她的枪子儿多半会打在车轮上,子弹绝不会弹跳到远处去。然而,她连这个也打不中了。”他没有解释原因,但是接下来的动作转瞬间就发生了,因此读者并不会感觉到侦探真的对自己有所隐瞒。
11.谋杀犯必不能是个疯子。谋杀犯只有在法律意义上触犯了谋杀罪才能被称之为谋杀犯[14]。
12.正如我之前所说,绝对完美的推理小说是写不出来的。何出此言?原因有二,其一我在附录第一条已经说过了。其二就是读者自己的态度。读者的类型千差万别,文化背景参差不齐。比方说,解谜爱好者会把读小说看成是作者和自己之间的一场竞赛,如果他猜到了答案,他就赢了,尽管他并不能为自己的猜想提供证明,也没有坚实、正当的理论基础。所有读者都存在这样那样的竞争心理,但是一心关注竞争的读者除了“猜答案”这个游戏之外,对小说其他的价值视而不见。还有些读者,全部的兴趣之所在就是感官刺激:虐待、酷刑、鲜血和死亡元素。当然我们每个人或多或少都对这些东西感兴趣,但是如果满脑子都是这些玩意儿,就会对所谓的“推理故事”毫不感冒,不管故事写得多么细腻入微。第三类读者对故事人物有操不完的心,问题的答案并不是她关注的重点,最让她难过的是傻乎乎的小女主角就快要在旋梯上被扭断脖子了。还有第四类,也是最重要的,那就是富有知识素养的读者。他们喜欢读推理作品,是因为这几乎是唯一一种不摆架子的小说。这种读者会细细品咂行文风格、人物刻画和曲折的情节这些写作技艺的精湛之处,而不会只是纠缠于问题的答案。没有一部小说能让所有读者皆大欢喜,因为各人的喜好是相互矛盾的。我本人作为读者来说,几乎从不会去猜测一桩谜案的答案如何,也并不觉得作者和我之间的较量有什么重要之处。老实说,我觉得这些都是低级趣味。
13.正如我以上所说,所有的小说都有赖于某种形式的悬念。但是对“恐吓”这种极端类型的技术研究揭示出了读者或是观众奇妙的心理双重性:一方面,他们会对隐藏在门背后的东西产生恐惧;而与此同时,他们一旦发现被害对象是女主角或女主角的扮演者,心里就明白她绝对不可能被害死。即使克劳德特·科尔伯特[15]所饰角色命悬一线,我们也深知科尔伯特小姐绝不可能出事,原因很简单——因为她是科尔伯特小姐。既然观众对这些心知肚明,为什么还会被恐惧攫住?可能的原因有很多,我在这里说两点。首先,人们对视觉影像和声音的反应,以及被描写唤起的感觉,是独立于理性思考之外的。原始的恐惧元素从未远离我们思维的表层,任何带有这些元素的东西都会在短时间内战胜理性。因此“恐吓”唤起的其实是一种古老的、非理性的情感。很少有人能无视它的影响。我想说的另外一个原因是,对于任何情节紧张的文学作品或是心理投射式作品而言,部分是大于整体的。出现在眼前的场景占据了观众的思想,没有一个普通人会试图将这个场景与整个故事结构结合起来看,而只会为眼前这一幕所左右。只有当你读完了一本书的时候,才也许会——不过也未必——把它当作一个整体来看待,由此才会对小说产生记忆。但是在阅读过程中,各个章节才是占据着主导地位的要素。情感想象带来的景象虽然转瞬即逝,但是却十分扣人心弦。
[1]《东方快车谋杀案》(Murder on the Orient Express)在美出版时曾用名《加莱车厢谋杀案》(Murder on the Calais Coach),为阿加莎·克里斯蒂代表作之一。
[2]《花斑带之谜》(The Speckled Band)为英国侦探小说家柯南·道尔创作的福尔摩斯探案故事系列中的一部。
[3]埃德加·爱伦·坡(Edgar Allan Poe,1809-1849),美国诗人、小说家、文学评论家,以神秘故事和恐怖小说闻名于世。他是美国短篇故事的先驱者之一,又被尊为推理小说的开山鼻祖,进而也被誉为后世科幻小说的始祖。
[4]乔托·迪·邦多纳(Giotto di Bondone,1266-1336),意大利雕刻家、画家和建筑师,意大利文艺复兴时期的开创者和先驱者,被誉为“欧洲绘画之父”。
[5]《一封失窃的信》(The Purloined Letter)为美国作家埃德加·爱伦·坡的短篇小说代表作。
[6]苏格兰警场(Scotland Yard)指英国伦敦警务处总部。1829年间,英国首都警务处位于伦敦旧苏格兰王室宫殿,因此得名。
[7]理查德·奥斯汀·弗里曼(Richard Austin Freeman,1862-1943),英国著名作家,早年从事医务工作,转行后创作了以约翰·埃文林·桑戴克为主角的系列侦探故事。
[8]应为小说《血红指印》(The Red Thumb Mark),奥斯汀·弗里曼创作的“桑戴克医师”侦探系列第一部。
[9]约翰·埃文林·桑戴克医师(Dr. John Evelyn Thorndyke)是奥斯汀·弗里曼笔下的神探,擅长科学办案,因而树立了“科学侦探”的最佳典范。以他为主角的系列小说开创了“倒叙推理”这一新文体。
[10]瓦伦丁·威廉姆斯(Valentine Williams,1883-1946),英国记者、通俗小说作家。
[11]《红发俱乐部》(The Red-Headed League)是柯南·道尔创作的福尔摩斯案件中的一个短篇,讲述夏洛克·福尔摩斯从一份红发俱乐部的广告开始破获一个犯罪团伙的过程。
[12]约翰斯顿办公室(Johnston Office)代指美国电影协会(Motion Picture Association of America),1922年创立伊始被称作“美国电影制片人及发行商联合会”(Motion Picture Producers and Distributors of America),由前邮政总长威尔·H.海斯(Will H Hays)担任主席,并颁布“海斯法典”等针对电影作品的高压法令。埃里克·约翰斯顿(Eric Johnston)为其第三任总审查长,其在任时期的1945-1963年该协会也被称为“约翰斯顿办公室”。
[13]《长眠不醒》(The Big Sleep)是本文作者雷蒙德·钱德勒的第一部长篇小说,出版于1939年。
[14]精神失常者谋杀罪名不成立。
[15]克劳德特·科尔伯特(Claudette Colbert,1903-1996),出生于法国巴黎的美国女演员,代表作《一夜爱情》、《名士殉情记》、《红楼春怨》等。
保罗·托马斯·曼(Paul Thomas Mann,1875年6月6日-1955年8月12日), 德国作家,1929年获得诺贝尔文学奖。
```
作品
长篇小说
《布登勃洛克家族》,1901年。译本:人民文学出版社,1962年
《国王的神圣》(Königliche Hoheit),1909年
《魔山》1924。译本:上海译文出版社,1991年
《约瑟夫和他的兄弟们》四部曲(Joseph und seine Brüder Tetralogie),1933-1943年
《亚克伯的故事》(Die Geschichten Jaakobs),1933年
《年轻的约瑟夫》(Der junge Joseph),1934年
《约瑟夫在埃及》(Joseph in Ägypten),1936年
《赡养者约瑟夫》(Joseph der Ernährer),1943年
《绿蒂在魏玛》(Lotte in Weimar),1939。译本:上海译文出版社,1989年
《浮士德博士》(Doktor Faustus),1947年
《被挑选者》(Der Erwählte),1951年
《骗子菲利克斯·克鲁尔的自白》,1954年。译本: 上海译文出版社,1998年
记叙类文章,短篇小说,中篇小说
《展望》(Vision),Prosa-Skizze,1893年
《堕落》(Gefallen),1894年
《对幸福的愿望》(Der Wille zum Glück),1896年
《失望》(Enttäuschung),1896年
《死》(Der Tod),1897年
《小人物弗利德曼先生》(Der kleine Herr Friedemann),1897年
《小丑》(Der Bajazzo),1897年
《图比亚斯·敏得尼克》(Tobias Mindernickel),1898年
《衣柜》(Der Kleiderschrank),1899年
《复仇》(Gerächt),Novellistische Studie,1899年
《小路易斯》(Luischen),1900年
《通往坟墓之路》(Der Weg zum Friedhof),1900年
《神的光辉》(Gladius Dei),Novelle,1902年
《托尼奥·克律格》(Tonio Kröger),Novelle,1903年
《特里斯坦》(Tristan),Novelle,1903年
《饥饿者们》(Die Hungernden),1903年
《神童》(Das Wunderkind),1903年
《幸运》(Ein Glück),1904年
《在先知那里》(Beim Propheten),1904年
《艰难的时刻》(Schwere Stunde),1905年
《一则轶事》(Anekdote),1908年
《铁路事故》(Das Eisenbahnunglück),1909年
《Jappe和Do Escobar是如何打架的》(Wie Jappe und Do Escobar sich prügelten),1911年
《威尼斯之死》,1912年
《主人与狗》(Herr und Hund),Ein Idyll,1918年
《儿童的歌唱》(Gesang vom Kindchen),Ein Idyll,1919年
《双生子之血》(Wälsungenblut),1921年
《特里斯坦与伊索尔德》,1923年
《无秩序和早先的痛苦》(Unordnung und frühes Leid),1926年
《马里奥和魔术师》(Mario und der Zauberer),1930年
《被换错了的脑袋——一则印度传奇》(Die vertauschten Köpfe - Eine indische Legende),1940年
《法律》(Das Gesetz),1944年
《被骗的女人》(Die Betrogene),1953年
译本有:托马斯·曼中短篇小说全编,漓江出版社,2002年
戏剧
《佛罗伦萨》(Florenza)
杂文
《一个不关心政治者的观察》(Betrachtungen eines Unpolitischen),1918年
《自由的问题》(Das Problem der Freiheit),1937年
《试分析席勒》(Versuch über Schiller),1955年
《关于歌德》(Über Goethe)
作品的中译
繁体本:
宣诚/译,《托马斯曼代表作:论托玛斯曼生活与创作》,台北市:志文,1970年。
诺贝尔文学奖全集编译委员会/编译,《翁塞特(1928)/托玛斯曼(1929)》,台北市:九华文化 1980年。
蔡美玉/译,《魂断威尼斯》,台北市:逸群,1981年。/台北市:日昇,1981年。
宣诚/译,《魂断威尼斯》,台北市:志文出版,1974年、1982年、1985年、1990年、1991年、1997年。
蔡静如/译,《魂断威尼斯》,台北市:小知堂文化,2001年。
蔡尔宏/译,《布顿柏鲁世家:某家族的没落》,台北市:志文,1986年。
彭淮栋/译,《魔山》,台北市:远景,1988年6版。
杨武能等人/译,锺英彦/导读,《魔山》,台北市:桂冠,1994年。
陈苍多/译,《大师撷英》,台北县三重市:新雨,1998年。
简体本:
《托尼欧‧克洛格》,安徽文艺出版社,2005年。
《魔山》,作家出版社,2006年。
《世界文学名著文库:魔山》,中国戏剧出版社,2006年。
《魔山》,长江文艺出版社,2009年。
《绿蒂在魏玛》,上海译文出版社,2006年。
《大骗子克鲁尔的自白》,上海译文出版社,2006年。
《中短篇小说选》,上海译文出版社,2006年。
《马里奥和魔术师》,人民文学出版社,2006年。
《威尼斯之死》,陕西师范大学出版社,2008年。
《布登勃洛克一家》,译林出版社,2009年。
《浮士德博士:一位朋友讲述的德国作曲家阿德里安·莱韦屈恩的生平》,上海译文出版社,2012年。
《浮士德博士》,上海译文出版社,2016年。
```
!外祖父悖论-[[柳文扬]]
-----
人不能两次踏进同一条河流
——赫拉克利特
逝者如斯夫,不舍昼夜!
——孔子
老苏不老,也就三十岁,他是那种“对众所周知的事情一无所知”的天才。比方说,他经常分不清东南西北。邻里间传言:有一天老苏下班,在自家附近的街上迷了路,一个多月以讨饭度日,亏得居委会万大妈心好,悄悄在路上画了许多箭头,引着他回了家。这当然是假的,是邻居们的幽默。老苏对此无可奈何。他本来就是丢三落四,整天失魂落魄似的。
高远就不一样。他是一只小公鸡,时常昂着头睥睨四顾,谁也别想嘲笑他。小伙子精神,上下楼梯总是一溜小跑,做事也迅疾如风。衣饰永远整洁,头发一丝不乱。
如此截然不同的两个人,每天坐在同一间办公室里,而且相处得还不错。那是因为他们的心思都被同一件事占满了。
这天上午高远对老苏说:“你想过没有,时空蠕虫必须全体同步萎缩,这个假设可以解决‘外祖父悖论’。”
老苏疲倦地说:“我想过。咱们的假设也够多了,我想的是实验,是验证。”
“实验要有钱。沈非跑得怎么样?”
提起沈非,老苏脸上露出一点笑意:“那家伙这两天净发牢骚。专利局的人不愿意预支,银行也不贷款,除非有人肯作担保。”
高远一抬眼,说:“找局长啊!这种科研项目,当然是咱们局自己担保最合适了。”
马局长,最好的一个老头儿。这位老兵在四十年前为共和国立下过汗马功劳。流年似水,双鬓如银。他的战刀挂在墙上,仍没有一点锈斑,然而这个“老伙计”现在也只能挂上墙壁,作一件装饰品了。如今不是跨马舞刀的年代,他领导的是科技开发局。
马局长明白上级派他来这里的用意。是的,他忠心耿耿,御下有方,而局里这批年轻人个个不安份。他要了解他们的心思,及时向上面汇报,要管理约束他们,使他们的才能都用在利国利民的事业上。
所以,当老苏为了做什么时间机器来申请经费的时候,马局长冷静地想到,这是一件于国于民毫无用处,而且浪费时间和金钱的事情,他断然拒绝。
老苏走了以后,马局长把高远叫进办公室,问:“你觉得小苏怎么样?”
高远并不回答,询问地看着局长。
局长说:“他要造个什么‘时间机器’,真是异想天开!”
高远谦和地笑笑:“老苏对这方面很感兴趣。”
“所以我常常对你们说,搞研究不能单从兴趣出发!”局长手指点着桌子,“你们是科学工作者!你们的研究要对国家对人民负责!”高远频频点头,局长的态度才和缓下来,“当然,你们年轻,没经验,所以上级才要我来把关。小苏的要求,我不同意。我看你们俩还不错,你是懂原则有责任感的小伙子——好好帮助帮助他!啊!”
局长在高远肩上一拍,高远点点头,一脸责任感地转身出门。
老苏回家,沈非躺在沙发睡着了。门一关,他像只大猫似的惊叫起来,打个呵欠说:“太困了!”坐起身又说,“你也熬得可以吧?人灯儿似的。干脆——”他递上一张纸条,“我找医院的朋友给你开了个病假条,慢性肾炎,先请三个月的假,踏踏实实在家里琢磨。成不成?”
“成!”老苏最听话。只要能安安静静研究他的机器,让他装病不算什么,装疯都成。
第二天,老苏就去局里交了病假条。马局长知道后又是叹气又是敲桌子。
老苏在家闷头苦想了十几天,眼眶又陷下去好多。沈非买些蜂王浆和鳌精灌他。
一天早晨,老苏大喊一声,沈非心惊胆战地瞧着他。老苏狂喜地冲他嚷道:“时间不存在!”沈非吁了口气,喃喃地说:“神经!”
吃早饭的时候,电话铃响了。老苏正在兴头上,忙抄起话筒。
是高远。听筒里,一惯冷静的声音微微颤抖:“老苏,我觉得你可能也想到:时间存在么?”
老苏兴奋地说:“对呀!我也刚想通:没有这种东西。像你说过的一样,我们不能单独逆转一条世界线,全体蠕虫应该同步萎缩!”
高远静默了片刻,说:“很好。你也这么想,那我就有把握了。”
老苏笑着叫:“喂!你也过来咱们一起干吧?”
高远停了一会儿说:“局里派了不少事下来,我脱不开身,咱们再联系吧。”
挂了电话,老苏说:“可惜!”
沈非一手托着腮坐在桌边看他,说:“我什么忙也帮不上,我只会耍笔杆子,耍嘴皮子。”
老苏瞧他一眼,不说话,喝豆浆。
下午,一位白世凡教授来拜访老苏。五十来岁的人,红光满面,沈非一见他就满心不喜欢,看看他的名片,放在桌上。
白教授喝茶、抽烟,然后开门见山,说自己也是“研究时间”的,慕名而来,请教几个问题。
老苏局促地说:“您是老前辈,我只不过对这个感兴趣而已,没什么研究……”
白教授从眼镜片后面看看老苏,说:“你太客气了,我听说你已经在做机器了。”
老苏说:“没有!就是想想。”
“那么,时间逆转是什么机理呢?”
老苏红了脸,说:“我还想不明白。”
白教授说:“你是内行,你知道个有‘外祖父悖论’……”
老苏还没说话,沈非插嘴道:“对不起,我是外行,您给我讲讲?”
白教授瞥他一眼,点点头说:“假如你,小伙子,假如你坐上一个时间机器,回到几十年前,你外祖父——就是姥爷,和你姥姥正在恋爱。如果你破坏了他们的恋爱,他们不结婚,就不会有你妈妈……”
沈非说:“也就不该有我?”
“对。”白教授权威地说,“可是你已经存在了,而且是你亲手破坏他们的婚姻——这怎么解释?”
沈非笑道:“我压根儿就不破坏,我最恨拆庙的。”
白教授也笑了,摇着一个手指头说:“年轻人,玩笑是玩笑,学术归学术。还有一个‘自杀悖论’,如果你回到二十年前,把小时候的你给杀掉了,那么,你在二十年前应该死了,不该再有二十年后的你——这又不可解释。”
沈非想了想,说:“所以我不当科学家——头疼!”
他自顾拿了一本小说,坐在旁边看。老苏和白教授就开始谈论。
老苏说:“我猜想,时间作为物质是存在的。它是一个概念,是物质演化、世界运行的先后顺序的度量。”
白教授说:“啊,这是我以前想过的,你仔细说说你的想法!”
老苏遇到知音,大为兴奋,并且,这是一个老前辈,把自己的猜想在这里证实一下有好处的。
他娓娓谈了一个多小时,拿了纸笔,画模型、做演算。最后,白教授说:“咱们想的差不多嘛。在空时连续统中,任何事情都是‘已经发生了’的。”
老苏说:“不知道。我们不能超越它去看,只能建立数学模型来演示。”
白教授想了一会儿,笑道:“和你聊天很受启发。能说说你设计的时间机器吗?”
老苏窘促地笑着说:“我还想不出怎么入手呢。”
白教授呵呵笑道:“年轻人精力充沛,有闯劲,总会想出办法的!”
过了不久,沈非气冲冲地回来,把一本杂志扔在桌上,说:“这个白世凡!老滑头!”
老苏拿起来一看,是《物理学报》,封面下角有一行字:白世凡教授谈时间机理,详见十八页。
沈非一屁股倒在沙发上说:“这明明是个老骗子,他把你说的那些都写在自己的文章里了。”
老苏翻看着杂志笑道:“文法错误这么多!物理学报也登这种文章?”
沈非哼哼地笑了笑,说:“这个白世凡,我得花番心思整治他。”
老苏笑道:“何必这么急呢,不值得。我跟你说,我想到了时间机器的原理。”
沈非皱着眉道:“别跟我讲,我不懂。”
老苏抓着他不放,硬是说了下去:“不用超光速,只要能量!要巨大的能量!逆转物质的运动。我只要再想一想,如何逆转?”
沈非说:“行!行!我脖子都快被你逆转了。你要我帮什么忙?”
老苏叹了气,说:“钱呀,还是没钱。如果有几十万块钱……”
沈非呆了一会儿,突然说:“咦?哪来的咸菜缸味儿?”吸着鼻子左右找寻了几下,“你!你快洗澡去!好家伙,有一个月没脱过衣服吧?”
老苏笑了,他知道沈非想让他放松一下。
脱了衣服,往浴缸里放水。老苏突然呆呆地盯住水面的旋涡,嘴里念念有词。
沈非在一边嘀咕:“快点儿,感冒了啊。”
老苏转过身来说:“旋转!……知道吗?从基本粒子到星系,万物都在旋转!”他兴奋地在屋里走来走去。
沈非说:“你有神经病啊?光着屁股满世界走!”硬把老苏拎进浴盆里。
老苏还是念叨着:“旋转,旋转……”用手在水里划着圈儿。
沈非一路摇着头走出去。
晚上,老苏已经画好了一张模型图,沈非坐在一边咬笔杆玩儿。
老苏忽然说:“你当一个月男保姆,也该回家了吧?”
沈非一愣,看着他说:“反正我回家也是一个人住……我其实是想省一点儿水电费!”
老苏笑道:“我知道你不放心我……”
沈非抬手止住他说:“别臭美啦。我愿意住这儿,谁也管不着。”
然后他穿好外衣,出门去散心。
沈非喜欢歌厅,时常还能上台唱两首。
今晚他几乎是下意识地走进去坐在一张桌边。他自觉满身疲倦,这些日子尽遇到不如意的事,让他烦闷不堪。
这副落落寡欢的样子,被邻座一位漂亮的青年女子发现。这样的一个人,生活优裕、安闲、无聊,她的同情心是过剩的,她的闲工夫也是无限的。她缺少的只是消遣的机会,而我们这位沈公子相貌不恶,甚至还颇为英俊。总之,那个女子就坐到沈非桌前,手托下颏瞅着他,低声问:
“怎么啦?”
沈非早年哄女孩子是拿手,看了看她,没一会儿工夫,就让这个温存的小妇人(她叫方婷)相信,她慧眼识英雄,发现了一位落难才子。这位不得志的年轻科学家(还挺精神),只要能借到一点钱(只是借),就可以实现他多年的夙愿:制造一台时间机器,在过去和未来之间随意旅行!不管信不信,她觉得新鲜刺激。
她快活地小声说:“我借给你呀,我有好几万块钱呢,本来想买衣服的。”
沈非笑笑说:“那不够。”
她又说:“我还有首饰呢。”
沈非又温和地笑了:“那是小姑娘的玩意儿。”他并不把这女子的话当真,只是开个玩笑罢了。
“那,”她指指右边一张桌子,一个四五十岁的男人和另一个较年轻的男子正在低声谈话,”瞧那个穿黑衣服的人,我帮你跟他借钱。我借多少他都给。”
沈非看了一眼问:“他是你爸爸?”
方婷捂着嘴乐:“不是,他是我老公。”
沈非不禁脸上发烧。方婷倒很大方,笑道:“没什么。咱们去找他。”
那边桌上,两个男人的声音低沉,但是互不相让地谈笑着。年轻的一个说:“老顾,这一次就恕我占先吧。”老的那个大度地笑一笑:“你突然买下这个厂,手头会紧一阵儿的。如果周旋不开,我可以帮你一把。”年轻的笑道:“谢了!我还行——瞧,你太太来了。”
方婷带着沈非坐在桌边,斯文地说:“这是我丈夫顾平,这位是余老板。这位是沈非,他是科学家。”
顾平应酬了几句,他不感兴趣。方婷每隔几天就会认识一个科学家、文学家、画家、音乐家,在他看来那都是混饭吃的,方婷也不过是闲得无聊拿他们开心而已。
余老板又坐了一会儿就走了。方婷喋喋不休,把时间机器的事儿讲给丈夫听。沈非有点儿疲倦,老想打呵欠。
顾平听完妻子有话,看着沈非说:“想法不错呀。我上学的时候也看过一篇小说,跟你这个差不多似的。”
沈非看得出他眼睛里尖锐、冷淡的讥嘲,一股怒气从他胸口升起来。他懒洋洋地一笑,说:
“你看不出来吧,我就是写小说的。”
顾平假装饶有兴味地问:“你的时间机器做出来之后,打算怎么用呢?”
沈非笑道:“我也要做个有钱的老板呀。你想想,一个商人利用时间可以怎么赚钱?这个顾老板最内行吧。”
方婷看着他们两个斗嘴,感到很有趣,在一旁左瞧一眼,右瞧一眼,宽容迁就地笑着。
顾平听了沈非最后一句话,心里一动。过了一秒钟,他笑道:“有意思!沈先生,这是我的名片,我们以后再谈。你可以打电话……”
沈非说:“这是我的名片——我另给你一个电话号码。如果你愿意谈,就打电话找我吧。”他把老苏家的电话写在名片上,然后对方婷点头笑笑,走了。
方婷歪头瞧着丈夫,笑道:“有意思吧?”
顾平淡淡地说:“新朋友交得真快啊。”他心里在想,如果……如果这是真的,那么姓余的那家厂子还可以抢在前头买过来,不仅如此,许多别的生意,许多别的事情……在他已经很少幻想的脑子里,一幅完全新鲜的、广阔无边的图景展现了。
不出沈非所料,第二天,顾平就打来了电话,说他对时间机器突然很感兴趣。沈非说了老苏家的地址,请他来谈。
顾平半小时后驱车赶到,沈非为他和老苏做了介绍。
顾平直率地对老苏说:“您不用客气,就当我是一个学生,仔细给我讲一讲时间机器。
好么?”
老苏铺开模型图,又说又比划,写写画画,讲了两个小时。顾平全神贯注地听完,沉默了一会儿,问:“您觉得做好这台机器,有几成把握。”
老苏说:“六成。”
顾平本想出五十万,立刻说:“这样吧,我出钱三十万。我觉得您讲得很透彻,我有信心。”
沈非和老苏对望一眼,顾平又说:“不过,咱们最好能订一个合同:这台机器造好之后,专利归我,我付给二位满意的报酬。”
老苏是无可无不可,沈非当然更不在乎,顾平当即打电话请公证人。他特意笑着又和沈非拉了拉手,说:“今天晚上我请你们两位吃饭!”
这下有钱了。这么快,这么容易,老苏竟不敢相信。他先打电话告诉高远,高远当然欣喜万分。老苏放下电话,就开列要采办的物品清单,自有顾平雇的人照单去买。
马局长几乎已经忘掉时间机器的事。他认为老苏是个异想天开、浮躁不踏实的年轻人,一时头脑发热,很快就会碰钉子。但他却听说,这个装病不上班的家伙已经弄到钱,开始造他的机器了。
局长不能坐视不管。这样下去,局里人人想出一个花花点子,就都能请个病假回家胡闹了!可他不知道怎么去管。请病假符合制度,钱也不是偷的抢的,他只有按老习惯给上级首长打个电话汇报。
丁首长比马局长年轻十岁,可看上去气派庄严得多,他思考问题也更加深谋远虑。所以,他立刻略去病假、借钱这些无关紧要的小事,看到了更重要的东西。如果万一那台机器造好了,那就是说,有人可以随意穿梭于过去和未来(他最担心的是“过去”),会发现不该看到的事情,会改变不应更改的历史。“流逝”和“遗忘”给予人们的安全感将不复破在,沉重严密的帐幕将被掀开——如果有人利用时间旅行来搞什么破坏,别人是无能为力的。
丁首长在一个较阴冷的宁静的下午,亲自探访了老苏那个五十平方米的家。一个年轻雇员开门,引他进屋。他看见最大的一间屋子作了实验室,堆满各式各样的管子、电线、钢架和不知名的球形玻璃罩。老苏站在杂物堆中间,满脸胡子,有点吃惊的样子,木讷地望着丁首长。他从未见过此人,这个人风度端庄而凝重,又亲切又严肃,老苏感到一丝不安。
沈非不在这儿,老苏就觉得没有主心骨儿似的,连倒茶都不知道。丁首长温和地作了自我介绍,并且说明来意。当然,自己下属的开发局里有老苏这样独一无二的人才,他是应当注意的,对老苏的“慢性肾炎”他也十分关切。“你愿意的话,”丁首长说,“我可以安排你去疗养,或者……你还可以去国外治病。”
老苏的脸红了,但他不敢说装病的事,他支吾着说:“我没什么,谢谢您……我得搞成这台机器。”
一听到“机器”,丁首长的眉毛轻轻挑了一挑,看着老苏说:“你说的这台机器,真的有把握造好么?”
老苏兴奋地点点头。
丁首长站起来,踱了几步,又坐下,眼睛看着远处,似乎在自言自语地说:“你的才能,为什么不用在国家更需要的地方,用在更能立竿见影、改善社会的方面?”他转头看着老苏,“我在各部门认识很多朋友,说一句话还是有些份量的——我提拔你作负责开发新能源的处长。”
老苏不懂,他张着两眼说:“我不太懂能源,而且,我也不能当官儿,我不行。”
丁首长摆手一笑,道:“把你的潜力都发挥出来吧!我对你有信心——这台机器,你是怎么想的?造出来有什么用?能创造多少价值呢?”
老苏呆住了,他想了一会儿,说:“我没想过,我觉得应该造它。”
丁首长哈哈地笑了,轻拍沙发的扶手说:“一个科学家,负有引导文明前进,造福人类的伟大使命,像你这样儿戏,岂止可笑,简直是犯罪了——想想现在,全国有多少人在挨饿,每年有多少房屋被风和洪水推倒,有多少田地沙化,每一年全国用电有多大的缺口?你很幸运有这么好的天赋,又受过国家高等教育,这正是有志男儿报效祖国的时候。”他不再说了,只是期待地、咄咄逼人地看着老苏。
老苏一时间如坐针毡,他在丁首长的目光中败下阵来——他理亏,他辞穷,他突然扪心自问,竟然汗流浃背。
“放弃你这台没用的机器吧。”丁首长温和地命令,“国家需要你的天才!”他感觉自己已经胜利了,把这个年轻人拿下来了。
老苏艰难地抬起眼睛,低声说:“我……我除了这台机器,就没想过别的。如果造不出来,我这一辈子就白活啦,就什么也没干。您说的都对,我是个废物……我只有对不起您,对不起国家了!”
丁首长愣了一下,问:“你说什么?”
“我现在只能造这台机器,我满脑子都是它。”
丁首长柔声问:“只能这样?”
“只能这样。”
丁首长仰天长叹:“又一个!又一个人才毁了!”
老苏听到“又一个”,感觉有些奇怪。丁首长闭起双目说:“像你这样的人才,如果钻了牛角尖儿,你不知道有多危险!——十几年前,我认识一个年轻人,聪明,有活力,二十七八岁,风华正茂啊。头脑灵活,却走进死胡同里,非要发明一个‘记忆再现机’不可,谁劝也不听。这本来就是一件无用之物,而且记忆这个东西,世界上多少年来都研究不透的。这个年轻人一钻进去,就是整整四年,也不知吃了多少苦,后来,他疯了!”
老苏全身一颤。
丁首长说:“你真敢保证,你对‘时间’就研究得那么透彻,可以玩弄于股掌之上么?
你也会碰到很多麻烦的。”
老苏心里渐渐发冷。看着面前的这个长者,他不禁产生了一种惧意。
他暗暗地咬咬牙,低声说:“多麻烦我也干。”
丁首长走后,老苏独自发了一会儿愣,突然端起身边的水杯,喘着粗气,像骆驼一样饮着……
第二天,老苏发现麻烦真的来了,局里医务室的几个医生上门为他检查身体。
老苏觉得要露馅了,可是医生说,他真的有病,很严重的慢性病,局里要他立刻进局属医院休养。
这比露馅更糟!老苏明白知道自己的身子其实像匹马一样结实——他们不想让他造完这台机器!
他求助地看着沈非。
沈非问医生:“如果老苏辞职了,你们还管得着他么?”
老苏惊道:“辞职?”
沈非瞪着眼睛吼:“辞职!还恋着那儿的什么?”
大夫们走了。
老苏辞了职,现在他真正是谁也管不着了。
一连几天老苏心绪低落,神情恍惚,几乎无法继续工作。
居委会万大妈(就是笑话中画箭头引导老苏重归故里的那位),三番五次找上门来,代表邻居们提意见,说这里声音太大太乱,而且时不时散放出一些怪味,算不算污染?老苏无言以对,沈非对老太太没招儿。顾平赶忙赠送街道俱乐部一张乒乓球桌,以及围棋、象棋、扑克牌等,并向老年俱乐部捐赠一台电视机,总算把这事平息了。
可是,老苏的家成了邻居们好奇心的焦点,各种望远镜对准他的窗户,窗下有徘徊不去的行人。万大妈低声向人们介绍,说老苏和沈非,一个大胡子,一个小白脸,一天到晚窝在那屋子里,不知搞些什么名堂。
老苏变得很敏感,看到窗子对面的望远镜,他就想把窗帘挂严。
沈非可不,他站在窗口让人家看,突然也抄起一只大号俄罗斯望远镜,举在眼前。看见对面一个方头硕脸的汉子,龇着两大牙正傻笑。那人一惊,忙缩回头去。沈非拿张白纸用红墨水写一行大字:“看够了没有?”贴在窗外。过一会儿,望远镜又伸出来,对着红字一照,缩了回去。沈非意犹未尽,又添写一行。那汉子实在好奇,举镜一看,含混地骂了一声,“砰”地猛摔一下窗户,不再露头了。老苏揭下白纸,见写的是:“刷刷你的黄板儿牙!”他不禁哈哈大笑,一舒闷气。
麻烦是每天都有的。房管所的人又来检修管道,邻居也常常不请自到。某个晚上,窗玻璃被人砸破,一块石头险些砸在机器上。老苏大为惶恐。
更可怕的是,“街道老年秧歌队”成立了,每天上午,就在老苏睡意最浓的时候,锣鼓声骤起,一群老同志兴高采烈地扭着。
顾平带了方婷来到这了解进展情况,老苏眼眶深陷,坐在床边。沈非一指窗外,说:“你瞧,外面这么闹,叫人怎么安心工作,怎么休息?”
顾平早已憋了一肚子火,盯着对面的望远镜,恨恨骂道:“混蛋!”他喘了口气:“我在东郊有一处新厂房,安安静静,四五里地没人烟。你们都搬去!好好地干。妈的!今天就搬!”
搬到东郊,石房宽敞,安静。老苏觉得舒服了许多,可是又有新的麻烦:买不到零部件。
机器的重要部分,需要加速器、能量放大器,只有部里直属的公司才有货。派去采购的人说,人家不肯卖,只说是脱销了。
老苏急得像热锅上的蚂蚁。到后来,只能买了零件,自己一点一点组装,而零件也买不全!采购员从一些大实验室买来许多旧件、次品,经过挑选凑合着用。
老苏的状况越来越让人担心。他时常呆怔怔地坐着,对着机器傻看,又好像在倾听着什么似的。一点儿响动会吓他一跳,被惊醒了一般茫然四顾。工作起来,他的效率越来越低,手掌不由自主地发抖,拧不好螺钉,接不准线头。
他的脾气也越来越坏,看着工作进度变慢,他常常无端地发火——他只冲自己发火,打自己的头,抓头发,嘴里恨恨地自言自语,一点点小事都会让他烦躁不安。
他上火了,头顶长了一个小脓包,这更让他烦恼——他从没想到,一个米粒大的小包会搅得人吃不好,睡不着,针刺一般的痛,顺着神经,电一样从头顶、后脑传到脖子根。
沈非有时候用担忧的目光看着老苏,他帮不上忙。
一天晚上,一个雇员打碎了一块玻璃板,老苏彻底发作了。他冲屋里所有的人吼叫:“滚,都滚!”沈非在他背后,把一个手指竖在唇边,示意大家安静,不要刺激他。老苏脖子上的青筋胀着,脑门通红,嘶哑着嗓子叫嚷:“没一个管用的人!我也没用!都他妈的给我捣乱!你们砸!都砸了!砸碎了你们好高兴。谁怕谁?我今天就撒泼了!都给我滚!”
他歇斯底里地发作了好一阵,大家默默地退出去。老苏低头说:“沈非留下!”
沈非关了门,走到他身边。老苏忽地趴在桌上,嚎啕大哭起来。
沈非笑了,无声地笑了。拍了拍老苏的肩背,小声说:“你这家伙!你也有撒泼的时候啦!”
老苏哭着说:“我真没用!我真没用!我是个废物!”沈非不说话,让他一个人念叨。
过了一阵,老苏好了。拿条毛巾,擦把脸,擤擤鼻涕,又喝了几口水,看着沈非,低声说:
“对不起!”
沈非笑道:“怎么了?该发脾气就发嘛,还跟我客气什么?”
老苏说:“这几个月,都是你在替我忙来忙去,照应这些事儿。我不该冲你发火。”
沈非说:“你说错了,你有脾气最好冲我发,因为我不在乎。”
老苏长长叹了口气,靠在椅子上,说:“我累,我烦!”
沈非说:“喂,不行就别干了。”
老苏说:“那不成,你也知道,我这一辈子就这么件事儿。如果造不成这台机器,我就白过了,我就……我就什么都不是,我必须干。”
沈非说:“那就干!还有,肚子里有气就发出来,发发脾气无伤大雅。冲身边儿的人,冲一棵树,冲一件儿东西,心里的火儿散出来,吃得香,睡得好。”
老苏点点头,说:“咱们出去走走。”
在外面散步的时候,沈非有点担心地看着老苏,发现他的郁闷并未消散。
“好久没看见月亮了!”老苏坐在一块石头上说。他游目远处的灯火,天边似乎有一片流动的光明,向上渐渐融化,变为幽蓝,最后消失在天顶黑幽幽的幕布里。风清月明,他感觉如此良辰都是属于别人的,属于在家里读书看电视抱孩子的幸福人们的,不是他的,但他仍深深地感动着、留恋着。
沈非说:“哎!你怎么了?”
老苏一笑,说:“沈非,我老像听见耳朵边上有一只秒表,嘀答嘀答地响,一秒也不停。我感觉世界也像一个人似的,他在长,在长大,在衰老,和我一样……”
沈非看他一眼,说:“你老了么?那赶快娶媳妇儿,生儿子,别绝了香烟后代。”
老苏疲倦地笑笑:“我的精力都耗尽了,我的血气也流光了,就剩这个干壳儿——还有个小脓包!这个包和那些杂事让我烦透了。”他忽然一惊,神经质地看看四周,说,“咱们回去吧!我得把这事儿干完,要不就没时间了。”
沈非越来越担心,跟着老苏回厂房。他想,过几天无论如何得强制老苏歇下来。
又过了一个月,“时间机器”居然做成了。
老苏用一些小动物做实验,让它们回到一年前、两年前,小动物一一在机器里消失无踪。
沈非好奇地问:“它们真的回到过去了么?”老苏说:“这是肯定的,我这台机器的原理无懈可击。”
他给高远打了个电话,并约顾平也来,他决定亲自做一次时间旅行,验证他的理论。
这一天在沈非眼里是最明朗的日子,他穿得里外一新,并把老苏也打扮好了。但老苏有些紧张,笨手笨脚地刮脸,弄破了两处。他们的客人都怀着各自的一份心情,陆续进了这间不同寻常的大厅。
高远微显激动,顾平踌躇满志,方婷兴奋好奇。马局长和丁首长也到了,沉稳地坐在两张大椅子里。白世凡教授穿着合体的西服,站在机器边摸这儿摸那儿,虔诚得好笑。十几个雇员排在两旁,穿着黑西装。
老苏喝了一大杯水,脸有点儿发红,他见了这么多人,不知道如何开场。
沈非抱过一只小猫,打开机盖丢进去,按下启动钮。透过茶色玻璃罩,人们似乎看到里面的一个东西在急速旋转。过了一会儿,旁边的散热孔里冒出一些热气。
当绿灯亮起时,机器停了,沈非掀开机盖——小猫不见了。
众人大为惊叹。丁首长笑着说:“这是魔术嘛!谁知道小猫儿在哪儿?”马局长点头附和。
老苏说:“它超越了时间,回到一年前了!这是确定无疑的!我的机器我知道。不信,咱们再做一遍,这次用往返程序——我呆一会儿也要用往返程序,否则就是单程旅行回不来了。”他在一个小键盘上按了几下。
一阵旋动后,大家透过玻璃盖,看到里面空空如也。过了一瞬间,机器又嗡嗡作响起来,机盖再次掀开时,小猫又在里面叫了。
老苏说:“如果它是人,就会说出刚才的感觉,不过,这样不叫时间旅行,过一会儿我要用另一种程序:我让程序运行到目的坐标就停转,然后我就可以在‘过去’有两个小时的自由时间,两个小时后回到原地点,程序又会把我带回来——对你们来说,你们只看见机器转了一次,只不过一会儿工夫——可我却已经老了两个小时!”
沈非拍拍机身,对老苏说:“老苏,请给大家简单介绍一下,不用说什么理论知识。这儿没几个人懂,我就不懂。”他看看两个首长和白教授。
老苏又喝了点儿。他摸着机盖说:“这个机器的原理很简单,嗯,那个……我先说说时间吧。简单地说,时间本身不是什么物质,它不存在,它是我们造出来的一个词儿。嗯……因为所有物质的运动都遵循一定的秩序,如果把这种秩序逆转,就像让河水倒流一样,让物质逆向运动,就是我们说的‘回到昨天’了。这需要很多的能量,所以我用这么大的电动机,它的能量是够把一个物体'抛'回到过去。对了,这台机器还只能输送生物,别的东西不行。所以,我呆会儿要脱衣服——对不起。”
沈非说:“老苏要做时间旅行,验证他自己的理论。”
高远一直没作声,忽然说:“老苏,你记得咱们想过:不能单独逆转一条世界线。”
老苏笑道:“那错了!这不是逆转,这是‘弯转’!”高远皱皱眉。老苏掀开机盖,抬高腿爬进去,站在里面的工作台上,说:“操作系统是两套同步的,外面一套,里面一套。”他弯下身子,脱鞋,脱衣服,机舱把半身挡住了,他不用担心女客会看见。方婷一笑。
衣服都扔了出来,老苏不知是冷还是紧张,身子抖了一下,说:“外面那个红钮是急停钮,直接控制加速器。如果有什么不对就按它!”
高远说:“会出故障么?”
沈非说:“加速器是用旧件组装的——人家不肯卖给我们!”高远点点头。
老苏探出半个身子说:“高远,这儿就你懂行了。万一有什么,你就急停……对了!我的笔记本在那个抽屉里!”高远把它拿出来,老苏说:“我送给你。”高远看了他一眼,翻翻那个厚本子。
沈非突然满手冷汗,说:“喂!”老苏扭头看他,两个人对望了一会儿,老苏点点头。
沈非说:“你不能先作一次短的?比如说,一天以前?”可怜的沈非,他以为“一天”的时间间隔比较短,就比较安全似的。
老苏说:“一天也好。我回到昨天,做一个小小的实验……”他若有所思地,“看看历史能不能改变?”
他关了机盖,一瞬间,时间机器启动了,里面在飞旋,散热孔冒出白气。
众人都眼巴巴地盯着看。
不一会儿,机器的“嗡嗡”轻响停息了,沈非一步纵过去把机盖拉开。
老苏还站在里面!
沈非抓着他的胳膊,说:“你怎么样?没事吧?”白世凡跑过来问:“你看见什么了?”
大家都关注着。
老苏茫然搔了搔头,说:“我……我没动!我一点儿没动!”
丁首长在大椅子里吁了口气,说:“哎呀,弄得我蛮紧张!”顾平瞥他一眼。
沈非说:“不行就算了吧,别硬干。”
老苏摸着脸说:“不对!我一定‘曾经’回到过昨天!你瞧,我早上刮破的那两道伤已经好了。”
大家沉吟,白世凡冒失地说:“你弄反了!你提前到了明天!所以伤口好了!”
老苏没理他说:“再试一次!一年!”他关了舱盖。
沈非想说什么,没来得及,大家都沉默着,大房间里只有机器的“嗡嗡”声。高远翻开那个笔记本看着。
这一次运行时间较长,而且,众人渐渐觉得身上热起来,也许是那个巨大的电动机散热过多,沈非用袖子抹着额头上的汗,两眼盯着机器。除了他以外,最紧张的就是顾平了,机器可以说是属于他的!方婷只是好奇。高远一页一页地看笔记,白世凡倒像是老天真似的,表情生动。丁、马二首长只远远地坐着喝茶。
时间机器又一次停转了。
老苏自己从里面推开机盖,满脸汗水地连连摇头。
沈非关切地说:“怎么了?”
老苏痛苦地摆手:“还是没动!还是没动!”
顾平忧形于色,问:“机器有毛病吗?”
沈非建议停止实验,老苏咬咬牙说,说:“不行,我不能再等了。必须做!”他默默地心算了一会儿,“一定是标准能级调整失准,运行角度有误差。只能加大跨度,一百年!”
沈非咧嘴叫:“一百年呀!喂……”老苏“砰”地合了盖子。
机器又运转起来。
高远突然大叫一声,一步蹿到机器前,伸手按了“急停钮”!
没有用!又按一下,电钮放出几个电火花。高远忽然暴怒,骂道:“废品!废品!”用拳头连连捶击那个报废的电钮。
沈非脸色苍白,抓住高远的手,急问:“你干嘛?”
众人都围了过来。
高远喃喃地说:“没用了,没用了!你们瞧吧。”
大家面面相觑,一言不发。屋子里越来越热,所有窗户都打开了,散热孔中冒出了白雾,浓如牛奶,高远额头的汗水一滴滴流到脸上。沈非吓傻了,四肢麻木。
良久,一切都停止了,浓雾开始渐渐散开。
沈非扑上机器,掀开舱盖。
这一回,里面真是什么也没有了,众人一齐低低地“啊”了一声。
沈非扭过头,看着高远。
高远已恢复平静,他低声说:“完了!”
“什么完了?”沈非吼道。
高远摇摇头:“老苏回不来了。我刚才翻他的笔记本,看见这句话,想了好一阵儿,突然明白过来,已经晚了。”他举着那个本子,扉页上,老苏写着两行字:“世界在流动,世界在生长!”
沈非急头急脸地说:“你说明白点儿成不成?”
高远说:“老苏的理论是对的:时间不存在,时间旅行就是逆转物质的运动,可是他的实验做反了。以往,我们都认为,在‘空时连续统’中,所有的事件都是固定的,可以乘坐时间机器去各个坐标点游览。其实,世界在流动,在生长,'过去'不会停在原地等你,它已经不存在了。而‘未来’还没有发生,实有的只是‘现在’。”
沈非说:“这是什么意思?”
高远说:“世界也在生长。如果你想回到过去,就必须制造一台无比巨大的机器,把全世界都装进去,使它的运动逆转,而你自己却不能进入。这样你才能看到世界过去的样子!这实际上是让整个世界返老还童,而你自己不能动!”
白世凡说:“有理!有理!”沈非一把推开他,问高远:“你只说老苏怎么样了?”
高远说:“他的这台机器,原理也是逆转物体的运动规律,使一件东西‘回到过去’,但是,是另一种‘回到过去’。它是一台返老还童机!”
沈非叫了一声,众人也都以不同的表情轻轻叫了一声!
高远继续说道:“老苏回到一百年前了!他的生长过程全部逆转,他没了。”
“这不是往返程序吗?”沈非暴怒地揪住高远的衣襟,“他还能不能回来?你说!你说呀?”
高远慢慢推开他的手说:“不行了!程序运行得太远,他连一个受精卵细胞都没留下。”
沈非猛踢了一脚机器,顾平叫道:“别踢坏了!”沈非瞪他一眼,白世凡以纯粹学术讨论的口气尖声道:“不对啊!小苏在第一、二次实验以后,按理说,应该有丧失记忆的现象。还老还童么,年轻一岁,这一年的记忆应该丢掉了。”
丁首长抢嘴说:“谁也弄不明白记忆的原理。”
沈非什么也听不见了,呆望着机器,手脚冰凉。
这实验毕竟成功了一半!不少人都这么想,至少,这是一个有用的机器!大家的心突然兴奋地跳起来:返老还童!
马局长心想:“我局里毕竟出了这么大成果!这是别的单位从没有过的。老马呀老马,你多少年没这么振奋了!”
方婷真的惊呆了,她兴奋得抓着丈夫的胳膊:从没见过这种事,甚至是闻所未闻!一个人乘坐时间机器,回不来了!简直是平庸的都市生活中的一个传奇故事。她心想:“我都可以写小说了。”
丁首长清清喉咙,说:“嗯,我说两句,这台机器是没有做成功,而且是很危险的一件东西,我们不应该把它留在这儿危害社会——一不小心,就会有人牺牲。我建议,由我把它带回去,由一小部分专家进行研究完善。还有,大家对这件事要严格保密,不要传得满城风雨,好不好?”
顾平说:“您说错了。不管这台机器好不好,它是我的!我这儿有经过合法公证的合同!
别人无权处理。”
丁首长深深凝视顾平,然后笑道:“顾先生,我们好好谈谈,这件事儿是挺复杂,挺麻烦的!牵扯到很多方面……”他拉着顾平的手,让他坐到远处沙发上。
白世凡已经向高远提了好几个问题,十几位雇员围在他们身边听着。
“悖论之所以出现,是因为我们在下意识里把时间当作一种不可逆转的物质流,其实时间只是一种度量,不是物质本身。如果宇宙是个大舞台,那只有物质是主角,时间只是情节。”
白世凡谦恭地问:“那,外祖父悖论怎么解释?”
高远微笑说:“西方科学家把原理弄复杂了,加入什么平行的‘贝贝宇宙’来解释,其实完全不必要。你可以破坏你姥姥、姥爷的婚事,你母亲也可以不出世。”
白世凡瞪着白果眼说:“可是,我怎么会出世呢?”
高远说:“你在做时间旅行的时候,让整个世界返回了过去,可是你自己没有动,你是原有世界在反转之前的那次运行的产物。你破坏了婚姻之后,世界又按另一种‘情节’运行了一次,可是你不需要再次出生呀。”
“这么说历史可以改变吗?”
“当然了,世界在生长。让它返老还童一次,再重新生长,里面就有无数偶然事件发生。”
白世凡搔搔头,恍然大悟,笑道:“那,‘自杀悖论’呢?”
高远轻“哼”一声,说:“这更简单。你不会看到小时候的‘你’,因为在世界反转运行时你已经跳出来了,那个世界里没有你。在宇宙中每个物体都是独一无二的,什么‘贝贝宇宙’,什么‘平行世界’并不存在。不论过去、现在、将来,都只有一个你。”
众人这下都明白了。白世凡也大喜,连连点头。
高远有点嘲笑地说:“白教授,回去会不会再写一篇论文哪?别忘了顺便署上我的名字。”白世凡谦逊地笑着说:“那当然!那当然!”
沈非握紧拳头呆立着,也不知在想什么。这时候,丁首长和顾平舌战方酣;方婷出神地幻想着,白世凡往一个小本上写着什么,一帮雇员在整理大房间中杂乱的仪器。
——一切都过去了!
高远心想:“时间旅行是不可能的么?不!老苏把笔记本给我是有道理的,我比他年轻,比他冷静……我想想,也许,这台机器再加一个同步反转仪器,和外界形成共轭系统,那么用不了多少能量……”一丝微笑绽现在他冷峻的嘴角,他想,“让我重新开始吧!老苏死得可惜!……”
(完)
```
Matrix 精选**
[Matrix](https://sspai.com/matrix) 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。
文章代表作者个人观点,少数派仅对标题和排版略作修改。
```
[Obsidian](https://obsidian.md) 是一款非常优秀的「现代化」笔记管理工具,因其快速的功能迭代和优秀社区活跃度,成为了近期较为热门的笔记软件之一。个人经过一段时间的使用和体验,认为 Obsidian 已经具备了成为「主力笔记管理软件」的能力,并陆续将自己的笔记迁移到 Obsidian 上进行管理。
Obsidian 和其他常见的「笔记软件」有什么不同,它具备哪些优势,以及想要用好 Obsidian 有哪些「方法论」,我在上一篇文章《[玩转 Obsidian | 打造知识循环利器](https://sspai.com/post/62414)》中有过详细的阐述,感兴趣的同学可以先翻过去了解一下。
由于后续我打算持续更新「玩转 Obsidian」系列文章,所以迫切需要一篇「关于基础设置和使用介绍」的入门级介绍文章,于是有了本篇。
碍于篇幅,我不可能将所有的功能都罗列出来,本篇「**只适用于快速上手体验**」,文中介绍的是个人认为比较重要的设定和使用方法。如果想了解 Obsidian 的所有功能特点,Obsidian 官方非常贴心的提供了帮助文档《[Obsidian Help](https://publish.obsidian.md/help/Index)》,同时为了方便大家进行「交互式」体验其功能,Obsidian 还内置了「Obsidian Help」仓库,并且以上两个文档都会得到官方的持续更新,大家可以选择任意方式进行阅读。
PS:本篇文章基于 Obsidian `v0.9.10` 版本。
Obsidian 的基本使用
--------------
大家可以去 [Obsidian 官网](https://obsidian.md)下载对应的客户端,由于使用了跨平台的「前端技术」,Obsidian 同时支持多个「桌面平台」的使用,当你安装好 Obsidian 后,我们就可以简单的设置并使用它写笔记。
### 新建仓库
Obsidian 支持「仓库」概念,我们可以将自己的「个人笔记」和「工作笔记」创建不同的仓库,这样他们之间的内容互不影响,当然一切都是自由的,你可以任意创建属于自己的「仓库」。
新建仓库
PS:如果我们设置仓库的存储目录为「云盘」的时候,Obsidian 就具备了「云同步」的能力。
云端管理
### Obsidian 的基本布局
Obsidian 的布局比较直观,如下图一些基本的操作和入口我已经标注出来,这里大家只需要做下了解:
基本布局
### 新建笔记
Obsidian 支持多种创建笔记方式,最简单的就是使用快捷键「CMD + N」,也可以在「资源管理面板」中点击「新建笔记」按钮。
新建笔记
通用设置
----
以下将介绍 Obsidian 的通用设置,包括主题设置、标签管理、编辑模式 VS 预览模式、命令模式、工作区管理等。
### 主题设置
由于 Obsidian 使用了前端技术,理论上通过 CSS 技术可以实现各种样式和布局,在 Obsidian 中设置「样式」也非常简单。
第一步,开启「自定义主题」插件:

第二步,选择符合自己的主题:

PS:作者使用的主题是「[Pisum](https://github.com/GuangluWu/obsidian-pisum)」,如果打不开「主题样式」列表,可能遇到了不可翻越的墙,可以去 Github 搜索「Obsidian」关键字查找。
### 附件存储设置
Obsidian 支持在笔记中插入图片和音频等「附件」,为了方便管理我们的仓库,可以单独设置「附件」的存储目录,这样就不会和文件都散落在仓库中。
附件存储
### 标签管理
Obsidian 支持标签管理,如果需要使用首先要开启「标签面板」。
标签管理
当我们在文章任意地方通过 `#标签名称` 插入标签后,就可以在「标签面板」中看到所有仓库中的标签。
标签使用
### 编辑模式 VS 预览模式
编辑模式,指的是在 Obsidian 中新建或打开笔记时,笔记处于「编辑」状态,此时我们可以直接输入 Markdown 语法进行编辑。
由于 Obsidian 不支持「所见即所得」的编辑模式,所以我们需要进入「预览模式」才可以看到我们笔记真实的样式,下图中可以看到他们的对比:

进入「预览模式」的方式常见的几种如下:
通过快捷键切换 CMD + E 菜单栏按钮切换
PS: 点击上图按钮时如果同时按下 CMD 键,会在右边打开新的笔记面板展示「预览模式」。
### 命令模式
Obsidian 也向大多数智能笔记工具一样具备「命令模式」,同样使用「CMD + P」打开命令面板,从中可以选择各种命令,如果想要查看各种命令的中文名称,可以去「仓库管理面板」切换到「中文」查看:

工作区管理
-----
工作区指的是,Obsidian 会把当前打开的多个「笔记页」、「右侧扩展区域」和「Backlinks For XXX」等全部面板的「加载打开」状态等当做一个「工作区」。我们可以任意保存和加载工作区。
工作区带来的好处,当我们同时处理各种笔记的时候,具备了「一键还原现场」的能力,方便我们快速进入「心流状态」,避免我们被各种事情所打扰,迟迟不能进入状态。
使用工作区的话,首先开启「Workspaces」插件,就可以看到「工作区」操作入口了,如图:
工作区管理
**保存「工作区」:**我们可以在 Obsidian 的任意界面,点击上图中「工作区操作入口」的按钮,打开「工作区管理面板」进行保存:

**加载「工作区」:**我们可以在 Obsidian 的任意界面点击上图中「工作区操作入口」的按钮,打开「工作区管理面板」进行加载操作:

模板输入
----
在使用笔记的过程中经常会遇到需要重复输入的内容,比如会议纪要的模板,此时我们可以使用 Obsidian 的「模板输入」功能,创建好「模板」后,就可以是实现「快速输入模板」的能力,具体操作如下:
1. 开启模板插件:

2. 设置模板目录和格式:

3. 创建模板文件:

4. 使用模板:

超链接使用
-----
Obsidian 支持多种「超链接语法」,这些功能也是「现代笔记管理」的必备技能。几种常见的语法如下:
* 双向链接:`[[Note Name]]`
* 话题引用:`[[Note Name #header]]`
* 别名引用:`[[Note Name |Alias]]`
* 嵌入引用:`![[Note Name]]`
* 块引用:`[[Note Name ^]]`
### 超链接语法 - 双向链接
「双向链接」的语法为`[[Note Name]]`,在前文中已经简单介绍过它的使用,下边是关于「双向链接」的详细介绍。
「双向链接」指的是在笔记 A 中通过输入 `[[笔记 B]]` 后,使得笔记 A 和笔记 B 建立了链接关系,如下:
在笔记 A 中可以看到它和 `[[笔记 B]]` 有关系,同时在笔记 A 的「预览模式」下,鼠标经过`[[笔记 B]]` 时,可以弹出笔记 B 的「缩略视图」,同时点击 `[[笔记 B]]` 后也可以打开笔记 B 的编辑页面。

PS:想要看到笔记 B 的「缩略视图」需要开启「Page Preview」插件。

在笔记 B 中可以通过「Backlinks For 笔记 B」看到都有哪些笔记和自己建立过「双向链接」。

PS:「Backlinks For 笔记 B」的打开方式常用的方法有两种,通过快捷键或者菜单按钮。

### 超链接语法 - 话题引用
在 Obsidian 中,由于 Obsidian 支持 Markdown 标记,我把用 `#` 标记的内容称为「话题」,如下图,「### English」和「### Chinese」就是两个「话题」:

话题引用的语法是`[[Note Name #header]]`,即在使用「双向链接」的时候,我们可以在输入的「笔记名称」后边输入笔记中的「话题」,这种「双向链接」的添加方式称为「话题引用」如图:

「话题引用」带来的好处是,当我们在「预览模式」下,鼠标经过「双向链接」时,弹出的「缩略视图」中只展示 `#话题` 所包含的内容(最新版本不再展示全文),并且点击「双向链接」也会直接跳转到对应的话题所在行。

### 超链接语法 - 别名引用
别名引用的语法是`[[Note Name | Alias]]`,即在使用「双向链接」的时候,我们可以在输入的「笔记名称」后边输入一个「别名」,这种「双向链接」的添加方式称为「别名引用」。

别名引用带来的好处是,可以更准确的「表述」我们在原笔记中输入「双向链接」时想表达的意思。
### 超链接语法 - 嵌入引用
嵌入引用的语法`![[Note Name]]`,即在使用「双向链接」的时候,我们可以在「双向链接」前边输入一个`!`(叹号),这种「双向链接」的添加方式称为「嵌入引用」。

嵌入引用带来的好处是,我们无需跳转,直接在原笔记中查看到被引入的「新笔记」。
### 超链接语法 - 块引用
块引用的语法 `[[Note Name ^]]` ,既在使用「双向链接」的时候,我们可以在「双向链接」的后边输入 `^` ,此时我们可以将被链接的笔记中的某一行(包括它的从属段落)引入到当前笔记中。这种方式成为「块引用」。
块引用带来的好处是,我们可以将一篇笔记中的「某个段落」引入到当前笔记中,结合「别名引用」更容易帮我们表达它的意思,如图:

总结
--
本篇作为「玩转 Obsidian」的基础入门介绍,希望能够让更多的人认识并使用它,也是得力于开发者持续不断的迭代更新,我个人非常喜欢 Obsidian ,并打算长期使用并体验,后续会我也会持续更新「玩转 Obsidian」系列文章,也欢迎大家持续关注。
「玩转」系列是王掌柜长期更新的关于「软件和服务」的使用体验,感谢大家阅读,相关推荐:
* [玩转 Obsidian | 打造知识循环利器](https://sspai.com/post/62414)
* [玩转 Agenda | 包办你的 work task](https://sspai.com/post/53310)
* [王掌柜带你玩转 Drafts5 | Writing Flow](https://sspai.com/post/46893)
* [王掌柜带你玩转 Drafts 5 | 预热篇](https://sspai.com/post/44671)
* [玩转 Todoist | 过滤技巧篇](https://sspai.com/post/44565)
* [玩转 IFTTT,互联网自动化也可以很简单](https://sspai.com/post/43731)
* [王掌柜带你玩转 Zapier - Zapier vs. IFTTT](https://sspai.com/post/39258)
* [王掌柜带你玩转 Zapier - 阅读自动化](https://sspai.com/post/39254)
* [王掌柜带你玩转 Zapier - 影评自动化](https://sspai.com/post/38989)
* [王掌柜带你玩转 Zapier - 读书笔记自动化](https://sspai.com/post/41838)
* [王掌柜带你玩转 Workflow - 进阶模板篇](https://sspai.com/post/38706)
* [王掌柜带你玩转 Workflow - 极客模板篇](https://sspai.com/post/38701)
* [玩转 Workflow - 一个极客文艺青年的观影之旅](https://sspai.com/post/38511)
* [王掌柜带你玩转 Workflow - 生产力模板篇](https://sspai.com/post/38582)
> 下载少数派 [客户端](https://sspai.com/page/client)、关注 [少数派公众号](https://sspai.com/s/J71e),让智能设备为你所用 💪
> 特惠、好用的硬件产品,尽在 [少数派 sspai 官方店铺](https://shop549593764.taobao.com/?spm=a230r.7195193.1997079397.2.2ddc7e0bPqKQHc) 🛒
汪曾祺(1920年3月5日-1997年5月16日),男,江苏高邮人。中国当代作家、散文家、戏剧家。以短篇小说和散文闻名。被视为京派作家,亦被视为里下河文学流派的创始人,被誉为是“中国最后一个纯粹的文人”,“中国最后一个士大夫”。
评价
汪曾祺在创作上主张回到现实主义、表现民族传统、表达纯真、自然的情感。他的小说大都取材民情风俗、日常生活,语言自然、活泼;文风清新、质朴;意境优雅、唯美。他的散文刻画民俗、民风,形象、生动,蕴涵着对民族文化传统的深切情感。他说,“风俗是一个民族集体创作的抒情诗,它反映了一个地方的人民对生活的挚爱,对活着所感到的欢愉”。他的作品对乡土文学、寻根文学有很大影响。他的代表作,短篇小说《受戒》和《大淖记事》,开创了“80年代中国小说新格局”。
汪曾祺一生经历了无数苦难和挫折,受过各种不公正待遇,尽管如此,他始终保持平静旷达的心态,并且创造了积极乐观诗意的文学人生。贾平凹在一首诗中这样评价汪曾祺:“是一文狐,修炼成老精”
王小波(1952年5月13日-1997年4月11日),北京人,中华人民共和国著名作家。
!! 作品风格
王小波在白话文叙述方面有很深的造诣,写作小说的同时他也创作过一些杂文与随笔文章。并且很多人都是由于精彩而睿智的杂文作品接触和认识到王小波。王小波的东西方生活与求学经历,使他成为一个富有自由人文精神和独立知识分子品格的写作者。在写给其老师许倬云的信中,王小波也表示他尝试着不裸露却引人入胜地将性的内容写入他的小说中。
在他的作品中,贯穿着其特有的黑色幽默,这些也表明了王小波对于生命和生活的态度。王小波的一系列小说都以自己所经历过的生活作为蓝本,如下放到云南的知识青年,在某个医院或高等专科学校从事技术工种的工程师等等,作品的年代背景也与王小波的生活与成长时期相重叠,在这些作品中,他刻画了这样一种现实:“我看到一个无智的世界,但是智慧在混沌中存在;我看到一个无性的世界,但是性爱在混沌中存在;我看到一个无趣的世界,但是有趣在混沌中存在”。
从杂文作品中看,哲学家伯特兰·罗素对他思想影响很深,他推崇和提倡科学与理性,并且认为人的生活应该追求未知,他反对进行思想禁锢,主张人们思维应该保持多样化,使生活变得有意思有趣,去热爱智慧。 他的作品在他身后盛行于世,影响了众多青年,特别是二十世纪九十年代的大学生,他们至今还会常常引用王小波作品中的文字,来表明自己的激昂和犀利。其曾编写过电影剧本《东宫西宫》,并由此获得了阿根廷国际电影节最佳编剧[1]。
!! 王小波现象
王小波生前两获《联合报》中篇小说大奖,在海外华人文学界获得普遍称誉。但当其期望进入内地文坛体制时,却遭到了前所未有的冷遇,甚至出版作品都很困难。王小波在其小说集《黄金时代》的后记中坦承:“本书得以面世,多亏了不屈不挠的意志和积极的生活态度。必须说明,这些优秀的品质并非作者所有。鉴于出版这本书比写这本书困难得多,所以假如本书有些可取之处,当归于所有帮助出版它的朋友们。”
而1997年王小波遽然逝世,成为了王小波现象的开端。其作品被空前的传播和接受,在民间与知识界都引起巨大反响,作品的发行量至21世纪仍为90年代小说家中的佼佼者。各种形式的王小波纪念会,作品研讨会层出不穷,一时间王小波现象席卷文坛、文艺界与文学批评界。
王小波现象的爆破点在于其杂文,值得一提的是,其杂文在身前就曾经受到关注。评论界有把王小波热比作陈寅恪热之后,自由主义浪潮在中国的第二次博兴。
关于王小波小说价值的技术性讨论,主流批评界保持了异常的缄默。关于王小波小说价值的讨论,在主流文学批评界一直处于边缘化的地位。可以说,王小波现象的主要焦点在于其杂文以及其所宣扬的自由主义思潮。而其小说在文坛的地位与技术性讨论,仍处于悬而不决的地位。
王小波在生前曾说过一句话,“有一天,我们都会死去,追求智慧的道路还会有人在走。死掉以后的事我看不到。但在这活着的时候,想到这件事,心里就很高兴。”
威格利大叔在康涅狄格州_九故事_塞林格
========================
# 威格利大叔在康涅狄格州
[[塞林格]]
-----
都快三点钟了,玛丽 • 简才总算找到了埃洛依斯的家。玛丽 • 简向跑到车道上来迎接她的埃洛依斯解释说,本来一切都绝对顺当,路怎么走她记得真真儿的,直到她拐开了梅里克林阴大道。埃洛依斯说:“是梅里特林阴大道,宝贝儿,” 并且提醒玛丽 • 简她从前有两次都是自个儿找到这所房子的,可是玛丽 • 简光是含糊其辞地哀叫出几个字,像是跟她那盒克林尼斯纸巾有关的什么事儿,接着便奔回到她那辆有活动顶篷的汽车旁。埃洛依斯翻起驼绒外衣领子,转身背对着风,等着。玛丽 • 简倒是立刻就回来了,用纸巾擦拭着,仍然显得心里很烦,甚至是气呼呼的。埃洛依斯乐呵呵地说。真倒霉,整顿午餐全给烧煳了一小牛胰脏以及所有的一切——但玛丽说反正她已经在路上吃过了。两个人朝房子走去时,埃洛依斯问玛丽 • 简她怎么今天正好得空。玛丽 • 简说她并不是垒天有空;只是因为韦困伯格先生疝气犯了, 不得不呆在拉契蒙镇家里,由她每天下午把他的信件送去,另外再带走几封。她问埃洛依斯,“对了,疝气到底是怎么回事?” 埃洛依斯把手里的烟头往脚下污雪里一扔,说她也不真正清楚,不过玛丽 • 简尽可以放心,她是不大会得这种病的。玛丽 • 简说了声 “哦”,于是两个姑娘便走进了屋子。
二十分钟以后,她们已经在起居室里快喝光她们的第一高脚杯威士忌酒了,并且以曾在大学同住过一个房间的那种特殊的、也许是仅限于 “室友” 才能有的方式聊起天来了。再说她们之间还有一层更深的关系;两人都没有念到毕业。埃洛依斯是在 1942 年二年级念到一半时离开学院的,一个星期前,她在宿舍三楼紧闭的电梯里跟一个大兵被人抓了个正着。玛丽 • 简退了学——就在同一年,上同一班时,几乎是同一个月里—嫁给了驻扎在佛罗里达州杰克逊维尔的一个空军学校学员,那是个来自密西西比州迪尔的瘦瘦的、对飞行着了迷的小伙子,他和玛丽 • 简的婚姻只维持了三个月,其中有两个月他倒是在监狱里度过的,因为用刀子捅了一个宪兵。
“不对,” 埃洛依斯说了。“那其实是红色的。” 她手伸着躺在长沙发上,那双细细的却非常好看的腿脚腕处搭在了一起。
“我听说是金黄色的嘛,” 玛丽 • 简重复了一遍。她坐在一张蓝色的直靠背椅子上。“那家伙名叫什么来着,赌咒发誓说那是金黄色的。”
“哎。错不了。” 埃洛依斯打了个哈欠。“她染头发那会儿我等于跟她在同一个房间里呢。怎么搞的’那里面连一根香烟都没有了吗?”
“不要紧。我这里有整整一包呢,” 玛丽 • 简说。“在哪儿来着。” 她在她的手提包里摸采摸去。
“我那傻女佣,” 埃洛依斯说,躺在长沙发上一动没动。“一小时之前,我就在她鼻子跟前扔下两条拆都没拆开的烟。你瞧着吧,不定什么时候她会进来问我,这些烟该怎么办。我方才究竟说到哪儿啦?”
“休林格,” 玛丽 • 简提醒她,同时点燃了一根她自己的烟。
“噢,对了。我记得清清楚楚的。她就是在嫁给那个弗兰克 • 亨克头大晚上染的发。你对那人还有点印象吗?”
“有那么点儿吧。又矮又显老的小兵? 非常不起眼? 对吗?”
“什么不起眼。我的天一他看上去整个儿个脏不拉儿的贝拉 • 卢戈西。”
玛丽 • 简仰天呵呵大笺。“妙极了,” 她说,又恢复了原来的喝酒姿势。
“把杯子递给我,” 埃洛依斯说,那两只穿长筒袜子的脚晃了晃落到地上,她站了起来。
“我可一点也没瞎说,那笨蛋。为了让她出来跟咱们果在一起,我仆么劲儿全使出来,光剩下没让路易去跟她睡觉了。现在我真后悔我——你那玩意儿哪儿来的?”
“这个吗?” 玛丽 • 简说,摸了摸她咽喉处的一只浮雕饰针。“你还不知道,我在学校时就有了。原先是我母亲的。”
“我的天,” 埃洛依斯说,双手捏着两只空酒杯。“我连一件可 “佩戴的神圣纪念物都没有。要是路易的妈妈有天死了——哈,哈——她没准留给我的是个印有姓名起首字母的碎冰锥或是这一类东西。”
“对了,你这一阵跟她相处得还好吗?”
“嗨,你就别逗了,” 埃洛依斯边说边朝厨房走去。
“喝完这杯我是绝对不能再喝了!” 玛丽 • 简在她背后喊道。
“鬼话。是谁上谁家来啦,又是谁晚到了两个小时? 你就给我老老实实果着直到我厌烦了你为止。你那破工作就给我见鬼去吧。”
玛丽 • 简脖子一仰,又哈哈疯笑起来,此时埃洛依斯已经进到厨房去了。
玛丽 • 简一个人留在屋里没什么事好做,便站起来走到窗前。她撩开点窗帘把手腕搁在窗玻璃之间的一根横档上,但是觉得有沙子硌,便把手抽回,用另一只手把沙子抹掉,然后把身子挺得更直地站着。窗外,污脏的雪水显然在开始结成冰。玛丽 • 简橙开窗帘,重新往蓝椅子那边走去,她经过两只塞得满满的书柜却对哪怕几本书的标题都没有瞥一眼。她坐下来,打开手提包,取出小镜子来照照牙齿。她闭上嘴唇,用舌头使劲舔上边的门牙,然后义照照镜子。
“外面那么冰冷冰冷的,” 她说,一边把身子转过来。“天哪,这么快啊。你褴往杯里对苏打水吗?”
埃洛依斯一手捏着一杯刚对好的酒,猛地站住。她伸出两只食指,装成枪口状,升口说:“谁也别动。这鬼地方我全包围了。”
玛丽 • 简哈哈大笑,一边把镜子收起来。
埃洛依斯端着酒走过来。她把玛丽 • 简的那杯不大稳当地放在杯垫上,自己的那杯仍然拿在手里。她又在长沙发上躺了下来。“你想像得出那婆子在里面干什么吗?” 她说。“她那太黑屁股坐得稳稳的,正在读《长袍》呢。我取出冰块盒的时候把盒子弄到了地上。她还抬起头看看,挺恼火的呢。”
“这是我的最后一杯。我可是当真的,” 玛丽 • 简说,一边拿起她的酒杯。“哦,听着! 你知道上星期我见到了谁? 在洛德. 泰勒公司大厅里?”
“嗯哼,” 埃洛依斯说,把脑袋下面那只枕头调整了一下位置。“阿基姆 • 塔米洛夫呗。”
“谁?” 玛丽 • 简问。“这家伙屉什么人?”
“阿基姆 • 塔米洛夫。他是电影里的人物。他总是说,‘你的玩笑开得戒大了——啊?’我喜欢他…” 这屋子里就没有一个我用着不难受的鬼枕头。你到底见到谁啦?”
“杰克逊呀。她那会儿——”
“哪-个杰克逊?”
“我说不清楚,跟我们一块上心理学课的那位,老是——”
“两个杰克逊都跟我们一起上过心理学课。”
“唉。就是那个有着特——”
“马西娅 • 路易丝。我有一回也撞上她了。她是不是跟你说个没完?”
“老天,就是她。可是你知道她告诉我什么啦? 惠廷博士死了。她说她收到巴巴拉 • 希尔的一封信,说惠廷去年夏天得了癌,后来死了,等等等等。她死的时候.体重才六十二磅。你说可怕不可怕?”
“这没什么。”
“埃洛依斯,你心肠越来越硬了。”
“可不。她还说什么啦?”
“噢,她刚从欧洲回来。她丈夫驻扎在德国或是别的什么地方,她随丈夫一起。他们有幢四十七个房间的太宅,她说,只跟另一对夫妇合用,有差不多十个用人。她有自己专用的马,他们雇的马夫,原先还是希特勒私人骑术教练什么的呢。哦,她还告诉我她怎么差点儿给一个黑人太兵强 xx 了呢。就在洛德泰勒正厅跟我大谈起来你知道杰克逊这人脾气的。她说那太兵是她丈夫的司机,有天早上正拉了她上市场或是去干别的什么事儿。她说她吓坏了,甚至都没有--”
“先等一等。” 埃洛依斯抬起了头,也提高了嗓门。“是你吗,拉蒙娜?”
“是的,” 一个小小孩的声音回答说。
“进来了就把前门关上,别忘了,” 埃洛依斯大声喊道。
“那是拉蒙娜吗? 哦.我可太想见到她了。你明白吗,我一直都没见到过她,自从她一”
“拉蒙娜,” 埃洛依斯嚷道,闭起了双眼。“到厨房去让格雷斯帮你把套鞋脱了。”
“好的,” 拉蒙娜说。“来吧,吉米。”
“哦,想见她可把我想死了,” 玛丽 • 简说。“哦,天哪! 瞧我闯了什么祸了。我太抱歉了,埃尔。”
“别管它了。别管它,” 埃洛依斯说。“反正我已经讨厌这块鬼地毯了。我给你重新倒上一杯。”
“不用,瞧,我这杯子里还剩下一半多呢 J” 玛丽 • 简举起她的杯子。
“真的?” 埃洛依斯说。“给我一根烟。”
玛丽 • 简把她的那包烟递过去,一边说:“哦,我想死她了,她这会儿长得像谁啦?”
埃洛依斯划燃一根火柴,“阿基姆 - 塔米洛夫。”
“别呀,说真的。”
“路易,她长得像路易。他妈妈过来的时候,他们仨看上去就跟三胞胎似的。” 埃洛依斯褴有坐起来,伸出手去够茶几那头的一摞烟灰缸。她还真捏起了最上面的一只,把它放在了自己肚子上。“我需要的是小磺犬之类的东西,” 她说。“那就会像我了。”
“她眼睛现在怎么样啦?” 玛丽 • 简问道。“我的意思是没变得更不好吧,是不是?”
“天哪! 我可说不上来。”
“她不戴眼镜不会什么都看不见吧? 我是说如果她晚卜起来上厕所或是干别的事的话?”
“她埘谁都币说。她是保密夫十。”
玛丽 • 简在椅子里转过身来。“嗳,你好,扣蒙娜!” 她说。“哦,这裙子真漂亮!” 她放下她的洒杯。“我敢说你都不记得我了吧,拉蒙娜。”
“她当然记得。这位女士是谁啊,拉蒙娜?”
“玛丽 • 简” 拉蒙娜说,一边挠着痒痒。
“真了不起!” 玛丽 • 简说。“拉蒙娜,你亲我一小口行吗?”
“别那样干,” 埃洛依斯对拉蒙娜说。
拉蒙娜停住不再挠挠了。
“亲我一小口行吗,拉蒙娜?” 玛丽 • 简又问。
“我不喜欢亲别人。”
埃洛依斯鼻子里哼了一声,问:“吉米在哪儿呢?”
“他在这儿呢。”
“吉米是谁?” 玛丽 • 简问埃洛依斯。
“哦,我的天! 她的小情人儿。她走哪儿他跟到哪儿。她干啥他也照着干。完全是瞎胡闹。”
“真的呀?” 玛丽 • 简很感兴趣地说。她身子往前倾。“你有了小情人儿啦,拉蒙娜?”
拉蒙娜的眼睛藏在厚厚的近视镜片后面,压根儿看不出对玛丽 • 简的热情有丝毫反应。
“玛丽 • 简问你话呢,拉蒙娜,” 埃洛依斯说。
拉蒙娜把一只手指伸到她那小小的塌鼻子里去。
“不许那么干,” 埃洛依斯说。“玛丽 • 简问你是不是有小情人”
“是的,” 拉蒙娜说,还在不住地抠鼻孔。
“拉蒙娜,” 埃济依斯说。“不许抠。马上给我停下。”
拉蒙娜把手放了下来。
“哎,我觉得这事真了不起,” 玛丽 • 简说。“他叫什么名宁? 你愿意告诉我他叫什么吗,拉蒙娜? 这不至于是个大秘密吧?”
“吉米,” 拉蒙娜说。
“吉米? 哦,我喜欢吉米这名字!吉米什么呢,拉蒙娜?”
“青米 - 吉默雷诺,” 拉蒙娜说。
“站好了,” 埃洛依斯说。
“噢! 这倒是千挺特别的名字。吉米在哪里呢? 你可以告诉我吗,拉蒙娜?”
“在这儿,” 拉蒙娜说。
玛丽 • 简往四下看看,又把眼光收回对着拉蒙娜,尽可能笑得甜一些。“这儿的什么地方,宝贝儿?”
“就这儿,” 拉蒙娜说。“我正拉着他的手呢。”
“这我就不明白了,” 玛丽 • 简对埃洛依斯说,她正要把她那杯酒喝干。
“别死劲儿盯着我,” 埃洛依斯说。
玛丽 • 简又转过头来看着拉蒙娜。“哦,我明白了。吉米只是一个让人信其有的小男孩。这太奇妙了。” 玛丽 • 简亲热地往前倾了倾身子。“你好啊,吉米?” 她说。
“他不会跟你说话的,” 埃洛依斯说。“拉蒙娜,给玛丽 - 简说说吉米的事儿。”
“给她说什么?”
“站直了,行不行…?? 告诉玛丽 - 简吉米长得什么模样。”
‘他有一舣绿眼睛,黑头发。”
“别的方而呢?”
“没有妈咪也没有爹地。”
“还有呢?”
“没有雀斑。”
“还有呢?”
“有一把剑。”
“还有呢?”
“我不知道了,” 拉蒙娜说,又开始挠起痒痒来了。
“听起来这孩子蛮不错的嘛!” 玛丽 • 简说,身子从椅子里更往前倾了。“拉蒙娜。告诉我。你进来的时候,吉米也脱掉他的套鞋了吗?”
“他穿着皮靴呢,” 拉蒙娜说。
“太了不起了,” 玛丽 • 简对埃洛依斯说。
“你倒想想看。我整天都得受这一套。吉米跟她一块儿吃东西。跟她一块儿洗澡。跟她一起睡觉,她紧挨着床的一边睡.生怕翻过身来把他压着了。”
听说这样的情况,玛丽 • 简显得很入迷很开心,她把下唇吸进去咬了咬,然后又松开并且问道:“不过他这名字是打哪儿来的呢?”
“吉米 • 吉默雷诺? 天跷得。”
“没准邻近有个小男孩叫这名字。”
埃洛依斯打着哈欠摇了摇头。“邻近没住着什么小男孩。根本就没有小孩。人家在背后都管我叫能下崽的芳妮了——”
“妈咪,” 拉蒙娜说。“我出去玩行吗?”
埃洛依斯看着她.“你刚刚进来嘛,” 她说。
“吉米又想出去了呢。”
“为什么.能告诉我吗?”
“他把他的剑丢在外面了。”
“唉,他跟他那把该死的剑,” 埃洛依斯说。“好吧,走吧。再穿上你的套鞋。”
“我拿上这个行吗?” 拉蒙娜说,捡起烟灰缸里的一根烧过的火柴梗。
“应该说请给我这个好吗? 行。别到街上去,听见了吧。”
“再见,拉蒙娜!” 玛丽 • 简拿腔拿调地说。
“再见,” 拉蒙娜说。“走吧,吉米。”
埃洛依斯猛地站起身来。“把杯子给我,” 她说。
“真的,不喝了,埃尔。我本该在拉契蒙的。我是说韦因伯格先生待我这么好,我真不想——”
“打电话去说你绐人杀了不就行了。松开那该死的杯子。”
“不了,真的不行,埃尔。我是说外面正冰冻得很厉害。我车子里几乎没一点防冻剂。我是说如果我不——”
“让它冻去。去打电话呀。就说你死了,” 埃洛依斯说。“杯子给我。”
“那…… 电话在哪儿?”
“它在,” 埃洛依斯说,拿着两只杯子朝餐厅走去,“——往这边走。” 走到起居室和餐厅之间的一块地板上时,她突然停步,把屁股扭了一圈又往后一顶。玛丽 • 简乐不可支,格格地笑了。*
“我的意思是你那时并不真正了解沃尔特,” 埃洛依斯说,此时已是五点一刻,她仰面平躺在地板上,一杯酒放在她 Rx 房扁扁的胸口上,居然还放得挺稳。“他是我认识的男孩子里惟一能逗我发笑的一个。我是说真正开心地笑。” 她朝玛丽 • 简望过去。“你记得那个晚上吗——咱们在学校的最后一年——那个疯疯癫癫的路易丝 • 赫曼森穿着她从芝加哥买来的黑奶罩闯进房间来了?”
玛丽 • 简格格地笑着,她面对埃洛依斯趴着睡在长沙发上,下巴搁在扶手上。她的杯子放在地上手够得到的地方。
“嗬,他能那么样地逗我发笑,” 埃洛依斯说。“他跟我说话能逗我荚。他打电话能逗我笑。他甚至写封信来也能逗我笑。面最最妙的是他甚至都没想显得滑稽——他人本来就滑稽。” 她把头稍稍转向玛丽 • 简。“嗨,给我扔根烟过来,行不?”
“我够不着呢,” 玛丽 • 简说。
“去你的。” 埃洛依斯又朝天花板看去。“有一回,” 她说,“我摔倒了。我总在公共汽车站那里等他,就在军人商店的外面,有一回,他来晚了,汽车都开动了。我们拔腿追,这时候我摔倒了,扭了脚腕。他说:‘可怜的威格利大叔。’他指的是我的脚腕。可怜的威格利大叔,他这么说我的脚腕…… 天哪,他真有意思。”
“路易就没有幽默感吗?” 玛丽 • 简说。
“什么?”
“路易就没有幽默感吗?”
“哦,上帝! 谁知道呢? 有的吧。我想是有的。他看了卡通漫画这类东西也会哈哈大笑的。” 埃洛依斯抬起头,把胸口上的杯子举起,喝了口酒。
“其实,” 玛丽 • 简说。“那也不是什么了不起的事。我说那也算不了什么。”
“什么算不了什么?”
“哦… 一你知道。让你大笑什么的。”
“谁说算不得?” 埃洛依斯说。“听着。如果你不想出家当修女什么的,那你还是笑笑的好。”
玛丽 • 简格格地笑了。“你这人真难伺候,” 她说。
“啊,上帝啊,他真是挺有意思的,” 埃洛依斯说。“他要么很滑稽,要么就挺可爱,伺也不是小男孩那种乏味的乖甜。这是一种特殊的温柔。你知道有一次他干了什么吗?”
“什么呀,” 玛丽 • 简说。
“我们坐火车从特伦顿去纽约——那是在他刚被征兵人伍之后。车厢里很冷,我把我的外衣好歹搭在我们俩的身上。我记得我在外衣里面穿的是乔伊斯 • 莫罗的毛衣--你还记得她的那件漂亮的对襟蓝毛衣吗?”
玛丽 • 简点点头,可是埃洛依斯眼睛没有转过去,因此也没注意到。
“嗯,他一来二去把手放在了我的肚子上。你知道吧。总之,他突然说我的肚子真是太美了,因此他希望能有个军官出现命令他把另外那只手伸到窗子外面去。他想他事情应该做得公平些。接着他把手抽了回去.并且告诉列车员得把胸挺直了。他告诉那人,如果有什么事他不能容忍的就是一个人不尊重自己所穿的制服。那列车员光是对他说接着睡你的觉吧。” 埃洛依斯沉思了一会儿,然后说,“有趣的不总是他说了什么,而是他是怎么说的。你明白吧。”
“你告诉过路易他的事吗——我是说,是不是压很儿没提?”
“哦,” 埃洛依斯说,“有一回,我开了个头。可是路易问我的第一件事就是他的军阶是什么?”
“他的军阶究竟是什么呢?”
“哈!” 埃洛依斯说。
“别呀,我的意思只不过是——”
埃洛依斯突然笑了起来,那声音发自她的小腹深处。“你知道他有一回是怎么说的吗? 他说他觉得自己在军队里得到提升,不过方向正好跟所有别的人相反。他说他得到第一次提升时,不是多了几道杠而是两只袖子被扯下来。他说等他当上将军,那就是赤条条一丝不挂的了。他身上惟一剩下的就是肚脐眼上那颗小步兵服的军扣了。” 埃洛依斯朝玛丽 • 简看去,见到她并没有笑。“你不觉得这很滑稽吗?”
“是的。不过,你干吗不找个机会跟路易谈谈他的事呢?”
“干吗? 因为路易这人太没有头脑,就因为这个,” 埃洛依斯说。“另外,听我的,职业女性。如果你有一天再次结婚,什么事儿也别告诉你的丈夫。你听到了吗?”
“为什么呢?” 玛丽 • 简说。
“就因为我是这样说的,这就是原因,” 埃洛依斯说。“他们愿意相信每回有一个男的接近你,你一辈子都为此觉得恶心。我这可不是开玩笑,知道吧。哦,你当然可以给他们说点儿什么。但永远不要老老实实地说。我的意思是永远别说老实话。如果你告诉他们以前认识一个挺帅的男孩,你得用同一口气接下去说这男孩也未免太漂亮了点儿。要是你告诉他们你认识一个风趣的男孩,你得告诉他们不过是那类爱招摇卖弄的角色,或者是精得过了头。如果你不这么说,他们会逮着每一次机会拿这个可怜的男孩来敲打你的。” 埃洛依斯停住话头,边喝杯里的酒边考虑。“哦,” 她说,“他们会非常有修养地听着,像模像样的。他们甚至还会显得很有智慧,挺了不起似的。可是你别给蒙住。相信我。要是你真的有丁点儿相信他们聪明,那你可有苦头要吃了。记住我说的话好了。”
玛丽 • 简显得很沮丧,她从长沙发的扶手上抬起下巴。她要换换姿势,把下巴搁在前臂上。她把埃洛依斯的忠告想了想。“你总不能说路易这人不聪明吧,” 她大声说。
“谁不能说?”
“我的意思是他不是挺聪明的吗?” 玛丽 • 简有点天真地说。
“噢,” 埃洛依斯说,“说这些话有什么用? 咱们不谈了。我只会让你心情不好的。别让我说了。”
“唉,那你干吗跟他结婚呢?” 玛丽 • 简说。
“噢,上帝! 我不知道。他当初告诉我他喜欢简 • 奥斯汀 @。他说她的书对他来说无比重要。这都是他的原话。我们结婚后我才发现她的书他连~本都没有读过。你知道他最喜欢的作家是谁?”
玛丽 • 简摇摇头。
“L• 曼宁 • 瓦困斯。听说过此人吗?”
“哼。”
“我也没有听说过。别的人也全没听说过。此人写了一本书,讲四个男人在阿拉斯加活话饿死的事。路易记不得书名了,但那是他读过的书里写得最摄美的一部。耶稣呀!他其实满可以老老实实说,他喜欢它因为写的是四个家伙在一座圆顶雪屋或是别的什么地儿饿死的事。他却非耍说因为它写得租美。”
“你也太苛刻了吧,” 玛丽 • 简说。“我说你太苛刻了。没准那书当时也算是本好——”
“相信我的话好了,那根本不可能,” 埃洛依斯说。她想了一会儿,接着说,“至少,你有一份工作。我的意思是至少你——”
“不过,你听我说,” 玛丽 • 简说。“你是想连袄尔特牺牲的事都不告诉他吗? 我认为他不会妒忌的,他还会吗,如果他知道了沃尔特已经——你明白吗。牺牲了,一切都过去了。”
“哦,多情种子!你这可怜的、天真幼稚的职业女性,” 埃洛依斯说,“他只会更加恶劣。他会成为一个盗墓食尸鬼的。听着,他只会记住我跟一个名叫沃尔特的家伙来往过——一个爱说俏皮话的大兵。再怎么着我也不会告诉他祆尔特死了。再怎么着也不会。要是我真的说了——那是绝对不会的——不过要是我真的说了,我会告诉他袄尔特是在战斗中被打死的。”
玛丽 • 简把她的下巴往前移了移,靠到自己前臂的外缘。
“埃尔……” 她说。
“怎么啦?”
“你干吗不告诉我他是怎么死的? 我发誓对谁也不说。真的。求求你了。”
“不行。”
“求求你了。真的。我不会告诉任何人的。”
埃洛依斯喝完她的酒,把空杯子重新立在了自己胸前。“你会告诉阿基姆 - 塔米洛夫的,” 她说。
“不,我不会的! 我真的不会告诉任何——”
“哦,” 埃洛依斯说,“他那个团在某个地方休整。那是在两次战斗或是什么事的间歇之中吧,给我写信的他那朋友是这么说的。沃尔特跟另一个小伙子正把这只小型的日本炉子打包装箱。有个上校要把它寄回家去。也可能是他们正把它从箱子里取出来以便重新包装一具体情况我也不清楚。总之,装满了汽油和乱七八糟东西的炉子在他们面前爆炸了。另外的那小伙子仅仅是瞎了一只眼睛。” 埃洛依斯开始哭了起来。她伸出~只手去拢住胸前的那只空杯子,不让它掉下来。
玛丽 • 简从长沙发上溜下来,她双膝着地往前挪动了三步,来到埃洛依斯跟前,开始轻拍她的脑门。“别哭,埃,别哭了。”
“谁哭了?” 埃洛依斯说。
“我知道,可是别这样。我是说犯不着的,没意思的。”
这时,前门开了。
“是拉蒙娜回来了,” 埃洛依斯糖着鼻子说。“帮我这个忙。你到厨房去告诉那婆娘早点儿给拉蒙娜开饭。行吗?”
“行啊,不过你得答应我别哭了。”
“我答应。去吧。我这会儿不想在那鬼地方露面。”
玛丽 • 简站起来,打了个越趄,又重新站稳,走出了房间。
不到两分钟她又回来了,拉蒙娜跑在她的前面。拉蒙娜尽可能让整个脚掌着地,以便让解松的套鞋发出最大的声音。
“她不肯让我帮她脱套鞋,” 玛丽 • 简说。
埃格依斯仍然仲面躺在地板上,正用手绢擦拭嘴。她透过手绢说话,是在吩咐拉蒙娜。“去那边房间告诉格雷斯让她给你脱套鞋。你知道你是不应该进来弄得——”
“她在上厕所呢,” 拉蒙娜说。
埃洛依斯放开手绢,把身子挺坐起来。“脚伸过来,” 她说。“先坐下来,好不好…… 不是那边——是这边。天哪!”
玛丽 • 简跪在地上找她的烟盒,她说:“嗨,你猜吉米出了什么事。”
“猜不出来。另外那只脚,那一只脚。”
“他让车压了,” 玛丽 • 简说。“这是不是太惨了点儿?”
“我看到斯基珀叼着一根骨头,” 拉蒙娜告诉埃洛依斯。
“吉米出什么事啦?” 埃洛依斯对她说。
“他让车压了,死了。我瞧见斯基珀叼着一根骨头,它不肯放--”
“把脑袋伸过来会儿,” 埃洛依斯说。她伸手出去摸了摸拉蒙娜的前额。“你有点发烧。去告诉格雷斯你得在楼上吃晚饭。吃完马上给我上床睡觉。我待会儿就上来。好,去吧,快点儿。把这些东西一块带上。”
拉蒙娜慢腾腾地跨着大步走出房间。
“扔一根给我,” 埃洛依斯对玛丽 • 简说。“咱们再喝一杯吧。”
玛丽 • 简拿了支烟递给埃洛依斯。“有点儿意思吧? 关于吉米,想像力够丰富的!”
“嗥。你去倒酒,行不? 干脆把瓶子拿来…… 我不想再去那边了。整幢房子一股橘子汁的气味。”*
七点过五分,电话响了。埃洛依斯从窗前椅子上站起来,在黑暗中摸索鞋子。她没能找到。于是她光穿着袜子,沉稳地,几乎是慢腾腾地朝电话走过去。电话铃声没吵着玛丽 • 简,她脸朝下趴睡在长沙发上。
“喂,” 埃洛依斯对着话筒说,也不去打开头顶上的电灯。“跟你说,我没法去接你。玛丽 • 简在这儿哪。她把车停在我车子面前,可她找不到车钥匙了。我出不去。我们大约花了二十分钟找钥匙,在那个叫什么来着的里面——雪和脏泥那类东西。你是不是可以搭迪克和米尔德里德的车子?” 她听着。“哦。是的,这太惨了,宝贝。你们这些小伙子干吗不组成一个排列队回家呢? 你们可以喊一、二、三、四这一套呢。你可以当头儿呀。” 她又听对方说话。我没在开玩笑,” 她说。“真的,我没有。就只是我那张脸让人觉得可笑。” 她把电话挂了。
她走回到起居室,步子没那么稳了。在窗前椅子那里,她把瓶子里剩余的酒倒进自己杯子。那大概有一指深。她把酒喝光,打了个冷颤,坐了下来。
格雷斯开亮餐厅电灯时埃洛依斯吃了一惊。她没有站起来,只是大声对格雷斯说,“你最好等到八点再开饭,格雷斯。温格勒先生要稍晚些才能回来。”
格雷斯身影出现在餐厅亮光里,但她没有再往前走。“那位女士走啦?” 她说。
“她在休息呢。”
“哦,” 格雷斯说。“温格勒太太,我想问一句,能不能让我丈夫在这儿过一夜。我的房间里地方还够,这样他就可以明天早上再回纽约去了,外面天气太糟糕了。”
“你丈夫? 他在哪儿?”
“哦,这会儿,” 格雷斯说,“他就在厨房里呢。
“啊,我怕他不能在这儿过夜,格雷斯。”
“太太?”
“我说恐怕他不能在这儿过夜。我不是开旅馆的。”
格雷斯站了片刻,接着说,“那好吧,太太,” 接着便走出房间上厨房击了。
埃洛依斯离开起居间登上楼梯,餐厅泛出来的光使这里幽幽地有些微亮。拉蒙娜的一只套鞋躺倒在楼梯口平台上。埃洛依斯捡起来朝栏杆外摔去,使出了她最大的劲儿,套鞋在门厅地板上通地发出很响的一声。
她啪地打开拉蒙娜房间的灯,手一直按在开关上,仿佛耍支撑住身子。她站住不动有好一会儿,注视着拉蒙娜。接着她松开电灯开关,快步走到床前。
“拉蒙娜。醒醒。给我醒醒。”
拉蒙娜紧靠床边睡着,右边屁股都出了床沿。她的眼镜放在一张唐老鸭模样的小床头柜上,整齐地折起,镜脚朝下。
“拉蒙娜!”
孩子猛抽了一口气,醒了,她眼睛睁得大大的,但几乎立刻又眯紧了。“蚂眯?”
“我记得你跟我说过吉米 • 吉默雷诺给车压死了。”
“什么?”
“我的话你听得很清楚,” 埃洛依斯说。“你为什么紧靠那边睡?”
“因为,” 拉蒙娜说。
“因为什么? 拉蒙娜,我不喜欢——”
“因为我不想压坏米基。”
“谁?”
“米基,” 拉蒙娜说,揉了揉鼻子。“米基 • 米基雷诺。”
埃洛依斯把嗓门提高到尖叫的程度。“你给我睡到床中间去。快点。”
拉蒙娜吓呆了,光是往上盯看着埃洛依斯。
“好啦。” 埃洛依斯抓住拉蒙娜两只脚腕,半提半拖地把她拉到床中间。拉蒙娜也不挣扎也不哭,任凭自己被拖过去,其实是一心的不乐意。
“现在睡觉,” 埃洛依斯说,喘着粗气。“闭上眼睛…… 听见没有,给我闭上。”
拉蒙娜闭上了眼睛。
埃洛依斯走到开关前,啪地把灯关掉。不过她在门口站了好一会儿。接着,突然,她在黑暗中朝床头柜冲了过去,膝盖撞在床脚上,只是注意力太集中也没觉得疼。她拿起拉蒙娜的眼镜,双手捏着,把它贴向自己的脸颊。眼泪顺着脸流了下米,打湿了镜片。“可怜的威格利大叔,” 她一遍又一遍地说。最后,她把眼镜放回到床头柜上,这回是镜片朝下。
她弯下身来,有点站不稳.开始把拉蒙娜床上的毯予往里掖了掖,拉蒙娜醒着呢。她在哭而且已经哭了好一会儿了。埃洛依斯吻了拉蒙娜的嘴,泪水口水混在了一起,她把按子眼前的头发撩撩开,接着便走出房间。
她下楼去,此刻脚步已是踉踉跄跄的了,她弄醒了玛丽 • 简。
“那是谁? 谁? 呃?” 玛丽 • 简说,腾地在躺椅上坐直了身予。
“玛丽 • 简。听着。求求你了,” 埃洛依斯说,一边抽噎着。“你记得咱们念大学一年级的时候,我穿过的那件在博伊斯买的棕黄色长裙吗,米里亚姆 • 鲍尔告诉我纽约没人再穿这类衣服了,我整整哭了一夜,记得吗?” 埃洛依斯摇晃着玛丽 • 简的胳膊。“我那会儿是个好姑娘,” 她恳求地问,“我那会儿是的,对吗?”
威廉·福克纳- 余华
========================
威廉·福克纳- [[余华]]
------
我手里有两册[[《喧哗与骚动》]],一册是1984年出版,定价1.55元,印数87500册;另一册是1995年出版的,定价18.40元,印数10000册。这十一年里,我们经历了很多变化,就像《喧哗与骚动》的定价和印数一样,很多事物都已经面目全非。当然也有不变的,比如这两册《喧哗与骚动》都是上海译文出版社出版,都是同一位出色的学者和翻译家李文俊的译文。这没有变化的事实似乎暗示了我们,一个过去的时代其实并没有过去,它和我们的今天重叠起来了,它的存在并不是为了让我们这些拥有着过去的人在回忆往事时增加一些甜蜜,或者勾起一些心酸,而是继续影响我们,就像它在过去岁月里所做的那样,影响着我们的理解和判断。也是同样的道理,[[威廉·福克纳]]是永存的。
这是一位奇妙的作家,他是为数不多的能够教会别人写作的作家,他的叙述里充满了技巧,同时又隐藏不见,尤其是他的一些中短篇小说,外表马虎,似乎叙述者对自己的工作随心所欲,就像他叼着烟斗的著名照片,一脸的满不在乎。然而在骨子里,却是一位威廉·福克纳,他在给兰登书屋的罗伯特·哈斯的信中这样写道:“……需要精心地写,得反复修改才能写好……”这就是威廉·福克纳,他精心地写作,反复修改地写作,而他写出来的作品却像是从来就没有过修改,仿佛他一气呵成地写完了十八部长篇小说,还有一堆中短篇小说,接下去他就游手好闲地在奥克斯福,或者在孟菲斯走来走去,而且还经常打着赤脚。
就像我们见过的那些手艺高超的木工,他们干活时的神态都是一样的漫不经心,他们从不把自己的认真显示出来,只有那些学徒才会将自己的兢兢业业流露在冒汗的额头和紧张的手上。威廉·福克纳就是这样,叙述上的训练有素已经不再是写作的技巧,而是出神入化地成为了他的血管、肌肉和目光,他的感受、想象和激情,他有足够的警觉和智慧来维持着叙述上的秩序,他是一个从来没有在叙述时犯下低级错误的作家,他不会被那些突然来到的漂亮句式,还有艳丽的词语所迷惑,他用不着眨眼睛就会明白这些句式和词语都是披着羊皮的狼,它们的来到只会使他的叙述变得似是而非和滑稽可笑。他深知自己正在进行中的叙述需要什么,需要的是准确和力量,就像战斗中子弹要去的地方是心脏,而不是插在帽子上摇晃的羽毛饰物。
这就是威廉·福克纳的作品,像生活一样质朴,如同山上的石头和水边的草坡,还有尘土飞扬的道路和密西西比河泛滥的洪水,傍晚的餐桌和酒贩子的威士忌……他的作品如同张开着还在流汗的毛孔,或者像是沾着烟丝的嘴唇,他的作品里什么都有,美好的和丑陋的,以及既不美好也不丑陋的,就是没有香水,没有那些多余的化妆和打扮,就像他打着赤脚游手好闲的样子,就像他的《我弥留之际》里那一段精彩的结尾──“‘这是卡什、朱厄尔、瓦达曼,还有杜威·德尔。’爹说,一副小人得志、趾高气扬的样子,假牙什么一应俱全,虽说他还不敢正眼看我们。‘来见过本德仑太太吧,’他说。”── 他就是这样一位作家,写下的精彩篇章让我们着迷,让我们感叹,同时也让我们发现这些精彩的篇章并不比生活高明,因为它们就是生活。他是这个世界上为数不多的始终和生活平起平坐的作家,也是为数不多的能够证明文学不可能高于生活的作家。
一九九七年八月十五日
# [[薇达]]/黄泉
破旧组屋伫立在荒地正中央,周遭是稀疏的枯黄植物,以及一座损毁得只余铁架,没有坐垫的跷跷板。组屋外观墙上,爬满青苔死亡后的艳红暗黑,看似鲜血的轨迹。忽然刮起的风,男子手臂上爬满鸡皮疙瘩,把外套袖子拉下。眼前的枯黄植物闻风不动,此阵风仿佛只绕着他们打转。
你确定是这里吗。男子问身边女子。女子肯定的点头。
男子携女子步入组屋,楼梯间遍布杂物及垃圾,排泄物味道灌入鼻尖,女子不以为意甚至隐隐微笑,踩着红色高跟鞋,脚步轻快愉悦,越接近目的地楼层越是兴奋。抵达目的楼层,男子跟在女子身后,转头望向路过的住户单位。窗门大开,室内却阴暗无比,男子无意与其中一个坐在沙发上阅报的老妇对望,老妇眼眶空无一物。男子吓了一跳再张望,老妇已把头埋进报纸里。大概是眼误,男子继续脚步,女子在一扇惨绿色的门前停下,伸出手,在木门上很缓慢的以固定节奏敲了7下。叩,叩,叩,叩,叩,叩,叩——
半响。惨绿木门被打门,竟是稍早阅报的老妇。
你在犹豫什么,进来呀。女子转头对倒退数步的男子说。
我按下暂停键。停格荧幕上女子诡异的微笑,苍白脸庞上有两个梨涡,非常甜美。
拎了打火机到公司楼下抽烟。昏黄街灯下有一只猫向我走来。猫的眼睛在黑暗里浑圆放大,瞳孔如细线。猫在一个距离之外停下脚步,缓缓张开口,恰巧有电单车经过。猫又对我张开口。我无从得知它仅仅是张开口,或者对我喵了一下。我把烟蒂丢在脚下踩熄,猫已经离开。
我看了看表,凌晨3点一刻。
凌晨3点,一天里阴气最重的时刻。老黄历称为寅时,夜与日的交替,太阴之止,少阳之始。医院死亡率最高的时刻,据说圣经里的耶稣也是约凌晨3点时断气。狗只齐嚎狂吠,号称吹狗螺。民间传说家中长辈告诫凌晨3点到5点之间,不要数阶梯,不要回头,不要朝西,不要照镜,不要哼童谣。许多许多的不要。我进入电梯,按了公司楼层所在的五楼。在经过四楼时,闭上眼睛,打了个呵欠。大家都说电梯会在四楼停留许久,可是没有人能具体说出是多久。四楼曾经是室内最有名的俄罗斯餐厅;数年前初入公司,我曾想过转正之后光顾,我听说过无数次这家餐厅的俄式酸汤及图拉姜饼非常美味且正宗。我转正前一日,餐厅因一场情杀案加上蓄意纵火,一直废置至今。我刷了公司门卡,进入剪接室,看着荧幕上美丽女子苍白脸庞的两个梨涡。我抚摸自己的脸颊,颧骨凹陷,民间所说的孤寡相;两腮无肉,一生贫困;下巴短窄,晚境必定凄凉。帮我看相的大师频频摇头,我低着头,无所见母亲的表情。凌晨3点切勿照镜,我无需拿出镜子都知道自己其貌不扬。我按下滑鼠,荧幕一动不动。系统当机。
重启电脑。搁在桌边的剧本阐述接下来的剧情。你在犹豫什么,进来呀。女子转头对倒退数步的男子说。男子恍恍忽忽被莫名力量牵引而入,空荡荡的客厅中央有一张长木桌,上头摆放两盏红色拜神灯,一闪一灭,一明一亮。拜神灯后方躺着几个成人手臂长的小棺材,棺材下压着几张符纸。其中一个棺材打开,黄色绒布上空无一物。男子剪下头部左边的一撮发,左眼睫毛,左手无名指指甲,放入倒满鸡血的杯中。老妇一饮而尽。杯忽然化成了刻着囍字的合卺,拜神灯忽然变成了龙凤烛。老妇的面容慢慢恢复青春,梨涡女子身形瞬间缩小变透明,飞入打开着的小棺材,在黄色绒布上闭上眼睛。男子浑浑噩噩走出客厅,从阳台一跃而下,裤脚沾染一朵阳台上不知哪个住户养的紫色凤仙,随他的坠落压得稀烂。
我读着读着剧本,直到打扫卫生的阿姨推开剪接室的门,清空垃圾桶。清晨6点,室友在公司楼下等我。吃了早餐一起返家,室友去沐浴,我坐在沙发看了一下晨间新闻睡着了。醒来室友已不在,大概是接到公司电话出门接任务。她昨日刚清洗的化妆品用具整齐的摆在餐桌上,用一条粉红色毛巾铺叠着。每一只刷子、剃刀、刮刀之间都是一样的距离。我打开化妆箱,空无一物的化妆箱一角躺着一枚金戒指。关上,打开。关上,打开。金戒指在不开灯的室内透出微弱光线。我想起剧本所描述的一闪一灭,一明一亮的红色拜神灯。童年旧居客厅神台上红色拜神灯后方是几张祖先遗相,黑白照上脸庞端庄严肃、没有笑容。某天拜神灯的灯泡一盏灯芯烧毁,另一盏跌落在地。大人们不断说另一个大人会去买,然后继续打牌,打麻将,打小孩,看马经,看电视等日常。写着作业的我抬头,感觉祖先黑白照更加阴暗了一下,仿佛随时能在漆黑里湮没。我想着想着又睡着了,醒来时已是上班时间。有光线从帘子下投入,是对面大楼的霓虹看板,或者小孩在玩手电筒镭射灯。童年时我常和妹妹躲在被窝里玩手电筒,把手电筒放在下巴扮鬼脸。妹妹咯咯的笑声多么可爱,至今我还常常听到。妹妹去世之后,我自己一个人在被窝里玩手电筒,模仿妹妹咯咯笑。某天手电筒没电了。大人们不断说另一个大人会去买,然后继续打牌,打麻将,打小孩,看马经,看电视等日常。我在被窝继续玩着不再发光的手电筒,听着推动开关发出的咯达咯达声。
我拉开帘子,对面大楼的霓虹看板正播放一则内衣广告。镶在内衣上的水晶米老鼠几乎快要在模特儿雄伟的胸口下陷窒息。
太阳经过昼夜平分点,把白天及夜晚平均分为12小时。而赤道地区的日照时间实际上比晚上长一些,为何黑夜往往感觉上比白昼漫长。我看着电脑主机上的不知谁带来的仙人球,一夜之间长出花苞,一夜之间掉落。依然紧密的白色花苞躺在盆栽泥土上,发黄,准备死去。剪接室的墙壁装设黑色隔音板,连天花板都漆成了黑色。空间把漆黑集结把情绪放大;空间太宽敞又把安全感分散,每一个角落都有什么在敛迹,每一个转身都有什么在潜伏。人心从来都习惯了作乱从来都不强壮,鬼片的操作原理不外如此。以恐惧为引,以救赎为索。恐惧是一种天敌。恐惧是一种需要,让你去寻求一些可靠并安定的力量,例如信仰,例如关系,例如自救,直到下一次恐怖来袭,直到下一次所有依靠崩毁。人心从来都不够强壮。你的恐惧是你的天敌,你的天敌是你的需要。我带了猫罐头到楼下抽烟,刚点燃烟猫就出现。它迎着光出现,脚步轻盈优雅。终于看清楚了猫的样子,是一只暹罗猫,身体为米色短毛,脸庞、四条腿及细长尾巴都是深褐色。打开罐头倒在地上,蹲着看猫埋头吃。看不清楚它舌头的颜色。身后传来脚步声,又停了下来。
街灯把身后那人的影子拖长,越过我投射在我身上投射在我前方。我没有回头。影子又转身离去。
我抬起手腕想看时间,发现忘了带手表。猫吃完了罐头在街灯下舔着自己的爪子,清理毛发,我看了它一眼,它并未回视。它从未回视。电梯又抵达四楼,我闭上眼睛,打呵欠。回到剪接室,翻开新剧本及场记纪录。场一,次三。场二,次八。场三,次一。场四,次一。场五,次五。小情侣开了几个小时的车,准备到半山腰避暑山庄度过甜蜜周末。天色渐暗,山路陡斜,沿途有几盏零零落落的路灯。男友忽然人有三急,想说随意停下在丛林里就地解决,女友递了空矿泉水瓶叫男友就地解决,男友坚持不肯。车继续往前行驶,眼前出现一座矮瓦房,贴着厕所的标志,大概是休息站。男友下车如厕,久久未归。女友正要下车查看,忽然有重物掉落在挡风玻璃上,发出巨响,血花四溅。男友的尸身,用已经分家的头颅站在引擎盖上打篮球。女友惊声尖叫。
场六,次八。我撷取片段,按下暂停键,拿起手机对着荧幕拍照。圈起其中一个位置,传给导演。
总是有些不该出现的东西。小至不应该在现场出现的布景道具如咖啡杯、鲜花、钥匙、桌布。大至不应该在现场出现的演员之外的对象。
导演没有回复。我一直工作到清晨6点。室友来寻我,我们在公司附近的便利商店吃早餐。昨天送来的大体是一具工业意外的女子,她从头顶到脖子被直直切开,送进来时是用那种做陶艺的黏土临时固定起来的。室友边比划边说。我和同事花了好久才勉强修复。同事说听到一声很轻的叹息,又如同低泣。
昨天。我疑惑。你是说今天。
不是,是昨天。现在是早上6点,我是昨天早上8点出的门。
不再区分昼夜之后,我不再去记取时间。
便利商店外坐着一只正慢条斯理舔着肚子毛发的暹罗猫,不知是不是我喂的那一只。日光下我仔细打量它,舌头是鲜嫩的粉红色,舌尖有一小块黑色斑纹。我买了一个猫罐头,打开放在地上,回公司工作。
场七,次一。刚翻开场记表我忽然觉得极累,眼皮无法睁开。梦里的自己那么小,大约才8岁,在公共游泳池里不断被什么拖着往下沉,被水呛入鼻间喉间眼里的感受那么真实。接下来的场景跳跃。我在被窝里玩着不再发亮的手电筒,抬头看见妹妹对我微笑。母亲或者某位长辈把昏迷不醒的我带到庙宇,仙姑在我身上用朱砂画上印记,庙祝不断把白米洒在我身上。母亲或者某位长辈把燃烧成符灰之后的符水灌入我嘴里,苦得要命。有一团热气如同瓦斯炉上烧开的水窜出壶嘴要从我身体窜出,找不到出口只好在我身体里流窜,经过之处留下黑色条纹好像爬虫蠕动沾上泥土的体液。被窝下妹妹的脸忽然重叠上室友的脸,她们的左边颈项同一个地方长着同样的痔。有人用力的摇晃我,我疲倦的睁开眼睛。
我疲倦的睁开眼睛,剪接室里除了我没有别人。小睡间我的口水滴在了场记表上,模糊了一些字眼。但可勉强看出场八,次六。场九,次三。场十,次二。接下来几天我没有返家。不知道为何。游乐场总是比人数多一个的孩子,大学迎新宿营的蝶仙,镜子里传出的低语声及歌唱声,浴室里怎么也关不上的红色水龙头。我仿佛着魔似的想要把所有片子剪完。医生说当眼睛使用到一个程度就会疲倦,并产生幻觉。是否真如此我已经不确定。蹲着看猫吃罐头,身后再度传来脚步声,又停了下来。街灯把身后那人的影子拖长,越过我投射在我身上投射在我前方。我没有回头。影子又转身离去。
而很多次我的生命里我没有回头,影子并没有转身离去,反而绕到我眼前。以各种型态飞舞环绕,细细碎碎。我小时候常常看见影子,完整的零碎的,透明的,有颜色的。有人形,有动物。我常常想过如果把自己的生命拍成恐怖片,我会如何去剪接。场一。阴年阴月阴时出生。场三,3岁那年第一次看见红衣女童坐在我床边,惊吓啼哭。场四,我静静坐在住家后院香蕉树下等天亮,第一声鸡啼响起第一丝光线洒下,周围的迷雾终于散去,我终于看到家近在咫尺。场九,不断有人呼唤我的名字,我已经可以视若无闻。场二十一,我8岁那年,我想跟妹妹开个玩笑,让她体会我每回下水就会有的遭遇,于是我游到深处拉着妹妹的脚把她往下拉扯,我觉得玩笑开够了刚放开手,有一个影子飘过来望了我一眼,把妹妹往下拉,我想去拯救妹妹,却被不断朝我打来的水波推开。
醒来我在医院,妹妹已经下葬。可是她常常回来看我,咯咯笑的时候,有水从鼻间流出。她每天早上6点都会来陪我吃早餐,她的左边脖子有一颗痔。她从未离开我。
我还在继续剪接,导演找我吃午餐。他说最近找到了一处卖野味的地方,让我好好补补。外面的世界阳光太灼热。我看着自己久未曝晒阳光的皮肤,仿佛吸血鬼的惨白。想来我从未剪接过吸血鬼的片子。东南亚有一种吸血鬼叫庞蒂雅娜,由难产而死的女性化成。出没时散发指甲花香,平常在空中到处飘浮,内脏垂挂在颈部以下,奇怪行动时怎么没有血液滴下呢。
导演点了几道野味,说他特别期待一道烤三六,神秘的对我眨眼。喝完甲鱼汤之后,烤三六上桌了。餐盘上烤三六尚未关上的眼睛望着我,舌尖有一小块黑色斑纹。
我离开座位,走出餐厅,在沟渠前扶着墙呕吐。
你不是不怕鬼吗。怎么连烤猫都怕。导演笑着说。
我用袖子擦去眼泪。
我怕鬼吗。不我不怕鬼。妹妹坐在我身边,对着烤三六扯开嘴。大片大片水从嘴角流出,沾湿红色桌布。
我觉得自己比鬼还可怕。
我想回到剪接室。被各种影子所环绕,那里才是我的归属。黑暗如同一条通往黄泉的路,没有声响没有温度。没有生息。我没有生息。
作者 : 薇达
文章来源 : 星洲日报 2021-03-09
# [[薇达]]/女子今有行
深夜。雨水从现形到狂轰只在一瞬,城市这一端被暴雨灌满。有些雨漫长而郁闷,有些雨强强弱弱停停下下,有些雨稍纵即逝。而这场雨有疾风袭击,窗前挂着的风铃用力颤动,细长丝线已经打结依然激烈旋转。我想起儿时家里养的名叫山竹的狗,它总追着自己的尾巴在原地打圈圈,然而它腿长尾短,怎样都够不着,越追不到就越紧张滑稽极了。我们小时候常常边吃零食边看山竹追尾巴看上很久,我最喜欢带糖的梳打饼,还有一种上头有不同颜色糖霜的圆形小饼干,即使表妹用小鱼或小熊饼干我都不肯交换。
妈妈你记得不记得山竹。我问。
当然。它可勇猛了,从前我们住在芭里,我跟你阿姨在山里迷路,遇到小山猪,一只野狗冲出来把它赶跑。我们把它带回家,叫它山猪。直到榴梿园里那个会听华语的马来员工向你外公抗议,说不能叫猪什么的,我们才把它改名为山竹。妈妈说。
山竹随妈妈从五条嫁到市区。大家都戏称山竹是母亲的陪嫁,妈妈出嫁的照片里山竹脖子上还扎着红色丝带,站在最前排喜气又神气。许多宾客都摸头称赞山竹,还给了它红包,山竹短而粗壮的尾巴快乐的摇了整天没停过。
3天后就是婚礼了。妈妈说。
对呀所以我睡不着。我答。
我们坐在沙发上,一起看《葡萄仙子》,五〇年代的香港旧电影。富家子弟邂逅了公司小职员,假扮同事亲近她,最后在游艺会表露身分,顺利抱得美人归。快转到大华百货里唱片部锺情向金峰解释,这唱片是78转,这是45转,顾客来了的话先让顾客看目录,然后放起姚莉的〈我要为你歌唱〉:我要为你歌唱,唱出我心里的舒畅,只因你带给我希望带给我希望……
前面还有一段更好听呢。我回转给妈妈看。锺情靠着柜台随音乐唱起:心许你,因为你太美丽,你是红花我是绿叶,我要陪伴你……
你怎么从印度回来之后就爱看老电影。妈妈问。
我小时候就喜欢看呀,你忘了你从前睡前把电视锁起来,就是为了防止我半夜偷偷看电视播放的老电影。我说。
家贼难防。我怎么藏你都能找到钥匙,把声量调得最低看得津津有味。妈妈摇头。
老电影的字幕有那么大。我用手比划。只是可惜那时为了怕你发现而调成静音,错过了许多好听的歌曲,现在慢慢补回。
我们明天看乐蒂的《太太万岁》吧,妈妈回房前说。
我才不要,太太万岁里没有好听的歌,我宁愿看桃花江或者那个不多情。我说。
电影继续往下演,在众人为锺情庆生,唱着快乐的诞辰在今朝时我眼皮渐重,陷入睡眠时雨还在下。早晨妈妈叫我起身出门,我们在四马路的熟食中心吃了水粿及猪肚汤,炒得油光的甜菜脯配搭三峇辣椒味道一绝。到六马路的华丽裁缝店取修改的旗袍,时间太早,华丽裁缝店斜对面的贻山面包店的我最喜欢的椰丝面包尚未出炉,妈妈与老板闲聊几句买了一条白面包及一罐咖椰,临走前又到T字路口打包菜头粿。不要辣,要多甜酱,我对老板说。菜头粿摊对面是一家马来小店,里头马来炒面很好吃;隔壁是一家印度理发店,可是前几年都结束了营业。
六马路这一区大多数房子早期都由木板搭建,年久失修后补砌上更多木板或者砖瓦;里头租户换了好几批,长年下来依然是仿佛容易被风推摧的木板屋型态。童年时我和表妹每回骑着脚踏车在附近溜弯,总会指着某家某家说这屋子应该可以再撑几年那屋子应该明年就塌了,还边模拟屋里人在木板屋坍塌之后逃出的狼狈模样。而如今里头的人早已不知何处去,木板屋依然健在,在风吹雨打时摇摇欲坠,依然伫立。
这一区很多人家里还是没有热水器跟抽水马桶。上了厕所就从旁边的水桶舀一桶水把排泄物冲入粪坑,要洗澡时还得取个大锅在煤气炉上烧热水。妈妈说。
华丽裁缝店同排有家中药店。已经移民的表妹前几天听说我回到家乡,提起我们童年时最爱到中药店前的大冰柜,有时是酸梅冰,有时是和路雪牌的彩虹雪糕,那洗脑的广告歌到现在还能唱完整哼出。她问了我一些细节之后说小镇变化不大,不像国外大都市,变化如同喝水吃饭,例如她公司大楼楼下的小店铺,去年是服装店几个月后变成珍珠奶茶店,现在是韩式炸鸡店。
变化还是有的。我告诉表妹。许多人决定留下或逐渐回归,把小镇发展起来。特别是一处由货柜打造的小广场,里头设有不少网红咖啡馆餐厅,还有一家日本餐厅及精品酒店,每到假日周末人满为患。
那些西式咖啡我不懂欣赏,我还是喜欢434咖啡。妈妈恰好经过,对视讯那端的表妹说。
我前天想吹冷气带妈妈去了星巴克,替她点了卡布奇诺,她说要咖啡加牛奶。结果她加了6包糖。我耸肩。
妈妈爱喝咖啡,三餐后必泡一杯即溶咖啡,有时看电视无聊又冲了一杯,拿梳打饼或油条沾着咖啡吃。去年起她常抱怨夜里难以入眠,却坚决否认是咖啡因的缘故。我曾建议她尝试低咖啡因或无咖啡因咖啡,她破口大骂这是什么鬼东西,褐色的白开水吗。
于是她睡不着的夜里我们开始看旧电影。第一部看的是《特别快车》。看完蔷薇歌舞团唱唱跳跳新天地。我问妈妈怎么没给我生出锺情那样的长腿细腰。
妈妈看着我空了的红酒杯说,你要去厨房吗,顺便帮我泡杯咖啡。
也不知道为什么你喜欢喝那玩意儿,红色的比较不酸的醋,又呛。妈妈又说。
妈妈不喝酒,顶多过年时喝一小罐仙地,来解肉干的油腻。结婚时不喝交杯酒吗我问。
交杯酒是古时候或者电影里的情节,妈妈说。我们那个时代结婚哪有那么多花样,早上起来随便一个亲戚来化妆梳头,穿上租来的礼服,在家门前拍几张合照及大合照,迎亲敬茶,晚上办婚宴。就这样了。
婚礼前两日。我们各坐在沙发另一端,看《哪个不多情》。锺情刷着秀发唱着春风吻上我的脸。我边看边赞叹她的腰真的好细,妈妈你说如果我现在去剪锺情这样的头发好不好看。妈妈没理我只叫我赶快转到董佩佩唱花开蝴蝶来那段,又叹到当初玉树临风的曾江如今也是个老头了。
妈妈青春永驻,干杯。我拿红酒杯碰了一下妈妈的马克杯。妈妈我们看这段,姚莉跟杨光合唱的〈月下情歌〉,姑娘呀她生来俏模样,俏模样。
其实那时结婚要喝交杯酒的。妈妈声音很低,我听得清楚,继续按着手中遥控器的快进键。
你阿姨是中学老师,对结婚礼俗坚持的很。交杯酒是一定有的,表示一生一世把臂交心同甘共渡。要喝交杯酒时你爸说他来倒酒,却一不小心把酒壶跟酒杯打翻,在地上碎成稀烂。身边的人愣了一阵回神马上说了很多吉祥话,碎碎平安,爱意绵长,今晚兰房双对望,白头偕老百年长。
我那时就知道。其实我从相亲时就知道,你爸从来没有忘记那个嫁入豪门的女人。
那时你怎么不离婚。我说。
我们那个时候,只要老公每天晚上回家,每月定时给家用。不做出任何出格的事,同床异梦都不构成太大伤害,更何况后来有了你。我想说睁一只眼闭一只眼,至少等到你上了大学,我就搬走,离婚不离婚没差,反正眼不见为净。
你知道我们后来为何离婚吗?只因为那女人怕狗,有一次她来找你爸借书,山竹冲出去朝她狂吠,那女人吓得梨花带泪,哭得你爸心疼不已。为了让她能不断来找你爸借书还书,你爸在山竹的饭里下了毒药。那日山竹七孔流血,身体冰凉僵硬的死在我房门前。门上好多抓痕,山竹一定是拼命的抓门求救,可是你爸放着古典音乐说可以助眠让我无法听见。
我坚持要离婚,你爸不了解为什么我要为了一只畜牲离婚。山竹是我的家人,你爸才是畜牲。
妈妈低头望着马克杯,声音很平静。
我正想说妈妈不如我们看《太太万岁》,耳里听到一阵响亮的鸣泣声。
我和妈妈披上外套拿了手电筒,走出屋子在社区里探照行寻。起风了落雨也不远,空气里有即将下雨前的咸,在杂货店前的垃圾堆里看到一只极小的猫在用力发抖,看见我们开始喵,仿佛用尽全身力气在鸣叫。我把小猫拎起,那么那么小只稍稍大过我的手掌。
我们把小猫带回家。用温水给它擦澡,全身泥巴褪去,跟山竹的花色好像哦妈妈说。小猫很乖巧用吹风机给它吹干毛发也不吵不叫,眼神流露出恐惧。妈妈拿出从前山竹的狗龙,在纸箱里放了一些旧衣服。小猫喝了牛奶爬进纸箱里,把自己埋在旧衣服里缩成一团,姿势非常惶恐不安。
你的陪嫁。妈妈说。
我才不要,翻了一个白眼。
第二天带小猫去看兽医,喂了驱虫药,暂时放在兽医处,我们前往预约好的挽面姑住处。挽面姑在我脸上擦了一层香粉,口里咬着纱线手里拿着另一端在我脸上游走去除绒毛,每动一下都痛得我哇哇叫。轮到妈妈时面不改色,我抚摸着还残余痛楚的脸问妈妈真的不痛吗。
你们前几辈的女人的我们,例如我,例如你外婆,我们擅长忍。妈妈微笑说。
你很多年前出嫁时被我妈挽面哭得稀里哗啦,叫得比我邻居家的狗还大声。挽面姑毫不给脸的拆台。
从前女人出嫁前一天才会来找我挽面,现在常常有年轻人预约,男女都有,当日常美容项目。还有好几个年轻女孩来找我学艺,到大城市开挽面工作室。几十年前大马路到六马路所有女孩出嫁前都是我妈跟她师妹挽的面,有些吉日一天要跑十来场。挽面姑说,忆起旧时辉煌脸盘发亮。
挽面姑明年大概也要退休了。离开挽面姑的住处妈妈说。挽面姑在院子里浇水,水梅开得正盛,香气扑鼻。她从院子里剪了一堆香兰叶要母亲带走,说明天可以煮汤圆。
挽面姑母亲的师妹癌症去世后,挽面姑的母亲养大了师妹的女儿并传授挽面手艺。师妹的女儿上电视台的综艺节目说自己来自古早挽面世家,诉说挽面的坏处并会让皮肤彻底溃烂。那一阵挽面姑的家常常被泼粪水及鸡血,还有人丢点燃的鞭炮,差点把挽面姑的家烧毁。后来就搬到了比较偏僻的住宅区,不再上门服务,只靠熟人口耳相传介绍。
师妹女儿图的是什么。她后来过得如何没有人知晓也没有人在乎。妈妈曾听说上电视几年后她曾求挽面姑原谅收留,跪在雨中声泪俱下,某一天她随着放晴的天气消失无踪,如同雨水蒸发得干干净净。挽面姑一生独身,从未豢养任何宠物,屋子里连蟑螂壁虎都没有一只。也许挽面姑在挽面之际或之后见证了过多各类关系的真伪。
我怎敢问呀,妈妈说,话刚启个头就被挽面姑忽悠去打麻将,一局下来输掉整月工资。
所以我要学会打麻将以逃避三姑六婆的八卦追问。我自觉自己捉到了重点。
你这个连用计算机都会算错账目的数字白痴,算了吧。母亲把猫粮倒入碗中,专注看着小猫狼吞虎咽,连鄙视的眼神都不给我。
明天要出嫁了,你说我们要看恨嫁还是阿珍要出嫁。我问妈妈。
看一见钟情吧,妈妈说。我总是记得里头鍾情跳恰恰穿的那件白色洋装,领口处镶两颗闪亮的大纽扣,腰上系一条小皮带,搭配那串长项链,青春又摩登。
跳一个恰恰恰,青春不老;跳一个恰恰恰,精神焕发;你不跳恰恰恰,就是傻瓜。鍾情与两个男舞者在人群的围观边唱边跳恰恰。
在和你爸相亲前我曾和学校男同学恋爱,后来他搬到邻国,写了几封信再无下落。妈妈说。他长得跟锺情右边那个男者一模一样。
你还会想起他吗。我问。
刚开始常常想,后来越来越淡,现在甚至不太想得起他长什么样子。那时还哭着跟女同学说,我一辈子都会记得他。年轻时脱口而出的一辈子不能算数,还没经过社会敲打。妈妈自嘲。
那你还说他和这男舞者长得一模一样。我指着电视说。
记忆是这样告诉我的。妈妈坚持。
也可能是你擅自篡改了记忆。我说。假如某些时刻的自己太难堪,无法扭转事实便只能以微调回忆来圆谎。
那你还会想起他吗。妈妈问。
被门铃声吵醒,室外一片漆黑。清晨5点,化妆师及阿姨们鱼贯而入,妈妈早已醒来在厨房搓汤圆。
妈妈你去化妆,我来搓吧。我洗了把脸,坐下接手。
厨房桌上摆着去年从印度菩提迦折来的菩提枝。当初折下时,想要将它栽培成树;却在成功扦插活,开始有继续生长的痕迹后,从土里连根拔起,放置阳光下晒干,放在厨房桌上玻璃瓶里当摆设。
那你还会想起他吗。昨天妈妈问。
和我一同前往印度蜜月旅行的人停留在那里。说他大彻大悟,红尘喧嚣,要潜心求道,追寻人生真谛。后来在社交媒体上看到他着一袭白色长袍,留起长发系起胡子,很有几分禅师的模样。说苦行即修行,罪恶之洗涤;坚固道念,莫失初心……。
当初那个与我在玫瑰泡沫浴里吃鱼子酱喝香槟,吃炸鸡喝啤酒熬夜追剧,等公车超过5分钟就大发雷霆,踩到口香糖会骂脏话,买菜要老板送葱送蒜送香菜的那个人,那个人是怎么在几朝之间截然不同。还是同一个人吗。莫不是被人夺舍了,被一个得道高僧之类的魂魄占据了躯壳,我还曾真如此怀疑。
其实我也知道我只是无法接受改变并且失去。谁又能安然接受曾经最亲近最珍贵忽然反面无情形同陌路。
妞妞你妈妈要喝咖啡,要两包。阿姨从妈妈房间吆喝。
我泡好咖啡端进妈妈房间。阿姨们正往墙上柜门贴囍字,边贴边问我妞妞贴得正不正好像歪了。妞妞你手巧你来贴。
从印度回返后,我过得浑浑噩噩,每翻一张日历就被抽走一丝力气,随时能被抽得干干净净。我辞掉首都的工作,回到出生成长的小镇,和阿姨们一起准备妈妈的婚礼。妈妈去年在菜市场买菜巧遇中学时暗恋她的老同学,相处下来决定一起过日子。男方执意要给她一个正式的迎亲及婚礼。
于是每日,去童年时常去的食阁用餐,去童年时常去的购物中心或杂货店买日常用品,随妈妈阿姨走遍大街小巷的老店,置办婚礼所需的物品。小镇里大多数老店铺还在经营只是换了下一代。到海边看那片一直浑浊的海,远方有渔船行驶,渔夫在船上撒网;有几个大叔坐在隄岸上钓鱼。到母校看稚嫩脸孔白色百褶裙脚在奔跑间轻轻飞起,青春而纯净;有几个老师还记得我,有几个已经快退休。小镇节奏如水往前流动,缓慢而温柔的浪花包覆起所有沉默的伤口。我逐渐长了肉,能和妈妈互怼,能关灯入睡。
也了然生活并不附带选择题,有些难题是自己设的与自己过不去的情绪关卡,卡久了会压抑成心魔。时间里小镇里平静下来是很美好的过关形式。
小镇的一切,人事物,与我记忆里没有太大的出入。大概也因为如此,无论离开多久回来都能即刻融入,有时还会恍忽仿佛自己从未离开太久。有的地方适合行经,有的地方适合长居,有的地方适合短暂逗留,有的地方适合回归。
有的地方适合回归。即使你时不时会离开,但也时不时会回来。它的存在让你知道并珍惜回归的意义。
我多么幸运,有一个小镇待我回归。每一个有着一个小镇可以回归的人都幸运。
屋外响起车笛声,新郎来迎亲了。阿姨大喊还不到吉时不要让他们进来。一阵兵荒马乱后,完成所有仪式,我把系着红色丝带的小猫递给妈妈,说别忘了你的陪嫁。
它叫山猪。我又说。
妈妈说了什么我听不清楚,吵杂声里被新郎迎上车。小猫还捧在我的手里,新娘车绝尘而去,留下一地彩带鲜花。
女子今有行,大江溯轻舟。古时诗人为女儿出嫁写出一首传诵千古的诗,我文采不佳,无法为母亲的再嫁赋歌做词。古时女子出嫁动辄千万里,要跋山涉水翻坡越岭才能返回娘家。而妈妈也只是嫁到后面那条街。
我把小猫放回猫笼,看它欢快的舔着牛奶。坐下打开笔电,点开求职网站。且行且安,我不再有犹豫。
# [[薇达]]/香香
房间空荡荡,四面斑驳的惨绿色的墙,中央摆着一张掉漆的红色皮沙发,用黑色胶布黏起撕开的裂口。沙发是前住客留下,大概是从大楼后方垃圾场捡回来的。房东说。从前那个垃圾场好精彩的,有好多很新还能用的好东西。不过现在大家都穷,垃圾场就只剩垃圾了还有旁边菜市场丢弃的剩菜。很多外劳流浪汉去那边拉屎顺便捡剩菜。
妹妹仔你几时开业,我叫朋友来捧场,这里很少你这种清纯学生妹,一定很受欢迎。房东递来一把系着红丝带的钥匙。
我在后面美术学院念书。我只是穷,这里房租便宜。我把手从房东手里抽出,关门上锁。
楼上租客动作很大,震得天花板悬挂的昏黄灯泡摇晃。摇一摇灯光开始忽亮忽闪,室内忽明忽暗。灯泡发出滋滋滋声,彻底熄灭。大概钨丝烧坏了。
我从行李袋找出睡袋在地上舖开。我想好好睡一睡。
醒来。房间唯一的窗口在浴室。我从浴室窗口看出去,天色灰白约莫是黄昏之末。隔壁租客把晒衣竹架挂在我窗前。洗得发黄印着祝君早安的毛巾,一件黑色内衣,几条肉色丝袜其中一条破了几个大洞。走廊与楼梯间的日光灯一闪一暗,整座酒店无论白天或黑夜都昏暗。走进附近的香烛店,低头打着盹烫着爆炸头的老板娘在我踏入店门马上睁开眼睛朗声问我妹妹仔要买咩。
一包香两叠刈金一叠大银一叠小银我回答。
妹妹仔要拜什么呀。给十方好兄弟要烧祖先金,过路钱也可以。我从前有个客人说她每天烧给老公收不到,老公觉得她一定是没有好好守寡才忘了烧钱天天来梦里打她。原来她烧错了每次都烧刈金,其实她应该要烧大银小银。刈金是要给死了3年以上的,土地公也可以。
她来买纸钱时身上都是黑色手印,颈项肩膀都有,很吓人呢。老板娘摸了摸脖子,把塑胶袋递给我。妹妹仔烧得开心再来光顾。
有黑色的鸟飞过。我猜想是乌鸦。我有个同学养了好几年的八哥,后来才知道那是乌鸦,她很难过的把笼子打开可是乌鸦不愿离去。她停止喂食,可是乌鸦依然每天出门觅食,再回到门从未锁上的笼子里睡觉。某天乌鸦没有回来,她不以为意,好几天了乌鸦都没出现。她出门找了很久走了很久的路。奇怪。那一天整个小区的乌鸦仿佛约好了躲起来一样。平常随处可见的黑色鸟一只未见,屋簷上柏油路旁尽是白色灰色或混色的鸽子鸽子无处不在。她哭着回家。笼子的门一直开着。乌鸦一直没有回来。
我回到住处,从行李袋里拿出铁盆跟打火机。走进浴室,推开窗口,烧起纸钱。屋子唯一的窗口在浴室,我不想被别人误会我烧炭自杀。
点了蚊香。客厅里好多蚊子。我几个月前做过一张作业,花了整个晚上在草丛里打死好多蚊子,把蚊子黏成一个女子的头像残影,再用红色水彩刷过一遍。马来传说里,满刺加苏丹马末沙向金山仙女求爱,仙女要求他建造一座金银桥,七盘蚊子心脏,七盘飞蛾心脏,苏丹都答应了。仙女再提出要苏丹及其儿子们的血各一杯,苏丹舍不得付出自己及孩子的血液才打消了念头。
我想着下次可以用飞蛾尸体来做一些作品,飞蛾比蚊子容易捕捉,只要灯火通明就可。我想着想着睡着了。
想着想着睡着了。醒来时天还未亮。或者是一个天不会亮起的阴天。灰白天幕灰色的云。灰色的天花板。周遭都那般灰。某处传来隐约音乐是一只旧歌。仿佛曾经听过,老旧杂货店裁缝店都会放的那种曲调,适合埋头苦干或发呆打瞌睡。我拿出画本,又放下。到厕所梳洗,地板上的铁盆里装着昨夜烧完的纸钱。我弯腰拎起一团乌黑,即刻在手中散成灰烬。我站起身体,脚下踩到了什么。
是一张没烧到的大银。
烧纸钱时一两张纸钱从铁盆飞出来是常见的事,有人说是风,有人说是气流。纸在烧时会起旋风,是亲人来收钱啦常叔那么说。如果圈外的纸钱在地上飘,表示是孤魂野鬼来偷钱啦。如果在圈外的纸钱飘起动静很大,表示是厉鬼来抢钱,烧了亲人也收不到都被抢走了。还有呀给亲人千万不能烧金纸呀,金纸是鬼道在用的,贪图金纸会坠入鬼道的。烧钱很多忌讳的呀,妹妹以后烧给常叔要记得,要不然常叔收不到。
常叔原本是隔壁殡葬店的员工,殡葬店倒闭后来母亲裁缝店当伙计,在母亲过世后接手了裁缝店。
我把大银压在铁盆下。热水刚好烧开,浇入杯面,飘出咖喱味。面没泡久一点都不软,我一口接一口很快把面吃完,快步下楼走到隔壁菜市场旁的垃圾场。我把手上的塑胶袋丢入垃圾槽,正好赶上垃圾车来清理垃圾槽把垃圾载走。一个穿着吉祥宝牌汽水衣服的外劳还在垃圾桶里翻找,被垃圾车员工斥责后慢慢走开。吉祥宝这个牌子的汽水我小时候常喝,绿色瓶子,都是色素,酸酸甜甜。
大榕树下的土地公庙前有人在拍戏。有一个穿着土地公服的演员坐在树下的凳子上。剧组都是马来人说的是马来话,大抵是马来戏剧或电影,为何会出现土地公。我好奇停下脚步看了一下,想看出是什么剧情。
你新搬来里奇摩尔酒店吗,住在几楼,之前没看过你。那个扮演土地公的演员不知何时来到我身后。
我没有回答就离开。酒店大门口保安在听着收音机,那种仿佛曾经听过,老旧杂货店裁缝店都会放的曲调,适合埋头苦干或发呆打瞌睡。保安一直低着头打瞌睡。不知为何酒店电梯只往上不往下,下楼要走楼梯。我关起画本时已经入夜。入夜之前果然都是阴天,一丝阳光都没灰白天幕灰色的云从灰色慢慢变黑。我放下画本天黑了我没有开灯。我习惯不开灯。母亲从前常说要省电,能不开灯就不开灯,有时只点着一盏煤油灯就着微弱光线车衣缝钮扣。很快眼睛就出问题,近乎半盲,有一天早上出门丢垃圾被车撞飞失了性命。常叔接手裁缝店之后让我继续住在店里的储藏室;常叔进监狱之后我无处可去,只好搬来中央车站附近的里奇摩尔酒店。酒店地下一楼是美食中心一楼是商店,楼上房间专门租给妓女居住兼接客,声名狼藉,但租金便宜异常便宜。
我又泡了杯面。隔壁传来女子娇声喘气,男声嘶吼着我听不懂的语言。我看着自己的画本,上面仅有炭笔画出的草稿。我只剩下黑色颜料。想起刚下楼丢垃圾时看见三楼有人在泼红漆,大概是有妓女欠了高利贷。拿着画本画笔到了三楼,油漆果然还未干。墙上写着贱人,还钱。我席地而坐拿画笔沾墙上红漆,沿着草稿上的弧线上色。墙上写着贱人,还钱。我沿着弧线上色。三楼没有声响仿佛无人居住。三楼如此安静世界如此安静。我静静画了几个小时。
又几日。我下楼丢垃圾顺便买杯面。大榕树下的土地公庙依然是同一个剧组,在拍着同一个场景,土地公给了几个马来人真字,马来人中马票之后没有还愿频频倒楣,只好请马来巫师来与土地公斗法。几天了怎么还在拍一个场景我在心里想。
他们回去之后发现之前拍的画面都不见了。土地公演员又不知在何时走到我身后。他们不信邪,重拍了几天还是一样,内容无法读取。今天尝试最后一次,如果不行就改剧本。
你新搬来里奇摩尔酒店吗,没有见过你。开业了吗。土地公演员继续问。
80令吉。我说。
我下班后来找你。他耸耸肩。
我告诉了他我的楼层及房号,从提袋里拿出要丢的塑胶袋。
你在丢什么。每天看你都在丢类似的塑胶袋。
我没有回答就离开,走到菜市场丢垃圾。一个穿着绿色吉祥宝汽水衣服的外劳在翻找垃圾,不知是同一个还是其他外劳。看着垃圾车把垃圾槽清空把所有垃圾载走,我转身离开。酒店门口保安还在打瞌睡,收音机在播着旧梦不需记,逝去种种昨日经已死。
旧梦不需记,逝去种种昨日经已死。呵。
你知道为什么电梯只往上不往下吗。曾经有妓女被跑帐,嫖客乘着妓女去洗澡时坐电梯逃跑。太多妓女投诉后管理层把电梯设定改了。但是还是有妓女被跑帐呀,女人哪里跑得过男人。完事后土地公演员告诉我。我在浴室穿上衣服,把80令吉压在铁盆下。土地公演员走后我拿着画本画笔到三楼。今天高利贷又泼了新的红漆。我席地而坐拿画笔沾墙上红漆,沿着草稿上的弧线上色。墙上写着死贱人,还钱。我沿着弧线上色。三楼没有声响仿佛无人居住。三楼如此安静世界如此安静。我静静画了几个小时。
天黑了天亮了。又是一夜。时间过得很快。某些日子开始时间变得很快。土地公演员成了我的常客。他每次从剧组下班后就会过来。有时带午餐肉罐头来,或者三文鱼罐头加梳打饼。他叫我不要每天吃杯面,对身体不好。午餐肉罐头跟梳打饼也对身体不好呀我笑说。很多电影电视剧的土地公都是我扮演的呢,行内都说我最能演出土地公的神韵跟气势。我从没看过他卸妆的样子。脱掉土地公的戏服,脸上依然有老人妆及长胡子。胡子弄得我发痒,我抱怨过几次。他把胡子拿下来,下巴有刚生出的胡渣。
那个马来电影如何了我问。
他们试拍最后一次,还是无法读取。后来把土地公那幕拿掉了,再拍之后发现片段依然无法读取,才发现原来是记忆卡的问题。土地公演员说着哈哈大笑。
我后天要演拿督公,所以明天要去拜拿督公,打个招呼,你知道怎么拜拿督公吗。
拿督公金,甘文烟,咖啡,我边开午餐肉罐头边回答。土地公演员惊讶看着我。
我母亲从前的伙计告诉我的,他在殡葬店工作过。我说,感觉痛轻呼了一下。手指被罐头边缘割伤。
我把手指放进嘴里吸吮,血腥味在唇舌间散开。
土地公演员走了,我把空罐头丢进垃圾桶。垃圾桶里躺着几团卫生纸,溅在白色卫生纸上的血液鲜红而刺眼。母亲死后常叔让我住在裁缝店的储藏室,帮我付学费,偶尔给我一些零用钱。我每一笔都仔细的记录在笔记本上,以后要还给常叔即使他说不用。偶尔我写完作业会帮忙常叔做一些店里的工作。我没有继承母亲的裁缝天分,连缝一个钮扣都会刺穿手指。常叔摇摇头说你除了长相没有一点像你妈,拿胶布给我贴在伤口上。
一只乌鸦停在阳台上。我晒衣服时想起隔壁已经好几天没晒衣服。是搬走了还是没生意。没生意就无需穿衣服或清洗内裤。我晒衣服时曾经看见隔壁租客依着窗口抽烟,赤裸着身体非常的瘦可是胸部惊人的大。她静静看着前方抽烟,抽完了就把烟蒂往窗外丢。好几天没看见她好几天没闻到烟味。晒完衣服乌鸦还没飞走。我想起同学的乌鸦。乌鸦一直没有回来,她哭了好几天乌鸦一直没有回来。那么多年了她还记得乌鸦吗。后来她嫁人,老公买了几只黄金猎犬给她。她常常在社交网站上放幸福家庭照,与三个可爱而精致的儿子微胖的富商老公坐在水晶灯下的豪华皮沙发上,几只戴着领结的黄金猎犬趴在脚边。她大抵已经不记得乌鸦了。谁会去记取年少的伤痕呢并且随着年月过去越来越微不足道。
土地公演员好几天没来。我下楼丢垃圾。在垃圾槽旁看到一个塑胶矮凳,很适合我在二楼坐着沾红漆作画。我拎起走回酒店,保安竟然醒着没在打瞌睡,看着我手上的凳子问妹妹仔从垃圾场捡到什么呀,东西不要乱捡呀。
旧梦不需记,从前情爱何用多等待,万千恩怨让我尽还你收音机唱着忽然卡在你你你你你你。保安把卡带从收音机拿出,边用原子笔把松了的卡带胶卷慢慢卷回边说,垃圾场的东西不要乱捡呀。从前有个妓女在垃圾场捡到了一包钱,很开心的买了很多东西,后来某天邻居闻到臭味,警察撞开房门发现她上吊在自己的房间里,尸体已经腐烂面目全非。她就住在三楼你知道为什么三楼几乎没人住吗。这里的三楼加上地下一楼跟一楼二楼其实是四楼呀,很多事情发生的。垃圾场的东西不要乱捡呀妹妹仔。
我把矮凳留在三楼。回到自己的房间。我拿出画本,想要做同学讨论群组说的教授吩咐的作业。我在美术学院的讨论区里而我没有进入美术学院我缴不起学费,我把唯一愿意帮我缴学费的人送进了监狱。
我把厕所地板上的铁盆移开,下面压着一叠大银一叠小银,以及土地公演员给的钞票。门被敲响,我打开,是一个玉皇大帝装扮的男子。土地公演员笑着说我这几天拍夜戏了,戏分还不少,有十多句台词呢。
你叫什么名字。完事后土地公演员忽然问我。
香香。香味的香。我说。
是假名吧。他笑。你们从来不会告诉我们本名。
对呀是假名。我笑,打开他带来的苏打饼。
我中学时有个同学叫香香,头发很长到腰间,大家都说她是全校最美的女生。每回她路过大家都会闻到一股香味,像草莓又像樱桃。
你叫什么名字。我问,把梳打饼递给他。
我叫志强,本名,烂大街的名字。他笑笑,吃完梳打饼穿上裤子走了。
我把厕所地板上的铁盆移开,把80令吉放在一叠大银一叠小银,以及土地公演员之前给的钞票上。拿出笔记本,画掉最后一笔,我欠常叔的钱已经赚足了,如今应该烧给他。美术学院同学讨论群组里提起我的名字,问我为何没来上课。我没有回应。我再也缴不起学费,我把唯一愿意帮我缴学费的人送进了监狱。那晚我刚下课,脱下衬衫穿着内衣在缝脱落的钮扣。储藏室的门忽然被推开,常叔喝得醉醺醺的走过来,叫着母亲的名字把我推倒。我从来不知道看起来瘦弱比我还矮的常叔力气那么大。他把我压得死死的进入了我,射精后翻身呼呼大睡。我穿上睡裙拿着沾满他精液的内裤走到警察局。
他被判了7年。进去几个月他在监狱里用一支牙刷自杀。刺穿喉咙,死状惨烈。
他判刑那天是我的中学毕业典礼,那个叫志强的男生篮球队的中锋红着脸递给我一封情书,他低着头结结巴巴的说话,颈项3颗相连的痔随着他动作摇晃。我没有接过只是转身离开,到理发店剪掉了及腰的长发。香香你真的要剪掉吗,好可惜呀理发师问我。我用力点头。我从没看过土地公演员卸妆的样子,他的胡子弄得我发痒,我抱怨过几次,他把胡子拿下来,下巴有刚生出的胡渣。我认得他颈项间3颗相连的黑痣,我曾无数次幻想,自己的嘴唇亲吻过他的脖子那3颗相连的黑痣。
我把大银小银及所有欠常叔的钱以及记账的笔记本丢入铁盆,念着常叔的名字点了火。看着所有纸钱及钞票烧成灰烬。我把所有物品塞入大背袋。今天租约到期。把钥匙放在桌上,背着背袋走到垃圾场。天还没亮。
我把最后一个塑胶袋从背袋里拿出,丢入垃圾槽。
常叔留下遗书说把他的骨灰分成30个塑胶袋,每天丢一个进垃圾桶里。他是垃圾,只值得丢垃圾槽。他说这样做他将无法投胎但是他应得的。他对不起我对不起我母亲。
从前那个垃圾场好精彩的,有好多很新还能用的好东西呢房东那般说。
再残缺的东西,在不同人眼中有不同用处。我们丢弃之物,也许是他人一生的求而不得。
可是。我有什么求而不得。我甚至从来没有拥有什么渴慕什么。除了。
我想起志强脖子上那3颗相连的黑痣,落下眼泪,把大背袋丢在垃圾槽里。
转身之前,那个穿着绿色吉祥宝衣服的外劳又出现,拎起我丢下的背袋快速离开。我凄然的笑。
旧事不需记,从前情爱何用多等待,万千恩怨让我尽还你。我轻轻唱起。
我要离开这个城市了。我不知道要去哪里,但。
旧事不需记。
作者 : 薇达
文章来源 : 星洲日报 2021-01-19
娓娓与喋喋-余光中
========================
娓娓与喋喋-[[余光中]]
-----
不知道我们这一生究竟要讲多少句话?如果有一种电脑可以统计,像日行万步的人所带的计步器那样,我相信其结果必定是天文数字,其长,可以绕地球几周,其密,可以下大雨几场。情形当然因人而异。有人说话如参禅,能少说就少说,最好是不说,尽在不言之中。有人说话如嘶蝉,并不一定要说什么,只是无意识的口腔运动而已。说话,有时只是掀唇摇舌,有时是为了表情达意,有时,却也是一种艺术。许多人说话只是避免冷场,并不要表达什么思想,因为他们的思想本就不多。至于说话而成艺术,一语而妙天下,那是可遇而不可求:要记入《世说新语》或《约翰生传》才行。哲人桑塔耶纳就说:“雄辩滔滔是民主的艺术,清谈娓娓的艺术却属于贵族。”他所指的贵族不是阶级,而是趣味。
最常见的该是两个人的对话。其间的差别当然是大极了。对象若是法官、医师、警察、主考之类,对话不但紧张,有时恐怕还颇危险,乐趣当然是谈不上的。朋友之间无所用心的闲谈,如果两人的识见相当,而又彼此欣赏,那真是最快意的事了。如果双方的识见悬殊,那就好像下棋让子,玩得总是不畅。要紧的是双方的境界能够交接,倒不一定两人都有口才,因为口才宜于应敌,却不宜用来待友。甚至也不必都能健谈:往往一个健谈,一个善听,反而是最理想的配合。可贵的在于共鸣,不,在于默契。真正的知己,就算是脉脉相对,无声也胜似有声:这情景当然也可以包括夫妻和情人。
这世界如果尽是健谈的人,就太可怕了。每一个健谈的人都需要一个善听的朋友,没有灵耳,巧舌拿来做什么呢?英国散文家海斯立德说:“交谈之道不但在会说,也在会听。”在公平的原则下,一个人要说得尽兴,必须有另一个人听得入神。如果说话是权利,听话就是义务,而义务应该轮流负担。同时,仔细听人说话,轮到自己说时,才能充分切题。我有一些朋友,迄未养成善听人言的美德,所以跟人交谈,往往像在自言自语。凡是音乐家,一定先能听音辨声,先能收,才能发。仔细听人说话,是表示尊敬与关心。善言,能赢得听众。善听,才赢得朋友。
如果是几个人聚谈,又不同了。有时座中一人侃侃健谈,众人睽睽恭听,那人不是上司、前辈,便是德高望重,自然拥有发言权,甚至插口之权,其他的人就只有斟酒点烟、随声附和的份了。有时见解出众、口舌便捷的人,也能独搅话题,语惊四座。有时座上有二人焉,往往是主人与主客,一来一往,你问我答,你攻我守,左右了全席谈话的大势,也能引人入胜。
最自然也是最有趣的情况,乃是滚雪球式。谈话的主题随缘而转,愈滚愈大,众人兴之所至,七嘴八舌,或轮流坐庄,或旁白助阵,或争先发言,或反复辩难,或怪问乍起而举座愕然,或妙答迅接而哄堂大笑,一切都是天机巧合,甚至重加排练也不能再现原来的生趣。这种滚雪球式,人人都说得尽兴,也都听得入神,没有冷场,也没有冷落了谁,却有一个条件,就是座上尽是老友,也有一个缺点,就是良宵苦短,壁钟无情,谈兴正浓而星斗已稀。日后我们怀念故人,那一景正是最难忘的高潮。
众客之间若是不顶熟稔,雪球就滚不起来。缺乏重心的场面,大家只好就地取材,与邻座不咸不淡地攀谈起来,有时兴起,也会像旧小说那样“捉对儿厮杀”。这时,得凭你的运气了。万一你遇人不淑,邻座远交不便,近攻得手,就守住你一个人恳谈、密谈。更有趣的话题,更壮阔的议论,正在三尺外热烈展开,也许就是今晚最生动的一刻,明知你真是冤枉,错过了许多赏心乐事,却不能不收回耳朵,面对你的不芳之邻,在表情上维持起码的礼貌。其实呢,你恨不得他忽然被鱼刺哽住。这种性好密谈的客人,往往还有一种恶习,就是名副其实地交头接耳,似乎他要郑重交代的,句句都是肺腑之言,恨不得回其天鹅之颈,伸其长蛇之舌,来舔你的鼻子,哎呀,真的是tête-tête还不够,必得nose-to-nose才满足。你吓得闭气都来不及了,哪里还听得进什么肺腑之言?此人的肺腑深深深几许,尚不得而知,他的口腔是怎么一回事,早已有各种菜味,酸甜苦辣地向你来告密了。至于口水,更是不问可知,早已泽被四方矣,谁教你进入它的射程呢?
聚谈杂议,幸好不是每次都这么危险。可是现代人的生活节奏毕竟愈来愈快,无所为的闲谈、雅谈、清谈、忘机之谈几乎是不可能了。“偶然值林叟,谈笑无还期。”在一切讲究效率的工业社会,这种闲逸之情简直是一大浪费。刘禹锡但求无丝竹之扰耳,其实丝竹比起现代的流行音乐来,总要清雅得多。现代人坐上计程车、火车、长途汽车,都难逃噪声之害,到朋友家去谈天吧,往往又有孩子在看电视。饭店和咖啡馆而能免于音乐的,也很少见了。现代生活的一大可恼,便是经常横被打断,要跟二三知己促膝畅谈,实在太难。
剩下的一种谈话,便是跟自己了。我不是指出声的自言自语,而是指自我的沉思默想。发现自己内心的真相,需要性格的力量。唯勇者始敢单独面对自己,唯智者才能与自己为伴。一般人的心灵承受不了多少静默,总需要有一点声音来解救。所以卡莱尔说:“语言属于时间,静默属于永恒。”可惜这妙念也要言诠。
一九八六年一月
为埃斯米而作:既有爱也有污秽凄苦_九故事_塞林格
========================
#为埃斯米而作:既有爱也有污秽凄苦_九故事_[[塞林格]]
-----
就在不久前,我收剑一份航空寄来的请柬,邀请我参加 4 月 18 日在英国举行的一次婚礼。这倒是个我愿意为之付了些代价去参加的婚礼,刚收到请柬时,我原以为没准真的能出国一趟,坐飞机去.花多少钱倒是无所谓。可是,后来在跟我太太 (那可是个头脑冷静得出奇的女子) 仔细研究之后,我们决定不去了——因为,别的先不说,我岳母早就打算 4 月下旬来我们家住上两周,我把这碴儿给全忘了。我的确是有些日子没见到格伦彻妈妈了,她又年纪不小了。都五十八了。(她逮谁都先提这档子事。)
虽然如此,不管参加还是不参加,我想自己决非那种为给婚礼助兴连丁点力气都不肯出的人。因此,我还是打起精神草草写下一些说明情况的札记,是关于大约六年前我认识的这位新娘的一些情况的。倘若我的札记会使我从未见过的新郎有几分钟感到不舒服,那我也不在乎。我本来就不打算讨任何人的喜欢。至于教训谁指导谁就更非我的本意了。
1944 年 4 月,大约有六十名美军士兵在英国德文郡英国情报部门办的一个有点专门性质的训练班接受准备反攻的训练,我就是其中之一。现在回想起来,我觉得我们这六十个人倒有个非常一致的共同点,那就是没一个是合群的。我们基本上都是爱写信的那种人,除了工作上的话之外,我们被此之间讲的一般话题是问别人有没有富余的墨水。要是有既不写信也不上课的时候,那就各干各的。我的习惯是,逢到天气晴朗,就到附近乡下景色不错的地方去散步。阴雨天呢,就找个干爽的地方看书,常常离乒乓球桌很近,球扣都儿乎抡得到我。
训练班持续了三个星期,结束的一天是星期天,那天雨下得真不小。根据计划,这最后一天傍晚七点钟,我们全体人员要乘火车去伦敦,有小道消息说我们将分别要插进为 D 日登陆而集结的步兵师和空降师。那天下午三点钟,我已把我全部东西打进背囊,其中包括一只盛满我从大洋彼岸带过来的书籍的装防毒面具的帆包袋。(面具我几个星期前就已从毛里塔尼 Ⅱ 号一个舷窗扔出去了,我非常清楚要是敌人一旦真的施放毒气,我是绝对来不及把这劳什子戴到脸上去的。)我记得自己在我们那座长拱形活动房了一端的窗前站了很久,凝视着凄风苦雨,右手食指隐隐约约有点痒痒想扳枪,但也仅仅有那么点儿意思罢了。我能听见背后许多枝钢笔在许多张 “胜利信笺” 上刮擦的很没有战友气氛的沙沙声。突然,我从窗边走开,脑子里没什么特别打算,我穿上我的雨衣,围上开司米围巾,穿上套鞋,戴上羊毛手套和海外兵团的军帽(到今天仍有人对我说,我戴的角度与众不同——两边都拉得较低可以盖住双耳上端)。接着,我把自己的手表与厕所里的钟对了一下,便从小山上那条长长的、湿漉漉鹅卵石路往下走,进人小镇。周围电光闪闪我全然不顾。要是该让雷电打死,想躲也躲不开。
市镇中心也许是周遭最最潮湿的地方了,我在一座教堂门前停下看布告牌,我多半是被写在黑纸卜的白数码宇吸引住了,但也没准因为在军队里呆了三年,我已经看告示看上瘾了。布告牌上说,三点一刻要进行儿童唱诗练习。我看看我的予表,又抬头再看布告。在一张用图钉固定的纸上升列了该来参加排练的儿童的名字。我站在雨地里把所有的名字都看了一遍,然后走进教堂。
长椅上散坐着十几个成年人,有几个膝上放着一双底朝上的小号雨鞋。我直着走,在第一排上坐了下来。讲台上紧挨着坐在三排座椅上的是一十来个孩子,多半是女孩,年纪大约七岁到十三岁。我坐下时,唱诗班的指导,一个穿花呢套装的高高大大的女人,正关照孩子们唱歌时嘴要张大一些。有谁听说过,她问道,一只可爱的小鸟儿在唱好听的歌儿时,竟敢不把它那小嘴张得大大、大大、大大的呢? 显然,没一个人听说过。因为回瞪着她的都是一张张没有表情、木呆呆的脸。她接下去又说,她要求她班上所有的孩子都充分领会他们所唱的歌词的意思,而不要像没有脑子的鹦鹉那样,光是从嘴巴里发出声音。这以后她吹定音笛定了个调,于是孩子们像一群未成年的举重运动员似的,把他们的赞美诗歌本举到胸前。
他们唱时是没有乐器伴奏的——或者,在此刻的情况下,更准确的说法是,没有任何干扰。他们的声音优美,毫不装腔作势,几乎达到这样一个水平:倘若听的是一个比我宗教意识多少强一些的人,那么无须多加想像,也会感受到天国的境界了吧。有两三个年龄最小的孩子节奏上稍稍有些滞后,但算不得什么毛病,会稍感不够完美的,大概只有作曲家的母亲了吧。我以前没听到过这首赞美诗,但我不断地希望它有十来节歌词,最好长些。我一面听一面打量孩子们那一张张小脸,但我特别注意的是其中一个的脸,这孩子坐得离我最近,就在第一排最边上的位子上。她大约有十三岁,直直的带点浅灰色的金发齐着耳根,前额很精致秀美,耳光倦怠,我想,没准是在点数到场的人吧。她的声音可以很清晰地与其他孩子的区别开,这小仅仅是因为她坐得离我最近。她进入高音区时一点也不费劲,音质极美,音也最准,自然而然在合唱中起着带头作用。然而这位年轻女士却对自己的歌唱才能稍稍有点感到厌烦,或者仅仅是对时间与环境有所不满;我发现有两回她在换唱另一段歌词的间歇时打了哈欠。那是有修养的女士的打法,嘴巴是闭着的,但是你不会看不出来;她的鼻翅泄露了秘密。
赞美诗一唱完,那位合唱指导立即长篇大论地说起来,对牧师布道时腿脚静不下来嘴巴闭不起来的孩子一一作了评述。我寻思排练的演唱部分到此已告一段落,不等指导刺耳的教训声把孩子歌唱散发出的魅力破坏殆尽,便站起身来走出教堂。
雨下得比方才更大了。我沿着街往前走,透过窗子看看红十字会的娱乐厅,只见士兵们三三两两地站在房间深处的咖啡柜台前面,而且,即使隔着玻璃,我也能听见另一个房间传出乒乓球的劈劈啪啪声。我走到街对面,进了一家平民开的茶室,那里除了一个中年的女招待之外再无别人,看她样子,像是更愿接待一个雨衣不湿的顾客的。我尽可能小心地将雨衣在一个枝形衣架上挂好,然后在一张桌子边上坐下,要了茶和肉桂吐司。这是我一整天头一次跟人说话。接下去我搜遍了我所有的口袋,包括雨衣口袋,终子找到两封可以重读的旧信,一封是我妻子写来的,告诉我第 88 街那家施拉夫店铺服务质量大不如前了,另一封是我岳母寄来的,她让我一得空走出 “军营”,就尽快给她寄些开司米毛线去。
我第一杯茶还未喝完,唱诗时我打量、倾听过的那位年轻小姐也走进茶室了。她的头发湿透了,两个耳轮都露了出来。同她一起来的是个非常小的男孩,显然是她弟弟,弟弟的帽予被她崩两个手指捏提走,仿佛那是实验室里的一什标本似的。在后面压阵的是一个看上去挺精明能干的妇女,戴一顶疲塌塌的平顶帽了
多半是他们的家庭女教师了。那位唱诗班的歌手一边走一边脱下外衣,并且选定了一张桌子--位置不错,从我的观点看,因为就在我正前方十英尺不到的地方。她和家庭女教师坐了下来。那小男孩,他大概有五岁,却还不打算安定下来。他身子一缩把海军衫脱掉,随手一扔;接着,他以天生捣蛋鬼不动声色的表情,开始淘气,他有条不紊地故意惹家庭女教师生气,好几次把自己的椅子推进又推出,还眼睛瞄过去观察她的脸。家庭女教师一直压低声音给他发出两三道命令,实际上就是要他别再瞎闹,但是只是在他姐蛆发话了他才走回来,把他那小屁股坐到了自己的位置上。他一把将餐巾抓过来扣在自己脑袋上。他蛆姐取下来把餐巾摊开,替他铺开在他膝头上。
大约在我们的茶端上来的时候,唱诗班歌手发现我的眼光在打量她们这几个人。她也回看我,还是以她那种清点屋子里人头的目光,接着,她突然向我展露了一个很小,很矜持的笑容。它却出奇地灿烂,有时候某些浅浅的、含蓄的笑也会让人觉得特别温暖的。我也回报了一个微笑,远没有她的动人,因为我得抿紧上唇,免得露出两颗门牙之间的一道黑缝,那是美国军医给我补牙临时塞上的煤一般黑的填充物。让我料不到的是,紧接着,这位年轻的小蛆已经以很令人歆羡的姿势站立在我的桌旁了。她穿的是一条苏格兰花呢裙子——坎贝尔花呢,我想是。在我看来,一位非常年轻的姑娘在一个没完没了的下雨天穿这样的衣服,那真是太美妙了。“我还以为美国人对茶是瞧不上的呢,” 她说。
她说这话倒不是卖弄聪明,而是想弄清事实或是弄清百分比什么的。我回答说,我们美国人也有除了茶别的什么都不喝的。我问她愿不愿意同我一起坐一会儿。
“谢谢你,” 她说。“也许我只能坐一小会儿,”
我站起身替她拉出把椅子,我对面的那把,她在椅子前面四分之一处坐下,脊背挺得直直的,很自然也很优美。我走同到--几乎是急匆匆赶回去的——我自己的椅子那里,一心想接上让我扣断了的淡话。但是我坐下后,却又想小起该说什么了。我又笑了笑,仍然极力不让我的煤黑色的填补物露出来。我说这样的坏天气出来真够糟糕的。
“是的,是够糟的,” 我的客人说,声音一个个字清清楚楚,显然不是个爱闲聊碎嘴子的人。她把手指平放在桌子边缘上,像个做降神术的人似的,但是,几乎紧接着,又把双手拳了拢来一一她的指甲是给啃嗑掉的,一直咬到肉根处。她戴了一只手表,是军用的那种,看上去几乎像是飞机驾驶员的精密计时器了。表面对于她纤细的手腕来说实在是太大了。“你来看我们的唱诗排练了,” 她平平淡淡地说。“我方才瞧见你了。”
我说我确实去了,而且从合唱中听出了她的声音。我说我认为她有一副非常好的嗓子。
她点点头。“我知道。我将来要做一名职业歌唱家的。”
“真的? 是唱歌剧吗?”
“我的天,不是的。我要在广播电台上唱爵士,挣大堆大堆的钱。然后,到三十岁,我就退休并且住到俄亥俄的一个牧场上去。” 她用手掌摁了摁湿漉漉头发的顶端。“俄亥俄你熟吗?” 她说。
我说我有几次坐火车经过这个州,但是不真正熟悉。我问她要不要吃一片肉桂吐司。
“不了,谢谢你,” 她说。“我食量真跟一只小鸟的差不多。”
我自己咬了一口吐司,告诉她俄亥俄有不少荒凉的野地。
“我知道。我遇到的一个美国人跟我说过。你是我遇到的第十一个美国人。”
她的家庭女教师这时使劲给她做手势,叫她回到自己桌子去
意思是别再打扰别人了。我的客人却若无其事地把她的椅子挪动了一两英寸,让自己的脊背完全阻隔了从自己桌子那边可能再传过来的任何联络信息。“你是在山上那所秘密情报学校受圳的吧,是不是?” 她冷冷地问道。
我跟旁人一样懂得要保密,便告诉她我因为身体不好才来德文郡的。
“真的呀,” 她说,“我可不是昨天才出生的小娃娃,你懂吗?”
我说她当然不是的,这错不了。有片刻工夫,我径自喝茶。我逐渐有点感到自己的坐姿不太好,便在椅子上稍稍坐直一些。
“作为一个美国人,你好像还是比较聪明的,” 我的客人若有所思地说。
我告诉她,如果细细琢磨,说出这样的话未免有些妄自尊大小瞧别人,我相信这样做与她的人品不太相称。
她脸红了——这又是在自动提醒我有点不注意社交礼仪了。“嗯。我见到的大多数美国人行为跟动物差不多。他们永远彼此打打闹闹,还出口伤人,还有——你知道有一个美国人干了什么吗?”
我摇摇头。
“有一个美国人把一只空威士忌酒瓶扔进我姨妈的窗子。幸好那窗子是开着的。你觉得这件事做得很聪明吗?”
那当然是不特别聪明,不过我没有这么说。我说在世界各地,许多大兵都远离家乡,只有极少数才在生活中获得比较多的补偿。我说我想大多数人对这一点都是会理解的。
“也许是吧.” 我的客人说,没有什么信心。她再次把手举到湿头发那儿,摸到几绺软疲疲的金发,想让它们遮盖住自己露出的耳轮。“我头发湿透了,” 她说。“我难看死了。” 她对我看了一眼。“干的时候我的头发是打卷的。”
“我看得出来。看得出你头发是打卷的。”
“不是真的卷成一个个卷儿,而是挺有波浪形的,” 她说。“你结婚了吗?”
我说我结婚了。
她点点头。“你深深爱着你的妻子吗? 是不是我太关心别人的私人问题了?”
我说她太过分的时候我会说的。
她把摆在桌子上的手和手腕又向前伸了伸,我记得我曾想对她戴的那只表盘巨大的手表作出点表示——比如说建议她不如把表系在腰上。
“一般说,我这人不特别合群,” 她说,同时把眼光对着我似乎想知道我究竟懂不懂这个词儿的意思。我没有作出任何表示,正面或反面的都没有。“我坐过来纯粹是因为我觉得你看上去太孤单了。你有一张极其敏感的脸。”
我告诉她她说得很对,我方才确实是感到孤单,我非常高兴她能坐过来。
“我正在训练让自己能有更多的同情心。我姨妈说我这人非常冷,” 她说着又去摁自己的头顶了。“我同我姨妈一起住。她是一个极其和善的人。自从我母亲去世后,只要力所能及,她总想尽办法让查尔斯和我觉得适应。”
“我很高兴。”
“母亲是一个绝顶聪明的人。有优美的情操,在许多方面都是这样。” 她以一种前所未有的炯炯目光盯看着我。“你觉得我这人非常冷冰冰吗?”
我告诉她决非如此——事实上,是恰恰相反。我把自己的名字告诉她,也问了她怎么称呼。
她犹豫了一下。“我前面的名字是埃斯米。我想暂时先不告诉你我的全名。我有一个封号,你会让封号给震住的。美国人都这样,你明白吧。”
我说我想自己还不至于会这样,不过既然如此,先不透露封号也许是个好主意。
就在此时,我觉得有谁在我的脖颈后面喷热气。我头一转,险些儿和埃斯米年幼的弟弟鼻子跟鼻子撞在一起。他不理我,却用刺耳的尖嗓门对他姐姐说:“梅格利小姐让你马上回去把茶喝了!” 口信传达完了以后,他就退到了我右面他姐姐和我之间的一把椅子上去。我非常感兴趣地打量着他。他显得很神气,穿一条棕色的设得兰呢短裤,一件藏青色的运动服,里面是白衬衫,还打着条纹领带。他用一双大大的绿眼睛盯看着我。“为什么电影里的人都侧着脸接吻?” 他问。
“侧着脸?” 我说。这个问题小时候也曾困惑过我。我说我猜是因为演员的鼻子都太大.所以没法正面接吻。
“他的名字是查尔斯,” 埃斯米说。“按他的年龄说就算是非常聪明了。”
“他的眼睛真绿呀。你是不是这样,查尔斯?”
查尔斯毫无表情地看了我一眼,我这问题很傻也只配有这样的回答,接着他在那把椅子里扭上扭下,直到整个身子都藏到了桌子底下,只有他的脑袋像摔跤运动员拱起身子时似的,留在了椅座上。“眼睛是橘红色的,” 他对着天花板说。他撩起桌布的一角,盖在了他那张漂亮却毫无表情的脸上。
“有时候他聪明可有时候又不聪明,” 埃斯米说。“查尔斯,给我坐好!”
查尔斯还是那样呆着。他好像在屏住呼吸。
“他非常想念我们的父亲。他在北非给——杀——害——,。”
我表示听到这件事我非常难过。
埃斯米点点头。“父亲特别喜欢他。” 她若有所思地啃起大拇指甲盖来。“他长得非常像我母亲——查尔斯,我指的是。我活脱脱是我父亲的样儿。” 她继续咬她的指甲。“我母亲是个感情很丰富的女子。她性格外向。父亲性格内向。他们很般配,不过,这也是表面上如此。坦率地说,父亲真是需要一位智力上优子母亲的女子作伴侣的。他是个天赋很高的才子。”
我默默地等候着,想听到更多的情况,可是她不再讲了。我低下头看看查尔斯,此刻他正将半个脸侧枕在他的椅子上。当他看到我在注视他时,他便闭上跟睛,假装睡觉,睡得像小天使般的甜美,接着又把他的舌头伸出来——他这器官长得出奇——并且发出了在我们美国碰到棒球裁判眼神差劲时准会奉送的大声倒彩。这吵声把整个茶座震得够呛。
“别叫了,” 埃斯米说,显然早已习以为常一点不觉得意外了。“他见到一个美国人在排队买炸鱼带土豆片时这样喊过,现在他一感到无聊了便这样干。给我停下,听见没有,不然我立刻让梅格利小姐来管教你。”
查尔斯把他那双大眼睛睁着,表示他已经听到姐姐的威胁了,但除此之外也不显得特别在乎。他又闭上眼睛,继续把半边脸枕在椅座上。
我发表意见说,也许他应该把这一手——指做鬼脸发怪叫什么的——留到他能正式使用封号时表演。那是说,如果他也能有封号的话。
埃斯米瞪着眼睛看了我好一会儿,有点像医生在诊断病人。“你的幽默感成色差点儿,对不对?” 她说带着点思念之情。“父亲总说我完全没有幽默感。他说我还不具备条件应付生活的挑战,因为我缺乏幽默感。”
我看着她,点燃了一根烟然后说,我认为,遇到要紧关头时,有没有幽默感并不起什么作用。
“父亲说是有用的。”
她这样说是出于对亲人的信赖,并非真的和我意见相左,于是我就赶紧扭转话题。我点点头说,她父亲也许是从长远的观点看问题,而我则是一时一地地看 (这到底什么意思连我自己都说不清)。
“查尔斯极其想念父亲,” 埃斯米沉默片刻之后说道。“父亲是一个极其可爱的人。他的相貌又是特别俊美。倒不是说一个人的长相有多么重要,不过他确实是俊美。以他这么一个难以逾越的①宽厚平和的人来说,他的目光是极具穿透力的。”
我点点头。我说我猜想她父亲词汇量一定异常丰富。
“哦,是的;相当丰富,” 埃斯米说。“他以前是一位档案收藏家一一业余玩玩的,当然是。”
正说到这里,我感到上臂那儿挨了一下挺烦人的拍击,几乎能说是挨了一拳了,是查尔斯那个方向打来的,我朝他转过去。他现在坐的姿势还算正常,只是一个膝头窝在身子下面。“一堵墙跟另一堵墙说什么话了?” 他尖叫着问。“这是个谜语!”
我对着天花板沉思地把眼球转来转去,并且大声把谜语重复了一遍。接着我作出被难倒的表情,说我认输了。
“墙角见!” 他用最大音量嚷出了谜底。
对这出戏最感得意的正是查尔斯自己。他简直是乐不可支。结果是埃斯米不得不走过来捶他的背,就像对待咳嗽不止的病人那样。“行了,别闹了,” 她说。她走回到自己的座位上去。“他不论见到谁都要把同一个谜语说一遍,每回都要疯上一遍。他一笑就跟犯病似的。好了,快停下来,行不行。”
“不过,倒是我听到过的最有意思的谜语之一,” 我说,一边望着查尔斯,他正一点点一点点地平静下来。听到我的夸奖之后,他身子在椅子上往下缩了多半截,还用桌布的一角蒙住自己的脸,一直蒙到眼睛下面。接着他用露出来的两只眼睛看着我,那里面充满了慢慢消退下去的兴奋表情以及一种得意神色,因为他掌握一两个最精彩不过的谜语。
“我可不可以问一下,你入伍之前是做什么事的?” 埃斯米问我。
我说我还没有工作过,我从大学毕业只有一年,不过我总喜欢认为自己是一个写短篇小说的专业作家。
她很有礼貌地点了点头。“发表过吗?” 她问。
这是一个别人老爱问而我总觉得不好回答的问题,我从不一二三那样具体回答。我开始解释,美国的编辑如何只是一伙——
“我父亲文笔很漂亮,” 埃斯米打断我的话。“我保存了一些他的书信,将来给后代入看。”
我说这主意我听着觉得不错。我的眼光恰好又落在她那个表盘极大、像是读秒器的手表上。我问她,这表是不是原来属于她父亲的。
她低下头,很庄重地看了看自己手腕那儿。“是的,原来是他的,” 她说。“是他在查尔斯和我疏散前不久给我的。” 她有点不好意思地把双手从桌面上移开,又说,“当然,纯粹是为了作个纪念。” 她转移了话题。“如果你什么时候能专门给我写一篇小说,我会感到十分荣幸的。我可是个贪婪的读者呢。”
我告诉她,如果写得出我一定会写的。我说,不过说来惭愧,我绝不是一个多产作家。
“并不需要特别多产的嘛! 只要写一篇不孩子气不那么傻的就行。” 她想了一想。“我偏爱写凄苦的小说。”
“写什么的小说?” 我说,身子向前倚了倚。
“污秽的。我对写凄苦的小说特别感兴趣。”
我正想从她那里再套出些细节来,可是我感到胳膊上让查尔斯重重地掐了一下。我转过头去,因为疼痛稍稍抽缩了一下。他站在我的右面。“一堵墙跟另一堵墙说什么了?” 他问,态度还挺亲热。
“这你方才问过他了,” 埃斯米说。“好了,别闹了。”
查尔斯理也不理他姐姐,更把身子踩在我一只脚上,又把谜面问了一遍。我注意到他的领带系得有点歪。我帮他弄弄正,接着正视着他的眼睛,假装问道,“是咱俩墙角见,对吧?”
话刚出口,我就后悔自己说了。查尔斯的嘴巴耷拉着松了开来。我觉得那像是让我一巴掌揍开的。他从我脚上下来,气鼓鼓神色凛然地走向自己的桌边,连头也没回。
“他气极了,” 埃斯米说。“他脾气很暴躁。我母亲总爱惯纵他。我父亲是惟一不娇惯他的人。”
我继续望着查尔斯,他已经坐下开始喝他的茶了,用两只手抱住杯子。我希望他能转过头来,可是他没有。
埃斯米站起身来。“Ifautquejeparte 我也该走了” 她说,叹了口气。“你懂法语的吧?”
我从自己坐着的椅子上站起来,感到有些怅然也有些迷惑。埃斯米和我握了握手;她的手,正如我猜测的那样,是神经质的人的那种,掌心潮滋滋的。我告诉她,用的却是英语,有她作陪我这段时间过得真是非常愉快。
她点了点头。“我料想你会的,” 她说。“以我的年龄来说,我算是比较善于跟人交谈的。” 她又试探地摸摸自己的头发。“我头发这样,真是不好意思,” 她说。“我的样子大概很不雅观吧。”
“哪里哪里! 实际上,我觉得不少波纹已经重新出现了”
她再次迅速地去摸了摸头发。“你看这阵子你还会再来这儿吗?” 她问。“我们每星期六都来的,排练结束之后。”
我回答说我非常希望再来,可是很遗憾,我看再来的可能性怕是没有了。
“换句话,就是说你不能透露有关部队换防的消息哕,” 埃斯米说。她没有离开桌边的迹象。事实上,她将一只脚搭在了另一只脚上,眼睛朝下看,把两只鞋子的尖端排齐。这个小动作挺漂亮的,因为她穿的是白短袜,她的脚踝和脚都长得很可爱。她突然抬起头来看着我。“你愿不愿意让我给你写信?” 她问,脸上稍稍泛起一些红晕。“我写信表达能力还是很强的,就我这种年龄——”
“我当然愿意,” 我拿出铅笔和纸,写下我的名字、军阶、编号与军邮信箱号码。
“我会先给你写信,” 她接过纸说道,“这样就不至于让你感到面子上过不去什么的了。” 她把地址塞在她衣服的一个口袋里。“再见,” 她说,朝自己那张桌子走回去。
我又要了一壶茶,看着他们,直到姐弟两个还有那位备受折磨的梅格利小姐站起来准备离去。查尔斯走在最前面,装出一副可怜相一瘸一拐地走着,就像是个条腿比另一条短了几寸的人似的。他还是不朝我这个方向看。梅格利小姐跟在后面,然后是埃斯米,她朝我挥挥手。我也挥手作答,还半欠起了身子。这竟是一个很让我动了些感情的奇异时刻呢。
还不到一分钟,埃斯米又回进茶室来了,还拽住查尔斯的海军服袖子把他拖在身后。“查尔斯愿意吻你一下跟你告别,” 她说。
我立刻把手里的茶杯放下,说这太好了,可是她没弄错真是如此吗?
“是的,” 她说,口气有点恶狠狠的。她松开查尔斯的袖子,把他朝我这边用力推了一把。查尔斯过来了,脸色铁青,在我右耳根下很响地吻了一下,嘴唇湿湿地发出了吧的一声。熬过这一关之后,他笔直朝门口奔去,要永远摆脱这种婆婆妈妈的事儿,可是我一把抓住他海军衫的后腰带,紧握不放,并且问他:“一堵墒跟另一堵墒说了什么?”
他变得容光焕发。“咱们在墙角那儿见 j” 他尖声喊道,一溜烟跑出茶室,乐得都快疯了。
埃斯米又采取交搭着脚站立的姿势了。“为我写小说的事你真的不会忘记吗?” 她问。“倒也不一定纯粹为我而作。也可以——”
我说忘记是决不可能。我告诉她我以前从来没有专为任何人写过一篇小说,但是这样做的时机似乎恰好来到了。
她点电头。“要写得极其污秽凄苦,极其动人呀,” 她建议道。“你对人世间的凄苦污秽多少有点了解吧,”
我说我不敢说了解得很透彻,不过好久以来,我已经越来越熟知它的各种表现形式了,我会尽力做得合乎她的要求的。我们握了握手。
“我们没有能在不那么严肃的环境下相识,这不是挺遗憾的吗?”
我说是的,我说的确是的。
“再见,” 埃斯米说。“我希望经历了战争后你身心都健康如初。”
我向她表示感谢,还说了几句别的什么,接着便看着她离开茶室。她走得很慢,像是在思索着什么,一边还摸摸发梢,看看干了没有。
下面便是故事中污秽凄苦,或者说感人的部分了,场景变了。人物也发生了变化。我仍然在故事里,不过从现在起,为了某种我无权公开的原因,我已把自己伪装得很巧妙,连最最聪明的读者也难以辨认出来。
胜利日几个星期之后,晚上十点半左右,地点是在巴伐利亚州的高弗尔特。参谋军士 x 正呆在一座老百姓住宅一楼他的房间里,早在停战之前,他就和另外九个美国军人驻扎在这里了。他坐在一张乱得没法看的小写字桌前的一把木折叠椅里,面前摊开着一本软纸封面海外版的小说,这书他读得很费劲。问题在他这方面,而不在小说本身。虽然军中特别服务部门每月送来的新书总是让住楼下的人抢着先挑,但是剩下倒像是他恰好想看的那些。可是他并小是经历了战争仍然身心健康如初的年轻人,因此一个多小时以来他都把几段文字读了三遍了,此刻他正逐个句子地重新读。他突然合上书,连读到哪里都没有作记号。他用一只手把眼睛遮了一阵,以挡住桌子上方那只没罩子的灯泡射出来的刺目、让人难受的亮光。
他从桌上的一包烟里取出一根,点燃了它,点的时候手指老是不断地轻轻碰撞。他在椅子上往后靠了靠,不知其味地吸着烟。几个星期以来他总一根接一根地吸烟。用舌头稍稍一顶他的牙龈就会渗血,可他又忍不住试着去顶;这是他在做的一个小游戏,有时候一做就是几个小时。有一会儿他坐着边抽烟边做这样的试验。可是突然,很熟悉的一种感觉像往常一样毫无预示就来到了,他只觉得他心里测着没落,悠悠晃晃的,就像头顶行李架上的一件行李没有系紧一样。他赶紧采取几个星期以来他一直在做的补救措施:用双手紧紧按住两边的太阳穴。他紧按了有好一会儿。他需要理发了,头发很脏。他在美因河畔法兰克福住了两个星期医院,洗过三四次头发,可是乘吉普车回高弗尔特,路很长,尘土飞扬,头发又脏了。到医院去接他的 z 下士还是按战时规矩把挡风玻璃全摇了下来,他才不管停战还是没停战呢。开赴德国的新兵有成千上万之多。只有把玻璃摇下来以战时的方式开车,才能显出自己跟他们可不一样,他绝不是什么刚来欧洲战区没见过一点世面的新兵蛋子。
X松开太阳穴后,开始朝写字桌面瞪看,那儿乱作一团,摊放着至少二卜来封没打开的信和至少五六个未拆的邮包,全是寄给他的。他的手越过这堆东西拿起一本靠墙立着的书。那是戈培尔的一本大作,书名是 DieZeitOh 史无前例的时代。这是属于几星期前还住在这里的这家人家那个三十八岁还没结婚的女儿的。她原是纳粹党的一名下级官员,但是官阶又稍稍高了点儿,正好划进军队条令规定理应逮捕的范围之内。逮捕她的止是X自己。此刻,从他出医院回来的那天起,他第三次翻开老小姐的这本书并且读出写在扉页上的简短题词。是用钢笔写的德文,字很小,规矩得都有点拘谨了,写的是:“亲爱的上帝,生活是地狱。” 没头没脑,别的什么也看不出来。在房间令人窒息的死寂里,书页上这孤单单的一句像是具有无可辩驳,甚至是经典性控诉的意味。x 对着扉页瞪看了好几分钟,苦苦地抗拒着巨大的吸引力,不让自己为之所动。接着,怀着几个星期以来他做任何事情都没有过的热情,他拿起一个铅笔头,在题词下面用英语写道:“父辈们师长们,我在考虑‘什么是地狱’这个问题。我认为因为不能去爱而受苦,这就是地狱。” 他正要在这句话后而加上陀思妥耶夫斯基的名字,可是看到方才自己所写的字几乎完全辨认不清,吓得全身一阵寒颤。他合上了书。
他急急地从桌子上拿起另一样东西,是他哥哥从奥尔巴尼发来的一封信。早在他住院之前这信就已经在他桌上放着了。他拆开信封,尽管决心不大还是想一口气把信读完,但是也仅仅是读了第一页的上半段。读到这几个字后他停了下来:“现在这场该死的战争结束了,你在那边也许有很多空闲时间,可否给孩子们捎些刺刀和万字章来……” 他把信撕掉,又低头看看字纸篓里的碎片。他发现自己没注意到信中还附了一张照片。他能看到有个人的脚站在某处的一块草坪上。
他把两只胳膊放在桌上,把头枕在 E 面。他从头到脚都疼,所有的痛区似乎都是相互依存的。他倒很像是一棵圣诞树,上面电线都连在一起,只要有一只灯泡出了毛病,其他的也全都不亮。
门连敲都没敲就给砰地推开了。x 抬起头,转过去,看到 z 下士站在门口。z 下士跟 x 合开一辆吉普车,从 D 日登陆以后,他们共同一口气参加了五次战役。他住在一楼,每逢听到什么小道消息或是自己有什么烦心事想发泄时,他总上楼来找 x。他是个高大魁伟、很上相的年轻人,今年二十四岁。战争期间,一家全国性的杂志曾在许尔特根森林给他拍过照;他摆好姿势,一副求之不得的模样,一手提着一只感恩节火鸡。“在写信呀?” 他问 x。“天哪,这儿怎么阴森森的。” 他总喜欢他进入的房间顶灯开得亮堂堂的。
x 在座位上转过身子,请他进来,还让他小心点别踩着狗。
“别踩着什么?”
“阿尔文。它就在你脚边,克莱。把那盏鬼灯帮我打开,行不?”
克莱找到开关,按亮了顶灯,然后走过这狭窄的用人房模样的小屋,在床边坐下,面对着房间主人。他那刚梳过的砖红色头发上还滴着水,为了弄顺自己的头发他每回都要用上不少水。跟往常一样,他那件黄绿色衬衫右面口袋里鼓鼓地塞着一把梳子,是带自来水笔卡子的那种。左边口袋上方,他别着步兵战斗部队徽章 (严格说,他没有戴的资格),别着欧洲战区勋标,上面有五颗铜星,表示参加过五次战役(他没有换成一颗银星,这相当于五颗铜的),还别着“珍珠港前即已服役” 勋标。他重重地叹了口气,说道:“我的好基督嗳。”其实这并不意味着什么;部队里全这么说。他从衬衫口袋里拿出一包香烟,磕出一根,把那包烟放回去,重新扣上兜盖。他一边抽烟,一边心不在焉地打量着房间。最后,他的日光落到那只收音机上。“嗨,”他说。“过几分钟就要广播那台精彩节目了。有鲍勃 • 霍普,好多大明星都参加演出呢。”
x 拆开一包新的烟,说他自己刚刚关掉收音机。
克莱情绪一点儿没受到打击,他看着 x 在费劲地点烟。“耶稣呀,” 他说,起劲得像个热情的观众,“你看看你那双不争气的手。小子哎,你是不是在打摆子。你自个知道的吧?”
x 总算把烟点着了,他点点头,还说克莱眼睛真尖,再小的事儿也瞒不过他。
“不跟你开玩笑,嗨。我在医院见到你时差点儿没晕过去。你跟一具尸体也差不离。你掉了多少肉? 几十磅? 你可清楚?”
“我不清楚。我不在的时候你收到的邮件正常吗? 有洛雷塔的消息吗?”
洛雷塔是克莱的女朋友。他们准备一等条件许可就马上结婚。她来信很勤,那可是个乐园,里面孽生着许许多多三重惊叹号和意思不甚精确的叙述描写。战争的全过程中,克莱给 x 大声念了洛雷塔所有的来信,不管它们写得多么亲热——事实上,越亲热克莱就越是来劲儿。他还养成了一个习惯,每次读完后总要求 x 帮他谋划或是敷衍成一封复信,要不就是帮他往里面嵌进去几个怪唬人的法语或德语词儿。
“有的,我昨天刚收到一封她的信。在我房间里呢。呆会儿我拿来给你看,” 克莱没精打采地说。他在床边上坐直身子,屏住呼吸,打了个长长的响嗝。他像是对这个成就比较满意,就又放松了下来。“她那操蛋哥哥因为坐骨有毛病要从海军退伍了,” 他说。“他倒有坐骨可以倚仗呀,这狗杂种。” 他再次坐直想打第二个嗝,可是这次成绩差点儿。他脸上出现了一些警觉的神情。“对了。趁我没忘赶快说。咱们明天早上五点钟就得起床,要开车去汉堡还是哪儿,给整个支队领艾森豪威尔式外套。”
x 满怀敌意地看着他,说自己可不想要什么艾森豪威尔式外套。
克莱显得大为惊讶,几乎有点受到伤害似的。“哦,这种外套很不错的!看上去很帅。你怎么回事儿?”
“不为什么。干吗让咱们五点钟起床? 谢天谢地,战争已经结束了。”
“我不清楚——咱们得赶回来吃午饭吧。他们又领来一些新表格要我们午饭前填好…? 我问过布林为什么不能今天晚上填——那些鬼表格他都领来了就在他桌子上放着呢。可是他不想现在就拆包,这狗娘养的。”
两人默默无言地对坐着,都在生布林的闷气。
克莱突然盯看着 x,以一种前所未有的新的——更大的——兴趣。“嗨,” 他说。“你还不知道你那半边该死的脸抽搐得很厉害吗?”
X 说他知道得很清楚,一边伸手上去捂住痉挛的部位。
克莱瞪看了他一会儿,接着说,口气很轻松,仿佛他有什么大好消息要传递似的,“我写了封信给洛雷塔,说你精神崩溃了。”
“哦,是吗?”
“是的。她对所有这类事感兴趣得要命。她止在专门念心理学呢。” 他直挺挺地在床上躺了下来,连鞋也不脱。“你知道她说州么来着? 她说没有人会仅仅因为战争这些事就精神崩溃的。她说你说小定是属于不稳定型的,你这倒霉的一生就是这样的。”
x 把双手捂在眼前——床上面的灯光像是真要把他刺瞎了——回答说,洛雷塔能把事情看得这么透,这真叫人高兴。
克莱斜瞥了他一眼。“听着,你这杂种,” 他说,“她对心理学上的问题看得可要比你透得多。”
“能劳驾把你那双臭脚从我床上移开吗?”x 问。
克莱把他的脚举起 “甭教导我该把脚往哪儿放” 那样长的几秒钟,然后扭了下身子,坐了起来。“反正我是要下楼去了。他们在沃克房间里开着收音机呢。”可是他仍然不从床上下来。“嗨。我方才正跟楼下那个叫伯恩斯坦的新兵蛋子说呢。记得那回我跟你开车去瓦隆涅吗? 咱们挨了他妈的差不多两个小时的炮轰,还有咱们趴在那个洞里,那只该死的猫跳到吉普车的顶篷上,我开枪打它的事? 记得么?”
“记得——别再开始唠叨猫的事了,克莱,真是烦透了。我不想听这事。”
“我不是要说这事儿,我光是说我把这事在信里告诉了洛雷塔。她跟心理学课全班学生讨论了这件事。在班上和班下。连那该死的教授和许多别的人也都参加了。”
“那很好。不过我不想听它了,克莱。”
“不,你知道洛雷塔说为什么我那么来劲儿给那猫一枪吗? 她说我是暂时性精神失常。不开玩笑。是因为炮轰什么的引起的。”
x 将手指插进他的脏头发,往后梳理了一下,然后再次用手挡住灯光。“你没有精神失常。你只不过是在履行职责。你扣死了那只小猫咪,任何一个人在这情况下都会毫不迟疑那样做的。”
克莱用猜疑的目光看着他。“你他妈的说些什么呀?”
“那猫是个间谍。你必须对准它使劲开枪。那是个披着件廉价皮毛的德国侏儒。因此绝对谈不上有野蛮、残忍、卑鄙,甚至是
“他娘的!” 克莱说,嘴唇绷得紧紧的。“你说话就不能正经点吗?”
x 突然一阵恶心,他在椅子上猛地转过身子,抓过字纸篓——总算还来得及。
等他直起腰,把脸对着客人时,他发现克菜很困窘地站在从床通向门的半路上。x 本想说几句道歉的话,但又改变主意,伸手去拿烟了。
“咱们下楼去听电台里的霍普表演吧,我说,” 克莱说,他虽然想躲远点但仍然力图表现得友好一些。“会让你舒服些的。真的。”
“你先去吧,克莱…… 我要看看我收集的邮票。”
“是吗? 你还集邮? 我怎么不知道——”
“我只是说着玩儿的。”
克莱慢慢地朝门口走了两步。“我也许呆会儿要开车去艾赫斯塔德,” 他说。“他们那儿有个舞会。没准会一直跳到半夜两点。要去吗?”
“不了,谢谢…… 我可以在房间里练舞步的。”
“好吧。晚安! 好好歇着吧,哎,看在老天的分上。” 门砰地关上,但马上又重新打开。“嗨。我把一封写给洛雷塔的信从门下边塞进来行吗? 我在里面用了儿个德文词儿。你帮我摆摆平行不行?”
“行。快让我清静一会儿吧,真是的。”
“这就走,” 克莱说。“你知道我妈妈来信说什么了吗? 她信里说她很高兴你跟我在一起而且整个战争中都这样。而且还共用一辆吉普什么的。她说自从咱俩搭伴以来我的信写得水平高多了。”
x 费了好大的劲儿抬起头米看他,说道:“谢谢。替我谢谢她。”
“我会的。晚安!” 门砰地关上,这次是真的关上了。
x 坐着朝门瞪看了好久,然后把椅子转向写字桌,从地板上拿起他的手提打字机。他在乱七八糟的桌面上为它清出一块地方,把那堆摊开的没拆的信和包裹往边上推。他寻思,给他在纽约的一个老朋友写封信也许能让他快点解除痛苦,即使疗效不会特别显著。可是他竟不能把纸平整地塞进卷筒,此刻他的手指颤抖得太厉害了。他把两只手垂到身边,等了一会,然后再试,最后却把纸揉在手里。
他明白应该把字纸篓拿到房间外面去,可是却一动没动,他只是把两只胳膊放在打字机上,头又伏了上去,并且闭上了眼睛。
头部的血管砰砰跳动了好几分钟,这以后,他张开眼睛,发现目光斜斜地正落在一只还未拆开的绿纸包上。那也许是他给打字机腾地方时从一堆东西里掉下去的。他看见这个小包已经转寄了好几次。光在一侧上就至少有自己的以前三个军邮信箱号码。
他动手拆包,但是丝毫不感兴趣,甚至都没去看寄件人的地址。他用的是点燃火柴烧断细绳的办法。他更感兴趣的是看着绳子怎样一路烧下去而不是拆开包裹,虽然他最后还是把它打开了。
盒子里有一张钢笔写的短笺,放在用纱纸包着的一样东西的上面。他拿起短笺,读了起来。
17 号,——路
——德文郡
6 月 7 日,1944 年
亲爱的 x 中士,
希望能原谅我在延搁 7 三十八天之后才开始和你的通信,我一直极其忙碌,我姨妈因患咽喉链球菌炎症动了手术几乎不起,我自当承担起一个又一个的重担。但是我经常想起你以及 1944 年 4 月 30 日 3 时 45 分到 4 时 15 分共同度过的那个极其愉快的下午,我写得这么详细是怕你也许忘了。
D 日的事使我们全都异常激动以及敬畏有加,只希望它能加快结束战争与一种生存的方式,说这种生存方式荒唐可笑还是最最轻描淡写的呢。查尔斯和我都非常惦记你;我们希望扣敦廷半岛首次强攻时你不在场。你参加了吗? 请尽快复信。代向你太太致以最热烈的问候。
你忠诚的,
埃斯米
又及。我非常冒昧地随信寄上我的手表,战争结束之前务请留下使用。我们那次短暂的会晤中我未曾注意你是否有表,不过这一只绝对防水防震而且还具有其他许多功能例如可以测知你正在步行的速度。我深信,在目前这样艰难的日子里,它对你肯定比对我能发挥更大的作用,我还希望你能把它看成是一件吉祥的护身符。
如夸我正在教查尔斯读书写字,我发现他是个极其聪明的初学者,他也要在信上写上几个字。请一有时间与心情就立刻回信。
你好你好你好你好你好你好你好你好你好你好爱你也吻你查尔斯
过了许久,x 才终于把信纸放下,更想不起要把埃斯米父亲的手表从盒子里取出来了。当他终于想起,把它取出时,他看到表面玻璃在邮寄过程中已经震碎了。他不知道手表别处有没有损坏,他已经没有勇气去拧紧发条作一番检查了。他只是把它拿在手里,又坐了很长一段时间。接着他突然发现自己有了睡意,这让他简直感到心醉神迷。
只要一个人真正有了睡意,埃斯米啊,那么他总有希望能重新成为一个——一个身心健康如初的人的。
为什么没有音乐-余华
========================
为什么没有音乐-[[余华]]
------
我的朋友马儿在午餐或者晚餐来到的时候,基本上是这样的:微张着嘴来到桌前,他的张嘴与笑容没有关系,弯腰在椅子里坐下,然后低下头去,将头低到与桌面平行的位置,他开始吃了,咀嚼的声音很小,可是将食物往嘴里送的速度很快,一直到吃完,他才会抬起头来,否则他不会破坏头颅与桌面的平行,就是和他说话,他也是低着头回答。
所以,当马儿吃饭的时候,我们都称他是进餐,进餐是一个很正规的词儿,要穿着合适的衣服,坐到合适的桌前,然后还要用合适的方式将该吃的吃下去,总之这是很有讲究的。而吃饭,吃饭这个词儿实在是太马虎了,可以坐在桌前吃,也可以坐在门口吃,还可以端着碗跑到邻居家去吃,我们小的时候经常这样。有时候我们还端着碗走进厕所,一边拉屎一边吃饭。
马儿从来都不是吃饭,他一直都是进餐。自从我认识他,那时候我们都才只有十岁,他就开始进餐了,他吃的时候就像写作文一样认真了。他低着头,那时候他的头颅就已经和桌面平行了,他兢兢业业地吃着,入迷地吃着,吃完以后,他手中的碗像是洗过似的干净,面前的桌子像是已经擦过了,盘中的鱼骨鱼刺仍然像一条鱼似的躺在那里。
这就是马儿。我们总是匆匆忙忙地走在路上,仿佛总是要去赶火车,可是对马儿来说,走在路上的时候,从来就不是赶路,他从来就是散步,双手插在裤袋里,凝视前方,从容不迫地走着。这就是他,做什么事都不慌不忙,同时也是一丝不苟,就是说话也字字清晰,语速均匀,而且十分讲究修辞。
马儿洁身自好,到了二十六岁的时候,他认识了我们都已经认识了的吕媛。我们坐在一起吃饭,是我们把吕媛请来的,吕媛还带来了另外两个年轻女子,我们这边有五个男人,我们都在心里打着她们的主意,而她们,也就是那三个年轻女子,也都在心里挑选着我们。就这样,我们吃着饭,高谈阔论,嘻嘻哈哈,一个个都使足了劲来表现自己,男的词语滔滔,女的搔首弄姿。
只有马儿一声不吭,因为他正在认真地进餐,他的头正与桌面平行着,他脸上挂着淡淡的笑容,听着我们又说又笑。那天晚上他只说了几句话,就是进的餐也很少,只是吃了六只虾,喝了一杯啤酒。
我们很快就忘了他。刚开始我们偶尔还看他一眼,看到他慢吞吞地喝上一口啤酒,过了一会看到他用筷子夹起一只虾放进嘴里,再过一会我们看到他鼓起两腮蠕动着嘴,然后我们就不再看他了。就在我们完全把他忘记以后,吕媛突然发出了一声惊叫,我们看到吕媛睁圆了眼睛,还看到她伸出手指,指着马儿桌前,于是我们看到马儿桌前并排放着五只大小不一的虾,我们看到透明的虾壳在灯光下闪闪发亮,虾壳里面的肉已经被马儿吃干净了。这时候另外两个女的也失声惊叫起来。
接下去我们看到马儿夹起了那天晚上最后的一只虾。他的手臂伸过去的时候,差不多和他低着的头一样高了,他手中的筷子夹住了虾以后,胳膊肘一弯,那动作像是虾钳一样迅速,然后他把虾放进了自己的嘴中。
这一次他抬起了头,平静地看着惊讶的我们。他的嘴唇闭上后,两腮就鼓了出来,接着他的嘴巴就像是十二指肠似的蠕动了起来,脖子上的喉结明快地一上一下。大约五分钟以后,我们看到他鼓起的两腮突然被吸进去了。与此同时,喉结被提上去后就停留在了那里。显然他正在吞咽,他看上去神色凝重,并且小心翼翼。
随后,我们看到他的喉结滑了下来,接着嘴巴也张开了,于是让我们目瞪口呆的时候来了,我们清清楚楚地看着他从嘴里拿出了一只完整无损的虾,重要的是里面的虾肉已经被他吞咽下去了。他将完整的却没有肉的虾放到了桌上,和另外五只同样的虾整齐地放在了一起。那三个年轻女子又是一连串的惊叫。
后来,也就是半年以后,吕媛成为马儿的妻子。当时在座的另外两位女子也结婚了,她们嫁给了我们谁都不认识的两个男人。
吕媛与马儿结婚以后,就将马儿和我们分开了。当我们再度坐到一起吃饭的时候,已经没有了进餐的马儿。说实话,我们有些不习惯,我们开始意识到桌子另一端的那两条平行线是多么有趣,马儿的头和桌子的面,它们之间始终不变的距离就像码头和海岸一样。有时候,当马儿坐在窗前,阳光又从窗外照射进来的时候,我们看到马儿的头在桌面上有了它的兄弟,黑乎乎的影子从扁圆开始,随着阳光的移动,慢慢地变成了细细的一条,这样又长又细的头颅我们谁都没有见过,就是在漫画里我们也找不到。还有一次,我们坐在一间昏暗的屋子里,一盏昏暗的灯又挂得很低,那一次我站起来时头撞在了灯上,我的头顶是又疼又烫,而那盏灯开始了剧烈的摇晃,于是马儿头的影子也在桌面上摇晃起来,既迅速又夸张,而且足足摇晃了两分钟,这桌上的影子将马儿一辈子的摇头都完成了。
马儿结婚以后,只有郭滨一个人与马儿保持着断断续续的联系。他经常在傍晚的时候,穿上灰色的风衣,双手插在口袋里,走在城里最长的街道上,从这一端走到了另一端,然后来到马儿的门前,弯起长长的手指,敲响了马儿的屋门。
郭滨告诉他的朋友们,马儿的新居所散发出来的全是吕媛的气息,从卧室到客厅,墙上挂满了吕媛的特写。这些照片的历史是从满月开始,一直到现在,总共有二十三张。其中只有三张照片里有马儿的微笑,而且旁边还有吕媛更为迷人的笑容,郭滨说:“如果不仔细看,你们是不会注意马儿的。”
郭滨继续告诉他的朋友们,马儿屋中的家具是在白色的基础上闪着粉红的亮光,地毯是米黄的颜色,墙壁也是米黄,就是马儿的衣服,他结婚以后购买的衣服也都有着米黄的基调,郭滨认为这都是吕媛的爱好和主意,郭滨问他的朋友:“你们以前看到过马儿穿米黄衣服吗?”
“没有。”他自己先回答,接着又说,“马儿穿上那些米黄色的衣服以后,看上去胖了,也比过去白了一些。”
郭滨说马儿的家就像是一个单身女子的宿舍,里面摆满了各类小玩意儿,从书架到柜子,全是小动物,有绒布做的,也有玻璃做的,还有竹编的。就是在床上,也还放着一只胖大的绒布黑熊。而属于马儿的,哪怕是他的一支笔也无法在桌子上找到,只有当他的衣服挂在阳台上还没有晾干的时候,才能在他的家中看到属于他的一丝痕迹。说到马儿床上那只绒布黑熊时,郭滨不由得笑了笑,问他的朋友,同时也问自己:“难道吕媛出嫁以后仍然是抱着黑熊睡觉?”
随着时间的流逝,郭滨对马儿家中的了解也逐步地深入,他吹嘘说就是闭上眼睛在马儿家中走上半个小时,也不会碰到一把椅子。而且,他说他知道马儿家中物件的分布,什么柜子放什么东西,什么东西在什么地方,只要他的朋友们有兴趣,他就可以让他们知道。
他说:“他们床头的那个柜子,里面有一个抽屉,抽屉里放着他们两个人的全部证件和他们全部的银行存折,抽屉是上了锁的。抽屉的下面叠着吕媛的短裤和乳罩,还有袜子和围巾。”
至于马儿的短裤、袜子和围巾,则没有单独的地方,它们和马儿的全部衣服,冬天的、夏天的和春秋的衣服堆在一个衣柜里,而且是在一格里面。有一次,郭滨看到马儿为了寻找一件汗衫所付出的艰辛劳动,他就像是在一堆破烂里挑选着破烂一样,先是将头插进柜子,然后他的肩膀也跟着进去了,半个小时以后,他出来了,手里只是拿着一条短裤,他将短裤扔在地毯上,接着将自己所有的衣服都抱出来放在地毯上,地毯上像是堆起了一座小山,他跪在那座小山前,又是半个小时,他终于找到了自己的汗衫。
郭滨表示,他已经非常了解马儿和吕媛之间的微妙关系。他们之间的关系不是你们所能想象的,他这样对他的朋友们说。为了使自己的话更为真实可信,他开始举例说明。
郭滨举例的时候,正坐在椅子里,他站起来走到门前,然后转过身来,看着他的三个朋友,他说了。
他说就是在前天,当他走到马儿家的门前,举起手准备敲门的时候,听到里面有哭泣的声音,哭声很低,很细,每一声都拉得很长,让他感到里面有着催人泪下的悲伤。于是他举起的手又放下了。他在马儿的门外站了很久,一直到哭声低下去,低到听不到。这期间,他在心里反复想着吕媛为什么要哭?是什么事使她如此悲伤?是不是马儿伤害了她?可是他没有听到马儿对她的斥骂,就是说话的声音也没有。
后来,也就是哭声消失了一段时间后,郭滨心想吕媛应该擦干眼泪了,他就再次举起手敲响了他们的屋门。来开门的是马儿,让郭滨吃惊的是,马儿的眼中泪光闪闪,而吕媛则手握遥控器,很舒服地靠在沙发里看着电视。他才知道刚才哭泣的不是吕媛,而是马儿。
你们明白了吗?郭滨微笑着问他的朋友,然后他走回到自己的椅子前,很舒服地坐了下去。
这一天,也就是一九九六年六月三十日的下午,马儿来到了郭滨家中。他的妻子吕媛在这一天去了上海,一星期以后才能回来,于是独自一人的马儿就想到了郭滨,因为郭滨有着丰富的录像带收藏,马儿准备借几盒录像带回家,从而装饰一下独自一人时的生活。
马儿来到的时候,郭滨正在午睡,他穿着三角短裤走到门前,给马儿开了门。他看到马儿的第一个动作就是将嘴巴缓慢地张开来,打出一个缓慢的哈欠,然后眼泪汪汪地问马儿:“吕媛走了?”
马儿有些奇怪,心想他怎么会知道吕媛出差了,就问他:“你怎么知道吕媛走了?”
郭滨伸手擦着眼泪回答:“你告诉我的。”
“我什么时候告诉你的?”马儿想不起来了。
“那就是吕媛告诉我的。”郭滨说。
郭滨说着走进了卫生间,他没有关上门就撒尿了。马儿在沙发里坐了下来,看着卫生间里的郭滨“啊啊啊啊”地打着哈欠,随后一只手又擦起了眼泪,另一只手拉了一下抽水马桶的绳子,在“哗哗”响起的流水声里,郭滨走出了卫生间,他走到马儿的沙发前,犹豫了一下后,又转身躺在床上,然后侧身看着马儿。
马儿看到阳台旁的墙角架着一台手掌摄像机,他问郭滨:“这是谁的摄像机?”
郭滨说:“我的,一个月前买的。”
马儿点点头,过了会他说:“我想借几盒录像带。”
郭滨问他:“你是要暴力的,还是要言情的?”
马儿想了想后说:“都要。”
“你自己去拿吧。”郭滨说。
接着郭滨又告诉马儿:暴力片在书柜的第三格和第四格,言情片在第五格里面,还有第六格的右侧。郭滨在和马儿说话的过程里,始终用手挖着自己的眼屎,同时还打着哈欠。
马儿走到书柜前,将眼睛凑上去,仔细看了一会,在第三格和第五格里都取出一盒录像带。他将两盒录像带拿在手里,转过身去时,看到郭滨的眼睛已经闭上了,他迟疑了一下后,轻声说道:“我拿了两盒。”
郭滨的眼睛睁了开来,他撑起了身体,然后歪着头坐在床上。马儿对他说:“你睡吧,我走了。”
这时候郭滨的脸上出现了笑容,他的笑容越来越古怪,然后他问马儿:“你想不想看色情片?”
马儿的脸上也出现了笑容,郭滨一下子就跳下了床,跪在地上从床下拖出了一只箱子,打开箱子后,马儿看到了半箱的录像带。郭滨得意地告诉他:“全是色情片。”
接着郭滨问马儿:“你要港台的,还是外国的?”
“我不知道。”马儿回答。
郭滨站了起来,看到马儿不知所措,就拍拍他的肩膀说:“你自己拿一盒吧,随便拿一盒。”
马儿随便地拿了一盒。这天晚上,马儿一个人躺在床上,先是看了那部让他眼泪汪汪的言情片,接着看了那部让他毛骨悚然的暴力片。最后,他决定看色情片了。
他将录像带插进了已经发烫的录像机,趁着倒带的间隙,他上了卫生间。当他从卫生间出来时,录像带已经倒完,开始自动放映了,他看到电视上一片雪花,雪花闪了几分钟后,画面出现了,一个女人赤身裸体地躺在床上,她的脸埋在松软的枕头里,两条腿曲起后架在一起。一个男人的一条胳膊在画面的左侧甩动了起来,接着出现了和胳膊连起来的肩膀,然后是整个背部,马儿看到了一个男人向着床走去,走到了床边,那个男人向前伸出了手,两条腿一前一后地向上一弯,他使用自己的膝盖爬到了床上,随后他将那个女人架在一起的腿分开,他的身体叠了上去。
马儿听到了一声轻微的“嗯”,接着看到男人的身体在女人的身体上移动起来。马儿注意到了男人抖动的屁股,像是被冻坏了似的在抖动。马儿听到了男人的喘息声,这时候女人的“嗯嗯”声接二连三地来到了。接下去画面没有变化,床上叠在一起的两个身体在抖动里出现了一些轻微的摇晃。就这样,单调的画面持续了一会,马儿听到了他们的叫声。随后,重叠的两具身体都静止了,仿佛一下子死了似的。过了一会,男人的身体出现了一个翻身,他下来了,于是马儿听到了那个女人撒娇地“嗯”了很长的一声。翻身下来的男人跪在床上,背对着镜头,低头在做着什么。
马儿意识到他们的工作已经结束,可是……马儿在心里想:“为什么没有音乐?”
他觉得很奇怪,心想:“难道色情片都没有音乐?”
这时那个男人又躺了下去,和那个女人并肩躺着,两个人跷起脚,共同将一条毯子扯过去,把两具光着的身体盖住了。
马儿听到男人问:“怎么样?”
女人说:“好极了。”
沉默了一会,男人突然提到了马儿的名字,让马儿吃了一惊。马儿听到他说:“我比马儿强吧?”
女人说:“强多了。”
马儿正在疑惑自己是不是听错了,那个男人又一次说出了他的名字。那个男人说:“马儿是怎么干的?”
“讨厌。”女人打了男人一下说,“我不是告诉过你吗?”
男人说:“我还想听一遍。”
女人这时笑了起来,笑了一会后她说:“他一动不动。”
“怎么一动不动?”男人问。
“真讨厌。”女人笑着说。
男人继续问:“怎么一动不动?”
“他进来后就一动不动了……你真是讨厌。”女人又挥手打了男人一下。
“他的身体在什么地方?”男人问。
“他的身体压着我,他一动不动地压着我,压得我气都喘不过来……行了吧?”女人说。
“他这么一动不动地把你压多长时间?”男人问。
“有时候长,有时候短,有几次他压着我睡着了。”女人说。
“他睡着了你怎么办?”男人问。
女人说:“我使劲翻一个身把他推下去……行了吧?”
两个人都哈哈大笑起来,笑了一阵后,那个男人突然坐了起来,脸对着镜头下了床,男人说:“我们看看自己的录像。”
马儿在走过来的男人那里,认出了郭滨的脸。在郭滨的后面,那个女人坐起来后,马儿看到了吕媛的笑容。
一个星期以后,吕媛回到了家中,她推门而进的时候,看到阳台前的桌旁坐着马儿,马儿正在进餐。吕媛自然就看到了两条平行线,她还看到一碗热气腾腾的面条把马儿的脸蒸得通红,她将自己的手提包扔进了沙发,然后对马儿说:“去把皮箱提上来。”
马儿抬头看了她一眼,然后继续进餐。吕媛走进了厨房,打开水龙头往自己的脸上泼水。泼上水以后,她开始用手掌轻轻拍打自己的脸。拍打了一会,她从架子上拿下洗面奶,仔细地洗起了自己的脸。当她洗完脸走回到客厅时,马儿仍然在一丝不苟地进着餐,她环顾四周后没有看到自己的皮箱,就问马儿:“我的皮箱呢?”
马儿继续进餐,这一回头都没有抬一下。吕媛继续说:“我的皮箱呢?”
马儿还是没有回答,吕媛的声音一下子响亮起来,她冲着马儿喊叫道:“你给我下楼去!”
马儿抬起了头,从桌上的餐巾盒里抽出一张餐巾纸,很斯文地擦了擦嘴,然后问吕媛:“你为什么要说我一动不动?”
怒气冲冲的吕媛没有准备去听这样一句话,所以她没有反应过来,她仍然强硬地说:“去把皮箱提上来!”
马儿继续问她:“你为什么说我一动不动?”
吕媛开始意识到出了什么事,她不再喊叫,而是眼睛发直地看着马儿。她看到马儿又抽出了一张餐巾纸,很斯文地擦起了额上的汗,马儿说:“其实我还是动了……”
马儿停顿了一下后又说:“到了关键的时候,我还是动的。”
说完后,马儿低下了头,去进行他最后两口面条的进餐。吕媛悄无声息地走进卧室,她在卧室的床上坐了一段时间后,又悄无声息地下了楼,自己将皮箱提了上来。
后来,什么事都没有发生。我的朋友马儿没有把那三盒录像带还给郭滨,郭滨也没有向马儿提起。在后来的日子里,有时候郭滨依然穿上灰色的风衣,双手插在口袋里,走完城里那条最长的街道,来到马儿的屋门前,弯起长长的手指敲响马儿的屋门。
------
一九九六年九月五日
喂——出来!
作者:[[星新一]]
-----
一场台风过后,晴空万里。
在离城市不远的近郊,有一个村庄遭到了台风的破坏。不过,损失还不太严重,仅仅是村外山脚下那座小小的庙被台风连根端跑了,并没有伤什么人。
第二天早晨,村里人知道了这件事以后便纷纷议论起来。
“那座庙是哪个朝代留下来的呀?”
“谁知道呀,正是年代很久了。”
“必须赶快重新建造一座新的庙。”
正当大家你一言我一语他说着的时候,有几个人神色慌张地跑了过来。
“不得了,闯大祸啦!”
“什么事?就在附近吗?”
“不,还要过去一点,就在那边。”
这时候,有一个人忽然失色惊叫起来:
“喂,快来看呀。这个洞究竟是怎么回事呀?”
大家跑过去一看,地面上果真有一个洞,直径大约在一米左右。人们探着头向里面瞧了瞧,可是洞里黑咕隆咚的什么也看不见。然而,人们却有一种深不可测的感觉,这个洞似乎是一直通向地球中心的。
有一个人怀疑他说:“该不是狐狸洞吧?”
一个年轻人对着洞里使劲地大叫了一声。
“喂——出来!”
可是,并没有任何回声从洞底下传上来。于是,他就在附近捡了一块小石头准备要扔进洞里去。
一位胆小怕事的老年人颤巍巍地摆着双手,要想劝阻年轻人别这么干。
“这可千万不能扔下去呀,说不定会受到什么可怕的惩罚的。”
但是,年轻人早就抢先一步,把石头扔进了洞里。然而,洞底下仍然没有任何回声传上来。
村里人砍来了许多树枝,用绳子一道一道地缠绕着做成了栅栏,把这个洞围了起来。然后,他们就暂时先回到村庄里去了。
“接下来该怎么办呢?”
“还是在这个洞上面按照原来的样子建造一座庙吧。”
大家七嘴八舌地商量着,众说纷纭,莫衷一是。一天就这样过去了。消息灵通的报社记者们很快就打听到了这件事,争先恐后地开着小汽车赶来了。不一会儿,科学家和学者也都闻风而了来。并且,每个人都显示出一副极其渊博、无所不知的神色,镇定自若地朝洞里张望着。随后,陆陆续续地又来了一大群看热闹的人。有的人反反复复地打量着这个洞,眼睛里露出贪婪的目光,心里不住地盘算着:是否可以从中牟取什么利润,要不要趁早出高价买下这个洞的专利权?派出所的警察们寸步不离地守卫在洞口周围,以防有人不慎跌落下去。
一位新闻记者拿来一根很长的细绳子,把只秤砣缚在一端,小心翼翼地往下放,渐渐地,绳子一尺一尺地放了下去。可是,等到绳子全部放完之后却拉不上来了。他叫了两三个人过来帮忙。大家齐心协力地使劲一拉,绳子居然在洞里的什么地方断掉了。一位手里拿着照相机的记者见到了这番情形,一声不响地解掉了扎在自己腰里的那条结实的粗绳子。
有一位学者叫人从研究所里搬来了一台大功率的扩音机,准备对洞底传上来的回声作频率分析。可是,他把扩音机摆弄了好久,各种各样的声音都试过了,却连半点回声也没听到。这位学者感到挺纳闷。他苦苦地思索着,这究竟是什么道理。然而,在众目睽睽之下决不能就此作罢,遭人耻笑。他把扩音机紧靠住洞口,把音量开到最大限度,震耳欲聋的声音源源不断地从扩音机里传了出来,经久不息。如果是在地面上的话,数十公里以外的人都可以听到这种声音。可是,这个洞却来者不拒,把所有的声音都一古脑儿地吞了下去。
学者不禁心里有些发虚了,他装着镇定自若、胸有成竹的样子关掉了扩音机,用不容置疑的口气吩咐道:“赶快把它填掉!”
虽说事情还没弄清楚,但还是赶快处理掉为妙,免得堂堂学者当众出丑。
难道就这么草草收场了?周围那些看热闹的人都觉得有点儿可惜。但也没有办法,看来只好扫兴而归了。正在这时候,有一个人满头大汗地从人堆里挤了出来,大声地提议道:“请把这个洞让给我吧。我来给你们填。”
他就是起先打算出高价买下这个洞的专利权的那个投机商人。
可是,这个村庄里的村长却不同意。
“你愿意给我们填掉这个洞固然是件好事情,可是这个洞却不能给你。因为我们必须在这上面建造一座庙。”
“请放心,我马上就给你们建造一座更加出色的庙,并且还附带一个广场,怎么样?”
村长还没来得及回答,村民们就异口同声地叫了起来。“这是真的吗?要是造在离我们村庄更近一点的地方就好了。”
“一个洞有什么稀奇的,现在就送给你吧。”
于是,这笔买卖就拍板成交了。当然,村长也只好对此表示同意了。
这位收买专利权的商人按照合同实行了自己的诺言。在离村庄更近的地方,一座小小的庙建造起来了,并且还附带建造了一个广场。
在这一年的秋收季节,这位专利权所有者创办了一家新奇的“填洞公司”。在这个洞的附近造起了一所小房子,门上桂着一块小小的招牌。
接着,这位专利权所有者就叫他的伙伴们在城里到处奔走,用各种方法进行宣传。
“本公司有一个绝妙的深不可测的洞。据学者们估计,其深度至少在五千米以上。这是容纳原子能反应堆的核废料等危险物品的最好的场所。机不可失,时不再来!”
不久,政府有关部门发给了营业许可证。许多原子能发电公司都争先恐后地前来签订合同。刚开始时,村里人都有点担心,生怕会出什么事情。可是,“填洞公司”派人对他们进行说明,这是一个非常保险的洞,即使过上几千年也绝不会对地面上产生什么危害。此外,村民们还可以从中得到好处呢。大家明白了这一点以后也就放心了。并且,从城里通到这个村庄的现代化高速公路也很快地建成通车了。
卡车在公路上奔驰着,源源不断地运来了许多铅做的大箱子。箱盖在这个洞的上方自动地打开,原子能反应堆的废料就倾泻到这个洞里。
外交部和国防部把那些用不着的机密文件连同保险柜一块儿扔了进去。随车前来执行监督任务的政府官员们,很轻松地谈论着打高尔夫球的事情,而那些职位较低的工作人员,则一边扔着各种文件,一边谈论着弹球房的事情。
看上去,这个洞似乎永远也填不满似的。大家都一致认为,这是一个深不可测的无底洞,并且,也许越往深处洞的直径越大吧。“填洞公司”的经营规模一点一点地扩大了起来。
在大学里做传染病实验的那些动物的尸体被运来,并且其中还夹杂着不少无人认领的流浪者的尸体。有关方面制定了一个计划,准备铺设大量的管道,以便把城市里的废物和污水全都排放到这个洞里去。这个办法要比向海洋排污高明多了。
这个洞使得生活在城市里的居民们感到了极大的欣慰。最近一个时期以来,由于人们只顾拼命地扩大生产规模,从而给城市造成了极其严重的公害。可是,要想治理这些公害却相当困难,无论是谁都感到很棘手。并且,人们都只愿意在生产性企业或商业公司工作,谁也不愿意天天和各种各样的垃圾打交道。然而,现在人们都认为,这个社会问题将由这个洞来逐步地加以妥善解决。
订了婚的姑娘们都把从前的那些日记本丢进了这个洞里。还有的人把从前同恋人一起拍的照片扔进了洞里,然后又心安理得地开始了新的恋爱。
警察把那些伪造得极其巧妙的假钞票没收来以后,也统统交给这个洞处理,从此便可万无一失了。而犯罪分子们则把各种犯罪证据都悄悄地扔进了洞里,以为这样就能逍遥法外了。
不管是扔进去什么东西,这个慷慨大方的洞全部一视同仁,照收不误。这个洞任劳任怨地给整个城市洗刷着各种肮脏的东西。渐渐地,海洋和天空又变成了美丽的蔚蓝色,远远地看上去就像是透明的玻璃一样。
在这瓦蓝瓦蓝的天空下面,新建造的高楼大厦就像雨后春笋一般接连不断地竖了起来。
有一天,一位工人爬在一幢正在施工的大楼顶上工作,他铆完了一颗铆钉之后,便放下工具稍微休息一会儿。忽然,他听到头顶上传来了奇怪的叫声。
“喂——出来!”
然而,他抬起头来朝天上看了看,却什么也没有,睛空万里,清澈如洗。他以为是刚才干得有点头晕了,产生了什么错觉。接着,正在他恢复到刚才的姿势,要好好地休息一会儿的时候,从刚才发出声音的那个方向飞过来一块石头,在他面前一掠而过,往地面上掉了下去。
可是,他只顾眯着眼睛得意洋洋地眺望着远处的地平线。啊,我们的城市变得越来越美好啦!
当然,那块微不足道的小石头根本就没引起他的丝毫注意。
-----
(李有宽译)
温暖和百感交集的旅程 余华
========================
温暖和百感交集的旅程- [[余华]]
------
我经常将川端康成和卡夫卡的名字放在一起,并不是他们应该在一起,而是出于我个人的习惯。我难以忘记1980年冬天最初读到《伊豆的歌女》时的情景,当时我二十岁,我是在浙江宁波靠近甬江的一间昏暗的公寓里与川端康成相遇。五年之后,也是在冬天,也是在水边,在浙江海盐一间临河的屋子里,我读到了卡夫卡。谢天谢地,我没有同时读到他们。当时我年轻无知,如果文学风格上的对抗过于激烈,会使我的阅读不知所措和难以承受。在我看来,川端康成是文学里无限柔软的象征,卡夫卡是文学里极端锋利的象征;川端康成叙述中的凝视缩短了心灵抵达事物的距离,卡夫卡叙述中的切割扩大了这样的距离;川端康成是肉体的迷宫,卡夫卡是内心的地狱;川端康成如同盛开的罂粟花使人昏昏欲睡,卡夫卡就像是流进血管的海洛因令人亢奋和痴呆。我们的文学接受了这样两份绝然不同的遗嘱,同时也暗示了文学的广阔有时候也存在于某些隐藏的一致性之中。川端康成曾经这样描述一位母亲凝视死去女儿时的感受:“女儿的脸生平第一次化妆,真像是一位出嫁的新娘。”类似起死回生的例子在卡夫卡的作品中同样可以找到。《乡村医生》中的医生检查到患者身上溃烂的伤口时,他看到了一朵玫瑰红色的花朵。
这是我最初体验到的阅读,生在死之后出现,花朵生长在溃烂的伤口上。对抗中的事物没有经历缓和的过程,直接就是汇合,然后同时拥有了多重品质。这似乎是出于内心的理由,我意识到伟大作家的内心没有边界,或者说没有生死之隔,也没有美丑和善恶之分,一切事物都以平等的方式相处。他们对内心的忠诚使他们写作时同样没有了边界,因此生和死、花朵和伤口可以同时出现在他们的笔下,形成叙述的和声。
我曾经迷恋于川端康成的描述,那些用纤维连接起来的细部,我说的就是他描述细部的方式。他叙述的目光无微不至,几乎抵达了事物的每一条纹路,同时又像是没有抵达,我曾经认为这种若即若离的描述是属于感受的方式。川端康成喜欢用目光和内心的波动去抚摸事物,他很少用手去抚摸,因此当他不断地展示细部的时候,他也在不断地隐藏着什么。被隐藏的总是更加令人着迷,它会使阅读走向不可接近的状态,因为后面有着一个神奇的空间,而且是一个没有疆界的空间,可以无限扩大,也可以随时缩小。为什么我们在阅读之后会掩卷沉思?这是因为我们需要走进那个神奇的空间,并且继续行走。这样的品质也在卡夫卡和马尔克斯,以及其他更多的作家那里出现,这也是我喜爱《礼拜二午睡时刻》的一个原因。
加西亚·马尔克斯是无可争议的大师,而且生前就已获此殊荣。《百年孤独》塑造了一个天马行空的作家的偶像,一个将想象力尽情挥霍的偶像,其实马尔克斯在叙述里隐藏着小心翼翼的克制,正是这两者间激烈的对抗,造就了伟大的马尔克斯。《礼拜二午睡时刻》所展示的就是作家克制的才华,这是一个在任何时代都有可能出现的故事,因此也是任何时代的作家都有可能写下的故事。我的意思是它的主题其实源远流长,一个母亲对儿子的爱。虽然作为小偷的儿子被人枪杀的事实会令任何母亲不安,然而这个经过了长途旅行,带着已经枯萎的鲜花和唯一的女儿,来到这陌生之地看望亡儿之坟的母亲却是如此的镇静。马尔克斯的叙述简洁和不动声色,人物和场景仿佛是在摄影作品中出现,而且他只写下了母亲面对一切的镇静,镇静的后面却隐藏着无比的悲痛和宽广的爱。为什么神父都会在这个女人面前不安?为什么枯萎的鲜花会令我们战栗?马尔克斯留下的疑问十分清晰,疑问后面的答案也是同样的清晰,让我们觉得自己已经感受到了,同时又觉得自己的感受还远远不够。
卡夫卡的作品,我选择了《在流放地》。这是一个使人震惊的故事,一个被遗弃的军官和一架被遗弃的杀人机器,两者间的关系有点像是变了质的爱情,或者说他们的历史是他们共同拥有的,少了任何一个都会两个同时失去。应该说,那是充满了荣耀和幸福的历史。故事开始时他们的蜜月已经结束,正在经历着毁灭前凋零的岁月。旅行家──这是卡夫卡的叙述者──给予了军官回首往事的机会,另两个在场的人都是士兵,一个是“张着大嘴,头发蓬松”即将被处决的士兵,还有一个是负责解押的士兵。与《变形记》这样的作品不同,卡夫卡没有从一开始就置读者于不可思议的场景之中,而是给予了我们一个正常的开端,然后向着不可思议的方向发展。随着岁月的流逝,机器的每一个部分都有了通用的小名,军官向旅行家介绍:“底下的部分叫做‘床’,最高的部分叫‘设计师’,在中间能够上下移动的部分叫做‘耙子’。”还有特制的粗棉花,毛毡的小口衔,尤其是这个在处死犯人时塞进他们嘴中的口衔,这是为了阻止犯人喊叫的天才设计,也是卡夫卡叙述中令人不安的颤音。由于新来的司令官对这架杀人机器的冷漠,部件在陈旧和失灵之后没有得到更换,于是毛毡的口衔上沾满了一百多个过去处死犯人的口水,那些死者的气息已经一层层地渗透了进去,在口衔上阴魂不散。因此当那个“张着大嘴,头发蓬松”犯人的嘴刚刚咬住口衔,立刻闭上眼睛呕吐起来,把军官心爱的机器“弄得像猪圈一样”。卡夫卡有着长驱直入的力量,仿佛匕首插入身体,慢慢涌出的鲜血是为了证实插入行为的可靠,卡夫卡的叙述具有同样的景象,细致、坚实和触目惊心,而且每一段叙述在推进的同时也证实了前面完成的段落,如同匕首插入后鲜血的回流。因此,当故事变得越来越不可思议的时候,故事本身的真实性不仅没有削弱,反而增强。然后,我们读到了军官疯狂同时也是合理的举动,他放走了犯人,自己来试验这架快要崩溃的机器,让机器处死自己。就像是一对殉情的恋人,他似乎想和机器一起崩溃。这个有着古怪理想的军官也要面对那个要命的口衔。卡夫卡这样写道:“可以看得出来军官对这口衔还是有些勉强,可是他只是躲闪了一小会儿,很快就屈服了,把口衔纳进了嘴里。”
我之所以选择《在流放地》,是因为卡夫卡这部作品留在叙述上的刻度最为清晰,我所指的是一个作家叙述时产生力量的支点在什么地方?这位思维变幻莫测的作家,这位让读者惊恐不安和难以预测的作家究竟给了我们什么?他是如何用叙述之砖堆砌了荒诞的大厦?《在流放地》清晰地展示了卡夫卡叙述中伸展出去的枝叶,在对那架杀人机器细致入微的描写里,这位作家表达出了和巴尔扎克同样准确的现实感,这样的现实感也在故事的其他部分不断涌现,正是这些拥有了现实依据的描述,才构造了卡夫卡故事的地基。事实上他所有的作品都是如此,只是人们更容易被大厦的荒诞性所吸引,从而忽视了建筑材料的实用性。
布鲁诺·舒尔茨的《鸟》和若昂·吉马朗埃斯·罗萨的《河的第三条岸》也是同样如此。《鸟》之外我还选择了舒尔茨另外两部短篇小说,《蟑螂》和《父亲的最后一次逃走》。我认为只有这样,在《鸟》中出现的父亲的形象才有可能完整起来。我们可以将它们视为一部作品中的三个章节,况且它们的篇幅都是十分简短。舒尔茨赋予的这个“父亲”,差不多是我们文学中最为灵活的形象。他在拥有了人的形象之外,还拥有了鸟、蟑螂和螃蟹的形象,而且他在不断地死去之后,还能够不断地回来。这是一个空旷的父亲,他既没有人的边界,也没有动物的边界,仿佛幽灵似的飘荡着,只要他依附其上,任何东西都会散发出生命的欲望。因此,他是一个实实在在的生命,可以说是人的生命。舒尔茨的描述是那样的精确迷人,“父亲”无论是作为人出现,还是作为鸟、蟑螂或者螃蟹出现,他的动作和形态与他生命所属的种族都有着完美的一致性。值得注意的是,舒尔茨与卡夫卡一样,当故事在不可思议的环境和突如其来的转折中跳跃时,叙述始终是扎实有力的,所有的事物被展示时都有着现实的触摸感和亲切感。尽管舒尔茨的故事比卡夫卡更加随意,然而叙述的原则是一致的。就像格里高里·萨姆沙和甲虫互相拥有对方的习惯,“父亲”和蟑螂或者螃蟹的结合也使各自的特点既鲜明又融洽。
若昂·吉马朗埃斯·罗萨在《河的第三条岸》也塑造了一个父亲的形象,而且也同样是一个脱离了父亲概念的形象,不过他没有去和动物结合,他只是在自己的形象里越走越远,最后走出了人的疆域,有趣的是这时候他仍然是一个活生生的人。这个永不上岸的父亲,使罗萨的故事成为了一个永不结束的故事。这位巴西作家在讲述这个故事时,没有丝毫离奇之处,似乎是一个和日常生活一样真实的故事,可是它完全不是一个日常生活的故事,它给予读者的震撼是因为它将读者引向了深不可测的心灵的夜空,或者说将读者引向了河的第三条岸。罗萨、舒尔茨和卡夫卡的故事共同指出了荒诞作品存在的方式,他们都是在人们熟悉的事物里进行并且完成了叙述,而读者却是鬼使神差地来到了完全陌生的境地。这些形式荒诞的作家为什么要认真地和现实地刻画每一个细节?因为他们在具体事物的真实上有着难以言传的敏锐和无法摆脱的理解,同时他们的内心总是在无限地扩张,因此他们作品的形式也会无限扩张。
在卡夫卡和舒尔茨之后,辛格是我选择的第三位来自犹太民族的作家。与前两位作家类似,辛格笔下的人物总是难以摆脱流浪的命运,这其实是一个民族的命运。不同的是,卡夫卡和舒尔茨笔下的人物是在内心的深渊里流浪,辛格的人物则是行走在现实之路上。这也是为什么辛格的人物充满了尘土飞扬的气息,而卡夫卡和舒尔茨的人物一尘不染,因为后者生活在想象的深处。然而,他们都是迷途的羔羊。《傻瓜吉姆佩尔》是一部震撼灵魂的杰作,吉姆佩尔的一生在短短几千字的篇幅里得到了几乎是全部的展现,就像写下了浪尖就是写下整个大海一样,辛格的叙述虽然只是让吉姆佩尔人生的几个片段闪闪发亮,然而他全部的人生也因此被照亮了。这是一个比白纸还要洁白的灵魂,他的名字因为和傻瓜紧密相连,他的命运也就书写了一部受骗和被欺压的历史。辛格的叙述是如此的质朴有力,当吉姆佩尔善良和忠诚地面对所有欺压他和欺骗他的人时,辛格表达了人的软弱的力量,这样的力量发自内心,也来自深远的历史,因此它可以战胜所有强大的势力。故事的结尾催人泪下,已经衰老的吉姆佩尔说:“当死神来临时,我会高高兴兴地去。不管那里会是什么地方,都会是真实的,没有纷扰,没有嘲笑,没有欺诈。赞美上帝:在那里,即使是吉姆佩尔,也不会受骗。”此刻的辛格似乎获得了神的目光,他看到了,也告诉我们:有时候最软弱的也会是最强大的。就像《马太福音》第十八章所讲述的故事:门徒问耶稣:“天国里谁是最大的?”耶稣叫来了一个小孩,告诉门徒:“凡自己谦卑像这小孩子的,他在天国里就是最大的。”
据我所知,鲁迅和博尔赫斯是我们文学里思维清晰和思维敏捷的象征,前者犹如山脉隆出地表,后者则像是河流陷入了进去,这两个人都指出了思维的一目了然,同时也展示了思维存在的两种不同方式。一个是文学里令人战栗的白昼,另一个是文学里使人不安的夜晚;前者是战士,后者是梦想家。这里选择的《孔乙己》和《南方》,都是叙述上惜墨如金的典范,都是文学中精瘦如骨的形象。在《孔乙己》里,鲁迅省略了孔乙己最初几次来到酒店的描述,当孔乙己的腿被打断后,鲁迅才开始写他是如何走来的。这是一个伟大作家的责任,当孔乙己双腿健全时,可以忽视他来到的方式,然而当他腿断了,就不能回避。于是,我们读到了文学叙述中的绝唱。“忽然间听得一个声音,‘温一碗酒’。这声音虽然极低,却很耳熟。看时又全没有人。站起来向外一望,那孔乙己便在柜台下对了门槛坐着。”先是声音传来,然后才见着人,这样的叙述已经不同凡响,当“我温了酒,端出去,放在门槛上”,孔乙己摸出四文大钱后,令人战栗的描述出现了,鲁迅只用了短短一句话,“见他满手是泥,原来他是用这手走来的”。
这就是我为什么热爱鲁迅的理由,他的叙述在抵达现实时是如此的迅猛,就像子弹穿越了身体,而不是留在了身体里。与作为战士的鲁迅不同,作为梦想家的博尔赫斯似乎深陷于不可知的浪漫之中,他那简洁明快的叙述里,其实弥漫着理性的茫然,而且他时常热衷于这样的迷茫,因此他笔下的人物常常是头脑清楚,可是命运模糊。当他让虚弱不堪的胡安·达尔曼捡起匕首去迎接决斗,也就是迎接不可逆转的死亡时,理性的迷茫使博尔赫斯获得了现实的宽广,他用他一贯的方式写道:“如果说,达尔曼没有了希望,那么,他也没有了恐惧。”
鲁迅的孔乙己仿佛是记忆凝聚之后来到了现实之中,而《南方》中的胡安·达尔曼则是一个努力返回记忆的人。叙述方向的不同使这两个人物获得了各自不同的道路,孔乙己是现实的和可触摸的,胡安·达尔曼则是神秘的和难以把握的。前者从记忆出发,来到现实;后者却是从现实出发,回到记忆之中。鲁迅和博尔赫斯似乎都怀疑岁月会抚平伤疼,因此他们笔下的人物只会在自己的厄运里越走越远,最后他们殊途同归,消失成为了他们共同的命运。值得注意的是,现实的孔乙己和神秘的胡安·达尔曼,都以无法确定的方式消失:“我到现在终于没有见──大约孔乙己的确死了。”“达尔曼手里紧紧地握着匕首,也许他根本不知道怎么使用它,就出了门,向草原走去。”
拉克司奈斯的《青鱼》和克莱恩的《海上扁舟》是我最初阅读的记录,它们记录了我最初来到文学身旁时的忐忑不安,也记录了我当时的激动和失眠。这是二十年前的往事了,如果没有拉克司奈斯和克莱恩的这两部作品,还有川端康成的《伊豆的歌女》,我想,我也许不会步入文学之门。就像很多年以后,我第一次看到伯格曼的《野草莓》后,才知道什么叫电影一样,《青鱼》和《海上扁舟》在二十年前就让我知道了什么是文学。直到现在,我仍然热爱着它们,这并不是因为它们曾使我情窦初开,而是它们让我知道了文学的持久和浩瀚。这两部短篇小说都只是叙述了一个场景,一个在海上,另一个在海边。这似乎是短篇小说横断面理论的有力证明,问题是伟大的短篇小说有着远远超过篇幅的纬度和经度。《海上扁舟》让我知道了什么是叙述的力量,一叶漂浮在海上的小舟,一个厨子,一个加油工人,一个记者,还有一个受伤的船长,这是一个抵抗死亡,寻找生命之岸的故事。史蒂芬·克莱恩的才华将这个单调的故事拉长到一万字以上,而且丝丝入扣,始终激动人心。拉克司奈斯的《青鱼》让我明白了史诗不仅仅是篇幅的漫长,有时候也会在一部简洁的短篇小说中出现。就像瓦西里·康定斯基所说的“一种无限度的红色只能由大脑去想象”,《青鱼》差不多是完美地体现了文学中浩瀚的品质,它在极其有限的叙述里表达了没有限度的思想和情感,如同想象中的红色一样无边无际。
这差不多是我二十年来阅读文学的经历,当然还有更多的作品这里没有提及。我对那些伟大作品的每一次阅读,都会被它们带走。我就像是一个胆怯的孩子,小心翼翼地抓住它们的衣角,模仿着它们的步伐,在时间的长河里缓缓走去,那是温暖和百感交集的旅程。它们将我带走,然后又让我独自一人回去。当我回来之后,才知道它们已经永远和我在一起了。
一九九九年四月三十日
文学和文学史-余华
========================
文学和文学史-[[余华]]
-------
这一天,纳粹党卫军在波兰的德罗戈贝奇对街上毫无准备的犹太人进行了扫射,一百五十人倒在了血泊之中。这只是德国纳粹在那个血腥年代里所有精心策划和随心所欲行动中的一个例子,无辜者的鲜血染红了欧洲无数的街道,波兰的德罗戈贝奇也不例外。死难者的姓名以孤独的方式被他们的亲友和他们曾经居住过的城市所铭记,只有一个人的姓名从他们中间脱颖而出,去了法国、德国和其他更多的地方,1992年他来到了中国,被印刷在当年第3期的《外国文艺》上,这个人就是布鲁诺·舒尔茨,这位中学图画教师死于1942年11月19日。
他可能是一位不错的画家,从而得到过一位喜欢他绘画的盖世太保军官的保护。同时他也写下了小说,死后留下了两本薄薄的短篇小说集和一个中篇小说,此外他还翻译了卡夫卡的[[《审判》]]。他的作品有时候与卡夫卡相像,他们的叙述如同黑暗中的烛光,都表达了千钧一发般的紧张之感。同时他们都是奥匈帝国的犹太人──卡夫卡来自布拉格;布鲁诺·舒尔茨来自波兰的德罗戈贝奇。犹太民族隐藏着某些难以言传的品质,只有他们自己可以去议论。另一位犹太作家艾萨克·辛格也承认布鲁诺·舒尔茨有时候像卡夫卡,同时辛格感到他有时候还像普鲁斯特,辛格最后指出:“而且时常成功地达到他们没有达到的深度。”
[[布鲁诺·舒尔茨]]可能仔细地阅读过卡夫卡的作品,并且将德语的《审判》翻译成波兰语。显然,他是卡夫卡最早出现的读者中的一位,这位比卡夫卡年轻九岁的作家一下子在镜中看到了自己,他可能意识到别人的心脏在自己的身体里跳动起来。心灵的连接会使一个人的作品激发起另一个人的写作,然而没有一个作家可以在另外一个作家那里得到什么,他只能从文学中去得到。即便有卡夫卡的存在,布鲁诺·舒尔茨仍然写下了本世纪最有魅力的作品之一,可是他的数量对他的成名极为不利。卡夫卡的作品震撼近一个世纪的阅读,可是他没有收到眼泪;布鲁诺· 舒尔茨被人点点滴滴地阅读着,他却两者都有。这可能也是艾萨克·辛格认为他有时候像普鲁斯特的理由,他的作品里有着惊人的孩子般的温情。而且,他的温情如同一棵大树的树根一样被埋藏在泥土之中,以其隐秘的方式喂养着那些茁壮成长中的枝叶。
与[[卡夫卡]]坚硬有力的风格不同,布鲁诺·舒尔茨的叙述有着旧桌布般的柔软,或者说他的作品里舒展着某些来自诗歌的灵活品性,他善于捕捉那些可以不断延伸的甚至是捉摸不定的意象。在这方面,布鲁诺·舒尔茨似乎与T.S.艾略特更为接近,尤其是那些在城市里游走的篇章,布鲁诺·舒尔茨与这位比自己年长四岁的诗人一样,总是忍不住要抒发出疾病般的激情。
于是,他的比喻就会令人不安。“漆黑的大教堂,布满肋骨似的椽子、梁和桁架──黑黢黢的冬天的阵风的肺。”“白天寒冷而叫人腻烦,硬邦邦的,像去年的面包。”“月亮透过成千羽毛似的云,像天空中出现了银色的鳞片。”“她们闪闪发亮的黑眼睛突然射出锯齿形的蟑螂的表情。”“冬季最短促的、使人昏昏欲睡的白天的首尾,是毛茸茸的……”
“漆黑的大教堂”在叙述里是对夜空的暗示。空旷的景色和气候在布鲁诺·舒尔茨这里经历了物化的过程,而且体积迅速地缩小,成为了实实在在的肋骨和面包,成为了可以触摸的毛茸茸。对于布鲁诺·舒尔茨来说,似乎不存在远不可及的事物,一切都是近在眼前,他赋予它们直截了当的亲切之感──让寒冷的白天成为“去年的面包”;让夜空成为了“漆黑的大教堂”。虽然他的亲切更多的时候会让人战栗,他却仍然坚定地以这种令人不安的方式拉拢着阅读者,去唤醒他们身心皆有的不安感受,读下去就意味着进入了阴暗的梦境,而且以噩梦的秩序排成一队,最终抵达了梦魇。
布鲁诺·舒尔茨似乎建立了一个恐怖博物馆,使阅读者在走入这个变形的展览时异常的小心翼翼。然而,一旦进入到布鲁诺·舒尔茨的叙述深处,人们才会发现一个真正的布鲁诺·舒尔茨,发现他叙述的柔软和对人物的温情脉脉。这时候人们才会意识到布鲁诺·舒尔茨的恐怖只是出售门票时的警告,他那些令人不安的描写仅仅是叙述的序曲和前奏曲,或者在叙述的间隙以某些连接的方式出现。
他给予了我们一个“父亲”,在不同的篇目里以不同的形象──人、蟑螂、螃蟹或者蝎子出现。显然,这是一个被不幸和悲哀、失败和绝望凝聚起来的“父亲”;不过,在布鲁诺·舒尔茨的想象里,“父亲”似乎悄悄拥有着隐秘的个人幸福:“他封起了一个个炉子,研究永远无从捉摸的火的实质,感受着冬天火焰的盐味和金属味,还有烟气味,感受着那些舐着烟囱出口的闪亮的煤烟火蛇的阴凉的抚摸。”
这是《鸟》中的段落。此刻的父亲刚刚将自己与实际的事务隔开,他显示出了古怪的神情和试图远离人间的愿望,他时常蹲在一架扶梯的顶端,靠近漆着天空、树叶和鸟的天花板,这个鸟瞰的地位使他获得了前所未有的快乐。他的妻子对他的古怪行为束手无策,他的孩子都还小,所以他们能够欣赏父亲的举止,只有家里的女佣阿德拉可以摆布他,阿德拉只要向他做出挠痒痒的动作,他就会惊慌失措地穿过所有的房间,砰砰地关上一扇扇房门,躺到最远房间的床上,“在一阵阵痉挛的大笑中打滚,想象着那种他没法顶住的挠痒”。
然后,这位父亲表现出了对动物的强烈兴趣,他从汉堡、荷兰和非洲的动物研究所进口种种鸟蛋,用比利时进口的母鸡孵这些蛋,奇妙的小玩意儿一个个出现了,使他的房间里充满了颜色,它们的形象稀奇古怪,很难看出属于什么品种,而且都长着巨大的嘴,它们的眼睛里一律长着与生俱有的白内障。这些瞎眼的小鸟迅速地长大,使房间里充满了叽叽喳喳的欢快声,喂食的时候它们在地板上形成一张五光十色、高低不平的地毯。其中有一只秃鹫活像是父亲的一位哥哥,它时常张着被白内障遮盖的眼睛,庄严和孤独地坐在父亲的对面,如同父亲去掉了水分后干缩的木乃伊,奇妙的是,它使用父亲的便壶。
父亲的事业兴旺发达,他安排起鸟的婚配,使那些稀奇古怪的新品种越来越稀奇古怪,也越来越多。这时候,阿德拉来了,只有她可以终止父亲的事业。阿德拉成为了父亲和人世间唯一的联结,成为了父亲内心里唯一的恐惧。怒气冲冲的阿德拉挥舞着扫帚,清洗了父亲的王国,把所有的鸟从窗口驱赶了出去。“过了一会儿,我父亲下楼来── 一个绝望的人,一个失去了王位和王国的流亡的国王。”
布鲁诺·舒尔茨为自己的叙述找到了一个纯洁的借口──孩子的视角,而且是这位父亲的儿子,因此叙述者具有了旁人和成年人所不具备的理解和同情心,孩子的天真隐藏在叙述之中,使布鲁诺·舒尔茨内心的怜悯弥漫开来,温暖着前进中的叙述。在《蟑螂》里,讲述故事的孩子似乎长大了很多,叙述的语调涂上了回忆的色彩,变得朴实和平易近人。那时候父亲已经神秘地消失了,他的鸟的王国出租给了一个女电话接线员,昔日的辉煌破落成了一个标本──那只秃鹫的标本,站在起居室的一个架子上。它的眼睛已经脱落,木屑从眼袋里撒出来,羽毛差不多被蛀虫吃干净了,然而它仍然有着庄严和孤独的僧侣神态。故事的讲述者认为秃鹫的标本就是自己的父亲,他的母亲则更愿意相信自己的丈夫是在那次蟑螂入侵时消失的。他们共同回忆起当时的情形,蟑螂黑压压地充满了那个夜晚,像蜘蛛似的在他们房间里奔跑,父亲发出了连续不断的恐怖的叫声,“他拿着一支标枪,从一张椅子跳到另一张椅子上”。而且刺中了一只蟑螂。此后,父亲的行为变了,他忧郁地看到自己身上出现了一个个黑点,好像蟑螂的鳞片。他曾经用体内残存的力量来抵抗自己对蟑螂的着迷,可是他失败了,没有多久他就变得无可救药,“他和蟑螂的相似一天比一天显著──他正在变成一只蟑螂”。接下去他经常失踪几个星期,去过蟑螂的生活,谁也不知道他生活在地板的哪条裂缝里,以后他再也没有回来。阿德拉每天早晨都扫出一些死去的蟑螂,厌恶地烧掉,他有可能是其中的一只。故事的讲述者开始有些憎恨自己的母亲,他感到母亲从来没有爱过父亲。“父亲既然从来没有在任何女人的心中扎下根,他就不可能同任何现实打成一片。”所以父亲不得不永远漂浮着,他失去了生活和现实,“他甚至没法获得一个诚实的平民的死亡”,他连死亡都失去了。
布鲁诺·舒尔茨给予了我们不留余地的悲剧,虽然他叙述的灵活性能够让父亲不断地回来,可是他每一次回来都比前面的死去更加悲惨。在《父亲的最后一次逃走》里,父亲作为一只螃蟹或者是蝎子回来了,是他的妻子在楼梯上发现了他,虽然他已经变形,她还是一眼认出了他,然后是他的儿子确认了他。他重新回到了家中,以螃蟹或者蝎子的习惯生活着,虽然他已经认不出过去作为人时的食物,可是在吃饭的时候他仍然会恢复过去的身份,来到餐室,一动不动地停留在桌子下面,“尽管他的参加完全是象征性的”。这时候他的家已经今非昔比,阿德拉走了,女佣换成了根雅,一个用旧信和发票调白汁沙司的糟糕的女佣,而且孩子的叔叔查尔斯也住到了他的家中。这位查尔斯叔叔总是忍不住去踩他,他被查尔斯踢过以后,就会“用加倍的速度像闪电似的、锯齿形地跑起来,好像要忘掉他不体面地摔了一跤这个回忆似的”。
接下去,布鲁诺·舒尔茨让母亲以对待一只螃蟹的正确态度对待了这位父亲,把它煮熟了,“显得又大又肿”,被放在盆子里端了上来。这是一个难以置信的举动,虽然叙述在前面已经表达出了某些忍受的不安,除了查尔斯叔叔以外,家庭的其他成员似乎都不愿意更多地去观看它,然而它是父亲的事实并没有在他们心中改变,可是有一天母亲突然把它煮熟了。其实,布鲁诺·舒尔茨完全可以让查尔斯叔叔去煮熟那只螃蟹,毫无疑问他会这么干,当螃蟹被端上来后,只有他一个人举起了叉子。布鲁诺·舒尔茨选择了母亲,这是一个困难的选择,同时又是一个优秀作家应有的选择。查尔斯叔叔煮熟螃蟹的理由因为顺理成章就会显得十分单调,仅仅是延续叙述已有的合理性;母亲就完全不一样了,她的举动因为不可思议会使叙述出现难以预测的丰富品质。优秀的作家都精通此道,他们总是不断地破坏已经合法化的叙述,然后在其废墟上重建新的叙述逻辑。
在这里,布鲁诺·舒尔茨让叙述以跳跃的方式渡过了难关,他用事后的语调进行了解释性的叙述,让故事的讲述者去质问母亲,而“母亲哭了,绞着双手,找不到一句回答的话”,然后讲述者自己去寻找答案──“命运一旦决意把它的无法理解的怪念头强加在我们身上,就千方百计地施出花招。一时的糊涂、一瞬间的疏忽或者鲁莽……”其实,这也是很多作家乐意使用的技巧,让某一个似乎是不应该出现的事实,在没有任何前提时突然出现,再用叙述去修补它的合理性。显然,指出事实再进行解释比逐渐去建立事实具有更多的灵活性和技巧。
查尔斯叔叔放下了他手中的叉子,于是谁也没有去碰那只螃蟹,母亲吩咐把盆子端到起居室,又在螃蟹上盖了一块紫天鹅绒。布鲁诺·舒尔茨再次显示了他在叙述进入到细部时的非凡洞察力,几个星期以后,父亲逃跑了,“我们发现盆子空了。一条腿横在盆子边上……”布鲁诺·舒尔茨感人至深地描写了父亲逃跑时腿不断地脱落在路上,最后他这样写道:“他靠着剩下的精力,拖着他自己到某个地方去,去开始一种没有家的流浪生活;从此以后,我们没有再见到他。”
布鲁诺·舒尔茨与卡夫卡一样,使自己的写作在几乎没有限度的自由里生存,在不断扩张的想象里建构起自己的房屋、街道、河流和人物,让自己的叙述永远大于现实。他们笔下的景色经常超越视线所及,达到他们内心的长度;而人物的命运像记忆一样悠久,生和死都无法去测量。他们的作品就像他们失去了空间的民族,只能在时间的长河里随波逐流。于是我们读到了丰厚的历史,可是找不到明确的地点。
就是在写作的动机上,布鲁诺·舒尔茨和卡夫卡也有相似之处,他们都不是为出版社和杂志写作。布鲁诺·舒尔茨的作品最早都是发表在信件上,一封封寄给德博拉·福格尔的信件,这位诗人和哲学博士兴奋地阅读着他的信,并且给予了慷慨的赞美和真诚的鼓励,布鲁诺·舒尔茨终于找到了读者。虽然他后来正式出版了自己的作品,然而当时的文学时尚和批评家的要求让他感到极其古怪,他发现真正的读者其实只有一位。布鲁诺·舒尔茨的德博拉·福格尔在某种意义上就是卡夫卡的马克斯·布洛德,他们在卡夫卡和布鲁诺·舒尔茨那里都成为了读者的象征。随着岁月的流逝,象征变成了事实。德博拉·福格尔和马克斯·布洛德在岁月里不断生长,他们以各自的方式变化着,德博拉·福格尔从一棵树木变成了树林,马克斯·布洛德则成为了森林。
尽管布鲁诺·舒尔茨与卡夫卡一样写下了本世纪最出色的作品,然而他无法成为本世纪最重要的作家,他的德博拉·福格尔也无法成为森林。这并不是因为布鲁诺·舒尔茨曾经得到过卡夫卡的启示,即便是后来者的身份,也不应该削弱他应有的地位,因为任何一位作家的前面都站立着其他的作家。博尔赫斯认为纳撒尼尔·霍桑是卡夫卡的先驱者,而且卡夫卡的先驱者远不止纳撒尼尔·霍桑一人;博尔赫斯同时认为在文学里欠债是互相的,卡夫卡不同凡响的写作会让人们重新发现纳撒尼尔·霍桑《故事新编》的价值。同样的道理,布鲁诺·舒尔茨的写作也维护了卡夫卡精神的价值和文学的权威,可是谁的写作维护了布鲁诺·舒尔茨?
布鲁诺·舒尔茨的文学命运很像那张羊皮纸地图里的鳄鱼街。在他那篇题为《鳄鱼街》的故事里,那张挂在墙上的巨大的地图里,地名以不同的方式标示出来,大部分的地名都是用显赫的带装饰的印刷体印在那里;有几条街道只是用黑线简单地标出,字体也没有装饰;而羊皮纸地图的中心地带却是一片空白,这空白之处就是鳄鱼街。它似乎是一个道德沉沦和善恶不分的地区,城市其他地区的居民引以为耻,地图表达了这一普遍性的看法,取消了它的合法存在。虽然鳄鱼街的居民们自豪地感到他们已经拥有了真正大都会的伤风败俗,可是其他伤风败俗的大都会却拒绝承认它们。
悬挂在[[《鳄鱼街》]]里的羊皮纸地图,在某种意义上象征了我们的文学史。[[纳撒尼尔·霍桑]]的名字,弗兰茨·卡夫卡的名字被装饰了起来,显赫地铭刻在一大堆耀眼的名字中间;另一个和他们几乎同样出色的作家布鲁诺·舒尔茨的名字,却只能以简单的字体出现,而且时常会被橡皮擦掉。这样的作家其实很多,他们都或多或少地写下了无愧于自己,同时也无愧于文学的作品。然而,文学史总是乐意去表达作家的历史,而不是文学真正的历史,于是更多的优秀作家只能去鳄鱼街居住,文学史的地图给予他们的时常是一块空白,少数幸运者所能得到的也只是没有装饰的简单的字体。
日本的[[樋口一叶]]似乎是另一位布鲁诺·舒尔茨,这位下等官僚的女儿尽管在日本的文学史里获得了一席之地,就像布鲁诺·舒尔茨在波兰或者犹太民族文学史中的位置,可是她名字的左右时常会出现几位平庸之辈,这类作家仅仅是依靠纸张的数量去博得文学史的青睐。樋口一叶毫无疑问可以进入19世纪最伟大的女作家之列,她的《青梅竹马》是我读到的最优美的爱情篇章,她深入人心的叙述有着阳光的温暖和夜晚的凉爽。这位十七岁就挑起家庭重担的女子,二十四岁时以和卡夫卡同样的方式──肺病,离开了人世。她留给我们的只有二十几个短篇小说,死亡掠夺了樋口一叶更多的天赋,也掠夺了人们更多的敬意。而她死后置身其间的文学史,似乎也像死亡一样蛮横无理。
布鲁诺·舒尔茨的不幸,其实也是文学的不幸。几乎所有的文学史都把作家放在了首要的位置,而把文学放在了第二位。只有很少的人意识到文学比作家更重要,保罗·瓦莱里是其中的一个,他认为文学的历史不应当只是作家的历史,不应当写成作家或作品的历史,而应当是精神的历史,他说:“这一历史完全可以不提一个作家而写得尽善尽美。”可是,保罗·瓦莱里只是一位诗人,他不是一位文学史的编写者。
欧内斯特·[[海明威]]曾经认为史蒂芬·克莱思是20世纪美国最重要的作家之一,因为他写下了两篇精彩无比的短篇小说,其中一篇就是《海上扁舟》。史蒂芬·克莱思的其他作品,海明威似乎不屑一顾。然而对海明威来说,两个异常出色的短篇小说已经足够了。在这里,海明威发出了与保罗·瓦莱里相似的声音,或者说他们共同指出了另外一部文学史存在的事实,他们指出了阅读的历史。
事实上,一部文学作品能够流传,经常是取决于某些似乎并不重要甚至是微不足道然而却是不可磨灭的印象。对阅读者来说,重要的是他们记住了什么,而不是他们读到过什么。他们记住的很可能只是几句巧妙的对话,或者是一个丰富有力的场景,甚至一个精妙绝伦的比喻都能够使一部作品成为难忘。因此,文学的历史和阅读的历史其实是同床异梦,虽然前者创造了后者,然而后者却把握了前者的命运。除非编年史的专家,其他的阅读者不会在意作者的生平、数量和地位,不同时期对不同文学作品的选择,使阅读者拥有了自己的文学经历,也就是保罗·瓦莱里所说的精神的历史。因此,每一位阅读者都以自己的阅读史编写了属于自己的文学史。
一九九八年九月七日
我-孔亚雷
========================
我-[[孔亚雷]]
------
醒来后,K做的第一件事就是把眼睛闭上。重新闭上,准确地说。他感觉着自己的存在。通过呼吸,通过床单,通过勃起。他又躺了五分钟。也许六分钟。然后起床。他拉起卷帘,推开窗户。他看见了海。
海?
K有点反应不过来。就像照镜子发现里面不是自己的脸。海?不,他看见的不应该是海,而应该是远处一栋栋积木似的高楼大厦。他闭上眼睛。他闭上眼睛也能看见:最近的那栋有紫色的玻璃幕墙,屋顶竖着一块巨大的定期更换的广告牌(昨天是IBM的广告,他记得)。视线再拉近,是马路对面的一排店铺,快餐店,24小时便利店,服装店(从左到右)。再拉近一点,是行人,路边的法国梧桐,路上的车。这就是我将看到的,K在心里说,刚才只是幻觉。他睁开眼睛。
他看见了海。
K在窗前呆呆地站了一会儿。他看着海。他听到了海。他甚至闻到了海。也许是某种高科技玩笑,他想,或者某种新型实验,他们没通知就把他做了实验品。他转身环视了一圈房间。一切正常。没有任何变化。至少看上去没有。他又转回来。他拉下卷帘。问题也许出在卷帘上,他想。他检查了一遍卷帘。没有问题。至少他没发现。他深深吸了一口气。他在心里默念十下,然后重新拉起卷帘。
海。
K觉得喉咙有点发干。他决定克制住自己把头探出窗户和出门查看的欲望。他决定先洗脸刷牙。他决定一切等吃完早餐再说。
K的公寓很小。它更像一间舒适的牢房。一个十五平米的房间,外加小小的厨房和卫生间,就像房间的两个耳朵。唯一的房间兼任客厅餐厅卧室和书房。房间里只有——也只能放下——四样家具:床(席梦思下的床架同时又是抽屉式衣柜),书桌(兼餐桌),转椅和书架。书架占了整整两面墙。房间里到处都是书。不仅在书架上,在所有地方。除了书,第二多的是植物。各种品种,大小形态各异的绿色植物。书桌(兼餐桌)上有一台手提电脑。靠床的书架上有一套迷你音响。没有电视。
房间跟以前没有任何不同,除了窗口的风景。有自来水(淡水)。有电。K像平常一样做早餐。煮咖啡。烤面包。煎蛋。吃早餐时他不时抬头瞄一眼旁边的窗。海还在那儿。好几次——两次,准确地说——他突然停下手里叮叮当当的刀叉,侧耳倾听从窗口传来的海涛声。这也许是梦,他想,我也许是在做梦。这是在梦中。但接着他就想起昨天晚上做的梦。他记得那个梦。难道是梦中之梦?不,这未免太博尔赫斯了。再说早餐快要凉了。
洗碗碟的时候,K第一次觉得厨房里没有窗并非一件坏事。
K套上球鞋,穿上外套。K打开门。K感觉到的第一件事是静。一种奇异的静。像云一样的静。膨松,柔软,既有形又无形,弥漫在整条楼道。他在楼道里来回走了一遍。一切都跟往常一样。一切又都跟往常不同。他试着敲了敲斜对面那户人家的门。那里住着一对漂亮的年轻夫妇(他们来找他借过一次打火机)。甚至在刚举起手的时候他就知道不会有人回答。果然没有。他不禁松了口气——这是为什么?他不知道。
他开始下楼(他住在三楼)。二楼和一楼给人的感觉跟三楼完全相同。一片死寂。K一边下楼梯,一边开始怀疑自己将会看见什么景象。城市,还是海?或者说他希望自己看见什么景象。希望看见城市,还是希望看见海?说实话,他不知道。
而就在他正这样想的时候,他已经看见了海。
仿佛为了验证大海的真伪,K迫不及待——甚至可以说不顾一切——地朝海滩走去。他尽量控制自己不要跑。空气清新得让他觉得有点透不过气。他面无表情地看着眼前越来越近的海。
半小时后,K平静下来。他得出三点结论。不,确切地说,是三点事实。
1.毫无疑问,海是真的。
2.出于某种未知的原因,他所住的位于A市的一幢五层的公寓楼被整体移到了另一个地方。
3.这个地方是一座海边小镇。
同时,他也列出了三点疑问。或者,也可以说,三点待查事项。
1.这到底是怎么回事?
2.公寓楼里还有没有其他人?
3.这是什么地方?(名字。居民。方位。)
最后他列出三项计划。
1.先不管到底怎么回事。
2.确认公寓楼里还有没有其他人。
3.四处勘察,搞清镇子的情况。
然后,他开始行动。
他先回到公寓楼,敲了每户人家的门。不出所料,没有人回答。每户人家都门窗紧闭。他考虑了一下要不要破门而入。然后决定不要。他回到自己房间,打开手机和电脑。手机没有信号。电脑网络连接失败。他坐在椅子上发了一会儿愣,然后拿出背包,放进水、干粮和瑞士军刀。出门前他又环视了一圈他那小小的充满书和植物的房间。
没用多久K就发现镇子是空的。无论是民居、店铺还是宾馆,都空无一人。唯一的一条水泥马路上空空荡荡,只有一只白色塑料袋在路中央随风飘舞。也没有看见任何动物。无论是狗、猫,还是其他家畜。他走进一家小卖部(门没有锁),打开摆在柜台上的电视机。雪花。他换了几个台。雪花。雪花。雪花。他关掉电视。他拿起柜台里的电话。话筒里传来的信号音让他心跳突然加速。他想了想,拨了两个他记得的号码——他只记得这两个。拨不通,当然。他放回电话。他对着里面整齐排列着各种饼干、零食的玻璃柜台研究了一会儿。他看中了一盒曲奇。但他没有去拿。
K一路上发现了好几辆停着的摩托车。其中一辆插着钥匙。他骑上去试着发动了一下。引擎发出快活的呼噜声。他本来只是想试骑一下,但想到这可以大大加快勘察的进度,K决定继续骑下去。
骑在摩托车上,K才突然意识到天气有多么好。这是五月(昨天是5月5日,他记得——当然,如果昨天确实是昨天的话)。阳光灿烂。天空蓝得令人吃惊。几朵移动的云就像正在空中散步。路拐了个弯,开始贴着海边蜿蜒前进。尽管路上只有K一辆车,他依然沿着马路中间单黄线的右侧行驶。海始终在他的左侧闪闪发光。
经过一天的勘察,K的成果大致如下:他发现了一座小港口,港口旁边有候船室和售票处,但没有看见客轮,只停着几艘渔船。没有一丝人影。到处都静悄悄的。除了海涛声。港口附近有家稍大的超市,从门玻璃往里看(门锁着),货品相当齐全。他还发现了一个小型的加油站(他顺手给摩托车加满了油)。居民区主要集中在港口和海滩——两者相距大概两公里——这两片区域。面向沙滩有两家宾馆。一家外墙是蓝色,一家是白色。都褪色得很厉害。民居大多是石头砌成的两层楼房,屋顶的瓦片上均匀密集地压着大鹅卵石。有几户门口晾着渔网。K敲了几户人家的门。没有任何反应。几乎所有人家的门都没锁,有的甚至虚掩着。他走进其中一家转了转。陈设很简陋。但看上去一切都很正常。除了没有人。
K没有发现镇政府或类似于镇政府的地方。
K也没有发现派出所或类似于派出所的地方。
它们也许在岛的另一面,K想,在他今天已经来不及去的那面。K在港口售票处的窗口发现了镇的名字。这是一个岛。他从未听说过这个岛。但从窗口贴着的起点和终点名称,可以推断出它应该位于东海。
回家路上他顺便观赏了日落。
K度过了在岛上的第一个晚上。虽然感到困惑不安,但由于白天的奔波,他还是睡得不错。醒来后他过了一会儿才意识到自己在哪里。他立刻爬起来去看窗口(昨晚他没拉窗帘也没关窗)。海还在那儿。他不知道自己应该高兴还是失望。
接下来的几天K一直在既好像有目的又好像漫无目的地四处游荡。他骑着摩托车跑遍了全岛(不能骑的地方就走)。岛比他想象的要大。岛的另一面——东面——没有沙滩,全是黄色的石头悬崖。东南边地势最高,那儿有片树林。K又发现了三个缩在海岬里的小渔村,最小的一个只有十几户,它们的房屋比港口和沙滩的更破旧。K一个人也没遇见。不仅是人,K没有看见任何活的东西,除了树和野草。当然,海里有鱼(应该有),但K看不见。
K在岛的另一面也没有发现镇政府或派出所或诸如此类的地方。
冰箱里的食物储备吃光后,K去了港口边的超市。他用石头敲破门玻璃,手伸进去从里面打开门。看上去这里的东西可以够他用一辈子。第一次他拿了米、罐头和饼干。第二次他拿了鱿鱼丝、萨其马和速溶咖啡。第三次他拿了卷筒纸和一瓶葡萄酒。他给摩托车又加了一次油。
一个月后,K已经彻底适应了这里的生活。他渐渐恢复了以前的日常作息(但比以前睡得更早,也起得更早)。他开始接着看读了一半的书。他开始继续工作。事实上,K发现在这里他工作得更好。工作腻了他就去海边散步。或者骑摩托车在空荡荡的岛上兜风。天气好的夜晚他会躺在沙滩上看星星。看好几个小时。星星总让他想到那个没解决的疑问。
这到底是怎么回事?
找不到任何合理的解释。正如他一开始就想过的,这有点像梦。但如果是梦,那么就一定会醒。所以也就无须担心。这也有点像死。我也许死了,K有时候想。但如果这就是死,K想,那么看来死并没有人们想的那么糟糕。而且,进一步说,如果这是死,他同样也无须担心。因为死就是死。死了就不可能复活。没人能拿死有什么办法。就像没人能拿梦有什么办法。
于是,K决定不再多想。不再想这一切是为什么。不再想将来会怎样。把目光只聚焦在现在。聚焦在他手头进行的工作上。无论如何,他有许多工作要做。
星星看够了,他就从沙滩上站起来,拍拍裤子上的沙往回走。整座岛一片漆黑。只有他的房间亮着灯。远远看去,就像一颗大一点的星。
最近又计划把本来使用的 TiddlyWiki 进行一些强化。本来 TiddlyWiki 是一个知识管理软件,然后我为它加了一些功能,使它变成一个给自己用的任务管理系统。到底在 TiddlyWiki 自身的限制下,这个任务管理系统是什么样子呢?
现阶段我未能把它分享出来,但是我可以介绍一下它有什么功能。希望跟大家分享一下。
> 基本元素:Tiddler
--------------
Tiddler 就是一个基本的元素,基本上可以理解它为一个页面,就像其他笔记软件的一篇笔记一样。我们可以用不同的语法为这个 Tiddler 制造列表 / 表格等,令笔记的元素更丰富。
但是 Tiddler 和其他软件的笔记有以下四个不同的地方,这四个不同的地方展开了这个系统。
1. 我们可以在一个 Tiddler 里以某些语法插入另一个 Tiddler 的连结。
2. 每一个 Tiddler 都可以指定复数的 Tag,而这些 Tag 也可以是一个 Tiddler。换句话说,这里可以形成不同 Tiddler 之间的从属关系。
3. 我们可以制造一些 Tiddler 放一些 [macro](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Macros%252520in%252520WikiText.html),而它们可以做到一些需要源代码才能完成的功能。例如我可以在一个 Tiddler 里呼叫某个 macro 的功能,使得能把自身 Tiddler 的标题放到剪贴薄里(参考:[TiddlyWiki 实用 macro:copy-block-1](https://zhuanlan.zhihu.com/p/346604189))。
4. 我们可以制造一些 [模版 Tiddler](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/TemplateTiddlers.html),有了这个后我们能做到一些功能,例如在一个 Tiddler 里放置另一个 Tiddler 模版来为自身展示所有子分页的连结(也就是所有 Tiddler 有自身的 Tag)。
有了这四个特别的功能,我们可以为 Tiddler 制造以下两个功能,而这两个功能就是这个系统的核心。
### > 第一功能:任务 Tiddler
我们可以为每个 Tiddler 加上两个 Tag 来标置这是一个任务 Tiddler。
第一个 Tag 就是标示它是一个任务。为了分开这是工作和自身的任务,我使用了两个 Tag, `task` 代表了公司上的任务,`ntask`代表了个人的任务。如果没有需要把它们分隔开的同学便不需这个 Tag ,只需要下面的 Tag 便足够了。
第二个 Tag 是用来标示这个任务的状态。我会使用以下其中一个 Tag 来表达:
* `later`: 就是我在未来需要做的任务,有点像是 Backlog。
* `now`: 就是这个星期需要做的任务。
* `archive`: 决定不会再做的任务。如果它本来有一些资料在内的话便不会把它移除,只是把这个任务变成这个状态。
* `waiting`: 就是一些自身因某些原因不能做的任务,例如是这个任务不是在当下能做的、又或是需要等待别人完成某事后自己才能继续做。
* `done`: 就是完成了的任务。
因为有 [模版 Tiddler](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/TemplateTiddlers.html) 的关系,我们可以设计成在该 Tiddler 中或是在某些其他 Tiddler 里以按钮的方式来为 Tiddler 变成任务(加上以下两款 Tag)、改变任务状态(移除所有任务状态 Tag 并加上要变成的任务状态 Tag)、或是为它移除任务(移除任务这两款 Tag)
另外,由于任务 Tiddler 也是一个 Tiddler ,所以我们可以在这些 Tiddler 里放下自己当前的完成进度和经验,方便下次继续时跟进;此外也可以放以 checklist(以这个 [Plugin](https://link.zhihu.com/?target=https%3A//github.com/tgrosinger/tw5-checklist) 实现)的方式来记录还要做的事。
基本上我的做法也是从这页开始改良,有兴趣的同学可以参考一下:[Joe Armstrong: Fun with the TiddlyWiki](https://link.zhihu.com/?target=https%3A//joearms.github.io/%232018-12-26%2520Fun%2520with%2520the%2520TiddlyWiki)
### > 第二功能:子分页 / 子任务
因为有 [模版 Tiddler](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/TemplateTiddlers.html) 的关系,我们可以随意为每一个 Tiddler 加上一个按纽来新建一个 Tiddler 有自身的 Tag 来代表这是子分页。例如在 Tiddler A 里加上一个按钮,按后会新建了一个 Tiddler B ,而它有一个 Tag 是 A 。
这个子分页的功能能够演变为为一个 Tiddler / 任务 Tiddler 新建一个子任务 Tiddler。
同理,我们也可以做到在这个 Tiddler A 中看到这个 Tiddler 有甚幺子分页和子任务,还可以根据子任务的状态来分类。
在这个结构下,我们可以制造一个无限层级的系统,在这样的结构下,Tiddler 本身可以是一个普通的文件、一个任务、也可以是一个交付物、甚至可以是一个项目。这视乎你如何看待它。
如果它是一个有完成条件的项目,那么我会先制造一个项目 Tiddler ,它的子分页就是这个项目不同的交付物,视乎复杂情况再决定是否为这些交付物制造子任务 Tiddler 。如果不太复杂我便直接把这个交付物 Tiddler 当作任务 Tiddler 般处理。
如果它是一个没有完成条件的目标或是一件能无限进化的产品,那么我会制造一个目标 / 产品 Tiddler ,它的子分页会是 时间间隔的 Tiddler 或是 版本号 Tiddler,然后它们的子分页才是交付物 和子任务。
另外,视乎情况我可能会在这个 项目 / 目标 / 产品 的 Tiddler 里开一个子分页来放置这个 项目 / 目标 / 产品 专用的知识或文件。
> 不同的视觉
-------
介绍了这个系统的元件后,简单介绍一下这个系统的不同视觉页。简单来就就是有几个重要的 Tiddler 来以不同的角度来管理这些任务。
### > 第一个视觉:全任务视觉

第一个就是任务视觉。这个任务页会把所有的任务 Tiddler 分类为 `now` / `later` / `waiting` / `archive` / `done` 来展示,每个任务前有不同的按钮用来改变它们的任务状态。
我在每个星期日做每周回顾时便会从 `later` 里选择出这星期要做的任务,并把它们变成 `now` 代表这星期要做的任务。
因为我有分开公司的任务和自身的任务,所以我需要两页这样的视觉。
### > 第二个视觉:项目 / 目标 / 产品 视觉

第二个是是项目 / 目标 / 产品 视觉,就是以一个 项目 / 目标 / 产品 的视觉出发,去看看它的所有任务状态和它的子分页。
同样,这页也有会把所有属于该 项目 / 目标 / 产品 的任务 Tiddler 分类为 `now` / `later` / `waiting` / `archive` / `done` 来展示,每个任务前有不同的按钮用来改变它们的任务状态。
### > 第三个视觉:日记视觉
TiddlyWiki 本来有一个名为 [Journal](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Creating%252520journal%252520tiddlers.html) 的功能,就是快速到新增一个代表今天的 Tiddler。
在这一页里,我会放下一个小 checklist(以这个 [Plugin](https://link.zhihu.com/?target=https%3A//github.com/tgrosinger/tw5-checklist) 实现) ,来放置一些今天要做的事,还有一些不需要为此新增任务 Tiddler 的小事来提醒自己今天要做完这些事。
另外,当我把任务 Tiddler 按下按钮改为 `done` 时,这个按钮还会自动为该 Tiddler 加上一个 Tag 为 Journal Tiddler 名称的格式。这样我便能够在 Journal Tiddler 里看到这天完成了什么任务,方便在每周回顾时回顾自己做了什么,并把重要的任务放到回顾表格里。
内心 OS: 以文字来描述这个系统有点复杂。
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
我的四个假想敌-余光中
========================
我的四个假想敌-[[余光中]]
-----
二女幼珊在港参加侨生联考,以第一志愿分发台大外文系。听到这消息,我松了一口气,从此不必担心四个女儿通通嫁给广东男孩了。
我对广东男孩当然并无偏见,在港六年,我班上也有好些可爱的广东少年,颇讨老师的欢心,但是要我把四个女儿全部让那些“靓仔”、“叻仔”掳掠了去,却舍不得。不过,女儿要嫁谁,说得洒脱些,是她们的自由意志,说得玄妙些呢,是姻缘,做父亲的又何必患得患失呢?何况在这件事上,做母亲的往往位居要冲,自然而然成了女儿的亲密顾问,甚至亲密战友,作战的对象不是男友,却是父亲。等到做父亲的惊醒过来,早已腹背受敌,难挽大势了。
在父亲的眼里,女儿最可爱的时候是在十岁以前,因为那时她完全属于自己。在男友的眼里,她最可爱的时候却在十七岁以后,因为这时她正像毕业班的学生,已经一心向外了。父亲和男友,先天上就有矛盾。对父亲来说,世界上没有东西比稚龄的女儿更完美的了,唯一的缺点就是会长大,除非你用急冻术把她久藏,不过这恐怕是违法的,而且她的男友迟早会骑了骏马或摩托车来,把她吻醒。
我未用太空舱的冻眠术,一任时光催迫,日月轮转,再揉眼时,怎么四个女儿都已依次长大,昔日的童话之门砰地一关,再也回不去了:四个女儿,依次是珊珊、幼珊、佩珊、季珊。简直可以排成一条珊瑚礁。珊珊十二岁的那年,有一次,未满九岁的佩珊忽然对来访的客人说:“喂,告诉你,我姐姐是一个少女了!”在座的大人全笑了起来。
曾几何时,惹笑的佩珊自己,甚至最幼稚的季珊,也都在时光的魔杖下,点化成“少女”了。冥冥之中,有四个“少男”正偷偷袭来,虽然蹑手蹑足,屏声止息,我却感到背后有四双眼睛,像所有的坏男孩那样,目光灼灼,心存不轨,只等时机一到,便会站到亮处,装出伪善的笑容,叫我“岳父”。我当然不会应他。哪有这么容易的事!我像一棵果树,天长地久在这里立了多年,风霜雨露,样样有份,换来果实累累,不胜负荷。而你,偶尔过路的小子,竟然一伸手就来摘果子,活该蟠地的树根绊你一跤!
而最可恼的,却是树上的果子,竟有自动落入行人手中的样子。树怪行人不该擅自来摘果子,行人却说是果子刚好掉下来,给他接着罢了。这种事,总是里应外合才成功的。当初我自己结婚,不也是有一位少女开门揖盗吗?“堡垒最容易从内部攻破”,说得真是不错。不过彼一时也,此一时也。同一个人,过街时讨厌汽车,开车时却讨厌行人。现在是轮到我来开车。
好多年来,我已经习于和五个女人为伍,浴室里弥漫着香皂和香水气味,沙发上散置皮包和发卷,餐桌上没有人和我争酒,都是天经地义的事。戏称吾庐为“女生宿舍”,也已经很久了。做了“女生宿舍”的舍监,自然不欢迎陌生的男客,尤其是别有用心的一类。但是自己辖下的女生,尤其是前面的三位,已有“不稳”的现象,却令我想起叶芝的一句诗:
一切已崩溃,失去重心。
我的四个假想敌,不论是高是矮,是胖是,是学医还是学文,迟早会从我疑惧的迷雾里显出原形,一一走上前来,或迂回曲折,嗫嚅其词,或开门见山,大言不惭,总之要把他的情人,也就是我的女儿,对不起,从此领去。无形的敌人最可怕,何况我在亮处,他在暗里,又有我家的“内奸”接应,真是防不胜防。只怪当初没有把四个女儿及时冷藏,使时间不能拐骗,社会也无由污染。现在她们都已大了,回不了头;我那四个假想敌,那四个鬼鬼祟祟的地下工作者,也都已羽毛丰满,什么力量都阻止不了他们了。先下手为强,这件事,该乘那四个假想敌还在襁褓的时候,就予以解决的。至少美国诗人纳许(Ogden Nash,1902—1971)劝我们如此。他在一首妙诗《由女婴之父来唱的歌》(Song to Be Sung by the Father of Infant Female Children)之中,说他生了女儿吉儿之后,惴惴不安,感到不知什么地方正有个男婴也在长大,现在虽然还浑浑噩噩,口吐白沫,却注定将来会抢走他的吉儿。于是做父亲的每次在公园里看见婴儿车中的男婴,都不由神色一变,暗暗想道:“会不会是这家伙?”想着想着,他“杀机陡萌”(My dreams, I fear, are infanticiddle),便要解开那男婴身上的别针,朝他的爽身粉里撒胡椒粉,把盐撒进他的奶瓶,把沙撒进他的菠菜汁,再扔头优游的鳄鱼到他的婴儿车里陪他游戏,逼他在水深火热之中挣扎而去,去娶别人的女儿。足见诗人以未来的女婿为假想敌,早已有了前例。
不过一切都太迟了。当初没有当机立断,采取非常措施,像纳许诗中所说的那样,真是一大失策。如今的局面,套一句史书上常见的话,已经是“寇入深矣”!女儿的墙上和书桌的玻璃垫下,以前的海报和剪报之类,还是披头士、拜丝、大卫·凯西弟的形象,现在纷纷都换上男友了。至少,滩头阵地已经被入侵的军队占领了去,这一仗是必败的了。记得我们小时,这一类的照片仍被列为机密要件,不是藏在枕头套里,贴着梦境,便是夹在书堆深处,偶尔翻出来神往一番,哪有这么二十四小时眼前供奉的?
这一批形迹可疑的假想敌,究竟是哪年哪月开始入侵厦门街余宅的,已经不可考了。只记得六年前迁港之后,攻城的将士便换了一批口操粤语的少年来接手。至于交战的细节,就得问名义上是守城的那几个女将,我这位“昏君”是再也搞不清的了。只知道敌方的炮火,起先是瞄准我家的信箱,那些歪歪斜斜的笔迹,久了也能猜个七分;继而是集中在我家的电话,“落弹点”就在我书桌的背后,我的文苑就是他们的沙场,一夜之间,总有十几次脑震荡。那些粤音平上去入,有九声之多,也令我难以研判敌情。现在我带幼珊回了厦门街,那头的广东部队轮到我太太去抵挡,我在这头,只要留意台湾健儿,任务就轻松多了。
信箱被袭,只如战争的默片,还不打紧。其实我宁可多情的少年勤写情书,那样至少可以练习作文,不致在视听教育的时代荒废了中文。可怕的还是电话中弹,那一串串警告的铃声,把战场从门外的信箱扩至书房的腹地,默片变成了身历声,假想敌在实弹射击了。更可怕的,却是假想敌真的闯进了城来,成了有血有肉的真敌人,不再是假想了好玩的了,就像军事演习到中途,忽然真的打起来了一样。真敌人是看得出来的。在某一女儿的接应之下,他占领了沙发的一角,从此两人呢喃细语,嗫嚅密谈,即使脉脉相对的时候,那气氛也浓得化不开,窒得全家人都透不过气来。这时几个姐妹早已回避得远远的了。任谁都看得出情况有异。万一敌人留下来吃饭,那空气就更为紧张,好像摆好姿势,面对照相机一般。平时鸭塘一般的餐桌,四姐妹这时像在演哑剧,连筷子和调羹都似乎得到了消息,忽然小心翼翼起来。明知这僭越的小子未必就是真命女婿,(谁晓得宝贝女儿现在是十八变中的第几变呢?)心里却不由自主升起一股淡淡的敌意。也明知女儿正如将熟之瓜,终有一天会蒂落而去,却希望不是随眼前这自负的小子。
当然,四个女儿也自有不乖的时候,在恼怒的心情下,我就恨不得四个假想敌赶快出现,把她们统统带走。但是那一天真要来到时,我一定又会懊悔不已。我能够想象,人生的两大寂寞,一是退休之日,一是最小的孩子终于也结婚之后。宋淇有一天对我说:“真羡慕你的女儿全在身边!”真的吗?至少目前我并不觉得自己有什么可羡之处。也许真要等到最小的季珊也跟着假想敌度蜜月去了,才会和我存并坐在空空的长沙发上,翻阅她们小时的相簿,追忆从前,六人一车长途壮游的盛况,或是晚餐桌上,热气蒸腾,大家共享的灿烂灯光。人生有许多事情,正如船后的波纹,总要过后才觉得美的。这样一想,又希望那四个假想敌,那四个生手笨脚的小伙子,还是多吃几口闭门羹,慢一点出现吧。
袁枚写诗,把生女儿说成“情疑中副车”,这书袋掉得很有意思,却也流露了重男轻女的封建意识。照袁枚的说法,我是连中了四次副车,命中率够高的了。余宅的四个小女孩现在变成了四个小妇人,在假想敌环伺之下,若问我择婿有何条件,一时倒恐怕答不上来。沉吟半晌,我也许会说:“这件事情,上有月下老人的婚姻谱,谁也不能窜改,包括韦固,下有两个海誓山盟的情人,‘二人同心,其利断金’,我凭什么要逆天拂人,梗在中间?何况终身大事,神秘莫测,事先无法推理,事后不能悔棋,就算交给二十一世纪的电脑,恐怕也算不出什么或然率来。倒不如故示慷慨,伪作轻松,博一个开明父亲的美名,到时候带颗私章,去做主婚人就是了。”
问的人笑了起来,指着我说:“什么叫做‘伪作轻松’?可见你心里并不轻松。”
我当然不很轻松,否则就不是她们的父亲了。例如人种的问题,就很令人烦恼。万一女儿发痴,爱上一个耸肩摊手口香糖嚼个不停的小怪人,该怎么办呢?在理性上,我愿意“有婿无类”,做一个大大方方的世界公民。但是在感情上,还没有大方到让一个臂毛如猿的小伙子把我的女儿抱过门槛。现在当然不再是“严夷夏之防”的时代,但是一任单纯的家庭扩充成一个小型的联合国,也大可不必。问的人又笑了,问我可曾听说混血儿的聪明超乎常人。我说:“听过,但是我不稀罕抱一个天才的‘混血孙’。我不要一个天才儿童叫我Grandpa,我要他叫我外公。”问的人不肯罢休:“那么省籍呢?”
“省籍无所谓,”我说,“我就是苏闽联姻的结果,还不坏吧?当初我母亲从福建写信回武进,说当地有人向她求婚。娘家大惊小怪,说:‘那么远!怎么就嫁给南蛮!’后来娘家发现,除了言语不通之外,这位闽南姑爷并无可疑之处。这几年,广东男孩锲而不舍,对我家的压力很大,有一天闽粤结成了秦晋,我也不会感到意外。如果有个台湾少年特别巴结我,其志又不在跟我谈文论诗,我也不会怎么为难他的。至于其他各省,从黑龙江直到云南,口操各种方言的少年,只要我女儿不嫌他,我自然也欢迎。”
“那么学识呢?”
“学什么都可以。也不一定要是学者,学者往往不是好女婿,更不是好丈夫。只有一点:中文必须精通。中文不通,将祸延吾孙!”
客又笑了。“相貌重不重要?”他再问。
“你真是迂阔之至!”这次轮到我发笑了,“这种事,我女儿自己会注意,怎么会要我来操心?”
笨客还想问下去,忽然门铃响起。我起身去开大门,发现长发乱处,又一个假想敌来掠余宅。
一九八○年九月于台北
我的阴阳两界-王小波
========================
我的阴阳两界-[[王小波]]
-----
-----
## 第一章
-----
### 一
再过一百年,人们会这样描述现在的北京城:那是一大片灰雾笼罩下的楼房,冬天里,灰雾好像冻结在天上。每天早上,人们骑着铁条轮子的自行车去上班。将来的北京人,也许对这样的车子嗤之以鼻,也可能对此不胜仰慕,具体怎样谁也说不准。将来这样的车子可能都进了博物馆,但也可能还在使用,具体会怎样谁也说不准。将来的人也许会这样看我们:他们每天早上在车座上磨屁股,穿过漫天的尘雾,到了一座楼房面前,把那个洋铁皮做的破烂玩艺锁起来,然后跑上楼去,扫扫地,打一壶开水,泡一壶茶,然后就坐下来看小报,打呵欠,聊大天,打瞌睡,直到天黑。但是我不包括在这些人之内。每天早上我不用骑车上班,因为我住在班上。我也不用往楼上跑,因为我住在地下室,上班也在地下室,而且我从来不扫地。我也不打开水,从来是喝凉水。每天早上我从床上起来,坐到工作台前,就算上了班。这时候我往往放两个响屁,标志着我也开始工作了。我呆的地方一天到晚总是只有一个人,所以放响屁也不怕别人听见。
我住的地方是医院的地下室。这里的大多数房间是堆放杂物的,门上上着锁,并且都贴一张纸,写着:骨科,妇产科,内科一,内科二,等等。我搬进来以后,找了一支黑蜡笔,在每张纸上都添了“的破烂”,使那些纸上写的是骨科的破烂,妇产科的破烂,等等。这样门上的招牌就和里面的内容一致了。但是没有人为此感谢我,反而说,小神经的毛病又犯了。他们对我说,我不该在门上写破烂二字。破烂二字不能写上墙。假如我要写,可以写储物室,写成骨科储物室,妇产科储物室。但是我说,你们玩去吧。他们听了这话,转身就逃了出去。地下室对他们来说,可不是个好地方。
除了这些堆破烂的房子,就是我住的房子了,门上写着仪修组王工程师的字样。我的左边隔壁是破烂,右面隔壁也是破烂。但是除了破烂,这里还有一些别的东西。走廊上,每隔不远就有一个龛,龛里放着标本缸。缸里泡了一些七零八碎的死人。其中一个就在我的对门,和我同一性别,但是既没有脑袋,也没有四肢。我闲下来就去看他,照我看,他死掉时,大概还没有我大。他的腰板挺得板直,一副昂首阔步的样子,只可惜他既没了首,也迈不开步了。人家在他肚子上开了一扇门,在内脏上拴了好多麻线,每根麻线上拴了一个标签,写着大肠小肠之类的字样。假如这位仁兄活过来,一低头就能看见,自己的哪一部分叫什么。除此之外,他还会发现人家把他的阴茎切掉了,但是把阴囊和睾丸都留着,所以那些东西泡在缸里,就像半头蒜的样子。不知道他会不会觉得好看。还有一些龛放着一些玻璃柜,放的是骨头架子。那些东西自己不能够站立,所以柜底下安着一根木杆子,杆顶上有个铁夹子,夹在项骨上。把死人弄成这个样子,可是一种艺术。一般的人,你就是给他最好的死尸,他也做不出好的标本。因为这个原因,我住的地方就像一个艺术馆。我对这个住处很是满意。
我住的地方就是这样。我就是门上写的那位王工程师。小神经也是我。他们叫我小神经,是因为我有点二百五。过了一百年,也许人们不知道什么叫二百五。这句话的意思是说,因为我只呆了二百五十天就从娘胎里爬了出来,所以行为怪诞。其实我在娘胎里呆足了三百天,但是因为我行为怪诞,大家就说我只呆了二百五十天。这种因果倒置是因为我们有幽默感。其实我行为怪诞,是因为我有阳痿病。因为我有阳瘘病,所以和前妻离了婚。我现在四十多岁,还在独身,而且离群索居,沉默寡言。
我不得不离群索居,沉默寡言,因为无论我到了哪里,总有人在我背后交头接耳,说我是个阳痿病人。这就使我很不好意思见人,虽然我已经阳痿了十年,对此已不再感到羞愧,但是我还是不乐意人家这样说我。我不愿他们把我看成了太监一类的东西,虽然实际上我的确和太监差不多。这件事的教训是不要找本单位的人结婚,除非你能确信自己没有阳痿病。我前妻原来是本院的护士,现在调走了。但是在调走以前,她已经把我不行这件事传得满城风雨。现在除了躲在地下室,我也采取了积极措施,到康复科去看病。康复科的马大夫和我关系很好,别人看病要钱(公费医疗不报销康复科),他不管我要钱。
马大夫治我的阳痿病,开头是用内科疗法,给我开了很多药,并且让我多吃巧克力。他说巧克力壮阳。但是巧克力吃多了食欲全无,我还长了口疮。后来又换了外科疗法,住了一段时间院,躺在床上打牵引。这就是说,在那玩艺上挂上十公斤铅锤,往外拉。牵引了两周,那玩艺拉到了一尺多长(后来不牵引,慢慢又缩回去了),但是似乎比以前还软了。他又建议我动手术,移一节肋骨进去。我觉得这样不好,因为肋骨移进去,就会永远硬挺挺,这样很不雅。他对我的病真是尽心尽力,认为我的病老不好,是对他医术的挑战。最后他建议我做变性手术,当不了男人当个女人好了。但是我坚决不答应,因为我身高一米八五,体重九十公斤,头大如斗,手大脚大,当了女人也不好看。最后他说我不肯合作,就再不给我看病了。但是我们俩关系还是很好,他经常跑到我的工作室来和我聊天。这家伙有六十岁了,养得又白又胖,因为不正经,在头头脑脑面前很没人缘,和一些小大夫小护士倒蛮亲热的。就是他有一天跑到我这里来,说要给我介绍女朋友。我觉得他脑子有问题:头几天还要叫我做变性手术,现在又要给我介绍女人,一点逻辑都没有。我就这样和他说了。正说时,有个女孩子从外边闯了进来,说道:马老师,您出去,我自己和他说!然后她就自己介绍说:我是妇科的,我姓孙。其实我在食堂里见过她,就是不知道她是妇科的,也不知道她姓孙。
小孙那一天来找我,起头情形就是这样的。马大夫走了以后,她一五一十地对我说:她马上就需要个男朋友,必须是人高马大,膀阔腰圆,能带得出去的那一种,来帮她解眼前的燃眉之急。这是因为她的前男朋友要结婚,今天晚上就要举行婚礼,她已经收到了邀请,想和一个大个子男人一块去。我想了想,说道:要是这样的话,我能帮上忙。别的事情我就帮不上忙了。这个姓孙的小鼻子小眼,娇小玲珑,一副小孩样,其实已经二十七岁了。到了晚上,我就和她一块去了。婚宴上全是些青年男女,大概都是她的同学,新娘子也是她的同学。我发现,医学院大概只招南方人,所以那一屋子男女全是小个子南方人,白面书生,个个戴着眼镜。我在其中像个巨人。认识我的人都说,我的脸相极凶,还说我吃相难看。我在席上喝了一瓶啤酒,就打了一个大嗝,声震屋宇。然后我讲了一个下流笑话,弄得四座皆惊。其实我没想去捣乱,只是在地下室里呆了很多年,很少有人请我来参加聚会,心里很高兴。但是已经把新郎吓坏了,把小孙叫到一边说了好半天。然后我们就提前退席了。回来的路上小孙说,王工,你把他们都镇了!你帮了我的大忙,我不会让你白帮的。我一定也帮你一个忙。
-----
### 二
后来小孙对我说,作为我给她出气的报答,她要把我的病治好。据她自己说,她读过Masters和Johnson的书,治我的病十拿九稳。我也看过那些书,所以我想这孩子真是个怪人。她梳了个齐耳短发,长得白白净净,还是蛮漂亮的。不管怎么说,也能嫁得出去,干吗要来给我治阳痿?女孩子只要嫁得出去,就不必理睬不想嫁的男人。我对她说,你没搞错吧?那都是夫妇双修的办法。她说知道,所以我要和你结婚。先结婚,后治病。
我和小孙要结婚的起因就是这样。开头我想,这个孩子还要给我治病,我看她自己就该找人治一下,是不是精神病。后来想到她起初找我那一回的情况,我怀疑她吃了别人的亏。既然她都要嫁我了,问一问也没什么。我就问道:你大概不是处女吧?她说当然不是。你要不要看看?我说看什么?她说我可以对她做个妇科检查。我对此是一没有经验,二没有兴趣,而且也没有必要。只有混充处女的,没有混充非处女的。所以我就说:结婚可是你自己要干的,将来可别埋怨我。她说绝不会。她说这些话时,一点也不脸红。
再过一百年,人们可以在现在留下的相片里想象我:我和大家一样,目光呆滞,脸色灰暗,模样儿傻得厉害。现在你到美术馆去看看十六世纪的肖像画,就会发现上面的人头戴假发,长一张大屁股脸,个个都是傻模样。过去的人穿燕尾服,瘦腿裤,显得头大身子小,所以很难看。但这样的装束在当时,一定是了不起的好穿着。以此类推,现在的人不论穿什么,将来也会傻得厉害。基于这种心理,我根本不打扮,经常不理发,不刮脸。当然,小孙是女孩子,不能和我一样。她经常打扮得干净漂亮,因为留着齐耳短发,下面的头发茬每天都要推一推。因为这些原因,我们俩在一起不够般配。但是我们俩经常一道去逛大街,表示我们在恋爱。这是计划的一部分,首先做出了恋爱的姿态,将来请求结婚就不至于显得突兀。
将来的人谈到我们结婚前的到处奔走,一定会感到奇怪。我根本就没有逛大街的欲望,我常年呆在地下室里,很少走动,所以腿上的肌肉都退化了,白天走了路,晚上就腿疼。天寒地冻,不能去公园。我们总是在商业区里逛,但也没有要买的东西,更没有买东西的钱。过去我一个人在城里逛,老是低着头,看看地上有没有掉的钱,这是我几十年的积习。现在我也和小孙在北京城里闲逛,我倒是不低头,但是对一切都视而不见。倒是小孙时常有所见,走着走着就会忽然捏我一把,说道:看见了没有,刚才那个人盯着我看。听了这话,我就会猛然转过头去,大声说道:哪一个?她把我拉回来说,别这样,你要把别人吓死了。走到街上,我有时也会注意到她忽然把小嘴一扁,小脸一扬,脸上似笑非笑的模样。要不然就是忽然抓住我的胳臂,把全身挂在我身上。这大概是因为又有人看她了。但是到底是些什么人在看她,我一个也看不见。
星期天小孙把我带到王府井一家理发馆门前,让我往橱窗里看。我看了好半天,才认出橱窗里有一张相片是她。那是一幅黑白上色的相片,再过一百年,人们就会根据相片上的水彩,断言拍照时彩色摄影尚未发明。相片上的小孙涂了个红脸蛋,和她本人一点也不像。那相片就像现在看到的玛丽莲·梦露,或者猫王的相片那种五官不清,色彩斑斓的样子,露出五十年代那种村气土气;但是再过一百年,人家看到一个女孩子站在橱窗里自己的相片前流连忘返,也会露出会心的微笑。我对她说,快走吧,呆会人家会出来说:小姐,是不是想把相片要回去?她就勃然大怒道:你说什么呀你!
小孙说,她在大街上走时,经常迎上这样的目光:先是盯上了脸,然后一路向下搜索,在胸部久久地停留。然后久久端详她细长的腿。她对自己的腿很是骄傲。这种景象我从没看见过。我想人家也许是在看她那条石磨蓝的牛仔裤,那条裤子值我一个月的工资。她对这种说法十分愤怒,说我在蓄意贬低她。其实我没有这样的意思。我早就注意到她的头发细密茂盛,柔软光滑,就像一只长毛猫的毛一样,每次从外面回去,走到医院门口时,她都要把手伸给我,让我拉着它。那只手非常小,柔若无骨,又凉又滑。我们拉着手从门口进去,她还要去问传达室的老头:有我的信没有?然后和每一个见到的人打招呼。我和小孙谈恋爱的情形就是这样的。
我和小孙每天下了班就到王府井喝咖啡。后来我对咖啡上了瘾,每天必须喝五大杯,否则就呵欠连天,而咖啡太贵了,比外国烟还贵。据马大夫说,我这叫做咖啡因依赖。他又要给我治这种病,但是我拒绝了。我怕他用咖啡搀上大粪给我喝,据说他就是这样给人戒烟。我只是向他打听外界对我和小孙恋爱的反应。他告诉我说,情况不容乐观,人家说,小孙是面子下不来。这句话的意思是说,她借用我在她前男友结婚那一天去给她撑过场面之后,如果现在就不理我,则显得太冷酷,太薄情。因此她必须和我假恋爱一段,然后再把我甩掉。这就是说,一个女孩子,应该表现得温柔多情,尽管她其实不是那么温柔多情,也要假装成这样。这也就是说,小孙借用我去参加婚宴的事现在已经是尽人皆知了。这件事起初只有三个人知道:一个是我,一个是小孙,还有一个就是马大夫。我们每个人都有把这件事泄露给别人的嫌疑。马大夫主动告诉我说:这件事我可没对任何人说过,也不知别人怎么就知道了。
假如马大夫没有把这件事告诉别人,小孙也不告诉别人(这事对她名声有损),剩下只有我最可疑。但是我成天呆在地下室,从来不和外人接触;最后的结论就是我们谁也没告诉别人,这事就自己传出去了。由此得到一个推论,我们医院里现在安装了一台可怕的仪器,可以窃听全院每一个角落。这台仪器由一个长舌妇操作,她听到了我们在地下室里的谈话,然后就告诉了医院里每一个人。但是这件事非常的不可能,因为他们安这仪器时,必定要找我。我是全院唯一的电气工程师。连我都不知道医院里有这台仪器,那就必定是没有。
根据医院里现在的传闻,小孙是个极好面子的姑娘。她不乐意在前男朋友结婚那一天显得孤独无伴,所以借用了我。这是很正确的。根据同上传闻,她的小算盘又极精,找一个阳痿的男人来撑场面,将来不会有任何损失;有损失的是我,因为我被女人耍了。但是实际情况不是这样,实际情况是小孙正在献身于科学,准备在我身上探索一条治疗阳痿的新路。我和她是医生与病人的关系。当然这一点是秘密的。在开始治疗前,她必须嫁给我,然后治疗才合法,治好以后,才好写报告,拿出去发表。为此必须叫大家相信我们在恋爱。小孙说,我们俩必须在人前再亲密一点。她建议我们中午时到门厅里去接吻,但是我觉得过于肉麻。于是她建议我们从外面回到医院里时,显得再亲热一点。这就是说,在经过大门时,她要骑在我脖子上。我问了她的体重,体检时什么也不穿是四十三公斤,现在着了冬装,顶多也就是四十八公斤,这不算重;更何况她说,把你治好了以后,骑我的时候还多着哪;所以我实在没有理由不答应她。
-----
### 三
在小孙骑我脖子之前,发生过很多事。首先是小孙说,她要扮演我未婚妻的角色,就要处处管着我。自从我成了小神经以后,已经习惯了别人对我耳提面命。在这些人里,女人尤多,多一个小孙也没什么。比方说,我去领工资,会计一定要再三关照我说:你数数,这是一百三十元。其实没有什么好数的,总共是一张一百元的大票,三张十元小票,完全可以一目了然;更何况数也数不多。因此我拿了钱总是看都不看就往兜里一揣。但是那个二十三岁的小会计一定从柜台后面赶出来,把我兜里的钱掏出来,当着我的面数一遍,然后再塞到我口袋里去。我到食堂里去买饭票,管理员大妈也会把饭票对我一五一十地交待:这种红的是菜票,那种绿的是饭票,千万别搞混了。其实我只是阳瘘而巳,并不色盲,更不是低智人。但是因为我阳痿,就不能阻止别人像关心低智人一样关心我。
人家总要把男人的大脑袋和小脑袋联系起来看,小脑袋不行的大脑袋一定不行——这成了一种成见了。我也无心去纠正这种成见,因为既然是成见,就无法纠正。我只管我行我素,呆在地下室里不出来。这样省了好多的事:因为大家都觉得我是个傻子,所以什么开会、学习等等都不叫我去了;这样省了我和大家一起磨屁股。后世的人,对我们要开那么多的会一定惊诧不已,因为到了那时候,只有总经理、部长、总统才须开那么多的会。所以那时的人一定会以为我们都是些很重要的人物。其实我们不过是些电工、技师等等,开会讨论过马路要走人行横道而已。而且要开这样的会,必须有一条坚硬的鸡巴,软的不行。过去我除了领工资和买饭票,从来不到楼上去,现在发现连领工资都不必去,因为工资是小孙领去了。饭票也不必去买,因为饭票是小孙代我买了。别人还说,现在好了,王二的事都可以交待给小孙,省了多少麻烦。说完了总要哈哈大笑一通。
小孙和我谈恋爱,结果是我们俩都变成了一种气体,叫做什么一氧化二氮,或者说,叫做笑气,人家一见到我们在一起就要笑。但是我们既然是气体,当然就没有自觉性。我和小孙一道出门去,走过楼道时,小孙一定要叫我站住,给我掖好围脖。其实我根本就不需要围脖,因为我长得相当肥胖,一点也不怕冷。但是小孙一定要这样做,她说这是在大庭广众下和我亲热的惟一机会。掖围脖的时候,过路的护士就会站下来,说道:“小两口出门去呀?”等等。小孙伶牙俐齿地答道:到王府井买点东西,等等。说完了我们一同向前走去。走不了几步,一阵大笑就会在脑后炸开。这时我们转过身去,就会看到那些护士聚成一堆,个个脸色涨红。很显然,她们是在嘲笑我们。我就想转回去,把她们教训一顿。但是小孙把我拉住,叫我沉住气。她说这种情况会改变的。然后她就挽住我的手臂,把全身都挂在我身上。因为我壮得像个狗熊,而她长得娇小玲珑,所以这么挂着还算好看。假如双方的身坯换过来,那就像蚂蚁举着一片饼干渣,一点也不好看了。但是尽管她使了很大的力气往我身上贴,别人也不相信她真的要和我谈恋爱,更不要说真心嫁给我了。
再过一百年,人们会这样形容我们的医院:这是一座四四方方的院子,四周围着栅栏。院子里全是一些古旧的灰砖房,有一些是两层的,有一些是三层的。他们想象起这些房子,就像现在我们想象地下的墓葬一样。那时候的房子大概都是一百层的大厦,底下五十层放汽车,上面五十层住人。在这些墓葬里,有一些人穿着白大褂来来去去,还有人穿着淡蓝色的睡衣睡裤来来去去。在这些灰砖楼之间,有几片草坪,几棵半死的树作为装点。但是我既不穿白大褂,也不穿蓝睡衣,穿一件粗蓝布茄克衫,在这座古墓里显得很扎眼。但是我根本就很少到上面去,所以也就很少叫人看见。
小孙那天骑着我脖子走进医院时,是星期天下午五点多钟,门诊下了班,天气又很冷,所以到处都看不见很多人。我驮着她,两个人连在一起有两米五十左右,只能小心翼翼从拱门正中通过。两米五十的庞然大物从医院的正门走进去,可算是惊世骇俗之举。这个举动总算是引起了注意,第二天妇科主任就去找小孙谈话,叫她注意影响。但是这个举动也是非常费力的。假如你到过草原,见过人家骑骆驼,就会理解了。骑马骑驴都可以飞身而上,但是骑骆驼时这样干就绝对不可以,因为骆驼太高了。你必须使骆驼倒下来,然后才能骑上去。但是骆驼一般是很不乐意倒下来的,赶骆驼的人要拿个装铁尖的小棍子,围着骆驼转上半天,敲敲前腿,敲敲后腿,磨上一两个小时的嘴皮子,骆驼才肯倒下去。那天下午,我就是那只骆驼,小孙就是赶骆驼的人,但是她手里没有赶骆驼的棍。她只是一遍又一遍地说:你快蹲下来呀!
我在蹲下之前,先把医院门前的街道打量了很多遍。那条街不算宽,扫得干干净净。星期天下午,没有很多行人。然后我又把小孙的脸打量了很多遍:那是一张白白净净的娃娃脸,留着刘海,嘴巴很大。那时我想的是:记住了,就是这娘们要在大庭广众下骑我的脖子,叫我名声扫地。最后我就打量她的下半身:就是这东西要骑上我的脖子。洗得干干净净的牛仔裤,又白又亮的护士鞋。最后我毅然决然地蹲了下来。她一把就揭下了我头上的帽子(那是一顶剪绒皮底的帽子,和二号的钢种锅一样大),然后哈哈笑了起来,说道:王二,你小时候头上几个旋?我知道自己是三个旋,因为一旋拧,二旋愣,三旋打架不要命。但是她说:你现在只剩一个旋了。他妈的,我怎么会不知道自己几个旋?我爸爸不到四十就秃了头,根据遗传,我现在本该一个旋都没有。
后来我就看见两条细细的小腿搭上了我的肩膀。在我站起身之前,那双小手还在我脸上摸了老半天。这倒不是在调情,而是在找可以抓的地方。最后她抱住了我的下巴,说一声起,我就站了起来,脖子后面热烘烘,想起了一句歇后语:大姑娘骑瘦驴,严丝合缝。虽然我不是瘦驴,但是体会到了严丝合缝的感觉。这感觉非常的不好。尤其是她在我脖子上上下磨擦了几下后说:王二,这感觉非常古怪!好像是我把你生了出来!这时我往左一看,看到一条裹在洗白了的粗布里的大腿,往右一看,也是一条这样的大腿。这是我一生未曾见过的景象。这两条腿一齐夹紧,夹得我眼冒金星,我的感觉就更坏了。这时我想起了小时候看过的《天方夜谭》中水手辛巴达的故事,那位辛巴达也被海老人骑过;但是海老人是个男人,所以辛巴达也没有被人如此严丝合缝地骑过。有史以来,有这种经历的,我是第一人。我就这样走进大门去,影影绰绰地发现有好多人在楼上的窗口看热闹。
小孙初次骑我脖子的事就是这样的。有关这件事,还可以补充如下:开头我是不乐意让她骑的,但是她把我说服了。她说,就她个人而言,对我的脖子是很尊重的——我比她早毕业好几年,所以这是老学长的脖子我比她大了十五六岁,所以这又是一位大叔的脖子。无论从哪方面说,骑这个脖子都是大不敬。但是为了事业,非骑不可。虽然这些说法相当牵强附会,但是我也无法批驳。而正式骑上去了之后,她就毫无崇敬之心。走过大门时,她把身体挺直,去够门顶上的灯泡。走过楼门时,她又蜷成一团,把我的脑袋整个包住。从大门口,到地下室门口,她总共在我头上盘踞了十分钟,在这十分钟里,她还给我讲了一个故事。其实这个故事我早就知道,典出纪晓岚《阅微草堂笔记》(假如你在那书里查不到这件事,你不要和我计较,我是小神经)。这故事说,某阁老家盖房子。按照中国的传统,盖房子时对梁柱之类都很崇敬,柱上要贴“擎天金柱”,梁上要贴“架海银梁”等等的红纸,安柱架梁时还要放鞭炮。当然了,这是生殖器崇拜的遗风,除了梁柱,祖宗还崇拜大炮、高塔以及一切又粗又长的东西。该阁老家放过了鞭炮,正要吊梁,发现一个丫环正骑在梁上。按照中国的传统,有一个东西是最肮脏,最不洁的;那东西却紧紧贴在了圣洁的架海银梁上。大家看了无比愤怒,有喊打的,有破口大骂的。但是那丫环却拍拍那东西答道:你们瞎嚷嚷什么?帝王将相,皆出于此也!
这个故事我讲起来是这样的,小孙讲起来就不是这样。首先,她把出处记错了,说是《聊斋》;其次,她也不记得骑的是什么,只记得是骑个很神圣的东西。结尾倒是记住了:帝王将相,皆出于此也。讲完了以后,她还问我有何感想。我只谈了一点感受:你给我下去!从大门骑到这里,还没骑够哇!
除此之外还有一点感想,就是她的裤子很干净,是用有香味的洗衣粉洗的,另带一点漂白粉的味道,这些气味很好闻,但是我没有说出来,我只是说这故事她完全讲错了。但是我丝毫也没有贬低她的意思,因为很少有女孩子会去看纪晓岚的书,所以就是看得不仔细也属难能可贵。谁知她根本就没看过纪晓岚的书,这个故事是她从老师那里听来的。原来她们在大学四年级分到了妇科实习,眼看后半辈子就要专门看这个东西,所以大家情绪沮丧。带实习的老师就讲了这个故事来鼓舞士气。这故事的寓意就是要让她们记住,眼前这个东西其实是很伟大的:帝王将相,皆从此出也!
小孙给我讲这个故事,也是想鼓舞我的士气。她还说,她有一个完整的计划,给我治阳痿只是其中的一环。这个计划包括将来写一篇医学论文,一本书(纪实文学类的),《我治好了阳痿的丈夫》,以及心理学、社会学方面的研究报告。干完了这件事,她就可以一举成名。要做这样的研究,和我结婚是必不可少的,否则就会受到社会方面的指责。考虑到这个研究惊世骇俗的性质,现在必须好好演出恋爱一幕,免得叫人看出漏洞来。这孩子是四川人,四川人就是有一点疯,而且她看侦探小说看多了,处处透着诡异的模样。她还怕我不乐意,答应将来把全部稿费都给我。为了这一切都能顺利实现,我也要付出些努力,其中就包括让她骑我的脖子,并且不要忘了,抵住我后脑的那个东西,帝王将相,皆从此出也。
-----
### 四
小孙骑过了我的脖子以后,我觉得丢尽了面子,更不肯上楼去了。这更合了她的意思,每顿饭都是她给我打来,可以向食堂里的人表示,我们的关系又进了一步。这就使她需要一架小计算器,以便每天晚上和我清账:早餐的油饼是多少钱,中午的肉片又是多少钱。这些都要从我的饭票账上支出。后来我从会计科送来修理的仪器里找到了一台,是精工牌的,上面带有一架打纸条的打印机,不但能算账,还可以打印收据,花了五分钟修好了给她用。在找到那台计算器之前,一切都要从她的小脑袋瓜子里算出来。这时她躺在我房里的空床上,搜索枯肠,挖空心思,再加上搔首弄姿,看上去真叫人于心不忍。我自己也是医学院毕业的,所以真不能相信医学院能把人教得不识数。我们俩不但都是医学院毕业,而且是同一所医学院毕业,唯一的区别就是我学医疗仪器,她学临床医学,但是这一点区别就使她时时问我十二减九等于几。但是她算账的模样还是蛮好看的,从她拖在地下的两条腿来看,你该相信她是仰卧在床上,但是从她的上半身来看,你又该相信她是俯卧在床上。假如是我在做这个姿势,下半生就要卧床不起了。那时候正是下午五点钟左右,一抹残阳从窗口照进来,正照在那块空床板上。她穿着一件牛仔上衣,脖子后面镶了一块三角形的皮革,一头柔软的短发都被她搔乱了。算到心力交瘁时,她就专心地去闻那支圆珠笔。这些表现一点也不像个人,倒像一只猫咪。这叫我觉得让她来给我治阳痿,实在不好意思。假如是个胖大女人,再长一点胡子,那就好意思了。
这个小家伙每天还要给我讲一课,对着“帝王将相”的图谱,给我上女性的生理解剖学。有件事已经讲了不下十次了,就是一到了我能在帝王将相里站住了脚,我们俩必须立即离婚。就其本心来说,她一点也不想嫁给我,到时候一定要离婚,绝对不准赖的。我当然同意了,但是有另一个问题要提出来的,就是假如治疗没有效果,我老也进不到帝王将相里面去,那该如何是好。她说那是绝对不会有的事。人家Masters和Johnson做了那么多例实验,应该是很有把握。实在治不了,也只好离婚算了。反正双方都没有损失。为了避免将来离婚时闹纠纷,现在就该把账算清。凡是共同开支,一律用二去除,精确到小数点后一位,然后再四舍五入。
就我的本心来说,也一点不想娶她当老婆。我一点也不想娶任何人当老婆,但是很想把阳痿病看好,省得大家拿我当个怪物。所以我们俩在这方面一拍即合。为此就需要在某个时间,某个地点,取得性交的许可。我们俩正为此做出努力。下个礼拜天,我们又出去转了一天,晚上她又是骑着我的脖子回来的,这一回引来了更多的人来看。
这一回我觉得她的裤子凉飕飕的,气息芬芳,不是洗衣粉的气味,也不是香水的气味,很可能来自帝王将相。那个东西,我虽然结过婚,却没有见过,现在每天看图谱,渐渐感到十分亲切。经过了一段时间训练,她认为可以了,我们就打报告请求结婚。谁知道居然出了意外,人家不批准。
后来我觉得这整个事情像一个谜。不知道为什么,小孙想和我结婚,也不知为什么,我会同意和她结婚。从表面上看,她是想给我治阳痿,傲一项医学试验,其实这样的理由根本就不可信。从表面上看,我是想让她给我治好这种病,以便从此做个正常的男人,但是这个理由也一点不可信。其实我并不渴望从此做个正常的男人,小孙也不渴望做成这个医学试验。这件事从始至终都可疑得很。惟一可能的解释就是我觉得她是自己人,她也觉得我是自己人。用她自己的话来说,我们俩有缘分。
-----
## 第二章
-----
### 一
二十年前,有一个冬天的早上,我骑车去找一个人。当时北京的上空飘着一层混了煤烟的脏雾,好像一口粘痰;我的自行车咔咔作响,好像一只铁皮玩具鸭子;我穿了一件油腻腻的棉袄,头上戴了一顶旧毡帽。当时的情形就是这样的。
北京城的中心是紫禁城,绕着紫禁城有一些街道名和紫禁城有些关系,比方说,太仆寺街,光禄寺街,内务府街等等。有条胡同叫饽饽房,大概那里过去是专给皇宫大内蒸饽饽的;有条胡同叫奶子府,过去大概住了一些为大内服务的奶妈。那些胡同里的房子都不怎么样。七三年到七四年,我经常到那一带去,对那一带的情形知之甚详。当时那一带的胡同里都铺了柏油,但是胡同还是那么窄。有些破房子拆掉了,但是没有好好翻盖。新盖的房子都是用烧得很次的红砖砌的,背面甚至是空心的煤渣砖。没有翻盖的房子都是又矮又破的四合院,和过去完全一样。和过去不一样的还有每条胡同里都多了一间灰渣砖砌的小房子,那就是公共厕所。过去这种房子也有,但是不那么多,这是因为院里的茅房都被填死了,大家都得上公共厕所。自从有了这种小房子,每一条街都臭得厉害。冬天里我骑一辆自行车,从那些胡同里经过,路两边都结了薄冰。我看到那些房子上都喷上了青灰,好像死了爹又死了娘的模样。过去北京城里,只有煤铺墙上才喷青灰。但是尼克松来北京时,到处都喷了青灰,像煤铺一样。大概觉得这样比较美。我小的时候就没看出煤铺怎么美。我是清晨路过那些胡同的。北京城里当时有一层薄雾,所以没有风。天气很冷,但是并没有冷到冻鼻子的程度。那时候除了上早班的人,都还没起来。在胡同口碰见一位少妇,正在倒尿盆。她的头发还能看出一点理发馆的模样,身上裹了一件锻子的(或者是线绨的,这两种东西我分不清楚)丝绵小棉袄,下面穿一件粉红的棉毛裤,脚下踩着两个毛窝(就是那种毡面松紧口的棉鞋),睡眼惺忪,手提一个搪瓷痰桶迎面走来。棉祆和痰桶都是崭新的,这些迹象表明,她结婚还不到一个礼拜。当时我正盯着她领口看,因为她的脖子和胸口像雪一样白。我记得她是很漂亮的,但是现在想不起她的模样。就我当时的年龄来说,记性本不该这么坏。这是因为她走到了下水道口上,就把痰桶一倒。不仅是哗啦一声,里面还滚出两截屎来。所以我就没记住她的模样,只记住了屎的模样,那屎橛子无比之粗,无比之壮。那东西就冻在了铁箅子上,大概要冻一冬天。在那上面还要冻上剩面条、剩米饭,好像一块奇形怪状的萨其马。这件事情好像马路上冻结的一口粘痰,冻进了我的脑子里,大概要到我死后,才会释放吧。
时隔二十年,我又想起了那天早上的事。那天我到奶子府去,是要找李先生。不知道现在李先生上哪里去了。现在他大概不会是过去那个模样。但是假如你在七三年看到他,就会说他是个狗头猫脸的玩意儿。狗头是指他的脸形,像个哈巴狗的模样,猫脸是指他的眼睛有点黄,瞳孔也有点窄长,他的头当时就歇了一半顶,现在大概全歇光了。此人身材不高,但是身上还算有肉。有一点鸡胸,又有一点驼背。我不但认识他的脸,还认识他的屁股,这是因为我那一天早上把他叫起来后,他只好当着我的面穿裤子。他的内裤太破了,就背朝着我。但是后面更破,和没有是一样的。那时我坐下来,一面欣赏他的屁股,一面找到了他的烟叶子,给自己卷一支烟。当时我看见他的屁股,就像个风干的苹果,皱皱巴巴的,还有无数小的黑病、息肉等等,我想任何狗急跳墙的同性恋者见了都不会动情。李先生背着脸说:给我也卷一根。这个笨蛋,穷到了抽烟叶的地步,却不会卷烟。于是他只好用烟斗来抽,那味道就像狗屁一样。抽到嘴里像狗屁,别人闻着也像狗屁。
有关烟叶子也有很多学问,现在眼看要失传。这种东西二两一包,外观像简装洗衣粉。有一种是白纸上印红字,那是晒烟,抽起来还可以,假如是特级,就是关东烟,比香烟还好。还有一种是绿字,那是烤烟,抽起来就像狗屁。但是狗屁也分级,二级以下烟叶里有草棍、席箔、秫秸杆,不是纯狗屁。李先生的烟叶子是五级的,抽到一半,烟头里掉出一个黑球来,经仔细辨认,是个烧糊了的死苍蝇。为此我还恶心了好半天。
我还能想起不少有关李先生的事情。李先生出门时骑一辆自行车,那辆车可不是一般的自行车,而是一辆匈牙利的倒轮闸。这种车非常少见,甚至比日本鬼子留下的老富士还少见,因为它是五二年匈牙利在北京开博览会时送来的样品。自从到了李先生手里,他就再没有修理过,任凭车上的零件一样样脱落下来。据说有一次车座不见了,李先生就在座管上骑了一段时间,其状就如在受桩刑:疼得龇牙咧嘴,手舞足蹈。后来他痔疮大发,才不得不买了一个旧车座。李先生上车的样子也是十分奇特,他总是推着车向前奔跑,在奔跑中弯下腰,把脚镫子转到一个特定的角度,然后踏着脚镫骑上自行车。那种奔跑中矮身转脚镫的身法,酷似狗撒尿。
李先生和我一样,专干些不能干的事。我干的事是想写小说,经常往刊物投稿,但是总是被退回来,并且不是退给我本人,而是退到党委办公室,附有一封公函,建议对投稿人加强思想教育。但是很少有人真来教育我,因为我是小神经。李先生干的事倒不是写有维多利亚时期风格的小说,而是要研究西夏文。这件事并没有思想意识方面的问题,但他本职工作是个俄文翻译,一研究起西夏文就看不进俄文了。而且他在研究西夏文时,你就是在他眼前放鞭炮他也听不见,这个样子完全不能上班。因此他早早退了职,靠偶尔翻些稿子为生。谁知后来碰见了“文化革命”,取消了稿费,差一点就把他饿死了。李先生因此气急败坏,说过好多大逆不道的话。我听见了这样的话,就这样安慰他:其实这件事也是蛮公平的一为什么只许老天不下雨,饿死非洲的游牧民,就不许中国搞“文化革命”,饿死你这搞翻译的游牧民?何况从现在的情形来看,你到底饿得死饿不死还不一定。但是他还是要继续说些反动话:要是天不下雨,饿死我认了。现在的事是,我又没招了谁惹了谁,有人非要逼我跳火坑。李先生的情形就是这样,我到今天还记得。人活在世界上就像一些海绵,生活在海底。海底还飘荡着各种各样的事件,遇上了就被吸附到海绵里,因此我会记得各种事情。
-----
### 二
那一年我正在山西插队。现在我长得人高马大,相貌凶恶,过去就不是这样。小时候我长得文静瘦弱,还爱和女同学跳猴皮筋。所以我到山西插队时,我妈就睡不着觉。她以为我连窝头都不会蒸,一定要饿死,假如没饿死,也会被人欺负死。但是只过了一年,我就长了一嘴络腮胡子,活像一个老土匪,而且满嘴都是操你妈。这说明环境可以改变一个人,只要一年就能变得连他的亲妈都认不出来。在乡下时我很少吃窝头,倒常常吃鸡。老乡们说,母鸡见了我就两腿发软,晕倒在地,连被提走了都不叫一声。这当然是过甚其辞。当时我虽然极具男性魅力,却未必能迷倒雌性鸟类。
那一年冬天我原准备在乡下过冬,但是当地正好刮着很厉害的白毛风,烧炕的柴又不够。我们五六个人挤在一个被窝里,身上盖上了所有的大衣。第二天早上起来,发现所有的大衣都从被顶上滚下来,掉到了尿尿的脸盆里,冻成了铁板一块。我们中间没有一个人有勇气不穿大衣就到外面去生火,就在屋里点火把那盆尿煮开,把大衣拿下来。那气味实在是可怕,把我的两只眼都熏坏了。出了这件事以后,大家都不好意思了;谁见了谁都是羞答答,因为六个堂堂的男子汉煮了一锅尿,实在是丢人。这说明我们虽然长得像土匪,脸还是很嫩。约定了谁敢把此事传出去就宰了谁后,我们就各奔东西。我跑回北京来,住在原来住过的地方。那地方原来是一所大学,里面有很多人。当时叫做“留守处”,里面只住了很少几个人。很大的院子里到处是荒草,人们都下干校了。李先生原来也住在这个地方,后来才搬走了。这地方原来每个人都认识李先生。
现在应该说说那天我去找李先生的原委。我从山西跑回来,住在留守处,那院里当时只有大崔一家住。这位大崔原来也是我们的邻居。除此之外,他还是我爸爸的同事,李先生的老同学,长得人高马大,笑口常开,一团和气。大家去下干校,家里还有些东西,是得找个大家都放心的人看着。大崔实在是最合适的人选。他老婆也是我们院的人,所以一起留下来。刚回来我去找他借房子,管他叫崔叔叔,管他老婆叫阿姨。借到了以后就改了口,管他叫大崔,管他老婆叫大嫂。当然这房子不能白住,我也得帮人家干点事,跑跑腿。所以大崔要找李先生,用不着自己去,告诉我一声就得。当时我非常年轻,也没有阳痿病。
我从小就认识李先生。李先生从我小时候就在搞西夏文,而且我们两家过去是邻居,也记不清我第一次见到西夏文时是几岁。所以我后来见到西夏文,也不觉得有什么古怪。那种东西看上去很像汉字,笔画多得叫人头晕,很像是疯子写的,据说除了李先生,世界上没人能够读懂。因为只有李先生能读懂西夏文,所以他有大学问。但是他依然穷困潦倒,这是因为只有他能读懂西夏文,所以他的学问就得不到承认。假如别人能先读懂了西夏文,或许他的学问就有人承认,但是那又不是他的学问了。除此之外,还因为当时在“文化革命”中,北京城八百年的城墙被人拆掉了都没人说个不字,还有谁关心西夏文。除了西夏文,我还记得隔壁李先生那间房子老是烟雾弥漫,李先生的脸色老是那么黄,好像得了黄疸病;李先生对我很凶。后来我才知道,过去李先生最烦有人不打招呼就到他那里串门。但是后来我专到他那里去串门,因为他反正没胆子把我吃了。所谓串门,就是没有事,跑到别人家里去坐着。但是那一天我去找李先生可不是没事,而是要告诉他,有人请他翻译些文件。没有稿酬,只有千字三毛钱的烟茶钱。李先生听了很高兴,马上就跑去了。在大天白日下骑着他那辆古怪车子,身穿着一件再生毛料的古怪衣服(那种料子和麻袋片是一样的),闯到那个原来是大学,当时叫留守处,而且人人认识他的地方去,并不是李先生的一贯作风。这是因为那个院子里现在没有几个人。人多时,李先生总是天黑后才去的。这说明李先生虽然穷困潦倒,依然很面嫩。
我和李先生熟,除了过去在一个院里住过几年邻居,还因为不住邻居后,他还是老找我给他修收音机。李先生有一台里加牌的收音机,那收音机有小柜那么大,非常气派。这说明李先生并不是一贯穷困潦倒,还有过能买起收音机的时候。这家伙晚上睡不着觉,想听听俄语台,但是听不清,就鼓捣他的收音机,胡乱修改线路。直到那收音机惨叫几声再也不响了,他才安心睡觉。李先生会那一点三脚猫的无线电,正好能把响的收音机修到不响。我去给他修收音机时,先要把他自己加上的放大全拆掉。同时还告诫他说,别只想着加放大,这不解决问题。还要想到有干扰:国家留着你的收音机,可不是让你听那些乌七八糟的东西。李先生说,是,是。我不听那些乌七八糟的东西,我只听外语。但是国家不相信李先生只听外语,还以为他要听乌七八糟的东西,所以还是要给他干扰掉。李先生又不相信收音机听不清是因为有干扰,老以为是灵敏度不够,就老往里面加放大。他的手还没有我的脚灵巧,一加就把收音机加死了。然后他就找我来修。这件事循环往复,周而复始。直到邻居揭发李先生偷听敌台,居委会把他的收音机拿走了方才告结束。我去找他那回,他刚刚失去了收音机。李先生见了我就说这件事,同时愁眉苦脸。我就安慰他说:这也好,省得再找我修。我这样安慰过以后,他好像更伤心了。这件事证明了一个道理:萨特先生说得很对,他人是你的地狱。我是李先生的地狱。李先生也是我的地狱:被他捅过的收音机就像个马蜂窝,焊过的线头就像些包锡纸的巧克力球。修完了他那个鬼东西,感觉就像吃了忆苦饭,不但肠胃难受,而且拉不出屎。
李先生走了以后,我在他那间小房子里还呆了好久,把他那一罐狗屁烟倒到了桌面上,把里面的死苍蝇、扫帚苗都挑了出来,然后又装了回去。我看了半天李先生的西夏文抄本,挨个数那些字的笔画。后来我从上面撕了一条纸,卷了一根烟,就替他锁上门,回家来了。时隔二十年,我还清清楚楚地记得,我干了哪些事。但是我再也想不起来自己为什么要干那些事。大概这就叫手贱。
-----
### 三
奶子府六号院里有一棵大槐树,盛夏时节,树上会掉下来数不清的槐蚕,弄得地上好像长满了会爬的草。那些草还会往家里爬。我对那儿的印象很好,因为那里一向邻近大内,街道上都立着禁止鸣笛的牌子,傍晚时分院里静极了。傍晚时分往往是阴天,云彩的颜色有点黄。黑暗凝集在古旧的窗棂上,附着在暗色的树皮上。在院里看天空,就像在水塘的水底,隔着厚厚的透明的水看水面。那院里还有一个个子高高的姑娘,傍晚时分穿一件床单布的大裤衩,赤着脚走来走去。我的视线久久地附着在她身上。朦胧中她是白蒙蒙的一团。久而久之,我的目光就和她的肌肤混为一体了。那是一种冷飕飕的感觉,好像早上的水汽一样。这种感觉真好,可惜过去了。
我们医院旁边有个农贸市场,我常到那儿去买水果。后来那儿的人都认识我了。有人想和我拉近乎,就说,老师傅,你有五十了吧。我听了大怒,强忍着没发作。另一个说,老师傅,你的孩子都上小学了吧?气得我几乎动手打他。照他们看来,人要是活到了五十,又有了上小学的孩子,就算有成就。像我这样没到五十,还没结婚就阳瘘的就是nothing了。虽然他们是想要拍我马屁,我也不高兴。从那天以后,我再也不去那儿买桃了。从这件事你就可以想象当年别人对李先生的态度,和李先生对别人的态度。当年李先生虽然没有阳痿,但也没老婆。除此之外,他还没工作。大家当然以为他是矮人一等的家伙。平心而论,奶子府六号的街坊对李先生挺好的,又给他介绍工作,又给他介绍老婆。虽然那些工作不过是临时在副食店卖卖咸鱼,那些老婆都是残疾人,但是别人怎能知道李先生读通了西夏文,并且自视甚高呢。大家都觉得给他找个瘸子就是帮了他的大忙了。就是揭发他偷听敌台,也是怕他给街坊上招事,并无恶意。但是李先生对奶子府六号和街坊都深恶痛绝,老想搬出去。大崔找他翻译东西,他就借机搬到我们院,住进了我屋里。这件事当然有冠冕堂皇的理由(要翻的是一些内部文件,带来带去的不好,等等),那间房子又是大崔借给我的;他能借给我,当然也能借给别人,但我仍然很不高兴。这件事证明我一无所有,连睡觉的地方都是借来的。
我现在依然一无所有,连睡觉的地方也不是我自己的。除此之外,又多了一个阳痿。现在马大夫要用心理疗法来给我治阳痿。所谓心理疗法,就是他反反复复对我说:兄弟,你想开点吧。人活在世界上,就是这一点享受哇。这话不错,但是不是我想不开,是它想不开。不知它听见了没有。
现在该讲讲我们院的情况。我们院是一片房子,除了一些老房子,都是不加掩饰的四方体,甭提有多难看。将来的人看到了这些房子,一定以为我们长着方鼻子,方眼睛。当时院里没人,长满了荒草。还有很多野猫,到了春天就嗷嗷叫。我和李先生,大嫂和大崔住在大门口一排平房里,就算看住了大门,可是别人从后面进来,把楼房的门窗都拆走了。我对那里的印象原来也很好,李先生来了才坏起来。李先生白天翻译文件,晚上也不睡觉,接着搞西夏文。我对此很不满,就坐在桌子对面,对西夏文发表自己的意见。我认为谁使用这种有这么多笔画的文字,就一定是笨蛋。这些笨蛋死了好几百年之后,还有人想把这种文字读出来,一定也是笨蛋。李先生听了一声不吭。然后我又喝李先生的茶。李先生不知从哪里搞来了一些茶砖,都发了霉,喝过以后嗓子疼。我又告诉他,这茶的味道像墨水,真叫难喝。他听了以后还是一声不吭。后来我问他:你说你已经把西夏文读通了,还看这玩意干吗?他说,不看这玩意,还有什么可看的吗?
和李先生同屋时,他告诉我说,他读通的不止是西夏文,还有契丹文、女真文;总之,他读通了一切看上去像是汉字又没人认识的古文字。这些文字有好多苏联人、法国人和中国人想读都没读懂。他认为这件事证明了他比大家都聪明,我认为这件事证明了他有毛病。对于这一点我还给出了证明如下:李先生干出了一件大家都干不出的事,这一点没有问题。这证明了他和大家不一样,这一点也没有问题。但是这种不一样是聪明还是有毛病,还没有定论。既然如此,就应该少数服从多数。大家说你聪明,你就是聪明,大家觉得你有毛病,你就是有毛病。很显然,认为他有毛病的人将是大多数。李先生听了为之语塞。后来他就不和我说什么了。
现在别人也都以为我有毛病,所以很浅显的道理,都要告诉我。但是我也不觉得讨厌,因为我可以举一反三。比方说,马大夫以为我直不起来,是不知道人生在世就是这么一点享受,好比每年冬天只能买三十斤好的冬贮大白菜。他和老婆干事的心境与排队买大白菜时的心境相同。其实我知道一年冬天只有三十斤大白菜,但是我还是直不起来。因为我不是兔子,不那么爱吃大白菜。
李先生住到我房子里以后,大崔就经常来了。他和李先生聊聊天,聊来聊去,总是当年在学校里的那点事,以致我到现在还能记得那些事:他们的学校叫做哈尔滨外专,四八年就成立了。五十年代初期是专门培养高级外语人才的,授课的全是专家,还雇了些老白俄来擦地板。在学校里不准讲中国话,讲一句做二十个俯卧撑。除此之外,还不准吃中国饭,只准吃红菜汤,刚来的吃不习惯,肠胃作起怪来,放起屁来抑扬顿挫,每个屁都在一分钟以上。可惜他们也就美了那么一阵子。后来中苏交恶,这帮家伙全坐了冷板凳。其实李先生还会德文、法文、英文等等,但是咱们当时和那些国家也交恶。李先生说,假如加把油的话,他还能学会柬埔寨文,但是这种文字里有美国炸弹的味道,学会了也不是好饭碗。看起来他们两个老同学很是亲热,其实不是的。李先生背地里告诉我说,大崔真讨厌,尽耽误他的时间。大崔也说过,李先生真讨厌。有一阵子我不明白大崔在搞什么鬼:既然不喜欢李先生,还把他招来干吗?后来才想明白了,这不关大崔的事。招李先生来的,另有其人。现在我很少到我们院去,因为它不再是“我们院”了。现在那里有好多的人,总数在两万六千以上。而在二十年前,偌大的院子里只住了我们四个人,简直就像一座鬼城。我记得那片荒草离离的院子,草棵下面的石子儿和碎玻璃。马路上有好多风吹下来的枯枝,所有房子的门窗都用木条钉死了。住在附近的人有时溜进来发点洋财,倒也不敢偷什么东西。见到哪个厕所没钉死,就进去把三合板都拆走。我常常一个人在院子里漫步,看着风吹来的砂子和碎石若有所思。后来我就在闲逛中碰上了李先生给大崔戴绿帽子。总的来说,这件事很难看。就和在草地上看见两条蛇绕在一起一样。在这种情况下我总是把两条蛇都打死。
-----
### 四
我现在经常想起李先生,想起我们俩一起逛破烂市,买几毛钱一公斤的废纸边,五分钱一大把的锈笔尖。北京过去有好多破烂市,全称叫做废旧物资门市部,现在没有了。我到那种地方去买便宜电子管和废电容,李先生到那种地方去买散打的过期墨水。墨水这种东西也会腐败,坏了以后比大粪臭好几倍。和李先生住过一个屋以后,北京最脏的公共厕所我也进得去了。
那一年李先生在我们院住了三个月,后来他又回奶子府去住了。其实他是被撵出去的,而且是我和大崔合力才把他撵走。这件事的详情不是我不肯讲,是我现在怎么也想不起来了。也可能推了他,也可能搡了他,甚至打了他,这些都记不得。只记得当时很有正义感。我这一辈子只有那一回有正义感,以后再也找不到那种感觉了。记得雨果说过,凡不可挽回的东西,都不属于人,属于上帝。所以正义感也不属于我,属于上帝。后来街道上把李先生的收音机还给他,等收音机坏了,他还来找我修。混到了那步田地,李先生不大要脸面。
雨果先生还说过:凡人分内所没有的东西都属于上帝。所以像我这样的阳痿病人想娶小孙这样的漂亮姑娘为妻就是冒犯了上帝。上帝他老人家够狠的,把我们管得这么紧。
我和前妻离婚时,听到了一种议论:阳痿根本就是一种思想病。换言之,上面的思想端正了,下面也会端正。人家还说,我一定是面对自己的老婆时想入非非,所以才阳痿。这话不是一点道理都没有的,当年面对我前妻的大裤衩时,我是有过一点古怪想法。如前所述,我自以为有写小说的才能,这种自信不是空穴来风。我的想象力极为丰富,以致我怎么也不敢相信自己的脑袋只有五号钢种锅那么大。在我该对我前妻行周公大礼时,脑子里忽然浮现出二十年前那个冬日骑车去找李先生时所见的情形:那个新婚少妇手提痰桶向我走来,把屎倒在铁箅子上,那个少妇的模样不知为什么,活脱脱就是我前妻。这件事对我penis的物理性质大概是有一定的影响,但是要说那就是我阳痿的主因还难定论,因为当时我还在害胃疼。我在山西吃过好几年的土豆和连皮碾的谷子面,那些都是标准的健康食品。但是要是纯吃它们就很伤胃了。结婚那天,我虽然出席了好几个婚宴,但是什么都没吃到,所以到了晚上胃就疼得翻江倒海。在这种情况下,就该和我前妻取个商量。但是她早早地脱了大半衣服上了床,闭着眼睛直挺挺地躺着,脸色潮红,一句话都不肯讲。看到这种情形,我只好关了灯,在她身边躺下睡了。然后的事情我已经说过,她哭起来了。从此后,我的生活就进入了软的时期。
后来我想起当年的事,觉得我前妻不会因为性欲没得到满足就哭了起来。她只是觉得在新婚之夜被弄破处女膜,是她分内当有的东西。只要是分内该有的东西还没拿到,就会引起一种急不可耐的情绪。至于弄破了疼不疼,她就不管了。
李先生有一套二十卷本的汤恩比的历史哲学,我叫他教我英文,他就拿那书来教我,教得我七颠八倒,认识好几万单词,却一点语法都不会。我怀疑他对我破了他的好事怀恨在心,用这个法子来害我。汤先生说:人类的历史分作阴阳两个时期,阴时期的人类散居在世界各地,过着吃了就睡,睡足了再吃,浑浑噩遯的生活。后来人类又到一些河谷平原聚群居住,有了文明,一切烦恼就由此而起。与此相似,我的生活也有硬软两个时期,浑如阴阳两界。软了以后,回想起过去是如此的硬,简直不敢相信我也会有软的时候。
我性情冷漠,不善与人交往,一辈子不认识几个人。也许就因为这个原因,我很怀念那位搞西夏文的李先生。现在他也许还活着,也许死掉了,这都无关紧要。紧要的是我现在终于知道了他为什么撇开了好好的工作不要,去搞西夏文。这还是因为我已经软掉了。假如还在硬着的话,就只能想自己是多么的硬,想不到这类事情。在山西时听过一种地方戏,它发出一种极凄厉的,酷似挨刀断气的声音。听时阴囊兜紧,全部神经都在极大的痛苦中。可是大家都走十几里山路去听它。还有我那位前妻,用不着多么达练人情就能看出,将来她准是个母夜叉。可我过去为之颠三倒四。这种感觉就叫做硬。硬的时候我们急着去要自己分内的那点东西,丝毫不想它是不是自己想要的。等到有了一点自己想要的东西,不管它是署了自己名字的小说,还是西夏文,就已经活到了另一界了。
-----
## 第三章
-----
### 一
我和小孙恋爱了一阵,就向领导上交了请求结婚的报告。从那时开始,大家就不再善意地对待我们。首先是登记结婚的证明老也开不来,总是说:这件事你是不是再考虑一下?我们再讨论讨论。实在逼急了,就说:介绍信找不到了,公章找不到了。其次就是开始听到各种闲话。其实应该说,人们开始不再善意地对待小孙。这件事完全是她在办。我说“我们”,不过是表示自己没有完全置身事外。虽然我呆在地下室里不出来,但我已经在请求结婚的报告上签了名,并且认真听取了小孙的各种抱怨,就算尽到了责任,别的事我就帮不了忙了。我可以不参加政治学习,不去开会,不去看上级组织的乏味电影,可以尽情胡说八道;这些好处当然是有代价的。这个代价就是我说话别人可以不理会。因此我被叫做小神经。
人家规劝小孙说,你千万不要和王二结婚。他这个人有点说不清。办公室的老太太还对别人说,他们俩的事拖一百年也不怕,反正不会造成人工流产。别人都说,不知我们结婚是要干什么。并且老有人把她叫到僻静处说:孙大夫,你真的要嫁他?你可真把自己看得一钱不值了。小孙说,她感到非常的不好意思,只好摆出一副瘦驴屙硬屎的架式说:我就是爱他嘛。但是晚上却对我说:我爱你个狗屁!除此之外,几乎每个人都要给她介绍对象,包括刚刚从护校毕业的不满二十岁的小护士。因为热心的人太多了,显得她简直像个花痴。假如不马上给她找个男人的话,她就要去和公牛睡觉,生下一个米诺牛来。对于这件事,她没有精神准备,感到惊慌失措。原先她以为结婚像在学校打报告申请实验动物一样轻松,写个报告交上去,然后拎着兔子耳朵到实验室,既可以把细菌打到它耳朵里,也可以把它炖了吃。现在我这九十公斤的公兔子就坐在对面,人家却不给她,可把她气坏了。
小孙告诉我这些事时,都是在晚上。我的小屋里黑洞洞的,所有的灯都没有开,只靠一台示波器的绿光照亮。我不喜欢光亮。她在屋里走来走去,双手插在上衣口袋里。走了几趟以后,忽然对准我的耳朵大叫一声:都怪你!我耸耸肩说:阳痿还没治好呢,你别先把我耳朵治聋了。你怪我什么?她想了想说:算了,谁也不怪。不过这件事实在是真他妈的。而且她对我也起了疑心(这都是因为别人说我复杂),老是问:王二,你这人可靠吗?你能肯定自己没有偷过东西,或者扒过女厕所窗户吗?
关于结婚的事,有一点开头我不明白。虽然我有阳痿病,但我还是个男人,起码户口本上是这样写的。群众怎样议论是另一回事,领导上决定问题,总要有个说头吧。这个谜后来马大夫给揭开了。他说他是康复科的主任,可以参加院务会,会上听见大家说,我有二十年工龄,十年院龄,加上中级职称;小孙又是本院的人。我们俩一结了婚,就是本院的双职工夫妇。其结果是婚后必须分给我们房子,这不是太便宜我们了?房子必须分给真正要结婚的人,而真正要结婚的人就是不管给不给房子都会结婚。他对我说这些话时,显出一副自己人的样子。但是我也不是傻瓜,一听就知道是上面有人叫他来传话。别看平日称兄道弟,但他不是自己人。所以我对马大夫说话用上了对领导说话的口吻:既然我们是为房子结婚,就别分我们房子了。他说,那是不可能的事。够了条件怎能不分哪。于是我就说,那就分我们房子吧。他又说,这也不成。你们想要房子就有房子,岂不是太便宜你了。想要房子的不能让他得房子,没想要的倒会得房子,这才符合辩证法。假如批了你们结婚,领导上会落入违反了辩证法的困境。惟一的办法就是不批准。我对马大夫说,其实我们真的不想要房子。您可以把我们俩都绑起来上电刑。假如我们在严刑拷打下说了是要房子,就别批准我们结婚。他说你又来了。到精神科去看看吧。说完就走了。
有关分房子的事,我还有一点补充。我们医院只要分一套房子,全院都要搬家。这是因为院长分到了一间四室一厅搬进去,剩下三室的给科主任。科主任搬进去,两间一套让给主治医师;余类推,一直推到看门的老大爷。因此很多人的箱笼捆上以后就不打开了,一心一意等待搬家和再搬家,十冬腊月宁可穿着毛衣硬抗,也不开箱子找大衣;所以我们医院结了婚的少妇比没结婚的姑娘显得漂亮,冬天在室外只穿一件毛衣,一个个是那么苗条可爱。但是现在小神经和小孙要从主治医师的层次插进去,打乱搬家的路线,就激起了公愤。
那天下了班之后小孙到我这里来,眼睛都哭红了。原来领导也找她谈了,让她端正态度。她说道:为房子结婚,我是这样的人吗?王二,我不想和你结婚了。但是我还是要给你治阳痿病。我对小孙的想法一点也不理解。为房子结婚不是挺光明正大的吗?总比为性交结婚好听多了。但是我没有说这话,只是说,那就算了。你也别给我治什么病了。回去睡你的觉吧。她说,不行,听你的说法,我倒像个卑鄙小人了。我要陪你坐会儿。我说,你爱坐就坐吧。这时候我想起我表哥说过的话:人活在世界上,假如你想要什么,就没有什么。这就叫辩证法。所以假如你真想要什么的话,就别去想它。他说,他当年考不上大学,就是因为太想考上大学了。假如早懂了辩证法,就不会遇到这种不幸。我在大学里虽然学过辩证法,回回都是补考才及格的。而且那些任课教师总是这样讲:让你及格,我是昧了良心的。
-----
### 二
晚上我一个人呆着时,总喜欢头戴立体声耳机。这样我虽然一个人呆在角落里,却与外面的世界取上了联系,可以听见各种声音,人家却听不见我;好像我从地下室往外看,看到了各种各样的人的脚,他们却看不见我一样。现在屋里有一个人,再也不能这样干了。为此我宁愿终身阳痿下去,也不愿有个人在我眼前转。这是因为她在我面前走动的样子,就像养貂场到了喂食的时间,铁笼子里那些貂一样。从人的角度来看,貂除了打盹的时候,都是神经病发作。假如人的行为像一条貂,那就更像神经病了。所幸她也有走累了的时候,那时候她也要坐下来歇歇腿。
那天晚上我和小孙并排坐在一张床上,头上戴着立体声耳机。我开始反省我们俩之间的事,我知道,我们之间的关系就要完了,以后她也不会来看我,不会给我打饭,也不会趴在对面的木板床上算账了。这让我感到伤心,我真的很想要她,想把她留在我身边。这也许是因为,我以为她是一个自己人吧。现在自己人是越来越少了。由于有了这样的想法,就违背了辩证法。
当年李先生说,自从创世之初,世界上就有两种人存在,一种是“我们”,还有一种是“他们”。现在世界上仍然有这两种人,将来还是要有这两种人。这真是至理名言。这两种人活在同一个世界上,就是为了互相带来灾难。过去我老觉得小孙是“我们”,现在我才发现,她最起码不是个坚定的“我们”,甚至将来变成“他们”也不一定。但是我不想说惹她生气的话,就闭上眼睛听广播。广播里正在劝女孩子们不要戴无纺布衬里的尼龙乳罩,因为无纺布的衬里会渗到她们乳房的导管里去,将来生了孩子没有奶。以前我不知道女孩子的乳房是像锅炉一样的设备,里面有很多管子,并且容易堵塞。于是我问小孙:你戴什么样的乳罩?她回答说:尼龙的,无纺布衬里,将来没有奶。这不要紧,反正牛奶很便宜。原来她和我一样,正在听广播,并且听着一个台。后来我又有口无心地问道:你穿什么样的裤衩?她又说道:尼龙绸的。想看看吗?我说不了。后来她猛地跳了起来,一把从我耳朵上摘掉了耳机,对我大叫道:王二,你的毛病我找到了。你是淫物狂!这叫我很不高兴。不把事情问明白了就大呼小叫,简直是讨厌!
有关裤衩的事是这样的:以前我结过一次婚,新婚之夜,我一看见我前妻那条皱皱巴巴的大裤衩,就不行了。这件事本不是没有挽回的余地,但是我前妻却大哭起来。引得丈母娘、大姨子都跑来了,问我:你什么意思吧?我妹妹可是个黄花闺女。叫她们这么一吵,我当然是越来越不行。最后终于离了婚。离婚之前我前妻还在医院哭闹了好几场,让大家都知道我不行,搞得我灰头土脸。但是对此我很能理解。她必须让大家都知道是我不行,而不是她有什么不好。小孙听了大笑说:我不穿大裤衩。咱们来试试吧。我苦笑一下说:还是别试为好。这件事现在对我已经很严重了。
晚上我翻书时,耳朵上老架着耳机。耳机里有很多人说话,多数是女的。这些声音很不一样。有的声音很干脆,很紧凑。顺着那声音看去,可以看到一张小巧、湿润的嘴,紧凑高耸的胸膛和平坦的肚子。因为是和这些紧凑的东西共振,所以声音也紧凑。再往下看,就看到一条黑色尼龙绸的内裤。这也是一件紧凑的东西。但是顺着某些故作甜蜜的声音看去,就看到了肥大的鼻甲,身上的零件也松。再往下看,就是一条床单布的大裤衩,这东西也松。共振起来也就松松垮垮。除了这些区别,还有一些主观上的东西。有些广播员尽力让声音紧凑,所以说话有一点艰涩。另一些人讲话松松垮垮,一张嘴就是一大串,全是傻话。声音里传来的性有两种,一种讨人喜欢,还有一种叫人讨厌。以前我不懂这一点,所以结了一次婚。结果是使我只能欣赏广播里的性了。
-----
### 三
后来我再想起小孙决定不和我结婚的事,也能够理解了。因为自从她和我表演了恋爱以后,软和硬这两个字就不再是物理名词,而归她专有了。工会分柿子,别人就这样对她说:小孙,来一点吧。软的。或者说,这个你准不喜欢,太硬。其实我们都决定要吹了,但是小孙还是老往我这里跑。别人也看不出我们要吹,还是说那些没咸淡的话。我告诉她说,讲这些话的都是些工友,是很朴实的人,别和人家当真,但她还是耿耿于怀。终于有一天,她在食堂里拿豆腐泼了大师傅一脸,然后哭着跑到地下室来,说道:快跟我走,什么也别问。呆会我叫你揍谁,你就揍谁。我跟着她跑上去,到了食堂里,见到一大群人。保卫科的人全来了,这也吓不倒谁。我可以直取目标,扭住他的领子。不管付多大的代价,都要把他的脸打烂。问题就在于找不到目标。过了一会,院长书记都来了,叫我们到办公室去解决问题。原来肇事的大师傅觉得在哪里都不能保证安全,已经跑到党委办公室去了。听说他事后对别人说:我真是晕了头啦,怎么就忘了地下室还有一个小神经!
那天的事“我们”大获全胜,给“他们”以沉重打击。大师傅被泼了一脸油汤,还要写检查。其实他不过说了一句:孙大夫,来一点豆腐吧。软的。这些话并不过分,不过是拾别人的牙慧,没有一点自己的发明。但是小孙已经火透了,就如一只骆驼,驮了好几百公斤,最后因为再加一根草的分量倒下了。
这样处理领导上并非情愿,但是该大师傅很怕我,主动提出要写检查(后来他说,我要是被小神经打了,那还不是白打)。所以院长决定说我们几句:你们两个同志也真是的。都受过高等教育,是知识分子嘛,怎么也干这种哗众取宠的事情?他这些屁话还没说完,我的目光就如两道冷电在他脸上扫了一下,把他后半截的话扫回去了。书记来打圆场说:其实你们俩要结婚的事并不是没商量的,你们不要做不理智的事情。我就叫起来:谁说我们要结婚?他们听了都说,不结婚就对了。其实我们不是不准你们结婚,一套房子也能给得起。我们只不过是希望你们多考虑。小孙马上又叫道:谁说我们不要结婚?院长就说:今天就谈到这里,你们回去冷静一下吧。
出来以后我问小孙:咱们不是说好了不结婚的吗?何不借此机会当众宣布一下?她说,咱们俩是说好了,但是没必要告诉他们。他妈的,结婚是咱俩的事,别人管得着吗?回到地下室里,想起没吃午饭,豆腐也泼了,赶紧在电炉上下挂面。吃完了,坐在光板床上晒太阳。吵了这么一架之后,吃饱了再一晒,就困了。小孙说,王二,你的胸围怎么这么大?我告诉她说是拉拉力器拉的。她说以后她也要拉健身器了。然后她打个呵欠说,太困了。我枕着它睡一觉,你没意见吧。说完她就枕着我的胸口睡着了。
那天下午小孙枕着我胸口睡觉的事是这样结束的:她一觉睡到了快天黑,双手还圈住了我的腰,使我一动也不能动。我只剩了一只左手能动,就用左手掏出烟来吸。还有一件事使我感觉不便:她的头发又轻又软,经常跑到我嘴里来,我又要不停地把它吹开。所幸后来她终于醒了,爬起来伸了个懒腰说,真舒服呀!好多天没睡好觉了。做了好多的梦,全和工地有关系。每个梦里都有打桩机。醒来才知道,是你的心在跳。你这里太好了。我要搬下来住。我听了没言声,因为她不是个自己人。我不欢迎她来住。过了一秒钟她又说,我干吗不搬下来住呢?这就去搬!
后来她真去把铺盖搬下来了,这件事连我都觉得像发疯。但是她说自己一点也没有疯,不过是想气气“他们”。于是她占领了对面的木板床,还带来了无数的毛巾,半干的小衣服,挂得满天都是。现在我在屋里走动,就要在三角裤底下经过了,这肯定要给我带来晦气。但是我一声也没吭。她要怎么干就怎么干吧,谈了小半年的恋爱,也该有这点交情。我不能像“他们”那样小气。
晚上睡觉前,我们又聊了一会儿天,谈到今天和大师傅打架。她说,从早上起就开始窝火了。早上她到病房时,看见有几个护士在交头接耳,传递某东西。她就走过去问:发什么好东西哪,不给我?那些护士一起笑得打跌道:东西倒是好东西,但和你没关系,你用不着。假如世界上没有王二其人,她马上就能想到,这是已婚的护士们在分发避孕工具。那样她就会红着脸走开,或者说一句:臭美什么?恶心死了。但是世界上有我这个人,所以老有人在她背后窃窃私语,她就气昏了头,劈手就抢(这孩子手快极了,她说她在大学里打过垒球,是接球手),结果抢到手一大把避孕套。那些护士就说:抢什么?告诉你了,你用不着。小孙一瞪眼说:你怎么知道我用不着?再给我一把,要大号的!
睡觉以前小孙说了一声:王二,往这边看。我抬头一看,发现她只穿了胸罩和裤衩站在地下,皮肤很白,胳臂腿很细,胸罩和裤衩都是黑色尼龙绸的。等我看完了以后,她就钻进了被窝,就着台灯看一本书。但是我还不能睡。我还要拉一百下拉力器,做一百个俯卧撑。这是因为我已经很胖了,如果不锻炼,很可能会死于高血压和心脏病。小孙说我练得不对,这样只会越练越肥。但是我没理她。在这些事情上,我有我的一定之规。她就这样在我房间里住下了。
-----
### 四
第二天一早我就起来拉拉力器,把弹簧撞得当当响。小孙在床上迷迷糊糊地说:你别这么抽风好不好,让别人也睡个懒觉。但是我不理她。谁让你到我这里来住的?于是她就揉起眼睛来,那架势活像是猫洗脸;然后坐起来,在被窝里穿上衬衣,又伸出腿来,穿上袜子,就光着腿下地,拿了脸盆去打水。出了门又鬼叫一声被吓了回来,大概是看到了门口那个标本缸,觉得陌生吧。就这么折腾了一早上,我始终没有理她。后来她对我说:王二,你好像不高兴了。我说我总是这样的。她又说,不结婚的事你别往心里去。我是说着玩的。我始终是意志坚定地要嫁给你。我就说,我可真的有阳痿病。她又说,有关治阳痿的那些话你也别往心里去。我闹着玩哪。我说,那我就不知道你要嫁我干什么了。她说:我知道你好多事,要不要我一一讲出来?我把拉力器扔下说:不用了。咱们一块去吃早饭吧。这时我再不以为小孙是小娃娃,以为她是个自己人了。
我十七岁时参加过北京市的数学竞赛,在复赛里得了八十来分。这件事本来是有点好处的,可以保送上什么大学数学系,但是后来我什么也没落着。小孙知道这件事。我告诉她,少提这件事。我现在对数学没有兴趣,而且连数都快不识了。我现在干的事是翻译Story of O,已经译到第三遍了。有些地方拿不准,就托人找老外问。有一次问到一个法国lady头上,她向我赌咒说,从来也没听说过这本书。没听说过就没听说过吧,赌咒干吗?虽然如此,我还是字斟句酌地译着。我干这件事,是因为我相信作者有极大的才气,还因为这本书不可能出版。假如一本书有可能出版,那么“他们”也会去译,并且会争到打破头,因为有稿费。但是假如一本书既没有稿费,也不可能出版,我们不译谁译?小孙看了我的译稿,说道:王二,你要是去干翻译,准是一把好笔。但是你干吗要翻这种书?连我这妇科大夫看了都要脸红,人家能给你出吗?我说,我根本就不想出。她说,不想出译它干吗?我没接她的茬,因为这不是我们的逻辑。再说下去就是灾难。但我也不能说,你在给我带来灾难。这样说她就会给我带来更大的灾难。
好多年前,我也说过这样的言论。那是在李先生的小屋里,抽着李先生的狗屁烟,喝着李先生的狗尿茶(那是用过期发霉的茶砖泡的),我在给李先生修他的狗屎收音机,一边修一边数落他。他听了不好意思,就埋头去看西夏文了。就在这时候我说,李先生,你看这玩艺干吗?能当饭吃吗?他听了没理我。再问时就说,不能当饭吃。我又问:那你搞它干吗?有人请你搞它吗?他再没吭声,就和没听见一样。对无聊的问题是否充耳不闻,这是“我们”和“他们”的分水岭。我听了小孙的话一声不吭,去拉了二十下拉力器,然后坐下来继续翻书。自从她搬进来以后,我的胸部越来越像两块门板了。小孙看着我拉拉力器,伸出一只手指抹抹鼻子,然后问:我说了什么错话了吗?我答道:没有。她听了要哭了:王二,你有什么话说哇。这么闷着干吗?我就说:一本书,你看看它写得好不好,译得好不好就得了。害臊干什么。听了这话,她开始为自己的卑鄙言论惭愧了,就说:刚才那句话算我没讲好不好?拜托了。
小孙住到我房里半个多月了,我对她秋毫无犯。虽然如此,我对她的行止也略有所知。她像只猫一样,喜欢钻被窝。一进了被窝就要把乳罩摘下来,挂在床头上,于是它就挂在那里晃晃荡荡,活像一副大号太阳镜,这使我很受刺激。她对我解释说,这东西就像缰绳一样。然后就把被子拉到下巴上看书,灯光把她的侧影照亮,我看了也很受刺激。她睡着了灯也不关,而我是有一点亮也睡不着——以前并不是这样的,所以经常半夜里起来去关灯。夜里经过她的床头,听见她轻轻的鼻息,也很受刺激。对此我很不满,和她说过一次。她回答道:你也抽烟哪,我也没有抱怨你,不是吗?一边说,一边瞪着眼睛看我,看了这个样子,我也很受刺激。我要是说,这是我的房子,那就是卑鄙的言论。所以我只好拉了一条线,把她的开关装到了我这边。要是看到她睡了不关灯,我就给她关上。此后半夜里经常听见她自言自语地说:这王二真讨厌,这不是逼着我犯错误吗!然后她就下了床,到我这边开灯来了。感到了她赤裸胸膛上传来的热气,我也很受刺激,只好紧闭着眼睛。现在我不但阳痿,还多了个失眠的毛病。我经常打呵欠,说晚上睡不好。我一打呵欠,她也跟着打呵欠,并且说:你以为我就睡得好吗?这件事证明了一点,在我和小孙之间,性的感觉等价于咖啡因,它的作用就是让人睡不着觉。
我和小孙之间,有好多话还没说。我翻译Story of O,不是因为它能让妇科大夫脸红,而是因为它是好的。这世界上好的东西岂止是不多,简直是没有。所以不管它是什么,我都情愿为之牺牲性命。我不知这话她是不是爱听。但是我知道还有一句话她肯定爱听,就是我觉得她也是好的。但是我没办法告诉她。人家不问我,我就讲不出话。所以我是小神经。
-----
## 第四章
-----
### 一
春天来到时,我把Story of O又译了一遍,仔细校对了一遍,觉得译得很好,看不出任何败笔,就把它收了起来。干完了这件事,暂时又找不到别的事可干,就和小孙出去玩。在城里逛了一天,又在小饭馆里吃了晚饭,回来时天完全黑了。走进地下室的走廊里。她忽然窸窸窣窣地脱起衣服来,在一片黑暗中,我看到一个白色的模模糊糊的影子,然后又闻到了越来越浓烈的香水味。夜里四外的楼上都开着灯,所以眼前的走廊里有很多的白方块,就像是白漆涂成。小孙走到那些方块里去,马上就变得浑身闪闪发光,而对面的标本柜上就会出现一个白色的影子。她就这样从一个个方块里走过去,在标本柜上留下了一个又一个影子。与此同时,门口的地下留下了蝉蛻似的影子。那些衣服扔在地下杂乱无章,好像是肢解了的人形。我把那些衣服捡起来,小心翼翼地跟在她后面,避开窗口照进来的灯光。仿佛我一贯是这样做的似的。
在每一块灯光里,小孙都回过头来朝我笑笑。那些人造月光照得她浑身惨白。这种感觉好像在做梦一样。有时候她像是要伸个懒腰一样,把手向上伸起来,但又不完全是伸懒腰,因为她把身体弯向一侧,笑得很开心。我觉得这不像真的,所以不打算把它当真。但是我也感到一种冲动,要把鼻子伸入捧着的衣服里。那些衣服散发着香味,尚有余温。这种冲动就像狗想闻东西一样。
走到房间里以后,小孙就径直钻进了被窝,一会就睡着了。我把她的衣服放在床头,回到自己床上,好久都没睡着。第二天早上起来以后,她不提起这件事,好像这件事只是她一时冲动,或者昨天晚上她在梦游一样。我也不便提起这件事。权当它没有发生。我想女人都有一种冲动,要把自己脱光。
中午小孙告诉我说,她们科主任找她谈话,问她为什么要到我房间里住。小孙就反问一句道,你们为什么不准我们结婚?那老太太就期期艾艾答不上来。于是小孙提高了嗓子高叫起来:既然我们俩结婚是有其名,无其实,纯粹是为了骗房子;现在住到一起,又无名,又无实,又不要房子,你管这个干吗?这一嚷嚷闹得全科都能听到。那老太太着了慌,委委屈屈地说:孙大夫,我求求你,不要这样。我这个科主任也不是我自己乐意当的。那口气好像是自己受了强奸一样。干完了这件事,小孙觉得兴高采烈,得到了很大的满足,跑下来告诉我说,她又打了个大胜仗,并且要和我接吻以示庆祝。这孩子嘴里有薄荷味,大概是常嚼口香糖。她还把舌头伸到我嘴里来了。吻完以后,她打了个榧子道:French kiss!就扬长而去,回去上班了。但是我整个下午都不得安生,想着她裹在白色牛仔裤里的屁股,细长的两条腿和白色的护士鞋。除了屁股圆和腿长,她还有不少好处,包括给我打饭,和在熄灯以后陪我聊天,没的聊时就说和我阳痿有关的事。我们在一起,经常玩两种游戏,一种是情人的游戏,一种是医生和病人的游戏。到了前一种玩不下去时,就玩后一种。
晚上我和小孙聊天时,她从被窝里钻出来,盘腿坐在被子上。这时候她背倚着被灯光照亮的墙。我看她十分清楚,那一头齐耳短发,宽宽的肩膀,细细的腰,锁骨下的一颗黑痣,小巧精致的乳房。乳头像两颗嫩樱桃一样。我也坐起来,点上一根烟,她眼睛里就燃起了两颗火星。我们俩近在咫尺,但是仿佛隔了一个世纪,有了这种感觉,什么话都可以说了。她问我,我长得好看吗?我说:很好看。她就说:真的呀。
我和小孙谈这些事时,她的床在窗口射入的灯光中,我的床在阴影里,我们住的地方就像阴阳两界。这叫我想起了我自己的生活,它也有阴阳两界。在硬的时期我生活在灯光中,软了以后生活在阴影里。在这一点上,我很像过去的李先生。只是我不知道李先生是不是也阳痿过。
-----
### 二
当年我问李先生,西夏文有什么用,他只是一声也不吭。后来他告诉我说,他根本不想它有什么用,也不想读懂了以后怎么发表成果。他之所以要读这个东西,只是因为没有人能够读懂西夏文。假如他能读懂西夏文,他就会很快乐。读不懂最后死了也就算了。后来他的晚景很悲惨,因为他终于把西夏文读通了,到处找地方发表,人家却不理他。因为他不是在组织的人,是个社会闲散人员。还因为当时对西夏文已经有了五六种读法,都读得通。李先生说,他的读法最优越,但是没人理他。后来他就把自己保留多年的西夏文拓片、抄本等等都烧掉了,到处去找工作,终于当上了一个中学教员。再以后就得了老年痴呆症。我算了算,李先生那会儿也有五十六七,到了该得这种病的年龄了。最后一次我见到他,他已经不认识我了。
在我的硬时期,总有一个女人是我的意淫对象。有一年冬天我的意淫对象就是大嫂,她当时是个大个子中年女人,两条大辫子,在那个时期,她那个年龄的女人留辫子,可有卖俏的嫌疑。大嫂的脸也很长,下巴稍有点翘。当时我觉得下巴翘一点好,比较俏皮。脸白白净净的,有点浅麻子。一天到晚老在笑,好像缺心眼的样子。作为意淫的对象,她的屁股太大,腰也比较粗,这都是美中不足的地方。但是她老是笑嘻嘻的,弥补了体形的不足。我想象她做爱时也是这样笑嘻嘻,这会让我激动不已。
小孙说我简直是个下流坯。她希望我永远阳痿下去。但是说了些话之后,她又承认这样说不对。她说她是医生,我是病人,医生不该说病人是个下流坯。现在我们又玩起了那种医生和病人的游戏。她问我那个大嫂是谁,我告诉她说,是我们院大崔的太太。她又问,什么院,什么大崔。这个话说起来就长了。我从小住在一所大学里,因为我的父母都是该大学的教师。大崔和大嫂是比我父母小十几岁的另一对教师,是我们的老邻居。而且大崔和雄都认识李魅,働、職同学。这的背景我给小孙讲过:那一年冬天我去找李先生,其实就是奉了大嫂之命。大嫂和我说起这件事前,她正蹲在水管前面洗带鱼。而和我说这事时,她站了起来,身上穿了一件红色的套头毛衣,里面衬了一件蓝格子的浅色衬衣。我看到她脖子上有了几道皱纹,下巴也有一点两层的意思,但是大嫂还是蛮好看的。她对我说,让我去找李先生,让他来一下,有件事情可以照顾到他。我听着这些话,眼睛却在她胸口上看。在毛衣底下,她乳房的样子还是蛮好看,只是略微有点下垂了。就在这时候,她用洗鱼的手在我脸上抹了一把,说道:看什么看!快干你的事去。她这种满不在乎的口吻很使我turn on。
小孙对我说,她也是很不在乎的。这种口吻很难说是医生对病人的口吻。这种口吻使我很紧张。好在她马上换了一种口吻说,好啦,讲你的大嫂吧。那天她叫你去找李先生,到底是为了什么?
其实那件事没有什么重要性。大嫂让我告诉李先生,有一批材料要翻译。没有稿费,但是有一点烟茶费,每千字三毛钱。这就是说,你翻译了一千个字,可以抽一支好香烟,或者喝一杯好茶。就是不抽好烟,这笔钱也是太少了。但是李先生答应了干这个活儿。不但如此,他还以取稿子方便为名,搬到了我们院,住到了我的房间里。这件事我已经讲过了。现在我怀疑,每千字三毛钱,就是对李先生也太少了。当年李先生接下这个活,动机根本就不纯。
比这还糟糕的是,大嫂和李先生开始在我眼皮底下幽会起来。见了面就接吻,手还不老实,李先生那对前蹄老从大嫂的毛衣底下伸进去。我一看见这种景象,就咳嗽不止。大嫂听见了,就说:小王,你好不好回避一下?我们俩玩哪。当时我真是恨得牙根痒痒。大嫂孩子都老大的了,还这么不自觉,老要玩。而且李先生又老又难看,和他有什么好玩?要玩可以和我玩嘛。除了这些讨厌之处,李先生还得了不睡觉的毛病,白天和大嫂鬼混,翻译稿子,夜里还不忘看他的西夏文,二十四小时连轴转。像他那么大岁数的人怎么会有这么大的鬼精神?
有关大嫂的情形,还有不少可以补充的地方。据说她一贯搞破鞋,年轻时就因为和苏联专家有不正当的关系,被开除了团籍。结了婚以后,还是乱七八糟。大崔也管不了她,只能要求她对丈夫好,对孩子好,在饭菜里别下耗子药。李先生在院里时,大崔气得要命,要打她。她也是满不在乎:要打你就打,只别打脸,打哪儿都成。可以用擀面杖,不准用火钩子一动铁为凶!
大嫂对我说,她爱上李先生了,甘愿为他牺牲性命。我以为大崔要和她离婚了,但是大崔没提这个事。他告诉我说,大嫂经常会爱上谁,甘愿牺牲性命也有好几回了,但是她到现在还活着哪。
只要我肯耐心等待,没准大嫂也会爱上我,甘愿为我牺牲性命。但是我最缺的就是耐性。我绝对不会像李先生那样搞了二十多年西夏文,最后变成一个白痴。我搞什么事都是要么不干,要么立竿见影。
-----
### 三
我和小孙聊天,经常聊到一半,她就说:今天聊到这里吧。再晚睡明早上查房起不来了。然后就钻进被子睡着了。当个住院医师实在辛苦,有时候白班,有时候夜班,睡觉的时间老是不够。小孙的眼窝常常发青,她问过我是不是该涂眼晕。我说你想涂就涂好了,我没什么意见。她说岂有此理,涂眼晕就是涂给你看,你居然没了意见!看到别人忙忙叨叨,我经常感到惭愧,因为我老觉得可干的事情太少。翻完了Story of O,就再也找不到像这样的书了。但是我也不能像“他们”一样,去干没意思的事情。我们的人在这种时候,往往是去证明一个定理,或者发明一个体系。比方说,费尔马和爱因斯坦干的事就是这样。但是去证明一个定理往往会掉进陷阱里——有些定理可能没有证,遇上了一辈子都会陷在里面。而发明一个体系则谈何容易。想来想去,只有写小说比较有把握。但是自打认识了小孙,我就一个字也没写过。我写的小说,她每一页都要看,这就破坏了我的写作情绪。想想吧,昨天刚写出来的东西,今天就成了谈资,那是多么叫人厌烦。剩下只有一件事可干,那就是睡觉。
后来我又想把李先生和大嫂的事讲给小孙听,但是她不肯听,说道:我知道,大嫂爱上了李先生,这就结了吧?讲点别的吧。其实那个故事还长得很。用大嫂的话来说,一次爱情就像吃一个巧克力壳的冰棍。开头是巧克力,后来是奶油冰激凌。最后嘴里剩下一个干木棍。我所讲的李先生,连巧克力壳都没化呢。但是小孙不肯听。她说与其听你这些胡说八道,不如到外面去看死人。说完她真的从床上爬了起来,拿了手电,到走廊上去了。
我想给小孙讲的事,包括夜里李先生和大嫂在一块坐着念俄文诗,叽叽嘎嘎,听得人好不心烦。那时候我躺在灯影里,大棉被也挡不住那些卷舌音。这时候我只好想象自己是土耳其苏丹,带了队伍征讨俄罗斯草原。逮住了讲这种话的人,就让他们脑袋瓜子朝上,屁眼朝下,坐在削尖的木棍上。还有他们俩唱一个俄文歌,叫做嘎嘎林。一边嘎嘎,一边亲嘴,就像斗鸡一样;听了叫人头大如斗。后来他们听我咳得那么厉害,也有点不好意思,到外面去找地方了。但是那已经是开了春后的事。在此之前,他们一直是在我面前表演。开了春以后,我们院子里就开始闹猫,天一傍了黑,它们就开始哀号。我总怀疑里面也有李先生和大嫂的一份。据说母猫的那玩艺里长了倒刺,公猫插进去,就像插进了蝎子窝一样,疼得拼命嚷嚷。不知李先生和大嫂是不是这样。
我想给小孙讲的事还包括,那一年春天特别暖,晚上外面刮着黑色温暖的风,那种风就像一条深不可测的暖水河,叫人见到它就想脱光了衣服跳下去。用不着别人告诉我我就知道,这条河就是未实现的性欲。现在我心里就流着一条这样的暖水河。我要干的事不过是把这件事说一说。
小孙刚出去时,我很上火。因为我想让她听我讲话,但是她却跑了,把我扔在突然到来的寂寞里。我在地下室里住了十年,原本最能忍受寂寞,现在却受不了啦。
寂寞是我的选择,正如在地下室里离群索居是我的选择一样。在我看来,寂寞就是可以做一切事的自由,这是因为你做什么都没人知道,或者知道了也不理会。所以我能够翻译Story of O,李先生能够读西夏文。自从我割断了对女人的单恋,寂寞就真正归我所有。寂寞纯黑如夜,甜蜜如糖,醇如酒。
但是现在我却受不了寂寞了,因为它不再是过去那个样子,既不黑,也不甜了;而是惨烈如白昼。
我坐在床上发了一会愣,忽然想起小孙出去半天了,我该去看看她。一推门看见门口堆了一堆衣服,原来现在她身上什么都没穿。我赶紧回去拿了件大衣,顺着灯光赶了去,看见她正趴在标本柜上,高举手电,正往死人眼窝里看哪。我叫道:你疯了,要冻死呀!她却头也不回地说:你别管我。
后来我把她裹在大衣里,抱回屋里去,一直抱到了我床上。在黑暗里摸到了大衣前襟上是湿的,又赶紧去拿手巾给她擦脸,还用那种眼泪鼻涕一块擦的手法。然后我又给她揉揉脚。她带着哭声说:别的地方也得揉揉。于是我就往上揉去。从膝盖往上开始有鸡皮疙瘩,她浑身都冷透了。我赶紧哄她几句:算了,我不讲那些无聊故事了。
她说:和故事无关。你得爱我!
我说:我爱我爱。这时正好揉到腰上,她趁势就钻了过来抱住我。我拿大衣把她包上,放在腿上,好像个大包裹。我和小孙恋爱就是这样的。
-----
### 四
我和小孙之间带有性意味的接触是这样开始的:我的手从大衣前襟里伸进去,把她那两个小小的冷冰冰的乳房摸了一遍;与此同时,她的手也从衣襟里伸出来,揪住了我的耳朵,定好了位,来和我接吻。这两件事干好了,我又把大衣裹好,把她裹成个铺盖卷,放在膝盖上,又拿被子给她搭上腿。她在这个铺盖卷里宣布说,她现在很幸福,可以听我讲李先生和大嫂的事了。她还说,刚才不幸福,那件事就不能听,因为它属于幸福的范畴。我告诉她说,李先生现在是个大傻子,一天到晚只会摇头。大嫂是个老太太,头发掉了多一半。她说她不管这个。反正我最后也要变成老年痴呆,她也要变成老太太,这些都没什么,这些都能受得住。受不住的事是现在想要幸福却不能幸福。原来她的幸福就是被摸上一遍,再打成个铺盖卷,我既有手,又有打铺盖卷的材料,就可以给她幸福。这件事听了让人放心。我接着给她讲有关李先生的事,一讲到猫儿叫春,她就喵喵地叫唤。但是一点不像猫儿叫春,倒和一般的猫叫很像。小孙的行为通常就像一只猫,这里就包括了喜欢钻被窝,喜欢被包裹起来。但是猫就不会长雪白的小屁股和圆嘟嘟的乳房。
后来我又给他讲李先生的故事。我们院子有一片待拆的危楼,我常到那里去转转,看看有什么可拆的,结果就碰上了他们两个给大崔戴绿帽子。但是不是当面撞见,是在对面一座门窗都没了的破楼里。李先生他们呆的也是一座破楼,也没有门和窗子,他们所在的地方比我呆的地方矮半层。我看到的时候,大嫂的衣服都躺在地下了,摆得倒像个人似的。她只穿了皱巴巴的针织背心和床单布的大裤衩,跪在地下铺报纸。李先生的样子更难看,他脱得精赤条条,正在摆弄自己的那玩艺。那玩艺更难看,半直不直的样子,完全看不得。
但是小孙却说,这也没什么看不得,人家相爱嘛,什么东西都能拿出来摆布。像这类的话,她早就听说了。前些日子她申请结婚时,有一些护士大姐吓唬她,什么话都说出来了。比方说,女孩子结婚时都要过一关,就像猪要挨杀一样。要是快刀子热水,死了也就完了。就怕碰上了钝刀子,软刀子,想死都死不了,那才叫难受哪。还有人说,遇上丈夫不成,就得拿手给他弄,后来就像摆布了死人,洗八遍手也去不了那股恶心劲。小孙说,那些话一点也吓不倒她,因为她是大夫,死人都敢摆布。她又说,让我摆布一下你好吧?也许能把你的阳痿治好呢。我说:算了,不好意思。她说有什么不好意思的?我都让你摆布了。这时候我闭上眼睛,小孙那双小手就出现在眼前。指甲老是剪得那么短,并且洗得老是那么白。这双手拿东西有个特别的样子,比方说,转个旋钮,从来不去抓,而是用侧握的姿势。拿个东西也是很用力,很仔细的样子。把自己交到这样的手里,大可以放心。所以我想了半天终于下定了决心,说道:好吧。呆会儿可别埋怨我。她说,绝不会的。咱是这样的人吗?
我想,假如女人都像小孙那样好说话,世界上就不会有阳痿的人了。但是我前妻就不是这样,她心情激动,满脸通红,上了新床就躺倒了像个死人。全身绷得甚紧,以致我把自己想象成一支打井队,要在地层上钻眼。但是我做这种对比,丝毫没有挖苦前妻的意思。不管怎么说,是我阳痿嘛。小孙说,你别紧张,就当咱们俩在一块吃个桃。这是因为咱们好嘛。她还帮我脱衣服。然后我平躺下,她一只手握住了我的把把说:王二,家伙很大呀。我告诉她说,这是马大夫用铅锤拉的,原来没这么大。等到她伸手兜了我几下,那东西就膨胀起来。于是她又说:你这就叫阳痿呀!我说平常我是阳痿的,今天也不知怎么了。她说,你说这话就叫没良心了。什么叫“也不知怎么了”?这是因为我呀!
干这事时,小孙骑在我身上。也不知是为什么,开头很艰难。她一面从牙缝里吸凉气,一面说:刚才哭过,影响了情绪,里面很干。我觉得也是很干,就说,要不算了吧。她说:哪能算了。你不懂,老实躺着吧。于是我就闭上了双眼,一动也不动。后来就湿了,也进去了。从这时开始,我就不算是个阳痿病人。她向前俯下身子,我伸出手来抚摸她。我摸她的脸,那张白白净净的小脸就出现在我眼前。我甚至看到了她脸上有几粒雀斑,是我以前没看见的。像我这样的人,一点也不怕变成瞎子。睁着眼能看见的,闭上眼我都能看见。
后来我又把手放到她肩上,大拇指和食指触到了她的脖子。她脑后那些乌黑的发根就进入我脑海里了。我最爱雪白皮肤上那些乌青的发根了。今后我可以尽情地亲近那些乌青的发根,这是一个很美好的前景。我的手还可以伸到这个小小的身体的任何地方,但是我不想那么做,我就想停留在现在这个地方。
后来她把身体俯得更低了,这时我能感到她呼出的热气。等到事情完了,她在我身边躺下时说道:咱们俩同时达到了性高潮。这很重要。我问为什么重要?她说这样我也不必为你服务,你也不必为我服务,性生活谐调,好呗。我想,要是能搂着她睡一觉,那就更谐调了。谁知她是那样的不老实,睡了没有五分钟,就撩开被子坐起来,说道:你等我一会,就从我身上跨过去跑掉了。
-----
### 五
那天晚上,我和小孙做完爱,她跑到自己床上去了。过了一会儿,她拿了一面小镜子回来,坐在我身上,拿了手电,往自己胯下照。然后她又转过身来,跨住了我的上半身,用手电照着说:你看。我抬头一看,看见她的帝王将相和图谱上画的有点不同,是一副血肉模糊的惨状。我吃了一惊,说道:怎么了?她从我身上下来,钻进被窝说:你干的好事呗。
后来小孙把头贴在我胸口上,我都快睡着了,猛然想起她说过自己不是处女,禁不住说出了口:不对呀。她马上就扬起头来说:什么不对什么不对。口气相当凶。我说我想起一本小说。她又问什么小说什么小说。我说,法国中尉的女人,那里面有个莎拉,干过你这种事。她就说,你真混。我想这样说是揭了她的疮疤,就不说了。正要睡着,她又把我推醒,说道:告诉你,以前我干过一回,谁知他干得这么不彻底。我说噢。然后我又问:你告诉我这个干吗?她说:我告诉你这个,免得你太臭美!
但是那天晚上我们到此还没有睡。她又跳起来说,等我一会。然后她又往腿上套裤子。我问她要干什么,她说上楼去,找人看看。我说这么厉害?我陪你去。她愣了一会儿,然后说道:那太好了!你也不能一点良心都没有,是吧?
后来我陪她到了妇科病房,把值班大夫叫了起来。但是我没敢到放着妇科椅子的房间里去,呆在外面,听见她在里面说:王二那个家伙,一只手都握不住!真是疼死我了!等到出来以后,我问她:既然如此之疼,你怎么不告诉我呀?她又说,没那么疼,骗她们呢。这我就不懂了’好好的骗人家干吗。她说:笨蛋,申请结婚,要房子呀。有房子不要,便宜他们吗?
果然到了第二天中午,马大夫就来找我传话说,让我们到楼上去拿介绍信,领导上批准我们结婚了。他又对我谈了一阵辩证法,但是我没听。我知道领导上的打算:因为涉及到了房子,所以要控制已婚人数,原则上不批准结婚。但是假如不批准就要引起非法的性交,那就批准,因为两害相衡取其轻。马大夫还说,想调小孙去康复科搞科研,治疗阳痿。因为她居然能把我的顽症治好,显然是很有办法。后来小孙真的调过去了。
科研工作比门诊、病房都轻松多了。她到康复科去给阳痿病人的妻子办学习班,讲Masters和Johnson那套方法,只不过是用中国式的术语——什么握、捏、捺、按、抹、勾、挑、弹八法,听上去就非常难懂了。
后来我和小孙结了婚,住在两间一套的房子里。开头每天都干,后来每三天干一次,现在是每礼拜干一次,因为我毕竟是四十三岁了。小孙扬眉吐气,走到院子里都趾高气扬。因为她自以为无比性感,连阳痿病人见了她都不阳痿了。
从此以后,寂寞再不归我所有。这有好处,也有不好处。走进了寂寞里,你就变成了黑夜里的巨灵神,想干啥就干啥,效率非常之高。你可以夜以继日地干任何事,不怕别人打断,直到事情干成。但是寂寞中也有让人不能忍受的时刻,那就是想说话时没有人听。
现在我不再拥有寂寞了。我的事非常之多。我既然不阳痿,也就没有理由神经。没有了这两项毛病,就得上楼去开会。除此之外,我又成了中年业务骨干,什么仪器都得修了。除此之外,还得念念英文,准备到美国去接仪器。院长对我说,咱们医院懂电子的人太少了,你的病好了,就得多干点。还听说他对别人说:这套房子给得不亏!除此之外,我现在已经混迹于“他们”之中了,说话做事都得特别小心。除此之外,回家还要应付小孙。除了背熟她身上的全部性敏感带,还要背熟她感情上的敏感带,才能讨到她的欢心。我和小孙结婚的事就是这样的。现在我们还住在一套房子里,有时还干那件事,但是已经谈到过离婚的事。我们医院不批准我们离婚,并且说:早就识破了我们想再骗一套房子的狼子野心。所以我们还在一起住。但是小孙说:她不能白给我做饭,我得给她洗裤衩。
我现在和小孙做爱时,岂止是温存,简直是恭敬得很。我还告诉她说,我觉得她是好的,这世界上好的东西不多,我情愿为之牺牲性命。她说她很爱听这句话。但是她又说,我休想因为这句话逃掉洗裤衩的家务劳动。她还说:吾爱王二,吾更爱有人洗裤衩。这话是从柏拉图的名言“我爱苏格拉底,我更爱真理”变化而来,但就是柏拉图,也绝不肯给苏格拉底洗裤衩。
小孙告诉我说,她是个女权主义者。所以用不着我告诉她,她就知道自己是好的。当时她到地下室去找我,就是向我证明这个。她所以要和我离婚,倒不是不喜欢我,而是要和我分清楚一点。这个小家伙现在又给我上课,不过不是讲纪晓岚,而是讲薄伽丘(!),“从前有个教士告诉一个木匠说,他骑的母马,晚上就会变成女人和他睡觉……”一听就叫人脑仁疼。这是《十日谈》里那个装马尾巴的故事,不过又被她讲了个七颠八倒。
现在你买一本《十日谈》,里面就没有那个故事了。这肯定是因为那个故事比其他故事编得都好。小孙说,这个故事说明了“你们男人一个好东西都没有”,因为我们想的是让她们白天变成马去干活,晚上又变成女人陪我们睡觉。我就是这样倒霉,前半辈子阳痿,后半辈子又娶了女权主义者为妻。但是我没有再次阳痿的打算。我认命了。
-----
本篇最初发表于1994年第3期《青年作家》杂志。——编者
我没有自己的名字- 余华
========================
我没有自己的名字- [[余华]]
------
有一天,我挑着担子从桥上走过,听到他们在说翘鼻子许阿三死掉了,我就把担子放下,拿起挂在脖子上的毛巾擦脸上的汗水,我听着他们说翘鼻子许阿三是怎么死掉的,他们说是吃年糕噎死的。吃年糕噎死,我还是第一次听说,以前听说过有一个人吃花生噎死了。这时候他们向我叫起来:
“许阿三……翘鼻子阿三……”
我低着头“嗯”地答应了一声,他们哈哈笑了起来,问我:
“你手里拿着什么?”
我看了看手里的毛巾,说:
“毛巾。”
他们笑得哗啦哗啦的,又问我:
“你在脸上擦什么?”
我说:“擦汗水呀。”
我不知道他们为什么这样高兴,他们笑得就像风里的芦苇那样倒来倒去,有一个抱着肚子说:
“他——还——知道——汗水。”
另一个人靠着桥栏向我叫道:
“许阿三,翘鼻子阿三。”
他叫了两声,我也就答应了两声,他两只手捧着肚子问我:
“许阿三是谁?”
我看了看他,又看了看旁边那几个人,他们都张着嘴睁着眼睛,他们又问我:
“谁是翘鼻子许阿三?”
我就说:“许阿三死掉了。”
我看到他们睁着的眼睛一下子闭上了,他们的嘴张得更大了,笑得比打铁的声音还响,有两个人坐到了地上,他们哇哇笑了一会后,有一个人喘着气问我:
“许阿三死掉了……你是谁?”
我是谁?我看着他们嘿嘿地笑,我不知道该怎么说。我没有自己的名字,可是我一上街,我的名字比谁都多,他们想叫我什么,我就是什么。他们遇到我时正在打喷嚏,就会叫我喷嚏;他们刚从厕所里出来,就会叫我擦屁股纸;他们向我招手的时候,就叫我过来;向我挥手时,就叫我滚开……还有老狗、瘦猪什么的。他们怎么叫我,我都答应,因为我没有自己的名字,他们只要凑近我,看着我,向我叫起来,我马上就会答应。
我想起来了,他们叫我叫得最多的是:喂!
我就试探地对他们说:
“我是……喂!”
他们睁大了眼睛,问我:
“你是什么?”
我想自己是不是说错了,就看着他们,不敢再说。他们中间有人问我:
“你是什么……啊?”
我摇摇头说:“我是……喂。”
他们互相看了看,然后哗哗地笑了起来,我站在那里看着他们笑,自己也笑。桥上走过的人看到我们笑得这么响,也都哈哈地笑起来了。一个穿花衬衣的人叫我:
“喂!”
我赶紧答应:“嗯。”
穿花衬衣的人指着另一个人说:
“你和他的女人睡过觉?”
我点点头说:“嗯。”
另一个人一听这话就骂起来:
“你他妈的。”
然后他指着穿花衬衣的人对我说:
“你和他的女人睡觉时很舒服吧?”
“我和你们的女人都睡过觉。”
他们听到我这样说,一下子都不笑了,都睁着眼睛看我,看了一会,穿花衬衣的人走过来,举起手来,一巴掌打下来,打得我的耳朵嗡嗡直响。
陈先生还活着的时候,经常站在药店的柜台里面,他的脑袋后面全是拉开的和没有拉开的小抽屉,手里常拿着一把小秤,陈先生的手又瘦又长。有时候,陈先生也走到药店门口来,看到别人叫我什么,我都答应,陈先生就在那里说话了,他说:
“你们是在作孽,你们还这么高兴,老天爷要罚你们的……只要是人,都有一个名字,他也有,他叫来发……”
陈先生说到我有自己的名字,我叫来发时,我心里就会一跳,我想起来我爹还活着的时候常常坐在门槛上叫我:
“来发,把茶壶给我端过来……来发,你今年五岁啦……来发,这是我给你的书包……来发,你都十岁了,还他妈的念一年级……来发,你别念书啦,就跟着爹去挑煤吧……来发,再过几年,你的力气就赶上我啦……来发,你爹快要死了,我快要死了,医生说我肺里长出了瘤子……来发,你别哭,来发,我死了以后你就没爹没妈了……来发,来,发,来,来,发……”
“来发,你爹死啦……来发,你来摸摸,你爹的身体硬邦邦的……来发,你来看看,你爹的眼睛瞪着你呢……”
我爹死掉以后,我就一个人挑着煤在街上走来走去,给镇上的人家送煤,他们见到我都喜欢问我:
“来发,你爹呢?”
我说:“死掉了。”
他们哈哈笑着,又问我:
“来发,你妈呢?”
我说:“死掉了。”
他们问:“来发,你是不是傻子?”
我点点头:“我是傻子。”
我爹活着的时候,常对我说:
“来发,你是个傻子,你念了三年书,还认不出一个字来。来发,这也不能怪你,要怪你妈,你妈生你的时候,把你的脑袋挤坏了。来发,也不能怪你妈,你脑袋太大,你把你妈撑死啦……”
他们问我:“来发,你妈是怎么死的?”
我说:“生孩子死的。”
他们问:“是生哪个孩子?”
我说:“我。”
他们又问:“是怎么生你的?”
我说:“我妈一只脚踩着棺材生我。”
他们听后就要哈哈笑很久,笑完后还要问我:
“还有一只脚呢?”
还有一只脚踩在哪里我就不知道了,陈先生没有说,陈先生只说女人生孩子就是把一只脚踩到棺材里,没说另外一只脚踩在哪里。
他们叫我:“喂,谁是你的爹?”
我说:“我爹死掉了。”
他们说:“胡说,你爹活得好好的。”
我睁圆了眼睛看着他们,他们走过来,凑近我,低声说:
“你爹就是我。”
我低着头想了一会,说:
“嗯。”
他们问我:“我是不是你的爹?”
我点点头说:“嗯。”
我听到他们咯吱咯吱地笑起来,陈先生走过来对我说:
“你啊,别理他们,你只有一个爹,谁都只有一个爹,这爹要是多了,做妈的受得了吗?”
我爹死掉后,这镇上的人,也不管年纪有多大,只要是男的,差不多都做过我的爹了。我的爹一多,我的名字也多了起来,他们一天里叫出来的我的新名字,到了晚上我掰着手指数都数不过来。
只有陈先生还叫我来发,每次见到陈先生,听到他叫我的名字,我心里就是一跳。陈先生站在药店门口,两只手插在袖管里看着我,我也站在那里看着陈先生,有时候我还嘿嘿地笑。站久了,陈先生就会挥挥手,说:
“快走吧,你还挑着煤呢。”
有一次,我没有走开,我站在那里叫了一声:
“陈先生。”
陈先生的两只手从袖管里伸出来,瞪着我说:
“你叫我什么?”
我心里咚咚跳,陈先生凑近了我说:
“你刚才叫我什么?”
我说:“陈先生。”
我看到陈先生笑了起来,陈先生笑着说:
“看来你还不傻,你还知道我是陈先生,来发……”
陈先生又叫了我一声,我也像陈先生那样笑了起来,陈先生说:
“你知道自己叫来发吗?”
我说:“知道。”
陈先生说:“你叫一遍给我听听?”
我就轻声叫道:“来发。”
陈先生哈哈大笑了,我也张着嘴笑出了声音,陈先生笑了一会后对我说:
“来发,从今往后,别人不叫你来发,你就不要答应,听懂了没有?”
我笑着对陈先生说:“听懂了。”
陈先生点点头,看着我叫道:“陈先生。”我赶紧答应:“哎!”陈先生说:“我叫我自己,你答应什么?”
我没想到陈先生是在叫自己,就笑了起来,陈先生摇了摇头,对我说:
“看来你还是一个傻子。”
陈先生很早以前就死掉了,前几天翘鼻子许阿三也死掉了,中间还死了很多人,和许阿三差不多年纪的人都是白头发白胡子了,这些天,我常听到他们说自己也快死了,我就想我也快要死掉了,他们都说我的年纪比翘鼻子许阿三大,他们问我:
“喂,傻子,你死掉了谁来给你收尸?”
我摇摇头,我真不知道死掉以后,谁来把我埋了。我问他们死了以后谁去收尸,他们就说:
“我们有儿子,有孙子,还有女人,女人还没死呢,你呢,你有儿子吗?你有孙子吗?你连女人都没有。”
我就不做声了,他们说的我都没有,我就挑着担子走开去。他们说的,许阿三倒是都有。翘鼻子许阿三被烧掉的那天,我看到了他的儿子,他的孙子,还有他家里的人在街上哭着喊着走了过去。我挑着空担子跟着他们走到火化场,一路上热热闹闹的,我就想要是自己有儿子,有孙子,家里再有很多人,还真是很好的事。我走在许阿三的孙子旁边,这孩子哭得比谁都响,他一边哭一边问我:
“喂,我是不是你的爹?”
现在,年纪和我差不多的人都不想再做我的爹了,以前他们给我取了很多名字,到头来他们还是来问我自己,问我叫什么名字。他们说:
“你到底叫什么?你死掉以后我们也好知道是谁死了……你想想,许阿三死掉了,我们只要一说许阿三死了,谁都会知道。你死了,我们怎么说呢?你连个名字都没有……”
我知道自己叫什么名字,我叫来发。以前只有陈先生一个人记得我的名字,陈先生死掉后,就没有人知道我的名字了。现在他们都想知道我叫什么,我不告诉他们,他们就哈哈地笑,说傻子就是傻子,活着时是个傻子,死掉后躺到棺材里还是个傻子。
我也知道自己是个傻子,知道我这个傻子老了,我这个傻子快要死了。有时想想,觉得他们说得也对,我没有儿子,没有孙子,死了以后就没人哭着喊着送我去烧掉。我还没有自己的名字,我死掉后,他们都不知道是谁死了。
这些天,我常想起从前的那条狗来,那条又瘦又小,后来长得又壮又大的黄狗,他们也叫它傻子,我知道他们叫它傻子是在骂它,我不叫它傻子,我叫它:
“喂。”
那个时候街上的路没有现在这么宽,房子也没有现在这么高,陈先生经常站在药店门口,他的头发还都是黑的,就是翘鼻子许阿三,都还很年轻,还没有娶女人,他那时常说:
“像我这样二十来岁的人……”
那个时候我爹倒是已经死了,我挑着煤一户一户人家送,一个人送了有好几年了。我在街上走着,时常看到那条狗,又瘦又小,张着嘴,舌头挂出来,在街上舔来舔去,身上是湿淋淋的。我时常看到它,所以翘鼻子许阿三把它提过来时,我一眼就认出它来了,许阿三先是叫住我,他和好几个人一起站在他家门口,许阿三说:
“喂,你想不想娶个女人?”
我站在路的对面看到他们嘿嘿地笑,我也嘿嘿地笑了几下,他们说:
“这傻子想要女人,这傻子都笑了……”
许阿三又说:“你到底想不想娶个女人?”
我说:“娶个女人做什么?”
“做什么?”许阿三说,“和你一起过日子……陪你睡觉,陪你吃饭……你要不要?”
我听许阿三这样说,就点了点头,我一点头,他们就把那条狗提了出来,许阿三接过来递给我,那狗的脖子被捏着,四只脚就蹬来蹬去,汪汪乱叫,许阿三说:
“喂,你快接过去。”
他们在一边哈哈笑着,对我说:
“傻子,接过来,这就是你的女人。”
我摇摇头说:“它不是女人。”
许阿三冲着我叫起来:
“它不是女人?那它是什么?”
我说:“它是一条狗,是小狗。”
他们哈哈笑起来说:“这傻子还知道狗……还知道是小狗……”
“胡说。”许阿三瞪着我说道,“这就是女人,你看看……”
许阿三提着狗的两条后腿,扯开后让我看,他问我:
“看清楚了吗?”
我点点头,他就说:
“这还不是女人?”
我还是摇摇头,我说:
“它不是女人,它是一条雌狗。”
他们哄哄地笑起来,翘鼻子许阿三笑得蹲到了地上,那条小狗的后腿还被他捏着,头擦着地汪汪叫个不止。我站在他们旁边也笑了,笑了一会,许阿三站起来指着我,对他们说:
“他还看出了这狗是雌的。”
说完他蹲下去又吱吱地笑了,笑得就像是知了在叫唤,他的手一松开,那条狗就忽地跑了。
从那天起,翘鼻子许阿三他们一见到我就要说:
“喂,你的女人呢……喂,你女人掉到粪坑里去啦……喂,你女人正叉着腿在撒尿……喂,你女人吃了我家的肉……喂,你女人像是怀上了……”
他们哈哈哈哈笑个不停,我看到他们笑得高兴,也跟着一起笑起来,我知道他们是在说那条狗,他们都盼着有一天我把那条狗当成女人娶回家,让我和那条狗一起过日子。
他们天天这么说,天天这么看着我哈哈笑,这么下来,我再看到那条狗时,心里就有点怪模怪样的。那条狗还是又瘦又小,还是挂着舌头在街上舔来舔去,我挑着担子走过去,走到它身边就会忍不住站住脚,看着它。有一天我轻声叫了它一下,我说:
“喂。”
它听到了我的声音后,对我汪汪叫了好几声,我就给了它半个吃剩下的馒头,它叼起馒头后转身就跑。
给它吃了半个馒头后,它就记住我了,一见到我就会汪汪叫,它一叫,我又得给它吃馒头。几次下来,我就记住了往自己口袋里多装些吃的,在街上遇着它时也好让它高兴。它啊,一看到我的手往口袋里放,就知道了,两只前腿举起来,对着我又叫又抓的。
后来,这条狗就天天跟着我了。我在前面挑着担子走,它在后面走得吧嗒吧嗒响,走完了一条街,我回头一看,它还在后面,汪汪叫着对我摇起了尾巴,再走完一条街它就不见了,我也不知道它跑哪儿去了,等过了一些时候,它又会突然蹿出来,又跟着我走了。有时候它这么一跑开后,要到晚上天黑了的时候才回来,我都躺在床上睡觉了,它跑回来了,蹲在我的门口汪汪叫,我还得打开门,把自己给它看看,它才不叫了,对着我摇了一会尾巴后,转身吧嗒吧嗒地在街上走去了。
我和它在街上一起走,翘鼻子许阿三他们看到了都嘿嘿笑,他们问我:
“喂,你们夫妻出来散步?喂,你们夫妻回家啦?喂,你们夫妻晚上睡觉谁搂着谁?”
我说:“我们晚上不在一起。”
许阿三说:“胡说,夫妻晚上都在一起。”
我又说:“我们不在一起。”
他们说:“你这个傻子,夫妻图的就是晚上在一起。”
许阿三做了个拉灯绳的样子,对我说:
“咔嗒,这灯一黑,快活就来啦。”
翘鼻子许阿三他们要我和狗晚上都在一起,我想了想,还是没有和它在一起。这狗一到天黑,就在我门口吧嗒吧嗒走开了,我也不知道它去了什么地方,天一亮,它又回来了,在我的门上一蹭一蹭的,等着我去开门。
白天,我们就在一起了。我挑着煤,它在一边走着,我把煤送到别人家里去时,它就在近旁跑来跑去跑一会,等我一出来,它马上就跟上我了。
那么过了些日子,这狗就胖得滚圆起来了,也长大了很多,它在我身边一跑,我都看到它肚子上的肉一抖一抖的,许阿三他们也看到了,他们说:
“这母狗,你们看,这肥母狗……”
有一天,他们在街上拦住了我,许阿三沉着脸对我说:
“喂,你还没分糖呢!”
他们一拦住我,那狗就对着他们汪汪叫,他们指着路对面的小店对我说:
“看见了吗?那柜台上面的玻璃瓶,瓶里装着糖果,看见了吗?快去。”
我说:“去做什么?”
他们说:“去买糖。”
我说:“买糖做什么?”
他们说:“给我们吃。”
许阿三说:“你他妈的还没给我们吃喜糖呢!喜糖!你懂不懂?我们都是你的大媒人!”
他们说着把手伸进了我的口袋,摸我口袋里的钱,那狗见了就在边上又叫又跳。许阿三抬脚去踢它,它就叫着逃开了几步,许阿三又上前走了两步,它一下子逃远了。他们摸到了我胸口的钱,全部拿了出来,取了两张两角的钱,把别的钱塞回到我胸口里,他们把我的钱高高举起,笑着跑到了对面的小店里。他们一跑开,那狗就向我跑过来了,它刚跑到我眼前,一看到他们从小店里出来,马上又逃开去了。许阿三他们在我手里塞了几颗糖,说:
“这是给你们夫妻的。”
他们嘴里咬着糖,哈哈哈哈地走去了。这时候天快黑了,我手里捏着他们给我的糖往家里走,那条狗在我前面和后面跑来跑去,汪汪乱叫,叫得特别响,它一路跟着我叫到了家,到了家它还汪汪叫,不肯离开,在门前对我仰着脑袋,我就对它说:
“喂,你别叫了。”
它还是叫,我又说:
“你进来吧。”
它没有动,仍是直着脖子叫唤着,我就向它招招手,我一招手,它不叫了,忽地一下蹿进屋来。
从这天起,这狗就在我家里住了。我出去给它找了一堆稻草回来,铺在屋角,算是它的床。这天晚上我前前后后想了想,觉得让狗住到自己家里来,和娶个女人回来还真是有点一样,以后自己就有个伴了,就像陈先生说的,他说:
“娶个女人,就是找个伴。”我对狗说:“他们说我们是夫妻,人和狗是不能做夫妻的,我们最多只能做个伴。”
我坐到稻草上,和我的伴坐在一起。我的伴对我汪汪叫了两声,我对它笑了笑,我笑出了声音,它听到后又汪汪叫了两声,我又笑了笑,还是笑出了声音,它就又叫上了。我笑着,它叫着,那么过了一会,我想起来口袋里还有糖,就摸出来,我剥着糖纸对它说:
“这是糖,是喜糖,他们说的……”
我听到自己说是喜糖,就偷偷地笑了几下,我剥了两颗糖,一颗放到它的嘴里,还有一颗放到自己嘴里,我问它:
“甜不甜?”
我听到它咔咔地咬着糖,声音特别响,我也咔咔地咬着糖,声音比它还要响,我们一起咔咔地咬着糖,咬了几下我哈哈地笑出声来了,我一笑,它马上就汪汪叫上了。
我和狗一起过日子,过了差不多有两年,它每天都和我一起出门,我挑上重担时,它就汪汪叫着在前面跑,等我担子空了,它就跟在后面走得慢吞吞的。镇上的人看到我们都喜欢嘻嘻地笑,他们向我们伸着手指指指点点,他们问我:
“喂,你们是不是夫妻?”
我嘴里“嗯”了一下,低着头往前走。
他们说:“喂,你是不是一条雄狗?”
我也“嗯”了一下,陈先生说:
“你好端端的一个人,和狗做什么夫妻?”
我摇着头说:“人和狗不能做夫妻。”
陈先生说:“知道就好,以后别人再这么叫你,你就别嗯嗯地答应了……”
我点点头,“嗯”了一下,陈先生说:
“你别对着我嗯嗯的,记住我的话就行了。”
我又点点头“嗯”了一下,陈先生挥挥手说:
“行啦,行啦,你走吧。”
我就挑着担子走了开去,狗在前面吧嗒吧嗒地跑着。这狗像是每天都在长肉,我觉得还没过多少日子,它就又壮又大了,这狗一大,心也野起来了,有时候一整天都见不着它,不知道它跑哪儿去了,要到天黑后它才会回来,在门上一蹭一蹭的。我开了门,它溜进来后就在屋角的稻草上趴了下来,狗脑袋搁在地上,眼睛斜着看我。我这时就要对它说:
“你回来啦,你回来就要睡觉了,我还没有说完话,你就要睡觉了……”
我还没有说完话,狗眼睛已经闭上了,我想了想,也把自己的眼睛闭上了。
我的狗大了,也肥肥壮壮了,翘鼻子许阿三他们见了我就说:
“喂,傻子,什么时候把这狗宰了?”他们吞着口水说,“到下雪的时候,把它宰了,放上水,放上酱油,放上桂皮,放上五香……慢慢地炖上一天,真他妈的香啊……”
我知道他们想吃我的狗了,就赶紧挑着担子走开去,那狗也跟着我跑去。我记住了他们的话,说下雪的时候要来吃我的狗,我就去问陈先生:
“什么时候会下雪?”
陈先生说:“早着呢,你现在还穿着汗衫,等你穿上棉袄的时候才会下雪。”
陈先生这么说,我就把心放下了,谁知道我还没穿上棉袄,还没下雪,翘鼻子许阿三他们就要吃我的狗了。他们拿着一根骨头,把我的狗骗到许阿三家里,关上门窗,拿起棍子打我的狗,要把我的狗打死,打死后还要在火里炖上一天。
我的狗也知道他们要打死它,要吃它,它钻到许阿三床下后就不出来了,许阿三他们用棍子捅它,它汪汪乱叫,我在外面走过时就听到了。
这天上午我走到桥上,回头一看它没有了,到了下午走过许阿三家门口,听到它汪汪叫,我站住脚。我站了一会,许阿三他们走了出来,许阿三他们看到我说:
“喂,傻子,正要找你……喂,傻子,快去把你的狗叫出来。”
他们把一个绳套塞到我手里,他们说:
“把它套到狗脖子上,勒死它。”
我摇摇头,我把绳套推开,我说:
“还没有下雪。”
他们说:“这傻子在说什么?”
他们说:“他说还没下雪。”
他们说:“没有下雪是什么意思?”
他们说:“不知道,知道的话,我也是傻子了。”
我听到狗还在里面汪汪地叫,还有人用棍子在捅它,许阿三拍拍我的肩膀说:
“喂,朋友,快去把狗叫出来……”
他们一把将我拉了过去,他们说:
“叫他什么朋友……少和他说废话……拿着绳套……去把狗勒死……不去?不去把你勒死……”
许阿三挡住他们,许阿三对他们说:
“他是傻子,你再吓唬他,他也不明白,要骗他……”
他们说:“骗他,他也一样不明白。”
我看到陈先生走过来了,陈先生的两只手插在袖管里,一步一步地走过来了。
他们说:“干脆把床拆了,看那狗还躲哪儿去!”
许阿三说:“不能拆床,这狗已经急了,再一急它就要咬人啦。”
他们对我说:“你这条雄狗,公狗,癞皮狗……我们在叫你,你还不快答应!”
我低着头“嗯”了两声,陈先生在一边说话了,他说:
“你们要他帮忙,得叫他真的名字,这么乱叫乱骂的,他肯定不会帮忙,说他是傻子,他有时候还真不傻。”
许阿三说:“对,叫他真名,谁知道他的真名?他叫什么?这傻子叫什么?”
他们问:“陈先生知道吗?”
陈先生说:“我自然知道。”
许阿三他们围住了陈先生,他们问:
“陈先生,这傻子叫什么?”
陈先生说:“他叫来发。”
我听到陈先生说我叫来发,我心里突然一跳。许阿三走到我面前,搂着我的肩膀,叫我:
“来发……”
我心里咚咚跳了起来,许阿三搂着我往他家里走,他边走边说:
“来发,你我是老朋友了……来发,去把狗叫出来……来发,你只要走到床边上……来发,你只要轻轻叫一声……来发,你只要喂地叫上一声……来发,就看你了。”
我走到许阿三的屋子里,蹲下来,看到我的狗趴在床底下,身上有很多血,我就轻轻地叫了它一声:
“喂。”
它一听到我的声音,忽地一下蹿了出来,扑到我身上来,用头用身体来撞我,它身上的血都擦到我脸上了,它呜呜地叫着,我还从来没有听到它这样呜呜地叫过,叫得我心里很难受。我伸手去抱住它,我刚抱住它,他们就把绳套套到它脖子上了。他们一使劲,把它从我怀里拉了出去。我还没觉察到,我抱着狗的手就空了。我听到它汪地叫了半声,它只叫了半声。我看到它四条腿蹬了几下,就蹬了几下,它就不动了。他们把它从地上拖了出去,我对他们说:
“还没有下雪呢。”
他们回头看看我,哈哈哈哈笑着走出屋去了。
这天晚上,我一个人坐在狗睡觉的稻草上,一个人想来想去,我知道我的狗已经死了,已经被他们放上了水,放上了酱油,放上了桂皮,放上了五香,他们要把它在火里炖上一天,炖上一天以后,他们就会把它吃掉。
我一个人想了很久,我知道是我自己把狗害死的,是我自己把它从许阿三的床底下叫出来的,它被他们勒死了。他们叫了我几声来发,叫得我心里咚咚跳,我就把狗从床底下叫出来了。想到这里,我摇起了头,我摇了很长时间的头,摇完了头,我对自己说:以后谁叫我来发,我都不会答应了。
一九九四年十月五日
* * *
近日在研究 [[RoamResarch]] 的时候,发现他们的白皮书和创始人的一系列关于信息获取和组织知识的思考蛮有趣,加上最近也在重构自己的知识库有所思考,所以结合其部分观点,谈谈对于信息获取和知识组织的看法。
我们遇到了什么问题
---------
信息过载,知识爆炸。据 IDC 发布《数据时代 2025》的报告显示,全球每年产生的数据将从 2018 年的 33ZB 增长到 175ZB ,相当于每天产生 491EB 的数据。如果把 175ZB 全部存在 DVD 光盘中,那么 DVD 叠加起来的高度将是地球和月球距离的 23 倍(月地最近距离约 39.3 万公里),或者绕地球 222 圈(一圈约为四万公里)。以 25Mb /秒网速计算,要下载完这 175ZB 的数据,需要 18 亿年。虽然这种指数级的增长为个人和整个社会带来了巨大的机遇,但无论是人类的大脑还是目前的技术,都无法充分发挥其潜力。
`Tips:Byte < KB < MB < GB < TB < PB < EB < ZB < YB`
信息时代是最近 200 年才开始兴起的,所以从进化的角度来看,人类对信息时代的适应性很差。虽然大脑的存储量惊人(并且消耗能量很少),但是也是出了名的不可靠 —— 这是因为我们并不会存储我们知道的而每一个细节,而是将其识别为各种「模式」,回忆的时候将各种「模块」拼装成大概的样子。比如当你经历「2001 年那个寒冷的下雪的晚上」,你会把「寒冷」「下雪」「晚上」以及 「2001 年」这些「记忆」分别存储,等需要调用的时候再一起「拼装」出来。同样当你回忆去年很冷的晚上遇见了一个老朋友,那么这个「寒冷」的感觉就是被复用的 —— **这也是为什么我们总会有一种「此时此地此景我似乎在哪里见到过」的原因 。**
另外,基于上述存储方式,我们很少能精确地进行量化 —— 我们生活中经常使用 「可能」、「肯定」、「也许」等词,在我们的直觉中,**我们会感觉到类似于我们对这些信念模糊的概率,但是实际上我们经常被客观数据打脸**。这也是为什么我们总强调客观,但始终还是做不到的原因,因为我们的记忆是模糊的。所以我们今天的大脑还是会有许多的认知偏差,让我们做出各种错误的决策。
这就是我们的大脑,虽然存储量很大耗能很少(基本上就是一个 5w 的灯泡),但是不够精确,充满了不确定性。
我们是如何获取[[知识]]的
----------
**我们通过观察、抽象(如定义词等)、建立模型、归纳推理和演绎推理等方式,形成了关于世界如何运作的复杂信念**,然后将其通过「词汇」在我们脑子里建立节点,形成一个彼此相连的网络。所以有些时候你会发现不同的语言之间确实很难翻译,因为这些词汇背后的「语境」需要很多文化背景才能解释。比如在德语中的「verschlimmbessern」,就是动词:尝试改善却使情况更糟。
但我们的学习过程,**是以非线性的方式形成的**。比如你在外面餐厅吃饭,可能同时增加了餐厅管理的知识,也增加了烹饪知识,而且很可能是某种面试的烹饪技巧。心理学家将能在 60 - 90s 记忆的一个信息,称之为一个「块(chuck)」。根据赫伯特 · 西蒙(什么是西蒙学习法\[1\] )的说法,每一门学问所包含的信息量大约是 5 万块,如果 1 分钟能记忆 1「块」,那么 5 万块大约需要 1000 个小时,以每星期学习 40 小时计算,要掌握一门学问大约需要用 6 个月 —— **不过如果这个知识块没有和现有的知识连接,那么根据用进废退的原则,这些神经回路很快就会萎缩**,也就是我们所说的遗忘。
每个受过高等教育的人,差不多都能识别 5 万到 10 万个不同词汇,并回想起它们的含义。这些词汇会形成专属的知识网络。「**在任何专门知识领域里,正是由于有了一张十分精致的网络,人们才能够从千万种不同事物、不同情境当中,判别出其中任一事物或情境,这种网络是专家的基本工具之一,是其直觉的主要源泉。** 」但随着你的观察越来越深入,获取的信息越来越多,你也很有可能会颠覆你在过去很久以来形成的决策或逻辑链(比如,在今天这个时代是不需要考虑「下线」这种产品状态的)。
那么写下来是否能解决这个问题呢?根据尼克拉斯 · 卢曼的说法,用你自己的话写出来当然能促进记忆,但问题是,如果你想把这些想法从脑子里拿出来,基于人类现在的 I/O 接口,你必须把图(Graph)变成一个流(Flow)。因为你一次只能说或写一个字。而我们日常受到的教育都是让我们按照八股文的形式,整理成完整的文档,而不是类似「原子化」的笔记。

而要想让别人(包括你未来的自己)吸收、有效地批判你的过去的思想基础上,他们必须把那一串话语 / 想法,在自己的脑海中重建原型 (说到这里推荐可以去看下《降临》,就能知道那种不需要时间维度一下就能将所有的信息讲述给对方的「外星语言」)。
即使是这样,对于真正重要的想法,也是很难的。因为有些想法或模型在你只听了一个片段的时候,是没有意义的,或者当你只听了一个框架的时候,这些想法或模型看起来很反直觉:比如突然跟你讨论「尼克拉斯·卢曼的卡片盒笔记法是非常好的笔记方法」,你显然会一脸懵逼,除非你已经有了一些入门的基础信息,否则根本无法参与讨论。同样当你学习一门语言的时候,你不是通过掌握一个单词就能学会的(虽然你确实需要一次学会一个单词),而是通过沉浸式的学习,在上下文中看到越来越多的单词在一起,直到事情开始有了眉目。
但是困难的是,我们无法直接识别对方的背景,只能通过不断地沟通(类似 什么是蒙特卡洛算法\[2\] )来测试对方知识的轮廓,然后有的放矢地沟通。

From《A City is Not a Tree》 by 克里斯托佛·亚历山大
目前知识管理的问题
---------

From Notion 官网
人类针对大脑的这些问题,其实不断地在思考如何能拥有一个「精确的大脑」。古登堡印刷术发明后,实体书和期刊大量涌现,此后部分被文字处理机、网站、博客、论坛、维基百科和软件应用所取代。除了记录文字,亚历山大图书馆这种组织知识的地方也非常有意义。
1893 年的世界博览会金奖得主,就是一种称之为「[[立式归档]]」的文件存储系统,相比横着堆叠文件的抽屉式存储,这种文件柜效率更高占地空间更少。而这种组织能力的提升,成为了信息革命前的基石 —— **由打字机和存储柜组成的高效信息生产及索引工具,带来了新的科技革命,一直到今天**。所以从历史的演进来看,知识管理一直伴随着两个亘古不变的话题:「存储对象」以及「组织方式」。
### 存储对象的迭代
从互联网的兴起到今天,我们大致经历了几个「存储」时代:
• **书签时代**(还记得 Delicious.com\[3\] 么):这时候你存储的对象仅仅是 URL,背后可能是一个 Homepage,也可以是一篇文章,但在浏览的时候你并不知道,他们也不存储 URL 背后的信息。
• **文章时代:** 随着移动设备的兴起,以及 UGC 的普及,内容创作越来越多,我们希望能把这些「信息/知识」都收藏起来,这时候收藏的对象多是一篇文章/视频等。但问题也随之而来 —— 一篇文章中往往会有许多的知识点,而这些知识点在不同的人看来,会放在不同的框架里面去。但是 Evernote(或者说 instapaper)他们却无意解决这个问题,只是将文章保存放到文件夹,而那些 ReaditLater 的文章,基本上就是 ReaditNever
• **Block 时代:** Pinterest 是个特殊的异类,但从保存信息的视角来看,则颗粒度更加精细了一层。比如在一篇图文混排的关于宫崎骏的介绍中,你可以把一些老爷子的照片放在「动画导演」这个 Board 中,而下面的「风之谷」的插画,则就可以保存在「吉卜力动画」及「动画场景」的 Board 中,相对来说更加自由。目前国外也有一些关于文本的尝试,如hypothes.is,WorldBrain's Memex 等。
### 信息组织的更新

虽然我们在组织知识的时候有很多选择,但几乎每一种技术都遵循同样的基本「文件柜」格式。**一个单位的知识被保存到一定的文件路径中,将其置于一个由文件夹、章节或类别组成的分类法中**。当一个项目与许多事物相关时,可以应用标签,但每个文件一般只存储在一个嵌套的层次结构中。要访问这些信息,用户必须记住他们将文件存储在哪里,用什么标记,或者使用搜索功能来定位。( Notion 小传\[4\] 中也提到这个问题 )
当你收集信息的时候,你会很快发现,每一篇内容可能都和你考虑的很多问题有关。但你不得不按照上面的方法将内容放在一个文件夹里,而无法同时和许多内容联结,而许多文件也脱离了上下文 —— 被丢进孤零零的文件夹里。
更麻烦的是,你读到的每一篇文章都有许多[[知识块]](chuck),这些知识块在你现在的思维结构中的不同层次和位置上都有。这会导致你使用文件夹的时候陷入困境 :如果一篇文章中对你现在研究的三个方面都有所关联, —— 那么你是否把它的副本放在所有三个地方?—— 如果你这样做了,那么你以后对它做的任何修改(无论你在什么时候对这个想法进行完善或建立在这个想法的基础上,或使其失效)都需要 3 倍的工作。
**虽然树形结构可以在给定的层次结构中嵌套的文件之间建立伪关系,但这些关系并不明确,只能描述垂直的 「父子」分类法,但是如上文所说,我们的大脑不是这么记忆知识点的。**
而 Tag 也并非好的解决方案,它们对于浏览来说是很好的,但因为它们是扁平的(而且很难合并在一起),需要你提前猜测你的结构。如果你依赖标签,你可以把同一个项目分成多个集合,但你就失去了从更高的 "鸟瞰能力 " —— 最后你需要在同级别的 100 个标签中寻找你想要的 —— 当然也看到有人对这种 tag 系统进行了补充,Bear 就是一个很好的例子,利用 #父级 / 子集# 这种标签方式,兼顾了标签的灵活性也增加了标签的逻辑层次,在整理和归纳信息的时候更加方便了一些。而 Roam / workflowy 则是走了另一条路,让每个 tag 都成为了一个实体 Block,这样就可以相互轻易地转换和引用。
那我们需要什么?
--------
今天我们作为从事脑力劳动的人,仅仅靠脑子显然不够应付这么复杂的局面。根据行为经济学家丹尼尔 · 卡尼曼的研究,大脑分为系统 1(直觉脑) 和系统 2(逻辑脑),许多逻辑运算都是基于系统 2 来的,但是系统 2 非常消耗能量,你必须把许多数据从大脑中挪出来(大脑一般能记录 5±2 的工作记忆),所以**我们需要把事情「从脑海中」剥离出来,在我们回忆的时候能更好地检索,继而让我们做出更好地决策**,而不是在海量信息来的时候,凭着「感觉做事情」。
一个好的工具应该能从以下几个方面来解决我们的问题:
• 信息的收集(包含对信息对象的原子化)
• 信息的整理和组织(这是从信息转化为知识的核心步骤)
• 知识的索引和发现(这是利用和拓展知识最关键的手段)
但除了工具之外,还要养成一个更好的习惯,即不断地整理「Evergreen note · 常青笔记」,这个概念来自于Andy Matuschak\[5\]。多数时候我们仅仅把把笔记当作临时性的草稿纸,并不会去好好整理和归纳,也没有打磨过自己的实践方式。这种态度其实让我们错失了许多思考的机会,毕竟写作不是为了表达,而是为了更好地思考。
具体的执行其实可以参考 [原子笔记法:Zettelkasten](http://mp.weixin.qq.com/s?__biz=MzI3NDEzMjIyMQ==&mid=2649474090&idx=1&sn=bf2fcc5c3a909e939795eb36b1ec33ae&chksm=f307d9b8c47050ae1f88ed976deef2e7e51b44fd4eac768b5541743a9876cc1a505df11a3a71&scene=21#wechat_redirect)\[6\] (可点击查看),在这里就不展开了。
值得一提的是,许多人思考「复利」的时候往往只考虑了金钱的回报,却忘记了**知识也是有复利的**。当这样积累一段时间之后,你的知识节点越来越多,连接越来越丰富,就会产生知识的复利效应 —— 毕竟知识网络是具有极强的[「梅特卡夫」效应的。](http://mp.weixin.qq.com/s?__biz=MzI3NDEzMjIyMQ==&mid=2649474119&idx=1&sn=590aacab41cd99ca5f6307114fab81dd&chksm=f307d9d5c47050c30e0e9692b605463b42ec7fddc7ad938a60aae265638d2fb6101c3f5a413f&scene=21#wechat_redirect)
**参考资料**
* [💡 Roam White Paper | Roam 白皮书](https://www.notion.so/Roam-White-Paper-Roam-ad25fca6b11d4aaab39a5686ecb5f12e)
* [新型笔记工具Roam Research简介及快速上手教程 – Jarodise](https://www.notion.so/Roam-Research-Jarodise-3b1625568365415aa57b4e019e37bb47)
* [Roam Research: Why I Love It and How I Use It - Nat Eliason](https://www.notion.so/Roam-Research-Why-I-Love-It-and-How-I-Use-It-Nat-Eliason-e48c7a54b4384e5491e72db699f6da76)
* [A brief rant on note-taking apps and the structure of thought. Or "Why Evernote is a terrible second brain."](https://www.notion.so/A-brief-rant-on-note-taking-apps-and-the-structure-of-thought-Or-Why-Evernote-is-a-terrible-second-4391c4c6873d43768c1f39c783332bd0)
* [原子笔记法:Zettelkasten](https://www.notion.so/Zettelkasten-25627d7ce99344c487f4e42d861f9e0a)
* [什么是西蒙学习法](https://www.notion.so/126c29c8b15441ab89c5eeb8fa948396)
* [meet.2018.1450450214.pdf](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/44d7c206-7d12-414f-99c4-414194c6602d/meet.2008.1450450214.pdf)
* https://twitter.com/rjs/status/1130609983408578561
我为你洒下月光- 简媜
========================
我为你洒下月光- [[简媜]]
-----
火车向东部奔驰。
那温柔秘密深藏在我的心底,
永远孤寂,永远见不到光明;
你的心呼唤,我心潮才会涌起,
一阵战栗,复归于原先的寂静。
她看着窗外风景,想着拜伦的诗。秋天的光芒洒在群山与平原之上,深绿树林间已有早发的枫红。岁月惊心?不,是心让岁月吃惊,怎么绕了一大圈路,还是觉得这个人值得天地好好把他珍惜。
他一身黑衣等在验票出口,黄昏彩霞烘托着他,须发皆乱,神情惨然。她第一眼就想哭,几年不见,脑海里留的是以前的模样,见不得眼前的他这么憔悴。
他问车行顺利否,帮她提袋子——中秋节已近,她买了各色月饼及几本稍可纾闷的书送他。
他说:“找个地方坐吧。”
“我是不是应该先到府上向伯父上香。”
“不用,你给我上香就好。”
“你乱说什么话呀!”她掉泪了,怎么可以说这种话?若不是在人潮中,她真的要大喊,因为这话让她联结到失去母亲的那种锥心之痛。
“唉!”
两人停住脚步,你看我,我看你,人群从他们中间穿梭。他自知失言,苦笑,不想多说家中事,这些都不重要。此刻像坠落深渊底,都明白不能共死还要活下去,只能鼓起力气,你救我,我救你。
“你陪我吃点东西,我今天还没吃。”
“昨天呢?”
他没讲话,想必饮食都乱了。
一碗清淡热面,正好安抚心事重重的这两人。都不讲话,也不抬头看吵闹的电视,不看对方,专心吃面,仿佛萍水相逢的陌生人共享一桌,各自把可恨的、可恶的、可笑的、可悯的世间事都吃光了,再来重新认识。
她问老人家后事,他提到父亲在病榻上受洗,最后一段路走得安详。
“你自己呢?身体还好吗?”她问,又自行替他答:“当然不太好。”
这让他笑起来,怎有人这样自问自答的?刚才脸上绷紧的线条松了,仿佛返回熟悉的往日,与欢喜的人置身校园。
他说有些免疫方面的遗传必须小心控管,当年服兵役时曾发作所以才提早退伍。除此外,眼睛过度负荷,常感到吃重,反复发炎。
“来,我看看。”
他摘下眼镜让她看。
“你太拼了,一定是睡眠不足。”又说:“这么近看你的眼睛好怪,里面一点灵魂都没有。”
他绽出笑容,仿佛被她念几句是愉快的事,自嘲:“灵魂早用光了,现在有眼无珠,变成行尸走肉。”
她第一个反应是嗔怪:你确实有眼无珠;第二是心疼:又乱讲话,你的主不会让你变成行尸走肉的。但话到嘴边,刹住,今晚实在不想提“遗珠之憾”或是“主”。改问平日吃什么过活?
原来跟她一样,都窝在研究室乱吃,都有胃疾。他说这样拼命很功利不知道意义在哪里,觉得自己会短命,她说她才会短命而且本来就不想活太久。
“我们连这个也要争吗?”他说。
“对,争到底,不是你死我活就是我死你活。”
他笑得开怀,因为看到她在胡闹。他未曾看过她耍赖胡闹的样子,觉得轻松起来。
“你学会炒米粉了没?”
她说:“唉,怎么可能,我哪有‘你的她’那么能干!”忽想及往事,说:“有个人说话不算话,说要炒给我吃,也没有。你都在骗我!”
他忽地沉了脸,表情肃然:“我没有骗你……”情绪涌上,竟沉重得说不下去。
她察觉了,说:“我不是……这个意思,我不是说你骗我,我知道一切都是……真的。”
一切都是真的。只是掉进迷宫再也找不到对方。
“那温柔秘密深藏在我的心底”,虽然内心深处有个情结散成丝丝缕缕浮出来,但此时不是软弱的时候,她不想让这个哀恸的人再次掉落谷底,问:“这里吵得耳朵痛,除了你家稻田,哪里可以安安静静说话?最好一个人都没有,有鬼没关系,反正我们两个差不多也是鬼样子。”
算是把他逗开了,“有个地方没人也没鬼,不过,更吵。”
他开车带她去海边。
夜还年轻,靛蓝薄纱一般,远处仍有一抹灰蓝,早月已升空,辽阔的沙岸连绵得无穷无尽,潮涨浪高,啸声惊人。
“大江东去,浪淘尽,千古风流人物。”她默想,知我者苏东坡也!惊涛裂岸,乱石崩云;高妙处在裂字、崩字,唉,人哪有力气去阻挡那裂字、崩字!
走一段沙滩,听海浪呼唤、拍岸。他说好久没到海边,在离岛当兵留下后遗症,看到海会怕。当时在小岛上,读狄兰·托马斯的诗,最喜欢《山蕨》其中两句:“岁月伴我青青和死亡,虽我吟哦如海洋。”
她抱怨:“从我们见面到现在,你提了三次死亡。你再讲,我回去了。我才不要跟你死在一起,被‘教官’发现会记大过!”
“好,不讲不讲,改说活得好开心、好快乐。”
两人都笑开。他不记得有多少年没听过“教官”这两字,没说过“好开心、好快乐”这样幼稚的话,瞬间像躲过教官偷偷去约会的高中生,跌入奇妙的梦游之境。她用几句话,替他卸下身上铁枷。
这是秋天的海了,想起他为她描述过秋天的海面,那么漂亮的字迹,那么丰沛多情的文采,那么动人的心灵。
如今,写信的人就在身边,一切却已成追忆。
“啊,我懂李商隐的《锦瑟》诗了,‘锦瑟无端五十弦,一弦一柱思华年。庄生晓梦迷蝴蝶,望帝春心托杜鹃。沧海月明珠有泪,蓝田日暖玉生烟。此情可待成追忆,只是当时已惘然。’这是商隐的‘隐伤’之作,一生情爱的惆怅,不必单指一人一情,指的是自己的生命基调与情爱体质,终究逃脱不了惘然的结局。”
他一字一字清楚地问:“我们怎么会走到这一步?”
她心里一惊,暗想:你怎么问我?难道走到这一步不是你要的吗?难道你忘了信上怎么写的吗?把我赶出来的不是你吗?
不能回首,俱往矣,丝丝缕缕的情结都散去吧,想问的都不需问了,轻声一叹,有所领悟:
“我们常说没碰到对的人,会不会是,没碰到对的自己;你还没碰到对的你,我还没碰到对的我。所以,即使碰到对的人,也不能成就。”
他静静听她讲。
“如果你勇敢一点、宽阔一点,如果我别那么骄傲,没那么害怕……”
“你害怕什么?”
“怕无法调教,没有能力给你及你的家人幸福,没有机会实现自己的梦想,最后像我妈一样一辈子忧郁,怕没有上主的恩泽能跟你共负一轭……”
“我的现实担子很沉重,你的才华应该被看见,不忍心把你拉进来,怕拖累你。”
“她很好,对你‘全心全意’。”
“我很‘感激’她。”
他正面且肯定地说起群,感激二字是一百两黄金的价值,她确信他们将会有稳固的婚姻,稳固婚姻里该有的小风小雨,恒久忍耐又有恩慈。
这个想法让她流泪,但没有酸涩了。
找一处视野宽阔的平坦沙地,坐下。月将圆,光芒柔美,一颗颗星子闪亮。这是生命中难得的有良人陪伴的良夜。
他说:“快中秋节了,你的生日也快到,先祝你生日快乐。”
她忽然起了算总账的念头:“你从来没有送我花。”
“没有吗?有送你种子。”
“不一样。种子是种子,花是花。种子是未知,花是眼前当下,是已知。”
他大笑:“原来你在意这个!”
“在意又怎样,不在意又怎样?”
换她豁出去了,口若悬河,清算他:
“你从来没有一个清二个楚、三个明四个白、五个肯六个定,告诉我你心里怎么想。你只会每年记得我的生日,祝我生日快乐。我生来这世界,毫无快乐可言。再说一遍,毫无快乐可言。你每年记得,反倒像你在快乐,你又不是我妈,也不知在乐什么!”
说完一大串,自己掩嘴笑了,怎像个泼妇在骂街呢!又补一句:
“唉,这样说你不公平,我也从来没有一个清二个楚、三个明四个白、五个肯六个定,告诉你我心里怎么想。”
两人都笑起来,笑着的人无法生气,笑完只有轻轻一叹。叹息中仍有不舍的况味,好似:坐在身边的这个人这么美,是唯一能够与自己在心灵深处共鸣的,却是别人家的,天亮前必须还回去。啊,良夜啊良夜,别太匆忙。
他问:“如果有个人天天送你花,你就跟他跑了吗?”
“不会。”
“那不就结了,送花没用。”
“那得看什么人送我什么花!有没有用要我来决定不是你决定。”
“嘿,有人好像在生气……”他笑着,“如果我现在送花给你,有用吗?”
“没用。而且海边哪来的花?请你睁大眼睛看清楚,只有浪花,这是空话,你也学会说空话啦!”
他貌似被骂得很高兴,“那不就结了,我送花也没用。”
“我们的‘送花时机’,过了。”
她想起,那茑萝确实开了花,但这是她呵护得来的,能算吗?他在外岛时,曾经为她描述过水仙花,也写过小雏菊与山芙蓉,这算不算送过花?如果每个字算一朵花,他送给她的算不算一整个春天的量?
“我们那时候怎么没像现在吵架?”他笑着问,像个高中生。
“我们好笨,连怎么吵架都不会。”
“是啊,我看到你高兴都来不及,有讲不完的话,怎么会吵架?”这是真话。
“所以呀,缺少练习,第一次吵就裂了。也许冥冥之中知道时间宝贵,舍不得拿来吵架。分手以后,天不怕地不怕,反而可以吵架。”
“你说‘分手’,听起来让我很难受……”
“……”
她沉默,心想:“执子之手,与子偕老”是中国古典里最美的牵手诗;而《上邪》:“上邪!我欲与君相知,长命无绝衰。山无陵,江水为竭,冬雷震震,夏雨雪,天地合,乃敢与君绝。”是最惊心动魄的山盟海誓。我与你,有的只是一场纸上的心醉情迷,毕竟人间里无半点缘分。
“好奇怪,我们好像都在晚上见面。”她说。
“你是我的黑夜。”
“那么,我只好当月亮,为你洒下月光。”她轻声说。
他看着她,犹似当年,眼睛望进她的眼眸深处:“希望我这一生,至少有一天要完完整整属于你。”
这是仅存的最后一小片波德莱尔成分的私语,她完全清楚,这个善男子现在对她没有任何防卫,把心交出来,她此刻要风有风,要雨有雨。
但她说:“帮我留着吧,哪一天我开口,你再给我。”
“你不会开口。”他说。
“我爱惜你,也同样爱惜我自己。有些事情,‘不去得’比‘得到’更珍贵。活在世上,难免有遗憾,留一点惆怅给老的时候回味,也很好。如果我们无视于阻碍走入家庭,说不定一切的一切,破的破、碎的碎,最后变成仇人。我不要把你变成仇人,也不要你想到我只有恨,我不要你一小时、一天,我要你一生……平平安安。”
这就是结论了。
我要你一生。
平平安安。
我怎样写《骆驼祥子》-老舍
========================
我怎样写《骆驼祥子》-[[老舍]]
-----
从何月何日起,我开始写《骆驼祥子》?已经想不起来了。我的抗战前的日记已随同我的书籍全在济南失落,此事恐永无对证矣。
这本书和我的写作生活有很重要的关系。在写它以前,我总是以教书为正职,写作为副业,从《老张的哲学》起到《牛天赐传》止,一直是如此。这就是说,在学校开课的时候,我便专心教书,等到学校放寒暑假,我才从事写作。我不甚满意这个办法。因为它使我既不能专心一志的写作,而又终年无一日休息,有损于健康。在我从国外回到北平的时候,我已经有了去作职业写家的心意;经好友们的谆谆劝告,我才就了齐鲁大学的教职。在齐大辞职后,我跑到上海去,主要的目的是在看看有没有作职业写家的可能。那时候,正是“一二八”以后,书业不景气,文艺刊物很少,沪上的朋友告诉我不要冒险。于是,我就接了山东大学的聘书。我不喜欢教书,一来是我没有渊博的学识,时时感到不安;二来是即使我能胜任,教书也不能给我象写作那样的愉快。为了一家子的生活,我不敢独断独行的丢掉了月间可靠的收入,可是我的心里一时一刻也没忘掉尝一尝职业写家的滋味。
事有凑巧,在“山大”教过两年书之后,学校闹了风潮,我便随着许多位同事辞了职。这回,我既不想到上海去看看风向,也没同任何人商议,便决定在青岛住下去,专凭写作的收入过日子。这是“七七”抗战的前一年。《骆驼祥子》是我作职业写家的第一炮。这一炮要放响了,我就可以放胆的作下去,每年预计着可以写出两部长篇小说来。不幸这一炮若是不过火,我便只好再去教书,也许因为扫兴而完全放弃了写作。所以我说,这本书和我的写作生活有很重要的关系。
记得是在一九三六年春天吧,“山大”的一位朋友跟我闲谈,随便的谈到他在北平时曾用过一个车夫。这个车夫自己买了车,又卖掉,如此三起三落,到末了还是受穷。听了这几句简单的叙述,我当时就说:“这颇可以写一篇小说。”紧跟着,朋友又说:有一个车夫被军队抓了去,哪知道,转祸为福,他乘着军队移动之际,偷偷的牵回三匹骆驼回来。
这两个车夫都姓什么?哪里的人?我都没问过。我只记住了车夫与骆驼。这便是骆驼祥子的故事的核心。
从春到夏,我心里老在盘算,怎样把那一点简单的故事扩大,成为一篇十多万字的小说。
不管用得着与否?我首先向齐铁恨先生打听骆驼的生活习惯。齐先生生长在北平的西山,山下有许多家养骆驼的。得到他的回信,我看出来,我须以车夫为主,骆驼不过是一点陪衬,因为假若以骆驼为主,恐怕我就须到“口外”去一趟,看看草原与骆驼的情景了。若以车夫为主呢,我就无须到口外去,而随时随处可以观察。这样,我便把骆驼与祥子结合到一处,而骆驼只负引出祥子的责任。
怎么写祥子呢?我先细想车夫有多少种,好给他一个确定的地位。把他的地位确定了,我便可以把其余的各种车夫顺手儿叙述出来;以他为主,以他们为宾,既有中心人物,又有他的社会环境,他就可以活起来了。换言之,我的眼一时一刻也不离开祥子;写别的人正可以烘托他。
车夫们而外,我又去想,祥子应该租赁哪一车主的车,和拉过什么样的人。这样,我便把他的车夫社会扩大了,而把比他的地位高的人也能介绍进来。可是,这些比他高的人物,也还是因祥子而存在故事里,我决定不许任何人夺去祥子的主角地位。
有了人,事情是不难想到的。人既以祥子为主,事情当然也以拉车为主。只要我教一切的人都和车发生关系,我便能把祥子拴住,象把小羊拴在草地上的柳树下那样。
可是,人与人,事与事,虽以车为联系,我还感觉着不易写出车夫的全部生活来。于是,我还再去想:刮风云,车夫怎样?下雨天,车夫怎样?假若我能把这些细琐的遭遇写出来,我的主角便必定能成为一个最真确的人,不但吃的苦,喝的苦,连一阵风,一场雨,也给他的神经以无情的苦刑。
由这里,我又想到,一个车夫也应当和别人一样的有那些吃喝而外的问题。他也必定有志愿,有性欲,有家庭和儿女。对这些问题,他怎样解决呢?他是否能解决呢?这样一想,我所听来的简单的故事便马上变成了一个社会那么大。我所要观察的不仅是车夫的一点点的浮现在衣冠上的、表现在言语与姿态上的那些小事情了,而是要由车夫的内心状态观察到地狱究竟是什么样子。车夫的外表上的一切,都必有生活与生命上的根据。我必须找到这个根源,才能写出个劳苦社会。
由一九三六年春天到夏天,我入了迷似的去搜集材料,把祥子的生活与相貌变换过不知多少次——材料变了,人也就随着变。
到了夏天,我辞去了“山大”的教职,开始把祥子写在纸上。因为酝酿的时期相当的长,搜集的材料相当的多,拿起笔来的时候我并没感到多少阻碍。一九三七年一月,“祥子”开始在《宇宙风》上出现,作为长篇连载。当发表第一段的时候,全部还没有写完,可是通篇的故事与字数已大概的有了准谱儿,不会有很大的出入。假若没有这个把握,我是不敢一边写一边发表的。刚刚入夏,我将它写完,共二十四段,恰合《宇宙风》每月要两段,连载一年之用。
当我刚刚把它写完的时候,我就告诉了《宇宙风》的编辑:这是一本最使我自己满意的作品。后来,刊印单行本的时候,书店即以此语嵌入广告中。它使我满意的地方大概是:(一)故事在我心中酝酿得相当的长久,收集的材料也相当的多,所以一落笔便准确,不蔓不枝,没有什么敷衍的地方。(二)我开始专以写作为业,一天到晚心中老想着写作这一回事,所以虽然每天落在纸上的不过是一二千字,可是在我放下笔的时候,心中并没有休息,依然是在思索;思索的时候长,笔尖上便能滴出血与泪来。(三)在这故事刚一开头的时候,我就决定抛开幽默而正正经经的去写。在往常,每逢遇到可以幽默一下的机会,我就必抓住它不放手。有时候,事情本没什么可笑之处,我也要运用俏皮的言语,勉强的使它带上点幽默味道。这,往好里说,足以使文字活泼有趣;往坏里说,就往往招人讨厌。《祥子》里没有这个毛病。即使它还未能完全排除幽默,可是它的幽默是出自事实本身的可笑,而不是由文字里硬挤出来的。这一决定,使我的作风略有改变,教我知道了只要材料丰富,心中有话可说,就不必一定非幽默不足叫好。(四)既决定了不利用幽默,也就自然的决定了文字要极平易,澄清如无波的湖水。因为要求平易,我就注意到如何在平易中而不死板。恰好,在这时候,好友顾石君先生供给了我许多北平口语中的字和词。在平日,我总以为这些词汇是有音无字的,所以往往因写不出而割爱。现在,有了顾先生的帮助,我的笔下就丰富了许多,而可以从容调动口语,给平易的文字添上些亲切,新鲜,恰当,活泼的味儿。因此,《祥子》可以朗诵。它的言语是活的。
《祥子》自然也有许多缺点。使我自己最不满意的是收尾收得太慌了一点。因为连载的关系,我必须整整齐齐的写成二十四段;事实上,我应当多写两三段才能从容不迫的刹住。这,可是没法补救了,因为我对已发表过的作品是不愿再加修改的。
《祥子》的运气不算很好:在《宇宙风》上登刊到一半就遇上“七七”抗战。《宇宙风》何时在沪停刊,我不知道;所以我也不知道,《祥子》全部登完过没有。后来,《宇宙风》社迁到广州,首先把《祥子》印成单行本。可是,据说刚刚印好,广州就沦陷了,《祥子》便落在敌人的手中。《宇宙风》又迁到桂林,《祥子》也又得到出版的机会,但因邮递不便,在渝蓉各地就很少见到它。后来,文化生活出版社把纸型买过来,它才在大后方稍稍活动开。
近来,《祥子》好象转了运,据友人报告,它已被译成俄文、日文与英文。
我怎样写《猫城记》-老舍
========================
我怎样写《猫城记》-[[老舍]]
-----
自《老张的哲学》到《大明湖》,都是交《小说月报》发表,而后由商务印书馆印单行本。《大明湖》的稿子烧掉,《小坡的生日》的底版也殉了难;后者,经过许多日子,转让给生活书店承印。《小说月报》停刊。施蛰存兄主编的《现代》杂志为沪战后唯一的有起色的文艺月刊,他约我写个“长篇”,我答应下来;这是我给别的刊物——不是《小说月报》了——写稿子的开始。这次写的是《猫城记》。登完以后,由现代书局出书,这是我在别家书店——不是“商务”了——印书的开始。
《猫城记》,据我自己看,是本失败的作品。它毫不留情地揭显出我有块多么平凡的脑子。写到了一半,我就想收兵,可是事实不允许我这样作,硬把它凑完了!有人说,这本书不幽默,所以值得叫好,正如梅兰芳反串小生那样值得叫好。其实这只是因为讨厌了我的幽默,而不是这本书有何好处。吃厌了馒头,偶尔来碗粗米饭也觉得很香,并非是真香。说真的,《猫城记》根本应当幽默,因为它是篇讽刺文章:讽刺与幽默在分析时有显然的不同,但在应用上永远不能严格的分隔开。越是毒辣的讽刺,越当写得活动有趣,把假托的人与事全要精细的描写出,有声有色,有骨有肉,看起来头头是道,活象有此等人与此等事;把讽刺埋伏在这个底下,而后才文情并懋,骂人才骂到家。它不怕是写三寸丁的小人国,还是写酸臭的君子之邦,它得先把所凭借的寓言写活,而后才能仿佛把人与事玩之股掌之上,细细的创造出,而后捏着骨缝儿狠狠的骂,使人哭不得笑不得。它得活跃,灵动,玲珑,和幽默。必须幽默。不要幽默也成,那得有更厉害的文笔,与极聪明的脑子,一个巴掌一个红印,一个闪一个雷。我没有这样厉害的手与脑,而又舍去我较有把握的幽默,《猫城记》就没法不爬在地上,象只折了翅的鸟儿。
在思想上,我没有积极的主张与建议。这大概是多数讽刺文字的弱点,不过好的讽刺文字是能一刀见血,指出人间的毛病的:虽然缺乏对思想的领导,究竟能找出病根,而使热心治病的人知道该下什么药。我呢,既不能有积极的领导,又不能精到的搜出病根,所以只有讽刺的弱点,而没得到它的正当效用。我所思虑的就是普通一般人所思虑的,本用不着我说,因为大家都知道。眼前的坏现象是我最关切的;为什么有这种恶劣现象呢?我回答不出。跟一般人相同,我拿“人心不古”——虽然没用这四个字——来敷衍。这只是对人与事的一种惋惜,一种规劝;惋惜与规劝,是“阴骘文”的正当效用——其效用等于说废话。这连讽刺也够不上了。似是而非的主张,即使无补于事,也还能显出点讽刺家的聪明。我老老实实的谈常识,而美其名为讽刺,未免太荒唐了。把讽刺改为说教,越说便越腻得慌:敢去说教的人不是绝顶聪明的,便是傻瓜。我知道我不是顶聪明,也不肯承认是地道傻瓜;不过我既写了《猫城记》,也就没法不叫自己傻瓜了。
自然,我为什么要写这样一本不高明的东西也有些外来的原因。头一个就是对国事的失望,军事与外交种种的失败,使一个有些感情而没有多大见解的人,象我,容易由愤恨而失望。失望之后,这样的人想规劝,而规劝总是妇人之仁的。一个完全没有思想的人,能在粪堆上找到粮食;一个真有思想的人根本不将就这堆粪。只有半瓶子醋的人想维持这堆粪而去劝告苍蝇:“这儿不卫生!”我吃了亏,因为任着外来的刺激去支配我的“心”,而一时忘了我还有块“脑子”。我居然去劝告苍蝇了!
不错,一个没有什么思想的人,满能写出很不错的文章来;文学史上有许多这样的例子。可是,这样的专家,得有极大的写实本领,或是极大的情绪感诉能力。前者能将浮面的观感详实的写下来,虽然不象显微镜那么厉害,到底不失为好好的一面玻璃镜,映出个真的世界。后者能将普通的感触,强有力的道出,使人感动。可是我呢,我是写了篇讽刺。讽刺必须高超,而我不高超。讽刺要冷静,于是我不能大吹大擂,而扭扭捏捏。既未能悬起一面镜子,又不能向人心掷去炸弹,这就很可怜了。
失了讽刺而得到幽默,其实也还不错。讽刺与幽默虽然是不同的心态,可是都得有点聪明。运用这点聪明,即使不能高明,究竟能见出些性灵,至少是在文字上。我故意的禁止幽默,于是《猫城记》就一无可取了。《大明湖》失败在前,《猫城记》紧跟着又来了个第二次。朋友们常常劝我不要幽默了,我感谢,我也知道自己常因幽默而流于讨厌。可是经过这两次的失败,我才明白一条狗很难变成一只猫。我有时候很想努力改过,偶尔也能因努力而写出篇郑重、有点模样的东西。但是这种东西总缺乏自然的情趣,象描眉擦粉的小脚娘。让我信口开河,我的讨厌是无可否认的,可是我的天真可爱处也在里边,Aristophanes(阿里斯多芬)的撒野正自不可及;我不想高攀,但也不必因谦虚而抹杀事实。
自然,这两篇东西——《大明湖》与《猫城记》——也并非对我全无好处:它们给我以练习的机会,练习怎样老老实实的写述,怎样瞪着眼说谎而说得怪起劲。虽然它们的本身是失败了,可是经过一番失败总多少增长些经验。
《猫城记》的体裁,不用说,是讽刺文章最容易用而曾经被文人们用熟了的。用个猫或人去冒险或游历,看见什么写什么就好了。冒险者到月球上去,或到地狱里去,都没什么关系。他是个批评家,也许是个伤感的新闻记者。《猫城记》的探险者分明是后一流的,他不善于批评,而有不少浮浅的感慨;他的报告于是显着象赴宴而没吃饱的老太婆那样回到家中瞎唠叨。
我早就知道这个体裁。说也可笑,我所以必用猫城,而不用狗城者,倒完全出于一件家庭间的小事实——我刚刚抱来个黄白花的小猫。威尔思的The first man in themoon(《月亮上的第一个人》),把月亮上的社会生活与蚂蚁的分工合作相较,显然是有意的指出人类文明的另一途径。我的猫人之所以为猫人却出于偶然。设若那天我是抱来一只兔,大概猫人就变成兔人了;虽然猫人与兔人必是同样糟糕的。
猫人的糟糕是无可否认的。我之揭露他们的坏处原是出于爱他们也是无可否认的。可惜我没给他们想出办法来。我也糟糕!可是,我必须说出来:即使我给猫人出了最高明的主意,他们一定会把这个主意弄成个五光十色的大笑话;猫人的糊涂与聪明是相等的。我爱他们,惭愧!我到底只能讽刺他们了!况且呢;我和猫人相处了那么些日子,我深知道我若是直言无隐的攻击他们,而后再给他们出好主意,他们很会把我偷偷的弄死。我的怯懦正足以暗示出猫人的勇敢,何等的勇敢!算了吧,不必再说什么了!
无个性的男人-[[星新一]]
-----
看上去,A氏是个极其普通的人。个子不高也不矮,脸长得毫不出众,一举一动,甚至连走路姿式也叫人难以发现有一点特别之处。太不显眼了。
不,不仅是外表,就连性格也是如此。简直就不能说他具有什么独立见解和个性。
那么个家伙,在现代社会里怕不会有什么用场的吧。很多人这样想。但,A氏却过着很豪华的生活。
事情是这样……
A氏挎着皮包,走访某旅馆的一个房客。敲敲门,里边传出了声音:“谁呀?……”
“我是‘变色龙’商会的,为了和您取得联系,特来拜访。”
A氏回过话,门开了,他被迎了进去。在房里的人是四十上下岁,身体结实,动作和说话的语调都显得有些忙乱的男人。
那男人向A氏说:
“啊,请坐在那张椅子上,你就是现场作证人吧①?”——
①专门扮作被告人,在某案件发生时,在别的场合出现,以便使目击人证明案件发生当时,被告人不在现场——
“对,是的。为您效劳,我深感荣幸。”
“作我的替身,真是绝妙的买卖,不过,怎么作这个替身,请略加解说一下。
“好吧。干这件事简单,我可以扮得和委托人一模一样,在他所指定的时间和地点走来走去。当然啦,这瞒不过家人和亲友的眼目,可是我担保在场的人事后都会在证词里说那个人就是委托人。”
“装扮成是我,不是容易事吧!
那人说完,A氏照原样又叙说了一遍:
“装扮成是我,不是容易事吧!”
从说话的口吻到声音的高低,真是维妙维肖。初次见面在这么短暂的时间里,就掌握了这么些要领,不禁使那个男人感到惊奇。
“这简直妙极了。听来仿佛是自己的录音。你在哪儿学的?”
“在哪儿也没学。不知什么时候,自然而然就变成这样了。我毕业的学校,学生都是一个模子铸出来的,这是教育方针的缘故。根本不培养独立的才能。”
“的确如此。”
“毕业后,我到一家银行就职,可那是发挥不出一点独创性的岗位。一面工作,一面立志当个作家。写了大量的稿子却全都成了废纸。有人指责说这些稿子都是现成作品的翻版。”
“是啊!”
“我想改行,求了电影界的熟人。被录用做了一名替身演员,虽然实在是乏味,可这段时间里,技术还是提高了嘛。这样有一天突然心血来潮,开始想干起这个买卖来。试着干了一阵,这件工作对我满合适。连自己讨厌过的社会经验,此刻,都变得对我非常有用了。”
“一直都很顺手吗?”
“托您福,干这行当的人还真不少,没有不景气的迹象。我光用嘴说,怕您不会信以为真吧,洽谈之前,不妨先看着我的本事。”
A氏从皮包里拿出道具。在自己脸上化起妆来。并且把对方的上衣借来穿上,模拟对方表情、动作的特征。随后,问:
“怎么样,有没有不到的地方……”
“唉哟,简直是一对挛生子在相会。我似乎是在照镜子。就‘百面相’①的技艺说,也够上第一流的呢。”
①面孔做各种表情的表演技艺。
“尽管如此,可收入却是提不起来的。”
“嗯,可也是。好,拜托您了,不过事后别添什么麻烦呐。”
“那自然,我得了钱,办完事,马上销声匿迹。至于目睹我在场的证人如何去利用,这,我是极不过问的。正因为如此,我才取得了主顾们的信任。”
“你冒充别人,不想知道那个人为什么叫你这样干吗?”
“还是不打听的好,耳不听,心不烦。比如说,知道是去干杀人的勾当,我的心情怎么好受得了,何况这会触犯刑律呢。”
“啊,明白了。请你在明天傍晚,六点到七点之间,到从这扇窗子就望得见的那家西餐馆就餐。只要做到这点就可以了。”
“好吧,到时候我故意向服务员打听钟点,给他点小费,多少能留下点印象吧。”
“你考虑得真是无懈可击了啊……”
于是,一笔交易达成了。
第二天,A氏按照约定的时间,装扮成委托人的模样,来到那个西餐馆。他一边暗自揣想现在那个男人在干什么,一边有意地向周围的人表明自己的存在,不紧不慢地进餐。
约定的一个小时过去了。A氏走出店门。这是何等惬意的赚钱买卖呀。
可是,就在这个当口,从两侧各伸出两只强而有力的手把他紧紧地抓住,两边响起了男人们任沉的语声。
“我们是警察,请到警察署走一趟。”
A氏一面苦苦挣扎,一面说:
“到底要干什么?我可是什么坏事也没干哪。”
“不知羞耻的家伙!前不久,一个强盗在宝石店闭店的时候伺机闯了进去进行抢劫。方才我们接到告密电话说,那个罪犯正在这家西餐馆进餐。为了慎重起见,我们还找来了那个强抢案的目击人,暗地观察,断定你就是那个犯人。”
“哪里话,这是误会。”
“有什么辩解的话,请到警察署去慢慢地讲吧。”
“这、这……”
A氏被押解着,边走边叹气。他想:似乎能争取时间逃走,要让警察相信自己冤屈,只能把和委托人的事情原原本本地说出来了。
唉呀,这一回可真碰上个冷酷的顾客。
-----
(译自讲谈文库1956年版《埃诺氏的游园地》)
郎享伯译——
无理之数-言叔夏
某小说家说童年初习数字时,在睡觉的床头总会从模糊的意识底层里拉起一条隐形的绳子,将这些看不见的数字 1、2、3、4 地往下排去。8、9、10 大概就在床尾边,11、12、13 已来到了客厅大门前(有时尚且回头与床边的 1、2、3 并排成行),顺着公寓的楼梯回旋而下,从辽宁街到南京东路、从南京东路到整个城市数不清的路口,仿佛不来梅的吹笛手与老鼠似的;这些从二位数变成三位数、从三位数膨胀成数以亿万计的数字们,就这样倒转变成了远方黑暗夜空里的星星,被整条悬浮的绳索支撑起来。
我记得在敲打论文的夜里读到这段时,忍不住会心笑了起来。因为小时候我也有一条非常类似的绳索。那时我们住在高雄与屏东交界的一个小镇上,而我们的房子又在这个边缘小镇的最边缘。我记得幼年时的夏天黄昏,母亲常常带我去散步。沿着房子旁的小路往山里走,起先会遇见林投树,接着树荫渐渐浓密了起来。夏日午后的雷声从极遥远极遥远的地方传递过来。可是我们什么也看不见。树林蓊郁地包围着我们,将我们兜头罩下。母亲与我的脸都阴暗了。雨要下下来了吗?又或者这只是一个关于下午的幻觉?童年的我担心地想着。
我指着山路两旁树枝上垂挂着的一袋一袋黑色的物体,问母亲说:
“那是什么?”
四周忽然阴翳。树林飘盪了起来,母亲眯着河童一般的脸孔对我说:
“是猫啊。”
我已经忘记那个夏天的傍晚,母亲和我究竟淋湿了没有,又或者我们其实一直被雨围困在那座森林,和许多的猫在一起。那时的我既不知道山路的尽头是什么,也不知道树林的外面有些什么。我们总是骑很远的车,到那像是夏季雷雨远来的小镇:买书,更多时候是买回一些卫生纸沙拉油之类的物事。在母亲的机车后座,公路的路灯一排一排地后退,我曾想过这些路灯就这样一路无止尽地倒退下去,像一条绳索,只要走着走着我们就会到美国。我还记得小学三年级的自然课,第一次知道宇宙黑洞的事。放学回家后我问奶奶:
“你知道我们住的这个地方,上面是什么吗?”
奶奶摇了摇头。我于是得意地说:
“是一个叫做宇宙的地方,有星星、月亮和太阳,而我们脚下的这个地面,其实是一颗圆型的大球。”
奶奶笑了起来。露出镶嵌的假牙,对我说:
“我们所住的地方上面,什么也没有。”
奶奶死的时候身体弯成一个 7。像一把拐杖。父亲败光了所有的家产,于是我们拥有一个很脆弱的葬礼。葬礼结束后父亲就离家出走了。讨债的人将我们的窗户全数拆走,泼上(他们可能精心挑选过颜色的)油漆。很多年以后,母亲告诉我关于奶奶的一切她已经全都忘记了,包括她们是如何在一间屋子里争吵或对峙,交锋着属于女性的心机。只记得奶奶被装进棺木前的身体。那么弯曲,像一枚鹦鹉螺,漂亮地发散着某种淡粉红。母亲说奶奶只有死掉时才会那么地漂亮过,像一个婴儿。肉身是 7,那么与死衔接的胎儿就是 8;8 是两个迴旋螺类往下交缠降落,从 A 到 B,从 B 到 A,莫比乌斯环。母亲后来用这两个数字签了六合彩(且受到牌支组头的嘲笑因为连号几乎是一件不可能的事),没想到竟得到一笔钱,将家里被砸烂的窗户全都换掉。某天回家,母亲指着那些和四周墙壁的败旧程度不成比例的全新窗框对我说:
“这一扇是 7,那一扇是 8,奶奶就藏在这些窗户里。”
我不知道奶奶是不是真的藏在这些窗户里。很多年以后,当我终于离开童年时代的那座小镇,那座挂满蜷曲身体的猫的森林,不知道为什么,总有一种整个森林都吊挂着一个又一个奶奶的错觉。奶奶的身体在树下被悬宕得好长好长,像一个弹簧尾端因拉扯而终于失重的 7,垂着小小的白色的头。
我终于离开这座树林,在大学的课堂里学习艰难的知识,写晦涩的论文。背起厚重的笔电爬一段几近垂直的坡,抵达山坡上的研究室,谈论那些与我无关的事物。冬天的城市尖锐严厉,季风吹来简直是一种指责。整个冬天的早晨我越过广场石子路上灰扑扑的鸽群,到一个阴暗的图书馆。图书馆里有极高的书架和狭窄的走道,书库里的书轻轻一吹就有灰尘雪花般地飘散在阳光里,悬浮降落。
从光里降落,降落在光谱渐层的暗影里,因为理解暗影才理解光。才知道光的内里有黑暗。所有的物事光天化日,在光里只是无干。我学习到将一颗苹果从桌上拿开,桌子并不会产生剪影般的凹洞。我对那样的苹果感到非常羡慕。因为我试着将离家出走的父亲作为一颗苹果从心上移走,胸口的世界却莫名地整个空掉了。只剩下父亲剪影般的轮廓。从前我以为那仅是苹果倒映在心上的阴影,后来某日伸了手进去掏才知道那其实是一个洞。洞里有风,呼呼地通过,发出呜呜的声音。
而其实那只是我中学时代写下的一段句子。在一个离家遥远的教会中学,午睡时间我老是趴在桌下的抽屉里写着没有人明白的小说。在放课前的第八节课,我钻进空无一人的教会大楼,大楼里有一部老旧的电梯,往上爬升到最顶楼就有了一个小阁楼。阁楼的窗外可以看见远处的球场上,奔跑的人群,缓慢运球的学生,还有那些漫步在圆弧形操场上的老人与狗。靠海的城市高楼多风,只听得风吹得制服的裙摆啪啦啪啦作响。还有洞。别针般地别在胸口的左侧,风一吹整个洞口就鸣笛般地作响。休休。休休。
曾经有很长的一段时间,我觉得自己并没有因为父亲的事而受到任何的一点伤害。无论那是倔强,还是仅仅只是一种自持。因为早在父亲离家之前,我便已经拥有了那凿刻在身体某处的洞。父亲只是从他自己人生的轨道上倾斜偏移,不慎失足坠入了这个洞口,被猪笼草般的这个洞穴给整个吞没,消化吸收。想起父亲,还有这个洞时,我总是有一种非常饥饿的感觉。好像从来没有真正吃饱过。但我喜欢这个洞,就一直保持着空空的状态,像一只袋子,可以装盛许多东西,可以在洞里藏匿一个小孩,可以随手就拉出一条手帕或者兔子来。我与这个洞穴,一起穿越了故乡山里那片挂满猫的树林;穿越离家极近、母亲日日骑车去眺望的海。有时它会像一个皮囊那样可以从内里往外整个翻出,将我反噬,把我密密地包裹,护持着我迁徒来去,如同童年时的那条数字绳索,从 1、2、3、4…… 乃至于无止无尽,穿时越空。
而绳索的数字之中,总也有那样一两个打结窒碍的号码,无论如何也无法被我以这个洞穴消化除尽。当我试图将它吸纳进洞里,它总是繁衍增生出无尽延伸的余数,仿佛自体分裂的细菌。隐喻牵连着隐喻。话语堆叠着话语。质量守恒。物质不灭。目下的一整条公路蜿蜒直至天际,我已在离家极远极远的异地。
我想起几年以前的某一天,父亲忽然来到我生活的城市。那时我与父亲已经许久没有见面。没有人知道他去了哪里,在什么地方做什么样的事,和什么人在一起。我带父亲到住处附近的学区餐馆,面对面坐了下来。等待菜肴上来之前,父亲一直非常侷促,嗫嚅地问我什么时候回家之类的话语。我还记得那是一家灯色昏暗的简餐店,卖着小火锅之类的饭食。店里的灯光把我们的影子拉得极长,低低地垂挂在墙上。我与父亲,就像大学城里随处可见的亲父与儿女,对坐在同一张餐桌的两侧,仿佛对弈。
晚餐结束,夜色昏暗。仿彿整个夜晚的浓稠黑色都在等待着这样的一刻。父亲终于对我开口,说:“…… 我来台北,看一个同事。他太太月初过世了。” 父亲的嘴唇微微地颤抖:“所以…… 所以你能不能借我几千块,包奠仪用……”
我不知道这是不是一个谎,还是父亲自己杜撰出来的一个故事。还有那些虚构的死亡与人物。这些年,母亲总是告诉我:不要相信你爸说的任何一句话。父亲究竟是怎样把自己的人生活成了一则小说?而关于虚构和死亡,你比起其他行业的同年龄人,何尝不更清楚地理解,所有的虚构既在死亡之后,也在死亡之前。虚构是丧礼,有时你执行它简直祭司般地行礼如仪。是凭吊吗?你比谁都明白,还是仅仅只是一种布置?像一种激活的仪式,对死亡说:醒来吧,请醒来吧!请醒过来看看我所装饰的世界!
我把皮夹里的钞票拿了出来,并且问父亲今晚住在哪里?要不要到我的房间来睡(但其实心里想着的是最好不要吧)?父亲告诉我没有关系,他会睡在台北的一个朋友家里。父亲且对我描述那个朋友就住在龙江路行天宫后面一个非常好的地方。我点了点头,我知道父亲在台北是没有任何朋友的。
我忽然想起国中时代父亲最后一次教我数学。童年时算不出习题、会对我掀桌咆哮的父亲,整个晚上和我在同一道题目周旋不去,无论如何也算不出解答上的数字。计算纸上画满红色的数字,父亲的手指沾满晕染的墨渍;√2 是 2 的头上戴着的一顶大帽子。像魔术师。我心里真想跟他说:不要把帽子掀开,否则帽子里就会拉出一连串根本无从理解的数字来。我还记得摇晃的日光灯管下父亲终于疲惫的脸孔,有着一种我彼时尚未能理解的成人的凹陷。他白日必须攀爬极高的天车,到炼钢厂里六七层楼高的地方去修理开关。
“爸爸没念过多少书。” 父亲这样对我说。
“以后的作业,我再也不能教你了。”
除不尽的命运。还有时间。√2 打开是 1.414213562,仿佛未来一直一直来。父亲那句话的意思是:就送你到这里了,以后的日子,你要多保重!
我们离开了餐馆,走进城市里满布着霓虹夜招的夜晚。华灯初上,漂浮而摇晃的夜色,像一个永远做不完的梦。我想起远方家乡的树林里,那些树枝上一丛一丛吊挂的猫,是否也正萤火虫般地点起了银色的灯笼?
那个夜晚,父亲的身影,很快地就被这个城市街道上熙来攘往的人群淹没了。我不知道他最终会否被这城市几千几万的人潮带到什么样的地方,也不知道父亲的手里是否也握有一根守护着他的数字绳索,可以保他穿街越弄,不受妖邪侵扰。我只是背转过身,与父亲走在同一条街两个完全悖反方向的道路上,怀抱着一种对任何人类都会有的担忧与哀愁。忽然,就像一个女儿般地沿路哭了起来。
吴诗玉/萎缩的青春
***
她又关进房里了。刚才吃了一碗面。轻轻打开塑料袋,不然窸窸窣窣的声音会引来怀疑。她张嘴,食指熟练地往喉咙伸去。呃——兀自带着温热的面条混合着胃液和唾液从胃里攀上喉咙,再往袋子冲泻而下。头颅般大小的袋子一下子就填满了。她细心地给鼓胀的塑料袋套多一个袋子。她不希望狼狈不堪的经历再次重演。
上一回刚绑好一包袋子,不想母亲把她叫出房去。她慌乱地将一大包秽物塞入床底,再推往深处,仿佛幽暗的床底有一只能把一切不能浮出水面的异常举止吞噬的兽。再回到房里,空气中已充斥酸腐的气味,探手入床底,那只没有被兽吞掉的袋子干瘪了许多,是袋子破了小孔,褐色液体浸湿了床底光洁的瓷砖,腐臭阵阵钻入七孔,她被熏得乱了方寸。最后,她用了半卷卫生纸才把粘稠呕吐物揩拭干净。
外头没人。午后的时间,大家几乎都在午睡,老房子浸在慵懒炎热的寂静中。她悄无声息地提着柔软温热又沉甸甸的袋子来到后院,打开垃圾桶盖,里面是一包包母亲绑好的垃圾袋子。她娴熟地翻动着垃圾桶,有几包袋子已长蛆,浅黄色肥硕的身躯蠕蠕挪动。她特别喜欢长虫子的袋子。让人厌恶的蛆虫能为她守护秘密。她给一包袋子松绑,拨开袋子内的垃圾,任蛆虫爬上手骨凸显的手掌,再把呕吐物混入其中后绑好。盖上垃圾桶,把污秽恶臭深埋里头,就永远没有人发现。她知道垃圾桶不会泄密。
每日总要进行一次充满罪恶感但又粘连着解脱的快乐的举止。之前是隐入厕所,食指灵巧地引着胃里的饭菜鱼肉倾泻而出,掏空了自己就是战胜了脂肪,她满意地往马桶吐了一口唾沫,用力抽水后看着秽物连着心中的苦涩一并消失。但老房子只有一间厕所,七名成员所有的解放只有这个私密空间,要轮上只能等待。躲在暗处的声音会不断地提醒她:食物转化成脂肪的速度是等不及的。她陷入惶恐,进食的罪恶感和他嫌弃厌恶的眼神牢牢掐着她的脖子,她只能拼命寻找机会解放自己的身体和灵魂。
锁上房门,她对镜掀起上衣,青春飞扬的胴体呈现年老色衰的枯干皱缩。镜中是骨架粘连表皮的躯体,胸前扁平似平静湖面掀不起波澜。15岁那年,她遇见一个自己愿意掏出心肺的男生,只是不成熟的爱总会终止于任何理由。因为他不喜欢,她也开始讨厌自己微胖的身体。她的青春小鸟刚要展翅飞翔,她用厌食的弹弓折损了小鸟双翼,飞不起来的青春渐渐萎缩成残缺的灵魂。母亲把瘦骨嶙峋的她拖进诊所数次又调养了近一年,她才稍稍养回了一点气色。只是快乐的15岁早在他离去的那天开始崩裂,一块块的碎片把她伤得体无完肤,再努力拼凑也回不去从前了。
洗了手,午睡的人鼾声正浓。她坐在书桌开始温习。总要隐藏好黑暗的灵魂,才能把光明的自己摆放在阳光下。厌食后的一年,她的灵魂和肉体总是处于剥离的状态,以至于后来,她在身体内豢养了一头双面贪食兽,它无止境地需索食物,她只能不停地暴饮狂食来满足它的无底洞。但塞满食物后的它又暴躁地捶胸顿足,焦虑急切地寻觅出口把食物推出体外。她和它都不会允许食物侵入体内构建脂肪的堡垒并占领基地。唯有这样她才觉得自己不会再次受伤害。
抠喉催吐的几年,家人不是没有怀疑。她总会抢在家人循着蛛丝马迹抓到证据绳索之前就把所有罪证销毁。虽成功躲过所有探测雷达,但母亲怀疑的眼神和她心惊胆跳的逃离几乎戳穿她小心掩盖在垃圾桶里的秘密。不能浮出水面的异常举止让她感到窒息,但她无法停止摧残自己,那是她为萎顿的生命寻得解脱的无限快乐。青春的胴体停滞在不断吞食吐出的时间轴里。她被自己困在萎缩干瘪的躯壳里,即便外头阳光明媚,她也看不见一丝光。
老房子的后院有一条没有铁盖的水沟,石灰剥落龟裂又长年苔藓覆盖的沟渠一直延伸到没有尽头的幽暗处,从盥洗刷洗冲洗的所有排水孔接来的脏水都会流到住家稍远的小丛林就没了去路,浑浊冒泡的死水就一直静止不动,像她停止发育又拒绝成长的灵魂。垃圾桶不再适合守密后,她把秘密倾倒入沟渠,再舀起一桶桶清水把它们冲入幽暗的丛林,让本就该配成一对的褐色呕吐物和污浊死水融为一体,此生再也不分你我。她咯咯地笑了,笑出了眼泪。
她以为脏臭的沟渠是没有人愿意触碰的角落,但母亲还是察觉了她的异常。那天未及倒入沟渠,母亲循声而至,她向着树林的方向使劲一抛,秽物绿色的袋子在空中划出弧形后掉落丛林污水中。不及细看,她落荒而逃。那天,母亲看她的眼神里藏着凄苦,隐着悲伤。她惊觉母亲其实一直都站在她的秘密前方,用最温柔的方式守护她。只是她深陷在自己挖掘的悲伤洞穴里,以致多年来竟没有发现洞口等待的母亲。
后来,她总会想起那包绿色袋子装载的秽物,被雨水冲走了吗?还是消失在污水中了?乘着没人留意她总会跑入丛林。不管她什么时候前来,那包绿色袋子恒常出现在眼里,浑浊静止的污水把它裹成了永远,它绿色的外装企图伪装成一片掉落的叶子,在草木森森的丛林里躺成永恒。
很多年后的梦里,那包鼓胀的绿色塑料袋没有停止漂流,它在通往沟渠至更深远的茂密丛林里悬浮,肿胀的袋子有腐烂恶臭传开,她掩鼻欲逃离,却惊觉自己站在老家的丛林深处,迷失了方向。
作者 : 吴诗玉
文章来源 : 星洲日报 2021-02-16
[[西西弗的神话 - 阿尔贝·加缪|https://www.kanunu8.com/files/little/2012/09-06-8135.html]]
西西弗的神话
来源: 作者:[[阿尔贝·加缪]] 发布时间:2012-09-06
阿尔贝·加缪作品全集
-----
诸神处罚西西弗不停地把一块巨石推上山顶,而石头由于自身的重量又滚下山去,诸神认为再也没有比进行这种无效无望的劳动更为严厉的惩罚了。
荷马说,西西弗是最终要死的人中最聪明最谨慎的人。但另有传说说他屈从于强盗生涯。我看不出其中有什么矛盾。各种说法的分歧在于是否要赋予这地狱中的无效劳动者的行为动机以价值。人们首先是以某种轻率的态度把他与诸神放在一起进行谴责,并历数他们的隐私。阿索玻斯的女儿埃癸娜被朱庇特劫走。父亲对女儿的失踪大为震惊并且怪罪于西西弗,深知内情的西西弗对阿索玻斯说,他可以告诉他女儿的消息,但必须以给柯兰特城堡供水为条件,他宁愿得到水的圣浴,而不是天火雷电。他因此被罚下地狱,荷马告诉我们西西弗曾经扼住过死神的喉咙。普洛托忍受不了地狱王国的荒凉寂寞,他催促战神把死神从其战胜者手中解放出来。
还有人说,西西弗在临死前冒失地要检验他妻子对他的爱情。他命令她把他的尸体扔在广场中央。不举行任何仪式。于是西西弗重堕地狱。他在地狱里对那恣意践踏人类之爱的行径十分愤慨。她获得普洛托的允诺重返人间以惩罚他的妻子。但当他又一次看到这大地的面貌,重新领略流水、阳光的抚爱,重新触摸那火热的石头、宽阔的大海的时候,他就再也不愿回到阴森的地狱中去了。冥王的诏令、气愤和警告都无济于事。他又在地球上生活了多年,面对起伏的山峦,奔腾的大海和大地的微笑他又生活了多年。诸神于是进行干涉。墨丘利跑来揪住这冒犯者的领子,把他从欢乐的生活中拉了出来,强行把他重新投入地狱,在那里,为惩罚他而设的巨石已准备就绪。
我们已经明白:西西弗是个荒谬的英雄。他之所以是荒谬的英雄,还因为他的激情和他所经受的磨难。他藐视神明,仇恨死亡,对生活充满激情,这必然使他受到难以用言语尽述的非人折磨:他以自己的整个身心致力于一种没有效果的事业。而这是为了对大地的无限热爱必须付出的代价。人们并没有谈到西西弗在地狱里的情况。创造这些神话是为了让人的想象使西西弗的形象栩栩如生。在西西弗身上,我们只能看到这样一幅图画:一个紧张的身体千百次地重复一个动作:搬动巨石,滚动它并把它推至山顶;我们看到的是一张痛苦扭曲的脸,看到的是紧贴在巨石上的面颊,那落满泥士、抖动的肩膀,沾满泥士的双脚,完全僵直的胳膊,以及那坚实的满是泥士的人的双手。经过被渺渺空间和永恒的时间限制着的努力之后,目的就达到了。西西弗于是看到巨石在几秒钟内又向着下面的世界滚下,而他则必须把这巨石重新推向山顶。他于是又向山下走去。
正是因为这种回复、停歇,我对西西弗产生了兴趣。这一张饱经磨难近似石头般坚硬的面孔已经自己化成了石头!我看到这个人以沉重而均匀的脚步走向那无尽的苦难。这个时刻就像一次呼吸那样短促,它的到来与西西弗的不幸一样是确定无疑的,这个时刻就是意识的时刻。在每一个这样的时刻中,他离开山顶并且逐渐地深入到诸神的巢穴中去,他超出了他自己的命运。他比他搬动的巨石还要坚硬。
如果说,这个神话是悲剧的,那是因为它的主人公是有意识的。若他行的每一步都依靠成功的希望所支持,那他的痛苦实际上又在那里呢?今天的工人终生都在劳动,终日完成的是同样的工作,这样的命运并非不比西西弗的命运荒谬。但是,这种命运只有在工人变得有意识的偶然时刻才是悲剧性的。西西弗,这诸神中的无产者,这进行无效劳役而又进行反叛的无产者,他完全清楚自己所处的悲惨境地:在他下山时,他想到的正是这悲惨的境地。造成西西弗痛苦的清醒意识同时也就造就了他的胜利。不存在不通过蔑视而自我超越的命运。
如果西西弗下山推石在某些天里是痛苦地进行着的,那么这个工作也可以在欢乐中进行。这并不是言过其实。我还想象西西弗又回头走向他的巨石,痛苦又重新开始。当对大地的想象过于着重于回忆,当对幸福的憧憬过于急切,那痛苦就在人的心灵深处升起:这就是巨石的胜利,这就是巨石本身。巨大的悲痛是难以承担的重负。这就是我们的客西马尼之夜。但是,雄辩的真理一旦被认识就会衰竭。因此,俄狄浦斯不知不觉首先屈从命运。而一旦他明白了一切,他的悲剧就开始了。与此同时,两眼失明而又丧失希望的俄狄浦斯认识到,他与世界之间的唯一联系就是一个年轻姑娘鲜润的手。他于是毫无顾忌地发出这样震撼人心的声音:“尽管我历尽艰难困苦,但我年逾不惑,我的灵魂深邃伟大,因而我认为我是幸福的。”索福克勒斯的俄狄浦斯与陀思妥耶夫斯基的基里洛夫都提出了荒谬胜利的法则。先贤的智慧与现代英雄主义汇合了。
人们要发现荒谬,就不能不想到要写某种有关幸福的教材。“哎,什么!就凭这些如此狭窄的道路……?”但是,世界只有一个。幸福与荒谬是同一大地的两个产儿。若说幸福一定是从荒谬的发现中产生的,那可能是错误的。因为荒谬的感情还很可能产生于幸福。“我认为我是幸福的”,俄狄浦斯说,而这种说法是神圣的。它回响在人的疯狂而又有限的世界之中。它告诫人们一切都还没有也从没有被穷尽过。它把一个上帝从世界中驱逐出去,这个上帝是怀着不满足的心理以及对无效痛苦的偏好而进入人间的。它还把命运改造成为一件应该在人们之中得到安排的人的事情。
西西弗无声的全部快乐就在于此。他的命运是属于他的。他的岩石是他的事情。同样,当荒谬的人深思他的痛苦时,他就使一切偶像哑然失声。在这突然重又沉默的世界中,大地升起千万个美妙细小的声音。无意识的、秘密的召唤,一切面貌提出的要求,这些都是胜利必不可少的对立面和应付的代价。不存在无阴影的太阳,而且必须认识黑夜。荒谬的人说“是”,但他的努力永不停息。如果有一种个人的命运,就不会有更高的命运,或至少可以说,只有一种被人看作是宿命的和应受到蔑视的命运。此外,荒谬的人知道,他是自己生活的主人。在这微妙的时刻,人回归到自己的生活之中,西西弗回身走向巨石,他静观这一系列没有关联而又变成他自己命运的行动,他的命运是他自己创造的,是在他的记忆的注视下聚合而又马上会被他的死亡固定的命运。因此,盲人从一开始就坚信一切人的东西都源于人道主义,就像盲人渴望看见而又知道黑夜是无穷尽的一样,西西弗永远行进。而巨石仍在滚动着。
我把西西弗留在山脚下!我们总是看到他身上的重负。而西西弗告诉我们,最高的虔诚是否认诸神并且搬掉石头。他也认为自己是幸福的。这个从此没有主宰的世界对他来讲既不是荒漠,也不是沃士。这块巨石上的每一颗粒,这黑黝黝的高山上的每一颗矿砂唯有对西西弗才形成一个世界。他爬上山顶所要进行的斗争本身就足以使一个人心里感到充实。应该认为,西西弗]是幸福的。
# 下到小船里_九故事
[[塞林格]]
------
晚秋时节一个小阳春天气的下午,四点刚过。女仆桑德拉紧抿嘴唇,从厨房那临湖的窗子边走开,从中午到现在,她这样做已不下十五、二十次了。这一回走开时,她不自觉地松开又重新系上她围裙的带子,试试对她那肥大的腰身松到什么程度才算最合适。接着她回到那张搪瓷面的桌子旁,让自己那穿一身新用人服的身子在斯内尔太太对面座位上坐下。斯内尔太太已经打扫完房间,熨烫好衣服,正准备享用她照例在走一段路去公共汽车站之前要喝的那杯茶。斯内尔太太帽子已经戴好。这依然是那顶有趣的平顶黑毡帽,这帽子她戴了不光是这整个夏天,而且还包括以往的三个夏天——它经历了多少次热浪和生活中风风雨雨,也不知在多少块熨板上被压过烫过,让多少个真空吸尘器处理过。那块 “卡内基帽店” 的招牌仍然贴在帽子内沿,颜色退了可是 (如果可以这样说的话) 还死守着阵地。
“我才不着这份急呢,” 桑德拉说,已不知是第五次还是第六次了,这话既是对斯内尔太太也是对她自己说的。“我下定决心不去操心了。我扯得上吗?”
“一点儿不假,” 斯内尔太太说。“我就不着急。我真的没操这份心。把我的提包递给我,亲爱的。”
一只真皮提包平放在餐具架上,很破旧了,可是里面的商标也跟斯内尔太太帽子内沿的那块同样显赫。桑德拉不用站起来就拿得到。她把提包隔着桌子递过去。斯内尔太太打开包,取出一包带薄荷味的香烟和一小盒鹳鸟俱乐部发的火柴。
斯内尔太太点燃一根香烟,接着把她的茶杯举到唇边,可是她又立即将杯子放回茶碟里去。“这荼若是还不快点凉,我真的要搭小上我的公共汽车,。” 她抬眼朝桑德拉看去,只见对面那人正心事重重地冲着墙上成排挂着的铜平底锅发呆。“快别操心了,” 斯内尔太太用命令式的口气说道。“操心又有啥用?他也许跟他娘说了也许没说。不就那么回事吗。操心又有啥用?”
“我倒不是为这操心,” 桑德拉回答说。“再怎么着也轮不到我呀。只不过会把你逼疯的,这孩子悄没声满屋子转。那劲头。你根本听不见他的动静,你懂吗? 我是说任谁也听不见,你懂吗? 头两大吧我正剥豆子——就在这桌子旁——我险些踩着了他的手。他就坐在桌子底下。”
“哼,那我也不会为这操心。”
“我的意思是你在他跟前时说一句话都得掂量掂量,” 桑德拉说。“这真能把人逼疯喽。”
“这荼我还是没法喝,” 斯内尔太太说 -…” 那倒真让人受不了,要是你说一个字都得掂量,生怕出什么事的话。”
“真能把人逼疯喽 j 我是有啥说啥。一多半的时间里我已经是半疯半癫了。” 桑德拉习惯性地掸了掸她想像中的膝头上的面包屑。她鼻子里哼了一声:“才四岁大的小毛孩!”
“他看上去倒是模样挺俊的孩子,” 斯内尔太太说。“那双棕黄大眼睛跟别的部位。”
桑德拉又哼了一声。“他那鼻子,长大了也准跟他爸的一个模样。” 她举起自己的茶杯,毫无困难地喝了起来。“我真不明白他们干吗整整一个 10 月都呆在这儿?” 她大为不满地说,一边把杯子放下。“我是说他们现在任谁连水边的近处都不去了。女的不去,男的不去,孩子也不去。仨人谁都不去。他们连那条怪船也不再拖出去。我就不明白他们把好好的钞票白扔在这上头图什么了。”
“我不明白的是你怎么就喝得下你那杯茶。我连一小口都没法喝。”
桑德拉怨气冲天地瞪看着对面的那堵墙。“要是能回城里去我就太高兴了。我不是说笑话。我恨这鬼地方。” 她充满敌意地朝斯内尔太太瞥了一眼。“对你倒合适了,你整年到头都住这儿。这儿有你来往的熟人,什么都方便。你不在乎呀。”
“哪怕烫死我也得喝了,” 斯内尔太太说,一边抬起头来看着电炉上方的那只钟。
“要是处在我的地位你会怎么办?” 桑德拉突然发问。“我是说你会怎么做? 要说实话。”
这种问题正是斯内尔太太会顺顺当当接过去回答的,就像让她套一件白鼬皮大衣一样。她立刻松开手中的茶杯。“呣,头一条,” 她说,“我压根儿不为这儿的事情着急。要说我会怎么做,那就是另找一份一
“我没着急嘛,” 桑德拉打断道。
“这我知道,可是问我会怎么做,我肯定先给自己找”
连接餐厅的转门被推开,这一家的女主人宝宝? 坦纳鲍姆走进厨房。她是个矮小,臀部几乎没有曲线的二十五岁年轻女子,那头没有样式、说不清什么颜色、发枯的头发拢在两只耳朵的后面,耳轮倒是特别大。她穿了条齐膝长的牛仔裤,一件高领套头衫,还穿着短袜和平底船形鞋。虽说她名字起得挺可笑,她哪儿哪儿都算不得漂亮,可是——就以恒久能让人记住、默默地善解人意、面孔一小块一小块分开很耐看来说——却不失为一个最终能吸引人的女子。她径直走到电冰箱前,开开它。在她双腿叉开两手撑住膝盖朝里张望时,她透过牙缝不成卢调地吹着口哨,还配合以臀部有点放肆、钟摆般左右扭动的节奏。桑德拉和斯内尔太太都没做卢。斯内尔太太不慌不忙地将自己的香烟掐灭。
“桑德拉……”
“什么事,太太?” 桑德拉警觉地从斯内尔太太帽子上方望过来。
“泡菜一点都没啦? 我想给他捎一块去。”
“他全吃了,” 桑德拉精明地回答道。“他昨晚临睡时吃的。当时也只剩下两块了。”
“哦。那好,我上车站时再买些来。我寻思没准能从那条船里把他吸引出来呢。” 宝宝关上冰箱门走到临湖窗口朝外眺望。“咱们还缺什么别的?” 她在窗子那边问。
“就缺面包了。”
“我把你工钱放在门厅桌子上了,斯内尔太太。谢谢你了。”
“没什么,” 斯内尔太太说。“我听说莱昂内尔爱往外跑。” 她短促地笑了一声。
“敢情真是这样,” 宝宝说,把双手往后裤兜里插去。
“至少他还不往太远地儿跑,” 斯内尔太太说,又发出一下短促的笑声。
宝宝在窗前稍稍侧过身子,免得自己完全背对这两个在桌边坐着的女人。“倒也是,” 她说,把几根头发拢到耳后去。她纯粹像通报消息似的接着说:“他从两岁起就经常爱往路上跑。不过从没跑得特别远。我想他跑得最远的一次--至少,在城里是这样——是中央公园里的林 xx 道。离家也才几个街区。他走得最不远
或者说最近——的地方就是我们楼房的前门了。他拐到那儿去是想跟他爸爸说声再见。”
桌边那两个女人都笑了。
“林 xx 道是纽约人老去溜冰的地方,” 桑德拉非常热心地对斯内尔太太说。“小孩大人都去的。”
“哦!” 斯内尔太太说。
“他那时候才三岁。也就是去年的事儿,” 宝宝说,一边从裤子侧袋里摸出一包香烟和一盒火柴。她点燃一根烟,这时,两个女人都兴致勃勃地看着她。“可热闹了。我们弄得整支警察部队都出动了。”
“他们找到他啦?” 斯内尔太太说。
“当然找着了呗!” 桑德拉满脸不屑的表情。“你以为还会怎样?”
“他们到深夜十一点一刻才找到他的,那是--我的天哪,2 月中,我想是。公园里小孩一个影儿都没有了。只剩下抢劫犯,我琢磨,还有各色各样的流浪汉和精神病人。他正坐在乐队演出台的地板上,在一道裂缝上来回滚动弹子。人冻得半死,看样子——”
“我的好老天!” 斯内尔太太说。“他怎么会这样干的呢? 我是说他干吗要往外跑呢?”
宝宝朝窗玻璃吐去一个歪歪扭扭的烟圈。“那天下午公园里有个孩子不知听了什么胡说八道,竟跑到他跟前说,‘你很臭呢,小鬼。’反正,我们认为他是因为这个才这么干的。我也说不清楚,斯内尔太太。我头脑里一片晕晕糊糊的。”
“他这么做有多久了?” 斯内尔太太问。“我是说他这么干已经有多长时间啦?”
“嗯,从两岁半起吧,” 宝宝报履历似的说道,“他在我们公寓地下窒水池底下躲藏过。就在洗衣房里。他的一个要好朋友叫内奥米什么的——跟他说她的热水瓶里有一条虫子。反正,这是我们从他嘴里能掏出的全部情况。” 宝宝叹了口气,从窗边走开,手中的香烟还带着长长的一段烟灰。她朝纱门走去。“我还得再去试上一次,” 她说,这就算是跟两个女人道别了。
她们都笑了。
“米尔德里德,” 桑德拉一边仍在笑着,一边对斯内尔太太说,“再不走你可真的要误车了。”
宝宝出去后随手带上了纱门。
她站在房前草地那片缓坡上,近晚低低、耀眼的夕阳照在她背上。在她前面大约二百码处,她的儿子莱昂内尔正坐在父亲小船的尾座上。船是拴住的,主帆和前三角帆都卸掉了,此时在水中漂荡,与伸入湖中木码头的尽头正好形成直角。在五十英尺开外,有块不知谁丢失或扔掉的精水板底朝天浮在水面上,可是见不到湖上有什么人们玩乐的船艇了,只能看到一只朝利奇码头驶去的县里汽艇的尾部。宝宝发现很奇怪,自己竟难以将眼光固定在莱昂内尔身上。阳光虽然不特别热,却非常明亮是以使任何稍远一些的图像——一个男孩也好,一条小艇也好——看上去几乎像水里的一根木棍似的飘忽不定反光晃眼。几分钟后,宝宝干脆不朝那边看了。她学大兵的派头把烟头往地上一甩,接着朝木码头走去。
此时是 10 月,码头木板反射出来的热气已不使她的脸觉得太烤了。她边走边透过牙缝吹出《肯塔基宝贝》的调子。走到码头顶端,她膝盖关节发出格格声,在右边蹲下来,低头看着莱昂内尔。他离妈妈还不到一枝木桨远。但是他没有抬起头来看。
“哎嗬,” 宝宝说。“铁哥们。大海盗。臭狗子。我回来啦。”
莱昂内尔仍然不朝上看,他像是突然想起要显示一下自己的驾船才能。他把那个不起作用的舵一直扳到右面,然后立刻猛拉回自己身边来。他日小转睛地盯着舱面。
“是我呀,” 宝宝说。“是舰队副司令坦纳鲍姆呢。本姓格拉斯的那位。我视察后舵手来啦。”
终于有了反应。
“你不是什么副司令。你是个太太,” 莱昂内尔说。他由于呼吸控制得不对,说出的句子常常至少出现一个停顿,使得他想强调的字声调非但没有上升,反倒下降了。宝宝不仅是在听,更像是在密切注视着他的声音。
“谁跟你说的? 谁告诉你我不是司令的?”
莱昂内尔回答了,但是声音轻得听不见。
“谁?” 宝宝说。
“我爸。”
宝宝仍然蹲着,此时伸出一只手穿过两腿之间的 V 字形空当,撑在码头地板上以保持身子平衡。“你爹是好样的,” 她说,“但他大概是我认识的人里最大的旱鸭子了。一点儿不错,我进港后是位太太——这是真的。可是我真正的职业最初、最终和永远绝对是——”
“你不是什么舰队司令,” 莱昂内尔说。
“对不起,你说什么?”
“你不是舰队司令。你一直都是个太太。”
一时间两人都不吱声了。莱昂内尔乘机再次试着去改变小船的航向他操舵的姿势是两只胳膊全趴在那上面。他穿着卡其布颜色的短裤和一件干净的白T恤,胸前染印有鸵鸟杰罗姆拉提琴的图画。他皮肤晒得黝黑,他的头发在颜色、质地上都几乎跟母亲的一模一样,发顶让太阳晒得都有点退色了。
“好多人都以为我不是舰队司令,”宝宝说,一边盯看着他。“那是因为我没有到处乱吹。”她边保持着平衡,边从裤子侧兜里摸出香烟和火柴。“我几乎从来也不去跟别人谈论我军阶的事儿。特别是那些我和他们说话时连看都不看我的小男孩。我那样做会影响我正在上升的前程的。”她没有点姻,却突然站直身子,直得都有点过了头,接着她用右手的拇指和食指围成一个椭圆形圈儿,放到嘴边,竟然——像吹玩具笛似的发出了有点像军号那样的声音。莱昂内尔顿时抬起了头。很可能他也清楚这号声是假的,但他显得还是很为之感到振奋;他的嘴巴不由自主地张开了。宝宝将这曲调——它是 “熄灯号” 与“起床号”奇特的混合体
一连吹了三遍,当中没有任何停顿。接着,又郑重其事地朝湖对岸行了个军礼。当她终于重新在码头边蹲下来时,她像是深感后悔,因为方才在老百姓和小男孩面前竟显示出对海军传统的威仪如此激动,未免失态。她朝湖的不太宽的水平线凝望了片刻,接着又似乎想起自己在这儿绝不是独自一人。她朝下——很庄重地——瞥了菜昂内尔一眼,菝子的嘴还没合拢来。“那是一种秘密的军号曲调,只有舰队司令才允许听的。” 她点燃香烟,又将火柴吹得飘出一股引人遐思的又细又长的烟柱,火柴给吹灭了。“要是有人知道我让你听到这号声——” 她摇了摇头。她又重新将她那像在看六分仪的眼睛对准着水平线。
“再来一次。”
“绝对不行。”
“为什么?”
宝宝耸耸肩膀。“头一条,这儿附近低级军官太多了。” 她改变了自己的姿势,采取了一种盘腿式的印度人蹲坐法。她把短袜拉拉高。“不过,我要告诉你我会怎么做,” 她说,挺一本正经的。“如果你告诉我你干吗往外跑,我就把所有的秘密军号曲都吹给你听。怎么样?”
莱昂内尔立即把眼光垂下,重新对着甲板。“不行,” 他说。
“为什么不行?”
“因为。”
“因为什么?”
“因为我不愿意,” 莱昂内尔说,扳了一下舵柄以加重语气。
宝宝遮挡住右边的脸,那儿的太阳很刺眼。“你跟我说过你不再跑的,” 她说。“咱们谈好的,你告诉我你不再跑了。你答应我的。”
莱昂内尔回答了一声,但是轻得听不见。
“什么?” 宝宝说。
“我没答应过。”
“啊,答应的,你答应过的。你非常明确地答应的。”
莱昂内尔又去扳他小船的舵了。“你说你是舰队司令,” 他说,“你的舰队又在哪儿呢?”
“我的舰队嘛,我很高兴你问我这个问题,” 宝宝说,一边开始把脚伸到小船里去。
“出去!" 莱昂内尔命令道,但是还没有到尖叫的程度,而且眼睛一直是朝下看的。“谁都不许进来。”
“准都不许吗?” 宝宝的一只脚已经碰到船头了。但她顺从地缩回到码头地而。“任谁都不让进吗?” 她又同复到她的印度人盘坐姿势。“为什么不让?”
莱昂内尔的回答是完整的一句话,可是仍然声音不够大。
“什么?” 宝宝说。
“因为不让所以不让。”
宝宝眼睛定定地盯着男孩,是是分钟什么话都没说。
“听你这么说我太难过了,” 她终于开口了。“我就是爱上你的船上去呢,没有你,我闷得慌。我太想你了。一整天我一个人在家,连个说话的人都没有。”
莱昂内尔这回没有转动舵把。他细看把手上的木纹。“你可以跟桑德拉说话呀,” 他说。
“桑德拉忙啊,” 宝宝说,“再说,我也不想跟桑德拉说话。我想跟你说。我要下到你的船上跟你说。”
“你蹲在那儿也可以说的。”
“不行,我办不到。距离太远了。我得挨近了才能说。”
莱昂内尔摇动舵把。“谁也不许进来,” 他说。
“什么?”
“谁也不许进来。”
“好吧,那你能不能在船里告诉我,你为什么要往外跑?” 宝宝问道。“而且在你答应过我再也不跑之后?”
舱板上离后座不远处放着一副潜泳护目镜。莱昂内尔一下子答不出话,便用右脚大脚趾和二脚趾去夹住护目镜的带子,然后用腿灵恬、迅速地一挑,把潜水镜甩出了舷边。护目镜立刻沉人水中。
“好哇。干得漂亮,” 宝宝说他这回可该高兴了。” 她又吸了 “那眼镜可是你韦布叔叔的。哦,口烟。“护目镜最早还是属于你西摩伯伯的”。呢。”
“我管小着,”
“我瞧出来了。我知道你满不在乎,” 宝宝说。她的香煳在她的手指间形成一个奇特的夹角;眼看香烟要烧到她指戈节一个凹处了。她突然感到烫手,便松开烟头,让它往湖面落去。接着她从只侧兜里摸出一样东西。那是包什么,纸牌般大小,白纸包着,用绿缎带捆扎着。“这是个钥匙串皮包,” 她说,觉得孩子眼睛抬起来在看着她了。“就跟你爸那只一样。但是比爸爸的 j 丕可以多穿几只钥匙。这上面有十个钥匙圈呢。”
莱昂内尔放开舵把,身子往前倾。他伸出双手作抓取状。“扔过来。” 他说。“行不?”
“咱们先都坐好不动,宝贝儿。我还得稍微考虑考虑。我照说是应该把钥匙串儿扔到湖里去的。”
莱昂内尔张开嘴瞪视着妈妈。他又合上了嘴。“那是我的嘛,” 他说,语气一点点弱下去,没那么理直气壮了。
宝宝向下看着他,耸了耸肩膀。“我管不着。”
莱昂内尔身子慢慢地往后坐正,一边瞅着他母亲,一边手往后伸去够舵把。他双眼流露出彻底的领悟力,他母亲早就预料会那样的。
“拿去吧。” 宝宝把那个包包往船上他身上扔去。包包不偏不斜地落到他的大腿上。
他看看腿上的包包,捡起来,捏在手里,看看,然后一拨——从身体侧面——把它拨进湖中。接着他马上抬起头来看宝宝,眼里噙含着的不是对抗情绪而是泪水。很快,他那张嘴一瘪,扭曲成一个横写的 “8” 字,他放声哭开了。
宝宝站起身来,小心翼翼地,就像在剧院里腿坐麻的人那样,然后让身子落到小船里去。不一会儿,她已经坐进后座,把那水手抱在膝上,一边摇着他一边吻他的后颈,并且还告诉他:“水手不哭的,乖宝。水手永远都不哭。除非他们的船快沉了。或者是遇到海难,在救生筏上吃尽苦头,连喝的水都没有除非是——”
“桑德拉--跟斯美尔(臭)太太说——我爸是个又大——又臭的——开克(风筝)”
宝宝抽缩了一下,动作小得仅仅能察觉,可是她把男孩从膝上举起,让他在自己面前站住,又把他的头发从前额往后捋了捋。“她说了,是吗?” 她说道。
莱昂内尔强调地上下点点头。他接近了些,仍然在哭,站在母亲两腿之间。
“哎,这也没什么了不起的,”宝宝说,把孩子抱拢在自己双臂双腿间那两个 “v” 字形里。“这还不是世界上最最糟糕的事呢。”她轻轻咬着孩子的耳朵边缘。“你知道‘开克’是什么吗.乖宝?”
莱昂内尔一下子不是不愿意说便是说不出来。不过,等哭泣所带来的抽噎稍稍缓和了些之后,他还是开口了。他是对着宝宝温暖的脖颈说的,给捂住了但总算可以听清楚。“是那种能飞上天的东西,” 他说。“用一根线拴住的。”
为了想把孩子看得更清楚,宝宝把儿子稍稍推开些。接着她把一只动作挺猛的手伸进他裤子的后裆,让孩子吃惊不小,但几乎也就在同时,她把手抽了回来,一本正经地帮他把衬衫掖到裤子里去。“跟你说咱们要干什么,” 她说。“咱们开车到镇上去,买点泡菜,再买点面包,咱们在车子里把泡菜吃了,然后开车到车站去接爸爸,接下来咱们把爸爸接叫家,让他带我们坐船。你帮爸爸把帆扛到这儿来。好不好?”
“好的,” 莱昂内尔说。
他们不是慢慢走回家去的,他们来了一次赛跑。莱昂内尔赢了。
iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAZGklEQVR4Xu1dCXgV1fX/nXkvC0lICGEJmxC25CGCIIpS2UQRSgFZkihCi8UiFqsgkKRo3frXJkEqWGkVRakof5KwiaXFBUFBKpSCIOQlKiHImrAESCDLy5vb70wIPkKWmXnz5iXx3e/LFzH3nm3O3Ln3rIRGOGJnH2wOixQNK6IJ6A5BXYhEMwE0BdCUBEIEVfz3FfYLSaBQEIoAFBJQKASdB4lDAvgW5ciGU87OeOXGc41NXNTQGYpN3B0m5OCBkoS7COgPUHcQWniEL4EzgpANIXbJMj4j6dK2jJR+FzyCyySgDU4BhkzdEtiqdeRggO4CYSgE+hLBYpK8rkEjBJwg7IHAFkB8lp936vOty4eWeIMWvTgbigJQ7Dz7IEmiKQKYSIQwvQx7cp0QuEDAalkWKzIW2L4AIDyJzwjY9VoBJszZH2Ox+k0BMJmIbjCCYbNgCCF+APCes9yxYs3CXllm4dWKp14qQOw8+2CS8BQR3aOVofo4XwjxiZDxYsYC2+f1jb56pQCxiZmjJNB8EA2ob4IyhB4hdsgQL2Wk9NhoCDwDgNQLBZiYYB8vET1DhN4G8FTvQQiBfbIQL6xOta31NrFeVQD+xlut/q+BMMzbgvAKfoHN5eVlj3nzjOAVBRg+d19wuMX/aQBzQOTnFeHXF6RCOAAsLHCW/d/HL/e+ZDZZpisAb/cWiRYB6GA2s/Uc31GnLGaZ/VkwTQFGT98dFBQevAREU+v5g/AueUIsv1xwaeaHS/tdNoMQUxQgfm5mT1ikdBBsZjDV4HEI2OGU49Je7nHA07x4XAHiEu2/AWgxEZp4mpnGBF8IFAPiifQU25ue5MtjCqDY7CMj3ybQA55koNHDFmJlXt6paZ7yMXhEAe6btbeZf0DgB0Q0qNE/IBMYFEJ8UVZaMnb9oj7njUZnuAKMSchqG0hiExHdZDSxP2V4QohvSgSN2JAac8JIORiqAFecNx81NMeNkQL1JCx2MDnLHfcaaTgyTAEmJGT1s0hiE4EiPCmEnzpsAXHWKdOINakxu42QhSEKoLz5fn7bfQ/fiEdSNwxFCRyOO43YCdxWgPEJ+9r7SQE7fJa9uh+cwTOOOuTSAWtTex9zB65bCjBupj3CP4S2+Qw87jwCN9YK2MuKxMB1S2xn9ULRrQCKQ8fqvxmg/nqR+9YZIQGxs6C8bJheR5JuBYhPtK8B0XgjWPDBcFMCQqxNS7FN0ANFlwLEJmY9IRHYo+cb9UQCssCsjJSYxVrJ0awAsQkHbiPJso1A/lqR+eZ7TgICokzIzoEZqT13acGiSQFGJe0PDxF+e0DUSQsS31yTJCBEbhE5+m5M7lWgFqMmBYhLsn9AoDFqgfvmmS8BAbEhPdk2Vi1m1QoQm2SfKoHeUQvYN897EpAhHspIti1XQ4EqBeBkS8nfku2xnDs1lPrmqJeAwBm5zBmtJplVlQLEJdqXEtFv1FPgm+ltCQgh3kxPsU2vi446FSA+IfN2QdIOItQ5ty5kvr+bJwEhIEjIA9JSe3xVG9ZaH2psbLqFOvf6708lYcO8x2MOJk5AETn7b8nIiHPWhLFWBYhPtD8CotfNIdeHxSMSEGJGWortDc0KMGTIFmvr/pHf+e78Hnks5gEVIjdv56luW7cOLa8OaY07gO/aZ94z8jSm2q6FNSjAc1J8UrxdKbfiG41AAuLbtOQ0G/CcXJWZahUgbp79AbLQykbAuY+FKxIQTjEpfYHt/9UpQJL9GwL19Emv8UhAQBxIT7ZdF6l9zQ4ghAiJSzp4s0TWbY2H9YbHSaA/ITLCH7knSw0lXhblAzNSem53BXpVAYQQPwfwwfIP8z/btKNguKGYfcBUS+DWHiF4eFxrhIVY8e2RYry66gTOnK/2AK8aZuXE6qyDigIIIfh3NoBu7/4jv/ifXxb48vg0i9f9BT27BCHpofawWn7cmM+cd+DFZUdx8gyXEXBvcBWz/LyTka5pZpUKwMWYPmbwqX8/hj1ZptcpcI+zRrDaIgELn4xStv6q4+wFB5L+cgSFl2o06KmWgOyU789Y0CPtyotvrVSA1QCUmLIn/3wYJ06XqQbom2iMBAbfEopHJ7apEdiBQ5fw4rJjEG5WHhTAP9P+FM0xHZMAPENCCC66eBqAnyxDTPlDNjmvuy0aw6QPSs0SeGpae9zUNbhWEa3efAarP9UdAQ7eZW6/qak8M65NjiRRV0bGCjAawAb+B7/5vAP4hrkSCG4i4c2nu0KSane4yrLAms1ncfGyE2VlMvILHDh5pgznC2v/NESEWXF3/2YY2i8MzZpaXZkrZAV4BcAs/r9fZxcheflxc7n3YUM/Wwjm/rKdbkmcLnDgYM5lHDxU8XO5xInuHZugR1QQbFFN0O2GJjUp12usAFy9Usnj35tVhJS/+xRA95PQufDBkS0xelBznauvX8Y7RV27yZVVQ1kBvgfQxbcDGCZ/zYCend4BtqggzevcWcAlaIi4d4IQXI1KuffbD1/G80uPugPXt1aHBN5+tiuCAs2teH++0HkoPNTalRWAu2Qox0/+dvz6ed4QfMMsCbRq7odX53U2C91VPHuziw71jWmqKMBJAJGVf5m9MMcQq5PpHDVQhGz6nTNF/wFQL9ubdpzLH/mziNasAHsA9KkElPbxaazb0uha4+iVk8fXTRgWgdi7PdPhpjbiV24643hw5JJAulBU/l5osOXBysnnC8vxWEoOyp1umpw8JLqmwRa0b+WPdvzTMkD5HR5qRYAfwd9PglMWisn04iUnzl4ox7G8UhzPL8ORkyUoqOO+7CGSawU7+8G26N+zsneVeRSs+ug01n56sjPt2Hc+9Y5eYfNcUad/cgZrP9NvcTKajRs7B+G2niGKpaxtS/05qWxT/+6HEmQfKVYOvEdOlrptWnWX18XzotC6uX6e9OJfs/kM0j7KH0nTX8hKWJTQLaVJgHQVFt8j2e7MxgVvDYsFGHFHOEb+LBwtmnmmoDgferNyi2HPuQx7bjFyT5Rq2vmIgJAmFoQGW8A7U0iQBQH+BIlIgXOxyIlzFx04d6EcpY7rd1SWOd8AiAGZPDZ8cQ4rN+bNprikzL9NGxs5Y/jt4deQwMJZtPIE9n9nvhJ07RCImXFt0KaFuW8GP7QfTpXiRH4Zzl50oLRMwM9Kyo+/lRDUxIKwEP6xKg+df1QaXHCp2IlTZ3kHKsZ3R4vx/dESRIRa8cx077RC+teXBVj+j1OvU1yifUPzUOvoP8/pDNddgLXB6RRY9fEZ/HP7OZjhIGJnxfi7IjBuaIRqwZr84hiKrrxcwFrhkDV9VChA3gaKT7RvAdGQUXeGY8qoVtUSwk4iPhf852ChRxRBkoDe3YJx/70t0LFNoOnC+Cki3Lj9HFb8I38rxSXZdxPoFhbCnCltcWuPmk+kF4rKsf3ri9j37SXlIMVbpJ7RPNSKbjcEomuHJuDtvkv7QOUE7xvmSYCv+2u3nP0vxSfZsyvj//kA89z0GxDVru63kD8Px/JLle9a3jkHikucKHdWfDb4KsbfUz4M8RWNH3jzsB9/m232NE+sDQfTK+8fx84Dhd/yDnCCQFdDUfgckPCrdqY7JxqO6BoHpRz3cfx06UlWgEIChbiyxafeh8a0wl23Nmsc3Pq4uEYCHGjKxj4BUURxiVnlNTVfvu3GEPxqdCtEhHnmHu57Lt6RwKe7zuOtdXlsBHPyNfAiEdV48mODDIcSjR0cgZbhPkXwziMzFuvCFcfxn8wiTgco5GvgcRC1rQsF39EH9Q3DmMHNTTfQ1EWb7+/qJcCH89/88XsUl8qcEHKCd4AsIopWDwKKPf6mrkGKbb5H5ya6ghn4tmBxSYDQgt83V78Evvz6Iv6SxhEASkJQNu8A/wFRP70g2YjTtX0gOkQGKJ+IVuF+aBIoIdBfUjJcLpfIKLrsRFGxExy8yA4YznmbMSESt9iuOXvqJcG3TqUEhBCYtygXx/Kv5H0IsZt3gM+IaKhKGIZNS5raDjdH+xTAMIGqALTzQCFeef/HlkNCiC18DfRK9c+5U9qhXw+fAqh4boZMYQ/v7187ouzAlYOriireQII0wxAsGoBMHd0KIwZc64HUsNw3VaME2KH37kZOAPtxCMivU3xC5ixIEieHmDru7h+Gh++7GopoKu6fGjKOipq/5AjKqsYkyPJsip13cIRksfzLbKG0bu6HxV6IhjWbT2/j4wP4U389gryz16eXy07nSIqduy9KsgbkeIPQ5N91RKe2dTuevEFbQ8DJp/raookuFpXjpbeP1VhpRC4v7UwAVwS7nwsCmP4kBvcNxaOxNadEN4SH4C0aOSl0xcZ8/Da2jRKKVnVwzOPfVp9C/rkaC0uUpCWvClbCUeIS7fu90eqVQ+E4LSqmk7lpUd56aEbi3frfC3h99SnF1c7W2ehOTQABxTW/be8FpchHbbUEuBVteoqtV4UCJNnfI9DV0HAjCa0LVstmVqQ80UmXNbEu2I357y+9fdSteE0B8X56sm2yogCxCZnTJEl6y1sCG9gnVAkC9Q11EuBT/dxFueom1zBLluWHM1J7LFMU4L4ke6cAkFcrQ9x1axh+Pbb1NQWS3OKwES9+Le2kEprnziiFiFqfbMu9GpIal5iVQ4Qod4C6uzamUxM8ObktQoOvqWLhLthGtf54finmLc6F7EYZHyFwOD0lRslIvaoA8YlZb4EwzdvS4soWL8zwTqy8t3mvCz97UJ994wclp8CtIbAsLSXm4WsUIDbRPkkiet8twAYsnjSyJcYYWC3DAJLqBQi25bMb99/7C92mx7Vu8NUdYNzcfa38LAEnagoPcxurCgAckLokqbPvRlBFVhyOvyT9pFun/kqQHAbmcJa2Xfdy7/xrdgD+R1xS1kYCuGSsV8YvBoZj8s+rT07xCkH1AOk3318CH/ouFLlfJJLZ4TqB6ckxoypZuyYvKXZeZrxkkVZ5g2+ORF48NwrNfQGoivhLymSkc1rel6qbgKp6bK6VQq/bAYZM3RLYqnWbU0Tg4pGmjol3R2DiMPMLJZjKpEpke7OLsGx9nmFFol22/+prBbvS5Y0egewZfHl2J/hZjUsP4xMzm0VbhlsNhavyGeqaxp67ZR/kGXLQq46AGquFu06OTTxwp9n9AhKntkMfg8PD+NvJNQ7Y3xDe1AouxsSKVvHbHy2v/FtLirernDi69twFBxgBx0G6OzJzLivf+nMXjSkNXx09tfYLuGYXMLFjCCefPDnZ+CJJyz/Mw6Yd5+t8LkqRhyALQoMqijxw2VZOVK2sC8C/HeVCCW4tLpGVSmpceoYfFDtbotoF4E+P6W+mzte71ZvPYt2Wsx6tVqKqY0iltOITM+8HSdf1l6lTmhonsLAXzo6qWr9WI5Tqp/8uNUeJQjZj/OmxjqoSaqvSUuaQkbz8GDJzij1PppAfSEvpcd0B36tdw2ZMjMSQW4w/bx7NK1XCn80aw29vpvgxtI631p/CpzsvaF2mY77GrmGMwdN9A3t1C8L8X3fQwUzdS5T6N/+6NgCy7lX6Z/BO9vr8LpoOm/wp4QwdMyqv6OgbCHiyc6i/Hylbv6dyDV9Y+gMyD5uwrbrozKxJbbkWv2otys69jGffMKEsr97OocyJp3oHx93TQqkF5Ilh5pvlSn//niGY/aD6w2xlhq4nZOAKU4Z4JCPZtrQmPKZ3D9dy5+e7PBehcW2iVJfAqma/1DXfqL/zrsZNHwL81dkyuA4j113y5HC7e7iyCyRk3i5I2kH0o+vYHaK5+kjfGHUZQZt3ncfgvmGaKmmt3HQaGz73Tqnbumosucrto38X4J0Nij/GI0MICBLygLTUHl/VhkBVjTKjrINca+Dvz3VX9UD5ipSwOBeL5mqrpM3Xqq+zvdP1jJs+cPMHNcM1S1fNfK1zqrP6VQdDlQLEzj7YXPK3ZIPgtrFebXMEfkPYOPL6fKW3keqR9Gqu4R031SK/5/ZmmKbyOshVWP/4pocOgQJn5DJndMYrN9a5FapSABaAUdfCCXdFIPae2vWIEx5mLzysWN+WPq1NAbxZ7n7c0OaIH65uB/Bkb4barn1VlVm1AnD4WFySfT2BuOec7sG2eHb71pbRwt6wlOXHwZ+Md5/vrqmQxPzXcpFz3Nieu2qZnfzzlvjFQPW9f+YolbqM7dHIGb/pybaxamnWogAYlbQ/PET47QGRfuM3gN8/1B69u9fcI+/jrwrw9gcVB6QXZ3ZUCkmqHX9ZdQJf7nM/bEotPtd5v42NVMroqB1/yziJz/e4F917DS4hcovI0Xdjci/VQQSaFED5FCQcuI0kyzYC6a7kfHP3YKVHbk2DC1CyKZedLZ3bBWDuL9srGTBqBmfFLEk/pWaq4XOen3EDojuqb7ts5EFQQJQJ2TkwI7XnLi2MaVYARQkSs56QCIu0IKo69/lHOiC6lpSwdzbk4aN/V3jzwptakDC1PaJUJJI6ymXMTM5RGkaYPZY+3UVTSLuRRitZYFZGSsxirTzrUgBGEp9oXwOi8VoRVs7nN4XfmJoG+9sXvHtcqUvMg8vYzp7UVlVZma++KVRK3Zs52B+w7JlumlFyZ/BvvnezJL8Qa9NSbErvZ61DtwIMn7svONzqvxmg/lqRVs5//P42GNA7tMbl/DYvXHECX19RAi5I9cj4SAxW4UHkyJpPvqo7HkAv7VXXdWwTgJTHtR+N2Nj15ro8N8gQOwvKy4Z9/HJvXcYP3QrAFI+baY/wD6FtINj0cMDROH9+Mqra9OZKeFxT/9VVJ7DrIHe3qxiTRrTAmMG1+xLYjMy58WZ1PekbE4yEX9V8rqlJPvwZmPHSoeurd6gRqIC9rEgMXLfEpru/j1sKwDSOT9jX3k8K2AFAl2/3zptD8Vh87YmhHDWT9skZZB0uVj4FHOhx641NMWlE7XduLoaY/M4xpbS9p4c7JW845n/bXs23gaMOuXTA2tTex9zhzW0FYOQT5uyPsfj5bSeQLhffoxPVbeuujHIAJRearNrlpKowSstkvLU+T4+ANcl17ODmeKAOhawJYFbuZTynwTUsIM46HY471yzslaWJyGomG6IAihIkZPWzSGKTHiXglm9832/fOkATP+wvUNtogneB9VvOYq+H/AT33tEMD43RHhVUybBaA5by8GUasSY1ZrcmYdUw2TAFuLoTWP0+IiLN2Z0cHPLHR2/QFB/Iu8CX+y7i3jvUl5vjNCtuDMX18g4dK1E6ppfo7HziKlN3y93s2HcRr66qKOFa0xBC/OAsd9xrxJtficNQBWCgYxKy2gaS2KSn5AwbfZ5+uIOm3MDHF+Rg4rAITRY4VwFzo0y+MnL7OHcGF73k4pd6B59z5rxyuMa2vVzSpUTQiA2pMYbebw1XABbAfbP2NvMPCPyAiAZpFQiHWbOpWG2NgJnJh5QQba4wwgdKPYNP4rNePuyW8ciIJtD7v7uk3FyqDiHEF2WlJWPXL+pj+L3WIwrADHCaWevWkctANEnrQ4kIs+Lh+1qjTy2BI/zGfLLz/NWgCo7v58OkFlu8K11ccWvjdtUm9GpZeuOpLkpPQXfGph0FWP6hS6CIECvz8k5N27p8qJtFAaqnymMKUIkuNsk+nQQtIoJ6I/mVxS2aWZUKYvx2BQZwBXLChUKn4kH7/mhxtblz3HruviHaLyNGWA+1uINrU5JdBwvx1/RTxZfLnLNqi+dzR9E8dgaojqj4uZk9YZHS9RqMtDI6qG8ouBaxlu5klS5orbhc5/MudEevporPIihQUuIDObOIjVKtI/w1eTUdDpHr50fDieg7d2iqa63Hd4BKAkZP3x0UFB68BERT6yLKiL/z7sHXsj7RwXV2IeXPCZ/AeRfw1GBfwYJZUaq9mlfoOA6gJxEZ/u03dQdwFerEBPt4i0TsSdRlOdT6gLhvIZeh4w7kbVr4KY2oud8vG4i4iiZX1OSii2YEkXCTTL7lcDMNDWMoEW3VMF/TVNN2AFeq2JHUzBrwBxLiSRC5n1qrgWV2KHGcQW1VNDWA0zyVleDxB9qqzSjeB+BWIvJYkqNXFKBSamxCtlr9XwNhmGZJNuAFHOp2x02h6Nej6bE+0UEFAf4S74Z8h63cGti5sxLAH4jIo8mDXlWAymfInwWJ6Bki9G7Az1U16ZywIQvxwupU21rXRUIIjn2zEJEu165qAlwm1gsFqKQnNjFzlASaD6IBepip92uE2CFDvJSR0mNjfaG1XinA1R0hyT5EEphPRPfUF0G5Q4cQ4hOZ8NLqZJvHDnN66auXClDJzLiEb2x+ZJ0MYLIeB5NeoRixjh03AN5ziPL31qXeZDcCpidg1GsFcP1Uxc6zD5IkmgJC7JUDkyfk4S7MixDIkGWxImOB7YuKsnz1ezQUBbgqRfYxtGzZaghJlqEgDIVAX29VN+WqmyDsgcAWITu3nD6dv9VTNntPqVGDU4CqgohN3B1GCGav41AC+gtCtJ6gFDUC5mAMEsgWwE4AWwQufZGR0s+j1zQ1dLkzp8ErQHXMczIrLFI0rIiWBKJB1AUQYQLgEh5NSSBEUMV/X1lfSAKFgsCRp4UEFApB5wkiRyZkoxzZcMrZapIt3XkY3ljbKBXAG4JsqDj/B9noTK8z19XfAAAAAElFTkSuQmCC
[[现代性的五副面孔 现代主义、先锋派、颓废、媚俗艺术、后现代主义|http://reader.epubee.com/books/mobile/44/441726ca303596cb07013add6b12d297/text00003.html]]
【美国】马泰·卡林内斯库 著
译林出版社
# 现代性的五副面孔:现代主义、先锋派、颓废、媚俗艺术、后现代主义 (名家文学讲坛) 后现代主义的手法及其意义
## 后现代主义的手法及其意义**
-----
首先,我要谈到一种似乎较为普遍的[[后现代主义惯例观]]。[[现代主义]]在其先锋姿态中已使我们熟悉了一种技法,它更多地是显露而不是隐藏用于建构一件艺术作品的惯例和手法([[俄国形式主义]]者用技术术语称之为 “凸现手法”)。[[布莱希特]]著名的“间离效果” 是一个经典的例子。然而在后现代主义中情况有所不同。手法继续就其作为手段而显露自己,但在这样做的同时,它声言任何其他东西无一例外也都是手段。但如果一切都具有手法的本性,或者说到底具有虚构的本性,“凸现手法”也就不再传达出新颖性、原创性和艺术自豪感,而在现代主义中这些都是与之相联系的。我们回想起马格丽特画有一支烟斗的 “现实主义” 绘画,其中有 “这不是一支烟斗” 的题词。这是唤引人们注意绘画本身,注意其艺术性现实,注意其想象性特质的一种极端现代主义途径吗?很难说是如此。这幅画看起来很像一幅[[超现实主义]]的游戏之作,但是其中令人奇怪地缺少意料之中的梦幻元素,在其中我们早已能够辨认出一种后现代主义质疑的先声,它不仅质疑形象后面的 “现实”,而且质疑形象本身在美学或其他方面的“真实性”(马格丽特的烟斗平淡无奇,它并不“意味” 着任何东西)。 58 我要说最终在这里凸现出来的并不是一种惯例,而是惯例性本身,是变成了存在之谜的惯例性。
在此背景中看,较为明显的后现代主义手法包括:叙事视角主义的一种存在论或 “本体论” 的新运用,不同于它在现代主义中主要是心理学的运用(这一点将在后面更充分地讨论);对开头、结尾和所叙活动的复制或多重复制(这令人想到[[约翰 · 福尔斯]][[《法国中尉的女人》]]的两种可供选择的结局);对作者的戏拟式变换(入侵式或操纵性作者的重新出现,但如今显然带有自我嘲讽的意味);对读者同样是戏拟式的但却更令人迷惑的变换(“隐含读者”成为一个角色,或是一系列角色,如在[[卡尔维诺]]的[[《寒冬夜行人》]]中);将事实与虚构、现实与神话、真理与谎言、原创与模仿等量齐观,以强调不可确定性;用自我指涉性和 “[[元虚构]]”(metafction)来生动表现循环性(如在[[博尔赫斯]]的[[《环形废墟》]]和《特伦,乌克巴尔,奥比斯 · 特蒂乌斯》中);“[[不可靠叙述者]]” 的极端形式,有时是悖论式地用于缜密地建构的目的([[纳博科夫]]在《绝望》中以一个自我忏悔同时也自我欺骗的说谎狂的语调讲述的“完美的罪”)。要增加这种类结构惯例方面的其他实例很容易。在风格上,除了对于大量传统修辞手法具体的、常常是戏拟式的运用外,还可以看到对有意的时代错误、同义反复、翻案(palinode)或悔言(retraction)之类非常规性修辞手法的明显偏好,这类手法常常起到广泛的甚至是结构性的作用。
为了不停留于仅仅列举此类手法,为了注意到它们之间错综复杂的历史性相似、关联和相辅相成,需要提出一个更大的比较性假设。我现在所要讨论的三位后现代主义研究者,[[D.W. 佛克马]]、[[布赖恩 · 麦克黑尔]]和[[埃尔鲁德 · 伊卜希]],都毫不迟疑地提出了这种假设。除此而外,他们建构后现代主义范畴的那种方式也特别令我感兴趣,因为它以大量令人信服的文学事例,证实了我前面所说的当代思想从认识论到阐释学的这一重大转移。
佛克马视 “[[假设的诗学手法]]”(poetical device of hypothesis)为现代主义散文的突出特征。 59 比如说,当[[普鲁斯特]],或者不如说他的叙事者和替身马赛尔,对一个人物缺乏足够的了解时,就会求助于丰富而复杂的假设,这会让[[《追忆逝水年华》]]的读者获得巨大的理知乐趣;或者用佛克马所引述的雅克 · 里维埃的话来说,他将用假设来填补他知识中的缺口。佛克马写道:“现代主义在创作文学文本方面最重要的惯例,是选用表现不确定性和暂时性的假设性建构。” 60 随后,他进一步阐明存在于纪德、拉尔博、托马斯 · 曼、泰尔 · 布拉克及其他人作品中的这一核心惯例。
在佛克马看来,与这类自大狂式 “现代主义假设” 相对的,是后现代作家(他们中有博尔赫斯、巴塞尔姆和罗伯——格里耶)的 “不可能性”,以及他们对根本的、不可超越的不确定性的一种普遍感觉,我愿把这种感觉称为一种认识论的虚无主义。按后现代主义的观点,即使是在理想的状况下,也根本没有什么“现实” 能确证这类假设。现代主义假设与反假设的游戏,连同其特有的紧张与期待、焦虑与欢乐,已丧失了根基。由于 “现实” 只不过是解释与虚构的混合物,佛克马认为后现代主义者再也不根据假设来写作;事实上,他们将根据不可能性来写作。
布赖恩 · 麦克黑尔承认佛克马选择[[认识论]]角度的意义,但改变了他用来区分现代主义和后现代主义的术语。麦克黑尔不是把 “[[认识论怀疑]]”(现代主义假设想象力的催化剂)与后现代的认识论不可能性相对立,他更爱谈论现代主义小说的“[[认识论主因]]” 和后现代主义小说的“[[本体论主因]]”。在考察麦克黑尔的核心论点之前,有必要就术语作简要的澄清。
“主因”(dominant)的概念来自[[罗曼 · 雅科布森]]。按雅科布森的看法,文学的演进可视为从某一时期首要的或主导性的诗学准则系统转向一个新的诗学准则系统,这个新的系统将主导下一个时期。雅科布森是[[俄国形式主义]]最杰出的成员之一,通过概括他们的立场,雅科布森指出,在旧时期属次要性的东西,在新的时期里变成了首要的,与此相应,在旧时期属本质性的东西,在新的时期变成了附属的或非必须的。值得注意的是,在采纳雅科布森的主因概念时,麦克黑尔将它从其最初的 “一统独尊”(monolithic)的含义中解放出来。就像时期这个“策略性的” 概念一样,主因的概念无权声称自身是独一无二。不是只有一种而是有很多可能的现代主义和后现代主义理论,它们取决于提出理论者的策略性目标。同样,在一个时期中人们可以设想出许多主因,这取决于所选择的视角,想要研究的内容,以及这种研究的目的。对于那些更熟悉德国形而上学(包括海德格尔)语言而非后维特根斯坦分析哲学语言的人来说,麦克黑尔使用 “本体论” 一词的方式也许会使他们感到迷惑。为消除可能的误解,麦克黑尔解释说,他的 “本体论” 来源于“这一术语在诗学中的使用,主要是罗曼 · 茵伽登对它的使用…… 以及托马斯 · 帕维尔和其他人的使用,他们从模态逻辑(‘可能的世界’)中采用该术语以描述虚构的世界…… 作为一种工作定义,且让我们引用帕维尔的说法:本体论是‘对宇宙的理论描述’”。 61
现在来谈麦克黑尔的观点。他从提出两个论点开始,这两个论点的有效性据他说只限于 “一种二十世纪小说的历史诗学”。第一个论点是:“现代主义写作的主因是认识论的。也就是说,现代主义写作旨在提出此类问题:要知道什么?谁知道?他们怎么知道,且具有多大程度的确定性?知识怎样从一个知者传达到另一个,这又在多大程度上是可靠的?等等。” 62 第二个论点是:“后现代主义写作的主因是本体论的。亦即,后现代主义写作旨在提出以下问题:什么是世界?有些什么样类型的世界,它们是如何构成的,它们有怎样的区别?…… 什么是文本的存在模式,什么又是文本所投射的世界(或诸世界)的存在模式?等等。” 63 为了解释从一个主因向另一个主因的过渡,麦克黑尔求助于一种内在的变化模式:当现代主义质疑的逻辑被推至极端,它就导致后现代主义质疑的逻辑;反之亦然。麦克黑尔写道:“将认识论问题推至足够远时,它们就会翻转过来,变成本体论问题——进步并不是线性的和单向的,而是循环的和可逆的。” 64
为了支持他的论点,麦克黑尔讨论了[[威廉 · 福克纳]]、萨缪尔 · 贝克特、阿兰 · 罗伯——格里耶,卡洛斯 · 富恩特斯、弗拉基米尔 · 纳博科夫和罗伯特 · 库弗的作品,试图表明现代主义 / 后现代主义的区分可以卓有成效地用于谈论一位作家的全部作品,有时也可以用于谈论某个单一的作品。比如说,罗伯——格里耶的《妒忌》可以表明认识论(现代主义)的主因,而他的《在迷宫中》则典型地是本体论或后现代的;至于[[威廉 · 福克纳]]的[[《押沙龙,押沙龙!》]],它主要是一部现代主义的小说,但有着迷人的后现代元素。在他文章的结尾部分,麦克黑尔回到两种主因是可逆的这一观点上,并且写道:“从现代主义诗学向后现代主义诗学的过渡并非不可逆的,这并不是一扇只能往一个方向开的门…… 有可能从后现代主义‘撤退’到现代主义,或者实际上在两者之间摇摆。” 65
在他的整个文章中,麦克黑尔似乎不愿承认不可逆性(没有它任何适当的历史性研究和思考都是不可能的)同现代 / 后现代的二元性有任何关系。鉴于麦克黑尔宣称他的著作是历史诗学方面的研究,这令人吃惊。在他的论述中被忽略的问题是:现代主义(我们选择的任何一种现代主义模式)是否是一个不可逆系列中的一个独特阶段,抑或如一些当代 “文本主义” 批评家所主张的,它是一切时代一切(真正)文学的一种本质冲动?以及:后现代主义(我们选择的任何一种后现代主义模式)是否是这一系列中的一个独特阶段,或者它是在一种超历史的现代主义内在逻辑中被给定的一种常见可能性?
尽管对于这些问题的一种历史主义回答不见得就与麦克黑尔的一般论点不合,但对历史不可逆性抱有的某种难以消除的结构主义偏见,使得他不去考虑此类问题。他认为回归现代主义式的认识论质疑,或者是摇摆于认识论主因和本体论主因之间,是后现代主义者们的一种选择,他的这种观点我不难接受。但这样一种选择的可能性不恰恰是一个历史过程的结果吗?在本体论主因被充分表达出来之前,早期的现代主义者也有同样的选择吗?麦克黑尔深入细致地分析过《押沙龙,押沙龙!》,在这部作品中的福克纳也许就是面临着本体论的困惑(实际上也许从塞万提斯开始的一长串小说家都是如此),但我们是否真的可以说,他处于在一种认识论解决办法和一种本体论解决办法之间作出抉择的地位呢?我要说,这样一种抉择只能出现在一个不可逆的历史发展进程中。在福克纳写作《押沙龙,押沙龙!》时,后现代主义的选择于他实事上并不可能。但当他说某个时期的贝克特或罗伯——格里耶可以在现代主义和后现代主义间来回游移时,麦克黑尔是对的。
后现代小说的 “可能世界” 或“本体论”主因不乏其自身形式的“不可能主义”(impossibilism)。埃尔鲁德 · 伊卜希在她的文章《从假设到修正》 66 中,通过对比分析罗伯特 · 穆西尔的《没有性格的人》(1930-1934)和托马斯 · 伯恩哈特的《修正》(1975),所表明的正是这一点。按伊卜希的看法,穆西尔伟大小说中的主人翁,乌尔里希或 “没有性格的人”,是[[尼采视角主义]](perspectivist)认识论的现代主义化身。我们记得,[[尼采]]的这种认识论以同样的力度反对现代形式的唯心主义和唯物主义知识理论。事实上,穆西尔把由尼采明确揭示出来的现代性的哲学和文化困境加以 “小说化”。因此,穆西尔的主人翁,一个非常悖谬而尖刻的 “说教者”,经常面对着一群处于暧昧不明的道德、政治、法律和语言学情境中的人物,这促使他没完没了地进行批评和自我批评性的假设。通过乌尔里希,穆西尔为 “[[假设的诗学手法]]”(佛克马语)的现代主义运用提供了最吸引人的范例之一。与乌尔里希相比,托马斯 · 伯恩哈特《修正》的主人翁,迷人地带有维特根斯坦色彩的罗伊塔默尔,目的在于对假设非神秘化,在于表明假设性思想内在的不准确、无力和虚弱。伊卜希的主张是关于一种历史转变的,即 “从假设到驳斥的转变:穆西尔作品中表现的种种观点,质疑了对某一种观点的教条式固执,在伯恩哈特的作品中,它们被一种无情地进行反驳的企图取代。” 67 因此乌尔里希的认识论怀疑主义和对推测的创造性运用,在伯恩哈特的罗伊塔默尔身上让位于一种 “修正”、修正之修正以及诸如此类的精神倾向,直至主人翁最后自杀或在存在之外的(自我)修正。
越出伊卜希对这部特定小说的分析,想想在多大程度上后现代主义者不仅运用反驳或修正,而且更普遍地运用我认为从属于 “翻案” 这个较大范畴的那些修辞手段和手法,将是十分有意思的。长期以来,“翻案”这个词的希腊语词源意义(即在一首赞美诗或颂歌中收回所说过的话)被拓伸,以包括任何形式的公开收回言论(可以是声明撤回,承认有错,承认欺骗,或是承认出于任何或严肃或游戏的目的而说谎)。我们是否可以说后现代主义中有一个分支,它的典型特征是坚持运用一种翻案或悔言的修辞,而这种修辞在那些较早的写作模式中仅仅被少量运用呢?这个问题无法在这里回答。但举一个简便的例子,来说明这种修辞怎样在一位重要当代作家的作品中起作用,也许会明确这个问题的意义。
我想到的是贝克特的叙事策略,在他五十年代著名的三部曲(《莫洛伊》、《马隆死去》和《叫不出名字的人》)中,它同其散文的风格、文本和文本间模式交织在一起。翻案问题很早就开始主宰读者的期待视野。如同三部曲的评论者之一布赖恩 ·T. 菲奇指出的,用心的读者很快即得知,“每一个措辞都会取消此前的所有句子…… 限定和修正不停地夹杂其间;刚刚才说过的马上就会被否认,然后又会被重复,如此等等。” 68 由于叙事者的犹豫不决和自觉的前后不一致(部分是由于遗忘、混淆和不能分辨 “事实” 与“虚构”),无法消除的不确定的感觉不断被加强。典型的情况是,贝克特式的叙事者会告诉读者:“由于我的虚弱,我不能俯身或下跪,因而一旦我忘了自己是谁,俯身了或下跪了,毫无疑问,那将不是我,而是别人。” 69 或者是更为逗趣地:“据我所知,这个女人从没对我说过话。如果我说过什么与此相反的话,那是我错了。如果我还说什么与此相反的话,我将会又一次犯错。除非我这会儿是错的。” 70 在整个三部曲的结构的层面上,创造(存在)谜团的技巧所采取的形式,是更大规模的一系列修正步骤和回头否认的做法。在第一部小说中,尽管不能肯定,叙述的语调似乎是莫洛伊的(或者说后来是莫洛伊的替身雅克 · 莫兰的)。而第二部小说的叙述语调是马隆的,它表明第一部小说实际上是由马隆自己写的,因而莫洛伊和莫兰只不过是马隆古怪想象力的产物。在第三部小说中,这种修正本身又被修正,马隆的存在变得像莫洛伊和莫兰的存在一样可疑。至于《叫不出名字的人》中不确定的、无名称的、错乱的叙述语调,读者根本无法说它是一种破碎的声音呢还是几种声音。悔言仍然是主要的技法,但无法确定是谁在悔什么言。
结论
在本文的结尾部分,我试图维护一种历史——假设性的后现代主义概念;在这里,我应作出更具概括性的总结,以再次强调我避免给这一概念下常规性定义的理由。“那些在其中符号化地凝缩了一个完整历史过程的概念是无从定义的,” 尼采曾经说过,“只有没有历史的概念才是可以定义的。” 71 在《新教伦理与资本主义精神》一书有关方法的简要陈述中,马克斯 · 韦伯重复了尼采关于历史性范畴不可定义的论断,但他进而具体地指出这类概念为何、怎样和在何时可被合理地运用,虽然它们是不可定义的。关于他的 “资本主义精神” 这个 “有点夸张” 的措辞,韦伯指出,只有当它指的是 “我们归为一个概念性整体的诸元素在历史实在中联结而成的复合体” 时,它才具有可以理解的意义。如同韦伯在一个关键性段落中所坚持主张的,选择这些元素并建构(或拼合、组合)这个整体的,显然是“我们”;这段话值得详加引述:
一个历史性概念…… 不能按 “属加种差” 的公式来定义,而必须用取自历史实在的那些单个的部分逐渐将它拼合出来,…… 换句话说,我们必须在讨论的过程中求得一个最佳的概念形式,作为我们讨论的最重要结果,用以概括我们当作资本主义精神来理解的东西;说它最佳,是就这里令我们感兴趣的角度而言。进而言之,这种角度…… 决非我们所要考察的历史现象能借以得到说明的唯一可能的角度。在这个历史现象上就像在别的历史现象上一样,其他的角度将会产生出其他的本质性特征…… 这是历史性概念本性的必然结果,出于方法论的目的,这些概念并非要在抽象的一般公式中把握历史实在,而是要在种种具体的发生性关系中把握它,这些关系总是明确地带有着独特的、个体的特征。 72
角度和方法论目的的重要性是至高无上的。如我在本文中多处表明的,我对后现代主义的论述有三个较大的目标:(1)指明自二十世纪四十年代至八十年代后现代主义获得概念化的领域和主要途径;(2)揭示这一术语的假定性本质,它应被视为一种解释性和操作性建构(有意思的是,对后现代主义的接纳或拒绝都涉及对其他重要时期建构的重新概念化,诸如现代主义和先锋派);(3)从一种元理论(metatheory)的角度,表明一种好的后现代主义理论必须满足的基本要求。在这些要求中,我特别关注了理论假设的自觉意识(这在历史性研究中尤其缺乏,历史性研究总是容易陷入 “现实主义” 或“目的论”的谬误)和应用的具体性,在本章的最后两节中,主要关注了后现代主义催生独创性见解的能力,这些见解新颖、令人兴奋,而且就算它们在实际中不可证实,也是可以商讨的(并且值得商讨)。
我自己的后现代主义理论,或者不如说我对后现代主义的理解,大体上仍是隐喻性,它可以根据生理学上的 “家族相似性” 得到最好的说明,这种 “家族相似性” 我在前面已经提到过。后现代主义是现代性的一副面孔。它显现出与现代主义的某些惊人相似(它的名称中仍然带有 “现代主义”),特别是在它对权威原则的反抗中,如今这种反抗既及于乌托邦理性,也及于为某些现代主义者所推崇的乌托邦非理性。在此世纪将近之时,后现代主义精致的折中主义,它对于统一性的质疑,以及它的重部分而反整体,都使得它仍然是十九世纪八十年代盛行的“颓废欣快症” 中的一种。然而后现代主义公然使用的通俗编码,使得它非常近似于媚俗艺术和坎普,它的反对者们也有意将它与后二者等同起来。后现代主义偶尔与先锋派有着孪生子般的相似性,尤其类似于先锋派的非极简主义形式(从德 · 席里柯的形而上学派到超现实主义者)。我们把这些不同面目看作是相互关联的,因为它们都与一种较广泛的现代性及其精神有着联系。如果不是有这种更广泛的现代性,这些面目之间的部分相似和表情差异将消失净尽,意义全无。因此我们可以推断,只要我们还在比较和对比这些不同面目,现代性就仍然存在,至少它会作为一种文化上的家族相似性的名称而存在;好也罢,歹也罢,我们会继续在这种相似性中认识自己。
附录
现代性,现代主义,现代化
现代主题的变奏曲
现代性本身并不现代,但显然,围绕现代性的冲突在某些文明中较在别的文明中更突出,而在我们的时代冲突更是前未有地剧烈。 23
摘要:本文根据这三个概念的历史和它们的结构关系来讨论它们。“现代主义”作为一种现代性的美学,涉及对现代性的一种特定的、常常是深刻矛盾的态度:既赞美又敌视;它还涉及对传统的一种特定态度:既拒斥又尊崇。“现代化”社会科学家们非常熟悉,但几乎从未被文学研究者们考察,我的主张将是,通过更仔细地思考社会科学中 “现代化” 概念的历史,以及在这个名称下发展出来的各种变化模式,文学研究可以变得敏锐。
主题是现代性,为了与副标题中的音乐隐喻保持一致,我最好是以演奏它作为开始——以一种概括定义的形式。现代性因而是一个时间 / 历史概念,我们用它来指在独一无二的历史现时性中对于现时的理解,也就是说,在把现时同过去及其各种残余或幸存物区别开来的那些特性中去理解它,在现时对未来的种种允诺中去理解它——在现时允许我们或对或错地去猜测未来及其趋势、求索与发现的可能性中去理解它。我的文章分三部分,它们都有一种基本的术语——历史关切。第一部分讨论现代性这个关键术语本身,以及现代性(常常被视为理性)的双重冲突——一方面是同传统,一方面是同它自身(或同一种与之对立的反现代性)——所导致的那些悖论。这部分以及全文的核心是波德莱尔的现代性定义:我自己的概括定义在很大程度上是对波德莱尔定义的一种重新表述。第二部分讨论各种现代主义;包括世纪之交罗马天主教会中现代主义危机的有趣情形,它被视为理知现代化努力所造成的制度性紧张的一个实例。第三也是最后一部分反思了一般的现代化概念,包括所谓的理知或文化现代化。
一、现代性
在环绕 “现代” 概念的语义星丛中,最重要的一个成员无疑是较晚近才形成的 “现代性” 一词。正如我以前在论 “现代性概念” 历史的文章 24 中指出的,现代性广义而言意味着变得现代(being modern),也就是适应现时及其无可置疑的 “新颖性”(newness),这个词从十七世纪起在英语中流行,将近十八世纪结束时霍勒斯 · 沃波尔首次将它用在美学语境中。在由著名的查特顿伪作(他假托的中世纪罗利诗篇问世于 1777 年)引发的讨论中,沃勒斯指出,任何有耳朵的人通过 “语调的现代性和观念与措辞的晚近倾向” 25 ,都很容易辨认出这些诗歌是查特顿所作。
在法国,根据主要的法语历史词典,“现代性”(modernité)只是在十九世纪前半期才被使用。强大的法国新古典主义传统关心语言的纯粹性和规范性(以及随之而来的对新造词的厌恶)也许是造成这种情况的一个原因。有趣的是,标准的《法兰西学院词典》甚至没有收录 “现代性” 一词,尽管它收入了 “现代化”(moderniser)和“现代主义”(modernisme),后者既用在宗教意义上(见下文)也用在广义的艺术意义上。《大罗贝尔词典》(1985 年版)用夏多布里昂《墓畔回忆录》(该书完成于 1841 年,但到 1849 年才发表)里的一段话来表明“现代性” 的意义。在暴风雨天气里的浪漫派式山景中(加上诗意的急流和远方响起的羊角号),夏多布里昂对比了一座乏味海关建筑的 “粗俗与现代性” 和一座 “哥特式大门” 所隐含的壮与美。
十年之后,在论康斯坦丁 · 盖伊的文章《现代生活的画家》(写于 1859 年,发表于 1860 年)中,波德莱尔提出了一个广义的、极其精微的(艺术)现代性概念,这个概念能够以一种有启发性的方式将 “现代生活” 和“现代艺术”这样隔得很远(却又微妙相关)的概念带到一起。波德莱尔的定义值得铭记,人们也对它作出了大量评论:现代性不仅仅是在其现时性、短暂特异性和瞬息内在性中被把握的现时,或《现代生活的画家》的作者带着微妙的悖论所说的 “现时记忆”(la mémoire du présent),在美学上,它还是美(这种美甚至可以在邪恶与恐怖事物中见到)的某种更广泛特性,实际上就是不能从已往大师们那里学到或模仿到的美的本质性一半,它只能靠人们自己去发现,靠他们感觉的敏锐性,靠他们对新事物的孩子式感受力,靠他们“持久而快乐” 的好奇心——艺术的这一半是真正神奇的,它允许人们从现实中提取“变幻无常”(phantasmagoric)的东西。
波德莱尔认为现代艺术家(以杰出的素描和水彩画家康斯坦丁 · 盖伊为典型)英雄般地投身于一种孤独的想象性追求:
他所寻求的这种 “别的东西” 我们也许可以称为“现代性”…… 他的任务就是独立于当代的时尚,而不管它在历史上包含了什么属于诗歌的东西;是从转瞬即逝中提取永恒…… 现代性是转瞬即逝、捉摸不定和随机偶发的;它是艺术的一半,艺术的另一半是永恒和不可改变的…… 总之,为了使任何现代性都值得最终变成古老性,人类生活无意识地给予它的那种神秘的美就必须从中蒸馏出来。 26
因此,不出意料,现代性的概念被用在它的第一位明确而重要的理论家身上:在《波德莱尔的处境》(1924)一文中,保罗 · 瓦莱里指出,那些也许比波德莱尔伟大的诗人(浪漫派的拉马丁、缪塞、雨果、维尼)只在法国被阅读,而 “在波德莱尔之后,法国诗歌使自己被全世界阅读;它把自己作为现代性的诗歌而强加于人”。 27
波德莱尔作为现代诗人的形象已成为批评上的权威之见,在瓦尔特 · 本雅明对波德莱尔的解读中这种形象处于核心地位,就像他论这位法国诗人的文章以及《巴黎,十九世纪的首都》这部未完成的纪念碑式著作的那些笔记与片断所表明的。本雅明的现代性概念的某些元素可以直接追溯至波德莱尔(例如 “变幻无常” 的概念),尽管它们通常结合了马克思对市场和资本主义的恶魔式观点——因此 “市场的变幻无常” 这类概念类似于马克思自己所说的 “商品拜物教” 和所运用于市场的巫术比喻。本雅明的现代性概念的其他元素在波德莱尔的诗歌中找到了特别好的文学实例(如 “寓言”,“零碎化”,“浪荡子” 的异化,“物化”,事物降格为商品等等)。本雅明恰当地指出波德莱尔结合了现代(the modern)与恶魔(the demonic) 28 ,他还补充说,当人们从诗人的天主教观点看待现代性时,恶魔的概念就至为清晰地浮现出来。
关于现代性,波德莱尔的异端式天主教(导致他的美在邪恶中的悖谬感觉 29 )可以在本雅明的马克思主义中找到有趣的对应物,本雅明的马克思主义大体上是神话式的,同卡尔 · 马克思完全过时的经济学著作中的看法相比,它允许他就资本主义提出更为复杂和更具有启发性的恶魔论观点。我们无需探讨细节。然而,我们必须指出的是,从波德莱尔到本雅明乃至以后,现代性概念显示出了容纳任何一种对现时及其意义的哲学解释的能力,无论这种解释是美学、道德、科学、技术的,还是更广义的历史——社会的,也无论它是积极的(现代性是好的、可欲的)还是消极的(现代性是创伤或 “悲剧” 30 性的,必须被忘记或被超越)。
在此有必要就现代性的各种意义及它们的理知来源一般性地说几句。人们可以注意到,现代性多数时候是被放在发展语汇中加以理论化的(循着启蒙的那些进步意识形态的思路),这意味着它较过去的历史 “阶段” 更“进步”。但人类为这种进步所付出的代价有时被认为过高——于是有了各种各样 “反现代” 或“对抗现代” 31 的意识形态与宗教潮流,它们在过去的大约一个世纪里遍及全世界。从启蒙运动开始,现代性同进步(或更晚近的源于达尔文生物学理论模式的进化)之间的联姻已在双重意义上变得牢固:当这两个概念激发了乐观主义的历史进程观时,这种联姻就是积极的;在各种悲观主义的历史哲学中,这种联姻则是消极的——在过去的大约一个半世纪里,悲观主义的历史哲学在左和右两方面都大量地繁殖,左的方面是尼采和斯宾格勒,右的方面是阿多诺和霍克海默在《启蒙辩证法》中对现代性的批判以及新左派对进步的总体拒绝。对待历史的这两种对立态度间出乎意料的游移与结合,导致了在一百多年前几乎不可理解的政治悖论与含混性。启蒙的进步信念倾向于向政治标尺的右翼 / 保守 / 古典自由主义一端移动(比如说,我们可以想想罗伯特 · 尼斯伯特的《进步概念的历史》,该书以一种明确无疑的当代保守主义视角赞同进步,而反对它的左翼批评者)。仅仅是最近我们才从左派观点中看到改造利用现代性概念的努力,比如在于尔根 · 哈贝马斯的《现代性的哲学话语》中,该书分析和驳斥了把现代性(亦即胜利的理性)等同于纯粹 “意识形态性权力意志” 的各种哲学努力。哈贝马斯从他自己的交往行为理论哲学的观点出发,致力于在如此之多的激进批评家(从尼采到米歇尔 · 福科,从阿多诺 / 霍克海默到雅克 · 德里达)的攻击之后,为受到诋毁的理性概念正名,并恢复现代性的规范内容,包括对话和共识的概念。 32
与此同时,那些继续认为自己 “进步” 的知识群体对进步及其生态(但也是政治)后果怀有深深的警惕,并赞同一个世纪前会被认为明显反动的那些观点。大体而言,由启蒙世纪的哲学家和文学家们留给十九世纪的“好现代性”(good modernity)观念,在二十世纪里从各种角度(宗教的、社会的、政治的、美学的)受到日益激烈的批评,而且已经让位于一种新的现代性(有人称之为后现代性),这种新现代性更加反现代和反传统,对于新事物的价值怀有深刻的矛盾态度。
就艺术和它们同社会的关系而言,我不禁要回到我早先在现代性研究中所区分的两种剧烈冲突的现代性:一方面是社会领域中的现代性,源于工业与科学革命,以及资本主义在西欧的胜利;另一方面是本质上属论战性的审美现代性,它的起源可追溯到波德莱尔。 33 如今我认为这两种现代性构成一种更广泛冲突的一个具体(如果说特别突出的话)实例。实际上在研究社会——历史问题的所有学科中,都可以表明这种两种现代性的深深分裂——一个是理性主义的,另一个若非公然非理性主义,也是强烈批评理性的;一个是富有信心和乐观主义的,另一个是深刻怀疑并致力于对信心和乐观主义进行非神秘化的;一个是世界主义的,一个是排他主义或民族主义的。
以一种自相矛盾的方式,现代性在上述第一种意义上产生了它自身的对立物,这个对立物以各种文化上反动的(往往是极端保守的)传统主义的形式出现,或者在更高的哲学层次上说,以一种对现代性的悲观主义甚至是虚无主义批评的形式出现。总而言之,现代性在解放批评精神的同时,未能阻止对于它自身的文化 / 意识形态信条和有意无意后果的各种批评性反动。对于现代性的这些批评有的很激进,针对它们所认为的史无前例的大灾难提出了激进的(总体的,往往是极权主义的)解决办法。
比如说,在社会理论的领域,就可以辨别出几种类型的冲突。首先,在那些明确拥抱现代性的人——现代性对他们来说意味着理性、民主、相信开放社会和政治多元主义的优点、高度尊重个体价值、竞争的市场体系等等——和那些以纯净而正义的集体主义未来或回归神话式过去的名义把个人主义——资产阶级现代性视为 “颓废” 或腐败特性而激烈地加以排斥的人之间,就存在着广泛的冲突。然而,后者想保留现代文明的某些元素,诸如那些有望促进经济增长的技术进步,但前提是这些元素必须脱离它们出现于其中的民主——多元主义语境:他们认为,这样的语境导致并不必然与发展相伴随的不平等和非正义。那些拒绝更深层现代性精神的“一党”(one-party)现代化者可以有千差万别的意识形态背景。他们有可能是左派(马克思主义者,新马克思主义者,外围马克思主义者,后马克思主义者),这些人以某种不确定的总体社会正义的乌托邦的名义,憎恨民主的和个人主义的资本主义(马克思主义社会工程的大规模实验的失败,似乎对真正激进的西欧知识分子没什么影响,尽管他们的数量也许减少了)。另一方面,现代性的敌人可能是宗教革命主义者,比如中东或其他地方的伊斯兰原教旨主义者,他们宣扬回归原初伊斯兰教的纯粹性和完全的古兰经法律,但他们却毫不犹豫地享用现代技术的福利,包括战争的技术。
在二十世纪的欧洲,有关这种反对现代的现代性的学说也采取了各种意想不到的形式,比如 “反动现代主义”,它是二十年代后期魏玛“保守主义革命” 和其后三十年代德国国家社会主义乃至第二次世界大战这场大灾难的特征。杰弗里 · 赫夫援引托马斯 · 曼的话,说国家社会主义意识形态是“高度技术性的浪漫主义” 34 。这句话指出了对现代性的纯技术方面的向往同对它的政治——民主内涵的拒绝这两者之间一种奇怪的、事实上是极富爆炸性和有害性的结合。
最后,现代性在欧洲的现代敌人有可能是老派的右翼分子,抑或新生的、后共产主义的右翼分子:各种极端的国家主义者,有时是神秘主义的国家主义者,或是陀思妥耶夫斯基这样信奉 “神义国家”(theophoric nation)概念的人。这些人以对国家的某种集体“神化” 的名义拒绝资本主义。国家主义的兴起是现代性的重大悖论之一:历史地看国家主义是现代性的产物,需要民族国家的体系才能滋生,它的内在逻辑决定了它必然会发明一种反现代神话,并竭力鼓吹回到原始种族的前现代状态——于是大量运用现代衰朽的修辞(“颓废”和 “堕落” 是关键词语)和复活的修辞(有 “复兴”、“再生”、“苏生” 等关键词语)。如果我们注意到,在今天后共产主义的东欧和苏联,对西方现代性的种族政治和法西斯主义式拒绝会得到那些前共产主义党务工作者与理论家的赞同的话,这种悖论就更突出了。在我们难以置信的目光下,法西斯主义(恐外的,甚至在那些不再有犹太人的地方也反犹的,反西方的,反民主的)同共产主义(激烈地反对市场、资本主义和企业家精神)之间已实现了一种新的反现代综合。为了解释这种新的现象,人们已经提出了各种在几年前还不可想象的名称,其中最引人注目(我认为也最恰当)的是 “法西斯主义共产主义” 或“红色法西斯主义”。
我们可以猜想现代性的战斗(既指理知上的也指实际的)远未结束。在下面讨论术语三元组中的其他两个(现代主义和现代化)时,我将主要关注持续不断的现代性战斗的理知——历史传统。
二、现代主义
“现代主义” 一词的历史可以追溯到十八世纪。在英语里它见于斯威夫特的作品,带有强烈的消极内涵。 35 在法语里,同它密切相关的形容词和名词 “moderniste”(现代主义者或现代主义的)用在“偏好现代事物的人” 的意义上,可以在让——雅克 · 卢梭的书信中找到 36 ,也就是说,可以在现代文明的第一个重要现代批评家和回归自然的热情宣扬者那里找到。(卢梭实际上是反现代的浪漫派和后浪漫派意识形态的重要来源之一。)对后缀 “主义” 在现代时期的运用做粗略的历史概观可以表明,直到十九世纪,它都主要是拥有神学的、往往是消极的内涵:它指宗教教派和趋势(卡尔文主义,冉森主义),经常是指异端(阿里乌主义,鲍格米勒主义,等等)——现代主义也许就是因此而在十九世纪有着消极内涵。
在十九世纪,“主义”意味着政治(雅各宾主义、社会主义、自由主义、共产主义)和文学艺术(浪漫主义、现实主义、象征主义、印象主义)方面的运动、信条或趋势。二十世纪前半期也许是堪称敬语的 “主义” 的黄金时期。在艺术与文学生活中,我们有未来主义、立体主义、达达主义、超现实主义、超主义、构成主义、现代主义,以及诸如此类。我们不妨顺便指出,“主义”的时代似乎已经结束。在过去的几十年里,我们的分期术语对前缀 “后” 表现出明显的偏爱:这意味着我们不是从正面辨识自己,或者根据某种规划或强烈信念辨识自己,而仅仅是根据在各种 “主义” 之后到来这一点来辨识自己。我们谈论后现代主义、后马克思主义、后共产主义、后结构主义,等等。
在二十世纪早期,现代主义获得了两种专门意义,对知识史家来说它们都是非常有意思的。除了现代主义 / 传统主义这种通常的术语对立外,现代主义还用于指艺术中各种革新和反传统的新趋势。这种艺术上的意义(对它的使用者们来说是非常积极的,对其他人来说则是很消极的)可以在许多欧洲语言中找到。在法国,前面曾经引用过的《法兰西语言瑰宝》以普鲁斯特(普鲁斯特在《索多姆和戈摩尔》中提到德彪西的《佩雷阿斯》是 “现代口味” 的范例)、保罗 · 莫兰和文学批评家阿尔贝 · 蒂博代的文本为例说明了这种美学意义。与此同时,艺术意义上的现代主义在英国主要被运用于建筑(如果我们考虑到《牛津英语词典》所引用的实例),但我们亦可以找到用它来指涉革新诗歌的相当重要的实例(约翰 · 克罗 · 兰塞姆与劳拉 · 赖丁和罗伯特 · 格雷夫斯的文本)。 37 在西班牙语中,“现代主义”(modernismo)当然是一场重要的世纪之交的诗歌运动,由鲁文 · 达里奥发动,安东尼奥 · 马卡多和胡安 · 拉蒙 · 希梅内斯这类重要诗人继之而起。
现代性的第二种专门意义出现得稍早,并有着更精确的历史界限:在二十世纪的头一个十年里,它命名了罗马天主教会内部一种松散的神学 “现代化” 运动(或者说试图使宗教信条同现代科学某些关键发现或理论相一致的运动),这个运动在《放牧子民》(1907)的通谕里被教皇庇护十世严厉地谴责为“所有异端的综合”。对于研究术语的学者,梵蒂冈对现代主义的狂暴拒绝从几点上说都是很有意思的。首先,它将现代主义和现代主义者当作羞辱词汇来用,对于一个始终警惕着变节者、异端和叛徒的顽固保守而好战的宗教机构,这是意料之中的事。比如说,教皇写道:“…… 现代主义者们(正如他们常常恰如其分地被称呼的)运用一种非常聪明的诡计……” 38 其次,也是对前面那一点的加强,现代主义者们(阿尔弗雷德 · 卢瓦西,弗里德利希 · 冯 · 于格尔,乔治 · 蒂雷尔,埃尔内斯托 · 波纳尤蒂,等等)并不称自己为 “现代主义者”,他们的“现代主义” 纲领也不是出现在通谕之前;我还可以补充的是,他们也没有意识到一种共同拥有的 “现代主义” 教义。(通谕中所记录的那种教义是教皇及其顾问的指控想象的发明:并不是像通谕所说的那样,现代主义者没有以康德的 “不可知论” 或“科学与历史无神论”作为他们理论的基础,他们也没有宣扬对 “生命内在性” 的信仰。)世纪之交天主教会的 “现代主义危机” 对今天观念史家有意思的第三个原因是,现代主义者以他们各自的方式,都卷入了使教会教义同现代科学知识(比如进化理论)和现代历史批评的信条更融洽的努力;也就是说,广义地看,他们是一个对变化与革新无动于衷、顽固地守旧与僵化的机构的潜在现代化者。比如说,他们试图考虑到“他们称为文本批评的那个批评分枝” 39 的发现,去怀疑摩西不是《五经》的作者,或是怀疑有关《福音书》作者的传统观点。(现代主义者们接受这些观点,而不是执着地反复钻研经院哲学——教皇针对现代主义灾难开出的主要药方;按梵蒂冈官方的看法,他们比教会的公开敌人更坏,也要危险得多:他们蓄意从内部推翻教会。)
现在我将简要地关注一下世纪之交天主教 “现代主义危机” 的这第三个方面,以为我讨论术语三元组中的最后一个即现代化开个头:因为我认为,天主教世界里的现代主义争吵是二十世纪有关文化现代化利弊的长期论争中最早的明确阶段之一。卢瓦西和其他现代主义者的所作所为,提供了在一个研究与反思的传统领域里进行理知现代化的非正式的、也许甚至是不自觉的范例,这个领域尽管有它的体制利益,也不能同现代科学的发展隔绝。有趣的是,我刚才使用的短语,“理知现代化”,用了将近一个世纪才在二十世纪七八十年代得到较稳定的使用,其间诸如 “经济现代化”、“社会政治现代化” 等短语在五六十年代广泛流行。因此,比如说,托马斯 · 帕维尔一部批评结构主义的著作的书名是:《语言学幻景:论理知现代化》。我要补充的是,这位作者认为,结构主义者选择语言学模式作为所有人文科学(从心理学到文学理论)的模式,试图以此来现代化所谓的“人文科学”,这是误入歧途和自欺欺人的。 40
天主教的现代主义危机源于一种正面冲突,冲突的一方是天主教的传统和教条,另一方是对科学方法及其要求的承认。同流行的观点相反,科学代表了不确定性对确定性的胜利,代表了怀疑和(如我们将看到的)普遍的易错论(fallibilism)对各种形式理知权威和无错论的胜利。我们不妨补充的是,灵活的、自我批评的、相对主义的、富有理论勇气的新的科学精神,不仅在前途渺茫的神学界有着巨大吸引力,而且在整个进步知识界,包括世纪之交的文学艺术先锋团体与流派中有着巨大吸引力:在立体主义绘画和从阿波利奈尔到桑德拉尔到马克斯 · 雅各布的早期现代主义诗歌中,都可以很容易地找到例证——如果我们只限于就法国文化界来谈的话。 41
三、现代化
正如各种现代欧洲语言的主要历史词典告诉我们的,“现代化” 这个词确立于本世纪的第一个十年。然而,它的意义仍然相当含混:现代化就是跟上时代,就是给予某物(一幢建筑,一处室内布景)一种新的或现代的外表,或是采纳一种更现代的观点。天主教会历史上的现代主义插曲,是理知现代化的复杂问题明确而富有戏剧性地出现的一种早期情形。现代主义者们究竟为的是什么呢?他们企图去做某种至少在当时是不可能的事:把作为教会权威之基础的天主教教条与传统教义,同现代历史批评的主要原则,以及更广泛地说,同现代科学世界观加以调和。在这一语境中,现代性既是一种心智结构(理性主义的,分析的,易于接受革新与变化,欢迎批评,以及如查理 · 桑德斯 · 皮尔斯所说的是 “易错论的” 42 0),也是对知识的一种特定态度——知识是通过假设和验证取得的,求知的过程理想地说应摆脱任何外在权威与体制(包括科学共同体本身)的专断,同时也应摆脱个人信仰与偏见的固执。换言之,在一种很重要的意义上,现代性是以知识(亦即科学)和技能概念以及它们在教育和教育之外各个领域中的广泛运用为主要内容的——最明显的应用之一是推动发现、发明、革新与发展。
世纪之交,天主教机构中作为宗教哲学家、神学家和教师的那些现代主义者,面对的是现代性的认识论——科学方面。有需要时,他们中的每一个都会以各自的方式试图去表明,教会所承认的那些教义或著作,包括《圣经》,仍然处在科学的权限之外,并因而是信仰的合法领域;他们也试图表明,这些教义和著作受到了科学的影响,必须重新解释,以避免同各种强有力的假设或理论所表达的那些在科学上不可否认的事实发生冲突。基督教信仰中的一些基本奇迹(基督的神圣性,他的实际复活——这与那些早期传教士所真诚地信仰的相反,等等)被给予一种有限制的(神学、象征式)解释,而不是传统的字面解释,在一个科学享有如此高文化威望的时代,这并不令人惊奇。重要的是要记住,现代主义者从未攻击过任何天主教教义或信条(如教皇说他们宣扬 “科学无神论” 时所表明的),相反,他们想让这些教义或信条在现代科学的深远影响面前尽可能站得住脚。在教义问题之外(第二次梵蒂冈会议证明现代主义者在大多数教义问题上是正确的),世纪之交的现代主义危机关系到现代化这个较大的问题——作为一个例证,它表明现代性在天主教会这样一个具有传统、等级和极权式结构的机构中所导致的紧张与冲突。这场危机是现代性的易错论逻辑同传统的权威逻辑之间对立的一个极有说服力的实例——前者有着个人主义——民主式的基础,包括思想与讨论自由的原则,后者有着走向无错论和不宽容的内在倾向。
在二十世纪晚些时候,当现代化这个词被社会科学家们更广泛地使用时(现代化是经济学家所说的发展在社会学上的对等物,而且往往是非西方或反西方国家趋向西方式工业化的一种委婉措辞),(被迫)现代化的某些意想不到的悖论就出现了。 43 这些悖论中最明显的,也许是那些内在地反现代、反民主并具有严格等级结构的组织所实施的现代化政策中的悖论。被一些历史学家视为一种发展 / 现代化策略的共产主义就是一个切题的好例子。不妨看看最强大的前苏联共产党,以及堪称 “共产主义黄金时期” 的斯大林主义。为了保持同列宁主义的社会主义理论一致,斯大林制订了使苏联实现现代化的计划——他的那些总是在四年里就超额完成的著名的五年计划,对他来说,现代化就是在由国家独占一切生产手段的集中计划经济内,不惜一切手段迅速发展重工业。共产党领导着这个发展过程——就像苏联共产主义者常说的那样,赶上并超过西方——党是一个绝对集权的 “铁板一块” 的组织,它的政策当然容易犯错误。如果犯了错误,对它们负责的只是人民的那些单个敌人(叛徒,间谍,破坏分子):党总是正确的,因为它体现了工人阶级最进步成分的集体智慧,这种智慧有效地集中在最高领导者的头脑中,也就是斯大林本人,“一切时代的最伟大天才”。今天我们知道趋向发展 / 现代化的布尔什维克运动有多“现代”。关于苏联以及第二次世界大战后它在东欧的那些卫星国,人们宁可谈论“伪现代化”。 44 社会工程中的全面共产主义实验(它也被认为产生了一种幸福的 “新人”)最终被证明是失败的,可悲的是,对于真正的发展问题它并没有提供有价值的见解,它也没有留下任何教训,要说有的话也完全是负面的。正如卡尔 · 波普尔常说的,我们总是从小错误中获得教训,但要从大错误中获得教训若非不可能也非常不容易。(极大的错误会毁了我们。)同共产主义趋向一种明显虚假的现代性的冲动相反,开放社会意义上的真正现代性可以视为一个框架,它能限制社会行动者们注定要犯的错误的规模与范围,并使他们处于一个能从那些较小错误中获得教训的地位——开放社会的基础是个人主义与民主价值观,以及在某些得到社会 / 文化认可的限制内运行的市场经济。
现代化的问题最直接地表现在第二次世界大战后的第三世界国家,也就是那些最近从殖民统治下独立出来的民族国家。对这些国家来说,经济的发展与增长似乎是极其合乎意愿的目标,它们居民的大多数仍旧生活在各种传统社会形式下。在一个新的语境中,现代化的概念加剧了传统同现代性之间的旧有冲突。这里我不打算讨论有关现代性的浩繁文献(主要写作于二十世纪五十和六十年代之间),也不打算讨论自这个概念出现以来它所受到的那些往往很有力的批评。
对我来说有意思的是,这些文献,特别是它们所运用的理论框架,显然已经由那些在世纪之交影响臻于极致的伟大社会学家的著作预示出来了——我想到的名字是费尔南德 · 特尼厄斯(1855-1936),埃米尔 · 杜尔凯姆(1858-1917),或马克斯 · 韦伯(1869-1924)。他们中没有一个人运用现代性 / 现代化的术语,但他们都提出了可以准确地转译为这类术语的概念,也都意识到从以传统为基础的社会 [以特尼厄斯所说的“集体”(Gemeinschaft)为典型] 向“社团”(Gesellschaft)型现代社会过渡所带来的急剧(有时是创伤式)变化。(现代社会以韦伯所说的工具理性的支配为特征,按照他的著名假设,现代社会主要是源于加尔文主义工作伦理在北欧和北美的胜利。)同马克思相反,韦伯反对简单化的单向经济决定论(它过去是也仍将是许多非马克思主义经济发展理论的特征):按韦伯的看法,经济中的变化源自复杂的、本质上不可预测的精神变化,源自人们的信仰、信念、生活习惯和期望的变化。今天,当东欧的前共产主义国家试图在几乎一夜之间转向市场经济时,韦伯的论点敲响了警钟:因为市场不只是一种单纯的经济机制,它也是一种精神的表现,一种文化现实的表现,一种个体生活投射与预期的复杂集合的表现。唯其如此,那些后共产主义情形的更为深思熟虑的观察家们认为,在这些国家中,向现代市场体系的过渡往好里说将是一个长期而痛苦的过程,也许需要好几代人的时间,往坏里说则永远不可能实现。如果老的精神状态继续存在,现代市场就仍然是一个没有内容的形式,一个空壳,一种假象,一种导致另一类型虚假现代性或者也许是伪现代性的新现代化策略(在社会主义的策略明显失败以后)。
世纪之交的社会学家(他们假定在传统社会与现代社会之间有裂缝)和二十世纪中期的现代化理论家们所预设的进化论模式,反映了十九世纪下半叶无所不在的达尔文进化论的影响。进化论模式取代了在它之前各种天真的永恒与和谐进步(包括技术进步)的学说。不幸的是,进化论往往被错误地解释,导致各种社会达尔文主义,包括各种生物学决定主义和种族主义理论,人种改良学主张,以及其他此类在二十世纪历史上起到有害作用的理知恐怖。有时这类理论是以现代性或现代化的欺骗性名义表达出来的,另一些时候它们是以相反的、同样有欺骗性的名义提出的,亦即同现代性(资本主义、犹太人、有钱人、共济会员、腐败的资产阶级民主等的剥削性现代性)斗争。
如果得到正确的理解,进化论就仍然是理解和解释变化特别是增长(按波普尔的看法包括知识增长)的最有效模式。然而,这个模式的有效性直接取决于承认进化不是也不可能是某些东西。首先,进化必须严格地以非神学的方式来理解 [它没有向之前进的目标,不表现某种规划,不显示“进化的一般规律”,不体现“天命”(providence)]。其次,它是不可预言的(人们无法确言哪些变革会获得成功,哪些趋势会取胜,哪些变化会被“选择” 掉)。当然它的不可预言性并不意味着进化失去了其解释力量,也并不意味着人们就不能用它来分析一种既定情境或问题,并对它进行假设。第三,由于进化适用于开放体系,在下述意义上它是非决定论的:它按照一种可能性相互作用的原则运作,或者按法国生物学家弗朗索瓦 · 雅各布所说的“可能的游戏”(le jeu des possibles)原则运作——没有必须要服从的进化道路或轨迹之类。第四,进化模式在运用到人类行动者所造成的人类情境(比如社会科学所分析的那些情境)时,必须考虑到卡尔 · 波普尔在其经典著作《历史决定论的贫困》中较详细地谈到过的那种“无意后果”。波普尔主张有关人类本性的心理学不能用作社会科学的基础,
因为社会科学主要关注的是人类活动的无意后果或影响。而在此语境中的 “无意” 也许并非 “没有经过有意识计划” 的意思;相反,它用于描述那些有可能违背社会行动者所有意愿的后果。 45
各种现代化企图的历史大体上就是各种宏大现代化规划带来无意后果并最终失败的历史的一部分,特别是那些根据马克思主义——列宁主义和其他类型历史决定论构想出来的规划。正如波普尔指出的,历史决定论为它自己是 “现代的” 而感到骄傲,但实际上它的教义极其古老。历史决定论者相信——他们对现代主义的神化还能允许什么呢?——他们自己那种历史决定论是人类心灵最新近和最大胆的成就,这个成就是如此惊人地新颖,以至于只有少数足够进步的人才能理解它。…… 把他们 “动态” 的思想同先前世代 “静态” 的思想相比,他们相信是下述事实使他们自身的进步成为可能:我们现在“生活在一场革命之中”,这场革命大大加快了我们发展的速度,以至于社会变革现在可以在一个人的一生中经验到。当然,这种说法纯属神话。重要的革命在我们的时代之前就已经发生了…… 46
伟大的变化(如波普尔在《开放社会及其敌人》中所认为的)是从原始封闭社会向 “自赫拉克利特的时代以来变化在其中一次又一次地被发现” 的社会过渡。
人们无需赞同波普尔对现代主义的全盘拒绝(他用现代主义来指激进变革或结构改革的意愿,或者更晚近时代堪称快速现代化激进纲领的思潮),也无需分享他对各种具体的历史决定论式现代性与现代化理论的厌恶。这些理论既是 “宿命论的”(现代性是不可避免的历史进程中的一个必然阶段),也是 “唯意志论的”(现代性是一个人们必须为之奉献、必须努力使之实现的纲领)。历史决定论差不多是注定(由于其有缺陷的内在逻辑)要走向在整体主义 / 极权主义 / 乌托邦语汇中得到表达的现代化问题。因而有如此多雄心勃勃的现代化规划遭到彻底失败。那些较有限、较局部、较具体的现代化尝试对社会的文化母体有着灵敏的感应,它们不仅更成功、更丰产,而且具有一种有益的累积效果,并使人们对无法避免的无意后果拥有较好的控制。在那些它们不仅设法适应了既定传统结构,而且使这些传统为现代化所用的地方,它们取得的成功就更大;比如在日本,个人主义的西方现代性经过调整,就有效地获益于日本文化传统的集体定向(group-orientation)。
作为文学批评家和文学理论家,同我们的关注点更切近的是 “文学现代化” 的问题。就文化而言,现代化冲动往往更关心知识时尚(尽管它可能会愤怒地谴责它们),而不太关心科学或认识论问题(尽管表面上它可能会关心)。就此而言,现代性 / 现代主义 / 现代化这一术语丛就接近于有关 “现代” 的错误词源学观点,即认为它源于 modus(风格,时尚),在法语中,这种观点还暗示出 “现代” 与“时髦”(mode)之间密切的亲缘关系。当然,知识时尚可以由科学或科学哲学中的潮流激发。但即使如此,知识时尚——以刚才提到的法国结构主义为例——也更多是同科学神话而不是同科学本身有关。正如帕维尔在其《语言学幻景》中表明的,语言学模式,更确切地说是音系学模式,就像克洛德 · 列维——斯特劳斯在其结构人类学中用来解释亲缘模式和神话思维的,没有任何科学的根据:然而,这并不妨碍它在人文科学中获得几近专暴的地位——时尚可以像任何形式的科学神话一样专暴,包括 “科学社会主义”。结构主义狂热差不多持续了二十年,并为一种古怪的、把自己当成唯物主义的语言学唯心主义所支配。这种唯物主义,或更确切地说是唯物主义幻象,来自于马克思,在二十世纪五十年代至七十年代早期,马克思的著作在法国享有巨大的“科学” 声望。为了使文学话语“现代化”,当时那些比较进步的法国批评家除阅读列维——斯特劳斯的著作外,还阅读他所承认的那些大师:语言学家费迪南德 · 索绪尔,马克思,以及弗洛伊德。这也许就像俄国和东欧通过马克思主义实现社会政治与经济现代化的尝试一样错误,不它过当然不会有那么大的破坏性后果。
这当然也是不得法的,就跟自世纪之交以来,促使文学批评现代化的那些早先尝试一样——它们试图给予文学批评以更多的科学尊严:从费迪南 · 布吕奈吉埃尔在《文学史中的文体演变》(1890)中相当粗糙地把达尔文模式运用于文学史,到更晚近在精神分析、精神分析马克思主义、结构主义马克思主义(路易 · 阿尔杜塞及其追随者)或后结构主义马克思主义这类知识时尚中接受实证主义——历史主义研究模式。作为(知识)时尚的现代性有其独立的社会学动力,而且就像前面已经指出的,同其误入歧途的社会——经济对应物相比,它是无害的。仅就文学与文学批评来谈,人们甚至可以谈及时尚的某些益处,至少是在它的初始阶段。服装时尚的内在性逻辑是对感觉的一种更新与变换,与之相似,批评中的方法论时尚也可以说是通过更新文学感觉,亦即人们赖以阅读文学作品的那些假设的结构(structure of assumptions),来更新文学作品。同这些假设最初的新颖性以及为使它们变得可行而必需的理知——想象努力相比,下述事实也许就不那么重要:它们可能是错误的、还原论式的或刻板教条化的。当时尚变得更为流行时,当它的新颖性逐渐消失时,当习惯与模仿削弱了付出真正的创造性努力以让它变得可行的需要时,它就已经度完了它的有用生命,而变得越来越有害,因为它生产出供人鹦鹉学舌的一套行话,并鼓励固执和遵从。
作为结论,我要说的是,由于真正的现代化在任何领域都是同创造性(解决现存问题的首创方式,想象,发明等)相联系的,它排除了模仿,或至多给予它一种外围角色,这同许多现代性或现代化理论家所认为的相反。唯其如此,我要说,人们不应只谈论一种现代性,一种现代化方式或模式,一个统一的现代性概念——它内在地是普遍主义的,并预设独立于时间与地理坐标的普遍一致标准。如果现代性的确是创造性的——无论是作为经济上的发展,还是处于可能性范围的另一端,作为知识与见解通过不可预言的发现获得增长——那它就只能是多元的、局部的和非模仿性的。因此,当波德莱尔说现代性就在于对现时、对现时之现时性的一种独特感觉时,他是对的,而且不仅仅是在美学上。在波德莱尔看来,这种感觉不可能通过模仿古代大师们学到,人们只能靠自己去获得,靠自己感觉的敏锐性,靠自己面对新事物时的好奇,靠波德莱尔定义为 “回复童年”(enfance retrouvé)的那种天赋——因为 “儿童看一切事物都是新的”,并因此能够更新世界。在此意义上,现代性只是又一个用来表述更新与革新相结合这种观念的词。
注释
现代性的概念
[1]. 米尔恰 · 埃里亚德,《永恒回归的神话》,威拉德 ·R. 特拉斯克译自法文(New York:Pantheon Books,1965)。关于各种时间观念的讨论,从原始人的 “梦幻” 时间到现代人的“无法阻挡地流逝的时间”,亦见 J.B. 普里斯特利,《人与时间》(Garden City, New York:Doubleday,1964),pp.136-189。
[2]. 《拉丁语言宝库》(Leipzig:Teubner,1966),卷 VIII, p.1211。
[3]. 恩斯特 · 罗伯特 · 柯蒂乌斯,《欧洲文学与拉丁中世纪》,威拉德 ·R. 特拉斯克译自德文(New York:Harper&Row,1963),pp.251,254。
[4]. 对于这个问题以及更广泛的对于中世纪时间范畴的讨论,见瓦尔特 · 弗罗因德,《中世纪的现代和其他时间概念》(K ln:B hlau Verlag,1957),pp.4ff。关于中世纪后期 “现代 / 古代” 对举的用法,见阿尔伯特 · 齐默尔曼编,《古代与现代:中世纪晚期的传统意识与进步意识》(Berlin, New York:Walter de Gruyter,1974),特别是韦尔弗里德 · 哈特曼、伊丽莎白 · 葛斯曼和君特 · 沃尔夫的文章;亦见伊丽莎白 · 葛斯曼,《古代与现代:一部定位史》(Munich:Sch ningh,1974)。中世纪总体上的传统主义,及其对于由独一无二、不可重复的时刻组成的历史时间普遍漠视,同基督教时间哲学所隐含的深刻历史感相反。关于中世纪排斥初期基督教时间概念的悖论式观点,德尼 · 德 · 鲁热蒙在《人的西方求索》中作出了令人信服的论证,该书由蒙哥马利 · 贝尔金英译(New York:Harper,1957)。对于基督教时间的革命性挑战,德尼 · 德 · 鲁热蒙写道,“中世纪通过回到种种循环概念、通过对过去与未来的规模加以严格限制来抵抗:由此造成的时间凝滞所带来的结果是,一切生成(becoming)都被根除”(p.95)。在鲁热蒙看来,“中世纪是欧洲的‘东方’时期”,这是因为它日渐倾向于…… 用传统、神话式寓言和传奇来代替那些仅仅由《圣经》表明具有历史性的事实,而《圣经》那时很少有人读。所有这些都加强了我的观点,即中世纪远非代表了某个模糊的 “基督教黄金时期”——如浪漫派首先宣称并从此被令人生厌地重复的——而是更一般地说代表了针对《福音书》带来的革命酵母而进行的长时间防卫反击(p.90)。
[5]. 柯蒂乌斯,前引书,p.119。
[6]. 索尔兹伯里的约翰,《元逻辑》,丹尼尔 ·D. 麦格里翻译、作序并加注(Gloucester, Mass.:Peter Smith,1971),p.167。
[7]. 对贝尔纳的比喻的解释,见埃都瓦尔 · 若诺,“站在巨人肩膀上的侏儒:试解沙特尔的贝尔纳”,Vivarium V,2(1967 年 10 月):79-99。关于贝尔纳的比喻在十二世纪的流传(布卢瓦的彼得,亚历山大 · 内克姆),见 J. 德 · 盖兰,“侏儒与巨人”,《中世纪拉丁文献档案》18(1945):25-29。后来论述这一主题的非常有用的文献是:福斯特 ·E. 盖耶,“巨人肩膀上的侏儒”,《现代语言随笔》45(1930):389-402;乔治 · 萨顿,“站在巨人的肩膀上”,Isis, no.67,XXIV, I(1935 年 12 月):107-109,以及雷蒙德 · 克利巴恩斯基对萨顿文章的回答,“站在巨人的肩膀上”,Isis, no.71,XXVI, I(1936 年 12 月):147-149。对侏儒与巨人主题的更晚近讨论,见罗伯特 ·K. 默顿,《在巨人的肩膀上:一个项狄式附言》(New York:The Free Press,1965)。正如凯瑟琳 · 德林克 · 波文在前言中所说的,这是 “杰出的、疯狂的、奔放的项狄式附言,…… 一次嬉闹,一场游戏,一次娱乐,一场舞会——一次不可能的学术探险,游荡一番之后又出来了……”(p.VII)
[8]. E.J. 特伦奇曼译,《蒙田随笔》(London:Oxford University Press,1927),卷 2,p.545。
[9]. 罗伯特 · 伯顿,《忧郁解析》(London:Dent, Everyman’s Library,1964),p.25。
[10]. 引自 L.T. 莫尔,《艾萨克 · 牛顿》(New York:Charles Scribner’s Sons,1934),pp.176-177。
[11]. 布莱兹 · 帕斯卡尔,《思想、书信与小品》,O.W. 怀特英译(Boston:Houghton, Miffin and Co.,1882),p.544。
[12]. 同上,p.548。
[13]. 见 J.B. 普里斯特利,前引书,p.38。亦见 L. 桑代克,“公元 1271 年左右机械钟的发明”,Speculum 16(1941):242-243。关于中世纪晚期老式时间意识与新式时间意识之间的区分,特别是测量时间的新机械方法的影响,见让 · 勒克莱尔,“中世纪早期的时间经验与时间概念”,齐默尔曼编,《古代与现代》,pp.1-20。关于中世纪两种冲突的时间概念——宗教时间对商业时间——有一篇值得注意的文章,就是雅克 · 勒 · 戈夫的 “中世纪:教会的时代与商业的时代”,《年鉴:经济、社会、文明》15(1960):417-433。
14 里卡尔多 · 基尼奥内斯,《文艺复兴对时间的发现》(Cambridge, Mass.:Harvard University Press,1972),p.7。
[15]. 同上,p.11。
[16]. 西奥多 ·E. 默森,“彼特拉克的‘黑暗时代’概念”,Speculum 17,2(1942 年 4 月):241。
[17]. 《非洲》,IX,451-457。引自默森前引文,p.240。
[18]. 弗朗西斯 · 培根,《知识的进步》W.A. 赖特编(Oxford:Clarendon Press,1900),p.38。托马斯 · 霍布斯在其《利维坦》(1651)的 “结论” 中使用了同一个悖论:“尽管我崇敬那些古代人,他们或者清晰地写明了真理,或者为我们安排了自己寻找真理的较好道路,但我认为没有什么要归功于古老本身:因为如果我们要崇敬古老的时代,那么现时就是最古老的时代。”(霍布斯,《利维坦》,1651 年版的重印版,Oxford:Clarendon Press,1947,p.556)。到斯威夫特的时候,这种观点差不多已是滥调了。因而《书的战争》(1704)的作者会取笑所有这种论调(特别是运用于文学时),他写道:“这儿有一个孤独的古代人,挤在满架的现代人中间,试图公正地辩论这个案子,提出理由以证明,由于长期的支配地位,鉴于他们的慎思明辩,应该是古人占优,同时他也显得非常困惑,为什么古代人敢于坚持他们的古老性,因为明摆着(如果他们想到的话),两者中间现代人更年老。”(斯威夫特,《一只桶的故事》,Oxford:Clarendon Press,1920,p.227)
[19]. 《弗朗西斯 · 培根著作》,J. 斯伯丁等编(Boston:Taggard and Thompson,1868),卷 VIII, p.26。
[20]. 同上,p.116。
[21]. 关于丰特奈尔对培根悖论的使用,见他的 “离题话……”,《全集》(Paris:1742),卷 IV, pp.191-192。奥古斯丁在人类进步与个体进步之间所做的老的比较,被用来配合启蒙的无限进步信条。因此,现代人比古代人年长,但他们永远也不会实际变老,因为这样的人类(不同于构成它的那些生命短暂的个体)永远保有成年人的优势。丰特奈尔写道;“因此,这个从世界开始之时一直活到现在的人类有他的童年,在这童年里他只关心生活中那些最迫切的需求,他有他的青年,在这青年里他在那些富有想象力的事物如诗歌和雄辩上相当成功,并且正是在这个时候他开始运用理性,但主要是带着热情而非稳健。现在他处在成年时期……” 但是,丰特奈尔补充说:“这个人决不会有老年。”尽管早在笛卡尔的时代培根的名言就已在法国使用,丰特奈尔的同时代人、耶稣会士多米尼克 · 布乌尔斯神父仍然认为它惊人地富于悖论。在他的《精神劳动中的良好思维方式》(1687)中,布乌尔斯引用了培根的话:“就我而言,我有点赞同大法官培根的话,他认为古代世纪就是世界的青年时期,因而我们便是古人。”但他接着指出:“我不知道…… 培根的思想是不是一点也不难把握。”(《精神劳动中的良好思维方式》,1715 年版,Brighton:Sussex Reprints,1971,pp.138-139)
[22]. 福斯特 ·E. 盖耶,“我们才是古人”,见《现代语言随笔》XXXVI,5(1921 年 5 月):260。
[23]. 奥古斯丁实际上坚决反对当时的 “进步主义” 和乐观主义神学家(切萨雷亚的埃乌塞比乌斯及其追随者),他的历史概念肯定是悲观主义的(他说他的时代是 “罪恶的”、“邪恶的” 等等)。对奥古斯丁反进步主义历史哲学的论述,见西奥多 ·E. 默森,“圣奥古斯丁与基督教的进步概念”,《观念史杂志》,卷 XII(1951):346-374。
[25]. 柯蒂乌斯,前引书,p.254。
[26]. H.R. 姚斯的文章作为复制版夏尔 · 佩罗《艺术与科学方面的古今比较》的前言发表(Munich:Eidos,1964),pp.8-64。
[27]. 佩罗,前引书(注 26),p.322。
[28]. 同上,p.308。
[29]. “现代式离题话”,见《一只桶的故事》(Oxford:Clarendon Press,1920),p.129。
[30]. 佩罗,前引书,p.296。
[31]. 帕斯卡尔,前引书,pp.545-546。
[32]. 布瓦洛,《诗艺》,阿尔伯特 ·S. 库克编,索默英译(New York:Stechert,1926),pp.195-196。
[33]. 引自 H. 里戈,《古今之争史》,1859 年版的复制版(New York;Burt Franklin,1965),p.89。笛卡尔认为《圣经》是诗歌美不可超越的典范,里戈注意到,这种观点同夏多布里昂《基督教天才》一书的基本假定有相似之处。但他同时强调了二者的差异。在评论德马雷的《心灵的欢乐》(1658)时,里戈写道:“德马雷用这种多产的思想做了些什么呢?一本某些章节奇特然而几乎不可读的书。夏多布里昂先生用这思想创作出《基督教天才》。这就是一些思想的特有幸运,它们孕育着这样的作品,并且等了整整好多个世纪直到一位伟大的作家使这些作品现身!”(pp.88-89)
[34]. 理查德 · 赫德,《关于骑士制度与罗曼司的信札》,1762 年版的复制版(New York:Garland,1971)p.57。
[35]. 同上,p.56。
[36]. 同上,p.55。
[37]. 实际上,司汤达《意大利绘画史》中论 “理想美” 的一节早在 1814 年就写了。司汤达在古代的美的理想和现代的美的理想之间所做的早期区分今天也许显得一目了然 [见他的《全集》,乔治 · 厄德编(Paris:Larrive,1953)卷 3,《意大利绘画史》,第四册至第六册,pp.155-214],但它在表述方式上较之在内容上更具独创性;在他提出这种区分之前,在英国、德国甚至法国,诸多术语和分类上的二元对立已经被提出来了。在法国,斯塔尔夫人的《论德国》已在 1813 年引入了“古典 / 现代” 这种美学对立。说到底,司汤达所理解的现代美相当于 “现代性” 的宽泛历史意义,或是出现于 “古今之争” 晚期阶段的浪漫主义。举个例子说,我们记得司汤达曾引用十六世纪后期塔索的作品《被解放的耶路撒冷》中的一句话,来表明体现在诗歌中的现代美同古代美的差别(p.216)。同时,通过强调爱——更具体地说是浪漫之爱——在现代的美的理想形成中的作用,司汤达不出意料地引出了中世纪的骑士制度。
除了通过气候、法律制度和气质理论之类因素来解释古代美与现代美这种一贯的论战性历史主义,司汤达方法中真正新的东西是他对现代文明某些价值观念的强调,这概括性地体现在他在巴黎这个现代大都市同古代雅典之间所作的富有启发性的对比。他写道:
太阳在法国有点苍白;在法国,人们富有才智,人们倾向于在激情表现中掺入一些研究…… 关于感情,也许在巴黎才能找到最细腻的评判者;但总是存留着一点冷淡。因此正是在巴黎,人们最完美地描绘缠绵的爱情,最完美地使人感受一个词、一瞥和一次注目的影响…… 在雅典人们并不追求这般的色彩变化,这般的细致。自然的(物理的)美在它所到的一切地方都获得一种崇拜。这些人最终难道不会想象,那些居住在美好身体里的灵魂会比那些藏在粗俗形式之下的灵魂怀着更多的厌恶离去?…… 然而对美的崇拜只是自然的(物理的),爱情也没有走得更远……(pp.226-227)
在司汤达的看来,什么是现代的美的理想的主要特征呢?作者以一种似乎相当随意的方式列举出来:
1. 极度活跃的精神。
2. 性格中富有优雅。
3. 闪亮的眼睛,不是闪着昏暗激情之火,而闪着跳跃激动之火。心灵活动的最生动表达是在眼睛中,这是雕塑捕捉不到的。现代的眼睛因而将非常大。
4. 非常愉快。
5. 丰富的感受力。
6. 轻盈的身材,特别是青春的灵活神态(p.219)。
在这些特征之外我们必须加上 “优雅”(p.229)和“高贵的” 外表(p.223)。这种美的概念难道不会被误认作十八世纪罗可可趣味的过时表现吗?司汤达的美学观点实际上更为复杂和有趣。甚至早在《意大利绘画史》中,他就提出了自由与创造对于艺术必不可少这种强烈主张,不屈服于任何规则、原则或方针能导致真正的艺术成功。一个真正的艺术家仅仅服从他自己的个性,而抵制去模仿任何其他艺术家的诱惑,不论他们是古代的还是现代的。因此,作为现代美的核心特征出现的,是某种精致的心理学复杂性,这种复杂性同罗可可风格的琐碎无关。但为了全面提出他的现代性理论,司汤达似乎需要 “浪漫主义” 一词,1823 年他从意大利语中采用了它,在一种较《意大利绘画史》更精确、更流动的意义上用它来指现代性。
[38]. 司汤达,《全集》,乔治 · 厄德编(Paris:Larrive,1954),卷 XVI, p.27。
[39]. 同上,p.227。
[40]. 同上,p.28。
[41]. 习惯约束想象,削弱人感受审美快乐的能力。司汤达说得非常清楚:“甚至对于那些最明智的人的想象,习惯也行使着一种专制权力,并且通过这些人的想象,对艺术所能给予他们的快乐行使专制权力。” 同上,p.54。
[42]. 关于现代性作为一个概念的一项详细研究,是汉斯 · 罗伯特 · 姚斯的 “现代性的文学传统与当代意识:术语史研究”,见汉斯 · 斯特凡编《现代性的诸方面》(G ttingen:Vandenhoeck and Ruprecht,1965),pp.150-197。从术语学角度对 “现代性” 进行分析构成阿德里安 · 马里诺《现代,现代主义,现代性》(Bucharest:Editura Univers,1970)一书主体部分的目标。更晚近,马里诺在一篇博学的文章中讨论了现代性问题,“现代主义与现代性:若干语义辨析”,发表于 Neohelicon 3-4(1974):307-318。
[43]. 这段引文出自致威廉 · 科尔的一封信,写于 1782 年 2 月 22 日。“据说,” 霍勒斯 · 沃波尔写道,“查特顿的某些作假行为将从他的一位同伙那里获得证据…… 我很少发现有人不被说服,那些诗歌的风格是查特顿的,尽管他也许找到了一些老的东西加以利用…… 但既然那些诗受到了这般审察,没有人(只要他有耳朵)会原谅那种语调的现代性,以及观念与措辞的那种新倾向…… 那家伙仍然是个天才…… 而且仍然无法解释的是,他是如何找到时间或素材来施展这类奇迹的。” 见 W.S. 刘易斯编,《耶鲁版霍勒斯 · 沃波尔通信》(New York:Yale University Press,1937),卷 II, pp.305-306。
[44]. 埃米尔 · 利特雷,《法兰西语言词典》(Paris:Gallimard-Hachette,1957),卷 5,p.315。
[45]. 保罗 · 罗贝尔,《法语类比词典》(Paris,1959),卷 IV, p.607。
[46]. 引自彼得 · 德梅茨,《马克思、恩格斯与诗人们》(Chicago:The University of Chicago Press,1967),pp167,169。
[47]. 泰奥菲勒 · 戈蒂埃,《戏剧、艺术与批评的回忆》(Paris:Charpentier,1883),p.203。包含所引文字的那篇文章发表在 L’Evénement(1848 年 8 月)上。
[48]. 除非特别指明,波德莱尔的话都出自英译本选集《作为文学批评家的波德莱尔》,洛伊斯 · 波 · 希尔索普与弗朗西斯 ·E. 希尔索普翻译并作序(University Park, Penn.:The Pennsylvania State University Press,1964)。前面的引文出自 p.40。
[49]. 同上。
[50]. 同上,p.41。
[51]. 同上,pp.296-297。
[52]. 保罗 · 德 · 曼,“文学史与文学现代性”,见《盲目与洞见》(New York:Oxford University Press,1971),pp.142-165。
[53]. 同上,p.147。
[54]. 同上,pp.151-152。
[55]. 同上,p.162。
[56]. 同上,p.161。
[57]. 同上,p.164。
[58]. 波德莱尔,《全集》(Paris:Gallimard, Bibliothèque de la Pléiade,1961),p.1277。
[59]. 同上,p.1255。
[60]. 同上。
[61]. 同上,p.951。
[62]. 《波德莱尔诗歌》,罗伊 · 坎贝尔英译(New York:Pantheon Books,1959)。
[63]. 见 “由于它是一个现实主义问题”,见《作为文学批评家的波德莱尔》,pp.85-88。
[64]. 同上,pp.92-94。
[65]. 同上,p.125。
[66]. 同上,p.119。
[67]. 同上,p.298。
[68]. 《全集》,p.1256。
[69]. 在 1853 年末或 1854 年初致费尔南 · 德努瓦耶的一封著名的信中,波德莱尔写道:“…… 你清楚地知道我不能够同情植物,并且我的心灵与这种独特的新宗教对抗,我觉得这种宗教将会永远以那种所谓‘震惊’为全部精神存在。我永远也不会相信上帝的灵魂居住在植物之中,而且,即使它住在那里面,我也会对此不太关心,并且认为我的灵魂比那些被神圣化了的蔬菜的灵魂具有高得多的价值。我甚至一直在想,在繁荣、新生的大自然中,有着某种无耻的、令人伤心的东西。” 见波德莱尔,《书信集》,克洛德 · 皮舒瓦编(Paris:Gallimard, Bibliothèque de la Pléiade,1973),卷 1,p.248。波德莱尔对自然的态度,见 F.W. 利基的著作《波德莱尔与自然》(Manchester:Manchester Univ.Press,1969)。
[70]. 《全集》,p.890。
[71]. 雷纳托 · 波吉奥里,“技术与先锋派”,见《先锋派理论》,杰拉尔德 · 菲兹杰拉德英译(New York:Harper&Row, Icon Editions,1971),pp.131-147。
[72]. 奥克塔维奥 · 帕斯,《泥沼的孩子》,拉切尔 · 菲利普斯英译(Cambridge, Mass.:Harvard University Press,1974),p.23。
[73]. 同上,pp.45-46。
[74]. 托马斯 · 莫尔纳,《乌托邦,永恒的异端》(New York:Sheed and Ward,1967)。
[75]. 恩斯特 · 布洛赫,《未来哲学》,约翰 · 卡明英译(New York:Herder and Herder),p.91。整段如下:“当然有席勒的名言及其所包含的唯心主义与无奈:‘唯从未到来以走向消逝者不会变老’。但运用于乌托邦及其假设时,这句话的真理性完全依赖于一个乌托邦式插入成分——副词‘未然’。那么,有所保留地看(辅以具有历史精确性的理解,即对潜在性的理解),这句话的意思就是:‘唯尚未到来以走向消逝者不会变老’。”
[76]. 于尔根 · 哈贝马斯,“恩斯特 · 布洛赫:一个马克思主义的浪漫派”,Salmagundi 10-11(1969 年秋 - 1970 年冬):313。
[77]. 帕斯,前引书,pp.27-28。
[78]. 见《乔纳森 · 斯威夫特书信集》,哈罗得 · 威廉斯编(Oxford:Clarendon Press,1965),卷 5,pp.58-59。斯威夫特致亚历山大 · 蒲柏信(1734 年 6 月)中完整的话是:“我希望你将发出号令反对那些蹩脚文人对英语的败坏,他们以拙劣的减省和古怪的现代主义带给我们用散文和诗写成的垃圾。” 这封信最初发表于 1734 年。
[79]. 在 “关于疯狂的离题话” 中,斯威夫特就他 “最真诚的朋友 W-tt-n 先生” 写道,“他的大脑经历了一次不幸的震动;这件事即使是他的‘现代主义者’兄弟们自己,就像‘忘恩’先生,也说得这么大声,以至于它传到了此刻我正写到的加勒特耳中。”《一只桶的故事》,版本同前,p.169。
[80]. 在 “晚近欧洲文学研究中对实证主义的反叛” 中,勒内 · 韦勒克指出,“第一次世界大战以后,事实主义(factudism)最接近于在法国获得胜利:数量繁多的论文;一个由费尔南 · 巴尔当斯佩尔热发起、有良好组织的比较文学学派的广泛分枝;那些备有详尽法国古典作品版本的学者的成功;达尼埃尔 · 莫尔奈的理论,他要求由少数甚至是很少作者写的‘整体’文学史——所有这些都是法国试图跟上十九世纪纯历史研究潮流的征象。”见勒内 · 韦勒克,《批评的诸种概念》(New Heaven:Yale University Press,1963),p.261。
[81]. 对鲁文 · 达里奥现代主义观点的全面研究,见艾伦 ·W. 菲利普斯,“鲁文 · 达里奥及其对现代主义的评判”,《拉丁美洲杂志》24(1959):41-64。西班牙语批评中现代主义的完整历史,见马克斯 · 恩里克斯 · 乌雷尼亚,《现代主义简史》,第 2 版(Mexico:Fondo de Cultura Económica,1962),pp.158-172。亦见,内德 ·J. 戴维逊,《西班牙语批评中的现代主义概念》(Boulder, Colorado:Pruett Press,1966),达里奥的话转引自恩里克斯 · 乌雷尼亚,p.158。
[82]. 恩里克斯 · 乌雷尼亚,前引书,p.159。
[83]. 同上,p.160。
[84]. 同上。
[86]. 同上,p.161。
[87]. 同上,p.168。
[88]. 同上,p.169。
[89]. 转引自戴维逊,前引书,p.6。
[90]. 参见戴维逊,前引书,pp.41-48。
[91]. 佩德罗 · 萨利纳斯,前引书,“西班牙的现代主义问题,或两种精神之冲突”,见奥梅罗 · 卡斯蒂略编,《关于现代主义的批评研究》(Madrid:Editorial Gredos,1968),p.24。
[92]. 萨利纳斯,前引书,p.28。
[93]. 胡安 · 拉蒙 · 希梅内斯,《现代主义:讲课笔记》,里卡尔多 · 古利翁与欧亨尼奥 · 费尔南德斯 · 门德斯编(Madrid:Aguilar,1962)。
[94]. 里卡尔多 · 古利翁,《现代主义的各种方向》,第 2 版(Madrid:Editorial Gredos,1971)。
[95]. 艾萨克 · 戈尔德伯格,“‘现代主义的’更新”,见《西班牙语美洲文学研究》(New York:Brentano’s,1920),pp.1-3。
[96]. 费德里科 · 德 · 奥尼斯,“关于现代主义概念”(1949),见《美洲中的西班牙:关于西班牙与西班牙语美洲主题的研究》,第 2 版(San Juan:Universidad de Puerto Rico,1968),p.177。
[97]. 同上,p.183.
[98]. 参见古利翁,前引书,p.26。
[99]. 费德里科 · 德 · 奥尼斯,《西班牙与西班牙语美洲诗歌选(1882-1932)》(New York:Las Americas,1961),p.XVIII。
[100]. 费德里科 · 德 · 奥尼斯,“马蒂与现代主义”,见《美洲中的西班牙》,p.625。
[101]. 关于这次论争的书目非常之多。对这个问题及涉及到的人物的一个较好介绍是《罗马天主教现代主义》,伯纳德 ·M. 里尔登编(Stanford, Calif.:Stanford University Press,1970)。
[102]. 波吉奥里,前引书,pp.216-218。
[103]. 约瑟夫 ·T. 希普利,《世界文学术语词典》(Boston:The Writer,1970),p.156。
[104]. 劳拉 · 赖丁与罗伯特 · 格雷夫斯,《现代主义诗歌概观》(Lodon:Heinemann,1929),p.156。
[105]. 同上,p.9。
[106]. 同上。
[107]. 同上,p.11。
[108]. 同上,p.155。
[109]. 同上,p.156。
[110]. 同上,p.157。
[111]. 同上,p.158。
[112]. 同上,p.156。
[113]. 勒内 · 韦勒克与奥斯汀 · 沃伦,《文学理论》,第 3 版(New York:Harcourt,1956),pp.262ff。“…… 一个时期不是一个类型或种类,而是内嵌于历史过程中并同它不可分离的、借助一套标准确定出来的一个时段…… 单独的一件艺术作品并不能作为一个种类的例证,而只是一分子,它同所有其他作品一起,构成了时期的概念。它因此改变了整体的概念。”(p.265)然而,已有的时期术语一直被用来也将继续被用来指艺术或心理的类型,而脱离其历史语境。
[114]. G.R. 赫克,《文学中的矫饰主义:语言炼金术与玄奥的组合艺术》(Hamburg:Rowohlt,1969)。
[115]. 斯蒂芬 · 斯彭德,《现代的斗争》(London:Hamilton,1963),pp.71-72。
[116]. 同上,p.77。
[117]. 莱昂内尔 · 特里林,《超越文化》(New York:The Viking Press,1961),pp.3-30。
[118]. 同上,pp.15-16。
[119]. 有趣的是,“现代”同 “当代” 之间的区分在苏联和二战后的欧洲批评中非常流行。整个有关 “当代性” 的讨论(在社会主义现实主义的理论框架内,这一讨论亦是它的组成部分)是拒绝 “现代性” 和“现代主义”这类在意识形态上有害的概念的一种方式,这两者都被认为是资产阶级颓废的表现。
先锋派的概念
[1]. 比较而言,论述 “先锋派” 这个词及 “先锋派” 这个概念的著作较少,尽管这个词不无误导性地出现在晚近相当多著作的标题中。在这里我将局限于一个例子,即约翰 · 怀特曼的《先锋派的概念》,副标题是 “现代主义探询”(La Salle, Illinois:Library Press,1973)。实际上,这本书只是一个论文集,谈的主要是二十世纪法国文学。只有一篇文章论述了先锋派的概念(pp.13-38),而即使在这篇文章中也只是泛泛而谈。我们可以说这样一本书非常有趣,充满了机智与富有启发力的观点,但这并不意味着读了它之后,你就可以对先锋派概念实际代表什么有一个比较清晰的看法。简略地这么说并非是要批评怀特曼的著作;我所要反对的只是它那给人误导的标题。而且即使是这样一种滥用也不无趣味:它表明在引入英语几十年后,“先锋派” 这个词已经成了一个时髦的词。
关于先锋派的一篇最详尽、最充实的术语学论文是阿德里安 · 马里奥的 “先锋派”,见他的《文学观念词典》(Bucharest:Editura Eminescu,1973),pp.177-224。亦见 “反文学”,同上,pp.100-159。
[2]. 雷纳托 · 波吉奥里,《先锋派理论》,p.8。
[3]. 唐纳德 · 德鲁 · 埃格伯特,“艺术与政治中的‘先锋派’概念”,《美国历史评论》73(1967):339-366。这篇文章被收入《社会激进主义与艺术——西欧》(New York:Knopf,1970)这部综合性研究著作。亦见拙文 “先锋派:一些术语性思考”,《比较文学与一般文学年刊》23(1974):67-78。
[4]. 埃蒂安 · 帕基耶,《选集》,雷翁 · 弗热尔编(Paris:Firmin Didot,1849),卷 2,p.21。
[5]. 同上,卷 1,pp.234-249。
[6]. 同上,卷 2,p.69。
[7]. 同上,p.72。
[8]. 同上,p.73。
[9]. 罗贝尔 · 埃斯蒂瓦尔、让——夏尔 · 高迪、加布里埃勒 · 韦尔热,《先锋派》(Paris:Bibliothèque Nationale,1968),pp.22-24。这本书是关于名称中带有 “先锋” 一词的法国期刊的一个目录学和社会学研究,从 1794 至 1967。
[10]. 《文学、哲学与工业观点》(Paris:Galérie de Bossange Père,1825)。“艺术家、学者与工业家:对话” 是该书的结论部分,pp.331ff。见《圣西门与昂方坦著作》,1865-1879 年版的影印版(Aalen:Otto Zeller,1964),罗德里格斯的对话以作者之名收在全书卷 XXXIX(圣西门作品卷 X),pp.201-258。“先锋” 一词出现于其中的段落见 pp.210-211。
[11]. 《克洛德——亨利 · 圣西门著作》(Paris:Editions Anthropos,1966),卷 VI,422。(该版本的第六卷收录《圣西门与昂方坦著作》中未收的圣西门作品。)
[12]. 《圣西门与昂方坦著作》,XXXIX,(X),pp.137-138。
[13]. 见注 10。
[14]. 《雪莱批评散文》,小布鲁斯 · 麦克尔德利编(Lincoln:Uinversity of Nebraska Press,1967),p.13。
[15]. 波吉奥里,《先锋派理论》,p.9。
[16]. D. 拉韦尔当,《艺术的使命与艺术家的角色》(1845 年沙龙)(Paris:Aux Bureaux de la Phalage,1845),p.4。
[17]. 《社会激进主义》,p.135。
[18]. 同上,p.134。
[19]. 斯特凡 · 马拉美,《全集》(Paris:Gallimard, Bibliothèque de la Pléiade,1970),p.870。马拉美说:“在这样一个诗人向社会罢工的时代里,他的态度是将所有可能提供给他的污浊技巧都弃置不用”。
[20]. 《法兰西语言瑰宝》(Paris:éditions du Centre National de la Recherche Scientifque,1974),卷 3,p.1056。
[21]. 奥诺雷 · 德 · 巴尔扎克,《全集》(Paris:Club de l’honnête homme,1956),《人间喜剧》,第 11 分册,p.561。
[22]. 同上。
[23]. 圣伯夫,《月曜日漫谈》(Paris:Garnier, n.d.),卷 XIII, p.152。
[24]. 同上,p.153。
[25]. 夏尔 · 波德莱尔,《我心赤裸》,诺曼 · 卡默隆英译(London:Weidenfeld&Nicolson,1950),pp.188-189。原文见夏尔 · 波德莱尔,《全集》,Pléiade, p.1285。
[26]. 汉斯 · 马格努斯 · 恩岑斯伯格,“先锋派的困境”,见《当代文学批评问题》,格雷戈里 T. 波莱塔编(Boston:Little, Brown and Co.,1973),p.745。约翰 · 西蒙英译。
[27]. 阿图尔 · 兰波,《全集 · 书信选》(法——英),华莱士 · 富利译(Chicago:The University of Chicago Press,1966),p.308。
[28]. 波吉奥里,前引书,pp.11-12。
[29]. 同上,pp.XVI-XVII。
[30]. 做先锋派肯定就是扮演一种领导角色,这是一件值得骄傲的事。先锋派往往同夸大狂走到一起。罗贝尔 · 埃斯蒂瓦尔在《1945 年以后巴黎文化先锋派中的文化史哲学》(Paris:Guy Leprat,1962)中讨论了这种特殊的关联。作者的态度基本上是马克思主义的,他把二战后的巴黎先锋派描述成一种 “小资产阶级” 现象,将其特征归结为他所说的“自我中心式夸大狂”。他在一些先锋派代表人物的作品中追寻这种态度,并就罗曼 · 伊西多尔 · 伊索的情况进行了详细的分析,伊索确立了所谓“文字主义”(Lettrisme)。在《先锋派》(见注 9)中,作为今日知识先锋派特征的自大狂的最早征象早在 1847 年即已发现,它出现在一份名为《农业先锋派》的杂志的纲领中。“这种现象在 1847 年后宣告来临:人们于是看到在农业经济的领域产生了一种先锋派:它已失去对政治秩序的任何关涉。由于其创立者的心理表现出自大狂和自我中心主义,因而对之进行探询是有趣的…… 由于要发现一种新的农业体系或一种新的绘画理论,人只是小群体中的人,只是为体现先锋性而进行革新的个体。”(p.73)
[31]. 《社会激进主义》,p.123。
[32]. V.I. 列宁,《〈党的再组织〉及〈党的组织与党的出版物〉》,俄语英译(London:IMG Publications, n.d.),p.17。
[33]. 关于卢卡奇对待先锋派的态度以及先锋派一词在德国的使用,见乌尔里希 · 韦斯坦广博而翔实的文章,“德国的先锋派概念与术语”,见《布鲁塞尔大学评论》,1975/1,pp.10-37。卢卡奇区分了一种虚假的、“颓废的”先锋主义和一种真正的、富有政治觉悟的文学先锋派。这个区分见 “现实主义的衰退” 一文(1938)。韦斯坦以此来概括卢卡奇的立场:
卢卡奇…… 在当代文学中(换句话说就是在颓废的小资产阶级文学中)分辨出三种基本倾向:1)他所说的 “那些为现存体制辩护,部分是公开反现代主义、部分是伪现代主义的文学”,2)“所谓先锋派” 文学,3)“这个时代最重要的那些现实主义作家”的作品。第二种倾向后来他用来反对真正的先锋派,即在政治上经过启蒙的文学先锋派,他把这种倾向理解为自然主义向超现实主义的延伸,并将它的主导特征定义为“永远同现实主义有很大距离”。(p.32)
关于卢卡奇勾勒出的真正先锋派——从塞万提斯延伸到巴尔扎克、托尔斯泰和托马斯 · 曼——我们不能不同意韦斯坦的评论:“由于他将先锋派这一术语准确地用于那些写作手法——有时甚至是世界观——公然保守的作家,作者可以说是反过来运用了‘先锋派’一词的美学意义”。(p.33)
[34]. 阿波利奈尔的文章发表于《不妥协》(1912 年 2 月 7 日)。收入阿波利奈尔,《艺术年鉴(1902-1918)》,布勒尼格收集、作序并注释(Paris:Gallimard,1962),pp.212-213。
[35]. 波吉奥里,前引书,p.5。
[36]. 欧仁 · 尤奈斯库,《记录与反记录》,唐纳德 · 华生英译(London:J.Calder,1964),pp.40-41。法语原文见尤奈斯库,《记录与反记录》
Paris:Gallimard,1962,p.27。
[37]. 罗兰 · 巴特,《批评文集》,理查德 · 霍华德英译(Evanston:Northwestern University Press,1972),p.67。法语原文见罗兰 · 巴特,《批评文集》(Paris:Editions du Seuil,1964),p.80。
[38]. 见《当代文学批评问题》,pp.734-753。
[39]. 《莱斯利 · 菲德勒文集》(New York:Stein and Day,1971),卷 II, pp.454-461。
[40]. 引自 “现代的概念”,见《文学现代主义》,欧文 · 豪编(Greenwich, Conn.:Facett Publication,1967),p.24。“现代的概念” 一文以 “现代主义文化” 之名重印在欧文 · 豪的《新艺术的衰落》(New York:Harcourt, Brace and World,1970)中,pp.3-33。《文学现代主义》包括一些论述先锋派的文章,诸如保罗 · 古德曼的“美国的前卫写作:1900-1950”(pp.124-143),理查德 · 蔡斯的“先锋派的命运”(pp.144-157)。然而,在这些文章中先锋派一词仅仅是现代主义的同义词。
[41]. 利奥纳德 ·B. 迈耶,《音乐、艺术和观念:二十世纪文化中的模式与预言》(Chicago:University of Chicago Press,1967),p.169。
[42]. 安杰罗 · 吉列尔米,《先锋派与实验主义》(Milan:Feltrinelli,1964),p.56。
[43]. 何塞 · 奥尔特加 · 伊 · 加塞特,《艺术的非人化》,海伦 · 威尔英译(Princeton:Princeton University Press,1968),p.11。
[44]. L. 阿尔杜塞,《捍卫马克思》,本 · 布吕斯特英译(London:Allen Lane,1969),pp.229-230。
[45]. 在阿尔杜塞同英国马克思主义者约翰 · 刘易斯的论战中,人本主义的问题得到了进一步的讨论:L. 阿尔杜塞,《答约翰 · 刘易斯》(Paris:Maspero,1973)。
[46]. 意识形态衰落的问题发生于二十世纪五十年代。在其富有挑战性的著作《知识分子的鸦片》中,雷蒙 · 阿隆是首先详细论述这一主题的的人之一。该书法文版出版于 1955 年,特伦斯 · 吉尔马丁英译(Garden City, New York:Doubleday,1957)。在 1960 年,丹尼尔 · 贝尔出版了《意识形态的终结》(Glencoe, Ill.:Free Press,1960)。这一论争延贯整个六十年代,尽管它招致了各种批评,但有关意识形态正在衰退的假设并没有破产。这方面更详细的情况见钱姆 ·I. 韦克斯曼编,《意识形态终结的论争》(New York:Funk&Wagnalls,1969),以及穆斯塔法 · 雷哈伊编《意识形态衰落?》(Chicago:Aldine-Atherton,1971)。
[47]. 吉列尔米,p.79。
[48]. 同上,p.80。
[49]. 同上,p.81。这里马克思主义是在一种广泛的哲学意义上来理解的,“…… 以它反形而上学的前提(尽管并不总是被遵循),以它对直接历史资料的敏感…… 以它面对一切新形势(和以不连贯为特点的独特概念体系)的出现所具有的极端灵活性。”
[50]. 见《比较文学与一般文学年刊》22(1973):42-50。有关无政府主义美学的更广泛描述见安德冽 · 雷茨勒,《无政府主义美学》(Paris:Presses Universitaires de France,1973)。
[51]. 米歇尔 · 福柯,《词与物》(Paris:Gallimard,1966)。关于人之死的问题见第 9 章(“人与他的两面”)和第 10 章(“人文科学”)。
[52]. 吉尔 · 德勒兹与菲力克斯 · 瓜塔里,《反俄狄甫斯:资本主义与精神分裂》(Paris:Editions de Minuit,1971)。
[53]. 波吉奥里,《先锋派理论》,p.178。
[54]. 菲德勒,II,404。
[55]. 迈耶,p.72。
[56]. 更晚近,在西班牙语世界中,“后现代主义”一词往往被用来指两次世界大战之间的时期。奥克塔维奥 · 科尔瓦兰在其《后现代主义:两次世界大战期间的西班牙语美洲文学》(New York:Las Américas,1961)中说:“正如副标题所清楚地说明的,‘后现代主义’这个名称指的是这段时期,其历史界限为两次世界大战。当然,一种新美学的那些最初表现形式在 1914 年之前的几年中就出现了,而我们所说的后现代主义的许多特征还延续到 1939 年之后。”(p.7)“总之,”科尔瓦兰写道,“费德里科 · 德 · 奥尼斯所区分的前后两个阶段,即‘后’现代主义和‘超’现代主义,我都称为后现代主义。”(p.8)《后现代主义》更像是一本关于两次大战期间拉美文学史的富有争议的教科书,它有着公开明确的教学目的。(这里)“后现代主义”概念所意指的正是欧美批评中毫无争议地认做 “现代主义” 的东西。
[58]. 参见《历史研究》(London:Oxford University Press,1954),卷 IX, pp.182ff。
[59]. 同上,p.235。亦见卷 I(London:Oxford University Press,1934),p.1,n.2,其中汤因比认为西方历史中的一个新时期(尚为命名)开始于 1875 年左右;同样的观点在卷 I 的第 171 页得到论述。
[60]. 同上,卷 IX, p.185。
[61]. 同上,p.189。
[62]. 同上,卷 VIII, p.338。
[63]. 同上。
[64]. 《莱斯利 · 菲德勒文集》,卷 II, pp.379-400。
[65]. “大众社会与后现代小说”,《党人评论》26(1959):420-436。重印于欧文 · 豪,《新艺术的衰落》,前引版本,pp.190-207。
[66]. 豪,《新艺术的衰落》,pp.196-197。
[68]. 同上,p.255。
[69]. 同上,p.258。
[70]. 哈里 · 列文,《折射》(New York:Oxford University Press,1966),p.271。关于 “后现代” 亦见 p.277。
[71]. 列文,《比较的基础》(Cambridge, Mass.:Harvard University Press,1972),p.15。
[72]. 菲德勒,前引著作,卷 II, p.461。出于对语义学的兴趣,我不禁要指出在这句引语中 “现代” 之名所激起的憎恶。
[73]. 同上,pp.462-463。
[74]. “‘后’现代‘主义’:超批评书目”,《新文学史》3(1971):5-30。重印于伊哈布 · 哈桑,《超批评:时代七思》(Urbana:University of Illinois Press,1975)pp.39-59。
[75]. 罗伯特 · 朗鲍姆,对雷纳托 · 波吉奥里《先锋派理论》的评论,见《边界 2》I,1,1972 年秋季号,p.234。
[76]. 约翰 · 凯奇,《寂静》(Middletown, Conn.:Wesleyan University Press,1961),p.10。
[77]. 《反对阐释》,前引版本,pp.13-23。在评论电影《去年在马里安巴》以及它 “有意识地…… 容纳众多同样合理的解释” 这一事实时,苏珊 · 桑塔格颇为典型地写道:“但必须抵制想去作出阐释的诱惑。在《马里安巴》中,重要的是它的一些影像具有纯粹的、不可传译的感官直接性……”(p.19)
[78]. 热拉尔 · 热奈特,《修辞格》,I(Paris:Editions du Seuil,1966),p.206。
[79]. 迈耶,p.72。
[80]. 同上,pp.93,102。
颓废的概念
[1]. 关于柏拉图对待原始主义的态度(包括他的神话式黄金时代的观点),见 A.O. 洛夫乔伊和乔治 · 博厄斯的讨论,《原始主义和古代的相关观念》(New York:Octagon Books,1965),pp.155-168。
[2]. B.A. 范 · 格罗宁格尔,《在过去的掌握之中:论希腊思想的一个方面》(Leiden:E.J.Brill,1935)。在该书的结尾,作者引述了普鲁塔克一个富有启发性的段落:“愚者的思想永远着眼于未来,从而无视和忽略了过去的福泽;智者通过记忆使过去清晰地呈现于面前。”(p.121)
[3]. 亨利——夏尔 · 皮埃什,“诺斯与时间”,见约瑟夫 · 坎贝尔编《人与时间:埃拉诺斯年鉴文选》(New York:Patheon Books, Bollingen Series,1957),p.43。
[4]. 同上,pp.47-48。
[5]. 肯拉德 ·W. 斯瓦尔特,《十九世纪法国的颓废感》(The Hague:Nijhoff,1964),p.19。
[6]. 弗拉基米尔 · 扬克列维奇,“颓废”,《形而上学与道德评论》55 卷第 4 期(1950 年 11-12 月):339。
[8]. 孟德斯鸠,《笔记(1716-1755)》,转引自 W. 克劳斯和汉斯 · 科尔图姆编,《十八世纪文学论争中的古代与现代》(Berlin:Akedemie Verlag,1966),p.253。
[9]. 斯塔尔夫人,《论文学与社会制度的关系》,保罗 · 范 · 提盖姆编(Geneva:Dorz,1959),卷 I, p.124。
[10]. 同上。
[11]. 同上,pp.127-130。
[12]. D. 尼扎尔,《关于颓废时期拉丁诗人道德与批评的研究》,第 5 版,2 卷本(Paris:Hachette,1888),I:IX。
[13]. D. 尼扎尔,《论浪漫派文集》(Paris:Calman-Lévy,1891),pp.245,248。
[14]. 同上,p.267。
[15]. 同上,p.352。
[16]. K.W. 斯瓦尔特,前引书,p.XI。
[17]. E. 勒南,《青年时代笔记(1845-1846)》(Paris:Calman-Lévy,1906),p.112。
[18]. 同上,p.105。
[19]. 同上,p.383。
[20]. 泰奥菲勒 · 戈蒂埃,《文学肖像与记忆》(Paris:Charpentier,1881),p.171。我所使用的这一著名段落的英译见 G.L. 范 · 罗斯布吕克《颓废派传奇》(New York:Institut des Etudes Fran aises, Columbia University,1927),pp.8-9。
[21]. Ch. 波德莱尔,《全集》,Pléiade, p.1525。
[22]. 同上,p.889。
[23]. 同上,p.1099。
[24]. 同上,p.1211。
[25]. 同上,p.1214。
[26]. E. 德拉克洛瓦,《日记》,安德烈 · 茹班编(Paris:Plon,1932),卷 2,p.439(记录日期为 1856 年 4 月 9 日)。
[27]. 同上,p.443(记录日期为 1856 年 4 月 16 日)。
[28]. 埃德蒙和儒勒 · 德 · 龚古尔,《日记》,罗贝尔 · 里卡特编定并注释的完整文本(Paris:Fasquelle and Flammarion,1956),卷 6,p.207。
[29]. 埃米尔 · 左拉,《我的仇恨》(Paris:Charpentier-Fasquelle,1913),pp.57-58。
[30]. 龚古尔,《日记》,卷 5,p.159。
[31]. 保罗 · 布尔热,《当代心理学论文集》(Paris:Lemerre,1893),p.28。
[32]. 见 J. 卡默比克,“颓废风格”,《比较文学评论》39 卷第 2 期(Avril-Juin,1965):268-286。卡默比克比较了布尔热对作为 “颓废风格” 典型特征的细节崇拜(cult of detail)的强调和尼扎尔对这一问题的相似论述。尽管没有证据表明布尔热读过尼扎尔的著作,文章的作者却猜测存在布尔热通过巴尔贝 · 道勒维里得知尼扎尔的可能性。巴尔贝 · 道勒维里是一位埃内斯特 · 埃洛的崇拜者,埃洛跟巴尔贝一样也是一位保守分子,在《人》(1872)一书中他就 “颓废风格” 提出了自己的定义,他的定义非常接近于尼扎尔的。卡默比克指出尼扎尔在巴黎右翼圈子里享有同情。“法兰西行动”(Action fran aise)的领导人夏尔 · 莫拉斯也是一位尼扎尔的崇拜者,他同尼扎尔拥有相同的观点,认为浪漫主义应等同于颓废。
[33]. 《文学世纪》(1876),转引自雅克 · 勒泰夫,“十九世纪末法国文学中的颓废主题”,《法国文学史评论》LXIII(1963):51。
[34]. 布尔热,p.24。
[35]. 同上。
[36]. 同上,p.28。
[37]. 同上,p.29。
[38]. J.-K. 于斯曼,《逆流》,《全集》卷 VII(Paris:Les éditions G.Crès et Co.,1928)p.134。
[39]. 同上,p.142。
[40]. A.E. 卡特,《法国文学中的颓废概念》(Toronto:University of Toronto Press,1958),p.20。
[42]. 同上,p.303。
[43]. 同上,p.XXI。
[44]. 见奥斯卡 · 王尔德,《社会主义下人的意图与灵魂》,罗伯特 · 罗斯编(London:Dawsons of Pall Mall,1969)。
[45]. 加布里埃尔 · 维凯尔和亨利 · 博克莱尔的 “颓废” 仿作以《衰退:阿多雷 · 弗鲁贝特的颓废诗》(Paris:“Byzance”,chez L.Vanné,1885)一书的面目出现。有关该书的讨论见诺埃尔 · 里夏尔,《象征主义的黎明:水疗法、骗子和颓废者》(Paris:Nizet,1961),第三部分,“颓废主义的骗局”,pp.174-268。亦见里夏尔研究附录中《衰退》序言的校勘版,pp.270-315。
[46]. 引自诺埃尔 · 里夏尔,《颓废运动:纨绔子弟、审美家和完美化身》(Paris:Nizet,1968),p.24。
[47]. 同上,p.25。
[48]. 同上,p.173。
[49]. 引自安德烈 · 比利,《1900 时代(1885-1905)》,(Paris:Tallandier,1951),pp.422-423。
[50]. 为充分认识这些词汇被使用和滥用的程度,且让我们引述有关法国颓废运动的一项新近研究中的描述。“颓废这个词,” 诺埃尔 · 里夏尔写道:“是一个轰动一时的词,它在 1881-1891 年的十年间被记者们乱七八糟地使用。如果一个人杀死他的情妇,人们称他为颓废者。而如果一些无政府主义者扔炸弹,又如何呢?这便是一些成熟的颓废者。我不知道是哪个爱开玩笑的人有一天在一家餐馆里‘为颓废者点水田芥’(du cresson du décadent)。”《颓废运动》,p.256。
[51]. 弗里德里希 · 尼采,《〈悲剧的诞生〉和〈论瓦格纳〉》,瓦尔特 · 考夫曼英译(New York:Vintage Books,1967),p.155。德语原文见《尼采著作》,校勘版全集,乔尔吉奥 · 科利与马齐诺 · 芒提纳里编(Berlin:Walter de Gruyter,1969),第六部分,卷 3,pp.3-4。
[52]. 同上,pp.155-156。德语原文同上,p.4。
[53]. F. 尼采,《〈论道德的谱系〉和〈看哪,这人〉》,W. 考夫曼英译(New York:Vintage Books,1969),p.222。德语原文同上,p.262。
[54]. 同上,p.223。德语原文同上,p.263。
[55]. 同上。德语原文同上,pp.263-264。
[56]. 《悲剧的诞生》,p.164。德语原文同上,p.15。
[57]. 尼采,《快乐的科学》,W. 考夫曼英译(New York:Vintage Books,1974),p.96。德语原文见前引版本(Berlin,1973),第五部分,卷 2,p.69。
[58]. 在此就 “憎恨” 这一概念和术语说上几句也许有点意思,在尼采对基督教的批评中它是如此重要——尼采把基督教对于古代多神教信仰的胜利解释为一次成功的“奴隶反叛”(参见《论道德的谱系》第一节 10,11,12,13,14;第二节 11,17 等)。然而,通过基督教并越出基督教,憎恨联系着整个现代性和颓废的问题。像社会主义、无政府主义和虚无主义——在尼采的眼中虚无主义是现代性的主要特征——这类现代学说或思潮都是通过憎恨而得到具体界定的。在《权力意志》(W. 考夫曼与 R.J. 霍林德尔英译,New York:Vintage Books,1968)中,尼采写道:
在其他的情况下,贫困的人不是(像基督徒那样)在他的 “罪” 中去寻找根由,而是到社会中去找:社会主义者,无政府主义者,虚无主义者——由于他们发现某人对他们的存在负有罪过——他们仍然是基督徒的最近亲,基督徒也认为,通过找到某个可以对他的病态与羸弱感觉负责的人,他就能更好地忍受它。在这两种情形中,复仇和憎恨的本能都显得是一种忍耐手段,是一种自我保护的本能:正如对利他主义理论与实践的偏好。
尼采认为当代欧洲憎恨的代表人物是 “那些悲观主义者…… 他们以在‘义愤’的名义下将他们的污言秽语神圣化为职志”(同上,p.402)。在该书的另一段落中,“没落本能” 和憎恨显然是相关的,而且有意思的是,其中提到了被尼采视为艺术中颓废之典型的维克多 · 雨果和理查德 · 瓦格纳:
没落本能(或憎恨、不满、毁灭冲动、无政府主义和虚无主义),包括奴隶本能,怯懦、狡诈本能,这些本能的拥有者,以及那些被压在下面的阶层的愚民,同所有阶级的血统相混杂:两三代人以后,一切都变成群氓…… 特权者们自身实际上已臣服于它…… 首先是那些 “天才人物”:他们成为那些用以感动大众的情感的使者——同情甚至崇敬所有过着受苦、卑微、可鄙、受迫害生活的人,这种音调响过了其他一切音调(典型:维克多 · 雨果和理查德 · 瓦格纳)。(同上,p.461)
就跟 “颓废” 和“颓废者”一样,尼采直接从法语中采用了 “憎恨” 一词。这是又一个事例,表明尼采偏爱法国心理学和道德概念的明晰与灵活,而不喜欢相应德语词汇的形而上学模糊性。憎恨概念在尼采思想中的重要性,以及在道德判断现象学与社会学这个较大层次上的重要性,为马克斯 · 舍勒在他的《道德结构中的憎恨》(1915)中极好地阐明。在这篇文章的 “开头语” 中,舍勒指出:
我们使用憎恨这个词并不是因为对法语的某种特殊偏好,而是因为我们没有成功地把它译成德语。进而言之,尼采已把它变成了一个技术词汇。在这个法语词的本义中,我辨认出两个要素。首先,憎恨是反复地体验和重温针对别人的某种特殊情感反应或反动。对这种情感的持续重温使它更深地沉入到人格的核心,与此同时又将它从个人活动与表现的区域中排除。它不仅仅是对于那种情感以及那种情感所 “回应” 的事件的理知回忆——它是重新体验那种情感,是原初感情的复活。其次,该词意味着这种情感的本质是否定性的,也就是说,它包含了一种敌意行动。也许德语词 “Groll”(积怨)最接近这个词的本质意义。“积怨” 就是被压制的愤怒,这种愤怒无关自我的活动,它暗中穿越心灵。(马克斯 · 舍勒,《憎恨》,刘易斯 ·A. 科塞编并作序,威廉 · 霍尔德海姆英译,New York:Schocken Books, p.39)
值得注意的是,在十九世纪四十年代,早尼采几十年,克尔凯郭尔用一些显然预示了尼采憎恨概念的词语来描绘现代性。唯其如此,在 1914 年,当泰奥多尔 · 黑克尔以《当代批判》之名翻译克尔凯郭尔的文章《现时代》(1846)时,他觉得可以用 “憎恨” 来翻译表达 “妒羡” 意义的丹麦词。(见克尔凯郭尔,《当代批判》,泰奥多尔 · 黑克尔译,Basel:Hess,1946,pp.29ff)克尔凯郭尔文章的英译者亚历山大 · 德鲁接受黑克尔的看法并用了 “憎恨” 这个词,在一条注释中他向不太熟悉该词的英语读者做了解释,其中引述了马克斯 · 舍勒的话(见克尔凯郭尔,《〈现时代〉与两篇伦理——宗教小论文》,亚历山大 · 德鲁与沃尔特 · 洛里译,London:Oxford University Press,1940,pp.23-24)。
克尔凯郭尔把 “现时代” 说成是一个毫无热情的、反思的时代,一个为“妒羡”、抽象思想和一种普遍扯平趋势所支配的时代,他写道:“比方说,没有人希望导致杰出人物的衰落,但如果能表明区别纯属虚构,那么每个人都会愿意承认它…… 在一个非常富于反思性而毫无热情的时代,妒羡是消极的统一原则。”(p.21)几页之后,克尔凯郭尔继而说:“程度越深,反思的妒羡就越是明显地变成道德憎恨。正如空气在一个密闭的空间里会产生毒气,如果没有任何类型的行动和事件为之通风,反思的禁锢就会产生憎恨。在反思中紧张的状态…… 导致所有较高级力量的失效,而卑下可鄙的力量走到了前台,正是它的卤莽轻率给人以虚假的力量效果,然而在它的卑鄙保护之下,它避免了吸引憎恨的注意。”(pp.23-24)
克尔凯郭尔对现代性的批评在他的《现时代》和系列小册子《瞬间》中得到直接阐述,也间接地见于他的大量匿名著作——特别是《非此即彼》、《人生道路的诸阶段》、《重现》、《“哲学片断”的结论性非科学附言》。本书并没有考察他的这种批评。理由是,这样一种分析将使我们过于远离我们本质上属于术语学的研究思路,而进入到最广义的神学、本体论、形而上学和社会批评的领域。对于那些对十九世纪拒斥现代性的更为哲学化的方面感兴趣者,我推荐卡尔 · 勒维特的伟大著作《从黑格尔到尼采:十九世纪思想中的革命》,戴维 ·E. 格林英译(New York:Holt, Rinehart and Winston,1964)。《从黑格尔到尼采》主要写作于三十年代期间,1941 年在瑞士首次出版,它关注的是黑格尔哲学的影响,主要关注的则是对黑格尔调和理性与现实企图的反动,黑格尔《法哲学》前言中的一句名言概括了他的这种企图:“理性的即现实的,现实的即理性的。”克尔凯郭尔同马克思、施蒂纳、尼采一样,属于为勒维特所说的 “激进批评现存秩序”(或用如今研究中的术语,现代性)奠定哲学基础的人。关于克尔凯郭尔对其时代的“理性” 的批判,具体见第三章,“黑格尔的调和在马克思和克尔凯郭尔的排他性选择中的瓦解”,pp.137-174。
[59]. 同上,p.99。德语原文同上,p.73。
[60]. F. 尼采,《权力意志》,W. 考夫曼译(New York:Vintage,1968),pp.25-26。
[61]. 同上,p.29。德语原文见前引版本(Berlin,1974),第八部分,卷 3,p.42。
[62]. 同上,pp.26-27。德语原文同上,p.326。
[63]. 汉斯 · 费因格尔,《“仿佛” 哲学》,C.K. 奥格登英译,第 2 版(New York:Harcout, Brace&Co.,1934),pp.341-362。
[64]. 同上,p.345。
[65]. 同上,p.357。
[66]. 同上,p.362。
[67]. 格奥尔格 · 齐美尔,《现代文化的冲突及其他论文》,K. 彼得 · 埃茨科恩英译(New York:Teachers College Press,1968),p.73。
[68]. 瓦尔特 · 考夫曼,《尼采:哲学家,心理学家,反基督》(Princeton, New Jersey:Princeton University Press,1968),p.73。
[69]. 《悲剧的诞生》,p.170。德语原文见前引版本,第六部分,卷 3,p.21。
[70]. 考夫曼,p.75。“这一风格难以捉摸的特性如此典型地属于尼采的思想和写作方式,它可以说是单子论式的,使每一条箴言的意向成为自足的,同时又能阐明几乎任何一条其他箴言,我们面对着一个‘多元宇宙’,其中每条箴言都是一个小宇宙。”
[71]. W.D. 威廉斯,《尼采与法国人:阅读法国作品对尼采思想与写作的影响》(Oxford:Blackwell,1952),具体见第 9 章,“文化与颓废”,pp.153ff。
[72]. 《袖珍尼采著作》,W. 考夫曼编选并翻译(New York:The Viking Press,1968),pp.553-554。德语原文见前引版本,第六部分,卷 3,pp.145-146。
[73]. 同上,p.555。德语原文同上,p.146。
[74]. 同上,pp.669-670。德语原文同上,p.423。
[75]. 同上,pp.667-668。德语原文同上,pp.421-422。
[76]. 《悲剧的诞生》,p.25。(这句话出现于 1886 年 “自我批评的尝试” 中,该文是为《悲剧的诞生》一个新版本写的。)
[77]. 同上,p.157。德语原文见前引版本,第六部分,卷 3,pp.7-8。
[78]. 同上,p.173。德语原文同上,p.25。
[79]. 同上,pp.172-173。德语原文同上,p.24。
[80]. 同上,p.179。德语原文同上,pp.31-32。
[81]. 同上,p.183。德语原文同上,p.36。
[82]. 何塞 · 奥尔特加 · 伊 · 加塞特,《现代主题》,詹姆斯 · 克鲁英译(New York:W.W.Norton,1933),pp.67-69。
[83]. 卡尔 · 曼海姆,《意识形态与乌托邦》,路易斯 · 沃斯与爱德华 · 西尔斯英译(New York:Harcourt, Harvest Books),p.310。
[84]. 《马克思主义与艺术》,梅纳德 · 所罗门编(New York:Vintage,1974),p.256。
[85]. 《马克思恩格斯论文学艺术文选》,李 · 巴克森德尔与斯特凡 · 莫罗斯基(St.Louis:Telos Press,1973),p.135。
[86]. 《马克思主义与艺术》,p.64。
[87]. 《艺术中的激进观点》,李 · 巴克森德尔编(Baltimore:Penguin,1972),“有关颓废问题的讨论集”,p.228。
[88]. 《马克思主义与艺术》pp.68-69。
[89]. 《苏联大百科全书》,第 3 版英译本(New York:Macmillan,1975),卷 8,pp.65-66。
[90]. G.V. 普列汉诺夫,《艺术与社会生活》(London:Lawrence and Wishart,1975),p.193。
[91]. 同上,pp.223,226。
[92]. 同上,p.204。
[93]. 同上,p.222。
[94]. 同上。
[95]. 同上,pp.222-223。
[96]. 克里斯托弗 · 考德威尔,《垂死文化研究与再研究》(New York and London:Monthly Review Press,1971),第 2 部分,p.107。
[97]. 同上,第 1 部分,p.47。
[98]. 恩斯特 · 菲舍尔,《艺术对意识形态》,安娜 · 博斯托克英译(London:Allen Lane,1969),p.156。
[99]. 同上,p.157。阿道夫 · 希特勒在 “1937 年德国艺术大展” 上开幕演讲的原文见《第三帝国的艺术》(Munich),卷 I,7-8(1937 年 7-8 月份),pp.47-61。这篇演讲的节选部分由艾尔斯 · 福克译成英文,收入赫谢尔 ·B. 切普编《现代艺术理论》(Berkeley:University of California Press,1968),pp.474-483。希特勒不仅在德国的一般(经济的、政治的)“没落”同现代主义的 “堕落艺术” 之间建立起明确的平行关系,而且进一步拒斥艺术中的整个现代性概念,他公开将之归咎于犹太人。“现代”同艺术相联系起来使用时,对希特勒来说就跟对斯大林的理论家一样,是受到诅咒的对象。关于现代性概念本身,下面这段出自希特勒演讲中的话很有意思:
一方面,艺术被定义为一种国际共同经验,从而抹杀了任何理解它与一个种族群体的整体关系的可能。另一方面,艺术与时代的关系得到了强调,也就是:不再有任何民族甚或是种族的艺术,而只有一种时代的艺术…… 因而今天没有德国或法国或日本或中国的艺术存在,而只有一种简单明了的 “现代艺术”…… 一度是印象主义,然后是未来主义,立体主义,也许甚至是达达主义,等等。进一步的结果是,即使那些最疯狂、最空洞的怪物,也要找成千上万的行话来称呼它们,而且确实找到了…… 直到国家社会主义执掌权力的时刻,德国都存在着一种所谓 “现代艺术”…… 然而,国家社会主义再次需要一种德国的艺术,这种艺术应该而且必将具有永恒的价值。(切普,p.476)
纳粹和日丹诺夫美学之间的某些惊人相似,以及某些同样明显的区别,长期以来已为人们注意到;二者都拒斥 “颓废” 或“病态”的“现代艺术”,然而,如安德烈 · 雷茨勒在他新近的论文《文化面前的马克思主义》(Paris:Presses Universitaries de France,1975)中指出的,纳粹的美学从未变成一种官方编制的文化纲领。雷茨勒写道:“作为极端意识形态化的美学,纳粹美学使艺术创造服从于一些具有政治实质的规范;与其他被转变为一个专制政党之文化纲领的美学不同的是,它(纳粹美学)从来也没有被系统化地制订出来。”(p.58)
[100]. 同上,p.160。
[101]. 这篇文章最早以英语发表于《哲学与社会科学研究》,卷 9(1941)。引文出自 pp.318-319。该文的德文版本题为 “没落之后的斯宾格勒”,收入 T.W. 阿多诺,《棱镜:文化批评与社会》(Frankfurt/Main:Suhrkamp,1955),pp.43-67。
[102]. 同上,p.325。
[103]. 见《现代音乐哲学》,安妮 ·G. 米切尔与韦斯利 ·V. 布卢姆斯特英译(NewYork:The Seabury Press,1973),pp.7ff。阿多诺认为,在我们的时代,不可能以任何传统风格创造出真正的音乐(也就是不带 “虚假音乐意识” 的音乐)。所有用于创造目的的传统都变成了媚俗。阿多诺写道(p.10):
不仅仅是公众的耳中充斥着轻音乐从而使得任何其他音乐表现形式在他们听来都是 “古典的”——一个武断的范畴,仅仅与其他类型相比较才能存在。也不仅仅是听觉能力已为无处不在的流行曲调所窒息,以至于负责任地聆听所必须的专心致志已被对这些音乐垃圾的缕缕记忆所穿透,从而不再有存在的可能。相反,在表演特性上,在对听众生活所发生的作用上,神圣的传统音乐已变得类似于商业性的批量产品,而且其内容也没有逃脱这种影响,音乐密不可分地联系着克莱门特 · 格林伯格所说的那种分裂,即所有艺术都分裂为媚俗艺术和先锋派,而且这种媚俗艺术——连同其利润支配文化的本性——长久以来已征服了社会领域。因此,在美学客观性中揭示真理的想法仅仅涉及先锋派,先锋派已同官方文化划清界限。
[104]. 《否定辩证法》,E.B. 阿什顿英译(New York:The Seabury Press,1973),p.3。
[105]. 在《现代音乐哲学》中,“颓废”直接对立于操纵性和反理知的 “大众文化”。具体见 pp.13-14 和 pp.112ff。阿多诺认为,音乐“并非如反动派所宣称的那样受到其颓废、个人主义和反社会特性的威胁。它实际上极少受到这些因素的威胁”(p.112)。他进而说,“颓废的” 或“先锋派的”无功能音乐实际上要发挥一项重要的(批评)功能。“只要一种根据批量生产的各种范畴构成的艺术还在为这种意识形态效力,…… 另外那种无功能的艺术就有它自己的功能”(p.113)。
[106]. 里卡尔多 · 斯克里瓦诺,《颓废主义与批评:批评史与批评文集》(Florence:“La nuova Italia”,1963),p.7。关于二战后颓废主义概念发展的描述,见阿德里亚诺 · 塞罗尼,《颓废主义》(Palermo:Palumbo,1964),其中特别强调了马克思主义方法,pp.56-74。
[107]. 贝内德托 · 克罗齐,《诗》(Bari:Laterza,1946),p.51。
[108]. B. 克罗齐,《十九世纪欧洲史》(Bari:Laterza,1948),p.50。
[109]. 在克罗齐对巴洛克概念的研究中,尼扎尔被赞同性地引用,这篇文章(“巴洛克”)作为他的《意大利巴洛克时期史》(第 5 版,Bari:Laterza,1967)的导言发表。有意思的是,克罗齐在巴洛克概念和颓废概念之间建立起密切的联系:“众所周知,尤其在所谓颓废的艺术家和诗人的作品中,特别是在罗马文学中那些所谓颓废的艺术家和诗人的作品中,巴洛克概念得到了研究…… 这些人的作品为尼扎尔的一部优美著作提供了材料。”(p.34)
[110]. 关于克罗齐的颓废观,见《巴洛克时期史》,pp.42-52。
[111]. B. 克罗齐,《美学新论》,第 3 版(Bari:Laterza,1948),pp.261-280。
[112]. 《巴洛克时期史》,p.33。
[113]. 同上,p.34。
[114]. 同上,p.35.
[115]. 参见 “新意大利的叙事文学”,特别是 “意大利新文学的欧洲化趋势”,见路易吉 · 鲁索《已成的历史图卷》(Bari:Laterza,1946),pp.199-205。
[116]. 瓦尔特 · 比尼,《颓废主义诗学》(Florence:Sansoni,1961),p.19。
[117]. 同上,p.20。
[118]. 同上。
[119]. 同上,p.21。
[120]. 诺尔贝托 · 博比奥,《颓废主义哲学》(Torino:Chiantore,1944)。戴维 · 莫尔英译(Oxford:Blackwell,1948)。
[121]. 关于弗朗切斯科 · 福罗拉晚期对颓废主义的看法,除了各种诗歌研究外(在这些研究中他确立了连续性,但也区分了颓废主义和隐逸派的诗学),特别见他的综论 “颓废主义”,见“意大利语言文学批评的问题与方向” 丛书中的《文学史的问题与潮流》,A. 莫米利亚诺编(Milan:Marzorati,1949),pp.760-810。福罗拉认为,在欧洲的层面上,奥斯卡 · 王尔德、W.B. 叶芝、A. 西蒙(英),瓦格纳、尼采、格哈德 · 豪普特曼、S. 格奥尔格、托马斯 · 曼以及表现主义者(德),陀思妥耶夫斯基以及在某些方面还有托尔斯泰(俄),这些艺术家和思想家都属于那些展现了颓废主义不同侧面的人(pp.791-792)。
[122]. 埃里奥 · 乔阿诺拉,《颓废主义》(R oma:Editrice Studium,1972)。乔阿诺拉使用的是极为广义的颓废主义概念,在他看来,该概念完全说明了 “我们时代的艺术经验”。因而他认为,与把颓废主义同世纪末的审美主义相联系而有限地使用它相反:“实际上,审美主义只是大的颓废主干上的一个分枝,而且是最不结果的一枝,尽管它是最显眼的一枝。” 这一分枝属最早枯萎之列(p.8)。同选择使用广义的术语相一致,乔阿诺拉在颓废主义的语境中讨论了象征主义、黄昏派、未来主义、表现主义、超现实主义、隐逸派这些诗歌运动。而且如我们能够料想到的,像乔伊斯、D.H. 劳伦斯、罗伯特 · 穆西尔,安德烈 · 纪德、切萨雷 · 帕韦斯、托马斯 · 曼这类作家,也就是那些几乎是自动与现代主义相联系的作家,也频频为他所援引。
[123]. 有关葛兰西在意大利马克思主义批评中的地位,阿德里亚诺 · 塞罗尼在《颓废主义》中有讨论,而且特别涉及到由颓废主义概念所提出的那些问题,pp.58ff。
[124]. 阿尔坎杰罗 · 莱昂内 · 德 · 卡斯特里斯,《颓废主义与现实主义》(Bari:Adriatica,1959),pp.15ff。在他的《伊塔洛 · 斯韦沃》(Pisa:Nistri-Lischi,1959)一书中,颓废主义的概念被特别运用于斯韦沃的作品。具体见 pp.27-38。
[125]. 卡尔罗 · 萨利纳里,《意大利文学中的幻想与意识》,第 4 版(Milan:Feltrinelli,1969),pp.9-10。在路易吉 · 皮兰德娄的小说中分析了颓废主义的 “危机意识”(“危机意识”,pp.249-284)。
媚俗艺术
[1]. 弗兰克 · 维德金德,《全集》(Munich:Georg Müller,1924),卷 9,p.210。
[2]. 哈罗德 · 罗森伯格,《新艺术的传统》,第 2 版(New York:McGraw-Hill,1965),p.268。
[3]. 阿历克斯 · 德 · 托克维尔,《论美国的民主》,亨利 · 里夫英译(New York:Schocken Books,1961),卷 II, pp.59-60。
[4]. 同上,pp.60-61。
[5]. T.W. 阿多诺,“凡伯伦对于文化的攻击”,《哲学与社会科学研究》9(1941):401。
[6]. 在其得到广泛讨论的《词语的炼金术》中,兰波宣称:“我喜欢蠢笨的绘画、门板、舞台布景、马戏团幕景、标语、通俗版画、老派文学、教会拉丁文、拼写糟糕的色情书籍、祖母辈的小说、童话、孩子们的小人书、老歌剧、可笑的叠歌、稚拙的韵律。”(《全集》,华莱士 · 富利英译,Chicago:The University of Chicago Press,1970,p.193)。
[7]. 苏珊 · 桑塔格,《反对阐释》(New York:Dell,1969),p.293。
[8]. 希尔顿 · 克雷默,“七十年代芝加哥的新艺术:视觉狂潮和坎普感受力”,《纽约时报》,1974 年 7 月 14 日,第 2 帖,p.19。
[9]. 见 “赫尔曼 · 布罗赫论‘媚俗艺术’问题”,《当代观念》(Florence:Vallecchi,1968),pp.47ff。
[10]. 同上,p.48。
[12]. 路德维希 · 吉茨,《媚俗艺术现象学》(Heidelberg:Rothe,1960),p.21。对诸如此类 “媚俗艺术” 起源假设的讨论,以及对它的各种意义的讨论,见曼弗雷德 · 杜尔查克的文章“媚俗艺术——它的不同侧面”,《德语课》,19,1971,1,pp.95-97;亦见约亨 · 舒尔特——萨塞,《启蒙时期对于消遣文学的批评》(Munich:Fink Verlag,1971),pp.136-138。有关颓废艺术研究的一般文献目录,见 H. 许林,《走向审美评价史:媚俗艺术研究论文目录》(Giessen,1971)。
[13]. 吉尔伯特 · 海特,“媚俗艺术”,见《牛津一职员》(New York:Oxford University Press,1954),p.211。
[14]. 这种区别十九世纪四十年代后期出现在德语中,并为一些人论及,其中有 H.E. 霍尔图森的 “论酸腐的媚俗艺术”,见他的《是与否》(Munich:Piper Verlag,1954),pp.240-248。
[15]. 《论美国的民主》,II, pp.70-71。
[16]. 同上,p.72。
[17]. 赫尔曼 · 布罗赫,“媚俗艺术问题札记”,见《媚俗艺术:坏趣味的世界》,吉洛 · 多尔富雷斯编(New York:University Books,1969),p.62。
[18]. 同上,p.73。
[19]. 在 “比较的方法:社会学与文学研究” 研讨会上的发言,发表于《比较文学与一般文学年刊》23(1974):18。
[20]. T.W. 阿多诺,《美学理论》(Frankfurt/Main:Suhrkamp,1970),pp.355ff。
[21]. 参见 “文化工业:作为大众欺骗的启蒙”,马克斯 · 霍克海默和泰奥多尔 ·W. 阿多诺,《启蒙辩证法》(Frankfurt/Main:Fischer Verlag,1969),pp.128-176。约翰 · 卡明将该书翻译成英文(New York:Herder and Herder,1972)。完整的法兰克福学派历史概观见马丁 · 杰全面而敏锐的著作,《辩证的想象:法兰克福学派与社会研究所历史,1923-1950》(London:Heinemann Educational Books,1973)。同大众文化特别相关的是该书的第 6 章,“美学理论和大众文化批评”,pp.173-218。
[22]. 阿多诺,“论流行音乐”,《哲学与社会科学研究》9(1941):38。霍克海默在 “艺术与大众文化” 一文中提出了类似的观点,这篇文章最初发表在《哲学与社会科学研究》的同一期上。霍克海默坚持强调流行音乐所特有的虚假内容:“给予艺术消遣以严肃性的,是个人与社会的对立,以及私人存在与社会存在的对立,它们已经过时了。那些接管了艺术遗产的所谓娱乐,今日无非是流行的强壮剂,就像游泳和足球。流行程度不再同艺术作品的具体内容或真理有关系。在民主国家,最终的决定不再出自受教育者,而是出自娱乐工业…… 对极权国家来说,最终的决定出自直接或间接宣传的掌管者,而宣传在本性上是不关心真理的。艺术家在自由市场上的竞争——在这种竞争中成功取决于受教育者——已变成了争取掌权者支持的竞赛……”引自 M. 霍克海默,《批判理论》,M.J. 奥康内尔英译(New York:Herder and Herder,1972),pp.289-290。
[23]. “论流行音乐”,同上。
[24]. 德怀特 · 麦克唐纳,“大众文化理论”,见《大众文化》,伯纳德 · 罗森伯格和戴维 · 曼宁 · 怀特编(New York:Free Press,1964),p.66。这篇文章最早发表在《第欧根尼》(1953 年夏季号),后被修订扩充为 “大众崇拜与中产阶级崇拜”——见《违背美国人的意愿》(New York:Random House,1962),pp.3-79。我仍然偏爱较早的版本,因为它的直接性和所产生的更大影响。
[25]. 亚伯拉罕 ·A. 莫莱斯,《媚俗艺术:幸福的艺术》(Paris:Mame,1971)。
[26]. 麦克唐纳,p.60。
[27]. 莫莱斯,pp.29-36。
[28]. 阿尔温 · 托夫勒,《文化消费者:对美国的艺术与富裕的研究》(New York:St.Martin’s Press,1964),pp.163ff。作者的态度可以用下述论断概括:“对通用汽车公司有益的可想而知对艺术也是有益的。”(p.108)他在文化消费、所消费文化产品的品质和富裕之间建立起直接的联系。仅就数量上看,美国的文化消费不仅是财富的指数,在作者看来,它还是文化进步的指数(作者接受了 “文化爆炸” 的概念)。出于他相当不成熟的经济观点,托夫勒拒不接受趣味标准随着大众文化的兴起而逐步堕落的精英主义观点,并主张 “高雅文化” 在我们时代前所未有地繁荣。当然,他没有意识到,高雅文化正如通俗文化一样可以被媚俗艺术利用,而且两者如今在相当程度上都受到大规模生产和大规模发行的规律的支配。
[29]. 珍妮 · 夏普,“它是新的,它是不同的,它一直存在”,Ark 41(皇家艺术学院学刊,伦敦),1967,pp.24-25。
[30]. 罗杰 · 弗莱,《视觉与设计》(London:Chatto and Windus,1920),pp.44-45。
[31]. 多尔富雷斯,p.31。
[32]. 罗森伯格,p.266。
[33]. 《被剥制的猫头鹰》(London:Dent,1930)主要涉及在杰出诗人作品中可以找到的这类坏诗的实例。作者在前言中解释说:“有坏诗和好的坏诗…… 好的坏诗是合乎语法的,它是根据规则构成的,它的节奏、音韵和格律无可挑剔…… 坏的好诗具有一种神秘超凡的美,就出乎人们的意料而言,这种美同好诗的美足可颉颃…… 坏的好诗…… 可爱得要命。”(pp.VIII-X)尽管作者没有使用媚俗艺术一词,他们提供给读者的却是杰出的诗的媚俗艺术,这首先由它们的故作伤感和 “那种使得维克多 · 雨果的小修辞变得如此拙劣可笑的炫耀卖弄与哼哼唧唧”(XIII)决定了。“好的坏诗” 的其他典型特征是 “所有那些与想象力的贫乏、多愁善感、陈腐、无诗意、浮华风格以及波利先生所谓的‘rockcockyo’相伴随的东西;诗才的缺血、便秘或梗阻;不能掌握灵感的钥匙……”(XIII)作为作者所谓“好的坏诗” 之一例——浪漫媚俗艺术的优美实例——我们可以引用华兹华斯的一首十四行诗,诗集的标题即由之而来:
被剥制的猫头鹰
(出自朱斯伯里小姐的描绘,写的是她长期卧病在床时,从那激发出这首十四行诗的无生气物品中所获得的快乐。——W.W.)
当安娜的同辈与儿时玩伴,
漫步于自由、山野与河畔;
或随音乐在节日的画舫上荡漾;
驾驭骄傲的骏马,或尽情欢舞;
她的命运是郁郁独卧绣榻——
直至她的守护天使,为某种力能
愈加急迫地呼唤,将舒展双翼,
而朋友们绝少抬起凝滞的头颅。
然而,得助于天才——不倦的慰藉者,
一个被剥制的猫头鹰的出现
于她可以欺瞒时间;将她的幻想
送至青藤古堡与皓月夜空,
虽他不能树一毛羽,发一嗥鸣,
亦不能以飘荡之雾掩其圆睁双眼。
(While Anna's peers and early playmates tread,
In freedom, mountain-turf and river's marge;
Or foat with music in the festal barge;
Rein the proud steed, or through the dance are led;
Her doom it is to press a weary bed-
Till oft her guardian Angel, to some charge
More urgent called, will stretch his wings at large,
And friends too rarely prop the languid head.
Yet, helped by Genius-untired Comforter,
The presence even of a stuffed Owl for her
Can cheat time;sending her fancy out
To ivied castles and to moonlight skies,
Though he can neither stir a plume, nor shout;
Nor veil, with restless flm, his staring eyes.)
[34]. 瓦尔特 · 基利,《德国媚俗艺术:一种案例研究》(G ttingen:Vandenhoeck&Ruprecht,1962)。
[35]. 有关先锋派有意运用媚俗艺术的更详细讨论,见多尔富雷斯《媚俗艺术》的 “结论”,pp.291ff;亦见阿洛尔多 · 德 · 坎波斯,“先锋派与媚俗艺术”,《一种没有可能前景的艺术》,第 2 版(S o Paulo:Edit ra Perspectiva,1972),pp.193-201。
[36]. 格林伯格的 “先锋派与媚俗艺术”,最初发表于《党人评论》VI,5(1939 年秋季号),收入他的《艺术与文化》(Boston:Beacon Press,1965),pp.3-21。
[37]. 多尔富雷斯,p.30。
[38]. 麦克唐纳,p.66。
[39]. 《莱斯利 · 菲德勒文选》(New York:Stein and Day,1971),卷 II, p.404。
[40]. 莫莱斯,p.74。
[41]. 多尔富雷斯,p.63。
[42]. 翁贝托 · 艾柯,见《启示的与整体的》(Milan:Bompiani,1965),pp.67-132。
[43]. 理查德 · 埃根特尔,《亵渎基督》,《媚俗艺术与基督教生活》的英文版(Chicago:Franciscan Herlad Press,1967),p.75。宗教媚俗艺术的 “恶魔特性” 这一主题并不新鲜。亚历山大 · 辛格里亚为罗马天主教的正统派说话,并把宗教艺术在现代堕落的主要原因归于宗教改革运动,在《神圣艺术的堕落》(Lausanne:Les Cahiers Vaudois,1917)一书中他写道:“我们最终来谈谈恶魔行为的另一种方式:我要说是梦幻。存在着某种真正恶魔般的艺术,它笨拙地模仿着美。这种艺术以花哨、各种诗意的外表以及光滑的材料赢得了全部公众的赞同。对于那些不够敏感、缺乏训练、不仔细、懒散的眼睛,这种光滑的材料掩盖了生活、智慧和美的完全阙如。”(p.45)尽管他没有使用媚俗艺术一词,辛格里亚也许是首先以著书的方式探讨这一主题的作者。他的 “堕落” 概念完全与媚俗艺术同义,他所认为的宗教艺术衰败的原因(道德原因如厌烦、懒惰、说谎,和历史原因如宗教改革、法国革命和世俗主义、浪漫主义和工业主义的兴起)也导向必然的结论,即他所说的 “堕落” 是一种特定的现代现象。现代性和媚俗艺术之间的关系又一次得到证实。辛格里亚的书 1930 年重印时加上了保罗 · 克洛代尔的序言(Paris:L’Art Catholique)。
论后现代主义(1986)
[1]. 见杰拉德 · 格拉夫,“后现代突破的神话”,《文学反对其自身》(Chicago:University of Chicago Press,1979),pp.31-62。
[2]. 见查尔斯 · 纽曼,《后现代氛围:通货膨胀时代的虚构行为》,杰拉德 · 格拉夫作序(Evanston:Northwestern University Press,1985)。
[3]. 克劳德 · 罗森最近评论约翰 · 阿什伯里的文章,“一位后现代运动场上的诗人”,发表于《泰晤士报文学副刊》,1986 年 7 月 4 日,p.724。
[4]. 贾雷尔对洛威尔《威尔利勋爵的城堡》的评论,最初发表于 1946 年,重印在兰德尔 · 贾雷尔的《诗歌与时代》(New York:Knopf,1953)中。引文见 p.216。在他的《后现代美国诗歌》(Urbana:University of Illinois Press,1980)中,哲罗姆 · 马扎罗强调贾雷尔是 “美国诗歌方面后现代一词” 的率先使用者,并指出两年后在 1948 年,“约翰 · 贝里曼使用了同一术语…… 并援引贾雷尔为其滥觞”(p.viii)。
[6]. 查尔斯 · 奥尔森,《散文补编》,乔治 ·F. 巴特里克编(Bolinas:Four Seasons Foudation,1974),p.40。完整的段落是:“我是一个黎明考古学家。我发现对当前工作有影响的写作行为是(1)自荷马上溯,而不是往下;和(2)自麦尔维尔以降,特别是他本人、陀思妥耶夫斯基、兰波和劳伦斯。这是些打破魔咒、投射出我们所是和我们所在的现代人。他们把人往前推向后现代、后人本主义、后历史、即时生活和 “美好事物”。
[7]. 有关 “后” 词汇更详细的清单出自一位代表性批评家,莱斯利 · 菲德勒,见本书 p.137。
[8]. 关于新诺斯替教和其他六十年代典型的思想潮流,见伊哈布 · 哈桑,《超批评:时代七思》(Urbana:University of Illinois Press,1975)。
[9]. 关于后现代主义一词早期阶段的详细历史,见米夏埃尔 · 克勒,“后现代主义:观念史概要”,《美国研究》22,no.1(1977):8-17。更近更全面的文化历史综述见伊哈布 · 哈桑《俄尔甫斯的肢解》第 2 版(Madison:University of Wisconsin Press,1982)中的 “1982 年后记:关于后现代主义概念”,pp.259-271。迄今为止,对后现代主义作为术语的历程作出最全面考察的是汉斯 · 伯顿斯,“后现代世界观及其与现代主义的关系”,见《走近后现代主义》,杜威 ·W. 佛克马和汉斯 · 伯顿斯编(Amsterdam and Philadelphia:John Benjamins,1986)pp.9-51。
[10]. 斯蒂芬 · 图尔明,“对现实的解释:现代与后现代科学中的批评”,见《解释的政治学》,W.J.T. 米切尔编(Chicago:University of Chicago Press,1983),pp.99-117。
[11]. 伊利亚 · 普里高津与伊莎贝拉 · 斯滕格斯,《从混乱到有序:人与自然的新对话》,阿尔温 · 托夫勒作序(New York:Bantam Books,1984)。莫诺的引用及对其意义的评论见 pp.3-4 和 84。
[12]. 同上,p.292。
[13]. 见理查德 · 罗蒂,《哲学与自然之镜》(Princeton:Pricenton University Press,1979),尤其是第 7 章 “从认识论到阐释学”,pp.315-316。
[14]. 在美国认为后现代主义可上溯至海德格尔的观点为威廉 ·W. 斯潘诺斯和理查德 · 帕尔默所支持。特别见《马丁 · 海德格尔与文学问题:走向后现代文学阐释学》,威廉 ·W. 斯潘诺斯编(Bloomington:Indiana University Press,1979)。理查德 · 帕尔默为该文集写的文章 “海德格尔的后现代性” 可视为后现代主义问题上此种态度的纲领,pp.71-92。
[15]. 引自瓦蒂莫 “瓶、网、真理、革命、恐怖主义、哲学” 的英译文,《丹佛季刊》16,no.4(1982 年冬季号):26-27。瓦蒂莫有关哲学后现代主义的主要观点见他的《关于主体:尼采、海德格尔与阐释学》(Milan:Feltrinelli,1981),和《现代性的终结:后现代文化中的虚无与阐释学》(Milan:Garzanti,1985)。有关 “弱思想” 的论争由《弱思想》发动,该书为贾尼 · 瓦蒂莫和彼尔 · 阿尔多 · 罗瓦蒂所编(Milan:Garzanti,1983)。有关意大利后现代主义的有益讨论,见斯迪法诺 · 罗索,“后现代意大利:关于‘理性危机’、‘弱思想’和《玫瑰之名》的札记”,见《后现代主义探索》,马泰 · 卡林内斯库与 D.W. 佛克马编(Amsterdam and Philadelphia:John Benjamins,即出)。
[16]. 于尔根 · 哈贝马斯,“现代性对后现代性”,《新德国批评》22(1981 年冬季号):14。
[17]. 同上,p.13。
[18]. 见于尔根 · 哈贝马斯,“问题与反问题”,《哈贝马斯论现代性》,理查德 · 伯恩斯坦编(Cambridge, Mass.:MIT Press,1985),p.196 与 p.229,n.6。哈贝马斯说,在把福科与德里达同魏玛共和国时期的 “青年保守主义者”(阿诺尔德 · 盖伦、马丁 · 海德格尔、卡尔 · 施密特与恩斯特 · 云格尔)相比时,他想强调,“他们都从尼采那里获得了与现代性决裂的激进姿态,以及对前现代能量的革命性更新,这种能量更新往往会远及于古代。同任何比较一样,这种比较也有其弱点,但在德国语境中,它确实表明了源出于尼采权威性的理知相似性,尽管双方有着对立的政治立场”(p.229)。另有一篇文章,“通向后现代性的法国路径:介乎性本能与一般经济学之间的巴塔耶”,《新德国批评》33(1984 年秋季号):79-102,在这篇文章中,哈贝马斯又一次指明尼采是某种有关现代性的话语的源头,这种话语在法国由巴塔耶肇端。同样源出于尼采这一点,也许可以解释巴塔耶和海德格尔这样原本迥异其趣的思想家之间惊人的关联。哈贝马斯写道,他们都 “致力于突破现代性的牢笼,突破已经在世界历史范围内取胜的西方理性主义。他们都想克服主体主义…… 在这方面两位思想家如此一致,以至于福科谈论巴塔耶越界(transgression)概念的话同样适用于后期海德格尔的超越概念,等等”。(pp.80-81)
[19]. 让——弗朗索瓦 · 利奥塔,《后现代状况:关于知识的报告》,杰夫 · 班宁顿与布赖恩 · 马苏米英译(Minneapolis:University of Minnesota Press,1984)。
[20]. 同上,pp.18-37。亦见让——弗朗索瓦 · 利奥塔,《对孩子而言的后现代》(Paris:Galilée,1986),pp.37-42 和 45-46。
[21]. 利奥塔,《后现代》,p.47。
[22]. 理查德 · 罗蒂,“哈贝马斯与利奥塔论后现代性”,《哈贝马斯论现代性》(见注 18),pp.161-176。关于哈贝马斯在这一论争中的观点,见彼得 · 杜斯为其编选的哈贝马斯作品所写的前言,《自主与一致:访谈》(London:Verso,1986),pp.1-35。利奥塔在此被认为是尼采影响下法国后结构主义的典型代表。对于利奥塔——哈贝马斯的现代性与后现代性之争的另一新马克思主义描述,见阿尔布莱希特 · 魏尔默的文章,“论现代主义与后现代主义的辩证法”,《国际实践》4,no.4(1985 年 1 月):337-361。
[23]. 新艺术两种策略创新(innovation)与更新(renovation)的问题,是收在《创新 / 更新:人文科学新视角》一书中那些论文的核心主题,该书为伊哈布 · 哈桑和萨利 · 哈桑所编(Madison:University of Wisconsin Press,1983)。特别见哈桑,“文化变化诸观念”,pp.15-46。关于通过一种 “对话多元主义” 的视角重新发现过去,见拙文“从一到多:今日思想中的多元主义”,pp.263-288。
[24]. 翁贝托 · 艾柯,《〈玫瑰之名〉后记》(意大利文),威廉 · 韦佛英译(New York:Harcourt Brace Jovanovich,1984),pp.66-67。
[25]. 见约翰 · 巴斯,《文学的耗尽与文学的充盈》(Northridge, Calif.:Lord John’s Press,1982)。
[26]. 居伊 · 斯卡皮塔,《不纯》(Paris:Grasset,1985),p.42。
[27]. 见拙文,“后现代主义与一些分期的悖论”,《走近后现代主义》(见注 9),p.249。
[28]. 伊哈布 · 哈桑,《俄尔甫斯的肢解》(见注 9),p.266。
[29]. 罗伯特 · 文图里,《建筑中的复杂性与矛盾》,第 2 版(New York:Museum of Modern Art,1977);以及文图里与丹尼斯 · 斯科特、斯蒂芬 · 伊泽诺,《向拉斯维加斯学习》(Cambridge, Mass.:MIT Press,1972)。
[30]. 查尔斯 · 詹克斯,《后现代建筑的语言》(New York:Rizzoli,1977);《晚期现代建筑》(New York:Rizzoli,1980);《后现代古典主义:新的综合》(London:Academy Editions,1980);以及收有威廉 · 蔡特金一篇文章的《当代建筑》(London:Academy Editions,1982)。
[31]. 保罗 · 波尔托盖西等,《过去的在场:第一届国际建筑展——1980 年威尼斯双年展》(London:Academy Editions,1980);波尔托盖西,《现代建筑之后》(意大利文),梅格 · 肖英译(New York:Rizzoli,1982),以及波尔托盖西,《后现代,后工业社会的建筑》(意大利文),艾伦 · 夏皮罗英译(New York:Rizzoli,1983)。
[32]. 海因里希 · 科尔茨,《后现代景象》(New York:Abeville Press,1985)。
[33]. 詹克斯,《当代建筑》(见注 30),p.158。
[34]. 同上,p.111。
[35]. 同上,p.12。
[36]. 翁贝托 · 艾柯,《〈玫瑰之名〉后记》(见注 24),p.71。
[37]. 同上,p.54。
[38]. 同上,p.64。
[39]. 琳达 · 哈琴,《戏拟理论:二十世纪艺术形式的教导》(New York and London:Methuen,1985)。这本书根据文本间的戏拟性双重编码探讨了后现代主义的问题。有关哈琴戏拟理论更详细的讨论,见我的评论文章 “戏拟与文本性”,《符号学》即出。
[40]. 居伊 · 斯卡皮塔(见注 26)把后现代主义的 “过度编码” 同作为某些先锋派特征的极简主义编码相对立。但他的这种对立并不如看起来的那么尖锐,因为他认为,后现代主义之所以从先锋派中成功地解放出来,不是通过“拒斥、反动,而是通过延伸、拓展、夸张、过度编码——不是通过否定先锋主义已引入的东西,而是通过把它吸纳进不那么极简主义的后现代主义程式”。(p.187)
[41]. 詹克斯,《当代建筑》(见注 30),p.16。
[42]. 关于后现代主义使用中的 “现实主义”(或我所谓的“戏剧”)谬误,见拙文“后现代主义:模仿和戏剧谬误”,《后现代主义探索》(见注 15)。有关社会科学中“现实主义幻象” 的更一般探讨,见雷蒙 · 布顿,《无序之地》(Paris:Presses Universitaires de France,1984),pp.229-238。
[43]. 克莱门特 · 格林伯格,“现代主义绘画”,见《新艺术:批评文集》,格雷戈里 · 伯特科克编(New York:Dutton,1966),pp.100-110。
[44]. 克莱门特 · 格林伯格,《“后现代” 的概念》,1980 年悉尼大学第四届威廉 · 多贝尔爵士纪念讲座讲稿(Syndey:Bloxham and Chambers,1980),p.12。
[45]. 同上,p.11。
[46]. 同上,p.14。
[47]. 希尔顿 · 克雷默,“八十年代的后现代艺术与文化”,《新标准》1,no.1(1982):36-42。作为《新标准》的编辑,克雷默把维护现代主义和全面拒绝后现代主义变成了该刊的总方针。
[48]. 弗雷德里克 · 詹姆逊,《攻击的寓言:温德姆 · 刘易斯,作为法西斯主义者的现代主义者》(Berkeley:University of California Press,1979)。有关詹姆逊的现代主义政治学立场的更详细讨论,见拙文 “现代主义与意识形态”,《现代主义:挑战与展望》,莫尼克 · 切弗多尔、里卡尔多 · 基尼奥内斯与阿尔伯特 · 瓦赫特尔编(Urbana:University of Illinois Press,1986),pp.79-94。
[49]. 弗雷德里克 · 詹姆逊,“后现代主义与消费社会”,见《反审美:后现代文化论文集》,哈尔 · 福斯特编(Port Townsend, Wash.:Bay Press,1983),pp.124-125。
[50]. 同上,p.125。
[51]. 同上。在更近的一篇文章中,詹姆逊讨论了詹克斯、利奥塔、哈贝马斯与希尔顿 · 克雷默等人对后现代主义的态度,并按意识形态的正负对它们进行了分类,“后现代主义的政治学:后现代论争中的意识形态立场”,《新德国批评》33(1984 年秋季号):53-65。他似乎暗示,后现代主义之区别于现代主义,是靠它的 “通俗主义”(populism),是靠它整合大众或通俗的元素 “从而使得我们较早的批评和评价范畴(恰恰以现代主义与大众文化的激剧分化为基础)不再起作用”;但他最后说,如果情况确实如此,“那么至少有可能的是,各种后现代主义辩白和宣言中的种种‘通俗主义’面具与姿态,实际上只是一种(肯定很重大的)文化转型的征象,在这种转型中,原先通常被贬斥的大众或商业文化被接纳进一个扩展了的文化领域”(p.65)——这是在重申早先矛盾的、说到底是否定性的立场。
[52]. 玛乔丽 · 珀洛夫,《不确定性的诗学:从兰波到凯奇》(Pricenton:Pricenton University Press,1981),p.4。
[53]. 同上,“不真实的城市”,pp.3-44。
[54]. 弗拉基米尔 · 纳博科夫,《埃达》(New York:McGraw-Hill,1969),pp.262-263。
[55]. 克里斯托弗 · 巴特勒《守灵之后:一篇关于当代先锋派的论文》(Oxford:Clarendon Press,1980),p.39。联系后现代主义概念同虚构与元虚构(及 “超虚构”)的关系而对它进行的杰出理论探讨,见克丽斯汀 · 布鲁克——罗斯的《非实在的修辞》(Cambridge:Cambridge University Press,1981),特别是 “外向内爆”(Eximplosions)一章,pp.339-363。
[56]. 见《赞同的视域:现代主义、后现代主义与反讽想象力》(Baltimore:John Hopkins University Press,1981),艾伦 · 怀尔德明确将贝克特排斥在后现代主义之外,从不把博尔赫斯或纳博科夫放在后现代反讽的语境中加以考虑,而差不多完全从英美作家中选取范例。基于怀尔德所选择的范例,人们完全可以得出结论说,现代主义大体上是一个英国事件(E.M. 福斯特和克里斯托弗 · 伊谢伍德是典型的现代主义者),后现代主义大体上是一个美国事件。
[57]. 贝克特式的 “失败美学” 是一个明显自相矛盾的概念,它得到一些人富有创见的探讨,其中有休 · 肯纳的《萨缪尔 · 贝克特》(Berkely:University of California Press,1968)。肯纳评论了贝克特在 1957 年的一个重要说法(“乔伊斯知道得越多就能做得越多。作为一个艺术家他正趋近于全知和全能。我是带着无能和无知工作。我不认为无能在过去已得到充分利用。”),他提出了一种富有启发力的隐喻性对比,即 “杂技演员” 型(娴熟地利用能力的人)和 “小丑” 型(娴熟地利用无能的人)之间的对比。肯纳指出,小丑表现的是“他不具备走钢丝的能力…… 他并不模仿杂技演员;很明显他做不到;他提供给我们的直接就是他的无能,这是一种复杂的艺术形式”(pp.33-34)。
[58]. 在他机智的评论作品《这不是一支烟斗》中,米歇尔 · 福科从马格丽特的画中读出了一些典型的后现代悖论(无限后退的那种),该书由詹姆斯 · 哈克尼斯英译(Berkeley:University of California Press,1982)。面对马格丽特的画,福科写道,你刚想确定 “‘这是一支烟斗’,却马上会修正自己,并踌躇不决,‘这不是一支烟斗,而是一支烟斗的素描’,‘这不是一支烟斗,而是一个说这不是一支烟斗的句子’,‘在“这不是一支烟斗” 这个句子中,“这”不是一支烟斗:绘画,写出来的句子,一支烟斗的素描——这一切都不是一支烟斗’”。(p.30)
[59]. D.W. 佛克马,《文学史、现代主义和后现代主义》(Amsterdam:John Benjamins,1984);以及 “后现代主义文本的语义和句法结构”,《走近后现代主义》(见注 9),pp.81-98。
[60]. 佛克马,《文学史、现代主义和后现代主义》,p.14。
[61]. 布赖恩 · 麦克黑尔,“从现代主义向后现代主义写作主因的转变”,见《走近后现代主义》(见注 9),p.75。
[62]. 同上 p.58.
[63]. 同上,p.60。
[64]. 同上。
[65]. 同上,p.74。
[66]. 埃尔鲁德 · 伊卜希,“从假设到修正:作为后现代主义话语一种成分的反驳”,见《走近后现代主义》(见注 9),pp.119-133。
[67]. 同上,p.122。
[68]. 布赖恩 ·T. 菲奇,《贝克特三部曲的维度、结构和文本性》(Paris:Lettres Modernes-Minard,1977),p.92。
[69]. 萨缪尔 · 贝克特,《莫洛伊》,帕特里克 · 保尔斯与作者英译(New York:Grove Press,1955),p.48。
[70]. 萨缪尔 · 贝克特,《叫不出名字的人》,作者英译(New York:Grove Press,1958),p.79。
[71]. 弗里德里希 · 尼采,《〈论道德的谱系学〉与〈看哪,这人〉》,瓦尔特 · 考夫曼与 R.J. 霍林德尔英译(New York:Vintage,1969),p.80。
[72]. 马克斯 · 韦伯,《新教伦理与资本主义精神》,塔尔科特 · 帕森斯英译(London:Unwin,1985),pp.47-48。
全文完
本文由 简悦 SimpRead 优化,用以提升阅读体验
使用了 全新的简悦词法分析引擎 beta,点击查看详细说明
现代性的五副面孔:现代主义、先锋派、颓废、媚俗艺术、后现代主义 (名家文学讲坛) 浪漫 “先锋派”:从政治到文化政治
========================
现代性的五副面孔:现代主义、先锋派、颓废、媚俗艺术、后现代主义 (名家文学讲坛) 浪漫 “先锋派”:从政治到文化政治
## 浪漫 “先锋派”:从政治到文化政治
------
对帕基耶来说,“先锋”只是一个暗示性的风格比喻,它同其他类似的修辞手法一道,传达出他对文学中的变化与演变的感觉。有意思的是,他从未表示过,那些被他归为 “先锋” 的人会以任何方式意识到自己的角色。而且如我们将会看到的,在更晚近的先锋派定义中,自我意识——或自我意识的幻觉——极端关键。
尽管我们是在战争语言中遇到 “先锋” 这个词的,现代的先锋派概念却更多地同一种较晚近的战争,即国内革命战争的语言、理论和实践有关。在此意义上,我们完全可以说先锋一词的实际里程开始于法国革命之后,它在那个时候获得了无可争辩的政治含义。不错,是一份军事期刊首先在它的名字里用上了这个词,但这丝毫不会让人怀疑其革命的、政治态度。我指的是[[《东比利牛斯军队的先锋》]],这份刊物出现于 1794 年,它的口号是 “自由或死”,镌刻在作为标志物的一柄剑的剑身上。这份刊物致力于捍卫[[雅各宾派]]的思想,并试图越出军事圈子而到达“爱国者” 这个较广泛的读者群。 9 因此我们可以把十八世纪九十年代视为起点,先锋概念随后开始了其在激进政治思想中的里程。事后看来,考虑到这个军事概念所具有的类比潜能,就不难解释这个隐喻对各种各样革命的、并从而着眼于未来的哲学所具有的吸引力:它们的代表人物肯定会喜欢他们比人类中的其他人(至少在理知上)更接近乌托邦这种想法,而这些其他人将会追循他们的道路。
因此,绝非偶然的是,文学艺术语境中先锋概念的浪漫运用直接源于革命政治的语言。这发生在 1825 年,当时,在[[圣西门]]最亲密的朋友和信徒之一奥林德 · 罗德里格斯撰写的对话《艺术家、学者与工业家》中,先锋一词被用于艺术。罗德里格斯的对话发表在《文学、哲学与工业观点》一书中,该书面世于 1825 年,也就是圣西门故世的那一年。尽管一般认为它是圣西门所作,但现在已经知道,这本未标明作者的书实际上是合作的产物,其中除了有那位大师的作品外,还收入了他的信徒的作品,这些人是:雷翁 · 阿累维,罗德里格斯,杜维尔日埃。 10 唐纳德 · 德鲁 · 埃格伯特对先锋概念在这里的出现给予了较为详尽的探讨,然而奇怪的是,他似乎只参考了 1825 年版的《文学、哲学与工业观点》,他把先锋一词的使用归功于圣西门,没有提到罗德里格斯的名字,而实际撰写艺术家、科学家和工业家之间对话的是罗德里格斯,即使他的灵感是来自圣西门的社会主义。
当然,为了理解[[罗德里格斯]]的文本,我们必须确定它在圣西门后期政治哲学这一较大框架中所占据的地位,尽管艺术家构成人类道德历史之先锋的观点,在相当程度上是更为一般的浪漫派和救世式信仰的产物。在人生的末期,圣西门认为,在理想社会中,艺术家,还有科学家和工业家,注定要成为三位一体的统治精英的一部分。这个使得艺术家成为新型社会领导阶层中杰出要素的社会组织原则,早已经圣西门提出,并为他和他的信徒在十九世纪二十年代早期详加阐述。比如说,这种观点就明白无误地表现在《圣西门致陪审员先生们的信》(1820)中,圣西门宣称:“新的思考向我表明,事情应该在艺术家的领导下向前进,他们后面跟着科学家,工业家应该走在这两者之后。” 11 我们很容易就可以看出,艺术家被指派了一种特殊的 “先锋” 角色,尽管在这里没有用先锋这个词。对圣西门来说,艺术家是 “想象的人”,因此,他不仅可以预见未来,还可以创造未来。他的宏伟使命是选取过去的“黄金时代” 并将它的神奇光芒投射到未来。在《社会组织》(1825)中,圣西门展望艺术家们开始“进军”,走向全人类的安乐与幸福的胜利进军:
…… 在这伟大事业中,艺术家们,那些想象的人,将开始进军:他们将从过去选取黄金时代,并将其作为礼物赠与将来的世代;他们将使社会满怀热望地追求其安乐程度的上升,为做到这一点,他们将描绘新繁荣的图景,将使每一个社会成员意识到,他们可以分享迄今为止只是一个极小阶级的特权的享乐;他们将歌颂文明的福祉,为实现他们的目标,他们将运用一切艺术、雄辩、诗歌、绘画和音乐手段;一句话,他们将揭示新制度诗意的方面。 12
看待艺术家问题的这种态度所存在的矛盾不难察知:一方面,艺术家享有荣耀,他们身处走向社会繁荣的运动的前列;另一方面,他不再自由,相反,那位慷慨地宣称他为领导者的政治哲学家给予他一整套要去实现的纲领,这套纲领完全是说教性的。这一切肯定会使我们想起本世纪的 “社会主义现实主义” 理论。这种指派给艺术家一种先锋角色的说教 - 功利性构想只会使他变成纪律严明的战士或军人。这种构想在罗德里格斯的对话中更是得到毫不含糊的肯定。罗德里格斯认为,如果艺术家先前在社会生活中只是扮演了次要角色,那是因为他们缺乏一种 “共同驱力” 和一种 “普遍观念”。这种“普遍观念” 自然将会是圣西门式高度集权化的社会主义,艺术家们被召唤来将它加以通俗化。罗德里格斯写道:
将充任你们先锋的是我们,艺术家;艺术的力量是最直接、最迅捷的。我们有各种武器:当我们想要在人民中间传播新的观念时,我们用大理石雕出它们或用画布绘出它们;我们通过诗歌和音乐使它们通俗化;同样,我们求助于里拉 9 或长笛,颂诗或歌谣,历史或小说;戏剧舞台向我们敞开,正是从那里我们的影响热力四射、无往不胜。我们诉诸人民的想象力与情感:因而我们被认为可以实现最生机蓬勃、最具决定性的行动;如果今天我们看起来没有发挥作用或充其量只发挥了次要作用,那是艺术家缺乏一种共同驱力和一种普遍观念的结果,这种共同驱力和普遍观念对于他们的力量与成功不可或缺。 13
我们感兴趣的是作为批评概念的[[先锋派]],但我们不可忽视下述事实:十九世纪早期在艺术语境中使用的先锋一词——使用者是一位政治思想家——仍然带有很强的军事含意。这就是为什么在上面引述的段落中我们会发现诸如此类的军事或准军事概念:“进军”,“力量”,“武器”、“无往不胜”,“决定性行动”,等等。
然而,如果把罗德里格斯所说的艺术家的先锋使命同帕基耶的风格比喻所具有的较狭隘意义作一比较,我们就会明白,先锋隐喻及与之相关的那些军事类比的功用已发生了重要转移。重要的变化在于下述含义:先锋派是(或应该是)有意识地走在时代前面。这种意识不仅给先锋派的代表人物加上了一种使命感,而且赋予他们以领导者的特权与责任。成为先锋派的一员就是成为精英阶层的一部分——尽管与以往的统治阶级或统治集团不同,这个精英阶层忠诚于一个完全反精英主义的纲领,它的终极乌托邦目标是所有人民平等地享受生活的所有福利。如我们将看到的,在先锋派问题上这种基本的精英主义 - 反精英主义态度,保留在了马克思 - 列宁主义的党作为无产阶级革命先锋队的理论中。就十九和二十世纪的艺术先锋派来说,同样的悖论提供了理解其大多数明显自相矛盾的言行的钥匙,尽管在这里悖论是从美学角度得到阐明的。这也许可以用洛特雷阿蒙著名的无政府主义格言来表明,这句格言后来被包含在超现实主义的信条中:“诗歌不应该由一个人来写,而应该由所有人来写。” 过去一百年中政治先锋派和艺术先锋派的主要区别在于:后者坚持艺术具有独立的革命潜能,前者则倾向于持相反的观点,即艺术应该服从于政治革命者的需要与要求。但两者都从同样的前提出发:生活应该得到根本的改变。两者的目标也都是乌托邦式的无政府状态(即使马克思在内心深处也是一个无政府主义者,当他同巴枯宁及其信徒论战时,他并非不同意他们的目标,即消灭国家,而只是不赞同他们所提出的实现这一目标的实际手段)。
如果仔细想想圣西门和罗德里格斯有关艺术家使命的观点,我们就不难辨认出一种浪漫派特有的语气。自浪漫派发轫之初,诗人作为先知的神话就被接受并得到发展,然而在此去回顾不胜枚举的可能实例会让我们离题太远。这里只需要指出,几乎所有思想进步的浪漫派都对诗歌的先锋地位深信不疑,即使他们并不使用 “先锋” 这个词,即使他们并不拥护一种说教 - 功利性的艺术哲学。雪莱很好地表明了后一点。作为威廉 · 戈德温的信徒——戈德温是著名的《政治正义探询》(1793)的作者——雪莱无疑是一个自由激进派,但他认为(用他自己的话来说)“一个诗人…… 将他自己有关对错的想法体现在他的诗歌创作中是不恰当的,他的对错观通常是他所处时代和地域的对错观,而他的诗歌创作是不参与其所处时代和地域的。” 14 诗歌的本质是想象,如果诗歌必须要有道德效果,也只能通过扩大想象来取得:“一个人要想非常地善,就必须广泛而深入地想象…… 诗歌扩大想象的周界。” 换句话说,诗歌之所以必须发挥一种重要的社会功用,不是因为它可以使观念或别的什么 “通俗化”,而只是因为它激发想象。
这些观点见于[[雪莱]]身后发表的[[《诗之辩护》]],此文写于 1821 年。雪莱是想驳斥 T.L. 皮科克的观点。在他的讽喻之作[[《诗的四个时代》]]中,皮科克主张 “在我们时代,一个诗人乃是一个文明社会中的半野蛮人”。对雪莱来说,诗人不是过去的残余,而是未来的报信人。在《诗之辩护》的结论部分,诗人被具体地称做“信使”,他们的心灵被称做“未来的镜子”。“诗人,” 雪莱写下一句不朽名言,“是不被承认的世界立法者。”
雪莱的文章可以说是一位伟大浪漫派诗人在我们所关注的论争中写下的证言,在其中我们发现一些在圣西门及其信徒的著作中得到强调的观点。首先是,诗人(或一般地说创造性艺术家)主要是想象的人这样一种形象;其次是,诗人作为未来的信使这种想法。艺术家的独有社会功能既为圣西门也为雪莱所强调。但在艺术家的使命上圣西门倾向于赞同一种重教诲、重主题的观点,雪莱则似乎认为,艺术家的这种使命是经由想象力的运用更自然地甚至是无意识地实现的,想象力不是受理性而是受自发灵感的支配。圣西门和雪莱之间本质的对立就在于,前者是指定一个计划让想象去实现(缺少了一种 “共同驱力” 和一种“普遍观念”,想象就不具有真正的力量),后者差不多完全是强调想象本身,把想象认做最高的道德特性。从根本上说,这种区别可以化简成专制主义和自由主义之分。这个区分对于理解先锋派概念后来在艺术和政治两方面的演变十分重要。
夏尔 · 傅立叶是圣西门在政治哲学和社会改革思想上的竞争对手,他没有明确分派给艺术家一种先锋角色,但他的学说中却以多种方式暗含了这种观点。因而下述事实并不令人惊异:他的信徒之一,湮没无闻的加布里埃尔 · 德西雷 · 拉韦尔当,差不多是以和圣西门与罗德里格斯相同的思路来构想艺术的使命的。他的一本小册子题为《艺术的使命与艺术家的角色》(1845),在雷纳托 · 波吉奥里看来,这本小册子是 “艺术作为社会行动与改革的工具、作为革命宣传与鼓动的手段这种学说” 15 的完美范例。其中,为使先锋一词显示出它的意义,拉韦尔当具体写道:
艺术是社会的表现,当它遨游于至高境界时,它传达出最先进的社会趋向;它是前驱者和启示者。因而要想知道艺术是否恰当地实现了其作为创始者的功能,艺术家是否确实属于先锋派,我们就必须知道人性去向何方,必须知道我们人类的命运为何。 16
显然,[[傅立叶主义]]对于大批艺术家所具有的广泛吸引力并非在于拉韦尔当所表达出来的那些观念。正如唐纳德 · 埃格伯特指出的,在傅立叶主义中艺术家们感觉有吸引力的东西是,傅立叶的政治观点 “接近于无政府主义…… 强烈的个人主义元素使得傅立叶主义和无政府主义同样对那些先锋派浪漫个人主义者具有吸引力,这些人先是服膺‘为艺术而艺术’的学说,然后又皈依象征主义。” 17 在傅立叶的哲学中还有另外一些元素,使得它比十九世纪发展起来的大多数其他社会主义思想派别对艺术家有着更大的吸引力。“傅立叶的普遍和谐的想法,” 唐纳德 · 埃格伯特写道,“归根结底同他新柏拉图式的普遍统一信念有关,而这种信念反过来又导致他的本质上属于浪漫派的信念,即相信他所认为的‘普遍类似’(即波德莱尔后来所说的‘交感’)。傅立叶在颜色、声音、弧线、热情与权利之间寻求类似。由此他拓展了在浪漫派以及在稍后的象征主义艺术理论中发挥了如此重要作用的声音与颜色之间的类比。” 18
先锋隐喻随后在文化上的运用应被视为一种更广泛现代趋势的标志之一,这就是在政治思想与美学上走向激进主义。非常自然的是,十九世纪的乌托邦改革者们呼唤一种忠诚的、战斗的、政治上负责的艺术。然而,有意思的是,政治上独立的艺术家,甚至是一些纯粹派理论的坚定维护者,也常常从激进主义的语言中借用词汇,用以谴责他们时代的 “官方” 文化及其所有美学和其他方面的禁忌。因此,临近十九世纪末,一些最重要的艺术主张都包含有直接脱胎于政治词汇的概念。最具说服力的例子也许是马拉美的观点:现代诗人,简单地说也好强调地说也好,是在“向社会罢工”(en gréve devant la sociétè)。 19 这个观点见于他同儒勒 · 于雷的一次重要谈话(1981)。
## 一些十九世纪中期作家与先锋派
到十九世纪中期,在其最初的政治意义和次生的文化意义上,先锋隐喻已为[[社会乌托邦主义]]者、各种改革家和激进新闻工作者使用,但就我所知,它极少为文学或艺术界人士使用。如前面已经指出的,认为艺术家赋有想象力、他们实际上是 “未来的镜子” 并因此而领先于他们时代的这样一种看法,是许多思想进步的浪漫派人士共有的。维克多 · 雨果便是其中之一。但在《悲惨世界》(1862)之前雨果似乎并未使用先锋比喻,只是在该书的一个段落中他才运用了这个比喻,这个段落表明,他热烈赞同一种广义的知识先锋派:
以[[狄德罗]]为首的[[百科全书派]],以[[杜尔哥]]为首的[[重农主义者]],以[[伏尔泰]]为首的哲学家,以[[卢梭]]为首的乌托邦主义者——这是四个神圣军团。当他们向进步的四个方向进军时,他们是人类的四支先锋——狄德罗向美的事物进军,杜尔哥向有用的事物进军,伏尔泰向真理进军,卢梭向正义进军。 20
为了更好地理解到十九世纪中期先锋这个词意味着什么,我们也应该考虑到巴尔扎克。在他为他的时代所做的宏伟而细致的编年史中,[[巴尔扎克]]注意到 “先锋” 已成为革命修辞的滥调。有意思的是,当他作为一个叙事者写作时,他并没有使用这个词,而仅仅是在报道一个特殊人物的讲话时,他才使用了它。这个人物被描绘成一个“共和激进派”(他的先知式革命主义同他做鸡眼治疗师的平凡职业形成有趣的对比),他有一个富有讽刺意味的名字:普布利科拉 · 马松,在《无知的喜剧演员》(1846)中短暂出现却令人难忘。在[[《人间喜剧》]]这个大系列中,[[《无知的喜剧演员》]]是属于[[《巴黎生活场景》]]的一个短篇。当普布利科拉 · 马松在一位著名画家的家中开展他那不怎么令人愉快的工作时,他宣称一场社会大动荡即将来临,同这场大动荡相比,法国大革命的恐怖显得颇为仁慈——他宣称,“我们在罗伯斯庇尔和圣鞠斯特之后到来,将比他们有所改进。” 21 有趣的是,他所描绘的意识形态先锋是一种为一场大爆炸做准备的颠覆力量,这场大爆炸将炸毁所有现存社会结构,并使一个新的、更好的社会成为可能:
一切都在协力同心地帮助我们。因此,所有怜恤人民的人,所有为无产阶级和工资问题呼喊的人,或所有为反对阴谋家而写作的人,或所有有志于改进一切事物的人——共产主义者,人道主义者,慈善家——所有这些人都是我们的先锋。我们在储备火药,他们在编织导火线,环境的火星将把它点燃。 22
第一位在比喻意义上使用先锋一词的重要现代文学批评家似乎是[[圣伯夫]],在他的[[《月曜日漫谈》]]中。在他评论伊波利特 · 里戈《古今之争史》的第二篇文章(写于 1856 年 12 月 22 日)中,圣伯夫谈到了十八世纪德庞教士的 “先锋热忱”。在著名的古今之争中,德庞显然是支持“现代人” 的,并反对——在圣伯夫引用的一个段落中——
“愚蠢的博学者”,实际上也就是反对权威的观念(“…… 要敢于自己思考,而不要听命于那些发誓无论如何都要忠实于荷马的愚蠢的博学者……”)。圣伯夫评论说:“我们不难看到,先锋热忱和战斗激情已使德庞教士愤怒难当,平常温文尔雅的他也开始用真正粗俗的词。” 23 有趣的是,如圣伯夫所说的,德庞 “宣称在诗歌和纯文学方面,就像自笛卡尔以来在哲学上一样,人们应该不受权威甚至是传统判断的影响。” 24 至于先锋这个词的使用,显然圣伯夫还谨记其军事和论战含义;同样很清楚的是,他并不赞成 “先锋热忱” 所隐含的夸大其词。
由于先锋派这个词频频被用于激进主义的政治语言,当它被用于文学或艺术时,它往往会指向一种忠诚,人们可以从一位视政党宣传为自己主要职责的艺术家身上发现这种精神。也许主要就是出于这个原因,在十九世纪六十年代初波德莱尔不喜欢也不赞成先锋派这个词和先锋派这个概念。在其个人笔记中一些有典型意义的段落里,[[波德莱尔]]相当明确地表达了对于 “文学先锋派” 的极度蔑视。他的笔记在他死后以《我心赤裸》之名发表。波德莱尔深邃的智慧感受到了先锋派(按当时的理解)的悖论:不顺从被还原成一种军事纪律,或者更糟糕,被还原成一种畜群式的服从。他自己的个人主义被他所谓的 “法国人对于军事隐喻的偏好” 所压制。波德莱尔对于先锋派的评说有一种强烈的讥讽性质:
论法国人对于军事隐喻的热烈偏好。在这个国家每个隐喻都长有八字须。文学的军事学派。驻守堡垒。高举旗帜…… 更多的军事隐喻:战斗的诗人。先锋派文学家。这种喜好军事隐喻的弱点是一些人的标志,这些人自己并非军事家,却是为纪律而生的——也就是说,是为服从而生的——这些人天生驯顺,这些只能步调一致地思考的比利时人。 25
的确,当波德莱尔如此激烈地排斥先锋派这个词的时候,它还没有同后来成为先锋派美学本质要素的那种艺术 “极端主义” 和“实验”精神发生联系。然而,波德莱尔的观点不只是一时之论;我们可以说,他对于先锋派的排斥具有某种预言性质,这种预言性质使得它对于整个先锋派问题具有意义。因为,不正是先锋派全面的不顺从滋生了一种新型的服从吗?(虽然这种新型服从是捣毁偶像式的。)因此,说波德莱尔是第一位指出在文化上使用先锋概念所导致的某些基本困境的作家,是不会有错的。一些最敏锐的先锋派研究者都遇到了这个特殊问题,德国诗人汉斯 · 马格奴斯 · 恩岑斯伯格在一篇出色论文中对它做了详细讨论,这篇文章就是[[《先锋派的困境》]](1962)。在评论布列东《第一次超现实主义宣言》的开头一句话时,恩岑斯伯格写道:
“惟自由一词尚能使我充满热情。我认为它适宜于使人类古老的狂热保持至无限的将来。”1924 年,安德烈 · 布列东用这两句话作为[[《第一次超现实主义宣言》]]的开篇。一如既往,这种新的教义围绕着它对绝对自由的渴望而形成。狂热(fanaticism)一词已经是一种提示,它表明自由只有以绝对纪律为代价才能获得:几年之内,超现实主义的卫队将它自己织进了条规之茧。 26
这里的论述显然使我们想起波德莱尔所强调的那种不可化解的矛盾,即存在于先锋派堪称英勇的不遵从主义和它对于盲目、不宽容的纪律的最终服从之间的矛盾。
## 两种先锋派:引力与斥力
十九世纪七十年代在法国,先锋派一词虽然仍保有其广泛的政治含义,但已开始用于指称一小群新进作家和艺术家,这些作家和艺术家把针对社会形式的批判精神转移至艺术形式的领域。这种转移并未导致艺术家从属于一种狭隘的政治哲学,或使他们沦为单纯的宣传家。宣传要富有效力,就必须求助于最传统的、图式化的甚至是简单化的话语形式。而新的先锋派艺术家,无论他们多么赞同激进的政治观点,感兴趣的是推翻所有羁缚人的艺术形式传统,享受探索先前被禁止涉足的全新创造境域的那种激动人心的自由。因为他们相信,对艺术进行革命与对生活进行革命并无二致。因此,艺术先锋派的代表人物有意识地背离一般公众在风格上的期望,这些一般公众是政治革命家试图通过陈腐的革命宣传来争取的。两种先锋派冲突的根源即在于此。
十九世纪七十年代新进艺术家这种新的、美学上革命的心态,仅举一例来说,极好地体现在[阿图尔 · 兰波]]的一些作品和书信中——例如,在著名的《预言家的信》中,这封信是他 1871 年 5 月 15 日写给保罗 · 德梅尼的。尽管诗人没有使用先锋派一词,但无疑涉及到了这个概念,以及其所有重要含义。“新来者,” 兰波给德梅尼写道,“可以自由地诅咒前辈。” 诗人应努力成为先知,达至未知的领域,创造出一种全新的语言。因而诗歌将是超前的(用兰波自己的话来说是:“诗歌将不再能使行为具有节奏,它将超前…… 与此同时,让我们要求诗人有新的东西——思想和形式。” 27 )青年兰波的社会主义——无政府主义信念众所周知;他对 1871 年巴黎公社的公开同情也是如此。在兰波身上——但他绝不是唯一的例子——两种先锋派(艺术的和政治的)趋于融合。波吉奥里注意到了这一有趣的现象。他认为这两者在大约十年之内几乎是完全统一的:
一时间两种先锋派携手并进,从而更新了浪漫派的先例或传统,这种先例或传统确立于 1830 和 1848 年革命之前的世代中…… 这种联合…… 在法国持续至第一个现代文学杂志的出现,该杂志颇有深意地起名为《独立杂志》。它创立于 1880 年,也许是把政治造反者和艺术造反者兄弟般地团结在同一面旗帜下的最后一个机构,这些人是社会和艺术思想这两个领域内新进观点的代表。此后不久,即可以说发生了这两种先锋派的离异。 28
在此应该说明,我发现波吉奥里有关两种先锋派突然且彻底离异的观点是无法接受的。两种先锋派之间的关系模式实际上更为复杂。确实,晚近欧洲所谓的 “新先锋派”(主要是二十世纪五十年代以后发展起来的)要求我们以一种波吉奥里不可能采取的角度看待整个先锋派问题——波吉奥里的书主要构思于 1946 至 1950 年间。 29 但即使是今天所说的 “老先锋派” 或“历史先锋派”,也不止一次地从政治上获得灵感;就算那些代表历史先锋派的运动从未完全成功地同那些多少是与它们平行的激进政治运动结合起来,说两种先锋派为不可跨越的鸿沟所分隔也是不正确的。
不过,我们可以说是一种词语之争,使得整个先锋派的问题有些混乱。这主要是由于先锋派一词本身所具有的积极内涵。 30 这些积极内涵最终压倒了先锋派作为一个文学术语所具有的贬义内涵,而在政治语言中,先锋派的积极内涵还要强烈。所有着眼未来的社会政治学说都认为自己属于先锋之列:圣西门派、傅立叶主义者、无政府主义者(克鲁泡特金 1878 年在瑞士出版名为《先锋》的杂志)、马克思主义者等争夺着这一术语,把它纳入到他们自己的修辞中。
先锋派在[[马克思主义]]中的应用提供了富有意味的例子。尽管马克思和恩格斯的《共产党宣言》(1848)没有使用先锋派这个术语,但它显然暗含了先锋派的概念。唯其如此,就像唐纳德 · 埃格伯特在《社会激进主义与艺术》中指出的,
到十九世纪八十年代,至少是马克思主义者已习惯于把先锋派作为一个政治术语来使用,这样做的一个结果是,九十年代期间,大量与工党马克思主义者有联系的法国地方报刊取名为《先锋》,或是在名字中带有这个词。但是把《共产党宣言》中的表述发展为党构成政治 “先锋派” 这种学说的是列宁(他自己即用的这个词)。 31
在《怎么办》(1902)一文中,列宁首次把党定义为无产阶级的先锋。非常有意思的是,在写于 1905 年的《党的组织和党的出版物》中,列宁运用有关革命先锋派的观点,强烈谴责任何不能在社会民主的 “巨大…… 机器” 中像小 “齿轮” 和“螺丝钉”一样发挥作用的文学活动,社会民主的巨大机器将完全由党来开动:
不要非党的文学。不要文学超人。文学必须成为无产阶级共同事业的一部分,成为一个巨大社会民主机器上的 “齿轮和螺丝钉”,这台机器由整个工人阶级的在政治上富有觉悟的整个先锋队来开动。文学必须成为社会民主党有组织、有计划的整体工作的一部分。 32
文学被降格为小 “齿轮”,这就不难理解为何它不能有任何独立发挥先锋作用的要求了。因此,自二十世纪早期以来,特别是在 1917 年俄国十月革命之后,先锋派一词几乎是自动地联系着整密无间的共产党的概念,在斯大林时代这一点愈发得到强调。不仅对苏联来说是如此,而且对全世界的马克思主义 - 列宁主义正统派来说都是如此。由于它在马克思主义 - 列宁主义 - 斯大林主义政治习语中所起的作用,对这些学说的拥护者来说,先锋派一词显露出极其庄严的含义,以至于若将它用在别的语境中,差不多都要被认为是亵渎。许多马克思主义批评家(即使在西方)在论及先锋派文学或艺术时,之所以宁愿把它说成“现代主义的” 或“颓废的”,原因之一也许就在于此。他们把现代主义同 “现实主义” 和“社会主义现实主义”对立起来使用,从而在他们的用法中这个词就获得了确定无疑的消极内涵。用 “颓废” 的好处则在于给歧义留下了更小的余地。例如格奥尔格 · 卢卡奇,他把现代主义视为资产阶级历史困境的表现而从美学上予以谴责,认为真正的先锋派趋向应到当代重要的现实主义作家的作品中去找。 33 苏联批评界没有走得那么远;从未有人从先锋派的角度探讨过 “社会主义现实主义” 的文学艺术(尽管它们是极端说教性的),因为这样做有导致双重混淆的可能:其一,是艺术功能和党的实际 “先锋” 作用之间的混淆(党将其无可置疑的领导权加之于社会和知识生活的所有领域);其二,是 “社会主义现实主义” 和资产阶级 “颓废艺术” 之间的混淆,后者僭妄而混淆视听地自称为 “先锋派”,或是被称做“先锋派”(用在这样的情形中,“先锋派” 显然是一种可恶的术语僭用的标志)。这里,我们获得了完全出于政治目的而对先锋派一词作教条式规范使用的明确实例。
同时,先锋派一词的文学艺术方面意义——自十九世纪七十年代以来已很明显——在法国继续稳步发展,随后也在其他新拉丁国家获得发展。若非一种有着彰明较著特征的新风格在这些新拉丁文化的文学艺术中形成,这种语义发展过程是不可能达到一个 “结晶” 阶段的。为了更好地理解在第一次世界大战前的年月里先锋派意味着什么,看看它如何为纪尧姆 · 阿波利奈尔所用不无裨益。阿波利奈尔是诗歌和艺术中追求新形式的最直言不讳的代表人物之一。在一篇关于 1912 年 2 月 5 日在巴黎举办的首次意大利未来主义画展的文章中,阿波利奈尔对意大利艺术家的艺术实验没有表示丝毫同情,他写道:“年轻的未来主义画家可以同我们的一些先锋派艺术家抗衡,但他们仍然是毕加索或德兰的不成气候的学生。” 34 在这篇文章较早的一个段落中,阿波利奈尔说,未来主义者 “声称他们与那些更为极端的法国流派的艺术相对立,然而他们只不过是那些流派的模仿者。” 由此我们可以推定,在阿波利奈尔看来,先锋派正是由这些 “极端流派” 构成。
## 先锋派与美学极端主义
尽管[[阿波利奈尔]]被认为是[[立体主义]]的主要理论家之一,在 1913 年春天他的著作《立体派画家》出版之前,他却极少使用 “立体主义” 一词。现在我们知道,《酒精》的作者最初并没有打算出版一本论立体主义的书;他想到的仅仅是以《美学沉思录》这个朴实无华的书名,出一本有关 “新绘画” 的文集。该书的一校样(他可能是在 1912 年 9 月收到的)表明,在整本书中,“立体主义”一词仅用过四次。只是在那以后,阿波利奈尔才写了专门论述立体主义的几个简短的历史与理论性章节,他把这些章节加入到书中,同时更换了书名。这些细节仅仅证明,诗人丝毫不关心立体主义之类的流派和学说,他一视同仁地拥护新的实验趋向和艺术上革命的趋向,而不管这些趋向出现在什么地方。因此,在 1913 年 6 月,他不但忘掉了自己对未来主义画家多少是有些尖刻的攻击,而且忘掉了未来主义头面人物之一翁贝托 · 波丘尼对他的严厉指责,写下了著名的《表现综合:未来主义的反传统》(1913)。我们可以认定,对阿波利奈尔来说,先锋派就是他后来所说的 “新精神” 的同义词(我指的是他 1917 年所做的重要讲演《新精神与诗人》,讲稿在他死后发表于 1918 年 12 月号的《法兰西水星》杂志)。
及至我们这个世纪的第二个十年,先锋派作为一个艺术概念已经变得足够宽泛,它不再是指某一种新流派,而是指所有的新流派,对过去的拒斥和对新事物的崇拜决定了这些新流派的美学纲领。但我们不应忽视一个事实,亦即:新颖性往往是在彻底破坏传统的过程中获得的;“破坏即创造”,这句巴枯宁的无政府主义名言的确适用于二十世纪先锋派的大多数活动。
由于能够将所有反传统的极端运动归入一个较广义的范畴,先锋派成为二十世纪文学批评中一个重要的术语工具。这个术语随后经历了一个自然的 “历史化” 过程,但与此同时,随着它的更加流行,其意义也呈现出几乎是不可控制的歧异性,这种歧异性在此只能一笔带过。
在前文已经提到过的著作中,波吉奥里说:
“先锋艺术” 这个术语(也许还有这个批评概念)差不多完全属于新拉丁语言和文化…… 比起在其他地方,该术语更深地扎根于法国和意大利,更好地适应了它们的水土,这可以表明,对该术语内涵的感受力在意大利和法国这样的文化传统中要更为活跃,意大利的文化传统对美学中的理论问题感觉灵敏,法国的传统则特别倾向于从艺术的社会气质及其社会性(或反社会性)的角度来看待艺术。 35
自[[《先锋派理论》]]一书的作者写下这些文字以来,情况已发生了激剧的变化。一方面,先锋派这个术语和概念占领了英语国家和德国,它们曾经在一段时间内抵制了这个术语和概念;另一方面,尽管在某些情形中还保持着其发生学的意义,先锋派主要变成了一个历史范畴,它的名下集合着大多数出现于本世纪前半期的那些最为极端的运动。即使是作为一个历史概念,在把先锋派作为术语使用上,存在的对立也多得惊人。例如,在美国批评界,先锋派一般来说是现代主义的同义词,而与先前的浪漫主义(尤其是它的过时形式)和自然主义运动相对立,同时也与更晚近的天启式的后现代主义相对立。在当今意大利,先锋派概念的 “历史化” 明显见于通常在老 “先锋派”(常被称为“[[历史先锋派]]”)和“新先锋派” 之间所做的区分,后者有时也被说成 “实验主义”。一个类似的过程发生在西班牙,在那里先锋派的概念从一开始就同现代主义的概念相对立。早在 1925 年,吉列尔莫 · 德 · 托雷就肯定了先锋主义的国际性,并在他的著作《先锋派的欧洲文学》中探讨了它。有意思的是,在该书最近的扩充版中,作者在标题中突出了他的“历史性” 意图:《先锋派欧洲文学的历史》(Madrid:Ediciones Guadarrama,1965,1971)。“先锋主义”一词为当代西班牙文学史家广泛使用:安格尔 · 巴尔布埃纳 · 普哈特所著的《西班牙文学史》堪称标准史,它的第四卷不无意味地题做《当今时代,或从先锋主义到存在主义》。在这里,先锋主义被同存在主义区别开来,而在已经提到过的吉列尔莫 · 德 · 托雷的著作中,他认为[[存在主义]]是第二次世界大战后先锋主义的一种形式。
从逻辑上讲,每一种文学或艺术风格都应该有它的先锋派,因为认为先锋派艺术家走在他们时代的前面,准备去征服新的表现形式以供大多数其他艺术家使用,这是再自然不过的事情。但文化意义上的先锋派一词的历史——我仅简略述及过——却与此相反。先锋派并没有宣扬某种风格;它自己就是一种风格,或者不如说是一种反风格(antistyle)。这就是为什么,比如说,尽管欧仁 · 尤奈斯库最初讨论先锋派时强调该词本身(以及《小拉罗斯词典》)所指明的军事意义,最终却被迫抛弃那种显然是常规性的思路:
我宁愿以对立和断裂来定义先锋派,虽然大多数作家、艺术家和思想家认为自己属于他们的时代,革命的戏剧家却感到与他的时代格格不入…… 一个先锋派的人就像一个处身城内的敌人,这个城市是他决意要摧毁的,是他要反对的;因为就像任何统治制度,一种已经确立的表现形式也是一种压迫形式。先锋派的人是现存制度的反对者。 36
在此我们需要再一次表明,尽管每个时代都有其反叛者和否定者,先锋派本身在十九世纪的最后二十五年之前并不存在。先锋派的大多数杰出研究者都倾向于同意,它的出现同一个特定的阶段有着历史的联系,在此阶段,某些同社会相 “疏离” 的艺术家感到,必须瓦解并彻底推翻整个的资产阶级价值观念体系,以及它所有的关于自己具有普遍性的谎言。因而被视为审美现代性之矛头的先锋派,是一种晚近的现实,就像被认为是从文化意义上指称这种现实的先锋派这个词一样。这种特殊情形被一些人注意到,其中有罗兰 · 巴尔特,他在 1956 年发表的一篇文章(后收入他的《批评文集》)中写道:
我们的词典没有确切地告诉我们,先锋派一词首次在文化意义上使用是在何时。显然这个概念相当晚出,它是一个历史阶段的产物,在这个阶段,资产阶级在它的某些作家看来是一种美学上倒退的势力,是一种需要与之抗争的力量。对艺术家来说,非常可能的是,先锋派常常是解决一个特定历史矛盾的手段:这是本性暴露的资产阶级的矛盾,除了以一种针对自身的暴力反抗的形式,资产阶级不再能夸耀它原初的普遍性;这种反抗最初是通过针对市侩庸人的美学暴力,随后,当与资产阶级秩序抗争成为一种生活方式的应尽责任时(例如在超现实主义者中间),是通过伦理的暴力,并且越发投入;但这种反抗从来没有通过政治暴力。 37
在同一篇文章中,巴尔特还是最早谈到先锋派死亡的人之一:先锋派正在死亡,因为认为它在艺术上有意义的,正是那个它如此激烈地拒斥其价值观念的阶级。实际上,先锋派的死亡将成为二十世纪六十年代反复出现的主题之一。
## 二十世纪六十年代先锋派概念的危机
作为一个文化概念,先锋派的内在矛盾是波德莱尔在十九世纪六十年代即已预言性地觉察到的,但要等到一个世纪之后,它才成为一场较广泛理知论争的焦点。第二次世界大战后,与这场论争的出现同时发生的是,先锋派艺术出乎意料地在公众中取得广泛成功,先锋派的概念本身也相应地变成一个被广泛使用(和滥用)的广告标语。长期以来先锋派有限的声名完全是靠触犯众怒而获得的,转眼间它却变成五十年代和六十年代最重要的文化神话之一。它的唐突冒犯和出言不逊现在只是被认为有趣,它天启式的呼号则变成了惬意而无害的陈词滥调。有讽刺意味的是,先锋派发现自己在一种出乎意料的巨大成功中走向失败。这种情形促使一些艺术家和批评家不仅去质疑先锋派的历史作用,而且去质疑这一概念本身的合理性。
在前面引述过的《先锋派的困境》一文中,德国诗人汉斯 · 马格努斯 · 恩岑斯伯格指出,从这个运动自相矛盾的前提和态度中,不可能产生出任何真正新的东西。 38 先锋派死了,如同莱斯利 · 菲德勒在《先锋派文学之死》(1964)一文中所认为的,这是因为它已从一种惊世骇俗的反时尚(antifashion)变成了——在大众媒介的帮助下——一种广为流行的时尚。 39 欧文 · 豪同样认定了 “先锋派的终结”。在二十世纪六十年代,先锋派已经被周围的文化吸收。“在现代主义文化与资产阶级社会之间的战争中,” 欧文 · 豪写道,“发生了某种任何先锋派代言人都无法想见的事。慨然向敌变成了沆瀣一气,中产阶级已然发现,对于其价值观念的最猛烈攻击,可以被转化成令人欢欣的娱乐,而先锋派的作家或艺术家必须面对一种他不曾有过防备的挑战:成功的挑战。” 40
在许多作家看来,在我们这样一个文化上多元的时代,先锋派的观念可以归结为一种严重错误,这种错误源于一种 “术语中的矛盾”(contradictio in terminis)。为了表明先锋派的概念在新的历史语境中毫无意义,这个词的词源成了关注的焦点。从词源学上说,任何名副其实的先锋派(社会的、政治的或文化的)的存在及其有意义的活动,都必须满足两个基本条件:(1)其代表人物被认为或自认为超前于自身时代的可能性(没有一种进步的或至少是目标定向的历史哲学这显然是不可能的);(2)需要进行一场艰苦斗争的观念,这场斗争所针对的敌人象征着停滞的力量、过去的专制和旧的思维形式与方式,传统把它们如镣铐一般加在我们身上,阻止我们前进。
但假如没有有效的或令人信服的标准能够确定一种趋势超前于任何其他趋势呢?在《音乐、艺术与观念》(1967)一书中,利奥纳德 ·B. 迈耶就持这种观点。他说当代艺术根本上是 “反目的论的”,并用静态平衡(借助“波动稳定状态” 的概念加以证明)来描述它,如果他是对的,那么他对先锋派概念的排斥就同样是对的:“先锋派的概念意味着目标导向的运动…… 如果文艺复兴结束了,先锋派就也结束了。” 41 然而,这种毫不含糊的论断并不妨碍作者在书中自始至终运用先锋派一词,以区别极端反传统的当代表现形式和更为传统的表现形式。这是否是前后不一致?抑或这只是一种证据,表明若不考虑其词源及理论含义,先锋派仍是一个有用的术语?
对于一种从词源学上定义的先锋派,第二个必不可少的条件是存在一个当代文化敌人,但这同样受到了质疑。安杰罗 · 吉列尔米是同意大利 63 集团(Gruppo 63)有联系的批评家之一,他认为先锋派应与之战斗的对立面,亦即官方文化,已经消失,它已被现代性的[[知识相对主义]]取代。进而言之,鉴于文化先锋派概念所包含的军事联想往往会令人反感,在我们这样一个近乎无限宽容的时代,强调先锋派的好战天性(以及它的所有含义如铁的纪律、盲目服从、严格的等级结构等等)是具有破坏性的。扩展最初的军事隐喻,并进而指出今天的先锋派实际上无敌可战,这不仅是在否认其有效性,而且是在取笑它。为理解对于先锋派的这样一种描述——它从根本上说是一种向荒谬的还原(reductio ad absurdum)——想想吉列尔米在 “老的” 或“历史的”先锋派与他所说的 “实验主义” 之间所作的比较将不无启迪:
当代文化的情形类似于一个敌人埋下地雷后弃之而逃的城市的情形。兵临城下的胜利者怎么办呢?派攻击部队去征服一个已经被征服的城市吗?如果他这么做,就将造成混乱,引发新的无谓破坏和死亡。相反,他将派后卫部队的专门分队进城,他们进城时带的不是机关枪而是盖格计数器。 42
在这种比较中(吉列尔米显然想到[[马里内蒂]]的[[战争式未来主义]]),老先锋派在今天的文化氛围中可以由完全不适用的攻击部队来代表。与此相反,实验主义则作为高度专门化的后卫部队出现,它所使用的将不是喧闹、残忍且毫无必要的机关枪,而是更为和平、精良的探测装置,它们典型地属于我们这个电子时代。战士及其英雄式的自我夸耀被专家取代,面对变化了的形势,老先锋派的整个策略已颇为可笑地过时了。
今日的普遍宽容只不过是一种假象,实则是客观上缺乏赖以在各种彼此冲突的可能性中进行选择的标准,在这样的氛围中,吉列尔米自己对于老先锋派的不宽容也许显得是古怪的往日遗风。即使是这个词也令他恼火。因此,他旗帜鲜明地拒绝 “新先锋派” 这个称号,并用意识形态上中性的 “实验主义” 来代替它。然而,吉列尔米的选择没有为 63 集团的其他成员所追随,他们继续视自己为一种新先锋派的代表人物。
上述事例表明,尽管在六十年代不得不面对危机,先锋派的概念却没有瓦解。它暗地里为其内在的矛盾所保护,实际上是为它的无数困境(aporias)——现代性不可化解的二律背反的极端形式——所保护,而且颇富悖论意味的是,还为它同文化危机的观念与实践长期而近乎过分亲密的关系所保护。事实是,从一开始,艺术先锋派就是作为一种文化危机而发展起来的。
广义地看,现代性本身可以说一种 “文化危机”,如同本书第一部分所论述的。然而并不令人奇怪的是,在现代性这个较大语境中,“文化危机” 的说法特别适用于先锋派。先锋分子远不只是对某种具体的或是一般的新颖性感兴趣,他们实际上试图发现或发明危机的新形式、新面貌或新的可能性。在美学上,先锋态度意味着最直接地拒绝秩序、可理解性甚至成功(阿尔道的 “不要杰作!” 可推而广之)这类传统观念:艺术被认为是一种失败和危机的经验,这种经验是有意地实践的。如果危机并不存在,它就必须被创造出来。在这方面,存在于先锋派和 “颓废主义” 这两个表面上互相矛盾的概念间的某些相似之处不容忽视。作为一种文化危机,在我们这个变化不息的世界里,先锋派有意识地投身于推进传统形式的 “自然” 衰朽,并竭力强化和加剧现有的一切颓败与衰竭症状。在有关颓废概念的一章里,我将就这方面做更为详细的探讨。在此,只需要强调指出,先锋派的 “颓废主义” 不仅是自觉的,而且明显是反讽的和自我嘲讽的——也是欣然自我毁灭的。
从这种观点看,“先锋派之死”(一个极其贴切的表述)就不能限定在本世纪的任何一个阶段,比如第二次世界大战前或第二次世界大战后,这只是因为先锋派一直在自觉自愿地死去。如果我们承认达达的虚无主义表达了先锋派的 “原型” 特性,我们就可以说,任何真正的先锋派运动(老的或新的)都有一种最终否定自身的深刻的内在倾向。象征性地说,当再也没有什么好破坏时,先锋派迫于自己的一贯性会走向自杀。美学上的死亡迷恋癖同通常与先锋派精神相联系的其他特征并不矛盾:理知上的游戏态度,捣毁偶像,对不严肃性的膜拜,神秘化,不雅的恶作剧,故意显得愚蠢的幽默。说到底,诸如此类的特征同先锋派所一直践行的[[艺术死亡美学]](death-of-art aesthetics)非常合拍。
### 先锋派、非人化和意识形态的终结
历史地看,先锋派的萌生和发展似乎都紧密联系着现代非神圣化世界中的 “人” 的危机。早在 1925 年,奥尔特加 · 伊 · 加塞特就把 “新” 艺术或 “现代” 艺术的一个显著特征定义为非人化(dehumanization)。在他看来,这导致十九世纪 “现实主义” 的终结,而现实主义实质上是一种“人本主义”。奥尔特加写道:
在十九世纪期间,艺术家以一种相当不纯粹的方式进行创作。他们…… 使自己的作品整个存在于对人性现实的虚构之中。在这种意义上,上个世纪所有的常规艺术都必须被称为现实主义的。贝多芬和瓦格纳是现实主义的,夏多布里昂和左拉亦是如此。从我们今天的角度看,浪漫主义和自然主义趋于一致,并显露出共同的现实主义之根。 43
今天我们可以说,在二十世纪的头两个十年里,作家和艺术家的反人本主义冲动不仅是一种 “反动”(针对浪漫主义或自然主义),而且很奇怪地是一种准确的预言。立体主义者和未来主义者在作品中扭曲并且常常是取消人的形象,打破人的常规图像,使人的结构错位,他们肯定属于最早意识到“人” 已成为一个过时概念、人本主义修辞必须被抛弃的那批艺术家。然而,对 “人” 的非神话化和对人本主义的激进批评更早就开始了。
尼采是奥尔特加哲学的主要源头之一,他在十九世纪八十年代宣告了 “人” 的最终死亡和超人的出现。关于尼采把现代性等同于颓废,以及他这样做的主要意义,我们将在论述颓废的一章中讨论。在此只需要指出,在尼采的思想框架中,上帝之死和 “人” 之死是相互联系的(两个隐喻都意味着人本主义在现代性的虚无主义侵蚀下的最终瓦解)。就像上帝一样,在整个人类的道德历史中,“人”是憎恨(ressentiment)的化身,是 “奴隶们” 为颠覆生活价值观念亦,即 “主人” 的价值观念而成功地设计出来的骗局。在尼采看来,现代性尽管是由来已久的 “死亡意志” 加剧了的表现,它相对于传统人本主义却至少有一个鲜明的优势:它承认人本主义作为一种信条不再可行,并承认一旦上帝死了,“人”也得清扫历史舞台。
对于先锋派研究者更有意义的是,左派不仅批评宗教和[[宗教人本主义]],而且批评一般的[[人本主义]],把它视为一种意识形态的表现形式。社会政治先锋派思想中 “人” 的概念最早的危机征象显然出现在马克思的作品中,而且无可怀疑,在更一般的层面上,历史的非个体化(若非彻底的非人化)在相当程度上是十九世纪革命激进主义的贡献。例如,在马克思主义中,“人”常常被说成本质上是一个资产阶级概念,是资产阶级反对封建主义革命斗争的意识形态遗产。在这些斗争中,人被用作反对上帝概念的武器,整个封建价值观念体系就建立在上帝概念的基础上。然而,即使是最正统的马克思主义者也会承认,“人”只是一种抽象。历史不可能由 “人” 来创造:它是阶级斗争的产物(用恩格斯著名的技术性比喻来说,阶级斗争是推动历史进程的 “引擎”)。因此,马克思主义从根本上质疑“人” 既创造历史又超越历史的普罗米修斯式能力(这是一种源于启蒙运动并在浪漫主义的 “英雄崇拜” 中臻于极致的理知神话)。人本主义只是一种“意识形态”,由于马克思主义宣称自己是一门“科学”,人们理所当然地认为它采取的是一种反意识形态同时也是含蓄地反人本主义的立场。这种观点得到了西欧最有影响(也最时髦)的马克思主义 - 结构主义思想家路易 · 阿尔杜塞的维护,而他在巴黎知识先锋派圈子里备受尊敬也绝非偶然。
马克思是一个 “人本主义者”(如那些所谓人本主义马克思主义者根据马克思的早期著作,特别是他在《1844 年经济学和哲学手稿》中定义的“异化” 概念所认为的),抑或是一个反人本主义者(如阿尔杜塞主张的),在此无关紧要。就个人而言,我认为两种看法都有其理由;真正有趣的是,对马克思的反人本主义阐释一直要等到二十世纪六十年代才被更广泛地接受。事实上,只是在人本主义的普遍危机达到某种深度以后,马克思才被说成是反人本主义者。阿尔杜塞拒绝对马克思的 “人本主义” 阐释(及其全部险恶的 “小资产阶级” 内涵),他在《马克思主义与人本主义》(1963)一文中写道:
因此,为了理解马克思的贡献中全新的东西,我们不仅必须认识到[[历史唯物主义]]概念的新颖性,而且必须认识到这些概念所隐含和发起的理论革命的深度。以此为前提,才有可能确定人本主义的地位,拒绝它的理论谎言,而承认其作为一种意识形态的实际功能。因此,严格地限于理论上,人们能够也必须谈到马克思的理论反人本主义,并在这种理论的反人本主义中,看到获取有关人的世界本身及其实际变迁的(正面)知识的绝对(负面)前提。唯有基于一个绝对前提,即有关人的哲学(理论)神话已灰飞烟灭,才可能对人有所认知。 44
为了正确地理解这些话,我们必须搞清楚,按阿尔杜塞的看法,马克思主义仅仅是理论(哲学)上反人本主义(和反意识形态)的。 45 在实践上,作为一种革命的政治学说,马克思主义可以宣扬也确实宣扬着它自己的意识形态,而且出于策略性目的,它可以运用任何它认为合适的武器(包括人本主义,但肯定是一种新的人本主义,滤除了所有资产阶级和小资产阶级元素的人本主义)。
走出阿尔杜塞微妙、时髦却又终归是教条化的态度,我们认为,正是科学与意识形态间基本的含混性,使得马克思主义成为这样一种惊人地灵活的学说(在其最独断的正统派中,由于背弃这种灵活性,马克思主义也成为一种如此容易僵化的学说)。这种含混性可以解释马克思主义对于美学上反叛的先锋派所具有的吸引力,从达达和超现实主义一直到我们今日各种各样的新先锋派运动。它同样可以解释马克思主义在当代意识形态危机中所占据的位置。显然,下面的论述只是谈到文学艺术中新先锋派的代表人物对马克思主义的态度。在这方面,吉列尔米的例子又颇能说明问题。
吉列尔米在《先锋派与实验主义》中认为,再没有一种意识形态能就整个现实向我们作出令人信服的解释;也没有一种意识形态如今能自圆其说地解释整个世界,或是能令我们相信它可以这么干。 46 现存的意识形态还能做的,只是指导我们作为 “有着公民和社会责任的” 人如何去行动。 47 在西方,吉列尔米进而指出,即使是马克思主义最深入的影响也没有超出社会生活和行动的范围,它的教导与艺术家所面对的哲学和美学问题毫不相干。因而,他写道:“我们投左派政党的票,同时我们不仅拒绝社会主义现实主义,而且拒绝任何其特性由传统意义上的内容决定的文学,也就是,任何假定客观内容存在并因而假定一套不可更改的先定价值观念存在的文学。” 48 尽管有着这些限制,马克思主义的吸引力仍然是巨大的;吉列尔米相信,这主要是由于一个事实,即马克思主义是一个 “在其中不连贯(incoherence)显得是优点” 的思想体系。 49 对于马克思主义的不连贯性的这样一种看法(这可以很容易地还原为意识形态和反意识形态之间的 “辩证” 含混性),可以在下面这一点上予我们以启示:为什么有如此之多的新先锋派作家和艺术家或直接或间接地联系着各种新左派团体的活动,而这些团体都自称源于马克思(根据不同阐释者如列宁、托洛茨基、毛、切 · 格瓦拉等的认识)。这也可以解释为什么在新先锋派的大多数作品中(不管它们的作者怎么说),丝毫不存在政治忠诚。
然而,认为唯有马克思主义才与关于今日文化先锋派的讨论有关则是错误的。有趣的事实是,即便是那些似乎在政治上倾向于马克思主义某一变种的艺术家,也往往自觉不自觉地实践一种无政府主义式的美学。安德烈 · 雷茨勒在最近论 “巴枯宁、马克思和社会主义的美学遗产” 的文章 50 中谈到艺术中的 “无政府主义复兴”,这种说法不仅适用于那些具体表达了无政府主义信念的人,而且包括许多自认为是马克思主义者的人。由于无政府主义作为一种态度暗含着真正的危机神话(危机越深重革命就越迫近),我认为这一趋势证实了更一般地把文化先锋派等同于文化危机这种做法的有效性。
回到 “人” 的危机,近来这种危机所达到的阶段是,有关 “人之死” 的天启式观念已成为广泛使用的哲学滥调。在这方面最好的例子是米歇尔 · 福柯,他被恰如其分地称做 “人之死的哲学家”。值得注意的是,福柯即使没有直接参与法国新先锋派的活动,也与他们的活动密切相关,他至少是和他们一样,对语言理论以及更一般地对符号学理论有着强烈的兴趣。在他的主要著作《词与物》(1967)中,他运用了他称为“知识考古学” 的反历史和反实证主义的方法,在该书中他试图确定 “人”“作为他自身认识论意识” 出现的确切日期,同样也要确定 “人” 死亡的确切日期。福柯相信,“人”的实际历史非常短。他所得出的最为人知的一个结论是,对西方世界来说“人是一种新近的发明”(始于十八世纪末),而且这种发明似乎已经过时。 51
另一位法国哲学家同样属于时髦的知识先锋派,在他看来,人只是 “一部欲望机器”。我指的是吉尔 · 德勒兹,特别指的是他最近的著作《反俄狄浦斯》(与菲力克斯 · 瓜塔里合著)。 52 上面提及的机械联想(人是机器)绝非偶然。该书旨在对正统精神分析学的无意识观作激进批评,弗洛伊德使无意识观服从于他对人类心灵的 “表现性构想”(expressive conception)。但无意识并不是——《反俄狄浦斯》的作者认为——人类 - 神话角色彼此相对的古希腊悲剧的重演。弗洛伊德的“表现性” 方法及其所有的戏剧联想都应被抛弃,并代之以一种非拟人性的 “生产理论”:无意识像一个工业单位般运作,它是一间欲望工厂。弗洛伊德的理论通过马克思得到根本修正,马克思的生产理论被认为包含了对无意识进行功能性描述所必需的一切关键概念。然而,作者的立场与其说是马克思主义的不如说是无政府主义的。有趣的是,他们对技术意象和技术概念的广泛使用——这同某些现代无政府主义分支所宣扬的技术神话非常合拍——倾向于证实雷纳托 · 波吉奥里有关先锋派与“技术主义” 关系的一般论述。“先锋派思想家或艺术家,”波吉奥里在《先锋派理论》中写道,“是…… 特别容易受科学神话影响的。” 53 然而,必须强调,对先锋派来说重要的并不是科学本身,而仅仅是有关它的神话。先锋派培植了科学主义(scientifsm),这是因为它具有反艺术和反人本主义的隐喻潜力。这种科学主义在哲学上和美学上都适应了非人化的策略;不仅如此,它还明确拒绝构成浪漫主义哲学与文学理论遗产的任何一种有机或生物学假定(被视为活的生物的世界,对应于一种自然生命力的天才,被视为有机生长过程的创造,等等)。
普遍的意识形态危机以及具体的人本主义危机所造成的后果之一,是一种相当普遍化的价值论相对主义。即使是在文学批评中,价值判断也日益被认为无关紧要。[[结构主义]]的方法公开反对任何对价值的关注。但在这方面结构主义者并不孤立。某些左倾的批评家(为一种无政府主义的本能所推动)找到道德上的理由,以拒绝维持一种文学与美学价值的等级观念,在他们看来这乃是精英主义的兴趣所在。这种平等主义的反等级冲动也许最好地体现在莱斯利 · 菲德勒的近期批评中。菲德勒是后现代主义的先知之一,他倡导一种相当有趣的观念,即批评应该变得波普些。菲德勒所具有的也许是一种新改宗的热情,他的态度却相当说明问题,尤其是他写到他日渐感兴趣于 “那种没有人会为能读到它们而自我庆幸的书”(亦即西部传奇,廉价畅销书,色情小说,以及其他类型代表当代通俗文学的书)。菲德勒还明确区分了“精英主义放逐” 和“畅销”,在前一种情况下作者只拥有一小群读者,后者则是借助波普艺术与较广泛读者交流的一种形式(他似乎丝毫没有考虑一个事实,即畅销书与其说是由读者大众选择的,不如说是由出版商通过对趣味的商业性操纵而强加给他们的)。令人奇怪的是,在他对波普艺术(往往无法同纯粹的媚俗艺术区别开来)的新热情中,菲德勒相信自己是一个激进派,甚至是一个无政府主义者:“我在这些文章中所采取的批评立场暗含着一种政治态度,这是一种平民主义甚至是无政府主义的姿态,它基于对依照社会阶级结构创造出来的所有区分的无法忍受。” 54
意识形态的危机反映在另一种非常有意义的现象中,这种现象构成大量先锋派(既有老的也有新的)艺术的特征,用 L.B. 迈耶的说法,这就是它的 “反目的论” 冲动。在《音乐、艺术与观念》中,迈耶写道:“先锋派的音乐不会把我们引向高潮——没有确立我们向之移动的目标。也许除了预期它将终止外,它没有唤起任何期待…… 这种没有方向的、无运动的艺术,无论是深思熟虑还是偶然为之的,我都将称它们为反目的论的艺术。” 55 这个问题将在后面做更详细的论述。
## 先锋派与后现代主义
近来美国批评界运用的一种术语区分使人想起欧洲大陆上对先锋派和新先锋派的区分,但它的意义和后果较后者更为深刻也更为混乱,导致这种区分的是现代传统中一种急剧断裂的感觉。我指的是现代主义和后现代主义的区分。当我们认识到就文学批评而言,“[[后现代主义]]” 不仅是一个略带贬义的分类标签(就像在二十世纪三十年代,费德里柯 · 德 · 奥尼斯在西班牙语文学中把后现代主义说成一种衰竭的、温和保守的现代主义) 56 ,而且是一个既有敌人也有拥护者的极富争议的概念时,整个事情就变得特别奇怪。对它的信徒而言,后现代主义的概念显然涉及一整套全然不同的哲学、政治和美学纲领。人们曾以其他术语来指称现今被称做后现代主义的东西(我们可以想到弗兰克 · 克莫德在 “早期现代主义” 和“新现代主义”之间不太恰当的区分),然而与 “后现代” 时代这个更广义概念相联系的后现代主义似乎很容易就占得上风。
在历史学语言中,前缀 “后” 是一个普通的术语工具,它绝大多数时候是一种中立而方便的手段,即通过提及在某些事件之前的一个重要时期,从而确定它们在时间进程中的位置。根据某一具体现象发生在另一现象之后来描述它,绝不意味着它就不重要。前缀 “后” 只是表明缺乏正面的分期标准,而在那些过渡时期,缺乏正面标准是很普遍的事。进而言之,由于历史时期是等级性的建构,它们不可能完全免于评价上的偏见,这一点在文化历史中尤为真实。因此,从文化现代性的角度看,我们有时会感到有理由重视前兆性的趋势,而相反地忽视间歇时期,描述这些间歇时期的方法只能是说它们出现在某些关键性的文化变化之后。例如,形容词 “前浪漫派” 不仅突出了一些十八世纪后期的诗人,而且通过把他们变成伟大的浪漫派革命的前驱,将他们的努力放在了一个有利的历史视野中;相反,形容词 “后浪漫派” 可以用于指称浪漫主义的后继者,或者不那么富有轻蔑意味地,用于指称那些试图摆脱浪漫派影响而又未能彻底动摇它的作家,这些作家实际上取得了一种新的文学身份。
形容词 “后现代”(post-Modern)显然是由历史学家——先知阿诺德 · 汤因比在二十世纪五十年代早期创造的。汤因比认为在十九世纪的最后二十五年,西方文明已进入一个过渡阶段。这种过渡——过渡到什么他没有说——在他看来更像是一种 “突变”(mutation)和一种对西方历史上现代时期的根本脱离,在他《历史研究》的后面几卷(8-13,1954 年开始发表)中,他选择把这个充斥着社会动荡、世界战争和革命的时期称为 “后现代时期”。汤因比区分了西方现代文明的四个时期:早期现代(早期文艺复兴),现代(文艺复兴及其后),晚期现代(这一时期在十七与十八世纪之交以保罗 · 哈泽德所说的 “欧洲意识的危机” 58 开始,经过启蒙运动而延伸至十九世纪),以及最终的后现代(这个时期 “开始于十九世纪的七八十年代”)。 59
大体而言,西方文明的后现代阶段——如我们看到的,它的存在已有一个世纪之久——可以被描述成一个无政府的时期。《历史研究》的作者在谈到得之于希腊哲学家的西方理性主义世界观的瓦解时,恰恰使用了这个词。作为文艺复兴重新发现古代的结果,对自觉心智(concious mind)的信念在整个西方文明的现代时期得到加强,这种信念在晚期现代时期遇到严重的挑战,而且在十九世纪五十年代以后这种挑战更为强烈。比如说,在知识史的广泛范围内,我们可以从一系列新科学,诸如心理学、人类学、政治经济学、社会学的迅速发展中看到这种挑战,汤因比认为这些新科学典型地是 “后现代的”。“在心理学领域,” 他写道,“后现代的西方科学心智已通过观察证实了帕斯卡尔的直觉,即‘心灵有其因由,对于它们理性一无所知’。在基督纪元的二十世纪,一种后基督教的西方心理学科学开始探索人类心灵的潜意识深渊,致力于发现统治着潜意识的‘自然法则’,这不是逻辑的法则,而是诗歌与神话的法则。” 60 在汤因比看来,这种发现可以解释 “知识上无政府的晚期现代和后现代时期” 彻底的相对主义。 61
就社会方面说,现代西方文明在汤因比看来是中产阶级或资产阶级时代:“……‘西方现代文明’中的‘现代’一词,可以转译为‘中产阶级’,从而使它具有更确切更具体的含义;这样做不会造成误差。一旦成功地生产出在数量和能力上都足以担当社会支配阶级的资产阶级,西方社会就成为‘现代的’(在这个词公认的现代西方意义上)。我们认为在十五、十六世纪之交翻开的西方历史新篇章是极其现代的,因为在接下来的四个多世纪里,直到十九与二十世纪之交‘后现代时期’的开始,中产阶级在整个西方世界那些较为主要和突出的部分里一直执掌权柄。” 62 后现代时期的 “标志是一个都市产业工人阶级的崛起” 63 ,以及更一般地,是一个 “大众社会” 及与之相应的 “大众教育” 和“大众文化”体系的出现。西方历史的当今篇章显然是一个“麻烦时期”,在这个时期所有解体与垮台的征兆都出现了,尽管仍然存在种种希望,使人相信西方文明的最终瓦解也许可以避免。
汤因比更多地是被描述成一个先知而不是历史学家,这种描述完全适用于他有关 “后现代时期” 的构想。尽管这个相当引人注目的词在《历史研究》的最后几卷中频频出现,但它从没有成为系统定义或系统分析的对象。就书中的情况而论,“后现代”是一个模糊的、准天启式的概念,它指的是那些晦暗不明的恶魔般力量,如果完全放纵这些力量,它们将推翻现代西方文明的结构。在汤因比的先知式语言中,“后现代”意味着非理性、无政府和危险的不确定性;而且从该词被应用于其中的各种语境看,有一点确凿无疑,这就是,“后现代”有着极强的消极(尽管不一定是贬损性的)内涵。尽管汤因比批评了斯宾格勒,他却常常被拿来同这位写了《西方的没落》的哲学家相比,有一点证明这种比较是合理的:在前者的 “后现代时代” 概念和后者应用于当代西方文化的 “没落”(Untergang)概念之间,存在着明显的类似。然而,这并不意味着“后现代” 就应被当作 “颓废” 的另一种表达,即使是在汤因比的用法中也不应作如是观。
汤因比的这一悲观主义标签在历史学家中取得的成功不如在文学批评家中取得的成功大。到二十世纪五十年代,如同我们在前文中已经看到的,无论是 “现代” 还是 “现代主义”,在批评语言中都已获得一种鲜明的历史——分类学意义,以至于可以把“现代” 同“当代”对举。形容词 “后现代” 以及随后出现的名词 “后现代主义”,似乎以恰如其分的模糊性传达出第二次世界大战后人们所经验到的新的危机感。一种感觉在年轻的世代中不断滋长,那就是:现代主义文学(艾略特、庞德、卡夫卡、曼等等)在已发生激剧变化的社会与知识情境中不再有意义。“后现代主义” 的最初运用在很大程度上是试探性的,而且稍稍带有为消费社会中的文化命运担忧的悲观主义色彩(在消费社会中旧有的知识标准似乎受到威胁),但它很快就成为一个几乎是备享荣宠的词。有意思的是,“后现代主义”被作为一个新的乐观主义的战斗口号来接受,这种新乐观主义是平民主义的也是天启式的,是感伤的也是不负责任的,它也许被最好地概括在 “对抗文化” 这个概念中。“后”这个显然无害的前缀本身在语义上被去中性化(deneutralized)了,在修辞上它被用来传达一种秘密的振奋感。魔术般地,这个前缀似乎消除了旧有的限制与偏见,让想象力自由地面对新的、不确定的、然而极度激动人心的经验。最近在重读莱斯利 · 菲德勒的《新突变体》(1965)一文时,我决定把所有以 “后” 这个前缀开头的词划出来,这样做不仅可以使我们对十年前代表青年一代的 “神话学少数”(mythological minority)有一个切近的观念,而且可以使我们对“后” 的准魔术式使用有一个切近的观念。“新突变体”世界的特征是:“后现代主义的”,“后弗洛伊德的”,“后人本主义的”,“后新教的”,“后男性的”,“后白人的”,“后英雄的”,“后犹太教的”,“后性的”,“后清教的”。 64 放在它们的语境中来读,所有这些词都有着强烈的赞同性内涵。
欧文 · 豪属于最早使用 “后现代” 这个形容词的批评家之列,他的[[《大众社会与后现代小说》]]一文发表在《党人评论》上。 65 按豪的看法,从现代主义到后现代主义的过渡乃 “大众社会” 出现的原因;在大众社会里,阶级区分比以往任何时候都要模糊,“像家庭这样的传统权威中心开始失去某些约束人行为的力量,在这个社会里,被动成为一般的社会态度,人被变成了消费者,他自己就像他所接受的产品、娱乐和价值观念一样被大量生产”。 66 我想说在这篇文章中欧文 · 豪对后现代主义不无同情。更晚近,在《纽约知识分子》这样一篇文章中,他的态度有了激剧变化:
我们面临着我们文化中的一个新阶段,就其动机和源泉来说,这个阶段代表着摆脱现代主义可恶遗产的愿望…… 新的感受力受不了观念。它受不了复杂而有条理的文学结构,而这些就在昨天还是批评界的口头禅。相反它需要的是像太阳一样绝对、像性高潮一样无可辩驳、像棒棒糖一样可口的文学——尽管文学也许是一个不恰当的词…… 左派作家的伦理焦虑不合它的口味,这些左派作家历经挫败,再也不能接受确定性的麻醉。它厌恶曼给予我们的那些反讽的放大复制品,厌恶卡夫卡引领我们走入的那些陷阱的幻象,厌恶乔伊斯留给我们的那些日常的恐惧与恩典。它流露出对理性的轻蔑,对心智的不耐烦…… 它烦透了过去:因为过去可笑之极。 68
看起来欧文 · 豪最憎恨的是后现代主义对公众喝彩的兴趣。现代主义是一种 “少数派文化”,它通过同一种“支配性文化” 相对抗来定义自己。但“新的感受力从一开始就是一次成功。渴望激动和羞辱的中产阶级公众欢迎它:大众媒体也是如此…… 自然也就出现了带着轻便理论的知识分子”。 69
哈里 · 列文从汤因比那里借用了 “后现代” 这个形容词,他同样在现代与后现代之间作出区分。因此,在一条介绍其文章《何为现代主义?》(1960)的按语中,他写道:
由于我们仍然是现代人,我要说,我们是人文主义和启蒙运动的孩子。在某种意义上,识别并隔离非理性力量乃理知的胜利。在另一种意义上,它也加强了那种反理知的潜流,当这种潜流浮出水面时,我愿称它为后现代的。 70
我们注意到,对哈里 · 列文来说——对欧文 · 豪也是如此——“现代”和 “后现代” 远不仅仅是用于分类的中性的历史或文化标签,它们暗含价值判断(同样也暗含价值偏见)。因此,在哈里 · 列文使用它的语境中,“后现代”传达出一种明显而强烈的不赞同感;如果放在列文的整体批评观念中加以审视,这种不赞同感将变得更为强烈和明显。列文最近的文章《个人回顾》是打算用作《比较的基础》(1972)一书导论的,在此文中,他把自己归入(略带一丝反讽地)“顽固守旧的老人文主义自由派”,这些人的地位已受到当代反理知的启示论的威胁。“如果我们正面对一种天启,”列文写道,“那我们也许需要像乔治 · 斯坦纳这样的天启式批评家,而不是像特里林教授和我自己这样顽固守旧的老人文主义自由派。” 71
对另外一些批评家来说,现代主义之死是令人愉快的消息,他们是在一种完全积极的意义上使用 “后现代” 和“后现代主义”的。现代主义是高雅、傲慢和玄奥的,没有必要哀悼它的死亡。唯一的麻烦在于,现代主义是以一种毫不招摇的贵族方式死去的,并不是人人都能意识到它确实死了。因而有必要宣布它的死亡。菲德勒在 1970 年写道:
我们正在经历现代主义垂死的苦痛和后现代主义出生的阵痛,这两种痛苦我们已经历了二十年——而且自 1955 年起已确知这一事实。僭取现代之名的文学(它还假定自己代表着感受力与形式的最终进步,假定在它之外无所谓新),它的胜利阶段从临近第一次世界大战的时候持续至第二次世界大战刚刚结束的时候,它死了,也就是说,属于历史而非现实。 72
新时代与现代主义文学所体现的那种自觉的 “分析、理性、反浪漫式辩证” 的精神截然相反,它是“天启式的,反理性的,极其浪漫和感伤的;是一个献身于快乐的知识嫌弃(misology)和预言式不负责任的时代;是一个完全不信任保护性反讽和过分伟大的自我意识的时代”。 73
后现代人同现代人的比较已成为持续了一个世纪之久的 “古今之争” 的最新形式。伊哈布 · 哈桑为我们提供了一个有趣的例子,他在[[《后现代主义:超批评书目》]](POSTmodernISM:A Paracritical Bibliography)一文中涉及到这个主题,这篇文章最初于 1971 年发表在《新文学史》 74 上,后收入《超批评》(Paracriticism,1975)。在文章中哈桑对现代主义和后现代主义进行了全面的比较,这种比较虽然没有具体涉及价值问题,却倾向于表明,在各方面都与现代主义不同的后现代主义绝对是一个同样有意义的文化现象。这种比较值得详细探讨。
哈桑的现代主义概念同众多当代英美批评家的现代主义概念相差无几。它包括大陆意义上的 “历史” 先锋派(亦即[[未来主义]]、[[达达主义]]、[[构成主义]]、[[超现实主义]]等等),但其含义又远较此广泛,实际上包括了二十世纪上半期西方文化史上稍具重要性的所有运动和几乎所有个人。这种极端宽泛的理解突出了一个事实,即多数从事二十世纪文学批评的美国批评家实际上都没有在现代主义和先锋派之间作任何区分。这两个术语隐含地,有时也是公开地,被当作同义词。下面是晚近诸多可供选择的事例之一。它节选自一篇评论波吉奥里《先锋派理论》的文章,发表在《边界 2》上。作者罗伯特 · 朗鲍姆写道:“因为标题中的‘先锋派’应理解为‘现代主义’。哈佛已故的波吉奥里教授用先锋派来意指我们多数人用现代主义所意指的东西,实际上写出了也许是最好的论述现代主义的著作。” 75 对于一个熟知先锋派一词的大陆用法的批评家来说,这种等同是令人诧异的,甚至是令人困惑的。在法国、西班牙和其他欧洲国家,尽管先锋派有着各种各样且常常是互相矛盾的诉求,都倾向于被认为是艺术否定主义的最极端形式——艺术本身成为首当其冲的受害者。至于现代主义,不管它在不同的语言中以及对不同的作者来说有何具体意义,都从未传达出如此典型地属于先锋派的那种普遍的、歇斯底里式的否定感。现代主义的反传统主义往往很微妙地是传统式的,这就是为什么从一个欧洲人的角度看,难以想象普鲁斯特、[[乔伊斯]]、[[卡夫卡]]、托马斯 · 曼、T.S. 艾略特或埃兹拉 · 庞德这样的作家会是先锋派的代表人物。这些作家同未来主义、达达主义或超现实主义这类典型的先锋派运动实际上几乎没有共同之处。因此,如果我们要前后一致地运用现代主义的概念(并把它用于上面提到的那些作家),就必须区分现代主义和先锋派(老的和新的)。的确,被定义为一种 “反对自身的传统” 的现代性使先锋派成为可能,但同样真确的是,先锋派的否定激进主义和全面的反传统主义并没有为艺术地重建世界留下任何余地,而这正是伟大的现代主义者们试图去做的。
为了更好地理解现代主义和先锋派之间的奇特关系(一种既依赖又排斥的关系),我们可以把先锋派看做一种有意而自觉的 “现代性的戏拟”(parody of modernity)。戏拟的地位比人们所能猜度的要模糊得多。在表面上,戏拟往往旨在通过夸张而对隐藏于原作中的缺陷或不足作出严厉批评,而它正是从这个原作中获得灵感的。然而,在较深入的层次上,戏拟者可以私底下推崇他打算去嘲弄的作品。就一位作家可能会有的戏拟者而言,他必须在一定程度上赞赏这位作家。谁会去戏拟他认为完全无意义或无价值的东西呢?进而言之,一件成功的戏拟之作以及它对原作的批评,在字面上和在精神实质上,都应该与原作有一定程度的相似,都应在一定程度上忠实于原作。理想地说,一件戏拟之作既要显得是戏拟之作,同时又要有被人误认为原作的可能。先锋派一旦被视为对现代性的戏拟,它就表露出所有这些模糊性;尽管它往往是毛糙而粗略的(多数戏拟之作都是这样),有时它却是如此接近其范本,以致会与之混淆。
回到哈桑的立场上,有趣之处在于,它概括性地体现的那种态度典型地属于英美批评的一条晚近发展路线(这条路线显示出对新批评的反动,以及更一般的对形式主义的反动)。在哈桑那里,后现代主义远不只是一个新的批评标签:与形式主义者对超然和客观性的要求相反,它传达了一种介入感,同时也传达出从传统(包括现代主义的自我批评传统)中获得解放的感觉;于是就有了他对于 “超批评” 的发现,有了在他整个文章中都可以感觉到的某种游戏特性。哈桑对现代主义和后现代主义的比较算不上系统,他是通过把这两个文化时期分成一系列类目来进行的,这些类目为多数研究文学艺术现代性的杰出学者(从奥尔特加到波吉奥里)一致认可:都市主义,技术主义,“非人化”,原始主义,反律法主义,以及实验主义。哈桑指明了每一个术语所同时包含的现代主义和后现代主义成分。
例如,在后现代主义中,都市主义典型地见于下述特性,哈桑故意将它们用电报的方式罗列出来:
城市和 “全球村”(麦克卢汉)和 “太空船地球”(富勒)。作为宇宙的城市。——同时,世界分裂成无数集团、民族、部落、宗族、政党、语言、派系。到处是无政府和分裂……——在生态行动主义中部分得到恢复的自然,绿色革命,都市复兴,等等。——同时,狄奥尼索斯进入了城市:监狱暴动,都市犯罪,色情作品,等等。
至于技术主义,哈桑强调了 “失控的技术,从基因工程、控制思想到征服太空”,他由此说到艺术正在 “追随再生加速化的趋势”,使读者面对两难之境:“计算机是作为意识的替代物呢还是作为意识的灭绝?”
让我们就哈桑作比较的方式举最后一个例子。关于非人化,奥尔特加的有力观点在一种新的历史语境中得到发展:老的非人化主要是按[[精英主义]]的思路展开的,而后现代主义的典型特征是一种深刻的 “[[反精英主义]],[[反权威主义]]。自我的扩散。参与。艺术成为公有的,可选择的,免费的,或无政府的。——反讽成为激进的、自我消耗的游戏。黑的画布或黑的书页。静默。还有荒诞喜剧,黑色幽默,疯狂戏拟”。
哈桑的结论是,现代主义 “创造了它自身形式的权威”,而后现代主义 “趋向于无政府,与分崩离析的事物深通款曲”。
我大量引用这篇文章,不仅是为了指出它所包含的某些有趣观点或主张,而且是为了表明使用过分宽泛的概念所隐含的危险。就先锋派一词在大陆上的公认意义来说,我们可以认为,哈桑所说的后现代主义很大程度上是第二次世界大战后的先锋派的延伸和多样化。历史地讲,哈桑所确定的许多后现代主义基本特征可以很容易地追溯到达达派,而且往往可以追溯到超现实主义。因此,反精英主义,反权威主义,无偿性,无政府,最后还有虚无主义,显然都包含在达达派 “为反艺术而反艺术”(特里斯坦 · 查拉的表述)的信条中。至于觅得物(found object)和签名的汤罐头盒,它们显然是马赛尔 · 杜尚和曼 · 雷的“现成品”(ready-mades)的延续——有些模仿的味道,而我想是有意如此。偶然的观念同样是达达派的一大发现,它不仅被达达主义者加以理论化和应用,而且被超现实主义者在他们的“自动写作” 和“超现实主义物体”的学说中加以理论化和运用。
哈桑通过把当代文化中的新达达主义或新超现实主义趋势同那些杰出现代主义者(如 T.S. 艾略特)公开的精英主义或纯粹主义主张相对比,或者通过把在后现代主义中如此盛行的左派激进主义同叶芝、劳伦斯、庞德或艾略特等的 “隐秘法西斯主义” 态度(这些人被认为代表了现代主义的这一方面)相对比,不止一次地找出这种似是而非的相似关系。但其他那些常常被作为现代主义范例的作家又如何呢?卡夫卡、普鲁斯特、纪德、托马斯 · 曼、赫尔曼 · 布罗赫、马尔罗和许许多多其他人又如何呢?哈桑的概括过于草率。而且,他似乎忘记了他的现代主义概念包括大陆意义上的先锋派,忘记了先锋派整体上是反精英主义并对各种形式的左派(共产主义、托洛茨基主义、无政府主义等等)有着强烈吸引力的——除了在意大利未来主义者中有一些显著的例外。
当然,精英的概念隐含于先锋派的概念之中,但正如我们前面已经看到的,这种精英是致力于摧毁所有精英的,包括摧毁它自己。所有先锋派的真正代表人物都非常严肃地抱有这种观念。这就涉及到对存在于生活各方面的等级原则的断然拒绝,而且很显然首先要拒绝的是艺术方面的等级原则。就此而言,超现实主义者声称他们没有天才——以及他们认为天才实际上是对手或者好心却幼稚的支持者能够扔给他们的最严重侮辱的看法——是与整个先锋派的精神相一致的。有一种观点认为,因为后现代主义是流行的——具体到作家来说,因为他们不再以 “畅销” 为耻——所以它是反精英主义的;这种观点完全是似是而非的。在我们的时代,成为流行就是为市场而创作,就是回应市场的需求,包括急切且相当容易辨识的对 “颠覆” 的需求。流行如果不等于接受“体制”,也等于是接受它的直接表现形式,即市场。屈服于市场力量的结果,既不是精英主义的也不是反精英主义的(两个概念都被用滥了,以至于失去了内容)。至于那些真正代表后现代主义精神的伟大艺术家,如贝克特或者甚至是品钦,他们决不比现代主义者或先锋派中那些最深奥的人更“流行”,也决不比他们更容易为一般大众接受。
## 理知主义、无政府主义和静态平衡
同老的先锋派相比,新的后现代主义先锋派在它的一条主要支流中,似乎更系统地涉及到理论思考。这种高度理知化的新先锋派在大陆欧洲最为活跃。前 63 集团的成员(爱德瓦尔多 · 圣圭内蒂,翁贝托 · 艾柯,纳尼 · 巴莱斯特里尼等);集结在 “新小说” 旗号下的法国小说家(罗伯——格里耶,克洛德 · 西蒙,罗贝尔 · 潘热等);党派团体“泰凯尔”,其成员是革命观念的狂热拥护者,把马基 · 德 · 萨德和马克思、马拉美和列宁、洛特雷阿蒙和毛毫无龃牾地结合在一起(菲利普 · 索列尔,朱莉娅 · 克里斯蒂娃,马塞兰 · 普莱内等);由科学主义者马克斯 · 本泽领导的斯图加特具体诗人团体——这些人属于这种新先锋派最著名和最有影响的代表人物。
在英国和美国,使一种更自发实际上也更无政府主义的趋势开始宣告自身存在的,是五十年代的垮掉派运动(杰克 · 凯鲁亚克,艾伦 · 金斯堡等)、利物浦波普诗歌群体(阿德里安 · 亨利,罗杰 · 麦戈,布赖恩 · 帕滕)、如今已经销声匿迹的 “活戏剧”(朱利安 · 贝克,朱迪丝 · 马利娜),以及音乐上的约翰 · 凯奇。但是,正如同约翰 · 凯奇的情况所清楚地表明的,没有高度的修养和对理论问题的意识,构成美学无政府主义典型特征的破坏性技巧——借助偶然或其他——是行不通的。凯奇在其著作《静默》 76 中说,要 “发现能让声音成为其自身而非人造理论的载体或人类情感的表现形式的手段”,这种尝试也许仅仅对鉴赏家或附庸风雅者有意义,而不会对街头百姓有意义。街头百姓很可能是媚俗艺术的忠实消费者,而不会关心剥离了人类意义的纯声音。这同样适用于有关图像的“感觉直接性” 的思考,在苏珊 · 桑塔格的《反对阐释》中,它被提高到美学准则的地位。 77 这些理论最终非常接近法国 “[[新批评]]” 的代表人物(他们中的一些人同泰凯尔有联系)所主张的文字性(littéralité)理论,这并非偶然。因此,按热拉尔 · 热奈特的说法,现代诗歌倾向于压缩文字和意义之间的任何距离,并消除旧有的意义对文本的超越。热奈特写道,今天,“语言的文字性似乎就是诗歌存在的本身,对于拥护这种看法的人来说,最令人不安的观点是,认为存在转译的可能,认为存在某种把文字同意义隔离开来的空间”。 78
在我们所说的理知主义新先锋派和无政府主义趋势之间尽管有明显的分歧,但长期而言,它们有着本质的相似性。使新先锋派艺术两个主要方面统一起来的原则,是它们共同的反目的论冲动。如利奥纳德 · 迈耶正确地指出的,当代艺术所涉及到的是 “一些迥然不同的目标,无论这些目标是通过精心计算而达到的(像在斯托克豪森的音乐、托比或罗斯科的绘画、贝克特或格里耶的作品中那样),还是通过随意的操作而达到的(像在凯奇的音乐、马迪厄的绘画或偶然派剧作家麦克洛的《结婚的处女》中那样)。这种新美学的基础是一种有关人和宇宙的观念,这种观念同自西方思想诞生以来就一直支配着它的那种观点几近相反”。 79
正如新先锋派的公共境遇所表明的,我们时代的一大特征是,我们已开始习惯于变化。即使是比较极端的艺术实验似乎也不能唤起人们的兴趣或激动。不可预测的东西成了可预测的。一般而言,日益加快的变化步伐倾向于降低任何一次特定变化的意义。新的东西不再是新的。如果说现代性主宰了一种 “惊奇美学”(aesthetics of surprise)的形成,现在似乎是它彻底失败的阶段。今天至为多样的艺术品(从高深莫测之作一直到纯粹的媚俗作品)在“文化超市” 里比邻而居,等待各自的消费者(富有讽刺意味的是,“文化超市”的概念同马尔罗 “想象的博物馆” 的概念有些相似)。各种互相排斥的美学僵持不下,没有一种能够在实际上扮演领导角色。大多数当代艺术的分析家都同意,我们的世界是一个多元的世界,在这个世界中任何事情在原则上都是许可的。老的先锋派是富有破坏性的,但它有时也欺骗自己,让自己相信实际上有新的道路可以去开拓,有新的现实可以去发现,有新的前景可以去探索。但今天,当 “历史先锋派” 是如此成功,以致它变成了艺术的 “恒久状况” 时,无论是破坏的修辞还是新颖性的修辞都已彻底失去了英雄式魅力。我们可以说,新的后现代主义先锋派在其自身的层次上反映了我们心灵世界日益 “模块化” 的结构,在这样的心灵世界中,意识形态的危机(表现在微型意识形态奇怪地、像癌细胞似的增生,而现代性的宏大意识形态丧失了它们的连贯性)使得越来越难以建立令人信服的价值等级系统。
在利奥纳德 · 迈耶的《音乐、艺术和观念》中(题为 “历史、静态平衡与变化” 的一章),艺术的这种境遇已得到敏锐的描述。作者认为,历史是“等级性的建构”,分期——“不仅仅是划分过去的一种便利方式”——是历史等级化特征的必然结果,“历史如果不是被等级性地表述成执政期、时代、风格期、运动等等的话”,它就是不可理解的。
然而就我们的时代而言,这样一种看法是不恰当的。迈耶相信,今天艺术的典型特征是一种 “波动稳定状态”。变化无处不在,但从文化上说,我们是生活在一个完全静止的世界中。矛盾非常明显,因为静态平衡 “并非缺少新颖性或变化——彻底的死寂——而是缺少经过有序编排的系列变化。就像在布朗运动中随意四处冲撞的分子,一种充斥着活动和变化的文化绝对不可能是静止的”。 80
在我看来,这种静态平衡是现代时间概念所包含的那些不可化解矛盾的一个结果。这些矛盾被先锋派有意识地夸大了,它极力将每一种艺术形式推向最深层的危机。在此过程中,现代性和先锋派都显示出一种特殊的危机想象力;它们联合起来成功地创造出一种复杂的对危机的感受力,这种感受力常常是反讽和自我嘲讽的,它似乎既是它们的最终成就也是它们的报应。
结果是,旧和新、建设和破坏、美和丑在经过相对化之后,都变成了近乎无意义的范畴。艺术和反艺术合而为一(后者不仅用在达达主义的论战意义上,还用于指称种类惊人的媚俗艺术品)。危机似乎已成为任何有意义艺术活动的重要标准,而静态平衡正是这种危机最容易为人觉察的方面。
## 颓废的概念
全面地看,终结的世纪不会是最完善的世纪,甚至也不是最复杂的世纪,但它是最匆促的世纪;在这个世纪里,文明的存在(Being)在运动中瓦解,在一种趋向最糟糕境地的极度冲动中,文明将在它所激起的旋风中化为碎片。既然没有什么能阻止它掉入深渊,那就让我们抛开对它的道德讥评,让我们就在令它欢欣的无度中,去努力发现某些令人兴奋的东西,发现某些企求我们节制自己的义愤并重新思考我们的鄙薄的东西吧。以这样的方式,如果我们想想令它们疯狂的种种无意识动机和深层原由,这些幽灵,这些机器人,这些僵尸,就不那么可憎了:难道它们没有感觉到给予它们的间隙正在一天天缩短,结局正在形成吗?难道不正是为了摒斥结局的概念它们才沉迷于速度之中吗?…… 有着如此的匆忙,有着如此的不耐烦,我们的机器是结果而不是起因。并不是机器驱使文明的人走向末日;而是文明的人发明了机器,因为他早就走上了通向末日的路;他寻找手段和辅助工具以更快、更有效地到达那儿。不满足于跑,他宁愿驱车趋赴毁灭。在此意义上,也仅仅在此意义上,我们可以说,文明人的机器能让他 “节约时间”。
E. M. 齐奥朗,《堕入时间》(1964)
(理查德 · 霍华德法译英)
关于颓废的各种说法
拉丁语名词 “颓废”(decadentia)是现代欧洲语言中一些相关词语的源头(英语中是“decadence”,法语中是“décadence”,意大利语中是“decadenzia”,德语中是“Dekadenz”,等等),如果说该词在中世纪之前并不为人所用,颓废的概念则肯定要古老得多,也许它就像人本身一样古老。几乎所有的古代民族都熟悉这种或那种形式的颓废神话。时间的破坏性和没落的宿命是所有神话——宗教传统都拥有的重要母题,从印度的“卡莉时代” 到犹太先知所散布的关于腐败和罪恶的恐怖说法,从古希腊罗马人对 “黑铁时代” 的幻灭信仰到基督徒的即将生活在一个由绝对恶统治(反基督统治)的邪恶世界中的感觉——如《启示录》所宣称的。
“早先时代的人,” 柏拉图认为,“比我们更好,也比我们更接近神。”(《菲雷波斯篇》,第十六章) 1 这仅仅是一个例子,它表明现时的人,即使是在一个被后人视为光荣与典范的时代,是如何认为他们的时代不如早先更有福的时代的。古希腊人在相当程度上受到 “过去的掌握” 2 ,而且在这方面,它同任何在现代性与进步概念携手控制西方心智之前兴盛的文明没有实质性区别。我们都知道 “黄金时代”(相对于“黑铁时代”)的神话在古希腊以及随后在古罗马是何等盛行,但在显而易见的诗歌——历史猜想领域之外,我们很少意识到颓废概念在古典形而上学中的表现。在这种情况下,很容易把柏拉图看成是第一位建立起一整套复杂的颓废概念本体论的伟大西方哲学家。因为在柏拉图的理念论中,区分了所有事物原型的、完美的、不变的和真实的范本,以及它们在由知觉对象构成的可感知世界中的纯粹“阴影”——在可感世界中一切都受到时间和变化的腐蚀;在对二者关系的描述中,显然暗含了一种形而上学的颓废(或衰退)概念。与我们对历史性颓废的关注更切近的是,柏拉图的历史和社会观概括了古希腊人的普遍信念,即认为时间无非是一个持续的没落过程。“与柏拉图一样,” 法国宗教史家亨利——夏尔 · 皮埃什写道:
希腊人猜测国家或社会形式的范本或理想图式,从中他们推导出一种适用于任何事件的必然的时间顺序。由此产生的法则是 “颓废而非发展的法则”(埃米尔 · 布雷耶):它们把变化看成是从一种理想的原始状态中堕落,这种理想状态是根据神话构想出来的;政治国家得不到改进,它们变得腐败;政府的历史是颓废的历史。在此我们觉察到希腊人的时间感的内核:时间被当成一个“衰退过程” 来经验——持续进步的概念闻所未闻。 3
但为了理解现代颓废概念的形成,以及它在文化现代性某些突出方面的应用 [从术语上表明这一点的是,将近十九世纪中期出现了形容词和名词 “decadent”(颓废的或颓废者),几十年后又出现了 “颓废主义”(decadentism)的概念],我们首先将不得不考虑产生于犹太教——基督教传统的时间和历史观,就像我们在解释现代性概念的发展时所做的那样。犹太教及其后基督教的历史哲学的独创性来自于它的末世论特征,来自于它对历史终结的信仰——这使得时间进程成为线性的和不可逆的——和对末日(eschatos,在希腊语中意为 “最后”)的信仰;按基督教的观点,末日之后上帝的选民将享受永恒的福乐(上帝创造人原本就是为了使他享受这种福乐的),罪人们则将永远受到地狱里的折磨。极度衰朽(严重腐败)的确定无疑的标志,以及(按照启示录的预言)反基督的邪恶力量,将宣告审判日的来临。
颓废因而成为世界终结的痛苦序曲。颓废得越深,离最后审判就越近。自中世纪早期开始,基督教内部的无数宗派和运动都抱有至福千年的信念,沉浸于对即将来临的宇宙崩溃和末日的阴沉期望之中,而宇宙的崩溃和末日将在时间终结之前到来。千禧年主义早就遭到奥古斯丁的拒绝,随后又为历次教廷会议所谴责,然而它得以幸存,并在宗教改革这个多事的时期带着苏生的力量重新抬头。在各种各样的革命和乌托邦学说中,可以明显看到一种现代的、世俗化的千禧年主义的活力;这中间包括马克思主义,以及它的共产主义作为人类异化之终结的末世论图景(颓废的观念——有关当代资本主义极度腐朽的观念,有关资本主义垂死文化的观念——在马克思主义中如此重要实非偶然)。
前面已经说到,基督教的时间是水平地组织自身的,而希腊的时间可以说在本质上是垂直的。这种类比虽然不可太拘泥于字面,实际上却是极富启发性的。希腊和基督教时间的这种对立已经为一些人论及,其中之一是亨利——夏尔 · 皮埃什,他指出了这种水平 / 垂直隐喻应用于那些互为对比的时间和变化观时所具有的某些含义:
对变化着的世界表象的垂直解释是借助于上层灵智世界固定的、非时间的和原型的实在来进行的,在古代基督教中它让位于对时间片断的水平解释,这些时间片断是互为解释的:过去宣告并准备着未来;或者…… 较早的事件是后来事件的 “模型” 或“预兆”,后来的事件反过来又是在它们之前的事件的现实化,先前的事件联系着后来的事件就像阴影联系着圆满的、真正的现实。因此我们可以说在基督教思想中是影像预期着范本,而在希腊思想中超验的范本永远优于影像。希腊的范本论恰恰被颠倒了。 4
如果说 “预兆” 或“阴影”同 “完满现实” 之间的水平时间关系只适用于古代基督教的话,那么广义的水平时间观及随之而来的对历史性(historicity)的强调(亦即对一种由独特事件构成的不可逆系列的强调,即使这些事件可以看成是某种预言的实现),则构成整个基督教的一大特征。
同古代人更为消极的态度相比(无论这些古代人是赞成斯多噶派的遁世和冷漠,还是培育了享乐主义的 “及时行乐” 哲学),基督教颓废观中新的东西是一种敏锐而不安的紧迫感。颓废被感觉成一种独特的危机,这种感觉前所未有地强烈;而且,随着时间的流逝,去做那些为了自己和同类的获救必须做的事而不再等待就变得极端重要。从世界的终结正在迅速临近的观点来看,每一个单独的瞬间都是决定性的。颓废的意识导致内心不安,导致一种自我审察、全力以赴和作出重大放弃的需要。基督教的启示论即使在它不公开表明自己的时候,也导致一种激剧增强了的时间意识。这也许是一种重要的心理因素,它为文艺复兴发现世俗时间和给予时间性(temporality)以高度重视做了准备。
在这里也许值得指出,文艺复兴绝没有以某种历史无限发展的清明乐观主义观点去肯定时间的价值。文艺复兴最杰出的代表人物大多数是悲观主义者,危机意识也广为流传。一位研究现代意义上的颓废的知识史家通过概括整个这方面的研究,就有关文艺复兴的乐观主义 “神话” 写道:
基督教的超自然主义逐渐为自然主义的和世俗的观点取代,但这并不必然导致更愉快的历史观…… 因此,列奥纳多 · 达 · 芬奇作为文艺复兴时期最自然主义的头脑之一,却为各种世界在一场大灾祸中终结的图景所苦恼,他不再把这大灾祸想象成神圣的审判,而是把它想象成一场所有人,不管他们有何功德,都要在其中经受同样折磨的灾难…… 萨伏那洛拉对文艺复兴时期社会的恶毒攻击所得到的广泛响应,也表明在十五世纪末期,许多意大利人把他们的时代视为一个危机与腐败的时期。换言之,文艺复兴时期洋溢的乐观主义只不过是一个神话。 5
列奥纳多的例子确实说明问题,而且非常有意思的是,他的幻觉都围绕着一种典型的基督教天启灾难的观念,这种天启灾难的观念如果除去其宗教含意,只会变得更加阴暗压抑和令人痛苦。
一方面是现代性和进步的概念,另一方面是颓废的概念,只有在最粗浅的理解中两者才会相互排斥。一旦我们考虑到它们在自身不同历史阶段得到实际应用的方式,我们就会意识到它们之间关系的辩证复杂性。沙特尔的贝尔纳的著名比喻是极好的例子。侏儒站在巨人的肩膀上从而能看得更远;与此类似,进步和颓废的概念是如此紧密地互相包含,以至于如果我们想作出概括,就会得到一个悖论式的结论:进步即颓废,反之,颓废即进步。贝尔纳的比喻的好处在于,它令人信服地表明,作为一种形象(或一种想象的投射),这样一种明显的、逻辑上不可接受的悖论,如何能够被看成一种完全可信的洞见。
同进步一样,颓废是一个相对的概念,而下面的事实只会使得这种相对性更难以捉摸,这就是 V. 扬克列维奇在一篇论颓废的杰出哲学文章中指出的:“没有什么历史内容‘本身’可以被说成是颓废的。颓废不是静态的而是动态的。” 6 因此颓废不是一种结构而是一种方向或趋势。
我们也注意到,颓废通常联系着没落、黄昏、秋天、衰老和耗尽这类概念,在更深入的阶段还联系着有机腐烂和腐败的概念——同时也联系着这些概念惯有的反义词:上升,黎明,青春,萌芽,等等。这使得人们必然会按自然周期和生物隐喻来思考它。颓废概念同有机过程的这些相似性可以说明,为何进步并非其绝对的对立面。的确,在较早的阶段,人们是根据进步同成长特别是同人类个体的智识发展的类似来看待它的(我们想起圣奥古斯丁在人类的逐步发展和个体的逐步发展之间所做的比较)。但历经几个同科学研究和技术进步紧密相连的世纪之后,进步的概念达到了一个抽象的层次,在这个层次上,早先的有机特别是拟人论的含义不再保留了。进步被认为是一个更多地与机械学而不是生物学相关的概念。
这同进步是生活之敌的观点非常接近,这种观点在我们这个世纪里并不鲜见。对进步神话的批评在浪漫派运动中发端,在突起于十九世纪末并一直延伸到二十世纪的反科学与反理性运动中增强了势头。结果是——如今这已成为老生常谈——高度的技术发展同一种深刻的颓废感显得极其融洽。进步的事实没有被否认,但越来越多的人怀着一种痛苦的失落和异化感来经验进步的后果。再一次地,进步即颓废,颓废即进步。就其生物学含义而言,颓废的真正对立面也许是再生。但是,将会再生我们这个衰竭世界的野蛮人何在?
在过去的大约一百年里,振奋人心的进步信念没有完全消退,但它被现代性、先锋派和颓废这些远为含混的神话取代(它们更为含混是因为它们更富于自我批评性)。当然,我的论述只限于这些神话在我们时代的文学艺术想象领域发生作用的方式。因此,我在这里特别感兴趣于从老的、一般意义上的颓废向新的、更为具体的文化颓废概念的过渡,这个概念在十九世纪逐步发展,在二十世纪随着 “[[颓废主义]]” 这个美学——历史范畴的出现而达至顶峰。换句话说,我关注的是颓废自觉地变得现代的过程。在此过程中,如我们将看到的,获得了对于颓废概念的一种全新阐释和评价。
## 从 “颓废” 到“颓废风格”
尽管多数文学史家一致认为,现代美学中的颓废概念源于[[浪漫主义]](这种主张基本上是正确的),但浪漫派自己从未自觉地认同于一种得到明确表述的或者哪怕是含糊其词的颓废纲领。他们偶尔会论及颓废的随便哪个方面,这也许是他们在当时的社会中观察到的,但这些论述与我们的主题无关,因为这个概念在这些情形中的应用既无原创性也无预示价值。富有讽刺意味的是,浪漫主义的反对者们在一种文化特别是美学的意义上运用颓废概念——尽管它保有传统的贬义内涵。这发生在法国;十九世纪初期,新古典主义在法国比在西欧任何地方都要强盛。
最早引入 “[[颓废风格]]”(style of decadence)这个理论概念,并用大量常见和可辨识特征来界定它的,是反浪漫派的法国保守批评家德西雷 · 尼扎尔。在写作《关于颓废时期拉丁诗人道德与批评的研究》(1834 年出版于布鲁塞尔)一书时,尼扎尔没有直接提到反对[[新古典主义]]死板规则的浪漫派,但他头脑里想着他所认为的浪漫派的无度与滥用。尽管他的书表面上是论述晚期罗马帝国诗歌的,但他批评的实际目标无疑是浪漫主义。有意思的是,尼扎尔的主张——特别是他认为艺术的“颓废风格” 是如此重视细节,以致破坏了作品部分与整体间的正常关系,使作品解体成为大量过度书写的片断——相当有影响,即使是在提出这些主张的人已经湮没无闻之后。(对那些感兴趣于概念之奇特生命力的人来说,)弄清下述问题的确是非常有趣的:保罗 · 布尔热有关 “颓废风格” 的著名论述在多大程度上得益于半个世纪前尼扎尔的观点?
罗马帝国的衰颓与最终崩溃长期以来一直是历史学家思考的主题,但直到十八世纪,它才得到一种完全现代的(亦即非神学的)理解。这种新的普遍态度的最好例子是孟德斯鸠的《罗马盛衰原因论》(1734)。这篇文章为《论法的精神》(1748)一书的巨大综合奠定了基础,并在一定程度上预示了它;孟德斯鸠在其中并没有考虑罗马衰颓时期的文学,而把他的分析局限于那些导致古代最强大帝国衰落的社会政治、道德和军事原因。
然而,在他的《笔记》中,在思考有关古今之争的问题时,孟德斯鸠接近于提出一种普遍的颓废规律,它见于衰颓与繁荣的悖论式相互关系中。这一规律同样适用于文化颓废,孟德斯鸠提出,恰恰是现代文学丰富多样的成就,可以被看作即将来临的颓废的标志:“在诸多帝国的历史中,没有什么比大繁荣更接近于颓废;同样,在我们的文学共和国中,人们担心繁荣会导致颓废。” 8
在他的《风俗论》(1756)中,伏尔泰在论及罗马帝国没落的原因(基督教的出现,以及随后在帝国面临野蛮人威胁时削弱了它的那些社会动乱)时,同样用了 “颓废” 一词,但像他的前辈一样,他并没有关注表现罗马衰颓的具体文学形式。仅仅是在对比路易十四时代(1739-1768)的辉煌成就而抱怨自己时代的趣味腐败时,伏尔泰才谈到了文学意义上的颓废。
然而,在十八世纪期间,出现了一种观点,即认为一个历史时期(无论是一个进步和发展的时期,还是一个颓废的时期)应被看成一个 “总体”(totality),而且社会政治现象和艺术表现形式是有机地互相关联的。这样一种较宽泛的历史概念是斯塔尔夫人《论文学与社会制度的关系》(1800)的核心观点。该书有时被认为是早期浪漫主义的一部文献,实际上它只不过是对启蒙时期审美意识形态的一次综合。以一种最为乐观主义的十八世纪方式,斯塔尔夫人分享了无限进步的信念,并对现代相对于古代所拥有的整体优势深信不疑。从这样的角度看,在某些过往时期所观察到的颓废就显得是一种偶然现象,其根源在于一些偏离了自由的理想与实践的孤立行为。斯塔尔夫人写道:
人们坚持认为艺术、文学和帝国的衰颓必然在某个辉煌时期之后到来。这种观点是错误的。艺术有一个边界,我相信它们不可能超出这个边界;但它们可以保持它们已经达到的水准;而且在所有不断发展的知识中,道德本性是倾向于增强的。 9
斯塔尔夫人自然提到了罗马的衰颓——她把其主要原因归为暴政——同时也承认它导致了先前趣味标准的窳败。但是她认为,即使是在这样一个颓废的时期,进步的原则也在微妙地发生作用,帝国时期的作家尽管在艺术上要逊色一些,“作为思想家却要比奥古斯都时期的思想家强” 10 。 10 至于她自己的时代,斯塔尔夫人确信,随着 “启蒙” 有益的、不可逆转的影响,不再有任何颓废的威胁。在她看来,颓废完全属于过去:
在自然的秩序中,帝国的颓废并不较文学和智慧的颓废为多…… 欧洲文明,基督教的确立,科学发现…… 已经…… 摧毁了导致野蛮主义的古代根由。因而,今天无须那么担忧国家的颓废,以及随之而来的文学的颓废。 11
就像她的许多十八世纪先辈,斯塔尔夫人没有更详细地思考这个问题,因为她干脆就排除了任何未来颓废的可能。
尼扎尔是第一位更持久地关注作为一种 “风格” 的文学颓废的批评家,他远不及斯塔尔夫人那么乐观。我们已经指出,是当代问题促使他去关注拉丁文学的颓废,这些问题是他处在四面楚歌的新古典主义价值维护者的立场上,在一个有利于浪漫主义的时代所感觉到的。就像他在《研究》第一版的序言中所指出的,尼扎尔对文学颓废的“复发特性”(recurring traits)感兴趣:
我提出一种有关颓废诗歌共同特征的成熟理论…… 我试图解释是什么样不可觉察的、持续的需要,把人类精神引入这种非同寻常的衰竭状态,在这种状态中,最丰富的想象力对于真正的诗歌无所增益,它们仅仅剩下不光彩地毁坏语言的力量。 12
因此,我们并不奇怪,尼扎尔将他的颓废理论(仅仅在他论拉丁诗歌白银时代的著作出版后两年)应用于法国最重要的浪漫主义诗人维克多 · 雨果。此前,在 1829 年,尼扎尔曾是雨果的拥戴者,但在随后的几年里,他内心经历了如此彻底的转变,以至于到了 1836 年,他如果算不上这位伟大诗人最直言不讳的批评者,也差不多算得上是最清晰有力的批评者。在他的《1836 年的维克多 · 雨果先生》一文中,这位《研究》的作者在雨果的《黄昏颂》中发现了颓废的所有重要标志——过度描写,突出细节,以及一般地抬高想象力而损毁理性。从理论上说,尼扎尔对雨果的批评可归结为对想象力和新颖性的攻击(如果我们把这种批评同波德莱尔对作为 “才能之女皇” 的想象力的热情颂赞相比较,就能更好地理解其深刻的反现代特性)。尼扎尔写道:
当我们说他 [维克多 · 雨果] 是一个革新者是,我们并不是在赞扬他。在法国,文学是实际而理智的,一个只具有想象力的作家,尽管这种想象力是绝无仅有的,也不能成为伟大的作家…… 在他那里,想象力取代了一切;只有想象力在运思和表演:它是一位统治着不受约束之物的女皇。在他的作品中理性无立足之地。没有实际的或可运用的概念,没有或近乎没有现实生活;没有哲学,没有道德。 13
尼扎尔认为,想象力如果不再处于理性的控制之下,就会无视整个现实,无视事物实际上的高下优劣之分,而只是关注细节(他非常乐于承认,在这方面雨果独擅胜场)。 14 尼扎尔理论另一个值得注意的特征是,它强调颓废艺术阴险欺骗的特性,即它进行诱骗的能力。颓废艺术的有害性同它的欺骗能力成正比。尼扎尔称维克多 · 雨果为 “诱骗者” 15 ,这再一次预示了尼采的颓废观,这种颓废观见于他对瓦格纳的著名批评。
颓废感在十九世纪当然不仅限于法国,但也许是因为 “这个国家在世界上的权力和荣耀正在衰落的感觉” 16 ,颓废的主题在法国不仅更引人入胜和令人困惑,而且被赋予各种极端矛盾的意义,这些矛盾意义表明了一种文化上典型的爱——恨关系。换句话说,颓废的概念连同其旧的和新的含混性,为文化的自我辨识(self-identifcation)提供了契机,这在法国甚于在其他任何地方。魏尔兰著名十四行诗《衰竭》(1884)的开头一句(“我是颓败将尽之时的帝国”)诗意地概括了相当一部分法国知识分子的感受,特别是在 1848 年革命失败后,以及在 1870 年普法战争中法国溃败和随后导致 1871 年短暂的巴黎公社的暴动之后——其时这种感受更为激烈。
显然,在众多拥有颓废意识的法国知识分子中,盛行着大量不同的态度和标准。一些人培育了一种 “再生主义” 的颓废概念,他们指斥没落所导致的后果,相信一种未来 “复兴” 的可能,对此他们寄予厚望。另一些人——这些人是我们的基本兴趣所在——则钟情于一种现代世界正在走向一场大灾难的感觉。后一集团中的大部分人是艺术家,他们是一种审美现代性的自觉宣扬者,这种审美现代性尽管有着种种含混之处,却从根本上对立于另一种本质上属资产阶级的现代性,以及它关于无限进步、民主、普遍享有 “文明的舒适” 等等的许诺。在 “颓废” 艺术家们看来,这类许诺蛊惑人心,人们借助它们来回避日益精神异化和非人化的可怕现实。恰恰是为了抗议这种伎俩,“颓废派”培养了他们自己的异化意识,这既是美学上的也是道德上的;而且,面对当时蛊惑家们虚假而自命不凡的人本主义,他们求助于某种反人本主义的进攻策略,以及几十年后奥尔特加 · 伊 · 加塞特所说的 “艺术非人化” 策略。进而言之,“颓废派”往往抱有各种革命的信念(无政府主义对他们特别有吸引力),因而把他们视为先锋派的代表人物亦不失公允。在十九世纪八十年代,文学颓废主义和文学先锋派若非完全同义的概念,也已是紧密相关的概念。稍后我们将讨论这种关系。
继续进行历史描述时,我们注意到,接近十九世纪中期,越来越多的法国知识分子在思考文学颓废的问题,其中既有 “为艺术而艺术” 运动的参与者,也有不属于这一运动者。与极端保守的尼扎尔不同的是,他们愿意重新评价文学的颓废,至少是部分地这么做。年轻的埃内斯特 · 勒南的记述在这方面富有意义。在他仍属年轻时期的著作《科学的未来》(写于十九世纪四十年代后期,但直到 1890 年才发表)中,勒南成为进步观念的热情拥护者,而在此之前,在他成长时期的哲学日记中,他一直关注着颓废的问题。他的哲学日记以《青年时代笔记》(1846-1847)之名为人所知。勒南认为,仅仅就纯粹想象性创造的力量而言,颓废的时期才会不如古典时期,而在批评的能力上,它们显然较古典时期强。勒南写道:“颓废的时期长于批评,往往较伟大时期强。” 17 为维护批评的价值,他宣称:
在某种意义上,批评强于创作。迄今为止,批评所取的是仆从般的谦卑地位;也许是批评正确评价自己并将自己抬高到它的那些评判对象之上的时候了。因此这个世纪在产生原创性古典式小说上成就寥寥。这意味着这个世纪不行吗?不,因为它更富于哲学性。 18
勒南也注意到,他的时代不仅对往昔的颓废时期而且对原始主义时期有着特别的兴趣。勒南正确地指出,对于颓废和原始主义二者的兴趣源于某种对古典主义的不耐烦:
我们时代对非古典主义文学的狂热是文学史上一个多么奇怪的事实啊。并不是说对希腊、拉丁和法国文学没有人感兴趣,而是说被研究的主要是它们的前古典和后古典时期。所有的兴趣都集中于所谓的起源和颓废时期。 19
对颓废的着迷,以及表面上与之矛盾的对起源和原始主义的着迷,实际上是同一现象的两个方面,勒南也许是第一个意识到这一重要事实的人。对过分高深、极度精致的颓废作品的狂热,和对 “原始” 创造力的天真、笨拙、不成熟表现形式的狂热,这两者之间的密切关系自十九世纪后期开始已为现代文学艺术的发展一再表明。
最早得到全面认同和有着广泛影响的把颓废视为一种风格的观点,出自泰奥菲勒 · 戈蒂埃 1868 年为波德莱尔《恶之花》写的序言。作为 “为艺术而艺术” 的倡导者,戈蒂埃表达了他对于某些常常与颓废相联系的文学主题的尊重,这种联系早在 1836 年《莫班小姐》及其著名的序言发表时就开始了。尽管我们注意到戈蒂埃并不太喜欢 “颓废” 这个词(这是一个多数时候被颓废研究者忽视的细节),但他把颓废概念运用于波德莱尔诗歌的那段话仍不失为他的关键言论:
被不恰当地称为颓废的风格无非是艺术达到了极端成熟的地步,这种成熟乃老迈文明西斜的太阳所致:一种精细复杂的风格,充满着细微变化和研究探索,不断将言语的边界向后推,借用所有的技术词汇,从所有的色盘中着色并在所有的键盘上获取音符,奋力呈现思想中不可表现、形式轮廓中模糊而难以把捉的东西,凝神谛听以传译出神经官能症的幽微密语,腐朽激情的临终表白,以及正在走向疯狂的强迫症的幻觉。 20
戈蒂埃文章论述的对象,波德莱尔本人,并非不熟悉对于颓废问题的这种新态度。的确,波德莱尔有时公开拒绝颓废这个词以及颓废这个概念,但同样经常的是,他会说一些赞同颓废的话。比如说,我们不妨想想《恶之花》第一版(1857)中,有关用中世纪拉丁语写的 “献给我的弗朗切斯卡的颂歌” 一诗的那条奇怪注释。这条注释不仅仅是一个解释,它旨在表达波德莱尔对某种风格的坚持,他把这种风格同时定义为“颓废的”、“精神的”、和“现代的”。文本在这三个关键概念之间建立的关系典型地体现了波德莱尔的思想方式:
难道读者不会像我一样,认为晚期拉丁颓废——一个已经转变并准备好过精神生活的强健之人的至深悲叹——唯一适合于表现现代诗歌世界所理解并感觉到的那种激情吗? 21
在从戈蒂埃到布尔热及之后的各种颓废定义中,波德莱尔的作品堪备一例,但他从未致力于提出一种有关该主题的统一理论。然而,他的批评包含有大量洞见,这些洞见显示出它们的作者在现代艺术颓废概念的进一步发扬光大中所发挥的核心作用。写作《1846 年的沙龙》的青年波德莱尔用 “颓废” 一词来描述维克多 · 雨果。这显然使我们想起尼扎尔早些时候对雨果的批评。但尽管波德莱尔保留了尼扎尔定义中的某些成分(比如,认为颓废诗人会经由词语来获取典型地属于其他艺术媒介如绘画或音乐的效果的观点),他却与尼扎尔反浪漫派和反想象力的主要矛头完全相反。当波德莱尔比较德拉克洛瓦和雨果时,他把前者作为 “真正的” 浪漫派加以颂扬(一位赋有 “走得最远的想象力” 的创造者),而拒绝用浪漫主义来描述雨果的通常做法。在《1846 年的沙龙》的作者看来,维克多 · 雨果是“一个灵巧多于发明的工人,一个勤奋与准确胜过创造的艺匠…… 他是一位颓废的作家…… 雨果先生甚至在出生之前就已是学院的天然成员。” 22 这里,颓废等同于学院主义的贫瘠。
十多年后,在题为《哲学化的艺术》(大约写于 1859 年,但死后才发表)的文章中,波德莱尔以更一般的方式思考颓废,并发展了他先前的观点,即认为颓废的主要特征是其打破不同艺术间传统边界的系统化努力。在 1857 年有关 “献给我的弗朗切斯卡的颂歌” 的那条注释中,波德莱尔在颓废和现代性之间建立起直接的关联,几个世纪里艺术史一直在趋向于日益显著的“力量分离”(separation of powers)和专门化(结果是“有属于绘画的主题,另有属于音乐的主题,另有属于文学的主题”),在此之后,波德莱尔注意到一种支配着当代艺术的恰恰相反的原则:
今日每一种艺术都暴露出入侵邻近艺术的欲望,画家引入音阶,雕塑家使用色彩,作家运用造型手段,而其他那些如今令我们不安的艺术家则在造型艺术中展现出一种百科全书式的哲学,这难道不是颓废的一种必然结果吗? 23
考虑到波德莱尔对现代性的崇奉,特别是他有关艺术本质统一性的深沉信念,他对于颓废的这种看法很难说是负面的。而当我们想想他公开提倡 “总体的” 或“综合的”艺术,以及他运用普遍类比(universal analogy)和联觉(synaesthesia)这两个近似原则讨论理查德 · 瓦格纳的方式时,诗人对颓废的接受就更加明显——在这里颓废被理解成不同艺术间手段和程式的自由交流。1861 年谈到瓦格纳时,波德莱尔特别赞扬了这位德国作曲家有关 “戏剧性艺术” 的构想。瓦格纳把 “戏剧性艺术” 设想成“多种艺术的重新统一和重合”,亦即,“最综合、最完善的优秀艺术”。 24 为表明瓦格纳趋向一种综合艺术的冲动,波德莱尔特别强调了瓦格纳音乐的视觉特性:
没有像瓦格纳这样擅长于运用绘画空间和背景的音乐家…… 听着那种热烈而专制的音乐,有时人们似乎会发现由画在半明半暗、为梦幻所撕裂的背景上的鸦片所引发的种种眩惑想象。 25
有趣的是,欧仁 · 德拉克洛瓦这位为波德莱尔承认的大师,对颓废现象同样不乏敏感,他的《日记》就充分地证明了这一点。德拉克洛瓦认为,颓废时期同它们之前的时期相比,往往更为复杂,更为精致,也更重分析。人对于他自身思想情感的意识似乎有一个必然的发展过程。对一位艺术家来说,违逆本性而培养某种拟古主义压根就是荒唐的:
我观点的本质是从属于自身时代的需要,因此,也就是关于违背潮流、老式作派的愚蠢的。拉辛同高乃依相比已经显得精致,而自拉辛以后我们又精致了多少啊…… 我们的现代艺术家不是仅仅抒写情感,他们描绘外部世界并分析一切。 26
在几天之后,即 1856 年 4 月 16 日的另一条记录中,德拉克洛瓦进而在颓废和对精致的需求间建立起清晰的联系:
关于在颓废时代对精致的需求。那些最伟大的精神不能回避它…… 英国人和德国人一直在这个方向上推动我们。莎士比亚非常精致。带着古代艺术家忽略掉或根本不知道的深厚情感去摹绘,他为我们发现了一个小小的情感世界,所有时代的所有人都在一种混乱状态中经验到这个世界…… 27
对十九世纪五六十年代的法国作家和艺术家来说,颓废的概念多数时候不是直接联系着进步的概念,就是间接联系着现代发展的 “歇斯底里” 给人类意识造成的影响。龚古尔兄弟在 1864 年谈到一种 “现代的忧郁”,他们把这视为社会需求加诸人类心灵的不可忍受的压力的结果,这个社会处于在各种意义上进行“生产” 的躁狂中。同下面引自龚古尔兄弟《日记》中的段落相比,也许难于找到一种同启蒙的乐观进步观念构成更鲜明对比的观点;在下面这段话中,进步与神经官能症是一回事:
自人类存在以来,它的进步、它的成就一直同感觉相类似。每一天,它都变得神经质,变得歇斯底里。而关于这种动向……
你能肯定现代的忧郁不是源自于它?何以见得这个世纪的忧伤不是源于过度工作、运动、巨大努力和剧烈劳动,源于它的理智力量紧张得几近爆裂,源于每一领域中的过度生产? 28
与龚古尔兄弟同时代,埃米尔 · 左拉谈到 “进步病”,他在自身时代的各种表现中发现了这种病的症状,包括在文学中:“我们病了,肯定是的,因进步而病…… 这种神经对血液的胜利决定了我们的行事方式,我们的文学,我们的整个时代。” 29
从术语上说,对于颓废的这种增强了的意识可以解释形容词 “décadent” 的复活。这个词流行于十六世纪的法国(布朗托姆),嗣后被弃置不用,也许是由于它带有新造词的特征,而这不适合十七世纪新古典主义的纯粹主义要求。在英语中,《牛津英语词典》告诉我们,“decadent”早在 1837 年就已被使用(卡莱尔在其著名的《法国革命史》中谈到 “那些没有理想会在其中生长或绽放的颓废时代”)。也许是卡莱尔在他研究法国革命的过程中偶然碰到了这个词;然而实际的情况是,在十九世纪前半期,主要的法语词典(利特雷、哈茨菲尔德、罗贝尔)都没有就这个形容词的用法给出任何实例。有意思的是,即使在十九世纪五十年代之前“décadent” 已被零星使用,只是在此之后它才经历了一个语义丰富过程,而这在十九世纪八十年代又导致一些新的、常常是嘲讽而花哨的词被创造出来,如动词 “décader”,或“décadisme”、“décadentisme” 之类的标签。后面我们将看到,只有后一个词得以存活,并成为一个重要的批评范畴(“decadentismo”)——不在它的起源国而是在意大利。
对颓废的执念,以及与颓废有关的词语的渐趋流行,都构成十九世纪前半期一个独一无二的语义事件发生的原因,这就是,由这个形容词相应地生成同形名词:“decadent”(一个颓废的人)。十九世纪六十年代期间,龚古尔兄弟在他们的《日记》中使用了这个词——例如,一条记录中引述了泰奥菲勒 · 戈蒂埃对两兄弟说的话:“我们三人以及其他两三个人,我们病了。我们不是颓废者,而是原始人;不,还不是,而是奇怪、无定规、崇高的个人。” 30 在十九世纪八十年代早期,龚古尔兄弟自己已被认为是颓废者,而这发生在具体的 “颓废主义” 运动于 1886 年开始之前。不仅如此,他们还被认为是当代颓废风格的突出代表,被认为是“出于自身选择的颓废者”。 31 对龚古尔兄弟作出这种描述的是保罗 · 布尔热,他是第一位毫不动摇地既接受颓废这个术语又接受颓废这个事实的法国作家(不像波德莱尔甚至戈蒂埃),也是第一个以有关颓废作为一种风格的成熟哲学和美学理论来表明这种接受的人。尽管布尔热几乎肯定读过尼扎尔 32 ,他的观点却不仅未受尼扎尔极其明显的保守主义论辩的影响,而且有着质的不同——远为复杂和深刻,这部分是由于他个人对 “可怕” 颓废现实的认同。布尔热从内部来谈论颓废,带着确定无疑的戏剧口吻,其方式预示了几年后尼采对待颓废的态度。即使是布尔热最早关于颓废的论述(1876),也传达出一种个人介入的感觉:
我们接受…… 颓废这个可怕的词…… 颓废,但精力充沛;颓废时期在作品上成就较少,它却优于有机的时期,因为它天才麇集。它的不规则的、暴力的创造展现出更大胆的艺术家,而无畏是一种尽管我们不具备却会引发我们同情的美德。 33
布尔热在他论[[波德莱尔]]的文章中提出一种 “颓废理论”(他自己的话),这篇文章发表在《新批评》(1881 年 11 月 15 日)上,并在《当代心理学论文集》(1883)中重印。在具体从风格上着眼之前,他看待颓废的方法是广义社会学的,而且明显受到那个时代盛行的科学时髦的影响(社会现象的生物学解释,进化论,遗传理论,等等)。布尔热认为,有“有机的社会”(在其中各组成部分的能量服从于“总机体” 的目标和需要)和颓废中的社会,颓废中社会的特征是 “无政府” 的程度日渐加深,以及社会结构各种元素之间的等级关系逐渐松弛。颓废社会是高度个人主义的:“一旦在已取得的富足和遗传的影响下个人生活变得不切实际地重要,社会机体就变得颓废。” 34 这些都不是很有独创性的见解。只有当他在社会的个人主义趋向和艺术语言的 “个人主义” 表现形式之间建立起类比关系时,布尔热的理论才变得真正有意思和富有成效。艺术语言的 “个人主义” 表现形式典型地属于“颓废风格”:
一条规则既支配着另一个机体的发展也支配着它的颓废,这个机体就是语言。颓废风格是这样一种风格,在其中书的统一性瓦解以为书页的独立腾出空间,书页瓦解以为句子的独立腾出空间,句子瓦解以为词语的独立腾出空间。 35
如果我们承认个人主义的概念居于任何颓废定义的核心,那么显而易见的是,除了从国家主义和单纯军事强力的观点看它们不可取外,颓废时期会有利于艺术的发展,而且更一般地说,会最终导致对于生活本身的一种审美理解。宁取颓废而不取它的极端对立面(即原始主义),至少从文化上说显得是一种合理的选择。因此,布尔热进而说,我们有权 “宁取颓废的雅典人的失败而不取强暴的马其顿人的胜利”。 36 这同样适用于文学颓废。在此作者采取了一种福音传道式的调子:“那么就让我们沉迷于我们的理想和形式的不同寻常吧,就算我们把自己禁锢在一种前所未有的孤独中也罢。那些投奔我们的人将真正是我们的兄弟,为什么要把那些最私密、最特殊、最个人的东西为别人而牺牲呢?” 37 在布尔热那里,对颓废事实的理性认知,同把颓废作为一种文化风格在美学上予以推崇,这两者之间的界线差不多彻底模糊了。在他那里,我们可以说,现代性的相对主义导致了理论上无羁束、无政府的颓废个人主义,这种个人主义虽然有着破坏性的社会后果,在艺术上却是有益的。颓废风格只是一种有利于美学个人主义无拘无束地表现的风格,只是一种摒除了统一、等级、客观性等传统专制要求的风格。如此理解的颓废同现代性在拒斥传统的专暴方面不谋而合。
## 颓废欣快症
在 1883 年,也就是布尔热论波德莱尔的文章在《当代心理学论文集》中重印的那一年,魏尔兰在《黑猫》杂志上发表了他著名的十四行诗《衰竭》(收在他 1885 年的诗集《今昔集》中)。这首诗可用做某种团体宣言,这个团体随着《颓废者》(1886)杂志的出现而发起了名为 “颓废主义” 的短命运动:
> 我是颓废终结时的帝国
>
> 看着巨大的白色野蛮人走过
>
> 一边编写着懒洋洋的藏头诗
>
> 以太阳的疲惫正在跳舞之时的风格……
对于现代颓废概念史远为重要的一件事,是于斯曼的小说《逆流》于 1884 年出版。对临近世纪末的读者来说,《逆流》不仅仅是又一部谈论颓废主题的书:它实际上是颓废的巅峰,是一部关于颓废趣味和癖好的百科全书,这些趣味和癖好涉及从烹饪到文学的一切事物。于斯曼的小说似乎既是颓废心理学——或者不如说心理病理学——也是颓废美学,在他的小说中这两个领域实际上不可区分。
为了理解这本书和它的主人公让 · 弗洛雷萨 · 德艾散特,重要的是要记住作者把现代性——人为性——颓废完全等同。在对德艾散特的描写中,前面提及过的波德莱尔对自然的嫌恶(导致对现代性作为人为性的颂扬)被推向最极端。对人为性的崇拜,如《逆流》中所鼓吹的,是基于一种绝对否定——破坏性的想象。德艾散特并非真的试图使自己脱离自然;说他的态度是由他挫败、惩戒和最终羞辱自然的强烈欲望所决定的也许更为正确。他的审美主义不是一种逃避而一种恒久的违逆自然。他对人为性的崇拜是一种对反常的崇拜。只要能使外在或内在的自然偏离其准则和规律,这位彻底的审美家就会因此而额手称庆。受着所有异常之物的吸引,他的想象力将恣意探索反常的领域,以追求一种被认为是既反自然又绝对新异的美。毫不奇怪,在这种情况下颓废具有吸引力。
德艾散特最精微的快乐也许是发现自然有时会服从于人类幻想的专横命令。我们不由想到,在决定了 “他希望真花会模仿假花” 38 后,当他收到一些丑陋的杯芋和其他由乖戾园艺家们培育的奇怪花卉之后,他是何等的高兴。他的思考颇为典型:“大多数时候,自然本身不可能生出这类反常物种……” 39 A.E. 卡特在其敏锐的研究著作《法国文学(1830-1900)中的颓废概念》中,评论了这一段落,他指出于斯曼对人与自然关系的看法涉及到了根本上是[[反卢梭主义(亦即反浪漫主义)的概念:“人的介入往往产生某些必然反常和腐败的东西。就像人为性崇拜的所有其他方面,这是把正统的[[卢梭主义]]里外掉个个儿…… 马基 · 德 · 萨德的主人公以犯罪来凌虐自然,德艾散特则通过人为性来凌虐自然。” 40
与我们对颓废概念的关切更直接相联系的是,《逆流》包含了文学颓废理论的各种主要元素,特别是在第三章(描写德艾散特的拉丁图书馆)和第十四章(讨论了主人公所喜欢的十九世纪作家)中。有一点很有意思,那就是德艾散特在 1884 年所做的大多数选择,特别是关于十九世纪文学的那些,都已为我们所谓的现代传统所确证。于斯曼拒绝浪漫主义和浪漫派修辞,他不喜欢巴那斯派所实行的反浪漫主义(戈蒂埃和勒贡特 · 德 · 里斯勒的诗歌最终被认为太完美和不能 “向梦延伸” 而遭摒弃),他还积极认同于我们也许会称为 “危机诗学” 的东西,这些都标识了一些现代文学意识随后会循之发展的最典型线路。然而,我们必须注意到,如果说于斯曼的这些和其他一些美学观念得以存留,他自己的 “颓废修辞” 则大体上被遗弃了。这一修辞在下面这段话中再明显不过了,在这里,马拉美被称颂为最后的诗人 [尽管我们会觉得这一观点本身并非完全站不住脚,特别是如果考虑到马拉美自己关于“书”(Book)的乌托邦,这“书” 是终极和绝对的文本,一旦被写出来,宇宙就不再有生存的理由]:
一种文学的机体受到不可挽回的损坏,它被观念的时代削弱,为句法的无度所耗尽,它仅仅对那些使病人发热的奇癖敏感,尽管如此它还在迟暮之中仓忙去表现一切,这种文学的颓废注定会弥补所有对于快乐的疏忽,并会留下有关苦痛的最幽微记忆——这种文学在其垂死的卧榻上,以最完美和精致的形式,在马拉美那儿得到体现。 42
就颓废的审美化来说,《逆流》也许代表了一个极端。就此而言,紧随于斯曼小说出版之后,在颓废欣快症达至顶点的那个时期,是不可能指望会产生任何新东西的。然而事实是,纯粹的颓废概念所涉及到的绝对审美主义,如德艾散特所设想出来的,实际上是一种站不住脚的立场。在小说中,德艾散特受到疯狂的威胁,他放弃了对于人为性的崇拜,并经验到彻底失败的苦涩滋味,尽管结尾留有他可能皈依基督教的前景。于斯曼在小说出版二十年后所写的前言中承认,创作《逆流》对他是一种净化,而且他也承认,尽管该书有意表现出悲观主义的观点,希望的种子却大量暗藏其中,以至于 “这本书是我孕育之中的天主教作品的开头,在其中它已经有了完整的雏形”。 43
在《逆流》之后,颓废审美主义更加自觉于它的批判——论战功能,而较少把自己当成现代生活令人痛苦的不确定性和矛盾的解救之道。即使是在其最令人不快的形式中,审美主义也没有同各种对实际生活的关切相隔绝,不仅如此,它也不再被它的拥护者们认为与道德、宗教或政治信仰不相容。这值得强调,因为有一种先入之见仍广为流传,即认为审美主义必然意味着对非审美事物全然不感兴趣。从颓废主义向公开提倡革命观念的演变是一个很好的例子,它表明审美主义同对社会介入甚至是对暴力的崇拜可以携手并进。在详细论述前,我要插几句话指出,即使是一位像马拉美这样的诗人(他的审美超然态度确凿无疑,不管我们把它看成 “颓废的” 与否),也毫不隐讳他的下述信念:“向社会罢工”是现代诗人的职责。而且他自己是无政府主义的公开同情者。在世纪之交的英国,颓废审美主义最显著的代表人物是奥斯卡 · 王尔德,当他谈到为乌托邦辩护时,当他沉醉于关于社会主义(一种带有强烈无政府主义色彩的社会主义)获胜的未来主义思考之中时,他也表明了同样的趋向。 44
在《逆流》出版后一年,颓废在巴黎已成为一个如此时髦的主题,以至于它竟被戏仿;更有甚者,像《衰退:阿多雷 · 弗鲁贝特的颓废诗》 45 这类拙劣的模仿之作竟会被认真对待。无法确定的是,安纳托尔 · 巴茹这位《颓废者》(1886)的创办人和颓废主义的拥戴者,是试图使其杂志的名称暗指魏尔兰的十四行诗《衰竭》呢,还是他从《衰退》一书的成功中获得了灵感。毫无疑问的是,巴茹和他的朋友被颓废的概念所吸引,这个概念不仅是资产阶级平庸乏味的绝对对立面,而且是使资产阶级震惊的一种新手段。发表在《颓废者》杂志上各种宣言(巴茹所写)的攻击性调子使这一点无可怀疑。从形式上看,这些宣言可归入先锋派挑衅措辞的早期练习(在此使用 “先锋派” 这个词有着双重的理由:首先,是因为这些宣言显然昭示了后来先锋派宣言那种势不可当的风格;其次,是因为它们提供了一个极好的例子,表明政治激进主义夸张的语言如何能被用于文学论辩)。毫不奇怪,巴茹的宣言大多数情况下都是关于颓废的:
不承认我们处身其中的颓废状态将是迟钝至极的…… 宗教,习俗,正义,样样都在衰朽…… 在一种衰落文明的腐蚀活动之下,社会分崩离析…… 我们把这一页交付给谋杀式的革新,交付给令人麻木的无畏,交付给三十六种基调的纷然杂陈,这三十六种基调同被称为公共道德的古老传统几近不相容。我们将是一种理想文学的明星…… 总之,我们将是永恒地叫嚣和宣谕着长生不老教义的救世主,而长生不老乃胜利的颓废主义本质所在。 46
然而,《颓废者》第二期的读者们得悉,颓废不过是对现代性的意识和对它的接受。进而言之,真正的颓废者不仅会使其作品同现代文明最突出的特征相谐调,而且会坚定无畏地表达一种进步的信条,一种对巴茹所谓 “人性的攀进” 的牢固信念。换言之,颓废者处在先锋地位(尽管并没有使用先锋这个词):
古代人属于他们的时代。我们希望属于我们的时代。蒸汽和电力是现代生活两个不可或缺的动因。我们应该有一种同科学进步协调一致的语言和文学。这难道不是我们的权利吗?这不就是所谓的颓废吗?就算是颓废吧。我们接受这个词。我们是颓废者,因为这种颓废不过是人性向着种种理想的攀进,这些理想被认为是不可企及的。 47
处在颓废欣快症的峰巅,魏尔兰——《颓废者》最著名的撰稿人——认为巴茹创造颓废主义这个名称不啻天才之举。在给《颓废者》的一封信(发表于 1888 年 1 月的那一期)中,魏尔兰写道:“颓废主义是一个天才的词,是一个将在文学史上长存的有趣发现;这种不规范的措辞是一种非凡的标志。它简短、方便、唾手可得,而且恰好排除了贬损性的颓废概念;它听起来富于文学性却不迂腐,它灵活而且有所突破。” 48
但魏尔兰热情的言辞仅仅被《颓废者》用做宣传,而且丝毫不加谨慎和节制,不久他即在支持颓废运动这一点上冷静下来。我们记得,在让 · 莫雷亚斯于 1886 年在《费加罗报》上发表《象征主义》的宣言后,到 1888 年,已有越来越多反传统的巴黎作家发现这个新名称方便适用。那些宣称自己是颓废派的人往往被简单地等同于安纳托尔 · 巴茹的追随者,而巴茹自己的文学声望决不足以使人们相信他能领导一场真正的文学运动。当巴茹试图用魏尔兰的名字来抬高其杂志和它所代表的趋向时,他也许已经意识到了这一点。然而,不可理解的是,魏尔兰似乎非常不愿意扮演他出于文学策略方面的原因正被迫扮演的角色。巴茹本人变得日益政治化,并在 1889 年停办《颓废者》杂志,全力以赴于 1889 年 9 月的立法议会选举,以及他作为社会主义候选人竞选国民会议席位的那场一败涂地的运动。不管怎么说,当它停办时,《颓废者》已处在失去最优秀撰稿人的过程中。在 1891 年,巴茹痛苦地回想起他在克服先前文学朋友的 “反动” 偏见上的失败,有一段时间,他认为这些朋友能够参与到他削弱资产阶级社会大厦基础的宏大而雄心勃勃的计划中来。这里巴茹是作为一个服膺总体革命理想的无政府主义者在说话:
我的撰稿人的数量,他们学识的各异,他们的天才,这一切构成一种力量,这种力量如果用于破坏的目的,将会逐渐损毁社会结构的基础。有些人攻击所有制、宗教和家庭,另一些人会嘲弄婚姻并提倡自由之爱。还有一些人会称颂世界主义和普遍联合的好处。每一个人根据他的气质,通过书、舞台或报纸,都会为在教育中形成那种革命行动的综合作出贡献,而没有了它,就只能取得部分和少许的进步。我的被吸引仅仅是我的一种想象的结果。我的大多数撰稿人是公认的反动派,他们愿意粗暴地对待资产阶级的某些偏见,但他们不会为了世界上的任何东西来毁坏它们。科学对他们来说天真可厌,他们认为艺术同社会主义不相容。这一切他们都漠然视之。 49
1889 年之后,所有的迹象都表明,颓废欣快症在迅速消退,颓废主义只不过是世纪末巴黎躁动不安的知识氛围中众多转瞬即逝的时髦之一。 50 然而,在十九世纪九十年代期间,“颓废者”一词保留了它在前两个十年中所取得的积极艺术内涵,而瓦莱里也在 “极度精致”(ultraraffné)的意义上使用它。但这样一来这个概念变得过于含糊,以致它不能成为一个切实有用的批评工具。新创造的词“颓废主义” 受到了挑战,并最终被显然更具吸引力的 “[[象征主义]]” 所取代。这也许可以解释为何今天的法国批评家仅仅在一种非常狭隘的历史意义上来使用 “颓废主义” 这个名称,即用它来指十九世纪八十年代后期那些明确声称自己是颓废者,并团结在《颓废》或《颓废者》这类有着旗帜鲜明名称的期刊周围的诗人。“象征主义”最终有着同样的命运,也只是意味着众多平行或连续的现代文学运动中的一种。[奇怪的是,正如我们在讨论现代主义时曾经指出的,法国批评中并没有一个统一或总体的概念——在范围上堪与浪漫主义相比——能用来指称文学上的后浪漫或 “现代” 时期,这个时期在英美批评中被称作现代主义,在意大利批评中被一致命名为“[[颓废主]]义”(decadentismo)。]
在法国,我们可以断言,像 “颓废者”、“颓废主义”(décadisme 或 décadentisme)这样的概念已不可能摆脱有关它们风靡一时的记忆。唯其如此,尽管是在法国人们首次跨越了把有关颓废的一般观点同有关颓废的现代美学理想(颓废作为一种激进反传统主义的形式)分隔开来的鸿沟,我们却不得不到法国之外去追寻与现代性概念有关的文化颓废概念的进一步发展。
## 尼采论 “颓废” 与“现代性”
在他的后期著作之一《论瓦格纳》(1888)中,尼采指出,“颓废” 已成为他哲学生涯的核心主题:
没有什么比颓废问题更深切地引起我的关注——我自有理由。“善和恶” 仅仅是该问题的一个变种。一旦你获得了发现颓废症状的敏锐眼光,你也就理解了道德——理解了在它至为神圣的名义和价值准则之下暗藏着什么:贫困的生活,终结的意志,高度的倦怠。道德否定生活。 51
这个简短的段落实际上综括了尼采思想的本质方向和创见,难以想象会有一种更好的方式能以同样精练简明的措辞描绘出他的贡献。
为了适当地理解尼采对于颓废充满激情的批判——实际上还有其哲学作为整体所具有的深刻辩证性——我们必须始终记住,他是作为一个懂得健康对于病态的价值,从而不可能认识不到疾病本身的哲学价值(没有疾病健康不可能获得自我意识)的人,从个人经验出发来谈论颓废的。在此意义上,正如他自己相当明确地指出的,他对于杰出的颓废者瓦格纳的攻击,即使是那些在最猛烈的时刻,也始终包含着它的辩证对立面,亦即,感激:
…… 瓦格纳只是我的疾病之一。并非我希望对这种疾病不存感激之情。在这篇文章中,当我说出瓦格纳有害的主张时,我同样想说明对什么人来说他是必不可少的——对哲学家。别的人没有瓦格纳也许能行,但哲学家少了瓦格纳就不是什么时候都行。他必须成为他的时代的坏的良心——因为他需要最好地理解它…… 当一位今天的音乐家说 “我恨瓦格纳,但我不再受得了任何其他音乐” 时,我完全理解。但我同样理解的是,一位哲学家会宣称:“瓦格纳总括了现代性。没有别的出路,你首先必须成为一个瓦格纳派。” 52
在《看哪,这人》(亦写于 1888 年)的一个著名段落中,尼采在更为一般的意义上谈到了他自身的二元本性。他把自己(“作为我父亲早已死了,作为我母亲却仍然活着并正在变老”)描绘成 “同时是一个颓废者和一个开端”,接下去还非常笃定地说:“对于上升和颓废的迹象,我比在我之前的任何人都有着更敏锐的嗅觉;在这方面我是最优秀的教师——两者我都知道,两者我都是。” 53 在同一章(“我为何如此聪明”)中,尼采讲述了他的疾病体验,他认为他的 “辩证家的清明” 即得益于这种体验,而辩证法本身,如他所强调的,是“颓废的一种症状”。 54 我所摘引的那一节以下面这段对颓废的礼赞结束,其中充满了悲悯和反讽:
漫长的、太过漫长的一连许多个年头对我意味着恢复;不幸的是,它也意味着旧病复发,衰朽,和一种颓废的周期性。在所有这一切之后,用得着我说在颓废的问题上我富有经验吗?我来来回回地琢磨它们…… 从病人的角度看那些比较健康的概念和价值,以及相反,从一种富裕生活的丰足与自信俯视颓废本能的秘密运作——在这方面我有着最长久的训练,有着我最真实的体验…… 如今我懂得如何去颠倒视角,拥有这么做的本领:这是为何 “价值的重估” 也许仅仅对我才可能的首要原因。 55
诸如此类的断言在防止对尼采思想做简单化解释方面也许不无作用,这类简单化解释屡见不鲜(它们倾向于把尼采思想的丰富性化约为粗暴的黑白式对比,或者相反,化约为一种根本的、不可消除的 “含混性”),但这些断言只是部分地表明了尼采颓废概念的实际复杂性。为了充分意识到这种复杂性,首先就必须认识到在多大程度上颓废精神是欺骗性的,也就是说,要在最可信和健康的外表下去追踪它的破坏活动。在尼采看来,颓废的策略是典型的说谎者策略,说谎者通过模仿真理,通过使他的谎言较真理更为可信来进行欺骗。因此,在它对生活的憎恨中,颓废伪装成一种较高层次生活的崇奉者,而且因为它精通哄骗的艺术,它能够使虚弱显得像有力,衰竭显得像充盈,怯懦显得像勇武。颓废是危险的,因为它总是将自己伪装成与它相反的东西。
瓦格纳,这位 “现代性的卡廖斯特罗 11 ”,是一个 “典型的颓废者,他对于他腐败了的趣味有一种必需感,他声称它是一种较高级的趣味,他懂得如何让他的趣味被当作法则、进步和满足来接受。” 56 按照这种逻辑,某种显得颓废的事物,某种确凿无疑地呈现出 “衰朽迹象” 的事物,也许同颓废关系不大或是毫不相干。举例来说,我们不妨想想《快乐的科学》中的两段箴言(I,23,24)。第一段题为“腐败的迹象”,尼采写作这一段时脑子里想着的显然是罗马颓废时期,而它最终也成为重新估价该时期和为该时期正名的一种尝试,以破除那些通常用来描绘该时期的陈词滥调(腐败,迷信,衰竭,道德败坏,等等)。在这位哲学家的锐利目光下,所有这些消极特征都显露出一种积极的内容。尼采认为,迷信“实际上是启蒙的一种征兆”,因为“同那些皈依宗教的人相比,迷信的人更大程度上是一个人;一个迷信的社会是一个有着许多个体的社会,它必然喜爱个体性”。 57 他还进一步表明,理所当然地把腐败和颓废相联系也是不正确的:
普遍被忽视的是,辉煌灿烂地表现在战争和类似战争的运动会中的古代民族能量和民族激情,如今已转变成无数的私人激情…… 恰恰是在那些 “衰竭” 的时期,悲剧会遍布家庭与街巷,会诞生伟大的爱与伟大的恨,而且知识的火焰会照耀苍穹。
我们在论述的结尾部分被告知,这类 “腐败” 的时代 “是那些苹果从树上坠落的时代;我指的是个人,因为他们带有未来的种子…… 腐败仅仅是用来指一个民族的秋天的一个低级词。” 如我们将会看到的,对尼采来说这样一个自然过程并不必然同颓废相联系,颓废是意志状况的一种现象——它是生活意志的丧失,这种丧失促成了一种针对生活的复仇态度,并通过憎恨(ressentiment)来表现自身。 58
照这么理解,颓废——总是涉及到自我欺骗——是一种恒久的危险,属于每一个时代,而不仅仅属于那些习惯地被认为颓废的时代。与上面刚刚引述过的那段箴言相比,题为 “各种不满足” 的那段箴言同实际颓废的问题要接近得多。但是在这里,处在弥漫于《快乐的科学》全书的那种非神秘化情绪中,尼采又一次选择去指出真实颓废(同他称为 “中国式‘快乐’” 的那种可怕选择相对立)的一些有益后果。箴言以一种典型的尼采式区分开头,这种区分的一方是弱小的和准女性的类型,另一方是强壮的或男性的类型,但这种区分是以一种出乎意料的方式提出的,至少对受到有关尼采的种种流行滥调影响的读者来说是如此。女性类型赋有一种 “使生活变得更美、更深沉的感受力”,它自中世纪之后盛行于欧洲。它偶尔受到欺骗,并满足于“些须的陶醉和奔放热情,尽管它从不能整个儿得到满足,还为其不满足的不可救药所苦”。尼采强调,这种类型应为“现实灾难的延续” 负责,但同时,没有了它,“欧洲那备受称颂的不断变化的能力也许根本就不会存在,因为在那些不满足者中间强者的要求太过残酷”。
相反的情况在中国发生过,在那儿 “大规模的不满足和变化的能力在几个世纪前就已经绝迹”。同中国的选择相对照,欧洲的“女性式不满足” 最终被表明是一种真正的福气:
欧洲的社会主义者和国家崇拜者,以及他们让生活变得更好更安全的措施,也许易于在欧洲确立其地位;中国的状况和一种中国式 “快乐” 也是如此,只要它们首先能够根除那种较病态、较柔弱、更女性化的不满足,以及那种至今仍在我们这儿极度繁盛的浪漫主义。欧洲是病了,但她应该无比感激她的不可救药,感激在她磨难中的永恒变化:这些始终新异的状况…… 已最终生成了一种理知兴奋性,这种理知兴奋性接近于天才,并且在任何情况下都是天才之母。 59
尼采对欧洲精神(他把它同德国国家主义令人窒息的狭隘性相对比)的喜爱,以及他关于危险地生活的著名格言,应该根据上面刚刚提到的那些观点来理解。至于颓废,最重要的是要识别它,意识到它,而且不被它的种种伎俩和伪装所误导。被尼采后期遗著的编者们收入《权力意志》的一系列笔记表明了这一点。由于颓废是生活一个无法回避的方面,它不是什么需要与之作斗争的东西;它是一个必然现象,属于每一个时代和每一个民族。需要与之作斗争的是机体健康部分的感染。 60 必须始终记住,对尼采来说,这种感染并非生理学的问题(在生理学上衰败同生长一样合乎自然),而完全是心理学的问题。
因此,一个人可以是有病的或虚弱的却无需是一个颓废者:只有当一个人冀求虚弱时他才是颓废者。区别在于实际的生病和病态的不同(对后者做道德推论就是 “在敌人面前退让和隐忍”)。尼采强调:“健康与疾病并非本质上不同…… 不应该把它们理解成为争夺活的机体而战并把它变成角斗场的截然不同的原则或实体。那是愚蠢的扯淡……” 61 因而,颓废作为一种心理、道德或美学的自我欺骗而出现,而作为这种自我欺骗的结果,就像尼采所说的,虚弱成为一种目标。
有关颓废的最有害神秘化导致原因和结果的混淆。颓废精神使正常的视角虚假化,使它的结果看起来成为了它的原因。如果这种误解不驱除,同颓废做斗争(同它所认为的原因做斗争,这些原因实际上只是它的结果)就将是一个全然堂吉诃德式的举动,这种举动只会走到其目标的反面,即促进颓废。尼采多次强调了这关键的一点:
人们混淆原因和结果:人们未能把颓废理解成一种心理状况,并把它的结果误当成这种不适的真正原因;例如:所有的宗教道德。 62
如果我们接受雅斯贝尔斯著名的方法论忠告,在尼采的著作中寻找与上面引述过的那些话相矛盾的段落,我们很快就会认识到这一点儿也不困难,并且认识到在他的大部分著作中,这位哲学家事实上都是人是一种 “幻想动物” 这一观点的公开维护者。作为 “幻想动物”,人的伟大由他的幻觉意志(will to illusion)、由他发明一整套使现实虚假化的幻想概念和欺骗机制的能力得到衡量。实际上在尼采的大量箴言中,数学和逻辑概念,科学法则,以及像理性、真理、原因、结果、主体和客体这一类的基本哲学概念,都被认为仅仅是虚构;而且在这些箴言中,人类知识被看成全然的隐喻活动。汉斯 · 费因格尔在他的《“仿佛” 哲学》中以重要的一章论述尼采,并提供了丰富的引语——如果说不乏偏见的话——以支持他的主张,他认为查拉图斯特拉的作者是一个 “幻觉意志” 的哲学家,是一个“仿佛形而上学”(Metaphysic of As-if)的先驱。 63 费因格尔显然意识到了这类概念对于美学(它们来源于美学)和伦理学的意义,但他的讨论仅限于有关认识论的问题。就此而言,我们可以指责他回避了一系列问题,而这些问题无论有多困难,也应被一个对尼采著作作整体研究的学者提出来并予以解答。比如说,如果艺术的本性是审美游戏和渴望幻觉,为什么瓦格纳会被指控为一个幻觉主义者和说谎者?瓦格纳的说谎中如此成问题的是什么,特别是对一个能写出下述文字的人来说(引文出自费因格尔的著作):“哈,现在我们必须拥抱非真实,现在错误终于变成一个谎言……”? 64
费因格尔的一般做法是只选择那些尼采谈到说谎、神话化和虚构的段落,而忽略所有那些表达了明显相反观念的段落。尼采有时候在坏的意义上接受虚构这一事实仅仅被简略而无关紧要地提到,尽管他指出了 “坏的虚构” 同“作为道德基础的那些概念”之间的关系。 65 但费因格尔显然没有分享尼采的反宗教情感。这使得他在论尼采一章的结尾推测,若非为疾病所中断,尼采的哲学生涯会采取什么样的方向。“他不会废止《反基督》…… 但他将会以同样无情的坦率去表现‘邪恶事物的正面’:他将会‘证明’那些宗教虚构的有用性和必要性。” 66 谁知道呢?
不管怎么说,为了理解尼采对于颓废的态度,重要的是要认识到,对他来说,无论是真理还是谬误、虚构或谎言,仅就它们自身而言并无任何价值。只有就它们同生活的关系,就它们是促进还是妨碍生活来看,它们才会具有积极的或消极的价值。就像格奥尔格 · 齐美尔在他的文章《现代文化的冲突》(1914 年,1918 年发表)中指出的,尼采
从生活本身之中发现了生活的目的,这种目的是受到外部的否认的。这种生活就其本性来说是增值、丰富和发展,它趋向于完满与力量,趋向于一种从它本身流溢而出的力与美…… 唯有生活的原初事实才提供了意义与尺度,积极的或消极的价值。 67
正是这种对生活的极端珍视,为尼采重估一切价值的宏伟计划提供了根据,并可以解释其思想狂热的辩证特质。
因此,尼采能够为超道德意义上的说谎辩护(如在费因格尔很重视的 1873 年片断《论超道德思考中的生存与谎言》中),也能够把瓦格纳的音乐作为颓废(道德)谎言的范例加以拒绝,而且并不会自相矛盾。完全是一个视角问题,在此想想尼采曾把他自己的哲学说成 “[[视角主义]]”(perspectivism)也许不无益处。在下述两者之间有着巨大的区别:人们借以认识到真理是虚构(生活的一种创造,旨在帮助它达到自己的目的)的视角,和颓废者借以把真理性赋予某种虚构的视角——这种虚构在某些情况下甚至以生活的名义被证明是合理的。如果我们把自己置于第一种视角,我们的心智所努力的就是一种富有成效的方向,在其中幻象变得自觉——而自觉通常是一种解放和提升生活的力量。相反,当我们把幻象当成现实,当我们赋予它以真理的“道德” 荣光时,我们就使自己看不见它的本性,并成为无生命教条的奴隶。尼采似乎暗示,道德戕害了幻觉有生命力的方面(也是意识会使之增强的方面),并开启了坏信念和自我欺骗之门。尼采认为存在于真理与虚假、现实与幻想或知识与创造之间的复杂关系,可以同样有效地用于生活的目的和相反的憎恨与报复生活的目的。这种观点实际上并无内在不一致之处。
从术语学的角度看,有一点是很有趣的:尼采是在比较晚的阶段开始使用 “颓废”(用法语的拼写形式,décadence)一词的。有人认为,阅读保罗 · 布尔热的《当代心理学论文集》(1883)对尼采采纳这个术语具有决定意义,但瓦尔特 · 考夫曼排除了这种错误看法,他指出该词首次出现在大约写于 1878 年的一个文本中,是在布尔热的《论文集》出版的五年之前。在该文本中,尼采说塞万提斯的《堂吉诃德》“属于西班牙文化的颓废”。 68 然而,毫无疑问的是,尼采从布尔热那里获得了 “颓废者” 这个名词,布尔热是第一个使用该词的杰出法国作家(如我们已经看到的,它出现在龚古尔兄弟《日记》里那些较早的、标明了日期的记录中,但《日记》只是在 1887 年才开始发表)。同样明显的是,在读了布尔热的书之后,尼采使用了 “颓废风格” 这一特定术语。不仅如此,在《论瓦格纳》中,尼采有关 “颓废风格” 的著名定义显然是在译述布尔热的思想:
每一种文学颓废的标志是什么?生活不再作为整体而存在。词语变成主宰并从句子中跳脱而出,句子伸展到书页之外并模糊了书页的意义,书页以牺牲作品整体为代价获得了生命——整体不再是整体。但这是对每一种颓废风格的明喻:每一次,原子的混乱,意志的瓦解…… 69
一个突出的事实是,这个借用的段落放在《瓦格纳的没落》和其他尼采晚期著作的语境中来读,就不仅显得具有独创性,而且确实具有独创性;之所以如此,是因为尼采联系于颓废概念的那些复杂而富于辩证矛盾的含义使它得到了丰富——其得到丰富的程度使人们能够把它看作尼采自己 “单子论” 风格的定义,就像瓦尔特 · 考夫曼所认为的那样。 70 就此而言,应该十分严肃地对待尼采关于自己已经是一个颓废者的申言——一个 “自我克服” 的颓废者。同时,这样一种明显的译述能够获得原作所不具有的意义与特质的事实(富有悖论意味的是,布尔热今天还能被记住似乎主要是因为尼采对他的赞扬),可以驳斥夸大这位特定法国作家对这位德国思想家的影响的做法。这么说也许更正确:尼采对 “颓废” 和“颓废者”这两个法语词(后一个词几乎可以肯定是取自布尔热)以及布尔热文化颓废理论的某些方面的采纳,是他长期而密切地熟悉法国文学与哲学的结果,也是他思考自十七世纪以来法国颓废这一更广泛主题的结果。如我们在前面已看到的,在 1848 年之后,颓废的感觉在法国广为流行,而且在 1870 年以后,这种感觉急剧增强。尼采之受惠于布尔热,应放在众所周知的尼采与法国文化的契合这一背景中来看,这种契合已得到令人满意的研究,其中之一是由 W.D. 威廉斯在他的《尼采与法国人》中作出的。 71
颓废和颓废者这两个词给尼采提供了综合和统一大量相关概念(没落、堕落、病态等)的机会,这些概念是他的生 / 死辩证法的构成元素。他的颓废概念实际上源于他对德国文化现代性的反动(早在 1873-1874 年他的 “无时间性” 的强有力观念中就很明显),以及他对浪漫主义的批评——他是最早强调浪漫主义与现代性关系的人之一;这两方面的原因要甚于他对法国文化的态度。尼采把浪漫主义作为颓废的一种表现形式加以拒绝,这使我们想起歌德的名言,“古典是健康的,浪漫主义是病态的”。尼采生机论哲学的另一核心观点也可以联系到歌德同样著名的思想,即“生活的目的是生活本身”。我们可以说,同尼扎尔之后的法国保守主义批评及其公开将浪漫主义和颓废相提并论的做法相比,歌德对作为浪漫主义批评者的尼采有着远为深厚的影响。在很大的程度上,正是歌德思想中他最为推崇的东西,使得尼采能够诊断出他两位青年时代伟大偶像叔本华和瓦格纳所患有的“浪漫病”。甚至尼采早期对狄奥尼索斯精神和阿波罗精神的区分也可能要归因于歌德,而他后来对这种区分的修正则肯定是得益于这位“现有最好的德语书”(《与艾克曼的谈话》)的作者,在他的修正中,狄奥尼索斯精神,包括阿波罗精神,变得与颓废的浪漫主义相对立。有趣的是,正是老歌德体现了尼采在他的哲学生涯将近结束之时所设想的狄奥尼索斯精神。在《偶像的黄昏》(发表于 1889 年初)中,他写道,歌德“并非一个德国的事件,而是一个欧洲的事件”:
…… 通过回归自然和追怀文艺复兴的自然性而克服十八世纪的宏伟努力——在这个世纪来说是一种自我克服…… 他用有限的视野包围着自己;他没有退出生活,而是将自己置于生活之中;他无怯懦之心,而是尽可能地担当自己、掌握自己、接纳自己。他企求的是总体性…… 在一个有着不现实观点的时代当中,歌德是一个无可置疑的现实主义者:他对与此相关的任何事物说 “是”——而他的经历不比叫做拿破仑的那位现实主义者伟大…… 这样一个已经自由了的精神站在宇宙之中,带着快乐而轻信的宿命论,相信唯有个别是可憎的,相信在整体中一切皆是受到尊敬与肯定的——他不再否定。然而,这样一种信念是所有可能信念的极致:我已经用狄奥尼索斯之名给它施洗。 72
作为一个历史人物,歌德也许是尼采愿意比较具体地给出的最接近他所理解的 “超人” 的实例。但在一个为 “倦怠本能” 与“情感浪漫主义”所支配的颓废、“混乱”和 “极度困惑” 的时期,歌德 “仅仅” 是一个“插曲”:“难道十九世纪…… 不只是一个被强化和野蛮化了的十八世纪,亦即,一个颓废的世纪吗?” 73
只有考虑到尼采对叔本华和瓦格纳的批评的细节,同时考虑到他对歌德所象征的精神的崇敬,他的颓废理论才能显露出它的全部哲学和美学意义。尼采针对叔本华和瓦格纳两人的论辩充满着至为强烈和真诚的理知情愫,就他的颓废概念来说,这种论辩比他针对从卢梭到波德莱尔的法国颓废者的任何言辞都更富启发性(卢梭显然是所有法国思想家中受到最猛烈攻击的)。考察尼采哲学同叔本华的关系会使我们走得太远,进入一些在此与我们并无直接关系的问题,因此我将让自己限于讨论瓦格纳的 “情形”。这将为把尼采的颓废观置于他的一般艺术观念这个较大框架中提供机会。
像哲学一样,艺术旨在服务于生活,它的具体任务是以一种在美学上有意义的方式组织经验。问题是:艺术促进的是哪一种生活?尼采说,
每一种艺术,每一种哲学,都可以视为一种救助,它要么服务于正在成长的生活,要么服务于正在没落的生活:它总是预设了受难或受难者。但有两类受难者:首先是那些因生活过度完满而受难的人,他们需要一种狄奥尼索斯式的艺术,以及一种对于生活的悲剧洞察力与观点——其次是那些因生活的贫乏而受难的人,他们需要艺术与哲学、镇静、阒寂、风平浪静的海洋,或是另一方面,疯狂、骚动和麻木。向生活本身报复——对那些如此贫乏的人来说,这是最能获得满足感的一种疯狂! 74
在艺术的谱系中,尼采认为音乐一般来说是迟到者,在任何特定的文化中,它都是作为典型的秋季产品而出现的:
在各种艺术中,音乐作为最后的作物而出现…… 它最后一个来临,在秋天,当它所属的文化正在暗淡之时…… 唯有莫扎特把路易十四时代和拉辛与克洛德 · 洛兰的艺术变成了清音泠泠的黄金;唯有在贝多芬和罗西尼的音乐中十八世纪才高歌引退…… 所有真正的、独创的音乐都是天鹅之歌。 75
然而,这并不意味着所有的音乐都是颓废的。如前面已经指出的,对尼采来说,颓废是一个 “意志” 问题,是一种“理想”,它不是没落本身(没落乃生命的一个事实,否认它就是胆怯),而是接受和促进没落。即使是在现代性的全面颓废情形中,尼采也承认一种音乐的可能性,这种音乐“不再像德国音乐那样有着浪漫派的起源…… 而是有着狄奥尼索斯式的起源”。 76 《论瓦格纳》的第一节提供了一个例子:比才的《卡门》,被认为是瓦格纳式颓废的绝然对立物。如果我们反过来理解尼采描述比才的词句,我们就以集中的形式获得了他反对瓦格纳的主要论点。
这种音乐对我来说显得完美。它轻快、柔婉、雅致地到来。它是快乐的,它不费力…… 这种音乐是邪恶的,隐隐中带有宿命论色彩:同时它仍然是通俗的…… 它的奥妙属于一个种族,而非某个个人。它建构,它组织、完成:因此它构成音乐中息肉的对立面,“无限的旋律”。在舞台上曾听到过更令人痛苦的悲剧口吻吗?没有鬼脸。没有造作。没有风格宏伟的谎言。 77
至于瓦格纳,他将浪漫派的颓废精神推向极致——他是伟大的说谎者:他的 “音乐从不真实。但它被当成真实的……” 78 这里 “真实” 在有限的意义上意味着 “忠实” 于音乐本身的特征,“忠实”于音乐作为一种自主艺术的特征,正是这种自主性使它在美学上获得存在的理由。瓦格纳的说谎就在于他把音乐用于本质上非音乐的目的。这里尼采运用了一个自尼扎尔之后在颓废理论中很常见的概念,我们记得,尼扎尔指责维克多 · 雨果用词语作画,也就是说,用词语去获得那些典型地属于一种不同于诗歌的艺术的效果。但尼采的洞察力远远较尼扎尔和其他先前的颓废理论家深刻。瓦格纳对音乐的歪曲不代表对一门艺术之特性的一种偶然偏离——它表达了现代性的整个危机,这种危机表现在尼采所说的 “戏剧政体”(theatrocracy)中,他的这种说法非常富有启发性。瓦格纳是一个“无与伦比的表演者”,一个演员。他不是一个误入歧途的音乐家,也不是一个诗人,他只是一个天才的演员——“他成为一个音乐家,他成为一个诗人,因为他体内的暴君(他的演员天才)迫使他如此。” 因而,
瓦格纳不是一个出自本能的音乐家。他以此表明了这一点:抛弃音乐中所有的规则性,更具体地说也就是抛弃音乐中所有的风格,以便把它变成他所需要的东西,戏剧修辞,一种表现的手段,一种强调姿势的手段,一种暗示的手段,一种创造心理生动效果的手段…… 他是音乐语言中的维克多 · 雨果。他总是假定人们首先得允许在某些情况下音乐可以不是音乐,而是语言、工具和戏剧辅助手段。如果不是托庇于一种非常宽容的戏剧趣味,瓦格纳的音乐根本就是糟糕的音乐,也许是所有音乐中最糟糕的。 79
瓦格纳和维克多 · 雨果之间的比较极其有趣。尼采是否在布尔热之外还知道了尼扎尔呢?后者曾把他的颓废理论具体应用到维克多 · 雨果身上。不管怎样,尼采——想想他的哲学和美学信念——天生就倾向于不喜欢雨果的整个人格,特别是他的社会浪漫主义。即使尼采熟悉尼扎尔对雨果的拒斥,他也通过比较雨果和瓦格纳开启了一种认识现代颓废现象的全新视角。同 “精英主义” 的颓废观相反,尼采属于最早强调颓废艺术取悦群众(crowd-pleasing)特性的人,这种特性既表现在雨果也表现在瓦格纳的作品中:
维克多 · 雨果和理查德 · 瓦格纳——他们意味着同一件事:在没落的文化中,任何由大众来做决定的地方,真实性就变得多余、可鄙,变成了一种有害无益之物。唯有演员还能唤取巨大热情。 80
值得指出的是,在强调比才音乐的 “通俗” 特性时,尼采谈到了雨果和瓦格纳之类艺术家对大众的吸引力。现代性导致戏剧政体,因为“戏剧是一种趣味上的大众崇拜:戏剧是大众的反叛,一种针对好趣味的平民公决。——这正是瓦格纳的情形所证明的:他赢得了群众,他败坏了趣味,他甚至破坏了我们对于歌剧的趣味”。 81 在此尼采非常接近于为二十世纪中期将由 “媚俗艺术” 一词来指称的事物提出一个定义。媚俗艺术是作为一个审美范畴的坏趣味。同时,尼采在此引入了 “大众的反叛” 这一较大主题——由于奥尔特加 · 伊 · 加塞特 1930 年富有争议的著作《大众的反叛》,这个主题变得众所周知。
尼采肯定意识到了基督教的现代危机。这个伟大的颓废宗教经历了一个解体的过程,该过程以较大的规模开始于十九世纪八十年代期间,在同一个世纪里,哲学家尼采发现了现代性最早的准确无误标志。但是,他为何要说现代性本质上是颓废的呢?这个问题的答案可以测度出尼采的思想与前辈和同时代历史哲学家们相比所具有的原创性:现代性从基督教中继承的不是一套符号(其中一些令尼采着迷),而是一种深沉的憎恨精神,对于生活的敌意。而且没有了基督教的特殊符号和教条也无损于这种敌意,它把全部的 “现代” 世俗理知神话用于自己的目的。尼采敏锐地直觉到,现代性的时间意识同犹太——基督教的时间概念并无本质的不同,正是这种直觉使他把 “永恒回归” 的观念变成了他哲学的核心。
尼采是最早指出表面上反基督教的现代性暗中受惠于基督教的西方思想家之一。这种观点被接受,半个世纪后,奥尔特加 · 伊 · 加塞特——也许是最有才华的尼采追随者——差不多是理所当然地强调基督教对于现代性的影响。在《现代主题》一书 “对生活的各种评价” 一章中,奥尔特加写道:
现代各时期代表了一场对基督教的圣战…… 到十八世纪中期,据称要来临的神圣世界已烟消云散。此生乃留给人类的一切…… 最近几个世纪的思想尽管是反基督教的,我们却看到它采取了一种同基督教生活态度极其相似的生活态度。
之所以如此,是因为现代的 “文化学说” 只不过是 “一种没有上帝的基督教”。从现代文化“进步主义” 的角度,奥尔特加强调,生活本质上是一种现时事实,它的意义和价值永远都保有对一个更文明的黎明的意识,它就如此延续着。真实存在永远处在从属的层次上,仅仅是通向一个乌托邦未来的一种过渡。文化的学说、进步、未来主义和乌托邦主义都是一种独一无二的主义。 82
奥尔特加在很大程度上以尼采的精神总结说,同基督教和现代世界相比,在古代世界中,生活较少受到 “超生命价值”(trans-vital values)的影响。
尼采会说,超生命的价值根本上就是反生命的价值,从而也是颓废的标志。当颓废把生活本身之外的意义归于生活时,当它引入一个救赎的 “彼岸” 的观念时(无论这个 “彼岸” 是根据基督教的 “死后生活” 还是根据现代的世俗乌托邦构想出来的),它就是在反对生活。从美学上讲,现代颓废者——以瓦格纳为代表——可以很容易地从革命主义走到虚无主义再走到基督教。所有这些可供选择的形式都表达了同样的对于救赎的基本需求,并试图颠覆真实生活的“趋附”(Yes-saying)精神。但是在一个没有颓废的世界中,生活如何才能自觉地意识到它的意义呢?如果没有颓废——没有诱惑,人们又如何践行必不可少的克己艺术呢?尼采没有回答这些。没有颓废——没有一种真正的危险,道德(或非道德)勇气的概念,戏剧和悲剧意识的概念,还有尼采哲学的许多其他核心概念,就全然没有了意义。归根结底,尼采不仅仅是把自己作为一个颓废者在克服——富有讽刺意味的是,他还创作了最完美的“荣耀归于颓废者”。
尼采的颓废理论最终是一种意识形态理论和一种意识形态批判。尽管通行的 “虚假意识” 意义上的意识形态概念来自于马克思,应该说,尼采对颓废特别是对现代颓废的分析,构成了对一般意识形态做全面而激进批判的最初尝试,其中还特别强调了现代资产阶级意识形态,包括有关现代性的各种意识形态。如果我们撇开马克思和恩格斯在意识形态问题上提出的零星观点不谈,在整个十九世纪,没有什么思想学说能稍稍接近尼采颓废哲学所具有的辩证复杂性和深刻性。卡尔 · 曼海姆是二十世纪知识社会学的领袖人物,他认识到马克思和尼采是新的意识形态批判的两个重要先驱。关于尼采,他写道:
现代意识形态理论和知识社会学的另一个源头要在尼采时时闪现的真知灼见中去找,尼采把这一领域中的具体观察同一种欲望理论和一种知识理论结合起来,这两种理论使人想起实用主义…… 从尼采往下而发展衍化出弗洛伊德和帕累托的原初冲动理论,以及他们通过把人类思想看成扭曲、看成本能机制的产物而得出的那些方法。 83
香港的旧书市-戴望舒
========================
香港的旧书市-[[戴望舒]]
------
这里有生意经,也有神话。
香港人对于书的估价,往往是会使外方人吃惊的。明清善本书可以论斤称,而一部极平常的书却会被人视为稀世之珍。一位朋友告诉我,他的亲戚珍藏着一部《中华民国邮政地图》,待价而沽,须港币五千元(合国币四百万元)方肯出让。这等奇闻,恐怕只有在那个小岛上听得到吧。版本自然更谈不到,“明版康熙字典”一类的笑谈,在那里也是家常便饭了。
这样的一个地方,旧书市的性质自然和北平、上海、苏州、杭州、南京等地不同。不但是规模的大小而已,就连收买的方式和售出的对象,也都有很大的差别。那里卖旧书的仅是一些变相的地摊,沿街靠壁钉一两个木板架子,搭一个避风雨的遮棚,如此而已。收书是论斤断秤的,道林纸和报纸印的书每斤出价约港币一二毫,而全张报纸的价钱却反而高一倍;有硬面书皮的洋装书更便宜一点,因为纸板“重秤”,中国纸的线装书,出到一毫一斤就是最高的价钱了。他们比较肯出价钱的倒是学校用的教科书、簿记学书、研究养鸡养兔的书等,因为要这些书的人是非购不可的,所以他们也就肯以高价收入了。其次是医科和工科用书,为的是转运内地可以卖很高的价钱。此外便剩下“杂书”,只得卖给那些不大肯出钱的他们所谓“藏家”和“睇家”了。他们最大的主顾是小贩。这并不是说香港小贩最深知读书之“实惠”的人,在他们是无足重轻的。
旧书摊最多的是皇后大道中央戏院附近的楼梯街,现在共有五个摊子。从大道拾级上去,左手第一家是“龄记”,管摊的是一个十余岁的孩子(他父亲则在下面一点公厕旁边摆废纸摊),年纪最小,却懂得许多事。著《相对论》的是爱因斯坦,歌德是德国大文豪,他都头头是道。日寇占领香港后,这摊子收到了大批德日文学书,现在已卖得一本也不剩,又经过了一次失窃,现在已没有什么好东西了。隔壁是“焯记”,摊主是一个老是有礼貌的中年人,专卖中国铅印书,价钱可不便宜,不看也没有什么关系。他对面是“季记”,管摊的是姐妹二人。到底是女人,收书卖书都差点功夫。虽则有时能看顾客的眼色和态度见风使舵,可是索价总嫌“离谱”(粤语不合分寸)一点。从前还有一些四部丛刊零本,现在却单靠卖教科书和字帖了。“季记”隔壁本来还有“江培记”,因为生意不好,已把存货称给鸭巴甸街的“黄沛记”,摊位也顶给卖旧铜烂铁的了。上去一点,在摩罗街口,是“德信书店”,虽号称书店,却仍旧还是一个摊子。主持人是一对少年夫妇,书相当多,可是也相当贵。他以为是好书,就一分钱也不让价,反之,没有被他注意的书,讨价之廉竟会使人不相信。“格吕尼”版的波德莱尔的《恶之华》和韩波的《作品集》,两册只讨港币一元,希米忒的《莎士比亚字典》会论斤称给你,这等事在我们看来,差不多有点近乎神话了。“德信书店”隔壁是“华记”。虽则摊号仍是“华记”,老板却已换过了。原来的老板是一家父母兄弟四人,在沦陷期中旧书全盛时代,他们在楼梯街竟拥有两个摊子之多。一个是现在这老地方,一个是在“焯记”隔壁,现在已变成旧衣摊了。因为来路稀少,顾客不多,他们便把滞销的书盘给了现在的管摊人,带着好销一些的书到广州去开店了,听说生意还不错呢。现在的“华记”已不如从前远甚,可是因为地利的关系(因为这是这条街第一个摊子,经荷里活道拿下旧书来卖的,第一先经过他的手,好的便宜的,他有选择的优先权),有时还有一点好东西。
在楼梯街,当你走到了“华记”的时候,书市便到了尽头。那时你便向左转,沿着荷里活道走两三百步,于是你便走到鸭巴甸街口。
鸭巴甸街的书摊名声还远不及楼梯街的大,规模也比较小一点,书类也比较新一点。可是那里的书,一般地说来,是比较便宜点。下坡左首第一家是“黄沛记”,摊主是世业旧书的,所以对于木版书的知识,是比其余的丰富得多,可是对于西文书,就十分外行了。在各摊中,这是取价最廉的一个。他抱着薄利多销主义,所以虽在米珠薪桂的时期,虽则有八口之家,他还是每餐可以饮二两双蒸酒。可是近来他的摊子上也没有什么书,只剩下大批无人过问的日文书,和往日收下来的瓷器古董了。“黄沛记”对面是“董莹光”,也是鸭巴甸街的一个老土地。可是人们却称呼他为“大光灯”。大光灯意思就是煤油打气灯。因为战前这个摊子除了卖旧书以外还出租煤油打气灯。那些“大光灯”现在已不存在了,而这雅号却留了下来。“大光灯”的书本来是不贵的,可是近来的索价却大大地“离谱”。据内中人说,因为有几次随便开了大价,居然有人照付了,他卖出味道来,以后就一味地上天讨价了。从“董莹光”走下几步,开在一个店铺中的,是“萧建英”。如果你说他是书摊,他一定会跳起来,因为在楼梯街和鸭巴甸街这两条街上,他是唯一有店铺的——虽则是极其简陋的店铺。管店的是兄弟二人。那做哥哥的人称之为“高佬”,因为又高又瘦。他从前是送行情单的,路头很熟,现在也差不多整天不在店,却四面奔走着收书。实际上在做生意的是他的十四五岁的弟弟。虽则还是一个孩子,做生意的本领却比哥哥更好,抓定了一个价钱之后,你就莫想他让一步。所以你想便宜一点,还是和“高佬”相商。因为“高佬”收得勤,书摊是常常有新书的。可是,近几月以来,因为来源涸绝,不得不把店面的一半分租给另一个专卖翻版书的摊子了。
在现在的“萧建英”斜对面,战前还有一家“民生书店”,是香港唯一专卖线装古书的书店,而且还代顾客装潢书籍号书根。工作不能算顶好,可是在香港却是独一无二的。不幸在香港沦陷后就关了门,现在,如果在香港想补裱古书,除了送到广州去以外就毫无办法了。
鸭巴甸街的书摊尽于此矣,香港的书市也就到了尽头了。此外,东碎西碎还有几家书摊,如中环街市旁以卖废纸为主的一家,西营盘兼卖教科书的“肥林”,跑马地黄泥甬道以租书为主的一家,可是绝少有可买的书,奉劝不必劳驾。再等而下之,那就是禧利街晚间的地道的地摊子了。
小说之未来为小说开刀或掷一颗炸弹118- D.H.劳伦斯
========================
小说之未来为小说开刀或掷一颗炸弹118- [[D.H.劳伦斯]]
------
你谈论一个孩童的未来,看着他躺在摇篮里那胖嘟嘟的样子,听他咿咿呀呀,此时这无疑是个浪漫迷人的话题。当一个邪恶的老爷爷躺在死榻之时,你也会与牧师谈这弥留老夫的未来。此时此刻的心情则大不相同,要迷惘得多,主要还是恐惧吧。
那么我们怎么看待小说呢?当我们畅想未来的优秀作家时,我们会感到欢欣鼓舞吗?或许我们会阴郁地摇摇头,希望这号儿邪性的家伙再多坚持几日?
小说到底是卧于死榻之上的老罪人呢还是围着摇篮蹒跚着的小乖乖?
在我们下结论之前,还是再看他一眼吧。
现代小说是个多面魔鬼,像一棵枝桠繁杂的树。其两面性就如同一胎连体人一样:一面是苍白但高雅的严肃小说,你不得不严肃地对待它;而另一面则是一个花言巧语假笑的轻佻女子,人称通俗小说。
先让我们来号一号严肃的百手巨人和他们的作品的脉搏,如《尤利西斯》,朵萝西·理查森女士119和马赛·普鲁斯特120先生。然后再来看看另一边的心跳,如《酋长》121和基恩·格雷先生122,还可以加上罗伯特·钱伯斯先生123等等。
《尤利西斯》是在摇篮之中吗?还摇篮呢,瞧它那张阴沉脸儿!《尖屋顶》(朵萝西·理查森著),是小女孩们的漂亮玩具吗?那位普鲁斯特又算怎么回事?
哦,你可以听到他们嗓子眼里死亡的咕噜声。他们自个儿也听得到。他们聚精会神地倾听,是想发现这嗓子眼里的死亡之声是小三度还是大四度的。这副样子倒真像儿童了。
你刚看到了,“严肃”小说正在拖着长长的十四卷124痛不欲生,其作者却又像孩子一样对这种现象入了迷。“我的小脚指头是不是有点疼?疼还是不疼呢?”乔伊斯先生、理查森女士和普鲁斯特先生的小说中几乎每个人物都问这个。他们还会问:“我的汗味是不是乳香、橘香与鞋油的混合香味儿?要么就是药味、咸肉油味和呢服味的混合味?”
死榻周围的听众凝神屏息等待答案,可一直读了几百页后才发现一个阴郁的声音说:“全都不是,是可怕的杂味儿。”于是听众浑身一颤,咕哝一声:“我觉得也是这么回事儿。”
这就是行将就木的严肃小说之无聊、冗长的喜剧。它把自我感觉撕碎成精制的小碎片,碎得几乎看不见,必得用嗅觉来发现它们才行。乔伊斯先生和理查森女士用自己万儿八千页的小说把自己撕成碎片,把最细微的情感都劈成最纤细的细线。读这种小说你会感到你内心深处织起的一片毛毯正被缓缓抖落着,你随之变成了羊毛。
这不好,因为太孩子气了。到了一定年龄再如此这般地自我沉醉,实在是孩子气。自我沉醉在豆蔻之年是自然而然的事,在弱冠之年还可以自我沉醉一点,可过了而立还这样,那只能说明你的人格发展迟滞了,不会是别的毛病。若是此种症状在近知天命的岁数上依然如故,很明显,你是个老小孩。
严肃小说就是如此,是老小孩。它总孩子般地沉溺于“我是什么”的问题。“我是这个,我是那个,我是别的。我的反应是这样这样这样。天啊,如果我更仔细地观察自己,如果我更详细地分析我的感情——如果我解开了裤子但不粗野地把解裤子的事说出来,那样我就可以继续写上亿页而不是上千页。事实上,这事越想越粗野,越不文明,怎么能直直地说我解开了裤子呢?总之,这是沉醉于探险!我先解哪一个扣子呢?——?”如此等等。
严肃小说中的人太专注地关心他们自己,他们感觉到了什么和没感觉到什么,他们对每个裤子扣儿的感知都生死攸关。而这类书的读者则同样发狂地关注作者的发现让他们产生什么反应,并且会说:“那就是我!真正如此,我在这书里找到了我自个儿!”天啊,这比死榻还有过之而无不及,几乎是死人的表现。
只有某些大灾变才会让严肃小说摆脱其自我沉醉状。最近的这次大战使它情况更糟了。怎么办呢?
可怜的东西,它真的还很年幼哩。小说从未成熟过,从未长到懂事年龄,它总是幼稚地企盼着最好,但最终总是感到失望无奈。这纯属幼稚。
而这种童稚气却被无限拖长了,不少青少年甚至把他们的青少年期拖到四十岁、五十岁、六十岁,如此而已。
看来非得给他们动动手术才行。
再来看看通俗小说吧,《酋长》们,《巴比特》们125,还有基恩·格雷们,它们同样地沉溺于自我而不能自拔,不同的是它们还对自己抱有更多的幻想。女主角们真的以为自己更可爱,更迷人也更纯情。男主角们真的觉得自己更英雄,更勇敢,更骑士,更迷人。于是群氓们便在通俗小说中也“找到了自个儿”。
可如今他们发现的“自个儿”是滑稽的。手持皮鞭的“酋长”,身上有鞭伤的女主角。可她受到了崇拜,不理会鞭子,只崇拜她身上未被说明的某个部位上看不见的鞭伤。
在通俗小说中他们发现的确是滑稽的自我。《如果冬天将至》126中的基本寓意是十分站不住脚的。“你越善,下场就越惨,可怜的人,可怜啊。千万别太善了,这可不好。”而《巴比特》里则这样说:“接下来,你发了财,然后再装作若无其事,以此压那些唯利是图的肮脏小人一头。这号人发了点财就不知道姓什么了,而你却能压他一头。”
总是这种同样的发酵粉让你发起来:苏打与酒石,酒石与苏打相互作用。《酋长》之类的女主人公,被鞭挞了臀部,却很受人推崇。巴比特们虽腰缠万贯,却自叹命薄而哭泣。“冬天将至”类的男主人公们倒是好样儿的,却给关进了大狱。教训:千万别太善太好,你会因此而坐牢。教训:没发财前不可自怜,没那个必要。教训:如果人家没用鞭子打你让你接受他的崇拜,千万别让人家崇拜你,否则你就成了小小罪恶或神圣婚姻的同谋。
这同样又是孩子气,是长不大的青少年的标志。进入自我意识的圈套中不能自拔,只会在里面发疯,疯得不成样子。把青少年期拖至中年和老年,这就像《董贝父子》中的那个疯老婆子“克莉奥帕特拉”一样,用尽最后一口气叨念着什么“玫瑰色的窗帘啊……”127真是个老巫婆。
小说之未来。可怜的旧小说,它正处在肮脏混乱的一隅,要么翻墙而过,要么砸洞而出。换句话说,它必得长大才行。要放弃那些孩子气的东西诸如:“我爱不爱这女子?”“我是不是既甜美又纯洁?”“我解裤子扣儿是从左边开始还是从右边?”“我母亲拒喝我的新娘子为她煮的可可,这会不会毁了我的生活?”这类问答早已不再吸引我了,尽管世上人们仍在一遍遍旧调重弹。至于我,我根本不在乎我爱不爱那女子,我是否是政府标准下纯洁或不纯洁的人,解裤子从左至右还是从右至左或我母亲怎样看待我。我对这类事再也不上心了,尽管我曾经很上心过。
简言之,这类纯情感的自我分析技巧在我这里玩不转,我没这本事。他们弹什么曲我只当是充耳不闻,他们演什么绝妙的马戏我则视而不见。
但是,我既不是在这方面玩腻了,也非愤世嫉俗,我只是对别的什么更感兴趣。
假如这些东西下面安了一颗炸弹,那我们怎么办?我们打算把什么样的感情带入下个时代?我们将被什么样的感情所裹挟?当这种民主——工业——多情——亲爱的带我找妈妈之状态爆炸后,什么样潜在的冲动能提供实现新状态的动力?
下一步是什么,我对此感兴趣。而现在是什么则了无情趣。如果你想在过去寻找“下一步”,你可以读早期的小说,这些小说作者是圣马太,圣马可,圣路加和圣约翰,这四本书被称作福音书。这些小说中有未来的线索,有新的冲动,新的动力和新的灵感。它们不在乎“现在”怎样或“过去”怎样,对《大街》,《如果冬天将至》,《酋长》或《琉璃蘩缕花》128视而不见。四福音书是要给世界注入新的冲动。
无论用多么高的标准衡量,四福音书也算得上小说,这一点无可否认。
柏拉图的《对话录》也是奇怪的小说呢。
在我看来,世上顶大的不幸就是哲学与小说分了家。它们曾是一家,从神话时代起就是一家子。后来它们就像一对唠叨嘴子夫妻一样分道扬镳了。分出去的人有亚里斯多德,托马斯·阿奎那,还有那不是个东西的康德。于是小说变得毫无条理,而哲学则干巴巴抽象无聊。这两者应该在长篇小说中再次聚首才好,那样我们才会读到现代的福音书,现代的神话,并学到新的理解方式。
你必须在人类身上发现为新事物奋斗的新冲动。但若想通过抽象概念来找到它,那是死活找不到的。甚至在福音书中也有太多的布道。“保佑X、Y和Z”,我根本不在乎X、Y和Z。让我看到汤姆、迪克或亨利这样实实在在的人受到保佑吧。让我看到,汤姆脆弱时他受到了保佑,或者他目中无人时更受保佑。耶稣登山训众时讲的福音里那些X们是要不得的。X若精神贫乏倒情有可原,可如果杰克什么的也这样就招人讨厌了。
不行,不行,哲学和宗教在代数的方向上走得太远了。若X代表羔羊而Y代表山羊,那X-Y就等于天堂,X+Y就等于大地,Y-X就等于地狱了。
谢谢!那么X穿什么颜色的上衣呢?
而另一方面,小说在情感方面又走得太远。在小说中,人们总爱端坐着受感情之苦,或享受感情之乐。但他们从不说:“起来,变它个样儿。”
不。只有类似四福音书的小说或传奇冒险小说如《使徒的行为》129,奥古斯丁的《忏悔录》130或《一个医生的信仰》131,它们才真的要改变感情,对某种真正新鲜的事物进行掘入。而陷在X们、Y们和Z们中间则会给绊倒的。
小说有其未来。它的未来在于取代我们已知的福音书、哲学和今日之小说。它应该有不用抽象概念解决新问题的勇气,它必须向我们展示新的、真正新的感情和整个儿全新的情感轨道,从而使我们摆脱旧的感情套路。与其为现在和过去鼻涕一把泪一把地悲泣或按照旧的路子发明新感觉,倒不如冲破旧的,如同在墙上砸开一个窟窿从中逃出。为此,公众会大为震惊,认为这是大逆不道。原因很简单:你长久挤在一个窄角落里,对其拥挤状态已十分适应,最终甚至会觉得十二分的舒坦。一旦你发现这舒适之墙角上出现了一个明晃晃的洞,你就会惊恐万状。你会吓得躲避起这股清新空气来,似乎这新空气是来害死你的。
但随着一个个胆小鬼从这口子中蹭将出去,他们会发现外面是个崭新的世界。
(本文1923年写于美国新墨西哥。起因是前一年劳伦斯在澳大利亚时看到当地报纸上刊载一篇题为《小说之未来》的文章,作者采访了60位英国作家,里面没有劳伦斯;但其中一位被采访作家却在回答问题时称劳伦斯是“他那代人里最伟大的作家”,“小说的未来掌握在他手中”。到美国后劳伦斯读了乔伊斯《尤利西斯》,对其评价很低,私下里称乔伊斯像一个满脑子污秽的教师。劳伦斯的美国出版商趁机建议劳伦斯写文章批评乔伊斯,但劳伦斯认为那样对乔伊斯“不公平”。他拒绝公开撰文抨击乔伊斯,而是写了这篇对小说之未来的宏观论述,恰逢《国际文学图书评论文摘》向他约稿,就将这篇文章发在该刊上。当然,文中提到《尤利西斯》时还是略有贬低。)
小姨娘-汪曾祺
========================
小姨娘-[[汪曾祺]]
------
小姨娘章叔芳是我的继母的异母妹妹。她比我才大两岁。我们是同学,在同一所初中读书。她比我高一班。她读初三,我读初二。那年她十六岁,我十四。但是在家里我还是叫她小姨娘。
章家是乡下财主。他们原来在章家庄住。章家庄是一个很大的庄子。庄里有好几户靠田产致富的财主,章家在庄里是首户。后来外公在城里南门盖了一所房子,就搬到城里来了。章老头脾气很“藏”,除了几家至亲(也都是他那样的乡下财主),跟谁也不来往。他和城里的上代做过官、有功名的世家绅士不通庆吊。他说:“我不巴结他们!”地方上有关公益的事情,修桥铺路、施药、开粥厂……他一毛不拔,不出一个钱。因此得了一个外号:“章臭屎”。
章家的房子很朴实,没有什么亭台楼阁,但是很轩敞豁亮。砖瓦木料都是全新的。外公奉行朱柏庐治家格言:“黎明即起,洒扫庭院,要内外整洁”。他虽然不亲自洒扫,但要督促佣人。他的大厅上的箩底方砖上连一根草屑也没有。桌椅只是红木的(不是“海梅”、紫檀),但是每天抹拭,定期搽核桃油,光可鉴人、榫头稍有活动,立刻雇工修理。
章家没有花园,却有一座桑园,种的都是湖桑。又不养蚕,种那么多桑树干什么?大厅前面天井里的石条上却摆了十几盆橙子。橙子在我们那不多见。橙子结得很好,下雪天还黄橙橙的挂在枝头,叶子不落,碧绿的。
章家家规很严,我从来没有见过外公笑过。他们家的都不会喝酒。老头子生日、姑奶奶归宁,逢年过节,摆席请客,给客人预备高粱酒,——其实只有我父亲一个人喝,他们自己家的人只喝糯米做的甜酒。席上没有人划拳碰杯,宴后也没有人撒酒疯。家里不许赌钱。过年准许赌五天,但也限于掷骰子赶老羊,不许打麻将,更不许推牌九。在这个家里听不到有人大声说笑,说话声音都很低,整天都是静悄悄的。
章家人都很爱干净,勤理发,勤洗澡,勤换衣裳,什么时候都是精神饱满,容光焕发。章家的人都长得很漂亮。二舅舅、三舅舅都可称为美男子。章老头只是一张圆圆的脸,身体很健壮,外婆也不见得太好看,生的儿女却都那么出众,有点奇怪。
我们初中有两个公认为最好看的女生。一个是胡增淑,一个是章叔芳。胡增淑长得很性感,她走路爱眯着眼,扭腰,袅袅婷婷,真是“烟视媚行”。她深知自己长得好看,从镜子面前经过,反光的玻璃面前,总要放慢脚步,看看自己。章叔芳和胡增淑是两种类型。她长得很挺直,头发剪得短短的,有点像男孩子。眼睛很大,很黑,闪烁有光。她听人说话都是平视。有时眨两下眼睛,表示“哦,是这样!”或“是吗?是这样吗?”她眉宇间有一股英气,甚至流露一点野性,但不细看是看不出来的,她给人的印象还是很文静,很秀雅的。
她不知为什么会爱上了宗毓琳。
宗毓琳和他的弟弟宗毓珂都和我同班。宗家原是这个县的人,宗毓琳的父亲后来到了上海,在法租界巡捕房当了个“包打听”——低级的侦探。包打听都在青红帮,否则怎么在上海混?不知道为什么宗家要把两个儿子送回家乡来读初中?可能是为了可以省一点费用。
和章叔芳同班有一个同学叫王霈。王霈的父亲是个吟诗写字的名士,他盖的房子很雅致。进门是一个大花园,有一片竹子。王霈的父亲在竹丛当中盖了一个方厅——四方的厅,像一个有门有窗的大亭子。这本是王诗人宴客听雨的地方,近年诗人老去,雅兴渐减,就把方厅锁了起来,空着。宗家经人介绍,把方厅租了下来,宗家兄弟就住在方厅里。
宗家兄弟也只是初中生,不见得有特别处。他们是在上海长大的,说话有一点上海口音,但还是本地话,因为这位包打听的家里说的还是江北话。他们的言谈举止有点上海的洋气,不像本地学生那样土。衣著倒也是布料的,但是因为是宁波裁缝做的,式样较新。颜色也不只是竹布的、蓝布的,而是糙米色的,铁灰色的。宗毓珂的乒乓球打得很好,是全校的绝对冠军。宗毓琳会写散文小说,摹仿谢冰心、朱自清、张资平、郁达夫。这在我们那个初中里倒是从来没有的。我们只会写“作文”。我们的初中有一个《初中壁报》,是学生自治会办的。每期的壁报刊头都是我画的。《壁报》是这个初中的才子的园地,大家都要看的。宗毓琳每期都在《壁报》上发表作品(抄在稿纸上,贴在一块黑板上)。宗毓琳中等身材,相貌并不太出众,有点卷发,涂了“司丹康”,显得颇为英俊。
小姨娘就为这些爱了他?
小姨娘第一次到宗毓琳住的方厅,是为了去借书,——宗毓琳有不少“新文学”的书。是由小舅舅章鹤鸣陪着去的。章鹤鸣和我同班、同岁。
第二次,是去还书。这天她和宗毓琳就发生了关系。章叔芳主动,她两下就脱了浑身衣服。两人都没有任何经验。他们的那点知识都是从《西厢记·佳期》、《红楼梦·贾宝玉初试云雨情》得来的。初试云雨,紧张慌乱。宗毓琳不停地发抖,浑身出汗。倒是章叔芳因为比宗毓琳大一岁,懂事较早,使宗毓琳渐渐安定,才能成事。从此以后,章叔芳三天两头就去宗毓琳住的方厅。少男少女,情色相当,哼哼唧唧,美妙非常。他们在屋里欢会的时候,章鹤鸣和宗毓珂就在竹丛中下象棋,给他们望风。他们的事有些同学知道了。因为王霈的同学常到王霈家去玩,怎么能会看不出蛛丝马迹?同学们见章鹤鸣和宗毓珂在外面下象棋,就知道章叔芳和宗毓琳在里面“画地图”——他们做了“坏事”,总会在被单上留下斑渍的。
没有不透风的墙。小姨娘的事终于传到外公的耳朵里。王霈的未婚妻童苓湘和章叔芳同班。童苓湘是我的大舅妈的表妹。童苓湘把章叔芳的事和表姐谈了。大舅妈不敢不告诉婆婆。外婆不敢不告诉外公。外公听了,暴跳如雷,他先把小舅舅鹤呜叫来,着着实实打了二十界方,小舅舅什么都说了。
外公把小姨娘揪着耳朵拉到大厅上,叫她罚跪。
伤风败俗,丢人现眼……!
才十六岁……!
一个“包打听”的儿子……!
章老头抓起一个祖传的霁红大胆瓶,叭嚓一下,摔得粉碎。
全家上下,鸦雀无声。大舅舅的小女儿三三也都吓得趴在大舅妈的怀里不敢动。
小姨娘直挺挺地跪在大厅里,不哭,不流一滴眼泪,眼睛很黑,很大。
跪了一个多小时。
后来是二嫂子——我的二舅妈拉她起来,扶她到她的屋里。
二舅妈是丹阳人。丹阳是介乎江南和江北之间的地方。她是在上海商业专科学校和二舅舅恋爱,结了婚到本县来的。——我的外公对儿子的前途有他的独特的设想,不叫他们上大学,二舅、三舅都是读的商专。二舅妈是一个典型的古典美人,瓜子脸、一双凤眼,肩削而腰细。她因为和二舅舅热恋,不顾一切,离乡背井,嫁到一个苏北小县的地主家庭来,真是要有一点勇气。她嫁过来已经一年多,但是全家都还把她当作新娘子,当作客人,对她很客气。但是她很寂寞。她在本县没有亲戚,没有同学,也没有朋友,而且和章家人语言上也有隔阂,没有什么可以说说话的人。丈夫——我的二舅舅在县银行工作,早出晚归。只有二舅舅回来,她才有说有笑(他们说的是掺杂了上海话、丹阳话和本地话的混合语言)。二舅舅上班,二舅妈就只有看看小说,写写小字——临《灵飞经》。她爱吹箫,但是在这个空气严肃的家庭里——整天静悄悄的,吹箫,似乎不大合适,她带来的一支从小吹惯的玉屏洞箫,就一直挂在壁上。她是寂寞的。但是这种寂寞又似乎是她所喜欢的。有时章叔芳到她屋里来,陪他谈谈。姑嫂二人,推心置腹,无话不谈。她是自由恋爱结婚的,对小姑子的行为是同情的,理解的,虽然也觉得她太年轻,过于任性。
二嫂子为什么敢于把章叔芳拉起来,扶到自己屋里?因为她知道公爹奈何不得,他不能冲到儿媳妇的屋里去。
章老头在外面跳脚大骂:
“你给我滚出去!滚!敢回来,我打断你的腿!”
老头气得搬了一把竹椅在桑园里一个人坐着,晚饭也不吃。
章叔芳拣了几件衣裳,打了个包袱往外走。外婆塞给她一包她攒下的私房钱,二舅妈把手上戴的一对金镯子抹下来给了她。全家送她。她给妈磕了一个头,对全家大小深深地鞠了三个躬,开了大门。门外已经雇好了一辆黄包车等着,她一脚跨上车,头也不回,走了。
第二天她和宗毓琳就买了船票,回上海。
到上海后给二嫂子来过一封信,以后就再没有消息。
初中的女同学都说章叔芳很大胆,很倔强,很浪漫主义。
过了两年,章老头生病死了,——亲戚们议论,说是叫章叔芳气死的,二哥写信叫她回来看看,说妈很想她。
她回来了,抱着一个孩子。
她对着父亲的灵柩磕了三个头。没哭。
她在娘家住了三个月,住的还是她以前住的房,睡的是她以前睡的床。
我再看见她时她抱了个一岁多的孩子在大厅里打麻将。章老头死后,章家开始打麻将了。二哥、大嫂子,还有一个表婶。她胖了。人还是很漂亮。穿得很时髦,但是有点俗气。看她抱着孩子很熟练地摸牌,很灵巧地把牌打出去,完全像一个包打听人家的媳妇。她的大胆、倔强、浪漫主义全都没有一点影子了。
章家人很精明,他们在新四军快要解放我们家乡的前一年,把田产都卖了,全家到南洋去做了生意。因此他们人没有受罪,家产没有损失。听说在南洋很发财。——二舅舅、三舅舅都是学的商业专科学校,懂得做生意。
他们是否把章叔芳也接到南洋去了呢?没听说。
胡增淑后来在南京读了师范,嫁了一个飞行员。飞行员摔死了,她成了寡妇。有同学在重庆见到她,打扮得花枝招展,还挺媚。后来不知怎么样了。
# 笑面人
[[塞林格]]
------
1928 年,我九岁那会儿,怀着最强烈的 espritdecorps(团队精神),我参加了一个叫 “科曼切人俱乐部” 的组织。上课日每天下午三点钟,在阿姆斯特丹大街附近 109 街上的第 165 公立学校男生出口处,我们二十五个科曼切人由我们的酋长收集拢来。接着我们推推搡搡,挤进酋长的那辆经过改装的商用货车,由他开车 (根据他和我们的父母作出的收费安排) 将我们带去中央公园。要是天气好,我们就玩上半个下午的橄榄球、是球或是棒球,主要看 (这也是很随便的) 什么球正好当令。要是逢下午有雨,酋长便毫无例外地带我们去自然史博物馆或是大都会艺术博物馆。
遇到星期天和大多数的法定假日,酋长便一大早来到我们各家公寓门口,把我们收进他那辆其貌不扬的客车,带我们离开曼哈顿进人相对较为开阔的范科特兰公园或是帕利塞兹丘陵。倘若我们脑子里对哪项体育运动有具体想法,我们就去范科特兰,那里的场地大小都合乎标准,对手队伍里绝不会包括一辆婴儿车或是一位拄着根拐棍脾气乖戾的老太婆。要是我们科曼切人一门心思要野营,那我们就上帕利塞兹去风餐露宿。(我还记得一个星期六,在利尼特指示牌和乔治 • 华盛顿桥西头工地之间那段错综复杂的地带上,我迷路了。但我没有乱了方寸。我干脆在一个巨大广告牌的阴影里坐了下来,尽管眼涓汪汪,仍然扣开我的饭盒照吃不误,我有一半把握,酋长准会找到我的。酋长没有一次丢掉过我们。)
在与科曼切俱乐部无关的时候,这位酋长就是家住斯塔腾岛的约翰 • 盖德苏德斯基了。他是个极端怕羞、和蔼的年轻人,约摸二十二三岁,在纽约大学念法律,真是个非常令人怀念的人。这里我无意列举他众多的成就与美德。就随便说几点吧,他是鹰级童子军,差点没当上 1926 年全美橄榄球阻截手,而且谁都知道他曾被极其热情地邀请去纽约巨人棒球队参加试打,每当我们在球场上吵成一团时,他总能公正、冷静地作出裁决,他能让我们群情激奋,又能让大家顿时火气全消,他是排急解难的行家里手。我们每个人,从最矮小的顽童到个头最大的恶棍,无不热爱他与佩服他。
酋长 1928 年时的形象我仍然历历在目。如果希望能让人长高,我们全体科曼切人恨不得让他一下子变成个巨人,可是事与愿违,他是个只有五英尺三四英寸的矬墩——再多一点就没有了。他的头发黑里带蓝,倒是一点都不秃,他鼻子很大而且肉鼓鼓的,还有他的上身几乎跟他的腿一般长。他穿着皮夹克,肩膀显得很有力,但是却窄了点儿而且斜着往下溜。可是当时,在我眼里,酋长简直水乳交融地荟萃了巴克 • 琼斯、肯 • 梅纳德和汤姆 • 米克斯最上照的容貌的特色。
每天傍晚,天刚暗到眼看要输的一方有借口说看不清场内飞球或是球门区传球时,我们科曼切人就干脆耍赖皮,把出路寄托在酋长讲故事的天才上。在这时候,我们往往变成一伙非常起劲、急不可耐的小猴子,我们乱打乱闹——既用拳头又用尖声嘶叫…~争夺车子里靠酋长最近的座位。(车子里有两排并行的干草填塞的座位。左边那排有三个座位伸出去——那可是头等包厢——可以看到司机的删面。)等我们全坐定后酋长才爬进车子。接着他面朝后骑坐在他的司机座上,用他那刺耳的却又变化多端的男高音,给我们开讲 “笑面人” 故事的新段子。只要他一开口,我们的兴趣就始终不衰。“笑面人”正是科曼切人最爱听的那种故事。它说不定还有点经典作品的格局呢。这是一种能说到哪算到哪的故事,但是总的来说仍然能让你魂牵梦萦。你回到家里还会念念不忘,哪怕是坐在水快漏光的浴盆里。
笑面人是一对富有传教士夫妇的独子,婴儿时期就被中国土匪拐走。这对有钱的传教士夫妇 (出于宗教信仰) 拒绝付赎金,土匪们显然恼羞戚怒,便把小家伙的头夹在木匠用的台钳上,往紧拧了几圈。这种不寻常做法的结果是孩子长大后脑袋成了个不长头发的山核桃形状的球,脸上该长嘴的地方仅仅是鼻子底下一个椭圆形的大洞。鼻子则是两个塞满了肉的窟窿。因此,每当笑面人呼吸时,鼻子底下那个丑陋、邪恶的裂口便一张一缩,像是个 (我简直亲眼看见似的) 可怕的液泡。(笑面人的呼吸方式酋长不是向我们解释而是学给我们看的。)陌生人见到笑面人那张瘆人的脸顿时会昏死过去,熟人也都躲开他远远的。可是说也奇怪,土匪们却让他在匪巢周围游荡——只是要他用一块罂粟花瓣做的轻纱般的粉红面罩把自己的脸蒙上。这面罩不单让土匪免得看到他们养子的那张脸,而且还可以随时了解其行踪;在那样情况下,他总会发出一股强烈的鸦片味儿。
每天早上,感到非常孤独的笑面人总是偷偷溜到 (他的脚步像猫一样轻) 土匪藏身处周围的密林里去。在那里他和各个种类的许多动物交上了朋友:狗啦、白鼠啦、鹰啦、狮子啦、能缠死人的大蟒啦、狼啦。而且,他还摘下面罩,柔声柔气、用音乐般的嗓音跟它们说话,用的是动物自己的语言。它们没觉得他丑。
(酋长花了好几个月的时间才把故事讲到这里。从此时起,他越来越放开大胆发挥了,他这样做完全是为了讨科曼切人的喜欢。)
笑面人是个非常留神周围动静的人,过不多久,他就掌握了土匪最最宝贵的黑道秘密。不过他没怎么把这些放在眼里,而是很快就建立起自己的一套更为有效的做法。起初规模还相当小,他开始在中国乡野间当一名独行侠,只在迫不得已时才干些杀人越货的勾当。很快,他那高超的作案手段,再加上他独特的对公平竞争的癖好,使全国人都在内心深处喜爱他。奇怪的是,收养他的那帮土匪 (原本正是他们才使笑面人走上犯罪道路的) 竟几乎到最后才察觉他的业绩。等他们知道后,他们嫉妒得都快神经失常了。有天晚上,他们认为自己已经用蒙汗药让笑面人睡死,便排成单行,走到笑面人的床边,每人朝被单下的人戳上一刀。可是被杀死的偏偏是土匪头的老娘——一个招人讨厌、唠唠叨叨的老太婆。这下更激怒了这些土匪,他们简直想喝他的血,笑面人只好用计将土匪一个不剩全关进一座深人地下却装修得很讲究的陵墓。他们好几次逃了出来给笑面人添了不少麻烦,可是他却不忍心杀死他们。(笑面人性格中有心软的一面,这简直让我气得发疯)。
不久,笑面人便经常越过中国边界去法国巴黎,在那里他能因为在马塞尔 • 杜法日面前炫耀自己高超却又深藏不露的天才而感到快乐,这是位国际上知名的侦探,很机智,却患有肺结核。杜法日和他的女儿 (一位很优雅的姑娘,但多少有穿异性服饰的怪癖)X 成了笺面人的死敌。他们多次想把笑面人诱人一条花同小径。纯粹是为了自娱,笑面人一般都跟他们一起走到牛路上,然后就消失不见,真是神不知鬼不觉,用什么方法逃遁一点儿也看不出来。他还时不时通过巴黎的下水道系统发来一张口气辛辣的告别小字条,这字条竟能迅速送抵杜法日的脚前。杜法日父女费了许多时间在巴黎地下臭水沟里仔细搜寻笺面人。
很快,笑面人便敛聚到世界上最多的私人财富。大部分财产他都匿名捐给了当地一家修道院的修士——这些谦卑的苦行僧终生致力于训练培养德国警犬。笑面人把剩下的财产都换成钻石,放进几个绿宝石镶成的拱顶藏宝箱,漫不经心地让它们沉人黑海。他个人的需求不多。他单靠米饭与鹰血维持生活,栖身在西藏多风暴海边的一所小茅舍里,那里有一个地下运动场和打靶场。四个对他死心塌地、忠心耿耿的同党和他住在一起:一个叫黑翼,是条能言善辩的森林狼,一个叫欧姆巴,是个挺可爱的侏儒,一个叫洪,是条蒙古大汉,他的舌头被白人烙烧掉了,还有一个是美艳绝伦的欧亚混血姑娘,她出于对笑面人的不图回报的爱以及对他个人安全的深切关怀,有时会对犯罪持一种满不在乎的态度。笑面人呆在一块黑丝帷帘后面向党羽们发号施令。连可爱的侏儒欧姆巴也不允许见到他的脸。
我不是说我想这么做,但是如果需要我可以护送读者一小时继一小时地来回穿越中法边界——必要时可以用暴力。我正好是把笑面人视作我的杰出先辈那样的一个人物的——比方说,像罗伯特 •E• 李,是具有被认为经得起血与火考验那样的品质的。这一幻想与我 1928 年所怀有的一比,简直就黯然无光了,当时我小仅认为自己是笺面人的直系后代而且是他惟一活着的合法子裔。在 1928 年,我不仅连我的父母的儿子都不是而且是一个深藏不露了无痕迹的僭儿,一等他们稍有过失便以此为由登堂入室,亮明我的真实身份——当然最好是不用暴力,但是必要时也不排除这种可能性。为了预防伤了我那所谓的母亲的心.我打算利用某种不明确然而是恰当合法的手段将她引人我的地下世界。不过我在 1928 年必须做的最王要任务是留神好自己的行动。得把这场好戏唱下去。我照样刷我的牙。梳我的头发。费尽力气,忍住不让我要自然流露的狞笑爆发出来。
事实上笑面人活在世界上的合法子裔并非只有我一个。俱乐部里有二十五个科曼切人,也就是说有二十五个笑面人的合法子裔——我们全都心怀鬼胎、隐姓埋名地游荡在全市各个角落,打量着一个个开电梯的工人,认定他们是潜在的最大敌人,向那些受宠的矮脚獚犬耳朵里轻声进去一个个用嘴角发出却是很熟练的命令,还用中指在数学老师们的前额上遥画珠子。同时一直在等待,等待大好机会到来让我们大显身手,使得身边的那些凡夫俗子心中又怕又敬。
科曼切人棒球季刚开始不久后,2 月里的一个下午,我在酋长的客车里见到一件新的装备。在挡风玻璃上方后视镜高处有一个小镜框,里面是张头戴学士方帽身披学士袍的姑娘的照片。在我看来,一张女孩的照片跟客车里纯属男子汉的气氛很不谐调,于是便愣头愣脑地问酋长这妞儿是谁。他先是支吾了阵,最后承认说这是个姑娘。我问她叫什么名字。酋长又很不情愿地说叫 “玛丽 • 赫德森”。我又问她是不是演过电影什么的。他说不是的,她以前在韦尔斯利学院,念书。他想了好一会儿之后,又加了句,说韦尔斯利可是家非常贵族化的学校。我又追问道,不过,他为什么要把她的照片挂在客车里呢。他略微耸了耸肩膀,我感觉那意思仿佛说,这照片多多少少是硬栽到他这儿来的。
在以后的几个星期里,这张照片不管它是硬性还是偶然栽到酋长这儿米的——并没有从汽车里摘下来。它没有跟印有贝贝 - 鲁思像的包装纸和掉下来的甘草糖屑一起被清扫出去。反倒是我们科曼切人对它逐渐习惯了。它一点点像只时速表一样,丝毫不招人注意了。
可是有一天,就在我们去公园的路上,酋长让汽车在六十大道路口的第五大街的人行道边停了下来,那儿离我们的棒球场还是是有半英里路。约摸二十位后座驾驶员同时开口,要求作出解释,可是酋长却不予理睬。相反,他干脆转过身子坐下,提前开讲 “笑面人” 的一个新段子。不过,他还没讲几句就有人拍打车门。那天酋长的反应真是调到高速挡上了。他简直就是呼地转过身子,一下扭开车门把手,紧接着一个穿海狸皮大衣的姑娘登上了车。
我不假思索就能记起,我一生之中只遇到三个女孩,使我一眼看到就强烈地感觉出她们有无法归类的惊人的美。第一位是个穿黑泳衣的身材纤秀的女孩,1936 年光景,她在琼斯海滩上费好大的事想撑起一把橘黄色的遮阳伞。第二个是 1939 年在一条加勒比海游艇上的一个姑娘,她将自己的打火机朝一只鼠海豚扔去。而第三个就是酋长的这位女朋友玛丽 • 赫德森了。
“我到得太迟了吧?” 她问酋长,对着他笑吟吟的。
她还小如问她是不是长得太丑了呢。” 没有!” 酋长说.他有点粗鲁地朝他座位边上那几个科曼切人盯看,示意那排人往后退退。玛丽 • 赫德森在我和另一个男孩之间坐下,那男孩叫埃德加什么的,他叔叔的铁哥们是个私酒贩子。我们为她让开了世界上尽可能多的地方。接着车子莫名其妙地、很业余水平地朝前猛地一冲。
在开往我们照例停车的场地时,玛丽 • 赫德森从她座位上身子前倾,兴致勃勃地向酋长讲述她没赶上哪班车又赶上了哪班车;她住在长岛的道格拉斯顿,酋长非常紧张,他勉勉强强才答上自己的几句话;他都几乎听不清她在讲什么。那换挡的圆球竟从他手掌心滑脱开去,这我还记得。
下车后,玛丽 • 赫德森紧紧黏住我们。我敢肯定,等我们走到棒球场时每一个科曼切人的脸上都露出了一副 “有些女孩子就是不明白什么时候该回家” 的表情。更不可思议的是,当我和另一个科曼切人抛掷硬币决定哪一队先攻球时,玛丽 • 赫德森竟渴求地表示她想参加比赛。对此我们的反应再鲜明不过了。对着这么一个活物,我们科曼切人原先只是作为一个异性瞪看着,现在我们简直是怒目而视了。她朝我们笑笑,这里有一些掩饰窘态的成分。这时酋长接手处理了,暴露出原先深藏不露的才能其实只是一种不称职。他把玛丽 • 赫德森拉到一边,刚好不让科曼切人听见,像是很严肃认真地对她说了些什么。最后玛丽 • 赫德森打断他的话,她的嗓音我们科曼切人倒听得清清楚楚。“可是我是真的,”她说。“我也想打球嘛!”酋长点点头又试着说服姑娘。他指指场地,那里潮滋滋、坑坑洼洼的。他拿起一根普通的球棒,显示它有多重。“我才不管呢,”玛丽 • 赫德森果断地说,“我这么远来到纽约来看牙和办别的事——可我现在要打球。”酋长又点点头不过这回却服软了。他小心翼翼地走到本垒板,“勇士队”和 “战士队”,科曼切人分成的两支球队,在那儿等着,他看着我。我是“战士队” 的队长。他提到我这个队里经常打中外野手那人的名字,这孩子止好牛病没来,建议让玛丽 • 赫德森顶替他的位置。我说我不需要中外野手。酋长问我,我不需要中外野手他妈的是什么意思。我大为震惊。这是我头一回听到他说粗话。更气人的是,我能觉出玛丽 • 赫德森在冲着我笑。为了有所表示,我捡起一块石头朝一棵树扔去。
我们队先攻球。第一局没中外野手什么事儿。我站在第一垒位置上时不时朝自己身后看去。每回我看的时候,玛丽 • 赫德森都高兴地朝我挥手。她戴了只接球手的手套,她很固执一定要戴。这简直让人没法看。
玛丽 • 赫德森在 “战士队” 的阵式上排第九。当我把这一安排告诉她时,她做了个小小的鬼脸同时说:“也行,那就快点比吧,好不好。”事实上我们也正想加快节奏。在第一局中她就轮上挥棒了。为此,她脱掉她的海狸皮大衣——以及她的接球手的手套——穿一身深棕色衣裙走进本垒板。我递给她一根球棒时她问我它怎么这么沉。酋长从投手身后裁判的位置上急匆匆走过来。他告诉玛丽 • 赫德森得把球棒的一端搁在右肩上。“我是这样做的,”她说。他告诉她别把球棒握得太紧。“我没有呀,”她说。他告诉她要把眼睛盯紧球。“我会的,”她说。“别在这儿碍事了。”她用力挥棒,击中了向她投来的第一个球,把球打得飞过了左外野手的脑袋。一般人能打到两垒打就够好的了,可是玛丽 • 赫德森一直跑到第三垒——而且还站稳了。
我的惊讶一点点消失,接着生出并且消失的是我的敬畏、我的喜悦,这时我看了看酋长。他都不像是站在投手的身后了,而像是在投手的头顶飘浮。他成了个通体快乐的人。玛丽在第三垒那里向我挥},我也向她挥手。我就是有心不想挥也做不到了。先不说她击球技术如何,反正她是个知道怎样从第三垒向别人挥手的姑娘。
在后来的比赛中,轮到她击球时她都能跑到垒。不知是什么道理,她像是讨厌第一垒;没办法把她留在那里。至少有三次,她都偷到了第二垒。
她的防守却是糟得没法说,不过我们跑垒赢分太多因此谁也不去管她了。我寻思如果她追飞球时随便戴块破布也比戴捕手的无指手套强。她却怎么不肯脱下。她说那样特有气派。
以后的一个多月里,她每星期都和科曼切人一起打两次球 (显然都是轮到她要看牙的时候)。有些下午她准时搭我们的车,有些下午她到得晚一些。有时候她在汽车里连珠炮般地说个不停,有时候她光是坐在那里抽她的赫伯特 • 塔雷顿牌香烟 (带软木嘴的)。坐在她身边,你能闻到一股迷人的香水味儿。
4 月里一个刮风的日子,酋长三点钟像经常那样,在 109 和阿姆斯特丹大街交叉处接人上车,然后开着装满人的车子在 110 大道那里往东一拐,沿着第五大街照例慢慢巡行。可是他头发梳得油光锃亮,他穿着大衣而不是他那件皮夹克,我自然要猜测玛丽 • 赫德森会来。当我们呼地越过我们一般要走的公园进口时,我就更加肯定了。酋长把车停在六十几街的拐角处,这地方等人最合适不过。接着,为了不让科曼切人觉得时间难熬,他转身反过来坐又讲开了 “笑面人” 的一个新段子。我记得里面每一个细节,但我只能简略说个主要内容。
由于环境错综复杂,笑面人的忠实朋友,他的森林狼黑翼 - 中计落人了杜法日父女之手,杜法日父女深知笑面人最讲义气,提出让他用自己的自由来换取黑翼。笑面人信以为真,同意了这样的做法。(他尽管绝顶聪明但也不是没有弱点,这往往会导致一些古怪的小失误。) 双方商定半夜在巴黎周边密林深处某个地段会面,在那里的月光底下,黑翼将被释放。然而杜法口父女却无意交出他们又怕又恨的黑翼。在交换的那晚,他们拴着一只替身森林狼,让它冒充黑翼,还先把它的右后脚涂得雪雪白,企图以假乱真。
但有两点杜法日父女没有料到:笑面人还有多情的一面以及他懂得森林狼的语言。笑面人剐让杜法日的女儿用带刺的铁丝把自己捆在一棵树上,他便觉得有必要用他那美妙,悦耳的嗓音大声对他相信是自己老友的黑翼说几句告别的话。站在月光下几码外的替身森林狼发现这陌生人居然会讲自己的语言便有礼貌地听了一阵笑面人所作的生活上与行业上的临终遗言。但是最后,这替身森林狼越来越不耐烦了,身子重心不停地在几只脚爪之间移动。他突然很不客气地打断笑面人,告诉他,第一,他的大名并不是暗翼、黑翼或是灰腿什么的,而是阿尔曼德,还有第二,他这辈子从未去过中国面且也没一点想去的意思。
笑面人自然气愤至极,他用舌头把面罩顶开,在月光下朝杜法日父女显示他真正的面容。杜法日小姐的反应是当场昏死过去。她的父亲比较幸运,那一刻他刚好低下头去咳嗽,因此没见到那致命的面容显露。等他咳完只见他女儿摊手摊脚仰卧在月光照着的地上。他脑子一转就明白是怎么回事了。他用一只手遮住眼睛,另一只把自动手枪里一满膛的子弹都朝笑面人发出咝咝粗喘气声的地方射去。
这个段子说到这里就告一结束。
酋长从表袋里掏出他那块售价一元的英格索牌表,看了看,然后转过身子发动马达。我也看了看自己的表。时间快到四点半了。汽车朝前走时,我问酋长他就不等玛丽 • 赫德森啦。他没回答我,还不等我有时间重复我的问题,他侧过头对我们全体说;“这车子里也他妈的太吵了,都给我静一静行不行。” 这话真叫人摸不着头脑,这道命令其实是毫无意思的。车子里原先和现在都非常安静。几乎每一个人都在惦记着笑面人被撂下的那个关子。我们早就不再为他的命运担心了——我们太相信他总能逢凶化吉——不过遇到他最最惊险的遭遇时,我们还是难以心情平静。
在我们那天下午的球赛打到第三或第四局时,我站在第一垒上瞥见了玛丽 • 赫德森。她坐在我左边大约一百码处的一张长凳上,夹在两个带着婴儿车的保姆中间。她穿着她那件海狸皮大衣,在抽烟,她像是在朝着我们球赛的方向观看,我为我的发现面激动,便向守在投手后面的酋长大声通报这一消息。他急匆匆地走到我跟前,不过还不是小跑。“在哪儿?” 他问我。我又指了指。他朝那个方向盯看了一会儿,接着说他去去就回来,于是离开了球场。他走得挺慢,一边解开大衣扣子又把双手插到裤子的后屁股兜里去。我在第一垒的地上坐下,观看着。等酋长走到玛丽 • 赫德森跟前时,他的大衣又重新扣上了,两只手也垂到了身边。
酋长在她身边站了大约有五分钟,显然是在跟她说话。接着玛丽 • 赫德森站起身来,他们俩朝棒球场走过来。他们走的时候没有说话,也没有相互对看。他们走到球场边,酋长又在投手后面站好位置。我对他叫嚷,“她不参加吗?” 酋长先让我管好自己的垒。我照做了,但是也斜过眼去看玛丽 • 赫德森。她在本垒后面慢慢地踱步,双手插在海狸皮大衣口袋里,最后在紧挨第三垒一张放得不是地方的球员长凳上坐下。她又点燃一根香烟并且叉起腿。
轮到 “战士队” 攻球时,我走到她坐着的长凳边上,问她想不想参加打左外野。她摇摇头。我问她是小是感冒了,她又摇摇头。我告诉她我左外野缺人。我告诉她我不得不让一个球员兼顾中外野和左外野。听了这消息她一点儿反应都没有。我把我的一垒手用的手套抛到空中想让它落在我头上,可是手套掉进了一个小泥淖。我在裤子上把泥擦掉,同时问玛丽 • 赫德森愿不愿意哪天上我家去吃饭。我告诉她酋长经常来的。“别缠着我了,”她说。“求求你就让我一人呆会儿。”我瞪眼看了看她,走进球场,朝 “战士队” 休息时的板凳走去,一边从我的口袋里掏出一只柑橘,并把它扔向空中。我沿着第三垒边线往前,快到一半时我转身倒退着走,一边看玛丽 • 赫德森一边继续玩我的扔柑橘游戏。我不知道酋长和玛丽 • 赫德森之间出了什么问题(而且至今也不清楚, 仅仅是凭直觉稍稍有所感觉),可是不管怎么说,我绝对肯定,玛丽 • 赫德森已经永远脱离我们科曼切人的队列了。这是一种能全然肯定的事,尽管你一点事实根据都没有,脑子想着这些使得倒退走更加危险了,这不,我砰地撞在了一辆婴儿车上。
又打了一局之后,光线太弱没法防守了。比赛停止,我们开始收拾东西。我最后看到的玛丽 • 赫德森是,她在第三垒那儿哭泣。酋长拉了拉她的海狸皮大衣袖子,可是她甩开了。她跑着离开球场,跑上了水泥小路还一直往前跑直到我看不见她。酋长没去追她。他光是站在那儿看着她消失不见。接着他转身走到本垒那里,捡起我们的两根球棒。我走到他跟前问他是不是和玛丽‘赫德森吵架了。他光是让我把衬衫掖进裤子里去。
就跟平时一样,我们科曼切人是奔跑着向几百英尺外停着的汽车冲去的,一边喊叫和推推搡搡,谁都想把别人挤到后面,可是每一个人都知道得很清楚.又到听 “笑面人” 新段子的时候了。越过第五大街时,不知是谁扔下一件他多余的或是不要了的运动衫.我让它给绊倒了。我好不容易冲到车前,可是这时最好的座位都给占了,我只好在汽车中部坐下。这样的结果让我大为气恼,我用胳膊肘向坐在我右边那男孩肋骨上捅了一下,接着便转过脸看酋妊穿过第五大街。天还没完全黑,但已经有五点一刻的那种苍茫了。酋长穿过第五大街,大衣领子竖着,两根球棒夹在左胳膊底下,注意力全放在街上的车辆上。他那头黑发,早些时候还梳得溜光的,现在已很干了,给风吹得乱乱的,我还想,要是酋长戴着手套就好了。
酋长爬上车时,客车里跟往常一样,很静——至少跟剧场内部灯光一点点暗下来时情况差不多。交谈赶紧以匆匆忙忙的几句耳语收场或是干脆打住。可是酋长劈头对我们说的第一句话却是 “行了,再别出声了,否则就不讲故事”。一刹那间,一种绝对的沉静笼罩着客车,使酋长别无选择只得以讲故事的姿势坐下。他坐定后,掏出一块手帕有条不紊地擤鼻子,先擤一只鼻孔,接着擤另一只。我们看着他,很耐心,甚至还带有一些观察家的兴趣。他手帕用完后,又细心地把它叠成四折,放回到兜里去。接着他给我们讲了“笑面人” 的一个新段子,这次讲了还不到五分钟。
杜法日的四颗子弹打中了笑面人,其中的两颗穿透了他的心脏。杜法日当时仍然挡住眼睛避免看到笑面人的脸,他听见从对手那边发出一种奇特的痛苦喊叫声,大喜过望,他那颗歹毒的心怦怦直跳,连忙跑到昏迷的女儿那里帮她恢复知觉,这对父女喜不自胜,竟然再不像懦夫那样胆怯,此刻竟敢对着笺面人直看了。笑面人像死了似的低垂着头,下巴耷拉在血淋淋的胸前。父女俩慢慢地、贪婪地挨近,想细细察看他们的手下败将。可是等待着他们的是一个大大的意外。笑面人离死还早着呢,他用一种奇特的功夫使劲收缩腹肌。一等丰十法日父女走近,他突然仰起脸,发出怪声的人笑,干净利落,甚至是仔仔细细地把四颗子弹全都反射出来。这一招实在厉害,两个人真是肝胆俱裂,顿时死在笑面人的脚下。(如果酋长确实不想多说,他满可以在这里告一结束;科曼切人好歹能对杜法日父女的猝死作出合理解释。但是故事并没有在这儿结束。) 日复一日,笑面人仍然被带刺铁丝捆着站在树前,杜法日父女的尸体在他脚下一点点腐烂,他大量出血,又得不到鹰血的滋养,他真的是离死只有一步之遥了。然而有一天,他用嘶哑却很有说服力的嗓音,恳求林中动物帮他一个忙。他让它们去找欧姆巴,那个可爱的侏儒。它们去了。但是来回穿越巴黎中国边界路途遥远,等欧姆巴带了药箱和新鲜鹰血赶到时,笑面人已昏迷不醒。欧姆巴做的第一件好事就是找回他主人的面罩,那已经给风吹得贴在长痛蛆的杜法日小姐的尸体上了。他满怀敬意将它放回到那张丑脸上,然后再着手包扎伤口。
笑面人终于睁开他那双小眼睛。欧姆巴赶紧把那小瓶鹰血凑到面罩跟前。可是笺面人没喝。他只是细声呼唤着他心爱的黑翼的名字。欧姆巴俯下他自己那稍稍有些歪扭的头告诉主人杜法日已经把黑翼害死了。笑面人发出一声古怪的、摧人心碎的最后哀鸣。他虚弱地伸出手去握住鹰血瓶并把它捏碎。他仅剩的不多的血顺着手腕流了下来。他命令欧姆巴把脸转开去,欧姆巴抽泣着服从了。笑面人的最后一个动作是扯下自己的面罩,让脸贴住浸透鲜血的土地。
自然,故事讲到这里全部结束了。(再也没法接下去一波三折。) 阿长开动客车。坐在过道我对面的比利 • 沃尔许是科曼切人中年纪最小的一个,他此时竟哭出声来。谁也没去叫他闭嘴。至于我自已,我记得我的双膝颤抖个不停。
几分钟后.我从酋长的客车里走下来,我看到的第一件东西恰好是张红色的纱纸,它给风吹得贴在路灯柱根基上。那看上去就像某个人的罂粟花瓣面罩。我在上下牙控制不住的打战中回到家中,立刻就被赶上床去睡觉了。
{{00001}}
[[00001]]
{{特斯塔}}
2020
星新一(1926年9月6日-1997年12月30日),本名星亲一,是日本科幻小说家。出生于东京府东京市本乡区曙町(今东京都文京区本驹込)。父亲是星药科大学及星制药的创建者星一,森鸥外为其外叔公(外祖母的兄长)。
星新一擅长微型小说,一生共创作微型小说1000多篇,其中不少构思奇特,情节曲折,文学价值与哲理意义俱备。其本人也被称为“微型小说之神”。代表作包括《ボッコちゃん》、《悪魔のいる天国》等等。此外也有写实作品。他在日本与小松左京和筒井康隆并称“御三家”。
作品
星新一作品的文学手法十分独特,一般会尽可能地淡化事物的特定性。比方说,他从不会写“100万日元”这样具体的数字,而是用“一大笔钱”、“山珍海味吃上好几顿才能花完的钱”来代替。在意图使故事独立于环境、社会、时代方面用心良苦。此外,只要有机会还会将不合时代的词汇/表达加以改写,比如把“拨电话”改为“打电话”等。暴力、色情场面几乎没有。不过据其本人描述这主要是为了更集中精力于有价值的地方,而不是出于某种道德上的动因。另外,其作品并不涉及时事,也会避免使用前卫的文学手法。具体的地名和人名基本不会出现。人物一般以“M氏”、“N氏”等形式登场,这几乎成为了其作品的关键词。不过,由于各个短篇的主人公处境、外貌、性格等迥异,并不会被认为是同一人物。
一些作品比较精确地预见到了未来世界的某些发展。如在《声の网》(1970年)一篇中,描绘了一个未来社会中的计算机网络:人们将数据通过电话线传送给计算机进行管理;到处都有计算机,并由网络连接在一起;人们可以在任何时候任何地点通过计算机访问数据。
作品被翻译成20多种语言。一些涉及冷战的作品被同时翻译成英语和俄语,在美国和苏联都获得出版,显示了对其作品普遍性的广泛认同。
许多作品具有寓言性质,连本人也自称“当代伊索”。想法独特而不失自然,观点冷静而切中事物本质,赢得了许多读者青睐。许多作品往往成为学校课本、电视节目的题材。
星新一的作品也得到了许多文学批评家和作家的高度评价。浅羽通明曾在他的文学评论中屡次援引星小说中的故事,强调其作品是“无论什么时代都通用的、对普遍人性的批评”。筒井康隆则指出星以斯多亚学派为约束前提,其对人类的深刻理解、无尽的爱和多元化的姿态给他的作品以一种透明感。
星新一的《喂——出来》被选入人民教育出版社八年级下的语文教材[3]。
雪夜
作者:〖日〗[[星新一]]
海明珠译
---
雪花象无数白色的小精灵,悠悠然从夜空中飞落到地球的脊背上。整个大地很快铺上了一条银色的地毯。
在远离热闹街道的一幢旧房子里,冬夜的静谧和淡淡的温馨笼罩着这一片小小的空间。火盆中燃烧的木炭偶尔发出的响动,更增浓了这种气氛。
“啊!外面下雪了。”坐在火盆边烤火的房间主人自言自语地嘟哝了一句。
“是啊,难怪这么静呢!”老伴儿靠他身边坐着,将一双干枯的手伸到火盆上。
“这样安静的夜晚,我们的儿子一定能多学一些东西。”房主人说着,向楼上望了一眼。
“孩子大概累了,我上楼给他送杯热茶去。整天闷在屋里学习,我真担心他把身体搞坏了。”
“算了,算了,别去打搅他了。他要是累了,或想喝点什么,自己会下楼来的。你就别操这份心了。父母的过分关心,往往容易使孩子头脑负担过重,反而不好。”
“也许你说得对。可我每时每刻都在想,这毕业考试不是件轻松事。我真盼望孩子能顺利地通过这一关。”老伴儿含糊不清地嘟哝着,往火盆里加了几块木炭。
突然,一阵急促的敲门声打破了这寂静的气氛。
两人同时抬起头来,相互望着。
“有人来。”
房主人慢吞吞地站了起来,蹒跚地向门口走去。随着开门声,一股寒风带着雪花挤了进来。
“谁啊?”
“别问是谁。老实点,不许出声!”
门外一个陌生中年男子手里握着一把闪闪发光的匕首。声音低沉,却掷地有声。
“你要干什么?”
“少罗嗦,快老老实实地进去!不然……”陌生人晃了晃手中的匕首。
房主人只好转身向屋子里走去。
老伴儿迎了上来:“谁呀?是找我儿子……”她周身一颤,后边的话咽了回去。
“对不起,我是来取钱的。如果识相的话,我也不难为你们。”陌生人手中的匕首在炭火的映照下,更加寒光闪闪。
“啊,啊,我和老伴儿都是上了年纪的人,不中用了。你想要什么就随便拿吧。但请您千万不要到楼上去。”房主人哆哆嗦嗦地说。
“噢?楼上是不是有更贵重的东西?”陌生人眼睛顿时一亮,露出一股贪婪的神色。
“不,不,是我儿子在上面学习呢。”房主人慌忙解释。
“如此说来,我更得小心点。动手之前,必须先把他捆起来。”
“别,别这样。恳求您别伤害我们的儿子。”
“滚开!”
陌生人三步两步蹿上楼梯。陈旧的楼梯发出吱吱呀呀的声音。
两位老人无可奈何,呆呆地站在那里。
突然,喀嚓一声,随着一声惨叫,一个沉重的物体从楼梯上滚落下来。
房主人从呆愣中醒了过来,慌忙对老伴儿说:“一定是我们的儿子把这家伙打倒的。快给警察挂电话……”
很快,警察们赶来了。在楼梯口,警察发现了摔伤了腿躺在那里的陌生人。
“哪有这样的人,学习也不点灯。害得我一脚踩空。真晦气。”陌生人一副懊丧的样子。
上楼搜查的警察很快下来了。
“警长,整个楼上全搜遍了,没有发现第二个人,可房主人明明在电话中说是他儿子打倒的强盗,是不是房主人神经不正常?”“不是的。他们唯一在上学的儿子早在数年前的一个冬天死了。可他们始终不愿承认这一事实。总是说,儿子在楼上学习呢。”
谁也没有再说话。屋里很静,屋外也很静。那白色的小精灵依然悠悠然然地飞落下来……
---
录自江苏文艺出版社《微型小说选(7)》(该册为“外国微型小说专辑”,1986)
言语与风格-老舍
========================
言语与风格-[[老舍]]
-----
小说是用散文写的,所以应当力求自然。诗中的装饰用在散文里不一定有好结果,因为诗中的文字和思想同是创造的,而散文的责任则在运用现成的言语把意思正确的传达出来。诗中的言语也是创造的,有时候把一个字放在那里,并无多少意思,而有些说不出来的美妙。散文不能这样,也不必这样。自然,假若我们高兴的话,我们很可以把小说中的每一段都写成一首散文诗。但是,文字之美不是小说的唯一的责任。专在修辞上讨好,有时倒误了正事。本此理,我们来讨论下面的几点:
(一)用字:佛罗贝说,每个字只有一个恰当的形容词。这在一方面是说选字须极谨慎,在另一方面似乎是说散文不能象诗中那样创造言语,所以我们须去找到那最自然最恰当最现成的字。在小说中,我们可以这样说,用字与其俏皮,不如正确;与其正确,不如生动。小说是要绘色绘声的写出来,故必须生动。借用一些诗中的装饰,适足以显出小气呆死,如蒙旦所言:“在衣冠上,如以一些特别的,异常的,式样以自别,是小气的表示。言语也如是,假若出于一种学究的或儿气的志愿而专去找那新词与奇字。”青年人穿戴起古代衣冠,适见其丑。我们应以佛罗贝的话当作找字的应有的努力,而以蒙旦的话为原则——努力去找现成的活字。在活字中求变化,求生动,文字自会活跃。
(二)比喻:约翰孙博士说:“司微夫特这个家伙永远不随便用个比喻。”这是句赞美的话。散文要清楚利落的叙述,不仗着多少“我好比”叫好。比喻在诗中是很重要的,但在散文中用得过多便失了叙述的力量与自然。看《红楼梦》中描写黛玉:“两湾似蹙非蹙笼烟眉,一双似喜非喜含情目。态生两靥之愁。娇袭一身之病。泪光点点。娇喘微微。闲静似娇花照水,行动如弱柳扶风。心较比干多一窍,病如西子胜三分。”这段形容犯了两个毛病:第一是用诗语破坏了描写的能力;念起来确有诗意,但是到底有肯定的描写没有?在诗中,象“泪光点点”,与“闲静似娇花照水”一路的句子是有效力的,因为诗中可以抽出一时间的印象为长时间的形容:有的时候她泪光点点,便可以用之来表现她一生的状态。在小说中,这种办法似欠妥当,因为我们要真实的表现,便非从一个人的各方面与各种情态下表现不可。她没有不泪光点点的时候么?她没有闹气而不闲静的时候么?第二,这一段全是修辞,未能由现成的言语中找出恰能形容出黛玉的字来。一个字只有一个形容词,我们应再给补充上:找不到这个形容词便不用也好。假若不适当的形容词应当省去,比喻就更不用说了。没有比一个精到的比喻更能给予深刻的印象的,也没有比一个可有可无的比喻更累赘的。我们不要去费力而不讨好。
比喻由表现的能力上说,可以分为表露的与装饰的。散文中宜用表露的——用个具体的比方,或者说得能更明白一些。庄子最善用这个方法,象庖丁以解牛喻见道便是一例,把抽象的哲理作成具体的比拟,深入浅出的把道理讲明。小说原是以具体的事实表现一些哲理,这自然是应有的手段。凡是可以拿事实或行动表现出的,便不宜整本大套的去讲道说教。至于装饰的比喻,在小说中是可以免去便免去的。散文并不能因为有些诗的装饰便有诗意。能直写,便直写,不必用比喻。比喻是不得已的办法。不错,比喻能把印象扩大增深,用两样东西的力量来揭发一件东西的形态或性质,使读者心中多了一些图像:人的闲静如娇花照水,我们心中便于人之外,又加了池畔娇花的一个可爱的景色。但是,真正有描写能力的不完全靠着这个,他能找到很好的比喻,也能直接的捉到事物的精髓,一语道破,不假装饰。比如说形容一个癞蛤蟆,而说它“谦卑的工作着”,便道尽了它的生活姿态,很足以使我们落下泪来:一个益虫,只因面貌丑陋,总被人看不起。这个,用不着什么比喻,更用不着装饰。我们本可以用勤苦的丑妇来形容它,但是用不着;这种直写法比什么也来得大方,有力量。至于说它丑若无盐,毫无曲线美,就更用不着了。
(三)句:短句足以表现迅速的动作,长句则善表现缠绵的情调。那最短的以一二字作成的句子足以助成戏剧的效果。自然,独立的一语有时不足以传达一完整的意念,但此一语的构成与所欲给予的效果是完全的,造句时应注意此点;设若句子的构造不能独立,即是失败。以律动言,没有单句的音节不响而能使全段的律动美好的。每句应有它独立的价值,为造句的第一步。及至写成一段,当看那全段的律动如何,而增减各句的长短。说一件动作多而急速的事,句子必须多半短悍,一句完成一个动作,而后才能见出继续不断而又变化多端的情形。试看《水浒传》里的“血溅鸳鸯楼”:“武松道:”一不作,二不休!杀了一百个也只一死!‘提了刀,下楼来。夫人问道:“楼上怎地大惊小怪?’武松抢到房前。夫人见条大汉入来,兀自问道:”是谁?‘武松的刀早飞起,劈面门剁着,倒在房前声唤。武松按住,将去割头时,刀切不入。武松心疑,就月光下看那刀时,已自都砍缺了。武松道:“可知割不下头来!’便抽身去厨房下拿取朴刀。丢了缺刀。翻身再入楼下来……”
这一段有多少动作?动作与动作之间相隔多少时间?设若都用长句,怎能表现得这样急速火炽呢!短句的效用如是,长句的效用自会想得出的。造句和选字一样,不是依着它们的本身的好坏定去取,而是应当就着所要表现的动作去决定。在一般的叙述中,长短相间总是有意思的,因它们足以使音节有变化,且使读者有缓一缓气的地方。短句太多,设无相当的事实与动作,便嫌紧促;长句太多,无论是说什么,总使人的注意力太吃苦,而且声调也缺乏抑扬之致。
在我们的言语中,既没有关系代名词,自然很难造出平匀美好的复句来。我们须记住这个,否则一味的把有关系代名词的短句全变成很长很长的形容词,一句中不知有多少个“的”,使人没法读下去了。在作翻译的时候,或者不得不如此;创作既是要尽量的发挥本国语言之美,便不应借用外国句法而把文字弄得不自然了。“自然”是最要紧的。写出来而不能读的便是不自然。打算要自然,第一要维持言语本来的美点,不作无谓的革新;第二不要多说废话及用套话,这是不作无聊的装饰。
写完几句,高声的读一遍,是最有益处的事。
(四)节段:一节是一句的扩大。在散文中,有时非一气读下七八句去不能得个清楚的观念。分节的功用,那么,就是在叙述程序中指明思路的变化。思想设若能有形体,节段便是那个形体。分段清楚、合适,对于思想的明晰是大有帮助的。
在小说里,分节是比较容易的,因为既是叙述事实与行动,事实与行动本身便有起落首尾。难处是在一节的律动能否帮助这一段事实与行动,恰当的,生动的,使文字与所叙述的相得益彰,如有声电影中的配乐。严重的一段事实,而用了轻飘的一段文字,便是失败。一段文字的律动音节是能代事实道出感情的,如音乐然。
(五)对话:对话是小说中最自然的部分。在描写风景人物时,我们还可以有时候用些生字或造些复杂的句子;对话用不着这些。对话必须用日常生活中的言语;这是个怎样说的问题,要把顶平凡的话调动得生动有力。我们应当与小说中的人物十分熟识,要说什么必与时机相合,怎样说必与人格相合。顶聪明的句子用在不适当的时节,或出于不相合的人物口中,便是作者自己说话。顶普通的句子用在合适的地方,便足以显露出人格来。什么人说什么话,什么时候说什么话,是最应注意的。老看着你的人物,记住他们的性格,好使他们有他们自己的话。学生说学生的话,先生说先生的话,什么样的学生与先生又说什么样的话。看着他的环境与动作,他在哪里和干些什么,好使他在某时某地说什么。对话是小说中许多图像的联接物,不是演说。对话不只是小说中应有这么一项而已,而是要在谈话里发出文学的效果;不仅要过得去,还要真实,对典型真实,对个人真实。
一般的说,对话须简短。一个人滔滔不绝的说,总缺乏戏剧的力量。即使非长篇大论的独唱不可,亦须以说话的神气,手势,及听者的神色等来调剂,使不至冗长沉闷。一个人说话,即使是很长,另一人时时插话或发问,也足以使人感到真象听着二人谈话,不至于象听留声机片。答话不必一定直答所问,或旁引,或反诘,都能使谈话略有变化。心中有事的人往往所答非所问,急于道出自己的忧虑,或不及说完一语而为感情所阻断。总之,对话须力求象日常谈话,于谈话中露出感情,不可一问一答,平板如文明戏的对口。
善于运用对话的,能将不必要的事在谈话中附带说出,不必另行叙述。这样往往比另作详细陈述更有力量,而且经济。形容一段事,能一半叙述,一半用对话说出,就显着有变化。譬若甲托乙去办一件事,乙办了之后,来对甲报告,反比另写乙办事的经过较为有力。事情由口中说出,能给事实一些强烈的感情与色彩。能利用这个,则可以免去许多无意味的描写,而且老教谈话有事实上的根据——要不说空话,必须使事实成为对话资料的一部分。
风格:风格是什么?暂且不提。小说当具怎样的风格?也很难规定。我们只提出几点,作为一般的参考:
(一)无论说什么,必须真诚,不许为炫弄学问而说。典故与学识往往是文字的累赘。
(二)晦涩是致命伤,小说的文字须于清浅中取得描写的力量。Meredith(梅雷迪思)每每写出使人难解的句子,虽然他的天才在别的方面足以补救这个毛病,但究竟不是最好的办法。
(三)风格不是由字句的堆砌而来的,它是心灵的音乐。叔本华说:“形容词是名词的仇敌。”是的,好的文字是由心中炼制出来的;多用些泛泛的形容字或生僻字去敷衍,不会有美好的风格。
(四)风格的有无是绝对的,所以不应去摹仿别人。风格与其说是文字的特异,还不如说是思想的力量。思想清楚,才能有清楚的文字。逐字逐句的去摹写,只学了文字,而没有思想作基础,当然不会讨好。先求清楚,想得周密,写得明白;能清楚而天才不足以创出特异的风格,仍不失为清楚;不能清楚,便一切无望。
阳台-蔡晓玲 - 副刊 文艺春秋 星洲网 Sin Chew Daily
===================================
# 蔡晓玲/阳台
-----
今年3月中旬,首相宣布整个马来西亚实施行动管制,大学也暂时停课了。
带着一点点愧疚在心里(世界很乱,我却有感岁月静好),我想我是无法领略“一万年太久,只争朝夕”那样的精神的,我只想要时间像阳光一样挥霍地撒在地上,而我也如此无感地让它爬满我的身上。如果生活这样,即使我无法写诗,我仍觉得我是个诗人。
我一个星期去一次附近的超市买菜,其他时间都在家里。
上午我把窗帘拉开,坐在客厅的沙发上晒太阳。晒久了我会觉得自己是一只家猫,或一件刚洗好的衣服,充满着懒洋洋的味道。晚上我也在沙发坐着,吃自己弄的小菜比如煎饺配啤酒,看洪尚秀的电影。我把洪尚秀的电影都看完了,看到后来我开始认为时间的存在都是照镜子,有正面和反面,这时对那时错。渐渐地我甚至想不起来今天几号,日子对我来说已经没有太大的意义。
久未呼吸外面的空气之后,我竟出现呼吸困难心脏疼痛等缺氧状态,于是每天傍晚我会走到阳台去吹吹风。阳台没有任何盆栽,我就靠着户外的远山远树感受绿意,吸收氧气。
主任拨电话给我,问我想不想要一些玫瑰花盆栽。因为她相熟的朋友在金马伦高原经营盆栽生意,但行动管制期间国人无法出门,那些漂亮的玫瑰花都要凋谢了。我最后还是拒绝了,我没有遗传到父母这方面的才能,我是连仙人掌都会种死的人。我家只有宜家买的假盆栽放在客厅摆设,我已经非常心满意足。
想起我父母那一辈人也是特别热衷于栽种。我们家后院种有所谓的“功能菜”,比如班兰叶,添加在白饭中一起煮,煮好的饭有一股清香,还可以驱虫。再来就是芦荟,清热解毒少不了芦荟汤,煮菜割伤手马上到后院切一截芦荟撸伤口。还有小辣椒,煮菜煮到一半可以摘几条丢进去加辣,还可以做辣酱配煎鱼吃。我们老家门前种的仙人掌也常年开花,我以前跟同学说,我家就是那一间仙人掌开花的房子。
大部分于吉隆坡生活的人都住在公寓,我刷脸书看见一位朋友竟在自己的公寓阳台上种了好多盆菜,满满的像要把阳台都挤爆了。我的父母如果住在公寓里,大概会跟那些公寓的菜一样,有种英雄无法伸展的窘迫吧。
那段时间有一个女生朋友偶尔会信息我,说她几乎要搬到阳台去住了。她和先生住在一房一厅的套房里,以前各忙各的倒是相安无事。行动管制之后两人被逼朝夕相对,她不确定自己是受不了先生的声音抑或气味,反正她每天都必须独自蜗在阳台上好几个小时。我问她在阳台能做什么,她说都可以啊。可以滑手机聊电话,或数邻居,她说原来隔栋楼层住着102户人家,说不定不久之后便可以掌握那些人的日常活动了。我安慰她说,那你拥有的是永远都不会重复也不会结束的电视节目。
我家阳台的视线跟她的不同。我只能看到隔栋的停车楼层,那些停止不动的车子。幸运的是,我不需要躲避任何人。
小学时候我也常在阳台活动。我们的家是双层排屋,隔壁家有一对姐弟与我年龄相仿,我从阳台上往下看,经常看见他们俩在屋前的院子腻在一起玩。有时我会跨过阳台的护栏,蹑手蹑脚地走在屋顶上。这其实一点都不好玩,我怀疑自己这么做的理由只是在模仿猫。我们家的猫或附近的猫总是喜欢在屋顶上看风景。我很好奇那到底是怎么样的感觉。我就像那些不擅游泳的人到了泳池,总是抓住泳池的栏杆,我也只敢在阳台护栏边笔直的来回走动。我偶尔会有一股冲动想跨到隔壁家的屋顶上,再爬到他们的阳台,然后敲他们家房间的门,找那一对姐弟。
童年和行动管制期间一样,时间是永无止境的。我在午觉后起来,太阳仍还没下山,我会打开父母房内的小抽屉,里面有他们年轻时候的情书,用一条红色布绳把一整叠的信捆绑起来。我随意抽读,亲爱的敏,爱你的选。亲爱的选,爱你的敏。阳台连接着两个房间,晚上我从另一个房间走到阳台上蹲着,蹲在父母房外听他们说话的声音。说话的内容听不清楚,但我一直听到他们的笑声。
当我还没学会享受孤独,孤独已经先抵达。
我现在住的公寓阳台上没有猫光临,但每天会有不同的东西。比如一根抽过的烟,一片花瓣,一些叶子。我还曾经遇见一只麻雀。
某天被鸟叫声吵醒,我循着叫声走到客厅,拉开窗帘发现有麻雀不知为何被困在我的公寓阳台。它飞得不够高,被阳台的玻璃护栏挡住,而另一只麻雀站在玻璃护栏的边缘上看它,它们唧唧叫像在对话。
发现我以后,玻璃上的麻雀飞走了,阳台上的麻雀就更紧张了。我决定要带它离开我的阳台。
搜寻网路上拯救鸟的方法,我准备了一个塑胶袋和一块布料柔软的布。我拉开落地窗走到阳台上,麻雀缩到阳台最角落,我先蹲下跟它说话。它很冷静地听,还认真看我,好像明白了。
之后开始行动。我看准它的头,把布从它的头部盖下去,它就不动了。我把它用布包好放进塑胶袋中。
我的公寓单位楼下是供住户散步运动的小公园。我把它带到那里去,把它从袋子中取出,打开软布发现它瘫软在布中央。我心一惊,赶快帮它立正,跟它说你到草地了哦。它大概只是头昏吧,几秒钟后从我眼前飞走了。
我快喜极而泣,感觉生命又可以继续了。
救了鸟以后我一直惦念着鸟身柔软的触感。我想起那个日本民间故事《仙鹤报恩》。里面提到仙鹤叼自己的羽毛来织布,那匹布十分十分柔软,可以卖很好的价钱。我小时候读了只能从猫毛去想像那种柔软。以前在老家,我都是负责赶鸟的,赶它们是为了救它们。老家后院常有麻雀要来偷吃猫碗剩下的饭粒,猫会躲在父母种的功能菜丛中埋伏鸟。我会故意发出声音来驱走麻雀,让猫无法得逞。
那些曾经跟我紧紧相依的猫最后都不在了。
离开家里上大学以后,我曾经跟同住的友人一起养了一只西施犬。那时候租的房间有一个阳台,阳台上有几张藤椅,我和屋友们偶尔会坐在那里聊天。晚上天气凉快,我有时会一个人抱着西施坐在阳台上吹风。西施总是害怕着阳台,缩在我的怀里颤抖。他是很黏人又很胆小的小孩。
我那时是全职研究生,平时都在房间读书写论文,只有我陪西施,或西施陪我。我会打开通向阳台的房门,让空气流通。西施会坐在那个房门看风景,舌头歪摆在嘴的一边,一脸幸福的神态。他从来都不敢跨到阳台去。
唯有一回我回乡过年,室友上班了,只有西施自己在房内。室友出门前照常把房门打开让西施吹风。后来房子对面的兽医诊所联系我们说,他们看见我们的西施在阳台外的屋顶上走来走去。刚开始以为是一只长得像狗的猫,仔细观察后发现不对,真的是一只狗啊。幸好之前曾经带西施去他们的诊所看诊打预防针,他们认得他,其中一位兽医马上到我们邻居家去按铃,从隔壁的二楼阳台跨到屋顶把西施救下来。
我想像他在房内听见外面的人声,循着人声走到阳台上,远眺对面商店来来往往的人,他想要找人陪伴,于是又从阳台走到屋顶上。他就像小时候的我,他只是太寂寞了。
与室友分道扬镳以后,我再也不曾见过西施。后来友人说,有一次他在车里对着一个在车旁走过的女生发出低低的呢喃声。那个女生和我留着一样的长卷发,背影像我。我觉得那个女生是我的幻影也是一则寓言。我不能回头,免得我回头了再转身离开,我们都会更难过。
西施就像其他失散或离世的猫一样,最后都不见了,留给我的是羽毛一样柔软的东西,很轻很轻,却是生命中无法承受之轻。
行动管制结束后,我发现很多东西也变了。比如以前很爱去的咖啡馆突然收了,店家几个月没有生意,经营不下去。还有我那些失业的朋友,正在想着未来该何去何从。而那位在阳台躲避先生的女生朋友自己买了一间很大的房子,明明足够她与先生分据各自的私人空间,他们的婚姻却走不下去了,正在办理离婚手续。
张爱玲的倾城之恋,写的是时代成全了我们的爱情,但有时候却是时代让我们看清了自己,瓦解了爱情。
我又回到忙碌的日子了。当我终于要被生活打败以前,我必会想像着那个无所事事的时刻,阳台上的光与风一直带我到一片无边无际的大草原。想起以前大学本科毕业在即,一位老师送给我们的祝福语竟是:人要盲目乐观的生活下去。
作者 : 蔡晓玲
文章来源 :
星洲日报 2021-02-05
杨嘉仁 行程——父后百行 - 副刊 文艺春秋 星洲网 Sin Chew Daily
========================================
[https://www.sinchew.com.my/content/content_2397663.html](https://www.sinchew.com.my/content/content_2397663.html)**
# 杨嘉仁/行程——父后百行
文艺春秋
-----
```
睡房暗角搁着公事包
上面的银亮纹理是
午觉外,一场凝滞的雨
冲刷多虫鸣的旧公路,和热气腾腾
喧嚣大道旁交错的枝桠
延绵半岛的梦境
覆盖汲汲流淌的汗
风砂的刮痕,若有若无
再次打开时——毛笔字洋洋洒洒
批下的命书。族谱复印本。
小学成绩册。尺寸不一黑白旧照。
多褶皱大伯公千字图。房屋买卖合同。最近的
电话账单。修车收据。中药处方——
早已叠好静躺。风吹了进来
不再掀起什么
还有一幅地图,时间的薄片
收在看不见的某处
孩子的地理课启蒙
是桌上的本子——每星期写下客栈地址与电话
无论落脚亚罗士打。大山脚。高渊。
太平。江沙。怡保。金宝。
关丹。龙运。瓜拉丁加奴。哥打峇鲁。
延绵油棕树急速倒退——
必须赶路的时候,能理会
电波不清,老旧收音机的预报吗?
不就是多云,多雷阵雨
即使天晴,头顶也常有
一路风驰,超速,而不雨的云
能预报放空的路中
闪避不及的事物吗?
能悠悠看见远方
如年轻时路过大山脚庙宇,守庙人说
“多添香油吧,这里会出首相”
在绘声绘影中等待的首相,后来
搬到隔邻住宅区山坡上
在近回教堂处三岔路口再次被捕
预言中的2020年仍在空转,转眼即将过去
那天,医院走廊尽头的阳光里
你看见远方一幅烟熏的地图
父辈从海拔千米的安溪山上,日夜
徒步到厦门,展开干渴的水的行程
延绵浪花急速倒退——
厦门港——维多利亚港——新加坡港
“山里沉默许久。另一本
深连血脉 ,而不存在的族谱
得穿过雾气,翻越多陡坡
景致参差的祖辈口音
循日月星辰,山川草木之间的诗句
往北方山头寻去”
你看见延绵橡胶树急速倒退——
新村围篱竖起,胶刀划过露珠
眼光别过,小碗里的
菜叶和稀饭,别过16岁那年
母亲骤逝,远走首都拥挤潮湿的巴刹
奋力刨开,年轻国家的椰子
已不记得溅出的椰汁是否酸涩
延绵绿色和群众急速倒退&——
双峰塔仍未竖起,骏马奔驰
在称作安邦的扁平草地,或许是
周末,以至人生中少有
带着闪亮的全新名字
奋力奔跑呐喊的时刻
当声光渐渐隐没在凝滞的雨里
你或坐或卧,翻看报纸,按时烧香
吃饭,休息。和门窗一样寡言
所有的时间急速倒退——别过
堆叠的药盒。营养品。检测报告。复诊卡。
你在设置精密仪器的房间闭目静躺
洗涤了血液,清空了杂质,积水
身体已轻盈无事
没有神,预报过的七夕清晨
最后一觉,在睡着的时刻渐渐终止
荧幕上闪现多个问号
源源不绝的氧气继续
输往另一个世界的花园
你仍在平缓呼吸,或许在一个湖边散步
几位马来护士匆忙寻找
枕边消失的护身符
而基督正涉水而来
“美好的仗已经打过。”
“谁没有浮沉水面,张嘴如鱼的时刻呢?”
批命书的最后一页偈语
“夕阳无限好,只是近黄昏”
该如何呼应这清晨,无边的蓝
仿佛万劫以来不曾有云
阳光穿透地表,所有虚实的黑色
一只老鹰在太平间上空盘旋
国旗飘扬,蚊子与病毒横飞
“欢乐假期”旅游巴士在路边停着
难以完成一首诗的时节
你若躺成意象,加入
油纸伞和莲花宝灯的行列
成为虚空的一部分
你是否依然承载着什么何以成意象
你若站成意象,在宽广多雾的月台徘徊
成为回忆的一部分,你不曾亦无法离开
你必须迅速化身乘客,赶上
一趟四十九日,上山的列车
无需携带公事包(公事包久已无公事)
无需开车了。能够专注看窗外急速倒退
乏善可陈,多纷扰的世界
不再有雨。列车将穿越真实不虚的地图——
高处照见,更久远的微尘
务必在最明亮的月台下车
(头顶总有一道,大家都提过的光)
时间将不再急速前进,或倒退
列车与月台,和所有悬浮的意象
事物之间的边界,都将在亮光中消失
再也没有诗,或经文,所能轻易碰触的
你会渐渐忘却名字,回到无边的真相里
安住,再也无需——启程。
```
作者 : 杨嘉仁
文章来源 :
星洲日报 2020-12-25
养蜂人-王晋康
========================
养蜂人-[[王晋康]]
------
上帝用最简明的规则建造了无比精妙繁复的宇宙,而今天,人类仅仅用0和1两个元素就建构了一个高踞于人类智慧之上的上帝。
副研究员林达的死留下许多疑问。警方从一开始就不相信是自杀,但调查几个月后仍没有他杀的证据,只好把卷宗归到“未结疑案”中。引起怀疑的主要线索是他留在电脑屏幕上的一行字(他坐在单身公寓的电脑椅上,死亡原因是服用了过量安眠药),但这行字的意义扑朔迷离,晦涩难解:
养蜂人的谕旨。不要唤醒蜜蜂。
很多人认为这行字说明不了什么,它是打在屏幕上的,不存在“笔迹鉴定”的问题。因而可能是外人敲上的,甚至可能是通过网络传过来的。但怀疑派也有他们的推理根据:这行字存入记忆的时刻是13日凌晨3点15分,而法医确定他的致死时间大约是13日凌晨3点半到4点半,时间太吻合了。在这样的深更半夜,不会有好事者跑到这儿敲上一行字。警方查了键盘上的指纹,只发现了林达和他女友苏小姐的。但后来了解到,苏小姐有非常过硬的不在现场的证据——那晚她一直在另一个男人的床上。
这么着就只有两种可能:或者,这行意义隐晦的字是林达自己敲上去的,可能是为了向某人或警方示警;或者,是某个外人输进去的,但他绝不会是游戏之举而是怀着某种动机。不管哪种可能,都偏于支持“他杀”的结论。
调查人第一个询问的是科学院的公孙教授,因为他曾是林达的博士生导师,林达死后又曾在同事中散布过林是“自杀”的猜测。调查人觉得,先对观点与自己相左的人进行调查是比较谨慎的,可以避免先入为主的弊病。当然这只是原因之一,是那种比较讲得出口的原因。实际上呢……人们都知道警方的一条原则:报案人的作案可能性必须首先排除。
公孙教授的住宅很漂亮,他穿着白色的家居服,满头白发,眉目疏朗。对林达之死他连呼可惜,说林达是他最看重的人,一个敏感的热血青年。他还算不上最优秀的科学家(因为他太年轻),但他有最优秀的科学家头脑,属于那种几十年才能遇上一个的天才,他的死亡是科学界的巨大不幸。至于林达的研究领域,他说是比较虚的,是研究电脑的智力和“窝石”,他的研究当然对人类很重要,但那是从长远的意义而言,并没有近期的或军事上的作用,“绝不会有敌对国家为了他的研究而下毒”。
谈话期间他的表情很沉痛,但仍坦言“林达很可能是自杀”。因为天才往往脆弱,他们比凡人更能看穿宇宙和人生的本质,也常常因此导致心理的失衡。随后他流畅地列举了不少自杀的科学天才,名字都比较怪僻,调查人员未能记录(保存有录音),只记得提到一人是美国氢弹之父费米的朋友,他搞计算不用数学用表(那时还没有计算机),因为数学用表上所有的数据他都能瞬时心算出来,这个细节给调查人员的印象很深。但此人三十多岁就因精神崩溃而自杀。公孙教授说:
“举一个粗俗的例子,你们都是男人,天生知道追逐女人,生儿育女,你们绝不会盘根究底,追问这种动机是从哪儿来的。但天才能看透生命的本质,他知道性欲来自荷尔蒙,母爱来自黄体胴,爱情只是‘基因们’为了延续自身而设下的陷阱。当他的理智力量过于强大、战胜了肉体的本能时,就有可能造成精神上的崩溃。”
调查人员很有礼貌地听他说完,问他这些话是否暗示林达的死“与男女关系有关”。很奇怪的是,公孙教授的情绪在这儿有了一个突然的变化,他不耐烦地说,很抱歉,他还有课,失陪。说完就起身送客。调查人员并未因他的粗暴无礼而发火,临走时小心地问,他刚才所说的电脑“窝石”究竟是什么东西,“肯定那是极艰深的玩意儿,我们不可能弄懂,只是请你用最简单的语言描绘出一个大致的轮廓”。
公孙教授冷淡地说:以后吧,等以后我有时间。
第二个被调查者是林达的女友苏小姐。她相当漂亮,可以说是性感,那时天气还很凉,但她已经穿着露脐装,超短裙,一双白皙的美腿老在调查人的眼前晃荡。两个调查者对她的评价都不高,说她绝对属于那种“没心没肺”的女人,林达尸骨未寒,她已经谈笑风生了,连点悲伤的外表也不愿假装,甚至有调查人在场的情况下,她还在电话里同某个男人发嗲。
苏小姐非常坦率,承认她和林达“关系已经很深”,不过早就想和他拜拜了,因为他是个“书呆子,没劲”。不错,他的社会地位高,收入不错,长得也相当英俊,但除此之外一无可取。幽会时林达常皱着眉头走神,他的思维已经陷入光缆隧道之中,无法自拔,那是狭窄、漫长而黑暗的幽径。他相信隧道尽头是光与电织成的绚烂云霞,上帝就飘浮在云霞之中。林达很迷恋他的女友,迷恋她高耸的乳胸、修长的四肢、浑圆的臀背及其他种种妙处,即使在追踪上帝时,他也无法舍弃这具肉体的魅力,公孙教授的分析并不完全适合他,但幽会时他又免不了走神。“我看近来他的神经不正常,肯定是自己寻死啦!”
关于林达死于“精神失常”的提法,这是第二次出现,调查者请她说一些具体的例证,苏小姐说,最近林达对白蚁啦,蚂蚁啦,粘菌啦经常挂在嘴边。比如他常谈蜜蜂的“整体智力”,说一只蜜蜂只不过是一根神经索串着几个神经节,几乎谈不上智力,但只要它们的种群达到临界数量,就能互相密切配合,建造连人类也叹为观止的蜂巢。它们的六角形蜂巢是按节省材料的最佳角度,符合数学的精确。对了,近来他常到郊区看一个放蜂人……
调查者立即联想到电脑屏幕上的奇怪留言,不用说,这个放蜂人必定是此案的关键。他们请她尽量回忆有关此人的情况。苏小姐说我真的不清楚,他是一个人骑摩托车去的,大概去过3次,都是当天返回,所以那人肯定在京城附近。林达回来后的神情比较怪,有时亢奋,有时忧郁,说一些不着边际的话,什么“智力层面”等,我记不住,也没兴趣听。
调查者当然也盘问了案发那晚她的活动,确信她不在现场,便准备告辞。这时苏小姐才漫不经心地说,噢,对了,林达有一件风衣忘在我家,里边好像有放蜂人的照片。听了这句话,调查人的心情真可以用喜出望外来形容。衣袋里果然有一厚叠照片,多是拍的蜂箱和蜂群,只有一张是放蜂人的。那人正在取蜜,戴着防蜂蜇的面罩,模样不太清晰。但蜂箱上提供了宝贵的信息,上面有红漆写的地址:浙江宁海桥头。
调查进行到这儿可以说是峰回路转。老刑侦人员常有这样的经历:看似容易查证的线索会突然中断,看似山穷水尽时却突然蹦出一条线索。3天后,调查人已经来到冀中平原,坐在这位放蜂人的帐篷里。四周是无边无际的油菜花,闪烁着耀眼的金黄。至于寻找此人的方法,说穿了很简单。他们知道这些到处追逐花期的放蜂人一般都不自备汽车,而是把蜂箱交火车或汽车运输。于是,他们在本市联运处查到了浙江宁海桥头张树林在15天前所填的货运单据,便循迹追来了。
不过见面之后比较失望。至少,按中国电影导演的选人标准,这位张树林绝对不是反派角色。他是个矮胖子,面色黑红,说话中气很足,非常豪爽健谈。可能是因为放蜂生活太孤单了,他对两位不速之客十分热情,逼着客人一缸一缸地喝他的蜂糖水,弄得调查人老出外方便。帐篷里非常简陋,活脱一个21世纪的中国吉普赛。一只行军床上堆着没有叠起的毛毯,饭锅是用三块石头支在地上,摔痕斑斑的茶缸上保留着“农业学大寨”的红字。他的唯一同伴是他的小儿子,一个非常腼腆的孩子,他向调查人问声好,就躲到外边去了。
放蜂人的记忆力极好,20天前的往事像是照了相似的,记得纤毫不差。一看到那叠照片他就说没错,是有这么个人找过我几次,姓林,三十一二岁,读书人模样,穿着淡青色的风衣和银灰色毛衣,骑一辆嘉陵摩托,车牌号是京E00120。“我们俩对脾气,谈得拢!聊得痛快!”
问他究竟谈了什么,他说都是有关蜜蜂生活习性的,便滔滔不绝地说下去。调查人接受了这番速成教育,离开时已经变成半个蜜蜂专家了。老张说:蜜蜂靠跳“8”字舞来指示蜜源,“8”字的中轴方向表示蜜源相对太阳的角度;蜜蜂中的雄蜂很可怜,交配后就被逐出蜂巢饿死,因为蜂群里不养“废人”;养蜂人取蜜不可过头,否则冬天再往蜂箱里补加蜂蜜时,它们知道这不是它们采的,就会随意糟蹋;蜂群大了,工蜂会自动用蜂蜡在蜂巢下方搭三四个新王台,这时怪事就来了!勤勉温驯的工蜂突然变得十分焦躁,它们不再给蜂王喂食,并成群结队地围着它,逼它到王台中产卵,王台中的幼虫就是以后的新蜂王。新王快出生时,有差不多一半的工蜂跟着旧王飞出蜂箱,在附近的树上抱成团,这时放蜂人就要布置诱箱,否则它们会飞走变成野蜂。进入新箱的蜜蜂从此彻底忘了旧巢,即使因某种原因找不到新巢,宁愿在外边冻死饿死也决不回旧巢,就像是它们的记忆回路在离开旧巢时卡查一下子给剪断了!这时旧巢中正热闹呢,新王爬出王台后,第一件事就是寻找其他王台,把它咬破,工蜂会帮它把里边的幼虫咬死。不过,假如两只蜂王同时出生,工蜂们就会采取绝对中立的态度,安静地围观着这场决斗,直到其中一只被刺死,它们才一拥而上,把失败者的尸体拖到蜂箱外。“想想这些小生灵真是透着灵气,不说别的,你说分群时是谁负责点数?那么大的数可不好点哪,它们又没有十个指头。”
林达与放蜂人并肩立在如雪的杏花里,白色的蜂箱一字儿排在地头,黄褐相间的小生灵在他们周围轻盈地飞舞。它们有自己的社会,有自己的数学和化学,有自己的道德、法律和信仰,有自己的语言和社交礼仪。一只孤蜂不能算是一个生命,它绝不可能在自然界存活下去。但蜂群达到一定数量后,就产生一种整体智力。所以,称它们为“蜂群”不是一个贴切的描述,应该说它们是一个叫做“大蜜蜂”的生物,而单个蜜蜂只能算作它的一个细胞。智力在这儿产生突跃,整体大于个体之和。林达对着养蜂人礼拜,林达对着蜂群自言自语,他说这些小生灵可以让我们彻悟宇宙之大道。他认真地追问老张,蜂群“分群”的临界数量是多少,但他又反过来说,精确数值是没有意义的,只要大略了解有这么一个“数量级”就行。放蜂的老张弄不明白这些话。
调查人员第二次听到“临界数量”这个词。这个词听起来有点神秘,也多少带点危险性(他们都知道核弹爆炸就有一个临界质量)。但他们针对这个词的追问得不到放蜂人的响应。老张只是夹七夹八地扯一些题外话,他指着那张戴面罩的照片说,这张照片是林先生特意给我照的,林先生说要寄到我家,不知道寄了没有。“本来不是取蜜期,他非要我戴上防蜂罩为他表演。他说我带上它像是戴上皇冠,说我是蜜蜂的神,蜜蜂的上帝。这个林先生不脱孩子气,净说一些傻话。”
调查人很敏锐,从这句平常话中联想到苏小姐说的“神经失常”,便掉头紧追下去。老张后悔说了这句话──他不想对外人讲说林先生的“缺点”。在再三追问下他才勉强说,对,林先生的确说过一些傻话。他说过,老张你“干涉”了蜜蜂的生活——你带它们到处迁徙寻找蜜源,你剥夺了它们很大一部分劳动成果供人类享用,你帮它们分群繁殖,如此等等。但蜜蜂们能察觉这种“神的干涉”吗?当然这肯定超出它们的智力范围,但它们能不能依据仅有的低等智力“感觉”到某种迹象?比如,它们是否能感觉到比野蜂少了某种自由?比如,当养蜂人在冬天为缺粮的蜂群补充蜂蜜时,它们是否会意识到有一只仁慈的“上帝之手”?它们糟蹋外来的蜂蜜,是否是一种孩子式的赌气?“林先生把我给逗笑了,我说它再聪明也是虫蚁呀,它们咋能知道这些。我看它们活得蛮惬意的。不过,”他认真地辩解着,“林先生绝不是脑子有问题,他是爱蜂爱痴了,钻到牛角尖里了。”
调查人对谈话结果很失望,这条意外得来的线索等于是断了。他们曾把最大的疑点集中在“养蜂人”身上,但是现在呢,即使再多疑的人也会断定,这位豪爽健谈的张树林绝不是阴谋中人。两人临告辞时对老张透露了林先生的不幸,放蜂人惊定之后涕泪滂沱,连声哽咽着“好人不长寿,好人不长寿哇”。
调查人又到了北大附中,林达的最后一次社会活动是来这里对学生作了一场报告。当时负责接待的教导处陈主任困惑地说,这次报告是林达主动来校联系的,也不收费。这种毛遂自荐的事学校是第一次碰上,对林达又不熟悉,原想婉言谢绝的,但看了那张中国科学院的工作证,就答应了。至于报告的实际效果,陈主任开玩笑说“不好说,反正不会提高这次期中考试的成绩”。
他们用随机抽样的方法喊来了5个听过报告的学生,两男三女,拘谨地坐在教导处的木椅上。这是学校晚自习时间,一排排教室静寂无声,窗户向外泻出雪亮的灯光,光怪陆离的霓虹灯在远处的夜空中闪亮。学生们的回答不太一致,有人说林先生的报告不错,有人说印象不深,但一个戴眼镜女生的回答比较不同:
“深刻,他的报告非常深刻,”她认真地说,“不过并不是太新的东西。他大致是在阐述一种新近流行的哲学观点:整体论。我恰好读过有关整体论的一两本英文原著。”
这个女孩个子瘦小,尖下巴,大眼睛,削肩膀,满脸稚气未脱,无论年龄还是个头显然比其他人小了一套。陈主任低声说,你别看她其貌不扬,她是全市有名的小天才,已经跳了两级,成绩一直是拔尖的,英文程度最棒。调查人请其他同学回教室,他们想,与女孩单独谈话可能效果更好些。果然,小女孩没有了拘谨,两眼闪亮地追忆道:
什么是整体论?林先生举例说,单个蜜蜂的智力极为有限,像蜂群中那些复杂的道德准则啦,复杂的习俗啦,复杂的建筑蓝图啦,都不可能存在于任何一只蜜蜂的脑中。但千万只蜜蜂聚合成蜂群后,这些东西就自然而然地产生出来──为什么如此?不知道。人类只是看到了这种突跃的外部迹象,但对突跃的深层机理毫无所知。又比如,人的大脑是由140亿个神经元组成,单个神经元的构造和功能很简单,不过是根据外来的刺激产生一个冲动。那么哪个神经元代表“我”?都不代表,只有足够的神经元以一定的时空序列组合在一起,才会产生“窝石”……
调查人又听到“窝石”这个词,他们忙摆摆手,笑着请她稍停一下。小姑娘,请问什么是窝石?我们在调查中已经听过这个词,不会是肾结石之类的东西吧,从没听过脑中也会产生结石。
小女孩侧过脸看看他们,有笑意在目光中跳动。她忍住笑意耐心地说,“我识”就是“我的意识”,就是意识到一个独立于自然的“我”。人类婴儿不到1岁就能产生“我识”,但电脑则不行,即使是战胜卡斯帕罗夫的“深蓝”,它也不会有“我”的成就感。“这是说数字电脑的情形,自从光脑、量子电脑、生物元件电脑这类模拟式电脑问世以来,情况已经有了变化。林先生在报告中也提到了‘标准人脑’和‘临界数量’……”
调查人员相对苦笑,心想这小女孩怕是在用外星语言谈话!他们再次请她稍停,解释一下什么是“标准人脑”,这个名词听上去带点凶杀的味道。女孩简单地说,这只是一个度量单位啦,就像天文距离的度量可以使用光年、秒差距、地球天文单位一样。过去,数字电脑的能力是用一些精确的参数来描述,像存储容量(比特)、浮点运算速度(次/每秒)等。对于模拟电脑这种方式已不尽适合,有人新近提出用人脑的标准智力作参照单位。这种计算方法还没有严格化,比如对世界电脑网络总容量的计算,有人估算是100亿标准人脑,有人则估算为10000亿,相差悬殊。“不过林先生有一个非常精辟的观点,他说,精确数值是没有意义的,不管是多少,反正目前的网络容量早已超过临界数量,从而引发智力暴涨,暴涨后的电脑智力已经不是我们所能理解的层面……”
调查人员很有礼貌地打断她的话,说很感谢她的帮忙,但是不能再耽误她的学习时间了,再见。然后苦笑着离开学校。
他们还询问了死者的祖父祖母(林达的父母不在本地)。按采访时间顺序来说他们是排在第三位,但调查报告中却放到最后叙述。这可能是一种暗示——暗示写报告者已倾向于接受林达祖父对死因的分析。那天他们到林老家中时,客厅里坐满了人,一色是60岁以上的老太太,头上顶着白色手巾,都在极虔诚极投入地祈祷着。林老急忙把两人让进他的书房,多少带点难为情地解释道,这都是妻子的教友,她们在为死者祷告。
他对爱孙的不幸十分痛心,因为他知道孙子是一个天才,知道他一直在构筑一种代号“天耳”的宏大体系,用以探索超智力,探索不同智力层面间交流的可能性。但在谈到林达的死因时,林老肯定地说是自杀,这点不用怀疑,你们不必为它耗费精力了。因为林达死前来过一次电话,很突兀地谈了宗教信仰问题,“可惜我们没听出他的情绪暗流,我们真悔呀。”
林老说,近两年他老伴一直在向孙子灌输宗教信仰,不过她的努力一直毫无成效。看得出来,孙儿只是囿于礼貌才没有当面反驳奶奶。但在那次奇怪的电话中林达突兀地宣布,他已经树立了三点信仰:1.上帝是存在的;2.上帝将会善意地干涉人类的进程,但这种干涉肯定是不露形迹的;3.人类的分散型智力永远不能理解上帝的高层面的思维。“我不知道他为什么突然获得了宗教的感悟,也不知道他为什么讲给我听,而不是他奶奶。”林老缓缓地摇着头,苦涩地说,“我不赞成他信教,但我觉得这三个观点倒是可以接受的,它实际上正符合西方国家开明放达的现代宗教观。不过孙子当时的情绪相当奇怪,似乎很焦灼,很苦恼。他在电话里粗鲁地说,正因为我确定了上帝的存在,我才受不了这个鬼上帝。我不能忍受有一双冥冥在上的眼睛看着我吃喝拉撒睡,就像我们研究猴子的取食行为和性行为一样。尤其不能忍受的是,我们穷尽智力对科学的探索,在他看来不过是耗子钻迷宫,是低级智能可怜的瞎撞乱碰。这样的人生还有什么意义!我和妻子当然尽力劝慰一番,可惜我们没听出他的情绪暗流,我们真悔呀。”林老摇着白发苍苍的头颅,悲凉地重复着。
调查人怀疑地问,他真的会仅仅为这种异想天开而自杀?林老说会的,他会的,我们了解他的性格。林老自嘲地苦笑道,这正是林家的家风,我们对于精神的需求往往甚于对世俗生活的需求——可惜我见事迟了一步,没能劝转他。调查人告别他下楼,看见他妻子在门口同十几位教友们话别,教友们严肃地说,上帝会听到我们的祷告,一定会的,达儿一定会升入天堂。两人扭头看看林先生,林先生轻轻摇摇头,眸子中是莫名的悲哀。
那个星期六晚上,戴眼镜的小女孩做完作业,迫不及待地趴到电脑屏幕前。那是父母刚为她购置的电脑。一根缆线把她并入网络,并入无穷、无限和无涯。光缆就像是一条漫长的、狭窄的、绝对黑暗的隧道,她永远不可能穿越它,永远不可能尽睹隧道后的大千世界。她在屏幕上看到的,只是“网络”愿意向她开放的、她的智力能够理解的东西。但她仍在狂热地探索着,以期能看到隧道中偶然一现的闪光。林达在台上盯着她,林达盯着每一个年轻的听众,他的目光忧郁而平静。这会儿没人知道他即将去拜访死神,以后恐怕也没人理解他这次报告的动机。林达想起了创立“群论”的那位年轻的法国数学家伽罗瓦,他一生坎坷,关于群论的论文多次被法国科学院退稿──那时世界上还没有一个人能理解它。后来爱上一个不爱他的女人,为此在一场决斗中送命。他在决斗前夜通宵未眠,急急地写出群论的要点。至今,在那些珍贵的草稿上,还能触摸到他死前的焦灼。草稿的空白处了草地写着:来不及了,没有时间了。来不及了,没有时间了。
他为什么在死前还念念不忘他的理论?也许只有他和林达能互相理解。
林达说,蜜蜂早就具备了向高等文明进化的三个条件:群居生活、劳动和语言(形体语言)。相比人类,它们甚至还有一个远为有利的条件:时间。至少在6000万年前,它们已经建立了有效的蜜蜂社会。但蜜蜂的进化早就终结了,终结于一个很低的层面上(相对于人类文明而言)。为什么?生物学家说,只有一个原因,它们的脑容量太小,它们没有具备向高等智力发展的物质基础。如此说来,我们真该为自己1400克的大脑庆幸──可是孩子们啊,你们想没想过,1400克的大脑很可能也有它的极限?人类智力也可能终结于某个高度?
没有人向女孩转述过林达的遗言:不要唤醒蜜蜂。不过,即使转达过,她也可以不加理会的,因为她年轻。
**野性之口-小松左京**
========================================
<https://www.zhihu.com/question/41047159>
《野性之口》
小松左京
完全没有理由。
为什么需要一个理由呢?人们总想要为每一件事都找出理由,可真理是永远无法解释的。所有的存在为什么是现存的样态?为什么是以这种方式而不是别的方式存在?
那种理由,还没有任何人可以解答。
他望着窗外磨牙,胸中怒火熊熊。有时候,这种愤怒突然之间就把他淹没了,在他躯体的中心弥漫着一种剧烈的无理性的冲动,一种无法对任何人解释的毁灭的冲动。他猛地拉上窗帘,用力吸气、收紧肩膀,然后回到里屋。
我们生活的世界是毫无价值、荒谬可笑的。活着是一件荒唐无益的事情。首先,这个毫无价值的玩意儿——我自己——就荒谬得让人无法忍受。
为什么这样荒谬?
“为什么?”——还是这个问题。
毫无价值,荒谬可笑,仅仅因为它就是这样。每件事——财产、科学、爱情、性、生活,老于世故的人——自然、地球、宇宙——所有令人作呕的污秽,让人沮丧的愚蠢。所以—— 不。根本不是所以,而是无论如何,我真的要去做那件事。
我要去做。他无声地喊:我确实要。
当然,这将和别的事一样愚蠢——事实上,在一切各式各样的蠢事中间,也许是最愚蠢的?但至少这件事有那么一点刺激——一种锐利的感觉。也许这个详细周全的计划的核心就是一种疯狂的尝试?也许是这样,但至少—— 我就要开始做的这件事是任何人在头脑正常的时候从未尝试过的。
毁灭世界?历史上有千千万万人有过这样的狂想。而他这个想法不是那么陈旧的。
不可能有更荒谬的想法了,只有它才能扑灭他心头的怒火。我内心的火焰被一种高贵的绝望扇起来了……
进入内室,他锁上门,打开灯。现在——这想法使他两眼放光——现在开始了。
清冷的光线照亮了房间。一个角落里摆着一台家用电烤箱;一组煤气灶、一部切片机、大大小小的平底锅、一套刀具、一个装满各种调味料和蔬菜的壁橱。旁边是一个自动工作台,设置了全套程序,可以进行人类有史以来对身体进行过的任何外科手术——不管是难度多大、多么复杂的手术,即使是最大的医院里才能做的,这里也都能完成。手术台旁边,是一些假肢:手、脚;任何一种最先进的人造器官。
万事具备。他花了整整一个月时间去策划细节,又花了一个月准备工具。据他推算,作好全部准备至少又多花了一个月的时间。 好,那么——让我们开始吧。
他脱下裤子,爬上手术台,把控制器的许多电极接在身上,扭开摄像机。
开始了—— 他用一种戏剧化的姿势拿起手术台支架上的注射器,检查压力刻度,调整设置——调高了一点,因为这是第一次注射——然后把禁用的麻醉剂注射进他右大腿。
大约过了五分钟,这条腿完全失去了知觉,他扭开了自动手术机。机器运作时吱吱呜呜的声音;自动指示灯熄熄亮亮;他的身体不由自主被向后猛拉,同时黑色的机械手延伸出多个分支。
桌上凸出的夹子固定住腿的胫部和足踝 。一只钢爪握着一个消毒纱布包往下滑到大腿和骨盆的连接处。
电子解剖刀如丝一般细细地切过皮肤,所过之处非常炽热,几乎没有鲜血流出。切开肌肉组织……露出大动脉……用钳子把肉夹下来……包扎……切除并处理感染的肌肉表面……嗡嗡叫着的轮转机锯条旋转着切向股骨。锯条切中了骨头,那一刹那他闭上了眼睛。
几乎没有什么震动感。当内置钻石头的超高速锯条切过骨头时,只发出了轻微的摩擦声,同时给骨头切面敷上混合的强力酵素。在精确的6分钟内,他的右腿干净利落地同躯干分离了开来。
机器用纱布擦拭他浸透汗水的脸,然后递给他一杯药水。他把药水一口饮尽,深吸了口气。他的脉搏在飞快地上升,更多汗水如雨般涌出。但几乎没有失血,也没有什么近似疼痛的感觉。神经治疗很管用。不需要输血。他吸了一些氧气,以缓解头昏眼花的症状。
他那条和身体分离的右腿直挺挺躺在床上。透过透明塑料的绷带,可以看到:一圈外围包着黄色脂肪的收缩的粉红色肌肉组织、白色的骨骼中心可见黑红色的骨髓。几乎没有流血。他望着这条膝盖骨突出的毛绒绒的玩意,几乎忍不住要歇斯底里地狂笑起来。但是此刻没有笑的时间:还有更多的事需要做。
他休息了片刻以恢复体力,然后发出下一步工作的指令。
机器伸出一条机械手,抓起一条人造腿,把它安在刚才的切割面上;没有扎绷带的肌肉上药以后已经恢复了。人工突触中心的信息终端被与从切割处拉出来的神经叶鞘连在一起。终于,躯干的义肢被用带子和特殊医疗器械牢牢安在残余的大腿骨上。完成了。他试着小心地弯曲这条新腿。
到现在为止一切顺利。他极其小心地站起来:变化使他头昏、摇摇晃晃,但不管怎么说他可以站立也能慢慢走路了。假腿是用某种运动时声音很细微的轻金属制成的。没问题——够好的了——反正大部分时间里他都会坐轮椅的。
他举起自己的右腿从桌子头上放下去。腿太沉,几乎使他蹒跚了一下。他又一次在心里爆发了一阵野蛮的狂笑。我整个一生中一直拖着这些分量来来去去。切下这个肢体使他减轻了多少公斤的体重呢?
“好吧,”他咕哝着说,还在咯咯笑,“够了。现在该把血排干净了。”
他把这一大块肉扛上操作台,剥掉塑料包装,系住脚踝倒吊在天花板上,用他的双手挤压,从切口处放血。
后来,在洗涤槽里冲洗它的时候,上面的毛被水敷湿了,在所有动物的肢体中,它看上去最像一只巨大的蛙腿。他瞪着以古怪的姿势戳出不锈钢洗涤槽的那只脚的脚底心。
我的腿。凸出的膝盖,很难找到合脚鞋子的高脚背,一只运动员的脚上生的脚趾——这是我的腿!他终于再也忍不住了,爆发出一阵恶毒的狂笑,在笑声中痉挛地折起腰。最后,这只见鬼的坚韧的运动员的脚终于完蛋了……
是准备烹调的时候了。
他用大切片刀把这条腿从膝部切成两截,然后开始用一把锋利的猪肉刀剥皮。大腿骨裹着看上去很可口的肉,很是粗壮。当然,这是火腿。筋腱很有韧性;他用硬切片刀切得大汗淋漓,很快在身边垒起了厚厚的带着肌肉膜的肉块。他把大块胫骨处的肉放进装满滚水的大罐子,加上桂皮、丁香、芹菜、洋葱、茴香、藏红花、胡椒粒、其他调料和辛辣的蔬菜一起炖。脚被他丢掉了,只从足踝处刮了些肉下来。他把腿肉中用来做肉排的都切了片、擦了盐和胡椒,并拍打肉片使它们变软。
我会有勇气吃它吗?他突然问自己。结实的肉团总会梗在他咽喉的某处。他真的能够把它咽下去吗?
他咬紧牙关,油一般的汗水流了下来。我会吃的。这和人类一直以来烹制并享用其他有智慧的哺乳动物没有什么不同:母牛和绵羊,那些温和的,无辜的,有着悲伤眼睛的食草动物。原始人甚至吃自己的同类;有些种族直到现代还延续着吃人的习俗。为了吃而杀掉动物——也许这中间有正当的理由。其他食肉动物也不得不靠杀戮生存。但是人类……
从他们存在的那一天起,贯穿人类历史,有多少亿万人被杀掉而连吃也没有吃?和那个相比,这样绝对是清白无罪的。我将不去杀任何别的人。我不会去屠杀可怜的动物。通过这种方法,我自己吃的是我自己的肉。还有哪种别的肉能像这种一样毫无罪过?
煎锅里的油开始噼啪作响。他用颤抖的手抓起一大块肉排,犹豫片刻,把它丢进锅里。噼啪响的脂肪使空气中弥漫着一股香喷喷的味道。他仍在发抖,他把轮椅把手握得太紧,几乎要把它折短了。
好吧。我是一只猪。或者,人类比猪要糟糕得多:卑鄙,污秽。在我体内有个部分比猪还不如,还有个“高贵”的部分为比猪还不如感到无尽的愤怒。那个高贵的部分将把那比猪还不如的部分吃掉。这件事里有什么让人害怕的东西么?
被烤得金黄松脆的肉排在盘子上滋滋作响。他往上面抹了芥末,配上柠檬和奶油,浇上肉汁。他拿起餐刀的时候,他的手在打颤,餐刀敲在盘子上,发出叮叮当当的声音。他汗如雨下,用尽全力握住餐刀,切割,用叉子戳起来,然后提心吊胆地把它送进嘴里。
第三天,他截下了左腿。这一只,胫骨和全部表面都被抹上了大量奶油,用烤肉叉叉起来,架在旋转型烤肉架上烤了。至此他已不再恐惧。他发现自己惊人的可口:这个发现使一种混合着愤怒和疯狂的情绪在他心底牢牢扎下了根。
第一周以后,事情越来越艰难了。他不得不切断了自己的下半身。
在轮椅的方便马桶上,他最后一次享受了排泄的乐趣。当他喷射的时候,他大笑了。
看看这肮脏的货色!我排泄的是我自己,在我自己的内脏中储存然后变成粪便!也许这是自我蔑视的最高形式了——或者是自我颂扬的最高形式?
当他失掉了髋骨以下的部分,两条假腿就基本没用了。但他还让它们留在老地方。现在是换下内部器官的时候了,他向机器的电脑咨询:“当我把肠子吃掉之后,还会有食欲吗?”
“它不会受什么影响。”这就是回答。
他抛掉了大肠,把小肠和蔬菜一起炖,把十二指肠做成腊肠。他用人造器官换下了肝脏和肾脏,然后把这两个器官做了小炒。肚子他先放在一边,放在装着营养液的塑料容器中保存。
在第三周的末尾,他换下了他的心和肺,最后,他把自己跳动的心切成细丝油煎:这是连阿兹塔克主持献祭的祭师都无法想象的事情。(注:阿兹塔克人:16世纪西班牙人入侵时期生活在墨西哥中部的印地安人部族)
当他开始把自己的腹部做成餐点时,他开始清醒地意识到:人类是可以在毫无食欲的情况下机械进食的。腹部用酱油浸泡着,加上了大蒜和红辣椒。
在无数各种各样、希奇古怪的被当作食物的产品中,有多少完全与饥饿无关、纯粹是由于好奇而被开发的?即使好奇心得到了满足,人类还是会吃最不可思议的东西,如果他感到饥饿。吃自己同类的肉时,那种愤怒的感觉就像是用牙齿咬碎玻璃杯一样。
食欲的源泉来自于原始的侵略冲动:杀戮和吃食;践踏和粉碎;吞咽和吸收 ——那就是野性之口。
到现在,他的咽喉只能与一根管子相连。直接输送到血液的营养来自一个装满营养液的容器。内分泌活动由人造器官完成。在这张嘴的尽头,双臂都被吃完;唯一保留的是颈部以上的部分,而在第五十天头上,面部所有的肌肉几乎都被吃光了;剩下两片嘴唇在安装的弹簧支持下咀嚼。眼球只剩一只,另一只被吞进嘴里嚼掉了。
现在坐在轮椅上的,是和错综复杂的大大小小的管子堆在一块儿的一副骨架,在这副骨架上,唯一留存的是大脑和一张嘴巴。
不……
即使是现在,一只机械手臂正在剥去头皮,用锯条把头盖骨的顶部干净利落地切了下来。
在暴露的小脑上撒上盐巴、胡椒粉和柠檬汁,舀起满满一大勺——我的脑子,想到这是我的小脑。我怎么能尝这个东西呢?难道一个活人能够品尝自己脑浆的滋味吗?
勺子毁坏了灰色的大脑。没有痛苦——大脑皮层没有感觉。但到了这时,机械手舀出一勺勺灰色糊状的东西放到骷髅的嘴里,嘴巴贪婪地吞咽下去时,“味道”已经无法辨别了。
“是杀人案。”警官从屋里走出来时,面对挤满出口处的记者们说,“此外,这是一起残忍、野蛮得难以想象的罪行。罪犯无疑是一个严重的精神病患者。看上去像是某种变态的实验——身体被 一块块卸下来,然后装上人工器官……”
警官处理好媒体方面的问题,进了屋,擦去脸上疲惫的汗水。
从焚化炉过来的侦探疑问地看着他。“录像带已经烧毁了,”他说,“但是,你为什么要说这是一次谋杀呢?”
“为了维持社会的美好与和平。”警官做了个深呼吸。“把它宣布为谋杀——指挥一次官方的调查——然后让它成为我的秘密。这次案件——抹去案件中的证据——它们完全是不合常理的。你不能让一个正常的市民看到在一些人心灵深处的疯狂和自我毁灭的欲望。如果我们做了这样一件事情,如果我们不小心让人们看到了内心寄居的原始的野兽——好吧,你可以肯定会有人学这个人的样。这一种人——你没办法知道他们能做出什么……
“如果广大民众突然了解了这样的东西,人们将对自己的行为失去自信——他们会开始钻入自己灵魂深处的黑暗中。他们会彻底无法理解自己——完全失去控制! “你看,人类存在的根源是疯狂——所有动物心底的那种盲目的侵略性的冲动。如果人们意识到了这一点——如果有大批人用存在解放或自己管自己之类的口号来表达这种疯狂——那就是人类文明的终结。不管我们用什么样的法律、武力、或规章来约束,一切将完全失控! “人们把别的人撕碎,互相残杀,破坏、毁灭,这些征兆已经开始显现——这个人吞下融化的炸药自杀——那个人倒上汽油自焚而死——另一个光天化日之下在城市中心性交。当没再有什么理智的行为可以作为攻击对象,笼中的野兽就开始毁灭自己的心智——”
“啊呀——” 年轻的侦探从正在腐烂的骨架旁跳开。刚才,正当他想把仍然塞在骷髅嘴里的恶臭的勺羹取出来时,那骷髅的牙齿扣下来,咬住了他的食指,咬掉了指尖的一小块肉。
“小心呀,”警官疲惫地说,“一切动物生命的根基就是那张带着如饥似渴的吞噬欲望的嘴巴,巨大的野性之口……”
在那具裸露着大脑的骷髅上,残留的一只眼球开始变松,有力的弹簧替代了消失的肌肉,正在用肿胀的舌头和坚硬的牙齿咯吱咯吱地咀嚼着那块小小的肉屑。
叶思杏 意姑 - 副刊 文艺春秋 星洲网 Sin Chew Daily
===================================
# 叶思杏/意姑
文艺春秋
-----
那一夜,满月过后的农历十九,意姑从岛上的医院回来,在抵达家门那刻,所有人都要转身背向,目光回避。
隔天,我去她的房间取照片,照片被放大洗印后将摆放在灵柩前。
在她房里的原木书架第二格,有一本已被世人遗弃的四角号码索引辞典,在辞典左侧,塞着一个红蓝边的航空信封。我打开信封,抖出几张一寸照片。有一张黑白的,短发,一片向右倾斜的厚浏海,使得左侧的头发稀疏些,露出半个兜风耳。她的脸颊两侧丰润,嘴唇轮廓分明,下颏一道浅浅的美人沟,好清秀的一张脸。她身穿中学的校服,可以清楚看到校徽和学号,是亭亭玉立的少女样,望向镜头的眼眸十分敏锐,目光如炬。
匆忙中,我仍禁不住深深地叹了一口气,和她默然对视了一下,仿佛在怪责她遽然离世。在那一刻,想到有些话,说或不说都已枉然。
在她离世后,几次进去她的房间呆着,试图捡拾她遗留的蛛丝马迹。她的房间约莫100平方呎,在方寸之地想像海阔天高,那究竟是怎样的?也许更宽裕,也许更匮乏。
我曾紧闭着双眸,坐在她坐过的高脚凳,模拟她想像的样子,假装搜索她搜索过的版图,感觉犹若深夜的泅泳,阒黑而不着边际,后来已猜不透的她的心思,大概都潜匿在她心底那块不透光的角落,仿佛还没来得及探测海洋的深度,海洋却更深沉了。
早年,曾经有人带意姑去算过命,八字摊开来,批说她的前世是叱咤战场的将军,今世身体的残障是为前世的杀戮赎罪偿还。倘若真的有轮回因果之说,意姑会否相信她的前世是来报应今世的呢?
而事实是,她自幼患上肌肉萎缩症,右脚尤其乏力,行步时一瘸一拐的,全依赖左脚支撑。医生当年断定她活不过25岁,仿佛会推算人的命运似的。
家里有两张她专属的高脚凳,一张是沐浴时专用,要从她的房间移去浴室,沐浴完毕后搬出来晾干,再摆回房里;另一张平时摆放在祖先神台侧边的,用膳时要移过饭桌来,看电视时要移过客厅去,晚间诵经时要移过菩萨神台前。
因意姑无法如常人一般屈膝蹲下,父亲在洗手间安装扶手,还让木匠特制一个残障专用的高脚马桶。她出门需要陪伴,上下轿车需要扶持。依据神明的嘱咐,所有清明和丧礼的祭拜品都严禁食用,似乎怕引来晦气,她倒是吃了不少营养补充剂和中药补品。
兴许是父亲刻意的安排,她那些特殊的日常料理成了我过去生活的另一个重心,那时我还不到10岁。
我自幼便要学会帮她掌控炉火煎药,三碗水慢慢熬成八分碗,像提炼仙丹似的,喝了便可长生不死。煎药的过程中,隔着沾湿的手巾抓药煲的圆柄,把药倒入陶瓷碗来回一两次检查。煎好了药,轻敲她的房门,监督她坐在房里的板床上端着徐徐服下。
我总是目不转睛地盯着,仿若在静待菩萨显灵、奇迹遽现。
我常听她述说在田舍的往事。她说蓝湛的天宇很辽阔,白兔、小羊和大鱼柔软得宛如白絮又似雪。在锌板屋前、池塘边和椰树下,她贪恹地大口呼吸着自由的风,眼眸常常不由自主地觑视不远处的玩伴,羡慕他们赤脚在田里踩泥巴,那是她不被允许的、可望而不可及的领域。
也许她从未想过,这世间还有抵达不到的地方,后来的路途艰难得俨如我未曾抵达她心房一般。
几年前,曾回去田舍巡视老残板屋,昂望同一片蓝天,徘徊在她逗留过的土地上,仿佛瞥见她在田边凝神眺望的孤单身影。霍然想起多年前的那张照片,照片中那看来特别醒目的浏海。想到她那片右倾的浏海和她伫立时一贯左倾的姿势,想到两个反方向相互拉扯之间的错觉,也许让她的背脊看来挺直些。
我想,她若能在过去生命中遭遇的两极找到平衡点,双脚踮在这尖点上,平稳地坚持着,活着的意义也许就不一样了。可那跛立的姿势恍若破解不了的宿命,宛若屋边那棵歪斜摇摇欲坠的椰树,终究是要倾倒的。
直到后来,她的步履愈是蹒跚,终于要使用U字型的扶手架。她步行时夹带“哒哒哒哒”的声响,像似镣铐铁链拖行的声音,又好像谁用力敲打舌尖在申诉。有几次我在睡梦中被吵醒,在清晨万籁寂静的时刻,那缓慢的、走远又走近的声音格外响亮;双眼未曾睁开,隔着门板,便猜到她夜里睡不好又起了个早。可是那行路时有规律的节奏,仿若她的前世在军队操练中的步调,似乎太过用心,听起来总觉得有点诡异。
她的右小腿在年少时动过一次手术,也许是后来致命的痛击。那道瘦长乌黑的伤疤,像一段蜿蜒曲折的幽林小径,仿佛离不开命中注定的崎岖。
几十年旋踵即逝,那旧患伤疤开始溃烂,总是结痂不成而长期需要清洗换药。帮她清洗伤口时,熟练地用钳子夹着沾了消毒药水的纱布,先抹去残留的分泌物,换好药再重新贴上一块手板大的纱布。当纱布染成晚霞的绛红时,黑夜不动声色地靠拢,天空越来越晦暗。
由于行动的不便,意姑几乎不外出,她的生活大致上只能在那局促的房间里进行。从房间的百叶窗望出去,可以看见父亲栽种的番石榴树,番石榴树很争气,常结满果子,宛如她曾经期待收获的人生。她眼底的彷徨透露出挂念的心事,常常使我不忍直视,窗外那遥不可及的蓝天,终究存在于房间之外,那些她用尽心思豢养的宠物溜达到更遥远的云端去了。
曾几何时,白兔和小羊被野狼吞噬,天色转成死灰,沮丧一点一点咀嚼她。有一次和她在房间里对话,她说活着像在虚延岁月,她的心事俨如白昼和黑夜层层叠叠,渐渐堆叠成一座山,我已然无力攀爬。
身体残障的事实几乎把她啃噬消化,她的懦弱换来我无心的藐视,挪步离开她的房间那刻,我装着若无其事,没能把她的心事一并带走,用自以为最聪明的方式轻轻搪塞跳过,到后来目睹她重重地摔下,我惶恐而早已无从懊悔。
她房里的摆设固定,几十年来纹丝不动。出殡那天,几个亲戚在她房里翻箱倒柜地大肆搜索,我忍不住叮嘱两句,似乎试图保留什么案发现场的证据,深怕弄丢了重要的线索,模糊了日后探索的方向。尔后,他们带走几本集邮册,那是她生前最宝贝的珍藏,汇集她的修养、态度和能耐,至于那些他们带不走的,却都是我一生的搜集。
仔细回想她在世的最后几年,觉得她更祈望独处时光,独处没什么不好。那时候我已在异乡工作,逢假期回家三两天,匆忙中和她话也说不多。有一次反手叩她的房门,等了好一会儿,门终于被半拉开,露出半张脸,她不耐烦地回应着,显然心情不好,见她浮躁的空拳使力敲击左边头壳,申诉说近来头痛得厉害;我没来得及反应,门砰然又关上了。
于是在她的房间之外,在距离渐渐地拉开之后,我们都住进各自的洞窟里。
这些年,有些心底的质疑是我一直不愿触碰的。我鲜少再进入她住过的房间,一个人拖曳着记忆中的迷惘踽踽独行,似乎也走远了。她房里的摆设已被更换,记忆已不是原来的样貌;高脚凳被保留下来,摆在父亲的房间里,用来堆放旧剪报,用尘埃来上锁原封不动的记忆。
我想起那本四角号码索引辞典,想留作念想,于是跟父亲讨了回来。翻开辞典内页,页页之间隐约感受到她指缝间的温度,原来关于注音符号和四声、单字和复词的词性,早已正确明晰地编列表明,愕然想起以前,关于四角号码索引辞典的应用,她大略指导过我的,只是那时我尚年幼而未曾认真记住。
直到最近,在整理家里的旧书架时,意外翻阅她少女时的留言,写的是太白〈行路难〉中的名句。而关于破浪启航,她似乎早已准备就绪,“长风破浪会有时,直挂云帆济沧海”……反复读着,酸了鼻子,酸得心里一直颤抖。记得她离世那年,已经有50岁了,医生当年的言之凿凿,终究沦为荒谬的迷信。
原来,她一直是很努力的。
快18年了,仿佛索居幽穴多年后找到出口,我终于决心把多年来愧疚的刺痛逐一调整安顿,把过去积淀并转换成富余为我导航前进。
不久前,梦里迂回,在人潮往来的夜市遇见意姑。她拉着我频频四顾而寻寻觅觅些什么的,绕了好多圈呢。醒来,记得她方才跑得飞快的,脚竟然不瘸了。
作者 : 叶思杏
文章来源 :
星洲日报 2021-01-05
夜巡 - [法] [[帕特里克 · 莫迪亚诺]]
-----
我愿在身后留下一点纪念:至少是给后人留下科科 · 拉库尔和埃斯梅拉达的名字。今夜有我照看着他们。但能持续多久?没有了我,他们将会怎样呢?他们是我唯一的伴侣。像羚羊一样,温柔、沉静而脆弱。我想起来,我曾在一本杂志上剪下了一张照片,那是一只刚刚被人从水中救起的小猫。浑身湿淋淋的,还淌着泥水。一条绳子一头拴住它的脖子,另一头栓着一块石头。我从未见过像它那样善良的目光。科科 · 拉库尔和埃斯梅拉达就和那只猫一模一样。请你们听清楚:我并非动物保护协会的会员,也不是人权组织成员。那么我干什么呢?我走在遭受劫难的城市街道上。夜晚,城市在灯火管制下隐没,而总督、菲利贝尔和其他人将我围在中间。天气异常燥热。我必须找到一块绿洲,就是对科科 · 拉库尔和埃斯梅拉达的爱,否则我会立刻死掉。我猜想希特勒也需要放松一下,抚摩他的狗。我保护着他们。若谁想伤害他们,就是想伤害我。我摸着总督给我的无声手枪。我的口袋里满是钞票。我有法国最美丽的名字(是窃取的,但在目前的境况下,这根本算不上是一回事)。我空腹体重九十八公斤。我有天鹅绒般的眼睛。是 “前途无量” 的小男孩。什么样的前途?所有的仙女都曾飞到我的摇篮前。她们可能喝醉了。你们的对手可不是好惹的。你们可别碰他们俩一根毫毛!头一次碰见他们是在格雷耐尔地铁车站。我立刻明白,只要碰一下,吹一口气,他们就会粉身碎骨。我真奇怪是凭借哪种神奇力量,他们还活在世上。我想起了水中救起的那只猫。高个子棕红头发的盲人叫科科 · 拉库尔,小女孩——或是小老太婆——叫埃斯梅拉达。面对这两个生命,我萌生了恻隐之心。一股苦涩、凶猛的潮水将我淹没。然后是眩晕,像随之而来的拍岸巨浪将我攫获:把他们推到铁轨上去吧。我当时准是把指甲都攥进了手心肉里,浑身僵硬。潮水再次吞噬我,汹涌的浪头竟是那么温柔,我闭上了眼睛,陶醉在其中。
我每晚都极轻地推开他们的房门,看他们安睡。我感受到了第一次见他们时的眩晕:真想在兜里抠响无声手枪,将他们击毙。我要砍断最后一根缆绳,抵达北极;在那里,人已无泪,因为泪水会冻在睫毛上。孤独感也不再能减缓了。一种干枯的悲伤。圆睁的双眼只能面对荒枯的植被。既然我还下不了决心摆脱这个盲人和这个小女孩——或这个小老太婆——,那么至少,我能出卖中尉吗?他的不利之点,是有勇气、自信心,以及一举一动所现出的威严。那直勾勾的蓝色目光使我恼火。他属于令人讨厌的那类英雄人物。但是,我却情不自禁把他看成是一个慈祥的老奶奶。我并不认真看待男子汉。终有一天,我看待所有男子汉,包括我本人,会用现在注视科科 · 拉库尔和埃斯梅拉达的目光,那些最强硬、最自负的人,在我看来都要成为需要保护的残疾人。
我也有自己的抱负,虽然这种抱负并不远大:只是在巴黎近郊一家旅馆当一名酒吧招待。那里应有高大的门庭,鹅卵石甬道,周围到处都是绿草地,还有高大的围墙。天气晴朗时,从四楼顶上,可以望见远方地平线上矗立的埃菲尔铁塔。
酒吧招待。会习惯的,但有时心里也很痛苦,尤其人在二十岁左右,总以为能有些作为。我没那个命了。要干些什么呢?配鸡尾酒。星期六晚上的顾客很多,点菜要酒的速度越来越快。加泡金酒。亚力山德拉巧克力奶酒。玫瑰夫人酒。爱尔兰威士忌冲咖啡。柠檬片。两杯马提尼潘趣酒。越来越多的顾客坐在柜台前。我在柜台里把五颜六色的饮料混合在一起。可别让他们久等。我怕稍有懈怠,他们就会扑向我。我急忙添满他们的酒杯,完全是为了同他们保持距离。我不大喜欢人与人之间的接触。要波尔图——弗利卜酒?要什么就给什么。我给他们灌酒。这不过是防备自己同类,或者说摆脱自己同类的一种办法。来杯玛丽 · 布利扎尔酒?他们的脸已变成猪肝色,步履蹒跚,呆会儿就会烂醉如泥了。我将双肘撑在柜台上看他们沉睡过去。他们伤害不了我了。终于宁静下来了。我的呼吸总是急促。
我们真没有什么好怕的。世上的喧嚣与疯狂斗消失在乙 3 号的台阶前。时间悄悄流逝。科科 · 拉库尔 和埃斯梅拉达上楼就寝。很快就会进入梦乡。埃斯梅拉达吹出的肥皂泡中,还有一只仍漂浮在空中。它浮游不定,飞向天花板。碰。我屏住呼吸。它碰碎在吊灯上。于是,一切都完全结束了。世上从未没有过科科 · 拉库尔和埃斯梅拉达。我独自一人,站在客厅中央,聆听似雨的燃烧弹。最后又动情地想了一下塞纳河岸码头、奥塞车站以及小环城路。继而,我又重新处于衰老的尽头。是在西伯利亚的勘察加地区。那里寸草不生。气候干冷。夜晚那么幽深,几成白色。在这个纬度里人无法生存。生物学家已经观察到,那里的人体将在止不住地狂笑中分化瓦解,笑声尖利得就像玻璃瓶碎片。原因是:在这极低的凄凉之中,你会觉得解脱了尘世的最后一点点联系。惟有一死。要大笑而死。
一个人的村庄-刘亮程
========================
一个人的村庄-[[刘亮程]]
-----
我出去割草,去得太久,我会将钥匙压在门口的土坯下面。我一共放了四块土坯迷惑外人,东一块,西一块,南北各一块。有一年你回来,搬开土坯,发现钥匙锈迹斑斑,一场一场的雨浸透钥匙,使你顿觉离家多年。又一年,土坯下面是空的,你拍打着院门,大声喊我的名字。那时村里已没几户人家,到处是空房子,到处是无人耕种的荒地,你爬在院墙外,像个外人,张望我们生活多年的旧院子,泪眼涔涔。
芥,我说不准离家的日子,活着活着就到了别处。我曾做好一生一世的打算在黄沙梁等你,你知道的,我没这个耐力,随便一件小事都可能把我引向无法回来的远处。在过去的几十年里,村里人就是为一些小事情一个一个地走得不见了。以致多少年后有人问起走失的这些人,得到的回答仍旧是:
他割草去了。
她浇地去了。
人们总是把割草浇地这样的事看得太随便平常。出门时不做任何准备,不像出远门那样安顿好家里的一切。往往是凭一个念头,也不跟家里人打声招呼,提一把镰刀或扛一把锨就出去了,一天到晚也不见回来,一两年过去了还没有消息。许多人就是这样被留在了远处。他们太小看这些活计了,总认为三下五下就能应付掉,事实上随便一件小事都能消磨掉人的一辈子,随便一片树叶落下来都能盖掉人的一辈子。在我们看不见的角角落落里,我们找不到的那些人,正面对着这样那样的一两件小事,不知不觉地过去了一辈子。连抬头看一眼天的时间都没有,更别说地久天长地想念一个人。
我最终也一样,只能剩一院破旧的空房子和一把锈迹斑斑的钥匙——我让你熟悉的不知年月的这些东西在黄沙梁,等待遥无归期的你。我出去割草。我有一把好镰刀,你知道的。
多少年前的一个下午,村子里刮着大风,我爬到房顶,看一天没回家的父亲,我个子太矮,站在房顶那截黑糊糊的烟囱上,抬高脚尖朝远处望。当时我只看见村庄四周浩浩荡荡的一片草莽。风把村里没关好的门窗甩得啪啪直响,连一个人影都看不见,满天满地都是风声,我害怕得不敢下来。
我母亲说,父亲是天刚亮时扛一把锨出去的。父亲每天都是这个时候出去。我们从来不知道他在伺弄哪块地。只记得过不了多长时间,父亲的那把锨就磨得不能使了。他在换另一把锨时,总是坐在墙根那块石板上,一遍又一遍地刮磨那根粗糙的新锨把,干得认真而仔细。有时他抬头看看玩耍的我们,也偶尔使唤我给他端碗水拿样工具。我们还小,不知道堆在父亲一生里的那些活,他啥时候才能干完,更不知道有一件活会把父亲永远留在一块地里。
多少年来我总觉得父亲并没有走远,他就在村庄附近的某一块地里,某一片密不透风的草莽中,无声地挥动着铁锨。他干得忘记了时间,忘记了家和儿女,也忘记了累。多少年后我在这片荒野上游荡,有一天,在草莽深处我看见翻得整整齐齐的一大片耕地,我一下认出这是父亲干的活。我跑过去,扑在地上大喊父亲、父亲……我听见我的声音被另一个我接过去,向荒野尽头传递。我站起来,看见父亲的那把铁锨插在地头上,木把已朽。我知道父亲已经把活干完了,他正在回家的路上。我也该回家看看了。我记不清自己游荡了多少年,只觉得我的身体在荒野上没日没夜地飘游,没有方向,没有目的,也不知道累,若不是父亲翻虚的这片地挡住我,若不是父亲插在地头的铁锨提醒我,我就无边无际地游荡下去了。
芥,那时候家里只剩了你。我的兄弟们都不知到哪里去了,他们也和父亲一样,某个早晨扛一把锨出去,就再不回来了。我怎么也找不到他们。黄沙梁附近新出现了好多村子,我的兄弟们或许隐姓埋名生活在另一个村庄了。有些人就是喜欢把自己的一生像件宝贝似的藏起来不让人看,藏得深而僻远。
我记得三弟曾对我说过,一个人就这么可怜巴巴的一辈子,为啥活给别人看呢?三弟是在父亲走失后不久说这句话的,那时我就料到,三弟迟早会把自己的一生藏起来。没想到我的兄弟们都这样小气地把自己的一辈子藏在荒野中了。
我把钥匙压在门口的土坯下面,我作了这个记号给你,走出很远了又觉得不踏实。你想想,一头爱管闲事的猪可能会将钥匙拱到一边,甚至吞进嘴中嚼几下,咬得又弯又扁。一头闲溜达的牛也会一蹄子下去,把钥匙踩进土中。最可怕是被一个玩耍的孩子捡走,走得很远,连同他的童年岁月被扔到一边。多少年后,这把钥匙被一个有贼心的人捡到,定会拿着它挨家挨户地试探,在人们都不在的一天,从村子一头开始,一把锁一把锁地乱捅。尤其没开过的锁,往里捅时带着点阻力,涩涩地,能勾起人的兴致。即使根本捅不进去,他也要硬塞几下。一把好钥匙就这样被无端磨损,变细、变短,成为废物。遭它乱捅的锁孔,却变得深大而松弛,这种反向的磨损使本来亲密无间的东西日渐疏离。爱情也是这样。这么多年我循序渐进地深入你,是我把你造就得深远又宽柔。我创造了一个我到达不了的远方,挖了一口自己探不到底的深洞。在这个漫长过程中我自己被消损得短而细小,爱情的距离就这样产生了。
早晨微明的天色透进窗户,你坐起身,轻轻移开我压在你腹部的一条腿。
你说:那块地都荒掉了。
哪块地。我似醒非醒地问你。
接着我听见锄头和铁锨轻碰的声音、开门的声音。
我醒来时不知是哪一个早晨,院子扫得干干净净,柴垛得整整齐齐,细绳上晾晒着洗干净的哪个冬天的厚重棉衣。你不在了。
村子里依旧刮着大风,我高晃晃地站在房顶朝四处望。风穿过空洞的门窗发出呜呜的鬼叫声。已经多少年了,每次爬上房顶我都在想,有一天我一定提一把镰刀出去,把村庄周围的草全都割倒。至少,割出一个豁口,割开一条道。我父亲走失的第五年,有一天,我在房顶上看见村西边的沙沟里有一片草在摇动。我猛然想到是不是父亲,我记得母亲说过,你父亲就喜欢扛一把锨在乱草中捣腾,他时不时地在一片草莽中翻出块地来,胡乱地撒些种子,就再不管了。吃午饭时,母亲又说:爬到房顶看看,哪片草动弹肯定是你父亲。
我翻过沙梁,一头钻进密密麻麻的深草。草高过了头顶,我感到每一株草都能把我挡到一边,我只有一株草一株草地拨开它们。结果我找到了一头驴。我认出是几年前王五家丢掉的那头,当时王五家为了这头驴惊动了方圆几百里,几乎远远近近每一条路上都把守着王五家的亲戚,村里每一户人家都被怀疑。没想到驴就藏在离王五家不远的一滩草中,几年间它没移动几步,嘴边就是青草,它卧在地上左一口右一口地就能吃饱肚子,对驴来说这是多好的日子。它当然不愿再回到村里去受苦。可王五家却惨了,本该驴做的事情都由王五家的人分担去做了。才几年工夫王五的腰就躬成驴背了。我出于好心把驴拉了回去送给王五家。王五的婆姨抱着驴脖子哭了好一阵,驴被感动了似的也吭吭地叫起来。王五的婆姨哭够了转过身来,用一双泥糊糊的眼睛瞪着我说:
你爹出去几年了。
五年了。我说。
那就对了。王五的婆姨一拍巴掌,说。
我家的驴也丢掉整整五年了,肯定是你爹把我家的驴拉出去使唤了五年,使唤成老驴了,才让你给送过来。你说,是不是。
芥,我记得我们种过一块地,离村庄很远。一个春天的早晨我们赶车出去,绕过沙梁后走进一片白雾蒙蒙的草地,马打着响鼻,偶尔也放两个屁。在装满麦种的麻袋上我解开你的上衣,我清楚地记得有一股大风刮过你双乳间那道白晰的沟槽,朝我脸上吹拂,我闻到一股熟悉的来自遥远山谷的芬芳气息,手不由自主往下滑去。马车猛然间颠簸起来,一上一下,一高一低,一起一伏,我忘掉了时间,忘掉了路。不知道车又拐了多少个弯,爬了几道梁,过了几条沟。后来车停了下来,我抬起头,看见一望无际的一片野地。
芥,我一直把那一天当成一场梦,再想不起那片野地的方向和位置。我们做着身边手边的事,种着房前屋后的几小块地,多少个季节过去了,我似乎已经忘记我们曾无边无际地播种过一片麦子。我只依稀记得我们卸下农具和种子时,有一麻袋种子漏光在路上了。
后来我们往回走时,路上密密麻麻长满了麦子。我们漏在路上的麦种在一场雨后全都长了出来,沿路弯弯曲曲一直生长到家门口,我们一路收割着回去。芥,我一直不敢相信的一段经历你却把它当真了。你背着我暗暗记住了路。那个早晨,我在睡眠朦胧中听见你说:那块地长荒了。我竟没想到你在说那一片麦地。现在,你肯定走进那片无边无际的麦地中了。
我带走了狗,我不知道你回来的日子,狗留在家里,狗会因怀念而陷入无休止的回忆。跟了我二十年的一条狗,目睹一个人的变化,面目全非。二十年岁月把一个青年变成壮年,继而老态龙钟。狗对自己忠诚的怀疑将与年俱增。在狗眼里,人一生中的不同时期是不同面孔的好几个人。它忠心尾随的那个面孔的人,随着年月渐渐就不见了。取而代之的是另一副面孔另一番心境的一个人,还住在这个院子,还种着这块地。狗永远不能理解沧桑这回事。一个跟随人一辈子的忠犬,在它的自我感觉中已几易其主,它弄不清人一生中哪个时期的哪副面孔是它真正的主人。
狗留在家里,就像你漂泊在外,是我最放心不下的心事。
一条没有主人的狗,一条穷狗,会为一根干骨头走村串巷,挨家乞讨,备受人世冷暖,最后变得世故,低声下气,内心充满怨恨与感激。感激给过它半嘴馊馍的人,感激没用土块追打过它的人,感激垃圾堆中有一点饭渣的那户人。感激到最后就没有了狗性,没有一丁点怨恨,有怨也再不吭声,不汪不吠。游荡一圈回到空荡荡的窝中,见物思人,主人的身影在狗脑子里渐渐怀念成一个幻影,一个不真实的梦。
这还不是最重要的。你回来晚了,狗老死在窝里,它没见过你的狗子狗孙们把守着院子。它们没有主人,纯粹是一群野狗,把你的家当狗窝,不让你进去。
家是很容易丢掉的,人一走,家便成了一幢空房子。锁住的仅仅是一房子空气,有腿的家具不会等你,有轱辘的木车不会等你,你锁住一扇门,到处都是路,一切都会走掉。门上的红油漆沿斑驳的褪色之路,木梁沿坑坑凹凹的腐朽之路,泥墙沿深深浅浅的风化之路,箱子里的钱和票据沿发黄的作废之路……无穷无尽的走啊。
我在荒草没腰的野地偶一抬头,看见我们家的烟囱青烟直冒,我马上想到是你回来了,怎么可能呢,都这么多年了,都这么多年了,我快过惯没有你的日子。
我扔下镰刀往回跑。
一个在野外劳动的人,看见自己家的炊烟连天接地的袅袅上升,那种子孙连绵的感觉会油然而生。炊烟是家的根。生存在大地深处的人们,就是靠扎向天空的缕缕炊烟与高远陌生的外界保持着某种神秘的联系。
炊烟一袅袅,一个家便活了。一个村庄顿时有了生机。
没有一朵云,空荡荡的天空中只有我们家那股炊烟高高大大地挡住太阳,我在它的阴影中奔跑,家越来越近。
我推开院门,一个陌生男人正往锅头里塞柴火,我一下愣住了,才一会工夫,家就被别人占了。我操了根木棍,朝那个男人蹲着的背影走去。
听到脚步声他慢腾腾地转过身。
你找谁?他问。
你找谁?我问。
我不找谁。他说着又往锅头里塞了根柴火,我看见半锅水已经开了,噗噗地冒着热气。
这个男人去另一个村庄,路过院门口时,一脚踩翻土坯,看见我留给你的钥匙。他小心翼翼捡起来,擦净上面的锈和尘土,顺手装进口袋。走了几步他又返回来。我一共留给你五把钥匙,能打开五扇门。我们家能锁住的地方我都上了锁。
他捡出一把粗短的黄铜钥匙,对准锁孔塞了几下,没塞进去。又捡出另一把细长的,没费劲就塞了进去,捅到底了,还露半截在外面,他故意扭了几下又拔出来。捅进第三把钥匙时,锁打开了。他在院子里转了一圈,然后又挨个地打开每一间房子。
他先走进一间宽大低矮的卧房,看见占据了大半个房间的几十米长的一张大土炕,他有点吃惊,从没见过这么大的土炕。他想,这家男人肯定雄壮无比呢,他修了如此阔大的一个炕,一定想生养几十个儿女。有这种雄心的男人一般都有一根了不起的粗壮阳物,又娶到一房样样能行的好媳妇,有了这些天赐的好条件,他就会像种瓜点豆一般,从大土炕的那头开始,隔一尺种一个儿子,再隔一尺插花地播一个女儿。这是长达几十年的辛勤劳作,要保质保量地种下去又不种出歪瓜裂枣也不容易。再能行的男人赶种到大土炕的另一头也会老得啥也干不动,腰也弯了,腿也瘸了,甚至再没力气下炕。而从这个大土炕上齐唰唰站起来的一群儿女,在一个早晨像庄稼一样密密麻麻立在地上,挡住从窗外照进来的那束阳光。
他想,这家男人在年轻力盛时一定很自负地算好了一生的精力和时间,才修了这样巨大的一个土炕,他对自己太有信心了。多少年后的今天,显然,他连半个儿子也没种出来,大土炕上一片荒芜,长着些弱小的没咋见阳光的杂草。只有靠东头的炕角上,铺着张发黄的苇席和半条烂毡,一床陈旧的大花棉被胡乱地堆在上面。
是什么东西阻止或破灭了这家男人的雄伟梦想呢?他不知道。
他用一根指头在布满裂缝的桌面上抹了一下,划出道清晰的印子,尘土足有铜钱厚。他是个流浪人,可能从没安心在一个地方长年累月地体验过一件事情。不像我,多少年来看着一棵树从小往大地长。守着一个院子,从新住到旧。思念着一个人,从年轻到年老昏沉。他没这种经历,因而弄不清多少年的落尘才能在桌面上积到铜钱这么厚。
他转过身,穿过满是杂乱农具的库房,墙上挂的,梁上吊的,地上堆的,各式各样的农具。有些他从没有见过,造型古古怪怪,不知是干什么活用的。
芥,有些活是只有我能看见的,它们细小或宏大地摆在我的一生里,我为这些不同种类的活制造了不同式样的专用农具,我不像父亲,靠一把简单的铁锨就能对付一辈子。有些活通过我的劳动永远不见了,或者变成另一种活等候在岁月中了。我埋掉的一些东西成为后人的挖掘物时,那种劳动又回来或重新开始了。我割倒垛在荒野中的干草,多少年后肯定有人赶一辆车拉回村里。这些深远的东西一个过路人怎能看清看透呢?他只会惊叹:这家男人长着怎样有力的一双手啊。他为自己准备了如此多而复杂的一库房农具,他到底想干掉多少活干出多大的事业,这些农具中的哪一件真正被用过?
他打开另一扇门,一股谷物腐烂的霉味扑鼻而来。这间房子没有窗户,光线很暗,只有接近房顶的墙上有两个很小的通风洞,房子中间突兀地立着一堵墙,墙的半腰处有个黑洞洞的豁口,他把头探进豁口,看了半天,才看清里面是黑糊糊的半仓粮食。他把手伸进去,抓了一把谷物走到院子里,在阳光下观察了一阵,又用鼻子闻了闻。
没准还能吃呢。他想。
要能吃的话,这半仓粮食够一个人吃一年了。
他在院子里转了一圈,捡了些柴火放到锅头旁。他决定住下不走了。他想,这么大一院房子,白白空着太可惜了。他本来去另一个村庄,另一个村庄在哪他自己也说不清,每到一个村庄,另一个村庄便隐约出现在前方,他只好没完没了地往前走。不知走了多少年,他忘记了家,忘记回去的路,也忘记了疲惫。
正是中午,阳光暖暖地照着村子,有两三个人影,说着话,走过村中间那条空寂的马路。
他想,先做顿饭吧,多少年来他第一次感到了饥饿。
我在这时候跑回家里。
我犯了一个天大的错误。芥,我扔下镰刀往回跑,快下午的时候,一个过路人捡走我的镰刀和一捆青草,往后很多年,我追赶这个人。我走过一个又一个喧哗或寂静的村庄,穿过一片又一片葱郁或荒芜的土地,沿途察看每一个劳动者手中的农具,我放下许多事,甚至忘记了家,忘记了等你……
芥,你不认识老四,你到我们家的时候,老四已走失多年。家里只剩下母亲,和两个我至今不知道名字的小兄弟。他们小我很多岁,总是离我远远的——像在离我很多年那么远的地方各自地玩着游戏。也不叫我二哥,也许叫过,只是太远了我没听清楚。他们总喜欢在某个墙根玩耍,望过去像两个投在墙上的影子。其实他们就是影子,只活在母亲的世界里,父亲离开后再没人带他们来到世上。我一直不知道我有多少个姐妹兄弟。但一定很多,来世的,未来世的,不计其数。我父亲的每一颗成熟的精子,我母亲的每一粒饱满的卵子,都是我的姐妹兄弟。他们流失在别处,就像我漂泊在黄沙梁。
多少年后我在这片荒野上游荡时,我又变成了一颗精子或一粒卵子。盲目,无知。没有明确的去处。我找到了你,在很多年间我有了一个安静温暖的归宿。我日日夜夜地爱你,我渴望通过你回到我母亲那里去。父亲走失后我目睹了母亲长达半世的寂寞和孤独。
芥,你每次满足我一点点,不让我全部进去。我一急切你便声声地叫着疼。我是从这里出来的。母亲,我记住了这条路,迟早我会回到你那里。我是不是进错了门呢,芥,我是不是走在一条永远的死胡同里,进来出去又进来,你让我迷路,很多年走不出这个叫黄沙梁的村子。
芥,你没看好我的母亲,你让她走了,带着我的两个不知名字的兄弟远远地走了。你指给我路,让我去追。
正是下午的时候,我扛着铁锨回来,院门敞开着,我喊你的名字,又喊母亲,院子里静静的没有回应,对面墙上也看不见我那两个兄弟的身影,往日这个时候他们玩得正欢,墙上的影子也就最清晰真实。
我推开一扇门,又推开一扇门,家里像是多少年没有人住。我记得我才出去了一天,早晨我出门时,你正在锅头上收拾碗筷,母亲拿一只小小的条把在扫院子,我还想,这么大的院子母亲用一只小条把啥时才扫完呢?我吩咐你帮帮母亲,你答应着。树在落叶子,我出门时,一些树叶又落在母亲扫过的地方。
我在地里干着活还不时朝村里望,快中午的时候,我还看见我们家的烟囱冒了一股烟,又不见了。我头枕在埂子上睡了一觉,是不是这一觉把几十年睡过去了?
我走出院子找你和母亲,村子里空空的一个人也看不见。我一家一家地敲门,几乎每户人家的院门都虚掩或半开着,像是人刚出去没走远,就在邻居家借个东西、去房后撒泡尿马上就回来,所以门没锁,窗户没关。但院子里的破败景象告诉我,这里已很久没人居住。我喊了几个熟悉的人的名字。喊第三声的时候,一堵土院墙轰然而倒。我返回到家里,看见你正围着锅头做饭,两盘炒好的蔬菜摆在木桌上。
活干完了?我听见你问我。
什么活?我在心里想着这句话,说出口的却是另一句:刚才你到哪去了?
我给你做饭哩。
那我回来昨没看见你。
你回来了?啥时?
刚才?
刚才?你说着又把炒好的一盘菜放在木桌上。
那我母亲呢?
刚走,她说不回来吃饭了,我才炒这么多好菜。你母亲太能吃饭了,一顿吃好几个人的饭还不停地叫饿。她说她是给你的几个兄弟吃饭的,她自己好多年前就不需要吃饭了,只喝点西北风就饱了。
我朝你指的路上追去,没跑几步又折回来。
那么,村里人都到哪去了?
都在哩。
在哪里?
还不是都在干自己的活哩,你想想你到哪去了就该知道其他人的去处。
你说着把一碗烧好的汤放在桌上。我看见发绿的汤里扔着几根白骨。另几盘也是些腐肉和陈菜,那些菜像是多少个季节以前摘的,发着陈旧的灰黑色。虽是刚炒出来,却一点热气都没有。倒像一桌供放多年的丧食。再看你,也像衰老了许多,衣袖有几处已朽烂,铜手镯绿锈斑斑,似乎这顿饭你做了很多年才做熟。炉膛里还是多年前的那灶火,盘子里是多年前的肉和蔬菜,我的胃里蠕动着的也是多年前的一次饥饿。
芥,我记得我才出去一天。
我三十岁那年秋天,我想,我再不能这样懵懵懂懂地往前活了。我要停下来,回过头把这半辈子认认真真回味一遍。如果我能活六十岁的话,我用三十年时间往前走,再用剩下的三十年往回走,这样一辈子刚好够用。
从那时起,我停住手中的一切活计,吃着仓里的陈旧谷子,喝着井里的隔年老水,拒绝和任何一个陌生人认识,也不参与村里家里的一切事务。唯一的外界活动是:当我回想不起来的时候,找几个熟悉我的人聊聊往事。
那年秋天家家户户大丰收,人人忙忙碌碌。仓满了,麻袋也用完了,院子里、房顶、马路上,到处堆放着粮食。人们被多年不遇的丰收喜昏了头,没谁愿意跟我闲扯陈年旧事。他们干着今年的活,手握着今年的玉米棒子,眼睛却满含喜庆地望着来年。他们说,啊,要是再有几个这样的好年成,我们就能把一辈子的粮食全打够,剩下的年月,就可以啥也不干在家里享福了。他们一年接一年地憧憬下去,好年成一个挨一个一直延伸到每个人的生命尽头。照这样的向往,我发现他们根本没有剩下的年月,可以啥也不干待在家里享福。往往是今年的收成还顾不上吃几口,另一年的更大丰收又接踵而来,大丰收排着大队往家里涌,人们忙于收获,忙于喜庆,忙得连顿好饭都顾不上吃,一村人的一辈子就这样毫无余地地完蛋了。
我庆幸自己早早刹住了车。芥,只有你理解我。在我满屋满院子翻找那些能够证明我过去生活的旧农具、旧家什以及老账单、破鞋帽时,你不动声色地配合我,一边收拾着满院子的粮食,一边找出你早年的衣饰,穿戴在身上,用你以往的眼神和微笑对着我,说着你对我说过的话,晚上重复着你对我做过的那些动作。芥,我就从前一天的晚上开始回想。我顶好院门,用一捆树枝把院墙上的豁口堵住。天还没有黑透,还不到睡觉的时候,你早早就喊我上炕,不教我出去转,和屋后的韩三吹吹牛、聊聊天,乘机抽他的一根烟。韩三叫我谝高兴时,就会递过一大张烟纸,抓一大撮烟颗,让我又粗又长地卷一根烟。这件便宜事我从没告诉过你,即使告诉了,你也不会放我出去一个人过瘾。我看得出,你从天一亮就开始盼着天早早黑,好早早上炕。那时你是多么狂热地依恋着我呵。多少年后的那些个晚上,当我闲着没事想出去混根烟抽时,韩三早已不在村里,他家装修考究的窗户门变成几个怪模怪样的黑洞,遇到风天便发出呜呜的怪叫。
我坐在炕沿脱衣服时,还听到村里忙忙碌碌的人声、狗和牲畜的叫声。我忙碌的时候,不会清晰地听到其他人忙碌的声音,现在我不忙了,要忙另一件事了。你让我早早闲下来,怕我累坏了身体干不成正事。
我就从这一夜开始回忆,从三十岁的这一夜起,我就往回走了,背对着你们——一村庄人,面朝曾经发生过的事情。熄灭的油灯又亮起来,桔黄的亮光重新温馨地照着这间房子,这面几十米长的大土炕。我们睡在土炕的一头,另一头堆满了玉米棒子,都是新鲜的刚收获不久的棒子,夜里我困顿时你顺手拿过又粗又长的一个,摇醒我:猜猜它像什么。你把玉米棒的小头抓在手里,大头对着我的嘴唇撩来弄去。你知道怎样弄醒我。一看到又粗又硬的东西我就会立马粗硬起来。外面这时刮起了风。我听见风把院子里的干树叶刮起来,带到很远很远的地方,紧接着一些很远处的树叶又被风刮到我们的房上和院子里。你不让我吹灯,你不知道灯亮着我多心疼,家里只有一小瓶灯油,我准备了好几个大桶,并排放在库房的墙根。我想年轻时多摸摸黑,节省点灯油,到我上了年纪,老眼昏花时就会有足够的灯油,在我四围点好多盏灯。当一个人视力渐衰时他拥有了好多盏灯,一盏一盏地,把他看不清的那些地方一一点亮,这是多么巨大的补偿啊。这种补偿不会凭空而降,要靠自己在漫长一生中一点点地去积攒。你怨我性急,总是三下五除二了事,我咋能不急呢,灯亮着,灯油一丝丝耗尽时,我就觉得自己没有了力气,只想早早和你干完事,熄灯休息。油灯平放在炕上,灯光朝上直照在我的胸脯和脸上,你催我快点,再猛点,你充满欲火的双眼仰望着我,又像在望着我身后的房顶和墙。许久以后的一个晚上,我躺在你身下,仰望你累累垂吊的双乳,体味做女人的幸福感觉时,才恍然明白你为什么要把灯放在炕上。那一刻,在摇曳的灯光中我看见你投在房顶和后墙上的巨大背影一下一下向我俯冲。我一把打翻了油灯。芥,多少个夜晚,你就是仰望着我黑熊一般巨大的影子和我做爱。
我站在村头观察了好一阵。月光下的黄沙梁,就像梦中的白天一样。一切都在银灰色的透明空气中呈现出原来的样子——树还是那样高,似乎我离开后树再没有生长过。房子还那样低矮,只是不知住在里面的,是不是我认识的那一村庄人。我走了半夜的黑路,神情有些恍惚,记不清自己离开黄沙梁已有多久。我好像做了一场梦,恍恍惚惚醒来,看见自己生活多年的一个村庄,泊在月色里。
就在前半夜,我还一直担心自己走错了路。我记得以前的路是在沙梁顶上蜿蜒向西,绕过一道沟后直端端戳向村子。
谁把路朝北挪动了半里。我自言道。
有人为了种地往往会把道路挤到一边,让过往的人围着他的地转。有一年我穿过一片戈壁去胡家海子,去时路还好好的,路旁长满了野草和灌木。几天后当我回返时,这片戈壁已被人耕翻了,并浇了水,种上粮食。我费了大半天时间才绕过去。我想,倘若这个种地人心贪,把地耕种到天边,那我就永远被隔在地这边的他乡了。
而这片荒野并没有人耕种,好像路不小心从沙梁上滑了下来,要么是向北的风一年一年地把路吹到这边了,像吹一根绳子一样。
不过,我想是另一种情景:一场大雪后,荒野白茫茫一片,雪把所有界线和标识覆盖得一片模糊。最先出门的人,搞不清道路的确切位置,但又不能不走,只好大概地瞄一个方向踏雪而去。晚出门的人、车马也都不加考虑地循着这行脚印走去。这样每一场雪后,道路总会偏离原来的轨迹,有时是偏左,有时偏右。整个冬天没有几只脚真正地踩在路上。只有到了春天——融雪之后,人们才惊讶地发现:把路走偏了。但又没有谁会纠正这个错误,回到老路上去。反正,咋走还是走到该去的地方,目的地不会错的。
那时候我们刚刚结婚,我整夜守着你,不知道村里发生了啥事。几个兄弟都离我远远的,夜里他们睡在房顶和院子里。母亲啥都不让我干,顿顿给我吃鸡蛋。
你最要紧的活,是让你媳妇赶快把娃娃怀上。
我最听母亲的话,父亲离开后,母亲的话语成了我们家里唯一的长辈的声音。她温和舒缓地覆盖着这个家庭,我们按她说的去做,或者当面答应,背后照自己的想法去干活。无论听从与否,我们都不能没有这种声音——从祖辈的高处贯穿下来的骨肉之音。父亲母亲,你们的声音将最终成为儿女们的声音在代与代的山谷间经久回应。不管我们年轻时怎样不听话,违背母语父令,最终还是回到父亲母亲的声音中,用你们的话语表达我们自以为全新的人生,做着父母语言中的所有事情。
芥,你也是听了你母亲的话温温顺顺做了我的妻子。你老早就喜欢我,想嫁给我,你母亲同意后这个意愿便成了你母亲的,你是个听话的好女儿,照母亲的意愿做了你愿意做的。我也一样,从第一夜开始,我整夜整夜地折腾你,我蓄了二十多年的劲,磨了二十多年的刀,练了二十多年的功,我每个夜晚都渴望着和你做这件事,现在终于和你睡在一个炕上,钻进一个被窝了,我却突然意识到这是母亲安排我做的一件事。母亲没说出之前我只是在夜里偷偷地想你,母亲说了,我就照她的意愿去干。我没干过这活,笨手笨脚的,惹得你咯咯直笑。我不知道先从哪下手,父亲没教过我这活,又好像教过。我记得八岁那年,有一天,父亲把我带到地边,让我看着他种地。
记住,种地要先从地头开始,一锨一锨往中间翻,不能图省事。
芥,我知道要去的地方,我不能走捷路,我等了二十年,这会儿就等不急了。你一直咯咯地笑。我是不是错了,你教教我。我是个老实人,不会图省事,直接在地中间挖一锨、洒一把种了事。我要翻过该翻的山,走过该走的平地,把边边角角沟沟凹凹都照管好,侍弄好。你夸我活干得很细呢。我说来粗的了。你大叫一声。院子里狗狂吠起来,它多少年没听到这种叫声,有些陌生了。房顶上一根檩子也同时嘎巴一声,像压断了似的。我不知道睡在房顶的是老几,他一定在为我干着急呢。芥,我得再用点力气,你让我再试试。
我十六岁那年,母亲让我去开一片荒地。放下这么多熟地不种,开什么荒呀。我心里捣咕着,还是去了。那是片稀稀拉拉长着些蒿草的白皮地,看样子没人动过一锨一锄。这叫处女地,开起来费些劲,但你不能老在别人开过的地里捣腾。男人嘛,总要整几块处女地。我在地上挖了几锨,地太硬,锨怎么也插不进去。母亲我是不是劲太小了,没到开荒的年龄。你父亲十三岁就开始在荒地里舞锨弄锄了。我懊丧地坐在地上,看着硬梆梆的生地愣了半天,快中午时,扛着锨回到家里。
你叫我做的每一件事我都躲不过去,现在不做,将来还会去做。
母亲我面对的依旧是你几年前让我去开的那块荒。我依旧像几年前那样慌乱无措。不是锨不行,你配给我的家什样样管用。可我好坏插不进第一锨,地太生,我一使劲芥便大声地喊疼,母亲你在隔壁的黑暗中一定听到了。
吃早饭时,我一直低着头不敢看你,也不敢看我的几个兄弟,他们眼巴巴望着我,想让我回答什么。母亲只有你看出来了:事没干成。我的脸上依旧是几年前从荒地回来时的那副表情。我想,我要开出那块地,就不会有今天这个结局。
芥,我看见母亲叫过你,低声地问着什么。你一脸羞红,不时摇头或点头。早晨的阳光温和地照着院子,我浑身躁热,坐立不安,几个兄弟放下碗筷,正收拾农具下地。其中一个有意碰了一下我立在墙根的铁锨,锨倒了,我起身去扶。我是善用镰刀的人,你们却让我使锨。
我要在地上挖个洞。
挖个坑。 挖口深井。
我想着有个东西就像锨把一样粗硬起来。我回过头,看见母亲把嘴贴在你耳朵上很神秘地说了句什么。
你一直没告诉我母亲对你说的那句话。母亲从没有那样神秘地对我说过什么,她有很多儿女,不能单独把某些话语告诉其中一个,她的每句话都是说给每个儿女听的。她一定想通过你把一句隐秘的话悄悄传给我,你却把它隐藏了,不向我透露一个字。芥你知不知道,有很多年,我每夜每夜在你身上翻找,一遍又一遍,不放过一个隐秘处,每个地方我都想进去。我想象母亲的那句话已作为秘典藏在你身体的某处,我要找到它。从那时起我就不再吻你的嘴唇,我把所有的热情用在你的其他器官上,我想感动它们——我能感动它们。你的嘴不告诉我,我就问其他的器官,它们会说话,你的嘴说不出来的,无法表述的,它们会表达得生动而美丽。
村子里忽然响起哼哼叽叽的声音。我听出是男人和女人在一起时发出的那种呻吟。从路旁那些黑洞洞的窗口飘出来,空气被这种声音搞得湿乎乎的。
都几更了,还有这么多男女在调情。
我记得以前村里没这种声音。那时的夜是多么安静,大人们悄无声息地行着房事,孩子们悄无声息地做着梦。
以前只有牲口交配时才发出这种快乐无比的呻吟。牲口所以要呻吟是因为,它们都是公的爬在母的背上行事。各自无法欣赏对方的面部表情,只好靠声音传递信息:母的一哼叽,公的便知道整舒服了。公的一噢噢,母的便领会日高兴了。
村里人啥时也学会这样叫了。是跟牲口学的。
多少年来村里的男人女人虽是面对面、眼对眼、嘴对嘴、心对心地干那事,但都是黑灯瞎火,有天没日地干。有时从窗户门缝透进点星光月光,也是朦朦胧胧,不明不白。只觉得稀里糊涂就有了一炕儿女,金童玉女也好,歪瓜裂枣也罢,都是一种方式整出来的。先是一对男女在黑暗的大土炕上摸到一起,尔后是一尾精子和一尾卵子在更加黑暗的阴道中摸索到一起。一个人从孕育到出生都是这么荒唐和盲目。
全不像种地,先分清种子。种瓜得瓜,种豆得豆。传宗接代的事却由不得你,到了兴头上一股子洒出去,五花八门,谁知是些啥货色。光图了快乐,管它饱子、秕子、病子,千万粒种子最后只发一个芽,结一个果。却不见得是最好的。
芥,我洒给你的都是秕籽吗?都是存放经年的陈腐老籽吗?很多年间我不分季节地播种,我在一小块地上洒了那么多种子,竟没一个发芽的。是饥饿的你把我的所有种子当口粮吞吃了,还是那一小块地只长芳草。芥你记不记得那个夜晚我提一把镰刀上炕,我让你脱衣,你惊讶地望着我,还是脱了。我在昏黄的油灯下一镰一镰,小心翼翼割光那片芳草,还用镰刃刮净毛根。“这下就能种出粮食了。”我说着,一口气吹灭油灯。
一个秋天的下午,我终于在一户人家的窗台上找到了我的镰刀,它被磨得只剩下一弯废铁。
这户人家看样子是喂牲口的,房前屋后垛了从远远近近的野地里割来的荒草,我的那捆草肯定压在这些高高的草垛中间,要是能翻出来,我会一眼认出它的。我捆草的方式跟谁都不一样。每一捆草上我都作了只有我能看出的记号。我暗暗在我经手的每件事情上都留下我的痕迹,甚至在鞋底上刻上代表我名字的一个字,我走到哪,就把这个字印到哪,在某些关键地段,我有意把脚印踩得很深,我这样做只是为了多年后当我重返这片荒野时,能清晰地看到自己生活过的痕迹。很早我就预感到我还会来到这片荒野上,还会住进黄沙梁,不是我一个人,而是一大群,那时的我作为曾经人世的向导,走在浩浩荡荡的人群前面,扛一把铁锨指指点点。我引他们走我走过的长短路途,经历我经历过的所有事物,他们不会比我做得更出色。
我房前屋后转了一圈,没见一头牲口,人也不知干啥去了,门窗敞开着。我想喝口水,可是水缸是干的,院子中间的一棵榆树,也像枯死多年了,树杈上高高地吊着只破马灯,足有两个人那么高。我想是树很小的时候,这家人把马灯挂在树枝上,坐在树下的灯影里一夜一夜地干着一件事。后来树长高了,马灯跟着升到高处,在这个谁也够不着的高度上马灯熬干灯油,自己熄灭了。这家人的活干完了没有呢?
枯树下面是一架只剩一只轱辘的破马车,一匹马的骨架完整地堆在车辕中间。显然,马是套在车上死掉的,一副精致的皮套具还搭在马骨头上。这堆骨架由一根皮缰绳通过歪倒的马头拴在树干上,缰绳勒进树身好几寸,看来赶车人把车马拴在树上去干另一件事,结果再没回来——或者来得像我一样晚。这期间榆树长了一圈又一圈……
我坐在一架吱吱乱响的木椅上,爱怜地抚摸着我的镰刀,我真心疼啊。是怎样的一个人把我的镰刀使唤成这样了。他用我的镰刀干完了本该由我去干的这些活,要不是找这把镰刀,我的草也会垛得跟这户人家的一样高。一把好镰刀,在别人手中经历了一切,变成一弯废铁,它干出的活成了别人的。我想了想,要干掉多少活才能磨废一把镰刀呢?干完这些活要花多少个年月?想着想着我惊愕了:这户人早已不在人世。
我不知道时间过去了多少年,也许我的一辈子早就完了,而我还浑然不觉地在世间游荡,没完没了。做着早不该我做的事情,走着早就不属于我的路。
亲人们一个个走掉了,村里人也都搬到别处,我的四周寂静下来,远远近近,没有人说话的声音,也听不到走路声。我在一个人的村庄进进出出,没有谁为我敲响收工的晚钟,告诉我:天黑了,你该歇息了。没有谁通知我:那些地再不用种,播种和收获都已结束。那个院子再不用去扫,尘土不会再飘起,树叶不会再落下。更没有谁暗示我:那个叫芥的女人,你不必去想念了。她的音容笑貌,她的青春,一切的一切,都在一场风中飘散。结束吧,世间还有另一些事情,等着发生呢。
一颗像里茨饭店那么大的钻石-[[菲茨杰拉德]]
-----
```
约翰 ·T· 昂格尔来自海德斯,在密西西比河畔的这个小镇上,昂格尔家族遐尔闻名已经有好几代人。约翰的父亲历经多次激烈比赛,一直保持业余高尔夫球赛冠军;昂格尔太太擅长政治演说,用当地一句话来说,“从热轴到热铺”1 名闻遐尔;而年轻的约翰 ·T· 昂格尔虽然刚过十六岁,却在换上长裤之前 2 便已经把纽约传过来的新式舞跳了个遍。现在,他要离家一段时间了。推崇新英格兰的教育是外地州县的通病,使它们年年流失许多最有前途的年轻人,这个病他的父母也染上了。什么都不合他们的意,非得送他去波士顿附近的圣米达斯学校不可:海德斯太小了,容不下他们的宝贝天才儿子。
你要是去过便知道,在如今的海德斯,那些比较时髦的预备学校和大学的名字已经没有什么意义。但居民们与世隔绝太久了,尽管在穿着打扮、生活方式和文学修养方面,他们的表现与时代保持亦步亦趋,但在很大程度上却是依靠道听途说;一个在海德斯看来是精心筹备的大场面,如果让一位芝加哥牛肉公主 3 来说上几句,她无疑会觉得 “恐怕有点儿俗”。
到了约翰 ·T· 昂格尔离家前夕。昂格尔太太以母性的愚顽昏庸,给他的大旅行箱里装满了亚麻布套装和电扇,昂格尔先生则送给儿子一只塞满钱的石棉钱包。
“记住,这儿永远欢迎你,” 他说:“你大可放心,小子,我们会让家里的炉火一直烧得旺旺的。”
“我知道,” 约翰说,喉头发干。
“别忘了自己是谁,来自什么地方,” 他父亲自豪地接下去说道:“你不能做有损于自己的事。你姓昂格尔──来自海德斯。”
就这样老的和少的拉拉手,约翰掉头而去,眼睛里泪水直往外涌。十分钟后,他走出了镇子的范围,停下脚步,最后一次回头看一眼。此时,大门上方那一条维多利亚时代的旧派箴言对于他似乎很有吸引力,真是奇怪。他父亲曾一次又一次想把它换成稍微带点儿鼓劲意味和生机活力的东西,譬如 “海德斯──你的机遇”,或者是简单的一块“欢迎” 标牌,下面用电灯缀成一幅热情握手图。那条旧箴言稍稍压抑了些──昂格尔先生曾经那么寻思,可现在……
就这样约翰看了一眼,然后毅然将脸转过去对着自己的目的地。他转身离去的时候,海德斯的灯火在夜空映衬下,仿佛充满了一种暖意融融热情洋溢的美。
乘罗尔斯-皮尔斯汽车,圣米达斯学校距波士顿有半小时路程。实际距离则永远不会有人知道,因为除了约翰 ·T· 昂格尔,从前没有人去那儿不是乘罗尔斯-皮尔斯汽车,而且今后也不会再有人那样去上学。圣米达斯是世界上最昂贵并且最排外的男生预备学校。
约翰在那儿的最初两年过得很愉快。少年们的父亲全都是富豪,约翰过暑假全都是去时髦的休闲胜地作客。他作客的人家,少年们全都令他喜欢,少年们的父亲却却令他感到震惊,因为他们几乎是一个模子里倒出来的。他常常以自己孩子气的思维方式,想弄明白他们为什么极其相像。他告诉他们他家在哪儿,他们就会快活而和蔼地问道:“那一带挺热吧?” 约翰便挤出一点淡淡的笑来,答道:“那倒不假。” 如果他们不是全都开这种玩笑,他的反应肯定会更热忱些。但他们的问法最多也就是换成:“你们那一带不是十分热吧?” 这同样令他反感。
第二学年的半道上,一个沉静、英俊,名叫珀西 · 华盛顿的少年插到了约翰他们班上。新同学举手投足讨人喜欢,衣着服饰即便在圣米达斯这种地方也是出类拔萃,但不知何故,他跟其他同学总是不合群。他唯一亲近的人是约翰 ·T· 昂格尔,但即便是对约翰,涉及到他的家和家人时,他也是缄口不语。他很富有那是不用说的,但是除开这种推断之外,约翰对他的朋友便没有多少进一步的了解了,因此,当珀西邀请他夏天去 “西部” 他们家作客时,他的好奇心有了大啖一餐糖果的指望。他毫不犹豫地应承了下来。
到了火车上,珀西才破天荒地变得健谈起来。一天,他们在餐车里吃中饭,正议论到学校里几个少年品行欠佳,珀西忽然话锋一转,说了一句很突兀的话。
“我父亲,” 他说:“是天底下没得比的首富。”
“哦,”约翰很有礼貌地说。他想不出用什么话来回应这种信任。他掂量着想说 “那好极了,” 可是这话听上去很空洞;正要说 “真的么?” 但又把话缩了回去,因为那好像是在质疑珀西的陈述。而这样一种令人震惊的陈述是不容置疑的。
“没得比的首富。” 珀西重复道。
“刚才我读《世界年鉴》,” 约翰开言道:“美国有一个人年收入超过五百万,有四个人年收入超过三百万,还有……”
“哦,他们算不上什么。” 珀西的嘴成了一个含讥带讽的半月形:“追逐蝇头小利的资本家,小打小闹的金融家,玩玩小聪明的商人和放放债的户头。我父亲能买下他们的全部家当还根本不当一回事儿。”
“但他是怎样……”
“为什么没有他的所得税记录?因为他根本不交。他最多交上一点点,但是他的真正收入不上税。”
“他一定非常非常富有,” 约翰直率地说:“我很高兴。我喜欢非常富有的人。”
“一个家伙越富,我就越喜欢他。” 他那微黑的脸上有一种热情坦率的神色:“上一个复活节我去辛力泽-墨菲家作客。维维安 · 辛力泽-墨菲有鸡蛋一样大的红宝石,还有眼球一样的蓝宝石,里面会发光……”
“我喜爱宝石,” 珀西热烈地表示同意:“我本人收藏了不少,只是我不想让学校里任何人知道。我习惯于收藏宝石而不是邮票。”
“还有钻石,” 约翰急切地说:“辛力泽-墨菲家有胡桃一样大的钻石……”
“那算不上什么,” 珀西凑上前来,压低嗓门悄没声儿地说:“那根本算不上什么。我父亲有一颗比里茨-卡尔顿饭店 4 还要大的钻石。”
译注:
1、热轴:全称是(火车的)过热轴颈箱;热铺:(廉价旅馆里)昼夜分租的轮睡床铺。“从热轴到热铺” 这个俚语是说从火车到旅馆,任何一个角落,到处。
2、在穿上长裤之前:意思是在他被当作未成年的小孩子的时候。
3、芝加哥牛肉餐馆是有名的连锁经营店,穿上标志服饰为其做宣传的姑娘称为 “芝加哥牛肉公主”,类似于麦当劳快餐的 “麦当劳叔叔”。
4、里茨-卡尔顿饭店,巴黎一家豪华大饭店。由瑞士经营旅馆业的著名企业家里茨开设。他在纽约、伦敦等地均有同以里茨(Ritz)命名的豪华大饭店,这个名字成了超级大饭店的代名词。
二
蒙大拿的落日躺在两座大山之间,像一个巨肿,暗黑的动脉从它上面兀自伸展开去,贯穿感染发炎的天空。与天穹相距无限浩瀚的下方匍匐着费希村,一个微如芥末、了无意趣、被人遗忘的地方。传说在费希村有十二个人,十二个阴郁、令人费解的人,他们吮吸着那一片几乎寸草不生的岩石的稀薄乳汁,生他们出来的便是它的一种神秘的滋生力。他们成了一个与世隔绝的种族,费希村的这十二个人像是这样一个物种:大自然起初一时冲动将他们生育出来,回头再一想,又把他们抛弃了,任由他们去挣扎和灭绝。
远处,从那蓝黑色的肿块中,一长串灯光爬出来,在荒无人烟的大地上蠕动。费希村的十二个人像鬼魂一样聚集在简陋的车站小屋旁,守望着这一趟七点钟经过的火车,这一趟从芝加哥开出的横贯大陆的快车。出于不可思议的权力,横贯大陆的快车每年总有六七次在费希村停靠。每次发生这种事的时候,总有一两个人下车,爬进一辆总是从薄暮中出现的四轮单马轻便马车,向着肿胀的落日驶去。观看这种无谓的反常现象,在费希村人中间已经成了一种膜拜仪式。只是看一看,如此而已;在他们身上,那种使人对事物产生惊奇、进行思索的生命之必备特征──幻想,已经不复存留,不然的话,围绕这种神秘的莅临可能已经产生了一种宗教。但是费希村人置身于任何宗教之外,即便是基督教的最低限度最原始的信条,在那一片不毛之石上都找不到立足之地。因此那里没有圣坛、没有教士、没有献祭,只有每晚七点钟简陋的车站小屋旁的沉默的集合,一干与会者从混沌、贫血的惊奇之心中扬起一片祷告之声。
如果说费希村人还会信奉什么神明的话,他们很可能会挑中扳道工做他们的主要神仙。在这个六月之夜,那个伟大的扳道工已经下令七点钟的火车在费希村留下它托运的人类或非人类。七点过两分,珀西 · 华盛顿和约翰 ·T· 昂格尔下了车,急匆匆地穿过十二个费希村人那着了魔的、大张着嘴的、怯生生的目光,爬进一辆显然从乌有处出现的四轮单马轻便马车,扬鞭而去。
半小时后,曙暮光已经凝为黑暗,赶马车的那个沉默的黑人,向他们前面昏暗中一个黑糊糊的形体喊了一嗓子。它对那声喊的回应是,将一只发光的圆盘对着他们,注视着他们,像深不可测的黑夜里一只恶毒的眼睛。走近一些之后,约翰发现那是一辆大而无当的汽车的尾灯,他从来没有见过如此之大,如此豪华的汽车。车身是一种闪闪发光的金属,比镍更贵重、比白银更轻;车轮的毂镶着绿黄两色光灿灿的几何图形,那是玻璃还是钻石,约翰不敢妄加猜测。
两个黑人,身穿可以在伦敦王室队列图片上看到的那种闪闪发光的号衣,毕恭毕敬地侍立在汽车旁;两个年轻人从马车里下来的时候,他们用客人听不懂的某种语言请安,那似乎是南方黑人方言中的最极端的一种。
“上车吧,” 珀西对他的朋友说,这时他们的行李已经扔到了轿车乌泽泽的车顶上:“很抱歉我们不得不让你乘这么远路的马车,不过,让火车上的人或菲希村那些被上帝遗弃的人看见这辆汽车,那当然是不行的。”
“天哪!多棒的车!” 这一声叫是车内的景观引起的。约翰看到,那些衬垫由成千块精美绝伦的织锦构成,间以宝石和绣品,织在金丝面料的底子上。两位少年尽情享用的两张带扶手的座椅上,铺着一种类似于绒布的料子,看上去却似乎是用无数种颜色的驼鸟羽绒织成的。
“多棒的车!” 约翰又一次惊叫。
“这东西?” 珀西笑了:“嗯,它只是我们当客货两用车来使唤的一辆老破车。”
这时,他们正穿过黑暗,驶向两座大山之间的豁口。
“一个半小时我们就到了,” 珀西看着表说道:“我还可以告诉你,那儿同你以前看到过任何地方都不一样。”
如果说这车子对于约翰接下来的见闻多少是一种暗示,那么约翰的确是准备好了让自己吃惊的。在海德斯一带流行的那种纯朴的虔敬,是以真诚崇拜财富和尊敬财富为首要信条的。如果约翰在财富面前的感觉不是心中洋溢着谦卑,他父母一定会被他的大不敬吓得扭过头去。
他们现在已经到达两座大山之间的豁口,正在驶进去;几乎是立竿见影,路变得崎岖得多了。
“如果月光照得到这儿,你会看到我们是在一个很大的沟壑里,” 珀西说,想透过车窗朝外看。他对着传声筒说了几个字,男仆立刻打开探照灯,用一道大而无当的光柱扫视着山坡。
“全是石头,你瞧。一辆普通汽车不出半小时便会颠成碎片。事实上,除非你认识路,你想从这儿通过就得开坦克才行。你留意到没有,我们现在正往山上开呢。”
他们显然在爬高,不出几分钟,他们越过了一道高坡,在那儿他们瞥到了一眼刚刚在远方升起的一弯苍白的月亮。车子突然停下来,几个人影从车旁的黑暗中现出身形,这些人也是黑人。两个年轻人又被人家用含混难辨的方言请安一遍;接着,黑人们开始干活,四根在头顶上方悬荡的大而无当的缆绳用钩子搭住了镶珠宝的巨大车轮的毂。随着回音四起的 “嗨-唷!” 一声喊,约翰感觉到车子缓缓地离地而起,升呀升,越过了两边高高的山岩,再升上去,终于,他看到了月光下一道波浪般起伏的溪谷,它从他眼前延伸开去,与他们刚刚摆脱的岩石阵形成了鲜明的对照。只有一面仍然是岩石,接着突然之间,他们的两边或者说四周,一块岩石也不见了。
明摆着,他们已经越过某一道大而无当、刀刃般峭峭然直指天空的山岩。一会儿他们又开始往下降,最后轻轻地碰撞了一下,他们便落到了平地上。
“最糟的已经过去,” 珀西说,瞟着窗外:“从这儿过去只有五英里了,我们自己的路,花毯式地砖铺的,一路都是。这是属于我们的。这是合众国的尽头,父亲说的。”
“我们在加拿大么?”
“不是。我们在蒙大拿州落基山脉的中央。不过你现在是在这个国家唯一没有经过测量的五英里土地上。”
“为什么没测量?他们忘了么?”
“不是,” 珀西说,咧开嘴笑着:“他们有三次想测。第一次我祖父贿赂了州测量局整整一个部门;第二次他收买了修改中的合众国官方地图,那一下拖延了他们十五年。最后一次比较困难。我父亲安排了一下,让他们的罗盘处于人工所能设置的最强磁场之中。他搞了一整套测量仪器,造得只有很细微的一点误差,那样一来,这个区域便不会显露出来了,他用这套仪器替换了他们将要使用的那一套。然后他让一条河改了道,在岸边造了一片像村庄一样的建筑,那样他们看到它时,便会以为是溪谷上游十英里以外的一个镇子。只有一样东西我父亲害怕,” 他总结道:“天底下只有一样东西可以用来发现我们。”
“那是什么?”
珀西压低声音,变成了耳语。
“飞机,” 他悄声说:“我们搞了五六架高射机枪,到目前为止我们一直安排得很妥当,只不过打死了几个人,囚禁了不少人。这并不是说我们,父亲和我,在乎那种事,而是母亲和姑娘们感到忐忑不安,而且总是有这种可能性,我们有时会来不及安排。”
一条条一片片破碎的绒鼠毛皮,新月的天空上的殷勤的云彩,正从新月上飘过去,像珍贵的东方呢绒列队接受某个鞑靼可汗检阅似的。对于约翰,现在似乎是白天,他正仰望着一些伙计在空中飘航,阵雨般地撒下小册子和专利药物传单,连同他们给山岩包围中的绝望的小村庄所带来的希望。他仿佛能看见他们从云中向下俯望和注视──注视着他所去的这个地方随便什么可注视的东西──然后呢?是不是他们受那边某种阴险手段的诱惑而着陆,被监禁起来,远离专利药物,远离小册子,直至末日审判的那一天?或者,假设他们未曾落入圈套,是不是在 “噗” 的一团烟和一颗爆裂的炮弹的刺耳的弧线促使下,掉到地上来,令珀西的母亲和姐妹们“忐忑不安”?约翰摇摇头,摇摇两片嘴唇间默默发出的嘿然一笑之依稀可辩的气息。这个地方究竟隐藏着什么无法无天的交易?那怪诞的大富豪究竟在道德上玩什么苟且的勾当?究竟是什么样的可怕而金光闪烁的秘密?……
绒鼠毛皮云彩现在已经飘过去了,车窗外的蒙大拿之夜亮同白昼。他们绕一湾寂静的、沐浴在月光中的湖水而去,巨大的轮胎行驶在花毯式地砖的路面上感觉平坦而光滑;有一会儿,他们进入了黑暗,经过一小片散发着浓烈松树气味、带着凉意的松林,然后出来,进入草坪中间一条宽阔的林荫道,约翰发出一声欣喜的感叹,与此同时,珀西一本正经地说了声:“我们到家了。”
星光辉映之中,一座美仑美奂的城堡从湖边拔地而起,闪耀着大理石的光泽,升至毗连的一座山的半腰,然后优雅地、以完美的匀称,呈着半透明的女性的倦慵,融入一大片松林的晦暗之中。那许多塔楼,胸墙斜面上那些纤巧的装饰线条,成千扇带有金光灿灿的长方形、多边形和三角形窗格的黄色窗户上的那些奇迹般的雕镂,星光平面和蓝影平面相交在一起所形成的那种令人震惊的柔美,这一切,像音乐的和弦一样在约翰的心灵上颤抖。其中一座塔楼,最高的那一座,底座最黑的那一座,塔顶外面缀饰着灯彩,创造出了一个飘浮的仙境。正当约翰一腔痴迷、凝神仰望之际,从上面飘下来微弱的小提琴短倚音,这样一种洛可可式 5 的和谐是约翰闻所未闻的。接着,瞬息之间汽车便停在了宽阔的、高高的大理石台阶前。在这周围,许多鲜花使夜间的空气充满了芳香。台阶顶端,两扇巨大的门打开了,琥珀色的光向黑暗中一泻而出,映现出一位纤美的夫人的剪影,她的一头黑发高高绾起,向他们伸出了双臂。
“母亲,” 珀西在说话:“这是我的朋友约翰 · 昂格尔,从海地斯来的。”
在约翰后来的记忆中,到这儿的第一夜是一团眼花缭乱:五彩缤纷的颜色,爱情絮语一样柔和的音乐,物件、光与影和脸庞移动交织成的美。有一个白发男子站在那儿,从一只金柄脚的水晶杯中啜饮着一种色彩缤纷的露酒。有一个面容如花姑娘,穿得像仙后泰坦尼娅,头发上扎着蓝宝石编缀的发带。有一个房间,它那坚固、柔软的金墙在他的掌压下凹陷;还有一个房间像是柏拉图终极监狱的概念:天花板、地板等等边沿全都镶着大量完整的钻石、各种尺寸各种形状的钻石,竟至于,在角落里高大的紫罗兰色灯盏点亮时,化成一片眩目的白色,那奇景只有它本身能与之媲美,人类的愿望与梦想皆不能及。
两位少年在这等房间的迷宫中游荡。有时他们脚下的地板会映现出明亮的图案,那是因为下面亮着灯。那些图案色彩原始而不协调,笔法细腻,底子是透光的白色物质或做工精细繁复的马赛克,出处肯定是亚德里亚海上的清真寺。有时,他会看见厚厚的水晶层下面是蓝色或绿色的的旋涡,里面养着活蹦乱跳的鱼和叶片像彩虹一样的水草。接下来又变成了他们脚踏各种质地和颜色的毛皮,或者走进了色泽最白的象牙构筑的走廊,它看不出接缝,仿佛是用整块材料雕琢而成,原料是史前时代灭绝了的恐龙的巨大獠牙……
接下来的记忆模模糊糊地过渡过去,他们在用餐:餐桌上的盘子都是由两层纯钻石贴合而成,但是这一点几乎察觉不出,贴面上离奇古怪地安着翡翠绿透雕图案,它简直就是一薄片绿色空气。音乐悠悠地回荡着,从远处的走廊里飘下来──他那张铺陈着羽绒、曲线贴合腰背的椅子,在他喝下第一杯波尔图葡萄酒 6 后,便令他陷进去不能自拔。他昏昏欲睡地试图回答人家问他的一个问题,但是那紧攫他身体的蜜一样的舒适更添了几分昏睡中的错觉──宝石、织物、酒和金属在他眼前模糊成一团甜蜜的雾……
“是的,” 他好不容易才不失礼数地答道:“要我去那儿当然够热的。”
他设法补上一声怪里怪气的笑,然后一动不动,不加反抗,似乎飘走了,留下一个梦一样呈粉红色的冰冻的荒原…… 他睡着了。
他醒过来的时候知道已经过去几个小时。他在一个很大很安静的房间里,墙壁是乌木的,有一点幽幽的亮,太弱、太柔,不能叫做光。小主人站在旁边俯望着他。
“你用餐的时候睡着了,” 珀西在说话:“我也差一点,在学校里待了一年之后重过舒服日子真是件乐事。你睡着的时候仆人们给你脱去衣服洗了个澡。
“这是一张床还是一朵云?” 约翰叹道:“珀西,珀西,你走之前,我想说声抱歉。”
“为了什么?”
“为了在你说你们有一颗像里茨-卡尔顿饭店一样大的钻石时,我怀疑你。”
珀西微微一笑。
“我知道你不信我。就是这座山,你知道。”
“什么山?”
“城堡造在上面的这座山。作为一座山,它不是很大。但是除开表面大约五十英尺生长草皮的土层和砂砾之外,它就是纯钻石了。一颗钻石,一立方英里,一丝裂缝一点瑕玼也没有。你在听么?喂……”
但是约翰 ·T· 昂格尔已经又睡着了。
译注:
5、洛可可:一种精巧、华丽的艺术风格。
6、波尔图葡萄酒:原产葡萄牙的一种高酒精度葡萄酒,呈深红色。
三
早晨。他醒来的时候,睡意犹存地意识到同一时刻房间里有了阳光,变得那么亮。一面墙的乌木镶板已经沿着槽道滑到一旁去,令他的寝室半敞在日光之下。一个身穿白色制服的魁梧的黑人站在他床边。
“晚上好,” 约翰嘟囔道,想让自己的脑子从不着边际中回过神来。
“早上好,阁下。你准备好洗澡了么,阁下?哦,不用起来,我会把你放进去的,你只消解开睡衣的扣子──行了。谢谢,阁下。”
约翰静静地躺着,让自己的睡衣被除去,他感到既好笑又开心;他估摸着自己会像孩子似地被这个侍候自己的黑高康大 7 举起来,但是根本就没有发生这种事;取而代之的是,他感到床缓缓地向一边倾斜,身体开始向墙壁方向滚动。起先他一惊,但是当他到达墙边时,墙帷让开了一条道,他在一个羊绒斜面上又滑出去两英尺,便轻轻地坠入了同他身体温度一样的水中。
他看看四周。送他过来的那条滑道或者说滚道,已经轻轻地折叠回原处。他被投到了另一间寝室里,正坐在一个陷进地板之中的浴池里,他的头刚好在地板的水平线上方。他的四周,从房间的墙壁到浴池的四壁和池底,整个儿衬着的是一个蓝色的鱼缸。透过他坐在上面的水晶表面,他出神地看着,看见鱼儿在琥珀色的光中游动,甚至毫无好奇之心地从他张开的脚趾头旁边滑过,中间只隔了一层厚厚的水晶。头顶上,阳光透过海绿色的玻璃而下。
“阁下,我估摸您今天早上想要热的玫瑰花水和泡沫肥皂水,阁下,最后也许可以用冷盐水冲一下。”
黑人站在他旁边。
“好啊,” 约翰表示同意,无谓地笑了一笑:“随你的便。” 任何按照他本人的粗劣标准安排这次沐浴的念头都是没有自知之明,而且不是一丁点儿过份。
黑人摁了一个按纽,便开始下一场热雨,表面上是从头顶上下来,而其实如片刻之后约翰所发现的那样,是从近旁一个喷泉装置里下来的。水转变成淡淡的玫瑰色,液体肥皂射流从浴池角上四个微型海象头里喷射进其中。不多一会儿,固定在池壁上的十几个小桨轮已经将这混合液搅成一片粉红色泡沫的亮丽彩虹,它以芬芳怡人的轻盈柔爽轻轻地裹住他,在他身边到处爆掉一个个亮闪闪的粉红色泡泡。
“要我打开电影机么,阁下?” 黑人恭敬地提议道:“今天这机子里有一部不错的单盘片喜剧,如果你不喜欢,一会儿功夫我就可以换上一盘严肃的。”
“不用了,谢谢。” 约翰答道,很有礼貌也很坚决。这样洗澡他很受用,不想让别的事分心。但是分心的事来了。片刻之后,他便在很专心地听长笛齐奏的声音,它就在外面,沥出的旋律就像一片瀑布,清凉碧绿恰如这房间,还伴随着一注泛着泡沫的短笛声,它的演奏比包裹着他、令他迷醉的肥皂液轻纱更为纤美。
用冷盐水作兴奋剂激过一遍,再用清新的凉水最后冲过一道之后,他走出浴池,披上迎过来的羊绒浴袍,躺到铺着同样材料的长椅上,享受油、酒精和香料的按摩。稍后他坐进一张极舒适的椅子里,修面、理发。
“珀西先生在你的起居室里等着,” 这些活儿干完之后,黑人说道:“我名叫吉格萨姆,昂格尔先生,阁下。我每天早晨来侍候昂格尔先生。”
约翰出了浴室,走进起居室里的璀灿阳光之中,他发现早饭正在那里等着他和珀西,后者潇洒地穿一件白色灯笼短裤,正坐在安乐椅里抽烟。
四
这是一个华盛顿家族的故事,用早餐的时候珀西给约翰所描述的就是它。
现在当家的华盛顿先生的父亲是弗吉尼亚州人,乔治 · 华盛顿的直系后裔,巴尔的摩勋爵。内战将近的时候他是一位二十五岁的上校,有一片逐渐衰落的种植园和一千个金美元。
菲茨-诺尔曼 · 卡尔佩珀 · 华盛顿,因为这就是那位年轻上校的姓名,决定将弗吉尼亚的产业馈赠给他弟弟,自己去西部。他挑选了两打最忠心的黑人,当然,那些人很崇拜他,买了二十五张去西部的火车票,他打算以他们的名义在西部申领到土地,创建一个大牧场养牛养羊。
话说他到蒙大拿州不到一个月,惨淡经营、诸事不顺,这时他碰上了那个伟大的发现。当时他骑马在山岗间迷了路,一天没吃东西,腹中饥饿。因为没带来福枪,他不得不去追逐一只松鼠,在追猎的过程中他注意到它嘴里携带着一样亮晶晶的东西。在它消失于洞穴中之前那一刻──因为上帝不打算让这只松鼠来缓解他的饥饿 ──它丢下了它的负载。菲茨-诺尔曼坐下来考虑一下处境,目光被身旁草丛中的亮光吸引住了。十秒钟后,他失去了胃口,得到了十万美元。那只令人恼怒地坚持拒绝成为食物的松鼠,送了一颗大而无瑕的钻石给他作礼物。
那天夜间晚些时候他找到了回营地的路,十二个小时之后,他那些黑人中的所有男性回到了松鼠洞旁,在山坡上一个劲儿地乱挖。他对他们说的是他发现了一个莱因石矿,由于他们中只有一两位从前见过很小的钻石,他们相信了他,丝毫没有疑心。当他明白过来这个发现有多么巨大时,他没了主意。那座山是一块钻石。它实实在在不是别的,就是一块纯粹的钻石。他装了满满四鞍囊闪闪发光的样品,骑马动身去圣保罗。他在那儿设法售出了五六块小石头──当他尝试卖一颗大一些的石头时,店主晕了过去,菲茨-诺尔曼作为扰乱公共秩序者被捕。他从监狱里逃出来,赶上了去纽约的火车,在那儿他卖掉了几颗中等大小的钻石,以此换来大约二十万金美元。但是他不敢把大的宝石拿出来。事实上,他离开纽约正是时候。珠宝界起了轩然大波,不但由于其钻石之大,而且因为它们在纽约城的出现来历不明。谣言四起,说发现了一个钻石矿,在卡茨基尔山 8、在泽西海岸 9、在长岛、在华盛顿广场下面。短途火车装满了携带镐头和铁锹的人,开始从纽约出发,每小时都有一列,开往附近各种各样的爱尔多拉朵 10。而这时年轻的菲茨-诺尔曼正在回蒙大拿的路上。
过了不到两个礼拜,他估算出山上的钻石数量大约相当于世界上其他所有地方已知钻石储量的总和。任何常规计算方法都无法计算它的价值;如果拿出去卖,不但会把市场弄个底朝天,而且按照通常那种价值按尺寸大小以级数增长的计算方法,世界上的所有黄金还不够买下它的十分之一。那种尺寸的一颗钻石,有谁有办法处理它?
这是一种奇异的尴尬处境。从某种意义上说,他是有史以来最富有的人,然而到头来他又算得了什么?如果他的秘密被人得知,政府会采取什么样的手段来阻止不但是珠宝业甚至是黄金业的一场大恐慌,那只有天知道了。他们也许会立刻接管产权,并实行专卖。
别无选择,他必须秘密地销售他的山。他派人去南方把弟弟找来,让他管理他的有色人种追随者──那些对奴隶制已经废除浑然不知的黑人。为了确保这一点,他向他们宣读了一份他自己撰写的公告,宣称福雷斯特将军 11 已经重新组织起受损的南方军队,在一次布好阵式的正式会战中打败了北方。黑人们对他的杜撰深信不疑。他们投票表决,声明这是一件好事,立刻开始为战后重建效力。
菲茨-诺尔曼本人则带着十万美元和两个装满各种大小尺寸毛坯钻石的大旅行箱,动身去外国。他乘一艘中国式帆船驶向俄国,离开蒙大拿六个月后他到了圣彼得堡。他找了个不起眼的住处,立刻去拜访宫廷珠宝商,声称自己有一颗钻石请沙皇御览。他在圣彼得堡滞留了两个礼拜,一直处于被谋杀的危险之中,不断地更换住处,整整两个礼拜只敢去看了那两只大旅行箱三、四次。
他答应一年后带更大更纯净的钻石回来,于是获准前往印度。但是在他离去之前,宫廷珠宝商已经向他在美国银行的账面上存入了总额为一千五百万美元的款项──在四个不同的化名账户之下。
他一去两年多,于 1868 年返回美国。他游历了二十二个国家的首都,同五位皇帝、十一位国王、三位王子、一位沙 12、一位可汗和一位苏丹交谈过。回国时菲茨-诺尔曼估计自己的财产已经达到十亿美元。一个事实对避免暴露他的秘密起到了持续的作用。他的大钻石中的每一颗,在公众眼中停留不到一个礼拜时间,便被赋予一段历史,加上足够的天灾人祸、偷情、革命和战争之类的经历,使之从第一个巴比伦王朝时代辗转至今。
从 1870 年起到 1900 年去世,菲茨-诺尔曼的历史是一部漫长的黄金史诗。当然,有一些旁枝末节:他躲过了测量;他与一位弗吉尼亚女士结婚,同她生下一个独子;因为一系列不幸的纠纷,他被迫杀死了他的弟弟,后者酗酒无节制到人事不省胡言乱语之程度的不幸习惯,曾经数次危及他们的安全。但是,几乎未曾有别的谋杀事件玷污这些发展和扩张的幸福岁月。
就在他临死之前,他改变了他的政策。他只留下几百万美元的浮财,其余的全用来大量购买稀有矿物,标以小古玩的名称,把它们存在世界各地的银行保险库里。他儿子布雷多克 · 塔尔顿 · 华盛顿沿袭了这个政策,其尺度之紧甚至有过之而无不及。那些矿物被换成了所有元素中最最稀有的元素:镭。这样一来,相当于十亿美元的黄金便能够放进一只大小不超过雪茄烟盒的贮藏器中。
菲茨-诺尔曼去世三年之后,他儿子布雷多克认定生意已经做得够大。他和他父亲从山中所获取的钱财数目已经完全无法精确计算。他弄了一本用密码书写的笔记本,在上面记下他所惠顾的千家银行里各自存放的镭的大约数目,以及存在什么化名之下。然后他做了一件很简单的事:把钻石矿封了起来。
他把钻石矿封了起来。已经从中取出的东西将足以让整个华盛顿家族世世代代过上无与伦比的奢华生活。他唯一操心的事是务必保住他的秘密,以免它暴露后所可能带来的巨大恐慌令他和全世界的财主沦为一贫如洗。
这就是约翰 ·T· 昂格尔所居留的家族。这就是他到达之后第二天早晨在他的白银为墙的起居室里听到的故事。
译注:
7、高康大:文艺复兴时期法国伟大作家拉伯雷之名著《巨人传》的主人公。
8、卡茨基尔山:纽约市附近的一座山。
9、泽西海岸:与纽约市相邻的泽西城边的海岸。
10、爱尔多拉朵:想像中的黄金国、幸福的理想之地。
11、福雷斯特将军(Nathan Bedford Forrest,1821-1877),美国内战时南部著名将领,自行组织骑军起家,大肆屠戮黑人,后率部投降,战后成为三 K 党党魁。
12、沙:伊朗国王的称号。
五
用过早餐之后,约翰走出巨大的大理石大门,好奇地眺望着眼前的风景。整个溪谷,从钻石山到五英里外陡直的花岗岩峭壁,依然在散发出一种金色晨霾的气息,它懒洋洋地盘旋在连绵秀美的草坪、湖面和花园的上空。到处是一簇簇的榆树,形成一丛丛雅致的绿荫,与那一大片一大片使山峦清一色呈深蓝绿的粗犷松树,形成鲜明的对比。约翰这样望着,竟看见排成一列纵队的三头幼鹿从大约半英里外一片树丛里出来,高兴得胡蹦乱跳地,消失在另一片黑栅栏条围起的半明半暗的树荫之中。现在即便看到一只山羊脚 13 在树林中吹着笛子行走,或者在最绿的绿叶中间瞥见粉红的仙女皮肤和飞扬的黄色头发,约翰也不会感到惊诧了。
他带着诸如此类的冷静的希望,走下大理石台阶,稍稍惊扰了一下台阶底下两只俄国猎狼狗的睡眠。他沿着一条蓝白两色砖铺成的步行道信步走去,它似乎并不通往哪一个特定的方向。
他眼下是能怎么快活就怎么快活。正是因为青春的欢乐和青春的缺陷,青春才永远无法生活于现在,而必须永远去衡量生活,其标准是自身对未来的光辉灿烂的想像──鲜花和黄金,姑娘和星辰,它们只是无与伦比、无法实现的青春之梦的征兆和预言。
约翰从一大片在空气中弥漫着浓郁花香的玫瑰花丛旁,绕过一个徐缓的弯,径自穿过一个花园,向树木掩映下的一小片苔藓走去。他从未在苔藓上躺过,他想瞧一瞧它是否够柔够软,足以证实其作为形容词使用时的性状。这时他看见一个姑娘从草地的另一边向他走来。她是他生平见过的最美丽的姑娘。
她穿一件长度刚过膝盖的白色裙衫,一只缀有蓝宝石薄片的木犀草花环箍着她的头发。她一路走过来,那双粉红色的光脚一路在身前溅起露珠。她比约翰小:不超过十六岁。
“喂,” 她轻柔地喊道:“我是吉丝敏。”
她远不止是约翰已经意识到的那样一位姑娘。他走上前去,到了她跟前便几乎一动不动,免得踩到她光着的大脚趾。
“你没有见过我,” 她那温柔的声音说。她那双蓝眼睛又加上一句:“啊,你真是错过太多了!”……“昨天晚上,你见过我姐姐佳丝敏。我病了,莴苣叶中毒,” 她那温柔的声音接下去说道,她那双蓝眼睛继续补充:“我生病的时候是很甜美的──不生病的时候也是。”
“你给我留下了极深刻的印象,” 约翰的眼睛说:“我本人并非那么迟钝。”──“你好么?” 他的声音说:“希望你今天早晨好些了。”──“亲爱的人儿,” 他的眼睛腼腆地补上一句。
约翰留意到他们一直在沿着那条小径走着。在她的提议下,他们一起在苔藓上坐了下来,它的柔软程度他拿不准。
他对女性很挑剔。单单一个缺点──脚踝粗壮,声音沙哑,或眼睛无色──便足以令他兴味索然。在他一生中,这是第一次,他身旁是一位在他眼睛里似乎是完美形体之化身的姑娘。
“你从东部来么?” 姬丝敏带着迷人的关注神色问道。
“不,” 约翰简单地答道:“我来自海德斯。”
要么她从未听说过海德斯,要么她想不出什么令人不快的话来评论它,总之她没有再谈它。
“今年秋天我要去东部读书,” 她说:“你觉得我会喜欢么?我要去纽约巴尔吉小姐的学校。它很严格,但是你瞧,周末我会去纽约的家,同我们家族的人一起过,因为父亲听说姑娘们出门走路得成双结对。”
“你父亲希望你们不失尊严,” 约翰评论道。
“我们的确是这样,” 她答道,眼睛里闪烁着庄严的光芒:“我们谁也没有受过责罚。父亲说我们永远不应受责罚。我姐姐佳丝敏还是个小女孩的时候,有一次她把他推下了楼梯,他只是站起来,一瘸一拐地走开了。
“母亲──嗯,她有点吃惊,” 吉丝敏继续说下去:“当她听说你是从…… 从你所来的那个地方来的时候,你知道。她说,当她还是个姑娘的时候…… 当时,你瞧,她是个西班牙人,旧派姑娘。”
“你有没有到外面去过很长时间?” 约翰问道,借以掩盖这番评论多少对他有些伤害这样一个事实。对于他的地方观念,这似乎是一个不友善的影射。
“珀西和佳丝敏和我每年夏天都在这儿,但是明年夏天佳丝敏要去新港。今年秋天起她要在伦敦露面一年。她会出席宫廷聚会。”
“你知不知道,” 约翰犹犹豫豫地开言道:“你比我第一眼看到你时留给我的印象老于世故得多?”
“哦,不,我不是,” 她着急地叫道:“哦,我不认为自己是那样的人。我觉得老于世故的年轻人是极其普遍的,你说呢?我根本不是,真的。如果你说我是,我要哭了。”
她沮丧极了,连嘴唇都在颤抖。约翰被迫进行申辩:
“我不是这个意思。我那样说只是逗着你玩。”
“因为如果我是的话我就不会介意,” 她坚持说:“但我不是。我很无知而且女孩子气。我不抽烟、不喝酒,除了诗歌以外什么也不读。我几乎不懂数学和化学。我穿着很朴素,其实,我几乎根本不打扮。我觉得你说我什么都比说我老于世故合适。我认为女孩子应该以健康的方式享受青春。”
“我也这样认为,” 约翰诚挚地说。
吉丝敏又高兴起来了。她冲他微笑,一颗剩下的泪珠从蓝眼睛的眼角滴落下来。
“我喜欢你,” 她亲昵地悄声说道:“你在这儿的这段时间,准备一直同珀西待在一起么,陪陪我行不行?只要想一想──我是一个玉洁冰清的姑娘。我一生中从来不曾同男朋友相爱过。甚至从来不允许我单独见一见男孩子──除了珀西。我专门跑出来,到这小树林里,希望遇见你,在这儿旁边没有家里人。”
深感荣幸之余,约翰像他在海德斯的舞蹈学校里学到的那样,来了个九十度鞠躬。
“我们得走了,” 吉丝敏甜甜地说:“十一点钟我得和母亲在一起。你还没有要我吻你一次。我觉得如今男孩子都是这样的。”
约翰骄傲地挺直身体。
“有些男孩子是这样的,” 他答道:“但我不是。姑娘们不做那种事情──在海德斯。”
他们肩并肩向回走去。
六
在直射的阳光下,约翰面对布雷多克 · 华盛顿站着。年长的男子大约五十岁,一张骄傲的、没有表情的脸,一双聪明的眼睛,一副强健的体型。早晨他身上有马──最好的马的气味。他拿着一根朴素的水桦木手杖,上面只嵌了一颗大蛋白石作柄。他和珀西正领着约翰四处看看。
“奴隶们的寓所在那边。” 他的手杖指着他们左边一道大理石柱廊,它以优雅的哥特式风格蜿蜒在山坡上:“我年轻时候有一阵子注意力从生活事务转移到了荒唐的理想主义目标上。那一段时间他们的生活很奢华。例如,我给他们每个人的房间配备上磁砖浴缸。”
“我猜想,” 约翰冒昧说道,奉承地笑了笑:“他们把浴缸用来装煤。辛力泽-墨菲先生告诉我说有一次他……”
“辛力泽-墨菲先生的观点不重要,我该设想,” 布雷多克 · 华盛顿冷冷地打断了他的话:“我的奴隶们并没有用他们的浴缸装煤。他们遵命每天要洗澡,他们照办。如果他们不洗,我可能已经下令给他们用硫酸洗发液了。我中止他们的洗澡完全是另有原因。他们中有几个得了感冒并且死了。水对某些种族没有好处,除非作为饮料。”
约翰笑起来,然后决定点点头,严肃地表示赞同。布雷多克 · 华盛顿令他不舒服。
“所有这些黑人,都是我父亲带到北方来的那些人的后代。现在他们的人数已经有大约二百五十。你看,他们与世隔绝地生活了那么长时间,他们原有的方言已经差不多变成了无法分辩的土语。我们培养他们中少数几个人说英语──我的秘书和两三个料理家务的仆人。
“这是高尔夫球场,” 他接着说道,这时他们走在丝绒般的越冬草上:” 一片绿,你瞧:没有球道,没有深草区,没有障碍物。”
他愉快地冲着约翰微笑着。
“笼子里有许多人么,父亲?” 珀西突然问。
布雷多克 · 华盛顿绊了一下,不经意之间发出一声咒骂。
“比应有的数目少了一个,” 他突然阴郁地冒出一句──片刻之后又加上一句:“我们有麻烦了。”
“母亲告诉我说,” 珀西嚷道:“那个意大利教师……”
“一个可怕的错误,” 布雷多克 · 华盛顿恼怒地说:“不过,当然很有可能我们还会抓住他。也许他倒在树林里某个地方,或者从悬崖上摔出去了。而且退一步也始终有这样的可能性:即使他逃脱了,也没人相信他的故事。但无论如何,我已经派了二十几个人到周围各个镇子去找他。”
“没有交上好运?”
“有一点。他们中十四个人向我的代理人报告说他们各杀死了一个与描述相符的人,当然,有可能只是因为他们要赏钱……”
他打断了话头。他们来到了一个大地洞跟前,它的圆围有旋转木马的转台那么大,上面盖着一块结实的铁格栅。布雷多克 · 华盛顿向约翰颔首示意,并且将手杖戳进铁格栅指着下面。约翰走到边上,向里面望。立刻,一阵狂乱的嚷嚷声从下面向他的耳朵袭来。(“六” 待续,“它” 说不能超过二万字--不知为什么)
译注:
13、指希腊神话中的脚为山羊之足的山林之神潘(Pan)。
“快下地狱去吧!”
“喂,小伙子,上面的空气怎么样?”
“嗨,扔一根绳子给我们!”
“老弟,给一个不新鲜的炸面圈,要不给两只吃剩下来的三明治行不?”
“喂,伙计,如果你把同你一起的那家伙推下来,我们就给你看一出转眼间失踪的好戏。”
“帮我给他一拳,干不干?”
下面洞中太黑,看不清楚,但是从言辞和声音里那种粗鲁的乐观主义意味和粗放的活力中,约翰听得出他们来自美国中产阶级,属于精神比较饱满的那种类型。这时华盛顿先生将手杖抽出来,触了一下草丛中的一个按钮,下面的场景一下子亮了起来。
“这是一些有冒险精神的水手,他们不幸发现了爱尔多拉朵,” 他评论道。
他们的下方出现了一个很大的地下空洞,形状像一只碗。洞壁很陡,显然是用光滑的玻璃打造的,在略有些凹的洞底,站着大约二十几个男子,一半穿飞行衣,一半穿飞行员的制服。他们仰起的脸上,放着或愤怒、或怨恨、或绝望、或讥嘲谐谑的光,满脸是长了多时的胡须;但是除了少数几个明显有些消瘦之外,他们这群人似乎吃得挺好,身体健康。
布雷多克 · 华盛顿将一张花园椅子拉到洞边,坐了下来。
“嗯,你们好么,小伙子们?” 他和蔼可亲地询问道。
一阵除了少数几个没精神喊不出之外全都参加的咒骂大合唱,扬起到阳光和煦的空中;但是布雷多克 · 华盛顿听在耳朵里,安之若素。这合唱声的最后一阵回音消逝之后,他再重新发话。
“你们想出摆脱困境的办法没有?”
他们之中这儿那儿飘上来一句话。
“我们决定为了爱的缘故待在这儿!”
“把我们弄到上面去,我们会给自己找到一个解决办法!”
布雷多克 · 华盛顿等着,等他们重新安静下来。然后他说道:
“我已经把局势给你们讲清楚。我不想把你们留在这儿。我对天发愿希望从没见过你们。是你们自己的好奇心把你们带到这儿来,任何时候你们想出一个不损害我和我的利益的办法,我都乐意采纳。但是既然你们把精力局限在挖地道上──是的,我知道你们又开始在挖一条新的──那你们就不会有多大成就。这并不是像你们所想的那样铁石心肠,对你们,连同你们所有思念家中亲人的哀号声。如果你们是很为家中亲人担心那种类型的人,你们就决不会干开飞机这一行。”
一个高个子从伙伴中间走出来,举起一只手,请他的俘获者注意听他要说些什么。
“我来问你几个问题!” 他说:“你装成一个公正的人。”
“多么荒谬。一个我这种地位的人,怎么可能对你公正?你还可以说什么一个西班牙人公正地对待一块牛排呢。”
这一番苛刻的言论令二十几块牛排的脸掉了下去,但是高个子没有住嘴。
“行啊!” 他嚷道:“这个我们以前已经透彻地争论过。你不是人道主义者也不是一个公正的人,但你是一个人──至少你说你是──你应该能够在足够长的时间里为我们设身处地考虑到多么…… 多么…… 多么……”
“多么什么?” 华盛顿冷冷地询问道。
“…… 多么不必要……”
“对我并非如此。”
“嗯,…… 多么残忍……”
“这一点我们已经讨论过。牵涉到自我保存的问题时没有残忍可言。你曾经当过兵,这一点你是知道的。再说说别的看。”
“嗯,那么,多么愚蠢。”
“这还差不多,” 华盛顿表示认可:“我同意。但是请考虑一下其他选择吧。我曾经提出把你们全体或部分毫无痛苦地处决掉,如果你们希望那样的话。我曾经提出将你们的妻子、心上人、孩子和母亲绑架,带出来,弄到这儿。我会在那一边把你们的地方扩大,供你们终生衣食。如果有什么导致永久失忆的方法,我会在你们全体身上实施,并且立刻将你们释放到我的领地以外的某个地方。但是我想到的办法也只有这么多了。”
“相信我们不会告发你,如何?” 有人叫道。
“你提这个建议不是很认真的吧,” 华盛顿说,面带鄙夷的表情:“我弄了一个人出来教我女儿意大利语。上个礼拜他逃走了。”
一阵狂野的欢呼声突然从二十几个喉咙里喷发出来,接踵而至的是一个欢乐的地狱。囚徒们跳起木屐舞、欢呼喝采、真音假音替换着唱歌、互相摔着玩,突然之间勃发起动物般的劲头。他们甚至尽快地跑上大碗的玻璃壁,又凭借他们的天生肉垫滑回到碗底。高个子唱起一首歌,他们全跟着唱起来:
“啊,我们要吊死皇帝
在一颗酸苹果树上……”
布雷多克 · 华盛顿谜一般沉默地坐着,直到歌唱完。
“你们瞧,” 稍稍能够得到他们的一点注意时,他评论说:“我对你们并无恶意。我乐意看到你们过得快快活活。这就是我为什么没有一下子把故事讲完整的原因。那人──叫什么名字来着?克里契蒂切罗?──在十四个不同的地方被我的代理人射中。”
他们没有猜想到十四个地方指的是城市 14,热闹的欢庆立刻平息了。
“不过,” 华盛顿带着一丝恼怒叫喊道:“他是想逃走。有了那样一次经验之后,你们还指望我再拿你们之中谁来碰一碰运气么?”
又是一阵猛然发出的叫喊声。
“当然!”
“你女儿愿意学中文么?”
“嗨,我会说意大利语!我母亲是意大利裔。”
“她兴许愿意学习侃几句纽约土话呢!”
“如果是那个小的,大大的蓝眼睛的,我可以教她许多比意大利语美妙的事儿。”
“我会爱尔兰歌曲──还能同时击打铜乐器。”
华盛顿先生突然伸手,用手杖触了一下草丛中的按纽。于是,下面的图景立刻便消失了,只剩下那张黑森森的大嘴,上面凄凉地覆盖着铁格栅的黑牙。
“嗨!” 下面一个孤单的声音唤道:“你不给咱们说声祝福的话就走么?”
但是华盛顿先生身后跟着两个少年,已经漫步向高尔夫球场的第九洞走去,仿佛那个坑以及里面的内容只不过是一个障碍物,他那得心应手的铁头球棒已经轻而易举地战胜了它。
七
钻石山荫庇下的七月,是一个夜间要盖毯子、白天热烘烘艳阳高照的月份。约翰和吉丝敏相爱了。他不知道,他送给她的那玫小小的金橄榄球(上面刻着铭文 Pro deo et patria et St. Mida 15),已经挂在白金项链上,憩息在她胸前。但是球儿知道。而在她这方面,她也没有留意到,有一天从她头饰上掉下来的一颗大蓝宝石,已经被柔情脉脉地收藏在约翰的珠宝盒里。
一天下午晚些时候,当那间红宝石白鼬皮音乐室静寂无声的时候,他们在里面共度了一个小时。他抓住她的手,她向他投过去一个的眼神,令他在私语中将她的名字喊出声来。她将身子俯向他──然后犹豫了一下。
“你是说‘吉丝敏’?” 她柔声问道:“还是……”
她要问个确切。她觉得自己可能误解了 16。
他们俩过去都没有吻过别人,但是在一个小时的过程中,这似乎并没有造成什么影响。
下午溜过去了。那天夜间,当最后一丝音乐从最高的塔楼上飘下来的时候,他们俩各自没有睡意地躺在床上,幸福地重温着白天的一分一秒。他们已经决定尽快结婚。
译注:
14、上面一段最后一句话的正常解释是:那人身上十四个不同的地方被射中,但也可解释为那人在十四个不同的地点被射死;说者所述与听者所解不是一回事。
15、拉丁文:献给上帝、祖国和圣米达。
16、此处误解一说缘于在英语里 “吉丝敏”(Kismine)和 “吻我”(kiss me)是谐音。
八
华盛顿先生和两个年轻人每天去密林深处打猎或捕鱼,要不就在那催人入眠的球场上打高尔夫球。这种比赛,约翰出于外交礼节总是让主人赢。再不就是到山区特有的清凉湖水中去游泳。约翰发觉华盛顿先生有一种有些苛严的个性:除了他自己的观点,对任何想法都完全不感兴趣。华盛顿太太总是冷淡矜持、沉默寡言。她显然对两个女儿漠不关心,一门心思用在儿子珀西身上。她总是在用餐的时候用讲得很快的西班牙语同他说个没完没了。
大女儿佳丝敏与吉丝敏在外表上很相像,只除了有些弓形腿,手大脚大而已;但是气质上就完全不同了。她最喜爱的书必定要涉及穷女孩为鳏夫父亲管家。约翰从吉丝敏处获悉,佳丝敏一直没有从世界大战结束所引起的震撼和失望中恢复过来,当时她作为熟练的随军餐饮服务人员,正准备动身去欧洲。她甚至为此憔悴了一阵子,布雷多克 · 华盛顿曾采取步骤,要在巴尔干半岛发动一场新的战争──但是她看了一张几个塞尔维亚伤兵的照片,便对整个行动丧失了兴趣。而珀西和吉丝敏似乎从父亲那里遗传了那种自高自大的傲慢态度。一种纯粹而执着的自私,像固定程式似地贯穿着他们的每一个念头。
约翰对城堡和溪谷里的奇观着了魔。珀西是这样告诉他的:布雷多克 · 华盛顿设法绑架了一位园林设计师、一位建筑师、一位舞台布景设计师和上个世纪遗留下来的一位颓废派诗人。他把他的整个黑人大军派去供他们支配,保证将天底下出产的任何材料供应给他们,并且任由他们琢磨出一些自己的点子出来。但是他们一个接一个地显示出他们的无能。颓废派诗人立刻便开始为离别了春天的林荫大道而恸哭,他含糊其词地对香料、类人猿和象牙发了些议论,但是没有说出一句有任何实际价值的话。就舞台布景设计师而言,他想将整个溪谷搞成一套机巧的布局,形成一种激起强烈情感的效果──那种布景华盛顿一家很快就会感到厌倦。至于建筑师和园林设计师,他们只想着按规矩办事。他们得做什么像什么,造什么成什么。
但是他们至少解决了一个问题,那就是如何处理他们。第一天晚上他们单独在一个房间里,就一座喷泉的位置想达成共识,耗了整整一夜,第二天一大早全都发了疯,现在舒舒服服地关在康涅狄格州韦斯特波特一所精神病院里。
“但是,” 约翰好奇地问道:“是谁设计了你们所有这些奇妙的会客室、门厅、过道、浴室……?”
“嗯,” 珀西答道:“说来惭愧,是一个搞电影的家伙。他是我们发现的唯一一个习惯于摆弄数不清的金钱的人,虽说他把餐巾塞进衬衣领,并且不会读也不会写。”
八月将尽,约翰开始为很快就必须返校而惆怅。他和吉丝敏已经决定明年六月私奔。
“要是在这儿结婚就更好了,” 吉丝敏承认:“可是我根本不可能得到父亲的许可嫁给你,那是自然。退而求其次我宁愿私奔。如今富人在美国结婚真是可怕:他们得在报纸上发布告,说准备靠一点剩下来的货色结婚,这其中的意思不就是他们有许多老货珍珠和欧仁尼皇后 17 穿戴过的旧花边。”
“我知道,” 约翰热烈地表示同意:“我在辛力泽-墨菲家作客的时候,他们家的长女格温多琳嫁给了一个人,他父亲拥有半个西弗吉尼亚。她写信回家说,为了丈夫当银行职员的薪水,她正在进行一场多么激烈的斗争,然后她在结尾时说:‘感谢上帝,我总算还有四个侍女,这多少有一点儿帮助。’”
“荒唐,” 吉丝敏评论道:“想一想世界上的亿万人民,做工的人之类,他们只有两个侍女,却也在将就着过日子。”
八月底的一个下午,吉丝敏偶然的一番话,改变了整个局势的面目,将约翰投进了恐怖状态之中。
当时他们正在他们最喜爱的那片小树林里,在亲吻的间隙,约翰沉溺于某种罗曼谛克的不祥预感之中,幻想着它会给他们的关系增添一层辛酸。
“有时我在想,我们永远不会结婚,” 他忧伤地说:“你太富有、太华贵了。像你这样富的人不可能跟别的姑娘一样。我该在奥马哈 18 或苏城 19 娶个富裕的五金批发商的女儿,对她那五十万嫁妆心满意足。”
“我倒是曾经认识一个五金批发商的女儿,” 吉丝敏评论说:“我觉得你不会对她感到心满意足的。她是我姐姐的朋友。她来这儿作过客。”
“哦,那样说来,你们还有过其他客人?” 约翰惊讶地嚷道。
吉丝敏似乎后悔说了这话。
“哦,是的,” 她匆匆忙忙地说:“有过几个。”
“但你们不是──你父亲不是害怕他们在外面说么?”
“哦,在一定程度上,在一定程度上,” 她答道:“我们来说说其他高兴的事儿吧。”
但是约翰的好奇心上来了。
“其他高兴的事儿!” 他追问道:“那有什么不高兴的?她们不是好姑娘?”
令他极其惊讶的是,吉丝敏抽泣起来。
“不…… 麻…… 麻烦…… 就出在这…… 这儿。我变得对她们几个十…… 十分依恋。佳丝敏也是,但她不管三七二十一,还是不断邀…… 邀请她们。我真弄不懂。”
一片怀疑的暗影在约翰心中形成了。
“你的意思是她们说出去了,你父亲就把她们…… 撵走了?”
“比那更糟,” 她结结巴巴地嘟囔道:“父亲不喜欢碰运气──可佳丝敏还是不断写信要她们来,她们玩得那么快活!”
她被一阵突如其来的悲伤弄得受不住了。
这番泄露所包含的恐怖令约翰怔住了,他张大嘴巴坐在那儿,感觉到身体里的神经在颤鸣,像许多麻雀栖息在他的脊柱上。
“喏,我告诉你了,我不该告诉你的。” 她说,突然平静下来,擦干她那深蓝色的眼睛。
“你的意思是说,你父亲在她们离开之前谋杀了她们?”
她点点头。
“通常是在八月份,或者是九月初。我们首先尽可能从她们身上取得种种快乐,这对于我们只是一件很自然的事。”
“多么可恶!多么…… 嗨,我要发疯了!你是不是真地承认……”
“是的,” 吉丝敏打断他的话,耸了耸肩膀:“我们无法很妥当地将她们囚禁起来,像对待那些飞行员一样,这样的话她们就会变成对我们的一种不断谴责,每一天都是。对于佳丝敏和我,那样干总是会好受些,因为父亲干得比我们意料中的要快。那样一来,我们就避免了任何道别的场面……”
“所以你们就谋杀她们!哼!” 约翰嚷道。
“活儿干得很干净。她们在睡梦中被毒死,她们家里人得到的死讯总是说她们是在比尤特 20 得了猩红热。”
“但是…… 我想不通你们干嘛不断地邀请她们来!”
“我可没有,” 吉丝敏发作了:“我一个也没有邀请。佳丝敏干的。而且她们总是会度过一段很好的时光。接近最后的时候她给她们最好的礼物。将来我也可能请客人来──我也会硬起心肠那么干。我们不能让死亡这样一件不可避免的事阻挡我们享受生命,在我们拥有它的时候。想一想,在这世外之地,如果一个客人也没有,会是多么的寂寞。嗯,父亲和母亲也像我们一样牺牲过一些最好的朋友。”
“所以,” 约翰大声谴责道:“所以你们让我向你求爱,并假装以爱来回报,还谈什么婚嫁,却自始至终心里完全明白,我永远不会活着从这儿出去……”
“不,” 她激动地申辩道:“这一回不一样。是我开的头。当时你已经到了这儿。我忍不住开了那个头,而且我认为你的最后几天对于我们俩也许都是快乐的。可是接着我爱上了你,而且…… 而且对于你要…… 你要被解决掉,我实实在在很难过,虽说我宁愿你被解决掉,不愿你今后去吻另一个姑娘。”
“哦,你说你愿意,你真的愿意么?” 约翰凶狠地嚷道。
“愿意得很。另外,过去我一向听说,姑娘同男人相好,可又知道永远不会嫁给他,就会格外有趣味。啊,我告诉你干嘛呀?现在我大概已经将你的快乐时光彻底给败坏了。你不知道那回事的时候,我们真的很快活。我知道这一下把事情搞得让你有些沮丧了。”
“哦,你说你知道,你真的知道么?” 约翰愤怒得声音发抖:“这一套我已经听够了。如果你那一点儿尊严和体面只够同一个你知道比一具死尸好不了多少的家伙搞风流韵事,我是不想再与你有什么瓜葛的!”
“你不是一具死尸!” 她恐慌地申辩道:“你不是一具死尸!我不想让你说我吻了一具死尸!”
“我并没有说那种话!”
“你说了!你说我吻了一具死尸!”
他们的声音升上去了,但是一个突如其来的干扰使他们俩全都噤口无言了。脚步声正沿着小径朝他们的方向而来,不一会儿,玫瑰花丛分开来,露出了布雷多克 · 华盛顿。那一双安在他那张漂亮而没有表情的脸上的聪明眼睛,正窥视着他们。
“谁吻了一具死尸?” 他带着明显不赞成的神色追问道。
“没有谁,” 吉丝敏很快地回答:“我们只是在开玩笑。”
“你们两个在这儿干什么,倒是说说看?” 他生硬地追问道:“吉丝敏,你应该…… 应该是在同你姐姐一起读书或打高尔夫球。去读书!去打高尔夫球!我回来的时候别让我发现你在这儿!”
然后他向约翰点了点头,便沿着小径走开了。
“看到了么?” 吉丝敏生气地说,这时他已经听不到这边说的话了:“你把事情全搞砸了。我们再也不能见面啦。他不会让我见你。如果他认为我们在相爱,他就会把你给毒死。”
“我们没有,不再相爱啦!” 约翰恶狠狠地嚷道:“所以他在这件事上大可以放下心来。此外,你别自个儿骗自个儿,以为我会待在这儿。要是我非得在那些山中间啃出一条路来的话,不出六个小时,我就会在山那边,上了去东部的路。”
这时他们俩都已经站起身来,听了这番话,吉丝敏靠过去,用胳膊挽住他的胳膊。
“我也要走。”
“你一定是疯了……”
“我当然要走,” 她不耐烦地打断他的话。
“一万个肯定你不能走,你……”
“很好,” 她平静地说:“那我们去追上父亲,把事情跟他讲个透彻。”
约翰败下阵来,挤出一丝苦笑。
“很好,最亲爱的,” 他表示同意,话说得有气无力,不大能令人相信:“我们一起走。”
他对她的爱回来了,平静地栖息在他心上。她属于他,她将和他一起走,分担他的危险。他用胳膊搂住她,热烈地吻她。毕竟她是爱他的;事实上,她救了他。
他们一边讨论这件事,一边慢慢地走回城堡去。他们下了决断:既然布雷多克 · 华盛顿已经看见他们在一起,他们最好晚上就离开。然而,用晚餐的时候,约翰的嘴唇异乎寻常的干,忐忑不安之余,他将一大汤匙孔雀汤全部灌进了左肺。他只好让一个操持家务的男性下人扛进那间绿松石紫貂皮牌戏室,使劲儿地给他捶背。珀西认为这是个大笑话。
九
子夜过去之后很久,约翰的身体神经质地猝然一抽,他一下子坐直了身子,眼睛瞪着笼罩在房间里的睡意之轻纱。透过那些暗蓝的方块──原来是敞开着的窗户,他听到遥远的地方一个微弱的声音,它还没有对他那梦魇缭绕的记忆表明身份,便已经随风逝去。但接踵而至的那一阵清晰的声响却离得比较近,就在房间外面 ──是球型门柄转动的咔嗒声,还是脚步声或窃窃私语,他说不出。一个硬疙瘩在他胃穴里凝结起来,在他挣扎着竭尽全力谛听的那一小会儿,他全身都疼。接着,轻纱中的一层似乎消弭了,他看到一个巨大的影子站在门边,那只是淡淡地勾画和成形在黑暗上面的一个人影,与帷帘的褶皱难解难分地交织在一起,看上去变了形似的,像一块脏兮兮的玻璃上出现的一个映象。
或许是出于害怕,或许是下了决心,约翰猛然间做了一个动作,摁下了床边的按纽,片刻之后他便坐在了隔壁房间那个陷进地板之中的绿莹莹的浴池里,半池子凉水激醒了他,使他恢复了警觉。
他跳出来,湿漉漉的睡衣在他身后洒下了一大滩水。他向那扇海蓝宝石门跑去,他知道它通向外面二楼的象牙楼梯过渡平台。门无声无息地开了。绯红色的一盏孤灯燃亮在上方一个巨大的穹顶里,把雕花楼梯那气派华丽的弯道照出了一种绝顶的美。有一会儿约翰不知所措,汇聚在周围的静寂的华彩,吓得他魂不附体,仿佛要用光与影的巨大褶皱和轮廓,将这孤零零湿漉漉、在象牙平台上发抖的小小身影包裹起来。接着同时发生了两件事。他本人的起居室的门敞开了,猛然间冲进来三个赤身裸体的黑人;当约翰在失魂落魄的恐惧中摇摇晃晃地向楼梯跑去时,走廊另一边另一扇门滑回到墙壁里,约翰看见布雷多克 · 华盛顿站在灯光照亮的升降机里,穿一件毛皮外套,一双齐膝马靴,膝头以上露出耀眼的玫瑰色内衣。
三个黑人立刻停止向约翰的方向移动,向升降机里的人转过身去,静候待命。此前约翰从未见过他们,一个念头闪过他的脑海:他们一定是职业刽子手。只听得他咆哮着发出一道帝王般的命令:
“进来!你们三个全进来!快快快!”
于是,片刻之间,三个黑人冲进了那笼子,升降起机的门刚合上,那长方形的光便被遮没了,大厅里重又只剩下了约翰一个人。他无力地坍倒在象牙楼梯上。
显然发生了什么重大的事情。这件事至少暂时延缓了他本人的一场大难。是什么事?是黑人们起来暴动了?是飞行员们绷开了格栅的铁条?还是费希村的人瞎摸瞎撞穿过山冈,他们那郁郁寡欢的眼睛瞄上了这华丽的溪谷?约翰不知道。他听到呼呼呼一阵微弱的风声,升降机嗖嗖地又上去了,一会儿,又下来了。也许是珀西赶过去帮他的父亲吧,约翰醒悟到,这正是他与吉丝敏会合、策划立刻逃跑的好机会。他等待着,等到升降机没有声息几分钟之后;夜间的寒气透过湿透的睡衣抽打着他,令他微微发抖,他回到房间,迅速穿好衣服。然后他爬了长长的一段楼梯,拐入那条铺着俄国紫貂皮的走廊,径直向吉丝敏的套房走去。
她的起居室门敞开着,灯亮着。吉丝敏穿着安哥拉羊毛的和服式晨衣,正以谛听的姿势站在窗前。约翰悄没声息地走进去,她向他转过身来。
“啊,是你!” 她悄声说,穿过房间向他走来:“你听到了么?”
“我听到你父亲的奴隶在我的……”
“不,” 她兴奋地打断了他的话头:“是飞机!”
“飞机?也许就是飞机声弄醒了我。”
“至少有一打。没多一会儿我还看到一架迎着月亮飞过去。后面悬崖上的卫兵开了枪,就是枪声把父亲惊醒的。我们马上就要跟它们开打了。”
“它们是特地上这儿来的么?”
“是的,是那个逃脱了的意大利人……”
她话音未落,一连串尖利的炸裂声透过敞开的窗户砸了进来。吉丝敏发出轻轻的一声叫,用手指从梳妆台上的一个盒子里摸索出一枚硬币,向一盏电灯跑去。片刻之间,整个城堡便一片黑暗:她烧断了保险丝。
“快来!” 她向他喊道:“我们到屋顶花园去,到那儿去看!”
她顺手抓起一件披肩,拉着他的手,摸索着走出门去。去塔楼的升降机只有一步之遥,在她摁下那一个将他们射向高处的按纽时,他在黑暗中用胳膊搂住她,吻了她的嘴。风流韵事终于临到了约翰 · 昂格尔。一分钟之后,他们已经走出来,到了星光白颜色的平台上。天上,雾蒙蒙的月亮在烘托着它的一片片涡云间滑进滑出,月下,十几架黑翼飞机在不停地兜圈子飘翔。溪谷中,随处有火舌窜向它们,随后是尖利的爆裂声。吉丝敏高兴地拍起手来,这股子高兴劲儿一会儿就变成了沮丧,因为那些飞机按照事先约定的什么信号,开始投弹,整个溪谷变成了一幅活动画景,回荡着沉闷的轰响,辉映着耀眼的红光。
不久,攻击者的目标开始向高射机枪设置点集中,其中一门炮几乎是立刻便沦为巨大的一堆残渣,躺在玫瑰花坪上冒烟。
“吉丝敏,” 约翰央求道:“如果我告诉你这次进攻正好赶在谋杀我的前夕,你会很高兴的。要不是听到那卫兵在后面山口开枪的声音,现在我已经死翘翘了……”
“我听不见!” 吉丝敏喴道,目不转睛地看着眼前的情景:“你得说响一点!”
“我只是说,” 约翰吼道:“我们最好在他们开始轰炸城堡之前离开这儿!”
突然之间,黑人寓所区的整个柱廊断裂成几截,一股火焰从廊柱下面喷涌而出,大块不成形状的大理石碎片被投掷到远及湖边的地方。
“价值五万美元的奴隶玩完了,” 吉丝敏嚷道:“还是按战前价格呢。尊重产业的美国人太少啦。”
约翰重新作出努力逼迫她离开。飞机一分钟比一分钟瞄得更准确,只有两架高射机枪还在还击。很明显,在炮火包围之中,卫队已经支持不了多久了。
“快来!” 约翰嚷道,拉着吉丝敏的胳膊:“我们不走不行了。你意识到没有,如果那些飞行员发现了你,肯定会把你杀了?”
她勉强同意了。
“我们得叫醒佳丝敏!” 他们匆匆地向升降机走去时,她说道。然后,她又带着孩子气的快乐加上一句:“我们会成为穷人,是不是?就像书里的人一样。我会成为孤儿,彻底自由。自由和贫穷!多么有趣!” 她停下脚步,仰起嘴唇,快活地吻了他一下。
“这两样东西一块儿来是不可能的,” 约翰残忍地说:“人们早已发现这一点了。在两样当中选,我宁愿要自由。另外提醒一句,你最好把珠宝盒里的东西全倒进口袋。”
两分钟之后,两个姑娘在黑暗的走廊里与约翰会合,三个人下到了城堡的主层。他们最后一次穿过那些光彩照人、富丽堂皇的厅堂,在外面的平台上站了一会儿,望着燃烧着的黑人寓所和坠落在湖另一边的两架飞机冒着火光的残骸。一架高射机枪孤零零地还在噗噗噗地顽强射击,进攻者似乎有些胆怯,不敢再飞低一些,而是绕着它盘旋着,发射出一团团炸雷似的烟火,等待哪一发碰巧消灭掉那个埃塞俄比亚种的射手。
约翰和两姐妹沿大理石台阶而下,急转弯向左,开始登上一条像钻石山的吊袜带似的狭窄山径。吉丝敏认识半路上一处树木浓密的地点,在那儿他们可以藏身,也能够观察到溪谷中的狂乱夜景,最终如果需要的话,还可以沿着一道石沟里的一条秘密小径逃走。
译注:
17、欧仁尼皇后(1826-1920),拿破仑三世的皇后。
18、奥马哈,美国内布拉斯加州东部城市。
19、苏城,美国依阿华州西北部城市。
20、比尤特,位于美国西北部的一个山区。
十
他们到达目的地的时候已经是三点钟。热心而沉着的佳丝敏倦乏之下,靠在一颗大树的树干上立刻便睡着了。约翰则同佳丝敏坐着,用胳膊搂着她,守望着正在沉寂下去的这场战斗的潮涨潮落;它所发生的地点昨天早晨还是一片花园,现在望出去是一片废墟。四点钟过后不久,最后剩下的那架高射机枪发出哐啷一声响,迅速地吐出一条冒烟的红舌头,便不管用了。尽管月亮已经下山,他们依然看得见飞翔的机身正在盘旋着离地面越来越近。一旦那些飞机确认被围攻者已经再无还手之力,它们便会着陆,这黑暗而光辉灿烂的华盛顿王国便会结束。
战火停息,溪谷随之而沉寂。像匍匐着在草丛中的什么妖魔的两只眼睛一样,两架飞机的残骸闪闪发光。城堡黑幢幢地、无声地矗立在那里,无光时它也是美丽的,一如在阳光下它是美丽的一样;而上空充满了复仇女神那木头一样的嘎嘎声,伴随着涨涨落落的怨言。这时约翰发觉吉丝敏同她姐姐一样,已经酣然熟睡。
他注意到他们刚走过的路上有脚步声过来,已经是四点钟过去之后很久。他屏息静声地等待着,直到发出脚步声的那些人走过他占据的有利地点。这时空中有了一种并非来自人间的轻微动静,露水冰凉,他知道天光很快就会破晓。约翰一直等到上山的脚步声离开一段安全的距离,听不见了为止。然后他跟了上去。从不到陡峭山巔一半路的地方起,树木稀稀拉拉不见了,一架顽石构成的鞍形山脊展开来,盖住了下面的钻石。到达该地点之前他放慢了脚步,一种动物的感觉警告他,有活物就在前面不远的地方。他来到一块高高的巨大砾石旁,渐渐地将脑袋升上它的边沿。他的好奇心得到了回报;这就是他看到的情形:
布雷多克 · 华盛顿一动不动地站在那儿,灰色的天空衬出他的侧影,无声无息,没有一点生命的迹象。东方已经露出曙色,给大地添了一抹冷冽的绿色,将那孤寂的人影带进与新的一天所形成的无足轻重的对比之中。
约翰在这边望着,而他的东道主则在那边沉浸于令人捉摸不透的思绪之中;过了一会儿,他向匍匐在他脚边的两个黑人做了个手势,要他们把搁在中间的重物抬起来。当他们奋力站直身子的时候,太阳的第一道黄色光线穿透了一颗雕凿得近乎完美的巨大钻石的无数棱面,一片白光燃起,在空中光芒闪烁犹如晨星的一块碎片。抬着它的人在重压之下蹒跚着移动了片刻,这时,在湿漉漉闪光的皮肤下,他们那波浪般滚动的肌肉凝住了、变硬了,三个人重又一动不动,面对苍天桀骜不驯而又无可奈何。
过了一会儿,白人昂起头,缓缓地抬起手臂,仿佛要召唤一大群人倾听似地做出请注意的姿势:但是并没有人群,只有群山与天穹的浩瀚寂廖,被下方树林中微弱的鸟鸣声打破。站在鞍形岩石上的人影带着遏制不住的傲慢,开始干巴巴地发话。
“在外面的你……” 他声音颤抖地喊道:“在那边的…… 你!” 他停了下来,手臂依然举着,脑袋专注地昂在那里,仿佛在期待回答。约翰竭力睁大眼睛,想看看是否有人从山上面下来,但是山上面空寂寂没有一个活人。只有天空,和沿林梢而来带有嘲讽意味的风的笛声。难道华盛顿是在祈祷?约翰疑惑了一会儿。然后错觉消逝了:那人的整个态度中有什么东西与祈祷是对立的。
“啊,在上面的你!”
声音变得强劲和自信起来。这不是孤寂者的乞求。如果说有什么的话,其中有的是一种骇人听闻的屈尊性质。
“在那边的你……”
话说得太快,听不清楚,一句串一句滔滔不绝…… 约翰屏息静气地谛听着,偶尔抓住一句;而那声音中止、接续、又中止,时而强劲而雄辩,时而带有一种迟疑而困惑的焦躁色彩。接着,这唯一的一位听众开始醒悟过来,当那种认识渐渐地在他头脑中成形时,他全身的血液奔涌起来,迅速流遍每一条动脉。布雷多克 · 华盛顿是在向上帝行贿!
就是这么回事,毫无疑问。他的奴隶用胳膊抬着的钻石是先期预付的样品,是一个许诺:接下来还有更多。
过了一段时间,约翰领悟到,那就是贯穿他的语句的一条线索。发了财的普罗米修斯在大声地为被遗忘的牺牲、被遗忘的祭仪和基督降生之前便已废弃的祝祷仪式作证。有一会儿,他的讲道采取了另一种形式:他提醒上帝别忘了神明陛下曾经屈尊从人类那里接受过的这样那样的礼物──救城市于瘟疫之灾便会得到大教堂,人们献祭的没药和黄金,人命、美女和被俘的军队,儿童和妃子,森林里田野上的兽,绵羊和山羊,庄稼与城池,为得到他的姑息而以贪欲和鲜血的形式所献出的全部被征服的土地,为了换取缓解圣怒的酬报。现在,他,布雷多克 · 华盛顿,钻石之帝,黄金时代的王者和祭司,显赫与奢华的仲裁者,愿意献出一份他之前的王者做梦都想不到的宝藏,在骄傲而不是乞求中把它呈献出来。
他将话题落实到具体说明上,接着说道,他愿意献给上帝世界上最大的钻石。这颗钻石将切割出千千万万个琢面,比树上的叶片还多,而且整颗钻石成形后的完美程度堪与一颗苍蝇大小的石头媲美。将有许多人为此工作许多年。将给它安一个黄金打造的巨大穹顶,雕刻上精妙绝伦的图样,配上蓝宝石嵌蛋白石包面的大门。钻石中央将掏空成一座小教堂,其主导是一个用不断分解、永远变化的彩虹色的镭做成的祭坛。拜神者祈祷时只要抬起头来,眼睛就会被镭灼坏。在这祭坛之上,为供神圣的施恩者取乐,将宰杀他所选中的任何牺牲,即便是世间最伟大、最有权势的活人。
作为回报他只要求一件简单的事,一件对于上帝来说易如反掌的事:只要让事态如昨日此时,永远不变。就这样非常简单!只要让天国的门打开,把这些人和他们的飞机吞进去──然后再关上。让他重新拥有他的奴隶,让他们复活过来,跟没事一样。
从来不曾有其他人他需要与之探讨问题,讨价还价。
他只疑虑他所行的贿赂是否足够大。当然,上帝有上帝的价格。上帝是以人的形象造出来的,所以据人家说:他必须获得他的价格。而他付出的价格是绝无仅有的:没有一座耗时多年的大教堂,没有一座成千上万劳工建造的金字塔,能与这一座大教堂、这一座金字塔相提并论。
说到这儿他停顿了一下。这就是他的提议。一切都会按具体说明办,而且如果说价格太便宜,他的主张也并无不雅之处。他暗示,接受或放弃由济度众生者看着办。
接近结尾的时候,他的语句变得结结巴巴,变得短促和没有把握,他的身体似乎紧张起来,似乎绷紧了要捕捉周围空间里最轻微的生命的动静和声息。在他说话的过程中,他的头发渐渐地变白了,现在他向天空扬起了头,仿佛是古代的先知──疯狂之态极其庄严动人。
约翰看得晕晕乎乎,如痴如醉。接着,在他看来,周围什么地方产生了一种奇异的现象。似乎天暗了片刻,似乎突然一阵狂风刮来一丝絮语,一缕从远处传来的号角声,一声像一件巨大绸袍的窸窣声那样的叹息。一时间,周围的整个大自然也随之黯淡下来;鸟儿停止了歌唱,树木静默不语,从山那边遥远的地方隐约可闻地传来一阵沉闷、威吓的雷声。
一切就是这样。风沿着溪谷里高高的青草一路沉寂下来。一时间,曙光和白昼又重新就位,已经升起的太阳驱送着黄雾的热浪,在它前方开出一条明亮的路来。树叶在阳光中欢笑,它们的笑声摇动了树木,最后每根树枝仿佛都成了仙境中的女子学校。上帝拒绝接受贿赂。
约翰又观看了一会儿白昼的胜利。然后他转过身去,看见一翼棕色的物体颤摇着降落在湖畔,然后又是一翼,然后又是一翼,像从云端里下来的金色天使在跳舞。飞机着陆了。
约翰悄悄地离开砾石,沿着山坡跑下去,来到树丛中。两个姑娘已经醒了,正在等他。吉丝敏跳起来,口袋里的珠宝叮当乱响,张开的唇边悬着疑问。但是直觉告诉约翰,已经没有时间说话。他们必须离开这座山,一刻也不能耽误。他抓住两人各一只手,三个人静悄悄地在树干之间穿行着,沐浴在此刻的阳光中与上升的雾霭里。他们身后,溪谷里全无一点人声,只有孔雀在远处抱怨,早晨在悄没声地欢唱。
他们走出去大约半英里以后,避开花园地带,进入一条通往下一个小丘的狭窄小径。在这小丘的制高点,他们停下脚步环顾四周。他们的目光落在刚刚离开的那一片山坡上,一种即将发生悲剧的不祥预感压上了心头。
在蓝天的映衬下,一个颓丧的白发男子的清晰身影正走下陡坡,身后跟着两个没有情感的巨人般的黑人,他们抬着的那个重物,依然在阳光下闪烁着光焰和光辉。下山的半途,另外两个人影加入到他们的行列里。约翰能够辩认出那是华盛顿太太和她的儿子,她靠在他的臂膀上。飞行员们已经从机舱里出来,登上城堡前那片开阔的草坪,正手提来福枪,以战斗队形开始上钻石山。
但是,在上面汇聚成一小群、吸引了所有守望者全部注意力的那五个人,已经在一处岩脊上停了下来。两个黑人俯下身子,拉起了一道机关,看来那是山坡上一道活门。他们全体消失在其中,白发男子首先进去,跟着是他的妻子和儿子,最后是那两个黑人。阳光在他们的珠宝头饰上辉映了片刻,活门便落下来,把他们全吞没了。
吉丝敏一把抓住约翰的胳膊。
“啊,” 她狂乱地嚷道:“他们去哪儿?他们要干什么?”
“一定是什么地下逃生暗道……”
两个姑娘的一声轻轻的尖叫打断了他的话。
“看见没有?” 吉丝敏歇斯底里地呜咽道:“山上安着电线!”
她话音未落,约翰已经举起双手捂住眼睛。他们眼前的这座山整个表面突然变成了一片灼灼燃烧的炫目的黄色火光,它透过生长草皮的土层映现出来,就像光线映透人的手一样。这无法忍受的光焰持续了一会儿,然后,像一根燃尽的灯丝一样消失了,露出一片焦黑的不毛之地,青烟袅袅升起,带走了植物和人肉的余烬。那些飞行员既没有留下血迹,也没有留下尸骨:他们像走进山里面的五个人一样,灰飞烟灭了。
与此同时,随着一阵大而无当的剧烈震荡,城堡整个儿地把自己抛上了天。它上去的时候炸成了火光四射的碎片,然后跌落回原处,化作烟气腾腾的一堆玩艺儿,躺在那儿一半身子伸进了湖水。看不到火,在那儿冒着的烟什么的,也同阳光混在一起漂走了。几分钟之后,从曾经是金堆玉砌珠光宝宅的那一堆不成形的玩艺儿上,扬起了一阵尘埃般的大理石粉末。再也没有一点动静,只剩下孤零零的三个人在溪谷里。
十一
日落时分,约翰和他的两个同伴到达了原本是华盛顿家族领土边界的那座高高的悬崖。回首望去,发觉暮色中的溪谷静谧而可爱。他们坐下来,把吉丝敏随身携带的一篮子食物吃完。
“瞧!” 她说道,一边把桌布铺开,把三明治整整齐齐地放成一堆:“看上去不是挺诱人么?我一向认为在野外吃东西味道更好。”
“凭这样一句话,” 佳丝敏评论道:“吉丝敏进入中产阶级啦。”
“那么,” 约翰急切地说:“把你们的口袋翻过来,我们来看一看,你们带上的是些什么珠宝。如果你们挑得好,我们三个这一辈子就该过得很舒服啦。”
吉丝敏顺从地将手放进口袋,将满满两把闪闪发光的石头扔在他面前。
“还不错,” 约翰热情洋溢地嚷道:“个儿不是很大,不过…… 喂!” 他对着夕阳的余晖举起基中一颗时,脸色变了:“嗨,这些不是钻石!出问题啦!”
“呀!” 吉丝敏大叫,一脸惊讶的神色:“我真是个白痴!”
“嗨,这是莱因石!” 约翰嚷道。
“我知道了。” 她放声大笑:“我开错了一只抽屉。那原本是一个来看佳丝敏的姑娘衣服上的东西。我让她把这些给了我,换给她钻石。那时除了宝石,我还从来不曾见过别的东西呢。”
“你带来的就这些了?”
“恐怕是的。” 她爱怜地用手指拨弄着那些亮晶晶的东西:“我想我更喜欢这些东西。我有一点厌倦钻石了。”
“很好,” 约翰忧郁地说:“我们得在海德斯过日子了。你会跟那些不肯轻信的女人讲你开错了一只抽屉,活到老讲到老。很不幸,你父亲的银行存折同他一起灰飞烟灭了。”
“嗯,海德斯怎么啦?”
“如果我在这个年纪回家时带上一个妻子,我父亲完全有可能不会用一块烧红的炭跟我断绝关系,就像他们那一带所说的那样。”
佳丝敏发话了。
“我爱洗东西,“她平静地说:“我一向自己洗手帕。我会给人洗衣服养活你们俩。”
“海德斯人用洗衣妇么?” 吉丝敏天真地问。
“当然,” 约翰答道:“就跟别的地方一样。”
“我想…… 也许太热了,什么衣服也不用穿。”
约翰大笑。
“不妨试一试!” 他提议道:“你还没脱一半,他们就会把你撵出去。”
“父亲会去那儿么?” 她问。
约翰惊讶地向她转过身去。
“你父亲已经死了,” 他严肃地回答说:“他干嘛要去海德斯?你把它跟另外一个地方弄混了,那地方 21 很久以前就已经作废。”
用过晚餐之后,他们折好桌布,铺开毯子准备过夜。
“真像一场梦,” 吉丝敏叹了口气,凝望着满天星斗:“待在这儿,身边就一套衣服和一个一文不名的未婚夫,看起来多奇怪!
“在星星下面,” 她重复道:“以前我从没留意过星星。我一向认为他们是属于某个人的巨大钻石。可是它们现在令我害怕。它们让我觉得一切都是一场梦,我的全部青春。”
“它已经成了一场梦,” 约翰平静地说:“每个人的青春都是一场梦,一种化学的发疯形式。”
“那么疯狂该是一件多么快乐的事!”
“人家也是这样对我说的,” 约翰忧郁地说:“我所知道的仅限于此了。不管怎么说,让我们相爱一阵子吧,爱上一两年,你和我。那是一种神圣的醉酒形式,人人都可以试一试。整个爱的世界里只有钻石,钻石,还有也许是幻灭所馈赠的破烂。嗯,我终于拥有了它,对于平常的那一种,我会根本不当一回事儿。” 他哆嗦了一下:“把你的外套领子翻上来,小姑娘,夜间寒气袭人,可别得上肺炎。谁第一个发明了知觉,可真是个大罪人。让我们失去它几个小时吧。”
于是他把自己裹在毯子里,坠入了梦乡。(1922)
译注:
21、指古希腊神话中的冥府(Hades),它与海德斯(Hades)这个地名同音同名。
```
!一日囚-[[柳文扬]]
-----
B先生死了。就在他搬进这座大楼不到二十四小时。
B先生是昨夜,不,准确地说是今天凌晨0点住进来的。那时夜雾弥漫,有两个黑衣男子陪着他,拎着三只大提箱,敲开我值班的房门,要租一间不带家具的房子。这个要求有点奇怪,因为大多数人都想要有家具的房间。
“请问你们要租多大的屋子?”我打量着B的光头问。他戴着眼镜,苍白而又腼腆,脸上有种愁苦的模样。
一个黑衣男人说:“最小的单元就可以了。一间卧室,带厨房和洗手间。”
“请原谅,三个人住这么小的房子是不是太挤了……”我说。
黑衣人面无表情,指了指B:“就他自己住。”
“好吧,您想租多久?半年还是一年?”我问B。
B先生低声说:“一天……”
“什么?”我没听清楚。
黑衣人说:“租一个月吧。这是你们最短的租期?”
“对。”我拿出登记簿,让B写下自己的名字。黑衣人付了一个月租金,然后我带他们上电梯,到了大楼16层的那个小套间。
B先生对客厅表示满意,但他抱怨房子的视野太狭窄了。黑衣男人们冷淡地沉默着,把大箱子打开。里面竟装满了简易家具——折叠的帆布衣柜、充气床垫,还有一些换洗衣服。最后,B安顿下来,一个黑衣人看了看表,说:“8月18日了,现在是凌晨0点整。”
两个黑衣人走了。我对B说:“早点休息吧,希望您在这里住得愉快。”
他点头说:“是啊,愉快……我不会打扰你们太久的。”
“您说什么?”
一瞬间,他眼睛里流露出虚弱和渴望,好像要说什么。我被吓住了。但他马上恢复了常态,也就是说,恢复了那种腼腆和愁苦的模样。
“麻烦你了。请让我休息吧。”他客气地把我送出门外。
这就是我记忆中的昨夜。
仅隔二十几个小时,B就死在房间里。他死后形容枯槁,看上去老了很多。
那两个黑衣人穿过夜雾走进大楼,还带了一位医生模样的人。我现在还不懂,他们是如何预知B先生的死讯的。当他们要我打开那间屋子的门,发现B毫无生气地躺在客厅地下时,他们一点也不惊讶。医生走过去,翻开B的眼皮,然后摸摸他的脖子,转身对两个黑衣人点了点头。
“他死了。”
他们想抬起B先生的尸体,我拦在门口说:“等一下,我应该去报警。还有,我都没有发现他已经死了,你们是怎么知道的呢?”
一个黑衣人走过来,低沉地说:“不必报警。”他拿出一份证件给我看,那是种让人无法怀疑其权威性的身份证明。我沉默了。
他们在房间里翻来翻去,把所有简易家具拆开,每一件衣服都抖开来看——我发现那些衣服都很旧,而且都是一模一样的套装。B在这儿住了还不满一天,难道能在房子里藏什么东西吗?最后,他们将屋中的一切装进大提箱,抬起B,消失在门外。只剩我一个人站在四壁皆白、空空如也的房间里。
对这个死去的人,我有种奇怪的感觉。我认识他只有二十几个钟头,但却像是多年的老友似的。细究原因,大概是他每次见我都表现出老友一般的熟络。
B先生真的有些古怪。他的精力一定非常旺盛,单看外表会被欺骗的,他苍白憔悴,仿佛弱不禁风,但是他整整一天频繁地出入于大楼内外,仅仅被我看见的就有十几次。他好像可以突然间出现在这里,又突然间出现在那里。
自从午夜安排好房间,我第一次看见B先生竟是在半分钟后。谁知道他是怎么样飞快地、神不知鬼不觉地下了楼,无声地站在我旁边。
我目瞪口呆地盯着他。他眼睛红红的,仿佛换了一个人,急切地问我:“现在怎么样?”
“什么怎么样?”我莫名其妙地说。
“现在是几点?几号了?”他梦游一样问。
我几乎被他吓住,很快地回答:“8月18日凌晨……0点过1分。您是什么时候下来的?”
他没有理睬我的问题,呆了呆,说:“哦,是这样……谢谢你。”
他回去睡了。但早上3点钟,我竟透过窗子看见他在楼外。他佝偻着身子,从雾气里慢慢地移动过来,苍白的脸像一盏昏灯。我赶忙出去,打开玻璃大门。他疲倦地走进来。
“您才安顿下来,不好好睡一觉吗?”我说,“是什么时候出去的?”
“什么?”他愣了一下,然后说,“哦,我不累。我出去的时候,你没看到?”
我迟疑地说:“可是,楼门一直是锁着的啊……”难道他是从十六层的窗户中爬下来的吗?
“是么?”他微笑,“你记错了吧。我是从这里出去的。”
他的背影蹒跚着走进电梯,我锁好楼门,回到值班室里打盹。
早晨七点半,他经过前厅,对我说:“早上好!”
“早上好!”我很惊讶,他只睡了这么一会儿,居然有精神出去散步。
奇怪的是,只过了几秒钟——至少在我的印象里,只过了很短暂的时间——又看到他经过前厅向楼门外走去。他冲我打招呼,就像刚才没见过面似的:“早上好!”
我诧异地望着他,他走出了楼门。
大约一个小时后,他乘着一辆出租车停在楼外,慢慢从车上挪出来,疲惫不堪地走进大楼,也不理睬我,直接上了电梯。
B先生怎么了?他在外面这一个小时做了什么?我想得走了神,却又看到他微笑着从我面前经过,道了一声:“辛苦!”就去按电梯的按钮。
我捧住头,使劲闭上眼睛又睁开。我疯了吗?我的大脑提前老化了吗?我在做梦吗?
我在前台上趴了一会儿,想养养精神。一抬头,就看到B愁苦地在大厅里走动着。我下意识地弹了起来!他对我羞涩而凄凉地笑笑:“我丢了件东西……”他茫然地说,“一定要找到,一定要找到……”
“您丢了什么?”我问他。
他摇摇头,走出了楼门。
我跟着他走到门外,身后有只手拍了拍我的肩,真是差一点叫我跳起来!
原来是住在1608号的那位老寡妇,她非常神经质,而且,说起来她还是B先生的隔壁邻居。
“他叫什么?”她伸出一根瘦得像巫婆的手指头,远远指着B先生的背影。
“B。怎么啦?”我问。
老太太低声说:“他很怪!”
这我知道,但怎么跟她说呢?
她看见B消失在拐角,把嘴凑在我耳边说:“刚才我听见他的房子里有人在哭!”
“哭?”我觉得她太敏感了。
“没错!我趴在门上听到了!”她忽然转向里面,脸上皱起惊恐的纹路。
B先生又从里面走出来了。
我也百思不解,但是客气地问了一句:“您丢的东西找到了吗?”
“什么?”他抬起头来,惊疑地望着我,“什么东西?”
真是莫名其妙。
他走出楼门。老太太拉着我跟出去,停在阳光下面,悄悄地说:“一个妖怪!”
B在远处上了出租车。我转过身,想着老太太的话,无意地向上一瞥。
我看见十六楼上,B先生房间的窗内有个人影。我退远几步,用手遮住阳光重新分辨。没错,是他的房间。那个清瘦而衰颓的人影移到了窗帘后面。我吓出一身冷汗。
“你看见了?你看见了?”老太太激动地念着。
我扯着老太太,在她的心脏和腿脚允许的情况下尽快跑到管理室,拿上电棍,乘电梯上了十六层,在B的门口站住。我们紧张地倾听着。
“B先生!您在里面吗?”我轻轻敲门。没有人回答。
老太太尖利的手指掐得我生疼。我拿出备用钥匙打开了门,必须搞清楚。我手握电棍,走进宁静狭小的房间。
里面空荡荡的。
老太太干瘪的嘴唇哆嗦着。“他是个妖怪,他是幽灵……”她惊惶地转动脑袋四处张望,好像这间屋子里真的有什么看不见的幽灵。
“我们快离开吧!”她使劲拉我的衣服。我也害怕了。
就是这样。我确实在今天一天里看到B先生十几次出入于楼门内外。而且,他的容貌像雾中的猫头鹰一般不可捉摸,一会儿苍老,一会儿又变得比较年轻。他的衣服也时新时旧。这个世界上是没有幽灵的,但我拿不准B先生是什么。
快到中午的时候,他拿着一副纸牌走到前厅,要跟我玩一会儿。
我无法拒绝,他明显的苍老了,真奇怪。而且他眼睛下面有暗淡的黑晕,目光仿佛是发高烧的病人。
他向我展露出令人惊叹的牌技,就算我把牌洗得再彻底,他还是能记住每一张牌的位置。我更加相信他是个隐藏在现代城市里的巫师。
最后,他把牌丢在台子上,说:“这一点也不神秘,我不是什么魔法师。年轻人,去买一副偏光眼镜吧。这牌留给你。有些时候你会发现,一件不可思议的事情,换一副眼镜就能看得清清楚楚。”
我真的托人去眼镜店帮我买了副便宜的偏光镜,戴上它再看那副纸牌,原来每一张的背面都用特殊墨水做着标记。
这是B先生教我的一件最有趣的事,也许他另有用意,但我没有猜破。
吃过午饭,我发现他站在楼门口,呆望着对面的路灯。
“天气很好。”我小心地跟他打招呼。
“是啊,天气每次都是这样。我倒希望某一次看见下雨。”他更像是在喃喃自语,然后他奇怪地说,“你瞧那盏路灯,”
“路灯?”
“对,它一直在那儿吗?”
我仔细看了看路灯,又看看他:“当然,它早就在那儿,一直在。”
“它……没有……没有被打破过?”他耳语似地问我,仿佛心怀恐惧。
“没有吧。”我摇摇头。这是拿不准的,附近的顽童很多,而我来这儿当管理员才两个月。
他问出一个令我浑身发冷的问题:“你没看见过路灯碎片从地面上飞起来,自动地重新组合好吗?”
阳光灿烂,他的脸还是那么苍白。我的心像被看不见的冰冷的手狠狠捏住了。他看出我在害怕,就笑一笑进去了。
老实说,才认识一天就能让我这样害怕的人,B先生算头一个。
我不敢再主动招呼他。下午我又看见他进进出出,来来去去。有时也跟我说话。但没有特别奇怪的事情发生。
夜里,他就死了。
两个黑衣人把B的尸体和屋子里所有东西都搬走以后,我站在他的卧室里茫然四顾,雪白的墙壁,一尘不染的地板。黑衣人想在房间中搜寻什么?B先生难道真的在这里藏了东西吗?回忆着B的种种诡异之处,我感觉这房间把我的心牢牢吸引住了。这里留着他的灵魂,我荒唐地对自己说。
突然,在灵机一动之下,我从衣袋里取出那副偏光眼镜。戴上它后,我惊呆了。
老天哪,墙壁上写满了字。
毫无疑问,这是B先生特意写给我的,他成功地瞒过了那两个黑衣人。我把门从里面锁好,回到卧室激动地读着墙上的字。这儿写着一个最让人毛骨悚然的故事:
我写下这些,是因为我预感到自己就要死了。我一直渴望对人说出自己的遭遇,但我不敢。现在,我用这种方法告诉你,世界不像你想的那么简单。
在墙上写字是因为:1,他们在最后会把所有能移动的东西都拿走,留下的只有墙壁;2,用这么原始、简单和不可靠的办法才能骗过他们。你很聪明,理解了我对你所做的暗示。
我死后没人能看到我的坟墓,让我来悼念自己吧:B,65岁,死于长久的孤独和生命力枯竭。他是个罪人,然而又是个可怜的牺牲者。我在这个地方,在这一刻,被囚禁了十年。
十年。
噩梦是这样开始的,由于人类共同的弱点,我犯了罪,大罪。在我的世界里,在你还没有见到、无法想象的世界里,我得知自己将接受什么样的惩罚。
法官说:“你被处以一日无期徒刑:在有生之年,你将永远过着同一天—我们为你随机选择的那一天,2008年8月18日,你的一切生命活动都只限于这二十四小时之内,直到自然赋予你的生命结束。作为一种人道主义的优待,你可以在一座热闹的都市中服刑,但在服刑期间,你不能对周围的任何人提起关于你和你所受的刑罚,否则,我们将把你转移到一个封闭的小空间内,在孤独中度过刑期。”
你理解吗?朋友,这是无止境的噩梦。
据说我是第一批被处以时间囚禁的罪人之一。他们还不能了解这一技术的全部内涵,我们算是实验品。
一开始,我对这刑罚的可怕之处还没有真正的体会。这是座热闹繁华的城市,处处充满生机。我住进自己的房间,对置身于开放的大世界里感到高兴,我透过玻璃窗观察下面的人群,不准备担忧以后的日子。
第一天——我这样说是按照自己的习惯,其实我度过的这十年,这三千六百多个日子,对你们来说都是同一天。第一天,我早早地起了床,打算出去散步,呼吸一下这座都市的空气。我的邻居,1608号的那位太太——她真是个细心人——热情地问候我。
“您好!您是新搬来的邻居吗?”
我答道:“是的。很高兴认识您。”
“您从哪里来?”
我把早已编好的谎言对她说了一番。她最后说:“希望您在这儿住得愉快!”
在楼下我对你打了个招呼:“早上好!”你对我报以关心。
走到大街上,我在拐角处的报童手里买了一份报纸,先看了看日期:2008年8月18日,头版的新闻很吸引人。我过马路,在对面的咖啡馆里要了早餐,巴西咖啡和烤面包。我看报纸,咖啡馆老板对我说:“我觉得您很面生。”
“对,我是刚刚搬来的。”我回答。
“喜欢我们这里么?”
“很好,大家都很友善,咖啡很香。”我向他微笑。
接下来我去公园散步,看场电影,吃午饭,在市政广场坐着喂鸽子,逗弄躺在婴儿车里的小孩。
吃过晚饭后,在街道上漫步,直到疲倦才回家。我躺在床上睡觉,一觉醒来,仍然是2008年8月18日。
第二天(还是按照我的习惯说的),我在同一时刻出门。1608号的太太站在楼道里问:“您好!您是新搬来的邻居吗?”
我答道:“是的。很高兴认识您。”
“您从哪里来?”
这真有趣,我又一字不差地说了那番话。她最后说:“希望您在这儿住得愉快!”
我又在下面问候了你,在街拐角买了同一份报纸:2008年8月18日的日报,头版的新闻对我来说早已是往事。我过马路,在对面的咖啡馆里要了早餐,还是巴西咖啡和烤面包。我看报纸,咖啡馆老板对我说:“我觉得您很面生。”
这一切都像钟摆一样准确。
我说出了跟昨天一模一样的回答。我感到自己好像一个无意间走进一部老电影里的客串者,我知道电影里发生的一切,但其他角色却对此一无所知。
公园、电影、午饭、鸽子、婴儿车里的小孩……一模一样的场景,一模一样的事,唯一不同的只有我。不,唯一不同的只有我的心。我很清楚,这个日子我已经是第二次度过。这感觉真怪,2008年8月18日,这一天是否像录像带一样永远保存在某处,保存在宇宙的一个神秘角落?而我则被施了咒语,一次次地进入这盘录像带,带着了解一切的心,却被迫重复着一成不变的情节……
在开始的几天里,我并不沮丧,也没有害怕。甚至还抱着一种优越感和好奇的兴趣,观察这发疯的世界。我按照固定的时间表过日子,我记熟了在每个时刻、每个地点将遇到的人,以及他们将做的事情。我背诵着自己的台词,还在心里替对方念出他想说的话,我暗自对他说:“嘿,我知道你下一分钟要做什么。”
但我很快厌倦了。如果你觉得生活中的某个日子是快乐的、丰富多彩的,那只因为它是唯一的,是转瞬即逝的。永不逝去的一天是可怕的一天,它会由新鲜变为陈旧,变为腐烂,变为恶毒。
我默默地服刑。第一个星期,我快乐;第二个星期,我累了;第三个星期,我愤怒;第四个星期,我想到死;第五个星期,我知道自己将会发疯。
真不可思议,在同一个人身上,在同一天,竟可以承载这么多的眼泪、愤怒、挣扎、绝望和疯狂。我躲在房间里痛哭,用力咬着自己的手。时间囚禁之刑,无法打破、不能逃脱的监牢。
有一种魔力笼罩着我,每当一个二十四小时的周期即将过去,我似乎要追随着时间之流,冲破牢笼;那魔力一下子又把我拉回二十四小时之前。于是一切周而复始。我又开始见到昨天见到的人,重复昨天做过的事。最可怕的是,只有我清楚这一切,其他人对此一无所知。我多羡慕他们,多嫉妒他们!对他们来说,我被永世困在其中的这一天只是生命中的千万个平凡日子之一。他们将无知无识地度过这普通的一天,然后把它忘记,走进我永远也看不到的“明天”。可我呢,我还要在循环往复的苦刑中挣扎下去,得不到一点同情和援助……
而且,要知道,除了我自己之外,其余的一切人、一切事,都是固定不变的,在每一次循环当中比原子钟还更稳定。所以,我必须注意每一件事的准确时刻,以免与这个世界脱节。我有一个固定的时刻表,精确到秒。在这钟表般的世界里我是唯一可变的因素,但我却要强迫自己成为钟表里的一个零件。我是罪有应得,但我要告诉你,这种刑罚过于残酷了,即便是对我这样的罪人。
时间的囚徒,比空间的囚徒更可悲。全世界都与你无关,只有你独自在不变的时光中老去,日复一日地重复着比死亡还苍白的生活。
时间是多么可怕、伟大和不可驾驭的东西。我是想说,当猴子学会了一种把戏,它只能想到凭借这把戏来换一点食物。人,只有人,才会把他所掌握的一切权力和知识都用于“惩罚”。
在无数次孤独的发作之后我决定破坏规则,看一看能给世界造成多大的麻烦。我扔掉了时刻表,故意在头一天的早上七点三十分整出门,而在第二天早上的七点三十分十五秒出门。我在比平时晚半分钟的时间进入咖啡馆,要热面包卷和冰咖啡。在下一个循环中,再晚半分钟进去,要蛋糕、柠檬冻和香草冰淇淋。我选择不同的时刻——但相差不超过一分钟——从报童手里买报纸。我在每个循环中换着看不同的电影。我这次踩死一只蜗牛,下次却把它从地上捡起来放进草丛里。出于一种可笑的仓惶失措,为了逃离牢笼般的感觉,我曾经到处乱跑,跑到城市的边缘,再乘坐出租车回来。
我在郊外过夜,仿佛希望这能帮助自己奇迹般地逃离被困于今天的命运。我蜷缩在草丛中,看着星星。时间一秒一秒地流逝,每一秒钟都在心中撞击出宏大的回响。午夜十二点,我激动地坐起来,在星空下奔跑。我狂喊着:“出租车!出租车!”我上车就问司机:“现在是几点?今天是几号?”
“0点十分啦。您喝得够多的,今天是8月18日。”司机说。我的心沉了下去。汽车穿过入睡的城市,停在被夜雾笼罩的大楼前,已是凌晨三点,我还要回到那间小屋,回到监牢中的监牢里睡觉。
我的歇斯底里症发作了不止一次。我幻想着,在某个特殊的时刻“再次”进入大楼,就能打破魔法。我从郊外回来,在午夜十二点整走进楼门,问你:“几点了?今天是几号?”
小伙子,记得吗?你说:“十二点啦,您住进这儿快有一整天了。今天当然是8月18号。”就是这个时刻,魔法的转折点,我要在你的见证之下突破了……我激动万分,盯住你,在那里站了一会儿,又问你:“现在怎么样?”
“什么怎么样?”仅隔几秒钟,你就像完全忘了刚才的事。我有种不祥的感觉,我说:“现在是几点?几号了?”
你惊讶地回答:“8月18日凌晨……0点过1分。您是什么时候下来的?”
你知道当时我是多么绝望吗?
我还有过更疯狂的主意:我想带着几个人走得远远的,走到郊外去。晚上,我们围坐在篝火旁,我要在午夜时分讲一个故事。当时钟越过12点、又回到二十四小时前的瞬间,我会看到什么情形?那几个人会像幻影一样消失吗?他们又会看到什么?他们会发现自己忽然从家里的卧室中来到了野外吗?
我不敢做那样的实验,风险太大了,可能会伤害别人。我只能用自己作实验品,给世界找一点小小的麻烦。
世界没有垮掉,无论我怎么躁动,都像笼中困兽的挣扎一样无济于事。只有寥寥几次,我从你和别人的目光中看出了诧异与恐惧。你们发现了吗?我不清楚。
本来我有种可怕的猜疑:这刑罚只是一种心理层面的感受,只有我的“灵魂”(我只能这么说)被硬生生地剥离出来,拉回一次次循环的开始,而肉体则像行尸走肉一样,僵硬地重复着比钟摆还准确的固定行为。也许为了打消这种恐惧,我才故意在每天的行动中做了一点变化。没有遇到阻碍,而且,我慢慢地发现自己的身体在衰老,我放心了。
如果你的外部行动被限制在一个小范围内,那么你会发现,心灵的活动将变得十倍百倍地丰富和激烈。我不是科学爱好者,但现在却对时间这个东西产生了兴趣。我很想知道自己是用什么方式被一次次拉回8月18日的凌晨0点。我还想知道,时间是什么,被困在时间中的人又如何与世界发生关系。
后来的日子里,我一直在观察和思索。这样反而不太难过。我列出了几种被抛入时间循环的方式。
第一种,像那些物理学家所说的,每当我被“拉回”一次,时间就在这里产生了一个分枝,出现了一个新的“平行世界”,在这个新世界里,除了我本人,其余的一切都与原来的世界相同。但是,我有证据否定这种理论:这个新世界中的人将不会知道原来那个世界在8月18日发生的事,可有一次,你突然问我:“您丢的东西找到了吗?”我大惑不解。想来这是因为在后面的某次循环当中,我将丢失一样东西,而时刻却在此时之前。后来证实了这个猜测,我的钱夹丢失了,时刻是上午九点。
还有一种最简单的解释:8月18日这一天是固定不变的,只有我一次次地回到这天当中,重复我的生活。但这会造成一个难点,我反复地度过这二十四小时,度过了三千六百五十次。我一个人在此期间所耗费的物质,比如水和电,会超过整个大楼中其他居民用量的总合。难道没人发现这桩怪事么?
有一次,我一言不发地走到大楼对面的路灯底下,脱下鞋子,用它打碎了路灯。然后我穿好鞋走回大厅里。当时你惊讶极了,你一定认为我发疯了。不,我在思考问题。
在路灯被打破后的整整一天里,我记住了每个人看着我的神情、对我所说的话。次日(我习惯的说法),我一早就发现路灯好好地立在那里,当然啦,我还没有去打它呢。这一天真的与前一个循环大不相同。
我的存在使世界变得充满悖论。我在这次循环当中,在上午九点打碎了街上一盏路灯,那么在别人即旁观者眼里,这盏路灯在九点之后就应该不存在了;但在此次循环之前的那些天里,路灯一直存在到一天的结束。旁观者究竟会“记得”那一种情况呢?
记得我问过你,在一个中午。你完全不知道我打碎过路灯。
我的最后一个猜测是:每当一个循环结束,我就仿佛被单独拉出这个世界,而那神秘的魔力,即操纵时间的力量,使整个世界(除我之外)退回到二十四小时之前的初始状态,然后我又被扔进世界里面,一切重新开始。那就是说,无论我在服刑期间做了什么,把路灯打碎多少次,旁观者都只会“记得”最后一次循环。
不知我猜的对不对,多想向某个旁观者询问一下啊。
但丢掉钱夹的事,还有你看到我不按时刻表行动时的诧异,又如何解释呢?
大概,在旁观者眼中,我在若干次循环中的行为,像立体空间的物体在平面上的投影一样,被叠加于一天里面,于是形成了这么一种情况:你看着我走出大楼,然后又看见一个我走出大楼,而紧接着,你可能发现我的房间里仍有一个我。我所处的微观时间循环被嵌套在整个宏观的时间之内,于是在外人看来就有了一种粒子态一般测不准的“闪动”。
如果有一位超然的观察者俯视这座城市,他会发现我就像一个做布朗运动的粒子那样,狂乱而无序地出现在各个角落。这一秒钟在东边,下一秒钟又到了西边,甚至在同一秒钟里出现在几个地方。普通人如果留意我的行踪,一定会被这奇怪的现象搞疯的。
我很遗憾在将要死去的时候才发现了思考的乐趣。我相信,那些孤守在灯塔上的人不会疯狂,因为他们是思想者。
但唯一不公平的是,他们的每一天都是不同的。
我要死了,我仍然没有明白时间是什么,被困于时间中的人又怎样与世界发生联系……再见了,朋友,你将幸福地进入明天,把今天的我永远忘记。而那个明天是我绝对无法想象的。再见。
我摘下眼镜,墙壁又变得洁白无瑕。这一切真的发生过吗?我又戴上眼镜,B先生写下的字迹布满了整面墙。
应该把这些字涂抹掉。谁知道以后的住户会不会戴起偏光眼镜来看这墙壁呢?B先生此时已经死了,但在此时之前,在2008年8月18日凌晨0点到夜里10点,他依然活着,永远活着,一次一次地活着。他的秘密仍然不能泄露。
我看了看手表,已经是11点半了。
我忽然激动起来。
B先生是今天0点住进来的,他的死亡时间是今夜10点,而现在是11点半,距离一个循环结束还有半小时!他在墙上写着,他曾在午夜12点从郊外回来,希望由我见证他突破时间的牢笼。我有办法验证他的猜想了。
“一个”B先生已经死了。如果在12点,“另一个”B先生从外面回来,那就至少能证明他的一部分猜想。可那种情况会多么诡异、恐怖和激动人心啊。
如果是那样,如果“另一个”回来了,我应该对他说什么?B先生,您已经死了,现在的您是无数镜子里的鬼魂之一?我能不能这样认为:当我们这些幸福的人无知无识地越过了今天午夜,进入B先生无法求得也无法想象的明天;在被我们超越、抛弃和遗忘的这一天里,还有一个、两个、无数个B,无可奈何,循环往复地永远被困于此。我对这些道理一点都不懂,也想不明白。
我怀着莫大的期望和恐惧,坐在大楼门口的管理员室内,望着窗外的夜世界。
我头一次注意到时间是这么奇妙,每一秒钟都仿佛在我心中跳跃着流过。流逝,流逝,流逝……在某一次循环当中,B先生此时此刻还坐在由郊外赶回来的出租车上。我心乱如麻,等待他穿过夜晚的浓雾,苍白的脸像一盏灯一样往大楼里走来;等待他从时间的某个角落佝偻着走来;等待他迷茫绝望地一边寻找一边走来。从未知走进未知,从无限走进无限,从幽暗走进幽暗,从牢笼走进牢笼。我要紧紧拉着他的手,不,我要紧紧地抱住他,跟他一起度过由今天到明天的那一秒钟。如果这样,我能够把他带进明天吗?或者是他把我拉进那循环的魔咒当中?天哪,我在想些什么?
12点钟就要到了,我的心跳几乎停止。
窗外,夜雾茫茫。
一只名叫Snowy的狗- 周晓枫
========================
一只名叫Snowy的狗- [[周晓枫]]
-----
九岁的侄女玥玥回国度假,在旅游景区遇到携带小狗的一家人。满月不久的狗,体积小巧,相当于一团膨起的棉花糖,走路歪歪扭扭,更多时候乖顺地蜷缩在随便什么人的臂弯里。这家小姑娘上初中,父母正因收养宠物会耽误女儿学习而忧心忡忡——见到玥玥喜欢,就顺水推舟,当场赠送。它迷迷糊糊地,从一双手传递到另一双手,不明白自己正被一次邂逅改变命运。为了尽快把小狗带回加拿大,玥玥一家需要办理各种手续;远渡重洋之前,它暂时寄养在我这里。
它看起来全身雪白,两只软耳朵耷在面颊两侧。什么品种呢?以为它是拉布拉多。它的名字由中文的小白,将改为移民后的Snowy——起名的基础,都是强调它的纯洁无瑕。在幼年的混沌期,这只小母狗的确以娇小体态和纯洁毛色成功伪装了自己的身份。名字虽源自白雪公主,可它出身远非王族的高贵。后来证明,这只小狗来自模糊而卑微的血缘……它只是在恰当的时间和地点,进行了恰当的隐藏。
在精心养育的数周里,Snowy带给我奇怪的迷惑。它的表情时而妩媚时而凶悍,时而幼萌时而沧桑。端详它,我经常不知道,这只狗到底长得好看不好看,因为Snowy的脸,像一个狗家族变幻着重叠的影像。
迷惑持续,及至成年,它保持着魔法般的成长性。星期一的Snowy和星期四的Snowy是不同的,清晨的Snowy和黄昏的Snowy是不同的,乞食的Snowy和孤傲入睡的Snowy是不同的,我所看到的Snowy和它内心自我判断的Snowy是不同的……因为我听到过Snowy的叹气,我就相信Snowy的祈祷。Snowy,Snowy,一只智商有限的狗让我为自己的记忆而频繁羞愧,因为我记不住它的准确性,记不住它作为具象的个体。此Snowy非彼Snowy,它像字典上“狗”这个字,很难选择一种确凿无疑的形象作为无可争议的绝对代表。身置哈哈镜迷宫里的Snowy,这是它的游戏还是它的恶意?或许,由于对自我没有坚定的认知,Snowy对这个世界坦白了它的混血中所暗示的混乱?
但是Snowy很小就流露出它讨好的生存技巧,也许这是本能,而非心机。尽管它年纪尚幼管理不好自己的排泄系统,尽管它任性地撕咬床罩和窗帘,尽管它挑食,有自己的脾气,尽管它突然希望独处,缺乏小狗对主人几乎是必然的亲昵。可每当我用钥匙转动回家的门,孤独睡眠了几个小时的它就猛然警醒,热烈地扑过来,上演它繁乱而漫长的欢迎仪式……它每每兴奋得失禁,地板上是滴落的尿液。我虽有轻微嫌厌,但Snowy那种鲁莽且难堪的表情和激情,还是让人心生怜惜。我总是一边收拾狼藉的现场,一边把身体微颤的肇事者搂到怀里。
很多狗一辈子没有坐过飞机,与Snowy相形见绌。不到百日的Snowy拥有自己的机票和专用航空箱,它飞越浩瀚太平洋,直抵温哥华。我去加拿大看望,离它的寄养时光已隔一年之久,Snowy已长成一只少女狗。
除了有人靠近自己宅院时例行的狂吠,开门迎接的Snowy并没有表现躁动与暴力,它似乎很快嗅出来自童年的气息,并顺从地仰躺,让我抚摸它毫无防范的胸腹,时而伸长脖子露出柔软喉管,时而偏头试图舔我的手指,以示它的友好欢迎。它当然长大了,但依然小巧,像最适宜孩子抱在怀里的毛绒玩具,只是抱起来沉赘——显然,养尊处优的生活增加了它的体重。
许多生物在胚胎早期极为相似,狼和羊别无二致,越发育,越受基因的支配而显现分歧。Snowy长大了,无法再以拟态掩饰它的血源。随着时间推移,我们发现,这是一个经过整容的白雪公主,只不过处处细节,留下手术的败笔。某种光线下,Snowy的白色皮毛露出发根处隐隐的浅灰,留下不完美的漂染效果。背毛像新雪一样闪烁晶莹之白,但它的肚皮,是尴尬而不洁的肉红色,像被屠宰的生猪,间着大片脏灰色——像某个贫困国家的地图,或者一个即将沉陷的岛屿。Snowy保持着拉布拉多那样垂耷的软耳朵和吉娃娃的迷你个头儿,还有一双说不清楚是单纯还是愚痴的眼睛。偶尔,它的眼神里流露鲁莽甚至凶狠的威胁,多数时候,它过着单调而平庸的日子——Snowy的眼睛,不像猫那样具备精密的刻度,有时像残留的积水那样陷入虚无。它的腮部,有两个不怀好意的黑斑——斑的大小,在粒与颗之间,再配合着一侧歪牙,它的侧脸有些微象征性的、又毫无实效的凶险。
下雨或洗澡,皮毛一旦被淋湿,Snowy的身体发出令人干呕的近于熟肉的浓郁的腥膻之气,平时这种气味并不明显。Snowy依然有伪装的爱好,它有时会像一只小鹿般呈现水滴一样的安详;有时,它愿意站在阳光照耀的百叶窗下……条纹状的光影照耀在皮毛上,把它变成一只奇怪的小斑马。
旅居温哥华期间,早晚遛狗是我的日常任务。
玥玥一家住在北温区,临近著名的旅游地松鸡山和吊桥公园。空气清透,植物的革质叶片上反射着新亮的光。森林,海边,建筑物和花园,许多地方都可以看到这种炫目的光,甚至可以用刺眼来形容。遛狗安排在早餐之前,可阳光,已经在高高低低的植物上炸溅开来……的确,太强烈了,像只发情孔雀整日绽放忘我的能量。
只是,早晨的阳光并无与亮度匹配的热度,体感上稍寒。这有利于Snowy从恍惚中醒过来,一出房门,它小弹簧似的活泼跃动……让我想起激浪汽水广告中那个跳水者,在骤降的清凉中甩动满头水珠。Snowy急迫向前,不断绷紧我手中的牵引绳,它需要在街角那棵剑蕨下排泄积储的尿液。
由于幼年遭受阉割,Snowy保持终身的处女气质。它尿尿后,用脚蹬踏草皮,撩起一些细碎之物试图掩饰自己的骚气,像猫一样自尊;便便过后,它猛地前跃,为此不惜承受由于牵引绳突然绷紧而在脖颈上加重的勒痕,它似乎急于要拉开令自己尴尬和羞涩的距离,显得某物与己无关的体面。Snowy还有不好炫耀的神异之处。如果食物的干湿适度,它也有闲情逸致,它可以把自己的粑粑轻松地梳理成辫子形排出体外。甚至比笨拙的小姑娘编得歪歪扭扭的样子好得多,它编得更齐整对称。
解决完体内的尴尬,Snowy才能从容开始它每天的巡游与勘探。
这里森林广阔,植被丰茂,土地像野生动物那样披覆浓密的皮丛,也的确常有熊、浣熊、臭鼬前来造访居民。想起这样的夜晚,令我动容——那些在草窠里,恋爱、试唱或者更衣的小虫子们,多么害羞,又多么骄傲;而密林深处,觅食或做梦的大动物,它们的心脏在暖厚的皮毛下面咚咚作响……和节日的鼓点相比,这种声音,名为宁静。
在北温的街区走动,我不知道自己所因循的,是昨夜哪个秘密潜行者留下的足迹。我想象月色下,它们深邃晶亮的眼睛。
从我的视角俯视,走在我脚踝旁的Snowy更像一只大白猫。尤其没吃什么东西,它的腰腹塌扁,看起来线条流畅——偶尔,Snowy试图保持一种它本身并不具备的做作的优雅。只有它快速迈动轻微的罗圈腿,向零食或骨头狂奔的时候,如此急切,让人分不清它的腿型是内八字还是外八字。多数的散步时光,这个出身低微的小土狗,也难以长久保持端庄步态,它抻长脖颈,沿途嗅着各种植株,或者埋首于一团污渍之中。Snowy走路的姿势,往好了说,像个缉毒犬,甚至福尔摩斯式的侦探,保持随时的警备;往坏了说,它孜孜以求地面上的遗落之物,满怀捡拾的渴望……Snowy一点也不体面和气派。
看别人家的狗,挺胸抬头、气宇轩昂,步履和仪态沉稳不凡,我不禁更对Snowy的低贱略感尴尬。尤其它时快时慢的节奏,不愿根据主人的节奏调整自己,而是根据自己的发现,即兴奔跑或停顿。Snowy只有一尺多长,可一旦发现什么,它的倔强,会让我感到牵引绳作用在手腕上的强劲蛮力,它不惜为此承受深陷脖子里的勒痕。
Snowy发现了什么?松塔、羽毛、纸片、树叶、草尖、野花、昆虫、牛奶渍、沥青、种粒、看不出任何异样的土壤,也许几分钟前,松鼠刚刚从上面越过它拱形的脊背……Snowy一路走走停停,兴味盎然。它像个动植物鉴赏家,对植被的变化有着深厚的好奇与了解;又像考古学家肯于埋首泥土里,去接触和挖掘。隔着牵引绳一米多远的距离,听得到它粗重而急促的鼻息。我看起来区分微小的事物,在它的嗅觉下千差万别——Snowy的智商肯定不如我,然而正是某种缺陷让它具有别样的天赋,就像盲人拥有更为敏感、强烈而丰富的辨听能力。它的鼻子经常长时间沉迷某处,尽管那里什么痕迹也没有留下,但它知道什么果实在这里坠落,又被什么动物的指爪捡拾。
经过树林的时候,Snowy停顿了,似乎听到什么隐秘的劝说。土壤上铺了一层厚厚的松针,以及间或点缀其间的松塔,站立一会儿,就会知道寂静长得什么样子。我发现,还有许多解体的碎片,仔细看是松塔,并非木质感强烈的深棕色,碎掉的均为幼嫩的青黄色,集中地摊散,像被一片一片仔细剥落的蹄甲。我不知道是什么原因,让它们没有达至成熟,是松鼠剥落还是因它粗暴的跳荡而震落?它们如此集中地死在有限的区域,几乎像从高空坠落的自杀式的瓦解。与此同时,一只松鼠停在树干上观察着我。我停下来,一动不动地与它毛丛中晶亮的小眼睛对视,并考验彼此的耐心。很快,松鼠攀援离开。我想,自己乏善可陈,支撑不住它一分钟以上的好奇心。我陪着Snowy继续在树林站立,才发现周遭掉落脚下的松塔如此密集,比人类史上摧毁的教堂还要多。
乌鸦的羽毛在这儿实在太多见了,Snowy很容易捡到。飞着飞着,它的一根更换的羽毛就会掉下来,像人类毛衣上的一个线头儿,失去毫无影响。是的,到处是黑得发光的鸟:乌鸦,能把风格做到绝对化的鸟。但乌鸦起飞时并不优雅,它吃力地扇动翅膀离开地面,微弓着背,尾翼向下弯曲,持续用力,才能纤夫般把沉重的自己拉上天空。不过,此地乌鸦大多都无惧,即使离人很近也不移动——它们的笨重,更似肌肉男的沉着。我把羽毛从Snowy嘴里抢夺过来的时候,它明显流露恼怒,喉咙里滚过一阵雷鸣。我诧异,即使看起来丑陋的鸟羽,也闪烁着优雅动人的炭灰色,缎子般分为正反面儿——背面是哑光的内敛,正面像平底船一样,以羽轴为中心呈现对称下陷的微弧,波光在这根死去的羽毛上依旧潋滟。乌鸦的弃物尚如此生动,何况艳异的飞鸟?它们也会掉落羽毛,即使它们的羽毛奢华得闪烁着珠宝的光芒。看似挥霍,其实只是一种自我更新的能力。
美国的哈斯凯尔在《看不见的森林》里写道:“棕林鸫的歌声由鸣管上至少10块肌肉塑造而成,每块肌肉都比一颗米粒还短。”在那些为我们日常所忽略的细节里,有多少美,像最小的萤火虫发出光亮。到处是动画片般活动着的松鼠,是童话般的蜂鸟,煤色的乌鸦亦非诅咒之鸟,和身着黑礼服裙的女士一样优雅。仿佛一座幽闭的花园,这里有那么多汹涌的绿色,让人错觉自己在开花……
难怪,早晚用于排泄目的的散步过程中,Snowy在犹豫、好奇、兴奋、恐惧、茫然、狂喜、怀疑、厌倦、渴望、发泄、迷醉中频繁变幻它的情绪,在这铺满松针的大地上,它的发现如此频繁,又如此令它易感。
我猜不出Snowy的心思。有时,我坚信是太多的诱惑让它走走停停;可有时,如果我加快脚步,它会轻捷地跟上,并保持悠闲错动几条灵活的小腿那种得意——仿佛正因我的慢速,它才在徘徊中缓步,只是不愿意浪费户外的好时光罢了,只是给缓步者以借口,使其不失尊严。我甚至不知道,人类的纵容或训诫,哪个更让它感受到自己被宠溺;就像我不确定,Snowy对玩具的快感,来自温情还是暴力。
它轮流热衷几样玩具。
第一样是毛绒玩具,小浣熊,被Snowy的牙齿撕扯、口水浸没,损坏得面目模糊。毛绒浣熊后来完全失去了生气,像个小尸体似的整天被拖来拖去,脸被按翻在地下,剩下一只悲惨的独眼支撑地面。
第二样玩具相当于简陋的体育器械:一头是麻绳,另一头是结实的橡皮锤。Snowy喜欢咬住麻绳,利用头颈的旋转甩动橡皮流星锤——“嘭嘭嘭”,木制阳台经常传来这个身怀绝技的武功高手用橡皮锤击打地面的声音。
第三个是它最为钟爱之物,是个可以发出声响的塑料热狗。面包中间夹着火红的香肠,上面挤着波浪形的蛋黄酱——鲜艳俗丽的外观,仿真食物似被浓重的工业色素腌制过。Snowy叼着它,乐趣无穷,因为伴随着上下颔的压力变化和齿痕轻重,这个热狗玩具会发出不同的声响。我一直觉得Snowy是个音乐爱好者,它喜欢吹奏带来的音阶、节奏与旋律。但突然有一天,在它显著的陶醉里,我发现,也许它迷恋的,不是外形,是近似的声音:一个垂死的受害者在自己的啃咬下发出阵阵高高低低的惨叫。
Snowy,Snowy,我猜不出它的善恶、它的道德归宿。
在加拿大期间,我和家人自驾旅行,历时数天。首次长途的Snowy,一上车就激动得失态,颤抖的腿几乎支撑不住自己的体重,它的舌头热烈地舔着车窗,像舔一片滋味长久的玻璃糖。远离入睡的暖窝,即将开始的历险让它喜悦又畏怯。
这对Snowy来说,是一场奇遇般的旅行,它不断有所发现。
我和Snowy在班芙游客中心门口的长椅上坐着,听风度翩翩的老者拉提琴。Snowy盯着一只袖珍蜻蜓:嗯,顶多只有我常见蜻蜓的一半,像枚铜色胸针。通常Snowy乐于招惹昆虫,它甚至有着令人恶心的甜点嗜好:偶尔捕捉并咽下一只苍蝇。对这只落在椅面上近在咫尺的蜻蜓,Snowy却毫无侵犯,就那么出神地凝视着,似乎被征服,饱含尊重地,向一种精湛之美致敬。我尝试去碰触,小蜻蜓并未飞走,反而顺着我的指端攀援上来。只是,小蜻蜓不爱照相,当我的手机镜头对准它的时候,害羞的它飞走了。
当我们在路边的休息区小憩,我远远看到爸爸试图拉开Snowy,它显然被地上的什么活物吸引。爸爸以为是条蚯蚓,我以为是条线虫——错了,我们惊恐地发现,Snowy想挑衅的,是条比毛线棒针还细的蛇。我觉得,蛇的形象,体现了上帝最恐怖的想象力。虽然这条小蛇比我的手掌大不了多少,且极为纤细,但这是我第一次在野外看到真的蛇,我依然感觉几近恶意的威胁。当然,在Snowy的判断里,或许存在着某种更宏观的平等。我很快见证,对那条孵化不久的幼蛇来说,Snowy是这个世界最后一个对它给予关注的生物——Snowy的耳膜,听到过它滑动时与地面摩擦的微弱之声,那几乎,就是它的遗言。半分钟以后,我亲眼看到这条正笔直地穿越道路的小蛇,被一辆拐行的房车后轮活活碾过。小蛇被自己破裂的体液粘在地上,左右晃动的头部进行垂死前毫无意义的挣扎。很快,它死去,变成具有装饰效果的S形……因为痛苦而扭曲自己,这条小蛇,是否以一个动物的卑微在模仿伟大的基督?灼日下,水分很快蒸发,幼蛇枯扁地按在地上……造型的曲线优美,像乐谱上的高音谱号,却无比宁静。与此同时,Snowy在越来越浓厚的倦意中闭上眼睛,它入睡,腹部微微起伏。死,太平常,这个世界不欠告别者任何缅怀的梦境。
Snowy在整个行程中有着持续的发现。
各种各样的羊。大角羊近切地经过,我看到它们满怀诅咒的邪恶眼睛。盘角羊群跃过高速公路,以及其中一只的正脸几乎按在车窗上,它梳着奇异的盘髻,不知形象是否近于动物版的老年简・爱——有人可以从羊角的刻槽上判断年龄,我当然不具备这样的科普知识的基础能力。峭壁上的羊,似乎是另外的品种。分趾蹄能以柔软而富于弹性的制动力,阻止因地心引力而导致的身体倾斜。有的羊无畏拍照者,站在护栏旁的碎石堆上,为了舔舐石堆上的矿物质和盐分。还有漫游的鹿,吃草,或者好奇地凝视正在好奇关注自己的人类。奇怪,羊或鹿之类的食草偶蹄目动物,都是既胆怯又好奇,它们迷恋盐的咸涩,就像食肉的熊迷恋蜜的甜润。还有麋鹿,举着烛台般的角叉,黄昏时分,它们托举着头颅上方隐约的光明,进入密林幽暗而不祥的深处……它们之中的某个或某些,可能,将死于当夜。
平日作风略带粗野的Snowy,旅途中反常的宁静。那么多新鲜的景色和面孔,汹涌在这个小宅女面前,它不由自主变得低微。
然而,Snowy对这个世界的好奇从未止息,旅行结束后的几周,戏蜂弄蝶的Snowy被毒蜂蜇伤,陷入抽搐和休克,很长时间才从昏厥中苏醒,几近丧命;此后不久,不长记性的Snowy招惹了臭鼬……怎么能招惹它呢?臭鼬是最不好招惹的,毛色黑白相间,它像个通吃两道的混混,张扬跋扈,而且袭击手段特别下三路,令人避之不及。Snowy为此代价惨痛,左邻右舍都听得见它恐惧而绝望的哀鸣。刚被袭击的Snowy,迅速在茶几下的地毯上,猛力而反复地蹭脸,想去掉臭鼬喷射的毒汁……于事无补,Snowy的头很快严重肿胀,眼睛似乎也要失明了。那只鼬强烈而恶劣的体臭,从客厅弥漫开来,传播到整个房间和院落——有毒的气体阴魂不散,徘徊了数周之久,令人产生阵阵呕吐感。闯祸并遭罪的Snowy,刚一恢复常态,它立即开始花园里的挖掘与探索。似乎,从未在教训里学会屈从。
我在温哥华住了四五十天。直到返程那天,我还是把搭钩扣到Snowy的项圈里,走之前,我还是带它去散步。淘气的Snowy步履轻快,它继续看那种长得像中国山水画的黑白鸟,继续无视领地里巡航的蜜蜂,继续在剑蕨附近排出编成辫子花儿的粑粑。沿途的庭院大多花事频繁,一边开放,一边凋亡。我想,有些告别,不过是花朵落下的重量……遗憾虽遗憾,但远非痛惜的程度。这是常情,是规律,也是我们用来标记岁月一种轻描淡写的方式。
清晨没起床那会儿,平躺的我半梦半醒,却在潜意识下纹丝不动,不敢动,不知道是梦到了,还是真以为自己是一片自我珍重的落叶……它不敢轻易翻身,怕破坏自己齿缘的缺刻,怕洒了自己弧陷里汪住的一滴水,怕路过的孩子踩碎自己。
其实,根本无需这么珍惜自己。历尽山水,草木一秋,亿万年来的树都是这样繁枝脱简,叶脉上的青葱岁月被风雨泡烂。生死短暂。只要这片枯叶放眼观看,无边落木萧萧下……世界不缺你一个。我需以此谨记并自我告诫。该开花就开花,该凋谢就凋谢,别拿着一副老朽样子摆雕塑造型。如果没本事重归枝头,就得甘愿零落成泥碾作尘——别自许什么香如故,那是一语双关,或许是在描述你的体味活像死人。
Snowy对我的感慨无动于衷,它沉浸于隐秘而汹涌的千万气味之中……自然,又是风度全无,Snowy以乡土或野蛮的方式,传达对这个世界难以自控的兴趣。Snowy在草皮上蹭摩、翻滚,碎细的梗节沾满它永远不会生育的腹部以及像火柴磷头那么微小的乳蕾,我听到兴奋的Snowy越来越重的咻咻鼻息。
我想,至少在写作上,我得多向Snowy学。别那么装腔作势,要保持天然的好奇,姿势难看无妨,低微些也没关系,只有这样,我们才能对世界产生更多的兴趣、了解和深情。有些创作者从破笔散锋中,足见气韵活泼、气象自由;相比之下,我局限太多,太拘谨,句子和语法的质感都过于坚硬——我以为钙化使它们更具骨感,其实只是僵化。因为对写作宗教般的神圣感,加之能力上的不自信,我像那些自以为是的贵族狗,把仪态看得太重,导致滞涩和约禁。我没有获得自由,因而也无缘创作上的大美。看着Snowy任性作乐,是的,我不应远离自己的初心、本心和野心。
Snowy是只血统混乱的小土狗,但我觉得它扮演寓言里的角色,仿佛具有秘而不宣的力量。比如吧,当看到一群蚂蚁倾巢出动,我们不会联想到,它们的流离失所可能意味着暴雨、洪水或是其他灾难即将到来——我们只按照自己的局限来理解,无法领略丰富的信息。人类的自负导致与自然的疏离,只有谦逊、笨拙、懵懂的生物,才能完整地接收到来自大地的暗示。在一只平凡的动物身上,也许就存在着人类的盲区;而真理可能,恰恰就隐藏在这个盲区。世界如此辽阔与神秘,我甚至不能保证自己的智商,必然高过一只狗悟出的真理。
有些日子没有洗澡,Snowy此刻体味浓重,我可不想把它抱在怀里招来一身异味,那会使同机的乘客不快。不过,当Snowy躺在地上,我很愿意为它效劳,按摩和抓痒——Snowy显出极度配合的舒适感。当顺着它的脊骨抚摸……我的手感清晰无比:指端,是隐藏着的一串硕大而圆整的佛珠。
一只特立独行的猪-理想国与哲人王 -王小波
========================
一只特立独行的猪-理想国与哲人王 -[[王小波]]
------
插队的时候,我喂过猪,也放过牛。假如没有人来管,这两种动物也完全知道该怎样生活。它们会自由自在地闲逛,饥则食渴则饮,春天来临时还要谈谈爱情;这样一来,它们的生活层次很低,完全乏善可陈。人来了以后,给它们的生活做出了安排:每一头牛和每一口猪的生活都有了主题。就它们中的大多数而言,这种生活主题是很悲惨的:前者的主题是干活,后者的主题是长肉。我不认为这有什么可抱怨的,因为我当时的生活也不见得丰富了多少,除了八个样板戏,也没有什么消遣。有极少数的猪和牛,它们的生活另有安排。以猪为例,种猪和母猪除了吃,还有别的事可干。就我所见,它们对这些安排也不大喜欢。种猪的任务是交配,换言之,我们的政策准许它当个花花公子。但是疲惫的种猪往往摆出一种肉猪(肉猪是阉过的)才有的正人君子架势,死活不肯跳到母猪背上去。母猪的任务是生崽儿,但有些母猪却要把猪崽儿吃掉。总的来说,人的安排使猪痛苦不堪。但它们还是接受了:猪总是猪啊。
对生活做种种设置是人特有的品性。不光是设置动物,也设置自己。我们知道,在古希腊有个斯巴达,那里的生活被设置得了无生趣,其目的就是要使男人成为亡命战士,使女人成为生育机器,前者像些斗鸡,后者像些母猪。这两类动物是很特别的,但我以为,它们肯定不喜欢自己的生活。但不喜欢又能怎么样?人也好,动物也罢,都很难改变自己的命运。
以下谈到的一只猪有些与众不同。我喂猪时,它已经有四五岁了,从名分上说,它是肉猪,但长得又黑又瘦,两眼炯炯有光。这家伙像山羊一样敏捷,一米高的猪栏一跳就过;它还能跳上猪圈的房顶,这一点又像是猫——所以它总是到处游逛,根本就不在圈里待着。所有喂过猪的知青都把它当宠儿来对待,它也是我的宠儿——因为它只对知青好,容许他们走到三米之内,要是别的人,它早就跑了。它是公的,原本该劁掉。不过你去试试看,哪怕你把劁猪刀藏在身后,它也能嗅出来,朝你瞪大眼睛,嗷嗷地吼起来。我总是用细米糠熬的粥喂它,等它吃够了以后,才把糠兑到野草里喂别的猪。其他猪看了嫉妒,一起嚷起来。这时候整个猪场一片鬼哭狼嚎,但我和它都不在乎。吃饱了以后,它就跳上房顶去晒太阳,或者模仿各种声音。它会学汽车响、拖拉机响,学得都很像;有时整天不见踪影,我估计它到附近的村寨里找母猪去了。我们这里也有母猪,都关在圈里,被过度的生育搞得走了形,又脏又臭,它对它们不感兴趣;村寨里的母猪好看一些。它有很多精彩的事迹,但我喂猪的时间短,知道得有限,索性就不写了。总而言之,所有喂过猪的知青都喜欢它,喜欢它特立独行的派头儿,还说它活得潇洒。但老乡们就不这么浪漫,他们说,这猪不正经。领导则痛恨它,这一点以后还要谈到。我对它则不止是喜欢——我尊敬它,常常不顾自己虚长十几岁这一现实,把它叫做“猪兄”。如前所述,这位猪兄会模仿各种声音。我想它也学过人说话,但没有学会——假如学会了,我们就可以做倾心之谈。但这不能怪它。人和猪的音色差得太远了。
后来,猪兄学会了汽笛叫,这个本领给它招来了麻烦。我们那里有座糖厂,中午要鸣一次汽笛,让工人换班。我们队下地干活时,听见这次汽笛响就收工回来。我的猪兄每天上午十点钟总要跳到房上学汽笛,地里的人听见它叫就回来——这可比糖厂鸣笛早了一个半小时。坦白地说,这不能全怪猪兄,它毕竟不是锅炉,叫起来和汽笛还有些区别,但老乡们却硬说听不出来。领导上因此开了一个会,把它定成了破坏春耕的坏分子,要对它采取专政手段——会议的精神我已经知道了,但我不为它担忧——因为假如专政是指绳索和杀猪刀的话,那是一点门都没有的。以前的领导也不是没试过,一百人也逮不住它。狗也没用:猪兄跑起来像颗鱼雷,能把狗撞出一丈开外。谁知这回是动了真格的,指导员带了二十几个人,手拿五四式手枪;副指导员带了十几人,手持看青的火枪,分两路在猪场外的空地上兜捕它。这就使我陷入了内心的矛盾:按我和它的交情,我该舞起两把杀猪刀冲出去,和它并肩战斗,但我又觉得这样做太过惊世骇俗——它毕竟是只猪啊;还有一个理由,我不敢对抗领导,我怀疑这才是问题之所在。总之,我在一边看着。猪兄的镇定使我佩服之极:它很冷静地躲在手枪和火枪的连线之内,任凭人喊狗咬,不离那条线。这样,拿手枪的人开火就会把拿火枪的打死,反之亦然;两头同时开火,两头都会被打死。至于它,因为目标小,多半没事。就这样连兜了几个圈子,它找到了一个空子,一头撞出去了,跑得潇洒至极。以后我在甘蔗地里还见过它一次,它长出了獠牙,还认识我,但已不容我走近了。这种冷淡使我痛心,但我也赞成它对心怀叵测的人保持距离。
我已经四十岁了,除了这只猪,还没见过谁敢于如此无视对生活的设置。相反,我倒见过很多想要设置别人生活的人,还有对被设置的生活安之若素的人。因为这个缘故,我一直怀念这只特立独行的猪。
本篇最初发表于1996年第11期《三联生活周刊》杂志。
遗民老谭-野夫
========================
遗民老谭-[[野夫]]
--------
一
去年,章诒和大姐忽然来电话,兴冲冲地问我故乡是叫利川吧,答曰是。她又问那你认识一个叫谭宗派的老人吗?我笑问:您怎么会知道他的啊?她说她第一次回故乡安徽,在那里的一个故老,和她谈起了我的家乡,并向她推荐了老谭——说这是一个埋名深山的高人。我对章大姐笑道——这是我的至交,没有人比我更熟知其人其事,其悲辛的一生……
老谭——我一直叫他老谭,与我忘年相交三十余年,其实算起来,他应该是我的父辈人物。从80年代初开始,我们就这样没大没小地订交起来,故乡街面上,鲜有不知我与他的深厚渊源的。那时,我是县教研室的菜鸟科员,他是县志办打零工的编辑写手。而他刚刚出狱未久,彻底平反的申诉,还正在频繁奔走苦求之中。
他是50年代利川的文学作者,我是80年代山中的文艺青年。整整两代人,却因为闭塞艽野,有此同好者非多;虽曰萧条异代,竟然也一见如故地相知相惜了。那时我大学归来,青春泼皮,在小城横来直去,很有些挥斥方遒的公子哥恶态。老谭则是身形魁梧,却一身寒素。二十年深牢大狱回来,还不免有种劫后余生的谦谨——但那表面的恭顺与和蔼背后,我依然能觉出其中的傲岸。在山中,他这样一个50年代初的州府一中的老高中生,骨子里是眼空无物,且不与人群的。
二
老谭身高一米八,与我初识之日,不过四十有六,正当壮年。那时正是改革开放的初期,国家拨乱反正,社会略显松绑。牢释人员的他,尚待政府更名其贱民身份,但依旧对未来积极乐观,似乎看不出丝毫怨恨。他镜片后面的小眼,总是笑意盈盈,和我们诗社那帮小混混,也多能玩笑一处。因为贫困,他从不烟酒。
其时,我和一帮兄弟在创办地下诗刊《剥枣》,老谭虽非社中同仁,但却是积极的参与者。我们组织诗会,则更多仰赖他的协助。他在劳改队办展览,练就一手标准的美术字,但凡写大字会标之类,全看他一个人在那儿画字并剪贴。我们有些活动偏激,他便在一边善意警告——我深知他的冤狱始末,也理解他的那种寒心和余悸。
我和他走得更近,是因为我调到宣传部之后,计划编写一本话说利川的闲书。我强调必须借用老谭,上级开恩,就成全了我这一企图。于是,我和老谭得以在很长一段时间,一起出入整个县域的乡村山水之中。在那一段时间里,我才算是真正了解了这个隔绝世界二十年的流徒,对故乡民俗文化和文史的烂熟。
他带着我走乡转村,深入边僻之野,访古问道。通常,在那些崎岖泥泞中,我根本无法跟上他的昂首阔步。他初出狱那两年,就是挑着担子,凭借一个漆匠的手艺,镇日行走在这样的艰难之中寻觅口粮的。他熟知哪里有风景,哪里有遗贤;他指着沿途的墓葬告诉我,这是巴人的悬崖穴墓,那是拾骨葬的古俗,这是苗民的合墓,那是古代汉民的庐墓——把坟墓安在家里堂屋中以示敬祖的古礼。
那时乡下没有招待所客栈之类,我们总要借居农户,搭伙寒门。老谭总是很快就能和山胞们搭讪熟悉,会将干净一点的床铺让与我睡;当然,更多的时候,我们则是抵足而眠。他熟知一切土家的民俗风情和礼仪,会唱山歌孝歌和号子。他仔细教我分辨哪种是石工号子,哪种是抬丧号子。可以说,关于故乡的那些民间文艺,我的知识多半取之于老谭。
三
1983年的老谭,终于在他的固执申诉下得以改判无罪。国家没有任何赔偿,当年陷他于狱的警察和法官,没有任何道歉。但是,他终于获得了一份正式的工作——安排到工艺美术厂,再调入文化站、文管所,还算是用其所长。
老谭的妻子,是其出狱之后娶的一个极端贤良和勤劳的农妇,靠摆摊卖亲手腌制的泡菜腐乳之类,勉强帮老谭贴补家用。他中年得子,白屋之中,珍如珠贝。老谭见我喜欢那孩子的顽劣,便送给我做“教子”,几岁的娃娃,呀呀欢叫着我这个尚是童男的“教父”。按民俗,这样的易子而教,也需行一个简单的古礼。老嫂子专门备了一桌好菜,我则给孩子送去一套读物和一把玩具剑,意思是要他长大也明白书剑恩仇。
后来我出山,每还,必与老谭长谈。再后来,我又轮到了他坐过的牢房。他、刘镇西和我,一代代山里读一点书的人,似乎宿命地都要押解到省城,想起他们前辈曾经的坎坷,也就不觉得自个儿的艰难了。等我出狱再见他时,他已然满头星霜。老少两代罪人相视一笑,背身却各自掩饰着各自的泪痕。依旧必请回家,依旧老嫂子亲炊的土菜,依旧我独酌,他陪茶,但他们二老的密布皱纹里,却平添了一些哀愁……
原来我那“教子”如我,青春早恋,被老师训诫和同学嘲讽,突然有些失常。原本是理科状元的他,坚决弃学,眼看高考在即,二老束手无策。等到我在北京安营扎寨了,老谭电话求我,说孩子休学一年,依然考上民院,入读之后又被网络迷途,坚决要求退学。他准备带孩子到北大校医那儿去治疗,希望我略助一臂。
我急忙将他父子迎来寒舍同住,孩子入院治疗,我则请老谭帮忙看稿编辑,顺便开支一份工资以便聊补困窘。六旬退休的老谭,工资几百元,老妻亦衰朽残年,依旧还在寒冷的菜市守着那些坛坛罐罐。老话说,落叶添薪仰古槐——我是深知他们一家的捉襟见肘的。可是,布衣之交的我们,杯水车薪的涓滴互助,又何能尽释寒门的重负?
我很多时候,只能说,他的苦难要么是命中注定,要么就是时代的造就。他在青春时代即被改写的命途,便像魔咒一样限定了他的后来。
四
很多时候,我想不清楚究竟该怎样来给老谭定位。几乎每一个县市小镇,都有一个或几个类似于老谭的人存在。他们熟知本地的人文掌故,埋首于故纸堆读写并传承着民间的道统。他们平生寒苦,不逐蜗名微利;白眼朝天,万事鸡虫,看穿了浮世的浅薄与功利,只是低调,仿佛卑微,而实则睥睨冠盖地活着。他们在漏雨深巷中坚守古礼,寒泉淡食甘之如饴,在世界的槛外、微醺的樽边独自冷笑,抑或歌哭……这就是贯穿千古中国的遗民。
老谭出生于1935年,3岁之时,抗日的武汉会战开始,省府败退鄂西深山。真正的乱世,正由每一个国民分担。他们家并非巴人之后,他的始祖是蒙古军官,元末被派往利川镇守南蛮。元朝覆灭之后,分驻僻野的蒙兵无法北归草原,只好在明初落业当地,他们祖上则归为谭峒安抚司所辖,因此改巴人姓氏为谭。
其后明清两朝,列祖有的当过总兵、知县,封过侯爷,但多数都是平民,于历史上无足轻重。老谭的父亲在光绪新政时,曾出任县衙吏员、警员,后辞职,在家和吏员叶松甫父女、仵作杨志清一起,悉心研习扬琴。其父是利川扬琴曲的首创人员之一,琴书自乐到民国,家道败落,但他却和秀才黄成绪一起创作了大量“扬琴曲子”(剧本)。可惜,这些剧本在“文革”中都被付之一炬。
乡间的乐者,自古都是师旷一辈人物的精神传承者,自命清高,不事经济,以身入衙门为耻。老谭的家训是“人生莫当官,当官必作冤。孝义要牢记,读书足吃穿”。他在新政初年便考上州一中,成绩名列前茅,却因体检而落第;而他的同学,则不乏清华北大者。他1957年便在省上报刊发表组诗,在当日的山中,可谓才俊风流。但是,未能上大学的他,则只好到硫黄厂打工。也许因为粗通化学,在养病中又被聘请到工艺厂研制肥皂。
也许正是散落在地方上的知识青年,声气相求的不多,才慢慢在他的身边聚集了几个同样爱读书议事的世家子弟。这几位因为家庭在土改中被毁,难免对新政颇多腹诽,有的甚至在当年参与过暴动和抵抗。当时光推进到1958年之时,整个国家已经在土改、清匪反霸、镇反、“三反五反”、“反胡风分子”等系列运动中,基本消灭了所有的异己分子,而山城利川还在“反右”。专政机关根据线报,很快便锁定了这些世家子弟(多是教书人),以及他们身边的老谭,是潜在的可能之敌。
于是,各种秘密侦查的方式开始运作,线民被派到老谭身边钓鱼。他们故意来宣说一些近乎反动的话,勾引这位年轻的乡村知识青年出笼。1957年,大饥荒渐至,但凡天良未泯的读书人,岂能真无怨言。他们跟着人家的言路,却落下了自己的话柄。23岁的老谭,完全无意地掉进了“反革命集团”案的陷阱。
五
四五个文学青年的所谓谋逆大案,完全凭空构陷。这种所谓侦破,仅为贪冒功赏而不顾草菅人命。即便三木之下,依旧无法索求一致的口供。因为,他们这些民国过来的遗少,即便对新政颇有微词,但确实不敢策划任何的反叛,更不要说所谓的“现行反革命”行动了。尤其是老谭,原本对新社会不乏感恩,家族也素无仇隙,所谓意见,也仅限于对某些干部的少许批评而已。
他们在利川的看守所脚镣手铐,一关就是三年。脚镣磨烂踝骨,脓血粘连钢铁,至今腿上犹有伤痕。最后酷刑之下,人人皆怀求死之心,而不得不承认任何莫须有的指控。但毕竟确不存在的阴谋和未经商量的供述,是难以完全落实判决的,他们就这样生不如死地渴望着早日走向断头台。
终于,其中一个嫌犯牟宪文熬不住这种漫长的考验,像《肖申克的救赎》一样掘洞越狱,但是很快被追捕回来。在那个年代,敢这样公然越狱对抗无产阶级专政的犯人,岂能不是反革命分子!于是,原本难以定案的老谭一伙,被激怒的押司很快定谳为现行反革命集团罪。于是,毫无罪行的老谭,被重判了二十年徒刑。
初被捕时,老谭戴着手铐被押回抄家,其父正坐在一把烂藤椅上,看他写的歌颂新社会的文稿。突然面对儿子绑缚回家,老人如五雷轰顶几乎当场气绝。当时的老谭远未想到此别竟是永别,还笑着安慰父母,会很快还他清白。警方把他家四代人所读的书挑了几担,一并没收。他外公是秀才,曾祖乃名医,几代的书香门第,初初踏入新社会,竟然就此打入了“反属”的另册。
之后,他们被发配到宜昌劳改。在他入狱五年之后,其父在耻辱和悲愤之中悄然长逝。他不知道家里的消息,更不可能千里奔丧。再之后,他们被流放到更远的汉阳,他将在那个著名的劳改砖瓦厂,和泥拉坯耗尽他的整个青春年华。
六
晴川历历汉阳树,多少冤骨寻无处?
我是熟知当年汉阳劳改砖瓦厂的严酷的——和泥拉坯要的还只是力气,真正要命的是出砖之日,为了抢速度提高产量,砖窑刚刚撤火不待完全冷却,就要犯人排队进去取砖。武汉的夏日已如火炉,犯人往往要将破烂的被子浸透冷水,披在身上冲进去抱着火热的砖跑出来。只需几趟下来,那湿透的被子就被烘干。
60年代初到70年代末,监狱中政治犯遍地皆是。而政治犯又多是知识分子,前朝遗留的老弱病残。要这样一些人从事这种强体力劳动,无异于变相处死。所幸老谭虽也戴着眼镜,却是山中平民之家出来的壮汉。那时年当而立,尚能勉强求生。在整个中国都处于大饥荒的年代,他说幸好监狱还能填饱粗粮。
二十年是怎样的概念?未经炼狱的人,怎知这一时间的真正长度?老谭像多数政治犯的传统一样——坚持“服法不认罪”,意即既然判定入狱,就必须遵守监规队纪;但对于强加的罪名,绝不自我承认。在那个申诉可能改判死刑的年代,即便再怎么冤屈,往往也只能隐忍。监狱还有一个恶法就是——凡是上诉或不认罪的囚徒,一律不给减刑。
犯人每月有两三元的生活费,用来买牙膏卫生纸等必需品。老谭念及父母的孤贫,竟然还能一年节约出十元,托干警寄给远在深山的双亲。父母没有回信,在那个人人自危的岁月里,更没有亲友千里相寻前来探亲。就这样,二十年,他始终不知道家人的死活。
终于熬到了1978年,那时已经打倒“四人帮”两年,老谭也终于熬到了刑满。劳改队对于那些无家可归的犯人,一般就动员刑满留场就业。老谭坚决要求回山,他在拖延了一个月之后,拿着监狱发的那点儿路费,挑着坐牢用的被子,第一次走到了汉口码头。这就是省城啊,他在省城边上劳作了十六年,第一次看见了这个城市的模样。
正好是深秋,1978年的第一场大雪,落满了老谭的发间,掩饰着他那早早降临的满头星霜。买舟西归,溯流而上,五天后抵达万州,再乘车奔赴久违的利川。二十年,儿童相见不相识,他摸索着找回深巷中破败的老屋。没有人知道他是谁、从哪里来,山中早已谣传他瘐死狱中。
他轻轻地踏进家门,发现陋室空堂,只有80多岁的老母正在灶屋的竹子楼上拣洋芋。他不敢喊,怕老人一激动摔下来。他在楼下站了半小时,流了半小时的泪,才看到老母亲一手抱着小半撮箕洋芋,一手扶着单楼梯,一喘一哼地从楼上抖抖索索地下来。他大喊一声妈妈,老母已经失聪,完全未曾察觉儿子的归来。他上前跪倒尘埃,抱着母亲的脚痛哭流涕,老母才白日见鬼般惊觉有人;开始是呆痴地望着他,毫无表情;后来,忽然一下就倒在地上晕死过去,撒了一地的洋芋,仿佛满地乱滚的大颗泪珠……
七
43岁的老谭出狱后,他哥哥接纳了他死而复活似的归来。他哥亲手用木板在灶屋一角为他钉了一个约有六平方米的房间,他自己拖石拉泥把地面平整,用祖上留下来的两条高矮各异的板凳搭铺,便算有了一间自己的蜗居。
家里寒苦,一个老人四个侄子,全靠哥哥一个人工作,嫂子做零工周济一家。幸好哥哥效力的电力公司,临时需要给电线杆刷油漆号码;老谭在监狱学过漆工,正好一个人背着油漆、刷子、雕版、板凳等,追随着电线的方向乞食。电线杆多在岩上田里,翻山越岭,上坡下坎,风餐露宿,一干就是两月,总算挣到了第一笔活钱。
胞兄四处张罗为他成家,在那个年代,谁家的大闺女敢嫁一个牢释犯?其兄只好劝他面对现实,托人为他介绍了一个寡居的贤良农妇。老谭看其心地善良,且不嫌弃他的贱民身份,于是便在那一无所有的灶屋里成了家。几十年后回头看,幸亏他们当年的互不相嫌,才有了后来的患难与共。虽谓贫贱夫妻,却是真正相濡以沫白头偕老的幸福眷侣啊。
成家未久,按乡俗要树大分桠,人大分家。于是,老谭便用油漆桶做了个炉子,正式分灶开伙。荆妻寒门出身,熟知各种野菜,老谭零工养命,三餐煮面当饭,但好歹这是他们自己的家了。当年春节,哥哥给了他一个小猪头和一小块肉,朋友给他送了一些萝卜,两口子寒泉配食,度过了自由世界的第一个新年。
之后,通过其兄关系,老谭进了城关镇的油漆厂,算是有了固定的工作。但是,好景不长,油漆厂油漆失火,本来与他毫无关系,但罪责按惯例还是栽在了他这个“坏分子”的头上。于是,他被驱逐。包里只有四元钱,走投无路的老谭只好走出利川,走出那寒酸但温暖的小家,来到州府恩施。他不敢吃住,在清江桥下坐了一夜,次日便用四元钱买了两把刷子和一小盒油漆,挨家挨户去找活路——问别人有没有碗柜桌椅要刷漆。做得好随便给点工钱,做得不好只管一点饭。
这样混了许久,他终于找到了一桩活路——摸落麻风病院去刷门窗!虽然那是一个怕传染谁也不愿去的地方,但对急需望门投止的老谭来说,这就是天赐良机了。就这样他又混进了安稳现世,开始渐渐熟习这个久违了的社会。久之,天性聪颖的他,渐渐地成了一个小油漆包工头。直到申诉平反,才重新安排进工艺美术厂当油漆工,每天工资0.6元。但每月18元的俸禄,对他那个嗷嗷待哺的老妻和初生的儿子,就已然是皇恩浩荡了。
八
炼狱出来的人,天生多有奔命的本事。劳改队的老话说——是太阳总要升起。老谭的知识储备和与世无争的品格,渐渐为周遭社会所器重。后来,民委把他借去编《土家族民族志》。再后来,又因文才展露,把他调到了城关镇的文化站。以后便搞文物、写地方志等,成全了他位卑然而受人尊崇的余生。
奉母,娶妻,生子,以一个布衣的身份,重塑乡村历史,传承民族文化。他辛苦而自得,终于开始了真正的人的生活。
我深知老谭的心灵手巧,本质上我们都是那种生命力特别强盛的男人。无论怎样的厄运,似乎都无法压垮我辈的精神穹窿。一个老读书人的本色,倘若不被时代所摧残,必将在一个开放和自由的社会凸显出来。他对这个古老县治的熟悉和热爱,在山里可谓无人能出其右。也因此,他得以告别筚路蓝缕的手艺人生涯,回归他打小热爱却被漫长隔绝的书桌。
1983年,在平反冤假错案的社会背景下,他得以改判无罪。一个无罪的人,生命却被活生生地剪走了20年,那是真正最可宝贵的青春啊。他拿着那个改判书,老泪纵横。他无处说理,无处追赔,他只能到父亲的坟头长歌当哭——让亡灵相信他,在这个国家,他确实是一个没有罪过的好人。
他以后的全部生活,就在我的故乡发掘着那些残存的文脉。他几乎忘记了那个时代强加给他的侮辱和折磨,无怨无悔地书写着利川。故乡今日的小有薄名,端赖老谭余生的奔走和研究。他先后撰编出版的有《利川市文物普查资料汇编》《利川市文化志》《鱼木寨研究》《利川文化遗产撷英》《支罗船头寨研究》《利川灯歌》等几本书籍,先后在省级以上刊物发表各种文章数十篇。利川现有的大水井、鱼木寨、利川灯歌等国家级文化遗产保护项目,都是由他主笔撰编并申报成功的。他为宣传利川土家文化,多次接受央视及湖北、凤凰等电视台采访。
而今,他已年将八旬,还在参与编撰《土家族大辞典》。我们都在各自自由了的岁月里,开始抒写自己喜欢的文章。我浪迹江湖,他依旧寒素如昨。每年还乡,他都要陪我重走往日山河。他依旧一身布衣,不喝酒,不抽烟,不求人,不拜官,健硕如壮年。他守着老妻和仍未更事的孩子,粗茶淡饭地在那依然破旧的老屋,读书上网,发帖甚至QQ,一步不落地更新着自己的精神生活……
忆我的弟弟汉斯-赫尔曼·黑塞
========================
忆我的弟弟汉斯-[[赫尔曼·黑塞]]
-----
生命中有一些我们无法忘却的时刻,当我们从外部观察自己,忽然发现一些本来不存在或不为自己所知的特点,这样的时刻,是无法忘却的。我们会全身震颤,震惊于这新的发现,发现我们的本质并非永远一致、并非如我们一向以为的那样固定不变。我们从骗人的甜蜜梦中醒过来一会儿,见到自己改变了,变大或变小,发展了或萎缩了。无论我们的心情是喜是忧,在这一刻里,我们见到自己随着无尽的激流漂流,它或是发展的,或是变动的,或是吞没一切的消逝,我们虽然知道它存在,不过,一般我们会将自己和自己的一些理想当成例外情况。因为,如果我们是清醒的,那么,这清醒的一刻会扩展为几个月或几年,那样我们就无法生存,我们无论如何受不了这种清醒状态。我猜大多数的人连清醒的一刻也没有经历过,他们毕生住在自己看似不会变动的尖塔里,像诺亚在他的方舟中一样,看着生命之激流、死亡之激流从身边咆哮而过,看着陌生人或朋友被卷走,于是追呼他们、恸哭他们,而以为自己会永远稳当停留在岸上观看,不会跟着被冲走,不会一起被吞没。每一个人都以为自己是世界的中心,世界围着每一个人转,每一个人的有生之日都是世界历史的终点和高峰:在他之前有几千年的时光逝去,有许多的种族消亡,而继他之后什么也没有,巨大的世界历史看来只是在为此刻、为当前的天顶服务。如果这种自己是中心、站在岸边不会被卷走的感觉被扰乱,幼稚的人会觉得这是种威胁,他拒绝被唤醒,被教导,他觉得苏醒过来、触及现实的真实是可恨的事,他觉得精神含有敌意,他会愤怒地、直觉地避开那些他认为被苏醒状态所侵袭的人,避开预言者、问题人物、天才、先知和精神错乱者。
今天看来,我也不曾有过许多这样的苏醒时刻,其中有些在我漫长的一生中已经被遗忘,记忆总想将它们尘封。我少年时代几次苏醒的体验最为强烈。当然,后来每当这样的警告时刻到来时,我已经比较有经验,比较聪明,也能够比较好、比较有智慧地去思考,不过经历和体验本身以及苏醒时那一刻的震颤,在少年时代则更为真切、更令人惊讶,那时的体验更加血淋淋、更加充满激情。一个八十岁的老人倘若遇到了大天使,他的心会跳得很厉害,不过他不会比少年时黄昏时刻在花园门口等待女友时更紧张、更欢欣。
我今天想起来的体验发生在片刻间,大概只有几秒钟之久。但是在那苏醒和知觉的瞬间我们看到了许多东西,回忆它、记录它所需要的时间,往往比经历本身要多得多,就像我们回忆和记录梦境一样。
那是在卡尔夫的老家发生的事,圣诞夜在我们那间“美丽的房间”里,高高的圣诞树上点着蜡烛,我们已唱完第二首歌。最庄严最重要的时刻已经过去了,那就是父亲朗读福音书的时刻:父亲高高的个子站在圣诞树前,手中拿着小小的福音书,他以节庆的声调读着、背着耶稣诞生的故事:“牧羊人在野外羊栏旁,他们夜间守护着羊群……”这是我们圣诞节的核心节目:围着圣诞树,听着父亲激动的声音,眼睛看着摆放在屋子一角的半圆桌上的青苔和石头之间的伯利恒城,紧张快乐地等待着礼物。这时心中会有轻微的矛盾,这是每一个节日都有的心灵挣扎,这种矛盾使我们有点儿败兴,同时又增加了节日气氛,这是尘世与神国的抗争,是自然的快乐与虔诚的快乐之间的矛盾。虽然这种矛盾在圣诞节不像在复活节那么糟,在耶稣诞生的日子里,人们允许欢乐,也应当欢乐,然而伯利恒马槽里的耶稣的诞生、圣诞树和烛光、圣诞饼干和星形饼干的香味所带给我们的快乐,与心中忐忑不安的催迫感相伴,因为想知道几星期来希望得到的礼物是不是真的会出现在礼物桌上,实在是一种很奇特的不纯的感觉。反正,和烛光和歌声一样,这种轻微的困扰和良心小小的不安也属于节日。在我们家,庆贺生日时总要先唱一首歌,歌词的头两行充满怀疑:生而为人,何言快乐?
虽然这样,我们还是快乐的。孩童时代,我唱这歌的时候总是把问号略掉,我确信,“生而为人”确是快乐的事,特别是有人生日的那天。所以,在圣诞夜我们大家都从心底感到欣喜。
福音念完了,第二首歌唱过了,唱歌的时候我已经偷偷往摆着我礼物的桌子一角看了看,现在我们走向自己的礼物,母亲领着女孩们到放她们礼物的地方。屋里已经很暖和了,房间闪烁着烛光,弥漫着蜡和树脂的气味,还有浓浓的饼干香味。女孩们彼此兴奋地小声说着话,显露出她们的喜悦,抚摸着她们的礼物,小妹妹正打开自己的礼物,不禁欢呼起来。当时我大约十三或十四岁。
我也像大家一样,离开圣诞树,走向我的礼物桌,我的眼睛已经寻找到礼物,于是看准目标走去。我得绕过小弟弟汉斯和那张摆着他的礼物的小矮桌子,走过的时候,我瞄了一眼他的礼物,其中最醒目最漂亮的是一套小茶具,那可爱的小人国用的小盘、小杯、小壶放在一起,那么小、那么漂亮,看去好玩而动人。我的小弟弟站在小桌旁,头向前伸,全神贯注看着这小茶具。走过的时候,我看见了他童稚的脸,就一秒钟的时间——他比我小五岁——过去的半个世纪里,我在记忆里曾几次重见这张脸,那一秒钟显示给我的这张脸:一张暗自欣喜的、粲然微笑的脸,因着幸福和快乐而完完全全着迷的童稚的脸。
这就是全部的经历。当我下一步走到我的礼物旁边的时候,我的注意力被礼物吸引,这瞬间的经历也就过去了。现在我一点也想不起自己得到的是什么礼物,而汉斯的小陶茶具则精确无比地留在我的记忆中。直至今天这景象仍保留在我心中,当时,在见到弟弟欢乐的面容后,我的心立刻被触动、被震撼,感情相当复杂。最先升起的是一股对小汉斯的浓浓的柔情,不过其中掺杂着优越感和距离感,因为我觉得,虽然这种粲然的幸福很美丽很悦人,可是对着这么点几毛钱就能买到的小陶制品就如此愉快幸福,那也未免幼稚了。接着,其实是与此同时,心中一动,我又感到,蔑视这些小陶杯小陶罐,意味着侮辱,实在可耻而卑鄙。更可耻的是我觉得自己比小弟弟高超、聪明,但小弟弟还能够欢喜得入神,圣诞节、小杯小盘以及这一切对他来说还具有完全的魔力,还是神圣的,而我也一度拥有过这样的能力。这就是这次经历的核心意义,令我惊醒,令我恐慌:我有了“一度”的概念!汉斯还是个孩子,而我突然间明白,我已不是孩子了,永远再也不会是了!汉斯面对他的礼物桌像进入乐园,而我不但已经没有这种体验,还骄傲地觉得超过他了,一方面是骄傲,一方面也有点妒忌。我从远处,从高处带着批判的眼光朝弟弟看去,同时又感到羞愧,羞愧于自己竟然这样看待弟弟和他的陶杯陶盘,以这样的蔑视和同情,以这样的高傲和妒忌看待他。一瞬间就造出这距离,就撕开这么深一条缝,突然间我明白我不再是孩子了,我比汉斯大,比汉斯聪明,也比他坏,比他冷漠。
在那个圣诞夜发生的,其实就是一小段成长在我内心挤压着我,使我不舒服,在我成为我的过程中有上千个圆圈要连接,这时其中的一个正在连接,但它不像其他圆圈那样在暗中进行,我有个瞬间醒过来了,意识到这一活动,我虽然并不知道一切成长都伴随着死亡,但是,从我的抗争中,我清楚地感觉到这一点。在那一刻,一片叶子从树上掉落了,我身上的一片鳞凋萎了。我们生命中每一小时都有这样的事发生,成长和凋萎的活动轮替不息,只是我们难得苏醒,难得注意到发生在我们身上、我们心中的事。见到弟弟那张欢畅的脸之后,我对自己和对生命有了许多了解,那是我进入这弥漫着节日气氛的房间时、唱着圣诞歌时所不知的。
这一次经历我后来想起过许多回,每一回我都惊讶于记忆中两种相反感觉的均衡。对应膨胀的自负感有模糊的负罪感、对应成长的感觉有变为贫乏的感觉、对应自己的优越感有良心的不安、对应心中对小弟弟的距离和嘲笑有请求原谅的愿望并承认童稚的价值。这一切听起来一点也不质朴天真,听起来很复杂,可是,在我们苏醒的那一刻,我们一点也不质朴天真,当我们赤裸裸面对真理的时候,我们总是不能心安理得,总是不能无条件地信任自己。在成长的那一刻,一个人可能自杀,但他绝不会杀别人。在苏醒的那一刻,人总是处于危险中,因为他是敞开的,必须让真理进入他的内里,必须学会爱真理、将真理作为生命的元素去感受,要做到这一点需要许多努力,因为人是创造物,对真理总是抱敌对态度。而且,真理从不像人们希望的或选择的那样美好,并且永远是铁面无情的。
就这样,在苏醒的一刻,我也见到了真理。我们可以立刻试图把真理忘记,可以事后把它粉饰得温和一点,我们也都这么做了,每次都这么做,然而每次苏醒之后总会留下一次闪光,在生命光滑的表面留下一道裂隙,留下惊恐和警告。我们后来记得的不是我们对于苏醒的思考和粉饰,我们知道那是粉饰,而是经历本身:那雷电、那惊恐。
我在差不多仍是孩子的时候忽然看见了从我身上枯萎掉落的幼年时代,在小弟弟的脸上看见的,此后几小时、几天内,我的思考所得仅是剥落的外壳,一切都在经历本身之中。我的经历其实很美丽、很友善,我所见到的、开启我眼的是一幅温柔可爱的图像,然而,这经历仍如闪电雷鸣,令我惊恐,因为每一次苏醒的内容都相同,真理只有一个,虽然它有千百种面孔。我看到的是,小汉斯拥有一些非常美丽非常宝贵的东西,而我已经失去这些了,或许我因此也就失去了最最好的东西,失去了惟一真正有价值的东西,因为,孩子是被称赞为有福的人,而大人,如果想要进入神的国度,他们就得如经书上所说的:“要承受神国的人,就要像孩子……”我失去了幸福和纯真,而我是在我之外见到这真理的,在另一张脸上见到的。这也是这次经历的所得:我们拥有的,我们见不到,也几乎不知道。我是个孩子,也不知道自己所拥有的。此刻,我开眼了,见到了。我见到了幸福,它以微笑和闪光的眼,以温柔的光亮的形象显示给我,这是只有当我们见不到它时,我们才能够拥有的幸福。这幸福看起来那么灿烂,那么吸引人,可是,它带着那么点孩子气,我甚至想说,它那么幼稚、笨拙,使人觉得自己比它高明。它令人羡慕,也会引人嘲笑,虽然幸福已经与我无缘,但我还能够嘲笑,也能够批评。当初,耶稣的门徒很可能像我看着汉斯一样看着被祝福的孩子们,在羡慕中掺杂着嘲讽的兴趣。他们知道自己是成人,比孩子聪明、有经验、知道得多、有优势。只不过成长、聪明、优势并非幸福,既不被祝福,也不能引人入神的国。
这是成长的闪电使我痛心使我怨恨之处。可是,这真理中还包含了一些更加令人痛心的东西。与我自己有关的是道德上的问题,我感到羞惭,得了一个教训,令我更加痛心的事则具有普遍性,当初刺痛得不厉害,末了却留下深深的伤痕,真理就是这样的不留情面。我想说的是,连汉斯的幸福,那使他喜上眉梢的幸福,也是不可靠的,它也会凋谢、也会失落,我也曾有过这样的幸福,如今丢失了,汉斯有一天也会失去它。我会这么想,是因为我对汉斯除了羡慕和讽嘲之外,还感觉到同情。不是那种强烈深切的同情,而是动人心弦的淡淡的难过,如同我们见到草地上的小花就要连同草被割去时产生的那种感觉。
让我再说一遍,当初我并不具备叙述和解释心灵状态的概念,那时我没有能力分析我所经历的,不过当天晚上已经开始试图去分析了,后来有时也在继续,直到今天。某些想法,我不知道是当时就有的,还是后来才加上的。比如死的概念,当时肯定是不会有的。对着弟弟微笑的脸孔,我虽有一种会逝去的感觉,并且感觉很强烈,可是,对于孩子来说,逝去和死亡差别还是很大的。苏醒的瞬间告诉我,我的童年正在凋落,童年最好的一部分已经失落,也告诉我,你的弟弟也将失去他的童年,他也受这法则的统治。但是没有任何声音告诉我,这法则就是死亡,因为当时我还不知死亡为何物,也不相信有死亡。事物会逝去,却是我已经确切知道的,在自然现象和诗歌中我对此知道得很多,树叶的飘落是我常见的。每一次“苏醒”,每一次与真实和法则接触也意味着与死亡的接触,这是当时我想不到的,虽然内心很可能是很恐惧地感受到了。
开始写这杂记的时候,我只是想以笔记的方式重温一下儿时家中那次圣诞节的一瞬间,因为当我们试图写下一次生命的体验或一种想法的时候,它有时是会以另一种面孔出现,会显示出新的层面和千丝万缕的新联系。可是,我现在看出,虽然这小小的经历对我而言历历在目,然而,就事论事,它并非充满生命力,甚至连间接的生命都没有。即使我是个大作家,我也无力把我弟弟脸上的天真快乐写得让读者联系到自己。以这次经历为契机,可以写出不少东西,可是,说的都是我自己,重要的不是那张灿烂的脸,而是我内心发生的事。小汉斯的笑容使我获得一次生命体验、一次苏醒、一次震撼,而他一点儿也不知道,从来都不曾知道。写到这里,我意外地发现,我弟弟汉斯不止一次在不知不觉中使我获得体验和震撼。如果我想符合事实地写出那次圣诞节的经历,我就不该单写它,而应该写出弟弟整个的形象和他的一生,即使我又得冒着多写自己的危险。我没有本事刻画出弟弟完整的形象,也就是说,我无法暗示自己,说我真正完全了解汉斯,真正完全认识他。不过,我们有过几次真正坦诚的相处,我几次经历了他,我们身上流着同一血脉,有出自同一家庭的许多相似之处,并且,我爱他。我想试试在此写出我所了解的他。这只是他真实生活里极小的部分,不过这里面会包含着本质性的他,因为,虽然童年过去之后,我们就不曾亲密地住在一起,不过我们的生活道路在重要关头曾经多次接近,他的生活与我的大不相同,但对于我却总是具有意义,有几次我觉得那就是我生活的镜像。
汉斯受洗的教名不叫汉斯,而是随着父亲叫约翰内斯。绝不会有人想到叫父亲为汉斯,约翰内斯这名字太适合父亲了,这名字带着权威和尊严,但不失柔和,福音书作者和耶稣最喜爱的门徒都叫约翰内斯,这名字还高贵、温柔、富于精神力量。也绝不会有人想到叫弟弟为约翰内斯。他是汉斯,是个亲近、熟悉、可爱而老实的人,他身上不像他父亲约翰内斯那样带着陌生感、神秘感,因此大家给了他一个亲切的市民名字汉斯。然而,他的人并不能像名字那样舒适愉快,他也并不像外表那样没有秘密。他也有他的秘密,他也遗传了父亲高贵的气质,也有骑士和堂·吉诃德的秉性。
他是我们家最小的孩子,在哥哥姐姐之间长大,受到大家的爱护,有时也受到我们的捉弄。他一直很乖,只有一次使父母担过心,那是他四岁时有一次走丢了。当时我们住在巴塞尔城郊,铁路这边延伸出去就是农村。有一天,小弟弟一人出去玩,他跨过铁路,往城里的方向走,在街上转了个弯就走进陌生而有趣的世界了。他越走越远,遇到一群和他一样大的孩子,就同他们一起玩起来了,可能也教了他们一些新的玩法,因为游戏是他的才能,这种才能他一生没有失去。玩伴们喜欢他,大概与他玩得十分尽兴,完全忘记该守的规矩。天黑了,家长把孩子带回家,孩子们不愿意汉斯走,家长也喜欢他,于是留住他吃晚饭。汉斯虽能够说出自己的名字,却说不出家住哪儿,于是人家留他过夜。这一夜汉斯不在家,他丢了,说不定掉进了莱茵河,说不定被拐骗了,父母急得不得了。第二天早上,留住他的人家把汉斯的事报到警察局,因为父母先前已报了孩子失踪,所以很快就把他领回来了。留他的那家人对汉斯赞扬有加,特别称赞他饭前和睡前虔诚的祷告,他好像也不大愿意离开他们。我们找到了他十分高兴,后来常骄傲地讲起小弟弟走丢的故事。
要到了很后来汉斯才有时令父母忧虑。那时,我们家已经搬到卡尔夫同外祖父住一起了,汉斯去了拉丁文学校。这个曾带给我许多麻烦的拉丁文学校后来简直就是汉斯的悲剧,他苦难的原因和方式与我的不同。后来我作为青年作家在《在轮下》中愤怒地清算了这样的学校,促使我写那本书的,除了我自己的经历,就是汉斯痛苦的学校生活。汉斯是个听话的、服从权威的孩子,但他学习不好,好几门课对他来说都太难了,对于处罚和折磨他无法冷漠处之,又太老实,不知道作弊,于是他成了老师,特别是坏老师放不过的学生,老师总是要找他的麻烦,总是要折磨他。学校里有好几个坏老师,其中一个,简直就是个魔鬼,他把汉斯折磨得不知道如何是好。这个老师有个恶劣的习惯,他在提问题的时候,恶狠狠地贴得很近威吓学生,像法官似的对学生吼叫。被他弄得不知所措的学生自然答不出问题,这时他就一个字一个字带着节奏不断地重复问题,他手上的大门铁制钥匙随着这节拍一下下敲在学生头上。后来听弟弟说,两年之久,他不但天天受这暴君的虐待,夜里还常做噩梦。到了放学时,他经常头疼得厉害,心里怕得要死走出学校。他在这学校受苦受难的那段日子,我已经不住在家里了,那时候我也令父母忧虑万分。
许多年以后,汉斯告诉我,父亲对他的教育比对我严格得多。或许他弄错了,不过,我相信他是对的。毫无疑问,父母因为我的自由放任,决定对弟弟严格管教。说来,我觉得我的教育也不轻松温和,虽然母亲有无尽的爱,父亲有骑士风范与温和优雅的气质。对我们严格苛求的从不是父母,而是原则。那是基督教新教的原则,认为人的自然禀性是恶的,必须先消灭意志,人才能够在神的爱里并在召会里得救。我们的父母非常爱我们,并且他们一点也不苛求。我们有些同学的父母并非基督徒,也不标榜什么理想,他们动不动就殴打孩子,动不动就关孩子禁闭。我们的教育不是斯巴达式的,我们受体罚的次数比同学少,也比他们轻,但是统治我们生活的律法十分严格,它对少年人,对少年的爱好、气质、需求和发展采取一种怀疑的态度,对我们的天赋、才能和特殊之处完全不愿促进、赞赏。我们虽然生活在这种严格的律法下,但我们生活的空间并非监牢或毫无生气的教育场所,而是充满爱,富于教养、精神生活和文化生活的家。在这家中,在那严格的律法之外,还有种种活泼可爱有趣的习惯、练习、游戏和活动:我们唱歌,玩乐器,讲故事,朗读;我们有个花园,晚上全家一起玩游戏,某些游戏还是父亲发明的;全家常一起散步,都喜欢树木花草和周围环境;过年过节房间布置得特别有气氛。最主要的是父母亲,他们是基督徒生活可敬的榜样,但他们不是圣徒,而是活生生的富于天分而卓越的热心人。他们通晓文学艺术,两人都是杰出的叙述者,都善于写信,母亲有时写诗,父亲是学者,对语言有特殊的爱好,能够即席编出谜语和语言游戏。虽然从属于律法,虽然在天性与良心之间常有冲突,我们家中的生活仍是多彩多姿,一点儿也不无聊。有矛盾,有担忧,有律法统治,但也有欢乐,有节庆,访客也经常不断。
这个家丰富的生活每天以圣经、歌唱和祷告开始和结束,每一个孩子从这生活中各有所得。我猜想,在学校已经被知识的学习弄得很紧张、自信心也减弱了的弟弟,对于家中活跃的精神活动大概有时会有压抑感。我可以想像得出,他可能感到父亲和外祖父以及他们的一些朋友是激励他的榜样,他们那样博学,外祖父精通印度学,说起梵文会使年轻的印度学者高兴又吃惊,对于汉斯来说,他们会太多的拉丁文、希腊文、希伯来文,这是他一辈子也无法达到的,因为学校里那点拉丁文和算术就已经难以应付了。我不知道是不是这样,我只是猜想。不过他受到压制和危害的天性在家中能够在其他方向吸取滋养,特别在音乐和游戏方面,他能够得到许多乐趣,也无需惧怕自己不如人。他唱起歌来全心投入,可以到忘我的地步,这是一种他直到最后都保留着的福气。玩游戏时他更是着迷,像个艺术家。汉斯喜欢的不是一般家庭经常玩的游戏,不是那些要警醒、注意,有韧性和组织能力以便最终击败对方的游戏,也不是两人对坐蹙眉沉思的棋类游戏。他喜欢的是自己发明的游戏,这个安静胆怯的小男孩在玩耍的时候能够达到忘我的地步,应该说,这时他完全寻回了自我,忘记了学校和外界,他心花怒放,成了个小天才。每一个有天分的孩子都渴望脱离一些他半懂不懂而又必须遵守的规则和目的,渴望投入自己创造的有意义、有目的的世界里去,对于汉斯这意味着更多,这是生死攸关的事。由成人或不理解人的神设计的世界秩序会压死人,如果我们想在其中成长起来,我们就必须创造一个自己的世界秩序。
游戏是各式各样的,有的游戏需要空闲和自由,有的游戏需要器具。却也有一些游戏随时随地可玩,即使在老师或家长的监督下也能够玩。上学途中,如果不是快要迟到的话,我们可以根据一定的节奏、根据自己发明的音乐走路,再在其中加上一些规定,使这段路更复杂、更生色,比如,不能踩到石板路上某种石头或某种花样,某一道路能走,某一道路不能走,等等。有时候走这段路成了庄严的舞蹈或几何图形,上课的时候可以用手指在椅子上按照呼吸节奏继续舞蹈。我们也可以在课前和一个同学约好,老师说到某个词的时候,就等于他说:我是个笨蛋。上课时,当老师说到这个词的时候,我们只需会心相顾,那么在死气沉沉的课堂上就能得到一点乐趣,一种快乐和胜利的感觉。
我们最喜欢玩的是音节字谜和演戏。我们没有舞台,也从未背过台词,不过扮演过许多角色,有时演给同学和兄弟姐妹看,更多的是我们自己演着玩。有时候我们几天甚至几星期都沉迷于同一个角色。每当放学、饭后或祷告完毕了,我和汉斯两人单独在一起的时候,我们就扮强盗、印第安人、魔术师、捕鲸者、招魂者。有观众的时候,我们最喜欢扮魔术师。我是巫师,汉斯是助手。不过我们只能在晚上做这样的表演,一方面因为我们和我们的观众到了晚上才会进入状态,另一方面则因为变魔法需要借助黑暗。我们家那栋宽敞的旧宅里有间大厅,上个世纪是宅里的舞厅,厅里有个高台,是乐队坐的地方,我们就在这厅里演戏。观众是家里的孩子和婢女,他们蜷缩在木板凳上和大木箱上,我作为魔术师站在厅的另一端,旁边一张小桌上放着我的工具和一盏煤油灯。汉斯是我的助手,他得听命行事,还得在暗中帮我做手脚。我们有许多听起来很庄严的长长的咒语,并且我还不断加以扩展,对我们两人而言,这是最主要的事,我们喃喃自语或者大声吼叫出咒语,可以制造夜晚从事冒险的魔法活动的氛围,这就足够了。观众不只想听我们滔滔不绝大念咒语、朗诵诗歌或悄声制造恐惧气氛,他们还想看我们表演。当我穿得稀奇古怪,头戴尖顶纸帽站在煤油灯小小的照明圈内,面对黑漆漆的大厅召唤精灵或魔鬼时,后面黑暗里就有东西动起来,一张椅子一小步一小步跌跌撞撞靠近了(那是汉斯用绳子拉动的),这时我们大家都入迷了,有些观众还会吓得大叫起来。有一次,我正沉浸在自己的咒语声中,觉得自己真的是个魔术师,我对助手汉斯大吼,要他为我照明,他抓起沉重的灯,好不容易拿稳了要照,可是他犹豫不决,迟迟不动,我非常不耐烦,以如雷之声对他吼叫:“啊,你犹豫了?过来,我跟你说,过来,你这人间可怜虫!”这吼叫声把汉斯吓坏了,灯掉到地上,差点没把汉斯和大厅烧着。
整个说来,我们当时的兄弟关系自然而正常,我无须为他感到羞愧。当然不总是亲密无间,我们也有吵架打架的时候,我是大哥哥,比汉斯高大强壮,这是无可改变的事实。不过,只要我想起当年,想起汉斯,眼前就会出现使这美好记忆成为谎言的一幕。
这一幕如同圣诞树下可爱的汉斯的形象一样,永远清晰地印在我的脑海中。我见到汉斯站在我的面前,低着头,头缩进两个肩膀间,因为我勃然大怒,正想揍他一拳。他屈服痛苦的脸无言地望着我,带着责备的眼神。又是一次体验一次警醒!那责备的眼神给我的打击很深,虽然它来得太慢了,没来得及阻止我打出那一拳。我的拳头落下,打在他的肩膀上,接着我突然惊醒过来,仓皇失措地跑开。我原是那么有把握、那么自信,觉得自己完全是个统治者,对他的不服从、他的失误完全有理由愤怒,于是握起拳头举了起来。我浸在愤怒中,只想作战,完全同意自己的行为,可是拳头未落下,我已经厌恶它,心也已经不安了,无法同意自己的行为,对自己的愤怒和暴力感到羞愧,并且想起了我其他的暴力行为,想起我年纪上的优势。我多么想忘却忘不了弟弟的这眼神,真实从这眼神向我望来,一切的痛苦、一切的无助看着我,控诉着我,我的愤怒和自信一扫而光,消亡于可怕的苏醒里;这是我平生第一次打人的时候与被打的人一同感受到痛苦和侮辱,心里深深希望,他不要如此沉默,不要原谅我,希望他奋起报复。
这就是烙在我脑海中的两幅弟弟童年的画像:对着圣诞礼物笑容灿烂像个天使的幼童汉斯和以无言的控诉目光对待我的拳头的少年汉斯。有时候,当我觉得自己的生命过得很失败时,这两幅画像就会浮现在我眼前:孩童的欢乐和孩童的痛苦,面对这两幅图像时,我看似优越、老到、强大,其实暗地里感到羞愧,感到被审判了。
相信后来我没有再打过汉斯。那次的经历只不过是片刻的经历,平时我们相处十分友爱,比许多别的弟兄相处得更好。可是,汉斯被打那片刻的情景看来却比平常的年月包含了更多的真理。我并不比常人恶劣,错误不比常人多,我认识许多人,他们做了坏得多的事而轻松地生活着,可是我已经明白了事理,苏醒的片刻让我见到了事情本来的面目,见到事情如何发生,见到我们人如何生活,强大的如何永远欺侮弱小的,弱小者又如何不得不屈服忍受,而最终一切强势和特权却都会烟消云散,道理总在忍受者这一边,我们多么容易麻木地伤害人,而瞬间的眼光又如何反射到我们身上惩罚我们。
后来我离开了家,只在节假日回去,在弟弟的日常生活中扮演一定角色的时光也就过去了。对弟弟的事我知道的不多,我有自己的同龄朋友,并且更加喜欢同比我年长的人交往,而汉斯在学校里有自己的苦恼,有自己的朋友,又因为我不再上音乐课,弟弟就得到了我的小提琴,他成了一个十分热衷学习音乐的孩子。当时我并不知道他在学校里有那么深重的苦难,到了很久以后他才把这些事告诉了我。当他早就笼罩在痛苦和忧愁的阴影中时,我还觉得他是个孩子,让我不忘我自己的童年。假期回到家里对我而言就是回到童年的世界,这时内心模模糊糊的需要总是促使我玩起童年的游戏,汉斯又成了我的玩伴,有时候真以为时光并未流逝。我越长大成人,对未来的目标越明确,就越知道珍惜汉斯不寻常的游戏天才。这时他一如既往能够全心全意投入游戏之中,在玩的时候他整个人就在游戏之中,他的脑子不会想着“更重要”或“更严肃”的事。
我当时认识的汉斯,那个在假期里与我玩的汉斯,看似完整,可是我只见到他的一半,我只认识他生活中快乐的一面,而他的生活比我知道的艰难得多。我虽然略知他学习上的困难,知道他颇受折磨,却因为未曾亲自看到,不能够设身处地为他着想,也没有心思这么做,因为当时我已经被自己的希望和愿望以及难处逼得透不过气了。
弟弟的义务教育阶段终于完成了,他非常高兴,父母亲也很高兴。摆在面前的问题是,下一步该怎么办。他怕学校,不喜欢思考性强的学习,学一门手工艺看来是最合适的了,不过,他爱好音乐以及其他美好的事物,加上他出身学者家族,这么早就让他走这样一条道路,将来可能满足不了他。家里人进退两难,这时已经显示出,找到生活的道路和生活的位置对我们的汉斯将是非常困难的事。猜想母亲一定热切地祷告了,也写了不少信,家人一定也商量了许多次,最后才决定让这孩子到商店里做学徒工。如父亲所言,从商是比较“实际”的职业,既可以像手工业者在店里工作,也可以从事较为理论和科学性的工作,在文书室、档案室、办公室工作,可以作为商业之神通过重重级别升为世界贸易之王。刚开始时得先在店里学手工,汉斯成了一家商店的学徒,学着搬运大捆的货物、钉箱子和开箱子、在楼梯上爬上爬下,还学会用秤。
这时汉斯的童年也似乎完全结束了。他虽然脱离了拉丁文学校,可是又套上了新的轭,压力并不比学校轻,一直到生命最后一刻他都在忍受着。汉斯误入了一个他不感兴趣的行业,他不适应不在行,他一直努力去适应,却总是不怎么成功,最后只有屈服,把这职业当做无法逃避的严酷命运去接受。
虽然我们从未完全断了联系,但是我并不清楚汉斯的每一段生活道路。现在我只能简略地勾勒出我所知道的。在这条人生道路上,有过居住地的迁移、工作的更换,有过失败和不得已的中断,也有过多次新的开始和努力。学徒阶段结束之后,他在邻近一个大城市一家老字号商店找了一份工作,后来他觉得有必要多学点会计,便到商业学校去学,找了新的工作,又学了速记和英语,终于成了秘书和通讯员,多半时间在工业界工作。可是他无论在哪儿都觉得格格不入,他非常严肃认真地工作,可是没有一样工作令他感兴趣、令他快乐,他肯定经常对自己和生活感到绝望。不过,他爱好音乐,拉小提琴,找一些朋友一起唱歌,有位表兄弟是他的好朋友,他们常年通信,假期时还聚一聚。汉斯二十几岁时,有一次实在受不了,把工作扔下跑了,我们大吃一惊,很是担心。我那时结婚不久,住在波登湖畔一个小村子里,于是请他到我那儿去休养。他来了,他所受的痛苦和折磨比我们想像的更加严重。我帮他打开行李,赫然有一支手枪在里面,他尴尬地笑了笑,我也笑了,然后我把枪收了起来,到他离开时才还给他。他在我那儿住了几个星期,我们弟兄处得很好,他身体恢复得不错,人也开朗了,于是开始找新的工作。不过今天回想起来,我们兄弟间的关系当时就已经有些儿不完全和谐的地方,我当时好像也感觉到后来在我们的关系中出现的变化和陌生感,而那不是我们谁有意造成的。
我的人生道路和弟弟一样不顺利,我也经历了学校的悲剧,虽然原因和弟弟的不同,我没有耐心,硬从学校逃了出去,让父母亲大为忧虑。我和弟弟很相似,总是给自己找麻烦,很容易羡慕别人的性格和成绩,很容易怀疑自己。我们两人都是边缘人。不过我和弟弟不同,我有一个目标,最初不很清楚,后来就越来越集中力量朝着从小就梦想的目标走去。当我经过激烈的斗争屈服于父母的安排先去做书店的学徒工时,我也是为着目标而那么做的,那是暂时的妥协。我到书店去,首先是为了不再依赖父母亲生活,再者为了让他们知道,必要的时候我能够克制自己,能做市民阶层做的事,从一开始这对于我就是达到目的跳板。而我也终于达到了目的,先从家里,再从临时的职业中解脱出来,成了作家,能够靠写作维生,我与市民世界和解了,得到他们的承认。我结了婚,住在风景秀丽的地方,按照自己的品位生活,与自然和书本为友,而这一自由选择的生活,其困难和矛盾当时还不严重,我自己也还没有意识到。对于在我家里做客的汉斯而言,我是个到达目的地的人,做成了自己想做的事。而他觉得自己永远也不会达到目标,永远做不好自己的事,迷失在自己不感兴趣的职业中,不会升迁,深信自己的无能,没有自信,在妇女面前无可救药地害羞,心中认为没有可以实现的梦想。汉斯在我和他之间看到一条鸿沟,而我却看不到,这条鸿沟随着时日的推移越来越大,后来我也感觉到了。
当然他心中也怀着梦想,有对幸福和真正生活的想像,可是他的愿望无法在生活中向前投射,而是指向童年,回到乐园。他是家中最小的孩子,习惯于比人小,比人无能,学校又使他觉得自己更加渺小,工作上超过他的人只不过因为他们比他强硬,比他自信。如此一来,为了谋生他逐渐学会顺应外在的需要,而内心则望向从前,望向童年,望向那热情单纯的梦想和游戏的世界,那儿没有斗争,可以尽情歌唱,无端欢笑,无目标地漫游。
他又找到了一份工作,继续学习英语,拉小提琴,在一个合唱团唱歌。除了音乐,还有一样事情使他如鱼得水,他可以呼吸,可以恣意发挥,展现自己,那就是同孩子交往。他工作地方附近的朋友和亲戚家,凡是有孩子的,每到星期日他一定会去,他是个懂得孩子愿望和脾性的好玩伴、好叔叔,大家都喜欢他,他和孩子们玩,和他们弹琴奏乐,把他们带入诗意的游戏世界,孩子们亲近他,却不知道他们的叔叔兼朋友是那么失意,那么忧伤。他非常渴望有自己的孩子,可是他拿什么来养家糊口呢?想成家的人,工作上必须有所进展,能够向上爬。况且女人是那么难以接近,若对自己那么没有信心,又怎能够向女人保证,一辈子使她温饱,使她幸福?
有好些年我们很少见面,我们住的地方相离很远,除了生日时写贺信,几乎没有别的联系。每当我有新书出版就寄一本给他,每次他都会来信致谢,却从未对我的书表示什么意见,我从来都不知道他喜不喜欢我写的东西。大战前三年,他在阿尔高地区的一个小城找到一份工作,一年后我搬到伯尔尼,这一来,我们相距就不太远了。有几次,汉斯星期日骑自行车到我家里,与我们一起坐在树荫下聊天,和孩子们玩,我们聊到巴塞尔、卡尔夫,聊起老家。那时汉斯工作的地方是家大工厂,那儿有许多办公室,汉斯就在其中之一担任书信写作的工作。他抱怨日子又长又无聊,也讲苏黎世的亲戚,星期日他常到那里去和他们的孩子玩。战争开始后,我有一次同他谈起国际政治,他只是摇摇头,他很少看报纸,也没有什么立场。他很特别,半是孩子,是圣诞树下笑容灿烂的汉斯,是同我玩耍、有一次被我打了一拳的汉斯;半是个谦虚的小市民,声音低沉,头向前倾,对工作很失望,工作只为了维生,一个耐心的小职员。
不过,除了小提琴,除了和亲戚的孩子一起度过星期日,他还有自己的一方天地,在那儿他的心灵能够得到更新,从那儿他能够得到生活的勇气。他不只在心灵上保持童真,他还保持了虔诚,双重意义上的虔诚,一是心灵上的纯真,对人类和世界秩序的敬畏,一是信仰上的虔诚,他是教会里虔诚的一员。不适应商业和工作的环境,职位总是很低,这他都认了,他接受他的命运。觉得难以忍受的时候,他并不埋怨上帝和世人,不埋怨设施和上司,更多的是埋怨自己。他完完全全不问政治,也不允许自己有什么批评,他过的虽不是苦修的生活,也并非滴酒不沾,但他十分节俭,因为他的钱来之不易。他一星期有一两天到教会的唱诗班去练唱,他的歌唱得不错。
战争开始之后,汉斯的日子似乎比我好过一些。政治上的事他不关心,他的生活虽然简朴,却有保障,在他看来,统治世界的不是将军和部长,而是神。战争期间父亲过世,我们兄弟姐妹都回去了,大家在一起有许多话谈,父亲把我们又联系在一起了,在悲伤之中,我们似又回到儿时,大家互相依赖,同甘共苦。
到了战争末期,我原先所享有的一切自由和舒适已经散失殆尽。书房早已成为办公室,家境大不如前,隐居在家自由自在工作的日子早就结束了,我被卷进世事的苦难和紧张之中,连心爱的音乐,我最后的慰藉,也无法忍受了。这时我太太病情严重住进医院,我只得把孩子送到别人家去,我一个人住在荒凉不堪的家里,一切似乎都崩溃了。恰在这时,也就是1918年的秋天,汉斯来信要我去参加他的婚礼。他已经订了婚,生命有了一线光辉,想试试建立起幸福的生活。
我的任务是代表我们的家庭出席他的婚礼,我们家其他的人都在德国,而边界是封锁的,没人来得了。我觉得为难极了,战争年代繁忙的工作压力和心灵的苦难已经把我变成个不愿见人的绝望者,不得已的时候,我可以拖着烦累的工作一天天过日子,麻痹自己。但是长期以来,我已经无法参与任何快乐的事,无法参加任何庆典。当然,去挨过这么一天也不是做不到,但是,我担心的不只是自己。我自己的婚姻刚刚结束,在我看来,不结婚的话,会比现在好过千万倍,我思潮如涌,想起十四年前决定结婚、举行婚礼时,内心有多么激烈的斗争。不,我不会带给汉斯什么好运的。我们这样的人扮演市民的角色去结婚,是不会有什么好结果的,我们适合做隐士、学者或者艺术家,要不然做荒漠里的圣徒,但是我们不适合做丈夫,做父亲。我们幼时所受的教育是当时虔诚的教育法称为“意志挫折法”,事实上,我们的许多东西也被压断,被毁灭了。可是,我们的意志恰恰是他们无法毁灭的,我们天生的、独一无二的个性,那一点闪光,那一点使我们成为边缘人、成为特立独行者的东西,还留在我们身上。
可是找个借口不去参加汉斯的婚礼根本就做不到。我自知纠缠于自己的不幸中,整个人十分神经质,并且,我怎能不衷心祝福弟弟终于找到的幸福呢?那不是太愚蠢太不公道了吗?我又怎能够不出席而使得他的婚礼蒙上阴影?那样做就代表我不关心他,不祝福他。况且我知道,婚礼上独自一人面对新娘济济一堂的亲朋好友,对于新郎是多么难堪的事。于是我穿上黑色礼服乘火车到阿尔高去,见到汉斯安静、幸福、有点不知所措地站在严肃友善的新娘旁边,我真有些感动了,也为自己的猜臆而感到羞愧。新娘的姐妹和姐夫妹婿也都来了,他们殷勤地接待了我,我对他们也颇有好感,这是个精力充沛个头高大的家族。结婚仪式完毕,到邻村新娘的娘家参加喜筵之前,我已经觉得汉斯境况不坏,前途光明。长久以来我未曾如此快乐,这健康平安的乡间世界离开一切的战争,革命和世界末日似乎很遥远。喜筵很好,大家兴高采烈,我不但放心,还十分高兴,见到弟弟经过长久的饥渴和寻找,终于安定下来,有了自己的家,融进众人之中,那种感觉真的是十分好。惟一不太满意的是他们在城里找的新房,不过出于礼貌,我还是称赞了几句。房子在一条嘈杂的街道旁,他们住在一层。接着而来的日子我自顾不暇,很少想到汉斯。战争结束了,革命也结束了,我在自己鬼屋似的家里度过了一个冻得半死不活的冬天,忧虑重重,我当时的整个存在都崩溃了。到了春天,我终于收拾了书和一张老书桌还有一点纪念品,搬到新的地方开始新的生活。汉斯的日子过得不错,他是个好丈夫,有个好家庭,下了班有自己小小的家在等他。他们有两个儿子,多年来他只有星期日在别人家里做客时才见到的,现在他自己也拥有了。
大概在那次婚礼四五年后,我刚好有事得在汉斯居住的城市停留一段日子。这时,他在这个城市已经住了十几年,一直在同一家工厂工作,动荡不安的日子已经过去了。我见到汉斯和他的家。他看起来安静了一些,也显得有点老了,当然他也有忧虑,这是我后来听说的。原来在他结婚之后,上司曾找他谈话,认为他在厂里工作已有年头,又勤快可靠,然而他目前的工作地位比较低,既然已经结婚了,就应该弄清楚厂里职位有高有低,而他还处于最基层。一个人只要肯干,又有点才干,他就会力争上游,不老是听从别人的吩咐,也得学会发命令,不老是受别人监督,也要监督别人。对一个一向辛勤工作又刚刚结了婚的职工,如果他努力,又自信能够做比目前更多、更重要的工作的话,应当给予升迁的机会,当然,工资也会相应增加。厂里决定让汉斯在一个比较重要的职位上试用一段日子,厂里希望他乐意接受这个机会并有良好的表现。我们的好汉斯恭恭敬敬听着这段话,羞涩地提了几个问题,接着请求给他一点考虑的时间。他的上司看到他不马上抓住这个机会,觉得有点奇怪,同意给他时间考虑。接下来的几天里,他忧虑重重,为作决定沉思着、挣扎着。到了约定的时候,他请求上面,还是让他留在原来的岗位上。这时他才把一切告诉妻子,很费了点气力才使她相信,他只能这么决定。这之后,人家再没有麻烦过他,他一直留在原来那个低微的岗位上,守着他的打字机。
那时候我还不知道这件事。我到他家里去过几次,星期日同他的家人一起郊游过,也请他到我住宿的旅馆吃过饭、聊过天,于是想看看他工作的地方。可是汉斯吃惊地一口拒绝,门房也不放我进入。为了至少对弟弟的日常生活有个概念,有一天中午放工前我跑到工厂大门口去等他。这个入口真是壮观,就像古堡的入口,门后有座小房子,门房就坐在窗口守望。从大门进去分成三条路通到工厂,工厂像个小城市,里头有一栋栋的房子、院子和许多烟囱。中间一条是车道,旁边两条是人行道。我在门外等着,顺着宽广的街道看去,看着房子,想像着在其中一栋房子里,我的弟弟日复一日、年复一年坐在一个有许多打字机的大厅里打信件。我见到的是个严肃、严厉而且还有点灰暗的世界,如果要我每天早上、每天中午按时到这里来上班,接受命令写信,写账单,那么我得承认,这事我做不来。当然,作为工厂厂主、高级主管和工程师或工头,作为一个能纵观全局的人在此工作,这我还想像得出是什么样子。可是做个工人或低级职员,日复一日做着相同的事,那就像身陷噩梦。我费劲地向门里望去,想着汉斯,想着那遥远的圣诞夜里他童稚灿烂的笑容,我的心整个揪了起来。
现在我见到大门内很远的地方开始有动静了,先出来了几个人,接着多一点,接着出来了许多人,他们都朝着大门走来,最先出来的已经从我面前经过,走向城里了,里面的人群还在不断涌出,黑压压一大片,快步走在两条人行道上,中间路上也有上百的自行车、摩托车,间或有汽车。男男女女都有,主要是男人,有些年轻人不戴帽子,他们粗鲁强壮自得其乐,有些人聊着天,但是绝大多数的人脸无表情,默默无言,看起来有点累,被人群带动着走。最先我看着他们的脸,想找出汉斯,可是人群从三条路上涌过来,在人流中,根本不可能认出个别的人,于是我不再找弟弟,就这么站在那里看着。大概有一刻钟的光景,人流才逐渐散尽,道路和院子又变得死气沉沉,等待着人群的归来。
后来,每次到这个城市来的时候,我都会到这门口等待午间的行军,有几次我能够逮到汉斯,有几次是他看见我,有时候看不到他,我只好走掉。对我,每一次都是痛苦和教训。当我在人群中发现弟弟,看见他在他们中间低着头快步走着,我就感到一股无济于事的深切同情,每当他看到我,抬起头静静地对我笑笑,手伸向我时,我就觉得他比我年长,比我成熟。我一直把他当孩子看,而他隶属于这几千人,他耐心的步伐、他疲乏却很友善有耐心的面容,这一切赋予他一种悲凉的庄严,一个备受折磨的屈从的印记。
对他的生活有所了解之后,我也想让他认识我生活的某些方面,让他认识我圈子里的人。他爱好音乐,自己也玩乐器,就算他不喜欢文学、哲学,不喜欢政治,我还是想可以和他一起听听好音乐,想找个晚上或者星期日,把他从他小市民的生活中拉到我们艺术家这边来,想带他到苏黎世听歌剧或音乐会,散场后和我搞音乐的朋友一起坐坐聊聊。约了他许多次,热情地邀请他、催他,他就是不答应。我只得略带失望地放弃了。汉斯不想听歌剧,不想听音乐,不想和我的朋友在一起。我忘记自己在战争期间的情况,那时我对音乐和朋友的聚会、对一切可以想起艺术的事物都不能够忍受,当时,只有忘了这些珍贵的事物才生活得下去,偶尔想起一段舒伯特和莫扎特的乐曲就会想哭。我没有看出、没有感觉到,我弟弟的处境与我当时很相似,不知道他勇敢地坚守着职业上的苦役需要多么大的决心,经历一次令人陶醉的艺术享受、全心投入《魔笛》,很有可能令他对至今的生活质疑,使他的生活受到危害。我只觉得失望,以为他满足于小市民生活,害怕晚上晚回家,不好意思和我的朋友在一起。后来我们就不再提这事了。我也渐渐得知,他不愿意有人向他提起他的作家哥哥。他喜欢我,对我很好,可是我的写作、我精神生活方面的兴趣对他始终是负担,他想得到保护,不愿参与。
我也想过这事,因为我们的交往有些受影响。有时候一两年不见,见了面问问彼此的健康和家人的情况外就没有什么说的了。到今天我仍不知真正的原因,我只能猜测。毫无疑问,弟弟在我面前总是不自在,在我面前,他表现出的漠不关心和市民气并不符合他的实际情况。在他自己的圈子里,他是个有趣的好同伴,有情趣、有想像力、会说笑,常使人惊喜不已。在他看来,我永远是被人家认为比较聪明的哥哥,我代表精神性,而他从小在家在学校都与此格格不入。他身上和我一样有艺术家的禀赋,他见到我的禀赋能够培养成为职业,受到承认,而在他身上这种禀赋停留在偶一为之的自由游戏上,保留着孩童游戏的无邪与无责任。不过这只是我心理学上的解释,不足以说明弟弟的态度。影响弟弟生活的还有一股力量,那就是宗教的力量。我身上也具有宗教情愫,我们的宗教情愫根源相同,不过我在少年时代先成为自由思想者,后来又成为泛神论者,读过一些外来的神学和神话,即使后来我和基督教逐渐和解,也没有放弃内省,总是孤独一人。汉斯不一样,他保留了源自父母亲的信仰,心灵上和理性上都很虔诚,并且参加教会。我知道,有时他也有怀疑,思考着自己带点冒险性的神学,不过,他履行着他的信仰,是非常坚贞的教会成员,聚会和圣餐他通常都参加。
这种虔诚的心和对妻子孩子的责任感给他力量,使他在实际生活里能够在那么不合适的工作岗位上坚持下来。这两种力量也使他免于苦恼和忧愤。他从不去想工厂经理的汽车和别墅,不去想他们的薪水与他的有何区别,他对人总是彬彬有礼。他不喜欢自己的工作,不过他总是小心谨慎地做好工作,回到家就不再谈工作上的事。家里有家里的事,生病、缺钱、孩子上学等等他都得操心,在家还有唱歌、乐器、晚间祷告、星期日做礼拜和孩子们去郊游,每次郊游,他口袋里一定带着歌本。我们见面时,他偶尔会抱怨办公室情况的改变,有一次对我说起一个严酷的上司,那时,我通过朋友把紧张关系平息了。看来他过得还好,只是当我有事到他们城市,在工厂门口等他的时候,有时会发现他太老太缺乏生气,太顺服太疲惫。后来,工厂里没那么多的事,老有人被解雇,而他的眼力越来越不济,冬天里长时间在灯光下写东西很难受,有几次我发现他忧心忡忡。
现在让我讲讲我们最后一次相会那几天的情形。
我有事到汉斯居住的城市去几天,那是在11月里。我又走到汉斯工厂大门口等他下班,那天我情绪欠佳,想想,觉得带着这种情绪见弟弟不大好,想走开,可是人流已经出来了,于是我等着,见到了汉斯,跟他点了个头,他过来,和我握握手,我们两人就向城里的方向走去,在一条安静的小巷子里来回走着。汉斯问我好不好,我没法好好说,我知道他中午的休息时间很短,家里妻子做好中饭在等他,于是约好晚上到旅馆聊聊。
汉斯晚上准时来到我房间,随便聊了一下,又经过一些犹豫后,他忽然开始用压抑的声音对我讲起他在办公室的处境。他快受不了了,眼睛常常不舒服;他的身体越来越差,人人都对他不好,办公室现在年轻人很多,他们总在背后说他的坏话,大概不久他就会被辞退。我吓了一跳,多年来没有听他用这种语气说过话。我问他,是不是发生过什么事。他说,是的,他做了件蠢事。有一次,一个同事对他很不客气,他感觉到,他们大家都反对他,他一下子控制不了自己,就很气愤地说,把我辞退好了,反正我也受够了。
他神情黯淡地呆看着前面。“汉斯,”我说,“事情真的没有那么糟!是什么时候的事?昨天还是今天?”
他低声说,不,这是几星期以前的事了。我看出,弟弟情况不妙。他怎会这么疑心,觉得被人追踪!他怎能几星期之久担心害怕!我对他解释,如果他的上司把话当真而想开除他的话,他早就被开除了。我又说,年轻同事不尊重他不是什么大不了的事,我们自己年少的时候,不也老是拿年长的人开玩笑吗,当我处在年轻人中间的时候,有时也觉得自己老了、无趣了,一旦年轻人察觉到我们的感觉,他们就喜欢装腔作势,让我们觉得自己不行。我鼓励他,安慰他,他也听进去了。他承认,年轻人的事没有什么大不了,但他觉得自己已经无法胜任目前的工作了,他觉得越来越费劲,并且从来也没有过乐趣。他问,有没有可能在别处找个工作,我能不能帮他,我不是有一些朋友和关系吗。
我的心刺痛了一下。我十分愿意为他做点事,十分愿意受到他的拜托,可是我太清楚,他说出这话有多难。他这样来找我,心灵一定极端痛苦。很显然的,在这儿他已经无法忍受下去了,无论如何都要走——但是,为什么他又那么害怕被辞退呢?
我又开始安慰他,答应他,一定会为他想办法,不过我也提醒他,如今找事不容易,到处都在裁员。在没有找到合适的事情之前先不要辞职,他还得养家糊口呢。想到这一点,他好像被吓着了,希望当做什么也没说过。可是我坚持要他把心思都说出来。这时他说,他只希望离开这里,离开这办公室,随便到哪儿去都行,也不一定做秘书工作,钱少一点也无所谓,比如做办公室勤杂工或者货仓看守都行。
他心灵的痛苦我很入心,我安慰他说,以前也有过不少次,看似前面已无路可走,结果还是都走过来了。我说,我在这里的这些天里我们要好好商量他的事,如能定下计划,我一定会帮他的。他同意了,脸上郁结消除。晚餐的铃声响了,我们一起去吃饭,喝了点酒,聊起从前的事,汉斯轻松起来了,还有点高兴的样子。大厅里有棋盘,我们坐下玩儿时玩过的游戏,我们没有小时候玩得好了,不过棋盘和棋子、手的动作和思考的模样把我带回童年,几十年没有想起过的事物,比如我们巴塞尔老家橡木饭桌的气味,那时我的一个玻璃球里的小白羊,等等,啊!那遥远的生机勃勃的世界,我们童年的原始森林!见到弟弟输棋时脸上显出的孩童般的惋惜神情,我感觉到,他也有点着迷了。逝去的时光带来多少甜蜜啊!
汉斯像往常一样早早就告别了。我回到房间去,刚才的一点轻松快乐一扫而光,我忘了我们的晚餐和棋盘,耳中想起弟弟压抑的声音,这是多年来我没有听过的声音。情况真的很糟糕,我马上感觉到弟弟陷入生命的严重危机了。他又怒又怕地谈起办公室里的年轻人,好像他们真能够控制他似的!这已经有点跟踪狂的影子了,还有他来来回回又想辞职又怕被辞退,这也不是好现象。他情愿做办公室勤杂工,这一点我不觉得是病态,倒觉得是正面的想法。我开始翻来覆去地想,能够在哪位朋友那儿为他找个职位,可是没有一家不是老早就在裁员,没有一个不在为他的职工发愁,特别是为那些有家的职工。就算找到个事,在一个人家不认识他、又没有二十年工龄的地方,他能够维持多久呢?不管留下或者离开,我知道,弟弟现在陷入他的老敌人手里了,这就是对自己的怀疑、对复杂而残酷的世界的恐惧。我躺在床上,久久不能入眠,后来疲乏了,只见到弟弟抬起童稚的脸对着我,那张我打他时他对着我看的脸。这张脸一直陪伴我到入眠。
接下来的几天里,出乎意料来了许多工作,我整天和信件、电话打交道,还有访客不断,等我匆匆和汉斯见一面时,又有别人在场,他也不像那天晚上那么压抑和激动。我们没有多谈,可是我心里仍然很为他的事着急,我决定,不把他的事解决好就不离开。汉斯身上的危机情绪,如果不是正好也存在我自己身上的话,我就不可能那么清晰地感受到。当时,我的存在从外部和内部同时受到威胁,使得我也能够见到他人身上类似的情况。多年来对我少言寡语的弟弟,现在肯把心思都告诉我,大概也是因为他感受到我的状况与他相似吧。
在这困难的时日里,有件事令我很高兴,有个周末我的两个儿子来了。他们是星期六到的,我要他们和我一起去看望他们的叔叔,我想,这说不定会令他兴奋、令他惊喜。我们到的时候,汉斯和他妻子还有他们的大孩子都在,小儿子作为交换学童在瑞士法语区一户人家那里,那家的儿子则在汉斯家,他来学德语。我的儿子同两个男孩聊天,我和汉斯坐在长沙发上。汉斯很友好地听着我们闲聊,可是可以看得出,经过一星期的工作,他已十分疲倦,我看见他不时偷偷打哈欠。他看起来心境相当平和,样子疲惫,脑子里空荡荡,但是并不烦恼,他有点冷,站起来好几次,到正要熄灭的炉边,把手放在烟囱上取暖。我们坐了一小时,告别的时候,他还是站在炉边,双手放在烟囱上,他疲惫、友善的脸弯向前方。此刻,我还见到他冷得有点发抖、疲惫地站在炉边,显然在等待晚上上床休息。
没有任何预感告诉我,我再见不到他了。相反,这次拜访麻痹了我对汉斯的忧虑,他温和的疲倦、他的哈欠、他安静地站在炉边半睡半醒的样子好像传染了我。这天黄昏时刻,我既见不到抬起脸控诉着的小汉斯,也见不到工厂灰色人流里的汉斯,又见不到最近在我旅馆房间里用那么压抑的声音对我讲述心中苦恼的汉斯。我只见到了平日的汉斯,见到星期日的汉斯,他高兴明天是星期日,就像我高兴明天和孩子们度过一样。没有任何不安警告我,要我后天把汉斯约到旅馆来谈他的问题。我们三个人就这样走了,过了很愉快的一个晚上和一个星期日。
几天后,我还穿着睡衣和拖鞋坐在小书桌前写信,有人敲门,告诉我楼下有位先生要见我,那是一位牧师。我换了衣服下楼去,见到阅览室里坐着一位白胡子的先生,第一眼我就看出,这并不是一次礼貌性的拜访。他自我介绍,是汉斯所属教会的牧师。他问,汉斯今天到过我这里没有,我马上知道事情不好了,难受和惶恐占据了我的心。他告诉我,这天早晨,汉斯比平时早出门,天虽很冷,他却没有穿大衣,一小时后,办公室来电话问他的情况,因为他没有去上班。我把汉斯告诉我的事讲给牧师听,这些他都知道,他知道的比我多。汉斯害怕被辞退,那是他想像出来的,在汉斯来找我之前,他已找过上司,人家向他保证,不会辞退他的。他来找我的时候把这给忘了,或者不相信那是真的。我向牧师讲了弟弟少年时的一些事,他点点头,他对汉斯认识很深,对这事的看法与我相同。我们都十分担心,不过我们不往最坏处去想,我们主要想到我弟弟的妻子。我们暂且假设,汉斯在林子里跑,在那儿挣扎着、诅咒着,等他跑累了,就会回家去。我不知道,是企盼的力量还是狡猾的直觉,使我不但能够劝说汉斯勇敢的妻子保持希望,自己也能相信,失踪的人会回来。我信任汉斯身上的童稚气和信仰,他接受政治和社会现状,即使他是这现状的牺牲品,他也承认神的秩序,他不会消灭自己的生命的。他会带着他的沮丧和绝望在林子里,在乡间大道上跑,把自己弄累了,一天,说不定两天,他就会回来的,会平安回来的,至少身体会没有问题,因为我们两人都知道,他精神上出问题了,他的妻子比我还清楚。她对我讲述了最近发生的几件事,显示出他精神上的问题,她也证实了,他不相信厂里会留他,他们的保证只让他安心了一会儿。
她还说,昨晚上床前,他没有自己做晚间祷告,而是请她做的。只在最后说阿门的时候大声跟着说。今天早晨他比平时起得早,他走的时候,她还在床上,后来她才看见他把大衣留在家了。这真是太不可思议了,他怎会做出使她如此担心害怕的事,他一向什么事都顾虑到她的,他的精神一定错乱了。
那天晚些时候我再去汉斯家时,仍然没有消息,白天里他的儿子骑着自行车已经找遍这一带了,我们商量后决定报警。那天天气非常冷,晚上回旅馆的时候,雪花飘落了。我觉得很冷,想到汉斯,我的心压抑得厉害,对他、对我们这都将是严峻的一夜。这一天夜里,我弟弟家灯火通明,暖和的房间里总有人坐着等他回来。弟媳妇的姐姐来陪伴她,在这忧患的时刻弟媳妇表现得很坚强,很勇敢。
夜过去了,灯熄灭了,灰暗冰冷的早晨降临了,汉斯仍然不见踪影。我的妻子也来了。我们坐在旅馆里,想着做点工作。这时来了访客,那是一位最近几天刚通过信的年轻诗人,现在他想认识我。来得真不是时候。我们跑来跑去、到处打电话已经三十个小时,这时已不抱任何希望了。我们到楼下大厅见客,虽然我们一点也不想聊天,但是这个年轻人的诗我们不久前刚读过,并且很喜欢,有他中断这可怕的等待也未尝不好。他从苏黎世来,带着一位共同的朋友的问候,我们像喜欢他的诗一样喜欢他本人。可是我们在一起还坐不到半小时,我就见到玻璃门外有人来,一位脸有愁容的白胡子先生,原来是牧师。我很快迎向他,他一面和我握手一面说:“有消息了,他们发现您的弟弟了。”我看着他,已经明白了。“他已经不在人世了。”他说。警察在离路边有点距离的田间找到了他,就在离家不很远的地方。从前那把手枪早就没有了,一把小刀就足够了。
汉斯十七年前结婚的时候,我这个兄弟姐妹中离开家庭最远、和家庭最疏远的人,有机会作为家中惟一的成员参加他的婚礼。我并不情愿去参加那个庆典,对于一切称为家庭、婚姻、市民幸福的东西,我都极为怀疑。然而,那一天,我感受到,我和汉斯同属一族,是同胞兄弟,这给了我很大的力量,从婚礼回来后,我为汉斯的幸福满心欢喜,也加强了自己生活的勇气。这一切在他的葬礼上又重复了。这一次,也没有哪个兄弟姐妹能够来。这一次,我也觉得没有人比我更不适合作为兄弟代表家族站在棺木旁。这一次我也是不情不愿地接受了任务,而结果和我想像的大不相同。
那是11月最后的一天。雪已停,毛毛雨落入灰暗的早晨,坟墓四周湿漉漉的泥土闪闪发亮。汉斯躺在他的棺材里,脸上带着笑容。封棺后,棺木就入土了。我们撑着雨伞站在草地上,送葬的人很多。教堂合唱队来为他唱告别歌,接着白胡子牧师站出来讲话。如果说诗歌合唱很美,那么,牧师的告别词就更美了。我不完全分享汉斯和牧师的信仰,这一点,此时一点意义也没有。这是哀伤的典礼,然而它是典礼,是一次温暖、尊严的告别。来了许多人,有的人在哭,我不认识这些人,他们大家都认识汉斯,喜欢汉斯,有些人多年来同他交往颇深,对汉斯说来,他们比我对他更有意义,然而我是惟一一个来自他的家族的人,惟一一个在记忆中保有他童年轶事,知道他所来道路、了解这一道路的人。越往回走,我越了解。我们苏黎世的堂姐也来了,汉斯从前每到星期日必到她家去,他曾是孩子们的好叔叔、好玩伴。两个孩子也同我一起站在墓旁,他们现在早已成人。牧师说完阿门之后我们还久久站着不动,我从许多人的话中听出,汉斯享有他们的爱,他童稚的魅力吸引他们。一切比我知道的多得多。如果我有幸喜好我的职业、能够为一种比较高尚的工作服务,那是我用很大一段生命换来的,或许用了太大的一段,而我不敢希望,将来在我的墓旁会照映着如许的光辉,回荡着如许亲切的爱意。我又看看这个坟墓,和它告别。我原先有点害怕的葬礼很快就过去了,快得奇特,也美得奇特。最先我看着棺材时产生了一种羡慕之情,那是年纪渐老的人看着长眠者偶尔会有的感情。这时,这种感觉也消失了。我同意这一切,我知道小弟弟得到安息了,我自己也做得对。如果没有一起经历这担心害怕的几天,如果不曾站在这墓旁,我就疏忽了许许多多宝贵的人生经历。
[写作杂谈][[音乐,美术之类,跟写作有啥关系?(附:拼接段落一) - 知乎|https://zhuanlan.zhihu.com/p/24454843]]
-----
[写作杂谈] 音乐,美术之类,跟写作有啥关系?(附:拼接段落一)
时隔许久,不聊写作技巧,不聊写作方法。我们说点别的。本篇之中大概会涉及很多人好奇的 “文字节奏”、“叙事节奏”、“文字色彩”、“叙事色彩” 之类的东西。
其实艺术是一个还算是完整的门类,准确的说,实际上的一切东西应该都是想通的,当然有人提炼出那些想通的部分,并总结成方法论,他们就是哲学家。
不过我们不是,我们还是浅显的瞎说一会。
音乐和写作
其实我还真是学过音乐的,恩从小学特长的那种,项目是——唢呐(就是完全没有给气质加分的那个)。不过说起来我也不知道为啥,懂乐理,耳朵也没太大问题,就是唱歌不准。不过这并不影响音乐在我写作上提供的帮助。
节奏感。
很多人好奇 “节奏” 这个东西。其实节奏这件事在文学很难解释,当然在音乐上解释就方便多了。大概节奏很多人觉得就是 “动次打次”,写东西难道也要“动次打次” 吗?是的,写东西也需要节奏。只是节奏在写作之中很多人说的都是文字节奏,什么长短句搭配之类的。而我再次主要要提及的是“叙事节奏”。
我们常常说节奏很玄学,但是实际上还是有据可循的。所谓的叙事节奏一般就是指轻重缓急,错落有致,当然高级一点还有可能涉及 “复调”...(唉我操,怎么从轻重缓急一下子就到了复调了)。
其实多听点交响乐并且学点乐理是很有助于写作的,“复调”简单来说指的就是 “多声部” 嘛,而在叙事之中是不是就是多叙事线呢?多叙事线的各部分独立行进并且相互重合呼应,其实就是复调。当然这一般也是一种结构方式。那么牵扯到单独叙事之中的节奏又是什么样子的呢?
其实单独的叙事节奏我们一般就是指在叙事时的紧张感和舒缓感,在一般情况下往往紧张感和激烈场面是重合的,舒缓感往往跟抒情场面是重合的。但是实际上,紧张感不一定需要激烈场面,舒缓感也不一定和抒情场面有关。这需要我们考虑到叙事方法,而这种再细节的叙事方法则需要我们回归到一个之前很重要的名词——“集中”。
而紧张感的营造一定是集中的!在叙事节奏之中,场面上越集中,事件和情感发展越迅速约紧张。这跟场上是不是就一个人坐在车上看着窗外划过的树没有什么关系,有可能这种紧张感来自己于人物的内心状态。而抒情场面往往集中度会相对更低,场面上的事件相对少一点,发展速度也相对缓和一些。
而有机的组合紧张的场面和舒缓的场面就是叙事节奏。这个有机我们可以分为两个部分
1. 作品所需。
作品所需就是这个作品其本身的需求,整个作品可能本身就是一个舒缓的民谣请不要将其弄成黑金...
2. 受众所需。
在中长篇叙事之中,我们需要考虑受众的阅读观看感受,连续的舒缓场面让人难以提起阅读的兴趣,而连续的紧张场面则往往让人难以忍受。
考虑受众所需的前提是满足作品所需,请不要因为受众喜欢黑金,就将民谣变成黑金。
绘画和写作
绘画其实是一个结构很重要,色彩,构图也很重要的东西。结构就不说了,结构之于写作其实最好的借鉴方式是 “建筑”。
那我们说说色彩好了,写作一样需要考虑色彩感。很多人说读一本书一个作品感觉到有种浓烈的色菜,有的作品有种灰色的质感。这其实就是文字反映出来的色彩感知,当然色彩在音乐中也有一种相似的反应。比如 bB 这个音,往往具有一种蓝色阴郁的感觉。而在文字之中我们不能用一个字或者一个词来表达一种色彩感知。
往往文字色彩是由段落或者说整体来呈现的,文字的色彩感更为抽象。但是我们一定要注意,文字色彩绝对,绝对不是我们对色彩的描写,而是文字本身呈现出来的一种质感。比方说杨显惠的作品往往透露出一种土黄色的质感,那种陕西荒凉的黄土地的色彩。而相对的李娟的散文则具有一种低饱和度的淡绿色质感。而我自己写东西常常有一种灰色度的感觉,死气沉沉的。
其实文字的色彩比节奏更加玄学,但是同样我们也可以稍微的解释一下。文字的质感往往来自于叙事时对于事件动作等其他部分的描写来体现。如果相对轻快的描写,那么往往文字的质感会相对偏亮,相反如果粗暴而简单则往往文字的质感偏暗。当然这也和同一事件之中所选择描写的部分有关。
以上言论仅属于个人感知... 不具备任何价值,看看即可。
其实艺术往往具有相通性,同样的这背后的原因大概来自于美学(哲学的二级学科)。所以丰富艺术的多角度认知和思考往往对于我们写作是有说不尽的好处的。在电影里面有个大师叫戈达尔,有兴趣的可以多看看。
其实艺术上升之后还是十分抽象的,所以想要提高自己的写作水平在哲学上也不能放松哟。当然写作的技术还是很朴实的,但是说实话,我个人并不认为写作技术是一个特别大的难点,毕竟东西就是那些东西,而且钻研写作技术是很苦很累很难的。拓展边境这件事又那么麻烦,我是没有那个本事了。
-------------------------------------------------------------------------------------------
拼接段落一
北方的天气远比南方要干燥的多,特别是入冬之后。
张三在南方住的时间长了,越发不适应家乡的空气了,要是落到一个好事之人的口中,张三这个流氓一定会被指认 “忘本”。
刚刚回到几年不曾归来的北方故乡,张的小腿上就因为干燥的空气而生起了一层如癣似的干裂硬皮,瘙痒难耐,只能天天涂上一层厚厚的乳液,勉强熬着。好在医院里面卖着七块五的维生素 E 乳,让张三的钱包不至于彻底宣告死亡。
不过,还是要承认一点。人,是很容易忘记过去,获得新的习惯的,张三同样是这样,长时间同一家早餐铺的包子和小米粥成为张三新的习惯。但是谁知道这到底是不是他仅仅拾起了几年前的习惯而已。
早餐铺开的很早,张三不知道早餐铺具体几点钟开门,但是他只要醒了或者凌晨的时候饿了,随便套上件外套走到早餐铺,一定能吃上一屉包子。
一屉包子加上一碗小米粥只要八块钱,在这个年代算是十分便宜的。但是那个早餐铺的卫生环境也确实堪忧,不过优惠的价格也确实让它每天早上都塞满了人,几个服务员的完美配合也常常搞不定最忙碌的时候。
早餐铺的老板娘是个消瘦的女人,消瘦的脸上透露出一股子隐约的刻薄,但是实际上张三从来没见过她发过火,反而十分的好说话。也正是如此,张三更加认定,老板娘是个刻薄的人。一天早上,张三吃完之后,忘记带钱,老板娘十分好说话的告诉张三没关系,于是张三就满心忐忑的走了。走在回家路上的张三已经想象出了老板娘今天一整天的不高兴,还有她一整天都会担心,“这个看上去就不靠谱的张三如果为了贪这八块钱的便宜,以后就不来的怎么办?” 的表情。
好在习惯没那么好改变,张三第二天还是毕恭毕敬的将钱递到老板娘的手上。老板娘结果钱的时候,嘴上说着 “没关系,没关系。”,但是张三还是从她的脸上看到了那么明显的放松和欣喜的表情。就如,偷渡到澳门,走进赌场,领了彩钱,玩老虎机,最终不赚不赔,又那么出来的轻松和欣喜表情。
这个小小早餐铺有很多固定顾客,一群同样早起的扫大街的、一群附近修路的农民工、一个拄着拐靠挪的糟老头、一个胖的不可救药的初中生、一个不知道是不是暗门子的女人、一个叫做张三的臭流氓。
当然更多的是不固定的客人,比方说旁边那家挂着三星级,实际上破烂不堪,导游定团购价格极低的旅馆里的旅客。大巴停在门口,导游扯着嗓子喊人,旅客们就拼命似得将包子塞进嘴里,来不及下咽就匆匆赶出去。老板娘面对成群的旅客,总是先收费后上饭的。算起来,这里一定是 “光盘行动” 的模范单位。
而张三常常看着一群带着口罩往大巴上赶的旅客,心中少不了一番讥讽,然后抹抹嘴巴,不戴口罩地走出门去,随手点上一支烟,为大气污染再做一番贡献。
一支烟的时间,刚刚是从早餐铺走到自家楼下的时间,上楼的时候张三总会下意识的抬头看看电表是否亮起,如果亮起说明电费又不足了,也说明这个月后面的几天不能每天去吃包子了。在停下看电表的时候,他一定会隔着两条裤子挠挠自己的小腿,如果忘记了,那么一定会在开门的时候挠。但是他不会在吃包子的时候挠,那时候挠是对包子和小米粥的不尊重,所以多痒他都会忍着,按照张三的话叫做,
“从小流氓到大流氓的路程总要付出一点代价,而代价就是看上去没那么自由。”
——————————————————————————————————————————
卖萌时间。
首先免责:以上文章全是我瞎编的,看个乐呵就行了... 千万别太当真。
唉,真的是拖了很久,一来是快年底了手上的事很多,二来是这个拼接的小段子实在是不太好写,所以这个部分实际上写的很渣... 当然也是一次成型,懒得修改。
然后我有点纠结后面还能写什么?再往后专栏文章的话,可能就真的要写 “元素削减” 了... 可是这个,有点麻烦,而且也有点...“先锋”了。
或者就是把之前的东西细化,深入,但是细化深入这个事我怕懵逼的人更多... 特别是专业阅读不够,写作量更不够的朋友们...
好吧,我承认是我有点吹逼吹不下去了... 唉,如何是好啊。
全文完
本文由 简悦 SimpRead 优化,用以提升阅读体验
使用了 全新的简悦词法分析引擎 beta,点击查看详细说明
[写作技术][[引发读者的“欲望” 附:拼接段落三 - 知乎|https://zhuanlan.zhihu.com/p/27292098]]
============================
----
[写作技术] 引发读者的 “欲望”| 附:拼接段落三
如果把一篇文章比作一个女人,那么我们需要让这个女人能够吸引别人,最好能吸引男人还能吸引女人,能让神奇魔法师更进一步;也能让情窦初开的小男生心猿意马;最好能能让一个久经沙场的老手同样深陷其中,欲罢不能。
在很多时候,这一切都先落在 “阅读感” 上面。当然,这个有办法训练,但是就我个人而言,其最有效的训练方式就是“使劲写”,写的多了自然文字的流畅度会好一点,至于如何更好的效果就需要多读点好书(安利阿城),然后体会体会了。不过我们还是再度提出一个前提:准确,是让文字变得更有阅读快感的基础。
那么我们还是回归:是什么,为什么,怎么办。
是什么
引发读者的 “欲望”,当然没有那么浪,所谓的“欲望” 分类很多,贪嗔痴恨爱欲情仇都算是欲望之一,从广义的较多来说,这个目的是为了引动读者对于事件的 “共情”,产生“移情作用”。从局部的描写来说,需要通过文字进一步引出读者对于文章所描述事件的“欲望”。当然一般来说,我们这个“欲望” 往往指的是“好奇”。
为什么
为什么这么说呢?“好奇心”实际上是让人阅读的一个很本源的原因,不好奇谁没事去看那些书啊,我宁可去喝酒打德州扑克。基本上无论什么文体都有吸引读者 “好奇心” 的必要,一个读者就算是读一本社科书,哲学书也是包含着对其所描述观念和事件的好奇的。(当然我们只说自发性阅读,被迫看课本这件事请忽略。)
所以,想要引发读者的 “欲望” 必须要让读者的好奇心被激发起来,而且最好强烈的激发出来,让读者产生联想,因为文字是毕竟是虚幻的,我们需要借助于描述让读者有概念,有倾向,有想象才能让读者产生进一步的好奇。
简单举一个例子,“食欲”,让我们请出汪曾祺老先生。
北豆腐切成厚二分的长方块,热锅温油两面煎。油不必多,因豆腐不吃油。最好用平底锅煎。不要煎得太老,稍结薄壳,表面发皱,即可铲出,是名 “虎皮”。用已备好的肥瘦各半熟猪肉,切大片,下锅略煸,加葱、姜、蒜、酱油、绵白糖,兑入原猪肉汤,将豆腐推入,加盖猛火煮二三开,即放小火咕嘟。约十五分钟,收汤,即可装盘。这就是 “虎皮豆腐”。如加冬菇、虾米、辣椒及豆豉即是 “家乡豆腐”。或加菌油,即是湖南有名的 “菌油豆腐”——菌油豆腐也有不用油煎的。
——汪曾祺《豆腐》
来看看,这个老餮,吃个豆腐都让人欲罢不能。这里是好奇什么?你就不好奇那个豆腐到底是什么味吗!不好奇是什么味吗!什么味吗!
而再看这老餮,并没有详细的描述这个豆腐到底是什么味道,而是描述了这个豆腐的原料和制作过程,剩下的就靠读者想象脑补了。
怎么办
好了重头戏来了,开不开心。上面提到了一个很重要的点:准确!
准确,提出无数次的一个词,反正我是做不到很准确的描述。想要让作品的描述足够准确是需要很深的功力的。不过我们可以想想办法,来拆分一下怎么做到准确的描述。
选择合适的信息和角度。
选择合适的描述手法。
选择合适的信息和角度
我们依旧以汪老餮为例,他选择的是原料和制作过程为信息来进行描述。而没有选择更直接的味道描述,其原因一部分是来自于,酸甜苦辣咸鲜几种味道,如果想要进一步的描述就需要选择具体食材的味道来代替描述了。那么就回到汪老餮的写法上了,而且他的角度是具有发展性描述的,从制作的手段和食材味道的叠加,让读者对这道豆腐的滋味有一种逐渐复杂和逐渐具体的发展过程。
读者不容易体会复杂的感觉,简单描述的感觉往往在读者的心中是单薄的。但是,相对的读者更容易体会到具象化的感觉。人的联想力首先会倾向于自身经验,之后才是进一步的延伸概念。
简单来说:香菜——香菜的味道——特别——喜欢 / 讨厌。
而作为文学作品,我们最为有效的描述是前两步的描述。过度的延伸描述必然带来拖沓和阅读感的下降。
而从角度上来说,汪老餮选择了制作的过程来描写,而不是选择吃的过程来描写。一方面是来自于作品本身的需求,选择这个角度来写更为适合这个作品。而如果是想要写一个男人和一个女人的情感的话,很有可能会选择女人在吃豆腐时候的描述。
另一方面,这种写法可以更为清晰和直观的表现出味道的质感和变化,并且会进一步的引发读者的另一种好奇,其是怎么制作出来的。
选择合适的角度的基本需求是为了更为有效的完成描述目的,选择更契合作品需求的角度来写是更为有效和准确的,而信息的选择也同样。
选择合适的描述手法
描述手法分很多方面,包括文字风格、详略选择、悬念营造等等。文字风格之前说过,如果有问题请回顾之前的文章,详略选择和信息选择重合,悬念营造的目的实际上是进一步加强读者的好奇心。
但是对于描述的手法上,还有一点特别重要,如果想要引发读者的兴趣和欲望,需要做到非常重要的一点。很多时候,不要描述的过于清晰,需要给予读者脑补的空间,一般情况下,过于清晰和复杂的描述往往会限制住读者的脑补能力,要给读者 “一想之美” 的空间。所谓的描述中的详略得当也不过如此,所以准确的描述在这个时候也尤为重要,也就是为什么很多时候白描的练习很重要,选择最为重要的点来准确描述。
尽量选择带有动势的描述方式,过于描述稳定的,平面化的场景十分容易让读者产生乏味的感觉。动势的描写更容易引起读者的联想,变化的,发展的描述会让读者的联想更具有持续性。而平面化的,详细的描述确实更具体,但是人并不习惯于对于一个场面进行过于详细的联想,同时具体化的联想更容易消耗精力,而且过于浪费精力的联想则会让读者更快的失去乐趣。所以选择动态的、变化的描述会更为有效。
动态的、变化的描述,不仅仅局限于作品中人物的行动,事件的发展,还包含着视角的变化。这就是大家读书的时候都知道的按照一个顺序描写场景:上面,中间,下面之类的。但是如果是按照这种描写方式来说,依旧十分乏味,依然十分的平面化。
这个时候,我们可以借助于人物的视角来描述,让读者带入人物的视角,这个时候就会有效的多。同时如果这么做,一定要对信息做好选择,而且最好让其描述对象本身具有吸引力,比如其背后具有着危机、问题,或者期待,这样可以让读者更容易被吸引。
至于对准确有更进一步要求,就真的只能靠多读,多写了。毕竟有的时候,详细的具体的平面化的描写可以体现另一种需求,只看是否契合作品本身。而更为具体的句子排布,用词选择等等真的我没有什么特别好的办法,这个我认为只能靠练或者靠天赋了。
然后我们回到 “欲望” 这个事。
如果想要引起读者更为直接的欲望,比方说性欲、食欲什么的该怎么办?
简单来说,就是要吸引读者的生理需求,而引发读者的生理需求,无非就是给予其相应的暗示。但是方式一样,通过更容易联想到的东西进行描述,会更好的让他们产生生理反应,而突出细节的描写也可以让人更好的有更好的联想。但是这里要提出,在需要的地方突出细节描写,而不要全部都将细节描写的无比详细。当然把握这个度,还是有些困难的。
——————————————————————————————————————————
拼接段落三
有那么一天,张三不知道从哪搞到两张票子,决定去咖啡厅装一个上流人。
他手里攥着两张票子,想着自己能够去什么样的地方做上流人,他一年到头只有白色的老头衫、破烂牛仔裤和一双拖鞋,如今更是因为穷的要死而让头发长得如同一窝杂草。张三也不知道上流人什么样,毕竟他的周围也没有上流人。
不过一个温暖的下午,游荡于路上的张三看到了一家开在地下室里的咖啡厅,他想,这样的地方一定是最适合的自己的。怀着忐忑的心情,张三走进了这家店。
店里面没有人,只有一个看上去同样邋遢的男人窝在角落里面,这个男人看到进来的张三,没有任何反应。张三猜测这个人也一定是个跟自己一样的顾客,这让张三感觉自己找到了适合自己的地方,只是这地方张三大概也就只能来一次了。
张三找了个地方坐下,另一边的男人不为所动,他们就这样尴尬的坐着。
沉默,除了咖啡厅播放的张三听不懂的音乐之外,没有其他的动静。
就这样,两个人一言不发,什么都不做,如同舞台上的静默,是对无趣社会的强烈不满与讽刺。可惜的是,张三只是因为不知道该怎么叫一杯咖啡,而男人看惯了只是进来看看的路人。
紧贴着地面的小窗,透露着太阳落下,路灯亮起来。
两个人一如既往的沉默,哪怕男人给张三递了一杯水,张三回答了一句 “谢谢” 都没有打破这种沉默。
张三多么希望,能来一个顾客,这样自己就可以学着顾客的样子装一个上流人。
就这样沉默到,男人告诉张三,这里要关门了,也没有另一个活物走进这里。
临走的时候,男人对张三说,“你今天穿的很不错。”
张三这个臭流氓就在这个时候觉得,这个男人,这个地方真不错。
——————————————————————————————————————————
卖萌时间。
我一个习惯性拖稿,弃坑无数,懒癌晚期的家伙又更新了,惊不惊喜,意不意外,难不难得。
我不得不告诉大家,我每次说自己忙,其实就是因为自己懒。
还有两个事情。
第一件,最近有个公众号 “演员经济汇” 抄了我的一个回答,然后我就去让他删稿了,不过我看不少回答被抄... 所以有关编剧表演之类的作者们可以去看看有没有自己的东西被抄。
第二件,我家这边吧,有个咖啡厅,天天就只有我自己,导致我害怕他某天就倒闭了,我喝咖啡赶稿就要去更远的地方了... 所以我决定在这搞个线下小活动,聊聊怎么写段子也行,聊聊书也行。恩,免费,地方在北京东三环潘家园这边,不过我还是想要看看有没有人愿意来,我在考虑这个活动是不是有的做。恩,咖啡厅老板是个清华毕业的建筑师...... 有兴趣的可以评论,也可以私信我,因为我就是那么一想而已。
如果有想来扯淡的人... 我再定时间好了。
好的就是这样。
全文完
本文由 简悦 SimpRead 优化,用以提升阅读体验
使用了 全新的简悦词法分析引擎 beta,点击查看详细说明

根據最新消息,英特爾下一代 GPU 架構「Xe4」日前在 Git 開源程式碼庫中曝光,顯示英特爾仍積極投入獨立顯示卡(獨顯)市場的研發,並在新架構開發上已有具體進展。
訂閱T客邦電子日報 掌握最熱門的科技話題、網路動態,升級你的科技原力!
自 Alchemist 專案(即第一代 Xe 架構)問世以來,英特爾的 GPU 發展雖較為低調,但根據此次曝光的資訊,Xe4 將被應用於代號為「Druid」的新一代獨顯產品上,代表英特爾並未放棄在競爭激烈的 GPU 市場中繼續站穩腳步的決心。

從架構世代命名來看,Xe 架構起初被定為第 12 代,接續為 Xe2(第 13 代)、Xe3(第 14 代),而這次的 Xe4 則被標記為第 15 代架構。
本次資訊來自 Linux 補丁與開源社群的代碼提交紀錄,這類曝光通常發生在 GPU 開發初期,雖然不一定代表最終產品的完整規格,但足以顯示英特爾已正式展開新架構的相關工作。
目前,基於 Xe3 架構的 GPU 正進行預矽驗證階段,預期最快會於 2025 年下半年隨「Panther Lake」處理器系列一同亮相。而最新的 Xe4 架構顯示卡則預估要到 2026 年才有機會正式推出。
事實上,早在 2024 年 12 月,英特爾 Xe 顯示卡發言人 Tom Petersen 就曾表示,Xe3 GPU 的 IP 設計已基本完成,當時軟體團隊正忙於相容性與驅動開發,而硬體團隊則已開始進入下一代產品(即 Xe4 架構)的前期設計工作。
儘管目前 NVIDIA 與 AMD 在消費級與專業級獨顯市場仍佔據主導地位,但英特爾顯然沒有打算退出戰局,未來數年內我們或許能看到更具競爭力的產品問世。
- **延伸閱讀:[Intel 第二代高階顯示卡 Arc B770 傳將於 Computex 2025 亮相,對決 RTX 5060](https://www.techbang.com/posts/122996-intel-arc-b770-computex-2025-vs-rtx-5060)**
- **延伸閱讀:[Intel 下一代 Arc 獨立顯示卡可望採用 GDDR7,效能潛力大增?招聘啟事洩天機](https://www.techbang.com/posts/122713-intel-celestial-gpu-gddr7-memory)**
[#顯示卡](https://www.techbang.com/tags/29)[#NVIDIA](https://www.techbang.com/tags/30)[#AMD](https://www.techbang.com/tags/46)[#gpu](https://www.techbang.com/tags/424)[#獨立顯示卡](https://www.techbang.com/tags/3587)[#獨顯](https://www.techbang.com/tags/8221)[#英特爾](https://www.techbang.com/tags/17134)[#panther lake](https://www.techbang.com/tags/39936)[#架構](https://www.techbang.com/tags/44671)[#druid](https://www.techbang.com/tags/46916)[#xe4](https://www.techbang.com/tags/52019)

卢曼的笔记类型分为四类:临时笔记、文献笔记、永久笔记、项目笔记,我们按照写文章的步骤来逐一讲解这四类笔记。
步骤一:[[Fleeting Notes 临时笔记]]
{{Fleeting Notes 临时笔记}}
不要在意你是用什么写下来的,或者写在什么上面,不要被这些细节分心。你只需要把它们统一放到一个地方,也就是你的临时笔记收集箱,稍后处理它们。
步骤二:[[Literature Notes 文献笔记]]
{{Literature Notes 文献笔记}}
''注意!这一步的关键是:用自己的话写
''
步骤三:[[Permanent Notes 永久笔记]]
{{Permanent Notes 永久笔记}}
这一步,你浏览一遍你的卡片盒很快就可以完成,毕竟那里面都是你感兴趣的东西。
''注意!这一步有两个关键点:''
其一:你要做的不是收集,而是激发思考:
# 这些笔记和你之前已有的想法或笔记相抵触吗?
# 可以改正或者支撑你之前的观点吗?
# 是否有新的内容可以加入你的知识库吗?
# 你可以把这些想法整合一下,产生新的洞见吗?
# 他们有没有触发新的问题?
“”“
他砸碎床头日历底下的小猪扑满(虽是不合宜的摆设,可他喜欢将小猪喂饱然后再砸碎,颇有时代的意义),举起了沉甸甸的,却只足够买一包烟。也不是说他的积蓄太少,而是香烟太贵。香烟像替罪羔羊,每当国家赤字高涨,征税总往烟酒方面挤海绵。若不是吸烟有助提神,保障驾驶安全,也是被舆论嚷嚷该被禁的份。
他到当铺典当信仰
政府推出利民政策
可以先将未来的养老金预支出来
他仔细推算
若能解决噪音问题
就能使他更有精力工作
预支出来的钱,很快就能填补回去
这显然是合算的投资
他发誓在招来修路工人的时候,并没有喝酒或嗑药,可是业务涉及政府工程的五金店的华人店主,在听完他的要求后,瞪大了双眼。然后恢复刻板的面容,估算材料,安排运达的时间,再介绍店里的外籍劳工前去铺设。计算器算出来的数字,带走了一半他刚提出的养老金。隔日早晨,卡车载着一车的沥青,加上开车的管工和两名外籍劳工。在原有的两道路墩之间,他嘱咐工人尽可能在介于间距一米,须谨守社交距离的宽度铺设路墩。直至所有的距离都规划清楚,并排的路墩都横跨路面,一共建构了十一道路墩,计上原有的两道,恰巧如国旗。他饶有趣味地将每一道路墩以州属的名字取名,其中一道距离较远的,命名为柔佛。
”“”
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [www.zhihu.com](https://www.zhihu.com/question/342288208/answer/1014951731) 爱故事推书
**目录**
**1.《满船清梦压星河》作者:白泽**
**2.《思北域, 宠青鸾》作者:木头弦**
**3.《夏夜树上有蝉鸣》作者:小狮 / 2.15**
**4.《一眼晴川》作者:云在意 / 2.16**
**5.《如珠似宝》作者:妩墨 / 2.29**
**6.《离人心上雪》by 绿亦歌 / 3.12**
**7.《小隐藏在盒子里》作者:岑桑 / 7.7**
**8.《没有人会像我这样爱你》作者:独木舟 / 7.25**
**9.《有些故事还没讲完,那就算了吧》作者:投我木瓜 / 10.07**
* * *
10.07
爱是天时地利人和才有的事, 出一个岔子都不行。

**9.《有些故事还没讲完,那就算了吧》作者:投我木瓜**
评价一个年轻的女孩最让人意味深长的一句话莫过于:她阅人无数。
我最近听到这句话是在一家常去码字的茶馆。闲着没事的店员聚在柜台边上讨论老板的新女朋友——一个名叫思悦的二十四岁女孩。
“我看了她的微博,据不完全统计,她跟老板好之前起码有过五个男朋友。”女店员说 “五” 的时候张开一个巴掌,激动的样子似乎要把这个巴掌轮流按在所有人脸上。
“其实是七个。”
坐在我对面的思悦笑着说。
我第一次遇到这样的女孩,可以果断地把个相处不过半天的人引为知交,并理所应当地把自己的经历坦诚相告。
“我交第一个男朋友的时候十八岁, 那时我为学习忙得灰头土脸。他是全校篮球打得最好的男生,他说他喜欢我,我不瞎也不傻,有这么帅的人喜欢我,为什么不和他在一起?在一起半年之后,我已经在想嫁给他那天要穿什么样的婚纱。要那种露出肩膀,裙摆很长很长的。可是没多久,他一声不响地又去喜欢别人了。我在篮球场死死揪住他的球衣,硬是要他说出不喜欢我的原因。他说,不喜欢就是不喜欢嘛,没感觉啦。我说好吧,然后放开了手,再也没和他说过一句话。
“进了大学,我陆续交过两个男朋友,都因为对方忽然没感觉而分手。那段时间真的觉得自己很惨,就学人家去酒吧买醉。第四个男朋友是在酒吧认识的。我那天戴了个棒球帽,后来喝多了把帽子弄丢了,看他戴个差不多的,就去抢,朋友拉都拉不住,最后他把帽子和他自己都送给了我。我们说好一毕业就结婚。毕业那天,我去民政局等,等到他们下班,等到整座大楼只剩下我一个人。
“其实早就有人告诉我他变心了,但除非他亲口对我承认不然我一个字都不信。没想到他那么窝囊。半个月之后,等我情绪稳定了,他约我见面。我也很窝囊,竟然做不到十八岁时那么潇洒,还在精心打扮图谋挽回感情。见了他,我没有开口,他倒先哭了。我还能说什么呢,在我奋力挽救我奄奄一息的爱情的时候,他却已经在用泪水为她哀悼。最终我们和平分手。就像有句话说的,你深深爱着的人,却深深爱上了别人,有什么办法。”
思悦说到这里忽然停住,拿起桌上的茶具,用新泡的茶烫洗茶杯,一杯接一杯。洗完最后一个杯子,她抬起头看我。
“很多女孩都热衷于一生一世一双人的爱情故事,连沈从文都说:我行过许多地方的桥,看过许多次数的云,喝过许多种类的酒,却只爱过一个正当好龄的人。以这个标准来看,我的故事真是俗到家了,你还愿意听吗?”
我说,好姑娘,我当然愿意。
她恢复了笑脸,继续说下去:“后来我去另一个城市做室内设计师,我的第五任男朋友是工作中认识的同行。交往没几天,他说我心里有别人,要分手。我说给我时间,我会慢慢忘掉,他说他没时间等。那时我们才二十二岁,我不知道他为什么那么着急。第六任男朋友也是以同样的理由分手。
“第七任男朋友是个内科医生。我那时工作压力大得感冒两个月都不好,换了好几个医生,最终是他治好了我。不过我觉得不是他医术高明,而是爱情的力量。他说,当我推开门的一刹那,就对我一见钟情,帮我测脉搏的时候,他心跳得太大声都快盖住听诊器里的声音。
这一次我很谨慎,提前告诉他我对曾经一份感情放心不下。他说他可以等。一年之后,我去见他爸妈,他爸妈很喜欢我,决定帮我们订婚我们订婚的请束发出去的第三天,他接到前女友的电话,原来在他不知道的时候他已经有了一个两岁的孩子。他前女友本打算一个人抚养,听到他订婚的消息还是受不了了。这段感情,又结束了。
思悦重新泡了一壶茶,我趁这个间隙发问,“你不介意别人说你阅人无数吗?”
“一开始介意,后来不了。” 她第一次害羞起来,“我也不想阅人无数啊,我从第一次恋爱开始,就抱着要和对方过一辈子的心情,但总是失败。电视里一再演一生一世的爱情,正说明这样的爱情现实中太少了,那是天时地利人和才有的事,出一个岔子都不行。那么我多谈几次恋爱,总会碰到一个能够和我一生一世的人吧。
“失恋虽然痛苦,被人讽刺阅人无数也会难过,但我不会因为这样就退缩。我没有对不起任何人,所以我无需在意别人的评价。想得到天长地久的爱情并不是件容易的事,我愿意,我也必须,付出代价。”
她笑着,我怜惜地握住了她的手,她有些意外,她不知自己此刻的笑容多么悲壮。思悦只是个一心想找到自己想要的爱情却又没那么好运气的女孩,世人冷眼旁观,以最恶毒的想法揣测她,她却安之若素。我想,这样的女孩,值得一份天长地久的爱情。
三个月后,我听茶馆店员说他们老板的恋情告吹。老板的妈妈不知从哪里听说思悦年纪轻轻就阅人无数,要老板和思悦分手。老板没怎么坚持就同意了。思悦在雨里等了一夜,老板始终没有出现。
在他们讨论老板如何绝情的时候,我打开微博看到思悦的更新,她拍了一张旅途中和一大群朋友的合照。照片中的她风尘仆仆,狼狈而憔悴,却依然用力地笑着,那张盈满了阳光的脸生动得几乎让人听到她的笑声。
她说:我行过许多地方的桥,看过许多次数的云,喝过许多种类的酒,爱过许多正当好龄的人,也有许多正当好龄的人爱过我。
* * *
**7.25**
> 很久以前看这个短篇的时候,一直不明白最后一句话,到底是什么意思?这句话到底有什么重要的?
> 在当时的我看来, 它好像并不具有什么大意义。
> 但在后来的时光里,当我想起这个故事时,我都会经常会想起这句话。
> 如果……,我愿意……。
> 我也不能说明这句话对我的意义,但是我总是会用这些字词在心里造句。
> 好像过去的事还有别的可能,好像还有别的路可以走,好像现在不必过成这样。

**8.《没有人会像我这样爱你》作者:独木舟 / 7.25**
如果真的有那样一座岛,我愿意永远都不离开。
[1] 陶然深爱梁静嘉
在我第一次见到你之前,我已经听说过你,很多次。
那年秋天,我们在小礼堂里为静嘉举行了一个小小的怀缅仪式。
礼堂的正前方挂着她生前最喜欢的一张照片,照片中她涂着大红色唇膏,睫毛的剪影落在墙上,脖子的曲线像骄傲的鸟,四分之一的脸淹没在阴影里。
她真是大美女,若干年后我看过许多姿色不俗的姑娘,但没有一个比得上她。
她的美丽以一种残暴的方式终止了我们所有人的眼界,就像是早早看过汪洋大海的人,不会对在一片湖泊面前啧啧称奇。
我无意间回了一下头,发现礼堂的最后一排坐着一个人,穿着黑色衬衣,脸上的神情„„我不知道该如何形容,极度平静,却又极度哀痛。
你当时的样子就像是被一把刻刀刻在了我的记忆中,往后很多很多年。
我低下头悄悄地问余意,最后一排坐着的是谁,
他回头看了一眼,低声回答我说,陶然。
陶然,这并不是我第一次听到你的名字。
我们这个小圈子的人都晓得,你家与梁静嘉家是故交,她比你年长两岁,你从懂事以来一直暗恋她,她不是不知道你对她的感情,多年来却一直只把你当朋友,当弟弟。
她在大二的一次活动中偶尔认识了那个男人,明知道他有家室,却也不管不顾地爱了。
你从南方坐飞机赶来与她理论,下机时冻得瑟瑟发抖却挤不出时间去买一件外套。
没有人知道那天发生了什么事,只是从那之后,你们便断绝了来往。
余意是你们共同的朋友,而那时我还没有和他在一起,之后我带着一点八卦的心思向他打听这件事的来龙去脉,可就连他也不知道究竟是怎么回事。
但有一件事情,我们所有人都知道。
陶然深爱梁静嘉。
每逢新年、圣诞,以及她的生日,你都会寄来礼物,每一样都东西都是她所喜欢的,你从不出错。
没有人知道千里之外的你是如何准确地把握着她的喜好、品位,还有多变的心思。
你诚意十足,并且执着。
我一直对你有些好奇,却没想到真正见到你,却是在这样的时间,这样的场合。
缅怀仪式结束之后,大家沉默着离开小礼堂。
余意牵着我,走到你面前时,他拍拍你的肩膀。你抬起头来看了我们一眼,目光掠过我时没有一丝情绪,我却仿佛心跳漏了一拍。
你那双眼睛深如寒潭,包罗万象。
你的声音有一点点沙哑,问余意,我当时不在国内,静嘉她究竟是怎么回事,
余意三言两语地将事情大概陈述了一遍,那男人的妻子使了些手段,加之这些年来,静嘉一直生活在失望与希望的交替中,早已经不堪重负,她曾多次流露出厌世情绪,但没想到真的会如此决然。
经年累月的煎熬和折磨,不处身其中是难以明白的,选择了离开,或许反而能让她平静安宁。
你沉默着,眼睛慢慢红了。
我回头看向那张照片,心里隐约有一个决断: 她会占据你心中一个无人能及的位置。
从这以后,你漫长的生命中或许还会爱上别人,但任你再怎么虔诚,也只能爱到七分。
[2] 从未真正在哪里得到过安慰和满足
那个夜晚的你,如同惊鸿掠过我的心间,却没有进入到我坚实的生活。
不久之后,我跟余意和平和分手,没有背叛没有欺骗没有第三者,我们坐在临街的餐厅里叫了焦糖布丁奶茶和一只十二寸的金枪鱼比萨,整个过程非常友好,没有人口出恶语。
我觉得这是非常大方得体的分手范本,只是,我没想到,最后他会问我,影白,你没爱过我对不对,
我拿着比萨的手十分尴尬地僵在半空中,过了三秒钟我才回过神来,笑着说,怎么会。
他的笑容里也有些意味深长,影白,我们相处的时间中,我经常有种黔驴技穷的无力感,好像不管我怎么努力都触碰不到真实的你。你从不对我提任何要求,也不介意我跟别的
女生走得太近,你不哭不闹不任性,所有人都说我有一个懂事的女朋友,但从另一方面来说,其实是因为你不在乎。
说到这里,他往前倾了倾,眼神直直地逼过来,到了今天,你可以承认了,影白,我不会怪你。
原本融合的氛围被打破了,我顿了顿,说,我不是不爱你,我是不知道怎么爱一个人。
我和余意就这样散了,不轻不重的一段青春,就这样不痛不痒地过去了。
再后来我想起这个人,只觉得模糊,温暖或者暴烈都没有,他在我的记忆中是那么清浅,我们共同的时光仿佛一律青烟。
他只是把你带给了我。
陶然,从你面无表情地望向我的那个瞬间,从我在那个瞬间的不经意颤抖开始,所有的情节已经铺展开来,只等命运一页一页地翻启。
与你重遇之前,日子就像白开水一样寡淡。
我有时候会一个人出去晃荡,在海边,在高原,在繁华的城市,我拍了很多照片,可是每一张上面都没有笑容。
我并不快乐,也从未真正在哪里得到过安慰和满足。
在我的生命中,有一样最重要的东西,一直缺失着,从未被填补。
直到——我又见到了你。
虽然季节不同,你的穿着打扮不同,你的神情不同,周围有那么多人啊,我的眼睛却在第一时间准确地辨识出了你。
我叫你的名字,陶然。
我叫得那么自然随意,一点陌生的感觉都没有,好像它在我的唇齿之间已经停顿了很久,只是一直在等待一个合适的契机。
你侧过头来看着我,有点惊讶也有点意外,你的表情告诉我你真的努力了但就是想不起我是谁。
事实就是这样,你对我毫无印象,这真令我沮丧。
但我还是很快调整好心态,微笑着对你说,我是静嘉的学妹。
你租的公寓离我住的地方只有两条街,虽然你没有说明自己来到这个城市的原因,但我想总归是跟梁静嘉有点关系。
爱人的坟茔所在的地方,就是故乡。
你还是没有忘记她,你真长情。
一路上我们有点尴尬,我看得出你对我有点抗拒,我像一个急着推销商品的热情的导购,带给你强烈的不适应和压迫感。
但我要怎么解释你才会知道,平时我的真的不是这样。
我冷淡,少话,不爱凑热闹,讨厌自来熟,有点清高。
我自己做扎染,做树脂工艺品在网上卖,标价很贵,一副你买不起就别买的样子。
我不愁钱花,我有一个很有钱的亲爸还有一个很有钱的后爸,他们除了我之外还都有自己的亲生小孩,或许是怕我不高兴,他们总是争先恐后地往我的账户里转钱。
我并不是一个厚脸皮的人,却一反常态,毫不矜持地主动把自己的手机号码报给你,半开玩笑半认真地说,一定要打啊。
你点点头,眼角眉梢都带着一点敷衍。
在路口分开时,你往左走了两三步,忽然回头发现我还站在原地。
你又折回来,像是终于想起来了什么,你说,你不是余意的女朋友吗,
是的,你终于记起了我,多多少少对我是点安慰。
我点点头,很快又摇摇头说,我们分手很久了。
然后,我又画蛇添足地补充了一句,我现在是单身。
我的意图太过明显,这一次,在夏天的晚风中,你咧开嘴笑了。
我的眼睛一闭一睁,咔嚓,你的笑容被我拍进了记忆里。
[3] 苍凉而又遥远的你
之前的岁月里,我仅有躯壳,在爱上你之后,灵魂才慢慢生长出来。
我爱上你,这个念头从我的脑子里蹦出来的那一刻,我丝毫不觉得惊慌,我的身体似乎比我的意识更早地察觉到了这件事。
第一次遇见你的那个夜晚,你望向静嘉的照片的眼神,就令我想要拥抱你。
你在公寓附近开了一间小小的陶艺吧,每天中午一点才开门,生意惨淡的时候用门可罗雀来形容都不为过。
但你觉得这样舒服,怡然自得,每天打开门,放上舒缓的音乐,坐在红色的大沙发上看书。
有时候我厚着脸皮去找你,你也不怎么答理我,叫我自便,我一边拉坯一边用余光打量你,那么苍凉而又遥远的你。
你跟我一样,不是个缺钱的主,单是从前看你给静嘉选的礼物就知道你不仅不穷,而且品位不差。
我们是两个胸无大志的无业游民,甘做燕雀,不羡鸿鹄。
比起那些一天到晚把奋斗挂在嘴上,一年到头为了薪水活得战战兢兢的男生,我更喜欢闲适懒散的你。
我们彼此做伴,没有上进心就没有上进心呗,管别人怎么看呢。
不晓得从什么时候起,喜欢你的姑娘越来越多。当然,我不觉得奇怪,因为你真的是非常美好的一个人啊。
我不爽的是她们隔三差五地就来陶艺吧找借口看你。
我开始留心你跟别人聊天的话题,你的语气,她们的笑声。
我心里憋着莫名其妙的一股火。
我想叫她们走,再也不要来了。
我想提醒你,自重一点好吗。
有一天傍晚,我们一起去吃晚饭,我站在你背后等你锁门。
忽然间,你没头没脑地来了一句,影白,你别不高兴。
电光石火之间,我的面孔上燃起两片绯红。
我知道,我变了。
我再也不是从前那个跟余意在一起时,对周遭的一切都毫不关心的陈影白了。
当初他说他喜欢我,我就接受了,后来分开,我也不觉得难过。
他是对的,我没有爱过他。
爱一个人时,看待世界的眼神都会因此而变得温柔起来。
事不宜迟,我决定向你表白。
[4] 你是我生命中的一次机会
那天下午我穿着我最喜欢的一条绿色裙子去陶艺吧找你,从天窗漏下来的光线中有灰尘飞舞,我静静地坐在你的面前。
你原本在看书,大概过了十分钟,你终于意识到这个下午跟平时有所不同。
你抬起头来看着我的时候,我仿佛又看到了第一次见到你时的画面。
陶然,没有人比你更明白那种感受了吧,我紧紧地攥住拳头,用尽全身的力量才控制住自己没有流下泪来,那是我生平第一次懂得这件事。
真的会有这样一个人,如果得不到他,你一辈子都不会甘心。
我竭力让自己平静下来,缓缓地说,我喜欢你。
你的脸比我的声音更平静,过了一会儿,你说,我知道。
我没有说话。
你问我,你想怎么样,
这个问题一落入我的耳朵,我便难堪地想立即起身离开,再也不要面对你,再也不要回到这个小小的屋子。
我相信你没有恶意,但那一刻,你的确刺伤了我。
然而一种更强劲的力量把我摁在了椅子上,逼迫我一字一句地说出心中最真切的想法,我想和你在一起。
在说这句话的时候,我感觉到有些什么东西被我自己撕下来,狠狠地摔在地上,裂成了碎片。
那是我的尊严。
所有我不愿意对任何人说的心事,在那个明亮得近乎什么也看不见的下午,我都对你和盘托出。
我是家中唯一没有人关心的那个小孩,父母各自组建家庭之后,我成了一个最最多余的存在。 童年时期的我性格孤僻,没有玩伴,一直孤单的长大,我没有得到过温暖,也没有得到过重视,甚至连责骂都不曾得到过。
有时候我觉得,我像是不属于这个世界的人,我活着或者死去,都不会引起任何人的注意。
我不相信一切温情脉脉的东西,也不相信一个人会无所保留的去爱另一个人。
直到我听到你的故事。
你那么专注,又持之以恒,完全不计算成本,不计较得失,只希望她快乐。
你没有感动她,却实实在在地感动了我这个旁观者。
你问我想怎么样。
我不过只是希望有人爱我。
陶然,多年后当我不再与自己较劲,不再与人一生中所必须经受的痛苦较劲时,我会明白,为何我的心底那样迫切地想要与你在一起。
你是我生命中的一次机会,唯一可能印证爱这件事的机会。
当你听我说完那番话,时间仿佛停滞了下来,过了足足一分钟,我觉得眼泪已经要落下来了的时候,你起身,过来抱住我。
你的姿势十分小心,好像我是一尊易碎品。
你的声音很轻却也很坚定,说,好。
[5] 眼神中充满了深远的忧伤
我原本以为你的应允会是我孤独的终结,却未曾料到是灾难的开始。
我们真的只有那么一丁点的好时光,在漫长的人生岁月中,它显得那么轻微、单薄,旋踵而至的便是我无度的索取和彼此之间激烈的伤害。
恋情的急转直下,是从我的嫉妒开始。
我反复追问你,究竟是为什么了事情,你和静嘉会走到决裂的程度。
每一次提起她的名字,你眼睛里一闪而过的刺痛,都会引起我内心畸形的快感。
你以缄默相对,却引发我更大的不满,像是为了更深地刺激你,我做出了更多过分的事情。
我买她最钟爱的那个牌子的衣服,用她最喜欢的那款香水,每次出门都涂上鲜红的红色唇膏,戴她喜欢的玛瑙耳钉。
我丧心病狂地做着这些事,一次次地挑衅你,你却只是不言不语地看着我,那眼神中充满了深远的忧伤。
你的忍耐终究到了极限,在那个日子,我睁开眼睛的第一句话是,你今年打算给她挑什么礼物,
几秒钟的空白之后,你暴怒地揪住我,我从来没有想到过你有那样的一张面孔,不是凶恶也不是狰狞,而是,绝望。
我们的眼睛相距只有几厘米,我能够看到你的眼球上反射着我惊恐的脸,我承认在那一刻我害怕了,也后悔了,如果能够重来的话,我愿意代替你掐死面前这个令人憎恨的女人。
在这样的情况下,我终于知道了那件事情的真相。
在得知梁静嘉与那个男人过从甚密的消息之后,你的心情非常复杂,愤怒、难过、惋惜、不理解、厌弃,种种情感交错在一起,驱使你买了第二天最早的那班航班赶来找她。
你坐在快餐店里打了几十通电话给她,她一个都没接,直到晚上才回复电话,说白天不方便接电话。
你们约在她住的公寓附近见面,仅仅心平气和的谈了十几分钟便开始争吵,年少气盛的你口不择言,什么难听的话都说了出来。
她起先是错愕,紧接着便勃然大怒,与你争了几句之后便扭头就走。
你知道自己的话深深地伤害了她,这并不是你的初衷,你不是那么自私的人,不是不准她和别人在一起,你只是希望她的感情清清白白,不要被人玩弄和亵渎。
她踩着十厘米的高跟鞋踉踉跄跄地在前面走,你亦步亦趋地跟在后面大声斥责她的荒唐,你一路跟着她上了楼,在她拿出钥匙打开门的时候,你冲上去,抱住她,强吻了她。
门在你们的身后被重重的关上。
你拨开自己短短的头发给我看那个伤疤,你说,如果不是她拿东西砸破了我的头,把我砸清醒了,我不知道自己接下来还会做出什么出格的事情。
你的声音十分冷酷,我知道你是从这一刻开始恨我。
如果不是我咄咄逼人,这件事你一辈子都不愿意再提起。
是我令你想起你人生中最最不堪的夜晚,鲜血从头上一路流下来,她扬起手就是一个重重的耳光。
还有,她说的那句,再也别让我见到你这个人渣,滚。
你真的滚了,滚得很干脆,滚得音信全无,滚得离她的人生十万八千里远,愧疚和思念通通打包在了那些礼物里。
你想总有一天她会原谅你。
但她至死都没有原谅你。
[6] 你从我的世界里,失了踪
我知道你恨我。
你不辞而别的离开了我的生活,连一句话一个字都没有留下。
你的公寓是空的,陶艺吧落了锁。我不知道你什么时候走的,更不知道你什么时候回来。
于是,我又回到了一个人,只是我变得比从前更孤独了。
我很努力地回想我们在一起那些快乐的时刻。
一起去看了一场闷得让人打瞌睡的电影,你歪着头靠在我的肩膀上,短短的头发刺着我的皮肤有点痒,那时我还不知道在你茂密的头发地下掩藏着一道伤疤。
你的衣服总有种好闻的气味,跟我买的那些洗衣液的气味都不一样。有一个大晴天,我睡了午觉起来,看到阳台上晒着你的衬衣和我的裙子,它们投射在地板上的影子,让我联想到一生一世之类的词语。
还有桌上摆着的那些形状怪异的陶器,杯子、碗、花瓶,我一闭上眼睛就会想起我们穿着围裙,你手把手的叫我在拉坯时如何用力,你的鼻息就喷在我的耳边。
如果你答应尝试着让我明白被一个人爱是什么感觉,或许我也不会变得那么贪婪,这段情感也就不会那么短暂。
你从我的世界里,失了踪。
我没再去找过你,事实上我发现尽管我们曾经有过亲密的关系,我却根本没有了解过你。
除了你的名字和你的身体,我几乎对你一无所知。 你的生日,你的星座,你喜欢什么类型的音乐和电影,你吃东西时有什么竞技,你写字是用右手还是左手,你喜欢篮球还是足球,曾经去过哪些地方旅行„„
关于真实的你,我什么也不了解。
我爱上的,是那个深爱着梁静嘉的你。
在第一次见到你的那个夜晚,你问余意,到底发生了什么事情。
他寥寥数语将你搪塞了过去,你没有再追问,所以你永远无法知道梁静嘉选择结束自己生命的原因。
在长时间的拉锯和折磨中,她的感情已经所剩无几,而他却一直争取不到自由之身。
他的妻子把她约了出来,两个女人都把话说得很直接。
他的妻子开了个价,要静嘉离开他,从此不再打扰他们的生活。
一开始静嘉并不为所动,而面前的那个女人却像是有十成的把握,一定会有一个价格能够买回自己的丈夫。
价格不断的上涨,梁静嘉开始认真的权衡利弊,她的鼻尖开始冒汗,神经也开始绷紧。
其实,要理解她的想法并不难,一边是耗费多年,已经所剩无几的青春,一边是足够十年八载衣食无忧的金钱。
她不是像我这种被钱砸着长大的姑娘,她的眼界和品位,都是那个人后来慢慢被培养出来的。
而他唯一没有改造成功的,是她不够长远的目光和不够坚定的立场。
如我们所知道的那样,她接受了这个交易,却不知道面前这个女人的手机一直是在通话的过程中。
她收下那张卡,沉默着离开了那间餐厅。
她在出租车上一会儿哭一会儿笑,觉得这比账不算亏。
她唯一错的地方,就是低估了对方对她的爱。
她不知道那个人费了多少力气,甚至决心净身出户也要和她在一起。她不知道真的只差了那么一点点,她就可以得到自己渴望了那么久的幸福。
他的妻子差不多已经同意离婚,却在最后关头,跟他打了这个赌。
梁静嘉最后的选择,是出于灭顶的绝望。
而那种灭顶的绝望,现在我也感受了。
[7] 这辈子能够好好活下去了
我在病床上醒过来,目光所及之处皆是雪白。
余意凑上前来叫我的名字,紧接着是更多的面孔,我努力的一一辨认,他们都是我曾经所在的那个小团体的成员,大家看到我醒来,脸上都是兴高采烈的表情。
我问他们,怎么回事,
大家你一眼,我一语的告诉我,我的公寓煤气泄漏,隔壁邻居闻到气味,通知了房东,房东又通知了余意,这才保住我一条命。
我头昏脑涨,好不容易理清思绪,又问了一个问题,你们有没有见到陶然,
我怎么也没想到,这句话一问出口,所有人都呆住了。
病房里安静了很久很久,最后还是余意开的口,影白,陶然一直在德国啊。
我有点生气,你是神经病吗,陶然上个月还跟我在一起,他是我的男朋友,我们一直没有说分手。
我话音一落,大家看我的眼神立刻变得有些恐惧。
我被他们的眼神弄得心里发毛,连忙一把拉过被子蒙住自己的头,你们都走吧,我现在只想见陶然。
他们零散的脚步声彻底消失了之后,我才开始哭泣。
我生平不饮酒,不嗜烟,不熬夜,无任何不良习性,甚至不爱任何人。
我极力节制地生活,却在青春丧尽的时候,毫不留情地狠狠地骗了自己一场。
事实是,根本没有那个夏天的偶遇,没有距离我的公寓两条街的陶艺吧,没有白色衬衣和绿色的裙子,也没用那些奇形怪状的杯子和花瓶。
没有那场短暂的恋情,没有不遗余力的伤害,也没有不辞而别的你。
一切都是我的幻想。
我幻想这世上有一个人,爱我,如同你爱梁静嘉。
事实上就是这样,我这一生,只见过你那一次。
在那个漆黑的晚上,你的眼睛里有浓烈得化不开的伤痛和忧愁,我在那个瞬间爱上了你,也是我生平第一次爱上一个人。
从此,我便着了魔。
我幻想与你一起生活,彼此照顾,天气好的早上我起床给你做法式土司,阴雨天我们哪里都不去,关上门睡一整天。
我幻想在我每年生日的时候,你也悉心为我挑选礼物。
我从医院回到住所,涂上跟梁静雅一个颜色的唇膏坐在镜子面前。
可是,镜子里是她的脸。
我随手操起一只瓷杯砸向镜子,它犹如银色的水花四溅,遍地都是碎片。
至此,一切都结束了。
我的心死了一次,这辈子能够好好活下去了。
[8] 我愿意永远都不离开
余意强迫我去看心理医生,看在朋友一场的份上,我听从了他的建议。
然而我却无法突破自己的心理防线,向一个陌生人承认我内心对爱的渴望,医生拿我没有办法,只好容忍我每周三的下午在她的诊所睡上两个小时。
有一天,我做了一个梦。
那是一座岛屿,我之前从未去过,那里的人告诉我,这座岛叫做遗失之岛,任何人在这个世界上遗失的任何东西都能够在这里找到。
岛上的人问我,你丢了什么,
我轻声说,自己。
当我醒来时,屋外大风呼啸,伴随着零落的雨声。
医生问我,你在想什么,
我说,如果真的有那样一座岛,我愿意永远都不离开。
* * *
7.7“不是吧,那我们就成同学了。”

**7.《小隐藏在盒子里》作者:岑桑**
小隐从小就是古怪的孩子,喜欢一个人做些别人无法理解的事。比如不断转圈,把自己转到想吐,然后大字形躺在地上,看头顶的天空继续旋转——云层勾织起涌动的漩涡,雁阵凌乱不知方向,从树枝上飞落下的叶子,在半空中画出诡奇的痕迹…… 小隐看着,看着,就会发出咯咯的笑声,像藏在森林里无人知晓的动物。
不过,对于八岁的小隐来说,她的森林只是一片种着香樟,红杉树的花园。
再远就是环绕四周的楼房。有 6 层的和 11 层的,错综地排列在一起。
那是她的迷宫。
小隐就是在 “迷宫” 里,遇见陈盒的。陈盒是小隐的同学,不过那是很久以后的事了。
那时候他们还不认识。那是暑假后的一星期。小隐刚刚搬来不久。
这一天,她在小区花园玩了很久。等到她回过神来,已经是傍晚,妈妈很快就要下班。于是她飞快地跑回家,敲了敲 202 的房门,说:“外婆,是我,快开门。” 可是门打开之后,露出一个男生的头。他就是陈盒了,毛刺的头发,像一把新鲜的草。他瞄了一眼小隐说:“喂,你叫谁外婆呢?”
小隐诧异地看着他说:“你是谁啊?在我家干什么?”
陈盒被小隐的问题气到了。他回头看了看,确定无误之后:“这是我家。你是不是走错门了?你家多少号?”
小隐想了想,说:“42 号 202。”
“唉,那是后面那栋楼啦,这里是 41 号。”
“啊?”
“从这里出门,右转过去了就是了。”
“啊……”
陈盒看小隐一脸迷糊的表情说:“算了,我带你去吧。”
陈盒穿着红色背心,穿着拖鞋走出门。小隐默默地跟着他身旁。陈盒看起来想块刚出炉的栗子蛋糕。那是经常在外面疯跑的男孩才有的肤色,在夕阳里泛着层蜜色。陈盒说:“你怎么连家也记不住?”
“这里的房子都长得一个样。”
“哦,是路痴。”
“你才是呢。”
陈盒嘿嘿地笑了。他说:“以后你要是再找不到家,就站在院子里大叫盒子,我就来救你。”
“这么好啊。”
“当然了。” 陈盒潇洒地甩了甩乱糟糟的头发,“对了,你是哪个学校的?”
“开学我就转到区四小了。”
“不是吧,那我们就成同学了。”
这一天,小隐回到家的时候,妈妈已经回来了,她黑着脸,发了好大的脾气。小隐和外婆两个人,挨挤在沙发上,低着头,接受批评。妈妈在客厅不大的小空地上,来回转着圈子 “你们一老一小,也太不让我省心了。让你好好练琴,你偷跑出去玩。让你看着她,你还帮她打掩护。你们联起手来对付我是不是?我每天上班已经够累了,能不能不让我再为你们操心……”
通常挨批的时候,小隐会感到一点压抑,一点难过,一点害怕,一点委屈,今天她却在妈妈的训斥中走神了。
她紧紧依在外婆身旁,脑子里却时不时冒出那个栗子蛋糕一样的男生。
于是微笑就在不经意间爬上了小隐的嘴角。
后来很长的一段时间,小隐都没再遇到陈盒,尽管她很想遇见。可是暑假那么漫长,妈妈每天把她关在家里,写作业和练琴。
其实,妈妈以前也并不是这样苛刻,可是与爸爸分开之后,脾气就变得有些捉摸不定。她的生命中,仿佛只剩下两件事——拼命工作和小隐。搬进新家的那天,妈妈疲累地坐在凌乱的房间里对她说:“小隐,虽然你是女孩子,但一定不要倚靠别人。你必须自己有本事,才能过得好,过得快活。”
可是小隐还那么小,哪里懂得妈妈要尽力过多少人生的刺痛,才有这番深刻的感悟。她只是暗暗地想:“完了,以后不知道要练多久的琴了。”
世界上,大概除了莫扎特意外,所有的琴童都想把钢琴毁掉吧。从拜耳弹到车尼尔。小隐觉得钢琴就像一只不断吃掉她的时间和空间的怪魔,让她只剩下 88 只琴键子,连做梦都是单调的黑白色。
这一天,妈妈在房间里敲工作报告,外婆躺在床上小憩。小隐一个人坐在客厅的钢琴边,对着琴谱发呆,爬在五线谱上的音符,仿佛有诅咒的超能力,让她害病似的垂着头。她要是真的病了就好了,可以有比较名正言顺的理由不练琴。
或者…… 钢琴病了呢?
她真是个善于逆向思维的孩子。如果钢琴病了,一定要修好多天吧。小隐拿起水杯,仔细地浇在钢琴键子上,然后低低地说:“对不起了,钢琴君,你快点感冒吧。”
“钢琴君” 尖着嗓子说:“你好狠毒啊!”
小隐吓了一跳。“钢琴君” 的声音,是从身后冒出来的。小隐转回头,看见陈盒正站在阳台上,隔着玻璃窗对自己挤眉弄眼。小隐惊讶地跑过去,压着声音,说:“你怎么上来的?”
陈盒看她小心翼翼的样子,也收小声音说:“我是从一楼防盗栏爬上来的。”
“你来干什么?”
“我的飞机上来了。”
陈盒捡起阳台角落里的一架飞机模型说,“忘了这是你的家,要知道我就不用爬了。”
小隐站在阳台边,向下看了看,说:“这里是不是也可以爬下去?”
当然了!
就在这时,妈妈的卧室里传来犀利的质问声:“小隐!你在和谁说话!我怎么听不到你弹琴。”
“没有啊,我在上厕所。”
陈盒把模型飞机,抛到楼下。说:“我先走了,下次我再来看你。”
这天小隐坐在还在滴水的钢琴前,弹了首车尔尼的《欢乐的牧童》,清澈流畅的琴音,第一次浸透了愉快的心情。她忽然开始对陌生的学校有点小小的期待了。
只是,期待是一种希望,亦是一种惩罚。因为所谓 “期待”,就在心底有一种你不愿听到的声音,在告诉你最合理,最真实的答案。比如你特别期待浇了水的钢琴君是会坏掉,是因为你知道那是不可能的事。比如,你特别期待某人可以再来找你,是因为你知道,只见过两次面,他又怎么会把和你说的话当真。
后来,整整一个暑假都过去了,陈盒刺猬一样的脑袋也没有出现在阳台上。开学的第一天,小隐就问同桌:“你认识陈盒吗?”
同桌说:“你说盒子啊。听说他爸成了什么大区的总经理,调到北京去上班了,他们全家都搬走了。”
小隐嗫嗫地说了声 “哦”。而她小小的,如桃子形的心脏,被漫长的期待之后的失望,砸出一只不易察觉的洞。
小隐再遇到陈盒,已是初三。在这段不算长的时间里,小隐从一介小女生,长成了一个大姑娘。她开始收集一些奇怪的唐胶公仔,喜欢 BAPE 家的大猴子,追迪幻家的各种剧。她的路痴症状明显好转,至少不会在自己家的小区迷路了。
小隐的朋友依然不多,或者说,几乎没有。因为,就像她微博的名字 “onlooker” 一样,她喜欢做一个旁观者。她喜欢听女生叽叽喳喳地八卦,或是看男生聚在一起,表演似的高谈阔论。但她只是听,偶尔附和着发出咯咯的笑声,就像许多年前,躺在小区 “森林” 里的那只“小动物”。
小隐的妈妈逐渐走出了离婚的阴影,日益开朗起来。于是小隐和外婆的日子好过多了。钢琴君也因为少了妈妈非人的苛刻,变得不再那么面目可憎。每天小隐都会在练琴之后,弹一段自己喜欢的曲子,把不为人知的心情,悄悄排散在婉转流动的旋律里。
一天晚上,小隐趴在书桌,对着语文书发呆,外婆端来一杯牛奶放在桌子上说:“累了就别看了。喝了牛奶去睡觉吧。”
小隐坐起来说:“外婆,你知道我今天看到谁了?”
“谁啊?”
“盒子。”
“什么盒子?”
“陈盒啊,就是小时候有一次我迷路了,他把我送回家的那个。”
“哦。” 外婆想了想,说,“不记得了。”
是啊,谁会记得那么久以前的事呢。
但小隐记得。那可是让她整整期待过一个夏天的男孩呢。现在,他又转学回来,进了初三(2)班。他变得太多了。不只是猛增的身高,还有他孤僻的性格。他总是独自坐在教室里的最后一排,不与任何人来往。
有人说,陈盒的父亲因为经济问题坐牢了,他和母亲迫不得已才搬回来。于是各种鄙视和嘲笑,流传在学校浮躁的空气里。
这天中午,小隐去学校的食堂吃饭。还没进门,就听到超乎寻常的声浪。
小隐看见陈盒。他满身汤汁地摔倒在地板上。周围都是讥笑的声音。一个男生指着他的鼻子说;“贪污犯的儿子,装什么酷!看着你就来气。”
陈盒发狠地从地上爬起,举着凳子向男生砸过去。小隐想去阻拦,可又不敢。还好管理老师及时赶来了。
那天陈盒被留下写检讨,直到放学才被放出来。天空已经淡淡地暗下去,自行车库里只剩下寥寥几辆车子。陈盒的车子倒在地上,不但脚踏和车把套不翼而飞,两只轮胎也被划破了。瘪瘪地塌在车圈上。
陈盒突然重重地把车钥匙摔在地上,愤怒地提了自行车一脚。就在这时,一个弱弱的声音,在陈盒身后想起来;“盒子,你不要生气了。” 是小隐。她从地上捡起陈盒的车钥匙,递给他。陈盒没有接,只是冷冰冰地问:“你是谁啊?”
“我是小隐啊,咱们住在一个小区的。”
“不认识。” 陈盒转身向车库外走去,小隐推起车子。追过去说:“你都记不得了?我迷路找错门,后来是你送我回去的。还有一次,你爬到我们家阳台捡模型飞机……”
“原来是你。”
“你终于想起来了!” 小隐高兴极了。她说:“那个…… 你的车子不管了吗?”
陈盒突然停下来,转身凶巴巴地说:“你最好离我远一点!” 说完,陈盒转身走了。小隐在身后,怔怔地看着他。她发现,自己真的不认识陈盒了。
这天晚上,妈妈加班不能回来,只有外婆陪着她。晚饭的时候,她向外婆讲述白天发生的事。外婆安静地听完,长长地吁了一口气说;“唉,可惜了。”
“就是啊。” 小隐一同感叹:“原来那么阳光的男生,变成这样。”
“我是说车子,好好地扔了不要,少爷作风!”
“呃……” 小隐无力地垂下了头,她真是败给外婆了。
可她又忽然抬起头,兴奋地说:“外婆,你说得对啊。”
“什么对啊?”“你帮我个忙吧。”
外婆看着小隐频频闪动的大眼睛,心底有点没底了。
清晨,日光推开微蓝的薄雾,现出迷蒙的淡金色。陈盒从楼下来,就看见了小隐一脸期待地看着他。陈盒皱起眉说:“怎么又是你啊?”
小隐推开自己的车子,露出后面陈盒昨天被别人损坏的那一辆。已经修好了,重新擦过的车身,在晨曦中闪着薄薄的光。
这可是小隐晚上拉着外婆从学校车库退出来,百般央求要回家吃饭的修车大爷给修好的。小隐说:“看,修好了跟新的一样呢。”
陈盒走到车子旁,默默不说话,但心里某些一直被缄封的东西,似乎悄悄裂开了。他隔了很久,才低声说:“谢谢你。”
“不用谢啦。” 小隐再一旁笑嘻嘻地把车钥匙放在他手里,说:“我外婆说的,你别当破烂不是东西,收拾收拾就是宝呢。”
陈盒陡然收起语气里的温柔,说;“你觉得我是破烂?”
“没,我我…… 我不是这个意思。” 小隐吓得有点结巴。
陈盒却突然露出浅浅的笑容,说:“傻瓜,逗你呢。”
小隐就真的傻傻地笑了。
这一天,小隐开心极了,仿佛许多年前的那个期待,终于等到了完美的结局。
初三的课业,变得格外繁忙,小隐却不觉得烦闷。
每天晚上写作业的时候,她都会悄悄挂起 QQ 视频,陈盒坐在视频的另一端。
他们不聊天,只是安静做伴。又是小隐遇到搞不定的化学配平,陈盒便会耐心地讲给她。妈妈加班的周末,外婆还会把陈盒放进家里来。他们就坐在阳台上温书,写作业。很安静的春日,阳光温暖绵密、柳絮轻缓落在书本上,时间都仿佛跟着停下来。一次,陈盒伏在围栏上,看着一楼的防盗栏说;“小时候真是不知道死,现在让爬,都会怕。”
小隐深有同感地说:“是啊,我也不敢爬了。”
“你也爬过?”
“我……” 小隐犹豫了一下说,“我不会告诉你,我也爬过。”
“不是吧。看不出来。”
“我…… 也不会告诉你,我是为了去找你,才爬的。”
是的,就在八岁那年,临开学的晚上,小隐一个人悄悄从二楼的阳台爬下来。那是天已经黑透了,她在昏暗的路灯里,找到陈盒的家,她只能站在小区的花园里,一遍一遍地大喊:“盒子——” 可是,那是的陈盒,已经搬走了。她只召唤了物业保安,把她送回了家。
陈盒说;“对不起”
“干嘛对不起啊,你都搬走了嘛。”
陈盒微笑着,伸手揉了揉她的头发。小隐再他的掌心下,有一瞬的呆。她说:“盒子,其实…… 其实…… 我不会告诉你…… 我不会告诉你……”
“不会告诉我什么?”
陈盒应该算是很好看的男生吧,眼睛深而明亮,像浓紫色的葡萄。小隐很怕这双 “葡萄” 会注视自己,会导致她面部不自然。
“我…… 我…… 我不会告诉你…… 我要上厕所啦!”
小隐头也不回地冲进厕所,镜子里的自己,脸红得发烫。她到底不会告诉他什么呢?
是她喜欢他吧?
小隐打开水龙头,把冷水泼在脸上。她仿佛听到有水气,刺刺蒸腾的声音,从脸庞悄然飞散开了。
小隐中考的成绩还不错,虽然化学差了一些,但还好有语文英语拉起来。放榜之后,小隐和陈盒靠近了同一所高中,并且好运气地分在了一个班。小隐为此高兴了好久。
这一年,小隐的妈妈恋爱了。那是个看起来很不错的叔叔,外婆和小隐都比较满意。
只是这位叔叔在国内工作的时间只剩三个月,妈妈如果要继续和他恋下去,并且嫁给他,就要和他一起飞越太平洋。
这让妈妈犹豫不决。
小隐当然不想让妈妈离开自己,可是外婆私下对她说:“小隐,你妈好不容易找到一个对她好的人,咱们两个可不准拖她的后退哦。”
小隐觉得外婆说的没错,于是某一天上学前,她给妈妈留了字条在梳妆台上。
她说:“就像你希望你的女儿能抓住幸福一样,你的妈妈也希望她的女儿不要错过自己的幸福。就像你希望你的妈妈活得快乐一样,你的女儿也希望她的妈妈能够永远快乐。亲爱的妈妈,趁外婆还没来,我已经长大,赶快嫁了吧。”
那天工作狂的妈妈直到下午才去上班。据外婆透露,是因为她把眼睛哭得像桃子一样红。
后来,陈盒听了小隐的光荣事迹,表扬说:“看不出来,个子一点点,做事还挺爷儿们的。”
“那是啊。” 小隐骄傲地昂了昂头。
高中时代的陈盒,变得不再那么孤僻了。或许因为小隐,或许也因为他爸爸不再是新闻。总之,他开始渐渐和小隐记忆中的样子重叠起来——热情,开朗,喜欢跑步与足球。不过,这样的陈盒,就不会有大把的时间陪着小隐了。
但小隐不太再也。因为这才是她喜欢的盒子啊,那个被夏天烤成栗子蛋糕的盒子。
是周四的午后,两个半在电教室合上国防大课,小隐和陈盒坐在最后一排。老师放上投影,到一边批作业去了。陈盒撕了张纸,在 “原子弹” 的爆炸声中,折飞机。
就在这时,一个陌生的女生悄悄移到小隐身边,递过一块口香糖,小隐迷糊地接过来,刚要说谢谢。女生就已经越过她,递给陈盒一块。她说:“Hi,我是小隐的朋友,梁雅佩。你可以叫我佩佩。” 小隐看着她,一脸诧异。因为她只知道梁雅佩是其他班的女生,并不认识她。
不过小隐没有拆穿。当面揭人家的底。时间多尴尬的事,小隐做不出来。那天下课,陈盒把飞机放在小隐的手里,说:“送你了。我去踢球了。”
梁雅佩的目光一路追随他跑出教室,才转对小隐说:“谢谢你刚才帮我忙啊。”
“什么忙?”
“没拆穿我呗。”
“那不算帮忙吧。”
“当然算。” 梁雅佩说:“看你总和陈盒在一起呢。你是他女朋友吗?” 小隐摇了摇头。
“哦,你喜欢他?”
“没有啊。”
“那就好了!” 梁雅佩一脸轻松地说:“你帮我追他好不好?”
“啊?”
“答应我吧。从今天起,咱们就是最好的朋友了。”
小隐觉得梁雅佩是自己的反面,直爽,尖锐,犀利。
她是那种可以和男生死拼到底的女生。小隐羡慕,却也有点怕。只是怕什么,她有点想不清楚。也许就是于她的不同吧。
小隐从来没有像梁雅佩这样强势的朋友。她会拉着小隐跑到操场旁,为陈盒的凌空抽射,雀跃加油。放学,她会绕一小段远路,跟着小隐、陈盒一起回家。
她有一大堆的足球话题,多得甚至让陈盒都感到惊讶。小隐的生活仿佛一瞬间热闹起来,可是,那些只属于她和陈盒的小欣喜,小快乐,却从此消失不见了。
梁雅佩偷偷地对小隐说:“你知道吗?每天晚上写完作业,我都要上网看足球新闻,那叫个无聊。”
“你不喜欢,为什么还看啊?”
“陈盒喜欢啊。我不看他喜欢的,他会和我说话吗?”
小隐说:“佩佩。你不怕自己为他做了这么多,他却不喜欢你吗?”
“不怕。” 梁雅佩坚定不移地说:“如果我原本有机会,他却从来不知道,你不觉得那样比较可怕吗?”
小隐被问住了。
是啊,她是喜欢陈盒的吧。可是陈盒知道吗?如果陈盒永远都不会知道,那才真正的可怕吧。
很快就是暑假,小隐的妈妈,就在那个夏天出家了。婚礼并不盛大,但很传统。这是外婆唯一的要求。她说上一次按着西式的来,嫁的不好,这一次一定要遵照老规矩。
那一天穿着红色旗袍的妈妈,安静地坐在梳妆镜前,漂亮极了。外婆拿着桃木梳子,为她梳头发。
“一梳梳到尾,二梳白发齐眉……”
小隐在一旁默默地听着,第一次感到了真正的别离。她轻轻拉起妈妈的手说:“妈,你还会回来的对吧?”
“当然了,我到那边安定了,就接你过去。”
“那外婆呢?”
“外婆…… 也过去。”
三个人很快都沉默了,因为她们都知道,那只是个美好的期望。
那天晚上,只剩下外婆和小隐的房子有点空。小隐爬到外婆的床上,要和她一起睡。她说:“外婆,如果你不走,我也不走。”
“别说傻话,我要是老得不能动了,就往养老院里一躺就行。我都不想拖累你妈,还能拖累你吗?”
可是,即便外婆这样说,小隐也不愿离开。也许,她还有另一个不愿说出口的理由。
外婆很快就睡着了,发出轻轻的鼾声。小隐的手机却嗡嗡地响起来。是陈盒发来了图片。小隐拿着手机,蹑手蹑脚地躲进洗手间,才打开图。陈盒一脸正义地出现在屏幕里,图片上写着:“伤心难过怎么办?打开盒子看一看!”
小隐刚要回复,第二张图片很快就到了。这一张陈盒掀起 T 恤的一点点,暧昧地对着自己挤眼睛。接着是第三张,T 恤掀得更高了,面部做一脸销魂状。第四张,陈盒咬牙切齿,掀起了一半,肚皮上好像画了什么。最后一张,终于揭晓了答案,那是一张动态图。陈盒露着肚皮,扭来扭去。肚皮上,画着一个野原的小朋友的头,圆圆的肚脐是他嘟起的嘴。
小隐扑哧一声笑出来。可是她忽然发现,小新怎么会长长头发?难道这个难看的头像会是……
陈盒打进了电话,他说:“嗨,猜你今天就会难过,看了我的大作开心了没有?”
“谢谢你。”
“谢什么。” 陈盒说,“对了,我的大作叫,隐,藏在盒子里。”
“那个长得像小新的姑娘就是我啊?我哪有那么难看。”
小隐愤愤不平地说着,笑纹却悄然慢上她的嘴角。
陈盒也笑了,他说:“这个不能怪我啊,是佩佩画得太差了。”
只是一瞬间,小隐所有温暖的笑容都冻结在脸上。
高二的下学期,学校分班。尽管小隐有一百个不情愿,但文科优秀的她,终究还是和陈盒分进了不同的班级。课间,梁雅佩来找小隐。她说:“你知道吗?我和陈盒分到一个班了,我感觉自己和他又进了一步。” 小隐看着梁雅佩兴奋的样子,忽然明白自己曾经为什么会怕她。她怕的,就是梁雅佩性格里的锋锐与坦白。
那样毫无遮拦地表达自己的一切,没有任何顾及地掠夺她想要的东西。
小隐做不到,永远做不到。
她轻声说:“佩佩,知道吗?我认识你以后,过得好不开心。”
梁雅佩愣住问:“我…… 欺负你了?”
小隐摇了摇头说:“因为,我总想做一个像你一样的女生。”
“你很好啊,为什么要做我?”
“所以,以后我不会不开心了。”
那天晚上,小隐没有看书,也没有上线。她只是坐在客厅的钢琴前,弹德彪西的那首《月光奏鸣曲》。
陈盒打来电话,问:“今天怎么没上线?”
小隐说:“以后,我都不会上线了。”
“为什么?”
“因为,我要做回我自己。”
好像就是那天起,小隐真的不会再难过了。每天一个人温书,一个人练琴。有时候闷了。她会找外婆说话。于是时间在平静如水的日子里,飞逝而过。
她和陈盒依然是最好的朋友。每次陈盒打比赛,她都会和梁雅佩一起站在球场边为他加油。他们三个仿佛从未改变,但他么也都清楚,小隐在中间,添了一点捉摸不定的生疏。
高三那年,小隐的妈妈回来了,要接她出国。可小隐怎么都不肯。她说:“妈,让我留下来,外婆不能没有我。”
那是妈妈第一次在小隐眼里看到了一中性子里的决绝,忍不住感概小隐再她离开的日子里长大了。
6 月,毕业季,整个学校里都弥漫着自由与离别的气息。小隐忽然想起自己刚刚踏进整个校园时,心情曾是怎样的欢喜与悸动。陈盒就坐在不远的后座,只要侧侧身,就可以看见他明亮如葡萄的眼睛。那是,她以为自己永远都有这样的好运气,可以在不经意间,找回她曾经丢掉的东西。
可现在,她的好运气,快要用完了。
谢师宴的那天,陈盒和他踢球的兄弟们哭倒一片,无暇顾及坐得遥远的小隐。只有喝醉的梁雅佩抱着她痛哭流涕。她说:“对不起,小隐,其实我一直知道你喜欢陈盒。可是我也真的好喜欢他,好喜欢他。”
小隐拍着她的背说:“没关系啊,反正盒子又不是我的。”
这一天,只有小隐没哭,因为她终于做回了自己。她就是那个叫自己 “Onlooker” 的旁观者,躲在别人看不见的角落,偷窥这个世界的喜怒哀乐。
大学就在本城。小隐没有像陈盒和梁雅佩那样,到外地去。其实她的成绩可以念一所排名更好一点的大学。
十八岁的小隐,已经会像大人一样思考问题了,她不能走得太远。因为她的外婆真的老了。
有时外婆会忙着忙着突然停下来,问自己,我要干什么来着?或则,煮一锅土豆,知道冒出黑烟来才想起来。
外婆说:“小隐,你找你妈去,我去养老院就行了。”
小隐却轻轻抱住她说:“外婆,你不明白吗?是小隐不能没有你。”
是啊,在小隐漫长的青春里,每个人都是来来去去的过客,只有外婆始终如一。
其实,上了大学的小隐,并不孤独。小隐加入了转笔社团,只有三个男生的小圈子,却蕴藏着消息哦啊的温暖。三位男生都有古怪的性格,但转笔的功夫,出神入化。小隐喜欢这个社团,几乎没什么人讲废话,只有一支一支的签字笔,飞旋在指尖。
小隐再微博里写:“一支笔要多爱手指,才会永远围绕在它身边。”
有人评论:“Hey,恋爱了?”
是陈盒。小隐看着他的头像,静静地坐了很久,把评论删掉了。她说不上为什么,也许只是怕见到他的微博名字——隐,藏在盒子里。
外婆在小隐大四那年出了意外,没有任何的征兆。小隐周末回到家的时候,看见她躺在地上,洗衣机里还有没晾的衣服,砧板上有切了一般的肉馅。小隐还算镇定,没敢轻易搬动外婆,只是叫来救护车。外婆昏迷了三天三夜,小隐就在病房里陪了三天三夜。直到第四天的早晨,外婆忽然醒来了。她推醒睡在床边的小隐,说:“我渴了。”
小隐惊喜极了,递给她一瓶矿泉水。外婆一口气喝了好多。她说:“小隐,外婆累了,想再睡一会。”
小隐轻声说:“好。” 然后扶着她躺下来。几天来,深压在心里的阴霾一扫而空。可是,外婆也许真的太累了。她睡着以后,就再也没有醒过来。
外婆去世后的第二天,妈妈才从美国赶回来。她给外婆办了一场简单的葬礼。陈盒看见小隐的微博,也来了。他比以前高了许多,说话也沉稳了。从墓地回来的路上,他做在小隐身旁和她讲自己近况,他现在已是校足队的队长,依然和梁雅佩谈着恋爱。陈盒问她:“你还没男朋友吗?”
小隐摇了摇头。陈盒说:“你应该谈一谈的,你不参与进去,就没法真正知道谈恋爱的感觉。”
小隐望着他深黑的眼睛,依然摇了摇头。那天晚上,妈妈拉着小隐说:“这一次,你要准备走了,一毕业就跟我过去。” 小隐点了点头,她再没理由推脱了不是吗?她再没有理由了。
那天晚上下了大雨。小隐趁妈妈睡熟以后,悄悄溜出了家门。外面暴雨如注,仿佛要倾尽一座城的雨水,冲尽所有的悲伤,
小隐一路去了她二十的 “森林”。红杉与香樟,摇曳在狂风里。她扔掉了雨伞,不停地转,不停地转。知道天空碎成漩涡,数目凌乱,她像一只逝去平衡的陀螺,重重摔掉在地上。她哭了吗?她不知道。
她只是像许多年前的某个夜晚,放声地大喊着:盒子——盒子——
只是这一次,所以的声音都淹没在盛大的风雨中,没人听到。
* * *
3.12 忘记那个曾经多余的人吧,我已经不需要你想起我了。

《离人心上雪》by 绿亦歌
1.
梁二少二十五岁生日时,许多多站在他家花园外的铁门边等他。
那年冬天,沈阳下了一场雪,她冷得直打哆嗦。
他从屋里走出来,没好气地看着她:“怎么不进来,外面多冷啊!”
她结结巴巴地笑:“我没请帖,门卫不让我进……”
梁二少愣了愣,一下子尴尬起来:“啊…… 抱歉,我给忘了。”“没事没事,” 许多多一边哈着气一边搓着手,“本来也只是来给你送生日礼物的,送完我就走。”
他皱起眉头:“大雪天的,你大老远跑来,就送个生日礼物多不值当,改天给不是一样的。”“不,” 许多多摇摇头,“这次就得在今天给。”
“为什么啊?
“因为,” 她笑起来,两眼弯弯,梁二少以前就曾经说过,许多多全身上下,也就只有一双眼睛可以得他一句赞扬,她说,“这是你多年来的心愿啊。'
“什么心愿?” 梁二少不解。
她不说话,只是笑吟吟地看着他。于是他只得接过她手中大大的礼物盒,没有想到,盒子轻得很,他将包装纸撕开来,盒子打开来,里面静静躺着一张纸。
梁二少将纸夹在指间,哭笑不得:“去墨尔本的机票?我梁二长这么大,心愿就只是去趟墨尔本?”
“不,” 她轻声说,声音在寒风中打了一个圈便消失了,“要去墨尔本的那个人,是我。我再也不会出现在你面前,讨你烦心了。”“你看,你多年夙愿终于成真。”
梁二少本名梁家明,后来大家知道他爹是谁后,才开始叫的梁二许多多和梁二少是从小学开始的交情,确实是很多年了,也难怪后来梁二少看到许多多,张口闭口就是 “那个白衣飘飘的年代”。
在那个白衣飘飘的年代,许多多就是一个圆滚滚的胖妞。
梁二只记得许多多总是在自己面前晃,烦人得紧,反正自己记忆里一直有这么个小胖子。好在他们之间的事,许多多都记得,不然,掉进岁月的河里,打个旋儿,估计连尸骨都无存了。
许多多是插班生,那时候插班生并不是什么大不了的事,每年都有人插班,她进行完简单的自我介绍之后,班主任就让她随便找个座。许多多从小就是个花痴,喜欢躺在床上抱着零食看少女漫画,所以才胖成了这样。她眼尖,一下子就看到了坐在最后一排穿白衬衫的男生,没错了,许多多的小宇宙滚滚燃烧,男主角的标配座位啊,于是她小跳着跑到了梁二少的身边 “咚” 地一声坐下。
而此时的梁二少,立了一本书在桌子上,正躲在后面睡觉。许多多这圆润的身子往凳子上一坐,把梁二的光线一下子挡完了,枕着桌子睡得半梦半醒的梁二立马醒了,一张开眼就看到许多多结实的手臂,他吓了一跳,不由自主地叫了出来。
这么一叫,立马引来了老师的注意,本来想装作没看见梁二的小动作也不行了,只能把他叫起来,按照老规矩,头顶水杯站走廊上去。
这正是一个男孩虚荣心和自尊心爆棚的年纪,想他梁二也是年级上响当当的一号人物啊,像杂耍的猴子一样被看了笑话,自然气得要放学之后,他就拦着许多多,横眉竖眼、一本正经地在桌子上画了一条三八线,并且警告她:“胖妞,你要是敢越界,我揍你噢!” 许多多这才真的看清自己同桌的这张脸,青嫩的脸上浓眉大眼现实中竟然有人也能这样好看。
于是她心里乐得跟蜂蜜罐子打翻了一样,漫画里可都是这么画的,一开始男女主角就是要成为敌人,针锋相对,才能擦出爱的火。看着对面女孩子的傻笑,梁二觉得一身恶寒,打了个哆嗦,背着书包走了。
2.
再过了两年,他们步入青春期,梁二少开始缓慢地脱胎换骨。一眨眼就蹿高好几节,眉眼也渐渐长开来,声音变得哑哑的,总之,是再也做不出和女生画三八线这种事了。
他和许多多还是算不上朋友,他要么叫她 “胖妞” 要么叫她“喂”,反正是没有什么好脸色给她看。
这也怪不得梁二,当一个人看过你睡觉流口水、憋尿憋得双腿不停地抖、喝汽水喝坏肚子…… 反正,你绝对不能露于人前的模样后,你怎么也对她笑不起来。
当梁二每天衣冠楚楚地出现在人群中,准备享受众人的崇拜的时候,她什么也不做,就嘿嘿地笑着看着他,梁二总觉得她是在说,有什么了不起,你什么怂样我没见过。
所以一看到许多多,梁二觉得自己身后开的屏 “哗啦” 一声全碎了,跟落败的公鸡似的。
而自认为是梁二骨灰级忠实粉丝的许多多,每次梁二恶声恶气地叫自己的时候,她还以为,他这是在害羞,所以她也跟着害羞地嘿嘿笑。
…… 这两人之间的误会,着实有点深。
填小升初志愿表的时候,少年梁二腰杆挺得笔直,眼睛却一直往许多多那边瞟,实验中学、一中、三中…… 正人君子梁二少看完同桌的表格后,顿时下笔如有神,在自己的表上写下:二中、四中、七中 ······
交完表的那一刹那,梁二少觉得心中有一团浊气终于吁出,顿时觉得天朗气清,惠风和畅。
一个暑假过完,开学那天,梁二在二中一年一班教室门口看到胖妞许多多的那一刹那,还以为自己这是又做噩梦了。
许多多兴奋得满脸通红,举起她的小粗手使劲摇啊摇,大声喊着:“梁家明!梁家明——”
许多多是真的没有想到,还能再见到梁二,因为她家从城北搬到了城南,所以只能读城南的中学了,和以前的同学都分开了。
梁二简直要抓狂了,也顾不得形象了,抓着许多多的肩膀问:“我明明看到你表上写的是实验中学啊!!”
许多多想了想,终于知道他在说什么了,她笑得两眼弯弯:“啊,那个啊,那是老师给的示范表格。”
梁二被这突如其来的笑容给惊了惊,只是时长只有一秒。
虽然搞了个大乌龙,不过梁二的中学时代混得还是如他所想般如鱼得水。不必再和许多多那个胖妞当同桌,他装模作样地好好学习了两周后,就开始了多姿多彩的课余生活。
可作业还是得交,班里成绩好的他又嫌人家是书呆子,成绩中上流的,又嫌字写得太丑,挑来挑去,还就只有许多多合适。
梁二没想到,许多多这么好说话,他才刚一张嘴呢,她好像就已经知道他要说什么,把作业本丢给了他
“许多多,够义气啊!” 他比着大拇指,“放学后请你吃东西。”
于是许多多当真了,放学后乖乖地坐在座位上等梁二,等啊等,等啊等,等到天都黑了,保安拿着手电筒来清理教学楼,才把她赶了出去。
许多多抱着自己的书包,慢吞吞地独自走在路灯下
第二天见了梁二,他和一大群男生勾肩搭背,讨论着昨天 NBA 的赛事,许多多走到他身后,想了想,又转身走了。
她虽然胖胖的,看起来好像反应很慢,但其实她一点都不傻。
不过梁二倒也没算食言,有次体育课下课,他去小卖部买水,正好遇到抱了一篮子零食的许多多,梁二便顺便把她的钱付了。
服务员找零钱的时候梁二帮许多多把零食往塑料袋里装,有个长方形纸盒子的饼干他没见过,是新出的夹心饼干。
“许多鱼?”梁二少 “扑味” 一声笑了出来,“许多多,你来看这上面画的鱼,像不像你啊?”
从那天起,梁二少不再管许多多叫 “胖妞” 了,他叫她“许多鱼”,其实还是在笑她胖,但是许多多听不出来,她固执地认为这是昵称,只属于他们两人的秘密。
3.
二中一向是省内名校,高中部比初中部还难考,许多多费了吃奶的劲儿才挤进来,心想着,这次完了,肯定再见不到梁二少了,结果一抬头,白衣黑裤,一双限量版的球鞋,梁二少靠在走廊栏杆上,越发英俊潇洒。
梁二少的名号,也是这时候开始有人叫的。
可是梁二真正一战成名,还是在那年的元旦晚会上,他是开场,报的歌曲是老狼的《同桌的你》,可是音乐响起,却是谢霆锋的《谢谢你的爱 1999》
那一年,谢霆锋靠着一把电吉他红遍大江南北,穿着长风衣,一曲歌毕,尽兴地将吉他砸得稀烂,无数少男少女为之痴狂。
梁二少早就安全度过变声期,他现在的声音十分有磁性,又带着少年人特有的潇洒,舞台一片漆黑,镁光灯落在他身上,他微微低着头,手指顺着吉他弦一拨,“说再见,别说永远,再见不会是永远…… 别问爱过多少人,在一起的人,只问爱你有多深……”1999 年的最后一天,沈阳下了一场雪,纷纷扬扬,淹没了许多多的整个世界。
全场嗨翻,叛逆张狂的年代,人人都恨不得跳上凳子跟着他一起喊。
“梁家明——梁家明——梁家明——”
最后收音,梁二少也跟着谢大少一样,手中吉他往地上狠狠一砸,碎了一地。
一代风流公子梁家明,这算是正式长成了。
“咚” 的一声,一锤定音,在渣男届留下一座新的里程碑。
其实梁二倒也不是真的渣,就是对谁都不太上心,和美人调笑打闹,一掷千金。身边的人换了一个又一个,没关系,还是有人眼巴巴排着队,反正大好青春,最不差的就是真心。
那段时间,许多多的生活被梁二狠狠刷屏了,不管走到哪里,都能听到梁二的名字,梁二梁二梁二,许多多在心底忍不住吐槽,你是梁二什么人你有资格成天梁二梁二地叫吗?他睡觉流口水、憋尿憋得双腿不停地抖、喝汽水喝坏肚子的样子,你看过吗你?!
看来,少年梁二的担忧,也并不是杞人忧天。
但是梁二的脾气也变得越来越难以捉摸,有一次下雨,他骑着摩托载着女朋友准备出校门,正好遇到一脸傻样站在雨中的胖妞许多梁二少停下来,皱起眉头:“你在这里千吗?
“准备回家。” 她抬起头看了他一眼和他身后漂亮高挑的女朋友,小声地回答。
“没带伞?”
许多多点点头,她感觉到了自己的双下巴。
梁二没再理她,回过头,面无表情地对身后的美人说:“下车。”
美人愣了:“啊?”
梁二耐心用完,翻脸比翻书还快:“叫你下车!'
“干什么啊?” 美人无辜地瘪瘪嘴。
“你不是有伞吗,自己走回去。” 梁二不耐烦地说。
美人目瞪口呆,一辈子都没受到过这待遇,一咬牙,从梁二的摩托车上走下去,脚一跺:“你给我等着!”
走了两步,又听到梁二的声音:“等等。”
美人心里一喜,调整好面部表情回头:“干吗?”
“头盔。” 梁二指了指她的头。
美人这下子是真的非常生气,粗暴地解下头盔,扔给梁二,梁二单手接住。等美人打着伞气冲冲消失了,许多多才收回目光,转过头来,看到梁二无语地看着自己。
“看完了?”
许多多点点头。
梁二翻了个白眼,将头盔丢给她:“看完了就快点上来,冷死我了。”
你以为这就代表着在梁二心中,许多多是特别的了吗?嗯,许多多也这么以为。
梁二送许多多回家的事,很快在学校里传开了,毕竟许多多是他载过唯一体重超过两位数的女生。
有八卦的人跑到梁二面前问,二少,您怎么突然换口味了?
梁二少好整以暇,似笑非笑地坐在课桌上:“我怎么会看上她?”
恰好许多多抱着一叠厚厚的作业本走进教室,脚刚踏进来就听到了梁二的这句话,她愣在原地,手一松,作业本 “哗啦” 一声在地散开来,听到了动静,所有人都一齐尴尬地望着她。
唯独梁二少,只是转过头看了她一眼,淡定地点点头:“哟,许多鱼。”
许多多蹲下去,将作业本一本一本捡起来,再在众人依然赤裸裸的目光下,吃力地将它们抱上讲台:“数学课代表在哪里?嗯,老师让你把作业发下去。”
然后全班才恢复了正常的气氛,大家该干嘛干嘛去。没有人会在意,一个小胖子,坐在角落里,将头深深埋进了臂弯。
是啊,他怎么会看上她呢?他可是高高在上的梁家二少。
4.
许多多他们这一届,高考志愿还没有改革,还是提前填志愿。
这一次,终于没有人再来问许多多,胖妞,你去哪里读书?
因为梁二少要留学去了,去英国。
送行那天,队伍排了很长,许多多大清早就坐着公车去机场等他,只可惜人真的太多了,矮矮的她一下子就淹没在人群中了。
她站着脚尖,看到穿着黑色 T 恤的梁二,同这个人击掌,那个人拥抱,笑得一脸阳光,根本不像是远赴他乡求学,倒像是战士打了胜仗凯旋归来。
许多多努力地跳脚,她一心只想多看梁二一眼,看一眼,记一眼,结果她重心不稳,脚尖一滑,就这样直直地冲前面的人扑了过去。本来大家站得就比较紧,许多多这么一倒,周围的人就像多米诸骨牌一样,噼里啪啦全部倒了。
梁二少一回过头,看到的就是这么惊悚的一幕。
还有人赶紧把许多多这个肇事者拉了起来,许多多整个人灰头土脸,浑身都疼,也不知道究竟扭到了哪里。
梁二眨眨眼睛:“许多鱼?”
许多多赶忙站正:“嗨。”
他皱起眉头:“你来干什么?”
许多多本来想说 “来送你啊”,可是话到嘴边又说不出来了,她看着梁二疑惑的目光,纳纳地低下了头。
他有说过,需要她来送吗?
这里浩浩荡荡一大堆人,个个都是梁二少货真价实的朋友,可是她呢?
是啊,她来做什么。
胖妞许多多上大学后,和很多女孩子一样,她上大学的第一件事,就是减肥。
可是减肥这种事,三分靠天赋七分靠拼搏,许多多才刚刚开始减肥,就在军训的时候晕倒了。
许多多倒是由此名声大噪,她念的是工科,男女比十比一,男生们课后闲谈,说到许多多,评价倒还宽容,说虽然有点胖,但是脸圆圆的,笑起来挺可爱。于是减肥不成功的许多多,也开始有男生追了。
可是她寝室的人放话了,你们别想了,人家许多多早就有意中人了。
对方可是在英国留学,你没见许多多寝室里的钟,调的都是伦敦时间吗?没见许多多每天都抱着收音机听 BBC 吗?没见许多多天天往图书馆里跑,看的都是英国历史吗?
然后不知道怎么的,就传成了,许多多有个在英国留学的男朋友。
许多多也没有去解释,有些时候,一个谣言同真相相差太远,你就会失去了解释的念头。
许多多第一个月放假回家,在家里吃了一顿大补的蹄花汤,肚子圆滚滚的,被她妈一脚踢出家门散步消化去。
不知不觉,又走到了中学的学校门口,许多多犹豫了一下,还是走了进去。
几个月没见,学校毫无变化,这是梁二玩滑板的地方,这是梁二被罚站的地方,这是梁二打篮球的地方…… 咦,前面那一大堆人,怎么看着那么眼熟?
许多多呼味呼味地跑上去,最中央的那个人,怎么会是梁二?
许多多忍不住喊道:“梁家明!”
梁二听到有一道熟悉的声音,愣了愣,又觉得哪里不对劲。还是身边的人推了推他,说,梁二,有人叫你。
噢,太久没有人叫他的本名,他都觉得有些不习惯。梁二少回过头去,看到累得气喘吁吁的许多多。
许多多说话牙齿都在打颤:“你你你,你不是在英国吗?” 梁二少哭笑不得:“英国而已,又不是外太空。”
出国以后,梁二少飞大西洋成了家常便饭,许多多算着他回国的日子,每次都去学校里找他,看他打球,一来二去,梁二他们唱 KTV 偶尔也会叫上许多多。
许多多不太会唱歌,被大家起哄起得厉害了,点了一首阿桑的《一直很安静》。
“给你的爱一直很安静,来交换你偶尔给的关心…… 原来眼泪是用来说明,你突然不爱我这件事情……”
唱得有点走音,大家还是很给面子地鼓了掌。许多多放下话筒,朝梁二的方向望过去,他正和几个男生打着牌,背着身,根本看都没往她这边看过一眼。
以为自己要的是曾经,却发现爱一定要有回应。
晚上散场的时候,梁二随便拉了个男生,指指许多多:“你送她回家吧。”
两个人一路沉默,走到公车站边,许多多笑着说:“送到这里就好,我自己坐车回去。”
男生摇摇头:“哪敢啊,梁二少亲自点的名。”
许多多不说话了,他们其实都心知肚明,要是梁二真有心,就不会随便找个别人来送了。
5.
再过了一年多,梁二少开始不怎么回国了。
许多多这才知道,梁二交女朋友了。这次的女朋友,和以往的查莺燕燕都不一样。大家都说,梁二这次栽了。
听说对方品学兼优,貌美如花,梁二为了追她,跑遍了整个区洲。
许多多喝着奶茶听他们聊梁二的风流韵事,吸管戳啊戳,戳到了自己的手。
“许多多啊。” 她听到有人叫她,抬起头。
“怎么不找个男朋友?要不要给你介绍个?”
许多多被吓了一跳,落荒而逃。
又过了两年,梁二少学成回国,风风光光,还带着女朋友一起。
这一次,有人叫上许多多一起,总算没有人再问她 “你来做什么” 了。
她用了多少年,十年?十五年?她终于成为了他的朋友。他最普通的一个朋友。
梁二的女朋友果真如传闻般,跟天仙下凡一样。许多多懵懵懂懂地夹在人群中,跟着他们去吃火锅,唱 KTV。
吃火锅的时候,人人面前摆一杯啤酒,好像这样才算是夏天。坐许多多身边的人站起来给梁二和他的女朋友敬酒,梁二看到许多多,忽然皱起眉头 “咦” 了一声。
“许多鱼?” 梁二少问,“你怎么把自己搞这样了?”
所有人的目光一齐落在许多多身上,许多多尴尬地站起来,举起杯中的酒一饮而尽。其实哪有他表情显示的那么夸张,她不过是瘦了二十斤。
也有人来问过她究竟是如何瘦下来的,其实没有什么秘诀,古人说,为伊消得人憔悴,许多多以前不信,现在信了。
不过现在,瘦不瘦也无所谓了,许多多想,就算是再瘦二十斤也换不到他的青睐。
再然后,大家发现,梁二少这次是真的真的动情了。眼里只看得到对方,情话只说给她听,每天准时准点在她公司楼下接她下班。甚至有情报表明,曾在某家专卖进口食品的超市里看到堂堂梁二少爷推着手推车在买菜!
“最重要的是什么你知道吗?梁二都把人往家里带了。” 聚会听八卦的时候,许多多正在吃牛肉丸,一个丸子卡在喉咙里,吞也不是,吐也不是。
“然后呢?” 她轻声问。
“还能有什么然后。” 对方耸耸肩,在脖子上比了一刀。
梁二少回国之后,许多多却更少见到他了。沈阳说大不大,只是两个人缘分走到了尽头罢了。
这样也好,许多多想,她也应该试着开始一段新的人生了。
可是她才这么想着,还没来得及付诸实践,就已经被梁二少扼杀在了摇篮里。
那天下着大雨,许多多急急忙忙地往家里跑,进入了楼道,却看见有人坐在楼梯口,昏暗的光线,外面是雷声隆隆,他半醉半醒,隐约地叫了她一声 “许多多”。
他到底叫的是许多多还是许多鱼,许多多至今都不知道许多多赶紧掏钥匙打开门,把他扶进屋,他身上半干半湿,也不知道等了多久。许多多将他扶到沙发上坐好。
她给他倒了一杯温水,又去泡热茶。梁二一动也不动地陷在沙发里,许多多忘记开灯了,室内光线很差,许多多端着茶杯回过头,感觉梁二好像和背景融为了一体。
沉默很久,梁二才声音哑哑地开口:“能在你这里借宿一晚吗?”
许多多受宠若惊,立刻腾出房间让给他,梁二说他睡沙发就可以,许多多执意不让,梁二看了她一眼。
屋外刮风下雨,许多多躺在沙发上翻来覆去睡不着觉,一两点的时候,她实在受不了,走到卧室敲了敲房门,轻声问:“你睡了吗?”
没人回答
她又自言自语:“你没睡吧。”
过了几秒钟,头发乱糟糟的梁二一脸无奈地开了门。他的酒已经全醒了,洗过澡,身上还留有一点点酒气,但是一点也不惹人烦。许多多笑起来,两眼弯弯:“嘿嘿。”
正好一阵闷雷,梁二少怔怔地松开握在门把上的手,眼前笑吟吟的女人,和多年前的小胖妞重合起来,隔着长久的时光,让人心里骤然一空。
见梁二忽然不说话了,许多多问:“你怎么了?”
梁二摇摇头,凶她:“你睡不着,吵我干什么?” 全然忘了,许多多才是这屋子的主人。
许多多支支吾吾:“我猜你心情不好。”
梁二盯着她,看了半响,还没开口,肚子先 “咕兽” 一声响,饿了。梁二少气急败坏,为什么每回出糗,总是在这个许多多面前?许多多忽然笑出来。
“笑什么笑!” 梁二继续凶她。
“不知道。” 她一面这样说着,一边越笑越开心,最后受不了捂着肚子在地上笑。
梁二哭笑不得,只得蹲下来,一边忍受着肚子饿,一边帮她顺气。
笑完之后,许多多打开天然气给梁二少下面条,外面还在下雨,油锅发出 “滋滋” 的声音,怕光线刺眼,客厅只开了一盏落地灯,梁二看着许多多的背影,觉得这真像是梦一场。
吃面的时候,梁二终于告诉了许多多他为什么会出现在她家门口。说来说去,还不是一个情字。他的女朋友出身在一个小康之家,但被梁家嫌弃了。
其实他也早就想到会闹得鸡飞狗跳,可是他梁二怕过什么,断信用卡,派人跟踪,被禁足在家他都不怕,反而越演越烈,非要抗争到底才觉得是爱得真。可是对方忽然有一天找到他,明明白白告诉他,她累了,不想再继续了。家中为她介绍了青年才俊,她决定放弃。“别人都说我狠心,你说,我和她,究竟谁狠心?”
梁二少人生第一次,为情所伤,打击太大。也不想被抓回家,看到一屋子的虚伪他就觉得烦,想来想去,他的朋友里,也就只剩下许多多不被人所知。
许多多点点头,拿着手中的啤酒瓶和他碰杯,一瓶两瓶… 梁二本来就醉过,没喝多少,就沉沉睡了过去。剩下许多多一个人,坐在茶几旁,自己和自己喝,一直喝到天边泛白。
第二天梁二醒过来,许多多已经出门上班了,桌上用碗扣着早餐,留一张纸条,上面写着电脑密码。
梁二便真的赖在了许多多家里。他一生得意,第一次摔了个跟头,痛得大半个月都回不过神。
许多多去上班,他就穿在她的狗窝里打游戏,看小说,邋邋遢遢,头发盖住了眼睛,就随手拿起许多多的发箍戴上。
他穿许多多给他从超市里买的二三十块钱一件的 T 恤,最普通的深蓝色家居拖鞋。哪里还有当初翩翩贵公子的样子?可是许多多偷瞟一眼,心里却止不住地欢喜。
有一天,许多多回家,抱了一大堆盒子,手里还捧着一大束鲜花,梁二才知道,这天是她的生日。
他的信用卡统统被冻结,全身上下找遍了,想起还有一只表能值点钱,他却不好意思送给她,就算是离家出走,他也还是梁家二少,哪有送人旧物的道理?
“怎么办?” 他愁眉苦脸。
许多多想了想,跑到房间里,从衣柜深处找出一把吉他:“你、你、你当年,不是说,要唱、唱……《同桌的你》吗?” 她结结巴巴地说,紧张得手心里全是汗水,“你能,给我唱一次吗?”
梁二很不给面子地 “卟嗤” 笑了出来:“许多鱼,你怎么变结巴了?”
许多多涨红了脸,不知道该说什么。
梁二摆了摆手,琴弦一扫,开始唱起来。
“明天你是否会想起,昨天你写的日记…… 谁娶了多愁善感的你,谁安慰爱哭的你,谁把你的长发盘起,谁为你做的嫁衣……” 一曲歌毕,许多多拍得手掌都疼了。梁二忍不住冲她翻白眼:“究竟你是寿星还是我是寿星?”
许多多 “嘿嘿” 笑。
“许多鱼……” 梁二少欲言又止。
6
第二天许多多回家,发现梁二少走了。
屋子收拾得干干净净,甚至比他没来之前还要整齐。许多多坐在沙发上发呆,除了第一天她执意,之后梁二都是睡的这里,她坐在上面,却一点都感觉不到梁二的气息了,好似他从未来过。
后来,许多多才听人说,梁二和他的女朋友和好了,她女朋友其实也是逼不得已,他家里人用她父母的工作来威胁她。好在误会解除,冰释前嫌,皆大欢喜。
在那之后,许多多又见了梁二少一次。他开车在她公司楼下等她,黑色的玛莎拉蒂,把整个公司的人都惊动了。
上了车,他问她想去哪里。许多多想了很久,最后才说:“回家吧。”
梁二点点头,开车看着前方,扭开电台,主持人笑着说 “还记得年少时你深深爱过的人吗”,梁二便伸手又把它关了。
正是下班高峰期,沈阳从黄昏堵到天黑,前面车辆的尾灯光落在他们眼前,梁二少忽然开口,他说:“许多多,别等了。” 许多多看着前方。
“不值得的。”
许多多没有回答,两个人沉默着到她家楼下,她拉开车门,像是才回过神来,低下头对他轻声说:“我知道了。”
那天之后,许多多搬家了。
梁二少最后一次见到许多多,是他二十五岁那天,在他家铁门外,她笑得两眼弯弯,说:“祝贺你,你多年夙愿终于实现。
他愣在原地,仿佛没有听懂她在说什么。
许多多回头望了一眼他家的别墅,灯火通明,热闹的声音从里面传来,那些,都是他的朋友。
许多多笑了笑,转身走了。没有同他说再见。
那天,沈阳下了一整夜的大雪。
7.
许多多走后,梁二少的生活并没有什么变化,该吃吃,该喝喝该谈恋爱谈恋爱。
在梁二少二十多年的人生里,她本来也只是一阵不起眼的风。只是梁二少一直没有同女友谈婚论嫁,他也不再去卖进口食品的超市,因为那里没有许多鱼。
直到有一天,女朋友受不了,终于提出分手。
她平静地说,“你的手表时间比北京时间早两个小时,这是澳大利亚墨尔本的时间吧。”
“梁二,你的心和你的时间,都活在南半球呢。”
梁二哑口无言地看着自己的表盘。他拿起茶几上的打火机,“擦” 的一声,一下,两下,却始终没能将火点燃。
这才想起来,这个打火机,还是许多多送给他的。那是他最缭倒的一段日子,众叛亲离,失恋失意,窝在她的小房子里,颓废不可终他对她说:“别等了,不值得的。
她笑着回答,两眼弯弯,似天上新月:“我知道了。”
再过了一年,沈阳又下雪了,梁二少抱了把吉他坐在院子里一边弹一边唱,问他唱给谁,他只摇头不说话。
“明天你是否会想起,昨天你写的日记……”
第三年的冬天,有朋友告诉梁二,在墨尔本街上看到一个人,应该就是许多多,还把地址抄给了他。梁二立马动身,办签证坐飞机,风尘仆仆地到了墨尔本,守在许多多家外的路边上,那时候,墨尔本还是夏天呢,汗水打湿了他的背,很是狼狈。
第三天,梁二就回来了,喝了一夜的酒,淋了一夜的雪。有知情人说,那天梁二其实等到了许多多,只是她不是一个人回家的。
后来有人问梁二:“你这次怎么这么死脑筋?她爱你爱了二十年,都能放手,你何苦在这里装痴情人?”
二十年,梁二苦涩地笑起来,第一次见面,她圆滚滚的身子往自已身边一坐,挡了他的阳光。
他恶狠狠地向她示威,胖妹,你要是敢越界,我揍你噢!
原来,他错了。
想到这里,梁二又拨了拨琴弦,弦松了,有点走音,他没有调,抱着吉他淡淡地说:“就是因为她等了我二十年,现在才要换成我等她。”
她没等到他,所以,他也等不到她了。
她才是他的太阳。自她离开,他再也不曾见过阳光。
* * *

2.29 闹什么呢?
《如珠似宝》作者:妩墨
001
没有什么浪漫的开端,沈曼珠说,从一开始,她就是以卑微的身份出现在他面前的。
1999 年的夏天,黎景森随祖母一起下乡,沈曼珠的父母从接到消息的那一刻起,就开始忙碌,抹桌子、擦窗户、洗衣晾晒,如果时间充裕,沈曼珠毫不怀疑,他们会将房子重新刷上一遍。
然而,就是这样的隆重和用心,依旧遭到了黎景森的嫌弃。沈曼珠记得,那天他穿着一件条纹开衫,下面是浅灰色的休闲裤,戴了一顶鸭舌帽,一脸不耐烦地从车上下来,看了看周围的环境,便转头对一旁怜着行李的中年男人说:“周叔,我要回去。”
“老周,送他去野外集中训练营。” 他话刚落,便有一位穿着端庄的老妇人从车上下来。
黎景森这才安静下来,十六岁的他是一个 “魔王”,但最怕祖母,黎氏的创始人谭庄。黎家靠酿酒发家,而这里便是她当年的根据地。之后,黎家的生意做得大了起来,涉足的行业也越来越多,便举家迁往更繁华的南岛。
酿酒厂交由原先的几位工人帮忙看顾、打理,沈曼珠的父亲便是其中之一。
沈曼珠与父母将他们迎进房间后,端茶倒水,表现殷勤,在这间,谭庄女士客气地询问了一番关于酒厂的状况,并让老周拿出她特意为表谢意所带来的礼物。
一台电视、一台冰箱,这些东西,即便是当时村里最富有的人家也未必能有。因此,她的父母看见这些,激动得几乎连一句完整的话都说不出来了,只知道一个劲儿地道谢。
沈曼珠觉得有些尴尬,抬起头,便迎上了蹙着眉的黎景森,他脸上轻视鄙夷的神情,让沈曼珠顿时羞愧得满脸通红。
她找了个理由离开房间,黎家的司机老周正靠在外面抽烟,看见匆匆跑出来的她,便笑着喊:“喂,小姑娘。”
两个无聊的人凑一对,便开始聊起来,老周同她说一些南岛的趣事,沈曼珠正听得津津有味时,黎景森走了过来。
老周看见他,恭恭敬敬地喊了声:“少爷。
黎景森点点头,径直看向她,眉峰微抬,淡淡道:“想得到什么好处,讨好周叔可没用。”
沈曼珠被他呛得说不出话来,抬头愤怒地瞪他,结果倒让自己吓了一跳,她从来没有见过这样漂亮的少年,一双眸子像黑耀石般,乌黑发亮,薄唇紧眠,皮肤白哲得连她一个女孩子都自愧不如。
“花痴。” 见沈曼珠盯着自己,他冷冷地蹦出两个字,转身便走了,留下红着脸的沈曼珠愣在原地。
0002
谭庄每次来酒厂,都会待上一段时间,乡下没有酒店,黎家的宅已经废弃,不能再住,因此只好暂住沈家,沈曼珠的父母将最大的房间腾出来给他们住。
小房间里原本就不透气,三个人挤在一起,就更闷热了,沈曼珠索性拿了蒲扇爬上房顶乘凉。
后半夜时,黎景森被热醒,郁闷地爬上房顶,看见背对着他坐着的沈曼珠,黎景森的坏脾气顿时便有了发泄的地方。
“喂,半夜不睡觉,跑来这吓人?” 他走过去,语气不善地开口。
沈曼珠仰头看着他,静静道:“三人挤一间房,太热了,睡不着。
她说得这样坦诚,让原本想要讥讽她的黎景森突然觉得不好意思,便木着一张脸坐在了她身边。
深夜,四周极静,霜白色的月光落下来,整个房顶都被照亮,微风徐徐,渐渐有了凉爽的感觉,可乡下的夏天,蚊虫极多,黎景森没坐多久,就遭到了毒手,平常娇生惯养的少爷,哪里受过这样的罪沈曼珠转头看着他一脸气急败坏的样子,抿起了嘴角。
她朝他挥动手里的蒲扇,这样的举动,虽然有用,却是累人的活,黎景森眯着眼打量她,只以为她是在讨好自己。
清晨,黎景森被刺目的阳光晒醒,沈曼珠已经离开了,老旧的蒲扇放在一边,他渐渐想起,昨晚整夜安眠,快天亮时,朦胧转醒,看见依旧在身边轻摇着扇子的她,一脸的安静。
那天后,黎景森对沈曼珠的态度,不再像之前那么恶劣了,偶尔也会主动与她说话,时间久了,甚至还会在清晨或傍晚凉爽时,与她起去河边散步,并分她一只耳麦,直到听完所有的歌,然后踏着月色回来。
沈曼珠喜欢去酒厂,老式的酿酒坊,不用机器操作,工人们都非常认真,呼吸间全是酒香味,她在那儿帮忙,整个人仿佛都被熏醉了,一点儿也不觉得累。
谭庄很喜欢她,常常亲自教她一些酿酒的方法,她学得非常认真,黎景森来看过一次,见她穿着大,满头大汗也顾不得擦的样子,蹙着眉说:“你还有没有个女孩儿的样子?”
她也不恼,仰头冲着他笑,并将刚酿好的酒端到他面前,满脸孩子般的得意,目光闪闪发亮。黎景森原本嫌弃的心,竟慢慢淡了下去,一时间不忍让她失望,便真低下头去闻。
不多久,谭庄决定离开这里回南岛,晚饭时,她向沈家父母致谢,沈曼珠怔了怔,随即,下意识地朝黎景森看过去,心里竟隐隐有些失落。
听到他们要离开的消息,沈曼珠的父亲突然站起来,对谭庄说:“太太,能请您帮个忙吗?”
谭庄微证,但很快便笑着开口:“你在厂里工作这么久,算是半个黎家人了,有什么困难,你尽管开口。”
“是这样的太太,阿珠今年中考,考进了南岛的一中,这孩子喜欢念书,可在南岛我们没有亲戚,能不能让她住在黎家,当然,钱这方面你可以从我工资里扣,如果不够,就让阿珠帮忙做做家事。” 沈曼珠诧异地望过去,录取通知书发下来时,父亲可不是这样说的,不要说去南岛的一中,她记得,当时父亲这样对她说,哪有这么多闲钱给你读书,还不如早早挣钱贴补家里。
余光中,黎景森缓缓抬起头,眉心微蹙,又露出那种厌恶的神色,沈曼珠呼吸一窒,刚想要开口拒绝,谭庄便笑着看向她,称赞道:“喜欢念书这是好事啊。”
OO3
黎家很大,哥特式建筑,光是修剪得整齐的草坪,就比她原先住的房子还要大,房子侧面,是非常漂亮的花园,摆放着白色的秋千、桌椅,后来她才知道,那是专门为喝下午茶准备的地方。沈曼珠说,从那天起,她才意识到,自己和黎景森究竟是有多大的区别。
就像林黛玉初入贾府一般,沈曼珠进了黎家,生怕自己哪里做得不好。因此,只好战战兢兢,勤勤勉勉,刚住下没几天,便抢着帮大家干活,原本就是乡下长大的孩子,并不娇贵,做起活来,又快又利沈曼珠话不多,与人说话时便噙着笑,十分礼貌谦逊,整个黎家,除了黎景森之外,大家都很喜欢她,谭庄更是常说:“阿珠,我若是有这么个贴心的孙女该多好。”
她正在为谭庄泡茶,听了这话,笑着道:“有您这样的奶奶,那可不是一般人才有的好运。”
黎景森从屋内出来,听见这话,挑了眉看向她,那样轻蔑的目光,让沈曼珠的情绪,整天都变得非常低落。
他是命运的宠儿,怎么会明白,像沈曼珠这样,因为侥幸得到了一直以来都梦寐以求的机会,所以不得不怀揣着忐忑,小心翼翼珍惜的心情。
在黎景森眼里,沈曼珠就是为了攀附荣华,虚伪到了极点的女孩儿,在乡下时,好不容易建立的那一点少得可怜的好感,早已消失殆尽,他与沈曼珠同校,早在刚开学时,就冷冷地嘱咐了她,不许告诉任何人她住在他家,并且不许她与他说话。
沈曼珠答应下来,整整一个学期,她都没有与他在学校说过一句话,偶尔迫不得已碰面,她也像不认识一样,低头很快走掉。
偶尔,黎景森会看着她的背影,怔怔出神,莫名其妙地想起,她为他摇扇子的那个夜晚。
这样的情况,持续到高一快结束时,那个时候,黎景森玩得很凶,与朋友飙车,去野外攀岩,去搏击俱乐部,终于,在某个深夜,安静的黎家,被一阵刺耳的电话声吵醒。
谭庄带着律师赶到时,黎景森已经被关了一整夜,眼圈下一片乌青,律师通过与人交涉才得知,原来,他与人在高速上聚众飙车,被巡警看见,随即拘留。
那晚,沈曼珠整夜未眠,天光乍破时,便起床打扫卫生,修剪花园,管家起床时,看见这场景吓了一跳。
黎景森回来后,谭庄发了好大的脾气,甚至要将他送往英国,沈曼珠站在窗外看着,他迎光站着,身体挺得笔直,低着头,眼角微垂,又倔强又可怜的模样,见他这样,谭庄到底没能狠下心来。
经过这次的事情,沈曼珠才得知,黎景森在十岁时,父母因为车祸去世,从此,便由谭庄抚养长大。谭庄说,至此后,黎景森性子就变了,渐渐孤僻尖锐。
“阿珠,你是稳妥的孩子,答应我,好好看着他,好吗?” 谭庄这样对沈曼珠说。
然而这样的决定,却让黎景森更加厌烦她了,可沈曼珠仿佛不以为意,依旧每日跟在他身后,不远不近的距离。
学校里的同学渐渐看出端倪,朝黎景森喊道:“喂,那是你女朋友吗?”
黎景森瞥了她一眼,冷笑道:“怎么可能。” 他说完便转过了身,没有看见沈曼珠眼底一闪而过的难过。
正是这样的话,让黎景森在忽然间想到了捉弄沈曼珠的方法。
学校里喜欢黎景森的女生很多,据说有过许多告白被拒的,沈曼珠想,他大概是喜欢那种非常特别又漂亮的姑娘,但没有想到,他很快就交了女友,对方果然很漂亮。
他们每天放学后约会,沈曼珠远远地跟着,看着他与女友甜蜜肉麻的模样,她有说不出的别扭,只好转过身,从书包里拿出书,装模做样地看,黎景森看她这样,目光里满是恶意的戏虐,突然,他拥着女生快速离开,躲起来看沈曼珠四处找自己,一脸的迷茫与着急。
他身旁的女友看他愉悦地挑起嘴角,顺着他的视线望过去,扭头不悦地说:“黎景森,当着我的面就这样看其他女生,是不是有些过分?”
女生的话还没说完,就被他突然俯下身堵住嘴唇。
十二月末的天气,寒风瑟瑟,路边的麻辣烫冒出白茫茫的雾气,羊肉串散发出阵阵香味,与年轻男女的欢笑声织成一片,隔着这热闹的街道,沈曼珠静静看着路灯下,亲吻着别人的黎景森,渐渐地,他的侧脸在她眼底变得模糊。
还未立冬,沈曼珠却觉得,真冷啊。
那天后,如黎景森所愿,沈曼珠不再跟着他了,上学放学的路上,他再也见不到她的身影,就连在家,她也仿佛是有意避开他一般,同住一个屋檐下,他们竟然许久都未见上一面。
004
放寒假后一个星期,他闭门不出,却始终没有看见沈曼珠,他装作无意地在管家面前提起,才得知她在刚放假时就已经回家。
他愣了愣,才反应过来,是沈曼珠在乡下的家,在那一刻,黎景森恍然想起,沈曼珠已经在黎家住了将近三年,而他也几乎快要忘记了,她原本就不是黎家人。
后来沈曼珠总在想,他如果没有突发奇想要去乡下找她,那么她与他接下来的人生,会不会又是另一番模样?
但人生从来不存在这样的假设,她还记得那天,她已经收拾好东西,准备回黎家,临行前,父亲将她叫进房间,沉声问她:“东西拿到了吗?”
她这才想起当日他父亲将学费交给她时所说的话,他说,沈曼珠,我让你去念书,是为了要你好好与黎景森相处,讨好谭庄,最好能够拿到黎家酿酒的秘方。原本她以为,这不过是一向势力的父亲的妄想,现在想来,他似乎是认真的。
沈曼珠皱起了眉,然后摇摇头,她父亲见状,突然大怒,扬声喊道:“要么牢牢栓住黎景森,与他结婚,要么就给我拿到酿酒秘方,老子的钱不是白花的。”
沈曼珠不愿与他多待一秒,敷衍着 “嗯” 了声,转身出去,打开门,看见站在夜色中的黎景森。
他眯着眼,神情骇人,四目相对,他眼底的寒意让她生生打了个冷战,半响,咬牙切齿道:“好样的,沈曼珠。”
这几天在家,他反复想起他与别的女孩恋爱时,她隐忍的目光,挺直的背脊,紧握的双手,以及被咬破的唇,心里一个念头闪过,难道她喜欢他?
居然以为她会喜欢他,他真是疯了,更疯的是,他居然还迫不及待想来找她问清楚,他不该忘记她原本就是虚荣至死,又有心机的那种人。
沈曼珠站在原地看他转身离开,想要去追,但抬起脚,却又放了下来,像被抽空了力气,整个人都变得软绵绵的,心脏像被一块铅石压着,钝重的疼,让人喘不过气来。
天空不知道什么时候下起了雨,她伸手揩脸,才发现是自己掉了眼泪,她拼命地咬着唇,怕自己会忍不住号啕大哭。
她是深夜回到黎家的,路过黎景森房间的窗户时,她停了下来,里面黑影影的,没有开灯,她又想起了黎景森寒意逼人的眸子,心里一阵尖锐的疼,转身快步离开。
沈曼珠想黎景森一定会把一切都告诉谭庄,她已经做好了被赶出黎家的准备,但翌日起来,却发现所有人待她,仍旧和从前一样,就连谭庄也不例外。
这样过了好几天,沈曼珠确定黎景森并没有将当日的事情告发,可有什么理由呢?他原本就那么讨厌她,好多次,她都想要跑去问他,偶尔鼓足了勇气,想要走到他身边,却看见他已经拥着别的女生离开。
他与她,形同陌路,即便在黎家遇见,他也是充满厌恶的神情,冷冷鳖她一眼,仿佛根本不愿见到她,沈曼珠被那样的目光击得溃不成军。
005
那些与他有关的回忆,其实并不美好,最温馨的记忆,竟然只是在她跟着他上学放学的路上,那条安静的公路,两边的植被郁郁亮葱,清晨的阳光像金子一般,落在他脸上,她装作不经意地侧头,只看一眼,心就会怦怦直跳。
红漆皲裂了朱门,绿藓挑染了苔岩,时光荏苒,仿佛是倏忽间的事,但只有沈曼珠自己明白,从高中到大学这几年,究竟是怎么谭庄身体因为太过操劳,终于渐渐不支,黎景森不得不去公司,担负起整个黎氏。过了一年,沈曼珠也大学毕业,她没有离开南岛,而是留校任教,做这个决定前,她也犹豫过很久,可是,每当看见黎景森蹙起的眉,越发冷峻消瘦的模样时,她的心就不由自主地塌陷下来。
何况,谭庄又有恩于她,沈曼珠这样告诉自己。
对于她这个决定,黎景森不是不意外的,但随即便冷笑着问:“怎么?想利用老太太的感情,得到秘方?”
沈曼珠抬起头,张了张嘴,最终什么都没说,低下头从他身边离开,她的眼神湿糖糖的,像快要溢出水来,黎景森的胸口突然闷闷的,透不过气。
那些日子,除了睡觉,上课之外,她所有的时间几乎都耗在了医院里,黎景森常是晚上过来,有时,谭庄睡着了,他便站在病床前静静看着,眉目间写满担忧与哀伤,沈曼珠看着他,想起这些年,他与谭庄相依为命的生活,喉咙里就一片灼热。
深夜,他开车载她回去,一路沉默不语,窗外的霓虹闪过,落在他脸上,皆是落寞,有几次,看见路边摆摊卖辊比的,他突然就将车停在一边,西装革履地坐在摊子上吃起来,她坐在一旁,这是他们两个人难得的宁静时光。
年末,谭庄的身体已经快到极限,偶尔清醒时,看着黎景森,便不停地掉眼泪,如果说这一生还有什么遗憾,那就是黎景森还没有结婚成家,她不忍心将唯一的孙子,孤零零地丢下。
黎景森看着瘦骨磷峋的祖母,表情悲恸,走出病房,站在走廊里,他低头看着沈曼珠,一字字地说:“我们结婚吧。
沈曼珠震惊地抬起头,然后,渐渐明白,一时间,哪里能找到可以立刻就结婚的人,毕竟谭庄又是这么喜欢她,想到这里,她牵起嘴角苦笑,半响,轻声道:“好。”
她一向这么顺从,黎景森想起那晚站在门外听见的话,不禁冷笑,她真是好样的,终于如愿,将自己卖给了荣华富贵。
沈曼珠望着他离开,心里像被无数针扎着,细碎尖锐的疼,一直扩散到四肢百散,这一刻,她终于明白了飞蛾扑火的悲壮,那一点点微弱的光,就是她毕生想要靠近的地方。
006
他们没有举办婚礼,虽然谭庄竭力反对,但是,考虑到她的身体状况,黎景森坚决没有同意,沈曼珠的父母对此颇有异议,他们好不容易可以大肆炫耀一番。然而当黎景森冷着脸,将一张数额庞大的支票扔过去时,沈曼珠的父母便人悻悻然地闭上了嘴,沈曼珠却羞愧地闭上了眼睛。
有那么一段时间,沈曼珠常常失眠,深夜,霜白的月光落在房间,她转过身,眯起眼睛盯着睡在一侧的黎景森,然后,想起新婚那晚,他盯着她时目光清冷的样子,心像被人掀住一般,疼得无以复加。
这样的生活,真的是自己要的吗?沈曼珠忍不住怀疑。可是,当黎景森偶尔在夜里醒来,低声呢喃一句她的名字时,她就又一次坚定起来,就是那样微不足道的温柔,成就了她海市蜃楼般的梦。
谭庄没能熬过第二年的春天,她去世后,黎景森开始变得喜怒无常起来。兴起时,半夜将她喊起,随便买一张飞机票,搭乘半夜的航班,飞往国外。他们一起在墨尔本看过日出,也曾相拥看过巴黎郊外的星空,算起来,那是她为数不多的快乐日子。
但更多的,却是黎景森突然莫名其妙的发难,在外面,他是疏离淡漠却彬彬有礼的人,只有在沈曼珠面前,完全像变了个样,刻薄、尖锐,并且翻脸无情,就连在床上也不例外。
有一次,她被逼急了,咬着唇仰头瞪他,恨恨地问:“黎景森,你究竟在闹什么?”
巴掌大的小脸,一双眸子波光溢艳,黎景森忽然就愣住了,许久后,才松开她。
从那天起,他回家的次数渐渐变少,沈曼珠看着空荡荡的大房子,瑟瑟发冷,之后,将所有的精力都投放在学习酿酒上,她喜欢这样单纯机械的工作,繁复的程序,能暂时掏空人所有的思想。
当她发现黎景森有了新欢,已经是很久之后的事了,整个南岛闹得轰轰烈烈,所有八卦杂志都在写,黎氏年轻有为的负责人,新交了女友。沈曼珠拿着杂志,手指渐渐泛出青白的颜色。
她怎么忘了,她与黎景森的婚姻,并不被人知晓,沈曼珠这三个字,并不存在于黎景森的世界,她闭上眼睛,感受到了前所未有的绝望与寒冷。
几天后,黎景森回家换衣服,看见客厅茶几上的那本杂志,他拥着别的女人的照片,占据了最大的版面,她终于知道了吗?那一刻,象景森甚至有些迫不及待地想要看看沈曼珠的反应。
然而,沈曼珠却同往常一样平静,她垂着眼眸,坐在落地窗前,听见动静转过身,看见是他,又慢慢抽回目光。
这样的神情,让黎景森恼怒到了极点,他一个箭步冲到她面前,居高临下地看着她,咬牙切齿地问:“沈曼珠,只要保得住一生荣华,你是不是什么都舍得出卖?”
沈曼珠仰头看他,迎着光,时光轰然倒退,让她想起了很久前在乡下的那个晚上,他说,好样的,沈曼珠。
从一开始,他就认定她是怎样的人,从来没有给过她解释的机会,沈曼珠想,他与她的这一生,大概是再也不会好了。
007
离婚是沈曼珠提出来的,她平静地说,“黎景森,荣华富贵,我都已经享受过了,我们离婚吧。”
黎景森的眼睛慢慢睁大,额上的青筋一点点暴起,胸口剧烈起伏着,他狠狠地握紧拳头,半响后,竭力控制住情绪,一字一句都仿佛都从牙缝里蹦出来,他说:“沈曼珠,从你决定将自己卖给我的那一刻,你就再也没有其他选择。”
她看着他愤怒离开的身影,心里无力到了极点,压抑着的情绪,几乎要让她崩溃,渐渐地,竟生出一种想要毁灭一切的恨意,当爱被困成魔,在她心里化成形,便再不受控制。
那天,黎景森坐在办公室里,回想起沈曼珠平静地说要离婚时的样子,忽然间,眉心直跳,内心躁动不安,仿佛发生了什么事一般。他赶回家时,找遍了所有房间,都没有看到沈曼珠,恐惧一点点从心底漫出来,他与她是最亲密的关系,可是,他居然连她爱去哪里都不知道。
黎景森开车在南岛漫无目的地转,横冲直撞到半夜时,接到了警局打来的电话,他的心随着手机里传来的声音,狠狠抽起,蓦地,手机从手里滑了下去。
从南岛到乡下,需要两个小时车程,黎景森将车开得飞快,一路闯红灯无数,一颗心仿佛被人拎起,悬在半空中,他大口大口地喘息着,脑袋里想的全是电话里那人的话,他说,酒厂着火了。
他第一个想到的人便是沈曼珠,是她纵火,那么她呢?黎景森简直不敢想下去,全身神经都绷得紧紧的。
远远的,就看见火光漫天,黎景森从车上跳下来,跌跌撞撞地向前冲,旁边的人以为他受不了刺激,伤心过度,都拼命拽着他,他四肢乱舞,拳打脚踢地挣扎着,撕心裂肺地吼道:“沈曼珠……” 一时气急,竟晕了过去。
他醒来时是在医院,睁开眼的第一秒就想起了那场大火与不知所踪的沈曼珠,于是拔了针头,立刻从床上起来,冲出去时遇见了正买饭进来的管家。
管家拽住他的胳膊喊道:“少爷,我带你去找夫人。”
酒厂的大火的确是沈曼珠放的,她喝醉了酒,最后 “啪” 一声擦亮了火柴,火苗踝起来时,被附近出来找小孩的村民看见,他喊了人,冒着危险冲进去,将已经龟龟一息的沈曼珠救出来。
沈曼珠躺在重症监护室,病房里很安静,只有呼吸机发出的 “嘀嘀” 声,他穿着无菌服蹲在床边,她脸色苍白,神情一如既往的安静。医生说,她能否醒来,就看她自己的意愿了。
他想起了那日,她瞪着他问,黎景森你究竟在闹什么?
在闹什么呢?后来,他也想了许久,却始终不敢承认,这些年,他时常对她厌烦、冷淡、责难、侮辱,就像个无理取闹的孩子,他想要以此来证明她对他的在乎,可是,她始终那么顺从与平静,就仿佛他始终都是她生命里无关紧要的人,所以才会这样的毫不在意。
黎景森将自己的手缓缓覆在她的手上,喉咙里一阵阵发紧,脑袋胀得生疼,突然间,他想起了许久前的一件往事。
那是祖母去世后不久,他整天不吃不喝地坐着,沈曼珠每次来送饭,都会被他不声不响地推开,后来,她索性不再做饭,就在一旁陪他坐着,整整一夜,他们就在那儿静静地坐着。清晨时,他转过身看她,四目相对,她轻声对他说:“黎景森,从今往后,我会代替祖母陪着你。
她侧着身,眼角噙着一束温暖的光,照亮了她的整个脸庞,他的心,在那一刹那,变得充盈温热。
一个女子将一生中如珠似宝的最美好的时光都给了他,是爱的吧?黎景森恍然想起,他们认识整整十年,居然从未开口对彼此表露过一丝一毫的关于爱的心迹。
他心里一痛,将她的手缓缓拾起,贴在脸颊上,微微闭眼,他在心底对她说,你醒过来,你醒过来,我就还你一辈子的时光。
end.

2.16
明天我就不像今天这样喜欢你了。
短古悲《一眼晴川》
作者:云在意
原来,她并不是天生爱哭。那无法抑制的泪水,来源于多年前少年在她的眼睛里,留下的一条河。
一、
月黑风高夜,杀人放火时。
西梨梨一不杀人二不放火——她要去杜府偷一个大美人。
对一个术师来说,这件事并不难。西梨梨背着昏睡的杜小姐飞身出了杜府。
疾奔入一处密林,梨梨将杜小姐放在大树底下。
小姐醒来后,大为惊恐。梨梨身为女子也不由得心生怜惜,柔声说:“别怕,我不是坏人。我请你来,只是想请教,如何能找到蝙蝠公子?”
蝙蝠公子北墨君,曾经的术师新秀,如今是臭名昭著的魔道高手。
他嗜血,专吸少女的血。据说他若看中谁,便会赠其奇异熏香。少女点燃熏香,他在千里之外都能闻到。他循香去见少女,并在幽会时吸食其血液。
那些名门闺秀,却因他俊美的外表和超凡脱俗的谈吐而痴爱上他。即使被吸干血液,也甘之如饴,九死不悔。
蝙蝠公子行踪诡秘,要找到他并非易事。不过最近有流言说,他相中了杜府的千金。
于是,为找到北墨君,西梨梨绑架了杜小姐。
此时,杜小姐倚在树边瑟瑟发抖,声音娇滴滴:“你找蝙蝠公子做什么?”
“我姥姥的传家宝玲珑佩在他身上,我要夺回来!”
小姐上下打量梨梨,看她不像在说谎,随即叹口气,矫健地翻身跃起,说道:“错了,错了。” 声音清朗,分明是个少年郎。
梨梨惊得后退了一大步,握紧了玉笛。
“杜小姐” 拍了拍身上的灰尘:“别怕,我也不是坏人。我叫鹿萌,是杜老爷请来的术师。”
原来杜老爷发觉女儿被妖孽缠身,护女心切,便请来术师除魔。为引诱蝙蝠公子,杜府今晚特意点燃熏香。鹿萌假扮杜小姐,在房内等候,不料却等来了西梨梨。
鹿萌笑着:“你也是术师吧。我以为你是北墨君的同党,打算将计就计,没想到…… 唉,你…… 你怎么哭啦?”
少年惊讶地瞅着梨梨,看着她眼圈瞬间变红,眼泪簌簌地落了下来。
他不知道,梨梨是个很容易掉眼泪的姑娘。只要情绪稍有波动,即使她不想哭,她的眼泪都会不受控制地流出来。
将梨梨带大的姥姥常为此生气:“身为我的传人,就该坚毅果敢。成天哭哭啼啼的,像什么样子!”
此刻梨梨知道摆了乌龙,心里懊恼,眼泪不由自主地落了下来。
泪光里,梨梨瞥见鹿萌奇怪地盯着自己,赶紧掏出手帕擦干眼泪,嘟囔一句:“眼里进沙了…… 对了,杜小姐在什么地方?”
“在这里!”
半空传来男子带着邪肆笑意的声音。两人惊觉仰头。
银白色的月光下,男子站在高高的树顶,朱红锦袍外的黑色披风微微拂动。他的手一松,怀里的女子便直直地坠了下来。
鹿萌纵身接住,暗惊:杜小姐身旁有那么多术师守着,竟然还是被他得手!
小姐憔悴枯瘦,似一朵即将凋落的花,可嘴中仍在轻声叫着公子的名字。
蝙蝠公子从不直接杀死少女。但她们很快会因血虚而死。
杜小姐看来也命不久矣。鹿萌蹙紧眉头,不管怎样,他还是要将她送回杜府。
“你要去追北墨君?” 他抬头问西梨梨,却见她同情地望着杜小姐,又已泪痕满面。
没见过这么爱哭的术师,鹿萌心中纳罕。他拍拍梨梨的肩头,然后抱着小姐纵身向杜府飞去。
少年隐隐不安:那个女孩单枪匹马地去追蝙蝠…… 不会有事吧?
二、
西梨梨虽然爱掉眼泪,却不怯懦。望见蝙蝠公子展开披风翩飞而去,她即刻紧追。
男子察觉被人追踪,反而放慢了脚步,待她靠近时,突然转身与她打个照面:“姑娘一路尾随,莫非是想打劫不成?”
月光映照着他略带轻佻的笑容。西梨梨看清他的脸,一呆:“是你!”
她见过他,十年前,她七岁时。
西梨梨是个孤儿,自小流浪无依。一日,肚子饿得慌,她在河边捕鱼,不小心落水,差点溺亡,幸好有路过的少年将她救起。
她不记得他怎样用法术烘干她的衣服,也不记得他怎样让水里的鱼儿自动跳上岸。她只记得,他雪白衣衫上的一竿墨竹,还有,他把烤好的鱼递给她时,凤眼里虽盛着淡淡笑意,却有种说不出的落寞。
她年纪小,吃饱喝足后就躺在少年的腿上睡着了。醒来时,身边已不见了他的踪影。
再后来,她被一位老婆婆收养,认她做了姥姥。姥姥传授她法术,让她成为了一名术师。
时光荏苒,少年忧伤的浅笑一直徘徊在她心头。
想不到今日重逢,少年竟然就是那个 “蝙蝠公子”。而她,要从他手中夺回传家之宝。
“是你啊,” 北墨君认出她,似颇为欣喜,“我记得,你叫西梨梨。”
十年前,当他听她怯生生地报出名字时,便说,淅沥沥?这名字好记,像是落雨的声音。
十年后,她听他叫出她的名字,心里一喜,眼泪掉了下来。
蝙蝠公子怔了怔,掏出丝帕递过来。西梨梨记起姥姥的嘱托,一咬牙,用玉笛挡开了他的手。“玲珑佩原是我家的传家宝,被北氏的人抢走后又落入你手中,请还给我。”
公子笑了。自从他拿到玲珑佩,每年都有不少人找到他,对他说出同样的话。
他回答:“恕不能从命。”
打斗不可避免。
西梨梨使出浑身解数,却奈何不了北墨君。若不是对方手下留情,她的脖颈早被捏碎。
再次被击退,梨梨摔倒在地上,眼泪扑簌簌地落了下来。她一声不响地擦干泪水,又扑了上去。如是三番五次,公子叹气:“小姑娘,你不累吗?不如我们明日再打?”
明日打不过,再等明日。明日复明日,明日何其多。
就这样,梨梨与蝙蝠公子,一路同行。公子待她甚好。他给她讲奇闻异事,想法弄来她最爱吃的桃酥饼。还给她买崭新的换洗衣裙。
更重要的是,他从不对她流不尽的泪水感到好奇,只是默默地、耐心地递来丝帕。
梨梨觉得他似乎还是十年前的温柔少年,而不是邪恶的吸血魔头。
她奇怪,他明明可以轻易击败她,或甩掉她,为何会任她纠缠,还对她百般照顾呢?
公子轻笑:“独行无聊。有你这么可爱的小姑娘作伴,我求之不得呢。”
又一日打斗完,梨梨泡在山泉里沐浴。她一遍遍回味着公子说话时的语气、神情,脸不自觉地红了。
然后她一转头,就看到了鹿萌。少年拿着她放在岸边的玉笛,笑眯眯地向她挥手。
鹿萌之前拍梨梨的肩时,在她肩头留下了 “寻踪符”。将杜小姐送回杜府后,他发动符咒,找到了梨梨的行踪,一路尾随窥探。梨梨与蝙蝠打斗的情形也落入他的眼里。
梨梨每败必哭、哭完又战的情形,让他颇觉好笑。但不知为何,这个喜欢掉眼泪,又默默把眼泪擦干的女孩,竟令他有一点动心。
这回他在梨梨面前现身,是想趁蝙蝠公子不在,与她共商对敌大计。可他还没开口,就听一声尖叫。泉水里蓦地溅起片片水花,将他兜头淋了一身。
他好不容易睁开眼睛。已穿着整齐的西梨梨,脸有泪光,两手不停地向他飞出暗器。
鹿萌狼狈躲闪,叫屈:“其实,我什么都没看到啊……” 话音未落,腹部狠狠中了一拳。
鹿萌连连赔礼道歉,还从怀里掏出一包杏仁糕给她吃,梨梨才终于消了气。
三、
梨梨听鹿萌说要一起对付蝙蝠公子,不置可否,却问他:“为什么当年前途似锦的术师北墨君,会堕入魔界?”
鹿萌讶异:“那可是轰动一时的事,你居然不知道?他落入魔道,是因为一个女子。”
少年缓缓道出往事,眼神幽暗不明。
对所有术师来说,最高的荣耀是成为国师。但本国的历任国师,都是出自最强大的的两个术师家族:南氏和北氏。南北两族明争暗斗,积怨已久。国师之争,更成为双方争斗的核心。十年前,恰逢前国师退位,国主需要新选一位国师。南北二族摩拳擦掌,各推举出一位本族最优秀的术师,参加甄选。
被推举的两位敌对天才术师,北氏北墨君与南氏南清荷,都不过十七岁。
谁都没想到,他们是一对爱侣。
据说,他们初识时,并不知彼此身份。待知晓真相时,情愫已深,难舍难离。
双方族长暴怒,逼两人分开。南清荷的性子执拗,宁可与亲人决裂,也绝不和情郎分手;北墨君却不愿背弃家族,希望北族可以接受他与清荷的感情——这当然是不可能的。
南清荷提议私奔,北墨君犹豫再三,答应了。两人相约在初识的地点碰面。可是那一晚,约定时辰已过,南清荷却没有等到北墨君。
她以为他改变心意了,退缩了。悲愤绝望中,性格刚烈的少女祭出三昧真火,引火自焚。
其实,北墨君是被族中长辈纠缠耽搁了。姗姗来迟的他,看到的,是恋人在火中燃烧的最后影像。那火灼痛他的眼,将他的心烧成一片灰烬。
那晚之后,北墨君便销声匿迹,再无人知晓他的行踪。
三年后,北墨君化身为嗜血公子重现世间。据说,他开始修炼一种邪术,需要少女血做引子。于是,他四处猎艳,将吸取的少女血都收集在宝物玲珑佩内。
蝙蝠公子沉迷于邪术,心性渐渐入魔。不久前,几位曾待他恩重如山的北族长老,也惨遭他的屠戮,现在的北墨君人神共弃。
鹿萌讲到这里,停下来。良久的沉默后,梨梨长吁了口气,忽然问:“南清荷是不是长得很美?”
鹿萌想了想:“我小时见过她,她的确很美。每次出现,都会让所有人驻足赞叹。”
临走时,鹿萌坦言,他斗不过蝙蝠公子,要找其他术师联手抗魔。
“你不帮我不要紧,别被北墨君骗了。他外表温柔,实则冷酷,因为他所有的感情,都已经……”
梨梨明白鹿萌未说完的话:北墨君全部的感情,都给了死去的南清荷,那个痴情如火的少女术师。
当夜,梨梨做了梦。她梦见北墨君笑着说喜欢她,将她抱住。突然,他露出雪白尖利的牙齿,咬穿她的脖颈。
梨梨惊醒,天色透亮,又到了她与北墨君每日打斗的时刻。
这天的比试,梨梨心不在焉。挥来舞去的一根玉笛,被公子一根指头就轻松拨开。可是忽然间,公子脸色大变,身形摇摇欲坠。
四、
“你…… 在玉笛上涂了毒!” 北墨君吃惊地盯着梨梨。但随即,一双凤眼微微眯起,目光冷冷地一笑,“是我笨…… 看错了你……” 他摇摇晃晃地昏倒在地上。
梨梨惊痛惶惑,不知道发生了什么事。她冲过去抱住昏迷的公子,帮他驱毒。
忽然,她感觉到身边多了个人,一抬头,看到神色深沉的紫衣少年——鹿萌。
笛子上的毒粉是鹿萌涂的。他在暗中窥视二人比斗,见蝙蝠公子对梨梨无甚防范之意,就想出借刀杀人的计策。他趁梨梨沐浴时,在玉笛上做了手脚。梨梨没有中毒,是因为鹿萌特意让她吃了混有解药的杏仁糕。
梨梨知晓经过后,又惊又怒。她握紧玉笛,护着公子,拦住欺身上前的鹿萌。鹿萌虽不情愿,也不得不与她拼斗起来。
梨梨落了鹿萌的下风,渐无还手之力。
原本躺在地上的北墨君,突然跃身跳起,与鹿萌对了一掌,将他震得摔了出去。
“区区一点毒药,能奈何得了我?” 蝙蝠公子闪电般逼近鹿萌,捏住他的脖子。
梨梨不忍,高叫:“别伤他!”
公子恍如未闻。他盯着鹿萌,面色忽然大变:“你…… 你是谁?与清荷有什么关系?”
刚才他一直未看清少年的脸,此时才恍然惊觉眼前的面容似曾相识。
鹿萌面色发白,勉强笑了笑:“我叫南鹿萌,清荷是我的姐姐。你觉得我们长得像吗?”
梨梨惊得说不出话来——鹿萌竟然是南清荷的亲弟弟!
北墨君凝视着鹿萌,缓缓收了手:“你来杀我,是要为你姐姐报仇?”
“不。姐姐虽因你而含恨赴死,但并非你所杀,我与你没有私仇,” 紫衣少年挺直了脊背,“我杀你,是为除魔卫道!”
蝙蝠公子冷笑:“报仇也罢,维护正道也罢,你要杀我,我不怪你。可是,不久前,有人冒充我暗杀了我北族长老,是你做的吧,这也是所谓的正道吗?”
梨梨吃惊地望向鹿萌:杀害北族长老,竟然是鹿萌冒充北墨君做的?他竟如此心狠手辣,残杀无辜同道?
鹿萌大怒:“你别血口喷人!我怎么会做这种事?何况,这世上除了你,还有谁能在一夜之间杀死北族几大长老?”
少年目光一转,瞥见梨梨脸上惊疑的神色,大急:“梨梨,相信我,我真的没有……” 他边说边猛地冲向前,梨梨不自觉地挥动笛子。笛子的一端碰到少年受伤的肩头,鲜血涌出。
伤口不深,但鹿萌的眼神却似受了重创。他悲伤地望着梨梨,声音低沉:“你不相信我?”
心思缜密、狡黠灵动的少年,此时失去了所有的应变。
梨梨想不到他没躲开,心内大为歉疚。
不容她多想。林间忽而升起浓密诡异的雾气,一群黑影无声地围住他们。
是鹿萌召集的术师们到了。
五、
术师们联手布下严密阵法,围困住北墨君。鹿萌、蝙蝠公子与众术师都消失在茫茫白雾里,梨梨被挡在阵外。白雾中传来的杀喊拼斗声,似渐行渐远。
梨梨焦虑无措。
过了许久,雾气终于散去。梨梨悬着心,在山林间攀爬寻觅,终于在一块巨石背后,找到重伤昏迷的北墨君。他中毒不轻,又与术师们斗法,能杀出重围躲到这里,实属不易。
此时梨梨可以轻而易举拿回玲珑佩,完成姥姥的心愿。望着公子苍白的脸,她无法这么做。
梨梨找了一处隐秘洞穴,在洞外布下障眼法,将公子安置在洞内。
喂药时,昏昏沉沉的蝙蝠公子突然叫了几声:“清荷,清荷!”
生死关头,他心里念念不忘的,始终是她。
夜半,公子睁开眼。他不说话,眼睛充满赤红的血色。长期修炼邪术,已影响他的心智。平时靠体内真气压抑的魔性,在真气大损时便如毒蛇般昂起头。
眼看公子的眼神渐显癫狂,梨梨急忙取出玉笛,吹奏起 “清心咒”。曲子有宁神疗伤的功效,却极耗费吹曲人的内力。
北墨君眼里的血色渐渐退去,神情安静下来,安宁地沉入了梦乡。
公子再次醒来时,一眼就看到伏在身边的少女,睡容倦怠。手边的玉笛里有斑斑血迹。
北墨君动容:这一夜,她到底吹奏了多少遍 “清心咒”?
煎熬的一晚终于过去。
两人坐在溪边汲水,北墨君忽然说起南清荷。
他们初次邂逅是在一条叫晴川的河边,两人因赌气斗法而相识,然后相知相恋。他答应她,会拿北氏的至宝玲珑佩送给她做聘礼;而她笑着说,要把晴川河带回去做她的嫁妆,因为这是属于他们两人的河。
然而,所有的深情誓言,永远消失在那个黑夜。
他伤心欲绝。
自甘堕落投入魔道,既是自恨自伤,也是要寻求救回清荷的方法——只有魔道才有起死回生的邪术。
邪术需要三件东西:逝去之人的身上之物、一个强大的法器、以及九十九个少女的血。
身上物最简单,他有清荷相赠的一小截发辫;强大的法器也不难找,他从北氏珍宝阁里盗走了玲珑佩;最后只剩收集九十九个少女的血——一旦开始,他就会踏上邪恶的魔道,再也无法回头。
第一次动手前,他又来到晴川河边。那时,他正巧遇到一个小女孩失足落水,便顺手将她救起——她就是西梨梨。
那日之后,世间只有蝙蝠公子,再无少年北墨君。
六、
“其实我让清荷复生,只为了跟她说一句话。不说出这句话,我的心永远不会安宁…… 你年纪小,是不会明白的。” 公子叹息。
梨梨当然明白。之前北墨君误会她时,她也曾不顾一切地想救回他,只为让他明白:她没有负他。所以,北墨君不惜被万人唾弃,化身成魔,只为回到那个错过的夜晚,回到那条河边,告诉苦苦等待的恋人:他没有负她。
“如今,我已收集到九十八个少女的血。” 公子笑着,眼中无丝毫喜悦,“我死后应当坠入万劫不复的地狱。不过,对我来说也不算什么。因为这么多年来,我每日都活在地狱之中。”
他的笑忽然消失,一股甜美的熏香味飘入他的鼻内——是他赠出的香料,第九十九个少女在召唤他。
方才亲密的交谈戛然而止,空气骤然变得冰冷。
“别再去害人了,我愿意把我的血给你。只希望你在救活南清荷之后,把玲珑佩交还我姥姥。”
北墨君沉默地望着梨梨,良久。
他笑了,语气轻飘飘:“这可不行。我也不是随便哪个女孩的血都会要的。”
说完这话,他用 “缚身咒” 制住梨梨,然后拿着玲珑佩,循着香味的方向疾飞而去。
西梨梨因整晚吹奏曲子,元气大伤,好不容易才解开 “缚身咒”,急急追上去。
无论如何,她不愿见到他再多害一名少女。
斜阳落下时,梨梨追踪到一处宅院。香味从内屋传来,隔着窗纱,屋里的情形清晰可见。
蝙蝠公子紧抱一妙龄女子,场面香艳无比。也许感觉到被窥视,公子抬起头,面对窗纱,接着张开嘴,狠狠咬住女子的脖颈,带着笑意的目光犹自盯着窗外的梨梨。
梨梨只觉浑身冰冷。虽然她知道他吸血,但亲眼目睹此景,记忆里的温柔少年砰然碎裂。她全身僵硬,连转身离开的力气都没有。
忽然,两只手掌挡在她的眼睛前面;“傻瓜,不想看就闭上眼。”
是鹿萌,他利用那枚 “寻踪符” 找到了她。梨梨的泪水呼啦啦地掉下来,止也止不住。鹿萌见她哭了出来,反而松了口气。
他拉着梨梨闪身躲到角落。看着梨梨伤心的模样,鹿萌心里痛惜,忽而闪过一个奇怪的念头:蝙蝠公子难道是故意暴露行踪,只为让梨梨看到刚才的那一幕?
梨梨一边擦眼泪,一边告诉他,北墨君修习邪术,是为了让南清荷起死回生。
鹿萌讶然,他摇摇头,眼神悲伤:“这种邪术从未成功过。有声称所谓复活的,不过是造出痴呆丑恶的活死尸罢了。”
他发出召集的信号。片刻后,南族术师们在夜色里显出身形,杀意四起。北墨君大笑着飞出屋子。
一场混战。
蝙蝠公子的身形如鬼魅般飘忽,他扇动披风,冲出了术师们的包围,消失在夜色里。
鹿萌气得直跺脚,无奈地回去找梨梨,却发现她不见了。他很快又发觉了另一件事:梨梨解开了他在她肩头落下的 “寻踪符”。
六、
梨梨在夜色里孤身前行,怀着微茫的希望:一是要劝阻北墨君施行邪术;二是要将玲珑佩带回给姥姥。
本来玲珑佩是她接近蝙蝠公子的最初目的,但现在已不那么重要了。
如果时光能倒转,她希望回到初遇他的那天。那么,她一定竭力劝阻他踏入魔道。
夜色漫漫,不过,梨梨很清楚要去哪里找北墨君。
晴川河。
他与南清荷相恋、决别的地方。他一定会在晴川河边让恋人重生。
凭着十年前的记忆,梨梨一路向东。黎明时分,到达一处翠绿幽静的小山谷。风景旧曾谙。
然而似乎少了什么——晴川河不见了!
梨梨焦急地东寻西觅,忽然惊喜:一袭黑披风的蝙蝠公子,在小山坡上负手而立。公子见到她的一瞬颇显讶异,随即换上一副有礼而冷淡的神态。
他听她说在找晴川河,笑了。
他说,清荷曾笑言,要把晴川河带去做她的嫁妆,因为这是属于他们两人的河。虽是戏语,但他知道借助玲珑佩的强大法力,可以将极大的物件缩成极小,那么带走一条河也是轻而易举的事。
清荷死后,他想起她说的话,就决定利用玲珑佩带走晴川河。
北墨君盯着梨梨,缓缓开口,“可是那天我正巧遇到一个小女孩。她的眼睛像晴川河的水一般清澈…… 于是,我把晴川河化作两滴水,分别藏在女孩的两只眼睛里。”
梨梨惊讶得说不出话来。
原来,她并不是天生爱哭。那无法抑制的泪水,来源于多年前少年在她的眼睛里,留下的一条河。
蝙蝠公子说到这里,取出玲珑佩,默运玄力,低声诵读咒语。
两粒晶莹的水滴,从梨梨眼底滑出,落在公子摊开的手掌上。公子手一扬,水滴落地,瞬间化作一条清澈的河,潺潺流淌在山谷之间。
“抱歉,我不知道它会让你掉那么多眼泪。” 公子道歉。
梨梨揉揉酸涩的眼睛,不习惯如此干燥。她摇摇头:“这也没什么。” 她急忙劝说他放弃邪术,说南清荷的死,不是他的错,“她在天有灵,当知道你从来没有辜负她,一定不希望见到你如此痛苦。”
蝙蝠公子神情一震。半晌,淡淡一笑:“太晚了。”
他不再理会她,径直走到河边,将清荷的发辫、贮血的玲珑佩摆在地面,手指翻动,连结了数个法印。骤然间,风起云涌,原本平静的晴川河开始翻滚激荡。
梨梨虽不会邪术,却也知道,这是起死回生的第一步:招魂。
清荷真的会起死回生吗?梨梨心如乱麻。
可是片刻之后,风停了,河水也平静了,一切异像消失得无影无踪。公子面色惨白,喃喃:“为什么?为什么你的魂魄不出来?难道你死都不肯原谅我吗?” 他俯身吐出一口血来。
梨梨一惊,跃上前扶住他。
忽然一片黑压压的人群冲入山谷。是南北两族的术师们,他们虽一向龃龉不和,此时却同仇敌忾,誓要铲除蝙蝠公子。鹿萌也在其中。这个心思机敏的少年,想起梨梨说北墨君要救活南清荷,很快就猜到蝙蝠前往的地点:晴川河。
周围嘈杂的人声,刺激了绝望的蝙蝠公子。他猛然抬起头,双眼一片赤红,神情狰狞欲狂。
七、
眼看蝙蝠公子魔性发作,术师们知是大敌来临,肃然严阵以待。血腥之战,一触即发。鹿萌冲上前,想将梨梨拉出来。
却见少女默默地取出一支玉笛,凝神吹起曲子来。曲音婉转温柔,如迷蒙的细雨,沁人心脾。空气里的杀意,也仿佛渐渐被雨声消融。
其实梨梨前一夜吹笛,耗费了大半内力,现在已是强弩之末。一曲吹毕,她两眼发黑,身子软绵绵倒了下去。
“梨梨!” 鹿萌惊叫。公子伸出手臂,接住少女,将她抱在胸前。他眼里的赤红已退去,神智复醒。
悠扬的曲音停止,四周的空气又变得紧张。
忽然河对岸有人说话:“可惜呀,可惜!”
说话的是位满脸皱纹的布衣老婆婆,她冷冷地盯着公子。梨梨听到熟悉的声音,睁开眼,惊喜:“姥姥!” 若不是浑身无力,她早已飞身扑到姥姥身旁了。
北墨君凝神望着老婆婆:“你是谁?” 也许是从对方眼神中捕捉到一丝熟悉的气息,他忽然神色大变,全身颤栗起来:“不、不可能…… 你…… 你不可能是……”
梨梨惊讶地看看公子,又看看姥姥,不知道两人之间发生了什么。
姥姥缓缓抹了一下面颊,人皮面具脱落,显出清丽无双的年轻面容。
那是明艳如彩虹的面容,一出现,便让所有人驻足赞叹。
北墨君与鹿萌先后叫出声来:“清荷!”“姐姐!”
梨梨震惊得不敢相信:收养了她十年的姥姥,竟然就是南清荷!
南清荷没有死。
十年前的那晚,她在晴川河边焦急地等待北墨君,没想到等来的却是北族几位长老,更没想到,他们竟然卑鄙地联手暗算她,要将她置于死地!
“是北墨君让我们来送你上路的!他胸怀大志,岂能被儿女私情所拖累?” 重伤之后,清荷听到有人这么说。
北墨君!刹那间清荷对这个名字恨之入骨。她跳入晴川河,利用仅剩的一点法力隐身,随水漂流而去。
她受伤极重,担心北族追杀,于是戴上人皮面具,化装成苍老虚弱的婆婆,隐居乡野。
不久,她遇到一个眼神清澈如晴川河水的孤女,心有所动。于是十七岁的她,以老婆婆的身份,收养了七岁的西梨梨。
伤痛渐愈。她通过暗中查探,终于明白整件事的始末。其实这是北族长老的阴谋:为了让北墨君一心一意成为国师,长老们不惜暗地对她痛下杀手;甚至还合力造出‘清荷自焚’的幻像,以让姗姗来迟的北墨君彻底死心。
虽然知道了真相,清荷依然恨着北墨君。
她心高气傲,性子激烈,一旦爱了,就将世间其他人、其余事皆抛之脑后;然而他呢?虽然爱她,却还牵挂着族人、荣誉、个人抱负…… 如果不是他犹豫不决,还将私奔之事告诉族中人,她又何至于受那么多的苦?
她对感情的要求极高。譬如巧夺天工的精美器物,若是不小心染上一点小瑕疵,她是宁可断然砸碎,也不会再用。所以,她不肯原谅他。
可是她还在暗中关注他。他颓废憔悴,他背弃族人、残害无辜、堕入万劫不复的魔道…… 所有发生的事,她都看在眼里,满心喜悦——因为这表明了他对她的爱是如此痴迷热烈、不顾一切。
杀害北族长老的人也是她。
她曾是南族的顶尖术师,法力可与北墨君比肩而立。这些年来,她一直潜心修炼,法术更加精进。装扮成北墨君去杀北族长老,对她来说,易如反掌。如此一来,不仅可报十年前之仇,还能令北墨君与族人更加势不两立,可谓一箭双雕。
她为了他,背弃尘世中的一切;所以,她宁可永不相见,也要他在痛苦中将她放在心的首位。
南清荷说着,睥视着目瞪口呆的两族术师们,露出得意的笑容。
八、
梨梨听完清荷的话,只觉脑海一片茫然困惑。她感激姥姥,不,是清荷的十年养育之恩。可是,她完全无法理解清荷的想法。她忽然想起所谓的传家宝玲珑佩——这只是南清荷的一个谎言罢了。
北墨君初始的震惊已经消失了,只是宛如泥塑般立在原地,呆呆望着曾经的恋人。
他深爱她,不惜为她沦为妖魔。可现在才知道,曾沉重如山的思念、痛苦、希冀竟皆是虚妄之沙,不堪盈手一握。
北墨君稳了稳心神,将怀里的梨梨郑重地交给鹿萌。一展披风,直飞去河对岸,站在清荷身边。
清荷嫣然一笑。蝙蝠公子缓缓伸手将她搂住,在她耳边低语:“其实,我只想告诉你一句话,我不曾负你。”
说这句话时,他脑海里忽然浮现出梨梨的脸,悲伤的、微笑的、担忧的,填满了他整个视野。北墨君闭上眼,继续说:“从今以后,你我再也不要分离。”
河对岸的梨梨抬起头。
她看到北墨君张开双臂抱住清荷,在她耳边呢喃着什么。清荷神色微变,却随即绽开笑容,也环抱住公子。接着,二人身上轰然起了火,烈烈红光瞬间罩住这对情侣。
蝙蝠公子竟是要用三昧真火,与清荷殉情。
众人惊呼。鹿萌急念引水咒灭火,根本不顶用。两位天才术师,一对爱恨纠缠的情侣,很快化为白色粉末,消散在风里。
梨梨难过地失声痛哭起来。鹿萌将她拥紧在怀里。
梨梨永远不会知道,公子在火中闭上眼时,耳边不断回响的,是阵阵温柔如细雨的笛声。
万水千山踏遍,所求的,原来不过是一曲笛音。然而,世情变幻流转,终究谁也无法为谁停留,只能在一曲终了之时,转身,离去。
* * *
2.15
陈年旧事的后续结局就是他会在将来爱上别人。谁知道自己有一天到底会不会拥有幸福呢,祝你好,祝福你,也许有一天我也可以像你一样碰到重要的人。

短现悲《夏夜树上有蝉鸣》
作者:小狮
1. 习惯总让人着迷
顾蝉冲着黑影叫了声 “夏叔叔好”,而后习惯性地将手伸进夏叔叔的大衣口袋里,试图从里面摸出几颗每次必有的冰糖。
她把口袋的边角都摸了一遍,没有发现冰糖质感的东西后略微诧异地抬头。
电影院正放着胶片电影,借着放映机口的光,顾蝉鼓大了眼睛。
夏夜正面无表情地看着她。
顾婵喇地涨红了脸,往后跳了一大步,但偏偏手卡在了夏夜的上衣口袋里,被拉链带住怎么都拽不出来,把她给急得:“我不是要偷东西,我只是 ·… 夏叔叔呢?” 夏夜将她的手从口袋里拿出来,低声道:“爸爸去世了。”
顾婵瞪大了眼睛。
“那天我爸放电影时突发脑出血,送医院没抢救过来。”
“对不起。”
夏夜摇了摇头。
放的片子是部黑白喜剧片,大都是顾婵这种十几岁刚刚结束考试的学生来看。电影里的男主角克拉克 · 盖博还没有出演后来让他大红大紫的《乱世佳人》,此时他和女主角在耶利哥墙吵得不可开交。整个电影院的人都在笑,
顾蝉却频频向后望,黑暗中少年的身影单薄且孤独,让顾婵有点难过。
夏叔叔是这家老电影院的中流砥柱,顾蝉记事起他就在这里给孩子们放电影看,口袋里永远装着一袋冰糖,孩子们来看电影时会主动跑过去在他口袋里掏冰糖吃。
不习惯的显然并不只有顾蝉一个人。
有男生踩在座椅上嚷嚷:“夏夜你带冰糖没有?”
夏夜摇头,闷头换胶片。电影结束时,顾蝉从他身边经过,双眼通红地站在他旁边时把夏夜吓了一大跳,顾蝉跟他说:“你下次可以在口袋里准备一些冰糖。”
也许大家想吃的并不是冰糖,只是那些习惯了的味道
让人着迷罢了。
夏夜无声地望着她,点点头。
2. 少年与汽水瓶盖
自从夏叔叔去世后,夏夜就退学去电影院接班。
听说他成绩本来就不好,虽然已经高三,但估计连大专都考不上,家里又没有可靠的亲戚,收入也成了问题,
他只能过早地学会扛起生活的重担。
顾妈妈把知道的这些告诉顾婵时,满是唏嘘伶恼的神情。
她给零花钱时也多给了顾蝉五块钱,嘱附她:“你下次再去看电影,别光买自己吃的,给夏夜也捐瓶牛奶。这孩子,挺可怜的。” 顾蝉也跟着唤声叹气,揣着钱去小卖部。她买了一瓶汽水,起子撬开瓶盖落在地上没听见声响,她住旁边一看一只手正巧接住了那只瓶盖。“你怎么在这儿?” 顾蝉见到夏夜,连忙又多买了一瓶牛奶。
夏夜笑了笑和她打招呼,在小卖部柜台前将汽水瓶盖一一捡起,而后从身后背包里掏出一把小锤子,在地上一个砸一个准地把每只瓶盖都敲扁。
“最近怎么没去看电影?” 夏夜反问。
顾蝉把牛奶塞给他:“最近在忙着月考,要中考啦,压力挺大的。”
夏夜坚持不要那瓶牛奶,反而从口袋里掏出几颗冰糖递给她:“你尝尝?和我爸以前买的有差别吗?”
他有点期待地望着顾蝉。顾婵把冰糖塞嘴里,被满嘴的甜味冲击得鼻酸。她有点不忍直视夏夜神情里的悲伤,只是笑嘻嘻地点头。
夏夜开心地笑了,将那些砸扁的瓶盖收到背包里后朝她挥手告别。
顾蝉握着没送出去的牛奶有些忧伤,惆怅了片刻后,沉默地跟上了夏夜。
她设想了一下要是自己最爱的爸妈出了事…… 好像只是想象一下那种可能,都悲伤得马上就能哭出来。而夏夜,已经告别了至亲,独自艰难生存着。
夏夜先是去了废品收购站。他把书包里那成百上千被砸扁的汽水瓶盖倒出来, 哗啦啦一阵声响堆成了一座小山, 夏夜扯着嗓子和老板讨价还价:“这次比较多,算我三分钱呗。我上次去问了,有些社区里卖五分钱一个,三分钱
你还赚了不少呢。”
他卖了那些自己捡来的瓶盖,从老板那里接过去几张皱巴巴的纸币。
顾婵躲在树后,心情越发低落,口袋里的零花钱更像是一记耳光,让她耳根发热。
夏夜将那几张纸币小心塞进背包。顾婵认得那个军绿色的老式背包,以前夏叔叔一直背着它,而现在换成夏夜背着它,小心翼翼带着缅怀的神态。
他随后去小卖部称了一斤冰糖,又买了一些话梅,用袋子封好后装进包里,按照来时的路慢腾腾往回走,脚下的石子被他踢来踢去,顾蝉这才注意到他的球鞋。
球鞋已经被穿得发黄,鞋帮也开了口。
顾蝉没再继续跟着他,她蹲在榕树后,盯着自己新买的运动鞋发了很久的呆。
3. 华灼灼的梦想
夏夜和他爸爸一样,习惯在口袋里装着一袋冰糖。
比较特别的是,夏夜买冰糖的钱是一个个汽水瓶盖换来的。他每天背着小锤子上下班,走路习惯看脚下,看见汽水瓶盖就捡起来,砸扁后开心地吹声口哨,扔进背包里。
顾婵初三最后一个学期,唯一的休闲活动便是来夏夜这里看电影。夏夜渐渐变得开朗,会用话梅糖果逗小朋友们玩,愿意花费自己的时间给他们额外放《猫和老鼠》剧场版。
顾蝉保证每周去两次的频率,和夏夜说话也熟练自如,但每次从他口袋里掏冰糖还是忍不住手指颤抖,好像夏夜是个电极,她稍稍触碰到就会导电。
九月份高中开学,顾蝉的同桌是个恶霸一般的女生。
苏苒对一切不顺眼的事物都抱以严重敌视,她长得膘肥体壮,俨然成了整个班级女生的风向标。
顾蝉很无奈,虽然看不惯她,但也始终不敢反抗。
那天自习课全班同学被老师叫去放映室看电影,放映室不大,苏苒领着一众姐妹抢占了前面几排的位子,顾婵只好落座最后一排,无意中一回头,看到了正在摆弄放映机的夏夜。
她抬手就想和夏夜打招呼,但不知怎么又默默转过身去。她孤身一人坐在远离热闹中心人群的角落,莫名就是不想让夏夜看见此刻形单影只的自己。
电影讲述了一个有关亲情的故事,中间有个片段是母亲在手术室里分娩,放映室里掀起了小小的波澜。
突然影片卡在某个镜头上,大家缓过神,回头去看放
映员。放映员正盯着电影出神,分明是忘了此刻自己应该换上另一半的胶片。
此时此刻,连顾婵也不禁觉得尴尬。
“什么呢!” 苏苒突然大叫了一声,站起来指着夏夜嚷嚷:“你看什么呢?”
夏夜没反应过来,慢半拍地站在原地,疑惑地看着那些对他怒目而视的女生。
顾婵心惊肉跳时,苏苒已经大步流星冲过去,涨红了脸站在夏夜面前,疾声厉色:“你还看得目不转睛了是吧?想什么呢?!”
苏苒不停地质疑夏夜,老师从外面跑进来,苏苒指着面露尴尬的夏夜咄咄逼人:“他盯着分娩镜头看了好久,连换胶片都忘了!谁知道他在想什么!”
顾婵在后面为夏夜捏了一把汗。
老师为夏夜解释了几句,苏苒仍是吐咄逼人,质疑夏夜的人格,老师让夏夜快走。
顾婵背着书包跟在夏夜后面跑了出去。
夏夜回电影院,又放了一场电影。面对欲言又止的顾婵,夏夜有点难为情地开口:“我刚才…… 刚才只是想到了我妈妈。她是个助产护士,看过太多母亲分娩的画面。她身体本来就不好,明知道那么痛苦,那么困难,还是不顾身体问题生了我。我……” 他哽咽了一下,觉得挺不好意思地压低声音,“我很想念她。嗯,天下所有的母亲都值得尊重。”
顾蝉仰头望着他,悄悄移动脚步站得离他近了些。她
说不出安慰的话,只是想将自己无声的慰藉传递给他。
这天的电影是《飞越疯人院》,影厅没什么人,夏夜就坐到她身边和她一起看。麦克墨菲带领精神病院的病人出海打鱼,夏夜少见激动地慨叹了一声。
顾蝉转头看他,发现他眼睛里满是跳跃的光芒。
他入戏到忘我,低声喃喃道:“麦克墨菲的梦想是自由,我的梦想是希望能在有生之年拍一部电影。嗯,一部不浪费胶片和时间的电影。”
或许夏夜自己都不知道,此刻他眼里的光芒,那么夺目灼人。
4. 前所未有的危机
夏夜的职业生涯面临着前所未有的危机。
也不知道是不是苏苒的缘故,夏夜近来频频被影院经理叫去谈话,说他行为不够检点,影院接到不少顾客的投诉电话。夏夜试着解释,但苦于没有证据。
苏苒气焰嚣张,每天课间便召集她那群小伙伴,自得地汇报有关夏夜的消息,说自己找朋友去给他工作的影院投诉,这么下去,夏夜一定会被解雇之类的。
顾婵握着拳头,怒瞪着她,小宇宙处在将要爆发的边缘,到底没敢站起来。
而半个月后,夏夜在那间工作的影院放了最后一部电影。那天是周末,顾蝉也去看,嘴里吹着夏夜给的冰糖,听见他说道:“我可能要换个工作了。”
顾婵讶然地看着他。
夏夜无奈地摊手,倒也并不是很失落:“不能继续接爸爸的班了,不知道他知道会不会伤心。”
“是因为上次在学校放电影那件事吗?”
夏夜似乎没有听到,跟着电影的片尾曲哼唱起来,俨然一副少年心性。生活对他并不公平,但他看起来并不愤世嫉俗。
夏夜在新开的数字电影院当检票员。他手舞足蹈地向顾婵描述数字电影有多么神奇,眼角眉稍都是孩子气的惊奇:“不用那种老式放映机了,也不用胶片,是数字电影,画面很清晰!”
他非常喜欢这个看似平凡卑微的工作。
顾蝉也为他高兴,唯一让她有点忧虑的是数字电影比胶片电影票价贵太多,她不能每周都借口跑去看电影和夏夜寒暄,搞得每个周末都非常无聊。
恰巧班里有同学过生日,顾婵就提议大家一起去电影院看电影。
他们一共才十几个人,夏夜却热情地帮他们争取到了包场待遇。夏夜笑咪睐地看着他们进场,从口袋里掏出冰糖。但没有人接,大家手里都握着奶茶和爆米花。
夏夜的笑容忽然就有些寂寞,顾蝉连忙接过来,一股脑全塞进嘴里,竖起大拇指:“味道真赞啊,多年不变的味道。” 夏夜这才笑逐颜开。
顾蝉没有预料到的是看电影途中会出差错。起初只是苏苒让某个男生递爆米花给她,男生没听到,自顾自地和同伴说笑,苏苒又叫了几声,大概是觉得面子上过不去,她腾地站起来手臂一挥,就把男生手里的爆米花夺过去。
男生愣了几秒,出乎大家意料,他也腾地站了起来。
两人就这么一言不合叫骂扭打起来,顾蝉凑过去拉架,夏夜也闻声赶来。苏苒力气大,拼命把拉架的人往外围推,随手拿起一杯滚烫的奶茶就砸过去 -
顾蝉下意识地偏头,那杯奶茶恰好砸到了夏夜的脸上。
夏夜听了一声,而后飞快捂住了左眼。顾婵匆匆跑过去,手忙脚乱的没找到纸巾,便把自己的围巾取下来给他擦脸,但夏夜左眼周围,还是被奶茶给烫红了。
5. 意气风发少年郎
夏夜被解雇了。
苏苒等人在影院内损坏了不少物品,夏夜虽然不用赔偿,但他向经理保证过不会有问题。此刻出了事,难免还是他首当其冲。
夏夜本就还在试用期,而现在,他捏着当月工资垂着脑袋走出来。
夏夜环顾了一圈,然后走到苏苒面前,他已经极力按捺愤慨的情绪:“我每次倒霉都是因为你,我拜托你大小姐,你活得高高在上就好了,别管我们这些凡人好不好?”
苏苒证愣间,夏夜抬步就走。
顾婵毫不犹豫地跟上了夏夜,她小心翼翼地歪头去看夏夜阴晴不定的脸,心里又是愧疚又是酸楚。若不是她提议,或许也不会出现这种状况。
他说过他很喜欢这个工作,可以接触更为现代化的电影制作,他的梦想就是拍一部电影——而顾婵的一个提议,让他的梦想脱节了。
“对不起啊,夏夜。”
夏夜没吱声,却将口袋里剩下的冰糖都递给她,苦笑道:“都给你吧,或许最近都用不上了。天色也不早了,你快回家吃饭吧,我想去原来的电影院看看。”
顾婵不声,始终保持与夏夜一步之遥的距离。
夏夜盯着她看了片刻,叹了一声后继续往前。
原来的电影院在施工,顾蝉坚持要夏夜去自己家吃晚饭。夏夜本来死活不肯,但经不住顾婵软磨硬泡,被她拖回了自己家,面对顾蝉爸妈的热情,夏夜窘迫不已。
他平日那点世故也用不上,笨拙地和顾爸爸讨论新闻,不知道怎么就说到了成龙最近的电影上。顾爸爸慨叹:“想当年,叔叔我也是个响当当的话剧演员啊,但苦于时运不济,还是没能如我所愿拍一部电影,真遗憾。”
夏夜被他逗笑:“我也想拍一部电影,不过可能没什么机会吧。” 顾爸爸眼前一亮,饭后和夏夜在阳台聊了很久,不时有笑声从阳台传过来。
告别时,夏夜也笑逐颜开:“叔叔我明天给你电话。”
他背上旧书包,兴高采烈地走了。
顾婵送他到门口,他跳起在树上摘了几朵花给她,笑睐睐的样子一点也不像是刚刚丢了工作的人。但似乎这样意气风发的少年郎,才是夏夜本该有的样子。
6. 未能果腹的梦想
夏夜近来频繁出入顾婵家,却不是来找她。
他和顾爸爸总躲在书房里密谋,饭点到了叫都叫不出来。顾爸爸兴高采烈,夏夜看起来也乐不可支,两个人都是一副对未来充满无限憧憬的样子。
顾蝉好奇地问起,他们又默契地三缄其口。
这样的日子持续了两个月,直到立春后某个晴天,顾爸爸在饭桌上突然咳了几声,而后和同样来做客的夏夜对视一眼,说道:“我打算和夏夜一起拍个自制电影。”
顾蝉和顾妈妈都呆滞了。
“嗯,剧本夏夜已经准备好了,我看了之后非常喜欢,简直是为我量身定做的角色啊,哈哈。我们也商量好了,拍摄团队就去找我以前的同事,他们有开影楼的,花点钱应该没问题。等拍好了,就放在网上参加一个原创电影比赛,
要是能拿奖的话就有收益啦。”
夏夜也跟着不停地点头,眼睛亮晶晶的。
老实说,顾蝉觉得有点没希望,但她不忍心泼他们冷水,笑着祝他们马到成功。顾妈妈却嘀咕:“能行吗?听着就不靠谱。一把年纪了拍什么电影啊,再说你有本钱吗?”
“咱们不是给顾蝉出国准备了二十万嘛,顾婵又不愿意出国,再说女孩子离家太远也不好,干脆就拿来做电影吧。毕竟人都有个梦想嘛,管他最终能不能得偿所愿。”
顾妈妈还想再说,但念及饭桌上还有外人,也没再出声。
直到夏夜离开,顾妈妈才关起房门来和顾爸爸理论,墙壁薄,说话声大一些便听得一清二楚。顾婵写不下去作业,听见顾妈妈说道:“老大不小了还和小孩子一起胡闹!”
顾爸爸说不过她,只一个劲强调:“你这是羞辱我的梦想!”
但顾爸爸决心已定,九头牛都拉不回,在维持一周的冷战后,他不知从哪个角落找出了那二十万的存折本,在顾妈妈的叫骂声里跑出去。老爸四十多岁的人了,跑远了还转过身,朝怒气冲冲的老妈做鬼脸扭屁股,顾輝在一旁
哭笑不得。
“什么梦想啊,能当饭吃吗?!” 顾妈妈不能理解。
资金到位,夏夜和顾爸爸真的开始策划忙碌起来,他们在社区里找有生活经历的中年人当演员,联系专业的摄影团队,恶补相关的常识,每天忙得脚不沾地。顾蝉每次见到夏夜,想问问他进度,也被他神秘地一笑带过。他说:“再等等,我们会给你们一个惊喜的。”
他们制作的电影在半年后完成,两人卖了太久的关子,连老妈也不禁好奇电影究竟好不好看。几个人挤在顾家窄小的沙发上,看着夏夜和老爸拍出的电影。
九十分钟后,顾蝉长叹了一声。
顾妈妈默然离席,去厨房准备晚餐,不置可否。
“怎么样?好看吗?看懂了吗?” 夏夜和老爸睁大眼睛望着她。
顾婵在那个瞬间突然改口,由衷赞叹道:“很棒。”
这样执着认真的他们,很棒,就算她其实并没看懂电影讲述了什么。
夏夜和顾爸爸兴冲冲地拿着作品去参赛,等待出结果的那一个月里,他们俩轮流在电脑前刷新网页,希望点击率很快增长,这样能证明他们的努力没有白费。
但三十天过去,电影的点击率还是只有寒酸的几百次。
原创比赛,别说拿奖,他们连提名都没有。没有人宣传,没有人提起,夏夜付出的心血、老爸付出的金钱和精力,
就这么在所有人的无视之中付诸东流。
老爸委婉地向老妈提起,花出去的近十万块钱,可能收不回来了。
老妈摔了碗:“我就说你们是在胡闹!夏夜那个小屁孩,高中都没毕业,天天还想着拍电影,我还想着去好莱坞拍电影呢!你以后少和他接触!”
老妈说完这句话一回头,夏夜正僵在门口。
是顾婵打电话给他的,叫他过来吃晚饭,她在电话里说:“你把我们都当成一家人啊,以后晚饭都来我家吃,我爸妈就是你爸妈。”
犹在耳边的话,和此刻夏夜落寞的眼神成了讽刺的对比。
7. 拿来冥想的念想
夏夜就真的再也没有出现过。
顾蝉后来见过他几次,他换了很多工作。铄石流金的夏天他在城市广场中心发传单,被广场保安追着跑进小巷子里避风头。他也在火锅城当过打工仔,任客人对他颐指气使。
夏夜依然是礼貌的夏夜,面对顾蝉关怀的眼神报以感激,但无论他的境况多么窘迫,他仍然会一脸从容地对顾婵说:“我很好。”
可顾婵觉得他一点也不好,她自作主张帮他申请社区补助金,自作主张帮他填了很多份表格,那天她兴高采烈地跑去火锅城找他,将那些表格拿给他看。她满心欢喜,收获的却是意料之外的冷淡应对。
夏夜盯着那些表单看了良久,而后将油腻腻的手在制服上擦了擦,伸手拿过那一堆表格,笑了一下:“谢谢你,但我不需要,我有手有脚。”
他的笑容隐藏着压抑的怒气,顾蝉呆呆地望着他,不知如何是好。
从那之后,顾蝉再去找他,总被他以各种各样的理由搪塞推拒。久而久之,顾婵也懂得他的意思。他不喜欢她的怜恼,他避之唯恐不及。
再后来,夏夜换了手机号码。
顾婵一间间火锅店去找,也找不到夏夜的身影。
而她升入高三,起早贪黑地学习,脚步匆忙经过喧闹的操场,高一的女生挤在场边满脸通红地给打篮球的高个子男孩加油,粉红的气息击中了顾婵,让她莫名有点怅恼。
大概每个女孩子的青春都曾虚幻过美好的幻象,一旦有美好走进视野,便会自动将幻象落实,成为心头那点小心翼翼的念想。
冰糖和夏夜一度都是顾婵的念想。
而念想,从来都是拿来冥想的,近在咫尺的人与事,用不着念想。
8. 久别重逢故人来
那之后的时间过得飞快,成长迅疾的顾蝉往往无暇顾及有如夜星凭空出现又消匿在她世界里的夏夜。她努力融入新的大学生活,积极参加各式聚会,她和总是给自己发天气预报的学长看电影、逛海滨公园。
她想,夏夜这个名字迟早会如湿润画布上的一抹墨迹,随着雨过天晴,淡出她的世界。
某个周末,顾蝉去家教兼职中心递交简历,在一堆翘首以盼的家长之中发现了一个出类拔萃的身影。侧影很是赏心悦目,顾婵多看了两眼,夏夜正好转头,就这么阔别重逢。“我办了个英语补习班,来和这边负责人谈合作的事
情。” 草草寒暄后,面对顾蝉疑惑的视线,夏夜从容地解释。
顾婵一脸欲言又止和难以掩饰的好奇,夏夜显然也洞察出她神情中的不可思议,解释道:“我前两年去上海,给一家外贸公司打工,特意去学了英语,攒了点钱,又想念书了,就回来一边创业,一边准备成人高考。” 他耸全肩,
看似乐观了许多。
难怪,少年曾经被苦难和现实所压抑的光芒,现在绽放倒也不晚。
夏夜给她留了手机号码,示意自己有事先走。顾婵站在原地目送他离开,那股说不上来的怅然环绕着心悸席卷心头,她突然说道:“夏夜,我英语六级还没过呢。
夏夜回头,迟疑片刻后,问道:“要我给你点建议吗?” 他说话永远带着礼貌性的笑容,隐含疏离与警惕,这些年来,没人能走进他的心。
顾婵莫名怅恼,又松了一口气。
她这才确定,自己是真的想抓住点什么的,旧时光里那些没能说出来,也没能实现的遗憾,哪怕早已过了天真的年纪,还是对那点无疾而终的念想很是挂记。
9. 爱情只能是爱情
夏夜身上有股光华,哪怕在少年时最尴尬的处境里也不曾被消磨殆尽。
顾婵以前说不上来那是什么气质,现在她觉得夏夜有点像松树,不抢眼却耐看,不卑不亢地立在那儿,怜悯和同情对他来说是空洞的,因为他根本不会被风摧毁。
他接受得了贫济现状,也敢于做不切实际的梦,他眼神里有股韧劲,有种无坚不摧的力量。也许正是因为这种力量,夏夜考上了顾婵学校知名的导演系。
那个周末顾婵说要出去庆祝,和夏夜约好在校门口见面。顾婵特意打扮了一番,换上了并不习惯的短裙和高跟鞋,还给夏夜准备了礼物。
约好的时间是傍晚,等到将近八点,顾婵忍不住给夏夜打电话。
夏夜那边一直忙音,隔了好久他才仓促接起来,他在电话里不停地道歉:“对不起啊顾婵,我…… 给忘了,跑去参加一个网络剧的面试了。”
顾蝉愣了愣,夏夜接着说道:“改天请你吃饭赔罪啊,马上就轮到我了,我挂了啊。”
她本来是想展示一下豁达的胸怀表示没关系的,想着迟到总比不到好。夏夜干脆得多,他不但将约定忘记,都没打算做出补救。
好吧,面试是比吃饭重要得多。
顾婵心里清楚孰轻孰重,仍是无法自制地难过。有些东西是不能比较的。
让顾弹没料到的是,夏夜会在面试现场巧遇苏苒。许久未见,苏苒俨然有逼近大美人的趋势,她瘦了也会打扮了,身上那股匪气也收敛了,甚至主动和夏夜打招呼。
夏夜向顾蝉说起时一副不可思议的表情,忧虑道:“你说我会不会又倒霉啊?”
顾婵笑他想太多。
苏苒所在的文学院和他们不在一个校区,顾蝉一直没见过她。但很快,苏苒频繁出现在主校区,更精确一点,是出现在夏夜身边。
她邀请夏夜去看电影、吃西餐,好感溢于言表。顾婵实在很好奇苏再怎么抛开对夏夜糟糕的印象的,还是年少时的咄咄逼人,其实也是不成熟的青春期想要吸引关注的抽劣方式,但如今的苏再极有诚意——那部剧就是她爸爸投资的。
夏夜对此表示很无语:“她以为我是什么人?为了利益和她在一起吗?”
顾婵连连点头,习惯性在他口袋里摸冰糖,本来只是无意识的一个动作,却在真的摸到怔时在原地。
夏夜有点不好意思地说道:“习惯了。”
有关对夏夜的那点念想,突然豁然开朗许多。
夏夜也很给力,他拒绝了在迎新舞会上向他表白的苏苒,闹得苏苒很丢脸。事后顾蝉试探问起,夏夜倒也很坦诚:“我虽然没什么背景,但我还是想靠自己。”
“至于爱情,我希望我的爱情纯粹就只是爱情。”
他这话说得动人,虽然没有明确的指向者,但顾婵自动将之归结为夏夜对爱情的承诺。顾婵被近在咫尺的夏夜迷花了眼,忘记问他,拒绝苏苒是出于何种理由。
是纯粹的不喜欢,还是纯粹的希望爱情和利益无关。
10. 昨天已成为过去
顾婵投到家教中心的简历被录用了,大三那一年除了复习雅思,她就给一个高三的学生补习,极少参加学校里的活动,和夏夜的聚会也越来越少。
不是她没空,就是夏夜在忙。
顾婵总是会去找夏夜要冰糖吃,在她眼里,夏夜口袋里常年备着的冰糖就像是一句无声的表白,代表着他们共同经历过的旧时光,所以哪怕没有明确说过一句喜欢,顾婵也甘之如饴。
她觉得这是迟早的事情。
夏夜现在忙着学业还有兼职,对待感情疏忽是难免,她要学着理解,也不能太过紧逼。顾婵是这么想的,她把苏苒这个存在完全抛在了脑后。
得知消息那天,是顾婵的生日。
她提前一周去找夏夜,和他说自己过生日的事情。顾婵满脸都是甜蜜的笑容,夏夜的神情也不知怎么有些不自然,他接了个电话欲言又止地提前祝她生日快乐。顾蝉没领会到那是婉拒。
生日这天,她在餐厅等了三个小时,闺密们已经吃完不堪等待去唱歌,她一个人还等在原位,望着窗外人来人往发呆,然后给夏夜打电话。
电话打不通,顾蝉失魂落魄地回去。她在超市买粥时听见几个男生在聊天,敏锐地捕捉到了夏夜和苏苒的名字——“夏夜真是,苏苒追他时死活不答应,现在人出国了,借钱跟着追过去,他同你借了多少?我给了他五百,这个月……”
顾蝉觉得浑身的力气都在那一瞬间被抽光,只好靠在一颗梅花树上。她无意中仰头,就看见了瑞雪压枝中盛放俏丽的梅花。
那年她十七岁,夏夜从她家走出来,脸上挂着大大的笑容,跳起来折下花枝送给她。
就是那短短一刹那,心底那纸纯白被郑重抹上一笔名为夏夜的浓墨重彩。
顾蝉生日过后的翌日凌晨,收到来自大洋彼岸的短信,夏夜祝她生日快乐。她没有回,八个小时的时差,已经不再是她的生日。
都已是昨天,都已成为过去。
11. 夏天有蝉鸣做伴
顾爸爸打电话给顾蝉说他收到了一笔钱。
顾蝉忙着准备教案,随口敷衍:“啊哈,难道是你中了彩票?”
“不是,我看信封上落款是夏夜。婵婵,你现在和夏夜还有联系吗?”
顾蝉下意识地去看电脑右下角的日历,时间已是 2014 年。
春节时她和夏夜出来聚过一次,夏夜最近在忙着拍什么网络剧,所以他挺忙的。饭桌上他没吃几口就结账匆匆离开了,临走前他又转身,从大衣口袋里掏出一颗冰糖递给顾婵。
席上热火朝天,顾蝉突然就掉了眼泪。
她特别想站起来冲夏夜吼两句说,你都有女朋友了,还天天在大衣口袋里放冰糖算怎么回事。但她到底没能站起来,也终究没敢问出口。
无论答案是哪一种,夏夜都已成为过去。
她得放下、得忘记、得释怀,还得依然怀抱着希望,坚信总能再遇上光芒。
“他给你寄了多少钱?” “挺多的,十二万。这孩子干吗去了,怎么挣了这么多。”
夏夜的网络剧红到尽人皆知,估计只有老爸这种只顾着养生的老年人才不清楚。十二万,和当年他和老爸一起拍的电影经费吻合,夏夜在用这种方式,彻底和岁月泯恩仇。
在他最好的年纪里,岁月不曾给予他温柔。他却坚信,自己这双不断往前的脚,总能让他看见不曾看过的风景,不曾领略的温柔。
顾蝉把网络剧的链接发给老爸,看到了视频推荐那里有一个采访夏夜的视频。
她随手点开,然后快进,听见夏夜谈起为什么总爱穿有口袋的上衣。
“我爸爸喜欢在口袋里装些冰糖,大人、小孩都很喜欢他。我想是不是自己像他一样, 也就能收获很多人的喜欢。我爸爸一辈子都在放电影,后来我想,那些冰糖告诉我的,大约就是十年如一日的坚持吧。坚持也许不能让你梦想成真,但你至少试过,就算遗憾也深刻。”
顾婵抬头,窗外涌动大片的阳光,蝉鸣声快要振聋发聩,又是一年盛夏。
夏天从不孤单,她有蝉鸣相伴。
顾蝉笑了笑,抬手抹去眼角渗出的泪水。
12. 谁的小心翼翼将时光断送
时光的断层回到顾婵十八岁的前一天。
她满心欢喜地抱着一堆表格去火锅店找夏夜,却失魂落魄地空着手独自回去。
垂头丧气的少女需要热量和甜品来重新点燃她的小宇宙,于是她咬牙狠心花光自己半个月的零花钱买了一盒哈根达斯,在单薄的路灯下吃得不亦乐乎。
她已经向前看,不曾知晓让她不开心的那位少年套着油膩腻的火锅店制服就奔了出来。他懊恼地想着该如何道歉,右手不停地摩挲口袋里那个精致的手办。
那个定制的手办几乎花了他半个月的工资,用来计划当作顾婵十八岁的生日礼物。但他冲出来,看见的是抱着哈根达斯吃得不亦乐乎的顾婵,他这才注意到,她从头到脚的衣服、鞋子都印着他难以望其项背的名牌 logo。
夏夜的口袋里还有五十块钱,那是买完手办后他仅剩的生活费。
他捏着那张薄如蝉翼的纸币,脚步无论如何再也迈不出去。
手办后来被他卖给了杂货店,两年后被顾婵在夜市淘到,包装整齐打算将它当作他考上大学的礼物。但那天夏夜没有出现,那个手办后来和一堆旧书放在一起,蒙尘朽蠹。
“不知道从什么时候开始,我变成一个很小心的人,每次我穿雨衣的时候,我都会戴太阳眼镜,你永远不会知道什么时候会下雨,什么时候出太阳。”
夏夜后来看《重庆森林》,单单记住了这句话。
那是他无依无靠小心翼翼的十九岁,畏惧习惯从而拒绝陪伴,害怕变故也因此提防爱情,他不知道什么时候能赚够一支哈根达斯的钱,他不确定他的人生何时升起太阳。
于是他狠下心,亲手掐断了曾予他温暖的光明,独自长眠永夜。
时间却比人心更狠,它让你在某个不经意的瞬间,怅然若失地意识到,他曾失去的,早就在光阴涤荡中释怀。
十九岁的他怀揣未送出去的礼物原路返回时,不曾预想他会在将来爱上别人。
* * *
思北域, 宠青鸾 文 / 木头弦
1
一千岁寿辰时,我在临虚宫办了一场宴会。宴会上有一名妖宠献唱,赢得了大家一致的赞赏,我便让他留在了大殿。
没想到他突然说起我在仙界的第一桩功绩:“帝姬的功绩无人能及!那场战争连清业帝君都殒身了,而帝姬挺身而出之后,就逼得魔族那些家伙不得不迁了都,真是厉害极了!”
他说完,大殿气氛霎顿时冷了下来,在座的上仙们都紧张地看向了我。
我慢慢饮尽杯中的酒,招来仙兵,下令将他遣送回万妖境。
仙界的妖宠都来自万妖境,。沾染了仙气的妖再回到万妖境就如唐僧进了妖精窝,除了死,还是死,所以他们都不会想回去。
这个妖宠哭得撕心裂肺,不住地说他是被人陷害的,求我开恩,求我饶恕他。
我没有看他,只是慢慢地给自己斟了一杯酒。
大殿里鸦雀无声。唯一的响动,就是我斟美酒入杯。
汩汩汩汩…… br>
那年清业死的时候,也是这样的声音。
汩汩…… 鲜血从他的胸腔流出,温热的,带着浓郁的血腥气。我拼命地用手去堵,却怎么也堵不住,只能眼睁睁地看着他的生命随着鲜血流逝,撕心裂肺痛彻心扉,却无可奈何。
这是仙界大部分仙人都亲眼见过的场景。当年为了验证我说的话,天帝曾亲自开天眼,当众还原了我和清业有关的记忆。
我们相爱,相知,相守…… 最初我只是清业的妖宠,后来他向我求了婚,为了让渡我成仙,他上战场想以赢得硕硕战功为以我向天帝求一枚飞仙丹,没想到在战场上遇到了意外。
他是天界唯一的,为了镇守气运而出生的仙人,。有他在,天界就福泽深厚,气运绵长。
大群的魔族像嗅到了血腥气的鲨鱼蜂拥而至,以悍不畏死的姿态向我们发起了攻击。清业将仙格丹给了我,只身杀进了魔族的包围圈……
后来我继承了清业的仙位,。天帝为了颜面,也是为了给我造势,对外宣称是我打退了魔族,逼着魔族迁了都。
但其实仙人们都心知肚明,是清业重创了魔军,所以我带着仙军复仇之时,才能高唱凯歌。
我的成仙之路上,满满浸染的是一地的清业的鲜血。
所以,我从成仙的那一刻起,便已后悔。
而那个愚蠢的妖宠,却揭开了那道最让我让我最为痛苦痛的伤疤。
2
当时,我的心情恶劣糟糕到了极点,。明微,就是在这样个糟糕的时刻,再度走进我的生命。
他是一位上仙献给我的礼物,。上仙见大殿气氛低迷,上仙便说拿出他来凑逗趣。
我不置可否地应了,然后,便陷入了黑暗。
没有光线和时间,只有纯粹的一片黑。
这是一种叫做黯汲图的仙术。
天界有着永恒的光明,黑暗在这里没有容身之地。于是有仙人突发奇想,想出了这个仙术。制造小小的黑暗,聊作情趣。
我刚刚进入临虚宫时,对清业说我思念北域的月光,所以他为我习得了这个小把戏。
那一夜他向我求婚,让我第一次见到了天界黑暗中的月光。
而现在,我第二再次见到了它。
在这一片纯黑里,那个人是唯一的光亮。他踏月而来,一步一步,仿若踩在我的心上。
翩然的姿态,清透的月光,淡然对我淡然微笑的身影……
这份礼物简直是戳着我的心送的直戳我心底。它在我回忆起清业的死的时候,把我送回了我与清业最美好的时光,让我的心疼得几乎不能呼吸。
偏偏那位上仙还在笑呵呵地问我:“帝姬怎么样,这个妖宠的仙术还不错吧?”
我从牙缝里挤出 “不错” 两个字,手心里被掐得全是血痕。
转过头,就让人把这个妖宠送进了最偏僻的院落里。
当时我被心痛的情绪击倒,未曾注意到明微是我的故人。
我去了军营,以疯狂的训练来磨去心中的痛楚。
也不知道明微因为我的态度而被总管下令贬入贱役,伺候宫里妖宠的起居。后来又因他太过出色而被其他妖宠陷害,几度受罚。最后更是被一个小仙栽赃,闹到总管那里,要把他送回万妖境去。
我听到的唯一关于他的讯息,便是他在被遣送回万妖境的途中,逃跑了。
我没有太过在意,只在总管问我要不要通知仙将通缉明微时说不用了。
得饶人处且饶人,他既然逃了,就随他去吧。
但我万万没想到他居然逃回了临虚宫,而且还给我带来一个大麻烦。
3
当时我刚刚收到北域来的消息,魔军血洗了天界的一座城池。
我虽然逼得魔族迁了都,却没有完全剿灭魔族。失去了帝都的魔族就像失去了头狼的狼群,不时对仙界展开疯狂的报复。
我成为帝姬之后,便立志成为剿清魔界的一柄剑,所以剿魔之事,一向由我统领。
我正在琢磨战术,总管来禀告我,说清玄帝君传来消息,他扣了我的军备物资,让我带着明微去换。
我诧异了一下清玄为什么会对这个妖宠的如此看重,然后顺口就让总管把人送去了。没想总管很快就回来禀我,那妖宠不肯走,还要求见我。
我有些不耐烦,但还是应了。
而看清明微的模样时,我不禁又惊又喜。
“微哥哥……” 我讷讷地唤他,完全的不知所措。
天界的妖宠都来自于万妖境,但我却不是。我长于北域的边境,是明微庇佑着我,我才能长大。
在我的记忆里,明微是个特别温柔的人。
北域十分荒凉,既有魔族的劫掠,又有仙军清剿,。他不过是一只法力微薄的小妖,常常会打不到猎物,甚至被其他的妖抢劫,却始终带着只会拖后腿的我。
他也从不凶我,唯一的一次,是在我们一个月只打到了一只兔子,我要让给他吃的时候。
当时他生气地把肉块塞进我的嘴里:“吃饱,你要给我好好活着!” 他对我,真的非常的好。
但那之后不久,我们就分开了。当时我们听说万妖境里有仙人收妖宠,妖宠有可能被仙人调教成仙,所以打定了主意要混进万妖境去。
明微先过去探路,我们说好他探好路向我发出讯号,我再顺着他的指引溜进万妖境的。但我没等他发来信号,就先遇到了魔军对仙军的夜袭。
我无辜地被当成了炮灰,。仙军的兵刃砍向我的头顶时,我原以为我会死,却被清业所救,然后幸运地成为了他的妖宠,从此生活天翻地覆。
此时回首,那竟已是百年前的事了,而我们也都已不再是当年的模样。
我看着明微,说不出一句话。
明微对我笑了笑,笑容温暖而又模糊:“鸣鸾,你还好吗?”
4
我很好,但他不是那么的好。
我们坐下来叙旧。明微说,那天他在边境等了我很久,但一直等不到我不到。后来遇上仙军巡查,他被发现,然后被追杀,等他侥幸逃脱时,却已身受了重伤,所以耽搁了第一年妖宠的选拔妖宠。
后来他终于被选上了,主人却不喜欢他,。他只好请托别人帮忙打听我,却始终没有音讯。
再后来我受封帝姬,明微在我的册封大典上认出了我,欣喜若狂。但他来求见我,却被侍卫拦住了。
正好他的主人要选妖宠学黯汲图,说是要送给我的礼物,所以他就去学了。
这样辛酸的过程,明微却以这句话结了尾:“鸣鸾,终于见到你了,真好。”
我心中不禁心酸。
是我让他遭了难,不说别的,仅仅是黯汲图…… 对仙人而言只是个逗趣的小把戏,但对一个没有仙力的妖宠而言,这个小把戏却是要化花去他许多修为的要命仙术。一滴精血,十年修为,他为了练成黯汲图,用掉了自己多少年苦修的修为?
而在我宫里的那些遭遇…… 我不信他进入临虚宫后没有求见过我,但我却从没听到过关于他的消息,这是何人在阻拦?
他逃跑那次,我尚记得总管说他是犯了大错所以逃出了宫…… 但有可能吗?而如果他没做错什么的话,又是谁在陷害他?
想到这些,我心中大恨。目露杀机地说:“微哥哥你别怕,我给你报仇雪恨。凡是欠过你的,我都会一个不漏地给你讨回来!”
“没,…… 没人欺负我,真的。” 明微结巴着说。
我惊愕地看着明微,他却低着头不敢与我对视,只是柔声重复:“真的没人欺负我……”
明微说,“鸣鸾,你变了,从前你不会把人想这么坏的。以前你不这样的,你很贴心,心也很柔软,连一块糖都要给我分一半自己才肯吃的……” 他慢慢地絮叨着,而我一直无声地盯着他,直到他的声音越来越小,直到不见。
我叹息了一声,有些失望。他说我变了,但我也觉得他变了。
从前的他虽然温柔,却从不怕事的。
那年有个成年的妖,趁他不在家,仗着妖力深厚打伤了我,还抢走了我们储藏的过冬食物。他回来之后,一言不发地给我敷好了药,然后提着刀就杀到了那个成年妖的洞府。那一仗他几乎和那个成年妖同归于尽,但他却丝毫都不肯退缩,。所以从那以后,北域没有一个妖敢抢我们的东西。
那时,我是多么地为自己有这样一个哥哥而感到多么的自豪,谁会想到如今的他变得这样懦弱又怕事。ont FACE='Arial'>
我想着这些,目光不经意地与明微相撞。但他就像受惊了的鸟雀,飞快地挪开了视线。我不禁又摇头,真的是完全变了。
不过算了。时移世易,总归我现在有自保之力,大不了以后我护着他吧。
我说:“以后留在临虚宫,这里就是你的家。差什么要什么,你直接跟总管说。其他的,我都会处理的。”
说完,我转身要走。
明微在身后叫住我:“鸣鸾,你不会拿他们怎么样吧?”
“这些你都就别管了…… 明微。” 我的声音顿了顿,终于叫出了他的名字。
就像一个仪式,将旧时的我们与现在正式地分割。
然后,我头也不回地走了。
5
打伤过他的仙兵,拒绝帮他传话的守卫,欺负过他的妖宠,栽赃他的小仙…… 这些一个一个地,我都帮明微惩处了。
为了不让他忧心,我什么都没告诉他。但临虚宫上下都是知道的,所以伺候明微时,都变得无比尽心。
又一次我问他觉得住得怎么样,他点头赞好:“他们很用心,很多事不用说,他们就已经帮忙做了。”
他说好,我心里也很快慰。以前我欠他太多,现在他每说一个好,我就觉得我偿还了他一分。这种偿还,让我心里痛快。
没几天,我已处理掉了明微带来的大部分问题。只剩下最麻烦的一桩,清玄帝君。
我说明微是我哥哥,请他给我个面子,但他不理。我提出用临虚宫宫藏的三件宝物来换他扣押的军备,他也不肯,始终坚持要明微。
我去问了明微他与清玄帝君相识的详细经过。明微说,他当时逃出临虚宫后晕倒在了云海里,被清玄帝君捡了回去。后来清玄帝君给他治好了伤,让他施展黯汲图,然后留下了他。但他实在想见我一面,所以偷溜了出来。没想到清玄帝君会对他恋恋不舍,还来找我讨要。
说这一节时,明微有些惴惴。不安地问我:“会不会给你带来麻烦?其实我见到你就够了,如果清玄帝君一定要我回去的话,那我就回去吧。”
我实在看不得他懦弱的样子,索性不去回答他。
不说让他去了清玄宫之后我的脸面问题,且说清玄要他是为了让他施展黯汲图,我就不能让他去那里送死。
这件事完全是个死结。我去面见了天帝,让他帮忙解决此事。但我虽得到了天帝的承诺,却不防清玄竟带人打进了临虚宫。
我本想就算拼死,也要跟清玄一战的。却没想到明微会主动出来打了我的脸:“清玄我跟你走,。鸣鸾,你也别管这件事了,让我走吧。”
“明微,你知不知道你自己在说什么?” 我不敢置信地望着明微。 明微背对着我,站到了清玄的身后:“鸣鸾,这是我自己的事。”
是很委婉的语气,但却更让我愤怒。
我咬牙说:“你…… 好!随便你!”
随后拂袖而去。
6
明微让我别多管闲事这件事,狠狠地伤到了我。我本来不想再理会他了的,但当晚,总管给了我他留下的一封信,却让我顾不得这些难堪的情绪了。
明微说:“我误入清玄宫后院,见一水晶棺,棺上有临虚宫印记,棺中是一绝美女子……”
我顿时就明白了清玄为何一定要带他回去了。
这个女子,如果他想永远藏在身边的话,确实不能走漏一丝风声。
这个女子叫紫苏,和我一样,属于是个亚魔族。
身为魔族附庸的亚魔族,没有人比我更明白这个种族的不幸。我们有着魔族的紫血,却没有魔族的气息,看起来反倒更类似于妖族,所以一直被魔族瞧不起。几千年前我们的祖先背叛魔族,投靠了天界,。他们以为这样可以改善我们种族的环处境,却没想到这反倒把我们推入了绝境。被圈禁在天界与魔界交接的北域,被魔族屠戮,被仙族清剿,每个亚魔族的生活都浸满了血泪。
但紫苏,却是这世上唯一一个幸福的亚魔族。她不曾像我们一般为每日的温饱而担忧,也不曾在仙魔两军的刀锋下瑟瑟发抖,。她从小被当成仙人养在天界,一生中唯一的不幸就是她的死亡,她死在了一场仙族对魔族的战争里。但就算死亡,她也依然幸福,。因为她活在一些人的心里,还被一些人永远地爱着。
她的好友,清玄。她的爱人,清业。
当初天帝要查看我的记忆,正是因为他觉得清业死得很奇怪。毕竟有什么仙,会为了一个妖宠而放弃自己的生命呢?
但我却知道,清业早就不想活了。
若是在最初清业答应娶我时,我还有些窃喜。但等他战死之时,我便不得不明白了。清业要娶我,奔赴战场为我求飞仙丹…… 一切都不过是一场谎言。
他活得太久了,太寂寞了,太想念紫苏了,所以他不想继续了。他给了我一个遗孀的身份,和偌大的财产,。他把一切都给了我,唯独带走的,就只有他的爱情。
他是追随紫苏而去的,却留给了我一段传说,和一份怎么也放不开的感情。
其实我心中不是没有过忿愤,。我想,既然不能给我我想要的,那就索性什么都不给,让我恨他岂不更好?偏偏他如此的行为,让我爱不得,恨不得。
但后来又想,他一直待我如兄如父,我又怎能因为他无法回应我的爱,就抹杀了我们之间的一切呢?所以最终,我依然爱清业,却还是承认了他不爱我。
那时我很寂寥地想,世间的爱情大约都是如此吧。
爱上他,就像盛开一朵花。有人欣赏,无人欣赏,都是自己的独自开落,不与任何人有关联。 SPAN>
所谓时光绵延,花开寂寞,不过如是。
7
明微去了清玄宫中,军备物资很快就备齐送到了我宫里。
此时前线告急,我便率着仙军向北域疾驰而去。
只是天界上下都以为只是魔族的一场例行骚扰,却没想到这其实是魔族对天界的反攻之战。
这回魔军的统领,是魔皇仅存的两位皇子,而他们带来的魔兵则有十万之众。其中具有各种神通的异魔,不计其数。
我率领的仙军措不及防之下,被他们包了饺子。
一场血战之后,我被魔族俘虏了。
虽然被断绝了经脉,关押在一片黑暗的地牢里,我却并没有多么丧气。我知道,作为继承了气运仙格的帝姬,天界不会放弃我。我甚至在地牢里计算起了回到天界之后,该如何组织对魔族的反攻。
时间一天一天地滑流逝,在我因为漫长的等待而生出恐慌的时候,终于等到了救援。
只是救我的却并不是我想象中的天界来使,而是明微。
他拉着我疾速地飞行,我看着他身上的血痕,和掩饰不住的苍老痕迹,知道他肯定做了些什么。但此刻并不适合多问,我只是沉默地跟在他的身后。
只是飞着飞着,就发现不对劲了。
“你要带我去哪儿?” 我倏地停下了脚步。
“人间。”
我顿时惊怒:“为什么?…… 我要回仙界!”
“仙界已经没有你的容身之地了,鸣鸾。” 明微平静地说,“天帝和几位帝君的意见已经达成了一致,他们任命了清玄为剿魔统领,已经放弃你了。”
“怎么可能……?我继承了清业的气运仙格……” 话一说完,我就意识到了我的幼稚。
是啊,我的仙格是从清业那里继承的。所以如果我死了,只要再等上几百年,天界自然会有继承我的仙格的人出现。所以我对天界而言,并非不可或缺。虽然我四处征战,为天庭立下汗马功劳,但他们依然毫不吝惜地舍弃我毫不吝惜…… 真是刻薄寡恩!
明微看出我已经想明白了,拉着我便要继续赶路:“走吧。我们先到人间让你养好伤,其他的事情以后再说。”
但我却没有动。反而更坚定地对明微说:“我要回天界。”
不是为了讨回公道,而是我还要为清业复仇。
虽然知道魔族并不是导致清业死亡的真正原因,但这却是我唯一能为他做的事。即使天界背弃了我,我也不能放过魔族集结在一起的这个千载难逢的机会,我要剿灭魔族。
“谢谢你救了我。但我不能跟你走。” 我如是说。
明微点点头,问我:“没的商量是吧?”
我正要点头,已经被他一记昏厥术打晕了。
转醒,我已经变成了一具被他扛着赶路的僵尸,除了吃饭,其他时候都动弹不得。
8
我本来应该生气的,但听着耳畔有风呼啸而过,感觉那么的熟悉,就怎么也气不起来了。
多年以前我们在北域,每次仙军或者魔军过来时,明微就是如此扛着我逃跑的。
明微这样的举动让我熟悉,也让我觉得他还是原来的那个他。 但也或许他一直没有变过,只是只有遇到困难时,我见到的,才会是真正的那个他。
我趴在他的肩头,乖巧地笑了笑。但就算他还是当年的那个他,我却已经不是当年那个什么都听他的话的我了。
逃跑了半个月,我一直装得不能动弹,但其实暗地里聚起了力气,并悄悄地在身边布下了法术。然后有一天,我假装身体不适,趁明微慌乱之时,我发动法术,制住了他。
我把他背进一个洞穴里藏好,离开时对着他平静得可怕的眼睛,我忍不住说:“微哥哥,对不起。” 这是我一直想说,一直欠着他的一句话。
明微却没有反应,只是依然那样看着我,平静地得让我害怕。
离开时我难过地想,或许我和明微之间,无声的离开是永恒最终的结局。就像他从不曾对我说出口的那些感情一样,永远地沉在了幽暗的海底。
那一晚看完明微的书信,半夜里忍不住,我曾偷偷潜入到过清玄宫。
我本来是怕清玄为了保守护他私自留下亚魔族尸体的秘密,而把明微灭口,却没想到会听到明微的一场真情告白。
清玄说:“紫苏死之后,我一直在后悔。我对她的喜欢明明一点也不比清业少喜欢她,却偏偏迟开口了一步,然后就步步落后,眼睁睁看她和清业在一起。如今我只能珍藏着她的真身,但我常常在想,若是我能早点向她表白,那现在光明正大地思念着她,追随着她而去的那个人,是不是就是我了……”
明微却只笑了笑:“感情的事哪里有什么先来后到?就像我喜欢鸣鸾,喜欢了几百年,但她却始终感受不到。而她一遇到清业,就明白了爱到底是什么。只有对的人,才能从心底里感受到爱情。这无关时间,也无关对方的心意。我从来没有想过要告诉鸣鸾我喜欢她,只希望她活得开心就好。如果想着清业能更让她幸福的话,那就让她一直念想念着。如果不见到我能让她欢喜,那我就离开…… 只要她好,我就好了。”
那晚我默默回到了临虚宫。
我脑中一片混沌,心里又是欢喜,又是迷惘。
明微不知道,他才是我的初恋。我人生中最初的懵懂与心动,产生在他把兔子肉塞进我嘴里的时候,小心地帮我绑绷带的时候,为了我与那个成年妖死斗的时候…… 只是我还来不及明白我喜欢上了他,就已经遇到了清业。
他说感情没有先来后到,但感情其实还是关乎时间的。我从对清业的感情里走不出来,就是因为我爱他爱了太久。爱到已经忘了我还可以不爱他,忘了我还曾爱过别人,也忘了我还可以继续爱另一个人了。
我爱上清业之后,其实已经隐约明白了明微的心意。但我已经变心了啊,如果我找到他了,清业会不会就觉得可以对我放心了,把我交到他的手里?这种可能性即使只是万分之一,我也不敢赌,只能逃避。
这是我对明微永恒的愧疚,我和他曾是这世上最亲密的亲人,但一次又一次的,我都选择了离开他。
9
我一路风尘地赶回天界,那时仙魔战争正进行得如火如荼。我想我回归,天帝必然愧疚,我并未想借机要什么好处,只是希望他继续让我当对抗魔族的统领,再给我增加仙兵就好。
但我没想到,我回到临虚宫时,迎接我的却是锁仙阵与漫天的兵刃。我奋力反抗,但我在魔族受的伤还未痊愈,不过几招,就被拿下了。
我被束缚在了临虚宫前,不敢置信地望着摆下仙阵的总管:“你以下犯上,就不怕天帝治罪于你吗?”
而总管一如既往的面无表情:“我正是受命于天帝,捉拿你这个亚魔族奸细。”
这时清玄带着天兵赶到,封锁了临虚宫,有小仙在一旁数落我,忘恩负义,背主离德,意图图谋不轨……
我听了好久才听明白,原来总管从我的衣物里找出一件带着紫色血液的小衣,他觉得奇怪,就去翻我的妖宠档案,却发现档案里少了我的一页。正好有小仙禀告,他发现水晶棺里清业帝君的尸骨竟然慢慢变透明了。总管一番打听,得知仙人的尸骨遇遭到紫血的浸染,就会出现这种状况。联想到清业死前我一直守着他,顿时得出了我不是仙人的结论。
他将此事上报了天帝,天帝一番查探,竟然查出清业的仙格是用手活生生挖出来的,所以他们觉得当机立断,我是剜了清业的心,而不是他主动把仙格给了我。
我听完这些,只觉得荒谬又凄凉。仅仅因为他们觉得我不是仙人,就否定了我对清业的感情,否定了我这些年斩杀的无数魔族。还认定我剜了清业的心?
呵嗬…… 我想起多年前清业对我说,紫苏会死,是因为她在战场上受伤,露出了她是亚魔族的痕迹,所以被仙人诛杀了。我以前还有些不敢置相信,我觉得作为相熟的战友,怎么可能因为一点点痕迹就干脆地被干脆地诛杀掉呢。!
但现在我信了,这些仙人,简直是谈魔色变,畏魔如虎!
我望向清玄:“清玄帝君,别人不信,但你是相信我的对不对?我承认我不是妖族,我是亚魔族人。但是我没有做过这种事,真的没有。”
我之所以看清玄,是觉得清玄应该明白知晓清业真正的死因。而且清业当年能因为我和紫苏同样是亚魔族就收留我,并对我千般照顾。那么同样喜欢着紫苏的清玄,应该也愿意在这种时候拉我一把吧?
但没想到他不仅没有拉我,反倒落井下石了。他冷哼一声说:“明微那个孽畜,我待之以诚,却不想他用黯汲图逃出天界之前,竟试图剜掉我的心。你不是承认他是你哥哥吗?那你忘恩负义剜掉清业的心又有什么不可能?” 我顿时如坠深渊。
而清玄又给我致命的一击:“你们把剜心当作成仙捷径,但你们以为这么做会有什么好下场吗?你定会被推上诛仙台,从此永世不得超生。而明微,他既然敢用黯汲图打开天界到魔界的通道,必要遭受损失百年寿命的反噬。而且从此三界之内,他都会被仙族通缉,他活着比死了更难受。所以你们就是聪明反被聪明误,凡敢对仙族不轨者,定遭天谴!”
我听得浑身发冷,不为清玄说出的我未来的命运,也不为他们直接将我定罪的无耻,只因明微…… 明微去救我,竟付出了这么大的代价吗? 我对明微满心愧疚,因为这种愧疚,我对被推上诛仙台,也不是那么的惶恐。
我甚至觉得,其实死了也没什么,反正我已经失去了清业,即使魂飞魄散又如何呢。
诛仙台上,我默默地等候着斩魂刀落下,撕裂我的身体与魂魄。而这时,突然天昏地暗,黑暗笼罩了永远明亮的天界的天空。
我心中大惊,才发现天地已被禁锢,整个世界只剩下了我和他。
明微在黑暗中踏月而来,一步一步,每一步都是一地的紫色血液,每一步都踩着我的心尖。
这是黯汲图…… 我从不知道,清业为了让我开心的把戏,在明微手里,会变成如此有威力的杀招。
“微哥哥…… 你快回去!” 我不要他来救我,他已经为我付出太多了。
而明微只是对我笑了笑,对我伸出了手,语调一如许多年前的温情而柔和:“鸣鸾,跟我走。”
他身上的血越来越多,头发早已银白,他的皮肤变得苍老…… 黯汲图,已经榨干了他的生机生命。
我心中痛得难以言喻,问他:“值得吗?”
黑暗中,他抓住我的手,把我拉进那道他开辟出的,通往人界的一线天里。
“没有什么比你更重要。” 他如此说。
随后一线天关闭,我落下人界。他再也无力支撑黯汲图的反噬,倒了下去。
“明微……”
那一刻,我的世界轰然倒塌了。
10
爱一个人,能有多爱?
为他生?为他死?为他复仇?还是为她他殉葬?
不,这些都不是。
爱的极致应该是,明明每一步都带着痛苦,却依然执着地向她走去,在绝境中开出一朵又一朵的爱之花。
体味到这些的时候,我已将明微深深地藏入了心底。他就像一个虔诚的信徒,一步又一步,为我描绘出了他的深情,让我不得不以真心来回应。
那时,我正守在他躺着的水晶棺前,回忆着我与他相处的每一个细节。他在北域的冰雪里背着我匍匐前行,他带着我千里奔逃赶往万妖境,他说我不再是当年的那个我了,他为了我耗净尽生命,打开了天界与人界的一线天……
那些曾让我爱过的,恨过的,愁肠百结的事情似乎都在岁月里褪了色,只有一个瞬间在我的脑海中越发的鲜明――最后的灾难前,我对他说对不起,向他道歉,我的无知挥霍了的他的无数的爱。而他,却目光平静地送我离开。
那一刻,他一定是看到了为救我而耗尽生命的结局。但他却在看到这个结局的那一刻,平静地下定了赴死的决心。
这就是他的信仰,他的爱。这样的他,怎能不让我动容?
后来我在人界建立了一个教派,名叫鸣鸾殿。
有一个身体羸弱的书生,跨过了雪山,穿过雾霾,躲过霹雳,来到我的面前求我收他为徒,让他能去万妖境救回他的爱人。
我指着躺着明微的水晶棺问他:“你愿意承受经脉寸寸断裂的痛苦吗?愿意像这样沉睡千万年吗?”
他点头。
我问他为什么,他说因为爱。
爱到了极致,便是尤死而不悔九死不悔的牺牲。
我看望着着水晶棺里的明微,看着我离开时,他和书生是一样的心情吗?
我恨他的决绝…… 也因此对他深爱。
所以这一次,换我来等待。
我说:“那你就学它吧。它叫,黯汲图。”
* * *
满船清梦压星河
作者:白泽
第一章 苏家嫡女
“大胆,现在人赃俱获,你居然还敢嘴硬?”
“那丫头是二姨娘房里的人,赃物也是她自己翻找出来的。从头开始二姨娘连一句解释的机会都不给清梦,如今还想暗地里指派这些嬷嬷对清梦用刑,敢问二姨娘一句,这是打算让清梦屈打成招吗?”
“哐当” 一声,伴随着瓷器碎裂的声音,隐隐有血的味道顺着花香漫了开来。一直挺直脊背的少女抬手随意抹了一把额角,终究还是在父亲愈加发寒的脸色下服了软:“请父亲责罚。”
这家里唯一肯护着她的那个人,很久以前就已经死了。
所以只能低头,只能服软,如果她还想活下去的话……
“苏家嫡女苏清梦,行为不检,出言不逊,不遵女训,不敬长辈。来人,家法伺候!”
一下,两下,三下……
少女趴在长凳上,素色的衣衫很快便被鲜血浸染,豆大的汗珠不住地从额角滚落。可饶是如此,她却依旧咬着牙不吭声,更不曾开口求过半字。
空荡的院落,凋零的繁花,他看见浑身是血的少女在长凳上趴了很久,才艰难地想要支撑着自己站起来,却又由于体力不支而重重摔倒在了地上。
一次次摔倒,便又一次次爬起来,分明是纤弱的背影可却充满着让人心折的倔强。
慕星河心中一动,终是忍不住走到了苏清梦身前,沉声道:“方才你若识相些,倒也不至于受这些皮肉之苦。”
在此之前他从未安慰过什么人,这些话也是他听那些老宫人对犯错的小宫女说的,想着虽然不甚悦耳,但总归也算是为她好。可偏偏苏清梦只是缓缓抬头,然后将视线停留在他绣着精致莽龙的袖口,唇角一弯便扯出一抹没有温度的笑:“我却不知原来十一殿下竟还有在女眷闺阁看笑话的爱好。”
不仅没有接受他的好意,反而把他噎得无从开口。好半晌,他才干巴巴地憋出一句:“既然你已经知晓我的身份,便该明白,若是得罪我,你在苏家绝对不会好过……”
谁知话还没说完,苏清梦便有些不耐地打断了他:“难不成事事顺着殿下的意,我便会好过了?听话的奴才宫里候着一大堆,若殿下无事便早些回宫,一来不用看着臣女心生厌烦,二来也不至于被臣女连累了殿下的清誉。”
话已至此,若慕星河再不察觉自己受到嫌弃这一事实,他就当真辜负了父皇对他批言的早慧聪颖。
十一殿下很生气,其最直接的后果便是在他的授意之下,苏清梦的日子越发难过。
可不管是滴水成冰的大冬天被打发洗再多的衣裳,亦或者炎炎烈日下的不停劳作,那身影单薄的少女始终挺直了脊背不肯屈服半分。
彼时但凡女子都莫不是以贤良淑德为成长目标。因此苏清梦越是倔强,他便越是想看她低头服软的模样,于是便暗示了苏家众人更加变本加厉地欺负她。
他不肯放过,她偏又不肯低头,他厌恶她的骄傲,她鄙夷他的虚伪。长此以往,两人的仇便这样不屈不挠地结了下来。
第二章 红袖添刀
元宵佳节,万家欢喜。
苏清梦抹了抹额上的汗,趁婢女们把所有膳食都上齐,自个儿也三五个一团吃酒玩闹的时候,这才提着一个篮子闪身从人烟稀少的后门快步走了出去。
柳云坡,乱葬岗。今夜是她母亲的忌日,而那里便是她母亲安息的地方。
但苏清梦没有想到的是,这厢她刚刚在母亲的坟头烧完最后一叠纸钱,那厢便隐隐有兵刃交接的声音由远及近。
“玄冰卫的功夫,你们是太子的人?” 清朗如玉的声音,听上去分外耳熟。
伴随着越来越浓郁的血腥味,双方的身影亦以极快的速度从林中跃了出来。
而在听到慕星河声音的瞬间,苏清梦拔腿就逃。却不知是他运气太好,还是她运气太差,总之两人居然误打误撞地碰到了一块。
当今圣上多子,但龙椅却只有一把,弱肉强食的结果便是,几乎每年都有脑子不够用的皇子死于自家兄弟手中。
眼下这情况,很显然便是太子已经开始忌惮逐渐长成的慕星河,所以想要趁自家弟弟还未长成,便把他夺位的可能扼杀在摇篮之中。
苏清梦不想把自己终结在这儿,所以面对慕星河的诧异一点解释的意思也没有,甚至还在不动声色地与他拉开距离后,看着对方来势汹汹的一群人淡淡地道:“要杀要剐你们继续,小女子只是路过而已。”
虽然他知道苏清梦从小便跟他不对盘,但居然被她这么赤裸裸地抛弃了,他亦觉得心中说不出的不甘。慕星河冷笑一声,将原本准备让她不用管他快走的台词默默咽下,便直接扯过苏清梦的胳膊,强行拉着她一路狂奔。
“就算要死,你也必须给我垫背!”
苏清梦挣脱不能,只能磨牙告诉他:“出了树林往左,有河。”
乱葬岗的路苏清梦在幼时寻找母亲尸身的时候,曾经走过数百次,所以对这周围自然分外熟悉。
可饶是慕星河带着苏清梦在暗卫们堪堪赶到之后便跳下了河,但最终他的肩膀和大腿还是分别中了一箭。
原因很简单,只因在坠河的同时,苏清梦仗着身材娇小,整个缩在他怀中,让他替她挡去了所有的伤害。
慕星河不懂,为何人人皆是红袖添香,怎么一轮到他就变成了红袖添刀?
随着河水的浮浮沉沉,好不容易摆脱了追杀。苏清梦偏头看着身边受伤不轻的少年,想的却是,对于一个你讨厌了很多年的人,此刻有难,帮还是不帮?
夜幕下少年昏迷不醒的脸精致而又脆弱。苏清梦手中的石头由左手换到右手,又从右手换到左手,却依旧下不了手。
第三章 伊人若雪
而她没有及时落井下石的结果,便是在终于回京之后,再度跪在了苏家祠堂门口。
“夜不归宿,败坏名声,苏清梦眼下你还有什么话好说?” 气急败坏的声音,听上去好似句句都在为她忧心一般。
苏清梦缓缓抬眼:“如若我说,我是因为救了十一皇子慕星河,才没能及时回来呢?”
话音一落,四下皆静,不过片刻便有娇媚的声音轻嗤道:“所有人都知道你与殿下从小就不对盘,又怎的可能救他?”
“反正不管我说什么,你们都不会相信。” 抬头缓缓扫过那一张张虚伪恶毒的脸,面色清冷地少女微微扬嘴,露出一抹嘲讽:“既然如此,你们还不如直接省了那些废话,家法伺候。”
被冤枉,被伤害,好似从来都那般理所当然。
以往这些无比熟悉的桥段,不知为何,慕星河却突然觉得极为刺眼。
“住手……” 他素来不愿欠人情,就当是还她没有抛下他的人情好了,“前几日我遭到暗杀,确实是被苏家小姐苏清梦所救。”
至此,真相终于大白。
碍于他的情面,苏家人还假惺惺地宽慰了一下苏清梦。
然,少女清澈的眼眸里却依旧没有任何温度,曲终人散之时,亦只是缓缓起身,看也未看他一眼,便欲转身离去。
“苏、清、梦!” 一直被无视的少年,终是忍不住转身拦住了她,“我伤还未好,想着你回家或许会有麻烦,便紧随着你过来了……”
“那又如何?我本就是被殿下所累。” 苏清梦微微侧首,如雪的容颜看不出任何表情,“更何况就算殿下不解释,于我而言亦没有什么大碍。”
从小到大,不管是他欺负她,亦或者真打算帮她,她总是有办法,让他恨不得立马伸手掐死她。
藏于袖中的双拳松了又紧,暗自磨牙许久,他才再度开口道:“那你当初为什么不抛下我,自己一个人逃?”
如果当初,她没有救他,兴许他已经死了,那么她在他的记忆中便只会是个倔强骄傲的姑娘。可她偏偏没有松开他的手,明明那般危险却依旧扶着他艰难前进。他甚至记得好几次在自己快要坚持不下去的时候,都是她紧握着他的手,一遍又一遍地对他说,一定要活下去,一起活下去。
她从来都是那般凉薄,可生死关头却没有放手,那是不是代表她心里也是有他的?
他只这样想着,便觉得无限欢喜,因此待御医刚给他抹好伤药,他便立马赶来了苏府。
可沉默良久之后,他却只听她轻轻开口:“当时我与殿下生死相依,覆巢之下焉有完卵?”
只此一句,便否定了他所想的一切。
“苏清梦,整个天下再没有比你更不识好歹的女人了!” 他咬牙切齿,伸手挥落满屋精瓷。
“谢殿下赞赏。” 她笑靥如花,转身留下一地寒霜。
他怒急回宫,本想着再也不要与她相见,却不知为何,心心念念的总是想着那个分外凉薄的姑娘,甚至在听闻花神节她会参加之后,以往从来不喜与人应酬的自己,竟是想也未想便直接策马前去。
丞相家的马车饶是在满目勋贵的人群里也分外打眼。他几乎是第一眼便瞧见了身着白裙的苏清梦正从马车上款款而下。
“我竟不知何时,苏家大小姐竟也对这种攀龙附凤的宴会有了兴致?” 他几步上前,几乎是用了全身力气,才克制住自己立马伸手将她带走的欲念。
“与殿下无关。” 而她仿佛没有听出他话里的怒意,只避开他从另一侧擦身而过,恍若从不相识。
她年初便已及笄,而从苏家最近对她有所缓和的态度来看,应当是有了想利用她攀龙附凤的打算,而最让他们满意的对象便是备受恩宠的皇十一子慕星河。
可她却清楚,如今苏家已经备受天子猜忌,谁搭上谁倒霉。
在此之前,她确实不介意拖慕星河下水。可自从上次他带伤前来又拂袖而去之后,她就算再无动于衷,却也察觉到他对她的在意。
也正因为那些许纯粹的真心,她不想害了他,再加上自己也不愿让苏家人如意,便索性直接走向了一旁的太子。
慕星河听出了她话里的冷淡,亦不断劝诫自己,不要再管她死活,园子里有大把温柔的大家闺秀等着他。
可眼瞅着她与太子相谈甚欢,慕星河胸中竟是又酸又涩,忍了半晌,终是挽了锦袖,直接三两步过去便将她扛出了园子。
“慕星河,你疯了!” 她不可置信,又羞又恼。
他快步出园,脑中却逐渐清晰:“你想要荣华富贵,我便给你荣华富贵!如果你非得在这园子里选一个嫁,那为什么不能是我?”
如若苏清梦一定要嫁人,那为什么不能嫁给慕星河?
再没有人能比他更熟悉她,再没有人比他更了解她,亦再没有人…… 比他更喜欢她。
第四章 相知不易
“慕星河,你究竟闹够了没有?”
自从上次她被他强行从赏花园子里扛出去之后,她原本就不怎么好的名声便越发被传得不堪,原有的打算更是被破坏得彻底,亦给了本来就不待见她的苏家一个关她静闭的大好借口。
可偏偏把她弄到如此境地的人,却恍若不知似的,明知她恨不得掐死他,还依旧天天在她面前晃荡。她锁紧了房门,他便翻窗;她关上了窗,他便直接砸穿了屋顶。
“一日不见如隔三秋。” 完全无视苏清梦冷若冰霜的脸色,某人淡定地从窗户爬进来,看着她笑容明媚:“清梦,我不是昨天才跟你说,晚上写字很伤眼睛吗?”
绣花、做衣裳、养花弄鸟、抄书画图…… 起初他还以为是她的兴趣所在,直到他派出去保护她的侍卫说苏家姑娘把那些东西全部拿去换了钱,他这才知晓原来这些年丞相府竟连一分月例也没有给过她。观之苏家其他姑娘的柔荑仿若上好的羊脂白玉,可她的十指却满是伤痕和劳作的痕迹。他心疼得无以复加,当下便让人送了好几箱子金银细软过去。一来想要弥补他这些年干过的蠢事;二来他是真的想要好好疼爱他喜欢的姑娘。
“打一巴掌给颗甜枣,这样的算计固然是好。” 知道赶不走他,面色清冷的少女亦只是斜睨了他一眼,便继续下笔如飞:“只是殿下别忘了,在你给的这些甜枣到来之前,你又做了些什么,你又是否知晓我是如何度过的?”
她的话宛如最致命的刀,只一句便让他苍白了脸色:“如果我说以往只是为了让你注意到我,我才会做了那样多的蠢事,你信吗?苏清梦,是不是不管我做什么,你都不会原谅我?”
即使隔了那么远的距离,少年话里的苦涩依旧清晰得让人心颤。笔尖一顿,苏清梦缓缓抬头,并不怎么明亮的光晕中,她看见慕星河的眉眼肩头都挂满了风霜浸透的寒意。
她记得他是最怕冷的,但凡以往只要到了冬天便很少会看见他的踪迹,就算偶尔出现在苏府也是皮裘披风裹满全身。可如今为了隐藏身形方便来看她,他竟是穿得这样单薄,日日在雪地里来回奔波数十里。而自从之前她把他送过来的所有珍宝都全数退了回去之后,他再来之时便每每都会带着一些不贵重但却异常耗费心血的东西。比方说他亲手熬的无比难喝的鸡汤、亲手做的风筝、亦或者是如今这一篮子他亲手折下的墨梅……
大滴的墨汁滴落在宣纸上,像极了黑色的泪。苏清梦握笔的手颤了颤,隔了许久才听她轻声道:“天色不早了,还请殿下早些回府。”
察觉她神色松动,他本以为自己终与她靠近了一点。可谁知她一开口,却依旧拒他于千里之外。
就好像双方对敌之时,明明自己已经使出了十分的力气,可真打过去才发现对方早就不在了原地。
烛光晃动,他离她那样近,却又隔了那样远。他看着她的眼,很久很久,最终低声叹道:“罢了。”
苏清梦便看着他跃出了窗外,鹅毛大雪纷纷从窗沿飘进。她捂着闷痛的心口想,也许再不会相见。
而后,他也确实没有再来过。
只是偶尔在她出门变卖字画的时候,会看见他带着家丁从闹市经过。然后听一些粉面含羞的妙龄姑娘们说,若能得十一殿下青睐,便再不枉此生。
她低头笑笑,便转身如往常那般从搭着高高戏台子的胡同快步离开。却不曾想那日也不知得罪了哪路神仙,往日夯实的戏台竟顷刻间倒塌。
两边院墙高耸,她避无可避,只愣愣地看着无数瓦砾墙砖往她身上砸来。
本以为再劫难逃,却不曾想许久未见的慕星河竟不知从何处闪身而出,将她拦腰揽过,几个纵跃便远离了危险。
看见她眼里的惊讶,他便立马松手,别开脸冷声解释:“苏小姐别误会,本王不过是恰好路过,绝对没有故意跟在你身后……”
她看着他微红的耳尖,心中一暖,终是忍不住微微笑道:“从来没有人关心过我,也从来没有人会在意我的原谅。”
话音一落,少年准备离去的背影便是一僵。她听见自己的声音越发轻柔:“慕星河,我从来没有喜欢过,我不知道那是什么。”
“可如果那人是你,我想努力试一试。”
那一霎那,千古横空,万籁俱寂。
他从未想过,原来从地狱到天堂,真的可以只因一个人,只因一句话。
第五章 人心难测
庚子年,腊月初三,皇十一子慕星河于宗庙行弱冠之礼。陛下亲临,文武百官纷纷来贺,送礼的队伍一路蜿蜒到了皇城之外。
每一个如花少女都代表朝廷之中举足轻重的一方势力,若换做其他任何一个皇子,大约此时都迫不及待的与之周旋。
可谁也没想到,那丰神如玉的少年竟是谁也不曾多看一眼,便直直跪在了御前,声音清朗,神色坚定:“儿臣与苏相之女苏清梦从小一起长大,青梅竹马,乃儿臣魂牵梦萦之人,恳请父皇为儿臣赐婚。”
此言一出,原本熙熙攘攘的大殿瞬间沉寂。
苏家是陪着太祖开国的功勋之臣,是从诸王混战时期一直到大业功成时太祖最信任的手足。也正是因为如此,当所有功高盖主的臣子都没能避免兔死狗烹、鸟尽弓藏的下场时,权力正当顶峰的苏家却留了下来。
太祖相信他的兄弟,但他的子孙后代却无一不视苏家为豺狼虎豹,但凡听闻苏家人有任何一点错误,哪怕是捕风捉影的讹传,便大肆惩罚甚至削爵贬官。直到如今,当年傲世天下的第一世家竟只有她父亲这一个靠考取功名走到现在的一品丞相,其他爵位诰命一个皆无。
谁都知晓,当今天子自登位以来便一直打压苏家,视其为眼中钉肉中刺。是以,她虽已及笄,可却谁都不敢上门提亲,唯恐触及龙之逆鳞。
但如今,却有那么一人,不顾隆恩圣眷,不管锦绣前程,在所有人面前,为了她而下跪,为了她而请求。
“逆子!你可想清楚了!” 皇帝的声音依旧威严,其中努力压制的怒意让百官心惊肉跳,几乎同一时间所有人便齐齐跪了下去。
若放弃,圣眷仍在,咫尺江山近在眼前;若坚持,则触怒龙颜,从此被隔绝在朝堂之外。
此时此刻,不管是谁都知道应暂避锋芒。
可那跪在最前面的少年,却只是轻轻看了她一眼,便再度俯首以额触地,淡然道:“儿臣,不悔。”
这个世上,谁都可以多情,可皇帝不能,皇帝看中的皇子更不能。
因此话音一落,皇帝便拂袖而去。原本满殿谄媚的大臣,也纷纷目露鄙夷匆忙离去,好似逃离阿鼻地狱。转眼之间,人走茶凉。
“慕星河,这样会毁了你的前程。” 她从未想过他会为她做到如此地步,亦不觉得自己值得他那样做。
而他却只是看着她的眼,微微含笑:“可我却从来都没想过要当皇帝,更没有想过要跟皇兄相争。”
“清梦,江山太重,而我却只想自由自在地跟我喜欢的姑娘携手相伴。” 他缓缓向她走近,拉过她拢于袖中的手,与她十指相扣:“你可愿信我?”
慕星河的感情,从来便是那样直接而真挚,那般灼热的温度,几乎烫伤了她的手,融化了她的心。
微微弯下腰,苏清梦看着他的眼,缓慢而郑重地将自己的手放在了他的掌心:“愿与君,共进退。”
她想,哪怕从此富贵不再,哪怕浮生诸多艰难,只要他还在,其余便都不重要。
她亦知晓,皇帝忌惮苏家,她与他的婚事定当没那么容易。
但她却始终没想到,苏家为了保全百年荣望,竟转眼便与太子牵上了线,而那与她只在园中有过一面之缘的太子,竟也点明了要她入主东宫。
第六章 退无可退
是如苏家所愿出嫁,还是如自己所愿逃离。
于苏清梦而言,根本没必要浪费力气选择。
趁着月黑风高,屋内屋外的仆人们都眼皮子打架之际,她果断敲晕了离她最近的丫鬟,然后换上了她们的衣裳,第二天再趁着众人于清晨忙碌之际,悄悄出了苏府直奔慕星河所在的景王府。
“要么一起走,要么你把马给我,我自己走。” 恰逢慕星河准备骑马出门,她便直接拦在他马前,仰面问道。
虽说私奔这样的话题于月色绵绵时更好行事,可眼下不知苏家的人是否会马上赶来,所以她没有时间去酝酿和纠结。再者,她虽相信慕星河的话,可如若他舍不得放下他的荣华富贵,她亦好就此死心,从此相忘于天涯。
然而,白马之上的如玉少年,只是微微一怔,下一刻便直接把她抱上了马,扬鞭往城门飞奔而去。
马蹄嗒嗒,乌发飞扬,他伏在她的耳边,轻轻笑道:“私奔这样的妙事,又岂能少了本王?”
东宫有他的暗线,是以他的皇兄与苏家私下商议打算横刀夺爱的事,他自然了然于心。而他今日本就打算去苏府把她强抢了出来,却没想到他喜欢的姑娘竟也和他想到了一处。
如此,甚好。
他琢磨过,他身强体壮,知识渊博,若隐居深山,他能砍柴下河,逮兔捉虾。若隐于闹市,他能从商开业或者教书育人。最不济他还能抹花了脸去大街卖艺,胸口碎大石什么的,对于一个从小练习铁布衫的皇子而言根本就算不得难事。至于他媳妇儿,那更了不得,写诗作画,描花刺绣等等俗事都无一不精。两人就算出逃,想来也可以把日子过得很好。
因此两人逃跑时,饶是知晓前路艰辛,却依旧充满了希望。
然,这般美好的感觉却只维持了很短的时间。
只因苏家和太子眼看抓捕他们无望,竟然直接隐瞒了苏清梦的逃跑,转而禀告圣上慕星河被歹人所掳。
虽说慕星河前些日子触怒了天颜,可毕竟是自己从小宝贝到大的儿子,自然紧张万分,当下便让画师画了慕星河的画像,从京城到地方,甚至偏远的小山庄,到处都张贴上了他的画像。
起初两人易容而行,可奈何进城门的男子都要由医官查看,无奈之下只好转走崎岖山路。
却不曾想,许是皇帝如此重视慕星河的态度,让太子忐忑不安,因而竟重金请来许多武林人士追杀慕星河。彼时两人身上的盘缠都已用尽,慕星河又因一路对她相护,染了风寒,无奈之下她只好用身上不多的几件首饰去寻医换药,是以终究还是暴露了踪迹。
从未有过一刻,苏清梦如现在这般痛恨自己的无能。
也从未有过一刻,她曾为自己的逃离,后悔不已。
如若不是她,慕星河不会受伤,美如冠玉的少年亦还是会如初见那般,翩然风华,惊羡了岁月,倾倒了苍生。
若没有跟她走,他不会这般狼狈,不会惹怒天颜,更不会引来太子倾尽一切的追杀。
眼看着慕星河出剑的手越来越慢,两人也逐渐被逼到了悬崖边缘。苏清梦终是咬了咬牙,一把掀了易容面具,张开双手护在了慕星河身前,然后踮着脚在少年的额头极尽缠绵地吻了吻,轻声道:“慕星河,我绝不会让你死。”
凛冽的寒风吹得衣摆猎猎作响,周围鲜血散落草木凋零,可少女雪白的容颜却仿若太湖池中最让人惊艳的白莲。
“告诉太子,若眼下能放景王一马,苏清梦从此侍奉东宫左右。”
第七章 向来缘浅
她知道,哪怕他明明知晓跟着她走,最好不过从此飘零,最坏会因此丧命,他却依旧选择义无反顾地带她离开。
如若她真嫁与了太子,她估计,他有九成的可能会去抢亲,有十成的可能会与对方同归于尽。
而她,却绝不能让他死。
所以,在太子还没有得到赐婚圣旨的时候,她以万寿节为陛下祝寿为名,跳了一支风华绝代的舞,择日便被接入了宫。
她只是希望他能好好地活着,不管庙堂之高,不论江湖之远,哪怕穷其一生他们都不能再相见,哪怕他会娶其他的姑娘,过没有她的人生。
只要她知道他还活着,她还能够把他埋在心里默默想念,那便已经足够了。
可她终究还是低估了她在他心里的位置。原本不问世事的少年,竟为了她走入了泥泞不堪的朝堂,下为结交党羽,上亦出谋划策,竟隐隐有直逼太子的趋势。
眼下皇帝虽按捺着不说,可是却渐渐以各种理由把他的人从朝堂剔了出去,便俨然已经动了杀机。而原本就忌恨他的太子,更是在此时不遗余力地落井下石。
他的处境很危险,她必须帮他。
只是皇帝疑心很重,每每银针试毒以后,还必须要她先吃,他才会动筷。如此一来,那些搭配在一起无解的毒,也渐渐侵入了她的五脏六腑。
皇帝原本的身体便不算硬朗,因此身子渐渐衰败亦没有人怀疑。而她日日侍奉在前,再加上傲然于后宫的美貌容颜,皇帝自然对她百般恩宠,不过两年,便给她册封了贵妃之位。
眼瞅着皇帝对她越来越依赖,而皇帝的身子也逐渐病入膏肓,苏清梦琢磨着日子,终究在除夕当夜,满朝文武进宫的时候,让贴身侍女去邀了太子。
都说妻不如妾,妾不如偷,偷不如偷不着,更何况太子原本便对她有意,想着将来登位了一切便是自己的,便也真胆大而来。
彼时月华似水,佳人如花,再加上苏清梦点燃的魅香,太子终究没能把持住,将她一把拉入了怀中。
而好不容易身子稍有起色的皇帝,便在此时携了百官踏月而来,瞧见自己爱妃的百般挣扎,又瞧见自家太子的放浪形骸,当下便怒急攻心,吐了一大口血,晕了过去。
事已至此,原本在皇帝心中就不甚讨喜的太子,终究被废。皇帝大怒之后,毒气攻心,亦性命垂危,苏家更因跟太子勾结而获罪。至此,朝政终于被慕星河全全把持。
而苏清梦体内的毒,亦在此时渗入了心脉,每日有很长一段时间都开始昏睡。
然而但凡慕星河进宫侍疾那日,她却好似有用不完的力气,不止有心思描眉梳妆,亦还有精神为他做些精致的吃食糕点,然后亭亭玉立地在他必定经过的花园候着。
有时他身边有百官大臣跟着,她便只是盈盈望着并不上前。若他得闲,她便给他煮茶,欢喜地听他说话。
他说得最多的便是:“清梦,等着我。”
而她答的最多的便是:“好,我等你把我接回去。”
他问是不是她设计了父皇和太子,她亦大方点头。他说以后再不会让她为他这般辛劳,他可以保护她了,她便眉眼弯弯的笑,却从不曾告诉他,她是以性命为代价,才得以对他父皇下手。
她不愿他内疚,更不愿他背上弑父的罪名。
尾声 怕见来年
丁丑年,冬至,皇帝驾崩,百官跪请景王登基。
那天雪下得很大,像极了很多年前慕星河踏雪来看她的那个夜晚。
朝阳刚升,苏清梦便穿上了她最美丽的衣裳,亲自动手化了最精致的妆容,这才屏退了侍女,从偏殿抱了两坛他曾经送给她的女儿红,一点一点洒满了她居住的宫殿,然后打翻了烛台,燃起了大火。
登基的新皇不能有任何的污点,所以她必须得死。
可她知道,慕星河下不了手,甚至还会为了她而宁可获罪天下。
能被他喜欢,她是如何幸运。
而他喜欢上她,却又是何其不幸。
远远地好像有越来越多的脚步声临近,她努力从滚滚浓烟中睁开眼,恍惚中,好像听到了有人大喊拦住陛下。
再一瞬,她便被人紧紧抱在了怀中。
“苏清梦,你不准死,我不准你死!”
已经贵为天子的少年,冲开了所有人的禁制,冒着大火将她背了出来,乌发散乱狼狈不堪。苏清梦把脸贴在他的胸口上,轻轻一笑,但笑着笑着便有乌黑的血从嘴角溢了出来。
“御医!快去传御医。” 少年一边怒喝,一边掏出丝帕小心翼翼地替她擦去嘴角的血迹,可不管他换了多少丝帕,却依旧擦不干净。
“我就知道,父皇疑心病那么重,怎么可能……”
大颗大颗的眼泪,滴落在她的脸上,苏清梦却再也提不起一点力气替他拭去泪水,只是努力扬了扬嘴角:“慕星河,能死在你的怀里,我很高兴。”
远处有哀乐杳杳传来,她最爱的男人为他泣不成声,而她的手,亦在他的怀里逐渐冰凉。
苏清梦缓缓闭眼,恍惚中好像回到了当初被他从百花中强行扛出去的那个黄昏,少年神采飞扬地对她说:“你想要荣华富贵,我便给你荣华富贵,如果你非得在这园子里选一个嫁,那为什么不能是我?”
然后,花落满地,香落满怀。
·END·
 小皮球儿
2019.10.6
我有一个收藏夹,都是我在知乎上看的虐的短篇小说,直接贴链接了吖
[虐短文www.zhihu.com](https://www.zhihu.com/collection/385982700)
2020.3.13
来源:好看的 @影视盘点小达人来源看水印
看着看着,就哭了
害,人这一生呐,开心最重要,莫要太执着于一人,才好
2020.05.16
嬛嬛 四郎
剪刀手真是个神奇的存在,是个有耐心有智慧动手能力极强的物种。光是构思从几十集里截取哪些场面就够我放弃了,更别说真上手一集一集一点一点剪了吾玉
为了救他深爱的师妹,他将她骗进了鬼衣谷,他说她是个极好的姑娘。
只是她那么好,他却不要。
(一)
“阿筝,你,你愿意与我…… 成亲么?”
鸢城的春天最是热闹,风掠浮云,一晴空的风筝,满满当当,令人目不暇接,不愧鸢城之名。
这一年的姚清让却来得晚了些,风尘仆仆赶到鸢城时,已是春末。
他破天荒的一个人,身边没带穆甜儿,却是找到宋筝,在她的筝坊里,欲言又止地向她求亲。
宋筝本正为他泡茶,闻言手一抖,滚烫的茶水飞溅而出,立刻烫红了一片。
她抬头,怔怔望向姚清让,有风过堂,眨了眨眼,泪水簌簌而下。
姚清让吓了一跳,还当她烫坏了,赶紧上前捧住她的手,正不住呵气间,耳边却忽然传来哽咽的一声:“不是,不是疼。”
“而是…… 欢喜。”
一下如潮水般涌来,根本承受不住的欢喜。
从来淡然处事的宋筝,此刻泪眼朦胧,望得姚清让心头一酸,也不由红了眼眶。
风拍窗棂,他情不自禁地拥她入怀,低低叹息:“阿筝,你是个好姑娘。”
宋筝喜欢姚清让十二年了,在她还是个小姑娘的时候,第一次见到来鸢城订做风筝的姚清让时,便悄悄喜欢上了。
那年她八岁,姚清让十五岁,春风沉醉,一切开场得恰如其分。
佩剑的少年,端得俊眉秀目,却站在堂前,指着整排悬挂的风筝,泣不成声:
“我深爱的姑娘要嫁人了,我来为她挑份贺礼,要做成红色的,大红色,还要特别喜庆……”
说到 “喜庆” 二字时,少年却是再也说不下去,捂住脸,肩头抖动,哭得昏天暗地。
宋筝躲在屏风后,探出脑袋,那是她第一次见到有人哭得那么伤心,仿佛一颗心被人活生生剜去了。
而事实上,姚清让的一颗心也的确被人活活剜去了。
他的心是穆妍,剜去他心的是穆妍即将下嫁的夫君,冷月亭。
穆妍是姚清让的师妹,两人从小一起长大,青梅竹马,愿本定了婚约,却在大婚前不久,穆妍忽然悔婚,一意孤行地要嫁给才相识三天的冷月亭。
冷月亭是个什么样的人呢?大抵能用 “魔君” 二字来形容。
他无门无派,独来独往,一柄弯钩使得出神入化,在江湖上颇有名气。
虽不是大奸大恶之徒,行事做派却诡异得很,与正道沾不上边,所以久而久之,有了魔君之称。
穆妍不过在花灯节上与他一次偶遇,消失了三天,回来后便跪在父亲面前,非君不嫁。
人人都道这魔君果然有些手段,穆妍却谁的话也听不进,甚至决绝地挥起金钗,狠狠划伤了来劝她的姚清让。
那一夜,姚清让既流了血,又流了泪。
他说:“师兄永远等你,若他待你不好,你…… 还能回头。”
(二)
彼时才八岁的宋筝还不知道什么叫 “痴情”,只是懵懂听了回故事后,觉得这样的姚清让很可怜,也很让人心疼。
她并不会知道,时过境迁,后来她的也很可怜,也很让人心疼。
筝坊接下了姚清让的单子,那时掌事的信芳鸢姑还一边摇头叹息着:“情之一字,情之一字……”
叹息中却也有丝庆幸,只因若想当上筝坊的鸢姑,其中一个条件是终生不嫁。
筝坊代代相传的秘术,唯有处子之身才能继承,才能做出那犹如活物的风筝。
姚清让在鸢城住了一段时间,等待那份独一无二的贺礼诞生。
宋筝年纪小,活也少,被鸢姑派去招待姚清让,带他四处看看,陪他散散心。
开始几天姚清让抱着剑,始终愁眉不展,宋筝嘴笨,也不知该如何是好,只是默默跟在他身后。
直到有一日姚清让忽然提到,他快过生辰了,他属兔,从前每次庆生时,穆妍都会做个兔子木雕给他,一晃眼,他都珍藏了满满一盒子。
只是穆妍即将嫁作人妇,以后怕是再也收不到她做的木雕了。
说者无心,听者有意,宋筝望着姚清让眉心闪过的落寞,在心底暗暗做了个决定。
回去后她就开始扎风筝,瞒着所有人,夜里偷偷爬起来。
因为筝坊做出去的风筝都是要登记在册,要收钱的,可是她不想收姚清让的钱,她想送给他,作为他的生辰礼物。
这一做就做了好几夜,赶在姚清让生辰那天,宋筝终于珍而重之地放在了他手上。
风筝是兔子形状的,玲珑可爱,一只耳朵上还绣了两个字——
清让。
直到一针一线绣出这个名字时,宋筝才后知后觉地意识到,姚清让的名字是多么好听。
清让,清让,轻轻念出来时,仿佛枝头的露水坠落,唇齿都留香。
收到礼物的姚清让很是意外,拿着看了又看,面对眼前这个一向默不作声,此刻目光里却又是忐忑又是期盼的小女孩,一时不知该说什么好。
有些感动是无法用语言来描述的,他郑重地道了谢,挠挠头,“不如我们一起去放风筝吧。”
天很蓝,云很白,风很轻,鸢城的春天是一年四季里最美好的。
同姚清让一起放风筝,那是宋筝再欢喜不过的事情。
可惜乐极生悲,到底年纪小,又黑灯瞎火地赶工,风筝扎得不稳当,居然怎么也没能放起来,最后被风一吹,还断了线直接从半空坠下。
宋筝脸都绿了。
面对奔去将风筝捡回来的姚清让,她咬紧唇,险些哭出来。
姚清让却拍了拍她的脑袋,眉眼含笑:“这是我收过最棒的礼物,真的!”
宋筝仰头望着他,阳光洒在少年身上,勾出一圈暖暖的金边,她不知怎么,居然鬼使神差问出一句:“比兔子木雕还好吗?”
才一说出口,她就悔得恨不能咬掉舌头。
果然,姚清让眸光立刻黯了下去,满身的活气像被瞬间抽走。
欢天喜地而来,却是垂头丧气而去,夕阳西下,宋筝跟在姚清让身后,暗骂了自己不止一千遍。
风掠长空,两人的身影被拉得很长很长,若是气氛不那么凝重,倒也是极动人的画面。
宋筝开始从姚清让口中听到一些往事,那些他和穆妍再也回不去的往事。
姚清让说,穆妍是个很好的姑娘,从小到大,一直都是,只是遇上冷亭月后,才疯魔了般,性情大变。
从前的她心灵手巧,笑容明媚,会在春光三月里,同他一起上山采花,会在仲夏夜时,同他一起入林捕萤,还会在凉凉秋雨里,与他一起倚在廊下看书,最暖人的还是每一年的冬雪纷飞,他们会坐在窗边,一边围庐暖酒,一边拈子下棋。
春天采花,夏日捕萤,秋雨看书,冬雪煮酒。
那样的时光,真是再美好不过。
姚清让至今也忘不了,有一年春日,漫山遍野的花儿都开了,穆妍就站在花间,头戴花环,张开双臂转圈,娇俏的笑声飞上了晴空:“师兄,你说我好看不好看?”
她那时眼中对他还满是笑意,还会甜甜地叫他师兄,甚至在下山时,他悄悄牵住她的手时,还会抿唇脸红:“师兄就不怕人看见……”
那些年岁的穆妍是多么的美好,美好到现在的姚清让还心心念念,不忘温柔的旧时光。
但这一切的一切,自从冷亭月出现后,便彻底改变。
望向他的穆妍再也没有笑容,她的温柔再也不属于他了,他精心为她编织的花环,她看也不看,直接踩在脚下,踩得稀巴烂。
她像变了个人似的,眼中只能望见冷亭月,对守护在身边的他残忍至极。
明月当空,忆起这些往事的姚清让神情哀楚,说到这终是再也忍不住,埋头捂住脸,泪流不止。
廊下,原本默默听着的宋筝有些慌了,想说些什么来安慰姚清让,却一时手足无措,不觉就抓住了姚清让的衣袖:“姚,姚大哥,这些事情,我也能陪你做,真的……”
她眼中亦有泪花泛起,越凑越近,试图力证自己般:“你别难过了,春天采花,夏日捕萤,秋雨看书,冬雪煮酒,这些我统统都能陪你去做,我,我还会扎风筝,姑姑都夸我的手艺好,以后我每年都送你风筝……”
风过廊下,姚清让忽然抬起头,在月下打断宋筝:“就像那只没能飞起来的兔子风筝一样吗?”
他望着她,脸上虽然泪痕未干,眸中却已少了大半凄楚,反而带着几丝逗她的意味。
宋筝愣了愣,破涕为笑,重重摇头:“当然不是!那,那是意外,我的手艺很好的!你不信我再做……”
话音戛然而止,只因她已被一把拉入怀中,少年拥住她,在月下感动莫名,下巴抵住她肩窝,柔声笑道:“傻丫头。”
他说:“我不信你还能信谁?”
“我们阿筝做的风筝是世上最棒的风筝,独一无二,谁也比不上,是不是?”
温热的气息撩过耳畔,宋筝的脸蓦地便红了,凉风皎月下,她心跳得无比快,快到姚清让还不曾注意到,她自己却已沉迷。
(三)
后来,兔子风筝到底被宋筝拿了回来,她不想留个次品在姚清让身边,在姚清让离开鸢城前,她也终于做好一个新的,偷偷塞给了他。
姚清让的行囊里,于是装了两个风筝,一个给穆妍,一个给自己,轻轻摩挲着那对兔耳朵的时候,好像内心的创伤也抚平了一些。
城门口,姚清让对宋筝投去感激的目光,风吹过他的衣袂发梢,他说:“阿筝,有机会我会再来看你的。”
伸手又摸了摸她的头,抱剑的少年终是转身,策马而去。
等到那身影彻底消失时,站在城门下的宋筝才捂住眼睛,终于哭了出来。
此后那个废掉的次品风筝,被她锁进了匣子里,没事时就拿出来看一看,怔怔的发呆。
老天是公平的,看风景的人永远不会知道,有人也正在默默看着他。
姚清让的一颗心是被剜去了,而宋筝的一颗心,却深深地藏在了匣子里,不知何年何月才能宣之于口。
时光如梭,在宋筝的念念不忘中,却是第四年,姚清让才终于再次踏上鸢城的土地。
只是这次不是一个人了,而是还带了个孩子——
穆甜儿,穆妍的女儿。
小家伙不认生,见着宋筝便咯咯直笑,还狡猾地冲她吐口水泡泡。
姚清让一手抱孩子,一手摸向宋筝的脑袋,语气熟稔得仿佛从不曾离去:“阿筝长高了不少,愈发俊俏了,是大姑娘了。”
宋筝眨眨眼,感觉视线模糊起来,耳边只听到姚清让继续道,笑中却有些歉意:“你为我做的兔子风筝被甜儿抓坏了,她争着要个一模一样的,我这才……”
这几年发生了很多事情,最大的一件,便是冷亭月抛弃了穆妍母女,或者说是…… 失踪了。
在某个清晨毫无预兆地不见了,连张字条都没留下,穆妍抱着刚满月的女儿枯坐了几宿,后来大病一场,在姚清让的照顾下才渐渐恢复,却总不见生气,眼里总望着下山的方向。
她不是没出去找过,只是既没找到,也没等回,冷亭月就像从人间蒸发了一般。
对于穆妍的固执,穆掌门是痛心疾首,只差没贴在她耳朵边吼了:“早说他不是什么正派人,行事一向诡异,哪能安下心来和你好好过日子,这下你可怎么办,孤儿寡母的,要不……”
要不…… 改嫁?
嫁谁,自然是一直在原地等待她回头的好师兄,姚清让。
只是这话提不得,一提穆妍就跟发疯似的,把屋里的东西摔得稀巴烂,还故技重施,拔下金钗又将姚清让划得血淋淋。
这回连穆掌门都看不过去了,直心疼爱徒:“你师兄又不欠你的,你何苦这样作践他,他便不是人么,便没心没肺的,能任你伤害吗?”
听这数落时,穆妍一声不吭,只是恨恨落泪。
她简直疯魔了般,冷亭月不回来,她便将所有过错推到姚清让身上,咬定是他赶走了冷亭月,对他恨之入骨。
姚清让能说什么?世间最悲惨的事也莫过如此了吧。
所幸穆妍还有个女儿,古灵精怪的穆甜儿,对姚清让倒是亲得很,反而有些害怕总是疯疯癫癫的母亲。
她成天黏着她的 “姚叔叔”,不觉间,姚清让扮演的角色,已如兄如父又如友。
一切穆甜儿提出的要求,他都愿意满足,就像满足他永远等待的师妹。
(四)
宋筝看了姚清让手臂上的陈年伤疤,心疼不已,姚清让却放下衣袖,不在意地挥挥手:“都是过去的事了,没什么要紧的。”
反倒是穆甜儿懂事地凑上来,挥舞着小拳头,替他忿忿不平:“坏,娘亲坏坏!”
愿打愿挨,连几岁孩童都能看明白的惨状,姚清让却偏偏迈不过,不是没有想过放下,可夜夜饮醉后,在看到那张冷如冰霜的脸时,又彻底忘记了自己要放下。
他大概上辈子真的欠了穆妍的。
宋筝如今已是信芳鸢姑最得意的弟子了,技艺不说炉火纯青,却也是筝坊里拔尖的。
当她将做好的兔子风筝拿出来时,穆甜儿瞪大了眼,拍手称赞:“阿筝姐姐好厉害!”
所谓狗腿,大概就是穆甜儿这样,自从有了宋筝,她就不怎么黏着姚清让了,姚清让摊手摇头,故作哀怨:“得得得,一个风筝就把你收买了,长期下去,看来我要失宠了。”
那模样逗得穆甜儿和宋筝直笑,阳光洒进屋内,枝头鸟雀呼晴,一时间,一切美好得像个梦。
穆甜儿沉浸在梦中不愿醒了,虽然顺利拿到了新风筝,她却吵着不肯离去,更是勾住宋筝的脖子,夸张得泪眼汪汪:“不,我不,我就要阿筝姐姐,除非把阿筝姐姐也带走……”
在鸢城的这段时日,她别提多开心了,放风筝、逛夜市、泛小舟…… 一想到回去就得面对那个神经兮兮的母亲,她简直心如刀割。
姚清让被气笑了:“嘿,还心如刀割呢,多大点人,看看心长全了没!”
他伸手就要接过穆甜儿,穆甜儿却死死巴住宋筝的脖颈,宋筝也是抱住她,一时竟没有要松开的意思。
“不如…… 就再留些时日吧。”
到底说出了这句话,心跳如雷中,宋筝只看到姚清让明显一愣,许久,他挠挠头,“也行,过完春天再走吧。”
一声欢呼响彻满堂,穆甜儿搂住宋筝就亲,吧唧吧唧中,却是忽然贴在宋筝耳边,压低声音,笑得狡黠:
“阿筝姐姐,你喜欢我姚叔叔,是不是?”
奶声奶气中,宋筝像被定住一样,对上穆甜儿滴溜溜转悠的眼睛,心虚莫名。
原来,喜欢一个人…… 这么明显吗?
(五)
年年春到,年年春去。
像成了惯例般,后来每年的春天,姚清让都会带穆甜儿来到鸢城,住上几个月,同宋筝朝夕相处,像真正的一家人一样。
宋筝长得很快,当又一年风筝飞满晴空时,她已经及笄,真正的成了个大姑娘。
城里开始有不少人上筝坊提亲,但宋筝通通都拒绝了,大家背地里都说她眼界高,却只有她自己明白,她的心,早就在很多年前,随着那只废掉的风筝,一并锁在了木匣子里。
而姚清让也不是傻的,多年来的细枝末节,再加上人小鬼大的穆甜儿 “军师”,他多少是明白宋筝心意的,但却从不回应,只因为那绵长温柔的情意中,他真的不知道该如何回应。
他习惯了被辜负,却还没习惯辜负别人,更何况还是那个春衫飞扬,也算他从小看着长大,爱护有加的小姑娘。
于是这层纸谁也不去捅破,漫天的风筝下,只有穆甜儿看着干着急,恨不能拿根绳子把这俩人绑一块。
终于,在又一年春风拂面时,宋筝找到姚清让,邀他独自泛舟,用穆甜儿窃喜的话来说,那就是阿筝姐姐终于 “开窍” 了!
但宋筝倒真不是 “开窍”,她只是没有时间再等了。
“信芳姑姑说想要我当下一任鸢姑,让我考虑一下,她看我也无成婚打算,却不知,我其实,其实……”
月色下,湖心一叶小舟,晃晃悠悠,像极了宋筝七上八下的一颗心。
她绞着衣角,低头不敢看姚清让,耳边一缕碎发垂下,夜风一吹,撩过那白皙的脖颈,看得姚清让长睫微颤,略微失神。
对宋筝是什么感觉呢?这么多年来,姚清让也说不上。
坦白说,他是喜欢她的,如果中间没有穆妍,也许他们早就花好月圆了。
宋筝是个极好的姑娘,话不多,却会为人打算,会默默做些暖人心的事,同这样的姑娘在一起,不用担心被伤害,更不用担心没有未来。
所以日久天长间,除却感动,他是真的生出了些情意的。
只是,姚清让内心多清楚,不够,这还不够。
他望着面前低眉垂眼的宋筝,深吸口气,长痛不若短痛,终是狠下心来打断了她:“对不起。”
宋筝的声音戛然而止,好半晌,她才颤巍巍地抬起头,红着双眼,身子在风中瑟瑟发抖,像只小白兔。
那目光叫姚清让不忍对上,别过头,暗骂自己是否太过残忍。
月移风动,宋筝却在这时,晃悠悠地站了起来。
“没,没关系,当鸢姑其实挺好的,就能,就能继承筝坊的秘术了,还能做出犹如活物的风筝,挺好的,真的……”
翻来覆去的话中,分明是柔里带泪,反而叫姚清让难过不已,鼻头一酸间,就想开口重新决定,却只听到扑通一声,水花四溅——
宋筝心神大乱下,竟然一个没站稳,栽倒进了湖中央!
只听得岸边传来一声大叫:“阿筝姐姐!”
一直躲在树后窥探的穆甜儿猛地跳出来,提着裙子拔足狂奔,一边跑还一边拼命招手:“来人啊,来人啊,有人落水了!”
(六)
从湖里捞出来的宋筝染了风寒,卧病在床,穆甜儿守在床边,一勺一勺地喂她喝药。
喂到最后,她忽然把碗一顿,药汁四溅中,一张小脸气呼呼的:“姚叔叔怎么回事?脑子被驴踢了吗?干嘛要拒绝你,他还能上哪找这么好的姑娘去?他莫非想打一辈子光棍么?亏我还为他出谋划策,当尽军师,真是,真是气死我了!”
一通发泄后,又像想起什么,赶紧摸出丝帕,手忙脚乱地去替宋筝擦眼角的泪:“对不起对不起,阿筝姐姐,我不是有意提起的……”
她越擦那泪却掉得越多,像坠了线的珍珠,滚滚而下,无声无息地浸湿了枕巾。
擦到最后穆甜儿也无力了,扔了丝帕,哇哇跟着哭:“都怪我娘,都怪她!”
汹涌大哭间,反倒把床上的宋筝惊起,她顾不上自己,赶紧先去安抚穆甜儿。
安抚了好半天后,两人筋疲力尽地依偎在一起,穆甜儿在宋筝怀里有一搭没一搭地抽噎着:
“我一点也不喜欢我娘,她太自私了,眼中只看得见自己那点情爱,将别人都视若草芥,从小到大她就没给过我一个笑脸,好像我不该来到这世上,不该做她的女儿,她还真当人人都欠她的么……”
声音里夹杂着又爱又恨的复杂情绪,床上帘幔飞扬,宋筝怜惜地抚过穆甜儿的长发,一声轻叹:“你娘却也是个苦命人,稳当平顺的一生,不该遇上了你爹,情之一字,的确煎熬……”
说到此,竟生出一番物伤其类,兔死狐悲之感,宋筝不禁潸然泪下。
门外的姚清让站得腿都僵了,手中的一碗药已尽凉,他耳边听着宋筝的泣声,缓缓靠着门滑坐下来,一时五味杂陈,双眼泛红。
过堂风拂过他的衣袂发梢,他从没有一刻那样怀疑,怀疑自己的苦苦守候,真的有意义么?
来年春日,宋筝正式接过《鸢经》,成为筝坊新一任鸢姑。
这一年,她才十八岁,却好像一生都已经走完了。
仪式上穆甜儿哭得不成样子,姚清让牵着她的手,也模糊了视线。
仿佛还是十年前那个春天,他初到鸢城,宋筝带着他四处看看,虽然话少却字字戳心。
“春有百花秋有月,夏有凉风冬有雪,若无闲事挂心头,便是人间好时节。”
那年春衫飞扬的小女孩对着他轻轻吟道,仿佛不经意,无一字相劝,却句句暗含抚慰,他面上不露声色,心中却是极感动的。
如今时光荏苒,那个当年默默跟在他身后的小姑娘,接过担子,摇身一变成了新一任鸢姑,守着筝坊将终生不嫁,他竟生出万般不舍,如锥刺心,带来一片迟缓的疼痛。
城门相送,宋筝换上鸢姑的穿着,长裙摇曳,目光泓然。
她说:“姚大哥,你今年也二十有五了,该找个好女子成家立业了,莫再枯等了,有些东西是强求不来的……”
就像…… 他之于穆妍,她之于他。
姚清让长睫微颤,四野风声中,情不自禁伸出手就想拂过宋筝一缕碎发,宋筝却一颤,退后一步,许久,在他讶然的眼神中笑了笑:
“如今成了鸢姑,可就不能再像往日一般与你打闹了,快去吧,明年春日,我会在筝坊沏茶以待,等你和甜儿的到来……”
跨马而去,姚清让频频回头,宋筝站在城门口挥手送别,夕阳下的剪影说不出的温柔,宛若仕女图里送丈夫离去,等待丈夫征战归来的妻子。
姚清让心头一疼,风声飒飒中,忽然就有了那么一丝悔意,悔得双手一紧,脸色都苍白了。
穆甜儿也跟着他回头,仰首看见他眸底的波光,好气又无奈,在他怀里哼哼:“姚叔叔,你真是天底下最笨的人了!”
(七)
最笨的姚清让在这一年春末,风尘仆仆地赶到鸢城,问了宋筝一句话:“阿筝,你愿意与我成亲么?”
一切发生得太不可思议,像双十年华老天爷馈赠的礼物,宋筝仿佛掉进一场好梦中,受宠若惊,却又诚惶诚恐地害怕梦醒。
姚清让也没解释太多,只是似乎赶时间,催促宋筝赶紧收拾东西,跟他离开鸢城。
于是在一个半夜,宋筝带走了自己做风筝的行当,留下一张字条,跟着姚清让出了城门。
她这样的私逃是大逆不道的,算是绝了自己所有后路,此生此世都不可能再回到筝坊了。
若是姚清让辜负她,她便当真是万劫不复了。
但此时此刻,夜风之中,宋筝依偎在姚清让怀里,听着他清晰可辨的心跳,却觉得一切都是值得的。
她原本以为一生在十八岁时就已注定,却未料熬到双十年华,姚清让牵了她的手,生命彻底改变,别有洞天。
一路快马加鞭,风餐露宿,抵达山谷时,是一个再平常不过的黄昏。
残阳如血,长风万里。
山谷口居然坐了黑压压的一片人,像是等候已久,宋筝见到时吓了一跳,只当是姚清让的同门,如此大的阵仗,却过分热情了些。
当先一人坐在一把太师椅上,折扇轻晃,长眉入鬓,一张玉面俊美异常,竟是个年纪轻轻的后生,远非宋筝所想象的威严穆掌门。
他折扇一点姚清让,唇角微扬:“很好,不愧是清风剑,果然很守时。”
姚清让面色铁青,并不接话,只是将宋筝抱下了马。
“这便是你的妻子么?” 那年轻人懒洋洋地摇着折扇,上下打量着宋筝,宋筝被他望得有些不自在,往姚清让身后躲了躲。
“是。” 姚清让面无表情。
“我要她回答。” 年轻人美眸流转,一拂袖,折扇指向了宋筝。
宋筝心跳如雷,在姚清让的示意下,上前一步,点点头:“是,我是他的妻子。”
没有红烛,没有嫁衣,没有拜堂,得一句承诺,携手远走天涯,也算是妻子了吧。
“好得很!”
一声笑喝,鸟雀惊飞,年轻人折扇一收,蓦然站起,目光陡厉:“来人,拿下他们!”
一挥手,人群从四面涌来,宋筝脸如白纸,却在这时听到熟悉的一声:“阿筝姐姐!”
不知何时有两道身影被押了出来,其中一个,正是满面泪痕的穆甜儿。
“你还是被姚叔叔骗来了吗,你怎么这么缺心眼呀,干嘛来送死?!”
她嘶声呐喊着,宋筝脸色大变,扭头望向姚清让,他却不敢对上她的目光,只是握紧手中剑,流露出痛苦的神色:
“阿筝,对不起,我得罪鬼衣谷,他们误抓了穆妍母女,定要我拿妻子来换,我,我实在是……”
有如候鸟-周晓枫
========================
有如候鸟-[[周晓枫]]
-----
1974年,湖北
外婆的指关节弯曲,依然飞针走线。抿着嘴,她吃力地绣花花草草。竹篾薄而韧,边弧磨得发亮——像面镜子,映出皱纹像支流丰富的河道布满外婆泥色的脸。
那时她五岁还是六岁?每当想起那个惊心动魄的下午,她理智上判断出那是记忆的失误。外婆当年五十多岁,不可能像自己记忆中那么老。可她觉得外婆一直是老人,从未年轻。外婆吃素,鸡蛋对她来说都是一团液体的肉。外婆虔诚供奉那尊袖珍神像……佛像法相庄严,生死,融化在观音因慈而悲、由悲而慈的眼神里。
与父母在北京生活过短暂的时光,作为幼儿,她还来不及存储记忆,参加三线支边建设的父母就要远赴贵州。他们奔波在大山荒凉的褶皱里,无法陪伴和照顾孩子,就把她托给外婆。她的童年和记忆,是从外婆居住的那座即将被淹没的村庄开始的。
村角的鲁班庙,柱檩粗大,却断了茬,许多小到肉眼无法辨识的牙藏在其间日夜咀嚼木屑,并抖落时间的粉尘。檐角铺张的蛛网,阳光里若隐若现……很难想象,酒窝大小的蜘蛛能够完成如此浩大工程,如同很难想象,操作着工具和机械的人类蚁行者,能够挖出宽阔的沟渠和浩瀚的人工湖,建起高耸堤坝,改变千万年来的山河样貌。蛛网悬挂虫尸,只剩萎缩、干透的皮壳或残肢——那是她最早见识的世间阴谋,轻盈又晶莹,美若魔法。只需横梁、墙壁、树木,甚至是瓦砾和草秸,蜘蛛便可织就一扇透风透雨却透不过生死的舷窗。它是真正的能工巧匠,人类相形见绌。鲁班庙里有扇朝南的奇怪窗户,始终空着,像豁牙,量好尺寸、打好框架,玻璃窗怎么也装不上去,工匠们不得其解,摇头叹气,沮丧收场。作为祖师爷的鲁班,嘲讽了他自诩骄傲的子孙。
赶上大旱,村里要去灵验之地请龙王。八抬大轿请来的龙王爷,其实是个硕大的红漆木龙头,雕刻着威风凛凛的眼目和头角。连续供奉数日,龙王爷必灵验,滚雷如同它低沉的喉音从天际传来,它呼风唤雨,灌溉大地上的割痕。据说某年,几个淘气少年趁着夜色把龙王从鲁班庙里搬出来,扔进井里。正当人们遍寻不见,恰恰飘来一片面积并不大的云,几乎笼罩着井口下起滂沱大雨。水位淹井,龙王终于从井口浮现暴烈圆睁的怒目……惊慌的老人跪拜不起,为莽撞的孩子代罪。
是龙王的余怒吗?春分登天、秋分潜渊的龙,终将报复村庄。分贝大于滚雷的机器轰鸣,储水大于雨量的汪洋覆盖,孤井一样的村庄,将被大水淹没,遭受没顶之灾。
其实灾难来临之前,人们已经陆续搬离这个时旱时涝的村庄。尽管在历史上曾经富庶,曾经护佑众生,但现在不再是能够安享丰收和睡眠的乐园,它阴晴不定,洗劫大于给予。人们不得不叹着气,离开。
庄稼一样根植乡土的人们,有人可以清晰地追溯来源,有人已说不清是几代之前移居此地,他们陆续搬离。山脊之间,他们像被河流冲刷的垃圾那样沿途漂荡、堆叠、淤积,在随波逐流的两岸,在贫瘠而孤零的角落,就这样存活并沤烂自己的光阴与骨骸。对老人来说,哪里能让他们终身安详待在自己的世界里,哪里就是天堂。如今,雨水冲刷蚁穴,就像宗教中象征惩罚与审判的洪水席卷他们安睡的床,老者能否与这场变故中满怀憧憬的壮年人一起,在方舟上获得未来?大地苍茫,他们不知所终。
走,背井离乡,带着捆绑的条箱,带着跋山涉水的鞋,带着五味杂陈的盐罐,他们走……除了少年起就渐渐沉淀在血液里的口音,还有什么在旅程中跟随而不丢失?有人搬到川贵一带的西南地区,需要习惯当地人普遍的辣食,火热的肠胃烧灼,种种不适就像储存在内脏里的乡愁。有人搬家的时候,带走了锅碗瓢盆,也挖走祖坟旁的一棵小树,以及它密集根系里像手指关节一样握牢的土。长辈的骨灰,早已溶解在土壤里。离开乡音,流放到不解其意的陌生方言里,沉睡的祖先能否继续往昔的护佑?
据说搬离前夜,有个七十多岁的孤寡者喝了有机磷农药,气味浓烈的毒一寸又一寸烧穿他的食道和脏器里的黏膜,他剧烈扭曲的五官上沾着自己呕吐的白沫。他本应了无挂碍,移动身躯等同搬运全部的家当,为什么还要以命相守?什么样的花开花谢,什么样的动物生育或腐烂,什么样的春秋和冷暖,值得如此陪葬?他目睹洪水汹涌,淹没他的整个江山。
离开的,再也回不来了。大水淹没他们的稻田、屋舍、道路,淹没他们生锈的农具、走失的牲畜、沉重的磨盘和年迈的果树,淹没他们往事里的狂喜与羞耻。走啊走,像野外降生的羊羔,刚刚脱落胎盘,就得迈动虚弱的腿,走向远方未知的凶险……皮毛上沾着的母亲湿漉漉的体液很快就会风干,很快,就会,忘记子宫里的味道。
多少年以后,她会想念这个村庄吗?想念它古怪的读音,想念春天时漫山遍野的伞状花序,想念那些腼腆又好奇的脸?也许记忆短暂,会沉入河床深深的淤泥之中,像那些远离者所丧失的。毕竟,这里不是她的籍贯和家园,她只是路人。
外婆不动声色地刺绣,沉浸在她一针一线的缝纫之中;她自己衔了半根酢浆草,幼嫩的茎,流出细而弱酸的味道……外婆和她,两个人之间,是真空似的安静。
惊心动魄的瞬间,即将到来。
她感到微凉的风,沿着低低的地面吹拂,似乎暴雨来临之前。甚至不是风,只是隐约的气息。抬起头,在涌动并缓慢下沉的云层之间,出现了移动着的斑点。斑点灰扑扑的,既不华丽也不精湛,看似无序,显得寥落和凌乱,仿佛翻卷的秋天落叶。起初她对自己的发现并无惊讶,继续漫不经心咬酢浆草,舌尖触到披针形的萼片。
慢慢地,她看清了编队飞行的天使。雁阵拉开优美的弓形,准备穿越前方蕴蓄风雷的云层。鸟群组成一个打开的斜角,那个阵形的图案,本身,就像一只鼓翼翱翔的飞鸟……如同每片树叶以模仿的方式纪念整棵大树,每只大雁都成为巨翅鸟的一部分。这是迁徙,这是季节性的朝圣——深埋地下的磁力,指引着候鸟内心的指南针,由此形成这个世界伟大的节律与钟摆。
她没有呼唤外婆,外婆依然感受到传递过来的某种震撼,让她的视线暂时离开刺绣的绷架。她发不出任何音节,突然变成一个哑孩子。她只是目不转睛地仰视,并沉默地伸出手臂,向上指引。她指着神秘而空阔的天际。那个瞬间,鸟群并非排列为“一”“大”或“之”那类的简单字谜,而是,组成一个神秘的星座。
她不知道大雁来自什么方向,也不知道它们将抵达哪里,然而就这样看大雁飞过,她内心燃起去远方漫游的渴望。等高空的雁阵远去,她才辨识出,笔画就是一个“人”字。也许一直如此,队形从未改变,只是当她尽力仰头,盯牢无垠的浅灰色中有限的深灰色,对这种奇怪角度的不适和缺氧感,使她眼中的天空多少有些虚幻,使她就像通过火焰上方颤动的气流去观察一样。鸟群就那样,在她的仰望和渴望之上飞翔,以至她在突如其来的慌张与激情中,丧失判断。
那个由翅膀组成的“人”,辐射出强烈的磁力,对她构成难以言喻的神圣的感召。她一动不动地驻足,不能飞,也不能歌唱,她体验着被弃的悲哀。那个奇迹过后,她比同龄的孩子都老了,因为尚还年幼的心脏已体验到无望。
尽管迁徙鸟群只有数十只大雁组成,很快就消失了,但对她来说,那场景依然称得上激动人心,史诗般的壮丽。成年以后,她偶尔重复地抬头仰望,天是空的……童年所目睹的迁徙场面,无声,却在记忆里轰鸣。外婆和自己就像两个濒于绝境的溺水者,仰头,看到穿透海面的万丈光芒。此后,迁徙鸟群成为她的梦境。金色的翅膀形成遮天蔽日的云层,如浪涌,翻滚、回旋、升腾……即使在梦中,她也感到醉氧似的晕眩。
1983年,江苏
迁飞的鸟,将整个内陆湖区域视作越冬地。
越来越多的翅膀。太多了,在湖面,在滩涂,在岸上的灌木丛里。它们不珍惜地到处停落,像地上轻易生长的块茎植物那么繁密。候鸟多得不像话。她想,这句话的意思是:多得,不像神话。
她在湖面捡拾到第一根飞羽的时候,觉得礼物来自天堂。羽枝排列极其精密,翎管像可食用的糯米糖纸那样,是乌蒙蒙的浅灰色。后来她捡到各种羽毛。冠羽。肩羽。尾羽。饰羽。绒羽。就像毛衣上脱落的线头那么平凡,让她有一丝平静中的惋惜。北方人见到燕子就知道春天来了,在这个南方省份,候鸟来的时候,最冷,沿着湖面漫延过来的寒意,穿透她毛衣上细小的缝隙。
湖区位于长江中下游地区,丰富支流灌溉着稻田,也盛产鱼虾。这里不临海,来自远方的鸥鸟也来越冬。鸥鸟像充气玩具似的,忽略体重地漂在水面。不会溺死的鸟,它们会飞、会走、会游,无所不能。它们与别的鸟类不同,恋爱主动方通常是雌鸥,它们在雄鸥身边娇娇滴滴、哼哼唧唧,亲昵地挨挨碰碰,不断对着雄性的下喙轻啄。起初,雄鸥拒绝,但雌鸥仍然纠缠,不断发出邀请,直到雄鸥屈从共度蜜月。
她见识过鸥鸟另外的面孔。湖区有个鱼摊,店家用利刀刮鳞掏腹,赤红的鳃、乳白的鳔、灰的胃、黄的肠、黑的胆囊,间杂古怪的铜绿与疳紫……大堆被扔掉的鱼内脏,湿腥地摊开。鸥鸟狂喜而来,又带着狂怒抢夺。它们一边争食,抢掠破碎的脏器;一边凄厉尖叫着相互打斗,冻疮色的脚蹼踩着地上脏黏的暗血。一截鱼肠被鸥鸟的利喙扯到细绳状,直至断开。当饱食的鸥鸟轻盈飞舞,或者一动不动,眯起仿佛陷入冥想的眼睛……她知道,优美背后,隐藏秘密的残忍与不堪。
星期二下午学校没课。她来湖边看鸟,有时安阿飘陪她一起来。安阿飘比她大几个月,个子高出半头,几乎是她唯一的朋友。不过,她安静,安静到几乎不需要朋友的地步。
这个习惯从童年和外婆在一起生活的时候就养成了。她们之间,呼吸得比针尖刺破织物的声音还轻,老少就像一对聋哑人那么相处;不,比聋哑人还安静,她们之间没有手势。那是恬静而美好的时光,她的内心就像映出飞鸟的湖。她天生早熟,在童年就拥有沧桑者的安宁。她和外婆在一起的每一天,都地老天荒、梦稳心安。
直到,外婆离世。好时光结束了。她被转移到亲戚家,继续漂泊。
她跟父母见面的机会有限,需要说服自己,说服自己相信她是父母的孩子——这是作为知识,而不是作为常识被她接受的。自从转学到这个省份,她暂时寄宿,半年没见过父母。他们在比候鸟还远的远方,未必守信地归来。她刚刚度过自己的十四岁生日,安静的、独自的、无人知晓和庆祝的生日。她习惯独自消化面临的一切。
安阿飘无所事事地用圆珠笔画圈,无意义的旋转曲线。画着画着,笔不出水了。安阿飘脾气急躁,她握牢涩住的圆珠笔,运刀那样在纸上用力地划来划去。不行。安阿飘把圆珠笔一端探进半张的嘴里,天冷似的呵气。将就着,安阿飘终于画出一只简笔的鸟。
记得和安阿飘一起去果园,她俩专门找那种树下落果多的,说明果子大多成熟,果柄与枝条之间已经松动,不会超过扭动一颗纽扣的力量,果实就落在她们采摘的掌心。她看到安阿飘衬衫上的纽扣松脱,像熟透的果柄。她生涩,不如安阿飘散发水果初熟的微甜。她知道她是一枚被虫子啃过的坏果子。安阿飘有着走起来会跳舞的头发……阿飘也会遭遇同样的事情吗?她无法启齿,只好转眼看鸥鸟的白羽毛,凿子般鲜红、锋利、纷纷的嘴。
……那天,黄昏之后才应聚拢的寒气提前到来。南方的凉冬,她系上外衣顶端的扣子,毛呢织物的微刺,让脖子不舒服。她往回走,才发现自己的短头发在枕骨上方打了结,用手指怎么也通不开。两只手交叠在后脑勺,左手抓住那缕头发,右手的拇指和食指夹紧,生生地,把那个讨厌的发结整个撕扯下来。发结中间的死疙瘩非常紧,成了硬结,周围长短不一的头丝呈放射状散开,就像一枚黑色蒲公英。
几个小时前,她的后脑勺在床单上剧烈地磨砺,甚至让肘后出现两块粗糙生涩的区域。除了皮肤摩擦,还有内伤。她像脊索发炎的鱼,又仿佛身体里横穿一把剑,开刃的血槽把她穿透了。
她那时以为三十五岁以上的前辈都老了,老到足够庄严。成年以后她回想起来,那个叔辈当年四十多岁。往事中的人在她的回忆里继续生长,外婆长成神灵的样子,那个叔叔长成幽灵的样子。关于那件事,她做过几次梦。微笑的邻居叔叔,暴露他隐藏在剑鞘之后赤红的凶器。叔叔像个凶狠的打铁人,遭受锻打的,是没有反抗的她自己。梦里的铁匠带着强烈口臭,用老年的猥琐,释放他不能平息的情欲。她惊悸醒来,睁开眼睛,就从那条半梦半醒的裂隙之间跌回真实的十四岁。叔叔富有操作经验,却无法自由滑动,因为她太青涩;所以他只能像慢蛇一样,以摩擦前行。他身体前行的每一步,都是她每一公分的黑暗。
坚硬而对称的壳里,柔软中的疼不止不息。她无动于衷,不会对谁哭诉,保持贝壳的守口如瓶。离开之前,老叔叔把嘴印到她的额头上。他的嘴,鸟喙那么硬。她的十四岁已经有了不能说的秘密,并且被封存,上面盖着一个沾了唾液的死印。对老叔叔来说,那或许是近似小钱的吻;对她来说,这笔小额的债,不知为此要背负多久的利息。
十四岁的她缩在小床上,遭遇此生第一次失眠。躬起身子的虾,貌似披坚执锐,她的肉体其实是一团黏稠的胶状物,寒硬。那个夜晚,像一只倒扣下来的钟,沉得窒息;她是隐匿其中的钟舌,几乎不呼吸,她只要一动不动,世界就停在喧响之前的一刻。
就在肋拱的底端,下陷的腹部侧缘,她的胃灼痛。她没吃晚饭,只咬了几口冷水果。她尝试,消化胃里不适的食物和疼痛。鸟类有两个胃。第一胃,也就是前胃里,化学酶非常强烈,腺体能将食物粉碎,甚至溶解猎物的骨骼。第二胃,又称为室胃,人们更常用它通俗形象的名称——砂囊。它是复杂的研磨肌,起到“牙齿”的功能,砂囊内鸟类吞食的石英砂等粗颗粒,能将钢针和胡桃壳磨成糊状。她必须让自己相信,之所以胃疼,是因为她的肚子里有牙。
有些雀类咬碎种子,它们的喙能够产生四五十公斤的压力,这对于体重只有几十克的小鸟来说非比寻常。为了减轻重量,鸟类的牙齿退化,靠强烈的化学物质来腐蚀、加工食物。只有刚出生的幼鸟具备卵齿,在喙尖突出的位置,啄破蛋壳后自动脱落。那就咬吧,咬破关在蛋壳里的自己。假设雏鸟没有及时见光,它就被彻底封死在黑暗里——它将永远紧闭青紫色眼睑下的世界,带着汗湿的永远不会为飞翔而振动的翅膀。她对自己说,没关系,她什么都能吃下去,什么都能消化。
类似的事发生数次,邻居叔叔叮嘱:谁也不能说。
她没说,无论是对亲戚,还是唯一的朋友安阿飘。猫头鹰把消化后不能吸收的皮毛骨头等杂质,混成团状呕吐出去。她不能,与自己草食动物的属性一样,她能够反刍却不能把它们当作唾余,扔到远离自己的地方。那些羞耻与恐惧,她的一生或许都会如此:难以消化,也难以启齿。
她早晚会鸟一样远远飞走,邻居叔叔猎隼般锋利的钩爪再也不会握牢自己柴枝般的手腕。十四岁的冬天,她瘦得就像只大鸟的骨架。鸟类的骨骼中空,以减轻重量飞行。她知道在远方,军舰鸟的翼展宽阔,这种海鸟的骨架竟比它的羽毛还轻。鸟骨充满气体的腔隙,形成蜂窝状;中间坚硬的骨柱,使鸟骨既轻巧又坚固。她想自己一旦飞走,再也不会回来。
失眠之夜,她看夜空。她看不到童年曾目睹的迁飞鸟群。但她通过科普书的阅读,得知许多鸣禽白天进食和休息,选择凉爽的夜晚飞行。夜幕中很难观察到鸟群,只能偶尔听见啁啾之声。当它们掠过月亮,才能被看到。事实上,观察月亮是统计鸟类迁徙的方法。手持望远镜,怀着持久耐心,你一定会看到候鸟掠过的翅膀。中等倍数的望远镜,也会显示足够的细节。
鸟群流星般,滑过幽寂的天空。远远高悬于头顶的,是天鹅、燕鸥、斑头雁和绿头鸭映射寒星的瞳孔,是它们小提琴般伸长的脖颈,是迎风呼啸的翅膀……洋流般,有力而汹涌。即使迁徙对劫掠者来说,意味着铺张而尽欢的宴席。所谓盛宴,由华丽与牺牲构成。猛禽占领路线上的重要位置,开始暴徒的嗜血生涯。它们微驼,含胸,淡漠凶悍,生冷不忌。在天空盘旋,它们拥有魔鬼的自信,随时撕碎猎物的胸羽和心脏。然而,密布的暴力之上,是更大的不可遏止的美。神从不省俭。星空的珠宝盒已逾出奢华的形容,抵达无限。亿万颗组成的星团,呈螺旋形;远渡千山的候鸟就在螺旋形的气流中,缓慢而完美地,旋飞。
1996年,北京
北京人喜欢养鸽子。她记得自己刚刚从江苏返回那年,每天都能听到鸽哨,看到一个男人舞动木棍上的红布条,指挥和部署他在天空的鸽子。
有只鸽子总是落单,在窗外的平台停落,似乎是专门来窥视她的。它有着晶簇般狡猾的眼睛,以及脖颈上贝母般隐约的晕彩。雨水在凹槽里聚积,鸽子一小口、一小口地喝,频繁低头,又抬起,脖子一梗一梗,微微抖动喉部。涟漪荡开,鸽子的喙落在一组荡开的同心圆的靶心。鸽子东张西望,中途,像被自己的倒影吓着,乍了两下翅膀。它的脚和尾巴末端,都浸在极浅的铅灰色水洼里,像海绵吸收混浊的液体。有时,鸽子不知用剩下的时间做点什么,左腿紧收在腹部,就这么不可思议像截肢者似的呆立。很长时间过后,它才醒悟似的飞走,影子像块飞快擦过的桌布。鸽子紧张而局促,被追赶似的抖动神经质的翅膀,看不见了。
回到北京,回到自己的出生地,她用了十五年的时光绕了一个圈。她的记忆里除了那个安静的山谷,那个泥泞的小城,还增添了有轨电车、空旷的天安门广场和北海绿荫中的白塔。她靠着院门的抱鼓石,听胡同里的小孩子安安静静唱那首童谣:“小燕子,穿花衣,年年岁岁来这里。”无人的时候,她也悄悄唱过几句,胸腔里发出的声音令她陌生而沮丧。她正式回家,是因为,要逃离黑暗。因为她银器一样干净的脸,正在时间中黯淡。
她曾独自承受羞耻——叔叔的犁,数次开垦在她身体荒凉而坚硬的冻原上。她感到恐惧,仿佛听到蛇的密语。如果她是蛇的敌人,将成为毒液下的牺牲品;如果她成为蛇的朋友,将被驱逐出上帝的乐园。她不知道怎么办。
据说,红头美洲鹫的嗅觉十分灵敏,可察觉腐肉中散发的臭气。工程师假如在输气管道中放入一种叫乙硫醇的化学物质,很快就能在它们盘旋的地方发现渗漏。安阿飘的妈妈就有这样一双猛禽的眼睛,以及辨别不洁气味的嗅觉——她查究出了情况,使之不再是秘密。
如果秘密只是秘密,谈不上羞耻,除非它被公布和放大。不伦的性侵或者苟且,这个消息很快扩散。没有什么法律惩罚降落到叔叔那里,但她,再也洗不干净了,败在自己的脏身体和坏名声里。没有外婆和父母的庇护,她只有独自面对比童年时更大的洪水,渐渐困陷沼泽,方舟也不能救援,因为她已身置泥泞,无法划开桨叶。她不是飞鸟,不是。只有鸟,能够从灾难中逃生,它的翅膀就是自己的方舟。
与其说她是为了躲避丑闻,不如说,她是作为丑闻回到北京的。父母痛悔于自己的失责,甚至调换工作,把她接回北京,为了让她得以陌生者的面孔开始新生。她得学会幼雁那样的逃生。为了避开天敌,白颊黑雁在峭壁上产卵,筑巢地点高于地面200米。出生几天的幼雁就要主动从悬崖跳落,它必须用柔软的腹部着地才能不摔断脖颈,必须用稚嫩的蹼足迅速穿过危险的岩滩,才能到达河边的庇护所。她必须从不堪往事中陡峭地下降,尽快把自己藏匿起来。她隐蔽来路,像一只蓄意忘记故乡的候鸟。
刚回来的时候,她不出门,跟父母也不交流。传播中的丑闻,使她成为一个自我价值遭到贬低的少女。奇怪,她觉得被父母知晓比起这件事情本身,更让她觉得丑陋。生疏的父母对她来说,既是遗弃者,又是拯救者。然而,她不再是孩子。她懂,如同叔叔对她的摩擦和开掘,父母同样苟且,自己的生命正是来自于这种苟且。作为成人,父母使用自己的身体。无损尊严,不必抱愧。她呢,洗澡都不看自己,像盲人处理自己的甚至感觉是别人的四肢。梳头她也不照镜子,不看自己的脸。该剪头发了,现在长度尴尬,放下来嫌长,梳起来嫌短,可她不愿出门。得用满头卡子,才能管住那些像漫画人物头顶光芒那样朝着四面八方生长的碎头发。狠狠地,她用皮筋把头皮和头发勒紧,眼梢都吊起来——京剧演员那样的眼梢,活像风流树下的桃花鬼吧?勒得太紧,她额头附近生疼,疼得梳好头发又马上摘下那些卡子……一根一根地取出头发里的细铁丝,像从一个针垫上拔针。她应该承受日常的警示和惩罚。其实,只要还处于父母保护的羽翼之下,她就没有真正摆脱自己的羞耻。
那个侦探似的鸽子,每天嘀嘀咕咕地来访,直到她习惯它的监视。她不喜欢鸽子。如果从归航意义来说,鸽子是行程最短的迁徙者;短得,更像是真正迁徙的模仿和反讽。鸽子偶尔远航,只是炫技,并非出自内心渴望——鸽子更多体现出留鸟的自得。鸽子仓皇,她不喜欢那种凄厉的啸音、警笛般的哨声。以前在湖北,她想等回北京就解脱了;现实并非预想,她没觉得有什么不好,也没觉得有什么好。多少人心怀梦想,终其一生,不过在小半径里盘旋,模仿着迁徙,不过鸽子的命运。鸽子在图片上象征美好与和平,可如果你从高处观察广场上停落的鸽子,灰的白的……就像有谁倒了碗剩饭,一副不堪的庸相。
餐厅,脆皮乳鸽。死去的小鸽子,焦糖色地跪在盘子里,散发金黄的色泽,和隐藏在肉香里的腥味。或许,这就是她的形象:发光的青春肉体,以及该死的命。她用牙齿撕咬年幼而熟透的那些肉,把它们啃得干干净净。她看着盘子里的骨头残骸。合成V形的锁骨卡在胸骨上,形成鸟类特有的“叉骨”结构。鸟的锁骨所占比例要比人大多了,而且越是擅长飞翔的鸟类,锁骨越发达。经过长期舞蹈训练的姑娘,都会拥有优雅的平行锁骨,她们再轻盈也不会飞。她的锁骨不好看,相比之下更近V形,可她不仅不会飞,走起来都踉跄,甚至需要停顿下来掩饰自己的匍匐。她拿起高耸的片状骨:这个沿胸骨中线的突起称为龙骨,固定着对于起飞来说至关重要的胸肌。龙骨显著、突兀、坚硬,状若袖珍的斧刃——原来,鸟类和她,都在自己体内埋了利器。
她用了很久来拆除体内的引爆器。有时候,她觉得把引擎也拆了,自己活得就像一具整洁漂亮的尸体。由令人恶心的蠕虫变出来的蛹,一动不动,被时间捆绑着,全身勒痕。昆虫从幼体到成虫,不仅体积变化,重点是要长出翅膀。她,无法长出可以飞的工具。后来她迷上了夜跑。飞翔,双脚离地……唯有奔跑与飞翔相似。无数次,她飞也似的奔跑,像逃命的姿态——似乎大地有根,有垂直向上的箭镞。
漫长而艰难的消化,使她爱起来相对困难。她比别人付出更多,才能接受一个有温度的嘴唇和一个有重量的胸膛。爱催生了自卑,她甚至怀疑和自暴自弃。后来她交付了自己,因为难以忍受情感的压力。爱情就像体内的叶绿素,没有它,她无法完成光合作用,无法生成自己的氧和枝叶……这意味着,所有闪光的东西将对她失去意义。而她愿意熄灭所有的光,让他的黑暗主宰,让一切,如夜晚盛纳万物。躺下,用她身体的缺陷迎接陌生之物和未来。当他试图用自己的钥匙,打开她习惯紧闭的锁孔,独特的撬动使她发出呻吟,就像锁孔里发出微弱扭动的咔嗒声。打开了,她的身体以及其中闭锁的秘密。她记得在他的鼻息下自己发丝的颤动,记得自己发出幼鸟一样尖声而变形的鸣叫。华丽之鸟,羽毛闪烁着矿物质般不可思议的鳞彩,相互哺喂,将喙置于对方的深喉……浑身频颤,有如交配。他喂她爱情的粮食。
直到图穷匕首现。
丘比特让人中箭,哪有不流血的道理。什么是感情?不过是浪费的时间里,说过的那些废话,干过的那些蠢事——那些无能为力又享乐其中的沉陷。等时过境迁,谈起所谓旧情,多少人敷衍地感叹,它还会被谁认真地怀念?“爱”,这个字,有时近似荒谬的修辞。可她,就是无以解脱,震惊于意外的结局。她在自己的迷宫中,在看不见的深处,连枝带蔓地疼。
疼,作为遗产保留了下来。当她躺上羞耻之床,再次分开蚌壳般闭合的部分……听任探测者打开光线,照射秘密的溶洞。她打开体内的墓穴,迎接崭新的死者。通过流产手术,她成功杀死自己的孩子。在一棵核桃树下埋葬了胚胎,她发出指甲般尖利的哭声。她只哭过一次。沙漠是枯死的涟漪,她的眼神如雾如烬,那不过是爱情最后的骨灰。
北京成为新的伤心之地。之后,她极端而决绝地处理了自己,远赴他乡。因为他在北京,这里就不再有她的立锥之地。
月亮啊月亮,就像一只放旧了的地球仪,她要跟随自己笨拙转动的手指飞到人们看不见的背面。无论彼岸有什么。留下萧索的掠食者和它们饥饿的肠胃,她要飞远,哪怕远方埋伏敌人。
2005年,加拿大
她喜欢鸟群迁徙的纪录片。鸟群移动,飞在天上的魔法织毯。缤纷而辽阔的大地图景,收拢在鸟类的俯视里。斑头雁飞越缺氧的高寒地带,飞越喜马拉雅的雪峰之巅。雁阵拍打翅膀所产生的气流,可以托起队尾的末雁,即使它气力弱,也能在集体帮助下抵达目的地。黑雨燕不知疲倦,离开鸟巢前往非洲,然后折返欧洲,它两年不曾驻足,饮食、睡眠和交配,全部在途中进行。
她还喜欢阅读科普读物。中文的。她的英语水平足以处理日常,不够应对术语。她从一本中文鸟类图谱上读到震惊的内容:如果自身的燃料不足,鹬会在飞行中自残,食用自己的肌肉甚至内脏,以求抵达繁殖地。从常识上判断,她认为这不可能,怀疑是译者之误。从另一本书上找到的说法更可信,佐证鹬鸟的魔术如何施展:长途迁徙之前,它们大量进食,体重倍增,样貌并不发生变化,因为它们可以通过挤压内脏的办法来腾出空间储存脂肪。看来内脏体积的减小,是因挤压而非食用。不到二十年的寿命里,这种鸟的飞行距离相当于从地球到月球。它们不停,飞翔如同呼吸。
鸟类里,她有点怕信天翁。
信天翁天使般宽阔到失衡、舒展到平衡的翅膀,体现着波澜壮阔的美,以及不能被阻挡的狂野自由。年幼的信天翁会用三年时间飞越大海,不着陆。飞行中的肌肉日益强健,硬得仿佛是骨骼的构成部分。有个新西兰的留学生,曾经送她礼物:一只木雕信天翁,可能出自旅游纪念品商店。信天翁本身就是一种最像木偶的鸟,脸像木头雕刻的,还有浅肉红的嘴,以及苍白的脸上一双不会转动的眼珠。信天翁模样简单,表情硬邦邦的,或者说就没表情。尽管信天翁的翼展能像三折伞那样便携地收起,她仍把它视作僵硬之躯。
这些不是理由。她怕信天翁是到加拿大以后的事。因为名字的巧合:信天。
作为师哥的信天与她大学时就认识,在温哥华重逢。信天是个书呆子,绰号信天翁,长得就像信天翁那么木呆呆的,也像信天翁那么勤奋刻苦。读书时候,他住在图书馆,几乎不需要宿舍里的睡眠。信天一直是受苦的命,但这份苦,使他越飞越远。他没想到,自己远到不能张开和收拢他的翅膀。他抱有知识分子的偏执,遭遇数次不公待遇,他历尽周折,破釜沉舟,斩断所有退路,毅然移民北美大陆,发誓不让孩子重复自己的挫折。他的女儿,必须拥有美丽且自由的未来。
为了孩子。他忍受不了中国的教育,“不要跟陌生人说话”,这样的声音,在家庭,在候车室,在学校的辅助教材,堂而皇之地出现,大家习以为常,几乎当作行为典范。“不要跟陌生人说话”,这是我们从孩子就开始的教育失败。我们太精明了,话说得那么明白,那么透。透心凉的透。他要让自己的女儿获得保障一生的温情。许多人像信天一样,因为财富、雄心、恩怨、灾难等各种原因,他们放弃乡土和祖国,选择移民,前往梦境中的理想国——他们把那里认作精神意义的故乡和理想意义的彼岸。
刚移民时,信天孜孜不倦地对亲戚介绍温哥华的空气、食物、自然环境和人文环境,他有着原住民似的骄傲感,不在意自己正激起听者秘密而强烈的反感。可惜,他后来没有获得天堂般的日子,过得不好。信天没有找到适合的工作,失业数年,被迫放弃专业,从事他并不喜欢的体力劳作:餐馆侍者,车衣,从事超市仓储或收银。
她理解信天,来加拿大时,她也经历过不容易,连成为合格侍者都难。她记恨那个台湾常客,餐桌上永远只要一碗汤,而她渴望小费。她自己不会到外面用餐,去超市她只买最平常的食物,不敢尝试最安全的冒险。色彩斑驳的豆子,长得奇怪的朝鲜蓟,易拉罐里气味汹涌的饮料,她猜不出它们的味道;后来,连好奇心也失去了。她只吃最基础的食物,选择最廉价的品种。
物质上的紧张出自现实压迫,但也不全是,深层原因是:心理上没有安全感。她并非受洗的教徒,但专门去过几次教堂,希望求得宁静与安慰。需要深仰,才能看清教堂穹顶那些悬在高处的灯盏。人们需要形而上的指引,否则自重就令人沉陷。她为什么喜欢飞鸟?因为它们用自己的翅膀钉住天空,保持人类仰望的高度;假如失去天堂,我们的世界不会成为替代的天堂,而是被坠塌下来的天堂,直接,压进地狱。
她后来没有再和众人一起祈祷。一方面,因为宿命。她觉得要上帝均匀地溺爱每一个人,本来就是对神的苛责,相当于要上帝管理的每一滴雨水都落点清洁……有些雨注定要落到花瓣上,有些雨注定要落到泥浆里。另一方面,她发现,有些教徒来到华人教区,并非出自信仰的需要。貌似虔诚,他们不忽略任何一次礼拜,但对教义的理解却模糊、陌生,乃至兴趣寥寥。这些华人移民在教堂聚合,是体面、快捷又功利的社交手段,他们希望从彼此那里获得一些嫁接当地生活的便利。当什么也抓不住的时候,同胞的黄土肤色,变成了彼此的乡土颜色——其实这种来自母语的安慰,不过是停留在语感和语气助词的安慰。每个人都在自己的困境里,孤立无援地作战。
经过努力,加上运气,她的处境得以好转,就像抵达终点的候鸟生活在迥异从前的环境里。信天呢,没有抽中命运的彩票。他预感自己将成为科学家,没想到,沦落到不需要头脑,手脚却不歇息的劳碌里。在温哥华,人到中年的他甚至不能获得沉稳的夜晚,失眠严重。当初信天移民的信念,是为孩子。他后来一无所有。关系疏离,离婚后的信天与妻女联系极少。
她和境遇困窘的师哥见面,请信天喝了一杯咖啡。看不出什么异常,他照样是信天翁那样缺乏表情变化的脸。提及妻女,信天并不避讳和难过,仿佛适应了孤寂。她喝了一口拿铁,看着咖啡上奶泡拉花的图案,不是树叶或卡通心,更像一个轻微不对称的臀部。这就是变形的享乐。她对信天,觉出无话可说的尴尬,她想:我们都有铁打的心肠、纸糊的自尊。
没想到,那是最后一次见面。数月之后,信天给自己买最贵的机票,飞往度假胜地。回来以后,他自杀了。他从高楼跃下,完成叹号一样的死亡。像希腊神话中的伊卡洛斯,飞得太高,蜡翼融化,他从靠近太阳的地方坠入冰冷的深海。
她看到新西兰皇家信天翁中心的纪录片时,感到头皮发麻。那是令人密集恐惧症发作的奥塔哥半岛,草坡、悬崖、游客的汽车以及供他们短暂停留的椅子上,到处是海鸥,身影、叫声、羽毛以及粪便。下一个镜头,是信天翁,孤傲远飞的信天翁。她回忆起死去的信天,这个名字,象征宿命的绰号、就范的命运。这部纪录片在数日之后给予她一个怪异的梦。大量的死鸟从天而降,没有一只砸中她,她就像毒后,穿着猩红的衣服。她辛酸地看着那些羽翼巨大的鸟,它们曾高飞的翅膀上端拱起宽钝的角……现在遍地鸟尸,她站在一堆弯折而破旧的伞骨之间。
信天死了。信仰的灯塔照耀,他向着光源走在触礁的路上。他走了那么远,飞了那么远,被拖行了那么远。如果说迁徙,是壮丽而不倦的朝圣队伍……在这个队伍中,有些,将成为献祭。除了事先到安息之所默默离开的鸟,也有鸟只死于飞行途中。飞着飞着,就垂直掉下来,像从天堂里扔下一块诅咒的石头。这个世界,无处不牢笼,黑暗天花板上的星星满含锈迹。死去的鸟,没有飞进它的自由。
据说,信天的骨灰是装在一个饼干筒里偷偷运回国的。他的母亲,不忍儿子装在托运箱里被忽略、被检查、被惊扰,坚持把他放入随手的行李。变成骨灰的他这么轻,信天离开世界的时候比他来到的时候还轻,似乎通过此生,他还回了什么欠下的东西。但愿信天在曲奇饼的奶油香里,能获得一个平生难得的珍贵睡眠。
至死也没有得到女儿的安慰与怀念。信天把自己千难万险地运抵死亡之地,像千百万溯游鲑鱼中的一条。他的女儿由此更换母语和信仰——习惯黄油、面包和牛排,热衷跑步,让粗砾般的阳光把自己晒成麦色,给予陌生人善意,成年以后远离父母。许多移民当初都是为了孩子,为了这些不再与他们相认的孩子。为了下一代,牺牲自己——这是鲑鱼的命运。
鲑鱼有着炯亮却愚痴的眼睛,季节一到,它们在各自家乡的河口聚集,溯游而上,寻找童年铺满沙粒的河床。体内的脊索就像一根颤动的磁针,校正它的磁极和方向。倔强的鲑鱼不断摆动鱼尾,直立起来跳跃,像水中的芭蕾舞者,不断从湍流和瀑布中跃起。经游浅滩时,水面可以看到它们宽阔的背脊,以及马达般有力击打的尾迹。为了抵达繁殖地,鲑鱼经历急流险滩,经历一路的牺牲。沿途布满猎食者,水里的,天空的,甚至还有陆地上的熊。雾气弥漫的早晨它们就来了,悬垂的水滴和升腾的热量从熊粗糙的毛丛里散发出来。可以说熊是个粗暴的食客,也可以说它是个精细的挑剔者——熊喜欢浪费,它撕下并享用湿亮的鱼皮,剩留大量鱼肉。被剥了皮、肢体也残缺的鲑鱼仍然活着,受尽折磨才允许去死。微弱而细小的水流,从鲑鱼闪耀的鳃盖里渗出,暖杏色的肉体暴露,像树木有着涡流状的年轮,记录它们渡过的江河湖海。
能够抵达洄游终点的,都是幸存者。
雌雄排卵排精的瞬间,彼此大张布满刺齿的嘴,在高潮中排出发亮的卵粒和精虫。胶囊一样的受精卵粒,是鲑鱼遗留在世的珠宝。为了这些致命的珠宝,它们耗尽最后的气力。矿物石英般闪光的大鱼,产卵后老化得非常厉害,甚至活着的时候就开始腐烂,沉入同样脱落鳞斑的陆续死去的尸堆。
她到北温区的鲑鱼繁殖中心,目睹艰难迁徙之后的死。自从克里夫兰水坝修筑起来,鲑鱼无法越过大坝抵达产卵地。鲑鱼繁殖中心,所谓更好地养育下一代,意味着这一代鲑鱼更悲剧的死。千难万险洄游的鲑鱼,甚至得不到腐烂中静悄悄的死。人类摧毁鲑鱼原本就谈不上美好的蜜月,“生殖工厂”取代了它们临终的身体狂欢。
人们用肘部夹住婚鱼隆起的额头,一只手固定鱼身,另一只手沿腹腔推挤,混合血色的精浆从泄殖腔里排出。对雄鱼不算粗暴,人们直接用利器剖开雌鱼的腹腔,长长一刀,几乎从下巴滑到尾巴……大团晶莹的卵粒,就像卡车卸货一样从腹切口里滑落出来。戴着橡胶手套的工人,搅动肉馅般搅动盆子里的精卵,完成速效的交配和受孕。粗粝带血的暴力婚配,不需要调情和审美,不需要它们婚礼的彩虹体色,不需要肢体的颤抖和悸动。鲑鱼在自然状态,受精卵成活率低,人工可以把生存概率调到九成。幼鱼将在水池,或者塑胶袋和聚氯乙烯的管道里,度过自己作为产品的童年。鲑鱼在繁殖中心产卵,提供人类愿意看到的节目。实际上,鲑鱼被改变了家族的遗训、旅行的终点、告别的墓地……死亡的时间提前,鲑鱼死于尽头之前的自己。
庄子写鲲鹏,是由大鱼变成的巨鸟……鸟是游在天上的鱼,鱼是游在水里的鸟。骨灰已运回故乡,信天算不算一只归心似箭的鸟、一条叶落归根的鱼?他移民,斩断退路,横刀一命,只为自己看不到的未来;他挣扎,放弃希望,横刀一命,只为自己不再看到未来。他的血,不能改变太平洋的咸度,就像候鸟的翅膀无法改变风向。
2014年,北京
服务员戴着尖顶软质的红帽子,步履弹跳,为她端过一套简餐。圣诞节,商场底层的茶餐厅里,重复播放圣诞欢歌。落地窗上,挂的雪花装饰物,直径达至一米,这些由毛织物构成的六角形,边缘缀着银丝绒,逼真模仿出晶状物上的寒霜。食客脚下堆积着大大小小的购物袋,空气里飘浮着即时酿制的人造欢乐……像啤酒模具那样有着永不破灭的泡沫。在东方和西方,在北京和温哥华,圣诞节变得一样热烈。不过,此时的圣诞节,蜕变为盛大的商业促销机会,无处不弥散着欢快的钱味儿,似乎信仰也能变成一本万利的生意经。
她在北京逃避过年少时期的黑暗,在北京忍受初恋的惊心动魄与万念俱灰,在北京读书和工作,但她从来没有对北京产生故乡的情怀。不过,哪里又让她有过归宿感呢?和外婆共同生活过的村庄,那个留下耻辱的小城,还是鲑鱼巡游的异域他乡?她和地理意义的联系微弱,不生根的,童年、青春期和成长期都在流浪里。当她成为离群孤雁,反倒有一种宿命之后的坚定。
当年北京留给她的印象,谈不上美好或不美好,只是日常状态的磨损。拥堵的早晨,人人行色匆匆,赶到某个地方去支付自己的体能与热量。头脑、手脚、腰肢或脊背,我们总要出卖身体的某一部分,才能换取把整个人都塞进去的立锥之地。十年后,到处还是追赶的人,追赶公交、艳遇和致富的机会。不能停,停下来就成为遗落站台的落伍者,成为被明天抛弃的弱者。
其实变化真大啊,北京。豆汁变成咖啡,提笼遛鸟变成手游里的宠物和精灵,京剧脸谱变成日韩风里雌雄同体的眼线与唇红,青砖灰瓦的四合院变成玻璃幕墙的摩天大厦……作为国际都会的北京,是否在城市群中沦为分母,沦为雷同的无数中的一个?
她曾听一位旅美老作家聊天,老人家清瘦、沉稳,在国外多年,依然保持着清晰的乡音。他生于二十世纪三十年代的北平,他回忆当年,北平的普通百姓,哪怕引车贩浆之流都颇识礼数,几乎听不到脏话——那极为不体面,人们耻于为之。他认为,这是因为北平数百年的帝都史,士大夫阶层的礼仪已经沉降到社会底层。内圣外王,修己安人,温良恭俭让等等被普遍认同。伴随消失的青砖灰瓦,老北平如今是记忆里的一座遗迹。现在的北京街道,满耳就是“操”“丫”“屌丝”“逼格”,脏字用于频繁的日常交流,从市井口语到话剧台词,它们出现得就像标点符号那么自然。北京丧失了……它曾经讲究的老灵魂。
就像池塘养不起鲸鱼,北京被称为城市森林的树丛养不起大动物。雾霾低沉。她的一个朋友出国前从未在北京驻留,快二十年了,他决心弥补这一课。没想到抵达当晚,他的眼睛和嗓子极不舒服,雾霾几乎诱发他的哮喘。为了预防病症,他乘坐第二天早班飞机匆匆逃离。他要回到河水浩荡的故乡——那个当初他死命逃开的地方,现在为了救命拼命赶回去。当然,没有哪个故乡能与天堂媲美,否则我们就不曾远离;也许故乡与天堂的相似之处在于,只有远离才能发现它的美,就像站在大地上才能仰望云层。
等她的朋友赶回故乡,记忆里的田园消失。水,早已在河道和村民的嘴唇上一起干涸。没有野花、果实和溪流,稻田里丛生杂草,青壮年离开了,留下的老人都在睡觉。没有劳动的体力和期待的热情,无所事事……整个村庄都在睡。生死恍惚,垂暮者提前躺了下来。
同样的失望,她体验过了。妈妈病逝之后,世间大概只有她记得外婆的生日,她一直把这个数字当作行李箱的密码。如果外婆活着,应该有一百岁了。她突发奇想,在外婆生日那天,回到了自己曾经和外婆一起生活过的地方。
面目全非,像是一场骗局。山被炸碎,为了攫取零碎的建筑材料。穿过村庄的河,那是长江无数支流中的一条,当然不见踪迹。长江,起自巴颜喀拉山,直到经济繁华地带的入海口;从众神仰望的高地,到众生喧嚣的冲积平原……长江经济带是全球重要的内河经济带。没有哪条河像长江这样,从远古走到现代文明的核心区域;也没有哪条河像长江这样,被改造得千疮百孔,剥夺得面目全非。城市化进程,如同一场告别故乡的迁徙。据说2013年,中国城市人口已超越农村人口。一个延续几千年的乡土中国,渐行渐远。“故乡”,这个含情脉脉的词语,内涵被改变,甚至从地图上被抹除标记。
像倾巢下的幼鸟,农民离开田地、老屋和亲人,走向远方的灯火。在乡村路上辗转,在生产线的履带上忙碌,在高速公路上奔行、运输……禁止调头!哪里才是故乡,哪里才是彼岸。不停地走,他们没有世亲和宿敌,一生命运悬系于陌生人之间。可以依靠脚旗、颈环和翅标,来跟踪和记录飞鸟;可这些离开家园的人们,如何判断他们的过与往,能否从他们脏脸上的泪痕看到泥色的河流,从他们荒腔走板的口音听出籍贯和家谱?
像倾巢下的幼鸟,农民离开田地、老屋和亲人,走向远方的灯火。可以依靠脚旗、颈环和翅标,来跟踪和记录飞鸟;可这些离开家园的人们,如何判断他们的过与往?
母亲喂养我们年少的胃,故乡的山河喂养我们的往事——这是爱国主义产生的基础。我们曾把营养不良的土壤当作贫瘠的故乡来热爱,可现在,我们难以找到整体的故乡,只剩破碎的土粒。家族、环境、习惯、风俗和传统,靠一代代人来存储和延续;当记忆遭到撕裂和洗除,出现难以逾越的代沟和断崖,某种秘密的遗传密码被篡改了。无论是乡村还是城市,难以记得自己昨天的脸。包括北京。
因为洪水和泪水,因为求学和求生,因为逃生和谋生,因为被动和主动;也因为羞耻和遗忘,因为挣扎和受挫,因为绝望和梦想……她不断离开又不断出发。她走过的地方,从乡村到城市,从祖国和异域。有些山清水秀之地,被水泥、塑料和垃圾填充;有些山重水复之地,被闪烁灯光和不熄渴望点燃。梦境中她会混淆母语与英语,现实里她会模糊故土与异乡。她觉得这一代人渐渐丧失了乡愁滋味;瓶装水的普及,使水土不服不再存在。人们不再需要故乡所代表的归宿,像候鸟在孤独的飞行中忘记方向。伤感徒劳,连地球都在宇宙中迁徙,在黑暗中沿着轨道失重地飞行。
第二天,她就会登上返回加拿大的飞机。来去匆匆,往事纷乱,却雁过无痕。像电视里有关迁徙的镜头,到处是密集舞动的羽翅,铺天盖地的鸟令人眩晕……节目结束,只留下斑点频闪的屏幕。这就是她的回乡,天空,空了,像一张曝光过度的相纸,只剩下黑白灰。
是否她的心境与季节有关?这个纬度的冬天难免萧索。当春天如一只巨翼的候鸟飞回,她也许会重怀期待。
她知道,至今北京残留的古建附近,依然麇集燕子。燕子勤勉,衔泥、筑巢、哺食、生育。喉部像颗毛茸茸的杏子,小而强反光的眼睛隐匿在阴影里……燕子凄厉地鸣叫、翻飞,尤其在暴雨之前。它们有着低频听觉,小巧的耳道能感知遥远之外的风起云涌。成年燕子有着幽深的钢蓝色、尾部的镰刀弧度;而刚出生的幼燕,嗷嗷待哺,张大嘴巴时,可以看到它们鲜艳的喉咙——那种黄色,通常是人类用来表示紧急救援的。每三只燕子中只有一只,能得到繁衍后代的幸运。
这些热爱童年和故乡的小精灵,去过哪里,穿越过风暴中怎样的闪电?燕子的体量,相当于一个孩子的拳头,削薄的翅膀既锋利又脆弱,难以想象它们经历的风浪。燕子在高压电线上休息,诗人描绘它们像五线谱。其实是由于很少着陆而只留残根的腿,不适合平地站立,燕子的短处暴露无遗,它们从天才变成残疾。
飞起来迅捷、走起来笨重的燕子,像她自己。每隔几年,她就改换生存环境,以至于她分不清,到底出于被迫还是惯性。她对远方保持谜语般的好奇,缺乏留鸟的忠诚。一成不变的生活甚至让她感到隐隐屈辱,她不能忍受,仅仅是地心引力,就把自己变成一条拴在链条上的狗。有一年脚踝受伤,她愣是拖着撕裂的筋腱,瘸脚去了一趟南美洲。朋友们嘲笑,可她把自己当成一只被捕获的鸟,把踝骨处的护腕当成一枚金属环……佩戴环志,是研究鸟类迁徙的常见方式。如果现实中不能疾走如飞,她就把飞当作自己的行走方式……人们说的遥远,看我飞翔。
每个人都向往变化,每座城市亦是如此吧。从飞机舷窗凝望北京,她发现璀璨灯火组成的图案,充满直线与横线、竖线与斜线,像插满蜡烛的生日蛋糕被划开数刀……但愿,切割使人们得以分享美味。她向后仰靠,北京渐行渐远。美妙在于往返之间,无论离去与归来,她都愿相信,远方的地平线上,有个发光的降落点。
坐在飞机上,她像骑鹅旅行的少年。机翼发出脉冲式的红色光闪,间隔的瞬间照亮周围一小团的雨,看上去就像一面磨损过多的玻璃。她想象,无数候鸟秘密地在高空潜行,它们飞得如此盛大又如此安静,如同缓慢移动的整个星空。星空,也像铺天盖地的候鸟群,金色的翅膀擦亮黑暗……我们忽略了日常生活里的奇迹。
种子、候鸟与漂泊者,他们抵达远方,是为自己创造一个可以回忆的故乡。落叶才能归根,浪子才能踏上回头之路,她走了这么远,为了让翅膀得到极致的体验。穿越昼夜和风暴,作为候鸟,她不能回头,只有抵达终点才能折返,甚至才有机会体会浅尝辄止的悔意。她默默地调整手表的时差,逆时针方向转动,指针像溯流而上的鱼。水流如同时间,打在洄游鱼脆质又倔强的头骨上。
2016年,肯尼亚
不仅止飞鸟。迁徙,是天上的事情,也是大地上的发生。八月的非洲,她去看动物迁徙——它们从坦桑尼亚的塞伦盖蒂草原,进入肯尼亚的马赛马拉。
满满都是集群的食草动物。长颈鹿,原始、华丽又优雅。斑马,经典的黑白配,形成令人眩晕的几何之美。转角牛羚的体色是铁锈红,臂部和腿部的瘀斑灰蓝。汤普森瞪羚,身姿轻盈,体侧有鲜明条斑。数量最多的是角马。成群结队的角马,罪人一样低着沉重的头,披拂垂散的发绺,漫山遍野,泥浆一样涌过草原。
什么都不能阻止前行,千军万马,仿若朝圣。即使迁徙途中,到处是敞开的伤口,兀鹫和秃鹳从尸首的体腔里换取肠胃。到处是骨架,剔得干净的肋拱上面,只剩头颅上的短角以及因暴露更显硕大的牙齿。害羞者常常是草食动物,拘谨紧张。它们只是作为一堆堆被单独包装的脂肪和血液,运输在肉食者的早餐与晚宴之间。一旦覆盖着的皮肤保鲜膜被撕开,它们迅速腐坏,烂在炽烈的阳光和成吨的暴雨里。
食草动物走到哪里,食肉动物就跟到哪里。角马,看到同伴被吃无动于衷,甚至因普遍而近切的死安静下来。它们与满脸血污的饱食者毗邻而居,继续咀嚼和反刍。就像被家暴伤害的女性选择留在婚姻里面那么自然,就像亲人死去我们希望自己健康地活着而不会殉葬那么自然。是没有选择的那种自然,并非麻木与冷漠,它只能承受随时的杀戮。然而,那些初生不久的斑马,那些孤独漫游的小羚羊,从未真正了解凶手,缘何能从空气中嗅到一丝猛兽气息就被惊吓得狂奔?它们从成年者那里继承的技能和遗产,是恐惧,让它们终身保持警惕和戒备,也让它们从同伴的死中得到暂时解脱。
为了从价值低廉的植物里摄取热量,素食者不得不整日奔波,无心他顾——它们艰难收集食物营养来养育血肉。而肉食者享用起来更加便利,所以它们进食所需时间短暂,可以有大量闲暇用来嬉戏、发呆,甚至情绪厌倦,乃至做出近于哲学的思考。她发现,食肉动物都有一张悲伤的脸。马赛马拉草原的狮和豹不怕人,游客密集窥看,丝毫不影响它们进食、玩耍、睡眠、排泄和交配,它们深知自己具有伤害的能力而呈现坦荡和蔑视。勇气来自暴力——是的,真正的勇气来自对暴力的控制,而不是激发。肉食者以一种不讲道理的暴戾,散发神秘之美。无需张扬,通常它们松弛、优雅,冷漠又懒惰……隐藏懒惰之中的,是惊人的果断。放纵的肉食动物拥有特权:一种因无耻而获得的自由,一种因自由而获得的傲慢。因此,别具魅力。
她想起,小时候怕夜晚来临,瞬间丧失方向感带来的压迫几乎让她哭起来。外婆不怕,外婆说她自己小时候臂肘烫伤,长辈给她涂过一层虎油,从此即使在丛林里遇到的狼都会绕行。据说,穿越黑暗的人脖子上假如佩戴一颗虎牙,村庄里的狗绝不会狂吠,而是噤无一声,深深低俯,仿佛臣服于归来的王者。她做过胆大妄为的猜测:上帝生杀予夺,既激情又淡漠,无惧非议和诋毁,整个世界屈服于他伟大的独裁……他,是肉食者。
没有来肯尼亚之前,她看电视节目得到的印象,马拉河是一道致死的关卡,只需闯关一次,之后就是伊甸园里的新生。事实并非如此。向塞伦盖蒂草原或马赛马拉草原的同一迁徙季,角马数次来回穿越马拉河。河的两岸都有角马,既有从此岸去彼岸的,也有彼岸来此岸的,两岸并无绝对差别。那么,角马为何过河?并且岸边犹豫,反复徘徊,最后才决绝跃下,穿越扬起的灰尘、溅起的水花和鳄鱼张开的大嘴。难道角马只是无法克制对远方的渴望,只是对现实的几乎进入潜意识的反抗,才让它们向死而生?纪录片拍到,角马甚至躲避较浅的安全地带,蓄意选择危险区域,似乎获得面对生死的勇气比获得侥幸的机会更为重要。也许,因为陆地也潜伏危险,杀戮者的齿锋无处不在,来自鳄鱼的威胁并不更大——鳄鱼饱餐一顿可以长久不进食,狮子和豹总在打猎。所以对角马来说,过河也许谈不上是额外冒险,不过是又一次日常的忍受。她甚至怀疑,这种生存竞速,只是角马自愿设置的考验,从而完成慷慨而隆重的祭献。
在马赛马拉草原,她第一次乘坐热气球。乘坐者最初需要以摔倒般的姿势躺在倾斜的吊篮里:屈腿,后背着地,缩在狭小局促的空间里。她听到燃料罐附近发出类似轻微爆炸的声音,喷灯上的火焰,将加热后的空气充入球囊。热气球升空后,垂直的吊篮非常平稳。她的手臂扶住边框,看天地辽阔,壮丽奔行的动物生生不息。
迁徙,不可思议的旅程。驱使伟大行动的,可能出自基础乃至卑微的目的,像鲸游动,追逐小如光斑的磷虾。当果实被洗劫,种粒埋入更深的地下,当鼠和蛇把身体卷成螺旋形进入黑暗的冬眠,那些理想主义者开始出发。动物迁徙多是因为食物和气候的现实原因,还有就是寻找与配偶共度的蜜月地,才迫使动物们遗弃曾经繁茂的聚居所,但她依然心怀激荡,深信这个世界有多少迁徙的脚步,就有多少流浪不羁的灵魂。
在云端,在大地上,在海洋里——迁徙铺开古老而壮阔的朝圣之路。斑马穿过博茨瓦纳的草原与狮子的阻击,抵达盐沼,去舔食岩块上的矿物质。海象游过白令海峡绕路北上,寻找结实的可供栖身的浮冰。水母从阴影密布的危险沙层,翕动着透明而诗意的伞膜,上升到光斑耀动的水面。出生在夏威夷的座头鲸,要从温暖的出生水域,滑动桨叶般的鳍肢,前往寒冷的阿拉斯加。奔跑有如舞蹈的瞪羚,虹膜和鳞片映照彩虹的鲑鱼,深沉歌唱的鲸鱼……从最柔弱的到最强悍的,都义无反顾,踏上征程。栖息在北美大陆的大桦斑蝶,每年要花130天,飞行3000公里,向南迁徙。重量甚至小于1毫克的蝴蝶,以远比婴儿拇指柔弱得多的肉身,扇动亮橘色的翅翼,麇集着,抵达千里之遥。冻原上走过的驯鹿,厚厚的皮毛下积聚脂肪,边走边哈出雪白的霜气,珊瑚状优美的角叉挂满冰晶……驯鹿在漫无际涯的苔原上跋涉,它一生走过的道路,足够绕地球三周,是世界上迁徙路线最长的哺乳动物。它们为此获得神赐的报答:无声却震撼的北极光就在它们头顶的高空闪耀,如同加冕。
……日出光芒万丈,她忍不住眯起眼睛。随着热气球高度的上升,无论是数量磅礴的角马,还是集体围剿的鬣狗,都变成微弱的斑点。不知不觉,她流泪了,她突然发现自己获得了飞鸟的视野。地面上的人看来,她也小得近乎斑点吧,像只飞高的候鸟。她把一条胳膊伸出吊篮之外,风吹拂指骨,她觉得自己正在长出季节性的羽毛。
人们曾以为鸟类的呼吸和鼓翼同步,事实上二者各自独立。当静止不动的时候,鸟类的呼吸比哺乳动物更慢;一旦飞行,鸟类的呼吸可以加速到静止时正常速率的20倍。这是内心激情在身体上的反映。鸟类,有着远比人类飞行员更丰厚有力的胸肌,凭借着光线、星宿、气流和磁极组成的地图,它高飞。在勺形的头颅里,每只鸟都藏好一根忠诚的指南针。即使长在两侧的眼睛未必能看到多远的前方,即使优雅前伸的脖颈后面是一双苦力的翅膀,只要终点和希望不灭,候鸟就会出发,密集的翅膀就像移动的花季。
她好奇,鸵鸟和鸸鹋,眼睛都是大且微陷,它们不会飞。鸟类中的善飞者眼睛偏小,如天鹅大雁之类。是否高空展翅,被猎杀的机会相对低,不必时刻警惕;加之俯瞰大地,万物渺小,眼睛大几毫米、小几毫米,并无差别,所以善飞者不再扩张眼眶?可事实上,从出发到回归,候鸟的死亡率很高,能够返乡的只是幸运的少数,衰老成为一种巨大的奖励。候鸟中的许多,死于跋涉或飞翔的中途,死于沙漠、森林、滩涂、积水或极地,死于天敌的追杀和自身体力的衰竭,死于变幻的云层和气流,死于不屈的心……履行诺言,需要昂贵的成本,所以,它们以命相抵。在濒死的疲惫中,它们锐而小的眼睛,最后是否见过蜃气中的天堂?即使星光照耀下的故乡已然死去,候鸟依然坚定地飞往它们的墓地。
季节的钟摆,把时间从此岸摆渡到彼岸。天空没有疆界,唯一的根系,是它学会飞翔的地方——候鸟既是信诺之鸟,又是不断的背叛者。飓风一样的鸟群。暴雨一样的鸟群。交响乐般的鸟群。铺满天空,鸟群不断变换图案,就像上帝传达秘密的旨意。可惜人类鲁钝,使他们无法读懂神的只言片语。古希腊神话中说宙斯曾经化身为天鹅,她觉得,神是可能以候鸟的样貌降临的。耶稣不是一只候鸟吗?在尘世和天堂之间折返,他的复活就是一次迁徙……他在十字架上,打开滴血的双翼。
热气球越升越高,已经难以区别有条纹的斑马和泥浆色的角马——如果你有鸟的翅膀,就不怕停在悬崖上。她不畏惧,如果说还残留一点点害怕,是因为她有几秒钟担心自己会越出吊篮,是因为在奇妙的出神之中,她错觉自己可以飞起来,可以像一只鸟那样飞得那么宁静,有如禅定……她仿佛看到了自己的往昔、今生与来世。她想起和外婆共同生活过的那个村庄。天空阴沉,水下的村庄看不到一丝痕迹,蓄积起来的水库淹没了一切,甚至改变了四周的远山。她相信,记忆,就藏在开阔水面的雾气里,如同鸟翼藏在云层之间。
……天上是飞鸟,它们迁徙自己的生活,使之更靠近自由。它们剪开地平线,然后在旋转而闪烁的光团与星宿之间,丧失重力地漂浮,由此体会虚空般的自由。地上是刚刚降生、还围裹湿漉漉胎衣的角马,它们尝试用颤抖的腿站立,以躲避巡行的狮子、有着哀悼泪线的猎豹和凶悍的鳄鱼,尽快加入迁徙的漫长之路。天上和地下,它们一同被召唤着,出发。
她习惯了肉身和精神一起流浪和迁徙,习惯了它们为此遭受疼痛和伤害。她想,肉身就是故乡,灵魂能够远游,甚至带领肉身迁徙。如果灵魂是被肉身软禁的囚徒,那就像是一只围绕墓碑盘旋的鸟。多少年来,她总是被远方蛊惑与召唤,因为若无梦想,整个生活不过是一个庞大的惩戒之所。并且,梦想若无一丝绝望,未免就缺乏神圣——绝望到极端的梦想才几近信仰。是否童年看到的候鸟,成为一生对她的感召?当鸟群开始史诗般的迁徙,那是魔咒——她仰头看到天上的飞鸟,低头开始路上的行走。
神话说:天上一日,等于地上一年。那么,走天上的路还是走地上的路更难?在天上,谁会成为障碍呢?没有,没有谁能伤害神,能阻挠他的意愿,所以神走一天的里程,大地上的生命需要一年才能完成。因为大地充满障碍,河流、石头、山脉、丛林、沼泽、沙漠、悬崖、陷阱、猛兽……需要逾越的,何其艰难。对人来说,甚至无论诱惑还是灾难,都是阻隔。
她想起了雪莱的那句诗:“你从大地上腾空而起,越飞越高,像一团火焰。”候鸟跃升,穿越人神之别。季节与季节之间裂开的口子,它们用羽翼一针针缝合,就像外婆刺绣,候鸟用彩色的羽毛在圆绷着的拱形天堂里绣出丝线。只有神和他的候鸟,能把天地之间的伤口都缝合得那么优美……弓形精湛,她会看到,暴雨之后的彩虹。
有 [[双向链接]]的`笔记`
!!无法离线
* [[Roam Research]]
* [[Remnote]]
* [[logseq]]
* RoamEdit(RE)
!!可离线
* [[TiddlyWiki]] 的 [[Stroll]]
* [[Org-roam]]
* [[obsidian]]
* [[思源笔记|https://github.com/siyuan-note]]
余光中(1928年10月21日-2017年12月14日),中华民国诗人、作家
文学评价
* 梁实秋:右手写诗,左手写文,成就之高,一时无两。[3]
* 向明:诗经、楚辞,唐、宋诗的名句,西洋典籍、旧约圣经,在他的诗中出出入入,自然轻巧,一点也不影响他诗中纯正现代风韵。
* 林沛理:语言的魔术师,香江第一才子。
* 夏志清:余光中所向往的中国并不是台湾,也不是共党统治下的大陆,而是唐诗中洋溢着‘菊香与兰香’的中国。
* 黄维梁:用紫色笔写诗,用金色笔写散文,用黑色笔写评论,用红色笔编辑文学作品,如果要用一句话来形容余光中的散文,则‘精新郁趣、博丽豪雄’八字当可称职。把他的散文放在中国历代最优秀的散文作品中,余光中的毫不失色。他的散文是中国散文史上璀璨的奇葩。这是对他散文最稳重最保守的评价……他的散文,通体洋溢着一股堂堂正正之气。那是一种自给自足、绰有余裕的才能,原无须借助外力、事件或经历的成全。我以为,一旦具备了余光中的才能,那么无论生在何时,长于何方,他都必然会在文学上崭露头角,大显峥嵘。
* 马世芳:“不,我不同意因为‘狼来了’或是他的政治倾向,就要把他的诗文都贬为不值一顾。”
* 李敖认为余光中四十余年来文学一点都没有进步,2011年7月的香港书展,李敖在《中国知识分子的走向》演讲中再次批评余光中:“余光中80多岁了,如果40年前就死了,他还是余光中,因为后40年都没进步嘛。”
余华(1960年4月3日-),浙江杭州人,中华人民共和国作家,中国先锋派小说的代表人。
作品
* 长篇小说:《活着》、《许三观卖血记》、《在细雨中呼喊》、《兄弟》、《第七天》;
* 中篇小说集:《鲜血梅花》、《现实一种》、《我胆小如鼠》、《战栗》、《世事如烟》、《黄昏里的男孩》;
* 随笔集:《[[温暖和百感交集的旅程|温暖和百感交集的旅程 余华]]》、《音乐影响了我的写作》、《没有一条道路是重复的》。
* 杂文集:《十个词汇里的中国》、《我们生活在巨大的差距里》,《我只知道人是什么》。
余华:伊恩·麦克尤恩后遗症
========================
文/[[余华]]
-----
我第一次听到[[伊恩·麦克尤恩]]的名字是在十多年前,好像在德国,也可能在法国或者意大利,人们在谈论这位生机勃勃的英国作家时,表情和语气里洋溢着尊敬,仿佛是在谈论某位步履蹒跚的经典作家。那时候我三十多岁,麦克尤恩也就是四十多岁,还不到五十。我心想这家伙是谁呀,这个年纪就享受起了祖父级的荣耀。
然后开始在中国的媒体上零星地看到有关他的报道:“伊恩·麦克尤恩出版了新书”、“伊恩·麦克尤恩见到了他失散多年的兄弟”、“伊恩·麦克尤恩的《赎罪》改编成了电影”……这几年中国的出版界兴致盎然地推出了伊恩·麦克尤恩的著名小说,《水泥花园》《阿姆斯特丹》《时间中的孩子》和《赎罪》,可是中国的文学界和读者们以奇怪的沉默迎接了这位文学巨人。我不知道问题出在什么地方,也许麦克尤恩需要更多的时间来让中国读者了解他。现在麦克尤恩的第一部书《最初的爱情,最后的仪式》正式出版,我想他的小说在中国的命运可以趁机轮回了。从头开始,再来一次。
这是一部由八个短篇小说组成的书,在麦克尤恩二十七岁的时候首次出版。根据介绍,这部书在英国出版后引起巨大轰动。可以想象当初英国的读者是如何惊愕,时隔三十多年之后,我,一个遥远的中国读者,在阅读了这些故事之后仍然惊愕。麦克尤恩的这些短篇小说犹如锋利的刀片,阅读的过程就像是抚摸刀刃的过程,而且是用神经和情感去抚摸,然后发现自己的神经和情感上留下了永久的划痕。我曾经用一种医学的标准来衡量一个作家是否杰出,那就是在阅读了这个作家的作品之后,是否留下了阅读后遗症,回想起十多年前第一次听到麦克尤恩名字时的情景,我明白了当初坐在我身边的这些人都是“伊恩·麦克尤恩后遗症”患者。
我感到这八个独立的故事之间存在着一份关于叙述的内部协议,于是[[《最初的爱情,最后的仪式》]]一书更像是一首完整的组曲,一首拥有八个乐章的组曲。
就像麦克尤恩自己所说的:“这些故事的主人公很多都是边缘人,孤独不合群的人,怪人,他们都和我有相似之处。我想,他们是对我在社会上的孤独感,和对社会的无知感,深刻的无知感的一种戏剧化表达。”
然后麦克尤恩在[[《立体几何》]]凝聚了神奇和智慧,当然也凝聚了生活的烦躁,而且烦躁是那么地生机勃勃;让《家庭制造》粗俗不堪,让这个乱伦的故事拥有了触目惊心的天真;[[《夏日里的最后一天》]]可能是这本书中最为温暖的故事,可是故事结束以后,忧伤的情绪从此细水长流;《舞台上的柯克尔》的叙述夸张风趣,指桑骂槐。麦克尤恩让一群赤裸的男女在舞台上表演性交,还有一个人物是导演,导演要求小伙子们在表演前先自己手淫,导演说:“如果给我见到勃起,就滚蛋,这可是一场体面的演出。”
《蝴蝶》里男孩的犯罪心理和情感过程冷静得令人心碎;《与橱中人对话》看似荒诞,其实讲述的是我们人人皆有的悲哀,如同故事结尾时所表达的一样,我们人人都会在心里突然升起回到一岁的愿望;《最初的爱情,最后的仪式》是没有爱情的爱情,没有仪式的仪式,还有随波逐流的时光,麦克尤恩给这些无所事事的时光涂上夕阳的余辉,有些温暖,也有些失落;《化装》是在品尝畸形成长的人生,可是正常人生的感受在这里俯拾即是。
这就是伊恩·麦克尤恩,他的叙述似乎永远行走在边界上,那些分隔了希望和失望、恐怖和安慰、寒冷和温暖、荒诞和逼真、暴力和柔弱、理智和情感等等的边界上,然后他的叙述两者皆有。就像国王拥有幅员辽阔的疆土一样,麦克尤恩的边界叙述让他拥有了广袤的生活感受,他在写下希望的时候也写下了失望,写下恐怖的时候也写下了安慰,写下寒冷的时候也写下了温暖,写下荒诞的时候也写下了逼真,写下暴力的时候也写下了柔弱,写下理智冷静的时候也写下了情感冲动。
麦克尤恩在写作这些故事的时候,正在经历他的年轻时光。二十二岁从苏塞克斯大学毕业后,去了东安格利亚大学的写作研究生班,开始学写短篇小说。第一个短篇小说发表后,立刻用稿费去阿富汗游玩。多年之后麦克尤恩接受采访,回顾了写作这些短篇小说时所处的境况:“我二十出头,正在寻找自己的声音。”当时他反感英国文学传统里社会档案式的写作,他想表达一种个人生存的翻版,他说:“早期的那些小故事都是倒影我自己生存的一种梦境。虽然只有很少的自传性内容,但它们的构造就像梦境一样反映了我的生存。”
麦克尤恩二十一岁开始读[[卡夫卡]]、弗洛伊德和[[托马斯·曼]],并且感到“他们似乎打开了某种自由空间”。然后“我试写各种短篇小说,就像试穿不同的衣服。短篇小说形式成了我的写作百衲衣,这对一个起步阶段的作者来说很有用”。麦克尤恩毫不掩饰其他作家对自己的影响,他说:“你可以花五到六个星期模仿一下[[菲利普·罗斯]],如果结果并不是很糟糕,那么你就知道接下来还可以扮扮纳博科夫。”而且还努力为自己当时写下的每一个短篇小说寻找源头,“比方说,《家庭制造》是我在读过《北回归线》之后写的一个轻松滑稽的故事。我感谢亨利·米勒,并同时用一种滑稽的做爱故事取笑了他一把。
这个故事也借用了一点罗斯的《波特诺的怨诉》。《化装》则效法了一点安格斯·威尔逊的《山莓果酱》。我不记得每篇故事的渊源,但我肯定巡视了别人的领地,夹带回来一点什么,借此开始创作属于我自己的东西。”
我在很多年前的一篇文章里,专门讨论了作家之间的相互影响,我用过这样一个比喻:一个作家的写作影响另一个作家的写作,如同阳光影响了植物的生长,重要的是植物在接受阳光照耀而生长的时候,并不是以阳光的方式在生长,而始终是以植物自己的方式在生长。我意思是说,文学中的影响只会让一个作家越来越像他自己,而不会像其他任何人。
麦克尤恩的写作经历同样证明了这个道理。《立体几何》里关于神奇的叙述与生动的生活场景合二为一,可以让我们联想到[[纳博科夫]]的某些段落;《夏日里的最后一天》和《最初的爱情,最后的仪式》会让我们联想到托马斯·曼的叙述风格,从容不迫,并且深入人心;《与橱中人对话》和《化装》或许与卡夫卡的那些奇怪的人生故事异曲同工;《舞台上的柯克尔》似乎是与荒诞派话剧杂交而成的;《蝴蝶》里的少年犯罪心理曾经是戈尔丁的拿手好戏,可是到了麦克尤恩笔下也是毫不示弱。
我想每一个读者都可以从自己的阅读经历出发,为麦克尤恩的这些故事找到另外的文学源头,找到麦克尤恩未曾阅读甚至是未曾听闻的文学源头。而且同样可以轻而易举地为卡夫卡、托马斯·曼、[[菲利普·罗斯]]、[[亨利·米勒]]、[[安格斯·威尔逊]]、纳博科夫、[[戈尔丁]]他们找到文学源头。为什么?很简单,因为这就是文学。
我喜欢引用这样两个例子,两个都是笑话。第一个是法国人嘲笑比利时人的笑话:有一个卡车司机满载着货物行驶在比利时的土地上,由于货物堆得太高,无法通过一个城门,就在司机发愁的时候,当地的比利时人自作聪明地向司机建议,将卡车的四个轮子取下来,降低高度后就可以经过城门。第二个来自中国古代的笑话:有一个人拿着一根很长的竹竿要过城门,他将竹竿竖起来过不去,横过来也过不去,这人不知所措之时,一位白发白须的老人走过来,称自己虽然不是圣人,也是见多识广,他建议将竹竿从中间锯断,就可以通过城门了。
这两个笑话究竟是谁影响了谁?这样的考证显然是没有意义的,也是没有结果的。我举出这样两个例子是为了说明,各民族的精神历史和现实生活存在着太多的相似性,而文学所要表达的就是这样的相似性。如同殊途同归,伟大的作家都以自己独特的姿态走上了自己独特的文学道路,然后汇集到了爱与恨、生与死、战争与和平等等这些人类共同的主题之上。所以文学的存在不是为了让人们彼此陌生,而是为了让人们相互熟悉。我曾经说过,如果文学里真的存在某些神秘的力量,那就是让读者在属于不同时代、不同民族和不同文化的作品里,读到属于他们自己的感受,就像在属于别人的镜子里也能看清楚自己的形象一样。
我相信麦克尤恩在阅读了纳博科夫、亨利·米勒和菲利普·罗斯等人的作品之后,肯定是在别人的镜子里看清楚了自己的形象,然后写下了地道的伊恩·麦克尤恩的作品。这家伙二十多岁就找到了自己的声音,读一读《最初的爱情,最后的仪式》这本书,就可以看到一个天才是如何诞生的。
麦克尤恩在这些初出茅庐的故事里,轻而易举地显示出了独特的才能,他的叙述有时候极其锋利,有时候又是极其温和;有时候极其优雅,有时候又是极其粗俗;有时候极其强壮,有时候又是极其柔弱……这家伙在叙述的时候,要什么有什么,而且恰到好处。与此同时,麦克尤恩又通过自己独特的文学,展示出了普遍的文学,或者说是让古已有之的情感和源远流长的思想在自己的作品中得到继续。什么是文学天才?那就是让读者在阅读自己的作品时,从独特出发,抵达普遍。麦克尤恩就是这样,阅读他作品的时候,可以让读者去感受很多不同作者的作品,然后落叶归根,最终让读者不断地发现自己。
我曾经说过,文学就像是道路一样,两端都是方向。人们的阅读之旅在经过伊恩·麦克尤恩之后,来到了纳博科夫、亨利·米勒和菲利普·罗斯等人的车站;反过来,经过了纳博科夫、亨利·米勒和菲利普·罗斯等人,同样也能抵达伊恩·麦克尤恩的车站。这就是为什么伊恩·麦克尤恩的叙述会让我们的阅读百感交集。
我的意思是说,当读者们开始为麦克尤恩的作品寻找文学源头的时候,其实也是在为自己的人生感受和现实处境寻找一幅又一幅的自画像。读者的好奇心促使他们在阅读一部文学作品的时候,唤醒自己过去阅读里所有相似的感受,然后又让自己与此相似的人生感受粉墨登场,如此周而复始的联想和联想之后的激动,就会让儿歌般的单纯阅读变成交响乐般的丰富阅读。
什么是伊恩·麦克尤恩后遗症?这就是。
#伊恩·麦克尤恩
#余华
雨-孔亚雷
========================
雨-[[孔亚雷]]
-------
雨已经持续不停下了整整一个礼拜。
对此任何人都无能为力,我和猫都这么想。我们并排坐在走廊上——我坐在小椅子上,时不时抽支烟;猫坐在地上,时不时用舌头舔舔爪子——看着灰蒙蒙的雨幕发呆。
那是1993年。8月。大学一年级结束的那个暑假。我刚刚过了十九岁生日没多久。生日是和一个女孩一起过的,两人吃完蛋糕便开始接吻,接吻的当中女孩流下泪来,然后说因为无法明说的原因必须要跟我分手。眼泪的咸味儿和蛋糕的甜腻味儿在口腔里融合成一种怪得要命的腥味,害得我什么话也说不出。我的初恋便是在那种奇特的味觉中结束的。
那之后没过几天,我就对父母说想去乡下的亲戚那儿住一阵子。我在旅行包里放进牛仔短裤和短袖衫,一本硬壳的《麦田守望者》,一只Walkman和一盘录满鲍勃·迪伦的九十分钟磁带。
亲戚是乡下一所中学的老师。我就借住在学校的学生宿舍。放暑假的校园空空荡荡,像被遗弃的古战场似的静悄悄地躺在8月的骄阳里。
不过,就在我到的第二天,雨便铺天盖地地下起来。
猫不知道是从哪里冒出来的。我注意到它时,它好像已经和我很亲密了。它用身体在我的小腿上蹭来蹭去。绕着我不停地转圈,还仰起小脑袋冲我咪咪咪地叫。简直和男孩追求女孩时的样子差不多。
我把吃剩的饭菜盛在一块凹下的瓦片里给它吃。它一边吃一边从肚皮里发出咕噜咕噜的声音。吃完它就坐在我旁边,眯着眼睛用舌头专心致志地舔湿脚掌,再用脚掌在脸上煞有介事地抹来抹去——就像我们洗脸那样。
我没给猫取名字。要喊它时,就叫声“喂”。久而久之,我和它都认为“喂”就是它的名字。反正我只要说声“喂”,猫就知道我是在跟它说话。
“喂,你说这雨什么时候会停?”
“……”
“嗯,看样子它好像决心要永远下下去。”
“……”
“雨真厉害,一点都不累。”
“……”
“喂,你有没有听说过加菲猫的故事?”
“……”
雨下到某种程度之后,似乎已经不能称之为雨了。我的意思是,那已经成为超越雨的意义之上的另外什么东西。一个整体,一个笼罩一切无所不在的整体。就像空气、房屋、泥土那样恒久存在的整体。如果有人说从我出生时起世界就一直在下雨,我大概也会相信。
总之,雨以一种不容置疑的态度永无疲倦地倾注下来。四处都弥漫着一股雨天特有的潮乎乎的气息。在长久凝视雨幕的时间里,眼前渐渐幻化为一片淡灰色,雨声也似乎嗖地一下被吸到哪里去了。周围像台风中心般静寂无声。
我突然想,怎么会有这么多水——有好几十吨——从无依无靠的天空上不间断地跌落下来呢?而这些落下的水又流到哪里去了呢?——地上并没有积水。
没有回答。
猫当然一如既往地保持沉默。
走廊很长,估计有二百米。每天早晨起床后,我就戴着Walkman耳机从走廊这头跑到那头,再从那头跑回这头。其间分别要经过我住的学生宿舍,101教室,102教室,103教室,201教室,202教室……一直到303教室。有时候觉得像是跑在一个狭长的桥洞里。雨水从倾斜的屋顶上沿着廊檐滴落下来,形成小瀑布那样的雨帘。
为什么偏要将校舍建成这副模样呢?每次产生在桥洞中的幻觉时,我就忍不住有点困惑。我在狭长的通道里不停迈动双腿,却感觉好像在哪里——在世界某个不为人知的角落——有人在为我静静哭泣。
一面看着外面的雨,一面静静哭泣。
好像我所在的这里,与另外某个场所有什么密切但却不为人知的联系。
我突然觉得莫名其妙地难过。
闲来无事,我便双手插在裤袋里,沿着一个个教室游来荡去。从焊着细铁条的窗子看进去,所有教室里的木头桌椅都破旧不堪。墙上贴着几张皱巴巴的伟人像。有的黑板上还留着零星的数学方程式和英文单词。
我靠在窗边一看就是好几个小时。看久了,仿佛能看到满教室的男女学生在桌椅间嬉戏玩闹。学校课间休息的嘈杂声似乎也从遥远的地方被搬运过来。直到猛地回过神,才发现眼前是黑咕隆咚空无一人的教室,雨声在耳边哗哗响。那些桌椅和黑板看上去都沾染着某种挥之不去的落寞神情。我看上去大概也一样。
我很想打个电话跟谁说说话。但不知道要打给谁好。而且,就算我拿起话筒,拨好号码,我也不知道到底该从何说起。
看见白裙子女孩的时候,我正坐在小椅子上抽烟,猫趴在我腿上呼呼大睡。
起先只是一个小白点。就像在灰色信纸上用涂改液点出的那样一个小白点。白点移动着,以几乎无法察觉的速度变得越来越大。当我吸第七口烟,弹第三次烟灰的时候,白点已经变成一个撑着白色雨伞的白裙子女孩,站在我面前的雨里。我听到雨点打在雨伞布上的声音。
透过迷蒙的水汽,我有些茫然地看着她。
她对我微微笑了笑,抬脚跨入走廊。猫醒过来,跳到地上伸了个懒腰,以同样茫然的眼神看着这位不速之客。感觉跟鲁滨逊发现荒岛上又来了一个白人差不多。
女孩以优雅的姿势将雨伞收拢。然后冲这边——弄不清是对我还是对猫——再次展开礼貌的微笑。我刚想开口说点什么,她已经转身背朝我向走廊的另一端走去。我看着她的背影。她走路的样子,怎么说呢,好像脚后跟有个微型弹簧,透着某种幼稚和天真,但其中又没有半点欢快。我仿佛能感觉到她背后连衣裙的拉链头在随着步伐微微颤动。
她远远地在301教室门前停下来,把伞挂在窗台上,顺手轻轻一推就进了教室。
教室的门没锁?
我低头伏到手臂上,耳朵贴近腕上的潜水表听着秒针的滴答声。犹疑片刻,我还是站起来,尽量轻巧——当然还不至于蹑手蹑脚——地走到301教室的后门。猫则兴致勃勃地跟在我身后。从后门旁边的窗子偷偷看进去,白裙子女孩正背对讲台用粉笔在黑板上写字。
满黑板的,大大小小的“爱”字。
然后她转过身,站在高高的讲台前,对着下面空空如也的桌椅。她的表情近乎凝滞,好像被冰冻住了一样。眼睛看向半空中什么似乎有形但我却看不见的东西。
一幅诡异冰冷的场景。满黑板的粉笔字加上神情古怪的女孩加上阴暗的光线以及四周绵延不绝的雨。可我却丝毫没有那样的感觉。相反,我感到胸口涌上一股温暖的泪意。对,就是那种让你觉得呼吸困难,仿佛可以马上哇的一声痛哭一场的泪意。
我最终还是没哭。但我总觉得,站在空荡教室里的白裙子女孩后来像雨点般落下的泪水中,也有我的一部分。
女孩离开之前好像轻松了一点。她在走廊上撑开雨伞,对着无边的雨幕看了一会儿,仿佛自言自语地轻声说:“雨停了就好了。”
然后她转过脸,露出用来代替说再见的微笑。
我也是一样。
从白裙子女孩消失在我眼前的那一刻起,我就开始试着回忆她的样子。但是不行,我无论如何都没法在脑海里拼凑出她准确的模样。眼皮是单是双,嘴巴是大是小,鼻子如何,脸形怎样,一概模糊一团。再硬想下去的话,眼前便出现初恋女孩和M女孩的脸。两张脸重叠在一起,一会儿是初恋女孩的眼睛搭配M女孩的笑容,一会儿是M女孩微翘的鼻尖下出现初恋女孩薄薄的嘴唇……再下去这些形象又都像被浸入褪色剂似的慢慢淡化,消失。最终眼前只剩下灰蒙蒙的雨幕。
不过,M女孩?
M女孩是我大学的同班同学。至于为什么称她为M女孩,是因为一想到她脑中便跳出M这个字母——原因怎么也说不清。
白裙子女孩再也没出现过。雨停了就好了。我总是想起她说的那句话。也许等雨停了就能再见到她。我这么想。
可是雨连半点停的意思都没有。
然后发生了一件事。
那天晚上我在学生宿舍床铺的蚊帐里边听鲍勃·迪伦边写一封写了无数遍还没有写好的信。给磁带翻面的间隙,我发觉外面正在电闪雷鸣。我跳下床,来到走廊上。
雨似乎下得更加凶狠了。像刀锋般刺破黑暗的闪电使瞬间被照亮的雨幕看来分外狰狞。我站在那儿一动不动。雨的碎末飘打到我身上。我不知道自己站了多久。我感到体内有什么在急剧地汇集,膨胀,即将喷涌而出。
我几乎本能地迈开脚步,朝301教室走去。
门果然没锁。
我打开开关,日光灯被惊醒似的依次亮起。黑板上依旧布满了大大小小各式各样的“爱”。我毫不迟疑地走上讲台。我就那样——像支标枪一样——立在讲台前,对着下面无声无息的桌椅。
雨下得更大了。雷声仿佛巨大无比的铁索砸过头顶。整间教室好像都在微微颤抖。
我咬紧牙关,双手握拳。好像在拼命与什么默默对抗。
耳边的雨声越来越响。但又好像从未有过的寂静。雨好像正在缓慢而坚定地渗透进来——渗透到所有的一切中来。雨已经控制了一切。仿佛地球上唯独只剩下这一间泛着暗淡灯光的教室,除此之外全都是漫无边际淋漓而下的雨水。并且顷刻之后,这仅有的空间也将被永久地摧毁,吞没。
就在那时,我觉得似乎有谁在注视着我。冷冷地注视着我。
那是雨。雨是活的。
雨在注视着我。
我不禁一阵晕眩。就像身体瞬间被吸空了。凉意像小虫子一样顺着脊背不断往上爬。我用力抓住讲台的边沿,以防自己瘫倒。
我能感觉到那冷冷的目光。它从某个广阔的角度凝视着我,孤零零地站在空教室灰白色灯光下的我。
我不记得自己是怎样回到床上的。我只记得把毛巾毯裹满全身,然后一头跌入梦中。我从未遇到过那种情形——以前没有,以后也没有——梦与现实衔接得天衣无缝,省略了所有过渡——简直就像推开门直接走进另一个房间。
那是个玻璃房间。梦中我站在一间大约十平米的玻璃房间里。没有猫。没有门窗。没有家具。什么都没有。只有四面透明得好像不存在的玻璃墙壁,屋顶也是玻璃的。
外面在下雨——很大的雨。
正是雨使玻璃墙壁和屋顶的存在得以确认。
雨水顺着屋顶的斜坡和墙壁不住流淌下来。外面只有白茫茫一望无际的雨。除了雨还是雨。
我就站在那里,什么也做不了。闭上眼睛,大声喊叫——诸如此类——都统统不行。我只能在里面不停地张望,转圈,而视野所及之处,全是无法闪避的雨。
没有任何出口。没有任何解决的办法。
没有。
*
考上大学是1992年。大学离家有一千公里。我每周和家乡一个女孩通半小时电话。那样持续了一年。1993年暑假我过十九岁生日那天,她提出分手。没有比那更叫人难忘的生日礼物了。
我和M女孩总共只说过四句话。
“嗨,你那盘鲍勃·迪伦的磁带能借来听听吗?”“当然……不过,现在不在手边。”“那……没关系,下次好了。”“嗯,下次给你。”
93年暑假住在乡下那所中学的时候,我大病一场。高烧四十一度。全身上下就像被火烤得滚烫的石头。我在床上躺了两天才被亲戚发现送回城里。你这条小命差点就没了。算你运气。他们都这么说。
对此我毫无知觉。因为我一直都在昏睡——既说不上痛苦,也谈不上快乐。
那年我在家休息到10月才返校。他们告诉我M女孩得了绝症。说是雨天在路上滑了一跤跌破了膝盖,然后不管怎样都止不了血,结果诊断为急性白血病。还说正在接受化疗,头发已经掉得差不多了,人也明显发胖,等等。
我回校的时候同班同学已经集体去看过她几次。我不知该不该单独再去看看她。我拿不定主意。我想不好。
我每晚都睡不踏实,有什么东西毛毛糙糙地堵在心里。
为什么?为什么会这样?
我常常半夜醒来,手里握着枕头下那盘鲍勃·迪伦,不停问自己。我总是幻觉外面又在下雨。永无止境的雨。好像整个大海从天空倒翻下来的雨。
我终于决定去看她。事情也许并没有想象的那么糟,而且我答应过借鲍勃·迪伦的磁带给她听。
等我到达医院的时候,才知道她已经在前一天晚上去世了。
我坐在从医院回校的双层巴士上层最角落的位置,右手在裤袋里紧攥着磁带盒。天色平淡,不阴不晴,窗外的街景无动于衷地变换。
我突然想起那狭长桥洞般的中学走廊。想起我在里面奔跑时从廊檐滴落下来的雨帘。想起白裙子女孩和她写在黑板上的字。想起我和猫一起坐在那儿看着永不停歇的雨。
对此任何人都无能为力。
从昏睡中睁开眼的那一刻,我心中异常地平静。我看着病房里被阳光照得近乎透明的白色窗帘。
雨已经停了。
紧密联结着这一刻的过去——对我来说——是玻璃房间的梦境和在夜晚教室中被雨注视的情景。世界已经变了,我知道。是怎样的改变一时还不清楚。但我知道已经变了。
*
事情已经过去了很久。“很久”这个词具有某种不确定性,让人想起闪着银色光芒的滑溜溜的金属手柄——一个抽屉或是一扇门的手柄。手柄本身是冰冷的,可是握久了会觉得温暖。仿佛来自金属的温暖。
就像往事。往事其实本来毫无意义,只是因为被握久了而让我们觉得温暖。所谓来自往事的意义与温暖,不过是长久地握住回忆。
确切地说,十年过去了。
整整十年。
十九岁时的绝望成了一个久远,潮湿,日渐模糊淡而又淡的梦。
我现在二十九岁。已经不再听什么鲍勃·迪伦。烟也戒了。每天挤地铁上下班。正在和女友计划向银行贷款按揭买房子。跟大部分人一样,既说不上痛苦,也谈不上快乐。
如同昏睡般的人生。
一到雨天,我就觉得失落,或者说孤单。我静静地坐着,感觉着外面或大或小、或急或疏的无数雨点洒落在世界的各个角落。包括那些不为人知的狭小的被遗忘的角落。我是在为什么而伤感呢?是为那些失去的,还是为那些得到的?我总是似乎马上就要想起什么,然而最终一切都像雨的微末那样掠过,消逝。
!WikiText中的硬换行符
```
"""
This is a line
and this is a new line
"""
```
月下迷宫-尼尔·盖曼
========================
月下迷宫-[[尼尔·盖曼]]
------
这是一个夏天的夜晚,我们攀爬着一座平缓的山坡。此刻已过晚间八点三十分,但感觉似乎依然还是下午。天空是蓝色的。太阳在地平线彼端低垂,将云朵染成金色、橙色和紫灰色。
“那么它是怎么终结的?”我问向导。
“它从未终结。”他说。
“但你说它已经没了,”我说,“那座迷宫。”
我是在网上看到有人提起这座月下迷宫的,它来自于某网站的一条小小脚注,那网站列举了世界各地有趣而值得注意的地点,都是些不同寻常的地方景点,越是破败且人工造成的越好。我不知道自己为什么会被这样的地景吸引:用黄色校车搭成的巨“石”阵,用大块奶酪造的聚苯乙烯模特,用粉煤灰混凝土塑成的假恐龙,还有其他诸如此类的东西。
我需要它们,无论我在哪儿,我需要它们给我一个停车的理由,让我好好跟人聊聊天。我曾经受到邀请,进入别人家中,成为他们生活中的一员,就因为我全心全意地称赞别人用引擎部件造的动物园,以铁皮罐和石块搭建并覆以铝箔的房屋,还有拿脸上油漆都已脱落的橱窗模特扮演的历史舞台剧。而这些人,这些令路边风景充满吸引力的人,他们会因为我是这样的人而接受我。
“我们将它烧毁了。”向导说道。他的年纪有点大,拄着一根拐杖。我遇到他时,他正坐在镇里五金店门前的长凳上。他答应带我去看月下迷宫的遗址。我们穿过草地,行进的速度并不太快。“终结这个月下迷宫,非常容易。迷迭香组成的篱笆着了火,劈啪作响,火焰升腾,浓烟滚滚,一直飘到山下,让我们都联想到了烤羔羊肉。”
“为什么叫它月下迷宫?”我问,“只是为了念起来好听吗?”
他思索了一会儿。“我现在不太确定,”他说,“我们将它称之为迷宫,但我想它只是个迷境……”
“只是很令人惊奇。”我重复道[1]。
“这里有传统,”他说,“我们会在满月后的第二天起,进入迷宫。从人口开始。找路进入中心,转身循旧路返回。正如我所说,我们只在月亏开始那天之后才去。天上的月亮依然明亮,足够让我们看见面前的道路。只要月光亮到足以让我们看得见,我们就会去。从这儿出发。步行。通常都是一对对的。直到月黑之时。”
“没有月亮的时候,就不会有人去?”
“哦,有些人还是会去的。但他们和我们不一样。他们都是些孩子,月黑之时就带上手电筒。他们在迷宫里穿行,那些坏孩子们,那些坏种们,他们只想相互吓唬对方。对那些孩子们来说,这就像是一个月一次的万圣节。他们挺喜欢被吓着的。有些孩子曾经说过他们见着了一个施虐狂。”
“什么样的施虐狂?”这个词让我有些惊讶。在和别人聊天的时候,这可不是个经常能听见的词。
“我猜只是个折磨其他人的家伙。我从来没见过。”
一阵清风从山顶吹拂而下。我用力嗅了嗅,却没有闻到花草烧焦的气味,没有烟尘,也没有任何不该存在于普通夏夜里的气息。附近有栀子花开放。
“月黑时,迷宫中只有孩子们。待到新月出现,年纪更小的孩子们会在父母的陪同下,来到迷宫中。父母和孩子们。他们一同走到迷宫的中心,成人们会用手指着新月,它看起来多像是天空中的微笑啊,一个巨大的、金黄的微笑,而小小的罗穆卢斯和瑞摩斯[2],或者叫其他什么名字的小孩,他们会微笑或大笑起来,挥动手臂,就好像打算将月亮从天空中拉下来,挂在自己的小脸蛋上似的。
“接着,等月亮慢慢变圆,情侣也渐渐出现。年轻一点儿的情侣们会数着数字来到这里,更年老些的则会成群结队地一起前来,他们早已忘记了当年数着数字的岁月。”他将身体重重地压在拐杖上。“其实没有忘记,”他说,“你绝不会忘记。它一定潜伏在你身体中的某个地方。甚至即使你的大脑忘记了,牙齿或许也会记得。要不就是手指。”
“他们会带手电筒吗?”
“有些晚上会,有些则不用。最受欢迎的夜晚,没有云层遮蔽月亮,你可以直接走到迷宫中。再过不了几天,人人都能这样做了。月光日复一日——我该说夜复一夜——地增强,月下的世界是如此美丽。
“他们会将车子停在山下,就在你停车的地方,在这块土地的周边,接着步行上山。大家总是步行,除了有些坐轮椅的人,或是那些得由父母抱着上山的。接着,到山顶上,他们会停下来搂在一起,一同漫步迷宫。迷宫中有些长椅,你可以在其上停留休息。他们会停下来,再次搂紧对方。你可能会觉得,只有年轻人才会搂搂抱抱的,但上了年纪的人也会这么做。肌肤与肌肤相贴。有时候你可以听到他们的声音,在篱笆的另一边,发出一些好像动物一般的声音,这是个信号,提示你放慢脚步,或是去查探一会儿其他的小径通道。别经过他们身边太多次。虽然当时没那么想,但现在回忆起来,我还是很赞赏这事儿的。在月光下,双唇触碰肌肤。”
“在被焚毁之前,这个月下迷宫存在了多少年?是房屋建起来之后才造的吗?”
我的向导鄙夷地哼了一声。“之前,之后……这种事得回溯到最初。人们常常提到米诺斯的迷宫,但它跟这个根本无法相提并论。那个迷宫不过是些通道,里面有个长角的家伙被吓坏了,饥饿地独自游荡。他其实不是真的牛头怪物,你知道吗?”
“你怎么知道?”
“牙齿。牛和羊是反刍动物,不吃肉。但米诺陶洛斯会吃。”
“我没想到这一点。”
“大家都没有。”山坡开始陡峭起来。
我想,这世上没有米诺陶洛斯,再也不会有了。我也不是什么施虐狂。但我只是说:“组成迷宫的灌木有多高?它们是真的篱笆吗?”
“是真的。需要多高,就有多高。”
“我不知道迷迭香在这个地区能长到多高。”我确实不知道,这儿离我的故乡很远。
“我们的冬天不太冷,迷迭香在这儿长得很茂盛。”
“那人们为什么要把它彻底焚毁?”
他停了下来。“等我们爬到山顶,你就能有个更明确的概念,知道一切都是什么样的了。”
“什么样的?”
“到山顶你就知道了。”
山路越来越陡峭。去年冬天,我的左膝摔在冰上,受了伤,导致我再也不能快跑。这些天来,爬山和上台阶都让我觉得费力,每走一步,膝盖就阵阵作痛,它以此来愤怒地提醒我它的存在。
有不少人,一旦知道想看的名胜奇景已在数年前被焚毁,就会直接回到车里,开往自己的最终目的地。我可不是这么轻易就能阻拦的。我所见过的最好的地方都是些死寂之地:一家已经关闭的游乐场,我以一杯酒的价格贿赂守夜人才得以进入;还有一个废弃的谷仓,农夫告诉我,在过去的夏天里,有六个大脚怪曾经居住其中,他说它们会在夜晚嗥叫,身上带着恶臭,但它们已在一年前离开了。那地方缭绕着某种动物的气味,可能是土狼。
“当月亮渐缺,他们会怀着爱走入迷宫,”我的向导说道,“而月亮渐满时,他们的心中便不再有爱,只有欲望。需要我给你解释个中区别吗?绵羊和山羊之间?”
“我想不用。”
“有时候会有病人来这儿。有伤残的人也会来,他们中的某些人得推着轮椅,或是被人扛着才能进去。但即使是这些人,也得自己选择迷宫中的路径,不能求助于推着他们或扛着他们的人。我还是个小男孩时,人们叫这种人‘残废’,我很高兴现在已经没人这么叫了。失恋的人也会来。独自一人。有时候人们会带疯子到这儿来。他们因月得名[3],只有在童话里,月亮才有机会修补事物。”
我们即将到达山顶。此时已是薄暮,天空呈现出葡萄酒的色彩,西边的云层被西沉的太阳染上红光。然而从我们所在的地方看去,太阳已沉入地平线之下。
“等我们到了,你会看见的。山顶上,那儿非常平坦。”
我想提供点故事,于是说道:“在我的故乡,五百年前,一位本地领主去拜访国王。国王炫耀了他巨大的桌子,他的蜡烛,他那些带着美丽画儿的天花板。他每展示一件,领主都没有夸赞,只是淡淡地说,‘我有个更漂亮的,更大的,更好的。’国王要求领主证明自己的所言非虚,于是他对领主说,下个月自己会到领主这儿来,在领主那张比这更好更大的桌子上吃饭,头顶上还得有那更大更好的天花板。”
我的向导说:“那位领主是否将一张桌布铺在平坦的山间,让二十名勇士握住蜡烛,然后和国王一同在上帝的星光下用餐?我们这儿也有类似的故事。”
“正是这个故事。”我承认道,我所提供的故事就这么轻松地被他一笔带过,不由恼羞成怒,“国王承认领主说得对。”
“国王没有囚禁他,虐待他?”向导问,“我们这附近的版本里,故事是这么发展的。他们说他甚至都没赶上厨师赶制出蓝带甜点。第二天,他们找到他时,他的双手已被砍去,舌头被割下紧塞在胸前的口袋里,脑门上还留着一个子弹孔。”
“这里?丢在后面的屋子里?”
“老天哪,当然不是。他们将他的尸体留在他的夜总会,就在城里。”
我感到十分惊讶。暮光已彻底消失,西边依然还有一丝红色,但天空的其他部分已彻底入夜,带着一片深紫红色。
“满月前的那些天,”他说,“他们会将迷宫留给虚弱的老人和那些有需要的人。我的妹妹曾经得过一种妇科病。他们告诉她,若她不动手术把肚子里面刮干净,就一定会死,当然刮了也可能会死。她腹部肿胀,就像是怀了个孩子,而不是生了一个肿瘤,然而她那时已快有五十岁了。满月前的那天,她来到这儿,走入迷宫。在月光下,从外走到里,又从中心回到外面,一步也没有跌跤、绊倒。”
“她后来怎么样了?”
“活下来了。”他简短地说道。
我们到达山顶,但我看不清面前的一切,太黑了。
“他们从她体内把那东西取了出来。它还活了一会儿。”他停下,过了一会儿,拍拍我的手臂:“看那边。”
我转身望去,月亮的尺寸让我大吃一惊。我知道月亮在升起时看起来会大一些,这不过是个光学错觉,但此刻在地平线上升起的月亮却让我想起弗兰克•弗雷泽塔[4]画的平装书封面。那些封面上时常出现举着剑的人,背景则是一轮巨大的圆月,还有一些狼在山顶嚎叫的画面,雪白的月亮勾勒出它们黑色的剪影。面前正升起的月亮,呈现出刚揽拌好的黄油似的奶黄色。
“现在是满月吗?”我问。
“是的,满月。”他的声音听起来很满足,“前面就是迷宫了。”
我们朝它走去。我本以为只会在地上看到灰烬,甚或空无一物,然而在黄油似的月光下,我看到了一座迷宫,复杂而优雅,一个巨大的正方形外墙内,填充着圆形和涡旋状的通道。在此时的光线下,无法正确判断距离,但我猜这正方形的各条边都至少得有两百英尺,甚至更长。
然而构成迷宫的植物却很低矮,高不过一英尺。我弯腰捡起一片针形的叶子,它在月光下呈黑色,我用拇指和食指捻了一下。我深吸了一口气,想起了烤羊羔,它被小心翼翼地肢解、涂上调料,然后放置在烤箱中,而那烤箱里铺着一层枝条和针叶,嗅起来的气息正如我面前这片叶子。
“我以为你们早已将这整个迷宫都焚烧殆尽了。”我说。
“是已烧尽了。它们已不再是篱笆,再也不是了。但在适宜的季节里,草木重又生长。它们并未全被杀死。迷迭香是很顽强的。”
“入口在哪里?”
“你站的地方就是。”他说。他是个走路时得拄拐杖、乐于与陌生人交谈的老头儿。平常没什么人会记挂他。
“那么满月的时候,这儿会发生什么事?”
“当地人不会在满月时走入迷宫。那是向一切付出代价的夜晚。”
我跨出一步,走入迷宫。一点儿也不难,没有一丛灌木高过我的小腿,全都和普通家庭菜园里的植物差不多高。如果我找不着方向,只要抬脚跨过树丛走回来就可以了。但眼下,我只是沿着小径走向迷宫深处。在满月的月光下,要看清前路非常容易。我可以听到向导继续说话。
“有些当地人认为,即使是这个代价也有些太高。所以我们来到这里,将月下迷宫焚毁。我们在月黑之时来到山上,手持燃烧的火炬,那画面像是一场老式黑白电影。我们都参与了,甚至连我也去了。但你不可能杀死所有的一切。事情不会像这样发展。”
“为什么迷迭香能留下?”我问。
“迷迭香用作回忆。”他告诉我。
黄油色的月亮升起的速度比我想象和预计的要快得多。现在,它已是天空中一轮苍白的幽灵般的面庞,极为平静,带着悲悯,颜色很白,白如骸骨。
老人说道:“要安全地离开迷宫是可能的,即使满月时也一样:首先你要进入迷宫的中心,那儿有一座喷泉,你一会儿就会看到了,你不会弄错地方。接着你得转身背对中心,不能被绊倒,不能走入死路,走进或走出时都不能犯错。相比灌木长得很高的时候,现在可能会更容易些。这是个机会。如果能完成,迷宫将治愈你所有的伤痛和烦恼。当然,你得跑起来。”
我回头望去,却没有看到向导。再也看不见他了。在我面前有什么东西,在那些灌木小径之外,一个黑色的阴影正静静地出现在正方形迷宫的边缘。它的体型看起来像是条大狗,然而跑动的样子却与狗截然不同。
它转头朝着月亮嗥叫,声音中带着喜悦和兴味。山顶上,巨大的平台随着欢乐的嗥叫阵阵回响,我的左膝却由于长时间爬山而隐隐作痛。我蹒跚向前。
迷宫是有路径的,我可以沿着它走出去。在我头顶上,月亮照耀如同白日。过去她总是接受我的赠礼,在这最后关头,她不会辜负我。
“跑!”一个几近咆哮的声音吼道。
在他的高声大笑中,我跑了起来,如同一头黑羊。
[1]“只是个迷境”(just a maze)与“只是很令人惊奇”(just amazed)谐音。
[2]双生子罗穆卢斯和瑞摩斯(Romulus and Remus)出自希腊神话,传说二人是战神之子,被牧羊人养大,是罗马城的缔造者。
[3]歲子在英文中是Lunatic,词根来源于月亮的Luna。欧洲传说里,月光会令人发疯。
[4]弗兰克•弗雷泽塔(Frank Frazetta,1928—2010),美国最重要的奇幻科幻插画大师,作品多以油画的形式,着重刻画人物的肌理与背景氛围。在他之前,插画家等同于画工,在他之后,插画及图书封面的重要性才逐渐被人认识。
"""
他每日定时祈祷
从不中断
他祈祷的时候要面向天空
祈祷的声音要传到外面的世界才有效
祈祷的力量要改变世界
不能被封闭在一间房间
就像他
每一天回家
都在自己的房间
不交际
不接触外面的世界
人生的空间,属于自己的空间
就是自己的房间
他祈祷安宁
他祈祷纯粹
他祈祷有种神秘的力量
能改变
他
他的上帝不是千依百顺的哆啦a梦
他的工作是散工
没有固定的薪水
目前受到疫情影响
没有钱,没有未来
但未来无法掌握
至少要先把现实的烦恼解决
要不然存再多的钱
活不到未来,
或途中精神病了
也是枉然
"""
张爱玲记- 胡兰成
========================
张爱玲记- [[胡兰成]]
-----
(一)
前时我在南京无事,书报杂志亦不大看,却有个冯和仪寄了天地月刊来,我觉和仪的名字好,就在院子里草地上搬过一把藤椅,躺着晒太阳看书。先看发刊辞,原来冯和仪又叫苏青,女娘笔下这样大方利落,倒是难为她。翻到一篇《封锁》,笔者张爱玲,我才看得一二节,不觉身体坐直起来,细细的把它读完一遍又读一遍。见了胡金人,我叫他亦看,他看完了赞好,我仍于心不足。
我去信问苏青,这张爱玲果是何人?她回信只答是女子。我只觉世上但凡有一句话,一件事,是关于张爱玲的,便皆成为好。及天地第二期寄到,又有张爱玲的一篇文章,这就是真的了。这期而且登有她的照片。见了好人或好事,会将信将疑,似乎要一回又一回证明其果然是这样的,所以我一回又一回傻里傻气的高兴,却不问问与我何干。
这样糊涂可笑,怪不得我要坐监牢。我是政治的事亦像桃花运的糊涂。但是我偏偏又有理性,见于我对文章的敬及在狱中的静。
及我获释后去上海,一下火车即去寻苏青。苏青很高兴,从她的办公室陪我上街吃蛋炒饭,随后到她的寓所。我问起张爱玲,她说张爱玲不见人的。问她要张爱玲的地址,她亦迟疑了一回才写给我,是静安寺路赫德路口一九二号公寓六楼六五室。
翌日去看张爱玲,果然不见,只从门洞里递进去一张字条,因我不带名片。又隔得一日,午饭后张爱玲却来了电话,说来看我。我上海的家是在大西路美丽园,离她那里不远,她果然随即来到了。
我一见张爱玲的人,只觉与我所想的全不对。她进来客厅里,似乎她的人太大,坐在那里,又幼稚可怜相,待说她是个女学生,又连女学生的成熟亦没有。我甚至怕她生活贫寒,心里想战时文化人原来苦,但她又不能使我当她是个作家。
张爱玲的顶天立地,世界都要起六种震动,是我的客厅今天变得不合适了。她原极讲究衣裳,但她是个新来到世上的人,世人各种身份有各种价钱的衣料,而对于她则世上的东西都还未有品级。她又像十七八岁正在成长中,身体与衣裳彼此叛逆。她的神情,是小女孩放学回家,路上一人独行,肚里在想什么心事,遇见小同学叫她,她亦不理,她脸上的那种正经样子。
她的亦不是生命力强,亦不是魅惑力,但我觉得面前都是她的人。我连不以为她是美的,竟是并不喜欢她,还只怕伤害她。美是个观念,必定如何如何,连对于美的喜欢亦有定型的感情,必定如何如何,张爱玲却把我的这些全打翻了。我常时以为很懂得了什么叫做惊艳,遇到真事,却艳亦不是那艳法,惊亦不是那惊法。
我竟是要和爱玲斗,向她批评今时流行作品,又说她的文章好在那里,还讲我在南京的事情,因为在她面前,我才如此分明的有了我自己。我而且问她每月写稿的收入,听她很老实的回答。初次见面,人家又是小姐,问到这些是失礼的,但是对着好人,珍惜之意亦只能是关心她的身体与生活。
张爱玲亦会孜孜的只管听我说,在客厅里一坐五小时,她也一般的糊涂可笑。我的惊艳是还在懂得她之前,所以她喜欢,因为我这真是无条件。而她的喜欢,亦是还在晓得她自己的感情之前。这样奇怪,不晓得不懂得亦可以是知音。
后来我送她到衖堂口,两人并肩走,我说:“你的身裁这样高,这怎么可以?”只这一声就把两人说得这样近,张爱玲很诧异,几乎要起反感了,但是真的非常好。
(二)
第二天我去看张爱玲。她房里竟是华贵到使我不安,那陈设与家具原简单,亦不见得很值钱,但竟是无价的,一种现代的新鲜明亮几乎是带刺激性。阳台外是全上海在天际云影日色里,底下电车当当的来去。张爱玲今天穿宝蓝绸袄裤,带了嫩黄边框的眼镜,越显得脸儿像月亮。三国时东吴最繁华,刘备到孙夫人房里竟然胆怯,张爱玲房里亦像这样的有兵气。
我在她房里亦一坐坐得很久,只管讲理论,一时又讲我的生平,而张爱玲亦只管会听。男欢女悦,一种似舞,一种似斗,而中国旧式栏上雕刻的男女偶舞,那蛮横泼辣,亦有如薛仁贵与代战公主在两军阵前相遇,舞亦似斗。民歌里又有男女相难,说书又爱听苏小妹三难新郎,王安石与苏东坡是政敌,民间却把来说成王安石相公就黄州菊花及峡中茶水这两件博识上折服了苏学士,两人的交情倒是非常活泼,比政敌好得多了。我向来与人也不比,也不斗,如今却见了张爱玲要比斗起来。
但我使尽武器,还不及她的只是素手。张爱玲的祖父张佩纶与李鸿章的小姐配婚姻,是有名的佳话,因我说起,她就把她祖母的那首诗抄给我看,却说她祖母并不怎样会做诗,这一首亦是她祖父改作的。她这样破坏佳话,所以写得好小说。
张爱玲因说,她听闻我在南京下狱,竟也动了怜才之念。我听了只觉得她幼稚可笑,一种诧异却还比感激更好。我连没有去比拟张佩纶当年,因为现前一刻值千金,草草的连感动与比拟都没有工夫。
回家我写了第一封信给张爱玲,竟写成了像五四时代的新诗,一般幼稚可笑,张爱玲也诧异,我还自己以为好。都是张爱玲之故,使我后来想起就要觉得难为情。但我信里说她谦逊,却道着了她,她回信说我“因为懂得,所以慈悲”。
从此我每隔一天必去看她。才去看了她三四回,张爱玲忽然很烦恼,而且凄凉。女子一爱了人,是会有这种委屈的。她送来一张字条,叫我不要再去看她,但我不觉得世上会有什么事冲犯,当日仍又去看她,而她见了我亦仍又欢喜。以后索性变得天天都去看她了。
因我说起登在《天地》上的那张相片,翌日她便取出给我,背后还写有字:
见了他,她变得很低很低,低到尘埃里,但她心里是欢喜的,从尘埃里开出花来。
她这送照相,好像吴季扎赠剑,依我自己的例来推测,那徐君亦不过是爱悦,却未必有要的意思。张爱玲是知道我喜爱,你既喜爱,我就给了你,我把照相给你,我亦是欢喜的。而我亦只端然的接受,没有神魂颠倒。各种感情与思想可以只是一个好,这“好”字的境界是还在感情与思念之先,但有意义,而不是什么的意义,且连喜怒哀乐都还没有名字。
(三)
我到南京,张爱玲来信,我接在手里像接了一块石头,是这样的有份量,但并非责任感。我且亦不怎么相思,只是变得爱啸歌。每次回上海,不到家里,却先去看爱玲,踏进房门就说:“我回来了。”
要到黄昏尽,我才从爱玲处出来,到美丽园家里,临睡前还要青芸陪我说话一回,青芸觉得我这个叔叔总是好的,张小姐亦不比等闲女子。一晚我从爱玲处出来径到熊剑东家,剑东夫妇和周佛海太太在打牌,我在牌桌边看了一回,只觉坐立不安,心里满满的,想要啸歌,想要说话,连那电灯儿都要笑我的。
我常时一个月里总回上海一次,住上八九天,晨出夜归只看张爱玲,两人伴在房里,男的废了耕,女的废了织,连同道出去游玩都不想,亦且没有工夫。旧戏里申桂生可以无年无月地伴在志贞尼姑房里,连没有想到蜜月旅行,看来竟是真的。
我们两人在一起时,只是说话说不完。在爱玲面前,我想说些什么都像生手拉胡琴,辛苦吃力,仍道不着正字眼,丝竹之音亦变为金石之声,自己着实懊恼烦乱,每每说了又改,改了又悔。但爱玲喜欢这种刺激,像听山西梆子的把脑髓都要砸出来,而且听我说话,随处都有我的人,不管是说的什么,爱玲亦觉得好像“攀条摘香花,言是欢气息”。
爱玲种种使我不习惯。她从来不悲天悯人,不同情谁,慈悲布施她全无,她的世界里是没有一个夸张的,亦没有一个委屈的。她非常自私,临事心狠手辣。她的自私是一个人在佳节良辰上了大场面,自己的存在份外分明。她的心狠手辣是因她一点委屈受不得。她却又非常顺从,顺从在她是心甘情愿的喜悦。且她对世人有不胜其多的抱歉,时时觉得做错了似的,后悔不迭,她的悔是如同对着大地春阳,燕子的软语商量不定。
我的囿于定型的东西,张爱玲给我的新鲜惊喜却尚在判定是非之先。旧小说里常有人到了仙境,所见珍禽异卉,多不识其名,爱玲的说话行事与我如冰炭,每每当下我不以为然,连她给我看她的绘画,亦与我所预期的完全不对。但是不必等到后来识得了才欢喜佩服,便是起初不识,连欢喜佩服亦尚未形成,心里倒是多少带有叛逆的那种诧异,亦就非常好,而我就只凭这样辛辣而又糊涂的好感觉,对于不识的东西亦一概承认,她问我喜欢她的绘画么,只得答说是的,爱玲听了很高兴,还告诉她的姑姑。
我是受过思想训练的人,对凡百东西皆要在理论上通过了才能承认。我给爱玲看我的论文,她却说这样体系严密,不如解散的好,我亦果然把来解散了,驱使万物如军队,原来不如让万物解甲归田,一路有言笑。我且又被名词术语禁制住,有钱有势我不怕,但对公定的学术界权威我胆怯。一次我竟然敢说出《红楼梦》、《西游记》胜过托尔斯泰的《战争与和平》,或歌德的《浮士德》,爱玲却平然答道,当然是《红楼梦》、《西游记》好。
牵牛织女鹊桥相会,喁喁私语尚未完,忽又天晓,连欢娱亦成了草草。《子夜歌》里有:
一夜就郎宿,通宵语不息,
黄蘗万里路,道苦真无极。
我与爱玲却是桐花万里路,连朝语不息。
如此只顾男欢女爱,伴了几天,两人都吃力,随又我去南京,让她亦有工夫好写文章。而每次小别,亦并无离愁,倒像是过了灯节,对平常日子转觉另有一种新意。只说银河是泪水,原来银河轻浅却是形容喜悦。
(四)
基督说:“属于西泽的归西泽,属于上帝的归上帝。”如今亦即如此把人们来分属,张爱玲却教了我没有禁忌。天下人不死于殉恶,而死殉善,怎样善的东西若是带上巫魇禁忌,它便不好了。
我因听别人常说学生时代最幸福,也问问爱玲,爱玲却很不喜学校生活。我又以为童年必要怀恋,她亦不怀恋。在我认定是应当的感情,在她都没有这样的应当。她而且理直气壮的对我说,她不喜她的父母,她一人住在外面,她有一个弟弟偶来看她,她亦一概无情。这与我的做人大反对。但中国文明原是人行于五伦五常,并不是人属于五伦五常,而伦常之所以在几千年来不被革命革掉,是因与二十四孝同时也可以有桃花女与樊梨花。
民间看戏,爱看与公公斗法的桃花女。也喜欢樊梨花,樊梨花杀夫弒父,但大唐世界还是要她这样美貌有本领的人。还有哪咤,哪咤是个小小孩童,翻江倒海闯了大祸,他父亲怕连累,挟生身之恩要责罚他,哪咤一怒,刳肉还母,剔骨还父,后来是观世音菩萨用荷叶与藕做成他的肢体。张爱玲便亦是这样的莲花身。
爱玲是她的人新,像穿的新衣服对于不洁特别触目,有一点点雾数或秽亵她即刻就觉得。《聊斋》里的香玉,那男人对着绛雪道:“香玉吾爱妻,绛雪吾腻友也。”爱玲很不喜。又我与爱玲闲话所识的几个文化人,爱玲一照眼就看出那人又不干净,又不聪明。我每听她说,不禁将人比己,多少要心惊,但亦无从检点起。
我称赞爱玲的房间,她却说这还是她母亲出国前布置的,若她自己来布置,她爱刺激的颜色。赵匡胤形容旭日:“欲出不出光辣挞,千山万山如火发。”爱玲说的刺激是像这样辣挞的光辉颜色。她看《金瓶梅》,宋蕙莲的衣裙她都留心到,我问她看到秽亵的地方是否觉得刺激,她却竟没有。她爱看小报,许多恶浊装腔的句子她一边笑骂,一边还是看。亦有妙语,小报上的妙语往往亦是可怜语,一点不得爱玲的同情,但她转述给我听时,她亦是这样的开心好笑。无论她在看什么,她仍只是她自己,不致与书中人同哀乐,清洁到好像不染红尘。
连对于好的东西,爱玲亦不沾身。她写的文章,许多新派女子读了,刻意想要学她笔下的人物都及不得,但爱玲自己其实并不喜爱这样的人物。爱玲可以与《金瓶梅》里的潘金莲李瓶儿也知心,但是绝不同情她们,与《红楼梦》里的林黛玉薛宝钗凤姐晴雯袭人,乃至赵姨娘等亦知心,但是绝不想要拿她们中的谁来比自己。她对书中的或现时的男人亦如此。她是陌上游春赏花,亦不落情缘的一个人。
我自己以为能平视王侯,但仍有太多的感激,爱玲则一次亦没有这样,即使对方是日神,她亦能在小地方把他看得清清楚楚。常人之情,连我在内,往往姑息君子,不姑息小人,对东西亦如此,可是从来的悲剧都由好人作成,而许多好东西亦只见其纷纷的毁灭,因为那样的好原来有限,是带疾的,其实不可原谅的还是不应当原谅。爱玲对好人好东西非常苛刻,而对小人与普通的东西,亦不过是这点严格,她这真是平等。
爱玲好像小孩,所以她不喜小孩,小狗小猫她都不近,连对小天使她亦没有好感。一次她搬印书的白报纸回来,到了公寓门口要付车夫小账,她觉得非常可耻又害怕,宁可多些,把钱往那车夫手里一塞,赶忙逃上楼来,连不敢看那车夫的脸。中国民间又说小孩的眼睛最净,睡梦里会微笑,是菩萨在教他,而有时无端惊恐,则是他见了不祥不洁了。张爱玲一点亦不研究时事,但她和我说日本的流行歌非常悲哀,这话便是说日本将亡,当时我连不敢告诉池田,他若知道,应当大惊痛哭。
(五)
张爱玲喜闻气味,油漆与汽油的气味她亦喜欢闻闻。她喝浓茶,吃油腻熟烂之物。她极少买东西,饭菜上头却不悭刻,又每天必吃点心,她调养自己像只红嘴绿鹦哥。有余钱她买衣料与胭脂花粉。她还是小女孩时就有一篇文字在报上登了出来,得到五元,大人们说这是第一次稿费,应当买本字典做纪念,她却马上拿这钱去买了口红。
她母亲是清末南京黄军门的小姐,西洋化的漂亮妇人,从小要训练爱玲做个淑女,到底灰了心。她母亲教她如何巧笑,爱玲却不笑则已,一笑即张开嘴大笑,又或单是喜孜孜的笑容,连她自己亦忘了是在笑,有点傻里傻气。爱玲向我如此形容她自己,她对于这种无可奈何的事只觉得非常开心。又道:“我母亲教我淑女行走时的姿势,但我走路总是冲冲跌跌,在房里也会三天两天撞着桌椅角,腿上磕破皮肤便是瘀青,我就红药水搽了一大搭,姑姑每次见了一惊,以为伤重流血到如此。”她说时又觉得非常开心。
爱玲给我看小时她母亲从埃及带给她的两串玻璃大珠子,一串蓝色,一串紫红色,我当即觉得自己是男孩子,看不起这种女孩子的东西。她还给我看她小时的作文。她十四岁即写有一部《摩登红楼梦》,订成上下两册的手抄本,开头是秦锺与智能儿坐火车私奔杭州,自由恋爱结了婚,但是经济困难,又气又伤心,而后来是贾母带了宝玉及众姊妹来西湖看水上运动会,吃冰淇淋。我初看时一惊,怎么可以这样煞风景,但是她写得来真有理性的清洁。
张爱玲是使人初看她诸般不顺眼,她决不迎合你,你要迎合她更休想。你用一切定型的美恶去看她总看她不透,像佛经里说的不可以三十二相见如来,她的人即是这样的神光离合。偶有文化人来到她这里勉强坐得一回,只觉对她不可逼视,不可久留。好的东西原来不是叫人都安,却是要叫人稍稍不安。
她但凡做什么,都好像在承当一件大事,看她走路时的神情就非同小可,她是连拈一枚针,或开一个罐头,也一脸理直气壮的正经。众人惯做的事,虽心不在焉亦可以做得妥当的,在她都十分吃力,且又不肯有一点迁就。但她也居然接洽写稿的事两不吃亏,用钱亦预算排得好好的。她处理事情有她的条理,亦且不受欺侮。一次路遇瘪三抢她的手提包,争夺了好一回没有被夺去,又一次瘪三抢她手里的小馒头,一半落地,一半她仍拿了回来。
我在人情上银钱上,总是人欠欠人,爱玲却是两讫,凡是像刀截的分明,总不拖泥带水。她与她姑姑分房同居,两人锱铢必较。她却也自己知道,还好意思对我说:“我姑姑说我财迷。”说着笑起来,很开心。她与炎樱难得一同上街去咖啡店吃点心,亦必先言明谁付账。炎樱是个印度女子,非常俏皮,她有本领说得那咖啡店主犹太人亦软了心肠,少算她的钱,爱玲向我说起又很开心。
爱玲的一钱如命,使我想起小时正月初一用红头绳编起一串压岁钱,都是康熙道光的白亮铜钱,亦有这种喜悦。我笑爱玲:“有的父亲给子女学费,诉苦说我的钱个个有血的,又或说是血汗。”爱玲听了很无奈,笑道:“我的钱血倒没有,是汗血的钱只使人心里难受,也就不这般可喜了。”
爱玲每用钱,都有一种理直气壮,是慷慨是节俭,皆不夹杂丝毫夸张。一次说起周佛海家,她道,那么多值钱的东西都其气不扬,没有喜意,我看过之后,只觉宁可不要富贵了。又爱玲住的公寓,邻房是个德国人,悭吝的叫人连不好笑,爱玲道:“西洋人都是悭吝的,他们虽会投资建设大工程,又肯出钱办慈善事业,到底亦不懂得有一种德性叫慷慨。”
(六)
爱玲从来不牵愁惹恨,要就是大哭一场。她告诉我有过两回,一回是她十岁前后,为一个男人,但我记不得是爱玲讨厌他或喜欢他而失意,就大哭起来。又一回是在香港大学读书时,一年放暑假,仿佛是因炎樱没有等她就回上海家去了,她平时原不想家,这次却倒在床上大哭大喊的不可开交。她文章里惯会描画恻恻轻怨,脉脉情思,静静泪痕,她本人却宁像晴天落白雨。
她道:“你说没有离愁,我想我也是的,可是上回你去南京,我竟要感伤了。”但她到底也不是个会缠绵悱恻的人。还有一次她来信说:“我想过,你将来就只是我这里来来去去亦可以。”她是想到婚姻上头,不知如何是好,但也就不再去多想了。
前此我问爱玲向来对结婚的想法,她说她没有怎样去想这个。她且亦不想会与何人恋爱,连追求她的人好像亦没有过,若有,大约她亦不喜。总之现在尚早,等到要结婚的时候就结婚,亦不挑三挑四。有志气的男人对于结婚不结婚都可以慷慨,而她是女子,却亦能如此。
但她想不到会遇见我。我已有妻室,她并不在意。再或我有许多女友,乃至挟妓游玩,她亦不会吃醋。她倒是愿意世上的女子都喜欢我。而她与我是即使不常在一起,相隔亦只如我一人在房里,而她则去厨下取茶。我们两人在的地方,他人只有一半到得去的,还有一半到不去的。
我与爱玲亦只是男女相悦,《子夜歌》里称“欢”,实在比称爱人好。两人坐在房里说话,她会只顾孜孜的看我,不胜之喜,说道:“你怎这样聪明,上海话是敲敲头顶,脚底板亦会响。”后来我亡命雁荡山时读到古人有一句话:“君子如响”,不觉的笑了。她如此兀自欢喜得诧异起来,会只管问:“你的人是真的么?你和我这样在一起是真的么?”还必定要我回答,倒弄得我很僵。一次听爱玲说旧小说里有“欲仙欲死”的句子,我一惊,连声赞道好句子,问她出在哪一部旧小说,她亦奇怪,说:“这是常见的呀”。其实却是她每每欢喜得欲仙欲死,糊涂到竟以为早有这样的现成语。
可是天下人要像我这样喜欢她,我亦没有见过。谁曾与张爱玲晤面说话,我都当它是件大事,想听听他们说她的人如何生得美,但他们竟连惯会的评头品足亦无。她的文章人人爱,好像看灯市,这亦不能不算是一种广大到相忘的知音,但我觉得他们总不起劲。我与他们一样面对着人世的美好,可是只有我惊动,要闻鸡起舞。
杂志上也有这样的批评,说张爱玲的一枝笔千娇百媚,可惜意识不准确。还有南京政府的一位教育部长向我说:“张小姐于西洋文学有这样深的修养,年纪轻轻可真是难得。但她想做主席夫人,可真是不好说了!”我都对之又气恼又好笑。关于意识的批评且不去谈它,因为爱玲根本没有去想革命神圣。但主席夫人的话,则她文章里原写的是她在大马路外滩看见警察打一个男孩,心想做了主席夫人就可拔刀相助,但这一念到底亦不好体系化的发展下去云云,如此明白,怎会不懂?而且他们说她文彩欲流,说她难得,但是他们为什么不也像我的欢喜她到了心里去。
七月间宇垣大将来上海,我说起张爱玲,他想要识面,我即答以不可招致,往见亦还要先问过她。熊剑东几次要宴请张爱玲,且要我陪同往见,我都给她谢绝了。我惟介绍了池田,每次他与爱玲见面,我在一道,都如承大事。池田说,他当炎樱是他的妹妹,当张小姐是他的姊姊,比他更是大人。张爱玲也说池田好,但是我看池田并没有从她受到什么影响。
我与爱玲只是这样,亦已人世有似山不厌高,海不厌深,高山大海几乎不可以是儿女私情。我们两人都少曾想到要结婚。但英娣竟与我离异,我们才亦结婚了。是年我三十八岁,她二十三岁。我为顾到日后时局变动不致连累她,没有举行仪式,只写婚书为定,文曰:
胡兰成张爱玲签订终身,结为夫妇,愿使岁月静好,现世安稳。
上两句是爱玲撰的,后两句我撰,旁写炎樱为媒证。
我们虽结了婚,亦仍像是没有结过婚。我不肯使她的生活有一点因我之故而改变。两人怎样亦做不像夫妻的样子,却依然一个是金童,一个是玉女。
(七)
世人多知恶的东西往往有大威力,如云恶煞,会惊得人分开顶门骨,轰去魂魄,不知好的东西亦可以有大威力,它使人直见性命,亦有这样的惊。佛经里描写如来现相,世界起六种十八相震动,竟像是热核炸弹投下的震动。但恶煞的威是威吓、惊是惊怖,使人藐小,好的东西则威如祥麟威凤的威,惊是惊喜,使人飞扬。惟有好的东西亦发挥了大威力,才能使恶煞的大威力亦化凶为吉。但西洋人惟发见了神,他们的人依然是燔祭的牺牲,不及中国人的可以直见性命,谁挡在面前,虽释迦亦可以一棒打杀,如汉高祖斩蛇开径。
我小时看花是花,看水是水,见了檐头的月亮有思无念,人与物皆清洁到情意亦即是理性。大起来受西洋精神对中国文明的冲击,因我坚起心思,想要学好向上,听信理论,且造作感情以求与之相合,反为弄得一身病。《红楼梦》里贾宝玉病重,和尚来说会医,袭人等把他身上带的通灵宝石解下来递出去,那和尚接在手里只见玉色暗漠昏浊,不觉长叹一声道,青梗峰下,别来十五年矣,竟如此为贪嗔爱痴所困,你那本性光明何在也!我读到这一节,回味过来,真要掩泣。
我在爱玲这里,是重新看见了我自己与天地万物,现代中国与西洋可以只是一个海晏河清。《西游记》里唐僧取经,到得雷音了,渡河上船时梢公把他一推,险些儿掉下水去,定性看时,上游头淌下一个尸身来,他吃惊道,如何佛地也有死人,行者答师父,那是你的业身,恭喜解脱了。我在爱玲这里亦有看见自己的尸身的惊。我若没有她,后来亦写不成《山河岁月》。
我们两人在房里,好像“照花前后镜,花面交相映”,我与她是同住同修,同缘同相,同见同知。爱玲极艳。她却又壮阔,寻常都有石破天惊。她完全是理性的,理性到得如同数学,它就只是这样的,不着理论逻辑,她的横绝四海,便像数学的理直,而她的艳亦像数学的无限。我却不准确的地方是夸张,准确的地方又贫薄不足,所以每要从她校正。前人说夫妇如调琴瑟,我是从爱玲才得调弦正柱。
前时我在香港,买了贝多芬的唱片,一听不喜,但贝多芬称为乐圣,必是我不行,我就天天刻苦开来听,努力要使自己懂得它为止。及知爱玲是九岁起学钢琴学到十五岁,我正待得意,不料她却说不喜钢琴,这一言就使我爽然若失。又我自中学读书以来,即不屑京戏绍兴戏流行歌等,亦是经爱玲指点,我才晓得它的好,而且我原来是欢喜它的。《大学》里说:“所谓诚其意者,毋自欺也,如恶恶臭,如好好色。”我是现在才有了自己。
爱玲把现代西洋文学读得最多,两人在房里,她每每讲给我听,好像“十八只抽屉”,志贞尼姑搬出吃食请情郎。她讲给我听萧伯纳、赫克斯莱、桑茂忒芒,及劳伦斯的作品。她每讲完之后,总说“可是他们的好处到底有限制”,好像尘渎了我倾听似的。她一点也不觉得我的英文不好有何不足,反而是她多对我小心抱歉。可是对西洋的古典作品她没有兴致,莎士比亚、歌德、嚣俄她亦不爱。西洋凡隆重的东西,像他们的壁画、交响曲、革命或世界大战,都使人觉得吃力,其实并不好。爱玲宁是只喜现代西洋平民精神的一点。托尔斯泰的《战争与和平》,我读了感动的地方她全不感动,她反是在没有故事的地方看出有几节描写得好。她不会被哄了去陪人歌哭,因为她的感情清到即是理性。连英娣与我离异的那天,我到爱玲处有泪,爱玲亦不同情。
我从来不见爱玲买书,她房里亦不堆书。我拿了《诗经》、乐府诗、李义山诗来,她看过即刻归还。我从池田处借来日本的版画、浮世绘,及塞尚的画册,她看了喜欢,池田说那么给她吧,她却不要。她在文章里描写的几块衣料,我问她,她只在店里看了没有买得,我觉可惜,她却一点亦不觉得有遗憾。爱玲是像陌上桑里的秦罗敷,羽林郎里的胡姬,不论对方怎样的动人,她亦只是好意,而不用情。
她对我这样百依百顺,亦不因我的缘故改变她的主意。我时常发过一阵议论,随又想想不对,与她说:“照你自己的样子就好,请不要受我的影响。”她笑道:“你放心,我不依的还是不依,虽然不依,但我还是爱听。”她这个人呀,真真的像天道无亲。
一个人诚了意未必即能聪明,却是“欲诚其意者,先致其知,致知在格物”,要聪明了然后能意诚,知尚在意之先。且不能以致知去格物,而是格物尚在致知之先。格物完全是一种天机。爱玲是其人如天,所以她的格物致知我终难及。爱玲的聪明真像水晶心肝玻璃人儿。我以为中国古书上头我可以向她逞能,焉知亦是她强。两人并坐同看一本书,那书里的句子便像街上的行人只和她打招呼,但我真高兴我是与她在一起。读《诗经》,我当她未必喜欢大雅,不想《诗经》亦是服她的,有一篇只念了开头两句:“倬彼云汉,昭回于天”,爱玲一惊,说:“啊!真真的是大旱年岁。”又古诗十九首念到:“燕赵有佳人,美者颜如玉,被服罗裳衣,当户理清曲。”她诧异道:“真是贞洁,那是妓女呀!”又同看《子夜歌》:“欢从何处来,端然有忧色。”她叹息道:“这端然真好,而她亦真是爱他!”我才知我平常看东西以为懂了,其实竟未懂得。
爱玲不看理论的书,连不喜历史。但我还是看了她的一篇写衣裳的散文,才与民国初年以来的许多大事觌面相见相知,而她这篇文章亦写衣裳只是写衣裳,全不用环境时代来说明。爱玲是凡她的知识即是与世人万物的照胆照心。
(八)
张爱玲是民国世界的临水照花人。看她的文章,只觉得她什么都晓得,其实她却世事经历得很少,但是这个时代的一切自会来与她交涉,好像“花来衫里,影落池中”。一日清晨,我与她步行同去美丽园,大西路上树影车声,商店行人,爱玲心里喜悦,与我说:“现代的东西纵有千般不是,它到底是我们的,与我们亲。”
爱玲的母亲还在南洋,姑姑已先从欧洲回来,今在怡和洋行做事,一日她说起柏林战时不知破坏得如何了,因就讲论柏林的街道,我问爱玲,爱玲答:“我不想出洋留学,住处我是喜欢上海。”所以我政治上诸般作为,亦终不想要移动她。
我与爱玲同看日本的版画、浮世绘、朝鲜的瓷器,及古印度的壁画集,我都伺候看她的脸色,听她说那一幅好,即使只是片言只语的指点,我才也能懂得它果然是非常好的。还有爱玲文章里描写民间小调里的鼓楼打更,都有一统江山的安定,我才亦对这些东西另眼相看。可是随即我跟爱玲去静安寺街上买小菜,到清冷冷的洋式食品店里看看牛肉鸡蛋之类,只觉与我刚才所懂得的中国文明全不调和,而在她则只觉非常亲切,她的新就是新得这样刺激的。
我与她同看西洋画册子,拉斐尔与达文西的作品,她只一页一页的翻翻过,翻到米开朗基罗雕刻的人像“黎明”,她停了细看一回,她道:“这很大气,是未完工的。”塞尚的画却有好几幅她给我讲说,画里人物的那种小奸小坏使她笑起来。爱玲自己便是爱描写民国世界小奸小坏的市民,她的《倾城之恋》里的男女,漂亮机警,惯会风里言、风里语,作张作致,再带几分玩世不恭,益发幻美轻巧了,背后可是有着对人生的坚执,也竟如火如荼,惟像白日里的火山,不见焰,只见是灰白的烟雾。他们想要奇特,结局只平淡的成了家室,但是也有着对于人生的真实的如泣如诉。
现代大都市里的小市民不知如何总是委屈的,他们的小奸小坏,小小的得意,何时都会遇着大的悲惨决裂。现代的东西何时都会使人忽然觉得它不对,不对到可怕的程度,连眼前那样分明的一切,都成了不可干涉。爱玲与我说:“西洋人有一种阻隔,像月光下一只蝴蝶停在带有白手套的手背上,真是隔得叫人难受。”又一次她告诉我:“午后公寓里有两个外国男孩搭电梯,到得那一层楼上,楼上惟见太阳荒荒,只听得一个说再会。真是可怕!”
扫帚星的尾巴有毒,扫着地球,地球上就要动刀兵或是发生大瘟疫,但不致因此毁灭,如今民国世界便像这样,亦不过是被西洋的尾巴扫着罢了,所以爱玲还是从赫克斯莱的影响走了出来。
中国文明就是能直见性命,所以无隔。我与爱玲两人并坐着看《诗经》,这里也是“既见君子”,那里也是“邂逅相见”,她很高兴,说:“怎么这样容易就见着了!”而庾信的赋里更有:
树里闻歌,枝中见舞,恰对妆台,诸窗倂开,遥看已识,试唤便来。
爱玲与阳台外的全上海即是这样的相望相识,叫一声都会来到房里似的。西洋人与现世无缘,他们的最高境界倒是见着了神,而中国人则“见神见鬼”是句不好听的话。
中国人说天意,说天机,故又爱玲在人世是诸天游戏,正经亦是她,调皮亦是她。我是从爱玲才晓得了中国人有远比西洋人的幽默更好的滑稽。汉乐府有个流荡在他县的人,逆旅主妇给他洗补衣裳,“夫婿从门来,斜倚西北眄”,我与爱玲念到这里,她就笑起来道:“是上海话眼睛描发描发。”再看底下时即是:“语卿且勿眄”,她诧异道:“啊!这样困苦还能滑稽,怎么能够!”两人把它来读完:“语卿且勿眄,水清石自见,石见何磊磊,远行不如归。”这末一句竟是对困苦亦能生气撒娇。这种滑稽是非常阳气的糊涂。
爱玲自己,便亦调皮得叫人把她无奈。报上杂志上凡有批评她的文章的,她都剪存,还有冒昧写信来崇拜她,或希望她为前进思想服务的,她亦收存,虽然她也不听,也不答,也不作参考。我是人家赞扬我不得当,只觉不舒服,责难我不得当,亦只咄得一声“无聊”,但他若是诚恳的,我虽不睬他,亦多少珍重他的这份心意。爱玲却不然。她笑道:“我是但凡人家说我好,说得不对我亦高兴。”劝告她责难她得不对,则她也许生气,但亦往往只是诧异。他们说好说坏没有说着了她,倒反给她如此分明的看见了他们本人。她每与姑姑与炎樱,或与我说起,便笑骂,只觉又是无奈,又是开心好玩。是这样的形相,即不论他们当中虽有心意诚恳的,她亦一概不同情。爱玲论人,总是把聪明放在第一,与《大学》的把格物致知放在诚其意之先,正好偶合。
又我与她正在用我们自己的言语要说明一件事,她却会即刻想到一句文艺腔,脱口而出,注曰,这是时人的,两人都笑起来,她这人就有这样坏。连她身为女子,亦会揶揄可笑的形容她自己。苏州灵岩寺客堂挂有印光法师写的字,是“极乐世界,无有女人,女人到此,化童男身。”苏青去游,见了很气,爱玲却丝毫没有反感。
我是从爱玲才晓得了汉民族的壮阔无私,活泼喜乐,中华民国到底可以从时代的巫魇走了出来的。爱玲是吉人,毁灭轮不到她,终不会遭灾落难。
夏天一个傍晚,两人在阳台上眺望红尘霭霭的上海,西边天上余辉未尽,有一道云隙处清森遥远。我与她说时局要翻,来日大难,她听了很震动。汉乐府有:“来日大难,口燥唇干,今日相乐,皆当喜欢”。她道:“这口燥唇干好像是你对他们说了又说,他们总还不懂,叫我真是心疼你。”又道:“你这个人嗄,我恨不得把你包包起,像个香袋儿,密密的针线缝缝好,放在衣箱里藏藏好。”不但是为相守,亦是为疼惜不已。随即她进房里给我倒茶,她拿茶出来走到门边,我迎上去接茶,她腰身一侧,喜气洋洋的看着我的脸,眼睛里都是笑。我说:“啊,你这一下姿势真是艳!”她道:“你是人家有好处容易得你感激,但难得你满足。”她在我身旁等我吃完茶,又收杯进去,看她心里还是喜之不尽,此则真是“今日相乐,皆当喜欢”了,虽然她刚才并没有留心到这两句。
(九)
一日午后好天气,两人同去附近马路上走走。爱玲穿一件桃红单旗袍,我说好看,她道:“桃红的颜色闻得见香气。”还有我爱看她穿那双绣花鞋子,是她去静安寺庙会买得的,鞋头连鞋帮绣有龙凤,穿在她脚上,线条非常柔和。她知我喜欢,我每从南京回来,在房里她总穿这双鞋。
有时晚饭后灯下两人好玩,挨得很近,脸对脸看着。她的脸好像一朵开得满满的花,又好像一轮圆得满满的月亮。爱玲做不来微笑,要就是这样无保留的开心,眼睛里都是满满的笑意。我当然亦满心里欢喜,但因为她是这样美的,我就变得只是正经起来。我抚她的脸,说道:“你的脸好大,像平原缅邈,山河浩荡。”她笑起来道:“像平原是大而平坦,这样的脸好不怕人。”她因说《水浒》里有写宋江见玄女,我《水浒》看过无数遍,惟有这种地方偏记不得,央她念了,却是“天然妙目,正大仙容”八个字,我一听当下呆住,竟离开了刚才说话的主题,却要到翌日,我才与她说:“你就是正大仙容。”但上句我未听在心里,央她又念了一遍。
还有一次也是,我想要形容爱玲行坐走路,总口齿艰涩,她就代我说了,她道:“《金瓶梅》里写孟玉楼,行走时香风细细,坐下时淹然百媚。”我觉得“淹然”两字真是好,要爱玲说来听听,爱玲道:“有人虽遇见怎样的好东西亦滴水不入,有人却像丝绵蘸着了胭脂,即刻渗开得一塌糊涂。”又问我们两人在一淘时呢?她道:“你像一只小鹿在溪里吃水。”
我问爱玲,她答说还没有过何种感觉或意态形致,是她所不能描写的,惟要存在心里过一过,总可以说得明白。她是使万物自语,恰如将军的战马识得吉凶,还有宝刀亦中夜会得自己鸣跃。我说苏青的脸美,爱玲道:“苏青的美是一个‘俊’字,有人说她世俗,其实她俊俏,她的世俗也好,她的脸好像喜事人家新蒸的雪白馒头,上面点有胭脂。”
爱玲与炎樱要好,炎樱这个名字是爱玲给她取的,她的本名是Fatima。她像敦煌壁画里的天女,古印度的天女是被同时代西方的巴比仑与埃及所照亮,炎樱亦这样,是生于现代西洋的,但仍是印度女子,且住在中国的上海。她比爱玲淘气。她只会说几句中国话,但对她所识的三五个中国字非常有兴趣,建议要与爱玲两人制新衣裳,面前各写一句联语,走到街上,忽然两人会合在一起,忽然上下联成了对。
爱玲每赞炎樱生得美,很大气,知道我也喜欢她,爱玲很高兴。炎樱每来,活动不停,三人在房里,我只觉笨拙,不但是我英文不行之故,即使她是讲的上海话,恐怕我亦应接不及。她又喜理论,但她滔滔说了许多,结果只像一阵风来去得无影无踪。有时爱玲要我评评,我就试与炎樱辩答。我说,但是事实如此,她道:“真可怕!”我说社会本来就是这样的,她道:“怎么可以这样愚蠢!”都只是小女孩的责怪,我的逻辑只好完全失败,而且甘愿认输。我忽然想起古乐府“欢作沉水香,侬作博山炉”,却又不切合眼前的光景,但与炎樱说话,的确好像闻得见香气。
爱玲与外界少往来,惟一次有个文化人被日本宪兵队逮捕,爱玲因倾城之恋改编舞台剧上演,曾得他奔走,由我陪同去慰问过他家里,随后我还与日本宪兵队说了,要他们可释放则释放。应酬场面上,只一次同去过邵洵美家里。又当初有一晚上,我去苏青家里,恰值爱玲也来到。她喜欢也在众人面前看着我,但是她又妒忌,会觉得她自己很委屈。她惟常到炎樱家里,虽与我一道她亦很自然。我美丽园家里她亦来过几次,但只住过一晚。平时她惟与姑姑朝夕相见说话,有什么事商量商量。
她文章里有写姑姑说,从前家里养叫蝈蝈剥青豆饲它,她正听姑姑说下去,却没有了。如今手头没有爱玲写的书,不大记得,但心里尚留着一种好,那是什么意义或情调都还未有的好,如前人写琴,“再鼓听愈淡”,人世只是历然都在,什么扰乱亦没有。
(十)
张佩纶当年为御史,排击李鸿章议和,力主与法军战,朝廷命他督师,兵败基隆,贬窜热河七年。罚满释归京师,听候起复,例须谒李鸿章,意外得到李鸿章的小姐赐以颜色,忧患感激,遂成婚配。但李鸿章因翁婿避嫌,倒反不好保奏了,夫妻遂居南京。同辈张之洞是两湖总督,吴大征是江苏巡抚,盛宣怀是邮传部大臣,他们或经过南京晤见,故人樽酒平生,张佩纶曾悲歌慷慨,泣数行下。爱玲说祖父好,姑姑却不喜,姑姑的漂亮是祖母的,她说祖父相貌不配。
张家在南京的老宅,我专为去踏看过,一边是洋房,做过立法院,已遭兵燹,正宅则是旧式建筑,完全成了瓦砾之场,废池颓垣,惟剩月洞门与柱础阶砌,尚可想见当年花厅亭榭之迹。我告诉爱玲,爱玲却没有怀古之思。她给我看祖母的一只镯子,还有李鸿章出使西洋得来的小玩意金蝉金象,当年他给女儿的,这些东西,连同祖母为女儿时的照片,在爱玲这里就都解脱了兴亡沧桑。
爱玲喜在房门外悄悄窥看我在房里。她写道:“他一人坐在沙发上,房里有金粉金沙深埋的宁静,外面风雨淋琅,漫山遍野都是今天。”
她是把古人亦当他们是今天的人。非烟传里的那女子,与人私通,被拷打至死,惟云“生得相亲,死亦无恨”,遂不复言,爱玲说道,当然是这样的,而且只可以是这样的。因为爱玲自己就是这样一个柔艳刚强的女子。她又说会真记里崔莺莺写给张生的信好,非常委屈,却又这样亮烈,而张生竟还去郑家看她,她当然不见。
好句是使人直见性命。白居易长恨歌有“宛转蛾眉马前死”,爱玲叹息道,这怎么可能!这样委屈,但是心甘情愿,为了他,如同为一代江山,而亦真是这样的。我听了忽然想起汪先生,汪先生便像是这样的宛转死在中华民国马前。
爱玲与我说赵飞燕,汉成帝说飞燕是“谦畏礼义人也”,她回味这“谦畏”两字,只觉得无限的喜悦,无限的美,女心真像是丝棉蘸着臙脂,都渗开化开了,柔艳到如此,但又只是礼义的清嘉。爱玲又说赵飞燕与宫女踏歌“赤凤来”,一阵风起,她的人想要飞去,忽然觉得非常悲哀。后来我重翻飞燕外传,原文却并没有写得这样好,爱玲是她自己有这样一种欲仙欲死,她的人还比倚新妆的飞燕更美。
爱玲真是锦心绣口。房里两人排排坐在沙发上,从姓胡姓张说起,她道:“姓崔好,我母亲姓黄亦好,《红楼梦》里有黄金莺,非常好的名字,而且是写的她与藕官在河边柳荫下编花篮儿,就更见这个名字好了。”她说姓胡好,我问姓张呢?她道:“‘张’字没有颜色气味,亦还不算坏。牛僧孺有给刘禹锡的诗,是这样一个好人,却姓了牛,名字又叫僧孺,真要命。”我说胡姓来自陇西,称安定胡,我的上代也许是羌,羌与羯氐鲜卑等是五胡。爱玲道:“羌好。羯很恶,面孔黑黑的。氐有股气味。鲜卑是黄胡须。‘羌’字像只小山羊走路,头上两只角。”
她只管看着我,不胜之喜,用手指着我的眉毛,说:“你的眉毛。”抚到眼睛,说:“你的眼睛。”抚到嘴上,说:“你的嘴。你嘴角这里的涡我喜欢。”她叫我“兰成”,我当时竟不知如何答应。我总不当面叫她名字,与人是说张爱玲,她今要我叫来听听,我十分无奈,只叫得一声“爱玲”,登时很狼狈,她也听了诧异,道:“啊?”对人如对花,虽日日相见,亦竟是新相知,荷花娇欲语,你不禁想要叫她,但若是真叫了出来,又怕要惊动三世十方。
房里墙壁上一点斜阳,如梦如幻,两人像金箔银纸剪贴的人形。但是我们又很俗气。爱玲的书销路最多,稿费比别人高,不靠我养她,我只给过她一点钱,她去做一件皮袄,式样是她自出心裁,做得来很宽大,她心里欢喜,因为世人都是丈夫给妻子钱用,她也要。又两人去看崔承禧的舞,回来时下雨,从戏院门口讨得一辆黄包车,雨蓬放下,她坐在我身上,可是她生得这样长大,且穿的雨衣,我抱着她只觉诸般不宜,但真是难忘的实感。
且我们所处的时局亦是这样实感的,有朝一日,夫妻亦要大限来时各自飞。但我说:“我必定逃得过,惟头两年里要改姓换名,将来与你虽隔了银河亦必定找得见。”爱玲道:“那时你变姓名,可叫张牵,又或叫张招,天涯地角有我在牵你招你。”
爱玲还与我说起李义山的两句诗,这又是我起先看过了亦没有留心的,诗曰:
星沉海底当窗见,雨过河原隔座看。
其后我亲见日本败战,南京政府覆没,又其后国民政府亦逃亡,解放军渡长江,我总要想起这两句,见星沉海底虽惊痛,但更可惜解放军只成了南下而牧马。
张隆溪:文学理论的兴衰_爱思想
在西方文学研究的领域, 二十世纪可以说是一个理论的时代, 但也是理论不断兴盛, 然后又盛极而衰的时代。二十世纪初, 俄国一些学者们首先把文学研究和语言学联系起来, 从文学语言本身去探讨文学的特性, 提出了著名的 “文学性” 概念 (литературность, 英文 literariness), 这是一个看来简单、实际上颇具内涵而且重要的概念。所谓文学性, 就是把文学语言区别于其他语言的本质特性, 是使文学成其为文学的东西。罗曼 • 雅各布森(Roman Jakobson) 认为文学语言突出诗性功能, 不是指向外在现实, 而是尽量偏离实用目的, 把注意力引向文学作品的语言本身, 引向音韵、词汇、句法等形式因素。维克多 • 施克洛夫斯基 (Victor Shklovsky) 提出 “陌生化” 概念 (остранение, 英文 defamiliarization), 认为艺术的目的是使人对事物有新鲜感, 而不是司空见惯, 习以为常, 所以采用新的角度和修辞手法, 变习见为新知, 化腐朽为神奇。从文学史的发展来看,“陌生化” 往往表现为把过去不入流的形式升为正宗, 从而促成新风格、新文体和新流派的产生。这一观念重视文学语言和文学形式本身, 强调文学与现实的距离, 而非现实的模仿或反映。正如施克洛夫斯基所说:“艺术总是独立于生活, 在它的颜色里永远不会反映出飘扬在城堡上那面旗帜的颜色。”通过这鲜明生动的比喻,“这面旗帜就已经给艺术下了定义”〔1〕。米哈依尔 • 巴赫金研究陀思妥耶夫斯基的作品, 认为其中不是只有作者权威的声音, 而是有许多不同的语调和声音, 构成表现不同思想意识的 “复调小说”, 如果脱离这种“复调” 空谈内容, 就不可能把握问题的实质, 因为 “不懂得新的观察形式, 就不可能正确理解借助于这种形式才第一次在生活中看到和显露出来的东西。正确地理解起来, 艺术形式并不是外在地装饰已经找到的现成的内容, 而是第一次地让人们找到和看见内容”〔2〕。这里反复强调的“第一次”, 与施克洛夫斯基的“陌生化” 概念一样, 也突出了艺术的目的是使人对生活中的事物获得新鲜感。事实上, 这是从俄国形式主义到捷克结构主义贯穿始终的思想, 是俄国形式主义对文学理论的重要贡献。
俄国形式主义虽然被称为形式主义, 但这种理论从一开始就和语言学有密切关系, 注意语言的结构和功能。雅各布森从莫斯科到布拉格, 后来又到美国, 对于俄国形式主义和捷克结构主义理论, 都做出了很大贡献。捷克学者穆卡洛夫斯基 (Jan Mukalovsky) 认为, 日常语言会由于长期使用而趋于自动化, 失去新鲜感, 而文学语言则尽量 “突出”(foregrounding) 自身, 不是传达信息, 而是指向文学作品自身的世界。这一观念显然与俄国形式主义有直接的联系。从莫斯科到布拉格再到巴黎, 从俄国形式主义到捷克结构主义再到法国结构主义, 这就形成二十世纪文学理论发展的三个重要阶段。六十年代之后, 结构主义从法国传到英美, 成为西方文学理论一股颇有影响的新潮流。
在二十世纪四十和五十年代, 英美的新批评同样注重文学的形式和语言, 通过细读和修辞分析, 力图把文学之为文学, 具体化到一个文本和文学语言的层面来理解。文萨特 (W. K. Wimsatt) 与比尔兹利 (M. C. Beardsley) 提出两个著名概念, 一个是 “意图迷误”(intentional fallacy), 认为文学作品是本身自足的存在, 作品的意义并非作者意图的表现。另一个是“感受迷误”(affective fallacy), 即自足存在的作品之意义, 无关读者众说纷纭的解释。这两个“迷误” 概念就使文学的文本 (text) 独立于作者和读者, 成为韦勒克 (René Wellek) 所谓 “具有特殊本体状态的独特的认识客体”〔3〕。韦勒克与沃伦(Austin Warren) 合著的《文学理论》一书, 就提到俄国形式主义的基本观点, 并把文学研究分为内在和外在两种。他们认为从社会、历史、思想、作者生平等方面去研究文学, 那是文学的外部研究, 而他们注重的是文学的内部研究, 即研究文学的语言和修辞, 包括音韵、节奏、意象、比喻、象征等形式特征。在作品分析方面, 尤其在诗的理解和阅读方面, 新批评取得了不可忽视的成就。
在五十年代末, 诺斯罗普 • 弗莱 (Northrop Frye) 在其《批评的解剖》一书中提出神话和原型批评, 就超出个别作品的细读, 为文学研究提供了比个别文本更广阔的理论框架。这种神话和原型批评所理解的文学是意象、原型、主题和体裁组成的一个自足系统, 批评家从这样的文学系统中, 可以找出一些具有普遍意义的原型(archetype)。这些原型“把一首诗同别的诗联系起来, 从而有助于把我们的文学经验统一成一个整体”〔4〕。原型在不同作品中反复出现, 有如昼夜交替、四季循环, 或者像各种仪节, 每年在一定时刻举行, 所以弗莱注重神话、仪式和历史的循环论, 把文学类型的演变与四季循环的自然节律相关联。对应于春天的是喜剧, 充满了希望和欢乐, 象征青春战胜衰朽; 对应于夏天的是传奇, 万物都丰茂繁盛, 富于神奇的幻想; 对应于秋天的是悲剧, 崇高而悲凉, 那是物盛当杀、牺牲献祭的时节, 表现英雄的受难和死亡; 对应于冬天的则是讽刺, 那是一个没有英雄的荒诞世界, 充满自我审视的黑色幽默。然而有如残冬去后, 又必是春回大地, 万物复苏, 牺牲献祭之后, 诸神又会复活一样, 讽刺模式之后, 文学的发展又有返回神话的趋势。原型批评从大处着眼, 注意不同作品之间的内在联系, 认为文学有一些基本程式, 这些最终来源于神话和祭祀仪式的程式是每一部新作得以产生的形式原因。所以弗莱说:“诗只能从别的诗里产生; 小说只能从别的小说里产生。文学形成文学, 而不是被外来的东西赋予形体: 文学的形式不可能存在于文学之外, 正如奏鸣曲、赋格曲和回旋曲的形式不可能存在于音乐之外一样。”〔5〕弗莱的原型批评在五十年代末, 就已经打破了新批评对作品的细读, 注重在不同文学作品下面, 去寻求决定文学形式因素的程式和原型, 这也就为后来从欧洲传来的结构主义, 在思想上奠定了基础。
弗莱的原型批评虽然超出新批评着眼于个别文本的细读, 但却没有否定新批评提出的 “意图迷误”。事实上, 二十世纪文学理论发展一个重要的趋势, 正是越来越否定作者的权威, 使批评成为独立于作者意图的一种创造。与此同时, 新批评提出的“感受迷误” 则完全被否定, 因为否定作者的同时, 文学理论也越来越注重读者在阅读和理解当中的积极作用。从现象学到阐释学, 再到德国的接受美学和美国的读者反应批评, 这就形成充分肯定读者作用的主流趋势。当然, 法国批评家罗兰 • 巴尔特 (Roland Barthes) 宣称作者已死, 好像读者的诞生非要以作者的死亡为代价, 那又是西方理论家喜欢走极端、言过其实的一个例子。凡大讲理论、奢谈作者已死的人, 往往正是从巴尔特这位作者那里接受了这一批评观念, 这在无形中就构成对其所谈理论本身的讽刺。我们在讨论理论问题时, 必须要有自己独立的见解和批判意识, 其重要性也由此可见一斑。
在西方文学研究的领域, 二十世纪可以说是一个理论的时代, 但也是理论不断兴盛, 然后又盛极而衰的时代。二十世纪初, 俄国一些学者们首先把文学研究和语言学联系起来, 从文学语言本身去探讨文学的特性, 提出了著名的 “文学性” 概念 (литературность, 英文 literariness), 这是一个看来简单、实际上颇具内涵而且重要的概念。所谓文学性, 就是把文学语言区别于其他语言的本质特性, 是使文学成其为文学的东西。罗曼 • 雅各布森(Roman Jakobson) 认为文学语言突出诗性功能, 不是指向外在现实, 而是尽量偏离实用目的, 把注意力引向文学作品的语言本身, 引向音韵、词汇、句法等形式因素。维克多 • 施克洛夫斯基 (Victor Shklovsky) 提出 “陌生化” 概念 (остранение, 英文 defamiliarization), 认为艺术的目的是使人对事物有新鲜感, 而不是司空见惯, 习以为常, 所以采用新的角度和修辞手法, 变习见为新知, 化腐朽为神奇。从文学史的发展来看,“陌生化” 往往表现为把过去不入流的形式升为正宗, 从而促成新风格、新文体和新流派的产生。这一观念重视文学语言和文学形式本身, 强调文学与现实的距离, 而非现实的模仿或反映。正如施克洛夫斯基所说:“艺术总是独立于生活, 在它的颜色里永远不会反映出飘扬在城堡上那面旗帜的颜色。”通过这鲜明生动的比喻,“这面旗帜就已经给艺术下了定义”〔1〕。米哈依尔 • 巴赫金研究陀思妥耶夫斯基的作品, 认为其中不是只有作者权威的声音, 而是有许多不同的语调和声音, 构成表现不同思想意识的 “复调小说”, 如果脱离这种“复调” 空谈内容, 就不可能把握问题的实质, 因为 “不懂得新的观察形式, 就不可能正确理解借助于这种形式才第一次在生活中看到和显露出来的东西。正确地理解起来, 艺术形式并不是外在地装饰已经找到的现成的内容, 而是第一次地让人们找到和看见内容”〔2〕。这里反复强调的“第一次”, 与施克洛夫斯基的“陌生化” 概念一样, 也突出了艺术的目的是使人对生活中的事物获得新鲜感。事实上, 这是从俄国形式主义到捷克结构主义贯穿始终的思想, 是俄国形式主义对文学理论的重要贡献。
俄国形式主义虽然被称为形式主义, 但这种理论从一开始就和语言学有密切关系, 注意语言的结构和功能。雅各布森从莫斯科到布拉格, 后来又到美国, 对于俄国形式主义和捷克结构主义理论, 都做出了很大贡献。捷克学者穆卡洛夫斯基 (Jan Mukalovsky) 认为, 日常语言会由于长期使用而趋于自动化, 失去新鲜感, 而文学语言则尽量 “突出”(foregrounding) 自身, 不是传达信息, 而是指向文学作品自身的世界。这一观念显然与俄国形式主义有直接的联系。从莫斯科到布拉格再到巴黎, 从俄国形式主义到捷克结构主义再到法国结构主义, 这就形成二十世纪文学理论发展的三个重要阶段。六十年代之后, 结构主义从法国传到英美, 成为西方文学理论一股颇有影响的新潮流。
在二十世纪四十和五十年代, 英美的新批评同样注重文学的形式和语言, 通过细读和修辞分析, 力图把文学之为文学, 具体化到一个文本和文学语言的层面来理解。文萨特 (W. K. Wimsatt) 与比尔兹利 (M. C. Beardsley) 提出两个著名概念, 一个是 “意图迷误”(intentional fallacy), 认为文学作品是本身自足的存在, 作品的意义并非作者意图的表现。另一个是“感受迷误”(affective fallacy), 即自足存在的作品之意义, 无关读者众说纷纭的解释。这两个“迷误” 概念就使文学的文本 (text) 独立于作者和读者, 成为韦勒克 (René Wellek) 所谓 “具有特殊本体状态的独特的认识客体”〔3〕。韦勒克与沃伦(Austin Warren) 合著的《文学理论》一书, 就提到俄国形式主义的基本观点, 并把文学研究分为内在和外在两种。他们认为从社会、历史、思想、作者生平等方面去研究文学, 那是文学的外部研究, 而他们注重的是文学的内部研究, 即研究文学的语言和修辞, 包括音韵、节奏、意象、比喻、象征等形式特征。在作品分析方面, 尤其在诗的理解和阅读方面, 新批评取得了不可忽视的成就。
在五十年代末, 诺斯罗普 • 弗莱 (Northrop Frye) 在其《批评的解剖》一书中提出神话和原型批评, 就超出个别作品的细读, 为文学研究提供了比个别文本更广阔的理论框架。这种神话和原型批评所理解的文学是意象、原型、主题和体裁组成的一个自足系统, 批评家从这样的文学系统中, 可以找出一些具有普遍意义的原型(archetype)。这些原型“把一首诗同别的诗联系起来, 从而有助于把我们的文学经验统一成一个整体”〔4〕。原型在不同作品中反复出现, 有如昼夜交替、四季循环, 或者像各种仪节, 每年在一定时刻举行, 所以弗莱注重神话、仪式和历史的循环论, 把文学类型的演变与四季循环的自然节律相关联。对应于春天的是喜剧, 充满了希望和欢乐, 象征青春战胜衰朽; 对应于夏天的是传奇, 万物都丰茂繁盛, 富于神奇的幻想; 对应于秋天的是悲剧, 崇高而悲凉, 那是物盛当杀、牺牲献祭的时节, 表现英雄的受难和死亡; 对应于冬天的则是讽刺, 那是一个没有英雄的荒诞世界,
充满自我审视的黑色幽默。然而有如残冬去后, 又必是春回大地, 万物复苏, 牺牲献祭之后, 诸神又会复活一样, 讽刺模式之后, 文学的发展又有返回神话的趋势。原型批评从大处着眼, 注意不同作品之间的内在联系, 认为文学有一些基本程式, 这些最终来源于神话和祭祀仪式的程式是每一部新作得以产生的形式原因。所以弗莱说:“诗只能从别的诗里产生; 小说只能从别的小说里产生。文学形成文学, 而不是被外来的东西赋予形体: 文学的形式不可能存在于文学之外, 正如奏鸣曲、赋格曲和回旋曲的形式不可能存在于音乐之外一样。”〔5〕弗莱的原型批评在五十年代末, 就已经打破了新批评对作品的细读, 注重在不同文学作品下面, 去寻求决定文学形式因素的程式和原型, 这也就为后来从欧洲传来的结构主义, 在思想上奠定了基础。
弗莱的原型批评虽然超出新批评着眼于个别文本的细读, 但却没有否定新批评提出的 “意图迷误”。事实上, 二十世纪文学理论发展一个重要的趋势, 正是越来越否定作者的权威, 使批评成为独立于作者意图的一种创造。与此同时, 新批评提出的“感受迷误” 则完全被否定, 因为否定作者的同时, 文学理论也越来越注重读者在阅读和理解当中的积极作用。从现象学到阐释学, 再到德国的接受美学和美国的读者反应批评, 这就形成充分肯定读者作用的主流趋势。当然, 法国批评家罗兰 • 巴尔特 (Roland Barthes) 宣称作者已死, 好像读者的诞生非要以作者的死亡为代价, 那又是西方理论家喜欢走极端、言过其实的一个例子。凡大讲理论、奢谈作者已死的人, 往往正是从巴尔特这位作者那里接受了这一批评观念, 这在无形中就构成对其所谈理论本身的讽刺。我们在讨论理论问题时, 必须要有自己独立的见解和批判意识, 其重要性也由此可见一斑。
在八十年代初, 英国批评家特瑞 • 伊格尔顿 (Terry Eagleton) 著有《文学理论》(Literary Theory: An Introduction, 1983)一书, 此书虽然作为一本入门的导论未必能尽如人意, 却成为英美大学校园里的畅销书, 学文学的学生几乎人手一册。但二十年之后, 他又写了一本书叫做《理论之后》(After Theory, 2004), 对越来越抽象虚玄、而且脱离现实、脱离文学的理论, 提出十分尖锐的批评。同一位作者写出这样两本很不相同的书, 也许颇具象征意味。其实在西方, 许多研究文学的学者和批评家都越来越不满意于理论取代文学、文化研究取代文学研究的趋向。进入二十一世纪以来, 理论热已明显地减退了。2006 年出版的美国比较文学学会最新的十年报告, 就对理论取代文学的趋向有十分深刻的反省, 并提出重新思考 “文学性” 的问题。当然, 历史从来不是一个简单的循环, 也不会简单回复到过去曾经有过的任何阶段。文学理论在二十世纪的发展, 自有其历史的背景和原因, 也有其成果和价值, 然而理论发展到极端, 似乎又盛极而衰, 走向自己的反面, 也并不难理解。究竟文学研究如何回归文学, 回到文学的鉴赏、分析和阐释, 重新帮助我们认识文学和人生的价值, 给我们新的指引和启示, 那是我们众多读者和研究者对于未来学术发展的期待。
注释:
〔1〕В. Шкловский, Хуложественная проза. Размышления и разборы (Москва, 1961), 6.
〔2〕М. Бахтин, Проблемы поэтики Достоевсково (Москва, 1963), 7-8.
〔3〕René Wellek and Austin Warren, Theory of Literature, 3rd ed. (New York: Harcourt Brace Jovanovich, 1975), p. 156.
〔4〕〔5〕Northrop Frye, Anatomy of Criticism: Four Essays (Princeton: Princeton University Press, 1957), p. 99,p.97.
〔6〕Fank Kermode, Shakespeare’s Language (London: Penguin, 2000), p. viii.
[[震惊了!我们一个同事是猩猩,今天被北京动物园的|https://www.douban.com/group/topic/49860713/]]
震惊了!我们一个同事是猩猩,今天被北京动物园的...
来自: 门柱 2014-03-07 10:58:54
标题:震惊了!我们一个同事是猩猩,今天被北京动物园的抓走了(Director's Cut Edition)
by 张大锤 2013.7.21 微信版
======================================================
我们一个同事是猩猩,今天被北京动物园的抓走了,大家都震惊了!一起工作半年多,居然没一个人发现他是猩猩!是楼下的大妈打电话给动物园举报后,大家才知道的。
单位租的写字楼楼下是绿地,老太太很多。大家都知道北京老太太责任心强,警惕性高,热爱生活,并且善于观察生活,所以说这次举报也在情理之中,因为是老太太举报的,如果是其他人举报,还可能怀疑是谁恶作剧,或者竞争对手整我们,是楼下老太太举报的,就有一定说服力了,因为老太太一般不轻易举报,但一出手,那基本十拿九稳了,可能这个同事真的有问题。
动物园来了一辆车两个人,来一看,说:“是猩猩。没错。”然后就准备抓走了,这时年轻的一个动物园人可能觉得就这样直接抓走不太好,对大家说:“是这样的,你们这个同事确实是猩猩。”接着走到我们同事跟前,用右手托起同事下巴,说:“大家看,你们同事的面部发黑,脸颊上有明显的脂肪组织的肉垫,有喉囊,这都是非常明显的特征,可以确定你们同事是猩猩了。“
然后又猛的拍了同事的后背一巴掌,同事受惊,”嗷!“的叫了一声,动物园人说:”大家听!这个叫声很有特点,短促,洪亮,使用颅腔共鸣,从叫声来判断,你们同事是一只苏门答腊黑猩猩,在亚洲分布非常稀少。可以说,你们公司对我国猩猩研究办了一件好事啊!“
动物园人意犹未尽,滔滔不绝:”猩猩是灵长目动物,主要分布在。。。。。。“这时年长的一个动物园人看不太下去,提醒说:”小王,差不多了,不要影响人家工作。“年轻动物园人停了下来,说:”不好意思,一不留神讲多了,我这人就是话密,再一个因了今天见到你们的猩猩,心情有些激动,因为不是在野外,而是在人类办公场所见到活生生的猩猩,而且是作为一个正式在职员工的猩猩,我的心情是非常激动的,因为。。。“年长的动物园人说:”小王!“年轻动物园人说:”对不起,我失态了!我们这就走。“说完拍了一下我们同事,说:”走吧。“
这样一说,基本就没办法了,同事还有些依依不舍,”欧~欧~“的拍了几下桌子,然后就被抓走了。大家都惊呆了!确实是没有想到。这个同事平时话也不多,工作认真,就是爱吃香蕉,谁都没想到居然是猩猩,人事部的这下有好果子吃了,怎么招人的居然把猩猩当员工给招进来了,医保公积金什么的都给上了,猩猩这一走,一堆活不知道怎么办,要损失不少了。
当代中国人与人之间关系有多冷漠可见一斑。这事儿一出,公司相当重视,第二天就召开了全体员工大会,由办公室刘主任主持,在会上刘主任说:”震惊!太震惊了!“
”堂堂一个500多人的大公司,居然混进一个猩猩当员工,还成为部门骨干,这太令人吃惊了!“
”简直是我们公司的耻辱!“刘主任欧~的拍了一下桌子
”这事儿一出,我们可就成业界笑柄了,光花钱摆平媒体网路就是一大笔钱,这钱谁出?!“
“以后还混不混了?”
”人事你们是干什么吃的!招人连是人是猩猩都分不出来吗?还要你们有什么用?“
”干脆解散算了!“主任非常愤怒,欧~的拍了一下桌子,站起来了,旁边的王干事赶紧递过来一根香蕉,说:”主任您别上火,慢慢说,有事儿咱慢慢说,您先吃根香蕉。“
刘主任吃了一根香蕉,稍微平静了一些,说:”张部长,你讲一下,到底是怎么回事儿,怎么给猩猩招进公司的?你讲一下。“
人事张部长比较腼腆,红着脸说:”确实是我们的失职,谁也没想到,都没认出来。Bob不爱说话,皮肤又黑,我们都以为是少数民族。谁也没想到他是猩猩!”不停的用右后腿挠左后腿内侧,显得很紧张。
“但谁又能想到他是猩猩呢!”张部长突然激动起来,“一般正常的猩猩怎么会跑到我们台企来应聘?业务还这么熟练,肯定是疯了!这个猩猩也有问题!”张部长激动说,嗷的一声站了起来。
“不能光说我们人事,这个事情全推到我们人事部门,我们不能接受!太欺负人了!”张部长双前手挥舞。
“老张你别激动,先吃点儿草。”刘主任示意张部长冷静,递过去一把草。
“事情虽然严重,讲清楚就好了。谁都会犯错,对不对。”刘主任说
“讲清楚就好了。老张你们在这件事上要引以为戒,一定要引以为戒,吸取教训。千万不能在招人问题上再出差错了。”说完拍了拍张部长后背,正在吃草的张部长很感动,流下了热泪。
“老李,你们技术部在这件事上是怎么想的?”主任接着问技术部李部长
“出了这么大事,你们也有责任,Bob是你们技术部的人,一起工作这么久,就没人发现他是猩猩吗?”主任问
技术部李部长显然是有备而来,站起来说:“这件事确实我们也有责任,虽说招Bob进公司的是人事,但一起工作这么久却没发现他是猩猩,我们技术部也是有责任的。”
“大家知道,我们技术部都是些干实事的人,比较专注于工作,和技术钻研,平时大家相互交流可能不够,这一点以后要改进。像这次,有猩猩混进来工作了这么久,如果我们技术部的警惕性高,能提前发现问题,也不会出现现在这种尴尬状况了。”
“事情出现以后我紧急召集技术部全体人员探讨了一下,大家也很有感触,都表示自己做的还不够,作为一个有责任心的员工,光光做好本职工作是不够的,还要做到能抛开部门观念,放眼全局,处处替公司着想,处处替公司分忧,主动替其他部门弥补过失,如果今后全公司所有员工都能这样想,并且这样去做,那我觉得这次的事件就是有收获的。“
”不管其他部门怎么想,反正我们技术部全体上下经过这次教训,现在都是一条心了。一个态度,今后坚决杜绝同类事件再次发生!不要说猩猩,就是驴,河马,狗熊混进来,我们也一样会把它揪出来!“
”来!技术部的大家来表个态!“李部长说,话音刚落技术部全体站了起来,”欧欧~“的左右手交替拍打胸部,齐声说:”技术部全体员工,向大家保证!从我做起,关心他人,绝不放一只猩猩进公司,请大家监督!“
李部长也很激动,”欧欧~“的拍了几下胸脯,对主任说:”刘主任,怎么样!“
主任也很激动,”欧~“的拍了一下桌子,站起来说:”非常好!大家都要向技术部学习,尤其是人事部,看看人家的态度。老张,你抬头看一下,老张,老张!你们人事部人来齐了吗,eric呢?“
张部长抬起头,擦了擦嘴,说:”eric来不了,他已经在桌子底下睡半个多月了。好像是冬眠了。“
刘主任说:”请假了吗?“
张部长说:”请了,工作也交接了,明年春天就醒过来。“
刘主任说:”请假了就行,冬眠是生理习性,是客观无法避免的,不要影响工作就好。“接着又问林秘书:”赵总呢?怎么还没到,会差不多了。“
林秘书说:“副总还在路上呢,他走的慢。”
刘主任说:“怎么回事儿,明知道赵总走的慢怎么不提前通知,现在到哪儿了?”
门口有人说:“到了到了!赵总快到门口了!”
刘主任指挥人说:“快快快,搭把手把赵总抬进来,不要浪费时间了,不然等赵总爬过来还得半小时。”
众人七手八脚把赵副总抬进来,在主席台上放好,刘主任过去说:“赵总,赵总!您给大家讲两句。”赵总没吭声。
刘主任说:“赵总,赵总!您讲两句!”
林秘书说:“主任,赵总好像睡着了。”
刘主任说:“既然赵总睡着了,那就算了,不要影响领导休息。这次事件,大家都有责任,回去好好反思。散会。”
第二天,公司出台三项政策:一是严防老太太。二是人事部全体加强学习,提高动物辨别能力,每人买一套动物世界vcd全集,行动电话上下载安装“亚洲动物图鉴”app,每周组织去一次动物园,与动物面对面交流。三是保障单位香蕉供应量不变。请大家安心工作。
员工们都觉的比较满意,这次事件上公司应对迅速,有礼有节,还是向着自己人的,于是恢复了平静。好多员工还欧欧~的拍了几下桌子,表示心情的激动。一场风波结束了。北京又迎来了新的一天。
知识(Knowledge)
目录
[隐藏]
1 什么是知识
2 知识的分类
3 知识的相关解释
4 相关条目
知识是对某个主题确信的认识,并且这些认识拥有潜在的能力为特定目的而使用。认知事物的能力是哲学中充满争议的中心议题之一,并且拥有它自己的分支—知识论。从更加实用的层次来看,知识通常被某些人的群体所共享,在这种情况下,知识可以通过不同的方式来操作和管理。
1、陈述性知识(Declarative knowledge)
陈述性知识指个人具有有意识的提取线索,因而能直接陈述的知识。是关于 “是什么”、“为什么” 的知识。
2、程序性知识(Procedural knowledge)
程序性知识是个人没有有意识提取线索,只能借助某种作业形式间接推论其存在的知识。程序性知识是一套办事的操作步骤。是关于 “怎么办” 的知识。
3、显性知识(Explicit Knowledge)
显性知识是指 “能明确表达的知识”,即:人们可以通过口头传授、教科书、参考资料、期刊杂志、专利文献、视听媒体、软件和数据库等方式获取,以可以通过语言、书籍、文字、数据库等编码方式传播,也容易被人们学习。包括 “可以写在书本和杂志上,能说出来的知识”。
4、隐性知识(Tacit Knowledge)
隐性知识是迈克尔 · 波兰尼(Michael Polanyi)在 1958 年从哲学领域提出的概念。他在对人类知识的哪些方面依赖于信仰的考查中,偶然地发现这样一个事实,即这种信仰的因素是知识的隐性部分所固有的。
波兰尼认为:“人类的知识有两种。通常被描述为知识的,即以书面文字、图表和数学公式加以表述的,只是一种类型的知识。而未被表述的知识,像我们在做某事的行动中所拥有的知识,是另一种知识。” 他把前者称为显性知识,而将后者称为隐性知识,按照波兰尼的理解,显性知识是能够被人类以一定符码系统(最典型的是语言,也包括数学公式、各类图表、盲文、手势语、旗语等诸种符号形式)加以完整表述的知识。隐性知识和显性知识相对,是指那种我们知道但难以言述的知识。
尽管知识是日常生活里的中心组成部分,但知识的确切定义仍然是哲学家、社会科学家和历史学家有着极大兴趣的话题。根据许多思想家的论述,知识必须具备三个特征:被证实的(justified)、真的(true)和被相信的(believed)。
描述知识的用法是考察知识的一种常见做法。在这种意义上,知识是由不同意向讨论着的信息。DIKW 体系将数据、信息、知识、智慧纳入到一种金字塔形的层次体系中,而这个模型与DIKW 体系是一致的。
Purser & Pasmore 认为要精确地定义知识是非常困难的。例如:何谓知识?如何获取知识?何者是有效的知识?这些问题是非常难回答的,但若无法回答知识是什么,将难以设计能产生更多知识及有效利用知识的组织。因此,Purser & Pasmore 则将知识定义为:“用以制定决策的事实、模式、基模、概念、意见、及直觉的集合体。”Badaracco 将知识定义为:从人类活动中所获取的真理、原则、思想及资讯。日本学者田中郁次郎则认为知识是一种多元的概念,具有多层次的意义。知识牵涉到信仰、承诺与行动等,可分为内隐与外显知识。何光国则认为知识是:经验累积的纪录;事实组织的系统化;对事实的理解;一种理解的行为或状态;人的已知和未知。此外 Davenport,依据知识的特性指出,知识是一种流动性质的综合体,其中包括:结构化的经验、价值及经过文字化的资讯,而且还包括专家独特的见解,为新经验的评估、整合与资讯等提供架构。
由上述可知,知识是抽象的,是传达概念的一种形式。例如:古代的结婚记事、白旗示降等,都是借由结绳、白旗等符号来传达概念。但是当人类活动越是频繁,则简单的符号就不足传达双方的意念。因此,有了文字、语言等符号兴起以作为沟通的工具。在沟通过程中还是需要经过思考,最后才能产生出知识。由此可知,知识就是经由前人的经验累积形成的。
几位学者对知识的定义:
Quinn(1996):知识是存在于专业人员身上的技能财产,可分为:实证知识、高级技能、系统认知、自我激励创造力等。
Harris(1996): 知识是资讯、文化脉络及经验的组合。
Qunitas(1997): 知识是企业无形资产。
Nonaka(1994): 认为当讯息 (message) 被赋予意义后,就成为资讯 (information),而资讯再经过整理后,才转化为知识 (konwledge)。知识是人类理解与学习的结果。
情境知识
知识社会
知识经济
知识管理
https://wiki.mbalib.com/wiki/%E7%9F%A5%E8%AF%86
知识分子的不幸-王小波
========================
知识分子的不幸-[[王小波]]
-----
乔叟《坎特伯雷故事集》里,有这样一个故事,有位武士犯了重罪,国王把他交给王后处置。王后命他回答一个问题:什么是女人最大的心愿?这位武士当场答不上来,王后给了他一个期限,到期再答不上来,就砍他的脑袋。于是,这位武士走遍天涯去寻求答案。最后终于找到了,保住了自己的头;假如找不到,也就不称其为故事。据说这个答案经全体贵妇讨论,一致认为正确,就是:“女人最大的心愿就是有人爱她。”要是在今天,女权主义者可能会有不同看法,但在中世纪,这答案就可以得满分啦。
我也有一个问题,是这样的:什么是知识分子最害怕的事?而且我也有答案,自以为经得起全球知识分子的质疑,那就是:“知识分子最怕活在不理智的年代。”所谓不理智的年代,就是伽利略低头认罪,承认地球不转的年代,也是拉瓦锡上断头台的年代;是茨威格服毒自杀的年代,也是老舍跳进太平湖的年代。我认为,知识分子的长处只是会以理服人,假如不讲理,他就没有长处,只有短处,活着没意思,不如死掉。丹麦王子哈姆雷特说:活着呢,还是死去,这是问题。但知识分子赶上这么个年代,死活不是问题。最大的问题是:这个倒霉的年头儿何时过去。假如能赶上这年头过去,就活着;赶不上了就犯不着再拖下去。老舍先生自杀的年代,我已经懂事了,认识不少知识分子。虽然我当时是个孩子,但嘴很严,所以也是他们谈话的对象。(就我所知,他们最关心的正是赶得上赶不上的问题。在那年头死掉的知识分子,只要不是被杀,准是觉得赶不上好年头了。)而活下来的准觉得自己还能赶上——当然,被改造好了、不再是知识分子的人不在此列。因此我对自己的答案颇有信心,敢拿这事和天下人打赌,知识分子最大的不幸,就是这种不理智。
下一个问题是:我们所说的不理智,到底是因何而起?对此我有个答案,但不愿为此打赌,主要是怕对方输了赖账:此种不理智,总是起源于价值观或信仰的领域。不很久以前,有位外国小说家还因作品冒犯了某种信仰,被下了决杀令,只好隐姓埋名躲起来。不管此种宗教的信仰者怎么看,我总以为,因为某人写小说就杀了他是不理智的。所幸这道命令已被取消,这位小说家又可以出来角逐布克奖了。对于这世界上的各种信仰,我并无偏见,对有坚定信仰的人我还很佩服,但我不得不指出,狂信会导致偏执和不理智。有一篇歌词,很有点说明意义:
跨过大海,尸浮海面,
跨过高山,尸横遍野,
为天皇捐躯,
视死如归。
这是一首日本军歌的歌词,从中不难看出,对天皇的狂信导致了最不理智的死亡欲望。一位知识分子对歌中唱到的风景,除了痛心疾首,不应再有其他评价。还有一支出于狂信的歌曲,歌词如下:
无产阶级文化大革命,
就是好!
就是好来就是好啊,
就是好!……
这四个“就是好”,无疑根绝了讲任何道理的可能性。因为狂信,人就不想讲理。我个人以为,无理可讲比尸横遍野更糟;而且,只要到了无理可讲的地步,肯定也要尸横遍野。“文化革命”里就死人不少,还造成了全民知识水平的大倒退。
当然,信仰并不是总要导致狂信,它也不总是导致不理智。全无信仰的人往往不堪信任,在我们现在的社会里,无信仰无价值的人正给社会制造麻烦,谁也不能视而不见。十年前,我在美国,和我的老师讨论这个问题,他说:对一般人来说,有信仰比无信仰要好。起初我不赞成,后来还是被他说服了。
十年前我在美国,适逢里根政府要通过一个法案,要求所有的中小学在课间安排一段时间,让所有的孩子在教师的带领下一起祷告。因为想起了“文化革命”里的早请示,我听了就摇头,险些把脑袋摇了下来。我老师说:这件事你可以不同意,但不要这样嗤之以鼻——没你想得那么糟。政府没有强求大家祈祷新教的上帝。佛教孩子可以念阿弥陀佛,伊斯兰教的孩子可以祷告真主,中国孩子也可以想想天地祖宗——各自向自己的神祈祷,这没什么不好。但我还是要摇头。我老师又说:不要光想你自己!十几岁的孩子总不会是知识分子吧。就算他是无神论者,也可以在祷告时间反省一下自己的所作所为。这种道理说服了我,止住了我的摇头疯:不管是信神,还是自珍自重,人活在世界上总得有点信念才成。就我个人而言,虽是无神论者,对于无限广阔的未知世界,多少还有点猜测;我也有个人的操守,从不逾矩,其依据也不是人人都能接受的,所以也是一种信念。从这个意义上说,我理应不反对别人信神、信祖宗,或者信天命——只要信得不过分。在学校里安排段祈祷的时间,让小孩子保持虔诚的心境,这的确不是坏主意——当时我是这样想,现在我又改主意了。
时隔十年,再来考虑信仰问题,我忽然发现,任何一种信仰,包括我的信仰在内,如果被滥用,都可以成为打人的棍子、迫害别人的工具。渎神是罪名,反民族反传统、目无祖宗都是罪名。只要你能举出一种可以狂信而无丧失理智危险的信仰,无须再说它有其他的好处,我马上就皈依它——这种好处比其他所有好处加起来,都要大得多啊。
现在,有这样一种信仰摆在了我们面前。请相信,对于它的全部说明,我都考虑过了。它有很多好处:它是民族的、传统的、中庸的、自然的、先进的、唯一可行的;论说都很充分。但我不以为它可以保证自己不是打人的棍子,理由很简单,它本身就包括了很多大帽子,其分量足以使人颈骨折断:反民族、反传统、反中庸、反自然……尤其是头两顶帽子,分量简直是一目了然的。就连当初提倡它的余英时先生,看到我们这里附和者日众,也犯起嘀咕来了。最近他在《二十一世纪》杂志上著文,提出了反对煽动民族狂热的问题。在我看来,就是因为看到了第一顶帽子的分量。金庸先生小说里曾言:“武林至尊,宝刀屠龙;号令天下,莫敢不从!”民族狂热就是把屠龙刀啊。余先生不肯铸出宝刀,再倒持太阿,以柄授人——这证明了我对海外华人学者一贯的看法:人家不但学术上有长处,对于切身利害也很惊警,借用打麻将的术语,叫做“门儿清”!
至于国内的学者,门儿清就不是他们的长处。有学者说,我们搞的是学术研究,不是搞意识形态——嘿,这由得了你吗?有朝一日它成了意识形态,你的话就是罪状:胆敢把我们民族伟大的精神遗产扣押在书斋里,不让它和广大群众见面!我敢打赌,甚至敢赌十块钱:到了这有朝一日,整他准比整我还厉害。
说到信仰,我和我老师有种本质的不同。他老人家是基督徒,又对儒学击节赞赏;他告诉我说,只要身体条件许可,他每年都要去趟以色列——他对犹太教也有兴趣;至于割没割包皮,因为没有和他老人家同浴的机会,我不知道。但我知道,他是一个信仰的爱好者。我相信他对我的看法是:可恨的无神论者,马基雅弗利分子。我并不以此为耻。说到马基雅弗利,一般人都急于和他划清界线,因为他胆敢把道义、信仰全抛开,赤裸裸地谈到利害;但是真正的知识分子对他的评价不低,赤裸裸地谈利害,就接近于理智。但我还是不当马基雅弗利分子——我是墨子的门徒,这样把自己划在本民族的圈子里面,主要是想防个万一。顺便说一句,我老师学问很大,但很天真;我学问很小,但老奸巨猾。对于这一点,他也佩服。用他的原话来说,是这样的:你们大陆来的同学,经历这一条,别人没法比啊。
我对墨子的崇拜有两大原因:其一,他思路缜密,有人说他发现了小孔成像——假如是真的,那就是发现了光的直线传播,比朱子只知阴阳二气强了一百多倍——只可惜没有完备的实验记录来证明。另外,他用微积分里较老的一种方法来论证无穷(实际是论兼爱是可能的。这种方法叫德尔塔-依伏赛语言),高明无比;在这方面,把孔孟程朱捆在一起都不是他的个儿。其二,他敢赤裸裸地谈利害。我最佩服他这后一点。但我不崇拜他兼爱无等差的思想,以为有滥情之嫌。不管怎么说,墨子很能壮我的胆。有了他,我也敢说自己是中华民族的赤诚分子,不怕国学家说我是全盘西化了。
作为墨子门徒,我认为理智是伦理的第一准则,理由是:它是一切知识分子的生命线。出于利害,它只能放到第一。当然,我对理智的定义是:它是对知识分子有益,而绝不是有害的性质。——当然还可以有别的定义,但那些定义里一定要把我的定义包括在内。在古希腊,人最大的罪恶是在战争中砍倒橄榄树。在现代,知识分子最大的罪恶是建造关押自己的思想监狱。砍倒橄榄树是灭绝大地的丰饶,营造意识形态则是灭绝思想的丰饶;我觉得后一种罪过更大——没了橄榄油,顶多不吃色拉;没有思想人就要死了。信仰是重要的,但要从属于理性——如果这是不许可的,起码也该是鼎立之势。要是再不许可,还可以退而求其次——你搞你的意识形态,我不说话总是可以的吧。最糟的是某种偏激之见主宰了理性,聪明人想法子自己来害自己。我们所说的不幸,就从这里开始了。
中国的人文知识分子,有种以天下为己任的使命感,总觉得自己该搞出些给老百姓当信仰的东西。这种想法的古怪之处在于,他们不仅是想当牧师、想当神学家,还想当上帝(中国话不叫上帝,叫“圣人”)。可惜的是,老百姓该信什么,信到哪种程度,你说了并不算哪,这是令人遗憾的。还有一条不令人遗憾,但却要命:你自己也是老百姓;所以弄得不好,就会自己屙屎自己吃。中国的知识分子在这一节上从来就不明白,所以常常会害到自己。在这方面我有个例子,只是想形象说明一下什么叫自己屙屎自己吃,没有其他寓意:我有位世伯,“文革”前是工读学校的校长,总拿二十四孝为教本,教学生说,百善孝为先,从老莱娱亲、郭解埋儿,一路讲到卧冰求鱼。学生听得毛骨悚然,他还自以为得计。忽一日,来了“文化革命”,学生把他驱到冰上,说道:我们打听清楚了,你爸今儿病了,要吃鱼——脱了衣服,趴下吧,给我们表演一下卧冰求鱼——我世伯就此落下病根,健康全毁了。当然,学生都是混蛋,但我世伯也懊悔当初讲得太肉麻。假如不讲那些肉麻故事,挨揍也是免不了,但学生怎么也想不出这么绝的方法来作践他。他倒愿意在头上挨皮带,但岂可得乎……我总是说笑话来安慰他:你没给他们讲“割股疗亲”,就该说是不幸之中的大幸,要不然,学生片了你,岂不更坏?但他听了不觉得可笑。时至今日,一听到二十四孝,他就浑身起鸡皮疙瘩。
我对国学的看法是:这种东西实在厉害。最可怕之处就在那个“国”字。顶着这个字,谁还敢有不同意见?这种套子套上脖子,想把它再扯下来是枉然的;否则也不至于套了好几千年。它的诱人之处也在这个“国”字,抢到这个制高点,就可以压制一切不同意见;所以它对一切想在思想领域里巧取豪夺的不良分子都有莫大的诱惑力。你说它是史学也好,哲学也罢,我都不反对——倘若此文对正经史学家哲学家有了得罪之处,我深表歉意——但你不该否认它有成为棍子的潜力。想当年,像姚文元之类的思想流氓拿阶级斗争当棍子,打死打伤了无数人。现在有人又在造一根漂亮棍子。它实在太漂亮了,简直是完美无缺。我怀疑除了落进思想流氓手中变成一种凶器之外,它还能有什么用场。鉴于有这种危险,我建议大家都不要做上帝梦,也别做圣人梦,以免头上鲜血淋漓。
对于什么叫美好道德、什么叫善良,我有个最本分的考虑:认真地思索,真诚地明辨是非,有这种态度,大概就可算是善良吧。说具体些,如罗素所说,不计成败利钝地追求客观真理,这该是种美德吧?知识本身该算一种善吧?科学知识分子说这就够了,人文知识分子却来扳杠。他们说,这种朴素的善恶观,造成了多少罪孽!现代的科技文明使人类迷失了方向,科学又造出了毁灭世界的武器。好吧,这些说法也对。可是翻过来看看,人文知识分子又给思想流氓们造了多少凶器、多少混淆是非的烟雾弹!翻过来倒过去,没有一种知识分子是清白无辜的。所以我建议把看不清楚的事撇开,就从知识分子本身的利害来考虑问题——从这种利害出发,考虑我们该有何种道德、何种信念。至于该给老百姓(包括我们自己在内)灌输些什么,最好让领导上去考虑。我觉得领导上办这些事能行,用不着别人帮忙。
作为一个知识分子,我对信念的看法是:人活在世上,自会形成信念。对我本人来说,学习自然科学、阅读文学作品、看人文科学的书籍,乃至旅行、恋爱,无不有助于形成我的信念,构造我的价值观。一种学问、一本书,假如不对我的价值观发生作用(姑不论其大小,我要求它是有作用的),就不值得一学,不值得一看。有一个公开的秘密就是:任何一个知识分子,只要他有了成就,就会形成自己的哲学、自己的信念。托尔斯泰是这样,维纳也是这样。到目前为止,我还看不出自己有要死的迹象,所以不想最终皈依什么——这块地方我给自己留着,它将是我一生事业的终结之处,我的精神墓地。不断地学习和追求,这可是人生在世最有趣的事啊,要把这件趣事从生活中去掉,倒不如把我给阉了……你有种美好的信念,我很尊重,但要硬塞给我,我就不那么乐意。打个粗俗的比方,你的爸爸不能代替我的爸爸,更不能代替天下人的爸爸啊。这种看法会遭到反对,你会说:有些人就是笨,老也形不成信念,也管不了自己,就这么浑浑噩噩地活着,简直是种灾难!所以,必须有种普遍适用的信念,我们给它加点压力,灌到他们脑子里!你倒说说看,这再不叫意识形态,什么叫意识形态?假如你像我老师那么门儿清,我也不至于把脑袋摇掉,但还是要说:不是所有的人都那么笨,总要留点余地呀。再说,到底要灌谁?用多大压力?只灌别人,还是连你在内?灌来灌去,可别都灌傻了呀。在科技发达的二十一世纪,你给咱们闹出一窝十几亿傻人,怎么个过法嘛……
本篇最初发表于1996年第2期《东方》杂志。
栀子花-简媜
========================
栀子花-[[简媜]]
------
怎么认识她的?跟一朵栀子花有关。
那时还是“解严”之前,踏出大学校园不久的我,满怀雄心壮志,刚在戒备森严的文坛边角插下歪歪斜斜的小旗帜,环顾四周皆是霸主,惊魂未定,又奉天承运地进入一家揭橥兼容并蓄精神的杂志,当起从买便当、影印到采访、发稿无所不包的小编辑。编辑音同“边集”,摸得到边的都集合到你身上,摸不到边的正在路上。
那时的我未驯化亦不谙政治之道,脑子里因涌动与生俱来的自由意识故时有惊险之事擦“编辑台”边而过。譬如,因尊重作者之创作意志与言论自由,竟未将文中描述购党外杂志评论时政一段、读毛泽东一段删去,据云“上头”很不高兴,大头目、二头目、三头目、四头目追究这篇文章是哪个混账发稿的?当然是一个不知“死活”的小编辑“小妹在下本人我”。我应该有跑到厕所滴几颗泪珠,也必然以不雅的动词诅咒那看不见的、把每个人调教成心中自有一座警备总部的黑暗力量。其实我没那么勇敢,只是郁闷。那是个漂白水与杀虫剂被过度使用到反扑力量即将溃堤而来的年代。有个隔壁单位见多识广的老大哥点拨了几句,他提到我们的“头儿”向一位因政治事件系狱甫假释的作家邀稿以营造自由开放形象,却在依约碰面的当下突然“因病不克前来”,留下无关紧要的同仁与有案底的作家喝咖啡、摄影留念。“你要懂,突然生病这招很好用。”
为了活下去,他必须突然生病。这逻辑太高深了,我不想懂。
除此之外,那个年代没什么好抱怨。公司里只要有一条罹患被迫害妄想症的鲶鱼、一尾酷爱追逐血腥权力的斗鱼、一只自我崇拜的鲸鱼——当然是随时可以朝你喷口水的老板——即刻会让大家陷入欲生欲死的集体歇斯底里状态。真的没什么好抱怨的。
在那个台湾钱淹脚目且没有网络、手机的手工时代,即使是小出版社也会借着登广告、办座谈演讲发表会、上广播电视拓展业务,风气如此,是以五天一会三天一宴乃艺文界基本生活。
我记得在某个中型研讨会后,“头儿”刻意安排近郊山上一处风格餐坊以飨嘉宾。天色犹亮,众人拾阶而上,走在前头的都是一方之霸及漂洋与会的娇客,我不擅交际,习惯殿后,与众人若即若离,最好掉入无人察觉的时空罅隙消失而去。
石阶边植有多棵我钟爱的栀子花,令我惊喜,早发的几株已布置得宛如月光盛筵,空气中浮着阵阵幽香,似久违的旧识,如远方的招引,沁润着我的肺腑。
我停步,凑近一朵盛放的重瓣栀子,深深嗅闻。我爱栀子花,只要遇见这花,一定这么做,那淡雅悠远的香味像一条白丝巾,不,是招魂幡,能让我安静,霎时挣开世间樊笼,悠游于茫茫渺渺之中,似已遗忘的前世,如将近的未来。只一霎,心生欢愉,仿佛能把美好事物永远贮存。
我随手折了一枝带叶白花,边走边闻,正要提步赶上众人,没料到背后有个声音:
“人香还是花香?”
正是她。我有点尴尬,攀折花木不是好青年该有的行为。我将花送她,她亦嗅闻,露出笑容。
“借花献佛。”我说。既然做了小偷,给自己也折了一朵,夹在指间。
人香还是花香?问得有几分禅意,风动还是幡动?我一寻思,不禁暗笑。
晚霞将褪去,早月像一枚淡淡的吻痕。山腰民家已点灯了,眼前这家农舍改修的餐坊亦亮起步道小灯,沿阶草漫过边堤,添了“翠薇拂行衣”的野趣。
我当然知道她,年轻学者,之前基于礼貌曾发过不痛不痒的邀稿函,此次为了研讨会亦有联系。但我不确定她是否知道我,毕竟我才刚出版第一本书,而且尚未以“我是作家”介绍自己,躲在编辑名片之后比较符合我的低调作风。
我报上名字。没想到她竟主动谈起我的作品,颇有几句溢美之词。但最让我惊讶的是,她提到我不久前发表的一篇稚嫩的小说,对故事中演绎“弱水三千,只饮一瓢”典故竟有学术评语之外的友好用词,“喜欢到心坎里去”,她的话。还问我是否有意朝小说发展,我答以还在摸索,她因此分析我的中文系血统对小说创作之优劣影响。日后我专神走上散文旅路,干脆自砍小说枝桠,早年写就的十几篇小说就这么埋了。于今想来,她是唯一与我谈到小说的人。但当时与她并肩沿阶而升的步伐中,我是不自在的,这是个怪病,当别人当面赞赏我的作品会让我不自在到想消失,所以那当下我只想与她一起踩空石阶坠落到夜的怀抱里。
还好二头目、三头目迎了出来,架着这位年轻的学术精英往主桌那儿去。资深霸主与海外贵宾一向是竞争惨烈的两大阵营极力拉拢的对象,生恐招待不周怕他们带“稿”投靠“敌营”(其实他们深谙两边通吃之道),是以其身边需巧妙安排擅长插抖打诨的弄臣与言之有物的陪客,以期宾主尽欢。她应该算是后者。
我径自往“儿童桌”,与行政人员共坐,他们赶我:“还不快去前面伺候!”我答:“偏不要。”
前头两桌真个是闹哄哄酒池肉林、笑盈盈男欢女爱,相较之下儿童桌才像在吃饭,可专心帮身材姣好的盐酥虾脱下甲胄。酒过三巡,她借着上化妆室竟弯到我这桌来,同事挪了位置,她一坐下,毫不掩饰对爱闹酒男人喜吃女性豆腐的轻俏言语感到不悦。我正夹着烟,“你抽烟啊?”她又一惊,今晚大概让她吓坏了。“都这样,有色无胆,一喝酒现出原形。要是惹你,顶回去别客气。”我说。
照说,她比我年长,轮不到我来指导餐桌防身术,也许学界空气比较新鲜,不像艺文江湖,琥珀魔液落喉,餐桌上涌动一股熟春闷夏气温,动物性荷尔蒙作乱,暗示性或性暗示语句犹如野猴子手上的小石头小果子,朝同伴丢掷,于是一树猴儿吱喳互掷,跳枝拊掌作乐。差别是,道行高的丢来花朵,丽辞香句挑之逗之,若有意似无情;品性差的丢的是石头,生恐别人不知道他是个猪八戒。也许学界端正多了,她对觥筹交错、疯言乱语越来越像水浒传野店的怪状,颇不能适应。
此时主桌传来笑声,擅酬酢的头儿正以高妙风雅的戏语“吹拂”(非“吹捧”)宾客。他是江湖上人人赞誉的饮宴大师、筵席教主,即使是青菜豆腐也能被他的灿舌说得像采自陶渊明的菜园,佐以恰到好处的引诗,滋味立时深远。吹拂之道,需手法细腻且神色泰然,全凭品味二字,没那个底蕴,一吹就只能吹鲍鱼多昂贵鱼翅多珍奇。深得吹拂之精髓者,既能吹得宾客心花朵朵开,又能展示自身品味不凡。
头儿正吹到他独创的“创作论”,大意是要写出伟大作品必有三条件,“酒要烈,烟要臭,茶要苦”,有个霸主接:“人要潦倒”,举桌皆乐。有理,人生得意,文章无味。
我们这桌“小朋友们”也跟着起哄,沿着话头往下接。有人说那是指小说家,写散文的,“心要碎,情要痴”,我接了。写诗的,“账单要长”,有个年轻诗人接话。“做学术的呢?”我拨了拨她的肘,她两颊酡红,开怀答曰:“敌人要多。”满座大笑。
她贡献了机锋,众人举杯敬她,我也畅快地碰了她的杯子,借着酒意随口念出她的诗句:“黄昏的咽喉,只不过是雨。干了干了!”
说不定,我与她熟稔起来不是因为那朵花,而是因为那杯酒。
! 进行中
//待完成的任务清单//
<<list-tagged-draggable tag:"中篇小说" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"你没有待处理的任务">>
! 已结束
//(已完成的任务清单)//
<$list filter="[!has[draft.of]tag[中篇小说]tag[done]sort[created]]">
<div>
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
</div>
</$list>
重访西敏寺-余光中
========================
重访西敏寺-[[余光中]]
-----
七月二十五日与我存从巴黎搭火车去布隆,再坐渡船过英吉利海峡,在福克斯东(Folkestone)登岸,上了英国火车,驶去伦敦。在伦敦三天,一直斜风细雨,阴冷如同深秋,始终无缘去访西敏古寺。后来我们就租了一辆飞雅红车,老兴遄飞,一路开去苏格兰,在彭斯的余韵和司各特的遗风里,看不完古寺残堡,临湖自镜。等到爱丁堡游罢南回,才专诚去西敏寺探访满寺的古魂。在我,这已是重访。就我存而言,这却是初游。
从西门一踏进西敏寺,空间只跨了几步,时间,却迈过几百年了。欧洲的名寺例皆苍古阴暗,历史的长影重重叠叠,压在游人的心上,西敏寺尤其如此。对我说来,西敏寺简直就是一座充满回声的博物馆,而诗人之隅简直就是大理石刻成的英国文学史。
西敏寺不及圣保罗大教堂高大,但在英国史上却享有特殊崇高的地位,因为九百年来它一直是皇室大典的场所。一〇六六年,诺曼底公爵在英国南岸的海斯丁斯打败了海洛德,进军伦敦,并于该年的圣诞节在甫告建成的西敏寺举行加冕典礼,以异族征服者的身份成为英国的君王。从此英王的加冕典礼,除爱德华五世及爱德华八世之外,一律在此举行。
英王的登基大典分成四个阶段。第一阶段是序幕,首先是新君入寺,由大主教导至典礼观众之前,并问观众是否同意进行典礼。观众表示同意,是为正式承认新君之统治权。继由新君宣誓,保证今后治国,必须尊重人民所定的法律,并且维护英格兰与苏格兰的革新教会。再由大主教呈上《圣经》,作为一切智慧与法律之根据。第二阶段是把新君敷上圣油,送上加冕椅。第三阶段是授予新君王袍与权杖。第四阶段是新君登台就位,在王座之上接受观礼者的致敬。观礼者分为三种身份:依次为灵职(Lords Spiritual,指大主教与主教)、俗职(Lords Temporal,指公侯伯子男等贵族)和人民的代表。典礼的程序九百年来大同小异,变化很少。
西敏寺吸引游人的另一传统,是英国历来的君王与皇后均在此安葬,游客只要买票,就可鱼贯而入纵堂(nave),参观伊丽莎白一世及维多利亚的石墓,发其怀古之遐思。凡能看的我也都随众看了,但是最令我低回而不忍去的,是其横堂(transept)之南廊,也正是举世闻名的诗人之隅。九年前我曾经来此心香顶礼,冥坐沉思,写了一篇长文《不朽,是一堆顽石?》,此番重游,白发陡增,对诗人身后的归宿,有更深长的感触。
西敏寺之南廊虽为诗人立碑立像,供后人之瞻仰徘徊,却非文学史之定论。诗人在此,或实有坟墓,或虚具碑像,情况不一。碑也分为两种:一种是地碑,嵌在地上,成为地板;一种是壁碑,刻在墙上。也不知道为什么,雪莱和济慈仅具壁碑,面积不大,且无雕像。旁边却有骚塞(Robert Southey)的半身石像,也许骚塞做过桂冠诗人之故:我相信雪莱看见了一定会不高兴。拜伦仅有一方地碑,却得来不易。他生前言行放浪,而且鄙薄英国的贵族与教会,所以死后百多年间,一直被摈于西敏寺外,沦为英国文苑的野鬼游魂。(我相信拜伦也不在乎,更无意与华兹华斯终古为伍。)索瓦生所雕的拜伦像,便是因为西敏寺不肯接受,才供在他母校剑桥三一学院的图书馆里。直到一九六九年,英国诗社才得以大理白石一方,铺地为碑,来纪念这位名满全欧的迟归浪子。
拜伦的地碑旁还有许多地碑,拜伦之石在其左上角。与拜伦同一横排而在其右者,依次为狄伦·托马斯、乔治·艾略特、奥登。下一排由左到右为露易士·卡洛尔、亨利·詹姆斯、霍普金斯、梅斯菲尔德。最低一排又依次为T.S.艾略特、丁尼生、布朗宁。最引人注目的是新客狄伦·托马斯:碑上刻着诗人生于一九一四年十月二十七日,卒于一九五三年十一月九日,下面是他的名句:“我在时间的掌中,青嫩而垂死——却带链而歌唱,犹如海波。”这两句诗可以印证诗人的夭亡而不朽,选得真好。
诗人之隅局于南廊,几乎到了碑相接像触肘的程度,有鬼满之感。说此地是供奉诗人的圣坛,并不恰当,因为石府的户籍颇为凌乱。首先,次要人物如坎贝尔(Thomas Campbell)竟有全身立像,像座堂皇,碑文颇长,而大诗人如蒲柏及多恩却不见踪影。其次,本国重要诗人不供,却供了两位外国诗人,美国的朗费罗与澳洲的戈登。再次,诗人之隅并不限于诗人,也供有狄更斯、韩德尔等小说家与作曲家,甚至还有政治人物。起拜伦于地下(他的地碑之下?)而问之,问他对诗人之隅的左邻右舍有何感想,敢说他的答复一定语惊四座,令寺中的高僧掩耳不及,寺外的王尔德笑出声来。
一九八五年八月二十五日
当你正在为 TiddlyWiki 里的 Tiddler 重新命名感到烦恼时,这篇可能会帮到你。
* 不同的记事软件的笔记连结方式有那两种?
* 什么是 TiddlyWiki 的 Plugin?
* ReLink 这个 Plugin 能够如何解决重新命名 Tiddler 的问题?
> 不同的记事软件的笔记连结方式有两种
-------------------
在有笔记连结功能的软件里,怎么能知道这个连结是连结到那个笔记呢?一般来说有两种方式。
像是 Evernote 这一类会为每一则笔记内定了一个 不会重复的 ID 来代表这个笔记的身份,所以我们有笔记 A 里加入笔记 B 的笔记连结时,其实我们加入的是笔记 B 的 ID。这样的好处是可以有多于一篇相同名称的笔记,以为就算笔记的名称更改了,这个笔记的连结也不会断掉。
而缺点就是我们很难把 Evernote 的笔记迁移出去。因为就算迁移了到其他的笔记软件后,我们也不知道这篇笔记里的所有笔记连结本来是要到那一篇笔记里。
而 TiddlyWiki 所使用的 Tiddler 连接方法是以 TiddlyWiki 的名称作为连结。这个方法有好有不好。这样的好处是我们可以在编辑 Tiddler 时已经知道这个 Tiddler 里的所有连结到底将会接到什么的 Tiddler 里。另一个优点是就算日后要转换笔记软件时的问题也没有 Evernote 等的问题那么严重。
但是缺点也很明显,第一是每个 Tiddler 的名称就是它的 ID ,所以我们在新建一个 Tiddler 时要很小心使用一些不会重复的名称,这最好在 Day 1 便要思考的问题。第二个缺点就是当我们要重新命名 Tiddler 时,如果有其他 Tiddler 有连结到这个 Tiddler,那些连接点便会断了。 (提外话,使用 Tag 来进行连结的话不会有这个问题, TiddlyWiki 会自动把这些 Tag 重命名。
针对第二个问题,我最近发现的一个 Plugin 很好的解决这个问题。
> 什么是 Plugin?
-------------
我好像在这里也没有介绍过这个概念。
Plugin 就是一些别人写好的 Tiddler 系列,通常都是一些工具,而这些 Plugin 都是别人写好后放到网上分享出来的。当你把它安装(也就是把这些 Tiddler 放到自己的 TiddlyWiki 里),便可以直接使用这些其他人已经做好的工具,其他人遇到过的问题,我们可以直接解决掉。
而安装的方式有两种。
第一个方法只是直接把网上的这些 Plugin 直接拖拉到自己的 TiddlyWiki 里便可以了。
如果你是使用 node.js 来使用 TiddlyWiki 的话,虽要把这个 Plugin 放到特定的位置并更改 [http://tiddlywiki.info](https://link.zhihu.com/?target=http%3A//tiddlywiki.info)。在这里就不多说了。详细[看此](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Installing%2520a%2520plugin%2520from%2520the%2520plugin%2520library)。
而且是介绍的这个接口,就解决了 Tiddler 重新命名的问题。
> 解决重新命名 Tiddler 的 Plugin:ReLink
--------------------------------
这个 [ReLink](https://link.zhihu.com/?target=https%3A//github.com/flibbles/tw5-relink) 的 Plugin 便是为了解决这个问题而生的。([按此看 Demo](https://link.zhihu.com/?target=https%3A//flibbles.github.io/tw5-relink/))
当安装了这个 Plugin 后。使用的方式十分简单。
假设我们有一个名为 B 的 Tiddler,而 Tiddler A 会连结到 B、或是 Transclude B。看下图:

当你重新命名 B 这个 Tiddler 为 C 时,你会发现在它会列出所有 连结到 这个 Tiddler 的 Tiddler(这个例子就是 A)。并且你可以选择是否把它们连接的 Tiddler 也更改为你将会命名的 Tiddler。

当你把 B 这个 Tiddler 命名为 C 后,你会发现所有在 Tiddler A 的连结全部都会由 B 自动改成 C 了。

而这个命名的范围也很阔,简单将普通的 Link,又或是 Transclusion、图片、Macro 的 Tidder 都可以自动重命名。这算是在 TiddlyWiki 里一个必装的 Plugin。
本文授权转载自个人博客:[点字记](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
《有如候鸟》收录了周晓枫近两年来十余篇散文新作,以繁复精彩、云谲波诡的巴洛克式修辞和对世间万物极其细腻的体察与感悟,为读者提供了大量颇具先锋意识的散文文本和真实、新鲜的人生经验。 自序《寄居蟹式的散文》及后记《关于写作》,谈了作者对当下散文写作和文学创作的看法。在《初洗如婴》中,她将记忆这一最为主观的哲学主题落实在最为客观的病症之上,构建起一幅互为意象与载体的内心画卷;《离歌》则是对散文结构的实验性抽离,以屠苏之死为线索,牵扯出与之相关的种种细碎的人和事、重现了主人公的悲剧人生以及导致如此悲剧的心路剖析,用小说外壳包裹,用散文的笔调述说,进行了人性与价值的深入探讨 作者用寄居蟹式的散文为文章标记,希望把戏剧元素、小说情节、诗歌语言和哲学思考都带入散文中,尝试自觉性的小说与散文的跨界掏空小说的肉,用更坚实的盾壳保护散文,向更深更远处探索散文写作的可能性。
朱利安·巴恩斯:马茨·伊斯拉埃尔松的故事 夜读_特鲁德
===========================
[https://www.sohu.com/a/392824802_771944](https://www.sohu.com/a/392824802_771944)
原标题:[[朱利安·巴恩斯]]:马茨·伊斯拉埃尔松的故事 | 夜读
```
朱利安·巴恩斯(Julian Barnes,1946年1月19日-)
后现代主义文学作家。1946年生于英格兰中部的列斯特,1968年牛津大学毕业。曾参与《牛津辞典增补本》的编纂工作。
著有长篇小说9部、侦探小说4部。曾四度获得布克奖提名(1984、1998、2005、2011),并在2011年以《终结感》获得布克奖。以1984年《福楼拜的鹦鹉》最为脍炙人口。是获得梅迪西文学奖(《福楼拜的鹦鹉》)和费米娜奖(《尚待商榷的爱情》)的惟一英国作家。
```
**马茨·伊斯拉埃尔松的故事****
作者/ 朱利安·巴恩斯
译者/ 郭国良
选自《柠檬桌子》,2020-3
教堂内有个三十年战争期间从德国带回来的石雕圣坛,前面立着一排共六个马厩。这些马厩全由白杉木雕刻而成,在小镇十字路口不远的地方风干,未加装饰,甚至连个标记都没有,但它们的简朴和表面看来人皆可用是有欺骗性的。在所有来教堂的人的心目中,不论他是骑马来的还是步行来的,那些马厩从左到右编为一到六号,分属于这附近最有权势的六位重要人士。要是哪个外乡人天真地以为自己有权利把马拴在那儿,去中央酒店享用Brannvinsbord,结果他会发现自家的牲口正在码头边晃荡,凝望远处的湖面呢。
每个马厩归谁,都是个人选择的结果,形式包括赠予契约、遗嘱或是文书明证。然而,虽说在教堂里面,一些长椅预留给某几个家族,代代相传,无论后代德行如何。而在外面,道德价值发挥着作用。老爷子也许一心把自己的马厩传给大儿子,但如果那小子没把这当回事儿,父亲脸上就挂不住了。哈尔瓦·伯里格伦嗜酒如命,举止轻浮,还是个无神论者。他曾要把第三个马厩的所有权转给一个走街串巷的磨刀工,当时人们非议的,不是那个磨刀的,反而是伯里格伦。后来给了那个磨刀的点儿钱,另选了一个更适合的人。
第四个马厩奖给了安德斯·博登,这也是意料之中的事。作为锯木厂的老总,他是出了名的工作勤恳,稳重得体,还特别顾家。虽说不是虔诚的教徒,他却很乐善好施。有一年秋天,打猎战果不错,他就用木头碎屑填满一个锯木坑,上面放了个铁架子,烤了一只鹿,分给工匠们吃。虽说不是土生土长的本地人,他却以陪同游客参观为己任,坚持带他们爬教堂旁边的钟楼。安德斯总是一只胳膊搭在大钟上,指着远处的砖砌建筑,再远一点的聋哑人收容所,还有视线尽头的1520年瑞典国王古斯塔夫斯·瓦萨讲话遗址纪念雕塑。他魁梧健壮,留着络腮胡,是个很富有激情的人,甚至会建议来一次朝圣之旅,去霍克伯格山参观近来刚刚安放的为纪念约翰内斯·斯蒂恩博克法官的大石头。远处,一艘汽船掠过湖面;山脚下,他的马儿等在马厩,扬扬自得。
有谣传说安德斯·博登花过多时间陪游客,因为这样他就可以晚点回家;还不止一次听说他第一次向耶特鲁德求婚时,她当面把他嘲弄了一番,而且是在跟一个叫马克柳斯的小伙子吹了以后才开始发现安德斯的好的;大家还猜想耶特鲁德的父亲找到安德斯,劝他重提求婚的时候,他俩之间的谈判并不简单。本来叫安德斯这样一个锯木厂的经理去追求像耶特鲁德这样才华横溢、充满艺术细胞的女人,就让他感觉有点门不当户不对,怎么说耶特鲁德也是跟舍格伦合作过钢琴二重奏的。但就小道消息来看,这桩婚事还是蛮称心的,虽说有那么几次耶特鲁德在公共场合说安德斯很无趣。他们有两个孩子,之所以没再要,也是因为给博登夫人接生的专家建议他们不要再生的。
药剂师阿克塞尔·林德瓦尔及夫人巴尔布鲁来镇上的时候,安德斯·博登带他们去了钟楼,还陪着去了霍克伯格山。回家以后,耶特鲁德就讽刺他说怎么不戴上瑞典旅行联合会的徽章。
“因为我不是会员。”
“他们真应该吸收你为荣誉会员。”她回答道。
对于妻子的冷嘲热讽,安德斯自有一套装迂腐的办法:假装听不懂弦外之音。这会让她更不爽,对他来说却是必要的防护举措。
“他们夫妻看起来挺友善的。”他漠然说道。
“谁你都喜欢。”
“没,亲爱的,不是那样的。”他的意思是,比如说,此时此刻他就不喜欢她。
“你对木头比对人都挑剔。”
“亲爱的,木头每根儿可都是不一样的。”
林德瓦尔夫妇的到来,在小镇上也没引起特别关注。那些去阿克塞尔·林德瓦尔那儿寻求专业咨询的人发现他是个典型的药剂师:慢条斯理,一脸严肃,一边宣称什么病都关乎性命,一边又断言说都是可以医治的。他身材矮小,头发浅黄,有谣传赌他会发福。对林德瓦尔夫人的评论相对较少,相貌既没有美得惊艳,也不是毫无姿色,着装既没有粗俗不堪,也不算高贵典雅,为人处世既没有乱出风头,也不是消极遁世。她只是一个新妇,因此她需要等着熬出头。由于初来乍到,林德瓦尔夫妇独来独往,显然没什么不妥,另外他们还会定期去教堂,这就更无可厚非了。有谣传说,阿克塞尔第一次领着巴尔布鲁去他们夏天买的游艇玩的时候,她很紧张地问道:“阿克塞尔,你确定这湖里没鲨鱼吗?”不过谣言也没法儿确定林德瓦尔夫人到底是不是在开玩笑。
每隔两个礼拜的周二,安德斯·博登都会开汽船去查看木材风干棚。当时他正站在头等舱的栏杆旁边,才发现自己身边站了一个人。
“林德瓦尔夫人,”话刚出口,就想起他妻子的话,“她的下巴还没松鼠的大呢。”想到这里,安德斯觉得很尴尬,就把视线转向湖岸线,说道,“那边是砖砌建筑。”
“是的。”
过了一会儿,他又说:“那是聋哑人收容所。”
“是的。”
“嗯,没错。”他意识到自己在钟楼上就已经指给她看过这些了。
她戴了一顶草帽,上面有一条蓝色缎带装饰。
两周以后,她又一次出现在汽船上。她有个姐姐就住在比赖特维克稍远一点的地方。他试着让自己看起来风趣一点,向她询问他们夫妇有没有参观丹麦人囚禁古斯塔夫斯的地牢,还向她解释了不同季节森林颜色和纹路的不同,还有即便远在船上,他如何判断那些树木是怎么被处理的,而其他人看到的估计仅仅是一大片树林。她顺着他指的方向礼貌地看过去。在侧面看来,她的下巴也许确实只是有点突出,鼻尖还会奇怪地动。他意识到自己从来就不会跟女人讲话,而在这之前他从来就没在意过这点。
“不好意思,我妻子说我应该戴上瑞典旅行联合会的徽章。”他说道。
“我喜欢听一个男人告诉我他知道的事情。”林德瓦尔夫人回答道。
她这话让他疑惑。这是对耶特鲁德的批评,对他的鼓励,还是仅仅是陈述一下事实?
那天晚饭的时候,他妻子问道:“你跟林德瓦尔夫人谈论了些什么?”
他不知道该回答什么,或者说他不知道该如何回答。但跟往常一样,他还是求助于最简单的字面意思,故作镇定地说道:“森林。我跟她解释了一些森林的事情。”
“她感兴趣吗?我的意思是,对森林。”
“她是在城市里长大的,来这儿之前,从来没见过那么多的树。”
“嗯,这里树实在是多得不得了,是吧,安德斯?”耶特鲁德说道。
他想说:你从来也没像她那样对树那么感兴趣过。他想说:你对她相貌的评价太苛刻了。他想说:谁看见我跟她说话了?但他什么也没说。
接下来的两个星期,他发现自己想到巴尔布鲁这个名字时,心头总有一丝甜蜜,而且感觉这名字叫起来也比其他名字温婉悦耳。他还发现一想到草帽上一圈儿蓝色缎带,心情就会愉悦起来。
星期二早上,他出门的时候,耶特鲁德叮嘱他说:“替我向林德瓦尔夫人问好。”
他突然想说:“万一我爱上她了怎么办?”不过,他回了一句:“要是我见到她的话。”
在船上,他差点儿都顾不了正常的社交礼貌了。还没开船,他就开始跟她讲自己所知道的东西。他讲了木材的生长、运输和砍伐,解释了弦锯和径锯,还解释了树干的三个部分:树心、心材和边材。成熟的树干里,心材成分最大,边材既坚硬又富有弹性。“树就跟人一样,”他说,“同样需要六七十年才能成熟,同样百年之后就没用了。”
他还告诉她有一次在伯格斯弗森,上面是一座铁桥,下面是湍急的流水,他看到有四百个男的试图截住浮出水面的木材,并且按照主人不同对那些木材分类整理。像个饱经世故的男人一样,他向她解释了不同的木材标记体系。瑞典木材用红色蜡纸标记,劣质木材用蓝色。挪威木材会在首尾两端同时用蓝色蜡纸标记,并带有货主的名字缩写。普鲁士的木材会在中间一段作标记。俄国的木材要么是有风干印花,要么是两边有捶打记号。加拿大木材用黑白蜡纸标记。美国木材则会在两侧用红色粉笔标记。
“这些你都见过吗?”她问道。他承认说没见过北美木材,只是在书上读到过。
“所以每个人都认识自己的木材喽?”她问道。
“当然。要不然肯定会有人偷别人的木材的。”他不确定她是不是在嘲笑他——又或者是,嘲笑天底下所有的男人。
突然,岸边划过一道闪光,这一闪使得她把视线移离对岸,回头看着他。这样一来,她的面部特征一下子和谐起来:小小的下巴让嘴唇看起来特别显眼,她的鼻尖,还有那大大的蓝绿色眼睛……那种感觉无法描述,甚至都无法赞美。他自感聪明,因为在她眼中看到了疑惑。
“那儿有个观景楼。可能有人拿着小望远镜在那边。有人在监视我们。”说“监视”这两个字时,他感觉自己都没底气了。这听起来一点儿不像他应该说的话。
“为什么监视我们?”
他不知道该怎么回答,朝着海岸望过去,观景楼那边又闪了一下。为了缓解尴尬气氛,他跟她讲了马茨·伊斯拉埃尔松的故事,但他讲的顺序不对,语速又太快,似乎并没有引起她的兴致。事实上,她甚至都没意识到那故事是真的。
“不好意思,”她说道,可能是感觉到了他的失望,“我没什么想象力的。我只对实实在在发生的事情感兴趣。在我看来,传奇故事……有点傻。我们国家传奇太多了。阿克塞尔也因为这个数落我,他说这是对国家的不敬,再者说了人家也会说闲话的,说我是那种现代女人。但实际上,什么都不是。问题在于我缺乏想象力。”
安德斯发现这段突如其来的演讲竟起到了平复心情的作用,就好像她在给他当导游一样。看着对面岸边,他跟她讲了自己有一次参观法伦一座铜矿的事,说的都是实实在在发生过的事情。他说那座铜矿是当时世界第二大铜矿,仅次于苏必利尔湖铜矿;它早在13世纪就开始运行;铜矿的入口旁是一个被称作“地震”的塌陷区,这个塌陷区形成于17世纪;这里最深的矿井有1300英尺深;现在矿井的年产量是400吨铜,此外还有少量金银;若想进去就得花两块里克斯,枪弹另计。
“枪弹另计?”
“嗯。”
“要枪弹干吗用?”
“用来听回声的。”
他告诉她游客一般都会在法伦事先打电话给铜矿,告知行程。铜矿那边则会发给他们矿工服,并派一名矿工随行。下井的时候,台阶边有火把照明,前提是得交两块钱。这个他已经讲过了。他注意到,她的眉毛画得很浓,比头发都黑。
“我想去法伦看看。”她说。
那天晚上,他感觉到耶特鲁德不大高兴。最终,她说:“丈夫跟情人私会,在老婆面前就得谨小慎微。”每个字听来都像钟楼的钟声一样响亮。
他就那么看着她。她又继续道:“你还真天真,至少这点我应该庆幸。其他男人至少会等到船驶离码头才开始卿卿我我。”
“你误会了。”他说。
“我爸要不是商人,肯定会毙了你。”她回应道。
“那你父亲应该庆幸阿尔弗雷德松夫人那个在赖特维克的教堂后面开糕点房的丈夫同样也是这样一个商人。”他感觉到这句话过长,但不失效果。
那天晚上,安德斯·博登把他老婆所有骂他的话都一一列举下来,整齐排列,就跟排列木头堆似的。他想,这些事儿她既然能信,那也就有可能发生。安德斯除了不想要什么情妇,也不想给糕点房里某个女人买礼物,或是跟一大帮男人抽雪茄时,有个女人好让他吹嘘。他想:当然,现在我明白了,事实是从我第一次在汽船上看到她,我就爱上她了。要不是耶特鲁德帮忙,我自己还不会这么快就知道这一点呢。我从来没想过,她的冷嘲热讽竟然也有用;可是这次的确如此。
在接下来的两周,他不允许自己做白日梦。他也不需要再做梦了,因为一切都清晰、真实、明确了起来。他每天去工作,得空就想想她对马茨·伊斯拉埃尔松的故事不感冒的事儿。她从一开始就认定那只是个传说。他也清楚自己故事讲得也不怎么样。所以他就开始练习,就好像学生学诗一样。他想再给她讲一遍,而这次,仅仅从他讲故事的方式,就要让她知道那故事是真的。讲故事本身并花不了多长时间,但重要的是,他要学会像讲那次铜矿之行一样讲这个故事。
1719年,他开始讲了,担心这么个遥远古老的时间会让她觉得无聊,但又确信这样才有可信度。站在码头上等着汽船返航,他正式开始讲。1719年,法伦铜矿发现了一具尸体。死者,他看着对岸,继续说道,是一个年轻人,名叫马茨·伊斯拉埃尔松。他早在四十九年前就死了,尸体保存得非常好,他告诉在汽船上方闹哄哄地盘旋的海鸥。接着他又详细解释原因,之所以能保存得这么好,在于硫酸铜阻止了尸体分解变质,就好像那些观景楼、聋哑人收容所,还有砖石建筑真的是他的听众似的。人们知道死者叫马茨·伊斯拉埃尔松,他又对着码头那边忙着拉绳子的码头工人嘟哝,因为有个老太婆认出了他。四十九年前,他最后说,这次压低了声音,有一个无眠之夜,热气氤氲,风吹帘动,旁边妻子轻轻打着鼾,四十九年前,马茨·伊斯拉埃尔松失踪了,而那个老太婆,当时和他一样年轻,正是他的未婚妻。
他记得当时她面对他的样子,手搭在栏杆上,方便看到结婚戒指,然后说了一句,简简单单地:“我想去法伦看看。”他想象着其他女人会说“人家超想去斯德哥尔摩”或者“人家晚上总是梦到威尼斯”。那些女人都是穿着皮大衣难伺候的城里女人,除了脱帽表示敬意,她们对其他的才没兴趣呢。但她说:“我想去法伦看看。”言简意赅,却让他无从作答。他练习着同样言简意赅的回答:“我愿意带你去。”
他确信,只要自己能把马茨·伊斯拉埃尔松讲好,她必然会再说一遍:“我想去法伦看看。”到那时,他便可以回答:“我愿意带你去。”这样一切就尘埃落定了。因此,他不断练习讲那个故事,直到确信找到了一种能取悦她的方式:简单,确凿,真实。一出发十分钟他就要讲给她听,连地方都想好了,就在头等舱外面的栏杆旁边。
快到码头时他又最后练习了一遍那个故事。那是六月的第一个星期二。日期必须做到精确。以1719年开始,并以我们这个时代,1898年6月的第一个星期二结束。天气晴朗,湖水澄清,海鸥也很安静很知趣,小镇后面山上漫山遍野的都是树,笔直笔直的,就像刚正不阿、诚信老实的人一样。她却没来。
谣传说林德瓦尔夫人对安德斯·博登爽约了,还暗示说他们吵架了,但后来又传出来说他俩决定隐瞒此事。还有人好奇八卦说一个锯木厂的经理,有幸能娶到拥有一架德国进口钢琴的女人当老婆,真的会把一个姿色平平的药剂师的老婆看在眼里吗?还真有人回应说安德斯·博登从来就是个土老帽,头发里老是带着锯末,他只是想找个跟自己是一路人的女人,就像所有土老帽一样。又有人添油加醋地说自从博登家生了第二胎,夫妻关系就名存实亡了。也有那么一小段时间,有人怀疑这些是不是都只是人们瞎猜,但最后还是坚持认为:什么事情都不是空穴来风,最糟糕的解释往往就是最安全,也是最真实的解释。
后来听说林德瓦尔夫人那天之所以没去拜访她姐姐,是因为怀了林德瓦尔家的第一个孩子。至此,谣言才算暂时消散,或者说至少平息下来。又有人说,这次突然怀孕,算是帮了巴尔布鲁一把,她的名声可已经是岌岌可危了。
事情就这样了,安德斯·博登这么想。一扇门打开了,你还没来得及走进去,它就关上了。人控制不了自己的命运,就像用红蜡纸标记过的木材被带着细长杆的工人扔回湍急的流水中一样。也许他真的是谣传说的那样:一个土老帽,走运才娶到了一个曾经跟舍格伦一起表演过二重奏的女人。但如果真的是这样,他意识到他的人生,从现在开始,将不会有任何变化,他自己也同样如此。从现在,不,从上周差点儿发生,本可以发生的那一刻起,一直一直,冷若冰霜,保守封闭。从此以后,偌大的世界,什么也不能阻止他心如死灰,妻子不能,教堂不能,朋友也不能。
直到意识到从此之后要跟她老公过一辈子,巴尔布鲁才确信自己对安德斯·博登的感觉。先是小乌尔夫,然后一年后卡琳又出生了。阿克塞尔对孩子们宠爱有加,她自己也是。也许她该知足了。姐姐搬到了遥远的北方,那里盛产黄莓,每季都会送她好多罐黄莓酱。夏天的时候,她和阿克塞尔会去湖上划船。他胖了很多,这也是意料之中的事。孩子们也长大了。有一年春天,锯木厂有个工人,在汽船前面游泳,被碾了过去,周围的水都被染成了红色,就跟遭遇鲨鱼袭击了似的。船上前甲板上有个游客赌誓说直到最后一刻,那个人都游得很淡定。有人振振有词说曾看见受害者的老婆在小树林里幽会他的一个工友,还有人添油加醋说他是喝高了,跟人打赌说可以游过船头。验尸官判定说他肯定是被水流震聋了,死亡原因系不幸意外。
巴尔布鲁肯定会这么说,我们不过是马厩中的马,马厩虽说没有标记,但即便如此我们也知道自己几斤几两。一切都是命中注定的,老天爷让你怎么活就该怎么活。
他要是在我之前了解我的心意该多好啊!我不会跟男的那样讲话,也不会那样听他们说话,更不会那么看着他们的脸。他怎么就是不明白我的心意呢?
那之后他们再见对方,是去教堂做完礼拜后在湖边散步时碰到的,那时彼此身边都有另一半陪着。一见面没过十分钟,她就感到一阵恶心,当时想到自己怀有身孕,还松了一口气,要不这恶心就来得不明不白,有点蹊跷了。她往草丛里呕吐的时候,唯一能想到的就是,扶着她的那双手属于一个不对的人。
她要确保自己永远不单独见安德斯·博登。有一次,她瞥见安德斯在她前面准备上船,就又折回码头那边去了。在教堂,她有时候会瞄见他的后脑勺,然后就想象着此刻他们单独在一起耳语。出门的话,她会确保有阿克塞尔陪同;在家呢,又跟孩子黏在一起。有一次,阿克塞尔提议说邀请博登夫妇来喝咖啡,她回答说博登夫人一定想喝马德拉葡萄酒、吃松糕呢,而且就算你把那些东西给她弄来了,她也会一副趾高气扬的样子看着他们夫妇俩,两个新来乍到的人。于是这个提议就此作罢,之后再也没提过。
她不知道该怎么看待所发生的事。没人可以给她建议。她想到了一些类似的案例,但那些例子都声名狼藉,而且似乎跟她的情况也没什么关系。对于持续不断、无法言说、需要默默承受的痛苦,她毫无准备。有一年,她姐姐送的黄莓酱来时,她看了看那罐子,那玻璃壁,那金属盖子,那圈棉布,那手写的便条,还有上面的日期——日期!——以及所有这一切的原因,也就是那些黄莓酱。她暗自想道:这就是我对自己的心所干的好事。每年,当黄莓酱罐子从北方来的时候,她都这么想。
一开始,安德斯还继续轻声细语地讲着他知道的事给她听。有时候他是导游,有时候又成了锯木厂经理。比如说,他本可以跟她讲讲木材的缺陷。“弧裂”指的是树木内部两圈年轮之间的自然开裂;“星裂”指的是龟裂朝不同方向扩展开来;“心裂”一般发生在老树里,裂缝从树心朝周围延展。
随后的几年中,每当耶特鲁德数落他的时候,每当喝多了的时候,每当别人表面对他很礼貌,眼神之间却告诉他他真的变成了一个讨厌鬼的时候,每当湖面结冰,可以举办赖特维克溜冰比赛的时候,当他家姑娘从教堂回来,已身为人妻,他从她眼中看到空中楼阁般的希望的时候,当漫漫长夜开始,他感觉到自己心门紧闭进入冬眠的时候,当他的马突然停下来,因为它能感觉到却看不到的什么而发抖的时候,当老汽船有一年冬天被停在船坞又重新漆色的时候,当他特隆赫姆的朋友请他带着参观法伦的铜矿,他也答应了,却在出发前一小时发现自己躲在卫生间,手指在喉咙里乱抠,想要使自己快点吐出来的时候,当汽船带着他驶过聋哑人收容所的时候,当小镇已是物是人非的时候,当小镇年复一年万年不变的时候,当海鸥离开了码头上的巢儿,转而飞到他脑袋里鸣叫的时候,当他有一次在风干棚无聊,从一堆木材里抽了一根儿从而导致左手食指第二个关节处截肢的时候——这些时候,以及其他很多时候,他都会想到马茨·伊斯拉埃尔松。随着时间流逝,在他心目中,马茨·伊斯拉埃尔松的故事已经从用来博美人芳心的清晰事实变成了一个更加模糊却又强大的概念。也许,变成了一个传奇——正是她不感兴趣的事情。
她曾说过:“我想去法伦看看。”而他只要回答说“我愿意带你去”就好了。也许,假设她真的像他想象中那些女人一样,嗲声嗲气地说“人家超想去斯德哥尔摩”或是“人家晚上总是梦到威尼斯”,他便会不顾一切,买了第二天早上的火车票,跟她一起制造一桩丑闻,几个月以后,借着酒劲回家求情辩解。但他不是那样的人,同样,她也不是。“我想去法伦看看”可比“人家晚上总是梦到威尼斯”有杀伤力多了。
多年过去了,孩子们也都长大了,巴尔布鲁·林德瓦尔时不时会感到有一阵可怕的焦虑袭来:担心她家姑娘嫁给博登家的小子。她觉得,那应该是世界上最残酷的惩罚了。不过最后,卡琳对布·维坎德情有独钟,而且任凭别人怎么开她玩笑都雷打不动。很快,所有博登和林德瓦尔家的孩子都结婚了。阿克塞尔也发福了,在药店里总是一边气喘吁吁,一边暗地里担心他会不会不小心开错药毒死病人。耶特鲁德·博登头发都白了,而且因为癫痫,只有一只手能弹钢琴。巴尔布鲁一开始还辛辛苦苦拔白头发,后来干脆染了。要说她有什么值得揶揄的小瑕疵的话,那就是她得靠塑形衣的帮助才能保持身材。
一天下午,阿克塞尔对她说:“你有一封信。”他说这话的时候,完全没什么感情色彩,只是把信递给了她。信封上的字体很生疏,邮戳来自法伦。
“亲爱的林德瓦尔夫人,我现在住在法伦的医院。有件事情我很想跟您讨论一下。不知您哪个周三是否方便来看看我?安德斯·博登敬上。”
她把信交给他,看着他把信读了一遍。
“你怎么想?”他问道。
“我想去法伦看看。”
“当然了。”他的意思是:你当然想去了,谣言一直就说你是他的情妇。我一直都不确定,但其实我早该猜到了,你突然变得性情冷淡,而且这么多年来一直魂不守舍,就是因为这个。当然,当然。但她只听到了一句:你当然必须得去了。
“谢谢,我想坐火车去。可能要在那边过夜。”她说。
“当然了。”
安德斯·博登躺在床上考虑着该说些什么。这么多年——确切地说,二十三年——过去了,他们终于看到了彼此的字。这种交流,这种对彼此的惊鸿一瞥,犹如香吻一样甜蜜贴心。她的字很小很干净,属于学校里教出来的那种,而且从字体里看不出一点苍老的痕迹。有那么一小会儿,他想到了他可能从她那里收到的好多好多信。
一开始,他想着要不就把马茨·伊斯拉埃尔松的故事再给她讲一遍,这次他肯定能完美呈现。这样她就会明白,懂得一切。又或者她会吗?仅仅因为这故事日复一日地陪了他二十多年,并不代表她对它有任何印象。这样,她就可能觉得这不过是个恶作剧,是场游戏,事情便会急转而下。
但很重要的一点就是不能告诉她他将不久于人世。这会让她有负担,而这是不公平的。更糟的是,出于同情心,她可能会改变主意。和她一样,他要的也是事实,而非传奇。他告诉护理人员说有个可爱的表妹要来看望他,但她心脏太脆弱了,所以千万不能把他的实际状况告诉她。他还让护士给他刮了刮胡子,理了理头发。等他们走了,他又弄了点牙粉,还把他那残疾的手藏在床单下面。
信来的时候,在她看来,似乎有点直言不讳,就算不是直言不讳,最起码也有点不容辩驳。因为二十三年来,这是他头一次有求于她,因为这个,她丈夫就必须得答应她,毕竟,这么多年来她从来没有做过对不起他的事。他确实也答应她了,不过从那一刻起,事情就变得说不清道不明了。这次出门她该穿什么呢?这样的场合,既非旅行,又非参加葬礼,似乎没什么合适的衣服穿。在车站,检票员还重复了一遍“法伦”,站长又盯着她的旅行箱看了半天。她感到无比脆弱,要有谁轻轻碰她一下,她定会开始跟人家解释她这一辈子,她此行的目的,还有她的德行。“我要去见一个不久于人世的朋友。”她估计会这么说,“毫无疑问,他肯定有什么最后的话想跟我说。”肯定是这样,他要死了,不是吗?要不他没道理这么做,要不早在孩子们都长大成家的时候,早在阿克塞尔和我的婚姻名存实亡的时候,他就这么做了。
她在市场附近的斯特德旅店住了下来,又一次感觉到店员打量着她的旅行箱看,还想打探她的婚姻状况和出行目的。
“我是来看一个住院的朋友的。”没人问,她自己就说了。
来到房间,她盯着环形铁床架、床垫还有崭新的衣橱看了好大一会儿。她之前从来没有自己一个人住过旅馆。她意识到这种地方是女人,确切地说,某些女人来的地方。她现在就能想象到谣言会怎么说她,一个女人家自己一个人住在旅馆。出人意料的是阿克塞尔竟然让她来了,而安德斯·博登什么也不解释就召见她,也够让人意外的。
她内心的脆弱伪装成了愤怒。她到底到这儿干吗来了?他到底想让她怎么样?她想到了之前读过的一些书,那些需要背着阿克塞尔看的书。在书中,旅馆房间的情景都是隐晦处理,不言自明的;在书中,恋人会一起逃到天涯海角,但从没有其中一方躺在医院的情形;在书中,有一些温暖人心的临终前婚礼,但前提是双方都是自由身。这么看来,到底会发生什么事呢?“有件事情我很想跟你讨论一下。”讨论?她,早已人过中年,带了一罐黄莓酱去看望一个只有一点点交情的男人,而且这交情还是二十三年前的事了。说起来,这事能不能有点意义全要看他的了。毕竟他是男人,对她来说,大老远跑来就已经仁至义尽了。这么多年来她一直是个守妇道、受尊敬的女人,可不是浪得虚名的。
“你瘦了。”
“他们说我瘦点好。”他笑着说。虽然他说的是“他们”,但很显然,他指的是“我妻子”。
“博登夫人呢?”
“她别的时候来。”这话在医院职工看来,意思很明白。噢,他老婆在这几天来看他,等他老婆一转身,“她”就来了。
“我以为你病得很严重呢。”
“没有,没有。”他兴高采烈地回答。她看起来很紧张的样子——不得不说,她眼睛一跳一跳的,很紧张,像只小松鼠。他必须安抚她,宽慰她。“我没事的,没事的。”
“我以为……”她停了一下。不行,他俩之间的事必须得说明白。“我以为你要死了。”
“我会像霍克伯格山上的杉树一样长命百岁的。”
他坐在那边咧着嘴笑。胡子刚刚刮过,头发也梳得很有型,他活得好好的,妻子也不在身边。她静静地等着。
“那是克里斯蒂娜大教堂的屋顶。”
她转过身,走到窗户旁边,看着对面的教堂。乌尔夫小时候,要想让他分享个秘密,她就必须转过身背对着他。也许安德斯·博登此刻需要的正是这个。因此,她看着教堂的铜屋顶在阳光下熠熠生辉,静静地等着。毕竟,他才是男人。
她这一沉默不语,背对转身,他就有点慌了。这可不是他计划的样子。他甚至都没能像过去一样,随意亲切地称呼她巴尔布鲁。她以前说过什么来着?“我喜欢听一个男人告诉我他知道的事情。”
“那座教堂是在19世纪中期建造的,”他开始讲了,“不过我不确定具体是什么时候。”她没有回应。“屋顶是用当地铜矿里开采的铜造的。”仍然没有回应。“但我不清楚屋顶是跟教堂同时造的,还是后来加上去的。我打算弄清楚。”他又加了最后这句,想让自己听起来意图明确。她仍旧没有反应。他唯一能听到的是耶特鲁德的窃窃私语:“瑞典旅行联合会的徽章。”
事到如今,巴尔布鲁也挺生自己气的。她从来就不了解他,从来就不知道他到底是个什么样的人。这么多年来,她不过是沉溺在一个小姑娘的幻想中而已。
“你身体挺好的?”
“我会像赫克贝格山的杉树一样长命百岁的。”
“这么说你完全可以到我斯特德旅馆的房间去了?”她说这话的时候,口吻尽量很严厉很刺耳,把自己对全世界男人的鄙视愤恨都表现出来,鄙视他们的雪茄、情妇、木材还有他们那虚荣、傻帽的络腮胡。
“林德瓦尔夫人……”他顿时一片混乱。他想说他爱她,他一直都爱着她,他大部分——不对,是全部的——时间都在想她。“我大部分——不,全部——时间都在想你,”他本来是这么准备的,然后再接着说,“从我第一次在汽船上见到你,我就爱上你了。从那时起,你就支撑了我的生活。”
她一生气,他就乱了阵脚。她以为他不过是个花花公子。所以他准备的那些话听起来也会像诱惑人的甜言蜜语。而且,说起来他也根本不了解她。或者说他根本就不知道怎样跟女人说话。有些男人,巧舌如簧,总是知道什么时候说什么话,一想到这个他就愤愤不平。看她生气了,他突然想,别憋着了,一吐为快吧,都是要死的人了,就别憋着了。
“我以为,”他感觉到自己舌头打结,又咄咄逼人,就像男人笨嘴结舌地跟人讨价还价一样,“我以为,林德瓦尔夫人,以为你爱我。”
他看到她的肩膀顿时僵硬起来。
“啊?”男人的虚荣啊。这么多年来,她一直以为他为人没得挑,谨言慎行,稳重老练,现在看来真是大错特错。事实上,他不过是一个普通男人,做着书里的男人做的那些事,而她不过是另一个相信他们与众不同的女人。
她仍旧背对着他,就好像他是当年的小乌尔夫,藏着自己孩子气的秘密。“你误会了。”接着她转过身来,面对着这个凄惨可怜、咧着嘴笑的花花公子,心想很明显他认识去旅馆的路。“不过,谢谢——”她不善于挖苦讽刺,简单考虑了一下终于想到一个托辞——“谢谢你告诉我聋哑人收容所在哪里。”
她想要不要把那罐黄莓酱拿回来,但又觉得那样不大合适。她还能赶上晚上一班火车,一想到在法伦的旅馆过夜,她就觉得恶心。
相当长的一段时间,安德斯·博登脑袋中都一片空白。他看到铜屋顶披上了一层暗色。他把自己残疾的手伸出床单,弄乱头发,还把那罐黄莓酱给了第一个走进病房的护士。
关于人生,他学到的一点就是:在巨大悲恸面前,小小痛苦会变得无关紧要。比如说,跟牙疼比,肌肉拉伤算不了什么,而要是手指被压碎了,牙疼也就无所谓了。现在,他真的指望着这条规则呢。他希望,癌症的痛苦、人之将死的痛苦能减轻他失去挚爱之痛,但,看起来好像不可能。
他想,心碎的时候,就跟木材裂开一样,顺着纹路自上而下完全开裂。他刚去木材厂的时候,曾见过古斯塔夫·奥尔森拿一块硬木头,弄一个楔子进去,然后轻轻一拧那楔子,木头就顺着纹路,从头到尾裂开了。心脏也是如此,只要找到了纹路,轻轻一扭,一个手势,一句话,就能将它击毁。
夜幕降临,火车环湖驶过,湖面一片暗色,这里可是一切开始的地方。随着羞愧和自责渐渐散去,她试着把这件事捋清楚。这也是唯一使自己不那么痛心的办法:保持头脑清晰,只关注真正发生的事情,只关注事实。而她所知道的事实就是:在过去的二十三年中,她可以随时为之抛夫弃子、名声扫地、地位全无的那个男人,她可以跟他直到天涯海角的那个男人,从来就不配,以后也配不上她的爱。阿克塞尔,她敬重的男人,他是个好父亲,养家糊口的本事也没得挑,他才是值得她爱的男人。但如果把她对安德斯·博登的感觉作为爱的标准的话,她并不爱他。这也就是她人生的悲哀:纠结在爱上一个不值得爱的人和不爱一个值得爱的人之间。她曾以为是自己人生支柱的那个人,那个不断给她带来各种可能性,那个她曾以为会像自己的影子或是水中的倒影一样忠诚可靠的人,不过真的是个影子、倒影而已。一切都是假的。尽管她自称缺乏想象力,尽管她对传奇毫不感冒,她却任凭自己在一个轻佻无聊的梦中度过了大半生。唯一还拿得出手的一点就是她的德行了,但这又算哪门子说法呢?假如有一场考验,她可是半刻也抵挡不了诱惑的。
讲条理,摆事实,她这么一考虑,羞愧和自责又卷土重来,而且有增无减。她解开左边袖口的纽扣,从手腕上褪下那个早已掉色的蓝色缎带,任其掉落在马车上。
听到马车驶入的声音,阿克塞尔·林德瓦尔随即把烟丢进空空的壁炉。他从妻子手里接过旅行箱,扶她下来,又付了车钱。
一进到房间里面,她就充满爱意地说:“阿克塞尔,你怎么总是在我不在的时候抽烟呀?”
他看着她,茫然不知所措,也不知道该作何回答。他不想问她法伦的事,怕这一问会逼她说谎又或者逼她说实话,而无论是谎言还是事实,他都同样害怕。沉默。唉,他想,我们总不能以后一辈子都这么一言不发地过日子吧。所以,他最后还是回答了一句:“因为我喜欢抽烟。”
她笑了笑。他们两个,站在黑黑的壁炉前。而他,仍然提着她的旅行箱。因为他知道,这箱子里边装着所有的秘密,所有他不想听到的秘密,所有事实和谎言。
“我比预计提前回来了。”
“嗯。”
“我决定不在法伦过夜。”
“嗯。”
“那个城市一股铜的味道。”
“嗯。”
“不过克里斯蒂娜教堂的屋顶在夕阳下熠熠生辉。”
“有人这么跟我说过。”
看着妻子这个样子,他很痛心。无论她准备了什么说辞,都得让她讲出来,要不都不人道。于是他问了个问题。
“他,他……怎么样了?”
“哦,他挺好的。”直到说出口,她才发现自己这话有多荒唐,“也就是说,他现在躺在医院,但他又挺好的,不过我怀疑事情不是这个样子的。”
“一般来说,人要是挺好的话是不会去医院的。”
“嗯,没错。”
他后悔自己这么讽刺他。曾经有一位老师对他的学生说过,讽刺是一种道德上的弱点。他现在怎么会突然想起这茬儿?
“然后呢?”
直到这一刻她才意识到自己得跟人家说说这次的法伦之行,不是说发生的各种小事,而是此行的目的。走的时候,她还想象,等她回来的时候事情肯定早就有了天翻地覆的变化,而不管具体怎么变,总之已经没有解释的必要了。现在一度陷入沉默,她开始慌了。
“他希望把他教堂的马厩给你,4号。”
“我知道是4号,睡吧。”
“阿克塞尔,在火车上的时候,我就在想咱俩可以一起变老,越快越好。我想人老的时候,事情就会容易很多。你觉得对吗?”
“睡吧。”
没人的时候,他又点了一支烟。她的谎言是那么荒诞可笑,以至于都有可能是真的了。但不管真假,结果都是一样的。要是她说的是假的,那真相就是她这次可是公开(比过去更公开)去看望了情人,或者说老情人?要是她说的是真的呢,那博登的礼物可就算得上是对他的讽刺了,老情人对受委屈的丈夫的嘲弄?这种礼物,必定会炒得沸沸扬扬、满城风雨的。
从明天开始,他的人生将会有一个全新的开始。他现在意识到,到目前为止,他的人生原来不是他想象中那样,而正是这一点,给他的人生带来了巨大变化。过了今晚,一切都得到证实,关于过去,他还能保有纯洁无污的回忆吗?也许她是对的,他俩是应该努力一起变老,然后指望着时过境迁,心脏变得冷漠坚硬起来。
“那边怎么回事儿?”护士问道。这个病人语无伦次了,一般最后一刻都这样。
“其他……”
“什么?”
“其他是枪炮钱。”
“枪炮钱?”
“为了唤醒回声。”
“什么?”
他不断重复那句话,声音听起来很吃力。“其他是枪炮钱,唤醒回声要用的。”
“不好意思,博登先生,我听不懂你在讲什么。”
“那我希望你永远不要弄明白。”
葬礼上,安德斯·博登的棺材就摆在三十年战争期间从德国带回来的石雕圣坛前面,棺木是用白杉树做的,在小镇十字路口不远的地方风干。牧师称赞他是一棵参天大树,倒在了上帝的斧头之下。这个比喻对会众来说也不是头一次听到了。教堂外面,4号马厩空空如也,在向死者致敬。遗嘱中没有规定马厩的归属去向问题,他儿子也早就搬到了斯德哥尔摩。一番商讨后,马厩被奖给了汽船船长,他可是出了名的德高望重。
走夜路请放声歌唱-李娟
========================
走夜路请放声歌唱-[[李娟]]
------
在呼蓝别斯,大片的森林,大片的森林,还是大片的森林。马合沙提说:走夜路要大声地歌唱!在森林深处,在前面悬崖边的大石头下——你看!那团黑乎乎的大东西说不定就是大棕熊呢!大棕熊在睡觉,在马蹄声惊扰到它之前,请大声歌唱吧!远远地,大棕熊就会从睡梦中醒来,它侧耳倾听一会儿,沉重地起身,一摇一晃走了。一起唱歌吧!大声地唱,用力地唱,“啊啊”地唱,闭着眼睛,捂着耳朵。胸腔里刮最大的风,嗓子眼开最美的花。唱歌吧!!
呼蓝别斯,连绵的森林,高处的木屋。洗衣的少女在河边草地上晾晒鲜艳的衣物。你骑马离开后,她就躺在那里睡着了,一百年都没有人经过,一百年都没人慢慢走近她,端详她的面孔。她一直睡到黑夜,大棕熊也来了,嗅她,绕着她走了一圈又一圈。这时远远的星空下有人唱起了歌。歌声越来越近,她的睡梦越来越沉。大棕熊的眼睛闪闪发光。
夜行的人啊,黑暗中你们一遍又一遍地经过了些什么呢?在你们身边的那些暗处,有什么被你永远地擦肩而过?那洗衣的少女不曾被你的歌声唤醒,不曾在黑暗中抬起面孔,在草地上支撑起身子,循着歌声记起一切……夜行的人,再唱大声些吧!歌唱爱情吧,歌唱故乡吧!对着黑暗的左边唱,对着黑暗的右边唱,再对着黑暗的前方唱。边唱边大声说:“听到了吗?你听到了吗?”夜行的人,若你不唱歌的话,不惊醒这黑夜的话,就永远也走不出呼蓝别斯了。这重重的森林,这崎岖纤细的山路,这孤独疲惫的心。
夜行的人啊,若你不唱歌的话,你年幼的阿娜尔在后来时光的所有清晨里,再也不能通过气息分辨出野茶叶和普通的牛草了。你年幼的阿娜尔,你珍爱的女儿,她夜夜哭泣,她胆子小,声音细渺,眼光不敢停留在飞逝的事物上。要是不唱歌的话,阿娜尔将多么可怜啊!她一个人坐在森林边上,听了又听,等了又等,哭了又哭。她身边露珠闪烁,她曾从那露珠中打开无数扇通向最微小世界的门。但是她却再也打不开了。你不唱歌了,她便一扇门也没有了!
要是不唱歌的话,木屋边那座古老的小坟墓,那个七岁小孩的蜷身栖息之处,从此不能宁静。那孩子夜夜来找你,通过你的沉默去找他的母亲。那孩子过世了几十年,当年他的母亲下葬他时,安慰他小小的灵魂说:“亲爱的宝贝啊你我缘分已尽,各自的道路却还没有走完,不要留恋这边了,不要为已经消失的疼痛而悲伤……”但是,你不唱歌了,你在黑夜里静悄悄地经过他的骨骸。你的安静惊动了他。你的面庞如此黑暗,他敏感地惊疑而起。他顿时无可适从。
要是不唱歌的话,黑暗中教我到哪里去找你?教我如何回到呼蓝别斯?那么多的路,连绵的森林,起伏的大地。要是不唱歌的话,有再多的木薪也找不到一粒火种,有再长的寿命也得不到片刻的自如。要是不唱歌的话,说不出的话永远只能哽咽在嗓子眼里,流不出的泪只在心中滴滴悬结坚硬的钟乳石。
我曾听过你的歌声。那时,我站在呼蓝别斯最高的一座山上的最高的一棵树上,看到了你唱歌时的样子。他们喜欢你才吓唬你,他们说:“唱歌吧,唱歌吧!唱了歌,熊就不敢过来了。”你便在冷冷的空气中陡然唱出第一句。像火柴在擦纸上擦了好几下才“嗤”地引燃一束火苗,你唱了好几句才捕捉到自己的声音。像人猿泰山握住了悬崖间的藤索,你紧紧握住了自己的声音,在群山间飘荡。那时我就站在你路过的最高的那座山上的最高的那棵树上,为你四面观望,愿你此去一路平安。
我也曾作为实实在在的形象听过你唱歌。还是在黑夜里,你躺在那里唱着,连木屋的屋檐缝隙里紧塞的干苔藓都复活了,湿润了,膨胀了,迅速分裂、生长,散落肉眼看不到的轻盈细腻的孢子雨。你躺在那里唱啊唱啊,突然那么忧伤。我为不能安慰你而感到更为忧伤。我也想和你一起唱,却不敢开口。于是就在心里唱,大声地唱啊唱啊,直到唱得完全打开了自己为止,直到唱得完全离开了自己为止。然后,我的身体沉沉睡去。但是,在这样的夜里,哪怕睡着了仍然还在唱啊,唱啊!大棕熊,你听到了吗?大棕熊你快点跑,跑到最深最暗的森林里去,钻进最深最窄的洞穴里去。把耳朵捂起来,不要把听到的歌声再流出去。大棕熊你惊讶吧,你把歌声到来的消息四处散布吧!大棕熊,以歌为分界线,让我们生活得更平静一些吧,更安稳一些吧……
OK,亲爱的,哪怕后来去到了城市,走夜路时也要大声地唱歌,像喝醉酒的人一样无所顾忌。大声地唱啊,让远方的大棕熊也听到了,静静地起身,为你在遥远的地方让路。你发现街道如此空旷,行人素不相识。
-----
2007
# 嘴唇美丽而我的双眸澄碧
[[塞林格 ]]
------
电话铃响起时,灰白头发的男人问那姑娘,口气里还稍稍带着几分恭敬,地是不是觉得他还是不接为好。姑娘像是从远处听到他说话似的,她把脸转向他,一只眼睛——给光照着的那只
一紧闭,那只张开的眼睛,尽管有点让人看不遗,却是特别的大,而且湛蓝湛蓝的几乎像是到了紫色的地步。灰发男人催她快着点儿,于是她抬起右前臂,仅仅没有慢到给人一种在应付差事的感觉。她用左手把前额上的头发往后掠掠,说道:“上帝啊。我也不知道。我是说你想是怎么回事?”灰发男人说他认为接与不接都不会有多大差别,接着便把自己的左手插到姑娘支撑身体的胳臂底下肘部前而点的地方,将几只手指往前挪,在地前臂与胸口之间那片温暖的区域里开拓空间。他用右手去够话筒。为了快些拿到话筒,他只得将身子往上坐了坐,这就使他的后脑勺轻轻触到灯罩的一角。在那一瞬间,灯光使他那头几乎已成白色的灰发显得特别辉煌,如果不说是特别充满动感的话。虽然头发此刻有些凌乱,但显然是刚理过的,——或者不如说,是新 “做” 过的。后颈与鬓角处按传统方式剪得短短的,但两侧与顶部的头发却留得比一般都显得长,而且,事实 L,是 “很有点气派” 了。“喂?”他用洪亮的声音对着电话问。姑娘继续用一只胳膊支起身子,看着他。她那双跟睛与其说是很警惕或猜疑,倒不如说仅仅是睁得很大,主要是在显示出它们本身的大小与颜色。
一个男人的声音从电话线那头传了过来,这声音石头般死板,却有点粗鲁,在目前这样情况下几乎是节奏快得有点让人反感。“是李吗? 我吵醒你了吗?”
灰发男子眼光快快地朝左边那姑娘扫了一眼。“是谁呀?” 他问。“是阿瑟吗?”
“是啊——我吵醒你了吧?”
“没有,没有。我在床上看书呢。出什么事了吗?”
“你能肯定我没吵醒你? 没说假话?”
“没有,没有——绝对没有,” 灰发男子说,“事实上,我一天平均也就是胡乱睡上个四小时——”
“我给你去电话的原因是,李啊,你有没有碰巧看到琼安妮是什么时候离开的? 你有没有注意她是不是跟埃伦博根两口子一起离开的? 你正好注意到了吗?”
灰发男子再次朝左看去,可是这回眼光扫得高了一些,没看那姑娘,她这会儿正像个年轻、蓝眼睛的爱尔兰警察那样盯看着他呢。“没有,我没注意,阿瑟,” 他说,眼光看着房间昏暗的远处,那是墙壁与天花板的接连处。“她没跟你一起离开吗?”
“没有。基督啊,没有。那么说,你根本没见到她离开了?”
“嗯,没有,我确实是没有见到,阿瑟,” 灰发男子说。“说实在的,我整个晚上实际上什么都没见到。我刚进门,就给缠住了,好长时间都摆脱不开,给那个法国傻瓜还是维也纳傻瓜——谁知道到底是什么地方人呢。他娘的每一个这号外国佬都眼睛瞪得老大,就等着一个子儿不出,享受免费法律咨询呢。怎么了? 出什么事了? 琼安妮不见了吗?”
“噢,基督。谁知道呢? 我可不知道。你知道她灌是了酒一心要走的时候会怎么样的吧。我不清楚。她也许只是一”
“你给埃伦博根家打电话了吗?” 灰头发的人问道。
“噢。他们还没回家,我不清楚。基督啊,我连她是不是和他们一起离开的都不清楚。我就清楚一件事。我他妈的就拿得准一件事:我是彻底把脑力都耗尽了。我不开玩笑。我这回确实是当真的。我完了。五年哪。基督呀。”
“好啦,先尽量宽宽心,好不好,阿瑟,” 灰头发说。“首先,如果我没看错埃伦博根夫妻的话,他们很可能是一起跳上辆出租车上村子去呆上几个小时了。他们仨没准会砰地一推门闯回——”
“我有这么个感觉,她方才也许是到厨房对某个狗杂种下功夫去了。我只不过是有这种感觉。她灌是了酒总要到厨房去跟某个混小子搂搂抱抱的。我算是完了。我对天起誓这回绝对不是开玩笑。是是五个年头一’
“你现在在哪儿,阿瑟?” 灰头发问。“在家里吗?”
“是啊。在家里。家,可爱的家。基督啊。”
“好了,你就尽量放松一点——你现在的状态是——喝多了,还是怎么的?”
“我不知道。我他妈的怎么会知道呢?”
“好了,哎,听着。放松些。就是要放橙,” 灰头发说。“你知道埃伦博根夫妻脾气的,老天爷呀。可能是出了什么事,他们可能误了他们的末班火车。他们仨没准下一分钟就会闻进你家门,兴高采烈,一股夜总会的一’
“他们是开车去的。”
“你怎么知道的?”
“给他们看孩子的姑娘呗。我跟她进行了几番很让人开窍的谈话。我们关系铁得很呢。都成了一个豆荚里的两颗豆子了。”
“很好。很好。不过那又怎么样呢? 你坐坐稳,放松一会儿,行吗?” 灰头发的男人说。“他们三个没准下一分钟就翩然驾到呢。信我的话好了。你是了解利昂娜脾气的。我不知道这究竟是怎么回事——这些 ^ 一旦来到纽约就仝会染上这种康涅狄格轻骨头病。你是知道的。”
“是啊。我知道。我知道。不过,我仍然不明白。”
“你当然是明白的。用用你的想像力嘛。那两口子没准是生拉硬拽,把琼安妮——”
“听着。琼安妮从来不需要谁把她拉拽到哪儿去。别给我灌输这一套鬼道理。”
“没人想给你灌输什么呀,阿瑟,” 灰头发心平气和地说。
“我知道,我知道!原谅我。基督呀,我真是昏了头了。说真的,我的确没把你从梦中吵醒吗?”
“真吵醒我会告诉你的,阿瑟,” 灰头发说。他下意识地把左手从姑娘前臂与胸口间抽出来。“嗨,阿瑟。你想听听我的劝告吗?” 他说。他把紧靠话筒的电话线在手指间捻来捻去。“我这是认真的。你想听听劝告吗?”
“唉。我也说不上来。基督啊。我在耽误你时间了。我干吗不干脆把我的——”
“就听一分钟,” 灰头发说,“首先——我一点也不开玩笑,懂吗——赶快上床,安静下来。给自己调好一大杯香喷喷的睡前酒,然后钻进——”
“睡前酒! 逗我了吧? 基督啊,刚才这两个倒霉的小时里我都往肚子里灌了大约~夸脱那玩意儿了。睡前还喝啊! 我此刻像上了石膏似的连动都--”
“好吧。好吧。那就上床吧,” 灰头发说。“别多想了--听到了吗? 老实说,坐着干着急又有什么用呢?”
“是啊,我懂。我连操心都不操心,天哪,可是这女的没法叫人相信! 我对天起誓。我对天起誓她这人没法叫人相信。你相信她的程度只能相当于扔出去一只——我也说不上来扔出去的是什么。唉——,有什么用呢? 我都快发疯了。”
“行了。别再想这事了,听话。忘了它,好吗? 你先尽力把这一切从脑子里清出去,就算帮我一个忙,行不?” 灰头发说。“依我看,你是在一一我真是这么想,你是在给自己背上一座大山——”
“你知道我在干什么吗? 你知道我在干什么吗? 我都没脸告诉你,可是你知道我几乎每天晚上都他妈的干什么吗? 我下班回家的时候? 你想知道吗?”
“阿瑟,听着,这不是一个——”
“等一等——我跟你说了吧,妈的。实际 E 我不得不强压着自己不去打开公寓里他妈的每一个壁柜的门——我对天起誓。我每天晚上回家,真怕会在这儿那儿找到藏起来的一个个狗杂种。开电梯的小子啦。送外卖的小子啦。警察啦——”
“好了。好了。咱们还是尽量放松一些,阿瑟,” 灰头发的人说。他猛地朝右瞥了一眼,那里有根晚上早些时候点着的香烟平放在烟灰缸上。可是显然早就熄灭了,他也设有拿起来。“首先,” 他对着电话说,“我告诉过你多少多少遍了,阿瑟,这正是你铸成最大错误的关键所在。你知道你干了什么吗? 你愿意听我讲你干了什幺吗? 你路走偏了——我这么说是非常认真的,懂吗——你确实是路走偏了所以在折磨自己。实际上,真的是你,在诱导琼安妮——” 他打断了话头。“你他妈真是福气碰到了她这么个了不起的孩子。我真是那么想的。你对这孩子完全不说一句好话.尽管她有这么高的趣昧——或者是头脑,大哪,为了这一点”
“头脑 J 你在开玩笑吧? 她他妈的一点儿头脑都没有! 她是个动物!”
灰头发的人,他的鼻孔在翕动,像是要深深吸一口气。“我们全都是动物,” 他说。“从根本上说,我们全都是动物.”
“我们才他妈的不是呢。我他妈的就不是。我也许是一个愚蠢、腐败的二十世纪的狗崽子,可是我不是动物。别给我来这一套。我不是动物。”
“我说,阿瑟。这样说话是不是让我们--”
“头脑。耶稣啊,你知道情况有多可笑吗? 她以为自己他妈的挺有学问呢。这正是好笑之处,这正是滑稽之处。她看报纸的戏剧版,她看电视节目看得眼睛都快瞎了一以为这一来她就有学问了。你知道我娶到的是谁吗? 你想知道我娶回家的是什么人吗? 我娶的是当夸最伟大最具潜力,有待发现的女演员、女小说家和女心理分析师,而且是纽约全能的他妈的没受到欣赏的名人兼天才。这你原来不知道吧,是吧? 基督呀,这真可笑我都想一刀把我喉咙给切了。哥伦比亚附校的一位包法利夫人呀。包法——”
“谁?” 灰头发问,听上去有点恼怒。
“包法利夫人还上《电视欣赏》课呢。上帝啊,你要是知道多么
“行了,行了:你知道这样说下去咱们什么问题都解决不了,” 灰头发说。他转过头去向那个姑娘做了个手势,将两根手指放在自己嘴边,意思是给他一根烟。“首先,” 他说.对准了话筒,“你也算是个绝顶聪明的人,可是你行事既不老练又简直像个普通老百姓。” 他把身子坐直,好让那姑娘能从他身后伸手过去够到香烟。“我不是在开玩笑。这表现在你的私人生活上,也表现在你的
“头脑,噢,我的天,真要了我的命了! 伟大的基督啊! 你可曾听到过她形容别人——某个男人,我指的是? 什么时候你没事儿做时,就算帮我一个忙,让她绐你形容一下某个男人。她把她看到的每一个男人都描写成‘极有魅力’。哪怕是最最老、最最不起眼、最最油滑的——”
“行了,阿瑟,” 灰头发很不高兴地厉声说。“说这有什么用。一点儿用也没有。” 他从姑娘手里接过一根烟。姑娘点燃了两根。“顺便问问,” 他说,把烟从两个鼻孔里喷出来,“今天你的事办得怎么样?”
“什么?”
“你今天的事情办得怎么样?” 灰头发重复了一遍。“你的案件办得如何了?”
“哦,基督! 我不知道。糟透了。在我正开始作最后陈述的前两分钟,原告的辩护律师,那个利斯贝格,把那个疯疯癫癫的女清洁工传进庭来,还带着一摞床单作为证据——上面都是臭虫污迹。基督啊 j”
“后来怎么样? 你输啦?” 灰头发问,又吸了口烟。
“你知道法官席上坐的是谁? 是‘维多利奥大娘’。这家伙干吗跟我过不去,我到死也弄不明白了。我连嘴都还没张开他就劈头盖脸压过来了。跟这样的家伙是无理可喻的,根本就说不清。”
灰头发扭过头去看看那姑娘在干什么。她已捏起姻灰缸,要把它放在两人中间。“你是输了,那么说,还是怎的?” 他对着话筒说。
“什么?”
“我说,你是小是输了?”
“是啊。我本打算告诉你的。可是晚会上乱哄哄的,我没找到机会。你认为二世会大发雷霆吗?倒不是我会有任何一电点在乎,不过你觉得怎么样? 认为他会吗?”
灰头发用左手在烟灰缸边缘上蹭了蹭他那根烟上的灰烬。“我不认为他非得要大发雷霆不可,阿瑟,” 他平平静静地说。“不过,几率非常之大的是,他也不见得会对这事兴高采烈。你知道,我们代理这三家倒霉旅馆有多久了吗? 斯坦利老头本人开创整个——',
“我知道,我知道。二世告诉我至少有五十遍了。这是我一辈子听到的最最美妙的故事之一。是的,我是输了那场倒霉官司。可是得说清楚,那可不是我的错。第一,这疯子维多利奥整个审判过程中给我设下圈套。然后那傻大姐女清洁工让大家传看被单,上面都是臭虫的--”
“没有人说是你的错,阿瑟,” 灰头发说。“你方才问二世会不会大发雷霆,我对此有何看法。我就给你一个坦白的——”
“我知道——我知道那…… 其实我也不清楚。管它呢。反正我可以重新进军队的。我告诉你这个了吗?”
灰头发再次把头朝姑娘转过去,也许是让她看看,自己的表情是如何的克制,甚至都像修炼得很好的苦行僧了。可是姑娘错过了看这张脸。她方才膝盖一动碰翻了烟灰缸,此刻止匆匆忙忙用手指把烟灰撮作便于收拾的一小堆;她抬眼看他恰好慢了一秒钟。“不,你没说过,阿瑟,” 他对着话筒说。
“是啊。我可以去的。我还没想好。自然,这个主意我并小是特别热中,能不去我也就不去了。不过我说不定只好去。我还说不上来。至少,那是一种解脱。如果军队能发还我那顶小头盔、我的又宽又大的写字桌以及我那顶可爱的大蚊帐,也许就不必——”
“我真想往你那脑瓜袋里塞点理智进去,伙计,这就是我想干的,” 灰头发说。“照说你是他妈的——众人眼里的一个聪明人哪,怎么说话十是像个菝子。我这样说完全是真心诚意的。你让一些微不是道的小事搀杂在一起,让它们滚雪球般滚到一个程度,它们就在你脑子里占着他妈的绝对统治地位,因此你就全然不能胜任一丁点儿——”
“我早就该离开她的。你知道吧? 去年夏天我就该把事情了结的,当时我刚真正开始滚这个雪球——你知道的吧? 你知道我为什幺没有这么做? 你想不想知道我为什么不做?”
“阿瑟。看在基督分上。咱们这么谈一点儿结果都不会有的。”
“等一等。让我来告诉你为什么! 你想知道我为什么没干? 我可以把准确的答案告诉你。因为我替她感到难过。这就是全部的简单真理。我替她感到难过。”
“这个嘛,我不大了解。我是说我无权发表意见,” 灰头发说。“不过,在我看来,有件事你似乎忘了,那就是琼安妮是个成年女人了。我不了解,不过在我看来--”
“成年女人! 你疯了吗? 她是个成年小孩,我的天哪! 听着,我正要刮胡子——好好听着——我正耍刮胡子,突然之间她从公寓的最远的一端喊我。我就得去看看出了什么事——我胡子正刮到
半,我那张倒霉的脸上满是泡沫。你知道她为什么叫我? 她想问,我是不是觉得她脑袋瓜挺好使。我对上天起誓。她不可救药了,我告诉你吧。她睡着时我认真观察过她,我知道我在说什么。相信我好了。”
“嗯,这事儿你应该了解得比——我是说我不宜发表意见,” 灰头发的人说。“但是,问题是,妈的,你根本没做任何建设性的事来”
“我们是错误的结合,就是这么回事。说穿了就是如此。我们错误结合错到家了。你知道她需要的是什么吗? 她需要有个粗壮高大、不爱吭声的狗杂种,隔上一阵走过来把她揍得人事不省——揍完了又走回去继续看报。她需要的就是这个。对她来说我他妈的太软弱了。我们结婚时我就知道这点了——我对天起誓,当时我就明白了。你鬼精灵,你从来不结婚,不过人们结婚之前,他们脑子里偶尔会闪过一些想法,预见到婚后会出现什么情景。我忽略了这档子事。我忽略了自己也得闪念闪念。我太软弱了。基本情况大体上就是这样。”
“你不是软弱。你只不过是不动脑子,” 灰头发说,从姑娘手里接过一根新点燃的烟。
“我当然是软弱! 我当然是软弱!他娘的,我是不是软弱我自己清楚! 如果不是我软弱,你以为我还会让所有的事搞得一团糟吗——啊,说这些有什么用? 我当然是软弱…… 天哪,我让你一整夜没法睡觉了。你干吗不把电话对我啪地一摔呢? 我说的是实话。你挂上得了。”
“我可不想啪地对你摔电话,阿瑟。我愿意帮助你,总要尽尽心吧,” 灰头发说。“实际上,你是你自己最大的——”
“她不尊重我。她甚至都不爱我,老实说。基本上把话说穿了我也不再爱她了。我也说不清楚。我爱,也不爱。造没准儿。总是起伏不定。基督啊! 每回我下定决心要采取行动了,我们总因为什么事到外面去吃饭,我们约好在什么地方见面,她戴着白手套什么的款款走来。我说不清楚。或者是我会开始想起我们初次驾车去纽黑文看那场普林斯顿球赛了。我们刚驶离花园人道有一只车胎就瘪了,天气冷得邪门,我拾掇倒霉的车胎时她给我打着手电你明白我的意思吧。我说不清楚。或者是我开始想起——基督啊,这挺不好意思的——我开始想起我们开始来往时我献给她的那首狗屁诗歌。‘玫瑰般我的肤色而且雪白,嘴唇美丽面我的双眸澄碧。’基督啊,真让人不好意思——这诗总让我想起她。她眼睛不是绿颜色的——她那双眼睛像他妈的海贝壳,我的老天——可是这诗还是让我想起她…… 我说不清楚,说这些又有什么用呢? 我都昏了头了。朝我捧电话吧,你干吗不摔? 我不开玩笑。”
灰头发那人清了清嗓子,说道,“我不想对你挂断电话,阿瑟。只有一件——”
“她有一回给我买了一身套服。用她自己的钱。这事我跟你说过吗?”
“没有,我——”
“她径直走进特里普勒时装店,我想是这家,买了下来。我甚至都没跟她一起去。我是说,她还有一些他妈蛮不错的素质的。好笑的是,那套衣服还不坏。我只需臀围处收小一点——我说是裤子——再改改短就行了。我是说她有些蛮不错的素质。”
灰头发又听了片刻。接着,他突然转向姑娘。他对她看了一眼,虽然只是短短的一瞥,但是充分告诉她电话那一头突然发生了什么。“哎,阿瑟。听着。这样做不会有任何好处。我是认真的。喂,听着。我这么说可是诚心诚意的。你能不能像个正常人那样,脱掉衣服上床睡觉? 好好放松自己,行吗? 琼安妮说不定两分钟以内就会回家的。你小想让她瞧见你这副样子吧,对吗? 该死的埃伦博根两口子没准会跟她一起闯进来。你总不想让这么多人看到你这副模样吧,是不是?” 他听着。“阿瑟? 你听见我说的话吗?”
“上帝啊,我弄得你一夜没睡。我不管做什么事,总做得——”
“你没使得我一夜没睡,” 灰头发说。“快别这么想。我不是跟你说过,我每晚平均也就睡四个小时嘛。只要办得到,我想做的是,伙计,就是帮助你。” 他听着。“阿瑟? 你在那儿吗?”
“是的。我在。听着。反正我也弄得你没法再睡了。我能上你那儿去喝上一杯吗? 你不在乎吧?”
灰头发那人把身子坐坐直,把没拿电话的那只手按在头顶上,说:“现在吗? 你的意思是?”
“对啊。我是说如果你不反对的话。我只呆一分钟。我只不过是想在什么地方坐上一坐——我说不清楚。这样行吗?”
“行啊,不过问题是我不认为你应该来,阿瑟,” 灰头发说,同时把按在头顶上的手放了下来。“我的意思是你来我再欢迎不过,可是我确实认为你应该做的就是稳坐家中了放松自己,等琼安妮翩然来到。你要做的就是在地翩然而至时正好在现场。我说得对呢,还是不对?”
“是啊。我说不清楚,我对天起誓,我说不上来。”
“嗨,我可清楚,我非常非常清楚,” 灰头发说。“我说,干吗你不立刻跳上床去,放松自己,过一会儿,倘若你真的想,就给我打个电话。我的意思是如果你想跟人谈谈的话。还有千万别着急。这才是最重要的。听到我的话啦? 现在你愿意这么做吗’”
“好吧。”
灰头发的人把话筒在耳朵边继续放了一会儿,然后将它放回到机子上。
“他说什么来着?” 姑娘紧接着问他。
他把他那根烟从烟灰缸里挑出来——也就是说,从一堆吸过和吸了一半的烟头中挑出来。他长长地吸了口,说,“他要过来喝杯酒。”
“天哪! 你是怎么说的?” 姑娘问。
“你不是听到我的话了嘛,” 灰头发那人说,眼睛看着她。“你听得见我的话的。不是吗?” 他把烟掐灭了。
“你方才真了不起。绝对了不起,” 姑娘说,注视着他。“天哪,我觉得自己真像是条狗!”
“哼,” 灰头发说,“是够难对付的。我不知道自己有这么了不起。”
“你是了不起。你真是神了,” 姑娘说。“我都瘫了。我绝对是瘫了。你瞧瞧我 l”
灰头发的人看着她。“嗨,说实在的,这局面是够难缠的,” 他说。“我的意思是这整个局面是那么奇特甚至都没——”
“亲爱的——真对不起,” 姑娘急匆匆地说.一边身子往前伛去。“我想你是着火了。” 她用几只手指的指肚在他手背上快快地拂了一下。“没事儿。只不过是一点点烟灰。” 她身子靠了回去。“不。你方才真了不起,” 她说。“上帝啊,我觉得自己纯粹是一条狗!”
“噼,局面确实是非常非常扎手。那家伙显然是在经受一场绝对的——”
电话铃猛地响起。
灰头发男人说了声 “基督啊!” 但不等铃第二次响他就拿起话筒。“喂?”他对着话筒说。
“李吗? 你睡着啦?”
“不,没有。”
“听着,我只是寻思你一定很想知道。琼安妮刚刚回到家了。”
“什么?” 灰头发那人说,把左手搭在眼睛上方,虽然灯是在他的身后。
“是啊。她刚大摇大摆回来了。就在我跟你通话后的十秒钟。我只是觉得乘她上厕所该给你去个电话。听着,真是万分感激。李,我不是开玩笑——你知道我是什么意思。你还没睡着吧,啊?”
“没,没有。我正要——没有,没有,” 灰头发说,手仍然搭在眼睛上方。他清了清嗓子。
“是的。事情显然是这样,利昂娜喝得烂醉如泥,随着便他妈的号啕在哭起来,鲍勃要琼安妮跟他们一起出去上哪儿喝杯什么来安定神经。我说不清楚,你是明白的。乱成了一团。总之,后来她回家了。真是乱到家了。说实在的,我想都是因为这该死的纽约。我想也许我们应该这样做:如果一切顺利,我们没准得在康涅狄格州给自己找一小块地方。倒不一定非得特别远,只要远得让我们能他妈的过正常生活就行。我是说她非常喜欢种点花草什么的。要是她有自己他妈的花园什么的她没准会乐得发疯。明白我的意思吗? 我的意思是,我们在纽约除了一群疯子之外还认识什么人? 你当然不在其列。就算是正常人也迟早会给逼疯的。明白我的意思吧?”
灰头发没有回答。挡在手掌后面的一双眼睛闭得紧紧的。
“不管怎样,我准备今天晚上跟她谈谈这件事。或者,也许明天。她仍然有些醉。我的意思是她从根本上讲还是个非常不错的孩子,如果我们有机会把我们的事情稍稍处理得好一些,那么至少该试一试,否则岂不是他妈的太蠢了。我这么做的时候,我也打算把这件糟透了的臭虫案子理理顺。我一直在考虑。我方才就在琢磨.李。你觉得怎样,如果我当初走进去亲自跟二世谈一谈,我本可以——”
“阿瑟,如果你不介意的话,我很想一’
“我的意思是我不想让你以为我又给你重新打电话什么的是因为我担心我那混账法律事务之类的事。我不担心。我的基本意思是,看在基督的分上,我最最不担心的就是这个。我只是想,要是我不费什么心思就能把二世的事摆平,那我不这样做岂不是个大傻——”
“听着,阿瑟,” 灰头发打断了对方的话,把手从他脸上移开,“我忽然觉得头疼得要命。我不知道这毛病是怎么得的。我们就先谈到这里好不好? 明天早上咱们再谈——行吗?” 他又听了片刻,然后挂上电话。
姑娘马上又去跟他说话,可是他没有回答。他从烟灰缸捡起一根点燃的香烟——这根是姑娘的——开始往嘴边送去,可是香烟从他手指间滑脱下来。姑娘想在烧着别的东西之前帮他抬起来,可是他却告诉她看在基督的分上坐着别动,于是姑娘抽回了自己的手。
!最后,TiddlyWiki 是一种哲学
取得和组织一份笔记(或记录任何类型的内容)的目的是为了能于稍后检索。如果在您的笔记记录系统中找不到您的笔记,则您的笔记变成浪费太多时间。
TiddlyWiki 哲学,是最好的做笔记方式,是把他们分成条目,可能的最小语义单位。条目可以是一张图片、一个网页链接、一个概念、一个术语定义或是一个特定的自订宏。
这些条目则可以被编织在一起以创建更长的单位:故事、文章、清单、图库和更多。TiddlyWiki 的功能如标签、超链接和筛选器,可以协助您以多种方式将条目联系和连接在一起,便于将来检索您的笔记,甚至帮助您看到条目与其包含的信息之间的非预期的关系。
最后的铁匠-刘亮程
========================
最后的铁匠-[[刘亮程]]
-----
铁匠比那些城外的农民们,更早地闻到麦香。在库车,麦芒初黄,铁匠们便打好一把把镰刀,等待赶集的农民来买。铁匠赶着季节做铁活儿,春耕前打犁铧、铲子、刨锄子和各种农机具零件,麦收前打镰刀。当农民们顶着烈日割麦时,铁匠已转手打制他们刨地挖渠的坎土曼了。
铁匠们知道,这些东西打早了没用。打晚了,就卖不出去,只有挂在墙上等待明年。
吐尔洪· 吐迪是这个祖传十三代的铁匠家庭中最年轻的小铁匠。他十三岁跟父亲学打铁,今年二十四岁。成家一年多了,有个不到一岁的儿子。吐尔洪说,他的孩子长大后说啥也不让他打铁了,教他好好上学,出来干别的去。吐尔洪说他当时就不愿学打铁,父亲却硬逼着他学。打铁太累人,又挣不上钱。他们家打了十几代铁了,还住在这些破烂房子里,他结婚时都没钱盖一间新房子。
吐尔洪的父亲吐迪·艾则孜也是十二三岁学打铁。他父亲是库车城里有名的铁匠,一年四季,来订做铁器的人络绎不绝。那时的家境比现在稍好一些,妇女们头戴面纱,在家做饭看管孩子,从不到铁匠炉前去干活。父亲的一把锤子养活一家人,日子还算过得去。吐迪也是不愿跟父亲学打铁,没干几天就跑掉了。他嫌打铁锤太重,累死累活挥半天才挣几块钱,他想出去做买卖。父亲给了他一点钱,他买了一车西瓜,卸在街边叫卖。结果,西瓜一半是生的,卖不出去。生意做赔了,才又垂头丧气回到父亲的打铁炉旁。
父亲说,我们就是干这个的,祖宗给我们选了打铁这一行都快一千年了,多少朝代灭掉了,我们虽没挣到多少钱,却也活得好好的。只要一代一代把手艺传下去,就会有一口饭吃。我们不干这个干啥去。
吐迪就这样硬着头皮干了下来,从父亲手里学会了打制各种农具。父亲去世后,他又把手艺传给四个弟弟和一个妹妹。他们又接着往下一辈传。如今在库车老城,他们家族共有十几个打铁的。吐迪的两个弟弟和一个侄子,跟他同在沙依巴克街边的一条小巷子里打铁,一人一个铁炉,紧挨着。吐迪和儿子吐尔洪的炉子在最里边,两个弟弟和侄子的炉安在巷口,一天到晚炉火不断,铁锤叮叮当当。吐迪的妹妹在另一条街上开铁匠铺,是城里有名的女铁匠,善做一些小农具,活儿做得精巧细致。
吐迪说他儿子吐尔洪坎土曼打得可以,打镰刀还不行,欠点儿功夫。铁匠家有自己的规矩,每样铁活都必须学到师傅满意了,才可以另立铁炉去做活。不然学个半吊子手艺,打的镰刀割不下麦子,那会败坏家族的荣誉。吐迪是这个家族中最年长者,无论说话还是教儿子打镰刀,都一脸严肃。他今年五十六岁,看上去还很壮实。他正把自己的手艺一样一样地传给儿子吐尔洪·吐迪。从打最简单的马黄钉,到打坎土曼、镰刀,但吐迪·艾则孜知道,有些很微妙的东西,是无法准确地传给下一代的。铁匠活儿就这样,锤打到最后越来越没力气。每一代间都在失传一些东西。比如手的感觉,一把镰刀打到什么程度刚好。尽管手把手地教,一双手终究无法把那种微妙的感觉传给另一双手。
还有,一把镰刀面对广阔的田野,各种各样的人。每一把镰刀都会不一样,因为每一只用镰刀的手不一样,每只手的习惯不一样。打镰刀的人,靠一双手,给千万只不一样的手打制如意家什。想到远近田野里埋头劳作的那些人,劲儿大的、劲儿小的,女人、男人、孩子……铁匠的每一把镰刀,都针对他想到的某一个人。从一块废铁烧红,落下第一锤,到打成成品,铁匠心中首先成形的是用这把镰刀的那个人。在飞溅的火星和叮叮当当的锤声里,那个人逐渐清晰,从远远的麦田中直起身,一步步走近。这时候铁匠手中的镰刀还是一弯扁铁,但已经有了雏形,像一个幼芽刚从土里长出来。铁匠知道它会长成怎样的一把大弯镰,铁匠的锤从那一刻起,变得干脆有力。
这片田野上,男人大多喜欢用大弯镰,一下搂一大片麦子,嚓的一声割倒。大开大合的干法。这种镰刀呈抛物线型,镰刀从把手伸出,朝后弯一定幅度,像铅球运动员向后倾身用力,然后朝前直伸而去,刀刃一直伸到用镰者性情与气力的极端处。每把大镰刀又都有微小的差异。也有怜惜气力的人,用一把半大镰刀,游刃有余。还有人喜欢蹲着干活儿,镰刀小巧,一下搂一小把麦子,几乎能数清自家地里长了多少棵麦子。还有那些妇女,用耳环一样弯弯的镰刀,搂过来的每株麦穗都不会撒失。
打镰刀的人,要给每一只不同的手准备镰刀,还要想到左撇子、反手握镰的人。一把镰刀用五年就不行了,坎土曼用七八年。五年前在这儿买过镰刀的那些人,今年又该来了,还有那个短胳膊买买提,五年前订做过一只长把镰刀,也该用坏了。也许就这一两天,他正筹备一把镰刀的钱呢。这两年棉花价不稳定,农民一年比一年穷。麦子一公斤才卖几毛钱,割麦子的镰刀自然卖不上好价。七八块钱出手,就算不错。已经好几年,一把镰刀卖不到十块钱。什么东西都不值钱,杏子一公斤四五毛钱。卖两筐杏子的钱,才够买一把镰刀。因为缺钱,一把该扔掉的破镰刀也许又留在手里,磨一磨再用一个夏季。
不论什么情况,打镰刀的人都会将这把镰刀打好,挂在墙上等着。不管这个人来与不来。铁匠活儿不会放坏。一把镰刀只适合某一个人,别人不会买它。打镰刀的人,每年都剩下几把镰刀,等不到买主。它们在铁匠铺黑黑的墙壁上,挂到明年,挂到后年,有的一挂多年。铁匠从不轻易把他打的镰刀毁掉重打,他相信走远的人还会回来。不管过去多少年,他曾经想到的那个人,终究会在茫茫田野中抬起头来,一步一步向这把镰刀走近。在铁匠家族近一千年的打铁历史中,还没有一把百年前的镰刀剩到今天。
只有一回,吐迪的太爷撑锤时,给一个左撇子打过一把歪把大弯镰。那人交了两块钱定金,便一去不回。吐迪的太爷打好镰刀,等了一年又一年,等到太爷下世,吐迪的爷爷撑锤,他父亲跟着学徒时,终于等来一个左撇子,他一眼看上那把镰刀,二话没说就买走了。这把镰刀等了整整六十七年,用它的人终于又出现了。
在那六十七年里,铁匠每年都取下那把镰刀敲打几下。打铁的人认为,他们的敲打声能提醒远近村落里买镰刀的人。他们时常取下找不到买主的镰刀敲打几下,每次都能看出一把镰刀的欠缺处:这个地方少打了两锤,那个地方敲偏了。手工活就是这样,永远都不能说完成,打成了还可打得更精细。随着人的手艺进步和对使用者的认识理解不同,一把镰刀可以永远地敲打下去。那些锤点,落在多少年前的锤点上。叮叮当当的锤声,在一条窄窄的胡同里流传,后一声追赶着前一声。后一声仿佛前一声的回音。一声比一声遥远、空洞。仿佛每一锤都是多年前那一锤的回声,一声声地传回来,沿我们看不见的一条古老胡同。
吐迪·艾则孜打镰刀时眼皮低垂,眯成细细弯镰的眼睛里,只有一把逐渐成型的镰刀。儿子吐尔洪就没这么专注了,手里打着镰刀,心里不知道想着啥事情,眼睛东张西望。铁匠炉旁一天到晚围着人,有来买镰刀的,有闲的没事看打镰刀的。天冷了还是烤火的好地方,无家可归的人,冻极了挨近铁匠炉,手伸进炉火里燎两下,又赶紧塞回袖筒赶路去了。
麦收前常有来修镰刀的乡下人,一坐大半天。一把卖掉的镰刀,三五年后又回到铁匠炉前,用得豁豁牙牙,木把也松动了。铁匠举起镰刀,扫一眼就能认出这把是不是自己打的。旧镰刀扔进炉中,烧红、修刃、淬火,看上去又跟新的一样。修一把旧镰刀一两块钱,也有耍赖皮不给钱的,丢下一句好话就走了,三五年不见面,直到镰刀再次用坏。一把镰刀顶多修两次,铁匠就再不会修了。修好一把旧镰刀,就等于少卖一把新的。
吐迪家的每一把镰刀上,都留有自己的记痕。过去三十年五十年,甚至一二百年,他们都能认出自己家族打制的镰刀。那些记痕留在不易磨损的镰刀臂弯处,像两排月牙形的指甲印,千年以来他们就这样传递记忆。每一代的印记都有所不同,一样的月牙形指甲印,在家族的每一个铁匠手里排出不同的形式。没有具体的图谱记载每一代祖先打出的印记是怎样的形式。这种简单的变化,过去几代人数百年后,肯定会有一个后代打在镰刀弯臂上的印记与某个祖先的完全一致,冥冥中他们叠合在一起。那把千年前的镰刀,又神秘地、不被觉察地握在某个人手里。他用它割麦子、割草、芟树枝、削锨把儿和鞭杆……千百年来,就是这些永远不变的事情在磨损着一把又一把镰刀。
打镰刀的人把自己的年年月月打进黑铁里,铁块烧红、变冷、再烧红,锤子落下、挥起、再落下。这些看似简单,千年不变的手工活,也许一旦失传便永远地消失了,我们再不会找回它。那是一种生活方式。它不仅仅是架一个打铁炉,掌握火候,把一块铁打成镰刀这样简单的一件事。更重要的是打铁人常年累月,一代一代积累下来的那种心理。通过一把镰刀对世界人生的理解与认识,到头来真正失传的是这些东西。
吐尔洪·吐迪家的铁匠铺,还会一年一年敲打下去。打到他跟父亲一样的年岁还有几十年时间呢,到那时不知生活变成什么样子。他是否会像父亲一样,虽然自己当初不愿学打铁,却又硬逼着儿子去学这门累人的笨重手艺。在这段漫长的铁匠生涯中,一个人的想法或许会渐渐地变得跟祖先一样古老。不管过去多少年,社会怎样变革,我们总会在一生的某个时期,跟远在时光那头的祖先们,想到一起。
吐尔洪会从父亲吐迪那里,学会打铁的所有手艺,他是否再往下传,就是他自己的事了。那片田野还会一年一年地生长麦子,每家每户的一小畦麦地,还要用镰刀去收割。那些从铁匠铺里,一锤一锤敲打出来的镰刀,就像一弯过时的月亮,暗淡、古老、陈旧,却永不会沉落。
(一)
(火车站,十点钟,几个静谧的寂寞散布月台,没有送行人,没有泪。)
M,列车误点,我心中的信仰已及时出发,送我抵达新的起点,在穿越这座城市最后一段灯火绚烂的路后,在闯出你温柔的疑惑后。当一切的一切都制度化和规律化的时候,美感和自由被压缩成一箱箱的罐头再按时配给。M,我心中的金线菊已凋谢,这儿的人文温度与气候,不再是我所能适应的环境,我知道我该去寻觅另一片土地来栽植自己的存在了。
(二)
M,在我永远离开这座城市前,让我以淡红月光刷亮我俩的往昔,好好的回味一遍,再将这些心灵的底片,深锁在脑袋秘密的一隅。你还记得吗?M,初遇你的那一天,我正在素描河岸的景色,画高高的淡紫的天(工厂的黑烟只在梦中得见),画静静的清泓的河(污染已成历史名词),画蓝蓝的草远远的山。你出现后,忍不住将你也轻轻放进去。长发是风的线条,你是山巅偷偷溜下来的冰雪精灵,用三分纯真三分清雅四分爽朗打造的笑声当钥匙,开启大门占据我的心城。手中的画笔一度是你我的桥梁,我说我每一幅画后头都隐藏一盏灯,孜孜然探索通往永恒的方向,一直到有一天你告诉我你已觅得永恒,我才惊觉一幅幅的画已竖立成一堵堵的墙,挡隔你的心河交流我的。
(三)
“画画?要画上多少幅才追得上你远远落在别人后头的生活价值指标的分数,成为和我同级的第一等市民?艺术创作部那里随便一名V型画家的随便一幅作品都比你的作品来得逼真!”听到我拒绝接受改造成为新人类,你负气地说出这番话。M,你成熟了,开始懂得追求你以前不懂或不屑去追求的,包括你所谓的永生。你往昔的灵秀已逐渐消失,也不再喜欢我的画了。M,你和我都冀求永恒,站在同一个起点出发,你却选择了大多数市民所认同的方向,不伴我彳亍另一条(的确,是苦得多且曲折得多的)路,你坚持你走的是通向伊甸园的大道,我虽不肯定自己的这一条路能否到达永恒,却坚信我要的永恒绝不是别人所能赐予的。我决定离去,M,你始终不了解我的画追求的并不是相似,正如我理想中的永恒不是寿命的延长而已。
(四)
星际战争结束已近百年,留下的阴影却化做紫云,从上一代飘临并笼罩下一代的心城。数不清的核弹带走七分之六的人口,也将战前的信念和人生价值观一起炸碎,浩劫来掠夺生命时如何避免被它擒下,成了战后文明最重要的焦点课题。电脑PL-56型说,在异地的古代有一种民族,为了祈求死后重生,尸体浸在甘草和香料混合的汁液里,再用特制的白布层层包裹。每次碰见新人类,我就联想起这个故事。M,过了今夜,你也是新人类了——除了大脑,全身上下都由大大小小的超合金零件组合成的不死人。过了今夜,全体市民不是机械人,就是新人类,所有不肯成为新人类的市民,都将被流放到异地去。听说,那儿是一个混乱和落后的地方,各民族尚未统一,人们也尚未掌握永生的科技,仍然有爱,有恨,有梦。
(五)
M,除了最原始的的生命,月台上的每一个人早将拥有的一切都典当了,换得一张奔向未知的车票,只为了不愿放弃我们的梦想。M,我们抛弃一切去追求的东西,正是你们所不屑一顾的。M,你还记得那一幅画吗?当一群白鸟飞向光明,它们的影子却飞向黑暗。M,你飞向你的,我飞向我的光明;你飞向你的,我飞向我的黑暗。
(六)
列车已抵站,M,这是最佳的分离方式最恰当的分离时刻吧?
(十点三十分,列车滑出月台,升上深紫色的夜空。四座爪性的引擎喷出雾状气流,缓缓摆动的车厢布满鳞状白金护片,两支细长的须型雷达仪不断旋转。上部两座炮台,下部装满丝型机枪的车头射出两道长长的激光,探测太阳系中第三颗蓝色行星的位置……)
The standard mechanisms in ~TiddlyWiki for creating Table-of-Contents are macros known collectively as "toc" [[macros|Macros]] (click on link to learn more about macros). They use `Tagging` as their means of creating relationships, so be sure to review the [[Tagging]] topic tiddler if tagging is a new concept for you.
A customisable [[table of contents|常用]] can be added to the sidebar with the following steps:
# Create a tiddler called [[TableOfContents]]
# Give it the tag ''~$:/tags/SideBar''
# Set the text to <div><pre><code><$text text="""
<div class="tc-table-of-contents">
<<toc-selective-expandable 'TableOfContents'>>
</div>"""/></code></pre></div>
# Add a ''caption'' field with the text ''Contents''
# Add a ''list-after'' field with the text ''~$:/core/ui/SideBar/Open''
Add entries to the table of contents by creating tiddlers tagged ''~TableOfContents''. An easy way is to choose <<.icon $:/core/images/new-here-button>> ''new here'' from the tiddler toolbar of the ''~TableOfContents'' tiddler.
(if you don't see the "new here" button, click on the down arrow <<.icon $:/core/images/down-arrow>> to see more menu options.)
To create child tiddlers (tiddlers that come below other tiddlers), tag them with the name of the parent tiddler.

在 COMPUTEX 2025 即將登場前,AMD 日前透過官方社群平台發佈預熱內容,其中一張顯示卡廣告圖引發玩家關注。從設計特徵判斷,該張圖片**極有可能對應尚未公開的 Radeon RX 9060 XT** 顯示卡。
訂閱T客邦電子日報 掌握最熱門的科技話題、網路動態,升級你的科技原力!

### 雙風扇雙槽厚度 僅需 8Pin 單組供電
從 AMD 曝光的圖片來看,這款新卡採用雙風扇散熱、雙槽厚度設計,並且僅需 **單組 PCIe 8Pin 供電接口**,在電力需求與整體發熱控制上預期較為溫和,對中階玩家與小機殼配置更為友善。
整體造型風格與先前曝光的 RX 9070(XT)相似,延續 Radeon 系列簡約、實用導向的設計語言。
值得注意的是,圖片下方標註「**Artist render. Not available for purchase.**」(藝術概念圖,非市售版本),代表此卡未來可能不會推出由 AMD 官方製造的 MBA(Made By AMD)版本,零售市場上將由 AIB 廠商(如華碩、技嘉、藍寶石等)推出各自客製版本。
### 預期規格:Navi 44 核心、最高 16GB 記憶體
根據先前爆料,RX 9060 XT 將採用 AMD RDNA 4 架構下的 **Navi 44 GPU 核心**,規格包括:
- **32 個計算單元(CU)**,對應 2,048 個串流處理器(SP)
- **128-bit 記憶體位寬**
- **GDDR6 顯示記憶體,提供 8GB 或 16GB 容量選項**
從整體定位來看,RX 9060 XT 將屬於中階甜點卡級距,主打 1080p 或 1440p 遊戲體驗,並對應更具效能與功耗效率比的主流市場需求。
- **延伸閱讀:[AMD Radeon RX 9060 XT 顯示卡傳並未取消8GB版本,預計將與16GB版本同步推出](https://www.techbang.com/posts/122999-amd-radeon-rx-9060-xt-launching)**
- **延伸閱讀:[傳AMD考慮取消RX 9060 XT 8GB版本,避免重蹈 RTX 5060 Ti 8GB覆轍](https://www.techbang.com/posts/122847-amd-rx-9060-xt-8gb-cancel-rumor)**
- **延伸閱讀:[AMD RX 9060 XT 傳將搭載 3.2GHz 超高頻率!劍指 RTX 5060 系列,價格有望壓到台幣13000元以內](https://www.techbang.com/posts/122601-amd-rx-9060-xt-32ghz-rtx-5060-rival)**
[#顯示卡](https://www.techbang.com/tags/29)[#AMD](https://www.techbang.com/tags/46)[#遊戲](https://www.techbang.com/tags/72)[#記憶體](https://www.techbang.com/tags/114)[#gpu](https://www.techbang.com/tags/424)[#radeon](https://www.techbang.com/tags/1988)[#rdna 4](https://www.techbang.com/tags/41752)[#navi 44](https://www.techbang.com/tags/41757)[#rx 9060 xt](https://www.techbang.com/tags/50741)[#computex 2025](https://www.techbang.com/tags/51691)

!!![[ODROID-HC4]]
[[ODROID-HC4|https://www.hardkernel.com/shop/odroid-hc4/]]$ 65.00/RM270
!!![[ODROID-H2+]]
[[ODROID-H2+|https://www.hardkernel.com/shop/odroid-h2plus/]]$119.00/RM500
---
!!!raspberry pi 4
* 4gb RM240
* 8gb RM311
---
NanoPi R4S
[[NanoPi R4S|https://www.friendlyarm.com/index.php?route=product/product&product_id=284]]
Go to edit mode in this tiddler (use the {{$:/core/images/edit-button}} button above), and after one of the paragraphs, type `[[dav`. You should see the autocomplete popup with the tiddler `Dave Gifford` listed. Hit enter, which will accept the autocomplete suggestion and will close the link with brackets.
<span class="indent1">//Note that when the popup gives you more than one tiddler to choose from, you will need to use the down arrow key on your keyboard to navigate to the other entries listed in the autocomplete popup. Once the tiddler you want to select is highlighted, you can hit enter, and that tiddler should be the one to appear in the link.<br><br>
Note that autocomplete does not work in iOS or other contexts where there is no down arrow key. At the end of the tutorial we will give instructions on how to disable autocomplete for those contexts.//</span>
Go back to viewing mode, click the link you created to the `Dave Gifford` tiddler, and follow the instructions in that tiddler.
When you are done here, return to [[Welcome to Stroll]] to continue the tutorial.
\define toc-heading(caption,body)
<$reveal type="nomatch" state=<<qualify "$:/state/toc/$caption$">> text="show">
<$button set=<<qualify "$:/state/toc/$caption$">> setTo="show" class="btn-invisible">{{$:/core/images/right-arrow}} $caption$
</$button>
</$reveal>
<$reveal type="match" state=<<qualify "$:/state/toc/$caption$">> text="show">
<$button set=<<qualify "$:/state/toc/$caption$">> setTo="hide" class="btn-invisible">{{$:/core/images/down-arrow}} $caption$
</$button>
</$reveal>
<$reveal type="match" state=<<qualify "$:/state/toc/$caption$">> text="show" retain="yes" animate="yes">
$body$
</$reveal>
\end
Welcome to ~TidMarks, a simple way to organize your web bookmarks in ~TiddlyWiki.
<div class="tw-table-of-contents">
# <<toc-heading "Download ~TidMarks" "
# {{ $:/_Download }}
">>
# <<toc-heading "Create bookmarks" "
# {{ $:/_CreateBookmarks }}
">>
# <<toc-heading "Navigate and retrieve bookmarks" "
# {{ $:/_NavigateRetrieve }}
">>
# <<toc-heading "Upgrade" "
# {{ $:/_Upgrade }}
">>
# <<toc-heading "Why no browser extension?" "
# {{ $:/_Extension }}
">>
# <<toc-heading "Help us out" "
# {{ $:/_Help }}
">>
</div>
[[All my tags]]<br>
[[All my indexes]]
You can create an n-dash with a double hyphen `--` and an m-dash with a triple hyphen `---`. For example -- this is an example --- and so is this
--example---
; Term being defined
: Definition of that term
; Another term
: Another definition
-----
That renders as:
Term being defined
Definition of that term
Another term
Another definition
... and the underlying HTML is:
<dl><dt>Term being defined</dt><dd>Definition of that term</dd><dt>Another term</dt><dd>Another definition</dd></dl>
Evernote file imported on 20210108T083350Z from Evernote/Windows (6.x)
!Fleeting Notes 临时笔记
临时笔记。Fleeting 是短暂的, 飞逝的意思, 恰好准确地定义了这种笔记的特性。 这类笔记保存于我们的“收件箱”。可以记录任何想到的事情,各种灵光一现的想法,是所有笔记的起始点。“短暂”的意思就是在这里存放的笔记是临时的,必须定时整理到下一个卡片盒中。“定时整理”是很重要的一件事,我对收件箱的定义就是“一个必须每天清空的地方”。如果不去及时整理,那么很容易就积累起来,成为一大堆笔记之后,我们就没有那个心气儿去整理了。这就像我以前使用稍后读应用一样,如果不坚持每天阅读,很快那个未读数量就会变成1K+,这时候,我最喜欢的功能就是“全部标记为已读”了。
Available character formatting includes:
* <code>`backticks`</code> for `code` (<<.icon $:/core/images/mono-line>>)
** Alternatively, <code>``double backticks allows `embedded` backticks``</code>
* `''bold''` for ''bold text'' (<<.icon $:/core/images/bold>>)
* `//italic//` for //italic text// (<<.icon $:/core/images/italic>>)
* `__underscore__` for __underscored text__ (<<.icon $:/core/images/underline>>)
* `^^superscript^^` for ^^superscripted^^ text (<<.icon $:/core/images/superscript>>)
* `,,subscript,,` for ,,subscripted,, text (<<.icon $:/core/images/subscript>>)
* `~~strikethrough~~` for ~~strikethrough~~ text (<<.icon $:/core/images/strikethrough>>)
\define lingo-base() $:/language/ControlPanel/Basics/
Welcome to ''Stroll'' and the ~TiddlyWiki community!
If you didn't come here from the Stroll website, please [[go there first|https://giffmex.org/stroll/stroll.html]] for the tutorial.
Before you start storing important information in Stroll, it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details
[[https://giffmex.org/stroll/stroll.html]]
!! Set up this ~TiddlyWiki
<div class="tc-control-panel">
|<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
|<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
|<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag="textarea" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
</div>
See the [[control panel|$:/ControlPanel]] for more options.
!Updating Stroll
To upgrade your Stroll file to the most recent version of TiddlyWiki, see https://tiddlywiki.com/static/Upgrading.html for details.
After upgrading, come to the present tiddler (https://giffmex.org/stroll/stroll.html#Updating%20Stroll) and drag this tag pill: <<tag $:/giffmex/stroll>> into your file and save changes. This should update the tiddlers and add any new ones.
The usual handling of [[paragraphs in wikitext|Paragraphs in WikiText]] causes single line breaks to be ignored, and double linebreaks to be interpreted as the end of a paragraph.
This behaviour isn't convenient when dealing with material that incorporates hard linebreaks - for instance, poetry. You can mark a block of content as containing hard line breaks like this:
<<wikitext-example src:'"""
This is a line
and this is a new line
while this is yet another line
and this is the final one
apart from this one
"""'>>
![[Home Assistant插件|https://www.home-assistant.io/integrations/#downloading]]
[[Deluge|https://www.home-assistant.io/integrations/deluge/]]
[[Transmission|https://www.home-assistant.io/integrations/transmission/]]
[[qBittorrent|https://www.home-assistant.io/integrations/qbittorrent/]]
[[Plex Media Server|https://www.home-assistant.io/integrations/plex/]]
[[Nextcloud|https://www.home-assistant.io/integrations/nextcloud/]]
!Summary
TiddlyWiki provides support for rendering pure HTML markup. To do this, simply wrap your HTML code in
```
<html>your html markup goes here</html>
```
This way you are able to use embed code using iFrames often suggested by popular media sites like ~YouTube.
!!"""Embedded HTML"""
```
<html>
<span style="padding-right:30px;font-size:2em;">any</span><br />
<b>valid</b> <em>xhtml</em>
</html>
```
<html><span style="padding-right:30px;font-size:2em;">any</span><br /><b>valid</b> <em>xhtml</em></html>
!!"""Embedded iFrame"""
```
<html>
<iframe src="https://www.youtube.com/embed/Cj6ho1-G6tw"
width="450" height="315" frameborder="0" allowfullscreen/>
</html>
```
<html>
<iframe src="https://www.youtube.com/embed/Cj6ho1-G6tw?vq=hd720&iv_load_policy=3"
width="450" height="315" frameborder="0" allowfullscreen/>
</html>
HTML tags and comments can be used directly in WikiText. For example:
```
<article class="hello">
This is my nice and simple block of text. HelloThere
<!-- This comment will not appear in the wikified output -->
</article>
```
[[Widgets share the same syntax as HTML tags|Widgets in WikiText]], and so the following information applies to them, too.
! Block mode versus Inline mode
To get the content of an HTML element to be parsed in block mode, the opening tag must be followed by two linebreaks.
Without the two linebreaks, the tag content will be parsed in inline mode which means that block mode formatting such as wikitext tables, lists and headings is not recognised.
! Self closing elements
The following tags are treated as 'void'. This means that `<tag>` is treated as if it were `<tag/>`, and that no terminating `</tag>` is needed (if one is provided it will be ignored and treated as plain text).
* `<area>`, `<base>`, `<br>`, `<col>`, `<command>`, `<embed>`, `<hr>`, `<img>`, `<input>`, `<keygen>`, `<link>`, `<meta>`, `<param>`, `<source>`, `<track>`, `<wbr>`
If you don’t close any other tag then it will behave as if the missing closing tag were at the end of the tiddler.
! Attributes
In an extension of conventional HTML syntax, attributes of elements/widgets can be specified in several different ways:
* a literal string
* a transclusion of a TextReference
* a transclusion of a [[macro/variable|Macros in WikiText]]
* as the result of a [[Filter Expression]]
!! Literal Attribute Values
Literal attribute values can use several different styles of quoting:
* Single quotes (eg `attr='value'`)
* Double quotes (eg `attr="value"`)
* Tripe double quotes (eg `attr="""value"""`)
* No quoting is necessary for values that do not contain spaces (eg `attr=value`)
Literal attribute values can include line breaks. For example:
```
<div data-address="Mouse House,
Mouse Lane,
Rodentville,
Ratland."/>
```
By using triple-double quotes you can specify attribute values that contain single double quotes. For example:
```
<div data-address="""Mouse House,
"Mouse" Lane,
Rodentville,
Ratland."""/>
```
!! Transcluded Attribute Values
Transcluded attribute values are indicated with double curly braces around a TextReference. For example:
```
attr={{tiddler}}
attr={{!!field}}
attr={{tiddler!!field}}
```
!! Variable Attribute Values
Variable attribute values are indicated with double angle brackets around a [[macro invocation|Macro Calls in WikiText]]. For example:
```
<div title=<<MyMacro "Brian">>>
...
</div>
```
!! Filtered Attribute Values
Filtered attribute values are indicated with triple curly braces around a [[Filter Expression]]. The value will be the first item in the resulting list, or the empty string if the list is empty.
This example shows how to add a prefix to a value:
```
<$text text={{{ [<currentTiddler>addprefix[$:/myprefix/]] }}} />
```
! 图片
显示保存于条目的图片,只需嵌入该条目:
```
{{Motovun Jack.jpg}}
[img[https://tiddlywiki.com/favicon.ico]]
```
您也可以从编辑器工具栏插入图片。点击''图片'' (<<.icon $:/core/images/picture>>) 且选择一个图片。
如果图片来源为图片条目名称,则直接显示条目。否则它被解译为一个 URL 和生成一个 HTML `<img>` 标记包含值为 URL 的 `src` 属性。
可以指定提示消息:
```
[img[An explanatory tooltip|Motovun Jack.jpg]]
```
可以提供属性以指定 CSS 类别的图片宽度和高度:
```
[img width=32 [Motovun Jack.jpg]]
[img width=32 class="tc-image" [Motovun Jack.jpg]]
```
请注意可以将属性指定为嵌入或为变量引用:
```
[img width={{!!mywidth}} class=<<image-classes>> [Motovun Jack.jpg]]
```
图片的语法是援引 ImageWidget 的简写形式。
! 嵌入显示图像
您还可以嵌入方式显示存储在条目的图片。这种方法的缺点是没有直接的方法来控制图片的大小。
```
{{Motovun Jack.jpg}}
```
显示结果:
{{Motovun Jack.jpg}}
! 图片作为链接
```
<$link to="HelloThere" tooltip="自定义工具提示">{{$:/core/icon}}</$link>
```
显示结果:
<$link to="HelloThere" tooltip="自定义工具提示">{{$:/core/icon}}</$link>
! 导入图像
使用 <<.button import>> 按钮 (在侧边栏的 <<.sidebar-tab Tools>> 页签中),或拖放。
详见 [[导入条目|Importing Tiddlers]]。
K星走狗-王晋康
========================
K星走狗
时空平移 [[王晋康]]
-----
1
于平宁一杯接一杯地往肚里倒酒,目光冷漠地环视这家小酒馆。他正休假,工作期间他是不喝酒的,因为“工作就是有效的麻醉剂”。但休假期间,只有睡觉时他才与酒杯暂别,他需要酒精来冲淡丧妻失女的痛苦。
已经八年了。
他今年三十八岁,身材颀长,五官端正,面部棱角分明,额角刻着一道深深的伤痕,鬓边有一绺醒目的白发,穿一件半旧的灰色夹克衫,敞着领口。八年前他参加世界刑警组织西安“反K星间谍局”(局内人常称反K局),从一名无名小卒已晋升到中校。每逢休假,他都要回到家乡古宛城,在一些烟雾腾腾,酒气汗臭混杂的小酒馆打发时光。他希望在这儿拾到一些儿时的回忆,把他的“自我”再描涂一遍,包括对妻女的痛苦思恋。
反K局极端残酷的工作使他逐渐失掉了自我。
快把一瓶卧龙玉液灌完时,腰间的可视电话响了。他取下来,液晶屏幕上是局秘书新田鹤子小姐的头像。于平宁低声喝道:“休假期间不许打扰我!”
新田鹤子在屏幕上焦急地连连鞠躬,就像阿拉伯魔瓶中关着的小精灵:“对不起,于先生,请你不要关机,老板有急事找你!”
老板是指反K局的局长伊凡诺夫将军,自从参加反K局他就在这老头的手下。这俄国人古板严厉,甚至可以说是残忍,但为人刚正,对于平宁一直很好。既然是老头子亲自出马,一定有急事,休假要提前结束了。
屏幕上出现便装的伊凡诺夫将军,他难得地微笑着,简捷地说:“很抱歉打扰了你的休假,你必须马上返回。”
酒店里人声鼎沸,女招待穿着超短裙,脊背裸露,在各个桌子间忙碌。酒鬼们高声猜拳行令,瞅空还要在女招待身上摸一把,引起一片哄笑。于平宁忧郁地看着芸芸众生,难免有些羡慕。这些人无忧无虑,不知道地球与K星的战争已迫在眉睫。实际上早在八年前,K星人就向地球展开间谍战,但是地球政府对此事一直严格保密,害怕造成全球性恐慌。试想,如果有一天你得知你的上级、朋友、甚至爱人孩子都可能是K星制造的与原型一模一样的生物机器人,他们守在你身边,伺机咬你一口,那时你对这个世界的信念还能保持么?
全世界只有数百人了解实情,他们默默地扛着这副沉重枷锁,这副本该由50亿人共同肩负的枷锁。于平宁是其中之一。
于平宁驾驶着白色风神900,这是2153年的新产品,时速可达300公里,有自动导航和防撞功能。不过他没有使用自动挡,从中学起他就喜欢体育,拳击、散打、攀岩……样样精通,手动驾驶时速300公里的汽车更是一种乐趣。他沿着宁西高速公路西行,很快就看到秦岭逶迤的山峰,前边出现了一个巨大的公路隧道。
已经八年了,但每次走到这里,他仍然感到噬人心肺的痛苦。八年前,他是位于十堰的风神汽车公司的一名工程师。有一次他带妻子和女儿去西安度假,行至此处,忽然看到前边山凹飞升起一块下圆上尖的东西,颇似农夫的斗笠,被一团阴冷的绿光浸透,似乎本身也是一块绿色透明体,飞起来极其轻灵飘忽。乍一见他并没想到这是飞碟,毕竟这只是炒了几百年的陈旧神话。但是女儿菲菲唱歌似地喊道:“爸爸、妈妈,这是飞碟,是E·T!”
她拍着小手在座位上窜跳,要爸爸快开过去找外星人玩。妻子笑着按住女儿,为她系牢安全带。他从后视镜中看到这最后一幕,妻女的这幅遗照永远刻印在他脑海中。几秒钟后,汽车电脑忽然失控,于平宁急忙换到手动挡,但随之他觉得天旋地转,陷于半昏迷状态。失去操纵的汽车冲过高栏,撞在隧道口。
在这场车祸中只有于平宁捡回一条命,在脸上、身上增添了几十道伤疤。妻女火化前,他像一尊石像一样,在两具残缺不全的尸体前守了一夜。第二天,人们发现他鬓角新添一绺耀眼的白发。
世界刑警组织派了精干的班子来处理这件事,由一个俄国人伊凡诺夫带队。于平宁从他那儿得知,K星飞碟是在一星期前发现的,行踪飘忽鬼祟。由于它们对雷达来说基本是隐形的,所以极难发现。这次是K星人第一次试图劫持地球人,虽然没有成功。
伊凡诺夫苦笑着说:“我们还曾准备隆重欢迎外星文明的使者呢,但显然他们不是来做客的。”
几天后,反K星间谍局匆匆成立。伊凡诺夫打电话来问他愿意不愿意参加,于平宁毫不犹豫地答应了。
酒劲开始上涌,是一种舒适的疲倦感。今天喝得太过量了。他伸个懒腰,快速抓握手指,手指节啪啪地脆响。这是他的习惯。他揉揉眼睛,知道今天不能坚持了,便把开关定在自动导航档,目的地定在西安,汽车便根据导航信号自动行驶。
天已黑了,高速公路上汽车如潮,像是逆向流动的一红一白两条河流,于平宁把驾驶椅放倒,扎牢睡眠安全带,很快进入梦乡。他梦见了妻女,她们在恐惧地尖叫,一架飞碟带着惨绿色光雾,幽灵般地扑过来。他想冲出去,手脚却不能动弹,直到那惨绿色把他淹没……
醒来时已到临潼。睡了一觉,他觉得精神焕发,有一种勃勃的新鲜感。但他随即又回想起那个梦境,目光顿时阴沉下来。
那个梦境似乎隐喻着他们的处境。在K星人的高科技间谍手段下,地球人几乎是无能为力的。反K局只有以十倍的献身,百倍的果决才能勉强维持一种苟安局面。
有时于平宁觉得,反K局简直是以巴战争中巴勒斯坦的自杀勇士。所以反K局的行事残忍,无法无天,也就可以原谅了。
2
反K局位于西安北边一座小山包下,与皇陵相距不远。几十座小平房星罗棋布,外貌很简朴,就像一座农场。实际上这儿戒备森严,配备有地球上最先进的电子警卫手段—至于这些手段对K星人有无作用就不得而知了。于平宁走进大门,电子警卫对他的指纹、声纹、瞳纹和唇纹做了检查,然后说:“欢迎K37号,局长在办公室等你。”
伊凡诺夫将军见到于平宁,心中颇感欣慰,“你看来气色很好,像新摘的葡萄一样新鲜。”于平宁往常休假回来可不是这样,在酒缸中浸泡一个月后,他总是烦躁颓唐,精神疲倦,要几天后才能恢复。反K局超强度的工作使所有人都处于崩溃的边缘,他们只有在休假期间才能喘口气,在海滨、滑雪场和女人胸脯上得到放松。唯有这个于平宁,每逢休假就把自己禁锢在对妻女的思念中,他的痛苦历八年而不衰。伊凡诺夫也是一个老派的人,注重家庭生活,所以他对于平宁休假期间的酗酒从不加指责。
屋内还有一个人,便装、黑发、戴金丝边眼镜,肩膀很宽,坚毅的方下巴,衣着整洁得体。这会儿正冷静地打量着于平宁。伊凡诺夫介绍说:“这是李力明上校,053实验室的安全负责人。”
于平宁知道053实验室,它是一个绝密基地,从事着一项与外星人有关的非常重要的工作,但具体内容不得而知。它的安全是由反K局内另一个系统负责的,于平宁与他们交往很少。他同李力明握手时,觉得对方的手掌很有力,骨骼粗壮,动作有弹性,一看便知是搏击好手。
伊凡诺夫说:“事情很紧急,开始介绍吧。”
李力明简明扼要地介绍了事情经过:053实验室的研究已接近成功,昨天实验室的四位主要研究者乘一架直升机前往山中基地做实验前的最后一次检查。飞至宁西公路某处时,直升机突然从雷达上消失,14分钟后又突然出现。李力明没有放过这点异常,立即将飞机招回做安全检查。“我对机上人员解释说,有人举报飞机上安有炸弹。在不引起四人怀疑的前提下,对他们尽可能详细地检查和询问,但无论是飞机还是机上人员都没有发现异常,驾驶员说飞机一直在正常飞行。如果不是有那么一点蛛丝马迹的话。”
于平宁看看他,他忧郁地说:“四人的手表和机上的钟表都很准时,只有驾驶员的手表慢了14分钟,正好是14分钟。驾驶员却赌咒发誓,说他的劳力士手表绝对不会出差错。这也是可信的,每次任务前我们都要校对时间。”
他继续说:“当然你们很清楚K星人的伎俩。他们常从时空隧道中把人劫走,十几分钟后又送回一个一模一样的复制人。所以我们不敢有丝毫疏忽,即使这次的证据很不充分。”
伊凡诺夫补充道:“我们已得到情报,正好在李力明上校所说的方位和时间,有人曾看到飞碟的绿光。但雷达上一无所见,可能是飞碟的隐形技术又提高了。”
李力明说:“两件异常事件加在一块儿,促使我们不得不采取行动。所以伊凡诺夫将军把你召回来。”
于平宁怀疑地问:“K星人会犯这样愚蠢的错误?他们难道独独忘记把驾驶员的手表也拨快,以补回进入时空隧道的14分钟?”
李力明苦笑着说:“我和你有同样的怀疑,但053基地的重要性不允许我们有丝毫侥幸心理。从另一方面说,尽管K星人的文明高得不可思议,但出现疏忽也并非不可能,人类在管理猴子时也会忘记锁笼门啊。”
于平宁把他的话梳了一遍,问道:“好吧,现在我来问几个问题。第一点,你们怀疑机上5人至少有一个被掉包?”
伊凡诺夫和李力明相互看看,坚决地说:“我们是这样认为。”
“第二点,你们为什么不把5个人隔离开做严格的审查?我们已发展了新式测谎仪,对K星人心理的研究也有很大进展。”
李力明再次苦笑:“你的问题说明你对K星人的生物间谍技术还不大了解。我介绍一点内情吧,尽管这多少泄露了053基地的研究方向。K星人过去劫持地球人后,送回来的是一个模样相似但内心不同的假冒者,咱们辨认这种白皮黑心的间谍已经不困难了,所以他们改变了策略。我们发现,他们现在换回的是白皮白心的真人,与原型一模一样,从外貌,包括指纹、声纹、体臭等;到内心,包括童年的隐私记忆,对K星人的憎恶等。
“当然,如果真的完全相同,K星人就不会这么费心费力了。复制的生物机器人在意识深处有一个程序,也就是他们要达到的某个特定目标—比如说,窃取053基地的研究成果并把基地破坏,这样,复制人就本能地锲而不舍地朝这一目标前行。但是,”他阴郁地强调,“这个目的是潜意识的,本人并不知道,就像海龟和中华鲟按照冥冥中的指令无意识地向繁殖地域回游。当复制人破坏053基地时,他会找出种种理由,自己(作为地球人)认为正当的种种理由。因此,只有在造成既成事实后,这个间谍才可能暴露,不过对我们来说为时已晚。对此我们无能为力,至少到目前为止无能为力。我们只知道某处有炸弹,却连定时器走动的嚓嚓声都听不到。”
他描绘的阴森图像令人不寒而栗,三个人都面色阴沉。
于平宁问:“第三点,让我干什么?”
李力明看着将军。伊凡诺夫简捷地说:“你去找到他们,尽量加以甄别,然后把复制人就地处决。”
那片惨绿色的光雾。杀死他们!……于平宁冷笑道:“让我一个人去甄别真假猴王?我是地藏王脚下的灵兽谛听?你们很聪明,让我承担误杀的罪责。”
伊凡诺夫冷冷地说:“这罪责我来承担。不错,我们可以把五人关起来仔细甄别,但甄别清的可能性是微乎其微的。那时我们怎么办?我们没有任何理由关押他们,但又不敢放他们。一旦某个复制人融入053基地的人群,他就能轻而易举地破坏基地。要知道,K星人发动战争的日子屈指可数,而053实验室的成果对战争胜负至关重要。”停一会儿他又说:“我们无路可走,在研究出甄别方法之前只有狠下心肠。无罪推定的法律准则在这儿不适用,我们是有罪推定—对可能是K星间谍的人,只要找不到可靠的豁免证明,就一律秘密处决。”
一片惨绿色光雾弥漫在眼前,仇恨逐渐膨胀。杀死他们!……于平宁闷声道:“驾驶员我不管。”我只答应杀死四个人。
李力明低声说:“好吧,驾驶员我们处理。”
“四个人在哪儿?”
“我们让这四个人休假了,借口是试验场要做最后一次安全检查。这样做……如果必须处决某个人时,不会对053基地造成震荡。这是四人的地址,电话号码,还有照片。”
于平宁接过来。纸条上有三男一女,其中一个美国人和一个日本人已经回国,还有两个中国人。“我先从美国人开始,让自己的同胞多活两天,你们不会反对我这点私心吧?”
临分手时,李力明紧紧握住他的手说:“将军对你评价极高,我真心希望你用非凡的直觉,从待决犯中甄别出几个无辜者,多少减轻我的自责。当然,鉴定结果要绝对可靠。”
于平宁冷冷地看着他。“鳄鱼的眼泪。”他想说。但李力明先说出来了:“这恐怕是鳄鱼的眼泪。”
他的声音很沉闷,忧伤十分真诚。于平宁没有再刺他,同他轻轻握手。临走他问:“如果四个人一并处死,难道不会影响053实验室的研究?”
“当然,这四个人是实验室的中坚,好在项目已接近尾声,开创研究方向时要天才,进行正常研究时只要资质中等的人就可以。”
于平宁点点头,同老将军告辞。老人送到门口,话语中有一丝伤感:“小于,我就要退休了,是我自己要求的。年纪不饶人,我的思维已经迟钝,不能胜任这项工作了。小于,你好好干。”他没有说他已经建议上司破格提升于平宁。于平宁同他紧紧握手,然后转身走了。
忽然听到后边有人轻声喊他,扭过头,见新田鹤子正责备地望着他。他笑了,以往每次出发时鹤子都要与他恋恋不舍地告别,但今天心情沉重,把这一点给忘了。他返身吻了她的额头,笑着拍拍她的脸,转身大踏步走了。
新田鹤子目送他走出大门。
3
十小时后,于平宁已到达美国得克萨斯州的旁帕。他租一辆奔驰700型轿车,出城向西疾行,在当地时间十二点钟找到莫尔的乡间别墅。
“乔治·莫尔,70岁,声名卓著的生物工程学家。妻子珍妮·莫尔,68岁。老派的美国人,注重家庭生活。”
这是纸上对莫尔的介绍。
他戴上红外夜视镜,戴上薄手套,轻捷地越过栅栏。这是一幢半地下式的建筑,平房显得很低矮,草坪修剪得整整齐齐,院内有一个游泳池,池水映着星光。透过红外夜视镜,他看到草坪上有几道稀疏的红线,这是普通的红外线防盗设备,对他毫无威慑。
他猫腰提着激光枪,轻轻跨过那几道红线,一边还心不在焉想着其他事。他记得中学时曾读到过,法国一位科学家曾从一例罕见的血友病中,考证出很多姓莫尔的欧洲人原来是地中海黑皮肤摩尔人的后裔。几百年的同化使他们忘记了自己的祖先,仅留下莫尔这个姓氏,但遗传密码中还顽强地保留着摩尔人的特征。
一个消亡的民族。地球人会不会也消亡在K星文明中?
忽然他的眼角余光瞥见草丛中竖立起一条黑影,是蛇头,微风中传来轻微的环尾碰击声。蛇头轻灵地点动着,使它看起来像是两个脑袋。他没有想到经常修剪的人工草坪中竟然还有凶恶的响尾蛇,幸亏及时发现,他的随身用物中可没带蛇药。
他举起激光枪瞄准响尾蛇,准备开枪,忽然瞥见不远处有一棵树,略为犹豫后,他轻步挪过去折下一根树枝,试了试,枝条很柔韧。他把手枪交到左手,手持树条微笑着向响尾蛇逼近。响尾蛇用它颊窝中灵敏的红外线传感器,感受到一个大动物的36度的体温。它凶狠地躬起身子准备扑过去,就在它扑出的瞬间,于平宁猛力一抽,干净利索地把蛇头抽飞。
蛇身在草丛中扭动着。于平宁欣喜地想,我还记得少年时的绝技。
他摸近房舍,听听屋内没有动静,就把激光枪调到低功率档,在走廊门的玻璃上划了一个洞,伸手进去轻轻把门打开。
莫尔夫妇睡在一张巨大的水床上,于平宁轻轻摸到莫尔夫人那边,用高效麻醉剂向她的鼻孔喷了一下,随后他绕过去,把莫尔拍醒。
莫尔睁大眼睛,恐惧地盯着面前的枪口。于平宁简短地说:“跟我来,我不想杀死你的妻子。”
老人扭头看看熟睡的妻子,尽量轻手轻脚地下床,他不知道妻子已被麻醉,害怕水床的振荡会把妻子惊醒。走到门口时他回头留恋地看看妻子,神情悲伤。
两人坐在客厅的沙发上,于平宁冷冷地看着老人。我要尽量加以甄别,但我实际上已经知道了这个老人的下场。他问:“你是在053实验室工作?”
老莫尔已从最初的恐惧中镇静下来,从参加053实验室起他就为今天做心理准备。他仇恨地骂道:“动手吧,我什么也不会告诉你,你是个K星畜生!”
于平宁冷笑道:“我是K星人?”
“你这条狗!你这条K星人的臭走狗!”
于平宁摆摆枪口:“听着,莫尔先生,我不愿在这儿多费时间,我也不希望你的妻子醒来,使我不得不多杀一个人。如果你能用可靠的方法证明你是地球人,我会很高兴同你喝一杯的,否则我只好得罪了。”
老人沉默一会儿,问道:“谁派你来的?是不是053实验室的什么人?我想你对一个死人不妨说实话。”
于平宁略为沉吟后回答:“李力明。”
“这条毒蛇!”老人愤恨地骂道:“他昨天突然命令停止实验,我已经觉得奇怪了,可惜我没把他揭露。”
于平宁疲倦地想:又多了一个K星间谍,K星间谍下令让K星间谍去杀K星间谍,一个怪圈,蛇头咬住了蛇尾。
“不要玩游戏了。我最后一次问你,有没有办法证明?”
老人冷笑道:“我当然有办法证明。不过,你有什么办法证明你自己是地球人?在你没有自我证明之前,我绝不会向一个K星间谍泄露这个秘密。”
又一个怪圈。他知道证明的方法,但只有在你自我证明之后才能说出来,可是你又不知道自我证明的方法。
好了,于平宁想,我已经尽力甄别了,可以心安理得地开枪了。他声音低沉地说:“开枪前我想告诉你,你们四人乘坐的直升飞机曾在时空隧道中消失14分钟,你们中至少一人被K星人掉包。如果不能从四只核桃中挑出一只黑仁的,我只有把四只全砸开。将来要是证明你是冤枉的,我会到你墓前谢罪。”
老人目光中闪出一丝犹豫。他开始怀疑了,于平宁想,在没有证明之前,他已对自己是谁发生了怀疑。作为053基地的专家,他肯定知道那个秘密:在潜意识未浮现以前,复制人的心理是对原件的认同。
他无法证明自己是自己。他无法揪着头发把自己揪离地面。
老莫尔的嘴张了张,也许他是想说出他的证明方法。不过他最终走到门前,对着暗蓝色的夜空傲然扬起雪白的头颅:“开枪吧,你这条狗!”
在开枪时,于平宁黯然地想,几乎可以肯定自己错杀了一个地球人。他无法排解自己的负罪感,但他知道,自己不得不如此。
莫尔夫人醒来时已经阳光灿烂,丈夫不在床上。她在客厅的沙发上发现了丈夫的尸体,胸前放着一朵小白花。她手指颤抖地拨通警局电话。
警车呼啸着开来,汤姆警官详细地勘察了现场。老莫尔是激光枪致死的,面容很平静,死亡时间约为凌晨一点。胸前的小白花是在院里采摘的。从脚印看,作案者有三十多岁,身高一米八零左右,中等体重。没有留下指纹和其他痕迹。
莫尔夫人悲痛欲绝,从她那儿没有了解到有价值的线索。他们仅得知莫尔刚从中国回来度假,这是他在家的头一天晚上,谁料死亡也接踵而至。
汤姆把小白花小心地收在塑料袋中。这朵小白花是什么用意?是对死人的嘲笑,还是哀悼?他觉得小白花上附有凶手的人格,或者他是绝对冷血的野兽,或者他有浓厚的人性。
一名警察拎着一条蛇和沾有血迹的树枝过来:“是在草丛中发现的,凶手看来很厉害,动作敏捷准确。不过他为什么不用激光枪来对付蛇呢?”
汤姆也想不通,一般来说,职业杀手就像一架精确走动的机器,他们不会在小事上无谓地冒险。他反复把玩这根枝条,总觉得上面有凶手的影子。
回到警车上,汤姆警官对部下说:“几乎可以肯定是政治性谋杀。在电脑里着重查询近两天进入美国的外国人,尤其是从中国来的。”
回到警局,他们看到查询结果。汤姆在一长串嫌疑者名单中盯着一个中国人的名字:唐天青,35岁,身高1米81,头天从中国乘飞机来,案发当天凌晨5点离开美国去日本。他的护照倒是毫无破绽,但时间与身材太吻合了。汤姆警官把上述情况向世界刑警组织作了通报。
4
当天傍晚,日本长崎海滨的裸体浴场。
夜色朦胧,来享受日光浴的人已经离开,还有不少裸体者躺在洁白的沙滩上,凉椅上。当衣冠整齐的于平宁走过来时,有人不解地看着他。
于平宁漫不经心地走着,犀利的目光扫视着沙滩上的游客。他在一张气垫上找到自己的目标。一对裸体男女在拥抱接吻,男的有40岁,身材粗短,臃肿,他的同伴是一名黑人妙龄女子,曲线玲珑,臀部凸起,像一只母豹一样健美。
“中野康成,日本人,40岁。著名脑生理学家。单身,喜爱临时性关系。”
关于这一点李力明曾补充道:“他尤其喜欢黑人女子。”
中野康成气喘吁吁,两手快活地在女人身上忙活。忽然觉得有人在盯他,抬起头,看见一个衣冠楚楚的陌生人立在面前,面无表情。他对来人的无礼很恼怒,正要发作,来人彬彬有礼地说:“是中野康成君吗?”
中野狐疑地点头。这个不速之客怎么认识自己?他特意赶到一个陌生城市来寻欢作乐,连身边的女子也不知道自己的真实姓名。知道他去向的,只有负责053基地安全的李力明上校,因为他曾要求随时同他联系—也许还有无所不知的可怕的K星人。
“是否让女士回避一下,我有些急事同中野君商量。”
来人说着纯正的日语,恰恰因为太纯正,中野知道他不是日本人,很可能是中国人。他千里迢迢追到这儿,绝不会是为了寒暄天气。不过,既然他先把这黑妞赶走,看来不会有什么恶意,一个杀手是不会让目击者逃生的。他笑着拍拍女人的光腚:“你到汽车里等我,我十分钟后一定回来。”
十分钟。如果来人不怀好意的话,他应对此有所顾忌。黑妞扭着腰肢走了,暮色已重,周围的人都在寻欢作乐,没人注意他们。于平宁在他面前蹲下,直截了当地问:“给我讲讲053基地的情况。”
中野吃了一惊,看来来人不是053基地派来的信使。他胆怯地看看于平宁:“是研究猩猩的智能行为。”
于平宁掏出激光枪,扣动扳机,在沙地上烧出一个黑洞,一缕青烟袅袅上升。他冷酷地说:“也许这把激光枪能帮助你恢复记忆,快讲!”
我要把他置于生死之地后再甄别。
中野因为恐惧而微微发抖。053基地的研究是绝密的,泄露机密的人会受到严厉的处罚,甚至是反K局的秘密处决,但毕竟激光枪的威胁更现实。他声音发抖地讲起来:“……K星人和地球作战的最大优势,就是这种足以乱真的第二代复制人。如果有那么七八个地球首脑被复制人掉包,而他们的潜意识是把战争引向失败,那地球还有什么指望?为此,在053基地集中了世界一流的科学家,研究出一种装置,称之为‘思维迷宫’,可以有效地识别第二代复制人。”
“是否已经成功?”
“基本成功。但你知道,地球人能够擒获并确认的复制人极少,迄今为止,我们基本只对地球人的潜意识做过实验。这些实验准确度极高,能够清晰地显影出地球人的潜意识,比如一个孩子的恋母情结,弑父情结。至于用到K星第二代复制人身上的效果,目前还不清楚。”
于平宁深思良久,问道:“如果杀死你、莫尔、安小雨、夏之垂,这个项目会不会中断?”
中野的大脑飞快运转着,力图摸清对方的心理脉络。此人极可能是一个K星复制人—有K星人显意识的第一代复制人,他的目的是什么?是要破坏思维迷宫的研究,还是为了窃取思维迷宫的技术秘密?是要杀死还是俘获自己?他要据此调整自己的答案。
他小心地回答:“不会中断,但要略略推迟。”
“思维迷宫的原理?”
中野讨好地笑道:“你已经问到核心机密了。这项装置非常非常精巧复杂,但其原理不难明白。160年前有一个中国人建立了醉汉游走理论—醉汉的每一步是无规律的,但只要他的意识并未完全丧失,那么大量的无序的足迹经过数学整理,就会拼出某种有规律的图形。如果意识完全丧失,足迹经过整理后仍然发散。053实验室的安小姐据此发展出‘思维迷宫’的方法,可用以剥露出K星复制人的潜意识指令。被试人在回答提问时,会对潜意识的秘密做出潜意识的粉饰、开脱、回避、自我证明……就每一个答案本身来说毫无破绽,但只要提问次数足够多,再经过思维迷宫系统的数学整理,就会从乱麻中理出一条隐蔽的主线。以上是粗线条的介绍,要想彻底弄清它的原理、结构和技术细节,可能要两个月时间。”
你不能杀我,我还很有用。
于平宁冷冷地说:“你是否猜到我是K星间谍?”
中野迟疑地回答:“猜到了。”
“那么你泄露这些秘密不觉得良心不安?”
中野贱笑道:“上帝教导我要珍惜生命,为了它,我还能做得更多。”他露骨地暗示。
那片惨绿色的光雾。杀死他们!……于平宁毫不犹豫地扣动扳机。激光枪射出一道红色的光束,光束经过处留下一道青烟,没有响声。
中野丑陋的裸体仰卧在气垫上,额头一个深洞,两眼恐惧地圆睁着。于平宁看到那个黑妞正犹犹豫豫地往这边走,便不慌不忙向另一边走了。附近的游客似乎看到红光一闪,他们抬起头,漠不关心地看着,又自顾寻欢作乐。
于平宁想,他几乎可以肯定又杀了一个地球人,但杀死这个贱种,他的良心不会受到太大的谴责。
那女人在中野的尸体前发抖。太可怕了,幸亏那个杀手不屑于杀她。我该怎么办?她紧张地思索着。她不想见警察,她是专在达官贵人圈子里做皮肉生意的,可不想卷进一场凶杀案。
她看看四周,没人注意,就悄悄溜走。在嫖客的汽车里,她急急忙忙检查他衣服中的钱包,把美元、日元揣在怀里。包中还有一叠人民币,看来他去过中国,那么,那个英气逼人的杀手—额上的伤疤使他更具男人气质—恐怕也是中国人。
钱包中还翻出驾驶证和护照,原来嫖客的确叫中野康成。她想了想,把嫖客的衣服和证件在地上堆成一堆儿,然后开着中野的车子找到一间电话亭。她通知警察局,海滨浴场有一具尸体,他的证件和衣服放在停车场的空地上。没等对方问话,她就急忙挂断。
我已经为自己留了后路,这样警察就不会怀疑我是凶手了。再说(她在心底窃笑着),这样多少对得起这叠钞票,数额还真不少哪。
她驾驶红色丰田一溜烟逃走了。
长崎警察局的远藤次郎警官立即赶到现场。死者证件表明他是东京人,八年前到中国西安一个动物智能研究所任职,40岁,单身。两天前刚从中国回来度假,是激光枪致死的。
在场的游客对警察的询问很不耐烦。不!我们什么也没看见,天太黑。再说我们来这儿不是给凶杀案当证人的。只有两个游客说凶手个子较高,约1.8米,穿戴整齐,看背影像个年轻人。
有一名泰国游客提供了一点有价值的细节,他说凶手来这儿后先把一名黑人女人赶走了,凶手走后那黑妞还回来过。黑妞很漂亮,胸脯很高,臀部凸出,走路带有弹性,像一头猎豹一样舒展,所以他印象很深。
远藤陷于沉思中,自然这黑人女子就是报案者。凶手为什么放过她,是同谋,还是心存怜悯?这些细节勾起他的回忆,他立即通知警察局查询近日世界刑警组织的案情通报。
果然查询到一个相同的案例,是在美国旁帕市,疑凶身高相同,使用同样的激光枪,行凶中也同样放过同床熟睡的死者妻子。疑凶唐天青是昨天,5月28日凌晨离开美国飞来日本,而且……远藤瞪大眼睛,美国的死者也是在西安动物智能研究所工作,是前一天刚从中国回来度假的。这就绝不可能是巧合!远藤果断地说:“毫无疑问,这是一起政治谋杀。立即寻找报案者,这种黑人高级娼妓在日本很少,一定不难找到。通知美国警方把凶手照片传真过来,找到报案者后由她辨认。通知中国警方,对西安动物智能研究所进行调查,并对有关人员进行监护—很可能,这轮凶杀还未结束。”
5
“安小雨,女,28岁,未婚,卓有成就的数学家。”
照片上的安小雨十分清纯,像一个天真未凿的中学生,笑得很甜,眸子里甚至还未消尽绯色的幻想。于平宁犹豫地想,不知道自己能否狠下心向她开枪。已经错杀了两个地球人,对此他几乎是百分之百的肯定。我是在干不得不干的事,但这并不能减轻良心的谴责。我就像身赴地狱的席方平,两个鬼卒正操着大锯忽忽隆隆锯开我的心脏。等他们解开我身上的绳索时,我就会裂成两片,扑在地上。(注:席方平是聊斋中的人物,为报父仇去阴司告状,被阎罗王以酷刑折磨,锯成两半。)
但是,他苦笑着想,正因为错杀了两人,安小雨是K星间谍的可能性就更大了,高达50%。
晚上九点,他驾着一辆租来的豪华风神900型轿车(他喜欢驾驶中国汽车),停在安小雨居住的公寓前。进公寓大门需要磁卡,所以他在等着一名持有磁卡的房客。
这是川鄂交界的一处浅山,公寓后面是清郁的竹林,竹子很高,枝干挺拔,微风中竹叶飒飒作响。透过栅栏望去,公寓很整洁,但算不上豪华,看来安小雨口袋里没有多少钞票。
也许先赶到丹江口新湖去解决夏之垂更好一些?如果可以肯定夏之垂是间谍,就不用向安小雨开枪。如果夏之垂又是错杀,那安小雨就一定是K星间谍,再向她开枪就心安理得了。
于平宁冷笑一声,在心里嘲笑自己的矫情。你不过是用愚蠢的逻辑游戏试图减轻良心的痛苦,他想。他在美国和日本留下了不少痕迹—本来可以不留的,但他不愿多杀人,那两个无辜女子不在他的使命之内。他要赶在追捕之网合拢前把剩余两个解决。很可能这个清纯秀丽的小女孩正是K星间谍,她会在甜笑中把几十亿人推向死亡,你大可不必奉送这样廉价的怜悯。
来了一辆车,驾驶者降下车窗,把磁卡塞进读卡器,大门随之无声地滑开。于平宁赶快随那辆车开进院内。
他来到安小雨租住的203室。侧耳听听,屋内只有哗哗的淋浴声。他看看走廊无人,就掏出一根合金钢丝,轻易地捅开门锁。他稍稍推开门,从门缝里看清客厅无人,便闪身进屋,轻轻把门锁上。
屋内像鸡蛋壳一样整洁,窗明几净,茶几上摆着水果、鲜花和几碟精致的茶点。厨房内已备好几样菜肴,似乎是在准备迎接客人。这会儿浴室内已把喷头关掉,玻璃屏风上挂满水珠。于平宁从容地坐到沙发上,从烟盒里抽出一支香烟。
安小雨在浴室听见外边有打火点烟的声音,她笑着高声问:“是老狼吗?我马上出来。桌上有你爱吃的茶点,你先吃吧。”
夏之垂原约定10点钟到,他今天竟然没踩着钟点来,可是件怪事。这位绅士是十分注重拜访女士的礼节的,虽然他们之间早就用不着彬彬有礼了。安小雨擦干头发,忽然噗嗤一声笑了。老狼,她一直这样谑称自己的情人。她曾笑着告诉他,这是有历史掌故的,你可以去查查《笑林广记》:尾巴上竖是狗,“下垂”是狼嘛。【注:笑林广记上有一则笑话,一位尚书借谐音巧骂一位侍郎,说路边的那只“是狼(侍郎)是狗”?不料该侍郎才思敏捷,反唇相讥,说“下垂是狼,上竖(尚书)是狗”。】
安小雨披着雪白的浴衣出来,发现沙发上并非自己的情人。“你是谁?”
于平宁掏出激光枪,缓缓地说:“两天前,053实验室的一架直升机曾在时空隧道中消失14分钟,可以肯定机上5人中至少有一人被K星复制人掉包。我希望你能同我配合,把你的身份甄别清楚。如果不能从四只核桃中挑出那只黑仁的,我只好全砸开。”
不要重复这些滥调了,于平宁厌倦地想,反正你要杀她。那片惨绿色的光雾。杀死他们!……不要怪我的残忍,我是为了人类。
安小雨脸上的恐惧凝固了:“你把那三人全杀了?”
于平宁摇摇头:“夏之垂是第四个。”
安小雨紧张地瞟一眼时钟,再过20分钟,夏之垂就会捧着一束鲜花准时赶到。她知道来人绝不是地球人,如果是反K局派来的审察人员,他就不会不知道“思维迷宫”装置已基本成功,可以用来挑出那只黑仁的核桃。凶手一定是第二代K星复制人,他在为K星卖命时还自以为是为地球尽职。
不过不要妄想唤醒他,在潜意识指令未完成前他是不会罢休的。她知道自己很难逃脱了,自从参加053实验室,她已做好心理准备。在这生死关头,她还暗自庆幸刚才没有直呼情人的名字。
一定要保住老狼,保住我的爱,也为“思维迷宫”的研究保留火种。快点,不能再犹豫了!
于平宁敏锐地察觉到她在看时钟。“不必担心,”他平静地说,“我不是嗜血杀手,你的客人即使赶来,我也不会动他一根汗毛。”
我愿为你做那么一件事情,他苦涩地想。
安小雨在心底苦笑:如果你知道客人就是你的下一个目标呢?不能再耽误。永别了,我的爱!
她声音发抖地问:“我可不可以吸支烟?”
于平宁点点头。她胆怯地走过来,坐在沙发上,伸手去烟盒里摸烟,她的浴巾散开了,酥胸白得耀眼,于平宁下意识地把目光避开。忽然白光一闪,一把水果刀向他劈过来。于平宁矫捷地闪开,激光枪同时亮了。安小雨慢慢倒在地上,胸膛上有一个深洞。她的表情慢慢冻结,最后凝结为安详的微笑。
于平宁垂下枪口,苦涩地看着安小雨的尸体,久久不动。
你又错杀了一个地球人,但这是命中注定的。他小心地抱起安小雨的尸体,平放在沙发上,用浴巾盖好。从桌子上的鲜花中挑出一只白色的水仙,轻轻放在她的胸膛上。
他把汽车开到门口,还像刚才那样等着一辆回公寓的汽车。几分钟后,一辆白色豪华风神900开到门口,验过磁卡后开进院内。于平宁趁大门还未关闭时开车出去。进院的那辆汽车中走出一个穿咖啡色西服的绅士,捧一束鲜花,步履轻快地向203室走去。这肯定是安小雨的情人,于平宁觉得愧疚。
他驾车以300公里的时速向丹江口开去。只剩最后一枚核桃了,它肯定是黑仁的,所以向夏之垂开枪时,不用再良心不安。快去把他干掉,我的刑期就结束了。
6
日本警察的工作效率很高,第二天就找到那名黑人娼妓的行踪。她正在东京,又傍上一名阿拉伯富豪。
远藤警官立即乘机赶到东京,他们来到这家极豪华的“春之都”酒店。那黑妞刚在室内游泳池裸泳完毕,正躺在白色凉椅上歇息。看见两名便装男子在光滑如镜的大理石地板上小心地走过来,她甚至懒得用浴巾把自己遮盖一下。
来人出示警察证件。“什么事?”苏娣不耐烦地问。
远藤直截了当地问:“昨天你是否在长崎,和一名叫中野康成的顾客在一块儿?”
苏娣嫣然一笑,她几乎已把这事忘了。
“对,是我报的案。你们不会怀疑我是凶手吧,我只是不想卷入。你知道,我干这行当,可不想上报刊头条。”
远藤安慰她:“对,我们只是想了解一些情况。如果苏娣小姐配合,在你的阿拉伯富豪回来之前我们就会离开。请你看看,凶手是不是这个中国人?”
苏娣接过唐天青的传真照片。嘿,当然是他!她对这人印象很深,两道剑眉英气逼人,目光冷漠,额上有条深深的伤疤,这些都更增添男人的魅力。哪一天能同他上床,肯定比这个阿拉伯富豪强多了!
苏娣忽然莫名其妙地泛出想保护他的冲动。也许是感谢他昨日手下留情?还是想为他日邂逅留下点希望?她笑着摇头:“NO,NO,那人……怎么说呢,长得很粗俗,大嘴,脸上没有伤疤,说话似乎带大阪口音,像是日本人。绝对没有照片上这么漂亮。”
远藤很失望。他十分怀疑这个唐天青就是凶手,各种情况太巧合了!已经查到他于昨天离开日本回到中国,正好又与长崎谋杀案的时间吻合。但苏娣不会是他的同谋,她没有为他掩护的动机。
他阴沉地说:“我想苏娣小姐一定清楚,作伪证是犯罪的。”
苏娣多少有些后悔自己的孟浪,不过事已至此,她只有硬撑到底。她朝远藤飞了一个媚眼:“当然,我懂。干我这个行当,你想我会同警察过不去吗?凶手不是这人。”她肯定地说。
远藤回到东京警署时,看到了中国警方发来的电传:“唐天青已回国,此人无前科,审查未发现疑点,正进一步调查。”
远藤很沮丧:“只好重新设定疑凶了。妈的,我真不愿承认自己错了!”
他没想到,中国警方的回文有反K局插手。
午夜于平宁赶到丹江口。他把车停在湖旁,略微打一个盹。醒后他下车来到湖边,一条大坝把这里变成烟波浩渺的人工湖,疏星淡月,四周是青灰色的远山。他长伸懒腰,活动一下筋骨,像往常一样快速抓握手指。然后回到车内。
他多少有些奇怪,平时他快速抓握手指时会啪啪脆响,今天却没有。不过没有时间去想这些琐事,他告诫自己,你的目标还未完成,要赶在天亮之前解决最后一名。
丹江口新湖湖畔是一幢连一幢的豪华别墅。这儿山清水秀,是中国的地理中心,又是亚洲蓄水量第一的水库,所以近二十年来,这儿成了科技界、商界新贵们的集聚地。他找到夏之垂的别墅,把汽车停在黑影里,翻身跳进栅栏。
他轻而易举地破坏了院内的防盗设备,踅到房前。正在这时大门外响起汽车马达声,他忙藏在黑影里。雪亮的汽车大灯穿透夜色,大门自动打开,一辆风尘仆仆的白色汽车开进院内,进入车库,车主人匆匆进屋。
于平宁冷笑一声。这个新贵肯定是寻花问柳去了,这个K星复制人倒是没有忘记地球人的癖好。屋内响起一阵哗哗的淋浴声,很快熄了灯,看来他已十分疲乏,草草洗浴后便入睡了。于平宁仍用激光枪打开门,闪进卧室,夜色朦胧中,看到夏之垂背向门口正在熟睡,他轻轻走过去。
忽然,他直觉到某些不妥。这种感觉是从夏之垂的汽车进院后产生的,但究竟是什么?他一时抓不住它。他加倍警惕地轻步上前,用激光枪挑开他身上的毛巾被。忽然灯光刷地亮了,身后有人切齿喝道:“举起手!”
他一愣,慢慢丢下手枪,举起双手,从眼角里瞥见一只双管猎枪正对着自己的后心,床上堆着一叠衣服。夏之垂的头发是干的,衣帽整齐,他根本没有洗澡。
“夏之垂,男,34岁,著名心理学家,兴趣广泛,爱好打猎。”
李力明还告诉他,夏之垂为人机警,他的枪法差不多可与专业射手媲美。
他忽然悟到不安的根源。刚才看到这辆车和这个人的背影时,有一种模糊的熟悉感,是在安小雨的公寓中见过,夏之垂就是安小雨等待的情人。
夏之垂绝对料不到一个温馨之夜变成凶日。他用安小雨给的钥匙打开门,看见安小雨盖着浴巾正在沙发上熟睡,胸脯上放着一朵白花。这个小精灵,这只装睡的小猫咪。他笑着悄悄走过去,吻吻她的双唇,双唇还是温热的,但刹那间他觉出异常,惊惧地喊:“小雨!小雨!”
没有回声。他颤抖地揭开浴巾,在她乳沟左侧发现一个光滑的深洞,是激光枪的伤口。安小鱼手中还握着水果刀,但神态十分安详,身上看不到被强暴的痕迹。夏之垂悲愤地跪在沙发前,泪水浇到死者身上。
他的直觉告诉他,这绝不是一件暴力凶杀案。凶手是有双重人格的人,他冷酷地向安小雨开枪后,又把尸体放端正,盖好浴巾,甚至放上一朵白花以表示无言的忏悔。
可是,是什么使安小雨在迎接死亡时这样安详?……忽然脑中电光一闪,他忍住悲痛,迅速向美国和日本拨了电话,几分钟后他就知道真相。
莫尔、中野康成都已被害,疑凶是一个三十多岁的中国男子。他知道这是K星人的杰作。凶手的双重性格正符合K星第二代复制人的特征,那是潜意识中的K星人指令和原身意识中道德观的冲突。
小雨死前显然已经了解真相,她用水果刀逼迫凶手早开枪,是为了避免她的情人和凶手相遇。只有这样才能解释她的安详表情。
我的爱。他低下身,深情地吻着死者的双唇。我一定要为你报仇。
他忍痛告别小雨,没有丝毫延误,立即开车返回。如果他没有猜错,凶手就在刚才与他相遇的那辆风神900上,他一定会赶到丹江口去杀最后一个人。
从实验突然暂停,让四人休假,到三人相继被害,这是一个精心组织的阴谋,主谋肯定在反K局内部。他要捉住凶手,问出幕后人。
他没有向警察通报,不,我一定要亲手捉住和宰了这个畜生。
身后冷酷地命令:
“走到墙边,把手支在墙上,脚向后移。”于平宁顺从地照办了。后脑勺遭到一记猛击,他眼前一黑,晕了过去。
等他醒来已被绑得结结实实,是拇指粗的强力尼龙绳。他揶揄地想,这下子可好了,不用担心死后裂成两半了。夏之垂居高临下地看着他,用激光枪指着他的胸膛,切齿道:“你这个畜生,你这个丧失自我的僵尸。我要告诉你究竟是谁,你是K星人复制的第二代生物人,他们杀了于平宁后用你掉包。你潜意识中的指令是杀死思维迷宫研究四名主要人员。我要杀死你,为了我的小雨,为了莫尔、中野、为了人类。”
于平宁冷冰冰地看着他,在心里冷笑:混蛋,我当然比任何人都清楚我究竟是谁。夏之垂凄厉地笑道:“我真想一刀一刀碎割了你。不过用不着了,当你知道自己究竟是谁,你就会受到最严厉的惩罚。你的幕后主使是谁?快说!”
于平宁冷笑道:“我的幕后主使?是我对K星畜生的仇恨。”
夏之垂冷冷地说:“我知道你的使命还未完成,在你没杀死我之前,你的自我感觉还是一个正人君子。那么快说是谁派你来的?”
于平宁挣扎着坐起来,靠在墙上,冷笑道:“我可以如实奉告,一点都不遗漏,希望这些事实不至于影响你对自己的信心。”他简要说了李力明派他来的经过。“四个人我已经杀了三个,我想都杀错了,无论是品德高尚的莫尔、安小雨,还是人品龌龊的中野,盖棺定论,他们都是地球人。这样一来疑犯就只有你一个了。当然,正如你刚才所说,在没有完成使命之前你是不会清醒的。”他讥讽地说。
夏之垂目光中闪过一丝犹疑。他摇摇头,抖掉这片疑云,仇恨地说:“这些鬼话你留着对死神去说吧。如果我对自己或任何人有怀疑,我自然有办法甄别。为了我的小雨,我一定要宰了你。快祈祷吧,不管是向地球的上帝还是K星的上帝。”
于平宁用肩膀顶着墙,慢慢站起来:“我想你是犯了一个错误,你不该扔下猎枪用我的激光枪。”
夏之垂冷笑道:“不必为我担心。在053实验室这是常见武器,我会用。”
于平宁微笑道:“但今晚我有一点疏忽,这点疏忽很可能救了我。我在割门玻璃时把手枪的功率调到低挡,忘记调回来了。低挡激光枪在这个距离杀不死我。”
夏之垂惊惧地低头看一眼,不错,是在低功率挡,他急忙用大拇指推换挡位,向于平宁开枪。就在这一瞬间,于平宁迅速低头,用嘴从衣领上拔出一根毒针,噗地吹到夏之垂身上,同时敏捷地闪身躲开。他觉得左臂一麻,随即无力地下垂,知道左臂已经被激光枪割断了,被同时割断的绳索散落在他身边。
夏之垂的喉咙咯咯响着,慢慢地倒下去,双眼一直仇恨地瞪着于平宁。激光光束随着他的身躯在屋中划过,被扫断的落地灯,书架等哗哗地倒下来。于平宁突然觉得极度的疲乏,浑身全散架了,他慢慢地倒下去。
我的使命已完成,他想,然后他的意识缓缓地分散。意识混沌中他看到鬼卒解开他身上的绳索,四天来一直捆着他的绳索,于是他便分成两半,扑倒在地上。
7
李力明得知四个预定的目标已解决三个,于平宁正赶往丹江口,估计最后一个的解决就在今晚。
这个结果已在他预料之中。虽然他真诚地希望于平宁能从待决犯中甄别出几个无辜者,但他知道这是不现实的。他对于平宁不大满意,于的行动留下不少活口。当然,李力明本人也不忍心祸及无辜,不过,万一反K局被牵涉进去,那些终日喊人权博爱的政治家们和记者们一定会把反K局撕碎。
那将是整个人类的灾难,在奶油中长大的公子王孙们怎能理解与K星人斗争的残酷!
吃过晚饭,他忽然有一种不祥的预感—当K星间谍混入053基地的阴谋破产后,K星人一定会直接向‘思维迷宫’装置下手。这种预感没什么证据,但却越来越强烈。他在间谍战中已经身经百战了,这种第六感从未欺骗过他。
他在办公室急急地踱步。随着时钟的嘀答声,他觉得越来越焦躁。一定要采取行动。可是怎样行动?怎样向别人解释?单凭他毫无根据的预感。连伊凡诺夫将军也不会相信。
时钟已到十一点。他终于下了决心,让我一个人承担罪责吧,我一定要在十二点前完成。
他唤来技术部主任捷涅克。要想进入“思维迷宫”所在的地下室,必须他们两人用两把钥匙同时操作,才能打开门锁。他阴郁地说:“伊凡诺夫将军向我通报,K星人今晚很可能向那个装置下手。我想咱俩今晚守在那里。”
捷克人犹豫着,这样做不太符合安全规定。李力明瞪他一眼:“是否还要按部就班地请示?我告诉你,莫尔、中野、安小雨,很可能还有夏之垂都已经被害了。凶手不明,不过可以认定是K星人下的毒手。”
捷涅克异常震惊。这四人是053试验的中坚,竟然在几天内全部丧生,达摩克利斯之剑已悬在头顶了!他意识恍惚地跟李力明来到地下室。
卫兵向李力明敬礼,李力明还礼后简洁地说:“加强警戒,今晚可能有情况。我和捷涅克主任在里面值班。”
两个门锁距离2米,他们分别对付一个,经过长达10分钟的复杂操作,一米厚的钢门缓缓升起。两人进去后钢门又缓缓落下。
地下室与外界严格地隔绝,是一个无声的世界,即使是轻微的赤足行走声、呼吸声,都会被极度灵敏的拾音器收到,放大为霹雳般的巨响。这样,外部守卫的士兵就会迅速进入戒备。
李力明进门后顺手关掉这套系统。他目光奇异地看着捷涅克,后者感到惶惑不解。李力明慢慢地说:“以后你们会理解我的。”
猛烈的一击把捷涅克打晕,看看手表,已是晚上十一点三十分。要赶快,我一定要在十二点前办完。
他急忙坐在主电脑的键盘前。053实验室为了应付突然事变,在唯一的“思维迷宫”装置上设有自毁机构,只要输入一套复杂的指令,装置就会在一声巨响中化为灰烬。
他实在不忍心毁掉它。这套装置是科技界的精英们殚精竭虑费时两年才搞成的,其中也有他的不少心血。一旦被毁,地球人该怎么识别K星复制人?
不要犹豫了。一旦K星人得到这个装置,那将对人类造成更大的危害。
手表的嘀答声在密室里像一声声雷鸣,也像一记记鞭抽。他横下心,飞速地敲击键盘,把自毁指令输进去。不过那些根深蒂固的怀疑仍在啃着他的心,K星人今天会对这个装置下手?如果K星人得到它,会对人类造成多大危害?是否毁掉装置是更大的危害?……
在敲击最后一道指令即自毁时,他的怀疑也达到顶峰,但是他仍无法说服自己收回自毁指令。
他在两种念头的激斗中痛苦地呻吟着。好吧,我仅仅来一点小改动,我只把时间推迟一分钟,这微不足道的时间不会影响我的使命的。
输完指令,他立即离开地下室,对门卫吩咐:“捷涅克主任在里面值班,我明天来换他。”
他回到自己的办公室,失神地盯着时钟。我实在不忍心目睹装置的毁灭,不过我确信自毁指令一定会执行。
时钟敲响十二点,在令人窒息的死寂中又过了一分钟。现在,我确信自己的使命已经完成。他的精神一下子散架,似乎听到身体自内向外的碎裂声。
8
断臂的剧痛使于平宁悠悠醒来,一种莫可名状的恐惧开始叩击他的精神之门。他呆呆地瞪着虚空,忘了疼痛。
我究竟是谁?究竟干了什么?
几天来他一直辛辛苦苦,锲而不舍地去完成一个目标,像在苦苦追赶一个飘飞的幽灵。幽灵忽然消失,他发觉自己已经堕入地狱。
为什么他一定要杀这四个人?即使他们中有一个K星间谍,也能用“思维迷宫”来甄别。那个日本人早就告诉他这个秘密,为什么追杀后两个人时他不愿想到这一点?
那片惨绿色的光雾。杀死他们!……于平宁忽然打起寒颤,连续的不可遏止的寒颤。那片绿光并不是思念妻儿引起的幻觉,而是在宁西公路上真实情景的潜记忆!莫尔和夏之垂都没有说错,自己—严格说不是自己,而是自己的原型,曾被K星人劫持、消灭、换了个一模一样的复制人。于平宁的所有记忆所有情感(包括对K星人的仇恨)都被保留,只是在潜意识中多了一道罪恶的指令。
他对K星人的仇恨被改头换面,变成替K星人卖命的狂热。
他的颤抖越来越厉害。他站起身,用力抓握手指,不,没有那种清脆的叭叭声。他苦涩地想,这大概是K星人复制工程的唯一疏忽。
他忆起夏之垂曾对他指出的一点事实:当复制人完成K星人的指令后,当他意识中不再有这个毒瘤时,他就复原了,变回成一个真正的地球人。
你在梦中残杀你的母亲,现在你要清醒地欣赏自己的杰作。
一条响尾蛇游过来,一双毒眼。它得意地狞笑着,一滴一滴地往他心中滴着毒液。不过他的痛苦很快就麻木了,麻木到可以清醒地思维。
是谁知道他回西安的路线和时间?伊凡诺夫、李力明、新田鹤子,当然不排除K星人也能窃听到。
是谁夸大时间的急迫性,要求他尽快把四个人消灭?伊凡诺夫和李力明。
是谁告诉他至今无法甄别复制人?是李力明。但作为053基地的安全负责人,他明知道思维迷宫的研究已基本成功。
他奇怪如此简单的答案自己竟然没想到,而他素来是以思维清晰自负的。不用说,是那个潜意识指令在干扰着他的思维。
李力明肯定是一个复制人,是一个和自己同样可怕的K星间谍。
我要杀死他,为安小雨、夏之垂他们报仇。为我,不,为于平宁报仇。
他的感觉已经麻木。抖掉绳索,爬起来,机械地检查了自己的断臂,伤口很光滑,激光枪切断它的同时也起到止血作用。他在起居室找到药箱,用一只手困难地把伤口扎好。又艰难地把夏之垂的尸体放到床上,盖好。在院里找到一朵白色的野花,把它放在夏之垂的胸前。
干这一切时他很冷漠,似乎是在梦游状态。然后他带上激光枪,坐进他的风神900,把挡位放在自动导航挡,目标定在053基地所在的神农架。风神车飞驰而去。
早上七点半,他到达053基地。他平静地向门卫通报了姓名,要求见李力明。那边很快回话,说他可以进来。大门打开了。基地很平静,看来四人的死讯还未传到这里,一名警卫把他领到李力明的办公室便走了。于平宁表情痛苦,右手托着断臂,用肩膀顶开门走进去。激光枪在断臂臂窝里藏着,可以很方便地抽出来,李力明不是等闲之辈,他必须小心。
但眼前的情景是他没有预料到的,李力明眼睛布满血丝,神情颓丧,正在狠命地灌酒。他冷冷地盯着于平宁,目光中满是鄙夷和刻毒的嘲讽。于平宁也冷冷地看着他。
“四个人全杀死了。”于平宁闷声说。
“我已经知道了,这正是我喝酒的原因。”
仇恨在胸中膨胀。于平宁嘎声问道:“你在庆贺胜利?”
李力明不回答,他又灌一口,恶毒地笑着,忽然问:“你的指令已经完成了,你肯定也意识到了吧?”
血液冲到头上。于平宁愤恨地想,他在戏弄我,就像一条蛇在戏弄嘴边的老鼠。这个畜生。他抽出激光枪,声音苦涩地说:“你这个复制人,K星人的走狗。”
李力明把酒杯摔碎,昂然迎着他的枪口走过来:“开枪吧!你这个混蛋复制人。告诉你,我的指令也完成了。”
于平宁缓缓地问:“你的指令?”
“对,我的指令是毁掉‘思维迷宫’装置,我已经把它炸毁,四个主要研究者也被杀光。地球人在几年内很难恢复元气。告诉你,我的指令完成后,我也复原了,变成了李力明,那个对K星人刻骨仇恨的李力明,哈哈!”
他笑得十分凄厉,像一只濒死的狼。于平宁的枪口慢慢垂下去,他怎么没想到这一点?他早该想到的。李力明和他是同病相怜。他的胸膛要爆炸,他也想凄厉地长嚎……但是一个念头忽然浮上来,他努力想抓住这根救命草。李力明已把‘思维迷宫’炸毁了?为什么在基地内看不到一点异常?他迟疑地问:“你把思维迷宫炸毁了?”
“我炸毁了!”李力明突然疯狂地喊,“我当然炸毁了!那装置在隔音地下室,人们还没有听到爆炸声。等他们打开地下室就一定会发现!”
求求你,于平宁,你不要再问了。我已经把它炸毁,我绝对相信这一点。
于平宁紧紧地盯着他,这里面肯定有蹊跷。自认识李力明后,他对李力明一直有惺惺相惜之意。这个人意志坚定,行事果断,绝不在自己之下。为什么他突然这样歇斯底里?这不像他的为人。也许他说的是实情,由于地下室隔音,他们尚未发现装置被毁。但为什么他如此急切地想向自己证明这一点?
于平宁敏捷地思考着,思维逐渐明朗,摸到了可能正确的答案。李力明一定是以极顽强的毅力,迫使他本人相信那个装置已经炸毁,这样他才能从K星人的指令中苏醒过来。能做到这一点实在太难了啊。于平宁不敢追问下去,一旦李力明知道思维迷宫并未毁掉,他潜意识中的指令就会死灰复燃。那时他又会变成一个可恶的难以防范的K星间谍。
于平宁忽然朗声大笑,把激光手枪推向长桌对面的李力明,用仅存的右手抱起酒瓶豪饮起来:“多好的酒,没想到死前还能喝上家乡的卧龙玉液。我告诉你,死前我们能干一件很不错的事,你我都可以为地球消灭的一个可恶的K星间谍。喂,把你的手枪扔过来。”
李力明也大笑起来。好,杀死这两个复制人,就再也不用担心某些事了。他把自己的手枪在长桌上推过去,捡起于平宁的手枪。两人坐在桌子的两端开怀痛饮,然后摔掉酒瓶。两个枪口慢慢抬起。于平宁微笑着说:“有什么未了之事吗?”
李力明苦笑着说:“有点放不下‘那个人’的妻儿。不过,他们不会承认我是丈夫和父亲的。不想它了。”
于平宁也想起那个‘于平宁’的妻儿,想起她们死前的那一幕,想起新田鹤子无言的柔情,想起古板热肠的将军……他一挥手,高兴地说:“瞄准眉心,我喊到三,咱们同时开枪。瞄得准一点,别丢丑。”
李力明笑着说:“放心吧。我们可以来个竞赛,明天请将军来检查各自的弹着点。”
他们互道永别,于平宁兴致勃勃地喊:“准备,一、二、三!”
9
接到报告后,伊凡诺夫将军很快赶到053实验室。李力明的办公室里,长桌两端,两个人对面坐着,脸上凝固着豪爽的笑容,眉心正中各有一个光滑的深洞。
基地的其他人用备用钥匙打开地下室,在里间找到捷涅克,刚一取下封嘴的胶带,捷涅克就喊:“快检查自毁装置!”
仔细检查一遍之后,捷涅克松口气:“昨天把我关在里间后,李力明启动了自毁装置。十分侥幸,这个可怕的K星间谍犯了一个可笑的错误。”他迷惑地说,“真的很奇怪,是一个十分可笑绝不该犯的错误。他准确无误地输进了整套指令,但预定自毁时间却定在23点61分。所以装置电脑拒绝执行。”
老将军心情沉重地回到李力明的办公室,沉默地看着两具尸体。他十分喜爱这两个部下,所以在心理上难以把他们同K星间谍联系起来。他沉重地扪心自问,我为什么如此轻易地听信李力明的话,草率地决定将四人处死?即使怀疑四人中有复制人,也可以用基本成功的“思维迷宫”系统来鉴别呀。仅仅是因为我老年昏聩么?
莫非……我也被K星人掉包?我也有一个潜意识的指令?他的心颤抖着,问:“思维迷宫一切正常?”
“是的。”
“那好吧,我来做第一个被试者。”他步履沉重地走过去,坐在受试椅上,向部下严厉地吩咐:“如果鉴别结果是……立即向我开枪!”
!External Links
To link to an external resource such as a website or a file, type its full URL, including the URI scheme such as a protocol (e.g. http://, file://) or mailto:
https://tiddlywiki.com/
[[TW5|https://tiddlywiki.com/]]
[[Mail me|mailto:me@where.net]]
[[Open file|file:///c:/users/me/index.html]]
```
https://tiddlywiki.com/
[[TW5|https://tiddlywiki.com/]]
[[Mail me|mailto:me@where.net]]
[[Open file|file:///c:/users/me/index.html]]
```
-----
For this syntax to work, the URL has to be recognisable as a URL. Otherwise, it is treated as a tiddler title. As a result, in case you want to link to a resource locatable using a relative path, use the extended syntax:
[ext[Open file|../l7943416/README.md]]
```
[ext[Open file|../l7943416/README.md]]
```
! Bulleted Lists
You can create bulleted (unordered) lists with `*` characters (<<.icon $:/core/images/list-bullet>>):
<<wikitext-example src:"* First list item
* Second list item
** A subitem
* Third list item
">>
! Numbered Lists
Numbered (ordered) lists use `#` instead of `*` (<<.icon $:/core/images/list-number>>):
# First item
# Second item
# Third item
You can also mix ordered and unordered list items:
<<wikitext-example src:"* To do today
*# Eat
* To get someone else to do
*# This
*# That
*## And the other
">>
Here's an example the other way around, with numbers as the first level:
<<wikitext-example src:"# To do today
#* Eat
# To get someone else to do
#* This
#* That
#** And the other
">>
! CSS Classes
You can also assign a CSS class to an individual member of a list with this notation:
<<wikitext-example src:"* List One
*.MyClass List Two
* List Three
">>
! Mixing Lists and Block Quotes
Note that [[Block Quotes in WikiText]] can be mixed with lists. For example:
<<wikitext-example src:"* List One
** List Two
**> A quote
**> Another quote
* List Three
">>
! Paragraphs in Lists
Entries in the list are delimited with a linebreak, making it impossible to include linebreaks within a list entry. There are a couple of workarounds.
First, you can transclude paragraph content from another tiddler. For example:
```
* First entry
* <$transclude tiddler="MyTiddler" mode="block"/>
* Third entry
```
Secondly, you can use an HTML "div" element to contain the multiline content. For example:
```
# Step 1
# Step 2
# Step 3<div>
Here is the first of several paragraphs. Note that the double linebreak preceding this paragraph is significant.
And here is the second of several paragraphs.
</div>
# Step 4
# Step 5
# Step 6
```
! Introduction
The list widget displays a sequence of tiddlers that match a [[tiddler filter|Filters]]. It can be used for many purposes:
* Displaying custom lists of links, like in TiddlyWiki5's sidebar
* Custom lists, such as "all tiddlers tagged 'task' that are not tagged 'done'"
* Listing each of the tags applied to a tiddler
* Handling the main story river
The tiddlers are displayed by transcluding each in turn through a template. There are several ways to specify the template and for controlling the behaviour of the list.
! Examples
''plain list''
```
<$list filter="[tag[ListWidget]sort[title]]"/>
```
Displays as:
<<<
<$list filter="[tag[ListWidget]sort[title]]"/>
<<<
''custom item output''
```
<$list filter="[tag[ListWidget]sort[title]]">
<<currentTiddler>>
{{||$:/core/ui/ViewTemplate/tags}}
</$list>
```
Displays as:
<<<
<$list filter="[tag[ListWidget]sort[title]]">
<<currentTiddler>>
{{||$:/core/ui/ViewTemplate/tags}}
</$list>
<<<
''custom item template''
```
<$list filter="[tag[ListWidget]sort[title]]" template="$:/core/ui/ViewTemplate/subtitle"/>
```
Displays as:
<<<
<$list filter="[tag[ListWidget]sort[title]]" template="$:/core/ui/ViewTemplate/subtitle"/>
<<<
!! Grouped Lists
See GroupedLists for how to generate nested and grouped lists using the ListWidget.
! Content and Attributes
The content of the `<$list>` widget is an optional template to use for rendering each tiddler in the list.
The action of the list widget depends on the results of the filter combined with several options for specifying the template:
* If the filter evaluates to an empty list, the text of the ''emptyMessage'' attribute is rendered, and all other templates are ignored
* Otherwise, if the ''template'' attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
* Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
* Otherwise, a default template is used consisting of a `<span>` or `<div>` element wrapped around a link to the item
|!Attribute |!Description |
|filter |The [[tiddler filter|Filters]] to display |
|template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. |
|editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode |
|variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' |
|emptyMessage |Message to be displayed when the list is empty |
|storyview |Optional name of module responsible for animating/processing the list |
|history |The title of the tiddler containing the navigation history |
!! Edit mode
The `<$list>` widget can optionally render draft tiddlers through a different template to handle editing, see DraftMechanism.
!! `storyview` attribute
The `storyview` attribute specifies the name of an optional module that can animate changes to the list (including navigation). The core ships with the following storyview modules:
* `classic`: renders the list as an ordered sequence of tiddlers
* `zoomin`: just renders the current tiddler from the list, with a zoom animation for navigating between tiddlers
* `pop`: shrinks items in and out of place
In order for the storyviews to animate correctly each entry in the list should be a single block mode DOM element.
!! History and navigation
The optional `history` attribute specifies the name of a tiddler that is used to track the current tiddler for navigation purposes. When the history tiddler changes the list view responds by telling the listview to handle navigating to the new tiddler. See HistoryMechanism for details.
!! Additional Notes and Edge Cases
* If the `filter` attribute is not present then a default of `[!is[system]sort[title]]` is used
* If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a `DIV` or a `SPAN` containing a link to the current tiddler (it’s a `DIV` if the list widget is in block mode, or a SPAN if it is in inline mode)
* If the `template` attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used
!Literature Notes 文献笔记
文献笔记。这是阅读一本书、一篇论文等记录的笔记,记录这类笔记,需要遵循两个要点
# 笔记要保持简短,需要做笔记的内容则要精心选择,不要做那种好像要把整本书都抄下来一样的笔记,择其精要而不是遍地开花。更重要的是,使用自己的语言进行转述。
# 将这些笔记和参考的文献保存在同一个地方,比如放在你的文献管理系统里。
题图
笔记,对于我个人来说,是一个非常重要的整理与回顾知识的工具。找到适合自己的笔记载体,将会极大地提高的效率。为追求最佳效率,我尝试过多种方式,从手写到电子,从文档到导图。它们各具特色,又难免缺失某种特性而使我最终放弃。
[[印象笔记]]
----
16 年,新买的笔记本电脑上预装了[[印象笔记]]。当时的印象笔记还仅支持富文本编辑模式。富文本编辑意味着所见即所得,格式可以轻松地点击菜单按钮随时调整。
但是对于我来说,这就意味着我将要腾出一只手握住鼠标,在需要时调整格式。这其实会降低笔记的效率,因为这种模式下,你不仅仅要关注笔记的内容,而且需时不时地分心调整格式。这与我追求高效的笔记体验背道而驰。
除此以外,在[[富文本模式]]下,公式的输入非常繁琐,这也是我最终放弃印象笔记的原因之一。
虽然,印象笔记在 18 年开始支持 [[Markdown]],但其编辑、预览双屏的设计,对于追求简洁的我太过复杂,也就没有再拾起。

印象笔记 Markdown 双屏设计
Typora
------
18 年左右,经朋友推荐,了解到 [Typora](https://typora.io/) 这款简洁的 Markdown 编辑器,并一直使用至今。

Typora: 所见即所得
Typora 主要令我喜爱的一点是其 “**所见即所得**” 的即时 Markdown 渲染。该软件只用一屏,既提供了 Markdown 的排版功能,又减去了编辑模式下 Markdown 中的影响阅读体验的格式符号。

Typora 代码块

Typora 数学公式
然而,Typora 只是一个编辑器,只能记录,**难以检索和回顾**。因此,仅靠 Typora ,难以完成笔记的完整闭环。一种常见的工作流可以勉强解决这个问题,即 [[Typora]](编辑)+ Hexo(生成静态博客网页)+ GitHub Pages(发布与检索)。然而,笔记的**私密性**和博客的**开放性**的矛盾无法得到有效解决,这使我陷入了两难的境地。
[[幕布]]
--

幕布
20 年,准备考研复试的专业课时,我开始尝试幕布这个在线笔记软件。对于整理概念性的知识,幕布绝对是一个非常强大的工具。将一门课,一本书化为一个个知识点,并通过层次表达它们的关系,最后还能生成相应的思维导图,这个笔记体验真的是太美妙了。
美中不足的是,幕布并**不支持公式和代码块的渲染**,这对于有大量公式代码笔记需求的我来说有点遗憾。
Logseq
------
最近,在 GitHub 上发现了一款开源笔记应用,[Logseq](https://github.com/logseq/logseq),个人感觉比较完美的满足了我的几点需求:
1. 支持 Markdown,并且所见即所得 ;
2. 支持公式和代码块渲染;
3. 保持笔记的私密性。
下一部分,我将聊一聊我对 [[Logseq]] 的使用体验。
快速上手
----
使用 Logseq 非常简单,只需要你拥有一个浏览器,一个 GitHub 账户及笔记仓库。
如果要保持你笔记的私密性,你可以创建一个**私有**的 GitHub 笔记仓库供 Logseq 存储数据文件。
当你,准备好上述要求,只需访问 [https://logseq.com/](https://logseq.com/) ,并使用 Github 登录授权,设置好笔记仓库,就可以开始你的笔记了。

Logseq 默认界面
登陆后,Logseq 会默认创建一个标题为今天的文件,你可以直接在此开始笔记。如果要创建新的页面,你可以在左上的搜索框输入新页面的文件名,并选择相应的下拉选项,完成创建。
体验感受
----
从我的使用体验来说,Logseq 的手感是十分惊艳的。主要有如下几点:
* **快速笔记**
* 十分类似于幕布的高效的笔记手感
* **数据完全属于你**
* Logseq 不保存你的任何数据。它在运行过程中,仅仅将你的数据缓存在浏览器的本地缓存中,并与你设定的 GitHub 仓库同步。
* **强大的页面引用、块引用**
* 受 [Roam](https://roamresearch.com/) 启发
* 这建立了独立的笔记文件之间的联系,更利于笔记整合成知识库。
* **支持 Markdown,并且所见即所得**

Logseq 中 Markdown 支持情况
* **丰富的命令**
* 键入 `/` (slash 键),你会发现一个全新的大陆:可以创建待办事项、插入页面引用或者块引用,甚至还能在其中插入一个画图的页面。

Logseq 中的命令
使用场景
----
在我看来,Logseq 具有非常丰富的使用场景:
* **自由写作**:你可以在 Logseq 写下任何你思想的火花,供日后整理。
* **待办事项**:Logseq 提供了比较丰富的待办事项功能,包括创建待办事项,设置事项优先级,设定 deadline 和 schedule。
* **知识整理**:这也许是 Logseq 最核心的使用方式之一。
* ...(也许还有更多)

Logseq 的 deadline 和 schedule
传统的笔记软件,通常把笔记独立为一个一个文件,关注一个文件内的内在联系,而忽视了不同笔记之间的联系。
Logseq 受 Roam 启发,将不同的笔记文件通过**页面引用**联系起来,从而更好地构建自己的知识网络。

Logseq 图谱示例
近期,新版的幕布也上线了 `@文件名` 引用不同的笔记,想必也是受到类似应用的启发。
由此可见,笔记软件正在从内联走向外联,越来越符合对知识整理的需求。
目前来说,Logseq 还存在许多不足:
* Logseq 还处在快速迭代阶段,很多功能存在不稳定的可能;
* 相关的文档稀少,对新手不太友好;
但我相信,开源社区的支持会使得它更加完善。
**NOTE:** This is Traditional Chinese Edition Document of Markdown Syntax. If you are seeking for English Edition Document. Please refer to [Markdown: Syntax](http://daringfireball.net/projects/markdown/syntax).
* [概述](#overview)
* [哲學](#philosophy)
* [行內 HTML](#html)
* [特殊字元自動轉換](#autoescape)
* [區塊元素](#block)
* [段落和換行](#p)
* [標題](#header)
* [區塊引言](#blockquote)
* [清單](#list)
* [程式碼區塊](#precode)
* [分隔線](#hr)
* [區段元素](#span)
* [連結](#link)
* [強調](#em)
* [程式碼](#code)
* [圖片](#img)
* [其他](#misc)
* [跳脫字元](#backslash)
* [自動連結](#autolink)
* [感謝](#acknowledgement)
**注意:**這份文件是用 Markdown 寫的,你可以[看看它的原始檔](https://github.com/othree/markdown-syntax-zhtw/blob/master/syntax.md) 。
概述
--
### 哲學
Markdown 的目標是實現「易讀易寫」。
不過最需要強調的便是它的可讀性。一份使用 Markdown 格式撰寫的文件應該可以直接以純文字發佈,並且看起來不會像是由許多標籤或是格式指令所構成。Markdown 語法受到一些既有 text-to-HTML 格式的影響,包括 [Setext](http://docutils.sourceforge.net/mirror/setext.html)、[atx](http://www.aaronsw.com/2002/atx/)、[Textile](http://textism.com/tools/textile/)、[reStructuredText](http://docutils.sourceforge.net/rst.html)、[Grutatext](http://www.triptico.com/software/grutatxt.html) 和 [EtText](http://ettext.taint.org/doc/),然而最大靈感來源其實是純文字的電子郵件格式。
因此 Markdown 的語法全由標點符號所組成,並經過嚴謹慎選,是為了讓它們看起來就像所要表達的意思。像是在文字兩旁加上星號,看起來就像 * 強調 *。Markdown 的清單看起來,嗯,就是清單。假如你有使用過電子郵件,區塊引言看起來就真的像是引用一段文字。
### 行內 HTML
Markdown 的語法有個主要的目的:用來作為一種網路內容的_寫作_用語言。
Markdown 不是要來取代 HTML,甚至也沒有要和它相似,它的語法種類不多,只和 HTML 的一部分有關係,重點_不是_要創造一種更容易寫作 HTML 文件的語法,我認為 HTML 已經很容易寫了,Markdow 的重點在於,它能讓文件更容易閱讀、編寫。HTML 是一種_發佈_的格式,Markdown 是一種_編寫_的格式,因此,Markdown 的格式語法只涵蓋純文字可以涵蓋的範圍。
不在 Markdown 涵蓋範圍之外的標籤,都可以直接在文件裡面用 HTML 撰寫。不需要額外標註這是 HTML 或是 Markdown;只要直接加標籤就可以了。
只有區塊元素──比如`<div>`、`<table>`、`<pre>`、`<p>`等標籤,必需在前後加上空行,以利與內容區隔。而且這些(元素)的開始與結尾標籤,不可以用 tab 或是空白來縮排。Markdown 的產生器有智慧型判斷,可以避免在區塊標籤前後加上沒有必要的`<p>`標籤。
舉例來說,在 Markdown 文件裡加上一段 HTML 表格:
```
This is a regular paragraph.
<table>
<tr>
<td>Foo</td>
</tr>
</table>
This is another regular paragraph.
```
請注意,Markdown 語法在 HTML 區塊標籤中將不會被進行處理。例如,你無法在 HTML 區塊內使用 Markdown 形式的`*強調*`。
HTML 的區段標籤如`<span>`、`<cite>`、`<del>`則不受限制,可以在 Markdown 的段落、清單或是標題裡任意使用。依照個人習慣,甚至可以不用 Markdown 格式,而採用 HTML 標籤來格式化。舉例說明:如果比較喜歡 HTML 的 `<a>`或`<img>`標籤,可以直接使用這些標籤,而不用 Markdown 提供的連結或是影像標示語法。
HTML 區段標籤和區塊標籤不同,在區段標籤的範圍內,Markdown 的語法是有效的。
### 特殊字元自動轉換
在 HTML 文件中,有兩個字元需要特殊處理:`<`和`&`。`<`符號用於起始標籤`&`符號則用於標記 HTML 實體,如果你只是想要使用這些符號,你必須要使用實體的形式,像是`<`和`&`。
`&` 符號其實很容易讓寫作網路文件的人感到困擾,如果你要打「AT&T」 ,你必須要寫成「`AT&T`」 ,還得轉換網址內的 `&` 符號,如果你要連結到:
```
http://images.google.com/images?num=30&q=larry+bird
```
你必須要把網址轉成:
```
http://images.google.com/images?num=30&q=larry+bird
```
才能放到連結標籤的`href`屬性裡。不用說也知道這很容易忘記,這也可能是 HTML 標準檢查所檢查到的錯誤中,數量最多的。
Markdown 允許你直接使用這些符號,但是你要小心跳脫字元的使用,如果你是在 HTML 實體中使用`&`符號的話,它不會被轉換,而在其他情形下,它則會被轉換成`&`。所以你如果要在文件中插入一個著作權的符號,你可以這樣寫:
```
©
```
Markdown 將不會對這段文字做修改,但是如果你這樣寫:
```
AT&T
```
Markdown 就會將它轉為:
```
AT&T
```
類似的狀況也會發生在`<`符號上,因為 Markdown 支援[行內 HTML](#html) ,如果你是使用`<`符號作為 HTML 標籤使用,那 Markdown 也不會對它做任何轉換,但是如果你是寫:
```
4 < 5
```
Markdown 將會把它轉換為:
```
4 < 5
```
不過需要注意的是,code 範圍內,不論是行內還是區塊,`<`和`&`兩個符號都_一定_會被轉換成 HTML 實體,這項特性讓你可以很容易地用 Markdown 寫 HTML code(和 HTML 相對而言。在 HTML 語法中,你要把所有的`<`和`&`都轉換為 HTML 實體,才能在 HTML 文件裡面寫出 HTML code。)
區塊元素
----
### 段落和換行
一個段落是由一個以上相連接的行句組成,而一個以上的空行則會切分出不同的段落(空行的定義是顯示上看起來像是空行,便會被視為空行。比方說,若某一行只包含空白和 tab,則該行也會被視為空行),一般的段落不需要用空白或斷行縮排。
「一個以上相連接的行句組成」這句話其實暗示了 Markdown 允許段落內的強迫斷行,這個特性和其他大部分的 text-to-HTML 格式不一樣(包括 MovableType 的「Convert Line Breaks」選項),其他的格式會把每個斷行都轉成`<br />`標籤。
如果你_真的_想要插入`<br />`標籤的話,在行尾加上兩個以上的空白,然後按 enter。
是的,這確實需要花比較多功夫來插入`<br />`,但是「每個換行都轉換為`<br />`」的方法在 Markdown 中並不適合, Markdown 中 email 式的[區塊引言](#blockquote)和多段落的[清單](#list)在使用換行來排版的時候,不但更好用,還更好閱讀。
Markdown 支援兩種標題的語法,[Setext](http://docutils.sourceforge.net/mirror/setext.html) 和 [atx](http://www.aaronsw.com/2002/atx/) 形式。
Setext 形式是用底線的形式,利用`=`(最高階標題)和`-`(第二階標題),例如:
```
This is an H1
=============
This is an H2
-------------
```
任何數量的`=`和`-`都可以有效果。
Atx 形式則是在行首插入 1 到 6 個 `#` ,各對應到標題 1 到 6 階,例如:
```
# This is an H1
## This is an H2
###### This is an H6
```
你可以選擇性地「關閉」atx 樣式的標題,這純粹只是美觀用的,若是覺得這樣看起來比較舒適,你就可以在行尾加上`#`,而行尾的`#`數量也不用和開頭一樣(行首的井字數量決定標題的階數):
```
# This is an H1 #
## This is an H2 ##
### This is an H3 ######
```
### 區塊引言
Markdown 使用 email 形式的區塊引言,如果你很熟悉如何在 email 信件中引言,你就知道怎麼在 Markdown 文件中建立一個區塊引言,那會看起來像是你強迫斷行,然後在每行的最前面加上`>`:
```
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
>
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
> id sem consectetuer libero luctus adipiscing.
```
Markdown 也允許你只在整個段落的第一行最前面加上`>`:
```
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.
```
區塊引言可以有階層(例如:引言內的引言),只要根據層數加上不同數量的`>`:
```
> This is the first level of quoting.
>
> > This is nested blockquote.
>
> Back to the first level.
```
引言的區塊內也可以使用其他的 Markdown 語法,包括標題、清單、程式碼區塊等:
```
> ## This is a header.
>
> 1. This is the first list item.
> 2. This is the second list item.
>
> Here's some example code:
>
> return shell_exec("echo $input | $markdown_script");
```
任何標準的文字編輯器都能簡單地建立 email 樣式的引言,例如 BBEdit,你可以選取文字後然後從選單中選擇_增加引言階層_。
### 清單
Markdown 支援有序清單和無序清單。
無序清單使用星號、加號或是減號作為清單標記:
```
* Red
* Green
* Blue
```
等同於:
```
+ Red
+ Green
+ Blue
```
也等同於:
```
- Red
- Green
- Blue
```
有序清單則使用數字接著一個英文句點:
```
1. Bird
2. McHale
3. Parish
```
很重要的一點是,你在清單標記上使用的數字並不會影響輸出的 HTML 結果,上面的清單所產生的 HTML 標記為:
```
<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>
```
如果你的清單標記寫成:
```
1. Bird
1. McHale
1. Parish
```
或甚至是:
```
3. Bird
1. McHale
8. Parish
```
你都會得到完全相同的 HTML 輸出。重點在於,你可以讓 Markdown 文件的清單數字和輸出的結果相同,或是你懶一點,你可以完全不用在意數字的正確性。
如果你使用懶惰的寫法,建議第一個項目最好還是從「1.」開始,因為 Markdown 未來可能會支援有序清單的 start 屬性。
清單項目標記通常是放在最左邊,但是其實也可以縮排,最多三個空白,項目標記後面則一定要接著至少一個空白或 tab。
要讓清單看起來更漂亮,你可以把內容用固定的縮排整理好:
```
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
```
但是如果你很懶,那也不一定需要:
```
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
viverra nec, fringilla in, laoreet vitae, risus.
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
Suspendisse id sem consectetuer libero luctus adipiscing.
```
如果清單項目間用空行分開, Markdown 會把項目的內容在輸出時用`<p>`標籤包起來,舉例來說:
```
* Bird
* Magic
```
會被轉換為:
```
<ul>
<li>Bird</li>
<li>Magic</li>
</ul>
```
但是這個:
```
* Bird
* Magic
```
會被轉換為:
```
<ul>
<li><p>Bird</p></li>
<li><p>Magic</p></li>
</ul>
```
清單項目可以包含多個段落,每個項目下的段落都必須縮排 4 個空白或是一個 tab:
```
1. This is a list item with two paragraphs. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
sit amet velit.
2. Suspendisse id sem consectetuer libero luctus adipiscing.
```
如果你每行都有縮排,看起來會看好很多,當然,再次地,如果你很懶惰,Markdown 也允許:
```
* This is a list item with two paragraphs.
This is the second paragraph in the list item. You're
only required to indent the first line. Lorem ipsum dolor
sit amet, consectetuer adipiscing elit.
* Another item in the same list.
```
如果要在清單項目內放進引言,那`>`就需要縮排:
```
* A list item with a blockquote:
> This is a blockquote
> inside a list item.
```
如果要放程式碼區塊的話,該區塊就需要縮排_兩次_,也就是 8 個空白或是兩個 tab:
```
* A list item with a code block:
<code goes here>
```
當然,項目清單很可能會不小心產生,像是下面這樣的寫法:
```
1986. What a great season.
```
換句話說,也就是在行首出現_數字-句點-空白_,要避免這樣的狀況,你可以在句點前面加上反斜線。
```
1986\. What a great season.
```
### 程式碼區塊
和程式相關的寫作或是標籤語言原始碼通常會有已經排版好的程式碼區塊,通常這些區塊我們並不希望它以一般段落文件的方式去排版,而是照原來的樣子顯示,Markdown 會用`<pre>`和`<code>`標籤來把程式碼區塊包起來。
要在 Markdown 中建立程式碼區塊很簡單,只要簡單地縮排 4 個空白或是 1 個 tab 就可以,例如,下面的輸入:
```
This is a normal paragraph:
This is a code block.
```
Markdown 會轉換成:
```
<p>This is a normal paragraph:</p>
<pre><code>This is a code block.
</code></pre>
```
這個每行一階的縮排(4 個空白或是 1 個 tab),都會被移除,例如:
```
Here is an example of AppleScript:
tell application "Foo"
beep
end tell
```
會被轉換為:
```
<p>Here is an example of AppleScript:</p>
<pre><code>tell application "Foo"
beep
end tell
</code></pre>
```
一個程式碼區塊會一直持續到沒有縮排的那一行(或是文件結尾)。
在程式碼區塊裡面,`&`、`<`和`>`會自動轉成 HTML 實體,這樣的方式讓你非常容易使用 Markdown 插入範例用的 HTML 原始碼,只需要複製貼上,再加上縮排就可以了,剩下的 Markdown 都會幫你處理,例如:
```
<div class="footer">
© 2004 Foo Corporation
</div>
```
會被轉換為:
```
<pre><code><div class="footer">
© 2004 Foo Corporation
</div>
</code></pre>
```
程式碼區塊中,一般的 Markdown 語法不會被轉換,像是星號便只是星號,這表示你可以很容易地以 Markdown 語法撰寫 Markdown 語法相關的文件。
### 分隔線
你可以在一行中用三個或以上的星號、減號、底線來建立一個分隔線,行內不能有其他東西。你也可以在星號中間插入空白。下面每種寫法都可以建立分隔線:
```
* * *
***
*****
- - -
---------------------------------------
```
區段元素
----
### 連結
Markdown 支援兩種形式的連結語法:_行內_和_參考_兩種形式。
不管是哪一種,連結的文字都是用 [方括號] 來標記。
要建立一個行內形式的連結,只要在方塊括號後面馬上接著括號並插入網址連結即可,如果你還想要加上連結的 title 文字,只要在網址後面,用雙引號把 title 文字包起來即可,例如:
```
This is [an example](http://example.com/ "Title") inline link.
[This link](http://example.net/) has no title attribute.
```
會產生:
```
<p>This is <a href="http://example.com/" title="Title">
an example</a> inline link.</p>
<p><a href="http://example.net/">This link</a> has no
title attribute.</p>
```
如果你是要連結到同樣主機的資源,你可以使用相對路徑:
```
See my [About](/about/) page for details.
```
參考形式的連結使用另外一個方括號接在連結文字的括號後面,而在第二個方括號裡面要填入用以辨識連結的標籤:
```
This is [an example][id] reference-style link.
```
你也可以選擇性地在兩個方括號中間加上空白:
```
This is [an example] [id] reference-style link.
```
接著,在文件的任意處,你可以把這個標籤的連結內容定義出來:
```
[id]: http://example.com/ "Optional Title Here"
```
連結定義的形式為:
* 方括號,裡面輸入連結的辨識用標籤
* 接著一個冒號
* 接著一個以上的空白或 tab
* 接著連結的網址
* 選擇性地接著 title 內容,可以用單引號、雙引號或是括弧包著
下面這三種連結的定義都是相同:
```
[foo]: http://example.com/ "Optional Title Here"
[foo]: http://example.com/ 'Optional Title Here'
[foo]: http://example.com/ (Optional Title Here)
```
**請注意:**有一個已知的問題是 Markdown.pl 1.0.1 會忽略單引號包起來的連結 title。
連結網址也可以用角括號包起來:
```
[id]: <http://example.com/> "Optional Title Here"
```
你也可以把 title 屬性放到下一行,也可以加一些縮排,網址太長的話,這樣會比較好看:
```
[id]: http://example.com/longish/path/to/resource/here
"Optional Title Here"
```
網址定義只有在產生連結的時候用到,並不會直接出現在文件之中。
連結辨識標籤可以有字母、數字、空白和標點符號,但是並_不_區分大小寫,因此下面兩個連結是一樣的:
```
[link text][a]
[link text][A]
```
_預設的連結標籤_功能讓你可以省略指定連結標籤,這種情形下,連結標籤和連結文字會視為相同,要用預設連結標籤只要在連結文字後面加上一個空的方括號,如果你要讓 “Google” 連結到 google.com,你可以簡化成:
```
[Google][]
```
然後定義連結內容:
```
[Google]: http://google.com/
```
由於連結文字可能包含空白,所以這種簡化的標籤內也可以包含多個文字:
```
Visit [Daring Fireball][] for more information.
```
然後接著定義連結:
```
[Daring Fireball]: http://daringfireball.net/
```
連結的定義可以放在文件中的任何一個地方,我比較偏好直接放在連結出現段落的後面,你也可以把它放在文件最後面,就像是註解一樣。
下面是一個參考式連結的範例:
```
I get 10 times more traffic from [Google] [1] than from
[Yahoo] [2] or [MSN] [3].
[1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
```
如果改成用連結名稱的方式寫:
```
I get 10 times more traffic from [Google][] than from
[Yahoo][] or [MSN][].
[google]: http://google.com/ "Google"
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
[msn]: http://search.msn.com/ "MSN Search"
```
上面兩種寫法都會產生下面的 HTML。
```
<p>I get 10 times more traffic from <a href="http://google.com/"
title="Google">Google</a> than from
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
```
下面是用行內形式寫的同樣一段內容的 Markdown 文件,提供作為比較之用:
```
I get 10 times more traffic from [Google](http://google.com/ "Google")
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
[MSN](http://search.msn.com/ "MSN Search").
```
參考式的連結其實重點不在於它比較好寫,而是它比較好讀,比較一下上面的範例,使用參考式的文章本身只有 81 個字元,但是用行內形式的連結卻會增加到 176 個字元,如果是用純 HTML 格式來寫,會有 234 個字元,在 HTML 格式中,標籤比文字還要多。
使用 Markdown 的參考式連結,可以讓文件更像是瀏覽器最後產生的結果,讓你可以把一些標記相關的資訊移到段落文字之外,你就可以增加連結而不讓文章的閱讀感覺被打斷。
### 強調
Markdown 使用星號(`*`)和底線(`_`)作為標記強調字詞的符號,被`*`或`_`包圍的字詞會被轉成用`<em>`標籤包圍,用兩個`*`或`_`包起來的話,則會被轉成`<strong>`,例如:
```
*single asterisks*
_single underscores_
**double asterisks**
__double underscores__
```
會轉成:
```
<em>single asterisks</em>
<em>single underscores</em>
<strong>double asterisks</strong>
<strong>double underscores</strong>
```
你可以隨便用你喜歡的樣式,唯一的限制是,你用什麼符號開啟標籤,就要用什麼符號結束。
強調也可以直接插在文字中間:
```
un*frigging*believable
```
但是如果你的 `*` 和 `_` 兩邊都有空白的話,它們就只會被當成普通的符號。
如果要在文字前後直接插入普通的星號或底線,你可以用反斜線:
```
\*this text is surrounded by literal asterisks\*
```
### 程式碼
如果要標記一小段行內程式碼,你可以用反引號把它包起來(`` ` ``),例如:
```
Use the `printf()` function.
```
會產生:
```
<p>Use the <code>printf()</code> function.</p>
```
如果要在程式碼區段內插入反引號,你可以用多個反引號來開啟和結束程式碼區段:
```
``There is a literal backtick (`) here.``
```
這段語法會產生:
```
<p><code>There is a literal backtick (`) here.</code></p>
```
程式碼區段的起始和結束端都可以放入一個空白,起始端後面一個,結束端前面一個,這樣你就可以在區段的一開始就插入反引號:
```
A single backtick in a code span: `` ` ``
A backtick-delimited string in a code span: `` `foo` ``
```
會產生:
```
<p>A single backtick in a code span: <code>`</code></p>
<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
```
在程式碼區段內,`&`和角括號都會被轉成 HTML 實體,這樣會比較容易插入 HTML 原始碼,Markdown 會把下面這段:
```
Please don't use any `<blink>` tags.
```
轉為:
```
<p>Please don't use any <code><blink></code> tags.</p>
```
你也可以這樣寫:
```
`—` is the decimal-encoded equivalent of `—`.
```
以產生:
```
<p><code>—</code> is the decimal-encoded
equivalent of <code>—</code>.</p>
```
### 圖片
很明顯地,要在純文字應用中設計一個「自然」的語法來插入圖片是有一定難度的。
Markdown 使用一種和連結很相似的語法來標記圖片,同樣也允許兩種樣式:_行內_和_參考_。
行內圖片的語法看起來像是:
```


```
詳細敘述如下:
* 一個驚嘆號`!`
* 接著一個方括號,裡面放上圖片的替代文字
* 接著一個普通括號,裡面放上圖片的網址,最後還可以用引號包住並加上 選擇性的’title’文字。
參考式的圖片語法則長得像這樣:
```
![Alt text][id]
```
「id」是圖片參考的名稱,圖片參考的定義方式則和連結參考一樣:
```
[id]: url/to/image "Optional title attribute"
```
到目前為止, Markdown 還沒有辦法指定圖片的寬高,如果你需要的話,你可以使用普通的`<img>`標籤。
其他
--
### 自動連結
Markdown 支援比較簡短的自動連結形式來處理網址和電子郵件信箱,只要是用角括號包起來,Markdown 就會自動把它轉成連結,連結的文字就和連結位置一樣,例如:
```
<http://example.com/>
```
Markdown 會轉為:
```
<a href="http://example.com/">http://example.com/</a>
```
自動的郵件連結也很類似,只是 Markdown 會先做一個編碼轉換的過程,把文字字元轉成 16 進位碼的 HTML 實體,這樣的格式可以混淆一些不好的信箱地址收集機器人,例如:
```
<address@example.com>
```
Markdown 會轉成:
```
<a href="mailto:addre
ss@example.co
m">address@exa
mple.com</a>
```
在瀏覽器裡面,這段字串會變成一個可以點擊的「address@example.com」連結。
(這種作法雖然可以混淆不少的機器人,但並無法全部擋下來,不過這樣也比什麼都不做好些。無論如何,公開你的信箱終究會引來廣告信件的。)
### 跳脫字元
Markdown 可以利用反斜線來插入一些在語法中有其他意義的符號,例如:如果你想要用星號加在文字旁邊的方式來做出強調效果(但不用`<em>`標籤),你可以在星號的前面加上反斜線:
```
\*literal asterisks\*
```
Markdown 支援在下面這些符號前面加上反斜線來幫助插入普通的符號:
```
\ 反斜線
` 反引號
* 星號
_ 底線
{} 大括號
[] 方括號
() 括號
# 井字號
+ 加號
- 減號
. 英文句點
! 驚嘆號
```
感謝
--
感謝 [leafy7382](https://twitter.com/#!/leafy7382) 協助翻譯,[hlb](http://iamhlb.com/)、[Randylien](http://twitter.com/randylien) 幫忙潤稿,[ethantw](https://twitter.com/#!/ethantw) 的[漢字標準格式](http://css.hanzi.co/),[WM](http://kidwm.net/) 回報文字錯誤。
[Markdown 中文文档](https://markdown-zh.readthedocs.io/en/latest/)
概述
--
### 设计理念
Markdown 致力于使阅读和创作文档变得容易.
Markdown 视可读性为最高准则. Markdown 文件应该以纯文本形式原样发布, 不应该包含标记标签和格式化指令. 尽管 Markdown 的语法受到了以下这些 text-to-HTML 过滤器的影响 -- 包括 [Setext](http://docutils.sourceforge.net/mirror/setext.html), [atx](http://www.aaronsw.com/2002/atx/), [Textile](http://textism.com/tools/textile/), [reStructuredText](http://docutils.sourceforge.net/rst.html), [Grutatext](http://www.triptico.com/software/grutatxt.html), 还有 [EtText](http://ettext.taint.org/doc/) -- 但是 Markdown 语法灵感最大的来源还是纯文本 email 的格式.
基于以上背景, Markdown 完全由标点符号组成, 这些标点经过仔细挑选以使他们看上去和表达的含义相同. 例如, 星号标记的单词就像 * 强调 *. 列表就像是列表. 如果你使用过 email 的话, 就连块引用都像引用的文本段落.
### 内联 HTML
Markdown 是用于 _创作_ web 文档的.
Markdown 从来都不是要取代 HTML . 它的语法集非常小, 只对应一小部分 HTML 标签. 它要做的 _不是_ 创造一种新的语法以使插入 HTML 标签变得更容易. 在我看来, HTML 标签已经很容易插入了. Markdown 的目标是易于阅读, 创作和编辑文章. HTML 是一种 _发布_ 格式; Markdown 是一种 _创作_ 格式. 因此, Markdown 处理的都是纯文本.
对于 Markdown 中未包含的标签, 可以直接使用 HTML. 没有必要使用定界符或标识符来表明从 Markdown 切换到 HTML; 直接使用标签就行了.
唯一的限制就是对于 HTML 块级元素 -- 像 `<div>`, `<table>`, `<pre>`, `<p>`, 等等. -- 必须另起一行单独放 , 并且开始和结束标签前面不能有任何缩进. Markdown 会自动识别这些块级元素而不会在他们周围添加额外的 `<p>` 标签.
例如, 下面是添加 HTML 表格到 Markdown 文件:
```
This is a regular paragraph.
<table>
<tr>
<td>Foo</td>
</tr>
</table>
This is another regular paragraph.
```
注意 Markdown 语法结构在 HTML 块级元素中不会被处理. 例如, 你不该在 HTML 块级元素中使用 Markdown 式的语法如 `*emphasis*` .
HTML 内联元素 -- 例如 `<span>`, `<cite>`, 和 `<del>` -- 可以在 Markdown 段落, 列表项, 标题中任意使用. 如果你乐意, 你甚至可以使用 HTML 标签替代 Markdown 格式; 例如你可以用 HTML `<a>` 和 `<img>` 标签替代 Markdown 的链接和图片语法.
不同于 HTML 块级元素, Markdown 语法_可以_ 在内联元素中解析.
### 特殊字符自动转义
在 HTML 中, 有两个字符需要特殊对待: `<` 和 `&`. 左尖括号用于起始标签; 英镑符号用于表示 HTML 字符实体. 如果你想将它们用作字面量, 你必须将它们转义为字符实体, 例如 `<`, 和 `&`.
英镑符号尤其使网页作者备受折磨. 如果你想得到'AT&T', 你得这样写 '`AT&T`'. 你甚至需要转义 URL 中的英镑符号. 因此, 如果你想链接到:
```
http://images.google.com/images?num=30&q=larry+bird
```
你需要编码 `href` 属性为:
```
http://images.google.com/images?num=30&q=larry+bird
```
不用说, 这很容易被忘记, 也是 HTML 校验中最容易出现的错误.
你可以在 Markdown 中自由地使用这些字符, 这些字符在生成 HTML 时会被自动转义. 如果你在 HTML 字符实体中使用英镑符号, 它将保持不变; 否则它将被转义为 `&`.
因此, 如果你需要得到版权符号, 可以写:
```
©
```
Markdown 不会将其转义. 但是如果你写:
```
AT&T
```
Markdown 会将其转义:
```
AT&
```
类似的, 由于 Markdown 支持 [内联 HTML](#html), 如果你使用尖括号作为 HTML 标签定界符, Markdown 将不会进行转义. 但是如果你写:
```
4 < 5
```
Markdown 会将其转义:
```
4 < 5
```
总而言之, Markdown 的块级元素和内联元素中, 尖括号和英镑符号 _总是_ 被自动编码. 这使得用 Markdown 来写 HTML 代码很容易. (相较之下, 原始的 HTML 中就很难书写 HTML 代码, 因为代码中的每个 `<` 和 `&` 都需要被转义.)
!Obsidian
初识
--
2020-12-15 更新:[中文论坛(Github Discussion)](https://link.zhihu.com/?target=https%3A//github.com/obsidianzh/forum/discussions)
在今年 Roam Research 凭借异于其它笔记软件的理念以及一众笔记爱好者的大力举荐在笔记软件届横空出世,而一众笔记爱好者在提到《How to Take Smart Notes》中所述的卡片盒笔记法(Zettelkasten)的联系概念时,总是将 Roam Research 看作是实践这种方法的一个极好工具;随后相似理念的新型在线服务不断涌出,老牌服务也逐渐在更新中加上了**双向链接**这个有趣的功能。
但是我因为网络以及其它特殊原因而无法接受在线笔记服务,所以只能看着 Roam Research 在知识管理者以及笔记爱好者手中不断地被倒腾以及展示它的优越能力,心生羡慕。
直到今年六月初,事情发生了点变化,我偶然在 [Hacker News](https://link.zhihu.com/?target=https%3A//news.ycombinator.com/news) 上发现了 Obsidian,那时候 Obsidian 只是一个相对简陋的带双向链接的本地笔记软件,但是在我看到了那时候开发者的发言,以及了解了一下开发者来历后,我认为可以在 Obsidian 上投入时间以及精力,并且趁软件还比较纯粹(简陋),可以及时适应软件所带来的笔记方法上的变化。

学习
--
在使用 Obsidian 的过程中,伴随着它的成长,我对它的依赖也逐渐加深,对于我来说,它几次重大的功能变化分别是(按照优先度排列):
* **URI**
应用程序接口,即 Obsidian 支持 `obsidian://` 定向链接,可以直接利用超链接跳转到 Obsidian 中的特定笔记
* 块引用
即可以在 Obsidian 内将某一个段落与另一个段落链接,或在某个文档中插入另一个段落,而且修改引用的原文中该段落时,会所嵌入或所连接的内容会变化。
* 文件相关图谱
即与当前文件所连接的图谱展示
* 图谱筛选
即对图谱中的节点所含的内容进行检索筛选
* 搜索内容复制
即 Obsidian 支持搜索结果的对应文件名批量复制
URI
---
在 URI 功能更新后,我发现它可以通过在 pdf 特定语句直接添加链接,从而跳转到相对应的笔记处,对于我这种 pdf 狂热者来说,给了我不需要依赖 pdf 的笔记功能的机会,而且又让我不需要等待 Obsidian 的 pdf 功能发展起来(虽然我认为 Obsidian 只要做好笔记软件的工作就好,专人做专事);而开发者在开发 URI 功能时给后续的功能拓展留下了伏笔,随着 Obsidian 的 0.9.5 版本中对块引用的更新支持后,兴许后续能直接通过 URL 连接到具体文章中的具体内容,未来可期。
此外,某些思维导图软件也支持快速添加超链接,所以当需要整理或者展示自己的知识库的时候,我往往会考虑要不要用上思维导图来辅助(虽然目前为止都还没有试过)
在 Obsidian 的功能更新的期间,为了让自己适应图谱给自己笔记习惯带来的变化,我开始重度使用 Obsidian 的图谱功能来快速查看以及筛选自己的笔记;而这也取得很不错的效果,我再也没有一个笔记是属于孤立的笔记,即每个笔记之间与其它至少一个笔记联系了起来。
而后我开始研究如何将笔记之间的联系程度以及相关程度再进一步提升,而且能够更直观地表示出笔记与笔记之间的联系,然后我在 Obsidian 论坛上闲逛的时候,发现了——
MOC
---
当你有内容需要与相似的内容做目录的时候,你一般会选择 TOC (Table Of Content) 来对内容进行排列以及概括;而 MOC 的原意是 Map Of Content, 即可以理解成内容地图,如下就是一个内容地图形式:
> 在 [[白切鸡]] 的做法中,突出了用冰水浸泡熟鸡的步骤,可以使得皮更加富有弹性;相似地,之前在看 [[宝塔肉]] 的制作视频时,视频里也提到了可以先将肉冰镇后再进行切片。(其中 [[]] 表示的是与其它文档、大纲或具体段落具体链接)
即利用文字将笔记与笔记之间暂时联系起来,而这个在尚未有成型的整个知识库之间尤为有用——因为笔记的建立往往是零散的,我**并不喜欢**一开始就先按照 123 的步骤列好每一步要记多少笔记或者每一步需要做点什么,所以在此之前,我都是只是看到哪在相对应的地方打个标记或者加个笔记框,显然这并不是一种高效的方式,高亮的内容以及笔记的内容后续都需要再次整理。
MOC 的方法(如果算得上方法的话),旨在让我先开始记笔记,所以我刚见到这个方法,就被当时写这个方法的人的思考折服,这是一个用双向链接功能的方法**特解**;利用 MOC 的做法,将笔记之间暂时通过文字联系起来,当笔记量足够大到可以开始用 TOC 来概括时,那时候就可以整理成章,当需要对某个领域进行从零开始的挖掘的时候,这种方法显得尤为有用。
利用 Obsidian 的双向链接以及图谱筛选,不断地将自己地笔记往外扩展以及与其它笔记相连,还是很方便的了。
但是如何组织笔记已经有了思路后,我又开始琢磨如何将笔记写得更好,自己愿意回去看,也是在同一个论坛上,我发现了两个重要理念:Evergreen 和 Atomic。
Evergreen&Atomic
----------------
即常绿与原子化,Evergreen 笔记指的是单条笔记会随着时间的推移不断更新;而 Atomic 指的是 Evergreen 笔记应当保持最小概念化,例如,单个术语的解释、一次事件的描述以及一个生活道理的体悟。
Evergreen 笔记并非是指你将笔记以及所思所想连接后的长篇大论,仅仅是为了保证你后续在查看笔记的时候不会因为笔记过于老旧而觉得无用(尤其是对一个生活道理的体悟是随着时间变化的)。而利用 Atomic 理念,你的笔记与笔记之间的联系会变得异常简单,因为你不需要再考虑需要引用一篇长文中的哪个部分,而是考虑你是引用一篇很短的笔记的全部抑或是单纯的句子或者词汇(这跟 Niklas Luhmann 提出的卡片盒笔记法中的最小化笔记有不谋而合之处)
在发现这对我无比新鲜的理念后,我在 Obsidian 中执行了类似的理念,并且逐渐发现自己的笔记与写作不再是串联起来,而是并联成了一个互相引用的关系;我的文章的观点基于我的笔记,而我的笔记足够细小,供得起自己文章的随意引用,而且不需要思考太多,因为一般一个笔记只会保留一个或者寥寥几个相关的知识点;而且由于 Obsidian 依旧是以文件为最小载体,所以实践起来反而更有一种卡片的感觉。当我将笔记都根据默认的模板修改后,我的笔记系统也逐渐成型了(或者说成系统化了)。
但新的问题总是在来的路上,当我开始熟练使用这个笔记系统后,我该如何保持以前那种喜欢裁剪收藏的爱好呢,我回顾那么多年来看过的一众知识管理概念,发现了——
Inbox
-----
即收集箱,这个本来是更广泛地应用在 GTD 中,且深受时间管理者的喜爱。当你脑子突然想到要去做某件事,但是你现在需要做另一件事——将事务暂时搁置且放入收集箱,后边在处理;在我看来,这和我之前喜欢裁剪的这件事其实观念上是不谋而合的(当然你也可以认为这是稍后阅读的方法)。这种方法暂时解放了自己的大脑,当我需要裁剪笔记,而且希望后续处理的时候,只要用上时间戳作为文章内容,后续就可以轻易用 Obsidian 现阶段支持的**搜索内容复制**的功能,直接将自己一段时间内以及特定方向的笔记全部拿出来,并且组合成一个新的待办事项清单。
这种方式几乎完美解决了我裁剪需求,但是还是有一点问题还没有解决,那就是如何保证自己回顾的效果——
Anki
----
2020-12-09 更新:
**Obsidian 的插件市场中已经有连通 ANKI 的插件了。**
几乎是在间隔复习类型软件中最流行的一个软件,我曾经在考虑如何在 Windows 下找到合适的既记笔记,又能让我间隔复习的方法;在找到 Anki with Obsidian 技巧之前,我还在犹豫要不要去使用 RemNote(另一款 Roam-Like 在线服务,但是完美融合了间隔复习的功能);但是偶然有一天,我又在论坛上闲逛的时候发现了这样一个脚本:[Obsidian To Anki](https://link.zhihu.com/?target=https%3A//github.com/Pseudonium/Obsidian_to_Anki)。利用了 obsidian 是基于本地文件的优势,通过在文章中插入特定的标识符,实现利用脚本转换成 Anki 卡片的需求。
但是这还不足够,因为我希望的是利用 Anki 给我的笔记进行排期,而非真的需要在 Anki 中复习我的笔记;然后在我的说服下,脚本开发者添加了 Anki 卡片链接到 Obsidian 的功能,即卡片中的相关链接处会有一个用于跳转的超链接,利用的则是上文说到的 URI 功能;在此之后,我的流程转换成了:
> pdf ⇋ obsidian ⇋ Anki
完美覆盖了我所有的需求面,但是如何将这套笔记系统或者说工作流和我自己的职业整合起来呢?
工作
--
当我想要将自己的笔记系统和自己的工作联系起来的时候,我发现这真的是异常困难;因为职业特殊性,我经常需要撰写严肃文章——由于文章的特殊性,我每次都只需要一次成文,而且不需要另外再思考有没有相类似的内容,卡片写作法(笔记法的衍生)在我身上失去了神奇的作用;一时间,笔记系统陷入了只能记,不能用的困境。
但是在我发现了 URI 功能以及标题级别块链接的功能后,事情再次发生了改变,我发现我可以利用之前撰写的严肃文章的**复读以及重温**来提高后续工作过程中,我所写的文章以及宣讲内容的质量,即不再强求于在 obsidian 上运用卡片法来写作,**而是专注于笔记这个过程**。
现在,我每次写完的文章出现了问题或者得到相关的赞扬后,我就会将其存档,且在里面新增一个链接到 obsidian 笔记的超链接,且在对应的笔记中加上链接到这个文档的 FILE 命令(同样可以链接到文档),相互软件间的超链接增强了我对我以往所写过的严肃文章的复盘效果——好在哪,不好在哪,有没有什么总结以及想法;同时摆脱了多次重复犯错的痛苦。
现在我是无比赞同这个观点:obsidian 将笔记之间互相连接,是一次复习行为,类似于不定期的间隔复习。从我将对我撰写的严肃文章开始复盘到目前为止,这种利用自己的工作而产生的内容越来越具有自己的条理性,也越来越能快速地找到问题所在。
生活
--
本来我很不喜欢记日记,但是在发现 Obsidian 的日记(Daily Note)功能后,我开始用 Daily Note 的方式给自己每日的事项进行排程,同时将上文中提到的收集箱的内容放入到 Daily Note 中,然后用删除线将相关的笔记删除;将每天的精力集中在自己所熟知的领域以及 DailyNote 上即可。
总结
--
作为一个已经完全全力投入使用四个月的用户来说,我看着 obsidian 的功能不断增多,从一开始只有双向链接的简陋到现在加上块引用,开发者以及社区都给我提供了很多新的见解以及支持,而我也终于借着这个笔记软件,将自己以前记笔记就再也不回去看的问题,逐渐给解决掉了;相信再继续深度使用它一年后,我应当会更加熟练地掌握笔记这回事,而且往着成为知识管理者继续努力。

Refer
-----
* [LYT kit](https://link.zhihu.com/?target=https%3A//forum.obsidian.md/t/lyt-kit-now-downloadable)
* [Obsidian to Anki](https://link.zhihu.com/?target=https%3A//forum.obsidian.md/t/obsidian-to-anki-v2-9-a-feature-rich-script-that-allows-you-to-add-notes-from-obsidian-to-anki)
Key Features
# Intel Quad-core processor J4115 (14nm) with 4MiB Cache, up to 2.5Ghz(Single Thread) or 2.3Ghz(Multi Thread)
# Dual-channel Memory DDR4-PC19200 (2400MT/s). Please look into the DRAM compatibility list first. Some memory modules are not compatible.
# Total 32GiB RAM Space with two SO-DIMM slots
# 4 x PCIe 2.0 for one M.2 NVMe storage
# 2 x 2.5Gbit Ethernet ports
# 2 x SATA 3.0
# SSE4.2 accelerator (SMM, FPU, NX, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES)
# Intel UHD Graphics 600 (Gen9.5 LP GT1) up to 700Mhz
# HDMI 2.0 and DP 1.2 multiple 4K/60Hz video outputs
# RTC / BIOS backup battery is included
* Amlogic S905X3 Processor
* DDR4 4GiB with 32-bit bus width
* 1x Micro SD slot (DS/HS mode up to UHS-I SDR104)
* 1 x GbE LAN ports (RJ45, supports 10/100/1000 Mbps)
* 1 x HDMI 2.0 (up to 4K@60Hz with HDR, CEC, EDID)
* 1 x USB 2.0 host port
* 1 x Debug serial console (UART)
* 2 x SATA Connectors
当 ~TiddlyWiki 生成具有特定标签的条目的清单 (例如,标签丸的下拉清单),其排序条目依循下列规则:
# 始于标签条目的 <<.field list>> 字段中[[声明|Title List]]的给定顺序。
# 在其余每个条目 <<.place T>>,寻找 <<.field list-before>> 字段,如果此字段有一条目名称作为其值,则置此如果此字段有一条目名称作为其值,则置此 <<.place T>> 于该条目之<<.em 前>>。
#* 一个特殊情况,如果该字段存在,但其值为空,则置 <<.place T>> 于清单的起始处。
# 在其余每个条目 <<.place T>>,寻找 <<.field list-after>> 字段,如果此字段有一条目名称作为其值,则置此如果此字段有一条目名称作为其值,则置此 <<.place T>> 于该条目之<<.em 后>>。
# 如果仍有其他条目,则将其放在依字母顺序升幂排序的名称清单的末尾。将忽略大写字母和小写字母的区别。
具有特定标签的条目的排序,可以在标签丸下拉清单中使用拖放直接修改。底层的 [[list-tagged-draggable 宏|list-tagged-draggable Macro]]也可以用在别处。
核心具有用于刷新周期的内置性能检测。请参阅控制台的“设置”页签上的“性能检测”。维基在生效之前需要重新加载。
打开性能检测后,每次触发刷新周期时,浏览器开发人员控制台都会显示附加的计时信息。例如:
```
performance: mainRender: 327.83ms
performance: styleRefresh: 9.14ms
performance: mainRefresh: 68.10ms
```
上述信息应解释如下:
* mainRender 是页面模板的初始显示所需的时间
* styleRefresh 是刷新页面样式表所需的时间
* mainRender 是刷新主页模板所需的时间
举个例子,尝试在侧边栏页签之间切换,以比较它们渲染所需的时间。
还提供了有关筛选器运行时间的更多详细信息。启用性能检测后,在浏览器开发人员主控台中输入以下 JavaScript 命令:
```
tw.perf.log()
```
将显示一个表格, 其中包含以下信息:
* ''name'' - 字符串 "Filter: " 加上筛选器的文本
* ''invocations'' - 自启动以来筛选器的调用次数
* ''totalTime'' - 自启动以来评估此筛选器所花费的总时间 (以毫秒为单位)
* ''percentTime'' - 此筛选器的运行时间与所有筛选器的总运行时间的百分比
!Permanent Notes 永久笔记
永久笔记。这里的笔记是对临时笔记和文献笔记定时整理之后的笔记, 存放在卡片盒中。这种笔记是卡片盒笔记系统的核心笔记,同样需要遵循以下要点:
# 梳理临时笔记和文献笔记,并思考他们和你自己的研究方向或者兴趣有哪些关联。用自己的语言进行加工、提炼或扩充,每个笔记记录一个要点。梳理完成之后,临时笔记就可以丢弃。
# 所有的永久笔记按照同一套规则存放在同一个地方。规则包括命名规则、链接规则。命名规则表示每一条笔记在卡片盒中的位置或者说排列方式,从而形成了一个树形的结构; 链接规则用于将某一条笔记与所有相关的笔记关联起来,从而形成了一个网状的结构。最终,你的卡片盒就是你所有知识点所汇集成的一张网。
# 当新建立一个笔记时,需要在已有的笔记中去寻找是否可以与新笔记建立起联系。如果有相关的笔记,就可以放在相关笔记的后面。如果是一个全新的笔记,可以放在卡片盒的最后。
# 为便于寻找到某条笔记,需要创建一个索引表,将该笔记链接到索引表。或者在索引表中创建某个主题的一个入口笔记,再将该笔记链接到入口笔记。
Ordinarily, at startup TiddlyWiki displays the tiddlers specified as a filter in the tiddler [[$:/DefaultTiddlers]].
Sometimes it's useful to re-open the same tiddlers that were open when the file was saved. To do so, set [[$:/DefaultTiddlers]] to this filter:
```
[list[$:/StoryList]]
```
This filter returns the tiddlers specified in the [[$:/StoryList]] tiddler, which is the system tiddler that TiddlyWiki uses to store the sequence of tiddlers in the current story.
!Project Notes 项目笔记
项目笔记只和一个特定的项目有关,他们保存在以项目命名的文件夹中。当项目完成之后,这个项目的相关笔记就可以删除或者存档。
This great trick was shown to the tiddlywiki google group by [[Alberto Molina|https://groups.google.com/forum/#!topic/tiddlywiki/OCntQ79DuwM]]. I enhanced it a bit.
|!Search tag: | <$edit-text tiddler="$:/temp/RenameTags/search" tag="input" type="text"/> |
|!Replace by: | <$edit-text tiddler="$:/temp/RenameTags/replace" tag="input" type="text"/> |
---
<$reveal type="nomatch" text="" state="$:/temp/RenameTags/replace">
!First step
!!//Apply the tag <$tiddler tiddler={{$:/temp/RenameTags/replace}}><$transclude tiddler="$:/core/ui/TagTemplate"/></$tiddler> to the following tiddlers//
<$list filter="[!has[draft.of]tag{$:/temp/RenameTags/search}!tag{$:/temp/RenameTags/replace}sort[created]]">
<$checkbox tag={{$:/temp/RenameTags/replace}}> <$link to={{!!title}}><$view field="title"/></$link></$checkbox><br/>
</$list>
</$reveal>
<$reveal type="nomatch" text="" state="$:/temp/RenameTags/search">
!Second step
!!//Remove the tag <$tiddler tiddler={{$:/temp/RenameTags/search}}><$transclude tiddler="$:/core/ui/TagTemplate"/></$tiddler> from the following tiddlers//
<$list filter="[!has[draft.of]tag{$:/temp/RenameTags/search}tag{$:/temp/RenameTags/replace}sort[created]]">
<$checkbox tag={{$:/temp/RenameTags/search}}> ~~<$link to={{!!title}}><$view field="title"/></$link>~~</$checkbox><br/>
</$list>
</$reveal>
"favicons" are small icons that most browsers display to help users identify websites. Note that all browsers support bitmap images, but only certain modern browsers support SVG format icons.
! favicons in the Browser
When TiddlyWiki starts up in the browser it looks for a tiddler called [[$:/favicon.ico]] and dynamically uses it as the favicon for the page. If you modify the image then the favicon changes instantly to reflect it.
<<.from-version "5.1.23">> To set an external image as the favicon, assign the URL to the ''_canonical_uri'' field of the [[$:/favicon.ico]] tiddler.
! favicons on the Server
On the server, the ServerCommand will serve the tiddler [[$:/favicon.ico]] at the path `/favicon.ico`.
设置标签是一种为条目分类的方法。例如,如果您有代表不同个体的条目,您可以标记他们为''朋友''、''家庭''、''同事''等,表明这些人与您之间的关系。
标签其实只是一个条目 (或是一个潜在的条目),而且可以有其自己的标签。您可以将任意数量的标签添加到同一个条目。
有关如何设置标签的说明,请参阅 [[创建和编辑的条目|Creating and editing tiddlers]]。
通过标记您的条目,您可以查看、导航,以及使用许多其他方式组织您的信息:
* 一个条目上的彩色标签丸让您快速访问所有其他具有相同标签的条目,以及呈现标签本身的条目。
* 如果一个条目当作标签,则在其[[信息面板|InfoPanel]]的''子条目''页签,将显示当前以其为标签的条目。
* 侧边栏的''更多''页签有一个''标签''页签,概述的所有标签,并允许您访问所有您标记的条目。
* 您可以使用[[筛选器|Filters]],创建基于其标签的条目清单。然后可以显示那些条目的[[字段|TiddlerFields]]的任意组合。例如,您可以构建一个词汇表,列出标记为''词汇表''的所有条目的名称和内容。这样的清单可以任何您希望的方式格式化:例如,项目符号、编号或以逗号分隔。
* 有一些特别的''系统标签'',控制条目和整个 ~TiddlyWiki 页面的布局。相关说明请参阅[[页面和条目布局定制|Page and tiddler layout customisation]]。
有另外两种使用标签方式:
! 设置一个标签的颜色和图标
若要更改标签丸的颜色或将图标添加到标签丸,您可以使用在边栏中的''更多''页签下的''标签''页签的 <<.icon $:/core/images/tag-button>> [[标签管理|$:/TagManager]]。
* 要改变颜色,可从点击''颜色''栏中的颜色选择器按钮选择之。或者,点击''信息''栏中的图标,然后于''颜色''字段中输入一个 [[CSS]] 颜色值。
* 要更改图标,请点击''图标''栏中的 <<.icon $:/core/images/down-arrow>> 按钮,然后从清单中选择可用的图标
! 变更列出的标签顺序
默认情况下,标记的条目是按字母顺串行出的。
如果您想要其它排序,添加 <<.flink ListField>> 字段到该标记条目,并设置其值是一个依此顺序的[[条目清单|Title List]]。
''list'' 字段没有提及的所有条目。请参阅 ~TiddlyWiki 使用的标记条目排序的[[确切规则|Order of Tagged Tiddlers]]。
This is a version of the TaskManagementExample enhanced with the ability to drag and drop the task list to re-order them.
! Outstanding tasks
//Drag the tasks to re-order them//
<<list-tagged-draggable tag:"task" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"You don't have any active tasks">>
! Completed tasks
//(Listed in reverse order of completion)//
<$list filter="[!has[draft.of]tag[task]tag[done]sort[created]]">
<div>
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
</div>
</$list>
```
//Drag the tasks to re-order them//
<<list-tagged-draggable tag:"task" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"You don't have any active tasks">>
! Completed tasks
//(Listed in reverse order of completion)//
<$list filter="[!has[draft.of]tag[task]tag[done]sort[created]]">
<div>
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
</div>
</$list>
```
TiddlyWiki5 可以作为一个简单的工作管理系统,无须进一步的客制化。这个想法是设置任务的标签为 `task`,那些已完成的也设其标签为 `done`。以这种方式是直接生成工作清单。
<<.tip """另有[[演示的增强版|TaskManagementExample (Draggable)]],添加了拖放任务,重新排序的功能。""">>
! 未完成的任务
<$list filter="[!has[draft.of]tag[task]!tag[done]sort[created]]">
<$checkbox tag="done"> <$link><<toc-caption>></$link></$checkbox><br />
</$list>
! 已完成的任务
<$list filter="[!has[draft.of]tag[task]tag[done]sort[created]]">
<$checkbox tag="done"> ~~<$link><<toc-caption>></$link>~~</$checkbox><br />
</$list>
<$checkbox tag="done"> <$link/></$checkbox>
{{{ [tag[task]] || $:/core/ui/TagTemplate }}}
Google 云端硬盘的一个附加程序,允许存放在那里的 TiddlyWiki 文件可直接被打开和保存。
若要了解如何将其加到您的帐户, 请到项目的信息页面:
{{!!url}}
<<<
I made an app that lets one edit TiddlyWiki files saved in your Google drive and then saving them back automagically. The page is here https://chrome.google.com/webstore/detail/tiddly-drive/oaphhjhbbabdjnpjpiliepphpmnioolo but I think you need to add it from the Google Drive web interface.
I even added an optional ability to save with ctrl + s hotkeys.
<<< [[Joshua's launch post|https://groups.google.com/d/topic/tiddlywiki/7pNJizR57e8/discussion]]
*TiddlyWiki 是一种工具
*TiddlyWiki 是一个工具箱
*TiddlyWiki 是一个用户和开发人员的社区
*最后,TiddlyWiki 是一种哲学
-----
-----
{{TiddlyWiki 是一种工具}}
-----
{{TiddlyWiki 是一个工具箱}}
-----
{{TiddlyWiki 是一个用户和开发人员的社区}}
-----
{{最后,TiddlyWiki 是一种哲学}}-、
-----
[[https://tiddlywiki.com/#WikiText]]
使用了 TiddlyWiki 有一段时间,今天来谈谈一些表格(table)中的小技巧。
> 基本应用
------
这是最简单的应用:每一行代表一个列(Row),而每一栏(Column)以`|`来分隔。我们用`|`来为表格的第一行决定了这个表格有多少列。
```
|header 1|header 2|header 3|
|info 1|info 2|info 3|
|info 4|info 5|info 6|
```

如果想在资料格里多于一行可以以 `<br>` 号来新增新行。
```
|header 1|header 2|header 3|
|info 1|info 2<br>next line|info 3|
|info 4|info 5|info 6|
```

> 格式设定
------
一般 TiddlyWiki 内的文字格式也是可以使用在表格里,例如以下的格式:
<table data-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal"><tbody><tr><th>字符</th><th>效果</th></tr></tbody></table>
```
|header 1|header 2|header 3|
|''info 1''|__info 2__|//info 3//|
|`info 4`|[[info 5]]|a^[^2]^^ b,,2,,|
```

* 要为全列加上 Header,可以在行末加上 `h`。
* 要为全列加上 Footer,可以在行末加上 `f`。
* 要为全列加上 Caption,可以在行末加上 `c`。留意 Caption 的那行只要有一栏便可。
另外,如果要为特定的格子变成 Header 的格式,只要在表格的内容后加上一个 `!`。
一起看例子:
```
|this is a caption|c
|header 1|header 2|header 3|h
|info 1|info 2|info 3|
|info 4|!info 5|info 6|
|info 7|info 8|info 9|
|footer 1|footer 2|footer 3|f
```

> 表格的对齐(Alignment)
------------------
想为表格内的内容对齐也是可以的,可以向上下左右对齐。
* 要向左对齐,只要在表格的内容后加上一个空格。
* 要向右对齐,只要在表格的内容后前加上一个空格。
* 要置中对齐,只要在表格的内容前和后各加上一个空格。
* 要向上对齐,只要在表格的内容前加上一个 `^`。
* 要向下对齐,只要在表格的内容后加上一个 `,`。
* 上下对齐、左右的对齐、单格的 Header 和格式可以混着用。
一起看例子:
```
|!header 1|!header 2 | !header 3|
|++++++++++++|++++++++++++|++++++++++++|
|info 1 | info 2 | info 3|
|info 4<br>new line|^info 5|,info 6|
|info 7<br>new line|^info 8 |^ info 9|
|info 10<br>new line|,info 11 |, info 12|
```

> 合并储存格
-------
* 如果要合并左格的内容,只需在该格里放进 `<`。
* 如果要合并右格的内容,只需在该格里放进 `>`。
* 如果要合并上格的内容,只需在该格里放进 `~`。
简单例子:
```
|sub 1|<|sub 2|
|sub 3|sub 4|~|
```

再来是一个比较复杂的例子,留意 info 7 的那一格是如何做到 2x2 的合并:
```
|info 1|info 2|info 3|info 4|
|info 5|info 6|info 7|<|
|~|info 8|~|
|~|info 9|>|info 10|
```

> 表格内放置表格
---------
由于表格的一列只能用一行来表达,所以要处理一些复杂的表格会比较麻烦,但是我们可以以把一个 Tiddler 的内容放入表格的 Tiddler 来解决。这个在 TiddlyWiki 里名为 [Transclusion](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520in%252520WikiText.html)。
这个方法比起 [AsciiDoc 的做法](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/AsciiDoc-%25E8%25A1%25A8%25E6%25A0%25BC%25E6%2595%2599%25E5%25AD%25B8/) 的来得麻烦,但是要修改时易读性大胜。
我们看个例子。
这是一个名为 Table 的 Tiddler:
```
|inside 1|inside 2|
|inside 3|inside 4|
```
我们要把 Table 这个 Tiddler 放入(Transclude)进另一个表格里。
```
|header 1|header 2|header 3|
|info 1|info 2<br><$transclude tiddler="Table" mode="block"/>|info 3|
|info 4|info 5|info 6|
```

> 表格里插入列表
---------
和表格内放置表格一样,我们也要使用 [Transclusion](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520in%252520WikiText.html) 来达到这个效果。以下是例子:
这是一个名为 List 的 Tiddler:
我们要把 List 这个 Tiddler 放入(Transclude)进另一个表格里。
```
* item 1
* item 2
```

> 参考资料
------
* [TiddlyWiki 官网:Tables in WikiText](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Tables%252520in%252520WikiText.html)
用纯文字来编辑系列:
* [使用 AsciiFlow 来画关系图的教学和心得](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/20201208-asciiflow-tutorial/)
* [AsciiDoc 表格教学](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/AsciiDoc-%25E8%25A1%25A8%25E6%25A0%25BC%25E6%2595%2599%25E5%25AD%25B8/)
本文授权转载自个人博客:点[字记](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
大家如果有用过 [Evernote](https://link.zhihu.com/?target=https%3A//evernote.com/) 的话,想必也会知道 [内部笔记链接](https://link.zhihu.com/?target=https%3A//help.evernote.com/hc/zh-cn/articles/208313588-%25E5%25A6%2582%25E4%25BD%2595%25E4%25BD%25BF%25E7%2594%25A8-%25E8%25A8%2598%25E4%25BA%258B%25E9%2580%25A3%25E7%25B5%2590-%25E5%25BF%25AB%25E9%2580%259F%25E5%259C%25A8%25E8%25A8%2598%25E4%25BA%258B%25E4%25B9%258B%25E9%2596%2593%25E9%2580%25A3%25E6%258E%25A5-) 这个功能。 在 TiddlyWiki 里,[内部笔记链接](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Linking%252520in%252520WikiText.html) 这个功能十分容易做到,只要加入 `<Tiddier 的名称>` 便可以了。只是,如果在只有 手机 或 平板电脑的场合下,要在编辑器里输入 `[[]]` 或是使用 内置的连结工具 会比较不方便和比较慢,有没有方法能够十分方便地获得 `[[<Tiddier 的名称>]]` 这个内部笔记链接呢?于是,便开始研究如何做到这个个人认为对效率提升是挺重要的功能。
由于实作上需要学习一些 TiddlyWiki 的概念,如果只想直接使用这个功能的话,请看本文的最后一个部分。
首先,我们在学习如何做到这个之前,首先学习两个概念,分别为 [Transclusion](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520in%252520WikiText.html) 和 [Transclusion with Templates](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520with%252520Templates.html)。
> Transclusion
--------------
Transclusion 就是把一个 Tiddler 的内容直接放在另一个 Tiddler 里的意思。如果我们在一个 Tiddler 里这样写: `{{IncludedTiddler}}`,这样便会展示 IncludedTiddler 这个 Tiddler 的内容。

我们也可以只 Transclude 该 Tiddler 的某些内容,只要在 Tiddler 名后加上 `!!` 和该字段的名称,例如只要 IncludedTiddler 这个 Tiddler 的标题我们可以这样写:`{{IncludedTiddler!!title}}`。

如果我们要展示自己的标题的话,我们可以这样写:`{{!!title}}`
例如,当我们这样写:

结果便会变成这样。

那么问题来了,如果 IncludedTiddler 这个 Tiddler 的作用是为了显示标题的话,我们有没有方法在 Display 这个 Tiddler 里 Transclude IncludedTiddler 这个 Tiddler 而得出 Display 这个 Tiddler 的标题呢?
如果我们只是单纯地 Transclude IncludedTiddler 的话,得到的只是 IncludedTiddler 的标题 :(

这个时候,我们要的是一个新概念。
> Transclusion with Templates
-----------------------------
没错,就如上面所述,这个概念名为 [Transclusion with Templates](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520with%252520Templates.html) 。
简单来说,这个概念是我们 Transclude 一张模板(Template),然后由这个模板来展示本体的资料。
要 Transclude 一张模板的方法很简单,只要这样写便可以了 `{{||<Template Tiddler的名称>}}`(就是加上 `||` 在前面)。
例如,当我们这样写:

结果便会变成这样。

好了,得知了这个后,我们回到正题:如何快速获得某 Tiddler 的连结呢?
> 复制内部笔记链接
----------
我们想要做到的是在每个 Tiddler 里都以 [默认文字](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/tiddlywiki-%25E5%25A2%259E%25E5%258A%25A0%25E9%25A0%2590%25E8%25A8%25AD%25E6%2596%2587%25E5%25AD%2597%25E7%259A%2584%25E6%2596%25B9%25E6%25B3%2595-snippet/) 的方法来加上一个按纽,从而我们能够在该 Tiddler 里按下这个按纽便能够把 `[[<该 Tiddler 的标题>]]` 放到剪贴板里。
我们想要做到的是在每个 Tiddler 里都 Transclude 一个能把该 Tiddler 的连结放到剪贴板里的模版。例如该展示的模版名为 `Copy Tiddler Link` 的话,那么我们加上 `{{||Copy Tiddler Link}}`,便会显示一个按纽,按下的话便便能够把 `[[<该 Tiddler 的标题>]]` 放到剪贴板里。

要防止不断复制贴上 `{{||Copy Tiddler Link}}` 的话,我们可以用 [默认文字](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/tiddlywiki-%25E8%25A3%25BD%25E9%2580%25A0%25E8%25A8%2598%25E4%25BA%258B%25E9%2580%25A3%25E7%25B5%2590%25E7%259A%2584%25E6%2596%25B9%25E6%25B3%2595/%257B%257B%2520site.baseurl%2520%257D%257D/tiddlywiki-%25E5%25A2%259E%25E5%258A%25A0%25E9%25A0%2590%25E8%25A8%25AD%25E6%2596%2587%25E5%25AD%2597%25E7%259A%2584%25E6%2596%25B9%25E6%25B3%2595-snippet/) 的方法加上 `{{||Copy Tiddler Link}}` 这段字。
而 `Copy Tiddler Link` 这个 Tiddler 的内容如下。大概做法是先把标题 (`!!title`)放到一个变数 variable 里,然后使用一个自制的 [macro](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/tiddlywiki-%25E5%25AF%25A6%25E7%2594%25A8-macro-copyblock1/) (`createLink`)把标题变成 `[[<该 Tiddler 的标题>]]` 的样子,最后制造一个按纽(button),按下后会呼叫默认的 [tm-copy-to-clipboard](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/WidgetMessage%25253A%252520tm-copy-to-clipboard.html) 把 `[[<该 Tiddler 的标题>]]` 放到剪贴板里。
另外,`$:/core/images/copy-clipboard` 只是系统内默认的 Icon。就是按纽上的那个。
```
\define createLink(content, openBracket:"[[", closeBracket:"]]")
$openBracket$$content$$closeBracket$
\end
<$set name=title value={{!!title}}>
<$set name=link value=<<createLink $(title)$>> >
<$button message="tm-copy-to-clipboard" param=<<link>>>{{$:/core/images/copy-clipboard}}</$button>
</$set>
</$set>
```
想继续研究的同学可以参考 [Tiddlywiki set widget](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/SetWidget.html) 和 [tm-copy-to-clipboard](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/WidgetMessage%25253A%252520tm-copy-to-clipboard.html)。
内心 OS: 这种做法还可以造更多有其他功能的按纽。
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
使用了 TiddlyWiki 也有一年半的时间,TiddlyWiki 在知识整理方面十分好,加上我自己的修改,它已经变成了我的知识和任务管理软件。而作为一个任务管理软件,收集是一个基本的功能。在这篇里介绍我是如何做这个收集的功能。
* 什么是收集和收集箱?
* 我对 TiddlyWiki 的收集箱的要求是?
* 为何我使用 TickTick 作为 TiddlyWiki 的收集箱?
* 有了 TickTick 作为收集箱后要如何做?
* 进阶:如何在 macOS 上快速地把心中所想放入 TickTick? 我们可以使用 Alfred 4
* 进阶:如何使用 WebServer API 来直接把资料放进 TiddlyWiki?
好了,什么是收集,以及为什么这个收集的过程这么重要?
> 什么是收集和收集箱?
------------
我们有时在工作的时候会突然想到一些东西。我们可能会把它记在脑里,又或是写在纸里。但是如果只是记在脑里,我们大脑的记忆空间十分有限,所以很容易会忘记刚刚想到的事情;而写在纸张里,便会因为日后资料太过散乱,而无法找到当时找到所有的东西。
根据 GTD 的理论,我们需要有一个收集箱(Inbox)。换句话说,当我们突然有一些灵感,我们要把它先放到收集箱;当别人有任务给我们时,我们要把它先放到收集箱。
而最好的做法是,这个收集箱只能有唯一一个,把所有的东西都放进这个唯一的收集箱中集中处理。
当我们把东西收集后,每一天或每隔一段日子把收集箱内的东西处理,也就是把它们分类或整理,然后变成资料放到知识管理系统 或是 拆解为下一步的行动放到任务管理系统里。
由于我的 TiddlyWiki 的两个主要功能便是 知识管理系统 和 任务管理系统,所以收集箱其实扮演一个十分重要的角色。
所以,我需要一个 TiddlyWiki 专用的收集箱。
> 关于作为 TiddlyWiki 收集箱的注意事项
--------------------------
在找出如何为 TiddlyWiki 作为收集箱的方法前,有两个问题需要思考:
1. 我们可以如何用什么的收集方法?
2. 收集后未经处理的资料应该直接放在 TiddlyWiki 还是在 TiddlyWiki 以外的地方?
先来回答第一个问题。
TiddlyWiki 是一个网页应用程序,所以无法像一般的 iOS 原生应用程序一样,能够让我快速的收集看到的东西或灵感。
例如平常在网上看到一个有用的连结,我们无法使用分享页面把网页链接直接分享到 TiddlyWiki 里等,而是每一次也要打开 TiddlyWIki,再输入账号和密码打开,然后把我看到、或是想到的东西放进去。平常有空时这样做还好,但是在收集灵感这类一瞬即逝的东西,多一个步骤或是多等候一秒也会让这些灵感消失。这个时候 TiddlyWiki 便无法达到我的要求。
由于这个是使用网页为应用程序的 TiddlyWIki 原生的问题,所以第一时间想到的方案是只能在 TiddlyWiki 以外寻找方法解决,大概就是找一个 TODO list 类的应用程序作收集,然后有空再整理再放进 TiddlyWiki 里。
然后再上网找了资料后,发现其实我们可以经由 iOS Shortcuts 呼叫 [WebServer API](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/prerelease/static/WebServer%252520API%25253A%252520Put%252520Tiddler.html) 的方法直接把资料放进 TiddlyWIki 里。这个方案的技术含量比较高,在本文的最后会稍微提一下(反正最后我也没有使用这个方案,所以没有兴趣的人也可以省掉)。但是使用这个方法虽然很快速,但是需要的技术含量比较高、一不小心可以直接杀死自己的 TiddlyWiki Server、还有最致命的缺点:如果本身正在打开 TiddlyWiki 的页面,要重新载入才能看到汇入的 Tiddler。
这个方法虽然很麻烦,至少能做到我的要求,所以也在考虑的方法之中。
所以现在有两个方法:
1. 找一个 TODO list 类的应用程序作收集,然后有空再整理再放进 TiddlyWiki 里。
2. 直接用 TiddlyWiki 内置的 WebServer API 把收集后的内容直接放入 TiddlyWiki 里。
再来回答第二个问题:收集后未经处理的资料应该直接放在 TiddlyWiki 还是在 TiddlyWiki 以外的地方?
我个人是偏向放在 TiddlyWiki 以外的地方,原因是有了这个 TiddlyWiki 外的地方坐缓冲,我可以确保 TiddlyWiki 里的资料都是有用和可靠的资料。但这只是我个人的偏意。
事实上,在我还未使用 TiddlyWiki 时,我有一段时间是在使用 Evernote ,这时我十分喜欢把很多东西直接汇入到 Evernote 的一个名为 Inbox 的记事本里,然后在处理时只是把这些原材料没有消化便放在不同的资料夹里,然后便再没有看过这些资料了。这做成了后悔我完全无法整理 Evernote 内的资料,因为资料量太大,而对自己有用的资料不多,扔掉又很可惜。
所以,最后决定是使用第一个方案:找一个 TODO list 类的应用程序作收集,然后有空再整理再放进 TiddlyWiki 里。
> 我对 TiddlyWiki 的收集箱的要求
-----------------------
在这个需求和这个应用的场景下,我需要的是一个收集功能要强,以及支援全平台的收集箱应用程序。我需要的东西如下。
* 这是一个 Todo List 的应用程序。我能把要收集的东西都放进去,然后在处理(也就是放到 TiddlyWiki)后把它在 Todo List 应用程序中打一个剔。
* 这个应用程序能够支援除了 Android 之外的全平台(Windows、iOS、Web)。因为我在公司的电脑是使用 Windows;我在家里看是用 MacOS;在街上我可能是用 iPhone 或 iPad ;在不是自己的电脑中使用网页浏览器。而这些场合上都需要使用。watchOS 反而不是必要。
* 由放我是使用 Apple 生态为主,所以这个应用程序必须是能够支援把一切的东西以 Share 的方式分享到这个 Todo List 的应用程序。
* 这个应用程序不需要分类或标签等等的功能,因为它只是一个作为收集箱的存在,本身不是一个任务管理软件。
* 令一点就是,这个应用程序在 iOS 里不可以是只是一个网页打包而成的应用程序。他必须要有内置的储存。这样我才能在网络不通的环境内也能使用。
* 如果这个应用程序能够支援 Shortcuts 会更好,这样我便可以修改我本来的 [听写捷径应用程序](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/%25E5%25A6%2582%25E4%25BD%2595%25E5%25BF%25AB%25E9%2580%259F%25E8%25A8%2598%25E4%25B8%258B%25E9%259D%2588%25E6%2584%259F%25E4%25BE%2586%25E5%25AF%25AB%25E9%2583%25A8%25E8%2590%25BD%25E6%25A0%25BC-%25E4%25BD%25BF%25E7%2594%25A8-ios-%25E8%2581%25BD%25E5%25AF%25AB%25E5%258A%259F%25E8%2583%25BD%25E5%25BF%2583%25E5%25BE%2597/) 进行收集。
* 不用钱、或是只需要不是太多的金钱。因为我只是使用不多的功能。如果是那种要分开平台收钱或是每月付费的那种在这个用法下便有点贵了。
> 我对 TiddlyWiki 的收集箱:TickTick
-----------------------------
经过几个选择后,我决定最后使用的是这个名为 [TickTick](https://link.zhihu.com/?target=https%3A//ticktick.com/) 的应用程序。

这个应用程序符合以上所说的功能。其实我也有考虑过以下的应用程序:
* [Bear](https://link.zhihu.com/?target=https%3A//bear.app/):它可以自制 Checkbox,但是它不是全平台也要要每月付费。
* Apple Reminder:原因同上,不是全平台。
* [Omnifocus](https://link.zhihu.com/?target=https%3A//www.omnigroup.com/omnifocus/):[网页版](https://link.zhihu.com/?target=https%3A//web.omnifocus.com/) 要每月付费,也不是全平台。再者用 Omnifocus 来做这个真是杀鸡用牛刀了。
* [Things](https://link.zhihu.com/?target=https%3A//culturedcode.com/things/):每个平台也要分开付费,以及 macOS 版实在是太贵了。
* [Todoist](https://link.zhihu.com/?target=https%3A//todoist.com/%3Flang%3Den):我有一段时间使用它的。因为它符合我本来的所有需求,在我的需求下免费,也支援全平台,只是在处理的过程中不太顺手,另外它的每一个 TODO item 只有一行。如果能支持多于一行的话在使用[听写捷径应用程序](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/%25E5%25A6%2582%25E4%25BD%2595%25E5%25BF%25AB%25E9%2580%259F%25E8%25A8%2598%25E4%25B8%258B%25E9%259D%2588%25E6%2584%259F%25E4%25BE%2586%25E5%25AF%25AB%25E9%2583%25A8%25E8%2590%25BD%25E6%25A0%25BC-%25E4%25BD%25BF%25E7%2594%25A8-ios-%25E8%2581%25BD%25E5%25AF%25AB%25E5%258A%259F%25E8%2583%25BD%25E5%25BF%2583%25E5%25BE%2597/) 时能制造多于一行的内容。
而 TickTick 和 Todoist 相似:它符合我本来的所有需求、在我的需求下免费、支援全平台、每一个 TODO item 多于一行。
所以便决定便用它,另外也为它制造了一个听写捷径应用程序(Shortcuts)。不懂 Shortcuts 的朋友也能直接使用应用程序的听写功能,只要在收集时按下这个咪高风按键便可以了。

> 有了 TickTick 作为收集箱后要如何做?
-------------------------
在介绍了什么是 GTD 中的收集箱,以及 TickTick 作为我收收集箱后,再来说说我在收集流程上的微调。
在以前使用收集箱的经验里,我发现一个麻烦的问题。
这个问题是一旦我把所有东西都先放到收集箱里,这个收集箱很容易会无限扩张,最后无十分抗拒并拖延把收集箱里的东西处理掉。
这个情况最常发生的情况是平时看到一些单纯想收集的东西,但是其实自己没有任何目标是和这个资料有关的话,这个时候把这个资料扔掉便十分可惜,但是又无法把它处理掉。一旦在处理收集箱的时候有很多这样的东西,我们大脑便会不胜负荷而拖延处理。
所以,我也在 GTD 收集箱这个流程中做了一些妥协。就是除非时间十分紧迫,否则我会尽可能把想到的东西先放到 TiddlyWiki 中属于它的位置,以减低日后处理收集箱的负荷;如果时间真是十分紧迫(例如在街上不能很快的打开 TiddlyWiki 或是一些灵感),我才会使用收集箱来进行收集。
> 进阶:如何在 macOS 上快速地把心中所想放入 TickTick? 我们可以使用 Alfred 4
----------------------------------------------------
如果你有在 macOS 上使用 Alfred 4 并购买了 [Powerpack](https://link.zhihu.com/?target=https%3A//www.alfredapp.com/powerpack/) 的话,也可以按 [这条](https://link.zhihu.com/?target=https%3A//www.packal.org/workflow/ticktick)链接 汇入一个 Workflow 快速在 macOS 里经由 Alfred 把心中所想真接加入 TickTick。
使用方法只需要以 opt + space 打开 Alfred ,再输入 `t <what you think>` 便可以把你所想的东西直接加入 TickTick 了。
只是,这个 Workflow 应该是以 Rest API 的方式直接把东西放到 TickTick 的远端数据库而不是把东西放到 TickTick 的应用程序里,所以如果不能在 TickTick 里看到新加入的东西,我们要在 TickTick 里按一次同步(cmd + s)让应用程序能拿取远端数据库后应该便能看到了。
> 附录:如何使用 WebServer API 来直接把资料放进 TiddlyWiki?
--------------------------------------------
方法就是便用 [http put request](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/prerelease/static/WebServer%252520API%25253A%252520Put%252520Tiddler.html):
* `PUT http://<link>/recipes/default/tiddlers/<tiddler title>`
* Authorization: `Basic authorization` 并输入 username 和 password
* Header 方面,要输入这两个:
* X-Requested-With: TiddlyWiki
* Content-Type: application/json
Request 的 Body 是一个类似以下的 Json:
```
{
"title": "Your title",
"tags": "[[Your Tag]]",
"text": "First Line\n\nSecond Line\n\nThird Line\n\n"
}
```
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [zhuanlan.zhihu.com](https://zhuanlan.zhihu.com/p/346651484)
这篇来分享如何在每一个 Tiddler 里加入页面来放置一些自订功能。这是使用 [TiddlyWiki](https://zhuanlan.zhihu.com/p/346599289) 效率提升的一大步。
> 需求
----
使用了 TiddlyWiki 一段时间后,会发现要是能够在每一个 Tiddler 里也能有一些自订的操作便好了。这样做的话,使用 TiddlyWiki 的效率应该会快了不少。
例如,如果每一个 Tiddler 的内容前有一排按钮,按下第一颗便能复制这 Tiddler 的标题到剪贴板里,按下第二颗按钮便能进行某一个操作等等。



这样的话,使用 TiddlyWiki 的效率应该会快了很多。例如我可以弄一颗按钮用来把今天的日期 tag 进这 Tiddler 里、又或是弄一颗按钮来新增一个 Tiddler,这个新的 Tiddler 有了一个 Tag 是刚刚按下的 Tiddler 的名称等等。
当然,你看着上图应该能够猜到,这些都是能够在 TiddlyWiki 上实行的。
我那么喜欢使用 TiddlyWiki 的原因,就是因为它的弹性十分好,我们可以自定义很多东西来符合自己的使用习惯。
> 如何做
-----
根据 TiddlyWiki 官网上的这一页 TiddlyWiki: [Page and tiddler layout customisation](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Page%252520and%252520tiddler%252520layout%252520customisation.html),我们能够这样做。
### > 第一步:先制作两颗按钮
第一颗按钮(名为 Copy Title Button)用来把当前的 Tiddler 标题的复制到剪贴板上;第二颗按钮(名为 Dummy Second Button)只是一颗假按钮,不会作任何东西(只作 demo 用)。
复制标题的那颗按钮的语法我就不介绍了,具体可以看[官网 tm-copy-to-clipboad 介绍](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/WidgetMessage%25253A%252520tm-copy-to-clipboard.html)。值得一提的是,这个不是 [macro](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Macros.html),所以虽然感觉上和我以前写过的这一页 [TiddlyWiki 实用 macro:copy-block-1](https://zhuanlan.zhihu.com/p/346604189) 很相似,但其实是两个完全不同的概念。

### > 第二步:把这两颗按钮加到一个 Tiddler 里(例如名为 ViewTemplate)
很好,我们现在有两颗按钮了。下一步就要制作一个 Tiddler (名为 ViewTemplate Header)把这两颗按钮放进去。

在加入按钮时,有两个地方要留意:
1. 我们是使用 [Transclusion](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520in%252520WikiText.html) 的方法把这两个 Tiddler 的内容放进 ViewTemplate Header。
2. 严格来说,我们是做用 [Transclusion with Templates](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Transclusion%252520with%252520Templates.html) 的方法来把这两个 Tiddler 的内容放进 ViewTemplate Header。否则在复制标题到剪贴板的按钮里,会复制的标题不会是当前 Tiddler 的标题,而是 “Copy Button Title” ,也就是复制标题按钮的那个 Tiddler 标题了。Transclusion with Templates 就是比普通的 Transclusion 多了 `||`,例如是 `{{||Copy Title Button}}`。
具体的分别我也有一篇文章,详细也可以看这篇 [TiddlyWiki 制造内部笔记链接的方法](https://zhuanlan.zhihu.com/p/346605304)。
然后就是想办法把 ViewTemplate Header 加到每一个 Tiddler 里。具体有三个步骤。
第一步:把 ViewTemplate Header 这个 Tiddler 加入这个神奇的 Tag: [$:/tags/ViewTemplate](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/SystemTag%25253A%252520%252524%25253A%25252Ftags%25252FViewTemplate.html)。这会把 ViewTemplate Header 这个 Tiddler 的内容放在每一个 Tiddler 的页面里。

$:/tags/ViewTemplate 这个 Tiddler 是系统内置的,所以不用自己增加。所有 开头为 $:/ 的 Tiddler 都叫 [System Tiddler](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/SystemTiddlers.html)。你也可以自己写一个 System Tiddler。System Tiddler 和普通 Tiddler 的最大分别只是不能被轻易搜寻。要在 [Advanced Search](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Searching%252520in%252520TiddlyWiki.html) 里才能搜寻到。
第二步:进入 `$:/tags/ViewTemplate` 这个 Tiddler 里。在 ViewTemplate Header 里按下 $:/tags/ViewTemplate 这个 tag 便可以进入。

第三步:修改 `$:/tags/ViewTemplate`。系统会先出一个 warning 问你是否修改 System Tiddler,选择 OK 便可。

然后把 ViewTemplate Header 这个字加在 list 这个 field 内的 `$:/core/ui/ViewTemplate/body` 前便可以了。这样 ViewTemplate Header 这排按钮便会出现在 Tiddler 的内容前面而不是后面。list 这个 field 是用定义所有 tag 过 `$:/tags/ViewTemplate` 的 Tiddler 的先后次序。
好,完成。我们现在加一个普通的 tiddler(名为 Test page),完成后应该能看到这两颗按钮。



有了这个方法,我们日后能玩的东西多着呢。
内心 OS: 这篇很重要,日后还有教学的话应该有不少教学也需要使用这一页的方法。
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
这篇承接上一篇 [在每一个 Tiddler 上加入自定义页面](https://zhuanlan.zhihu.com/p/346651484)。在这一篇里我会利用相同的方法,在每一个 Tiddler 的内容下方加入第一个我个人认为实用的东西:子分页。
所以在看这一篇文章前,请务必先看懂 [在每一个 Tiddler 上加入自定义页面](https://zhuanlan.zhihu.com/p/346651484)。
> 在这篇里我会谈及:
* 什么是子分页?
* 我们想达成的东西:在每一个 tiddler 的最底部里看到自己的所有子分页连结
* 我们要如何在 TiddlyWiki 实作这个在父页看到子分页连结的功能?
* 后续要解决的问题
> 什么是子分页?
---------
这个只是我的定义啦。
假设我们有一个名为 Test page 的 tiddler,那么所有 Tag 了 “Test page” 的 tiddler 都是 Test page 这个 tiddler 的子分页。
例如在这个情况下,Test subpage 1 就是 Test page 的子分页,而 Test page 就是 Test subpage 1 的父页。

但是要是先新建一个新的 tiddler,然后再 tag 回父页太麻烦了。有没有一些快捷的方法?
我们可以在每个 tiddler 的右上角按下这个指向下的按钮,然后选择 “new here” 便可以立即新建一个子分页。

要再快一点的话,可以利用上一篇的方法制作一个按钮来新建子分页,这样可以减少一下按键,有兴趣的同学可以试试自行研究如何实作这个按键。
有了分页这个概念后,整个 TiddlyWiki 的世界会阔了很多。我们的 tiddler 不只是一个扁平的知识网络,现在还多了「分类」这个概念(请看 [从维基百科学习管理个人知识的方法](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/%25E5%25BE%259E%25E7%25B6%25AD%25E5%259F%25BA%25E7%2599%25BE%25E7%25A7%2591%25E5%25AD%25B8%25E7%25BF%2592%25E7%25AE%25A1%25E7%2590%2586%25E5%2580%258B%25E4%25BA%25BA%25E7%259F%25A5%25E8%25AD%2598%25E7%259A%2584%25E6%2596%25B9%25E6%25B3%2595/))。这有三件值得提的事。
第一:有了分类的概念,我们可以把相同性质的 tiddler 都有同一个父页( tag ),这些子页便有了一个不怎么明显的连结。
例如在这个情况下,Test subpage 1 和 Test subpage 2 这两个 tiddler 都有相同的父页 Test page,我们便可以按下 Test page 这个 Tag 便看到所有 Test page 的子分页。

第二:也因为分页的做法只是多了一个 tag,所以我们可以有没有限层级的分类,以及每一个 tiddler 可以有多于一个的父页。在多了一个管理 tiddler 的方式又不失本来的弹性。
第三:由于 tag 这个连结的方法只是 [soft link](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Hard%2520and%2520Soft%2520Links),所以我们就算更改了父页的 tiddler 名称,子分页也没有失去父页这个问题。这个情况下不用 [Relink](https://zhuanlan.zhihu.com/p/346651116) 这个 Plugin 的帮忙解决重新命名的问题。
那么,有了子分页这个概念后,这次我们想做什么呢?
> 我们想达成的东西:在每一个 tiddler 的最底部里看到自己的所有子分页连结
-----------------------------------------
假设我们有以下的情况:
* 有五个 tiddler,分别名为 Test page、Test subpage 1、Test subpage 1a、Test subpage 1b、以及 Test subpage 2。
* Test subpage 1 和 Test subpage 2 都 tag 了 Test page,也就是说 Test page 有这两个子分页。
* Test subpage 1a 和 Test subpage 1b 都 tag 了 Test subpage 1、也就是说 Test subpage 1 有这两个子分页。
有点树状架构是吗?我们就是想在 Test page 里看到这些,应该说想在每一个 tiddler 里都看到自己的子分页连结,并以树状方式表达。留意子分页的子分页是可以折叠的。这样我们能在需要时才展开它们。

> 我们要如何在 TiddlyWiki 实作这个在父页看到子分页连结的功能?
--------------------------------------
如果有了 [上一篇](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/20210102-tiddlywiki-tutorial-viewtemplate-header/%2520) 的概念,这个真的不难。
第一步:新建一个 tiddler 用来展示树状结构,就叫它做 ViewTemplate Footer 好了。

这里我们写了一个 macro 名为 `categories` 并呼叫它。这个 macro 呼叫了 [官方的 toc-selective-expandable macro](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Table-of-Contents%2520Macros) 来把子分页以树状方式展开。
有几个能聊聊的点:
1. `{{!!title}}` 指的是这个 tiddler 的名称,或是使用 transcluion template 时的呼叫者名称,详细看 [官网介绍 Tiddler fields](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23TiddlerFields)。
2. 这里我们使用 `<$macrocall $ xxx />` 而不是 [我们以前学习 macro](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/tiddlywiki-%25E5%25AF%25A6%25E7%2594%25A8-macro-copyblock1/) 时认知的 `<<categories xxx>>` 是因为 `<<categories xxx>` 无法放入 `{{!!title}}` 作为参数,而 `$<macrocall $>` 作为 `<<categories>>` 的原始型态则可以,详细看 [官网的 MacroCallWidget 介绍](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23MacroCallWidget)。
3. 如果我们想把某文字以 tag 的样子表达,可以使用官方的 [transclusion template](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Transclusion%2520with%2520Templates),也就是 `$:/core/ui/TagTemplate`。
第二步:把 ViewTemplate Footer tag 上 `$:/tags/ViewTemplate`,原因请看 [上一篇](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/20210102-tiddlywiki-tutorial-viewtemplate-header/)。就是要在每一个 tiddler 都能展现这一页的意思。
第三步:修改 `$:/tags/ViewTemplate` 并把 ViewTemplate Footer 加在 $:/core/ui/ViewTemplate/body 后。

好,完成。
这次我也把 source 放在 [这里](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/TiddlyWiki_Demo/ViewTemplate_Footer_SubPage.html),大家可以参考看看。
> 后续要解决的问题
----------
可能你会问:这样做要是某一页有很多子分页,那一个 tiddler 会变得很长,不好阅读吧。
对,是有这个问题。
但是我们可以用 [Reveal Widget](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23RevealWidget) 解决掉。简单来说就是根据某 tiddler 的状态来决定展开或是隐藏某些内容。
有了 Reveal Widget 的话,我们可以把整个子分页树都隐藏掉,有需要时才展示。
但是由于篇幅所限,这里就不介绍 Reveal Widget 了、有兴趣的同学可以自行研究如何做。
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [zhuanlan.zhihu.com](https://zhuanlan.zhihu.com/p/346604189)
这是一个 TiddlyWiki 的 macro 教学。这次我们会试试写一个简单的 macro ,为这个 Tiddler 的特定文字旁加上一个按纽,按下便会把该文字放到剪贴板里。方便在其它程序中使用。
虽然这个功能实作起来十分简单,但是对放有时需要快速使用把某些已知的特定文字时可是能省下「选择文字并复制」这个步骤。
> 什么是 Macro?
------------
我们看看什么是一个 macro。一个 [macro](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Macros.html) 就是一个程序把你的输入以自定的方式输出并放到 Tiddler 的方法。
比如说,如果我们定义了一个名为 `display-hello` 的 macro 是展示 `Hello` 这个文字时,我们可以这样写:
```
\define display-hello()
Hello
\end
```
当我们要使用这个 macro 时,我们可以这样写:
又或是这样写(这是最原始的用法):
```
<<display-hello>>
```

> 开始实作这个 macro
--------------
好吧,其实我们也要使用 TiddlyWiki 系统内的 Macro 才能完成我们这次的任务。
在 [TiddlyWiki 的官网](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/) 里有得多实用的资讯,善用搜寻使可以很容易找到一个名为 [copy-to-clipboard](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/copy-to-clipboard%252520Macro.html) 的内置 macro。
于是我们试试使用这个 macro:

我们试试按 copy to clipboard 的按纽,test 这个字真的被放到剪贴板里,只是感觉有点奇怪,因为我们看到这个 copy to clipboard 的时候,其实我们不知道将会把什么东西放进剪贴板里。所以最好的做法是当我们呼叫这个 macro 时,我们能知道自己将会把什么放到剪贴板里,这段字最好能够以等寛字體 [monospace / code](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Formatting%252520in%252520WikiText.html) 的方法显示。
所以,参考了 TiddlyWiki 里关于 [定义 macro](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/MacroCallWidget.html) 的介绍 后,我们可以写出以下的 macro:
```
<$macrocall $ />
```
这里的 src 就是输入到这个 macro 的资料,然后在介绍页里可以以 $src$ 的方式把 src 这个输入文字展示出来,所以如果我们呼叫 `copy-block-1` 这个 macro 时的效果便会变成这样,而按下 copy to clipboard 时便会把 test 这个字放到剪贴板里。

> 每一次都要把 macro 写一次很麻烦啊
----------------------
放心,就像 以 [TiddlyWiki 使用默认文字](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/tiddlywiki-%25E5%25A2%259E%25E5%258A%25A0%25E9%25A0%2590%25E8%25A8%25AD%25E6%2596%2587%25E5%25AD%2597%25E7%259A%2584%25E6%2596%25B9%25E6%25B3%2595-snippet/) 般,我们只需要把 macro 的定义放入 `$:/tags/Macro` 这个 tag 里,那么这个 macro 便会被放到系统里,不用每次定义一次,直接使用便可以了。

> 如果我们呼叫的文字里有双引号怎么办?
--------------------
根据 [官网关于呼叫 macro 的介绍](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Macro%252520Calls%252520in%252520WikiText.html) 里,在呼叫 macro 时,除了把要使用的文字放在 `""`(双引号) 外,我们还可以使用 `' '`(单引号) 或是 `""" """`(三个双引号)
例如:

> 参考资料
------
* [TiddlyWiki: Macros in WikiText](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/static/Macros%252520in%252520WikiText.html)
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
! TiddlyWiki 是一个工具箱
除作为一种多功能的工具之外,TiddlyWiki 也是一个工具箱。
其他笔记产品以基本程序钩住您,然后以非常有用的功能向您收费。TiddlyWiki 有不断扩充的完全免费的视觉主题、调色板、插件、小工具和宏的搜集,您可以混用与匹配,因此您可以调整和自订您的 TiddlyWiki,使其成为您想要的方式。
!TiddlyWiki 是一个用户和开发人员的社区
我们是一个用户和开发人员的社区,彼此互相帮助想像新的思维和组织方式,并创建新的解决方案,故此 TiddlyWiki 正在不断调适以便更好地服务您的需求。TiddlyWiki 用户和开发者分享问题和意见于 TiddlyWiki Google 论坛。他们还创建教学、应用和插件来提升您的 TiddlyWiki 经验。更多详细信息,请参阅目录的社区部分。
!TiddlyWiki 是一种工具
TiddlyWiki 首先是一种工具:它是一个免费的可下载工具,用于从网站、从您的文档或从您的大脑截取和管理内容。它是笔记、书签、便条、写作、管理待办事项清单和项目、协作、博客和出版的工具。
在 TiddlyWiki 您创建或剪贴内容到称为条目的笔记,然后用超链接和标签连接您的条目。可由如标签丸、侧栏页签和 TiddlyWiki 的闪电般快速搜索窗口等功能快速访问您的笔记。您甚至可以动态引入一个条目内容于另一个条目 - 类似使用构建基块 - 创建文章、清单、演示文稿和更多的内容。
使用了 TiddlyWiki 一段时间,也有一些心得想分享。这次介绍的是一个目测比较少用的功能,就是增加默认文字的方法。
在 TiddlyWiki 里,我们首先把一些默认的文字放在不同的 Tiddler 并加上特定的 Tag,然后我们便可以在新的 Tiddler (也就是笔记编辑页)里按下某些按钮便可以立即令编辑器出现该特定的默认文字。
> 如何新增默认文字?
-----------
例如,我们想新增一款默认文字,我们可以:
1. 新增一个 Tiddler
2. 输入这组默认文字(这组默认文字也可以是任何东西,包括 Macro 如下图的 `<<copy-block-1 "">>`,这是我自己新增的 [Macro](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/tiddlywiki-%25E5%25AF%25A6%25E7%2594%25A8-macro-copyblock1/))
3. 为这个 Tiddler 加上 `$:/tags/TextEditor/Snippet` 这个 Tag,这是一个默认的 Tag ,有加上这个 Tag 的 Tiddler 都是默认文字。
4. 可以为 Tiddler 加上一个名为 caption 的 field, 这会改变默认文字显示的名称。如果没有加上这个 field,默认文字会显示为该 Tiddier 的名称。这里我们设置 caption 为 `copy-block-1`

> 如何使用默认文字?
-----------
当我们新增了默认文字后,我们可以在编辑 Tiddler 时按下图的按纽,然后选择已新增的 默认文字,便可以插入该默认文字。

写作日期: 2019-04-29
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理。
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [fspark.me](https://fspark.me/archives/TiddlyWiki-Deploy-To-Server.html)
又是好久没更新了,真是怠惰啊。然而,这次又是旧坑不填挖新坑,前段时间 (N 月前) 又因为隔壁 zcp 的一篇[博文](https://chengpengzhao.com/2020-02-05-kai-shi-shi-yong-tiddlywiki-ge-ren-bi-ji-xi-tong-he-gnucash-ge-ren-cai-wu-guan-li-xi-tong/)折腾起了 TiddlyWiki,因为的确很小众,所以还是觉得有必要记录一下折腾的过程。。。
_pid: [48813987](https://www.pixiv.net/artworks/48813987)_
0. 啥是 TiddlyWiki
----------------
说了半天这到底是个啥啊?用官网的一句话概括便是——
> 一款独特的[非线性](http://tiddlywiki.cn/#Philosophy%20of%20Tiddlers)笔记本。
固然,非线性是也有融入进 TiddlyWiki 设计哲学的方方面面,你大可以随意地打乱或组织你知识点,再用[链接](http://tiddlywiki.cn/#TiddlerLinks)、[标签](http://tiddlywiki.cn/#Tagging)、[列表](http://tiddlywiki.cn/#ListField)和[宏](http://tiddlywiki.cn/#Macros)进行[结构化](http://tiddlywiki.cn/#Structuring),成线成网成面...
但不得不说,TiddlyWiki 没能火起来,与这标语是离不开的..
令我现在只想用一句话彰显它的与众不同——
**能够包含进一个 HTML 网页文件的程序,随你保存到任何地方。**
[](https://fspark.me/usr/uploads/2020/08/2316168025.png)
* **无论平台的强大**——只寄托于 JS 的数据动态处理 与 HTML&CSS 无穷的表现力。有浏览器,就够了。
* **真正的 "Serverless"**——数据就存储在程序本身,一直迭代。
* **开源自由**——用你自己的思考方式来做笔记, 而不是那些笔记软件公司帮你想出来的'目录与标签'的死板方式
* **永久免费**——将你的知识跟一个商业公司的命运捆绑在一起是一种不负责任。
* **便捷无依赖**——真的只是一个 HTML 文件。
* ……
综上,我看到了——**「永恒」**。
也许我又说大了,但它绝对可以保证,在未来几十年,[仍然可以使用](http://tw5-zh-hans.tiddlyspot.com/#Future%20Proof)今天所做的一切。实际上,TiddlyWiki 已经走过了将近十六年。
将 Quine (自产生程式) 与 SPA (单页 web 应用) 完美结合的典范之作,让我激动不已。
1. 前置条件
-------
### 1.1 了解 TiddlyWiki
首要条件不是配置上的,而是你是否想好了要去使用这样一个工具,下面一些链接可以帮助你更好的认识 TiddlyWiki,建议好好读读再来看看要不要入坑,折腾是难免的。
* [使用 TiddlyWiki 打造轻便个人 Wiki 知识库 -- 钉子の次元](http://blog.dimpurr.com/tiddly-wiki/)
* [TiddlyWiki 的使用 -- 钉子的 TiddlyWiki 实例](http://note.dimpurr.com/#TiddlyWiki%20%E4%BD%BF%E7%94%A8)
* [使用 TiddlyWiki 进行个人知识管理 -- Ahonn's blog](https://www.ahonn.me/blog/using-tiddlywiki-for-personal-knowledge-management)
* [开始使用 TiddlyWiki 个人笔记系统 -- zcp](https://chengpengzhao.com/2020-02-05-kai-shi-shi-yong-tiddlywiki-ge-ren-bi-ji-xi-tong-he-gnucash-ge-ren-cai-wu-guan-li-xi-tong/)
* [TiddlyWiki 中文官网 (暂时无法访问)](https://tiddlywiki.cn/)
* [TiddlyWiki 官网](https://tiddlywiki.com/)
* [TiddlyWiki 简中 Wiki](http://tw5-zh-hans.tiddlyspot.com/)
* [用 TiddlyWiki 替代 Notion 和 EverNote 作为个人知识管理系统](https://zhuanlan.zhihu.com/p/140473235)
### 1.2 存储方式概览
TiddlyWiki 当然不会把你的知识条目像钉死在铁皮棺材一样死板地牢牢封印在一个 HTML 里
官方收录的所有存储方式指南:[https://tiddlywiki.com/#GettingStarted](https://tiddlywiki.com/#GettingStarted)
<table><thead><tr><th>存储地 存储形式</th><th>整体 (HTML)</th><th>分立的 Tiddler 条目文件 (Tid)</th><th>数据库</th></tr></thead><tbody><tr><td><strong>本地</strong></td><td>本体 + 浏览器, TiddlyDesktop</td><td>TiddlyServer, Node.js</td><td>Noteself + 浏览器 Local Storage(PouchDB)</td></tr><tr><td><strong>第三方服务</strong></td><td>Github, Gitea, TiddlySpot, 同步盘</td><td>理论上所有的同步盘</td><td>NoteSelf + 第三方 CouchDB(如 IBM Cloudant)</td></tr><tr><td><strong>自部署</strong></td><td>WebDAV, PHP Server, Git service</td><td>TiddlyServer,Node.js</td><td>Noteself + 自部署 CouchDB</td></tr></tbody></table>
实际上这是个很草率的分类,而且每个格子只是例举了最有代表性的方案,且关键的是并不是只能够选定一种,其中组合和转换,足够眼花缭乱了。
### 1.3 为何要部署在服务器
还能为啥,同步呗(现在的笔记没个多端同步编辑都不敢上台
但部署在服务器上的操作实质上违背了 TiddlyWiki 的初衷,破坏了完整的封装性,所以请考虑自己的实际需求。
当然将 HTML 同步在云盘也算一种部署的话,也行,可惜每次同步一点点的更改都需要传输**整个文件**的大小,实则令人不爽。(实际上也不过几 mb,而且同步没有 server 式那么频繁)
### 1.4 部署在云端前你应该
* 熟练 TiddlyWiki 基本操作
* 有基础的建站经历
* 掌握 Linux, Docker 基本命令操作
* **有一颗敢于折腾的心**
2 . 部署在服务器
----------
注意了,这里只是我的折腾记录,所以也没敢说指南,保姆级教程也是没有的,主要只是说说我的使用体验和一些要注意的地方。
### 2.1 Node.js
官方简介:[https://tiddlywiki.com/#Installing%20TiddlyWiki%20on%20Node.js](https://tiddlywiki.com/#Installing%20TiddlyWiki%20on%20Node.js)
项目地址:[https://github.com/Jermolene/TiddlyWiki5](https://github.com/Jermolene/TiddlyWiki5)
依赖 Node.js,也是官方主推,并开发维护的方案。
内存占用大 (Node 通病),随便 100 多 M 对小机真是极大的负担。
推荐国内和内存较多的主机可以试着搭建,当然在本地局域网搭建也可。
好处就是流量极省,速度也快,以及[懒加载](https://tiddlywiki.com/#LazyLoading)。
部署场景的话,可以选择中心或者分布式。中心的话,一切操作都经 HTTP 协议以 Web API 的方式与服务器通信来完成,而分布式则需要依托其他方案来同步 tiddler 数据文件夹达成物理修改。
同步的话,只用同步单次更改所变动的 tid 文件就行了,看起来是个不错的方案了,可惜另一个弊端又出现了——
在手机上用 Termux 搭建测试后,发现同步后的内容不会马上更新到网页上,而要重启 node 服务,这下这个功能又变得鸡肋起来了(当然也可以简单的用 nodemon 或 pm2 解决)。
### 2.2 Github/Gitlab
官网简介:[https://tiddlywiki.com/#Saving%20to%20a%20Git%20service](https://tiddlywiki.com/#Saving%20to%20a%20Git%20service)
已经并入 TiddlyWiki 核心的同步方式,设置好就可以同步保存整个文件到指定仓库。
好处不必说,直接获得了版本管理能力,还可以直接上传到个人 io 仓库托管为 Git Page,随时公开更新的 Wiki 页面就完成啦
缺点也显而易见,不忍直视的 commit 量和 git 仓库冗余,尤其是开启加密后(真是自己交的代码就好了(小声嘀咕
[](https://fspark.me/usr/uploads/2020/08/2374348348.png)
### 2.3 Note Self
官网简介:[https://noteself.org/](https://noteself.org/)
项目地址:[https://github.com/NoteSelf/NoteSelf.github.io](https://github.com/NoteSelf/NoteSelf.github.io)
这应该是目前使用起来体验最贴近现代笔记应用的方式了,本来就是以印象笔记目标开发的。能够实现离线和在线同步的无缝切换。可以仅仅依靠浏览器的 LocalStorage 存储数据库,当然更保险的措施是先给它搭个 CouchDB 后端,推荐使用 Docker。
#### 直接安装
参考官网文档:
1. [https://docs.couchdb.org/en/stable/setup/single-node.html](https://docs.couchdb.org/en/stable/setup/single-node.html)
2. [https://docs.couchdb.org/en/stable/install/unix.html](https://docs.couchdb.org/en/stable/install/unix.html)
如果到最后没能启动,千万不要傻到和我一样直接 root 运行
[https://stackoverflow.com/questions/18401788/couchdb-on-freebsd-doesnt-start-as-couchdb-user/18416985#18416985](https://stackoverflow.com/questions/18401788/couchdb-on-freebsd-doesnt-start-as-couchdb-user/18416985#18416985)
而得用服务的方式启动
`systemctl start couchdb`
#### Docker
1. 安装 Docker,将当前用户加入 Docker 组或以下命令 sudo 运行
2. 创建 tiddlywiki_db 卷,便于今后迁移
`docker volume create tiddlywiki_db`
3. 启动实例
`docker run --name tdwkdb -p 5984:5984 -v tiddlywiki_db:/opt/couchdb/data -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=你的管理密码 -d apache/couchdb:latest`
4. 直接访问 IP:5984,或者[反代](https://docs.couchdb.org/en/stable/best-practices/reverse-proxies.html)到一个域名上,多级目录也可
5. 出现`{"couchdb":"Welcome","version":"3.0.0","git_sha":"03a77db6c","uuid":"794705608cb4dacc4637b6d305b3de3a","features":["access-ready","partitioned","pluggable-storage-engines","reshard","scheduler"],"vendor":{"name":"The Apache Software Foundation"}}`之类的就成功了
6. 进入域名 /_utils/#login 登录设置
7. 解决 CORS 跨域问题,设置为自己的域名更安全。
8. 延长登录时间,参照[文档](https://docs.couchdb.org/en/2.3.1/config/auth.html#couch_httpd_auth/timeout),避免每天都要手动重新登录同步,是的,设置在 CouchDB 上而不是 NoteSelf
关于后面这块老外 @[thelostadmin](https://forum.noteself.org/u/thelostadmin) 的教程讲得比我好多了,还有不懂就看看吧——[How to Setup CouchDB for Note Self](http://thelostadmin.tiddlyspot.com/#How%20to%20Setup%20CouchDB%20for%20Note%20Self)
### 2.4 TiddlyServer
官网简介:[https://tiddlywiki.com/#TiddlyServer%20by%20Arlen%20Beiler](https://tiddlywiki.com/#TiddlyServer%20by%20Arlen%20Beiler)
项目地址:[https://github.com/Arlen22/TiddlyServer](https://github.com/Arlen22/TiddlyServer)
Node.js 程序,若想同时部署多个 Wiki 程序且提供简易的 HTTP 文件服务,TiddlyServer 不要错过。
TiddlyServer 可以映射网址路径到指定文件夹,若是 TiddlyWiki 数据文件夹则会识别为 Wiki,这样带来的最大的好处就是可以随意延伸扩展,且提供了文件直链供 Wiki 直接引用,且自带权限组管理。
3. 几种方式的异同
----------
NoteSelf 将渲染运算的任务完全交由前端负责,服务器上需要的只是一个 CouchDB,开销比 NodeJS 方式小得多,而且也可以直接进入数据库进行编辑,而且也能够直接继承 CouchDB 数据库的版本控制,备份等功能。
其他人表面上访问只有一个空 NoteSelf wiki 文件,只有手动输入绑定后端数据库才能够得以运作。
亮点还在离线模式也可以凭借浏览器的 LocalStorage 进行数据存储,待到下次连接服务器再进行同步。不过不要太相信 LocalStorage 的可靠性,这里已经经历过数次不明原因的数据丢失,但在同步在服务器上的都没事。
同步效率是最高的,甚至能够协作编辑,电脑上草稿编辑页面都能够近乎实时的同步在手机上。适合 TodoList 这样依赖同步较高的应用。
TiddlyServer 可以较为便捷的在多 wiki 中切换,但随之而来的代价是高内存占用,因为 nodejs 式其实都是把 wiki 内容全部装载进内存在服务器端进行渲染返回 html 的。基本上可以按照一个 wiki(空) 100M 左右来换算,小机根本撑不住啊。
但之后的数据交互只有 tidder 的更新和半分钟一次的状态更新比对。
TiddlyServer 的亮点在于自身也有一套权限组管理系统,以及可以直接挂载外部储存路径,方便直接上传图片或其他附件到服务器以便 wiki 直接引用直链而不是嵌入 wiki 使得这些二进制数据将 wiki 的体量一下撑破天。毕竟你就算天天记录的话,几十年年下来纯文本又能增长个几 M?
还有一种安心感,不会像 NoteSelf 一样怀疑自己究竟同步没有,这里每一次更改都会推送到服务器。
如果想直接通过修改 wiki 文件夹中的 tiddler 文件来直接修改条目内容的话还不行。之前也说了,已经加载在内存里了,所以每次修改之后还得重启 TiddlyServer/Node。想通过直接两端同步 wiki 文件夹也是可行的。数据交换也小更安全。
HTTPS 保证传输不泄密。还不放心可以自签证书,将根证书分发到每个私人设备,但一定要保证私钥什么的放在安全的地方。
遗憾的是作者似乎并没有打算支持懒加载功能,因为可能会带来许多[麻烦](https://github.com/Arlen22/TiddlyServer/issues/58)。
4. FAQ
------
**Q1:我要用 Markdown 而不是 TiddlyWiki 主推的 WikiText!**
**A1:** 我开始也看不惯这一点,虽然用了官方市场提供的 Markdown 支持插件,但后来发现这个支持不了在 Typora 等一些 Markdown 编辑器里用的超爽的指定语言代码块,后来才转去研究 WikiText。之后却深深爱上了它的用法,很多常见语法的确不一样但实质上却相通着,比如字体加粗变为了`"`,段落变为了`!`,但这并不妨碍我们使用它的时候灵活转换。
最关键的是 Markdown 削弱了 WikiText 的表现力,无法使用宏,过滤器,wiki 内引用等等 wiki 才有的魔法,纯 Markdown 只是个记事本,WikiText 才是真正的使用 Wiki。
**Q2:没有图表?**
**A2:** 使用强大的 [TiddlyMap](http://tiddlymap.org/),用图连接组织你的任意条目。
[](https://fspark.me/usr/uploads/2020/08/3323957369.png)
使用 [D3.js](https://tiddlywiki.com/plugins/tiddlywiki/d3/),进行数据可视化。
[](https://fspark.me/usr/uploads/2020/08/3183792662.png)
事实上你可以轻松地移植任何 js 实现的图形库来为你的 wiki 增强表现力。
**Q3:没有双向链接?**
**A3:** **「双向链笔记」**的概念随着 [Roam Research](https://roamresearch.com/) 的出现而大热,而 RoamResearch 封闭又昂贵,实在不看好长期发展,与时俱进的 TiddlyWiki 则成了不错的开源替代。目前共有两个 Roam-like 的分支选择—— [Stroll](https://giffmex.org/stroll/stroll.html#Welcome%20to%20Stroll)(前身是 [TiddlyBlink](https://giffmex.org/gifts/tiddlyblink.html))和 [TiddlyRoam](https://tiddlyroam.org/) ,不妨试试。
**Q4:没有加密?**
**A4:**加密当然是有的,按照粒度分整体 HTML 加密和 Tiddler 加密。因为存储架构的问题基于 Node.js 版的自然是用不了整体加密的,应当转而使用 [EncryptTiddler](https://danielorodriguez.com/TW5-EncryptTiddlerPlugin/) 插件来进行 Tiddler 加密(支持批量)并开启 HTTPS 加密传输。 而同步整体的如 Github 式则能够应用整体。具体参考文档:[https://tiddlywiki.com/#Encryption](https://tiddlywiki.com/#Encryption)。
**Q5:哇,好丑啊,能好看点嘛**
**A5:** 颜值至上的笔记软件社会里,我们 TiddlyWiki 什么时候才能站起来?气抖冷!好吧,的确很多人一开始就被这有年代感的界面给劝退了,事实上已经有许多 wiki 主题界面被魔改到第一眼都快认识不出是 TiddlyWiki,社区中也涌现了许多富有现代感的主题:[Moments](https://ibnishak.github.io/Tesseract/themes/moments.html)、[WhiteSpace](http://j.d.whitespace.tiddlyspot.com/)、[Material](http://j.d.material.tiddlyspot.com/),尽情展现你的前端魔法吧!
[](https://fspark.me/usr/uploads/2020/08/3089826444.png)
**Q6:有没有几个范例?**
内容组织和管理形式,其实官方 wiki 就已经是最好的教科书了,但在这还是贴上几位国人分享的 wiki 供参考,能够带来更多启发。
* [https://wiki.hintsnet.com/](https://wiki.hintsnet.com/)
* [https://wiki.zhiheng.io/](https://wiki.zhiheng.io/)
* [https://onetwo.ren/wiki/](https://onetwo.ren/wiki/)
插件和宏的探索,请用 [TiddlyWiki toolmap](https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM)。
当然很多 trick 只有开发插件和宏的时候才能体会到,参与[社区](https://groups.google.com/forum/#!forum/TiddlyWiki)一起讨论吧!
5. 后记
-----
### 5.1 Hackability
对作者的一篇演讲深以为然——
**可编程性也是人权
[Hackability as a Human Right](https://www.youtube.com/watch?v=a16yczjr50s&feature=emb_title)**
这一点体现在 TiddlyWiki 设计的方方面面,以至每次版本更新都有专门的一栏显示对于可编程性的更新:[http://tw5-zh-hans.tiddlyspot.com/#Releases](http://tw5-zh-hans.tiddlyspot.com/#Releases)
信息最终储存的形式也是自由多样,无论是 html,单个的 tid 文件,CouchDB 后端数据库,都能够被随意的被拿来二次开发,对信息再度加工联系转换。
### 5.2 Tiddler 之禅
Tiddler 的本意是小鱼,使用者则是 TiddlyWiki 图标上的小猫。Tiddler 是信息的最小单位,储存着你的知识,你的所知所想,你的一切。
记录 (log) 是第一步 ,回顾 (review) 和组织(organize) 才是最重要的。这将花费大量时间,但同时也改变着你的思维方式和组织想法的方式。
文章,技术都是迭代的,就算第一步偏差得再远,不迈出第一步,就永远都无法收敛到正果。过于追求完备而拖延是不可取的,用 Tiddler 的方式来捕捉平时的灵感再组织,比构思成文简易得多。
> **写作之难,在于把网状的思考,用树状的语法结构,转换成线性的字符串。** ——_Steven Pinker_
实际上自上而下的组织方式本身就是反人类直觉的,大脑总会不自觉地由点及面不停跳转,然而又不会像 CPU 一样容易切换上下文,而是更倾向不受控制的沉浸。
如今各种鼓吹的所谓 “第二大脑”,便是如此吧。
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [zhuanlan.zhihu.com](https://zhuanlan.zhihu.com/p/346647657)
个人学习 [TiddlyWiki](https://zhuanlan.zhihu.com/p/346599289) 时,一个比较花时间去学习的是 [Filter Expression](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Expression)。一旦学会了即使一点也好,也能为 TiddlyWiki 解封了十倍以上的威力。在这篇里将会介绍什么是 Filter Expression、Filter Expression 能做什么、以及基本的语法和例子。
* 什么是 Filter Expression,以及 Filter Expression 能做什么?
* Filter Expression 的基本的语法是?
* Filter Expression 有什么基本和进阶的应用?
> 什么是 Filter Expression,以及 Filter Expression 能做什么?
--------------------------------------------------
> Filter Expression 的的一个常见用途是用作找出符合条件的 tiddler 们,并在 tiddler 上展示。
Filter Expression 本身只是一个字串。例如是 `[tag[Today]field:caption[hello]]` 这样。我们可以利用 Filter Expression 来找出符合条件的 tiddler 们(List of tiddler)。
例如最基本的例子是找出所有有某个 Tag 的 tiddler `[tag[Today]]`、找出所有标题含有某个字的 tiddler `[regexp:title[Journal]]` 、或者复杂一点是找出所有有某个 Tag 的 tiddler 并且标题含有某个字的 tiddler 等`[tag[journal_2020]regexp:title[Journal]]`。
那么我们找出这些符会条件的 tiddler 来做什么?例如我们可以在一个 tiddler 里加入一个 [list widget](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23ListWidget),而当我们把这句 Filter expression 放入这个 list widget 后,这个 tiddler 便会把所有符合这个条件的 tiddler 都展示出来,这对于我们管理和处理 tiddler 时十分有用。

一个常见例子就是用作 TODO List。我们可以把所有 tag 上 task 的 tiddler 展示出来,并在旁边加上一个 check box。我们可以设定一旦该 check box 被打勾,这个 tiddler 的 tag 便会由 task 变成了 done,所以再也不会在这个 TODO List 上出现了。关于这个用途官网有一个 [详细的例子](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23TaskManagementExample)。

当然,实际上 Filter Expression 能做到的东西可以远比刚才的例子强大得多。例如假设你把 tiddler 们 tag 上日子,而这个日子的格式例如是 `20200716 Journal (Week 29 Thu)`,我们甚至能找出所有 Week 29 的 tiddler。
也因此,Filter Expression 的语法相对上比较复杂。以下会稍微介绍一下基本语法。
> 基本的语法
-------
我们以以下的这句 filter expression 作为例子来介绍:
`[tag[task]regexp:title[Blog]] -[regexp:title[omni]] +[tagging[]] ="Additional Tiddler"`
首先,一句 Filter Expression 里是由一个或多于一个的 [run](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Run) 所组成(由 “ “ 所分隔)。例如这个例子里有 4 个 run,分别是:
1. `[tag[task]regexp:title[Blog]]`
2. `-[regexp:title[omni]]`
3. `+[tagging[]]` 以及
4. `="Additional Tiddler"`
至于那些 `-` 、 `+` 、`=` 是一个连接每个 run 的方式,稍后再谈(留意这些 `-` 、 `+` 、`=` 并不是 run 的一部分)。
而每一个 run 是由一个或多于一个的 [step](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Step) 所组成(都是由 `operator:suffix[parameter]` 的方式来表现)、或是直接以 `"<text>"` 的方式来代表。operator 指的是一些官方提供的操作,例如上面出现的 tag 等等。[这里](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Operators)有详细的清单。
以以上的例子来说:
* `[tag[task]regexp:title[Blog]]` 这个 run 里有两个 step。
* 第一个是 `tag[task]` ,operator (名称)是 [tag](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23tag%2520Operator)、parameter 是 task。
* 第二个是 `regexp:title[Blog]`,operator 是 [regexp](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23regexp%2520Operator)、suffix 是 title、parameter 是 Blog
* 这个 run 的意思是找出所有有 tag 为 task 、并且标题包含 Blog 的 tiddler(以 [regular expression](https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Regular_expression) 来表达)。
* `-[regexp:title[omni]]`这个 run 里有一个 step。
* operator 是 [regexp](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23regexp%2520Operator)、suffix 是 title、parameter 是 omni
* 这个 run 的意思是找出所有标题包含 omni 的 tiddler(以 [regular expression](https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Regular_expression) 来表达)。
* 而每一个 run 是和前面的 run 有关系的。由于这个 run 的前面有 `-` 的关系变成了剔除这些 tiddler 的意思,这变成了这个加上前一个 run 加起来的意思是 “找出所有有 tag 为 task 、并且标题包含 Blog 的 tiddler,并且剔除标题包含 omni 的 tiddler。”
* `+[tagging[]]` 这个 run 里有一个 step, 而这个 run 的 operator 是 [tagging](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23tagging%2520Operator)。
* 假设之前两个 run 得出来的结果只有两个 tiddler ,分别是 “Blog : Post: aaa” 和 “Blog : Post: bbb” ,那么这三个 run 得出的结果是所有有 tag 上”Blog : Post: aaa” 或 “Blog : Post: bbb” 的 tiddler 们。
* 最后,`="Additional Tiddler"` 指的只是一个名为 “Additional Tiddler” 的 tiddler。而 `=` 的意思是在前面 3 个 run 的结果上直接加上这个 run 的结果,也就是”Additional Tiddler 这个 tiddler。
例子有点复杂。但我相信有了概念后,看这几篇应该不是问题了。
* [Filter Syntax](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Syntax)
* [Filter Expression](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Expression)
* [Filter Run](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Run)
* [Filter Step](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Step)
* [Introduction to Filter notation](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Introduction%2520to%2520filter%2520notation) 这篇有更多 Filter Expression 的例子。
> 进阶应用:Filter Expression 不只是为了找出 tiddler 们而存在哦
----------------------------------------------
随着时间的发展,Filter Expression 里的 operator 也不只是为了 tiddler 而服务,例如加上了很多的关放文字操作的 operator(String operators) 和数学操作的 operator(Mathematics Operators)。
例如以下的 Filter Expression,你猜会出现了什么的结果?
`=1 =2 =3 =4 +[multiply[4]multiply[3]] -12`
相信看到这里,也知道这个 Filter Expression 有 6 个 run 了。以下来说每个 run 得出的结果吧。
我们可以只在 TiddlyWiki 里不用写程序便能进行这些数学运算,不要忘记这只是一个 Wiki 软件而已!
<table data-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="striped"><tbody><tr><th></th><th>Run</th><th>每个 run 得出的结果(以逗号分隔的列表)</th></tr><tr><th>1</th><td>=1</td><td>1</td></tr><tr><th>2</th><td>=2</td><td>1,2</td></tr><tr><th>3</th><td>=3</td><td>1,2,3</td></tr><tr><th>4</th><td>=4</td><td>1,2,3,4</td></tr><tr><th>5</th><td>+[multiply[4]multiply[3]]</td><td>12, 24, 36, 48</td></tr><tr><th>6</th><td>-12</td><td>24, 36, 48</td></tr></tbody></table>
> 进阶应用:把 variable 和 transclusion 和 Filter Expression 结合
-------------------------------------------------------
另外,我们还可以在 step 里放入 [variable](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Variables)(以 `<variable_name>` 的方式表达) 、或是 [transclusion](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Transclusion%2520Basic%2520Usage) 的表达式(以 `{transclusion_value}` 的方式表达)。因为 Variable 和 Transclusion 不是这篇的课题,在这里不多谈了,有兴趣可以看 [这里](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Filter%2520Parameter)。
此外,我们可以把 Filter Expression 的结果以 transclusion 的方式展示出来(这叫做 Filtered transclusions)。方法是使用 `{{{ Filter Expression }}}` 。详细[看此](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Widgets%2520in%2520WikiText)。但如果以这个方式以 [set widget](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23SetWidget) 的方式放在 variable 里,这个 variable 只包含该 Filter Expression 的第一个结果。
事实上,还真的有人利用以上的特性制造了一个为每个 tiddler 作计时器的工具(连结[按此](https://link.zhihu.com/?target=http%3A//tiddlytools.com/timer.html))。由于我有把 TiddlyWiki [当作任务管理软件](https://zhuanlan.zhihu.com/p/346603481)的习惯,最近我还把这个工具用作为自己的每个任务计时的工具。
> 总结
----
Filter Expression 虽然不算容易学习,但是这是我认为和其他 wiki 应用的很大的分别,这个功能和其他的 [widget](https://link.zhihu.com/?target=https%3A//tiddlywiki.com/%23Widgets%2520in%2520WikiText) 结合起来 ,就会变成了订制度十分高的工具,功能基本上已经超越了 wiki 工具的范围。
也因为 TiddlyWiki 有这么弹性的功能,才能让我们自己做出满足自己需要的功能。
本文授权转载自个人博客:[點字記](https://link.zhihu.com/?target=https%3A//roulesophy.github.io/),仅授权知乎账号[闷声](https://www.zhihu.com/people/2dob)转载,仅做简化字处理
欲标示为任务清单的任务条目需标签为task
已经完成的任务需标签为done
! 进行中
//待完成的任务清单//
<<list-tagged-draggable tag:"task" subFilter:"!has[draft.of]!tag[done]" itemTemplate:"TaskManagementExampleDraggableTemplate" emptyMessage:"你没有待处理的任务">>
! 已结束
//(已完成的任务清单)//
<$list filter="[!has[draft.of]tag[task]tag[done]sort[created]]">
<div>
<$checkbox tag="done"> ~~<$link/>~~</$checkbox>
</div>
</$list>
!Markdown
''I have the markdown plugin, but autocompletion for linking doesn't work in my Markdown tiddlers!''
<span class="indent1">
The autocompletion of links with double brackets `[[link]]` is controlled by the comptext plugin. Users of Markdown have noticed that they can't use the autocomplete in their Markdown tiddlers. To make autocompletion compatible with formatting in Markdown tiddlers, create a tiddler with the title `$:/config/EditorTypeMappings/text/x-markdown` and put this in the text field: `comptext`
$:/config/EditorTypeMappings/text/x-markdown
Then, to enable the `[[]]` format for a link, open the following shadow tiddler: $:/config/markdown/renderWikiTextPragma and replace the text with: `\rules only html image macrocallinline syslink transcludeinline wikilink filteredtranscludeblock macrocallblock transcludeblock prettylink`
</span>
```
"""
This is a line
and this is a new line
while this is yet another line
and this is the final one
apart from this one
"""
```
"""
This is a line
and this is a new line
while this is yet another line
and this is the final one
apart from this one
"""
[[ZT:武汉某幸福中产家庭里一个狗,的波澜壮阔大计...|https://www.douban.com/group/topic/19145313/]]
来自: 弱水(水无色,色丰……) 组长 2011-04-16 21:38:54
标题:ZT:武汉某幸福中产家庭里一个狗,的波澜壮阔大计划(励志向上)——HPer 佛搂蜜
中午。
-----
一个狗把男主人叫到客厅。
"你来。" 它说。
"请坐到沙发上。我有重要的事情和你说。"
"我要走了。" 一个狗说。站在男主人左侧,双前手叉腰。
"出远门,去寻找自己。"
"我必须走了!" 它说, "我想了好久,必须走了。"
"我腿短。"
"必须出门,去寻找自我, 进行灵魂认知的旅程。"
"不,不能再等了。" 一个狗说。走过来站在男主人右侧。前手们交叉抱胸前。
"普通一个狗的寿命只有十来年。"
"我已经五岁。不再年轻。"
"我的身体在走下坡路。我能感觉的到。"
"要对自己负责!这是我最宝贵的年华。"
"青年一个狗的路在何方? "
"上帝派我来这个世上,我的使命是什么?" 一个狗激动,前手们激烈比划。
"我要出去,我必须出去! 去寻找灵魂!寻找自我!"
"解构,打乱,重组,"
"寻找!寻找!寻找! "
"找到真正的我!" 一个狗继续激动。
接着,一个狗走到阳台,跳进单缸洗衣机里,双前手扒着内缸上沿,只把眼睛露出来,又开始说。有一种嗡嗡的回声。
"很多时候我不知道自己是谁。"
"躺在床上,触摸不到自己的灵魂。常常整晚流泪。" 眼眶湿润。
"我究竟是谁?" 捧心。
"一个一个狗的生活必须是文艺的!"
"精致。诗意。"
"象一个水晶罐子,充满万物的灵。"
"爱自己。玩命爱自己。"
"让世界陌生化!"
"保持敬畏。"
"我应该这样。而不是每天混吃等死,迷失在物质。"
抹一下眼角。
"幸福是一杆热枪 ,妈妈。
是的,它是的。"
"你看旁边屋子里那头狗熊!" 一个狗提高音量,从洗衣机里探头说。
"假装冬眠,半夜爬出来翻腾冰箱,偷东西吃。"
"耻辱!" 一个狗再次提高音量。
"还有那只猫头鹰!" 一个狗指着冰箱上的猫头鹰说,使用右前手。"这么多年就一直在那里站着,和咕咕钟有什么区别?"
"有什么区别?!"
"我绝不会过这种低级的生活!"
"如果那样我情愿死!"
"不死也要抽自己至死。"
bia唧了一下嘴。从洗衣机里跳出来,凑到男主人脸跟前,搂肩膀严肃的说: "你必须给我5000块钱。"
停顿,
"这是毫无疑问的。"
再次停顿。
"这5000块钱不是说我要享受,不是的。" 一个狗严肃的说。
"我绝不是要享受!绝不会去买好吃的:鸭脖子,酱肘子,火腿肠,驴肉火烧。也不会去喝啤酒。更不会去洗桑拿,做足底按摩。不会的,绝不会!"
"这5000块钱只是让自己安心一点。"
"万一,我是说万一。如果我有什么不测,病倒在他乡,或者掉井盖里,有人可能会送我回家。这是一个保证。"
"将会且必将是一次纯粹的心灵之旅,绝不会掺杂物质纷扰。"
神色庄重。
"我腿短。做出这样的决定是多么的不易。这需要何等坚强的毅力,伟大精神,所以你必须给我5000块钱。"
"而且我腿短。" 一个狗补充。再次强调。双前手在胸前外翻,做了个献宝的动作,手心向上。
"你放心,这5000块钱我会放在紧贴肚皮的地方。" 一个狗小声说, "因为我腿短,而且肚皮有些下垂,与地面的距离极近,所以是绝不会被人发现的。除非他们把我翻过来。"
"人们不会轻易把一个狗翻过来,这极不礼貌。所以钱放在这个位置是很安全的。" 一个狗娓娓道来。
最后的关键时刻了。一个狗爬上沙发靠背,扶墙移动至左侧边缘,"噌"一下跳到冰箱顶上。转身。猛然发力,"嗷"的叫一声,靠后腿们直立起来,和猫头鹰并排,激动的开始说:
"我是尤利西斯!
"我是摩西!"
"我是吉庆街边的俄狄浦斯!"
"我是东湖岸边的达摩!"
"我是二人转台上的jim morrison!""
高速率挥舞双前手。
"我见到过地狱与天堂的婚礼,战舰在猎户座肩旁熊熊燃烧!"
"我注视万丈光芒在天国之门的黑暗里闪耀!看时间枯萎。"
"我驾着疯狂通往智慧的圣殿!"
"在我面前的是一条荆棘路!"
"我放弃舒适安逸的生活,去进行灵魂之旅,"
"去醉日逐舟!"
"去叩开感知的大门!"
"去参加电子葬礼!"
"与众神裸体午餐!"
"这是多么的伟大!"
挥舞。眼神焦点放无限远。迷离。
"一个狗! 伟大!伟大!"
"生活! 伟大!伟大!"
"文艺! 伟大!伟大!"
"你必须给我5000块钱!"
声嘶力竭。
"你必须给我5000块钱!"
舔一下嘴唇。
"到南方去!到南方去!到云的南方~"
"寻找!寻找!寻找!寻找自己!"
停顿,
"寻找自己!"
停顿,
"寻找自己!"
身体剧烈起伏。盯着男主人。右后腿撑冰箱顶部。成四十五度角。
男主人说好你去吧。不过我只能给你20块钱。
没有抬头。
第二天中午就回来了,还带了一头驴。进门喊:我要吃肉!